预算类型

master
lion 8 months ago
parent 397a99a61a
commit 27d894fe76

@ -3,12 +3,12 @@ ENV = 'development'
# base api # base api
#VUE_APP_DOMIAN=http://192.168.60.99:8003/ VUE_APP_DOMIAN=http://192.168.60.99:8003/
#VUE_APP_BASE_API = '' VUE_APP_BASE_API = ''
#VUE_APP_UPLOAD=http://192.168.60.99:8003/api/admin/upload-file VUE_APP_UPLOAD=http://192.168.60.99:8003/api/admin/upload-file
#VUE_APP_OUT_URL = http://192.168.60.18:8001 VUE_APP_OUT_URL = http://192.168.60.18:8001
VUE_APP_DOMIAN=http://192.168.60.99:9003/ #VUE_APP_DOMIAN=http://192.168.60.99:9003/
VUE_APP_UPLOAD=http://192.168.60.99:9003/api/admin/upload-file #VUE_APP_UPLOAD=http://192.168.60.99:9003/api/admin/upload-file
VUE_APP_OUT_URL = http://192.168.60.18:2021 #VUE_APP_OUT_URL = http://192.168.60.18:2021

@ -199,7 +199,6 @@
:table-item="table" :table-item="table"
@cellClick="showPaymentPlan" @cellClick="showPaymentPlan"
@delete="(row)=>deleteContract(row.id)" @delete="(row)=>deleteContract(row.id)"
@editor=""
> >
<template v-slot:btns> <template v-slot:btns>
<el-table-column fixed="right" header-align="center" label="操作" width="200"> <el-table-column fixed="right" header-align="center" label="操作" width="200">
@ -643,16 +642,50 @@
<!-- 搜索使用 预算计划 --> <!-- 搜索使用 预算计划 -->
<xy-dialog :is-show.sync="isShowPlanForSearch" title="预算计划" :width="720" @on-ok="planSelectForSearch"> <xy-dialog :is-show.sync="isShowPlanForSearch" title="预算计划" :width="720" @on-ok="planSelectForSearch">
<template v-slot:normalContent> <template v-slot:normalContent>
<Input <div class="search-controls">
v-model="planSearch.name" <Input
search v-model="planSearch.name"
enter-button="搜 索" search
placeholder="搜索预算计划.." enter-button="搜 索"
@on-search="searchBudgets" placeholder="搜索预算计划名称"
/> style="width: 300px; margin-right: 10px"
@on-search="searchBudgets"
/>
<Select
v-model="planSearch.plan_department_id"
placeholder="选择部门"
style="width: 200px; margin-right: 10px"
clearable
@on-change="searchBudgets"
>
<Option
v-for="dept in departments"
:key="dept.id"
:value="dept.id"
>
{{ dept.name }}
</Option>
</Select>
<Select
v-model="planSearch.year"
placeholder="选择年份"
style="width: 120px"
clearable
@on-change="searchBudgets"
>
<Option
v-for="year in availableYears"
:key="year"
:value="year"
>
{{ year }}
</Option>
</Select>
</div>
<div style="margin: 10px 0;display: flex;justify-content: space-between;align-items: center;"> <div style="margin: 10px 0;display: flex;justify-content: space-between;align-items: center;">
<div v-if="planSource === 'search'">已选择:<span style="margin-right:10px">{{ select.plan_name }}</span></div> <div>已选择<span style="margin-right:10px; color: #409EFF; font-weight: 500;">{{ select.plan_name || '未选择' }}</span></div>
<div v-if="planSource === 'modal'">已选择:<span style="margin-right:10px">{{ form.plan_display }}</span></div>
<el-link type="success" @click="clearSelectForSearch"></el-link> <el-link type="success" @click="clearSelectForSearch"></el-link>
</div> </div>
<xy-table <xy-table
@ -665,11 +698,8 @@
@rowClick="selectPlanForSearch" @rowClick="selectPlanForSearch"
> >
<template v-slot:btns> <template v-slot:btns>
<el-table-column v-if="planSource === 'modal'" label="使用金额" header-align="center"> <div>
<template slot-scope="scope"> </div>
<Input :value="scope.row.useMoney" @input="planInput($event, scope.row)" />
</template>
</el-table-column>
</template> </template>
</xy-table> </xy-table>
<div style="display: flex;justify-content: flex-end;"> <div style="display: flex;justify-content: flex-end;">
@ -994,7 +1024,7 @@ export default {
request: true, request: true,
purchaseApproval: true, purchaseApproval: true,
tenderReview: true, tenderReview: true,
contractSign: true contractSign: true
}, },
planSource: 'search', planSource: 'search',
isShowPlanForSearch: false, isShowPlanForSearch: false,
@ -1553,9 +1583,11 @@ export default {
plans: [], // plans: [], //
planSearch: { planSearch: {
name: '', name: '',
plan_department_id: [], // plan_department_id: '', // 使
year: (new Date().getFullYear() )+ '' year: (new Date().getFullYear() )+ ''
}, },
//
availableYears: [],
planTotal: 0, planTotal: 0,
plansPageIndex: 1, plansPageIndex: 1,
@ -1607,6 +1639,7 @@ export default {
this.getDepartment(-1) this.getDepartment(-1)
this.getPurchaseWay() this.getPurchaseWay()
this.getMoneyWay() this.getMoneyWay()
this.initAvailableYears()
// //
window.onfocus = () => { window.onfocus = () => {
@ -1625,7 +1658,16 @@ export default {
}, },
clearSelectForSearch() { clearSelectForSearch() {
this.select.plan_id = '' this.select.plan_id = ''
this.select.plan_name = '请选择预算计划' this.select.plan_name = ''
},
//
initAvailableYears() {
const currentYear = new Date().getFullYear()
this.availableYears = []
for (let i = currentYear - 5; i <= currentYear + 2; i++) {
this.availableYears.push(i)
}
}, },
async getPlanTypes() { async getPlanTypes() {
const res = await getparameter({ const res = await getparameter({
@ -1946,27 +1988,16 @@ export default {
// //
async getBudgets() { async getBudgets() {
if (this.form.contract_carry_department && this.form.contract_carry_department.length > 0) {
// 使ID
this.planSearch.plan_department_id = this.form.contract_carry_department
}
console.log('科室选择:', this.planSearch.plan_department_id)
const res = await getBudget({ const res = await getBudget({
name: this.planSearch.name, name: this.planSearch.name,
page_size: 10, page_size: 10,
page: this.plansPageIndex, page: this.plansPageIndex,
plan_department_id: this.planSearch.plan_department_id, plan_department_id: this.planSearch.plan_department_id,
top_pid: 1, top_pid: 1,
year:this.planSearch.year year: this.planSearch.year
}) })
this.plans = res.list.data this.plans = res.list.data
this.planTotal = res.list.total this.planTotal = res.list.total
this.toggleSelection(this.plan.map(item => {
return item.value.plan_id
}), 1)
}, },
// //
async getMoneyWay() { async getMoneyWay() {
@ -2074,67 +2105,29 @@ export default {
this.isShowPlan = true this.isShowPlan = true
await this.getBudgets() await this.getBudgets()
}, },
showPlanForSearch(source) { showPlanForSearch() {
this.planSource = source this.isShowPlanForSearch = true
this.isShowPlan = true
this.getBudgets() this.getBudgets()
// plan
if (source === 'modal') {
this.plan = this.form.plan || []
} else {
this.plan = []
}
}, },
selectPlanForSearch(sel, row) { selectPlanForSearch(sel, row) {
if (this.planSource === 'modal') { console.log(sel,row)
if (sel) { if (sel) {
const select = sel.map(item => { this.select.plan_name = '[' + sel.year + '] - ' + sel.name
const plan = this.plans.find(p => p.id === item.id) this.select.plan_id = sel.id
return {
label: plan.name,
value: {
plan_id: plan.id,
use_money: plan.useMoney || 0,
new_money: plan.money
}
}
})
this.plan = [...this.form.plan, ...select]
//
this.form.plan_display = this.plan.map(item => item.label).join(', ')
} else {
this.plan = this.form.plan
//
this.form.plan_display = this.plan.map(item => item.label).join(', ')
}
} else { } else {
this.select.plan_name = row.name this.select.plan_id = ''
this.select.plan_id = row.id this.select.plan_name = ''
} }
}, },
planSelectForSearch() { planSelectForSearch() {
if (this.plan.length === 0) { if (!this.select.plan_id) {
Message({ Message({
type: 'warning', type: 'warning',
message: '选择计划不能为空' message: '请选择预算计划'
}) })
return return
} }
for (const item of this.plan) { this.isShowPlanForSearch = false
if (!item.value.use_money) {
Message({
type: 'warning',
message: '金额不能为空'
})
return
}
}
//
this.form.plan = this.plan
//
this.form.plan_display = this.plan.map(item => item.label).join(', ')
//
this.isShowPlan = false
}, },
// //
selectPlan(sel, row) { selectPlan(sel, row) {
@ -4039,4 +4032,16 @@ export default {
.payment-preview-modal { .payment-preview-modal {
z-index: 4000 !important; z-index: 4000 !important;
} }
.search-controls {
display: flex;
align-items: center;
margin-bottom: 15px;
padding: 15px;
background-color: #f8f9fa;
border-radius: 6px;
}
</style> </style>

@ -213,6 +213,97 @@
<el-dialog :visible.sync="postPaymentFormDialogVisible" title="事后支付表格" width="800px"> <el-dialog :visible.sync="postPaymentFormDialogVisible" title="事后支付表格" width="800px">
<div v-html="currentPostPaymentForm"></div> <div v-html="currentPostPaymentForm"></div>
</el-dialog> </el-dialog>
<!-- 预算计划选择弹窗 -->
<xy-dialog
:is-show.sync="isShowPlanForSearch"
title="预算计划"
:width="720"
@on-ok="planSelectForSearch"
>
<template v-slot:normalContent>
<div class="search-controls">
<Input
v-model="planSearch.name"
search
enter-button="搜 索"
placeholder="搜索预算计划名称"
style="width: 300px; margin-right: 10px"
@on-search="searchBudgets"
/>
<Select
v-model="planSearch.plan_department_id"
placeholder="选择部门"
style="width: 200px; margin-right: 10px"
clearable
@on-change="searchBudgets"
>
<Option
v-for="dept in departments"
:key="dept.id"
:value="dept.id"
>
{{ dept.name }}
</Option>
</Select>
<Select
v-model="planSearch.year"
placeholder="选择年份"
style="width: 120px"
clearable
@on-change="searchBudgets"
>
<Option
v-for="year in availableYears"
:key="year"
:value="year"
>
{{ year }}
</Option>
</Select>
</div>
<div
style="
margin: 10px 0;
display: flex;
justify-content: space-between;
align-items: center;
"
>
<div>
已选择<span style="margin-right: 10px">{{
select.plan_name
}}</span>
</div>
<el-link
type="success"
@click="clearSelectForSearch"
>清空选择</el-link>
</div>
<xy-table
ref="singlePlanTable"
:list="plans"
:show-index="false"
:table-item="planTableSearch"
:height="310"
style="margin-top: 10px"
@rowClick="selectPlanForSearch"
>
<template v-slot:btns />
</xy-table>
<div style="display: flex; justify-content: flex-end">
<Page :total="planTotal" show-elevator @on-change="planPageChange" />
</div>
<el-tag type="warning">点击行进行选择</el-tag>
</template>
<template v-slot:footerContent>
<Button type="primary" @click="confirmPlanForSearch"></Button>
</template>
</xy-dialog>
</div> </div>
</template> </template>
@ -263,35 +354,34 @@ export default {
}, },
planSearch: { planSearch: {
name: '', name: '',
plan_department_id: '' plan_department_id: '',
year: this.$moment().format("YYYY")
}, },
//
departments: [],
//
availableYears: [],
plans: [], plans: [],
planTotal: 0, planTotal: 0,
plansPageIndex: 1,
plan: [], plan: [],
moneyWay: [], moneyWay: [],
planTableSearch: [ planTableSearch: [
{ {
label: '分类', label: '分类',
prop: 'type_detail.name', prop: 'type_detail.name',
// formatter: (cell, data, value) => { width: 120
// const res = this.moneyWay.filter((item) => {
// return item.id === value
// })
// return res[0]?.value || ''
// },
width: 170
}, },
{ {
label: '年份', label: '年份',
prop: 'year', prop: 'year',
align: 'center', align: 'center',
width: 100 width: 90
}, },
{ {
label: '名称', label: '名称',
prop: 'name', prop: 'name',
width: 260, width: 200,
align: 'left' align: 'left'
}, },
{ {
@ -464,6 +554,8 @@ export default {
this.select.plan_id = plan_id this.select.plan_id = plan_id
this.select.plan_name = plan_name this.select.plan_name = plan_name
this.getFundLogs() this.getFundLogs()
this.initAvailableYears()
this.initDepartments()
}, },
created() { created() {
const type = parseInt(this.$route.path.split('_')[1]) const type = parseInt(this.$route.path.split('_')[1])
@ -580,6 +672,8 @@ export default {
} }
}, },
// //
async getBudgets() { async getBudgets() {
await getBudget({ await getBudget({
@ -587,10 +681,10 @@ export default {
page_size: 10, page_size: 10,
page: this.plansPageIndex, page: this.plansPageIndex,
plan_department_id: this.planSearch.plan_department_id, plan_department_id: this.planSearch.plan_department_id,
top_pid: 1 top_pid: 1,
year: this.planSearch.year ? this.planSearch.year : ''
}).then((res) => { }).then((res) => {
this.plans = res.list.data this.plans = res.list.data
this.planTotal = res.list.total this.planTotal = res.list.total
this.toggleSelection( this.toggleSelection(
@ -601,6 +695,7 @@ export default {
) )
}) })
}, },
// //
toggleSelection(plans, type) { toggleSelection(plans, type) {
if (plans) { if (plans) {
@ -622,6 +717,31 @@ export default {
this.select.plan_id = '' this.select.plan_id = ''
this.select.plan_name = '请选择预算计划' this.select.plan_name = '请选择预算计划'
}, },
//
initAvailableYears() {
const currentYear = new Date().getFullYear()
this.availableYears = []
for (let i = currentYear - 5; i <= currentYear + 2; i++) {
this.availableYears.push(i)
}
},
//
async initDepartments() {
try {
// API使
this.departments = [
{ id: 1, name: '财务部' },
{ id: 2, name: '工程部' },
{ id: 3, name: '采购部' },
{ id: 4, name: '行政部' }
]
} catch (error) {
console.error('初始化部门列表失败:', error)
this.departments = []
}
},
pageSizeChange(e) { pageSizeChange(e) {
this.pageSize = e this.pageSize = e
this.pageIndex = 1 this.pageIndex = 1
@ -632,6 +752,8 @@ export default {
this.getFundLogs() this.getFundLogs()
}, },
async getFundLogs(is_export) { async getFundLogs(is_export) {
await getFundLog({ await getFundLog({
is_auth: this.is_auth, is_auth: this.is_auth,
@ -838,4 +960,13 @@ export default {
} }
</script> </script>
<style scoped lang="scss"></style> <style scoped lang="scss">
.search-controls {
display: flex;
align-items: center;
margin-bottom: 15px;
padding: 15px;
background-color: #f8f9fa;
border-radius: 6px;
}
</style>

@ -165,15 +165,32 @@
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>资金列支渠道 <span style="color: red;font-weight: 600;padding-right: 4px;">*</span>资金列支渠道
</div> </div>
<div class="xy-table-item-content"> <div class="xy-table-item-content">
<el-select <div class="money-way-tree-container">
v-model="paymentRegistrationForm.moneyWay" <el-tree
multiple ref="moneyWayTree"
style="width: 300px;" :data="planTypes"
placeholder="请选择资金列支渠道" :props="defaultProps"
@change="moneyWayChange" show-checkbox
> node-key="id"
<el-option v-for="item in planTypes_arr" :key="item.id" :value="item.id" :label="item.value" /> :default-checked-keys="paymentRegistrationForm.moneyWay || []"
</el-select> :check-strictly="false"
@check="handleMoneyWayCheck"
style="width: 300px; max-height: 200px; overflow: auto; border: 1px solid #dcdfe6; border-radius: 4px; padding: 10px;"
/>
</div>
<div class="selected-money-way" v-if="selectedMoneyWayLabels.length > 0" style="margin-top: 10px;">
<div style="margin-bottom: 5px; font-size: 12px; color: #606266;">已选择</div>
<el-tag
v-for="(item, index) in selectedMoneyWayLabels"
:key="index"
closable
size="small"
style="margin-right: 5px; margin-bottom: 5px;"
@close="removeMoneyWay(item.id)"
>
{{ item.label }}
</el-tag>
</div>
</div> </div>
</div> </div>
</template> </template>
@ -286,6 +303,8 @@ export default {
payment: [], // payment: [], //
planTypes: [], planTypes: [],
planTypes_arr:[], planTypes_arr:[],
//
selectedMoneyWayLabels: [],
payTable: [{ payTable: [{
label: '申请金额', label: '申请金额',
prop: 'apply_money', prop: 'apply_money',
@ -443,10 +462,15 @@ export default {
watch: { watch: {
isShow(newVal) { isShow(newVal) {
if (!newVal) { if (!newVal) {
this.paymentRegistrationForm.actMoney = '' this.paymentRegistrationForm.actMoney = ''
this.paymentRegistrationForm.moneyWay = '' this.paymentRegistrationForm.moneyWay = []
this.paymentRegistrationForm.plan = [] this.paymentRegistrationForm.plan = []
this.selectedMoneyWayLabels = []
this.$refs.planTable.clearSelection() this.$refs.planTable.clearSelection()
//
if (this.$refs.moneyWayTree) {
this.$refs.moneyWayTree.setCheckedKeys([])
}
} }
} }
}, },
@ -491,6 +515,83 @@ export default {
// this.getBudgets() // this.getBudgets()
}, },
//
handleMoneyWayCheck(data, checkedInfo) {
const { checkedKeys, checkedNodes } = checkedInfo
//
const leafNodes = checkedNodes.filter(node => !node.children || node.children.length === 0)
//
this.paymentRegistrationForm.moneyWay = leafNodes.map(node => node.id)
//
this.selectedMoneyWayLabels = leafNodes.map(node => ({
id: node.id,
label: node.name
}))
//
this.moneyWayChange()
},
//
removeMoneyWay(id) {
//
const index = this.paymentRegistrationForm.moneyWay.indexOf(id)
if (index > -1) {
this.paymentRegistrationForm.moneyWay.splice(index, 1)
}
//
const labelIndex = this.selectedMoneyWayLabels.findIndex(item => item.id === id)
if (labelIndex > -1) {
this.selectedMoneyWayLabels.splice(labelIndex, 1)
}
//
this.$nextTick(() => {
this.$refs.moneyWayTree.setCheckedKeys(this.paymentRegistrationForm.moneyWay)
})
//
this.moneyWayChange()
},
//
updateSelectedMoneyWayLabels() {
if (!this.paymentRegistrationForm.moneyWay || this.paymentRegistrationForm.moneyWay.length === 0) {
this.selectedMoneyWayLabels = []
return
}
// IDplanTypes
const selectedNodes = []
const findNodes = (nodes, ids) => {
nodes.forEach(node => {
if (ids.includes(node.id)) {
selectedNodes.push({
id: node.id,
label: node.name
})
}
if (node.children && node.children.length > 0) {
findNodes(node.children, ids)
}
})
}
findNodes(this.planTypes, this.paymentRegistrationForm.moneyWay)
this.selectedMoneyWayLabels = selectedNodes
//
this.$nextTick(() => {
if (this.$refs.moneyWayTree) {
this.$refs.moneyWayTree.setCheckedKeys(this.paymentRegistrationForm.moneyWay)
}
})
},
inputMoney(e, row) { inputMoney(e, row) {
row.use_money = e row.use_money = e
this.paymentRegistrationForm.plan.forEach(item => { this.paymentRegistrationForm.plan.forEach(item => {
@ -504,6 +605,7 @@ export default {
number: 'money_way' number: 'money_way'
}) })
this.planTypes_arr = res1.detail this.planTypes_arr = res1.detail
const res = await getPlanType({ const res = await getPlanType({
page_size: 999, page_size: 999,
page: 1, page: 1,
@ -602,6 +704,11 @@ export default {
this.paymentRegistrationForm.actMoney = res.apply_money this.paymentRegistrationForm.actMoney = res.apply_money
this.paymentRegistrationForm.moneyWay = res.money_way_id?.split(',').map(item => Number(item)) this.paymentRegistrationForm.moneyWay = res.money_way_id?.split(',').map(item => Number(item))
//
if (this.paymentRegistrationForm.moneyWay && this.paymentRegistrationForm.moneyWay.length > 0) {
this.updateSelectedMoneyWayLabels()
}
await this.getContract(res.contract) await this.getContract(res.contract)
await this.moneyWayChange() await this.moneyWayChange()
}, },
@ -773,4 +880,40 @@ export default {
::v-deep .planselsct .el-checkbox__input .el-checkbox__inner { ::v-deep .planselsct .el-checkbox__input .el-checkbox__inner {
border-radius: 50%; border-radius: 50%;
} }
//
.money-way-tree-container {
::v-deep .el-tree {
.el-tree-node__content {
height: 32px;
line-height: 32px;
&:hover {
background-color: #f5f7fa;
}
}
.el-tree-node__label {
font-size: 14px;
}
.el-checkbox {
margin-right: 8px;
}
}
}
.selected-money-way {
.el-tag {
background-color: #e1f3d8;
border-color: #67c23a;
color: #67c23a;
&:hover {
background-color: #f0f9ff;
border-color: #409eff;
color: #409eff;
}
}
}
</style> </style>

@ -91,13 +91,48 @@
@on-ok="planSelectForSearch" @on-ok="planSelectForSearch"
> >
<template v-slot:normalContent> <template v-slot:normalContent>
<Input <div class="search-controls">
v-model="planSearch.name" <Input
search v-model="planSearch.name"
enter-button="搜 索" search
placeholder="搜索预算计划.." enter-button="搜 索"
@on-search="searchBudgets" placeholder="搜索预算计划名称"
/> style="width: 300px; margin-right: 10px"
@on-search="searchBudgets"
/>
<Select
v-model="planSearch.plan_department_id"
placeholder="选择部门"
style="width: 200px; margin-right: 10px"
clearable
@on-change="searchBudgets"
>
<Option
v-for="dept in departments"
:key="dept.id"
:value="dept.id"
>
{{ dept.name }}
</Option>
</Select>
<Select
v-model="planSearch.year"
placeholder="选择年份"
style="width: 120px"
clearable
@on-change="searchBudgets"
>
<Option
v-for="year in availableYears"
:key="year"
:value="year"
>
{{ year }}
</Option>
</Select>
</div>
<div <div
style=" style="
margin: 10px 0; margin: 10px 0;
@ -255,8 +290,13 @@ export default {
plans: [], // plans: [], //
planSearch: { planSearch: {
name: '', name: '',
plan_department_id: '' plan_department_id: '',
year: this.$moment().format("YYYY")
}, },
//
departments: [],
//
availableYears: [],
planTotal: 0, planTotal: 0,
plansPageIndex: 1, plansPageIndex: 1,
isShowPlanForSearch: false, isShowPlanForSearch: false,
@ -389,6 +429,7 @@ export default {
mounted() { mounted() {
this.getMoneyWay() this.getMoneyWay()
this.getFundLogs() this.getFundLogs()
this.initAvailableYears()
}, },
methods: { methods: {
planPageChange(e) { planPageChange(e) {
@ -445,10 +486,10 @@ export default {
page_size: 10, page_size: 10,
page: this.plansPageIndex, page: this.plansPageIndex,
plan_department_id: this.planSearch.plan_department_id, plan_department_id: this.planSearch.plan_department_id,
top_pid: 1 top_pid: 1,
year: this.planSearch.year || ''
}).then((res) => { }).then((res) => {
this.plans = res.list.data this.plans = res.list.data
this.planTotal = res.list.total this.planTotal = res.list.total
this.toggleSelection( this.toggleSelection(
@ -459,6 +500,15 @@ export default {
) )
}) })
}, },
//
initAvailableYears() {
const currentYear = new Date().getFullYear()
this.availableYears = []
for (let i = currentYear - 5; i <= currentYear + 2; i++) {
this.availableYears.push(i)
}
},
async showPlanForSearch() { async showPlanForSearch() {
this.isShowPlanForSearch = true this.isShowPlanForSearch = true
await this.getBudgets() await this.getBudgets()

Loading…
Cancel
Save