Files
finance-master/apps/finance/src/views/posting/reconciliate/components/Selected.vue
chenghuan 8971243f23 feat(对账): 新增批量对账功能并优化对账流程
- 添加批量对账模式,支持按金额批量选择账单
- 优化rowKey处理逻辑
- 调整对账表单验证规则,增加金额校验
- 修改时间单位从月到天,提高精确度
- 优化选中账单展示,增加标记和计数功能
- 修复SelectDropdownRender组件选项更新问题
2026-01-16 14:21:14 +08:00

187 lines
4.3 KiB
Vue

<script lang="ts" setup>
import type { CreateOrderType } from '../types';
import { computed, ref, watch } from 'vue';
import { Button } from 'ant-design-vue';
import { reconciliateBillsApi } from '#/api/posting/reconciliate';
import { useCardList } from '#/components/card-list/index';
interface RecommendedUser {
tel: string;
}
const props = withDefaults(
defineProps<{
errorItem: CreateOrderType[];
isBatchMode: boolean;
}>(),
{},
);
const emit = defineEmits(['deletedChecked']);
const errorData = ref<any[]>([]);
watch(
() => props.errorItem,
(newVal) => {
errorData.value = newVal.map((item) => ({
id: item.id,
}));
gridApi.setErrorItems(errorData.value);
},
{ deep: true },
);
const gridOptions = computed(() => ({
columns: [
// { field: 'productName', title: '名称' },
{
field: 'orderType',
title: '类型',
formatter: (value: string) => {
const typeMap: Record<string, string> = {
'0': '充值',
'1': 'VIP',
'2': '课程',
'3': '实物',
'4': '培训班',
};
return typeMap[value] || value;
},
},
{
field: 'come',
title: '来源',
formatter: (value: string) => {
const comeMap: Record<string, string> = {
'0': '一路健康',
'1': '吴门医述',
'2': '手动添加',
};
return comeMap[value] || value;
},
},
{
editRender: {
name: 'SelectDropdownRender',
props: {
fetchOptions: (row: CreateOrderType) =>
reconciliateBillsApi
.getRecommendUser({
paymentId: row.paymentId,
come: row.come,
orderType: row.orderType,
courseId: row.courseId ?? '',
vipType: row.vipType ?? '',
})
.then(
(data) =>
data.list.map((item: RecommendedUser) => ({
value: item.tel,
})) || [],
),
allowClear: true,
},
},
field: 'tel',
title: '用户手机号',
colSpan: 2,
show: () => !props.isBatchMode,
},
{ editRender: { name: 'Input' }, field: 'orderMoney', title: '订单金额' },
{ editRender: { name: 'Input' }, field: 'realMoney', title: '实际金额' },
{
editRender: {
name: 'DatePicker',
props: {
valueFormat: 'YYYY-MM-DD',
},
},
// 仅VIP 和课程订单 显示
show: (row: CreateOrderType) =>
!props.isBatchMode && (row.orderType === '1' || row.orderType === '2'),
field: 'startTime',
title: '开始时间',
},
{
editRender: {
name: 'Select',
props: {
options: [
{ label: '1个月', value: '30' },
{ label: '3个月', value: '90' },
{ label: '半年', value: '180' },
{ label: '一年', value: '365' },
{ label: '两年', value: '730' },
{ label: '三年', value: '1095' },
{ label: '四年', value: '1460' },
],
},
},
// 仅VIP 和课程订单 显示
show: (row: CreateOrderType) => row.orderType === '1' || row.orderType === '2',
field: 'endTime',
title: '到期时间',
},
],
cardConfig: {
keyField: 'id',
},
showTitle: true,
titleField: 'productName',
gridColumns: 3,
fieldColumns: 2,
gridHeight: '220px',
cardHeight: '210px',
}));
const [Grid, gridApi] = useCardList<CreateOrderType>({
gridOptions: gridOptions.value,
});
// 添加选中项
function handleAdd(rows: CreateOrderType[]) {
gridApi.insertAt(rows);
}
// 卡片删除触发
function handleDelete(row: CreateOrderType) {
emit('deletedChecked', [row.id]);
}
// 删除数据
function deleteData(id: number) {
const index = getData().findIndex((item) => item.id === id);
gridApi.remove(index);
}
// 清空已选
function clearData() {
gridApi.clear();
}
function getData() {
return gridApi.getData();
}
defineExpose({
getData,
handleAdd,
handleDelete,
clearData,
deleteData,
});
</script>
<template>
<Grid>
<template #card-extra="{ row }">
<Button type="link" size="small" danger @click.stop="handleDelete(row)">删除</Button>
</template>
</Grid>
</template>
<style scoped lang="scss"></style>