<template>
|
<basicContainer>
|
<avue-crud :option="option" :table-loading="pageF.loading" :data="tableData" :page="page"
|
:permission="permissionList" :before-open="beforeOpen" v-model="form" ref="crudRef" @row-update="rowUpdate"
|
@row-save="rowSave" @refresh-change="refreshChange" @row-del="rowDel" @search-change="searchChange"
|
@search-reset="searchReset" @selection-change="selectionChange" @current-change="currentChange"
|
@size-change="sizeChange" @on-load="onLoad">
|
<template #menu-left>
|
<el-button type="primary" icon="el-icon-plus" v-hasPermi="['cwgl:receivableFeeManagement:add']"
|
@click="showFeeDetail('receivable')">新增
|
</el-button>
|
<el-button type="success" :disabled="selectDisplay" v-hasPermi="['cwgl:receivableFeeManagement:edit']"
|
@click="handleBill">生成应收账单
|
</el-button>
|
<!-- <el-button type="success" icon="Edit" :disabled="pageF.single"
|
v-hasPermi="['cwgl:receivableFeeManagement:edit']" @click="handleUpdate">修改
|
</el-button>
|
<el-button type="danger" icon="Delete" :disabled="pageF.multiple" @click="handleDelete"
|
v-hasPermi="['cwgl:receivableFeeManagement:remove']">删除
|
</el-button> -->
|
<el-button type="warning" plain icon="Download" @click="handleExport"
|
v-hasPermi="['cwgl:receivableFeeManagement:export']">导出
|
</el-button>
|
<el-button type="warning" plain icon="Upload" @click="handleImport"
|
v-hasPermi="['cwgl:receivableFeeManagement:import']">导入
|
</el-button>
|
</template>
|
<template #menu="{ size, row, index }">
|
<el-link class="link-btn" type="primary" :underline="false" plain :size="size" icon="View"
|
@click="handleExamine(row)" v-hasPermi="['cwgl:receivableFeeManagement:view']"> 查看
|
</el-link>
|
<el-link class="link-btn" v-if="row.status == 0" type="primary" :underline="false" plain :size="size"
|
icon="el-icon-edit" @click="handleEdit(row)" v-hasPermi="['cwgl:receivableFeeManagement:edit']"> 编辑
|
</el-link>
|
<el-link class="link-btn" v-if="row.status == 0" type="primary" :underline="false" plain :size="size"
|
@click="handleCancellation(row)" v-hasPermi="['cwgl:receivableFeeManagement:invalid']"> 作废
|
</el-link>
|
<el-button type="text" icon="View" @click="handleFlow(row)"
|
v-hasPermi="['cwgl:receivableFeeManagement:flow']">日志</el-button>
|
|
</template>
|
</avue-crud>
|
</basicContainer>
|
|
<FeeDetailModal ref="modalRef" :type="currentType" @submit="handleSave" />
|
<GenerateBillDialog ref="billDialogRef" @confirm="onBillConfirm" />
|
<DetailModal ref="detailModalRef" />
|
<OperationLogModal ref="logModalRef" />
|
<XlsFileImport title="应收信息导入" uploadUrl="/cwgl/receivableFeeManagement/importTemplate" templateUrl="/cwgl/receivableFeeManagement/importTemplate"
|
:open="pageF.importOpen" @submit="importSubmit" @cancel="pageF.importOpen = false" />
|
|
</template>
|
|
<script setup name="receivableFeeManagement" lang="ts">
|
import {
|
ReceivableFeeManagementI, addReceivableFeeManagement, delReceivableFeeManagement, exportReceivableFeeManagement, getReceivableFeeManagement, listReceivableFeeManagement, updateReceivableFeeManagement,
|
getStatistics, addCreateBill, receivableFeeManagementVoid
|
} from "@/api/cwgl/receivableFeeManagement";
|
import useCurrentInstance from "@/utils/useCurrentInstance";
|
import { computed, reactive, ref, toRefs } from "vue";
|
import { PagesInterface, PageQueryInterface } from "@/utils/globalInterface";
|
import { usePagePlus } from "@/hooks/usePagePlus";
|
import { hasPermission } from "@/utils/permissionUtils";
|
import FeeDetailModal from '@/components/FeeDetailModal/index.vue';
|
import GenerateBillDialog from '@/components/GenerateBillDialog/index.vue';
|
import DetailModal from '@/components/DetailModal/index.vue';
|
import OperationLogModal from '@/components/OperationLogModal/index.vue';
|
import { listReceivableFeeManagementLog } from "@/api/cwgl/receivableFeeManagementLog";
|
|
|
|
const { proxy } = useCurrentInstance();
|
const crudRef = ref();
|
|
const permissionList = computed(() => {
|
return {
|
addBtn: hasPermission(["cwgl:receivableFeeManagement:add"]),
|
delBtn: hasPermission(["cwgl:receivableFeeManagement:remove"]),
|
editBtn: hasPermission(["cwgl:receivableFeeManagement:edit"]),
|
viewBtn: hasPermission(["cwgl:receivableFeeManagement:query"]),
|
}
|
})
|
|
const data = reactive({
|
form: <ReceivableFeeManagementI>{},
|
queryParams: <ReceivableFeeManagementI & PageQueryInterface>{},
|
page: <PagesInterface>{
|
pageSize: 10,
|
total: 0,
|
currentPage: 1,
|
},
|
selectionList: [],
|
selectDisplay: true,
|
})
|
const { queryParams, form, page, selectionList, selectDisplay } = toRefs(data);
|
const option = ref({
|
pageKey: 'ReceivableFeeManagement',
|
rowKey: 'id',
|
searchSpan: 5,
|
addBtn: false,
|
editBtn: false,
|
viewBtn: false,
|
delBtn: false,
|
labelWidth: 150,
|
searchLabelWidth: 120,
|
column: {
|
// id: {
|
// label: 'ID',
|
// },
|
systemNo: {
|
label: '系统编号',
|
addDisplay: false, // 新增时不显示
|
editDisplay: false, // 修改时不显示
|
minWidth: 150,
|
search: true,
|
rules: [
|
{
|
required: true,
|
message: "系统编号不能为空", trigger: "blur"
|
}
|
],
|
},
|
relatedBillNo: {
|
label: '关联账单编号',
|
minWidth: 150,
|
search: true,
|
// rules: [
|
// {
|
// required: true,
|
// message: "关联账单编号不能为空", trigger: "blur"
|
// }
|
// ],
|
},
|
sourceSystem: {
|
label: '来源系统',
|
minWidth: 120,
|
type: 'select', dataType: 'string', dicUrl: '/system/dict/data/type/sys_system',
|
search: true,
|
rules: [
|
{
|
required: true,
|
message: "来源系统不能为空", trigger: "blur"
|
}
|
],
|
},
|
businessSector: {
|
label: '业务板块',
|
minWidth: 120,
|
type: 'select', dataType: 'string', dicUrl: '/system/dict/data/type/sys_business',
|
search: true,
|
// rules: [
|
// {
|
// required: true,
|
// message: "业务板块不能为空", trigger: "blur"
|
// }
|
// ],
|
},
|
documentType: {
|
label: '单据类型',
|
search: true,
|
minWidth: 120,
|
type: 'select', dataType: 'string', dicUrl: '/system/dict/data/type/sys_receipts',
|
rules: [
|
{
|
required: true,
|
message: "单据类型不能为空", trigger: "change"
|
}
|
],
|
},
|
receivableAmountStr: {
|
label: '应收金额',
|
// label: '应收金额描述',
|
|
minWidth: 150,
|
search: true,
|
formatter: (row) => {
|
if (!row.receivableAmountStr) return '-';
|
// 将空格替换为换行符。如果后端返回的是 "0港币 2420人民币"
|
// 我们将其转换为 "0港币\n2420人民币"
|
return row.receivableAmountStr.replace(/\s+/g, '\n');
|
},
|
styles: {
|
whiteSpace: 'pre-wrap',
|
lineHeight: '1.5'
|
},
|
},
|
documentNo: {
|
label: '单据编号',
|
minWidth: 150,
|
search: true,
|
rules: [
|
{
|
required: true,
|
message: "单据编号不能为空", trigger: "blur"
|
}
|
],
|
},
|
isInternalSettlement: {
|
label: '是否内部结算',
|
search: true,
|
minWidth: 120,
|
type: 'select', dataType: 'string', dicUrl: '/system/dict/data/type/sys_whether_type',
|
rules: [
|
{
|
required: true,
|
message: "单据类型不能为空", trigger: "change"
|
}
|
],
|
},
|
internalSettlementUnit: {
|
label: '内部结算单位',
|
minWidth: 150,
|
search: true,
|
},
|
customerName: {
|
label: '客户名称',
|
minWidth: 150,
|
search: true,
|
rules: [
|
{
|
required: true,
|
message: "客户名称不能为空", trigger: "blur"
|
}
|
],
|
},
|
projectName: {
|
label: '项目名称',
|
minWidth: 150,
|
search: true,
|
},
|
businessTime: {
|
label: '业务发生时间',
|
minWidth: 150,
|
// search: true,
|
rules: [
|
{
|
required: true,
|
message: "业务发生时间不能为空", trigger: "blur"
|
}
|
],
|
},
|
businessTimeArray: {
|
label: '业务发生时间',
|
minWidth: 150,
|
search: true,
|
searchRange: true,
|
addDisplay: false, // 新增时不显示
|
editDisplay: false, // 修改时不显示
|
type: 'daterange',
|
startPlaceholder: '开始日期',
|
endPlaceholder: '结束日期',
|
valueFormat: 'YYYY-MM-DD',
|
hide: true
|
},
|
receivableConfirmTime: {
|
label: '应收确认时间',
|
minWidth: 150,
|
rules: [
|
{
|
required: true,
|
message: "应收确认时间不能为空", trigger: "blur"
|
}
|
],
|
},
|
receivableConfirmTimeArray: {
|
label: '应收确认时间',
|
minWidth: 150,
|
search: true,
|
searchRange: true,
|
addDisplay: false, // 新增时不显示
|
editDisplay: false, // 修改时不显示
|
type: 'daterange',
|
startPlaceholder: '开始日期',
|
endPlaceholder: '结束日期',
|
valueFormat: 'YYYY-MM-DD',
|
hide: true
|
},
|
// receivableAmount: {
|
// label: '应收金额',
|
// rules: [
|
// {
|
// required: true,
|
// message: "应收金额不能为空", trigger: "blur"
|
// }
|
// ],
|
// },
|
|
// remark: {
|
// label: '备注',
|
// type: 'textarea', minRows: 3, maxRows: 5,
|
// },
|
|
createBy: {
|
search: true,
|
label: '创建人',
|
},
|
createTime: {
|
// search: true,
|
label: '创建时间',
|
minWidth: 150,
|
},
|
createdTimeArray: {
|
label: '创建时间',
|
search: true,
|
searchRange: true,
|
addDisplay: false, // 新增时不显示
|
editDisplay: false, // 修改时不显示
|
type: 'daterange',
|
startPlaceholder: '开始日期',
|
endPlaceholder: '结束日期',
|
valueFormat: 'YYYY-MM-DD',
|
hide: true
|
},
|
updateBy: {
|
search: true,
|
label: '更新人',
|
},
|
updateTime: {
|
// search: true,
|
minWidth: 150,
|
label: '更新时间',
|
},
|
updateTimeArray: {
|
label: '更新时间',
|
search: true,
|
searchRange: true,
|
addDisplay: false, // 新增时不显示
|
editDisplay: false, // 修改时不显示
|
type: 'daterange',
|
startPlaceholder: '开始日期',
|
endPlaceholder: '结束日期',
|
valueFormat: 'YYYY-MM-DD',
|
hide: true
|
},
|
status: {
|
search: true,
|
label: '状态',
|
fixed: 'right',
|
minWidth: 120,
|
type: 'select', dataType: 'string', dicUrl: '/system/dict/data/type/sys_charge',
|
},
|
|
}
|
})
|
|
const { tableData, pageF, rowSave, rowUpdate, rowDel, beforeOpen, searchChange,
|
searchReset, selectionChange, onLoad, currentChange, sizeChange, handleDelete, handleExport, handleUpdate, refreshChange } = usePagePlus({
|
form: form,
|
option: option,
|
queryParams: queryParams,
|
idKey: 'id',
|
page: page.value,
|
getListApi: listReceivableFeeManagement,
|
getDetailApi: getReceivableFeeManagement,
|
exportApi: exportReceivableFeeManagement,
|
deleteApi: delReceivableFeeManagement,
|
addApi: addReceivableFeeManagement,
|
updateApi: updateReceivableFeeManagement,
|
handleUpdateFunc: () => {
|
crudRef.value.rowEdit(selectionList.value[0]);
|
},
|
handleSelectionChangeFunc: (selection: any) => {
|
// 假设你要对比的字段名是 customerFullName isInternalSettlement internalSettlementUnit
|
|
// 1. 数组长度必须大于 0
|
if (selection && selection.length > 0) {
|
// 取出第一项作为对比基准
|
const firstItem = selection[0];
|
|
// 2. 检查每一项是否都与第一项的三个关键字段完全一致
|
const isAllMatch = selection.every(item =>
|
item.customerId === firstItem.customerId &&
|
item.isInternalSettlement === firstItem.isInternalSettlement &&
|
item.internalSettlementUnit === firstItem.internalSettlementUnit &&
|
item.status == 0
|
);
|
|
// 如果全部匹配,selectDisplay 为 false,否则为 true
|
selectDisplay.value = !isAllMatch;
|
} else {
|
// 3. 如果数组为空,根据你的逻辑通常返回 true (即不显示或禁用)
|
selectDisplay.value = true;
|
}
|
selectionList.value = selection;
|
},
|
getBeginListFunc: (params = {}) => {
|
// 创建新参数对象
|
let newParams = { ...params };
|
newParams = proxy.addDateRangeNew(newParams, newParams?.createdTimeArray, 'createTime') || [];
|
newParams = proxy.addDateRangeNew(newParams, newParams?.updateTimeArray, 'updateTime') || [];
|
newParams = proxy.addDateRangeNew(newParams, newParams?.businessTimeArray, 'businessTime') || [];
|
newParams = proxy.addDateRangeNew(newParams, newParams?.receivableConfirmTimeArray, 'receivableConfirmTime') || [];
|
|
delete newParams.createdTimeArray;
|
delete newParams.updateTimeArray;
|
delete newParams.businessTimeArray;
|
delete newParams.receivableConfirmTimeArray;
|
|
queryParams.value = newParams;
|
return newParams;
|
}
|
})
|
|
const modalRef = ref(null);
|
const currentType = ref('receivable');
|
const addIshorw = ref(false);
|
const showFeeDetail = (type) => {
|
currentType.value = type;
|
addIshorw.value = true;
|
modalRef.value.open();
|
};
|
/* 编辑 */
|
const handleEdit = (row) => {
|
currentType.value = 'receivable';
|
addIshorw.value = false;
|
getReceivableFeeManagement(row.id).then((res) => {
|
if (res.code === 200) {
|
modalRef.value.open(res.data);
|
}
|
});
|
|
};
|
/* 新增编辑 */
|
const handleSave = (data, receivableFeeDetailList) => {
|
if (addIshorw.value) {
|
data.receivableFeeDetailList = receivableFeeDetailList;
|
data.status = '0';
|
addReceivableFeeManagement(data).then((res) => {
|
if (res.code === 200) {
|
proxy.$message.success(res.msg);
|
onLoad(page.value);
|
modalRef.value.canceleClick();
|
|
}
|
})
|
} else {
|
data.receivableFeeDetailList = receivableFeeDetailList;
|
updateReceivableFeeManagement(data).then((res) => {
|
if (res.code === 200) {
|
proxy.$message.success(res.msg);
|
onLoad(page.value);
|
modalRef.value.canceleClick();
|
|
}
|
})
|
}
|
};
|
const billDialogRef = ref(null);
|
const handleBill = () => {
|
const ids = selectionList.value.map(item => item.id).join(',');
|
getStatistics(ids).then((res) => {
|
if (res.code === 200) {
|
// 打开弹窗并传入数据
|
console.log(selectionList.valu);
|
billDialogRef.value.open(res.data, selectionList.value, 'receivable');
|
}
|
});
|
// // 打开弹窗并传入数据
|
// billDialogRef.value.open(mockData);
|
};
|
const onBillConfirm = (statisticsData, obj: any) => {
|
const payload = {
|
billType: obj.billType,
|
billName: obj.billName,
|
statisticsData: statisticsData,
|
customerName: selectionList.value[0].customerName,
|
isInternalSettlement: selectionList.value[0].isInternalSettlement,
|
internalSettlementUnit: selectionList.value[0].internalSettlementUnit,
|
|
};
|
addCreateBill(payload).then((res) => {
|
if (res.code === 200) {
|
proxy.$message.success(res.msg);
|
billDialogRef.value.cancel();
|
onLoad(page.value);
|
|
}
|
});
|
|
};
|
const detailModalRef = ref(null);
|
const handleExamine = (row) => {
|
getReceivableFeeManagement(row.id).then((res) => {
|
if (res.code === 200) {
|
detailModalRef.value.open(res.data);
|
}
|
});
|
|
};
|
/* 作废 */
|
const handleCancellation = (row) => {
|
proxy.$confirm('是否确认作废该条数据?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
}).then(() => {
|
receivableFeeManagementVoid(row.id).then((res) => {
|
if (res.code == 200) {
|
proxy.$message.success(res.msg);
|
onLoad(page.value);
|
}
|
});
|
})
|
};
|
const logModalRef = ref(null);
|
const handleFlow = (row: any) => {
|
// 这里可以从 row 中直接获取日志,或者调用后端接口查询
|
// 示例模拟数据
|
listReceivableFeeManagementLog({ receivableFeeId: row.id }).then((res) => {
|
if (res.code == 200) {
|
logModalRef.value.open(res.rows,'receivable');
|
|
}
|
});
|
}
|
const handleImport = () => {
|
pageF.importOpen = true;
|
}
|
|
const importSubmit = () => {
|
pageF.importOpen = false;
|
onLoad(page.value);
|
};
|
|
</script>
|
<style scoped>
|
/* 确保 el-table 能够识别换行符 */
|
:deep(.el-table .cell) {
|
white-space: pre-wrap !important;
|
word-break: break-all;
|
}
|
</style>
|