fix: 修复前端报错 — VxeTable组件、MaterialSelectModal路径、dayjs类型

- 明细表改用 VxeTable + VxeColumn(项目标准模式)
- MaterialSelectModal 导入路径从 ../../ 改为 ../../../
- ref 类型简化为 any,去掉 InstanceType<typeof>
- dayjs 导入用于业务日期默认当天
This commit is contained in:
zhouz
2026-07-22 11:27:25 +08:00
parent 31a3906e24
commit ec05ee98d0
2 changed files with 30 additions and 51 deletions

View File

@@ -1,6 +1,4 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { WmsIostorInvApi } from '#/api/wms/iostorinv';
import { computed, ref, watch } from 'vue'; import { computed, ref, watch } from 'vue';
import { useVbenModal } from '@vben/common-ui'; import { useVbenModal } from '@vben/common-ui';
@@ -9,6 +7,7 @@ import dayjs from 'dayjs';
import { message } from 'antdv-next'; import { message } from 'antdv-next';
import { useVbenForm } from '#/adapter/form'; import { useVbenForm } from '#/adapter/form';
import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
import { import {
type OutboundCreateReq, type OutboundCreateReq,
type OutboundDetail, type OutboundDetail,
@@ -24,9 +23,7 @@ import ManualDetailModalComponent from './manual-detail.vue';
const emit = defineEmits(['success']); const emit = defineEmits(['success']);
// ========== 仓库选项 ========== // ========== 仓库选项 ==========
const storOptions = ref< const storOptions = ref<any[]>([]);
{ label: string; value: string; storCode: string; storName: string }[]
>([]);
async function loadStorOptions() { async function loadStorOptions() {
const list = await getBsrealStorAttrSimpleList(); const list = await getBsrealStorAttrSimpleList();
storOptions.value = (list || []).map((item: any) => ({ storOptions.value = (list || []).map((item: any) => ({
@@ -38,7 +35,7 @@ async function loadStorOptions() {
} }
// ========== 业务类型选项 ========== // ========== 业务类型选项 ==========
const billTypeOptions = ref<{ label: string; value: string }[]>([]); const billTypeOptions = ref<any[]>([]);
async function loadBillTypeOptions() { async function loadBillTypeOptions() {
const list = await getSimpleDictDataList(); const list = await getSimpleDictDataList();
billTypeOptions.value = (list || []) billTypeOptions.value = (list || [])
@@ -125,16 +122,13 @@ const [Form, formApi] = useVbenForm({
}); });
// ========== 明细数据 ========== // ========== 明细数据 ==========
type DetailRow = OutboundDetail & { vehicleCode?: string; materialName?: string }; const detailList = ref<any[]>([]);
const detailList = ref<DetailRow[]>([]);
function updateSummary() { function updateSummary() {
const totalWeight = detailList.value const total = detailList.value.reduce((sum, d) => sum + (Number(d.planQty) || 0), 0);
.reduce((sum, d) => sum + (Number(d.planQty) || 0), 0)
.toFixed(3);
formApi.setValues({ formApi.setValues({
detailCount: detailList.value.length, detailCount: detailList.value.length,
totalWeight: String(totalWeight), totalWeight: total.toFixed(3),
}); });
} }
@@ -147,34 +141,13 @@ watch(
}, },
); );
// ========== 明细表格 ==========
const vxeGridRef = ref();
const gridOptions = computed(() => ({
columns: [
{ type: 'seq', title: '序号', width: 50 },
{ field: 'vehicleCode', title: '箱号', width: 100 },
{ field: 'materialCode', title: '物料编码', width: 120 },
{ field: 'materialName', title: '物料名称', width: 150 },
{ field: 'pcsn', title: '子卷号', width: 100 },
{ field: 'planQty', title: '出库重量', width: 100 },
{ field: 'qtyUnitName', title: '单位', width: 60 },
{ field: 'remark', title: '备注', width: 120 },
{ title: '操作', width: 80, slots: { default: 'actions' } },
],
data: detailList.value,
height: 'auto',
rowConfig: { keyField: 'materialCode', isHover: true },
toolbarConfig: false,
pagerConfig: false,
}));
function handleDeleteDetail(index: number) { function handleDeleteDetail(index: number) {
detailList.value.splice(index, 1); detailList.value.splice(index, 1);
updateSummary(); updateSummary();
} }
// ========== 库存选择弹窗(子组件自带 Modal用 ref 调用 open ========== // ========== 库存选择弹窗 ==========
const inventorySelectRef = ref<InstanceType<typeof InventorySelectModalComponent>>(); const inventorySelectRef = ref<any>();
function handleSelectFromInventory() { function handleSelectFromInventory() {
const storId = formApi.getValues().storId; const storId = formApi.getValues().storId;
@@ -204,8 +177,8 @@ function onInventorySelected(rows: any[]) {
updateSummary(); updateSummary();
} }
// ========== 手动新增弹窗(子组件自带 Modal用 ref 调用 open ========== // ========== 手动新增弹窗 ==========
const manualDetailRef = ref<InstanceType<typeof ManualDetailModalComponent>>(); const manualDetailRef = ref<any>();
function handleManualAdd() { function handleManualAdd() {
manualDetailRef.value?.open(); manualDetailRef.value?.open();
@@ -247,7 +220,7 @@ const [Modal, modalApi] = useVbenModal({
storName: stor?.storName, storName: stor?.storName,
bizDate: masterValues.bizDate, bizDate: masterValues.bizDate,
remark: masterValues.remark, remark: masterValues.remark,
details: detailList.value.map((d) => ({ details: detailList.value.map((d: any) => ({
materialCode: d.materialCode, materialCode: d.materialCode,
materialId: d.materialId, materialId: d.materialId,
pcsn: d.pcsn, pcsn: d.pcsn,
@@ -274,10 +247,7 @@ const [Modal, modalApi] = useVbenModal({
if (isOpen) { if (isOpen) {
await loadStorOptions(); await loadStorOptions();
await loadBillTypeOptions(); await loadBillTypeOptions();
// 业务日期默认当天 formApi.setValues({ bizDate: dayjs().format('YYYY-MM-DD HH:mm:ss') });
formApi.setValues({
bizDate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
});
} }
if (!isOpen) { if (!isOpen) {
detailList.value = []; detailList.value = [];
@@ -303,17 +273,26 @@ const [Modal, modalApi] = useVbenModal({
</div> </div>
</div> </div>
<vxe-grid ref="vxeGridRef" v-bind="gridOptions"> <VxeTable :data="detailList" show-overflow>
<template #actions="{ rowIndex }"> <VxeColumn type="seq" title="序号" width="50" align="center" />
<a-button type="link" danger @click="handleDeleteDetail(rowIndex)"> <VxeColumn field="vehicleCode" title="箱号" width="100" />
<VxeColumn field="materialCode" title="物料编码" width="120" />
<VxeColumn field="materialName" title="物料名称" width="150" />
<VxeColumn field="pcsn" title="子卷号" width="100" />
<VxeColumn field="planQty" title="出库重量" width="100" />
<VxeColumn field="qtyUnitName" title="单位" width="60" />
<VxeColumn field="remark" title="备注" min-width="120" />
<VxeColumn title="操作" width="80" align="center" fixed="right">
<template #default="{ rowIndex }">
<a-button type="link" danger size="small" @click="handleDeleteDetail(rowIndex)">
删除 删除
</a-button> </a-button>
</template> </template>
</vxe-grid> </VxeColumn>
</VxeTable>
</div> </div>
</div> </div>
<!-- 子弹窗不通过 connectedComponent而是通过 ref 调用 -->
<InventorySelectModalComponent <InventorySelectModalComponent
ref="inventorySelectRef" ref="inventorySelectRef"
@select="onInventorySelected" @select="onInventorySelected"

View File

@@ -5,7 +5,7 @@ import { useVbenModal } from '@vben/common-ui';
import { useVbenForm } from '#/adapter/form'; import { useVbenForm } from '#/adapter/form';
import MaterialSelectModalComponent from '../../base/materialbase/components/MaterialSelectModal.vue'; import MaterialSelectModalComponent from '../../../base/materialbase/components/MaterialSelectModal.vue';
const emit = defineEmits(['confirm']); const emit = defineEmits(['confirm']);