liu
3 天以前 fe2d6627b8f1002af7a31b08f6f43bec034d04ee
src/views/finance/reimbursement/modules/item-form.vue
@@ -1,21 +1,35 @@
<script lang="ts" setup>
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { FinanceReimbursementAiApi } from '#/api/finance/reimbursement/ai';
import type { FinanceReimbursementApi } from '#/api/finance/reimbursement';
import type { SystemStorageApi } from '#/api/system/storage';
import type { DefaultOptionType } from 'ant-design-vue/es/select';
import { nextTick, watch } from 'vue';
import { nextTick, ref, watch } from 'vue';
import { DICT_TYPE } from '@vben/constants';
import { getDictOptions } from '@vben/hooks';
import { erpPriceInputFormatter } from '@vben/utils';
import { Button, DatePicker, Input, InputNumber, Select } from 'ant-design-vue';
import {
  Button,
  DatePicker,
  Input,
  InputNumber,
  Select,
  message,
} from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { $t } from '#/locales';
import { toSubmitItems, useItemColumns } from '../data';
import {
  INVOICE_TYPE_OPTIONS,
  toSubmitItems,
  useItemColumns,
} from '../data';
import OcrUpload from './ocr-upload.vue';
const props = withDefaults(
  defineProps<{
@@ -28,7 +42,13 @@
  },
);
const emit = defineEmits(['update:items', 'update:totalAmount']);
const emit = defineEmits<{
  'ocr-blobs': [blobs: SystemStorageApi.StorageBlob[]];
  'update:items': [items: FinanceReimbursementApi.ReimbursementItem[]];
  'update:totalAmount': [totalAmount: number];
}>();
const ocrUploadRef = ref<InstanceType<typeof OcrUpload>>();
const expenseTypeOptions = getDictOptions(
  DICT_TYPE.FINANCE_EXPENSE_TYPE,
@@ -101,6 +121,22 @@
  recalc();
}
/** OCR 识别结果:追加为明细行,并把发票文件同步给主表附件 */
async function handleOcrSuccess(
  payload: FinanceReimbursementAiApi.OcrImportPayload,
) {
  for (const item of payload.items) {
    await gridApi.grid.insertAt(item, -1);
  }
  recalc();
  message.success(
    `已填入 ${payload.items.length} 条发票明细,请补充费用类型后提交`,
  );
  if (payload.blobs.length > 0) {
    emit('ocr-blobs', payload.blobs);
  }
}
/** 删除明细行 */
async function handleDelete(row: FinanceReimbursementApi.ReimbursementItem) {
  await gridApi.grid.remove(row);
@@ -146,6 +182,7 @@
</script>
<template>
  <OcrUpload ref="ocrUploadRef" @success="handleOcrSuccess" />
  <Grid class="w-full">
    <template #expenseType="{ row }">
      <Select
@@ -153,6 +190,16 @@
        :disabled="disabled"
        :options="expenseTypeOptions"
        placeholder="请选择费用类型"
        allow-clear
        @change="() => recalc()"
      />
    </template>
    <template #invoiceType="{ row }">
      <Select
        v-model:value="row.invoiceType"
        :disabled="disabled"
        :options="INVOICE_TYPE_OPTIONS"
        placeholder="请选择发票类型"
        allow-clear
        @change="() => recalc()"
      />
@@ -217,7 +264,8 @@
      />
    </template>
  </Grid>
  <div v-if="!disabled" class="-mt-4 flex justify-center">
  <div v-if="!disabled" class="-mt-4 flex justify-center gap-2">
    <Button @click="ocrUploadRef?.open()">OCR 识别发票</Button>
    <Button type="primary" ghost @click="handleAdd"> 添加报销明细 </Button>
  </div>
</template>