From fe2d6627b8f1002af7a31b08f6f43bec034d04ee Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期三, 21 十月 2026 18:29:07 +0800
Subject: [PATCH] feat: 完善课题、会员、财务、企微页面并新增资产/用车/采购
---
src/views/finance/reimbursement/modules/item-form.vue | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 53 insertions(+), 5 deletions(-)
diff --git a/src/views/finance/reimbursement/modules/item-form.vue b/src/views/finance/reimbursement/modules/item-form.vue
index 3c852a4..c87f1f5 100644
--- a/src/views/finance/reimbursement/modules/item-form.vue
+++ b/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>
--
Gitblit v1.9.3