预算类型

master
lion 2 months ago
parent 397a99a61a
commit 27d894fe76

@ -3,12 +3,12 @@ ENV = 'development'
# base api
#VUE_APP_DOMIAN=http://192.168.60.99:8003/
#VUE_APP_BASE_API = ''
#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_DOMIAN=http://192.168.60.99:9003/
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_DOMIAN=http://192.168.60.99:8003/
VUE_APP_BASE_API = ''
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_DOMIAN=http://192.168.60.99:9003/
#VUE_APP_UPLOAD=http://192.168.60.99:9003/api/admin/upload-file
#VUE_APP_OUT_URL = http://192.168.60.18:2021

@ -199,7 +199,6 @@
:table-item="table"
@cellClick="showPaymentPlan"
@delete="(row)=>deleteContract(row.id)"
@editor=""
>
<template v-slot:btns>
<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">
<template v-slot:normalContent>
<Input
v-model="planSearch.name"
search
enter-button="搜 索"
placeholder="搜索预算计划.."
@on-search="searchBudgets"
/>
<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 v-if="planSource === 'search'">已选择:<span style="margin-right:10px">{{ select.plan_name }}</span></div>
<div v-if="planSource === 'modal'">已选择:<span style="margin-right:10px">{{ form.plan_display }}</span></div>
<div>已选择<span style="margin-right:10px; color: #409EFF; font-weight: 500;">{{ select.plan_name || '未选择' }}</span></div>
<el-link type="success" @click="clearSelectForSearch"></el-link>
</div>
<xy-table
@ -665,11 +698,8 @@
@rowClick="selectPlanForSearch"
>
<template v-slot:btns>
<el-table-column v-if="planSource === 'modal'" label="使用金额" header-align="center">
<template slot-scope="scope">
<Input :value="scope.row.useMoney" @input="planInput($event, scope.row)" />
</template>
</el-table-column>
<div>
</div>
</template>
</xy-table>
<div style="display: flex;justify-content: flex-end;">
@ -994,7 +1024,7 @@ export default {
request: true,
purchaseApproval: true,
tenderReview: true,
contractSign: true
contractSign: true
},
planSource: 'search',
isShowPlanForSearch: false,
@ -1553,9 +1583,11 @@ export default {
plans: [], //
planSearch: {
name: '',
plan_department_id: [], //
plan_department_id: '', // 使
year: (new Date().getFullYear() )+ ''
},
//
availableYears: [],
planTotal: 0,
plansPageIndex: 1,
@ -1607,6 +1639,7 @@ export default {
this.getDepartment(-1)
this.getPurchaseWay()
this.getMoneyWay()
this.initAvailableYears()
//
window.onfocus = () => {
@ -1625,7 +1658,16 @@ export default {
},
clearSelectForSearch() {
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() {
const res = await getparameter({
@ -1946,27 +1988,16 @@ export default {
//
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({
name: this.planSearch.name,
page_size: 10,
page: this.plansPageIndex,
plan_department_id: this.planSearch.plan_department_id,
top_pid: 1,
year:this.planSearch.year
year: this.planSearch.year
})
this.plans = res.list.data
this.planTotal = res.list.total
this.toggleSelection(this.plan.map(item => {
return item.value.plan_id
}), 1)
},
//
async getMoneyWay() {
@ -2074,67 +2105,29 @@ export default {
this.isShowPlan = true
await this.getBudgets()
},
showPlanForSearch(source) {
this.planSource = source
this.isShowPlan = true
showPlanForSearch() {
this.isShowPlanForSearch = true
this.getBudgets()
// plan
if (source === 'modal') {
this.plan = this.form.plan || []
} else {
this.plan = []
}
},
selectPlanForSearch(sel, row) {
if (this.planSource === 'modal') {
if (sel) {
const select = sel.map(item => {
const plan = this.plans.find(p => p.id === item.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(', ')
}
console.log(sel,row)
if (sel) {
this.select.plan_name = '[' + sel.year + '] - ' + sel.name
this.select.plan_id = sel.id
} else {
this.select.plan_name = row.name
this.select.plan_id = row.id
this.select.plan_id = ''
this.select.plan_name = ''
}
},
planSelectForSearch() {
if (this.plan.length === 0) {
if (!this.select.plan_id) {
Message({
type: 'warning',
message: '选择计划不能为空'
message: '请选择预算计划'
})
return
}
for (const item of this.plan) {
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
this.isShowPlanForSearch = false
},
//
selectPlan(sel, row) {
@ -4039,4 +4032,16 @@ export default {
.payment-preview-modal {
z-index: 4000 !important;
}
.search-controls {
display: flex;
align-items: center;
margin-bottom: 15px;
padding: 15px;
background-color: #f8f9fa;
border-radius: 6px;
}
</style>

@ -213,6 +213,97 @@
<el-dialog :visible.sync="postPaymentFormDialogVisible" title="事后支付表格" width="800px">
<div v-html="currentPostPaymentForm"></div>
</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>
</template>
@ -263,35 +354,34 @@ export default {
},
planSearch: {
name: '',
plan_department_id: ''
plan_department_id: '',
year: this.$moment().format("YYYY")
},
//
departments: [],
//
availableYears: [],
plans: [],
planTotal: 0,
plansPageIndex: 1,
plan: [],
moneyWay: [],
planTableSearch: [
{
label: '分类',
prop: 'type_detail.name',
// formatter: (cell, data, value) => {
// const res = this.moneyWay.filter((item) => {
// return item.id === value
// })
// return res[0]?.value || ''
// },
width: 170
width: 120
},
{
label: '年份',
prop: 'year',
align: 'center',
width: 100
width: 90
},
{
label: '名称',
prop: 'name',
width: 260,
width: 200,
align: 'left'
},
{
@ -464,6 +554,8 @@ export default {
this.select.plan_id = plan_id
this.select.plan_name = plan_name
this.getFundLogs()
this.initAvailableYears()
this.initDepartments()
},
created() {
const type = parseInt(this.$route.path.split('_')[1])
@ -580,6 +672,8 @@ export default {
}
},
//
async getBudgets() {
await getBudget({
@ -587,10 +681,10 @@ export default {
page_size: 10,
page: this.plansPageIndex,
plan_department_id: this.planSearch.plan_department_id,
top_pid: 1
top_pid: 1,
year: this.planSearch.year ? this.planSearch.year : ''
}).then((res) => {
this.plans = res.list.data
this.planTotal = res.list.total
this.toggleSelection(
@ -601,6 +695,7 @@ export default {
)
})
},
//
toggleSelection(plans, type) {
if (plans) {
@ -622,6 +717,31 @@ export default {
this.select.plan_id = ''
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) {
this.pageSize = e
this.pageIndex = 1
@ -632,6 +752,8 @@ export default {
this.getFundLogs()
},
async getFundLogs(is_export) {
await getFundLog({
is_auth: this.is_auth,
@ -838,4 +960,13 @@ export default {
}
</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>资金列支渠道
</div>
<div class="xy-table-item-content">
<el-select
v-model="paymentRegistrationForm.moneyWay"
multiple
style="width: 300px;"
placeholder="请选择资金列支渠道"
@change="moneyWayChange"
>
<el-option v-for="item in planTypes_arr" :key="item.id" :value="item.id" :label="item.value" />
</el-select>
<div class="money-way-tree-container">
<el-tree
ref="moneyWayTree"
:data="planTypes"
:props="defaultProps"
show-checkbox
node-key="id"
:default-checked-keys="paymentRegistrationForm.moneyWay || []"
: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>
</template>
@ -286,6 +303,8 @@ export default {
payment: [], //
planTypes: [],
planTypes_arr:[],
//
selectedMoneyWayLabels: [],
payTable: [{
label: '申请金额',
prop: 'apply_money',
@ -443,10 +462,15 @@ export default {
watch: {
isShow(newVal) {
if (!newVal) {
this.paymentRegistrationForm.actMoney = ''
this.paymentRegistrationForm.moneyWay = ''
this.paymentRegistrationForm.plan = []
this.paymentRegistrationForm.actMoney = ''
this.paymentRegistrationForm.moneyWay = []
this.paymentRegistrationForm.plan = []
this.selectedMoneyWayLabels = []
this.$refs.planTable.clearSelection()
//
if (this.$refs.moneyWayTree) {
this.$refs.moneyWayTree.setCheckedKeys([])
}
}
}
},
@ -491,6 +515,83 @@ export default {
// 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) {
row.use_money = e
this.paymentRegistrationForm.plan.forEach(item => {
@ -504,6 +605,7 @@ export default {
number: 'money_way'
})
this.planTypes_arr = res1.detail
const res = await getPlanType({
page_size: 999,
page: 1,
@ -602,6 +704,11 @@ export default {
this.paymentRegistrationForm.actMoney = res.apply_money
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.moneyWayChange()
},
@ -773,4 +880,40 @@ export default {
::v-deep .planselsct .el-checkbox__input .el-checkbox__inner {
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>

@ -91,13 +91,48 @@
@on-ok="planSelectForSearch"
>
<template v-slot:normalContent>
<Input
v-model="planSearch.name"
search
enter-button="搜 索"
placeholder="搜索预算计划.."
@on-search="searchBudgets"
/>
<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;
@ -255,8 +290,13 @@ export default {
plans: [], //
planSearch: {
name: '',
plan_department_id: ''
plan_department_id: '',
year: this.$moment().format("YYYY")
},
//
departments: [],
//
availableYears: [],
planTotal: 0,
plansPageIndex: 1,
isShowPlanForSearch: false,
@ -389,6 +429,7 @@ export default {
mounted() {
this.getMoneyWay()
this.getFundLogs()
this.initAvailableYears()
},
methods: {
planPageChange(e) {
@ -445,10 +486,10 @@ export default {
page_size: 10,
page: this.plansPageIndex,
plan_department_id: this.planSearch.plan_department_id,
top_pid: 1
top_pid: 1,
year: this.planSearch.year || ''
}).then((res) => {
this.plans = res.list.data
this.planTotal = res.list.total
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() {
this.isShowPlanForSearch = true
await this.getBudgets()

Loading…
Cancel
Save