Merge pull request '修复付款申请 + 收款/付款结算单搜索栏' (#16) from fix/20261110-修复结算单页面-web into master

Reviewed-on: #16
This commit was merged in pull request #16.
This commit is contained in:
2026-11-10 16:16:04 +08:00
7 changed files with 413 additions and 298 deletions
+7 -119
View File
@@ -1,14 +1,11 @@
/**
* 付款申请列表(avue-crud)配置
* ------------------------------------------------------------------
* 列表页与其它模块统一使用 avue-crud,头部 4 个按钮(刷新 / 列显隐 / 搜索显隐 /
* 表格卡片切换)由 avue-crud 自带,不做二次封装。
* 列表页与其它模块统一使用 avue-crud,头部按钮(刷新 / 列显隐 / 表格卡片切换)
* 由 avue-crud 自带,不做二次封装。
*
* 搜索项与表格列 label 不一致的(如表格列「收款方」/ 搜索项「客户名称」),
* 单独定义一个 hide 的搜索列,并用 searchProp 映射到后端字段。
*
* ⚠️ avue 的 searchOrder 为降序排序,值越大越靠前(见 header-search2.js:
* `list.sort((a, b) => (b.searchOrder || 0) - (a.searchOrder || 0))`)。
* 搜索栏与应收/应付明细等页面统一为页面级手写搜索区(见 payment-application.vue),
* 此处只保留表格列配置。
*/
const textFormatter = (row, value) =>
@@ -16,46 +13,10 @@ const textFormatter = (row, value) =>
const moneyFormatter = (row, value) => Number(value || 0).toFixed(2);
// 仅用于搜索、不在表格中出现的列
const searchOnlyColumn = ({ label, prop, searchOrder, searchProp, dicData }) => {
const column = {
label,
prop,
search: true,
searchOrder,
searchPlaceholder: '请输入',
hide: true,
showColumn: false,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
};
if (searchProp) column.searchProp = searchProp;
if (dicData) {
column.type = 'select';
column.searchPlaceholder = '请选择';
column.dicData = dicData;
}
return column;
};
export const paymentApplicationOption = ({
paymentTypeOptions = [],
approvalStatusOptions = [],
kingdeeStatusOptions = [],
} = {}) => ({
export const paymentApplicationOption = () => ({
height: 'auto',
calcHeight: 32,
tip: false,
searchBtnText: '查询',
emptyBtnText: '重置',
searchShow: true,
searchIcon: true,
searchLabelWidth: 88,
// 查询/重置紧跟首行 4 个条件(4×5 + 菜单 4 = 24),不再独占下一整行
searchMenuSpan: 4,
searchIndex: 4,
searchMenuPosition: 'right',
border: true,
index: true,
indexLabel: '序号',
@@ -73,84 +34,11 @@ export const paymentApplicationOption = ({
menuFixed: 'right',
dialogClickModal: false,
column: [
// ---------- 搜索项(前 4 项默认展示,其余折叠;searchOrder 越大越靠前) ----------
{
label: '单据号',
prop: 'paymentNo',
slot: true,
search: true,
searchSpan: 5,
searchOrder: 9,
searchPlaceholder: '请输入',
minWidth: 150,
},
{
label: '日期',
prop: 'applyDateRange',
type: 'daterange',
searchType: 'daterange',
search: true,
searchSpan: 5,
searchOrder: 8,
hide: true,
showColumn: false,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
},
{
...searchOnlyColumn({
label: '客户名称',
prop: 'payeeNameSearch',
searchOrder: 7,
searchProp: 'payeeName',
}),
searchSpan: 5,
},
{
...searchOnlyColumn({
label: '项目名称',
prop: 'projectNameSearch',
searchOrder: 6,
searchProp: 'projectName',
}),
searchSpan: 5,
},
searchOnlyColumn({
label: '关联结算单',
prop: 'settlementNo',
searchOrder: 4,
}),
searchOnlyColumn({
label: '付款类型',
prop: 'paymentType',
searchOrder: 3,
dicData: paymentTypeOptions,
}),
searchOnlyColumn({
label: '审核状态',
prop: 'approvalStatus',
searchOrder: 2,
dicData: approvalStatusOptions,
}),
searchOnlyColumn({
label: '金蝶单据状态',
prop: 'kingdeeStatus',
searchOrder: 1,
dicData: kingdeeStatusOptions,
}),
// ---------- 表格列 ----------
{ label: '单据号', prop: 'paymentNo', slot: true, minWidth: 150 },
{ label: '付款类型', prop: 'paymentTypeName', minWidth: 110, formatter: textFormatter },
{ label: '所属项目', prop: 'projectName', minWidth: 140, formatter: textFormatter },
{
label: '所属组织',
prop: 'deptName',
search: true,
searchOrder: 5,
searchslot: true,
minWidth: 120,
formatter: textFormatter,
},
{ label: '所属组织', prop: 'deptName', minWidth: 120, formatter: textFormatter },
{ label: '合同编号', prop: 'contractNo', minWidth: 130, formatter: textFormatter },
{ label: '合同名称', prop: 'contractName', minWidth: 140, formatter: textFormatter },
{ label: '付款方', prop: 'payerName', minWidth: 130, formatter: textFormatter },
+20 -105
View File
@@ -1,21 +1,18 @@
/**
* 正式结算单列表(avue-crud)配置
* ------------------------------------------------------------------
* 列表页与其它模块统一使用 avue-crud,头部 4 个按钮(刷新 / 列显隐 / 搜索显隐 /
* 显示方式)由 avue-crud 自带,不做二次封装。
* 列表页与其它模块统一使用 avue-crud,头部按钮(刷新 / 列显隐 / 显示方式)
* 由 avue-crud 自带,不做二次封装。
*
* 搜索栏与应收/应付明细页统一为页面级手写搜索区(见 formal-settlement.vue),
* 此处只保留表格列配置。
*
* 表格列复用 formalSettlementTable.js 的 formalSettlementTableColumns(与弹窗内
* 明细表共用同一份列定义),此处只补充 avue 需要的展示/搜索属性,避免两处维护。
*
* ⚠️ searchOrder 为降序排序,值越大越靠前。
* ⚠️ 仅用于搜索的列必须 hide + showColumn: false,否则会混进「列显隐」抽屉。
* ⚠️ column 数组顺序 = 表格列顺序,搜索专用列统一放在数组最前面。
* 明细表共用同一份列定义),此处只补充 avue 需要的展示属性,避免两处维护。
*/
import { formatSealTypes } from '@/utils/settlement-seal';
import {
approvalStatusOptions,
invoiceStatusOptions,
kingdeeSyncStatusOptions,
kingdeeWriteOffStatusOptions,
paymentStatusOptions,
@@ -34,47 +31,9 @@ const moneyFormatter = (row, value) =>
const pickLabel = (options, value) =>
options.find(item => item.value === value)?.label || value || '-';
const searchOnlyColumn = ({ label, prop, searchOrder, type = 'input', dicData }) => {
const column = {
label,
prop,
search: true,
searchOrder,
searchSpan: 5,
hide: true,
showColumn: false,
addDisplay: false,
editDisplay: false,
viewDisplay: false,
};
if (type === 'select') {
column.type = 'select';
column.searchPlaceholder = '请选择';
column.dicData = dicData || [];
} else if (type === 'daterange') {
column.type = 'daterange';
column.searchType = 'daterange';
column.searchPlaceholder = '请选择';
} else {
column.searchPlaceholder = '请输入';
}
return column;
};
/** 表格列的 avue 增量配置:搜索项、插槽、覆盖宽度等 */
/** 表格列的 avue 增量配置:插槽、覆盖宽度等 */
const COLUMN_EXTRA = {
formalSettlementNo: {
slot: true,
search: true,
searchSpan: 5,
searchOrder: 12,
searchPlaceholder: '请输入',
},
payerName: { search: true, searchSpan: 5, searchOrder: 7, searchPlaceholder: '请输入' },
payeeName: { search: true, searchSpan: 5, searchOrder: 6, searchPlaceholder: '请输入' },
projectName: { search: true, searchSpan: 5, searchOrder: 11, searchPlaceholder: '请输入' },
deptName: { search: true, searchslot: true, searchSpan: 5, searchOrder: 10 },
contractNo: { search: true, searchSpan: 5, searchOrder: 9, searchPlaceholder: '请输入' },
formalSettlementNo: { slot: true },
sealTypes: { formatter: sealTypesFormatter },
invoiceStatusName: { slot: true },
paymentStatusName: { slot: true },
@@ -82,27 +41,27 @@ const COLUMN_EXTRA = {
adjustFlag: {
formatter: row => row.adjustStatusName || (row.originFormalSettlementNo ? '调整后单' : '-'),
},
kingdeeSyncStatus: {
slot: true,
search: true,
type: 'select',
dicData: kingdeeSyncStatusOptions,
searchSpan: 5,
searchOrder: 2,
searchPlaceholder: '请选择',
},
kingdeeSyncStatus: { slot: true },
kingdeeLockStatus: { slot: true },
kingdeeWriteOffStatus: { slot: true },
kingdeeAssignStatus: { slot: true },
createTime: { width: 180 },
};
/** 收款/付款结算单按结算类型展示各自标签 */
const PAYMENT_FIELD_LABELS = {
paidAmount: { payable: '已付合计(含预付)', receivable: '已收合计(含预付)' },
paymentStatusName: { payable: '付款状态', receivable: '收款状态' },
};
// 已指定应付仅付款结算单(先票后款 A302-6)有,收款结算单不展示
const buildTableColumns = settlementType =>
formalSettlementTableColumns
.filter(column => !(settlementType === 'receivable' && column.prop === 'kingdeeAssignStatus'))
.map(column => {
const extra = { ...(COLUMN_EXTRA[column.prop] || {}) };
const label = PAYMENT_FIELD_LABELS[column.prop]?.[settlementType];
if (label) extra.label = label;
if (column.money) {
extra.formatter = moneyFormatter;
extra.align = 'right';
@@ -118,15 +77,6 @@ export const formalSettlementOption = (settlementType = '') => ({
height: 'auto',
calcHeight: 32,
tip: false,
searchBtnText: '查询',
emptyBtnText: '重置',
searchShow: true,
searchIcon: true,
searchLabelWidth: 100,
// 查询/重置紧跟首行 4 个条件(4×5 + 菜单 4 = 24),不再独占下一整行
searchMenuSpan: 4,
searchIndex: 4,
searchMenuPosition: 'right',
border: true,
index: true,
indexLabel: '序号',
@@ -141,45 +91,10 @@ export const formalSettlementOption = (settlementType = '') => ({
editBtn: false,
menuWidth: 320,
menuFixed: 'right',
column: [
// ---------- 仅搜索列 ----------
searchOnlyColumn({
label: '预付结算单号',
prop: 'preSettlementNo',
searchOrder: 8,
}),
searchOnlyColumn({
label: '发票状态',
prop: 'invoiceStatus',
searchOrder: 5,
type: 'select',
dicData: invoiceStatusOptions,
}),
searchOnlyColumn({
label: '收付款状态',
prop: 'paymentStatus',
searchOrder: 4,
type: 'select',
dicData: paymentStatusOptions,
}),
searchOnlyColumn({
label: '审核状态',
prop: 'approvalStatus',
searchOrder: 3,
type: 'select',
dicData: approvalStatusOptions,
}),
searchOnlyColumn({
label: '生成日期',
prop: 'createDateRange',
searchOrder: 1,
type: 'daterange',
}),
// ---------- 表格列(部分兼搜索项) ----------
...buildTableColumns(settlementType),
],
column: [...buildTableColumns(settlementType)],
});
export const kingdeeSyncName = value => pickLabel(kingdeeSyncStatusOptions, value);
export const kingdeeWriteOffName = value => pickLabel(kingdeeWriteOffStatusOptions, value);
export const paymentStatusName = value => pickLabel(paymentStatusOptions, value);
export const paymentStatusName = (value, settlementType) =>
pickLabel(paymentStatusOptions(settlementType), value);
+20 -39
View File
@@ -6,27 +6,28 @@ export const approvalStatusOptions = [
{ label: '已作废', value: 'voided' },
];
export const invoiceStatusOptions = [
{ label: '未开/收票', value: 'unreceived' },
{ label: '部分开/收票', value: 'partial' },
{ label: '已开/收票', value: 'completed' },
];
export const invoiceStatusName = (value, settlementType) => {
const payable = settlementType === 'payable';
const labels = {
unreceived: payable ? '未收票' : '未开票',
partial: payable ? '部分收票' : '部分开票',
completed: payable ? '已收票' : '已开票',
};
return labels[value] || value || '-';
/** 发票状态选项按结算类型区分:付款结算单=收票方向,收款结算单=开票方向 */
export const invoiceStatusOptions = (settlementType = '') => {
const received = settlementType === 'payable';
return [
{ label: received ? '未收票' : '未开票', value: 'unreceived' },
{ label: received ? '部分收票' : '部分开票', value: 'partial' },
{ label: received ? '已收票' : '已开票', value: 'completed' },
];
};
export const paymentStatusOptions = [
{ label: '未收/付款', value: 'unpaid' },
{ label: '部分收/付款', value: 'partial' },
{ label: '已收/付款', value: 'paid' },
];
export const invoiceStatusName = (value, settlementType) =>
invoiceStatusOptions(settlementType).find(item => item.value === value)?.label || value || '-';
/** 收付款状态选项按结算类型区分:付款结算单=付款方向,收款结算单=收款方向 */
export const paymentStatusOptions = (settlementType = '') => {
const suffix = settlementType === 'payable' ? '付款' : '收款';
return [
{ label: `未${suffix}`, value: 'unpaid' },
{ label: `部分${suffix}`, value: 'partial' },
{ label: `已${suffix}`, value: 'paid' },
];
};
export const kingdeeSyncStatusOptions = [
{ label: '未同步', value: 'unsynced' },
@@ -38,23 +39,3 @@ export const kingdeeWriteOffStatusOptions = [
{ label: '未冲销', value: 'unwrittenoff' },
{ label: '已冲销', value: 'writtenoff' },
];
export const formalSettlementSearchFields = [
{ label: '结算单号', prop: 'formalSettlementNo', type: 'input' },
{ label: '预付结算单号', prop: 'preSettlementNo', type: 'input' },
{ label: '项目', prop: 'projectName', type: 'input' },
{ label: '所属组织', prop: 'deptName', type: 'cascader' },
{ label: '合同编号', prop: 'contractNo', type: 'input' },
{ label: '付款方', prop: 'payerName', type: 'input' },
{ label: '收款方', prop: 'payeeName', type: 'input' },
{ label: '发票状态', prop: 'invoiceStatus', type: 'select', options: invoiceStatusOptions },
{ label: '收付款状态', prop: 'paymentStatus', type: 'select', options: paymentStatusOptions },
{ label: '审核状态', prop: 'approvalStatus', type: 'select', options: approvalStatusOptions },
{
label: '金蝶单据状态',
prop: 'kingdeeSyncStatus',
type: 'select',
options: kingdeeSyncStatusOptions,
},
{ label: '生成日期', prop: 'createDateRange', type: 'daterange' },
];