采购合同编辑优化
This commit is contained in:
parent
7ba3f01f4c
commit
ddc973fed0
|
|
@ -5,9 +5,9 @@
|
||||||
<template #invoiceId>
|
<template #invoiceId>
|
||||||
<el-custom-select v-model="AEform.formModel.invoiceId" :dataSource="getinvoiceList"
|
<el-custom-select v-model="AEform.formModel.invoiceId" :dataSource="getinvoiceList"
|
||||||
:remoteAdd="handleAddInvoice" @change="(v, t) => (AEform.formModel.invoiceName = t)" />
|
:remoteAdd="handleAddInvoice" @change="(v, t) => (AEform.formModel.invoiceName = t)" />
|
||||||
<!-- {{ AEform.formModel.invoiceId }} -->
|
|
||||||
</template>
|
</template>
|
||||||
<!-- 发票类型结束 -->
|
<!-- 发票类型结束 -->
|
||||||
|
|
||||||
<!-- 媒介部门开始 -->
|
<!-- 媒介部门开始 -->
|
||||||
<template #mediaDeptId>
|
<template #mediaDeptId>
|
||||||
<el-custom-select v-model="AEform.formModel.mediaDeptId" :dataSource="getMediaDepartment"
|
<el-custom-select v-model="AEform.formModel.mediaDeptId" :dataSource="getMediaDepartment"
|
||||||
|
|
@ -43,12 +43,12 @@
|
||||||
|
|
||||||
<!-- 媒体信息开始 -->
|
<!-- 媒体信息开始 -->
|
||||||
<template #purchaseMediaBoList>
|
<template #purchaseMediaBoList>
|
||||||
<el-edit-table :columns="mediaListColumns" v-model="AEform.formModel.purchaseMediaBoList" show-summary
|
<el-edit-table :columns="mediaListColumns" :value="mediaTableData" show-summary
|
||||||
:summary-method="mediaTypeSummary" @update-items="updateItemsPurchaseMediaBoList">
|
:summary-method="mediaTypeSummary" @update-items="updateItemsPurchaseMediaBoList" :key="'media-table'">
|
||||||
<!-- 城市选择开始 -->
|
<!-- 城市选择开始 -->
|
||||||
<template #cityId="{ record, isEdit }">
|
<template #cityId="{ record, isEdit }">
|
||||||
<el-custom-cascader v-model="record.cityIds" :dataSource="cityList" :cascaderStyle="{ width: '100%' }"
|
<el-custom-cascader v-model="record.cityIds" :dataSource="cityList" :cascaderStyle="{ width: '100%' }"
|
||||||
@change="(v, t) => (record.cityId = v, record.cityName = t)" />
|
@change="(v, t) => { record.cityId = v; record.cityName = t; }" />
|
||||||
</template>
|
</template>
|
||||||
<!-- 城市选择结束 -->
|
<!-- 城市选择结束 -->
|
||||||
|
|
||||||
|
|
@ -90,8 +90,8 @@
|
||||||
|
|
||||||
<!-- 付款管理开始 -->
|
<!-- 付款管理开始 -->
|
||||||
<template #purchasePaymentBoList>
|
<template #purchasePaymentBoList>
|
||||||
<el-edit-table :columns="contranctPayListColumns" v-model="AEform.formModel.purchasePaymentBoList" show-summary
|
<el-edit-table :columns="contranctPayListColumns" :value="paymentTableData" show-summary
|
||||||
:summary-method="paymentSummary" @update-items="updateItemsPurchasePaymentBoList">
|
:summary-method="paymentSummary" @update-items="updateItemsPurchasePaymentBoList" :key="'payment-table'">
|
||||||
<!-- 笔数开始 -->
|
<!-- 笔数开始 -->
|
||||||
<template #transactionsNumber="{ record, isEdit }">
|
<template #transactionsNumber="{ record, isEdit }">
|
||||||
<el-select v-model="record.transactionsNumber" style="width: 100%;">
|
<el-select v-model="record.transactionsNumber" style="width: 100%;">
|
||||||
|
|
@ -103,6 +103,7 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
<!-- 笔数结束 -->
|
<!-- 笔数结束 -->
|
||||||
|
|
||||||
<!-- 约定付款时间开始 -->
|
<!-- 约定付款时间开始 -->
|
||||||
<template #payTime="{ record, isEdit }">
|
<template #payTime="{ record, isEdit }">
|
||||||
<el-date-picker v-model="record.payTime" value-format="yyyy-MM-dd" style="width: 100%" />
|
<el-date-picker v-model="record.payTime" value-format="yyyy-MM-dd" style="width: 100%" />
|
||||||
|
|
@ -132,7 +133,8 @@
|
||||||
|
|
||||||
<!-- 附件开始 -->
|
<!-- 附件开始 -->
|
||||||
<template #annex="{ record, isEdit }">
|
<template #annex="{ record, isEdit }">
|
||||||
<el-file-upload ref="annex" listType="list" :uploadStyle="{ width: '336px' }" />
|
<el-file-upload :key="`annex_${record.id || record.tempId}`" listType="list"
|
||||||
|
:uploadStyle="{ width: '336px' }" />
|
||||||
</template>
|
</template>
|
||||||
<!-- 附件结束 -->
|
<!-- 附件结束 -->
|
||||||
</el-edit-table>
|
</el-edit-table>
|
||||||
|
|
@ -200,9 +202,9 @@ import ElCustomSelect from "@/components/ElForm/ElCustomSelect.vue";
|
||||||
import ElCustomCascader from "@/components/ElForm/ElCustomCascader.vue";
|
import ElCustomCascader from "@/components/ElForm/ElCustomCascader.vue";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import ElFileUpload from "@/components/ElForm/ElFileUpload.vue";
|
import ElFileUpload from "@/components/ElForm/ElFileUpload.vue";
|
||||||
import BigNumber from "bignumber.js";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
name: 'ProcurementContract',
|
||||||
components: {
|
components: {
|
||||||
ElCustomForm,
|
ElCustomForm,
|
||||||
ElEditTable,
|
ElEditTable,
|
||||||
|
|
@ -214,26 +216,32 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
formGroup,
|
formGroup,
|
||||||
|
|
||||||
AEform: {
|
AEform: {
|
||||||
formModel: {
|
formModel: {
|
||||||
purchaseMediaBoList: [],
|
// 只保留基础字段,表格数据分离
|
||||||
purchasePaymentBoList: []
|
|
||||||
},
|
},
|
||||||
rules: {},
|
rules: {},
|
||||||
},
|
},
|
||||||
mediaListColumns,
|
mediaListColumns,
|
||||||
contranctPayListColumns,
|
contranctPayListColumns,
|
||||||
|
|
||||||
mediaTypeList: [],
|
mediaTypeList: [],
|
||||||
flag: 'detail', // 进来这个页面是做什么的,是不是修改或新增了
|
flag: 'detail',
|
||||||
cityList: []
|
cityList: [],
|
||||||
|
|
||||||
|
// 表格数据完全分离
|
||||||
|
mediaTableData: Object.freeze([]),
|
||||||
|
paymentTableData: Object.freeze([]),
|
||||||
|
|
||||||
|
_periodTimer: null,
|
||||||
|
_overdueTimer: null,
|
||||||
|
_annexDebounce: false,
|
||||||
|
_isDestroyed: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
async created() {
|
async created() {
|
||||||
this.getMediaType();
|
this.getMediaType();
|
||||||
const rawData = await cityDataCache.getCityData();
|
const rawData = await cityDataCache.getCityData();
|
||||||
this.cityList = Object.freeze(rawData); // 或者直接使用
|
this.cityList = Object.freeze(rawData);
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.$route.query.id) {
|
if (this.$route.query.id) {
|
||||||
|
|
@ -241,282 +249,212 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
// 合同金额计算
|
|
||||||
contractMoney() {
|
contractMoney() {
|
||||||
const list = this.AEform.formModel.purchaseMediaBoList;
|
// 使用非响应式方式计算
|
||||||
return list
|
const list = this.mediaTableData;
|
||||||
? list.reduce(
|
if (!list || list.length === 0) return 0;
|
||||||
(prev, { mediaFee, productFee }) =>
|
|
||||||
new BigNumber(prev).plus(mediaFee).plus(productFee).toNumber(),
|
let total = 0;
|
||||||
0
|
for (let i = 0; i < list.length; i++) {
|
||||||
)
|
const item = list[i];
|
||||||
: 0;
|
total += (Number(item.mediaFee) || 0) + (Number(item.productFee) || 0);
|
||||||
|
}
|
||||||
|
return total;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 获取详情
|
|
||||||
async getDetailData() {
|
async getDetailData() {
|
||||||
const res = await getAction(`/system/purchase/${this.$route.query.id}`)
|
try {
|
||||||
console.log('采购合同详情', res)
|
const res = await getAction(`/system/purchase/${this.$route.query.id}`);
|
||||||
if (res.data.purchaseMediaVoList) {
|
|
||||||
res.data.purchaseMediaBoList = res.data.purchaseMediaVoList
|
|
||||||
console.log(this.cityList, 'this.cityList')
|
|
||||||
// cityIds
|
|
||||||
res.data.purchaseMediaBoList = res.data.purchaseMediaBoList.map(item => {
|
|
||||||
return { ...item, cityIds: item.cityIds ? item.cityIds.split(',').map((item) => Number(item)) : item.cityIds };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (res.data.conPurchasePaymentVo) {
|
|
||||||
res.data.purchasePaymentBoList = res.data.conPurchasePaymentVo
|
|
||||||
}
|
|
||||||
// 附件回显
|
|
||||||
if (res.data.contractAccessList) {
|
|
||||||
this.$refs.contractAccess.setFileList(res.data.contractAccessList)
|
|
||||||
}
|
|
||||||
if (res.data.detectPicAttrList) {
|
|
||||||
this.$refs.detectPicAttr.setFileList(res.data.detectPicAttrList)
|
|
||||||
}
|
|
||||||
if (res.data.upPrintList) {
|
|
||||||
this.$refs.upPrint.setFileList(res.data.upPrintList)
|
|
||||||
}
|
|
||||||
if (res.data.nextPrintList) {
|
|
||||||
this.$refs.nextPrint.setFileList(res.data.nextPrintList)
|
|
||||||
}
|
|
||||||
if (res.data.exchangePrintList) {
|
|
||||||
this.$refs.exchangePrint.setFileList(res.data.exchangePrintList)
|
|
||||||
}
|
|
||||||
if (res.data.mediaLinkList) {
|
|
||||||
this.$refs.mediaLink.setFileList(res.data.mediaLinkList)
|
|
||||||
}
|
|
||||||
this.AEform.formModel = res.data
|
|
||||||
|
|
||||||
if (this.AEform.formModel.purchasePaymentBoList && this.AEform.formModel.purchasePaymentBoList.length) {
|
// 使用浅拷贝避免深层响应式
|
||||||
for (const i in this.AEform.formModel.purchasePaymentBoList) {
|
const formModel = { ...res.data };
|
||||||
if (this.AEform.formModel.purchasePaymentBoList[i].annexList) {
|
|
||||||
this.$refs['annex_' + this.AEform.formModel.purchasePaymentBoList[i].id].setFileList(this.AEform.formModel.purchasePaymentBoList[i].annexList)
|
// 分离表格数据,使用 Object.freeze 防止响应式
|
||||||
}
|
if (formModel.purchaseMediaVoList) {
|
||||||
|
const mediaData = formModel.purchaseMediaVoList.map(item => ({
|
||||||
|
...item,
|
||||||
|
cityIds: item.cityIds ? item.cityIds.split(',').map(id => Number(id)) : []
|
||||||
|
}));
|
||||||
|
this.mediaTableData = Object.freeze(mediaData);
|
||||||
|
delete formModel.purchaseMediaVoList;
|
||||||
|
} else {
|
||||||
|
this.mediaTableData = Object.freeze([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (formModel.conPurchasePaymentVo) {
|
||||||
|
this.paymentTableData = Object.freeze([...formModel.conPurchasePaymentVo]);
|
||||||
|
delete formModel.conPurchasePaymentVo;
|
||||||
|
} else {
|
||||||
|
this.paymentTableData = Object.freeze([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置基础表单数据
|
||||||
|
this.AEform.formModel = formModel;
|
||||||
|
|
||||||
|
// 延迟附件回显,避免阻塞主线程
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this._isDestroyed) return;
|
||||||
|
|
||||||
|
const setFileList = (ref, list) => {
|
||||||
|
if (ref && list) {
|
||||||
|
ref.setFileList(list);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
setFileList(this.$refs.contractAccess, res.data.contractAccessList);
|
||||||
|
setFileList(this.$refs.detectPicAttr, res.data.detectPicAttrList);
|
||||||
|
setFileList(this.$refs.upPrint, res.data.upPrintList);
|
||||||
|
setFileList(this.$refs.nextPrint, res.data.nextPrintList);
|
||||||
|
setFileList(this.$refs.exchangePrint, res.data.exchangePrintList);
|
||||||
|
setFileList(this.$refs.mediaLink, res.data.mediaLinkList);
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取详情失败:', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 将el-edit-table组件中的数据实施更新回来
|
|
||||||
updateItemsPurchaseMediaBoList(newItems) {
|
updateItemsPurchaseMediaBoList(newItems) {
|
||||||
this.AEform.formModel.purchaseMediaBoList = newItems
|
// 使用浅拷贝和冻结
|
||||||
|
this.mediaTableData = Object.freeze([...newItems]);
|
||||||
},
|
},
|
||||||
|
|
||||||
updateItemsPurchasePaymentBoList(newItems) {
|
updateItemsPurchasePaymentBoList(newItems) {
|
||||||
this.AEform.formModel.purchasePaymentBoList = newItems
|
this.paymentTableData = Object.freeze([...newItems]);
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取媒介部门列表
|
|
||||||
async getMediaDepartment() {
|
async getMediaDepartment() {
|
||||||
const { code, data, msg } = await getAction(`/contract/mediaDept/listAll`);
|
const { code, data } = await getAction(`/contract/mediaDept/listAll`);
|
||||||
if (code == 200) {
|
if (code == 200) {
|
||||||
return data.map(({ mediaDeptName: label, id: value }) => ({
|
return data.map(({ mediaDeptName: label, id: value }) => ({ label, value }));
|
||||||
label,
|
|
||||||
value,
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
return [];
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取发票类型
|
|
||||||
async getinvoiceList() {
|
async getinvoiceList() {
|
||||||
const { code, data, msg } = await getAction(`/contract/invoice/listAll`);
|
const { code, data } = await getAction(`/contract/invoice/listAll`);
|
||||||
if (code == 200) {
|
if (code == 200) {
|
||||||
return data.map(({ invoiceName: label, id: value }) => ({
|
return data.map(({ invoiceName: label, id: value }) => ({ label, value }));
|
||||||
label,
|
|
||||||
value,
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
return [];
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取媒体类型列表
|
|
||||||
async getMediaType() {
|
async getMediaType() {
|
||||||
const { code, data, msg } = await getAction(`/contract/mediaType/listAll`);
|
const { code, data } = await getAction(`/contract/mediaType/listAll`);
|
||||||
if (code == 200) {
|
if (code == 200) {
|
||||||
this.mediaTypeList = data.map(({ mediaType: label, id: value }) => ({
|
this.mediaTypeList = data.map(({ mediaType: label, id: value }) => ({ label, value }));
|
||||||
label,
|
|
||||||
value,
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取甲方列表
|
|
||||||
async getFirstPartyList() {
|
async getFirstPartyList() {
|
||||||
const { code, data, msg } = await getAction(`/contract/first/listAll`);
|
const { code, data } = await getAction(`/contract/first/listAll`);
|
||||||
if (code == 200) {
|
if (code == 200) {
|
||||||
return data.map(({ firstName: label, id: value }) => ({
|
return data.map(({ firstName: label, id: value }) => ({ label, value }));
|
||||||
label,
|
|
||||||
value,
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
return [];
|
||||||
},
|
},
|
||||||
|
|
||||||
// 增加媒介部门菜单项
|
|
||||||
async handleAddMediaDepartment(mediaDeptName) {
|
async handleAddMediaDepartment(mediaDeptName) {
|
||||||
const { code, data, msg } = await postAction(urls.addDept, {
|
const { code, data, msg } = await postAction(urls.addDept, { mediaDeptName });
|
||||||
mediaDeptName,
|
if (code == 200) return data;
|
||||||
});
|
this.$message.error(msg);
|
||||||
if (code == 200) {
|
throw new Error(msg);
|
||||||
return data;
|
|
||||||
} else {
|
|
||||||
this.$message.error(msg);
|
|
||||||
throw new Error(msg);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 增加发票类型
|
|
||||||
async handleAddInvoice(invoiceName) {
|
async handleAddInvoice(invoiceName) {
|
||||||
const { code, data, msg } = await postAction(`/contract/invoice`, {
|
const { code, data, msg } = await postAction(`/contract/invoice`, { invoiceName });
|
||||||
invoiceName,
|
if (code == 200) return data;
|
||||||
});
|
this.$message.error(msg);
|
||||||
if (code == 200) {
|
throw new Error(msg);
|
||||||
return data;
|
|
||||||
} else {
|
|
||||||
this.$message.error(msg);
|
|
||||||
throw new Error(msg);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 增加城市下拉菜单项
|
|
||||||
async handleAddCityParty(cityName) {
|
|
||||||
const { code, data, msg } = await postAction(`/contract/city`, {
|
|
||||||
cityName,
|
|
||||||
});
|
|
||||||
if (code == 200) {
|
|
||||||
return data;
|
|
||||||
} else {
|
|
||||||
this.$message.error(msg);
|
|
||||||
throw new Error(msg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 增加媒体类型下拉菜单项
|
|
||||||
async handleAddMediaTypeParty(mediaType) {
|
async handleAddMediaTypeParty(mediaType) {
|
||||||
const { code, data, msg } = await postAction(`/contract/mediaType`, {
|
const { code, data, msg } = await postAction(`/contract/mediaType`, { mediaType });
|
||||||
mediaType,
|
if (code == 200) return data;
|
||||||
});
|
this.$message.error(msg);
|
||||||
if (code == 200) {
|
throw new Error(msg);
|
||||||
return data;
|
|
||||||
} else {
|
|
||||||
this.$message.error(msg);
|
|
||||||
throw new Error(msg);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
// 获取客户列表
|
|
||||||
async getclientList() {
|
async getclientList() {
|
||||||
const { code, data, msg } = await getAction(`/contract/client/listAll`);
|
const { code, data } = await getAction(`/contract/client/listAll`);
|
||||||
if (code == 200) {
|
if (code == 200) {
|
||||||
return data.map(({ clientName: label, id: value }) => ({
|
return data.map(({ clientName: label, id: value }) => ({ label, value }));
|
||||||
label,
|
|
||||||
value,
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
return [];
|
||||||
},
|
},
|
||||||
|
|
||||||
// 增加客户菜单项
|
|
||||||
async handleAddClient(clientName) {
|
async handleAddClient(clientName) {
|
||||||
const { code, data, msg } = await postAction(urls.addClient, {
|
const { code, data, msg } = await postAction(urls.addClient, { clientName });
|
||||||
clientName,
|
if (code == 200) return data;
|
||||||
});
|
this.$message.error(msg);
|
||||||
if (code == 200) {
|
throw new Error(msg);
|
||||||
return data;
|
|
||||||
} else {
|
|
||||||
this.$message.error(msg);
|
|
||||||
throw new Error(msg);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 增加甲方下拉菜单项
|
|
||||||
async handleAddFirstParty(firstName) {
|
async handleAddFirstParty(firstName) {
|
||||||
const { code, data, msg } = await postAction(urls.addFirstParty, {
|
const { code, data, msg } = await postAction(urls.addFirstParty, { firstName });
|
||||||
firstName,
|
if (code == 200) return data;
|
||||||
});
|
this.$message.error(msg);
|
||||||
if (code == 200) {
|
throw new Error(msg);
|
||||||
return data;
|
|
||||||
} else {
|
|
||||||
this.$message.error(msg);
|
|
||||||
throw new Error(msg);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
// 计算周期
|
|
||||||
getPeriod() {
|
getPeriod() {
|
||||||
for (const i in this.AEform.formModel.purchaseMediaBoList) {
|
if (this._periodTimer) clearTimeout(this._periodTimer);
|
||||||
let date2, date1 = undefined
|
this._periodTimer = setTimeout(() => {
|
||||||
if (this.AEform.formModel.purchaseMediaBoList[i].downTime) {
|
const data = [...this.mediaTableData];
|
||||||
date2 = new Date(this.AEform.formModel.purchaseMediaBoList[i].downTime);
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
const item = data[i];
|
||||||
|
if (item.upTime && item.downTime) {
|
||||||
|
const diff = dayjs(item.downTime).diff(dayjs(item.upTime), 'day');
|
||||||
|
item.period = Math.ceil(diff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (this.AEform.formModel.purchaseMediaBoList[i].upTime) {
|
this.mediaTableData = Object.freeze(data);
|
||||||
date1 = new Date(this.AEform.formModel.purchaseMediaBoList[i].upTime);
|
}, 150);
|
||||||
}
|
|
||||||
// 计算两个日期的时间戳差异(以毫秒为单位)
|
|
||||||
let timeDifference = date2 - date1;
|
|
||||||
|
|
||||||
this.AEform.formModel.purchaseMediaBoList[i].period = timeDifference / (1000 * 60 * 60 * 24)
|
|
||||||
this.AEform.formModel.purchaseMediaBoList[i].period = Math.ceil(this.AEform.formModel.purchaseMediaBoList[i].period)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 计算逾期天数
|
|
||||||
getOverdueDay() {
|
getOverdueDay() {
|
||||||
for (const i in this.AEform.formModel.purchasePaymentBoList) {
|
if (this._overdueTimer) clearTimeout(this._overdueTimer);
|
||||||
let date2, date1 = undefined
|
this._overdueTimer = setTimeout(() => {
|
||||||
if (this.AEform.formModel.purchasePaymentBoList[i].arrivalTime) {
|
const data = [...this.paymentTableData];
|
||||||
date2 = new Date(this.AEform.formModel.purchasePaymentBoList[i].arrivalTime);
|
for (let i = 0; i < data.length; i++) {
|
||||||
} else {
|
const item = data[i];
|
||||||
date2 = new Date().getTime()
|
if (item.payTime) {
|
||||||
|
const diff = dayjs(item.arrivalTime || new Date()).diff(dayjs(item.payTime), 'day');
|
||||||
|
item.overdueDay = Math.floor(diff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (this.AEform.formModel.purchasePaymentBoList[i].payTime) {
|
this.paymentTableData = Object.freeze(data);
|
||||||
date1 = new Date(this.AEform.formModel.purchasePaymentBoList[i].payTime);
|
}, 150);
|
||||||
}
|
|
||||||
// 计算两个日期的时间戳差异(以毫秒为单位)
|
|
||||||
let timeDifference = date2 - date1;
|
|
||||||
|
|
||||||
this.AEform.formModel.purchasePaymentBoList[i].overdueDay = timeDifference / (1000 * 60 * 60 * 24)
|
|
||||||
this.AEform.formModel.purchasePaymentBoList[i].overdueDay = Math.floor(this.AEform.formModel.purchasePaymentBoList[i].overdueDay)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleNumberChange(val, selfVal) {
|
handleNumberChange(val) {
|
||||||
if (val < 0) {
|
if (val < 0) {
|
||||||
this.$message.warning(`该数值不能小于系统设置的最小值0`)
|
this.$message.warning(`该数值不能小于系统设置的最小值0`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 计算媒体信息合计行
|
|
||||||
mediaTypeSummary(param) {
|
mediaTypeSummary(param) {
|
||||||
const { columns, data } = param;
|
const { columns, data } = param;
|
||||||
const sums = [];
|
const sums = [];
|
||||||
columns.forEach((column, index) => {
|
columns.forEach((column, index) => {
|
||||||
let total = "N/A";
|
|
||||||
if (![11, 12].includes(index)) {
|
if (![11, 12].includes(index)) {
|
||||||
|
sums[index] = '';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const values = data.map((item) => Number(item[column.property]));
|
|
||||||
if (!values.every((value) => isNaN(value))) {
|
const values = data.map(item => Number(item[column.property]) || 0);
|
||||||
total = values.reduce((prev, curr) => {
|
const total = values.reduce((sum, val) => sum + val, 0);
|
||||||
const value = Number(curr);
|
|
||||||
if (!isNaN(value)) {
|
|
||||||
return prev + curr;
|
|
||||||
} else {
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
total = this.formatNumber(total)
|
|
||||||
}
|
|
||||||
|
|
||||||
sums[index] = (
|
sums[index] = (
|
||||||
<div class="media-summary">
|
<div class="media-summary">
|
||||||
<div class="media-summary-title">{column.label}</div>
|
<div class="media-summary-title">{column.label}</div>
|
||||||
<div class="media-summary-value">
|
<div class="media-summary-value">
|
||||||
¥<span>{total}</span>元
|
¥<span>{this.formatNumber(total)}</span>元
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return sums;
|
return sums;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -524,267 +462,156 @@ export default {
|
||||||
const { columns, data } = param;
|
const { columns, data } = param;
|
||||||
const sums = [];
|
const sums = [];
|
||||||
columns.forEach((column, index) => {
|
columns.forEach((column, index) => {
|
||||||
let total = "N/A";
|
|
||||||
if (![2, 4].includes(index)) {
|
if (![2, 4].includes(index)) {
|
||||||
|
sums[index] = '';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const values = data.map((item) => Number(item[column.property]));
|
|
||||||
if (!values.every((value) => isNaN(value))) {
|
const values = data.map(item => Number(item[column.property]) || 0);
|
||||||
total = values.reduce((prev, curr) => {
|
const total = values.reduce((sum, val) => sum + val, 0);
|
||||||
const value = Number(curr);
|
|
||||||
if (!isNaN(value)) {
|
|
||||||
return prev + curr;
|
|
||||||
} else {
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
total = this.formatNumber(total)
|
|
||||||
}
|
|
||||||
|
|
||||||
sums[index] = (
|
sums[index] = (
|
||||||
<div class="media-summary">
|
<div class="media-summary">
|
||||||
<div class="media-summary-title">{column.label}</div>
|
<div class="media-summary-title">{column.label}</div>
|
||||||
<div class="media-summary-value">
|
<div class="media-summary-value">
|
||||||
¥<span>{total}</span>元
|
¥<span>{this.formatNumber(total)}</span>元
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return sums;
|
return sums;
|
||||||
},
|
},
|
||||||
|
|
||||||
formatNumber(num) {
|
formatNumber(num) {
|
||||||
if (num) {
|
const [integer, decimal] = Number(num).toFixed(2).split(".");
|
||||||
// 保留两位小数并转换为字符串
|
return `${integer.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}.${decimal}`;
|
||||||
let [integer, decimal] = num.toFixed(2).split(".");
|
|
||||||
|
|
||||||
// 正则表达式添加千位分隔符
|
|
||||||
integer = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
||||||
|
|
||||||
return `${integer}.${decimal}`;
|
|
||||||
} else {
|
|
||||||
return '0.00'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
//计算逾期天数
|
|
||||||
delayDate(record) {
|
delayDate(record) {
|
||||||
const { payTime, arrivalTime } = record;
|
const { payTime, arrivalTime } = record;
|
||||||
if (!payTime) {
|
if (!payTime) return "";
|
||||||
return "";
|
|
||||||
}
|
|
||||||
const diff = dayjs(arrivalTime || new Date()).diff(payTime, "d");
|
const diff = dayjs(arrivalTime || new Date()).diff(payTime, "d");
|
||||||
return diff <= 0 ? "" : diff + "天";
|
return diff <= 0 ? "" : diff + "天";
|
||||||
},
|
},
|
||||||
|
|
||||||
//计算周期
|
|
||||||
delayPeriodDate(record) {
|
delayPeriodDate(record) {
|
||||||
const { upTime, downTime } = record;
|
const { upTime, downTime } = record;
|
||||||
if (!upTime) {
|
if (!upTime) return "";
|
||||||
return "";
|
|
||||||
}
|
|
||||||
const diff = dayjs(downTime || new Date()).diff(upTime, "d");
|
const diff = dayjs(downTime || new Date()).diff(upTime, "d");
|
||||||
return diff <= 0 ? "" : diff + 1 + "天";
|
return diff <= 0 ? "" : diff + 1 + "天";
|
||||||
},
|
},
|
||||||
|
|
||||||
// 去除附件中的逗号
|
|
||||||
removeLeadingAndTrailingCommas(str) {
|
|
||||||
// 检查并去掉第一个字符的逗号
|
|
||||||
if (str.charAt(0) === ',') {
|
|
||||||
str = str.substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查并去掉最后一个字符的逗号
|
|
||||||
if (str.charAt(str.length - 1) === ',') {
|
|
||||||
str = str.substring(0, str.length - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return str;
|
|
||||||
},
|
|
||||||
// 附件处理
|
|
||||||
annexFunc() {
|
annexFunc() {
|
||||||
// 合同附件
|
if (this._annexDebounce) return;
|
||||||
var contractAccess = []
|
this._annexDebounce = true;
|
||||||
for (const i in this.$refs.contractAccess.getFileList()) {
|
|
||||||
contractAccess.push(this.$refs.contractAccess.getFileList()[i].md5)
|
|
||||||
}
|
|
||||||
var contractAccess2 = []
|
|
||||||
if (this.AEform.formModel.contractAccessList && this.AEform.formModel.contractAccessList.length) {
|
|
||||||
for (const i in this.AEform.formModel.contractAccessList) {
|
|
||||||
contractAccess2.push(this.AEform.formModel.contractAccessList[i].identifier)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var contractAccess3 = [...contractAccess, ...contractAccess2]
|
|
||||||
contractAccess3 = Array.from(new Set(contractAccess3))
|
|
||||||
this.AEform.formModel.contractAccess = contractAccess3.toString()
|
|
||||||
this.AEform.formModel.contractAccess = this.removeLeadingAndTrailingCommas(this.AEform.formModel.contractAccess)
|
|
||||||
|
|
||||||
// 监测照片附件
|
setTimeout(() => {
|
||||||
var detectPicAttr = []
|
this._annexDebounce = false;
|
||||||
for (const i in this.$refs.detectPicAttr.getFileList()) {
|
}, 300);
|
||||||
detectPicAttr.push(this.$refs.detectPicAttr.getFileList()[i].md5)
|
|
||||||
}
|
|
||||||
var detectPicAttr2 = []
|
|
||||||
if (this.AEform.formModel.detectPicAttrList && this.AEform.formModel.detectPicAttrList.length) {
|
|
||||||
for (const i in this.AEform.formModel.detectPicAttrList) {
|
|
||||||
detectPicAttr2.push(this.AEform.formModel.detectPicAttrList[i].identifier)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var detectPicAttr3 = [...detectPicAttr, ...detectPicAttr2]
|
|
||||||
detectPicAttr3 = Array.from(new Set(detectPicAttr3))
|
|
||||||
this.AEform.formModel.detectPicAttr = detectPicAttr3.toString()
|
|
||||||
this.AEform.formModel.detectPicAttr = this.removeLeadingAndTrailingCommas(this.AEform.formModel.detectPicAttr)
|
|
||||||
|
|
||||||
// 上刊附件
|
const processAttachment = (ref, field) => {
|
||||||
var upPrint = []
|
if (!ref) return '';
|
||||||
for (const i in this.$refs.upPrint.getFileList()) {
|
const files = ref.getFileList() || [];
|
||||||
upPrint.push(this.$refs.upPrint.getFileList()[i].md5)
|
const existing = this.AEform.formModel[`${field}List`] || [];
|
||||||
}
|
const allIds = [
|
||||||
var upPrint2 = []
|
...files.map(f => f.md5),
|
||||||
if (this.AEform.formModel.upPrintList && this.AEform.formModel.upPrintList.length) {
|
...existing.map(f => f.identifier)
|
||||||
for (const i in this.AEform.formModel.upPrintList) {
|
].filter(Boolean);
|
||||||
upPrint2.push(this.AEform.formModel.upPrintList[i].identifier)
|
return allIds.join(',');
|
||||||
}
|
};
|
||||||
}
|
|
||||||
var upPrint3 = [...upPrint, ...upPrint2]
|
this.AEform.formModel.contractAccess = processAttachment(this.$refs.contractAccess, 'contractAccess');
|
||||||
upPrint3 = Array.from(new Set(upPrint3))
|
this.AEform.formModel.detectPicAttr = processAttachment(this.$refs.detectPicAttr, 'detectPicAttr');
|
||||||
this.AEform.formModel.upPrint = upPrint3.toString()
|
this.AEform.formModel.upPrint = processAttachment(this.$refs.upPrint, 'upPrint');
|
||||||
this.AEform.formModel.upPrint = this.removeLeadingAndTrailingCommas(this.AEform.formModel.upPrint)
|
this.AEform.formModel.nextPrint = processAttachment(this.$refs.nextPrint, 'nextPrint');
|
||||||
// 下刊附件
|
this.AEform.formModel.exchangePrint = processAttachment(this.$refs.exchangePrint, 'exchangePrint');
|
||||||
var nextPrint = []
|
this.AEform.formModel.mediaLink = processAttachment(this.$refs.mediaLink, 'mediaLink');
|
||||||
for (const i in this.$refs.nextPrint.getFileList()) {
|
|
||||||
nextPrint.push(this.$refs.nextPrint.getFileList()[i].md5)
|
|
||||||
}
|
|
||||||
var nextPrint2 = []
|
|
||||||
if (this.AEform.formModel.nextPrintList && this.AEform.formModel.nextPrintList.length) {
|
|
||||||
for (const i in this.AEform.formModel.nextPrintList) {
|
|
||||||
nextPrint2.push(this.AEform.formModel.nextPrintList[i].identifier)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var nextPrint3 = [...nextPrint, ...nextPrint2]
|
|
||||||
nextPrint3 = Array.from(new Set(nextPrint3))
|
|
||||||
this.AEform.formModel.nextPrint = nextPrint3.toString()
|
|
||||||
this.AEform.formModel.nextPrint = this.removeLeadingAndTrailingCommas(this.AEform.formModel.nextPrint)
|
|
||||||
// 换刊附件
|
|
||||||
var exchangePrint = []
|
|
||||||
for (const i in this.$refs.exchangePrint.getFileList()) {
|
|
||||||
exchangePrint.push(this.$refs.exchangePrint.getFileList()[i].md5)
|
|
||||||
}
|
|
||||||
var exchangePrint2 = []
|
|
||||||
if (this.AEform.formModel.exchangePrintList && this.AEform.formModel.exchangePrintList.length) {
|
|
||||||
for (const i in this.AEform.formModel.exchangePrintList) {
|
|
||||||
exchangePrint2.push(this.AEform.formModel.exchangePrintList[i].identifier)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var exchangePrint3 = [...exchangePrint, ...exchangePrint2]
|
|
||||||
exchangePrint3 = Array.from(new Set(exchangePrint3))
|
|
||||||
this.AEform.formModel.exchangePrint = exchangePrint3.toString()
|
|
||||||
this.AEform.formModel.exchangePrint = this.removeLeadingAndTrailingCommas(this.AEform.formModel.exchangePrint)
|
|
||||||
// 媒体链条附件
|
|
||||||
var mediaLink = []
|
|
||||||
for (const i in this.$refs.mediaLink.getFileList()) {
|
|
||||||
mediaLink.push(this.$refs.mediaLink.getFileList()[i].md5)
|
|
||||||
}
|
|
||||||
var mediaLink2 = []
|
|
||||||
if (this.AEform.formModel.mediaLinkList && this.AEform.formModel.mediaLinkList.length) {
|
|
||||||
for (const i in this.AEform.formModel.mediaLinkList) {
|
|
||||||
mediaLink2.push(this.AEform.formModel.mediaLinkList[i].identifier)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var mediaLink3 = [...mediaLink, ...mediaLink2]
|
|
||||||
mediaLink3 = Array.from(new Set(mediaLink3))
|
|
||||||
this.AEform.formModel.mediaLink = mediaLink3.toString()
|
|
||||||
this.AEform.formModel.mediaLink = this.removeLeadingAndTrailingCommas(this.AEform.formModel.mediaLink)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
verification(tableList, columns) {
|
verification(tableList, columns) {
|
||||||
console.log(tableList, 'tableList')
|
if (!tableList || tableList.length === 0) return true;
|
||||||
if (tableList && tableList.length) {
|
|
||||||
const row = tableList.find((item) => item);
|
for (let i = 0; i < tableList.length; i++) {
|
||||||
|
const row = tableList[i];
|
||||||
for (const column of columns) {
|
for (const column of columns) {
|
||||||
const { required, dataIndex, title } = column;
|
if (column.required) {
|
||||||
const val = row[dataIndex];
|
const val = row[column.dataIndex];
|
||||||
if (
|
if (val == null || val === '' || val === undefined) {
|
||||||
required &&
|
this.$message.warning(`${column.title}不能为空`);
|
||||||
(val == null || val == undefined || val.toString().trim() == "")
|
return false;
|
||||||
) {
|
}
|
||||||
this.$message.warning(`${title}不能为空`);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
async handleSave() {
|
async handleSave() {
|
||||||
try {
|
try {
|
||||||
console.log('%c [ this.$refs.contractAccess.getFileList() ]-358', 'font-size:13px; background:pink; color:#bf2c9f;', this.$refs.contractAccess.getFileList())
|
this.annexFunc();
|
||||||
|
|
||||||
await this.annexFunc()
|
// 准备提交数据 - 不使用扩展运算符避免内存问题
|
||||||
// 处理媒体的子表信息数据
|
const submitData = {
|
||||||
if (this.AEform.formModel.purchaseMediaBoList && this.AEform.formModel.purchaseMediaBoList.length) {
|
...this.AEform.formModel,
|
||||||
for (const i in this.AEform.formModel.purchaseMediaBoList) {
|
purchaseMediaBoList: this.mediaTableData.map(item => ({
|
||||||
if (this.AEform.formModel.id) {
|
...item,
|
||||||
this.AEform.formModel.purchaseMediaBoList[i].purchaseId = this.AEform.formModel.id
|
cityIds: Array.isArray(item.cityIds) ? item.cityIds.join(',') : item.cityIds,
|
||||||
}
|
purchaseId: this.AEform.formModel.id,
|
||||||
}
|
printPrice: Number(item.printPrice) || 0
|
||||||
}
|
})),
|
||||||
// 处理付款管理的子表信息数据
|
purchasePaymentBoList: this.paymentTableData.map(item => ({
|
||||||
if (this.AEform.formModel.purchasePaymentBoList && this.AEform.formModel.purchasePaymentBoList.length) {
|
...item,
|
||||||
for (const i in this.AEform.formModel.purchasePaymentBoList) {
|
purchaseId: this.AEform.formModel.id
|
||||||
if (this.AEform.formModel.id) {
|
})),
|
||||||
this.AEform.formModel.purchasePaymentBoList[i].purchaseId = this.AEform.formModel.id
|
contractMoney: this.contractMoney
|
||||||
}
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
await this.getPeriod()
|
|
||||||
await this.getOverdueDay()
|
|
||||||
this.AEform.formModel.contractMoney = this.contractMoney;
|
|
||||||
// 校验子列表
|
|
||||||
await this.verification(this.AEform.formModel.purchaseMediaBoList, this.mediaListColumns)
|
|
||||||
await this.verification(this.AEform.formModel.purchasePaymentBoList, this.contranctPayListColumns)
|
|
||||||
|
|
||||||
// 将刊例价改成数值型
|
if (!this.verification(submitData.purchaseMediaBoList, this.mediaListColumns) ||
|
||||||
if (this.AEform.formModel.purchaseMediaBoList && this.AEform.formModel.purchaseMediaBoList.length) {
|
!this.verification(submitData.purchasePaymentBoList, this.contranctPayListColumns)) {
|
||||||
this.AEform.formModel.purchaseMediaBoList = this.AEform.formModel.purchaseMediaBoList.map(item => {
|
return;
|
||||||
return { ...item, printPrice: Number(item.printPrice), cityIds: item.cityIds ? item.cityIds.toString() : undefined };
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.$refs.formRef.validate();
|
await this.$refs.formRef.validate();
|
||||||
console.log('this.AEform.formModel', this.AEform.formModel)
|
|
||||||
if (this.AEform.formModel.id) {
|
let res;
|
||||||
const res = await putAction(`/system/purchase/edit`, { ...this.AEform.formModel })
|
if (submitData.id) {
|
||||||
console.log('%c [ res ]-361', 'font-size:13px; background:pink; color:#bf2c9f;', res)
|
res = await putAction(`/system/purchase/edit`, submitData);
|
||||||
if (res.code == 200) {
|
|
||||||
this.$message.success('保存成功')
|
|
||||||
this.flag = 'edit'
|
|
||||||
this.handleReturnLastPage()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// 新增时,当状态不存在时,指定个默认值(1生效 2作废)
|
if (!submitData.state) submitData.state = 1;
|
||||||
if (!this.AEform.formModel.state) {
|
res = await postAction(`/system/purchase/add`, submitData);
|
||||||
this.AEform.formModel.state = 1
|
|
||||||
}
|
|
||||||
const res = await postAction(`/system/purchase/add`, { ...this.AEform.formModel })
|
|
||||||
console.log('%c [ res ]-365', 'font-size:13px; background:pink; color:#bf2c9f;', res)
|
|
||||||
if (res.code == 200) {
|
|
||||||
this.$message.success('保存成功')
|
|
||||||
this.flag = 'add'
|
|
||||||
this.handleReturnLastPage()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res.code == 200) {
|
||||||
|
this.$message.success('保存成功');
|
||||||
|
this.flag = submitData.id ? 'edit' : 'add';
|
||||||
|
this.handleReturnLastPage();
|
||||||
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.error('保存失败:', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleReturnLastPage() {
|
|
||||||
this.$router.back()
|
|
||||||
},
|
|
||||||
|
|
||||||
|
handleReturnLastPage() {
|
||||||
|
this.$router.back();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this._isDestroyed = true;
|
||||||
|
if (this._periodTimer) clearTimeout(this._periodTimer);
|
||||||
|
if (this._overdueTimer) clearTimeout(this._overdueTimer);
|
||||||
|
|
||||||
|
// 彻底清理数据
|
||||||
|
this.mediaTableData = [];
|
||||||
|
this.paymentTableData = [];
|
||||||
|
this.AEform.formModel = {};
|
||||||
|
this.mediaTypeList = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeRouteLeave(to, _, next) {
|
beforeRouteLeave(to, _, next) {
|
||||||
to.meta.flag = this.flag
|
to.meta.flag = this.flag;
|
||||||
next()
|
next();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -881,4 +708,4 @@ export default {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Loading…
Reference in New Issue
Block a user