4b01316f64
结算单附件增加项目预付核销;常用线路超管默认查全部组织并按筛选归属新增;付款申请提交后关页并刷新列表;平台公司选项 ID 按字符串绑定。 Co-authored-by: Cursor <cursoragent@cursor.com>
301 lines
9.6 KiB
Vue
301 lines
9.6 KiB
Vue
<template>
|
|
<section-card title="项目预付核销">
|
|
<template v-if="editable" #extra>
|
|
<el-button type="primary" :disabled="!contractId" @click="openSelectDialog">选择</el-button>
|
|
</template>
|
|
<el-table :data="rows" border>
|
|
<el-table-column type="index" label="序号" width="64" align="center" />
|
|
<el-table-column
|
|
prop="paymentNo"
|
|
label="预付单号"
|
|
min-width="160"
|
|
align="center"
|
|
show-overflow-tooltip
|
|
/>
|
|
<el-table-column label="项目预付金额" min-width="140" align="center">
|
|
<template #default="{ row }">{{ formatMoney(row.projectAdvanceAmount) }}</template>
|
|
</el-table-column>
|
|
<el-table-column label="可核销金额" min-width="140" align="center">
|
|
<template #default="{ row }">{{ formatMoney(row.availableWriteOffAmount) }}</template>
|
|
</el-table-column>
|
|
<el-table-column label="本次核销金额" min-width="160" align="center">
|
|
<template #default="{ row }">
|
|
<el-input-number
|
|
v-if="editable"
|
|
v-model="row.writeOffAmount"
|
|
:min="0"
|
|
:precision="2"
|
|
:controls="false"
|
|
class="project-advance-write-off__amount"
|
|
@change="handleAmountChange(row)"
|
|
/>
|
|
<span v-else>{{ formatMoney(row.writeOffAmount) }}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="kingdeeBillNo"
|
|
label="金蝶预付单号"
|
|
min-width="160"
|
|
align="center"
|
|
show-overflow-tooltip
|
|
>
|
|
<template #default="{ row }">{{ row.kingdeeBillNo || '-' }}</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="createUserName"
|
|
label="创建人"
|
|
min-width="120"
|
|
align="center"
|
|
show-overflow-tooltip
|
|
>
|
|
<template #default="{ row }">{{ row.createUserName || '-' }}</template>
|
|
</el-table-column>
|
|
<el-table-column prop="createTime" label="创建时间" min-width="170" align="center">
|
|
<template #default="{ row }">{{ formatDateTime(row.createTime || row.paymentCreateTime) }}</template>
|
|
</el-table-column>
|
|
<el-table-column v-if="editable" label="操作" width="90" align="center" fixed="right">
|
|
<template #default="{ $index }">
|
|
<el-link type="danger" @click="removeRow($index)">删除</el-link>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
|
|
<el-dialog
|
|
v-model="dialog.visible"
|
|
title="选择项目预付单"
|
|
width="960px"
|
|
append-to-body
|
|
destroy-on-close
|
|
class="dialog-form-title"
|
|
@closed="handleDialogClosed"
|
|
>
|
|
<el-table
|
|
v-loading="dialog.loading"
|
|
:data="dialog.rows"
|
|
border
|
|
@selection-change="handleSelectionChange"
|
|
>
|
|
<el-table-column type="selection" width="55" align="center" :selectable="rowSelectable" />
|
|
<el-table-column type="index" label="序号" width="64" align="center" />
|
|
<el-table-column
|
|
prop="paymentNo"
|
|
label="预付单号"
|
|
min-width="160"
|
|
align="center"
|
|
show-overflow-tooltip
|
|
/>
|
|
<el-table-column label="项目预付金额" min-width="140" align="center">
|
|
<template #default="{ row }">{{ formatMoney(row.projectAdvanceAmount) }}</template>
|
|
</el-table-column>
|
|
<el-table-column label="可核销金额" min-width="140" align="center">
|
|
<template #default="{ row }">{{ formatMoney(row.availableWriteOffAmount) }}</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="kingdeeBillNo"
|
|
label="金蝶预付单号"
|
|
min-width="160"
|
|
align="center"
|
|
show-overflow-tooltip
|
|
>
|
|
<template #default="{ row }">{{ row.kingdeeBillNo || '-' }}</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="createUserName"
|
|
label="创建人"
|
|
min-width="120"
|
|
align="center"
|
|
show-overflow-tooltip
|
|
>
|
|
<template #default="{ row }">{{ row.createUserName || '-' }}</template>
|
|
</el-table-column>
|
|
<el-table-column prop="createTime" label="创建时间" min-width="170" align="center">
|
|
<template #default="{ row }">{{ formatDateTime(row.createTime) }}</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
<template #footer>
|
|
<el-button @click="dialog.visible = false">取消</el-button>
|
|
<el-button type="primary" :disabled="!dialog.selection.length" @click="confirmSelect">
|
|
确定
|
|
</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
</section-card>
|
|
</template>
|
|
|
|
<script>
|
|
import { getProjectAdvanceWriteOffOptions } from '@/api/payment/paymentApplication';
|
|
|
|
export default {
|
|
name: 'ProjectAdvanceWriteOff',
|
|
props: {
|
|
modelValue: {
|
|
type: Array,
|
|
default: () => [],
|
|
},
|
|
editable: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
contractId: {
|
|
type: [String, Number],
|
|
default: '',
|
|
},
|
|
settlementAmount: {
|
|
type: [String, Number],
|
|
default: 0,
|
|
},
|
|
settlementType: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
settlementId: {
|
|
type: [String, Number],
|
|
default: '',
|
|
},
|
|
},
|
|
emits: ['update:modelValue'],
|
|
data() {
|
|
return {
|
|
dialog: {
|
|
visible: false,
|
|
loading: false,
|
|
rows: [],
|
|
selection: [],
|
|
},
|
|
};
|
|
},
|
|
computed: {
|
|
rows: {
|
|
get() {
|
|
return Array.isArray(this.modelValue) ? this.modelValue : [];
|
|
},
|
|
set(value) {
|
|
this.$emit('update:modelValue', value);
|
|
},
|
|
},
|
|
},
|
|
methods: {
|
|
formatMoney(value) {
|
|
const amount = Number(value);
|
|
return Number.isFinite(amount) ? amount.toFixed(2) : '0.00';
|
|
},
|
|
formatDateTime(value) {
|
|
if (!value) return '-';
|
|
return this.$dayjs(value).format('YYYY-MM-DD HH:mm:ss');
|
|
},
|
|
money(value) {
|
|
const amount = Number(value);
|
|
return Number.isFinite(amount) ? Number(amount.toFixed(2)) : 0;
|
|
},
|
|
openSelectDialog() {
|
|
if (!this.contractId) {
|
|
this.$message.warning('请先选择合同');
|
|
return;
|
|
}
|
|
this.dialog.visible = true;
|
|
this.loadOptions();
|
|
},
|
|
async loadOptions() {
|
|
this.dialog.loading = true;
|
|
try {
|
|
const res = await getProjectAdvanceWriteOffOptions({
|
|
contractId: this.contractId,
|
|
excludeSettlementType: this.settlementType,
|
|
excludeSettlementId: this.settlementId || undefined,
|
|
});
|
|
this.dialog.rows = res?.data?.data || [];
|
|
} finally {
|
|
this.dialog.loading = false;
|
|
}
|
|
},
|
|
rowSelectable(row) {
|
|
const selectedIds = new Set(this.rows.map(item => String(item.paymentApplicationId)));
|
|
return !selectedIds.has(String(row.paymentApplicationId));
|
|
},
|
|
handleSelectionChange(list) {
|
|
this.dialog.selection = list || [];
|
|
},
|
|
confirmSelect() {
|
|
const nextRows = [...this.rows];
|
|
const existed = new Set(nextRows.map(item => String(item.paymentApplicationId)));
|
|
this.dialog.selection.forEach(item => {
|
|
const id = String(item.paymentApplicationId);
|
|
if (existed.has(id)) return;
|
|
nextRows.push({
|
|
paymentApplicationId: item.paymentApplicationId,
|
|
paymentNo: item.paymentNo,
|
|
projectAdvanceAmount: this.money(item.projectAdvanceAmount),
|
|
availableWriteOffAmount: this.money(item.availableWriteOffAmount),
|
|
writeOffAmount: this.money(item.availableWriteOffAmount),
|
|
kingdeeBillNo: item.kingdeeBillNo || '',
|
|
createUserName: item.createUserName || '',
|
|
createTime: item.createTime,
|
|
paymentCreateTime: item.createTime,
|
|
});
|
|
});
|
|
this.rows = nextRows;
|
|
this.dialog.visible = false;
|
|
this.validateTotal();
|
|
},
|
|
handleDialogClosed() {
|
|
this.dialog.rows = [];
|
|
this.dialog.selection = [];
|
|
},
|
|
handleAmountChange(row) {
|
|
const available = this.money(row.availableWriteOffAmount);
|
|
let amount = this.money(row.writeOffAmount);
|
|
if (amount < 0) amount = 0;
|
|
if (amount > available) {
|
|
amount = available;
|
|
this.$message.warning('本次核销金额不能超过可核销金额');
|
|
}
|
|
row.writeOffAmount = amount;
|
|
this.validateTotal();
|
|
},
|
|
validateTotal() {
|
|
const total = this.rows.reduce((sum, row) => sum + this.money(row.writeOffAmount), 0);
|
|
const settlementAmount = this.money(this.settlementAmount);
|
|
if (settlementAmount > 0 && total > settlementAmount) {
|
|
this.$message.warning('项目预付核销合计不能超过结算单金额');
|
|
return false;
|
|
}
|
|
return true;
|
|
},
|
|
validateBeforeSave() {
|
|
for (const row of this.rows) {
|
|
const amount = this.money(row.writeOffAmount);
|
|
if (amount <= 0) {
|
|
this.$message.warning(`预付单${row.paymentNo || ''}本次核销金额必须大于0`);
|
|
return false;
|
|
}
|
|
if (amount > this.money(row.availableWriteOffAmount)) {
|
|
this.$message.warning(`预付单${row.paymentNo || ''}本次核销金额不能超过可核销金额`);
|
|
return false;
|
|
}
|
|
}
|
|
return this.validateTotal();
|
|
},
|
|
removeRow(index) {
|
|
const nextRows = [...this.rows];
|
|
nextRows.splice(index, 1);
|
|
this.rows = nextRows;
|
|
},
|
|
toSavePayload() {
|
|
return this.rows.map(row => ({
|
|
paymentApplicationId: row.paymentApplicationId,
|
|
writeOffAmount: this.money(row.writeOffAmount),
|
|
}));
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.project-advance-write-off__amount {
|
|
width: 100%;
|
|
}
|
|
:deep(.project-advance-write-off__amount .el-input__inner) {
|
|
text-align: right;
|
|
}
|
|
</style>
|