gaoluyang
6 天以前 98312d84f785c09574bfd5add730ea448fb0cbd5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<script lang="ts" setup>
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { FinAccountSubjectApi } from '#/api/erp/finance/subject';
 
import { nextTick, ref } from 'vue';
 
import { message, Modal } from 'ant-design-vue';
 
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getAccountSubjectPage } from '#/api/erp/finance/subject';
 
defineOptions({ name: 'FinAccountSelect' });
 
const emit = defineEmits<{
  selected: [subject: FinAccountSubjectApi.AccountSubject];
}>();
 
const open = ref(false); // 弹窗是否打开
const selectedRow = ref<FinAccountSubjectApi.AccountSubject>(); // 选中的科目
 
/** 表格配置 */
const [Grid, gridApi] = useVbenVxeGrid({
  formOptions: {
    schema: [
      {
        fieldName: 'subjectCode',
        label: '科目编码',
        component: 'Input',
        componentProps: { placeholder: '请输入科目编码', allowClear: true },
      },
      {
        fieldName: 'subjectName',
        label: '科目名称',
        component: 'Input',
        componentProps: { placeholder: '请输入科目名称', allowClear: true },
      },
    ],
  },
  gridOptions: {
    columns: [
      { type: 'radio', width: 50 },
      {
        field: 'subjectCode',
        title: '科目编码',
        minWidth: 140,
        treeNode: true,
      },
      { field: 'subjectName', title: '科目名称', minWidth: 200 },
      {
        field: 'subjectType',
        title: '科目类型',
        minWidth: 120,
        cellRender: {
          name: 'CellDict',
          props: { type: 'finance_subject_type' },
        },
      },
      {
        field: 'balanceDirection',
        title: '余额方向',
        minWidth: 100,
        cellRender: {
          name: 'CellDict',
          props: { type: 'finance_balance_direction' },
        },
      },
    ],
    height: 480,
    keepSource: true,
    radioConfig: {
      highlight: true,
      trigger: 'row',
    },
    proxyConfig: {
      ajax: {
        query: async (_params, formValues) => {
          // 树形展示不适用分页,一次性拉取全部命中科目
          const page = await getAccountSubjectPage({
            pageNo: 1,
            pageSize: -1,
            status: 0,
            ...formValues,
          });
          return {
            list: page.list,
            total: page.list.length,
          };
        },
      },
    },
    rowConfig: {
      keyField: 'id',
      isHover: true,
    },
    toolbarConfig: {
      refresh: true,
      search: true,
    },
    treeConfig: {
      parentField: 'parentId',
      rowField: 'id',
      transform: true,
      expandAll: true,
      reserve: true,
    },
  } as VxeTableGridOptions<FinAccountSubjectApi.AccountSubject>,
  gridEvents: {
    radioChange: ({ row }: { row: FinAccountSubjectApi.AccountSubject }) => {
      selectedRow.value = row;
    },
  },
});
 
/** 打开弹窗 */
async function openModal() {
  open.value = true;
  selectedRow.value = undefined;
  // 特殊:弹窗是 destroy-on-close,里面 Grid 随弹窗重建,必须等挂载完成后 gridApi 才有真实例
  // (vben 的 gridApi.grid 初始是空对象,mount 时才赋值),否则 clearRadioRow 会报 is not a function
  await nextTick();
  await gridApi.grid.clearRadioRow();
  await gridApi.formApi.resetForm();
  await gridApi.query();
}
 
/** 确认选择 */
function handleConfirm() {
  if (!selectedRow.value) {
    message.warning('请选择一条会计科目');
    return;
  }
  emit('selected', selectedRow.value);
  open.value = false;
}
 
defineExpose({ open: openModal });
</script>
 
<template>
  <Modal
    v-model:open="open"
    title="选择会计科目"
    width="70%"
    :destroy-on-close="true"
    @ok="handleConfirm"
    @cancel="open = false"
  >
    <Grid table-title="会计科目列表(仅启用状态的科目可被凭证引用)" />
  </Modal>
</template>