|
|
|
|
@ -78,34 +78,37 @@
|
|
|
|
|
<vxe-column title="备注" width="460" align="left" field="remark">
|
|
|
|
|
</vxe-column>
|
|
|
|
|
<vxe-column title="创建信息" width="180" align="center" field="created_at">
|
|
|
|
|
</vxe-column>
|
|
|
|
|
<vxe-column
|
|
|
|
|
min-width="120"
|
|
|
|
|
header-align="center"
|
|
|
|
|
field="operate"
|
|
|
|
|
title="操作"
|
|
|
|
|
fixed="right"
|
|
|
|
|
>
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-button type="primary" size="small" @click="showDetail(row)"
|
|
|
|
|
>查看</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
</vxe-column>
|
|
|
|
|
</vxe-table>
|
|
|
|
|
<div style="display: flex;justify-content: center;margin-top:15px">
|
|
|
|
|
<el-button :disabled="paymentsList.length>0?false:true" type="primary" size="small" @click="payClose">设为已支付完毕 <i class="el-icon-arrow-right"></i> </el-button>
|
|
|
|
|
</div>
|
|
|
|
|
<vxe-column
|
|
|
|
|
min-width="120"
|
|
|
|
|
header-align="center"
|
|
|
|
|
field="operate"
|
|
|
|
|
title="操作"
|
|
|
|
|
fixed="right"
|
|
|
|
|
>
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-button type="primary" size="small" @click="showDetail(row)"
|
|
|
|
|
>查看</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
</vxe-column>
|
|
|
|
|
</vxe-table>
|
|
|
|
|
<div style="display: flex;justify-content: center;margin-top:15px">
|
|
|
|
|
<el-button :disabled="paymentsList.length>0?false:true" type="primary" size="small" @click="payClose">设为已支付完毕 <i class="el-icon-arrow-right"></i> </el-button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>发起新的支付审批</h3>
|
|
|
|
|
|
|
|
|
|
<div v-for="pay in payList" :key="pay.id" style="margin-top: 12px;">
|
|
|
|
|
<div style="font-weight: 600; margin: 6px 0;">{{ pay.title }}</div>
|
|
|
|
|
<div style="display: flex;align-items: center;justify-content: space-between;">
|
|
|
|
|
<div style="display: flex;align-items: center;">
|
|
|
|
|
<div class="xy-table-item-label">
|
|
|
|
|
<span style="color: red; font-weight: 600; padding-right: 4px">*</span>申请付款金额
|
|
|
|
|
</div>
|
|
|
|
|
<div class="xy-table-item-content xy-table-item-price">
|
|
|
|
|
<el-input clearable type="number" placeholder="请填写付款金额" v-model="fundlogForm.applyMoney"
|
|
|
|
|
<el-input clearable type="number" placeholder="请填写付款金额" v-model="fundlogFormMap[pay.id].applyMoney"
|
|
|
|
|
style="width: 150px;margin-left:10px" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
@ -114,7 +117,7 @@
|
|
|
|
|
<span style="color: red; font-weight: 600; padding-right: 4px">*</span>款项类型
|
|
|
|
|
</div>
|
|
|
|
|
<div style="display: flex;align-items: center;">
|
|
|
|
|
<el-select placeholder="选择款项类型或直接录入其他类型" v-model="fundlogForm.type" style="width: 200px;margin-left:10px"
|
|
|
|
|
<el-select placeholder="选择款项类型或直接录入其他类型" v-model="fundlogFormMap[pay.id].type" style="width: 200px;margin-left:10px"
|
|
|
|
|
filterable allow-create clearable popper-append-to-body>
|
|
|
|
|
<el-option v-for="item in paymentType" :key="item" :label="item" :value="item">
|
|
|
|
|
</el-option>
|
|
|
|
|
@ -126,12 +129,11 @@
|
|
|
|
|
<span style="color: red; font-weight: 600; padding-right: 4px">*</span>是否为最后一笔
|
|
|
|
|
</div>
|
|
|
|
|
<div class="xy-table-item-content" style="margin-left:10px">
|
|
|
|
|
<el-switch v-model="fundlogForm.isLast" />
|
|
|
|
|
<!-- @change="toggleSelection"-->
|
|
|
|
|
<el-switch v-model="fundlogFormMap[pay.id].isLast" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<vxe-table ref="table" stripe style="margin-top: 10px" keep-source :column-config="{ resizable: true }"
|
|
|
|
|
<vxe-table :ref="'table_' + pay.id" stripe style="margin-top: 6px" keep-source :column-config="{ resizable: true }"
|
|
|
|
|
:print-config="{}" :export-config="{}" :expand-config="{
|
|
|
|
|
accordion: true,
|
|
|
|
|
padding: true,
|
|
|
|
|
@ -142,11 +144,10 @@
|
|
|
|
|
checkMethod: ({ row }) => {
|
|
|
|
|
return parseFloat(row.hasPayNum) < parseFloat(row.num)
|
|
|
|
|
}
|
|
|
|
|
}" :row-config="{ keyField: 'id' }" :custom-config="{ mode: 'popup' }" :data="list">
|
|
|
|
|
}" :row-config="{ keyField: 'id' }" :custom-config="{ mode: 'popup' }" :data="getGroupList(pay.id)">
|
|
|
|
|
<vxe-column type="checkbox" width="50" align="center"></vxe-column>
|
|
|
|
|
<vxe-column title="本次报销数量" width="120" align="center" field="payNum">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
|
|
|
|
|
<vxe-number-input v-if="parseFloat(row.hasPayNum) < parseFloat(row.num)" v-model="row.payNum"
|
|
|
|
|
placeholder="数量"></vxe-number-input>
|
|
|
|
|
<div v-else>-</div>
|
|
|
|
|
@ -154,9 +155,9 @@
|
|
|
|
|
</vxe-column>
|
|
|
|
|
<vxe-column title="已报销数量" width="100" align="center" field="hasPayNum">
|
|
|
|
|
</vxe-column>
|
|
|
|
|
<vxe-column align="center" v-for="item in table_item" :title="item.label" :field="item.prop"></vxe-column>
|
|
|
|
|
|
|
|
|
|
<vxe-column align="center" v-for="item in table_item" :key="item.prop + '_' + pay.id" :title="item.label" :field="item.prop"></vxe-column>
|
|
|
|
|
</vxe-table>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<template #footer>
|
|
|
|
|
@ -166,11 +167,11 @@
|
|
|
|
|
</template>
|
|
|
|
|
</vxe-modal>
|
|
|
|
|
<vxe-modal
|
|
|
|
|
fullscreen
|
|
|
|
|
fullscreen
|
|
|
|
|
:remember="true"
|
|
|
|
|
class-name="oa-modal"
|
|
|
|
|
title="流程查看"
|
|
|
|
|
v-model="isShowOaModal"
|
|
|
|
|
v-model="isShowOaModal"
|
|
|
|
|
:z-index="zIndex+100"
|
|
|
|
|
>
|
|
|
|
|
<div style="width: 100%;height: 100%;">
|
|
|
|
|
@ -188,7 +189,7 @@
|
|
|
|
|
import {
|
|
|
|
|
getItems,
|
|
|
|
|
detailContract,
|
|
|
|
|
getFundLog,
|
|
|
|
|
getFundLog,
|
|
|
|
|
fundLogEnd
|
|
|
|
|
} from '@/api/flow/pay'
|
|
|
|
|
import {
|
|
|
|
|
@ -205,13 +206,21 @@ import {getToken} from "@/utils/auth";
|
|
|
|
|
default: false,
|
|
|
|
|
required: true
|
|
|
|
|
},
|
|
|
|
|
// 新增:接收支付列表,包含各项的 out_contract_id
|
|
|
|
|
// payList: {
|
|
|
|
|
// type: Array,
|
|
|
|
|
// default: () => []
|
|
|
|
|
// }
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
payId: '',
|
|
|
|
|
payList:[],
|
|
|
|
|
defaultModalSize,
|
|
|
|
|
zIndex: PopupManager.nextZIndex(),
|
|
|
|
|
list: [],
|
|
|
|
|
// 每个区块(pay.id)对应的表单:申请金额/类型/是否最后一笔
|
|
|
|
|
fundlogFormMap: {},
|
|
|
|
|
table_item: [],
|
|
|
|
|
flowDetail: {},
|
|
|
|
|
fundlogForm: {
|
|
|
|
|
@ -231,7 +240,12 @@ import {getToken} from "@/utils/auth";
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
// 获取某一 pay 的分组数据
|
|
|
|
|
getGroupList(flowId) {
|
|
|
|
|
return (this.list || []).filter(r => r.sourceFlowId === flowId)
|
|
|
|
|
},
|
|
|
|
|
async getConfig() {
|
|
|
|
|
// 改造:不再通过 view 接口获取,直接使用传入的 payList
|
|
|
|
|
const loading = this.$loading({
|
|
|
|
|
lock: true,
|
|
|
|
|
text: "拼命加载中",
|
|
|
|
|
@ -239,45 +253,98 @@ import {getToken} from "@/utils/auth";
|
|
|
|
|
background: "rgba(0, 0, 0, 0.8)",
|
|
|
|
|
});
|
|
|
|
|
try {
|
|
|
|
|
const res = await view(this.payId);
|
|
|
|
|
console.log('this.payList', this.payList)
|
|
|
|
|
// 初始化本地可编辑列表(聚合 payList 的各自明细:JSON.parse(data.caigoumingxi))
|
|
|
|
|
this.list = [];
|
|
|
|
|
(this.payList || []).forEach(pay => {
|
|
|
|
|
let subList = []
|
|
|
|
|
try {
|
|
|
|
|
subList = JSON.parse(pay?.data?.caigoumingxi || '[]')
|
|
|
|
|
} catch(e) {
|
|
|
|
|
subList = []
|
|
|
|
|
}
|
|
|
|
|
// 初始化每个区块的表单默认值
|
|
|
|
|
if (!this.fundlogFormMap[pay.id]) {
|
|
|
|
|
this.$set(this.fundlogFormMap, pay.id, {
|
|
|
|
|
applyMoney: 0,
|
|
|
|
|
type: '',
|
|
|
|
|
isLast: false
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
subList.forEach(item => {
|
|
|
|
|
const newItem = Object.assign({}, item, {
|
|
|
|
|
payNum: 0,
|
|
|
|
|
hasPayNum: 0,
|
|
|
|
|
sourceFlowId: pay.id
|
|
|
|
|
})
|
|
|
|
|
this.list.push(newItem)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
console.log('this.list', this.list)
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
fields
|
|
|
|
|
} = res?.customModel;
|
|
|
|
|
this.flowDetail = res?.flow
|
|
|
|
|
const {
|
|
|
|
|
data
|
|
|
|
|
} = res?.flow
|
|
|
|
|
fields.forEach((field) => {
|
|
|
|
|
if (field.type === 'relation') {
|
|
|
|
|
// 增加 自己提交的数量 和 已提交的数量
|
|
|
|
|
this.list = JSON.parse(data[field.name])
|
|
|
|
|
this.list.map(item => {
|
|
|
|
|
item.payNum = 0
|
|
|
|
|
item.hasPayNum = 0
|
|
|
|
|
// 组装逗号分隔的 flow_id / id 字符串用于 getItemNum
|
|
|
|
|
const ids = (this.payList || [])
|
|
|
|
|
.map(i => i && (i.id))
|
|
|
|
|
.filter(id => !!id)
|
|
|
|
|
.join(',')
|
|
|
|
|
|
|
|
|
|
if (ids) {
|
|
|
|
|
await this.getItemNum(ids)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取字段配置:取第一条的 sub_custom_model_id
|
|
|
|
|
// const firstSubModelId = this.payList && this.payList[0] && (this.payList[0].sub_custom_model_id || this.payList[0].field?.sub_custom_model_id)
|
|
|
|
|
// if (firstSubModelId) {
|
|
|
|
|
await this.getFieldConfig(81)
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// 历史支付记录由 payList 汇总的 out_contract_id 直接获取
|
|
|
|
|
await this.getFundLogList()
|
|
|
|
|
|
|
|
|
|
// 确保子表渲染到最新数据
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
try {
|
|
|
|
|
(this.payList || []).forEach(pay => {
|
|
|
|
|
const refKey = 'table_' + pay.id
|
|
|
|
|
const tableRef = this.$refs[refKey]
|
|
|
|
|
const data = this.getGroupList(pay.id)
|
|
|
|
|
if (tableRef && data) {
|
|
|
|
|
if (typeof tableRef.reloadData === 'function') {
|
|
|
|
|
tableRef.reloadData(data)
|
|
|
|
|
} else if (typeof tableRef.loadData === 'function') {
|
|
|
|
|
tableRef.loadData(data)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
this.getItemNum(this.payId)
|
|
|
|
|
this.getFieldConfig(field.sub_custom_model_id)
|
|
|
|
|
} catch(e) {
|
|
|
|
|
console.warn('vxe-table reloadData failed', e)
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
this.getFundLogList()
|
|
|
|
|
console.log("this.list", this.list)
|
|
|
|
|
loading.close();
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
loading.close()
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error(err)
|
|
|
|
|
this.$message.error("配置失败");
|
|
|
|
|
loading.close();
|
|
|
|
|
this.$message.error("配置失败")
|
|
|
|
|
loading.close()
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 获取历史支付明细
|
|
|
|
|
async getFundLogList() {
|
|
|
|
|
let payments =
|
|
|
|
|
(
|
|
|
|
|
// 从传入的 payList 中汇总 out_contract_id,用逗号连接
|
|
|
|
|
const contractIds = (this.payList || [])
|
|
|
|
|
.map(i => i && i.out_contract_id)
|
|
|
|
|
.filter(id => !!id)
|
|
|
|
|
.join(',');
|
|
|
|
|
|
|
|
|
|
let payments = []
|
|
|
|
|
if (contractIds) {
|
|
|
|
|
payments = (
|
|
|
|
|
await getFundLog({
|
|
|
|
|
contract_id: this.flowDetail.out_contract_id,
|
|
|
|
|
contract_id: contractIds,
|
|
|
|
|
show_type: 1
|
|
|
|
|
})
|
|
|
|
|
)?.data || [];
|
|
|
|
|
)?.data || []
|
|
|
|
|
}
|
|
|
|
|
this.paymentsList = payments
|
|
|
|
|
console.log("paymentsList", this.paymentsList)
|
|
|
|
|
},
|
|
|
|
|
@ -312,66 +379,61 @@ import {getToken} from "@/utils/auth";
|
|
|
|
|
item.forEach(item => {
|
|
|
|
|
itemMap.set(item.wuzicaigou_item_id, item.total_num);
|
|
|
|
|
});
|
|
|
|
|
// 遍历 list 数组,根据 id 从 Map 中获取 total_num 并赋值给 hasPayNum
|
|
|
|
|
this.list.forEach(item => {
|
|
|
|
|
if (itemMap.has(item.id)) {
|
|
|
|
|
item.hasPayNum = itemMap.get(item.id);
|
|
|
|
|
// 遍历合并后的 list,根据 id 从 Map 中获取 total_num 并赋值给 hasPayNum
|
|
|
|
|
this.list.forEach(row => {
|
|
|
|
|
if (itemMap.has(row.id)) {
|
|
|
|
|
row.hasPayNum = itemMap.get(row.id)
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error(err)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
showDetail(row){
|
|
|
|
|
let url = `/oa/#/flow/detail?module_name=oa&auth_token=${window.encodeURIComponent(getToken())}&isSinglePage=1&flow_id=`
|
|
|
|
|
let pay = row.fund_log_flow_links.find(i => i.tag === 'pay')
|
|
|
|
|
//url += `&to=/flow/detail?flow_id=${caigou.id}`
|
|
|
|
|
url += pay?.flow_id
|
|
|
|
|
this.oaUrl = url
|
|
|
|
|
this.isShowOaModal = true
|
|
|
|
|
},
|
|
|
|
|
payClose(){
|
|
|
|
|
this.$confirm('将此采购记录设为“已⽀付完毕”,同时会将最后⼀笔⽀付记录的“是否为最后⼀笔”属性设置为“是”,请确认是否要进⾏此操作', '提示', {
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
callback: action => {
|
|
|
|
|
if(action==='confirm'){
|
|
|
|
|
fundLogEnd({
|
|
|
|
|
contract_id:this.flowDetail.out_contract_id,
|
|
|
|
|
}).then(res=>{
|
|
|
|
|
this.$emit('update:isShow', false)
|
|
|
|
|
this.$emit('refresh')
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// this.fundlogForm.isLast = true
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
showDetail(row){
|
|
|
|
|
let url = `/oa/#/flow/detail?module_name=oa&auth_token=${window.encodeURIComponent(getToken())}&isSinglePage=1&flow_id=`
|
|
|
|
|
let pay = row.fund_log_flow_links.find(i => i.tag === 'pay')
|
|
|
|
|
//url += `&to=/flow/detail?flow_id=${caigou.id}`
|
|
|
|
|
url += pay?.flow_id
|
|
|
|
|
this.oaUrl = url
|
|
|
|
|
this.isShowOaModal = true
|
|
|
|
|
},
|
|
|
|
|
payClose(){
|
|
|
|
|
this.$confirm('将此采购记录设为“已⽀付完毕”,同时会将最后⼀笔⽀付记录的“是否为最后⼀笔”属性设置为“是”,请确认是否要进⾏此操作', '提示', {
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
callback: action => {
|
|
|
|
|
if(action==='confirm'){
|
|
|
|
|
fundLogEnd({
|
|
|
|
|
contract_id:this.flowDetail.out_contract_id,
|
|
|
|
|
}).then(res=>{
|
|
|
|
|
this.$emit('update:isShow', false)
|
|
|
|
|
this.$emit('refresh')
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// this.fundlogForm.isLast = true
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
async submit() {
|
|
|
|
|
try {
|
|
|
|
|
if (!this.fundlogForm.applyMoney) {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: '请填写本次申请付款金额',
|
|
|
|
|
duration: 2000,
|
|
|
|
|
type: 'warning'
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (!this.fundlogForm.type) {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: '请选择款项类型',
|
|
|
|
|
duration: 2000,
|
|
|
|
|
type: 'warning'
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const records = this.$refs.table.getCheckboxRecords()
|
|
|
|
|
|
|
|
|
|
// 收集所有子表勾选记录
|
|
|
|
|
let records = []
|
|
|
|
|
this.payList.forEach(pay => {
|
|
|
|
|
const refKey = 'table_' + pay.id
|
|
|
|
|
let tableRef = this.$refs[refKey]
|
|
|
|
|
// 兼容 v-for 下 ref 可能为数组的情况
|
|
|
|
|
if (Array.isArray(tableRef)) tableRef = tableRef[0]
|
|
|
|
|
if (tableRef) {
|
|
|
|
|
const sel = typeof tableRef.getCheckboxRecords === 'function' ? (tableRef.getCheckboxRecords() || []) : []
|
|
|
|
|
const reserveSel = typeof tableRef.getCheckboxReserveRecords === 'function' ? (tableRef.getCheckboxReserveRecords() || []) : []
|
|
|
|
|
records = records.concat(sel, reserveSel)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
console.log("records", records)
|
|
|
|
|
let count = 0
|
|
|
|
|
let totalCount = 0
|
|
|
|
|
let allCount = 0 // 每一条本次报销数量+已报销数量 = 数量
|
|
|
|
|
// 分组逐块校验数量
|
|
|
|
|
if (records.length < 1) {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: '请选择需要报销的明细',
|
|
|
|
|
@ -380,20 +442,57 @@ import {getToken} from "@/utils/auth";
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
records.map(item => {
|
|
|
|
|
if (parseFloat(item.payNum) === 0 || parseFloat(item.payNum) > parseFloat(item.num)) {
|
|
|
|
|
count++
|
|
|
|
|
// 校验每个分组(pay.id)的区块表单是否填写(金额、类型)
|
|
|
|
|
const idToTitle = {}
|
|
|
|
|
;(this.payList || []).forEach(p => { idToTitle[p.id] = p.title })
|
|
|
|
|
const groupIds = Array.from(new Set(records.map(r => r.sourceFlowId)))
|
|
|
|
|
for (const gid of groupIds) {
|
|
|
|
|
const form = this.fundlogFormMap[gid] || {}
|
|
|
|
|
if (!form.applyMoney || Number(form.applyMoney) <= 0) {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: `【${idToTitle[gid] || gid}】请填写本次申请付款金额`,
|
|
|
|
|
duration: 2000,
|
|
|
|
|
type: 'warning'
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (parseFloat(item.payNum) + parseFloat(item.hasPayNum) > parseFloat(item.num)) {
|
|
|
|
|
totalCount++
|
|
|
|
|
if (!form.type) {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: `【${idToTitle[gid] || gid}】请选择款项类型`,
|
|
|
|
|
duration: 2000,
|
|
|
|
|
type: 'warning'
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (parseFloat(item.payNum) + parseFloat(item.hasPayNum) === parseFloat(item.num)) {
|
|
|
|
|
allCount++
|
|
|
|
|
}
|
|
|
|
|
// 数量校验:按分组逐块处理,并在“等于总数量”时自动设置该块为最后一笔
|
|
|
|
|
const groupMap = records.reduce((acc, row) => {
|
|
|
|
|
const gid = row.sourceFlowId
|
|
|
|
|
if (!acc[gid]) acc[gid] = []
|
|
|
|
|
acc[gid].push(row)
|
|
|
|
|
return acc
|
|
|
|
|
}, {})
|
|
|
|
|
const groupsToAutoEnd = []
|
|
|
|
|
for (const gid of Object.keys(groupMap)) {
|
|
|
|
|
const rows = groupMap[gid]
|
|
|
|
|
let count = 0
|
|
|
|
|
let totalCount = 0
|
|
|
|
|
let allToRemain = true
|
|
|
|
|
rows.forEach(item => {
|
|
|
|
|
const payNum = Number(item.payNum)
|
|
|
|
|
const num = Number(item.num)
|
|
|
|
|
const hasPay = Number(item.hasPayNum)
|
|
|
|
|
const remain = num - hasPay
|
|
|
|
|
if (isNaN(payNum) || payNum === 0 || payNum > num) count++
|
|
|
|
|
if (payNum + hasPay > num) totalCount++
|
|
|
|
|
// 判断是否每一条都“正好补齐剩余”
|
|
|
|
|
if (!(payNum > 0 && Math.abs(payNum - remain) < 1e-6)) {
|
|
|
|
|
allToRemain = false
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
if (count > 0) {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: '报销数量不能为0或报销数量大于总数量',
|
|
|
|
|
message: `【${idToTitle[gid] || gid}】报销数量不能为0或报销数量大于总数量`,
|
|
|
|
|
duration: 2000,
|
|
|
|
|
type: 'warning'
|
|
|
|
|
})
|
|
|
|
|
@ -401,88 +500,111 @@ import {getToken} from "@/utils/auth";
|
|
|
|
|
}
|
|
|
|
|
if (totalCount > 0) {
|
|
|
|
|
this.$message({
|
|
|
|
|
message: '本次报销数量大于剩余可报销数量',
|
|
|
|
|
message: `【${idToTitle[gid] || gid}】本次报销数量大于剩余可报销数量`,
|
|
|
|
|
duration: 2000,
|
|
|
|
|
type: 'warning'
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (allCount === records.length) {
|
|
|
|
|
this.$alert('本次报销数量已等于总数量,默认为最后一笔', '提示', {
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
callback: action => {
|
|
|
|
|
this.fundlogForm.isLast = true
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// 记录需要自动置为“最后一笔”的分组,统一在提交前弹一次提示
|
|
|
|
|
if (allToRemain && this.fundlogFormMap[gid] && !this.fundlogFormMap[gid].isLast) {
|
|
|
|
|
groupsToAutoEnd.push(gid)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// return
|
|
|
|
|
//wuzicaigou_items 报销的物资明细数组
|
|
|
|
|
if (groupsToAutoEnd.length > 0) {
|
|
|
|
|
// 等待用户确认后再继续,避免先跳转
|
|
|
|
|
await this.$alert('本次报销数量已等于总数量,默认为最后一笔', '提示', {
|
|
|
|
|
confirmButtonText: '确定'
|
|
|
|
|
})
|
|
|
|
|
groupsToAutoEnd.forEach(gid => {
|
|
|
|
|
if (this.fundlogFormMap[gid]) this.$set(this.fundlogFormMap[gid], 'isLast', true)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
// 组合成单个审批
|
|
|
|
|
let wuzicaigou_items = []
|
|
|
|
|
let zhifutitle = ''
|
|
|
|
|
records.map(item => {
|
|
|
|
|
// 建立 flowId -> contractId 映射
|
|
|
|
|
const flowIdToContractId = {}
|
|
|
|
|
;(this.payList || []).forEach(p => {
|
|
|
|
|
const fid = p.id
|
|
|
|
|
if (fid) flowIdToContractId[fid] = p.out_contract_id
|
|
|
|
|
})
|
|
|
|
|
records.forEach(item => {
|
|
|
|
|
const form = this.fundlogFormMap[item.sourceFlowId] || { applyMoney: 0, type: '', isLast: false }
|
|
|
|
|
wuzicaigou_items.push({
|
|
|
|
|
flow_id: this.payId,
|
|
|
|
|
flow_id: item.sourceFlowId || this.payId,
|
|
|
|
|
contract_id: flowIdToContractId[item.sourceFlowId] || undefined,
|
|
|
|
|
wuzicaigou_id: item.belongs_id,
|
|
|
|
|
wuzicaigou_item_id: item.id,
|
|
|
|
|
name: item.pinminghuofuwuxuqiu,
|
|
|
|
|
num: item.payNum,
|
|
|
|
|
total: item.num
|
|
|
|
|
total: item.num,
|
|
|
|
|
// 区块级的额外字段注入到每条明细,便于后端识别
|
|
|
|
|
apply_money: form.applyMoney,
|
|
|
|
|
type: form.type,
|
|
|
|
|
is_end: form.isLast ? 1 : 0
|
|
|
|
|
})
|
|
|
|
|
zhifutitle += item.pinminghuofuwuxuqiu + '*' + item.payNum + ','
|
|
|
|
|
})
|
|
|
|
|
console.log("wuzicaigou_items",wuzicaigou_items)
|
|
|
|
|
// return
|
|
|
|
|
// 聚合相关合同信息:从 payList 收集 contract_id,逐个请求 detailContract 并整合为数组
|
|
|
|
|
const contractIds = Array.from(new Set((this.payList || []).map(p => p.out_contract_id).filter(Boolean)))
|
|
|
|
|
let contracts = []
|
|
|
|
|
if (contractIds.length > 0) {
|
|
|
|
|
try {
|
|
|
|
|
contracts = await Promise.all(contractIds.map(id => detailContract({ id })))
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.warn('fetch contracts failed', e)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 仍以第一份合同作为展示主合同(标题等),其余信息通过聚合参与计算
|
|
|
|
|
const mainContract = contracts && contracts.length > 0 ? contracts[0] : null
|
|
|
|
|
|
|
|
|
|
// 跳转到支付审批流程
|
|
|
|
|
let payments = this.paymentsList;
|
|
|
|
|
const actNumsTotal = () => {
|
|
|
|
|
return payments.reduce((pre, cur) => {
|
|
|
|
|
return pre + (!!Number(cur.act_money) ? Number(cur.act_money) : 0);
|
|
|
|
|
}, 0);
|
|
|
|
|
};
|
|
|
|
|
let contract;
|
|
|
|
|
if (this.flowDetail.out_contract_id) {
|
|
|
|
|
contract = await detailContract({
|
|
|
|
|
id: this.flowDetail.out_contract_id
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
const actNumsTotal = () => payments.reduce((pre, cur) => pre + (!!Number(cur.act_money) ? Number(cur.act_money) : 0), 0)
|
|
|
|
|
|
|
|
|
|
// payments = this.paymentsList
|
|
|
|
|
// (
|
|
|
|
|
// await getFundLog({
|
|
|
|
|
// contract_id: this.flowDetail.out_contract_id,
|
|
|
|
|
// show_type: 1
|
|
|
|
|
// })
|
|
|
|
|
// )?.data || [];
|
|
|
|
|
// 付款登记的字段
|
|
|
|
|
let zhifutitle2 = zhifutitle.slice(0, -1)
|
|
|
|
|
zhifutitle += "(" + this.flowDetail.title + ')'
|
|
|
|
|
let baseInfo = {
|
|
|
|
|
"oaUrl": contract?.number,
|
|
|
|
|
"zhifutitle": zhifutitle,
|
|
|
|
|
// ?contract?.name
|
|
|
|
|
"contract_id": contract.id,
|
|
|
|
|
"type": this.fundlogForm.type,
|
|
|
|
|
"is_end": this.fundlogForm.isLast ? 1 : 0,
|
|
|
|
|
"amt": this.fundlogForm.applyMoney,
|
|
|
|
|
// out_pay_id: row?.id,
|
|
|
|
|
"xiangxishuoming": zhifutitle,
|
|
|
|
|
"yifujine": actNumsTotal(),
|
|
|
|
|
"xiangmuzonge": contract.money,
|
|
|
|
|
"zhifucishu": contract?.sign_plan?.length,
|
|
|
|
|
"cishu": payments.length,
|
|
|
|
|
if (mainContract?.name) zhifutitle += `(${mainContract.name} 等${contractIds.length}个合同)`
|
|
|
|
|
|
|
|
|
|
// 从明细中聚合主数据:合同ID串与金额合计
|
|
|
|
|
const contractIdStr = Array.from(new Set(wuzicaigou_items.map(i => i.contract_id).filter(Boolean))).join(',')
|
|
|
|
|
const amtTotal = wuzicaigou_items.reduce((sum, i) => sum + (Number(i.group_apply_money || i.apply_money) || 0), 0)
|
|
|
|
|
|
|
|
|
|
// 从合同列表聚合展示数据
|
|
|
|
|
const sumMoney = (contracts || []).reduce((sum, c) => sum + (Number(c?.money) || 0), 0)
|
|
|
|
|
const sumPlanLen = (contracts || []).reduce((sum, c) => sum + ((c?.sign_plan?.length) || 0), 0)
|
|
|
|
|
const plansNames = Array.from(new Set((contracts || []).flatMap(c => (c?.plans || []).map(p => p?.name)).filter(Boolean))).join(',')
|
|
|
|
|
const contractNos = (contracts || []).map(c => c?.number).filter(Boolean).join(',')
|
|
|
|
|
const relatedFlows = Array.from(new Set((contracts || []).flatMap(c => (c?.contract_flow_links || []).map(l => l?.flow_id)).filter(Boolean))).join(',')
|
|
|
|
|
|
|
|
|
|
const baseInfo = {
|
|
|
|
|
// oaUrl: mainContract?.number,
|
|
|
|
|
zhifutitle,
|
|
|
|
|
contract_id: contractIdStr,
|
|
|
|
|
type: '',
|
|
|
|
|
is_end: '',
|
|
|
|
|
amt: amtTotal,
|
|
|
|
|
xiangxishuoming: zhifutitle,
|
|
|
|
|
yifujine: actNumsTotal(),
|
|
|
|
|
cishu: payments.length,
|
|
|
|
|
|
|
|
|
|
"liezhiqudao": contract?.plans.map(i => i.name)?.toString(),
|
|
|
|
|
"contractno": contract?.number,
|
|
|
|
|
"guanlianliucheng": contract?.contract_flow_links?.map(i => i.flow_id)?.toString(),
|
|
|
|
|
"wuzicaigou_items": wuzicaigou_items
|
|
|
|
|
};
|
|
|
|
|
console.log(baseInfo, baseInfo)
|
|
|
|
|
let url =
|
|
|
|
|
`/flow/create?&module_name=oa&isSinglePage=1&module_id=75&default_json=${window.encodeURIComponent(JSON.stringify(baseInfo))}`;
|
|
|
|
|
this.$router.push(
|
|
|
|
|
url
|
|
|
|
|
);
|
|
|
|
|
// this.oaUrl = url;
|
|
|
|
|
// this.isShowOaModal = true;
|
|
|
|
|
xiangmuzonge: sumMoney,
|
|
|
|
|
zhifucishu: sumPlanLen,
|
|
|
|
|
liezhiqudao: plansNames,
|
|
|
|
|
contractno: contractNos,
|
|
|
|
|
guanlianliucheng: relatedFlows,
|
|
|
|
|
|
|
|
|
|
// xiangmuzonge: mainContract?.money,
|
|
|
|
|
// zhifucishu: mainContract?.sign_plan?.length,
|
|
|
|
|
// liezhiqudao: mainContract?.plans.map(i => i.name)?.toString(),
|
|
|
|
|
// contractno: mainContract?.number,
|
|
|
|
|
// guanlianliucheng: mainContract?.contract_flow_links?.map(i => i.flow_id)?.toString(),
|
|
|
|
|
|
|
|
|
|
wuzicaigou_items
|
|
|
|
|
}
|
|
|
|
|
const url = `/flow/create?&module_name=oa&isSinglePage=1&module_id=75&default_json=${window.encodeURIComponent(JSON.stringify(baseInfo))}`
|
|
|
|
|
this.$router.push(url)
|
|
|
|
|
this.$emit('update:isShow', false)
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error(err)
|
|
|
|
|
@ -495,14 +617,16 @@ import {getToken} from "@/utils/auth";
|
|
|
|
|
if (newVal) {
|
|
|
|
|
this.zIndex = PopupManager.nextZIndex()
|
|
|
|
|
|
|
|
|
|
if (this.payId) {
|
|
|
|
|
// 直接拉取历史支付记录(无需依赖 getConfig)
|
|
|
|
|
console.log("this.payList123", this.payList)
|
|
|
|
|
this.getFundLogList()
|
|
|
|
|
// 加载表格字段配置与数量统计(基于传入的 payList)
|
|
|
|
|
this.getConfig()
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
this.list = []
|
|
|
|
|
this.payId = ''
|
|
|
|
|
this.oaUrl = ''
|
|
|
|
|
this.payList = []
|
|
|
|
|
this.isShowOaModal = false
|
|
|
|
|
this.table_item = []
|
|
|
|
|
this.paymentsList = []
|
|
|
|
|
@ -523,4 +647,4 @@ import {getToken} from "@/utils/auth";
|
|
|
|
|
::v-deep .el-checkbox-group {
|
|
|
|
|
font-size: inherit;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
</style>
|
|
|
|
|
|