lion 6 months ago
parent 65f038f8c2
commit 3b9787d36c

@ -0,0 +1,18 @@
import request from '@/utils/request'
export function getPlanActLinks(params, noloading = false) {
return request({
method: 'get',
url: '/api/ht/fund_log/index',
params,
noloading
})
}
export function updateContractPlanActLinks(data) {
return request({
method: 'post',
url: '/api/ht/fund_log/update-contract-plan-act-links',
data
})
}

@ -435,17 +435,34 @@ export default {
.toFixed(2)
.replace(/(\d)(?=(\d{3})+\.)/g, '$1,') : ''
}
}, {
label: '预算计划',
width: 330,
align: 'left',
customFn: (row) => {
if (row.plan_link && row.plan_link.length > 0) {
return row.plan_link.map((item) => {
return (
<div>
[{item.plan?.year}] - {item.plan?.name}
<br/>
[使用金额] {item.use_money}{' '}
</div>
)
})
}
}
}, {
label: '已纳入资金执行率金额',
width: 300,
align: 'left',
customFn: (row) => {
if (row.plan_link && row.plan_link.length > 0) {
return row.plan_link.map((item) => {
if (row.plan_act_links && row.plan_act_links.length > 0) {
return row.plan_act_links.map((item) => {
return (
<div>
{' '}
[{item.plan.year}] {(item.plan && item.plan.pid_info) ? item.plan.pid_info.name : ''} - {item.plan.name} <br /> [使用金额]{' '}
[{item.plan.year}] - {item.plan.name} <br /> [使用金额]{' '}
{item.use_money}{' '}
</div>
)
@ -458,24 +475,6 @@ export default {
prop: 'type',
width: 120
},
{
label: '预算计划',
width: 330,
align: 'left',
customFn: (row) => {
if (row.plan_link && row.plan_link.length > 0) {
return row.plan_link.map((item) => {
return (
<div>
[{item.plan?.year}] {(item.plan && item.plan.pid_info) ? item.plan.pid_info.name : ''} - {item.plan?.name}
<br/>
[使用金额] {item.use_money}{' '}
</div>
)
})
}
}
},
{
prop: 'flow_links',
label: '流程状态',

@ -0,0 +1,758 @@
<template>
<div style="padding: 0 20px">
<lx-header
icon="md-apps"
text="计划执行关联"
style="margin-bottom: 10px; border: 0px; margin-top: 15px"
>
<div slot="content" />
<slot>
<div class="selects">
<div>
<span style="padding: 0 6px; word-break: keep-all">关键词</span>
<span>
<Input
v-model="keyword"
placeholder="请输入关键字"
style="width: 180px"
/>
</span>
</div>
<div>
<span style="padding: 0 6px; word-break: keep-all">是否进入资金执行率</span>
<Select
v-model="enter_act_link"
clearable
placeholder="请选择"
style="width: 120px"
>
<Option :value="0" label="否" />
<Option :value="1" label="是" />
</Select>
</div>
<div>
<span style="padding: 0 6px; word-break: keep-all">状态</span>
<Select
v-model="status"
clearable
placeholder="请选择"
style="width: 100px"
>
<Option :value="0" label="待审核" />
<Option :value="1" label="已审核" />
</Select>
</div>
<div>
<Button
type="primary"
@click="doSearch()"
>查询</Button>
</div>
<div>
<Button type="primary" ghost @click="resetSearch"></Button>
</div>
</div>
</slot>
</lx-header>
<xy-table :list="list" :table-item="table">
<template v-slot:btns>
<el-table-column
label="操作"
:fixed="$store.getters.device === 'mobile'?false:'right'"
width="180"
header-align="center"
>
<template slot-scope="scope">
<Button
size="small"
type="primary"
style="margin-left: 10px; margin-bottom: 4px"
@click="showEditDialog(scope.row)"
>修改资金执行率</Button>
</template>
</el-table-column>
</template>
</xy-table>
<div style="display: flex; justify-content: flex-end">
<Page
:total="total"
show-elevator
show-sizer
@on-change="pageChange"
@on-page-size-change="pageSizeChange"
/>
</div>
<!-- 修改资金执行率弹窗 -->
<el-dialog
title="修改资金执行率"
:visible.sync="editDialogVisible"
width="80%"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<div v-if="currentEditRow">
<!-- 基本信息 -->
<div style="margin-bottom: 20px; color: #000;display: flex;justify-content: space-between;">
<div v-if="currentEditRow.contract">
<strong>合同名称</strong>{{ currentEditRow.contract.name }}
</div>
<div v-if="currentEditRow.fund_log_collect">
<strong>付款集合</strong>{{ currentEditRow.fund_log_collect.name }}
</div>
<div>
<strong>金额</strong>{{ currentEditRow.apply_money ? Number(currentEditRow.apply_money).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,') : '' }}
</div>
</div>
<!-- 预算计划搜索区域 -->
<div class="select-container" style="margin-bottom: 20px;">
<DatePicker
:value="planSelect.year"
placeholder="选择所属年份"
placement="bottom-start"
style="width: 180px; margin-right: 10px"
type="year"
@on-change="handleYearChange"
/>
<el-select
v-model="planSelect.plan_department_id"
placeholder="科室选择"
clearable
size="small"
style="width: 180px; margin-right: 10px"
@change="getBudgets(true)"
>
<el-option
v-for="item in departments"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
<el-cascader
:value="planSelect.type"
:options="planTypes"
:props="{
checkStrictly: false,
label: 'name',
value: 'id',
}"
placeholder="资金类型选择"
clearable
size="small"
style="width: 220px; margin-right: 10px"
@change="handleTypeChange"
/>
<Input
v-model="planSelect.name"
search
enter-button="搜 索"
clearable
placeholder="搜索预算计划.."
@on-search="getBudgets(true)"
/>
</div>
<!-- plan_link表格有数据时显示 -->
<div v-if="showPlanLinkTable && currentEditRow.plan_link && currentEditRow.plan_link.length > 0">
<h5 style="margin-bottom: 10px; color: #67C23A;">预算计划使用情况</h5>
<el-table :data="getPlanLinkData(currentEditRow)" border>
<el-table-column label="" width="55" align="center">
<template slot-scope="scope">
<el-checkbox v-model="scope.row.selected" @change="handleSelectionChange(scope.row)" />
</template>
</el-table-column>
<el-table-column prop="year" label="年份" width="100" align="center" />
<el-table-column prop="name" label="名称" min-width="200" />
<el-table-column prop="content" label="内容" min-width="200" />
<el-table-column prop="money" label="计划金额" width="150" align="right">
<template slot-scope="scope">
{{ scope.row.money ? Number(scope.row.money).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,') : '' }}
</template>
</el-table-column>
<el-table-column label="使用金额" width="150" align="right">
<template slot-scope="scope">
<el-input-number
v-model="scope.row.use_money"
:precision="2"
:min="0"
:max="999999999"
:disabled="!scope.row.selected"
controls-position="right"
size="small"
style="width: 100%"
/>
</template>
</el-table-column>
</el-table>
</div>
<!-- 预算计划选择表格没有plan_link数据或搜索后显示 -->
<div v-if="!showPlanLinkTable">
<h5 style="margin-bottom: 10px; color: #67C23A;">选择预算计划</h5>
<xy-table
:header-cell-class-name="cellClassName"
:list="plans"
:show-index="false"
:table-item="planTable"
:height="400"
style="margin-top: 10px"
ref="planSelectTable"
row-key="id"
border
default-expand-all
@select="planPick"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<template v-slot:btns>
<el-table-column
label="使用金额(元)"
:fixed="$store.getters.device === 'mobile' ? false : 'right'"
header-align="center"
width="144"
>
<template slot-scope="scope" v-if="scope.row.pid > 0">
<InputNumber
style="width: 120px"
:min="0"
:precision="2"
:active-change="false"
v-model="scope.row._inputMoney"
:formatter="
(value) =>
`${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
"
:parser="(value) => value.replace(/\$\s?|(,*)/g, '')"
/>
</template>
</el-table-column>
</template>
</xy-table>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="handleDialogClose"></el-button>
<el-button type="primary" @click="confirmEdit"></el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getPlanActLinks, updateContractPlanActLinks } from '@/api/planActLink/index'
import { Message } from 'element-ui'
import { getBudget } from '@/api/budget/budget'
import { getparameterTree } from '@/api/system/dictionary'
import { listdeptNoAuth } from '@/api/system/department'
export default {
data() {
return {
keyword: '',
enter_act_link: '',
status: '',
list: [],
total: 0,
pageIndex: 1,
pageSize: 10,
editDialogVisible: false,
currentEditRow: null,
planLinkDataMap: {},
showPlanLinkTable: false, // plan_link
plans: [], //
departments: [], //
planTypes: [], //
planSelect: {
name: '',
page_size: 20,
page: 1,
is_tree: 1,
year: new Date().getFullYear().toString(),
plan_department_id: '',
type: ''
},
planTable: [
{
sortable: false,
width: 44,
type: 'selection',
reserveSelection: true,
fixed: 'left',
selectable: (row, index) => {
return row.pid > 0
}
},
{
label: '科室',
prop: 'plan_department.name',
width: 120,
align: 'center'
},
{
label: '年份',
prop: 'year',
width: 80,
align: 'center'
},
{
label: '分类',
prop: 'type_detail.value',
width: 120
},
{
label: '名称',
prop: 'name',
minWidth: 180,
align: 'left'
},
{
label: '内容',
prop: 'content',
minWidth: 240,
align: 'left',
showOverflowTooltip: true
},
{
label: '计划金额',
prop: 'money',
align: 'right',
width: 120,
formatter: (v1, v2, value) => {
return `${
value && parseFloat(value) !== 0 ? value : v1.update_money
}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
},
{
label: '实付金额',
prop: 'use_money_total',
width: 120,
align: 'right',
formatter: (v1, v2, value) =>
value ? `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',') : ''
},
{
label: '已用金额',
prop: 'has_money_total',
width: 120,
align: 'right',
formatter: (v1, v2, value) =>
value ? `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',') : ''
}
],
table: [
{
label: '合同名称',
prop: 'contract.name',
minWidth: 200,
align: 'left'
},
{
label: '付款集合',
prop: 'fund_log_collect.name',
minWidth: 200,
align: 'left'
},
{
label: '金额',
prop: 'apply_money',
width: 150,
align: 'right',
formatter: (cell, data, value) => {
return value ? Number(value)
.toFixed(2)
.replace(/(\d)(?=(\d{3})+\.)/g, '$1,') : ''
}
},
{
label: '状态',
prop: 'status',
width: 100,
align: 'center',
customFn: row => {
return row.status === 0
? (<span style='color:rgb(96, 109, 241)'>待审核</span>)
: (<span style='color: rgb(147, 201, 134)'>已审核</span>)
}
},
{
label: '计划预算资金',
width: 300,
align: 'left',
customFn: (row) => {
if (row.plan_link && row.plan_link.length > 0) {
return row.plan_link.map((item) => {
const planId = item.plan_id || ''
const year = item.plan?.year || ''
const planName = item.plan?.name || ''
const useMoney = item.use_money || 0
return (
<div>
{planId} - [{year}] - {planName} -{useMoney}
</div>
)
})
}
return null
}
},
{
label: '实际预算资金',
width: 300,
align: 'left',
customFn: (row) => {
if (row.plan_act_links && row.plan_act_links.length > 0) {
return row.plan_act_links.map((item) => {
const planId = item.plan_id || ''
const year = item.plan?.year || ''
const planName = item.plan?.name || ''
const useMoney = item.use_money || 0
return (
<div key={planId}>
{planId} - [{year}] - {planName} -{useMoney}
</div>
)
})
}
return null
}
}
]
}
},
mounted() {
this.getList()
this.getDepartment()
this.getPlanTypes()
},
methods: {
//
async getList() {
try {
const params = {
page: this.pageIndex,
page_size: this.pageSize
}
if (this.keyword) {
params.keyword = this.keyword
}
if (this.enter_act_link !== '') {
params.enter_act_link = this.enter_act_link
}
if (this.status !== '') {
params.status = this.status
}
const res = await getPlanActLinks(params)
this.list = res.list?.data || res.data || []
this.total = res.list?.total || res.total || 0
} catch (error) {
Message({
type: 'error',
message: '获取数据失败'
})
console.error('获取列表数据失败:', error)
}
},
//
doSearch() {
this.pageIndex = 1
this.getList()
},
//
resetSearch() {
this.keyword = ''
this.enter_act_link = ''
this.status = ''
this.pageIndex = 1
this.pageSize = 10
this.getList()
},
//
pageChange(e) {
this.pageIndex = e
this.getList()
},
//
pageSizeChange(e) {
this.pageSize = e
this.pageIndex = 1
this.getList()
},
//
showEditDialog(row) {
this.currentEditRow = row
this.planLinkDataMap = {}
this.plans = []
// plan_linkplan_link
if (row.plan_link && row.plan_link.length > 0) {
this.showPlanLinkTable = true
this.planLinkDataMap[row.id] = row.plan_link.map(planItem => ({
year: planItem.plan?.year || '',
name: planItem.plan?.name || '',
content: planItem.plan?.content || '',
money: planItem.plan?.money || 0,
use_money: planItem.use_money || 0,
selected: true, //
plan_id: planItem.plan?.id || '',
plan_link_id: planItem.id
}))
} else {
// plan_link
this.showPlanLinkTable = false
this.getBudgets(false)
}
this.editDialogVisible = true
},
// plan_link
getPlanLinkData(row) {
// planLinkDataMap
if (this.planLinkDataMap[row.id]) {
return this.planLinkDataMap[row.id]
}
// row
if (!row.plan_link || row.plan_link.length === 0) {
return []
}
return row.plan_link.map(planItem => ({
year: planItem.plan?.year || '',
name: planItem.plan?.name || '',
content: planItem.plan?.content || '',
money: planItem.plan?.money || 0,
use_money: planItem.use_money || 0,
selected: true, //
plan_id: planItem.plan?.id || '',
plan_link_id: planItem.id
}))
},
//
handleSelectionChange(row) {
//
},
//
clearDialogData() {
//
this.$refs.planSelectTable?.clearSelection()
//
this.currentEditRow = null
this.planLinkDataMap = {}
this.plans = []
this.showPlanLinkTable = false
//
this.planSelect = {
name: '',
page_size: 20,
page: 1,
is_tree: 1,
year: new Date().getFullYear().toString(),
plan_department_id: '',
type: ''
}
},
//
handleDialogClose() {
this.clearDialogData()
this.editDialogVisible = false
},
//
async confirmEdit() {
if (!this.currentEditRow) {
return
}
let act_plan = []
if (this.showPlanLinkTable) {
// plan_link
const planLinkData = this.planLinkDataMap[this.currentEditRow.id] || []
const selectedItems = planLinkData.filter(item => item.selected)
if (selectedItems.length === 0) {
Message({
type: 'warning',
message: '请至少选择一条预算计划'
})
return
}
// 使0
for (let i = 0; i < selectedItems.length; i++) {
const item = selectedItems[i]
const useMoney = parseFloat(item.use_money) || 0
if (useMoney <= 0) {
Message({
type: 'warning',
message: `预算计划"${item.name}"的使用金额必须大于0`
})
return
}
}
act_plan = selectedItems.map(item => ({
plan_id: item.plan_id,
use_money: parseFloat(item.use_money) || 0
}))
} else {
//
const selections = this.$refs.planSelectTable?.getSelection() || []
const validSelections = selections.filter(item => item.pid > 0)
if (validSelections.length === 0) {
Message({
type: 'warning',
message: '请至少选择一条预算计划'
})
return
}
// 使0
for (let i = 0; i < validSelections.length; i++) {
const item = validSelections[i]
const useMoney = parseFloat(item._inputMoney) || 0
if (useMoney <= 0) {
Message({
type: 'warning',
message: `预算计划"${item.name}"的使用金额必须大于0`
})
return
}
}
act_plan = validSelections.map(item => ({
plan_id: item.id,
use_money: parseFloat(item._inputMoney) || 0
}))
}
console.log('act_plan', act_plan,this.currentEditRow.contract_id,this.currentEditRow.id)
// return
await updateContractPlanActLinks({
contract_id: this.currentEditRow.contract_id,
fund_log_id: this.currentEditRow.id,
act_plan
})
Message({
type: 'success',
message: '保存成功'
})
this.clearDialogData()
this.editDialogVisible = false
this.getList()
},
//
getDepartment() {
listdeptNoAuth().then((res) => {
this.departments = res.data || []
})
},
//
async getPlanTypes() {
const res = await getparameterTree({
id: 3
})
const dataHandler = (data) => {
data.forEach((i) => {
if (Object.prototype.hasOwnProperty.call(i, 'detail')) {
i.children = i.detail.map((j) => {
j.name = j.value
return j
})
} else if (i.children) {
dataHandler(i.children)
}
})
return data
}
this.planTypes = dataHandler(res?.children) || []
},
//
handleYearChange(e) {
this.planSelect.year = e
this.getBudgets(true)
},
//
handleTypeChange(e) {
this.planSelect.type = e && e.length > 0 ? e[e.length - 1] : ''
this.getBudgets(true)
},
//
async getBudgets(refresh) {
if (refresh) {
//
this.$refs.planSelectTable?.clearSelection()
// plan_link
if (this.showPlanLinkTable) {
this.showPlanLinkTable = false
this.planLinkDataMap = {}
}
}
const res = await getBudget(this.planSelect)
this.initInputMoney(res.list)
this.plans = res.list || []
},
//
initInputMoney(list) {
if (!Array.isArray(list)) return []
return list.map((item) => {
this.$set(item, '_inputMoney', 0)
if (Array.isArray(item.children)) {
item.children = this.initInputMoney(item.children)
}
return item
})
},
//
cellClassName({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
return 'allSelect'
}
},
//
planPick(selection, row) {
if (row.year != new Date().getFullYear()) {
this.$confirm('您选择了非本年预算,是否继续?').catch(() => {
this.$refs.planSelectTable.toggleRowSelection(row)
})
}
}
}
}
</script>
<style scoped lang="scss">
.select-container {
display: flex;
justify-content: space-between;
align-items: center;
}
::v-deep .allSelect .cell {
display: none;
}
.selects {
display: flex;
flex-wrap: wrap;
& > div {
margin-bottom: 6px;
margin-right: 4px;
& > span {
word-break: keep-all;
padding: 0 4px;
}
}
}
</style>
Loading…
Cancel
Save