明细支付

master
lion 3 weeks ago
parent b7ccb4dc0c
commit edac2f8f56

@ -310,6 +310,309 @@
/>
</el-tab-pane>
<el-tab-pane
:label="`明细拆分前${
beforeSplitBadgeCount ? '' + beforeSplitBadgeCount + '' : ''
}`"
name="beforeSplit"
>
<div
style="
margin-bottom: 10px;
display: flex;
justify-content: flex-start;
align-items: center;
gap: 10px;
"
>
<el-input
v-model="beforeSplitQuery.keywords"
placeholder="关键词"
size="small"
clearable
style="width: 200px"
/>
<el-select
v-model="beforeSplitQuery.creator_department_id"
placeholder="科室"
size="small"
clearable
style="width: 150px"
>
<el-option
v-for="item in departments"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
<el-select
v-model="beforeSplitQuery.created_by"
placeholder="发起人"
size="small"
clearable
filterable
style="width: 150px"
>
<el-option
v-for="item in users"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
<el-select
v-model="beforeSplitQuery.chengbanren_id"
placeholder="采购负责人"
size="small"
clearable
filterable
style="width: 150px"
>
<el-option
v-for="item in purchasers"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
<el-select
v-model="beforeSplitQuery.caigouneirong"
placeholder="采购类别"
size="small"
clearable
filterable
style="width: 150px"
>
<el-option
v-for="item in purchaseContents"
:key="item"
:label="item"
:value="item"
/>
</el-select>
<el-button
type="primary"
size="small"
icon="el-icon-search"
@click="handleBeforeSplitQueryChange"
>查询</el-button
>
<el-button
type="primary"
size="small"
icon="el-icon-edit"
@click="handleBatchPayBeforeSplit"
>批量支付</el-button
>
</div>
<el-table
ref="beforeSplitTable"
:data="beforeSplitRows"
border
style="width: 100%"
row-key="id"
@selection-change="handleBeforeSplitSelectionChange"
>
<el-table-column
type="selection"
width="50"
reserve-selection
></el-table-column>
<el-table-column label="申请人" width="80" align="center">
<template #default="{ row }">
{{ row.applicant }}
</template>
</el-table-column>
<el-table-column label="申请科室" width="100" align="center">
<template #default="{ row }">
{{ row.department }}
</template>
</el-table-column>
<el-table-column label="流程名称" width="160" align="center">
<template #default="{ row }">
<div
@click="showModal(row)"
style="cursor: pointer; color: #409eff"
>
{{ row.flowTitle }}
</div>
</template>
</el-table-column>
<el-table-column
label="采购类别"
width="100"
align="center"
show-overflow-tooltip
>
<template #default="{ row }">
{{ row.purchaseContent }}
</template>
</el-table-column>
<el-table-column
label="采购负责人"
width="100"
align="center"
show-overflow-tooltip
>
<template #default="{ row }">
{{ row.purchaser }}
</template>
</el-table-column>
<el-table-column label="本次报销数量" width="120" align="center">
<template #default="{ row }">
<el-input-number
v-model="row.applyNum"
:min="0"
:controls="false"
size="small"
:class="{ 'error-input': isApplyNumInvalid(row) }"
style="width: 90px"
@change="validateApplyNum(row)"
/>
</template>
</el-table-column>
<el-table-column label="付款金额" width="120" align="center">
<template #default="{ row }">
<el-input-number
v-model="row.money"
:min="0"
:precision="2"
:controls="false"
size="small"
style="width: 90px"
/>
</template>
</el-table-column>
<el-table-column label="已报销数量" width="100" align="center">
<template #default="{ row }">
{{ row.paidNum }}
</template>
</el-table-column>
<el-table-column label="数量" width="100" align="center">
<template #default="{ row }">
{{ row.total }}
</template>
</el-table-column>
<el-table-column label="是否合同审批" width="120" align="center">
<template #default="{ row }">
<el-select
v-model="row.shifouhetongshenpi"
placeholder="是否合同审批"
size="small"
@change="
(val) =>
handleBeforeSplitFieldUpdate(row, 'shifouhetongshenpi', val)
"
style="width: 90px"
>
<el-option label="是" value="是" />
<el-option label="否" value="否" />
</el-select>
</template>
</el-table-column>
<el-table-column label="清单情况" width="120" align="center">
<template #default="{ row }">
<el-select
v-model="row.shifouqingdan"
placeholder="清单情况"
size="small"
@change="
(val) =>
handleBeforeSplitFieldUpdate(row, 'shifouqingdan', val)
"
style="width: 90px"
>
<el-option label="清单内" value="清单内" />
<el-option label="清单外" value="清单外" />
</el-select>
</template>
</el-table-column>
<el-table-column label="是否比价" width="120" align="center">
<template #default="{ row }">
<el-select
v-model="row.shifoubijia"
placeholder="是否比价"
size="small"
@change="
(val) => handleBeforeSplitFieldUpdate(row, 'shifoubijia', val)
"
style="width: 90px"
>
<el-option label="是" value="是" />
<el-option label="否" value="否" />
</el-select>
</template>
</el-table-column>
<el-table-column label="是否收货" width="120" align="center">
<template #default="{ row }">
<el-select
v-model="row.shifoufahuo"
placeholder="是否收货"
size="small"
@change="
(val) => handleBeforeSplitFieldUpdate(row, 'shifoufahuo', val)
"
style="width: 90px"
>
<el-option label="是" value="是" />
<el-option label="否" value="否" />
</el-select>
</template>
</el-table-column>
<el-table-column
label="品名或服务需求"
min-width="140"
show-overflow-tooltip
>
<template #default="{ row }">
{{ row.itemName }}
</template>
</el-table-column>
<el-table-column
label="型号与规格"
width="140"
show-overflow-tooltip
>
<template #default="{ row }">
{{ row.model }}
</template>
</el-table-column>
<el-table-column label="产地" width="100" align="center">
<template #default="{ row }">
{{ row.origin }}
</template>
</el-table-column>
<el-table-column label="单位" width="100" align="center">
<template #default="{ row }">
{{ row.unit }}
</template>
</el-table-column>
<el-table-column
label="用途"
min-width="140"
show-overflow-tooltip
>
<template #default="{ row }">
{{ row.purpose }}
</template>
</el-table-column>
</el-table>
<el-pagination
style="margin-top: 10px"
@size-change="handleBeforeSplitSizeChange"
@current-change="handleBeforeSplitPageChange"
:current-page="beforeSplitPage"
:page-sizes="[10, 20, 30, 40, 50, 100]"
:page-size="beforeSplitPageSize"
layout="total, ->, prev, pager, next, sizes, jumper"
:total="beforeSplitTotal"
/>
</el-tab-pane>
<el-tab-pane label="已支付" name="paid">
<div
style="
@ -765,11 +1068,26 @@ export default {
pendingTotal: 0,
pendingSelectedIds: [],
pendingSelectedMap: {},
beforeSplitQuery: {
creator_department_id: "",
created_by: "",
keywords: "",
chengbanren_id: "",
caigouneirong: "",
},
beforeSplitRows: [],
beforeSplitPage: 1,
beforeSplitPageSize: 10,
beforeSplitTotal: 0,
beforeSplitSelectedIds: [],
beforeSplitSelectedMap: {},
selectedPreviewVisible: false,
selectedPreviewRows: [],
selectedPreviewSelection: [],
selectedPreviewSource: "pending", // : "pending" "beforeSplit"
syncingPreviewSelection: false,
syncingPendingSelection: false,
syncingBeforeSplitSelection: false,
isShowPay: false,
paidQuery: {
creator_department_id: "",
@ -791,6 +1109,11 @@ export default {
? this.pendingSelectedIds.length
: 0;
},
beforeSplitBadgeCount() {
return this.beforeSplitSelectedIds && this.beforeSplitSelectedIds.length
? this.beforeSplitSelectedIds.length
: 0;
},
},
methods: {
async handlePendingFieldUpdate(row, field, value) {
@ -805,6 +1128,18 @@ export default {
this.$set(row, field, oldValue);
}
},
async handleBeforeSplitFieldUpdate(row, field, value) {
const oldValue = row[field];
// v-model 使
try {
await updateList({ id: row.id, [field]: value });
this.$message.success("已保存");
} catch (e) {
//
this.$message.error("保存失败,请重试");
this.$set(row, field, oldValue);
}
},
showModal(row) {
this.modalUrl = `/oa/#/flow/detail?module_id=${
row.yibancaigou?.flow?.custom_model_id
@ -889,6 +1224,15 @@ export default {
}
this.openSelectedPreview();
return;
},
async handleBatchPayBeforeSplit() {
//
if (this.beforeSplitSelectedIds.length === 0) {
this.$message.warning("请先选择需要支付的明细");
return;
}
this.openSelectedPreviewBeforeSplit();
return;
//
if (this.pendingSelectedIds.length === 0) {
this.$message.warning("请先选择需要支付的明细");
@ -1202,6 +1546,75 @@ export default {
this.pendingPage = val;
this.getWaitList();
},
handleBeforeSplitQueryChange() {
this.beforeSplitPage = 1;
this.getBeforeSplitList();
},
handleBeforeSplitSizeChange(val) {
this.beforeSplitPageSize = val;
this.beforeSplitPage = 1;
this.getBeforeSplitList();
},
handleBeforeSplitPageChange(val) {
this.beforeSplitPage = val;
this.getBeforeSplitList();
},
handleBeforeSplitSelectionChange(selection) {
if (this.syncingBeforeSplitSelection) return;
// ID
const currentPageIds = selection.map((row) => row.id);
// ID
const currentPageAllIds = this.beforeSplitRows.map((row) => row.id);
//
currentPageIds.forEach((id) => {
const record =
selection.find((row) => row.id === id) ||
this.beforeSplitRows.find((row) => row.id === id);
if (record) {
this.$set(this.beforeSplitSelectedMap, id, record);
}
});
currentPageAllIds.forEach((id) => {
if (!currentPageIds.includes(id)) {
if (this.beforeSplitSelectedIds.includes(id)) {
const index = this.beforeSplitSelectedIds.indexOf(id);
if (index > -1) {
this.beforeSplitSelectedIds.splice(index, 1);
}
}
if (this.beforeSplitSelectedMap[id]) {
this.$delete(this.beforeSplitSelectedMap, id);
}
}
});
currentPageIds.forEach((id) => {
if (!this.beforeSplitSelectedIds.includes(id)) {
this.beforeSplitSelectedIds.push(id);
}
if (!this.beforeSplitSelectedMap[id]) {
const record = this.beforeSplitRows.find((row) => row.id === id);
if (record) {
this.$set(this.beforeSplitSelectedMap, id, record);
}
}
});
},
syncBeforeSplitTableSelection() {
this.$nextTick(() => {
if (this.$refs.beforeSplitTable) {
this.syncingBeforeSplitSelection = true;
this.$refs.beforeSplitTable.clearSelection();
this.beforeSplitRows.forEach((row) => {
if (this.beforeSplitSelectedIds.includes(row.id)) {
this.$refs.beforeSplitTable.toggleRowSelection(row, true);
}
});
this.$nextTick(() => {
this.syncingBeforeSplitSelection = false;
});
}
});
},
handlePaidQueryChange() {
this.paidPage = 1;
this.getPaidList();
@ -1246,6 +1659,55 @@ export default {
.filter(Boolean);
this.selectedPreviewRows = rows;
this.selectedPreviewSelection = rows.map((row) => row.id);
this.selectedPreviewSource = "pending";
this.selectedPreviewVisible = true;
this.$nextTick(() => {
if (this.$refs.previewTable) {
this.syncingPreviewSelection = true;
this.$refs.previewTable.clearSelection();
this.selectedPreviewRows.forEach((row) => {
if (this.selectedPreviewSelection.includes(row.id)) {
this.$refs.previewTable.toggleRowSelection(row, true);
}
});
this.$nextTick(() => {
this.syncingPreviewSelection = false;
});
}
});
},
openSelectedPreviewBeforeSplit() {
// 便
const editedMap = {};
(this.selectedPreviewRows || []).forEach((r) => {
editedMap[r.id] = { applyNum: r.applyNum, money: r.money };
});
//
const rows = this.beforeSplitSelectedIds
.map((id) => {
if (!this.beforeSplitSelectedMap[id]) {
const record = this.beforeSplitRows.find((row) => row.id === id);
if (record) {
this.$set(this.beforeSplitSelectedMap, id, record);
}
}
const rec = this.beforeSplitSelectedMap[id];
if (!rec) return null;
//
const edited = editedMap[id];
if (edited) {
if (edited.applyNum !== undefined && edited.applyNum !== null)
rec.applyNum = edited.applyNum;
if (edited.money !== undefined && edited.money !== null)
rec.money = edited.money;
}
return rec;
})
.filter(Boolean);
this.selectedPreviewRows = rows;
this.selectedPreviewSelection = rows.map((row) => row.id);
this.selectedPreviewSource = "beforeSplit";
this.selectedPreviewVisible = true;
this.$nextTick(() => {
if (this.$refs.previewTable) {
@ -1298,18 +1760,31 @@ export default {
return;
}
//
//
const newIds = [...this.selectedPreviewSelection];
this.pendingSelectedIds = newIds;
const newMap = {};
newIds.forEach((id) => {
const record =
this.selectedPreviewRows.find((row) => row.id === id) ||
this.pendingSelectedMap[id] ||
this.pendingRows.find((row) => row.id === id);
if (record) newMap[id] = record;
});
this.pendingSelectedMap = { ...newMap };
if (this.selectedPreviewSource === "pending") {
this.pendingSelectedIds = newIds;
const newMap = {};
newIds.forEach((id) => {
const record =
this.selectedPreviewRows.find((row) => row.id === id) ||
this.pendingSelectedMap[id] ||
this.pendingRows.find((row) => row.id === id);
if (record) newMap[id] = record;
});
this.pendingSelectedMap = { ...newMap };
} else if (this.selectedPreviewSource === "beforeSplit") {
this.beforeSplitSelectedIds = newIds;
const newMap = {};
newIds.forEach((id) => {
const record =
this.selectedPreviewRows.find((row) => row.id === id) ||
this.beforeSplitSelectedMap[id] ||
this.beforeSplitRows.find((row) => row.id === id);
if (record) newMap[id] = record;
});
this.beforeSplitSelectedMap = { ...newMap };
}
//
const titleParts = selectedRows.map(
@ -1445,6 +1920,7 @@ export default {
const params = {
page: this.pendingPage,
page_size: this.pendingPageSize,
is_before: 0, // 0
};
if (this.pendingQuery.creator_department_id) {
params.creator_department_id = this.pendingQuery.creator_department_id;
@ -1498,6 +1974,63 @@ export default {
//
this.syncPendingTableSelection();
},
async getBeforeSplitList() {
const params = {
page: this.beforeSplitPage,
page_size: this.beforeSplitPageSize,
is_before: 1, // 1
};
if (this.beforeSplitQuery.creator_department_id) {
params.creator_department_id = this.beforeSplitQuery.creator_department_id;
}
if (this.beforeSplitQuery.created_by) {
params.created_by = this.beforeSplitQuery.created_by;
}
if (this.beforeSplitQuery.keywords) {
params.keywords = this.beforeSplitQuery.keywords;
}
if (this.beforeSplitQuery.chengbanren_id) {
params.chengbanren_id = this.beforeSplitQuery.chengbanren_id;
}
if (this.beforeSplitQuery.caigouneirong) {
params.caigouneirong = this.beforeSplitQuery.caigouneirong;
}
const res = await waitList(params);
this.beforeSplitTotal = res.total || 0;
//
this.beforeSplitRows = (res.data || []).map((item) => ({
...item, // 便使
checked: false,
applicant: item.yibancaigou?.flow?.creator?.name || "",
department: item.yibancaigou?.flow?.creator_department?.name || "",
flowTitle: item.yibancaigou?.flow?.title || "",
purchaseContent: item.yibancaigou?.caigouneirong || "",
purchaser:
item.yibancaigou?.flow?.logs && item.yibancaigou.flow.logs.length > 0
? item.yibancaigou.flow.logs[0]?.user?.name || ""
: "",
isContractFlow: item.yibancaigou?.flow?.contract_flow ? "是" : "否",
paidNum: item.fund_log_wuzicaigou_items_sum_num || 0,
total: item.num || 0,
itemName: item.pinminghuofuwuxuqiu || "",
model: item.xinghao || "",
origin: item.chandi || "",
unit: item.danwei || "",
purpose: item.yongtu || "",
applyNum: null, //
money: null, //
shifouqingdan: item.shifouqingdan || "",
shifoubijia: item.shifoubijia || "",
shifoufahuo: item.shifoufahuo || "",
}));
this.beforeSplitRows.forEach((row) => {
if (this.beforeSplitSelectedIds.includes(row.id)) {
this.$set(this.beforeSplitSelectedMap, row.id, row);
}
});
//
this.syncBeforeSplitTableSelection();
},
async getPaidList() {
const params = {
page: this.paidPage,
@ -1559,7 +2092,10 @@ export default {
//
if (newTab === "pending") {
this.pendingPage = 1;
this.pendingPageSize = 40;
this.pendingPageSize = 10;
} else if (newTab === "beforeSplit") {
this.beforeSplitPage = 1;
this.beforeSplitPageSize = 10;
} else if (newTab === "paid") {
this.paidPage = 1;
this.paidPageSize = 10;
@ -1576,6 +2112,16 @@ export default {
};
this.pendingSelectedIds = [];
this.pendingSelectedMap = {};
} else if (newTab === "beforeSplit") {
this.beforeSplitQuery = {
creator_department_id: "",
created_by: "",
keywords: "",
chengbanren_id: "",
caigouneirong: "",
};
this.beforeSplitSelectedIds = [];
this.beforeSplitSelectedMap = {};
} else if (newTab === "paid") {
this.paidQuery = {
creator_department_id: "",
@ -1593,6 +2139,9 @@ export default {
if (this.$refs.pendingTable) {
this.$refs.pendingTable.clearSelection();
}
if (this.$refs.beforeSplitTable) {
this.$refs.beforeSplitTable.clearSelection();
}
});
});
@ -1602,6 +2151,9 @@ export default {
} else if (newTab === "pending") {
//
this.getWaitList();
} else if (newTab === "beforeSplit") {
//
this.getBeforeSplitList();
}
},
//

Loading…
Cancel
Save