From 1ed040591afdcbe3c5df42ad5e02e2cfa56edd87 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 20 十月 2026 11:19:20 +0800
Subject: [PATCH] feat(mobile): 优化移动端质检记录界面功能
---
src/views/mes/pro/batch/modules/form.vue | 122 ++++++++++++++++++++++++++++++++++++----
1 files changed, 109 insertions(+), 13 deletions(-)
diff --git a/src/views/mes/pro/batch/modules/form.vue b/src/views/mes/pro/batch/modules/form.vue
index f27d9bb..f405c55 100644
--- a/src/views/mes/pro/batch/modules/form.vue
+++ b/src/views/mes/pro/batch/modules/form.vue
@@ -5,7 +5,7 @@
import type { MesProBatchApi } from "#/api/mes/pro/batch";
import type { SystemUserApi } from "#/api/system/user";
- import { computed, nextTick, ref } from "vue";
+ import { computed, nextTick, reactive, ref } from "vue";
import { useVbenModal } from "@vben/common-ui";
import { DICT_TYPE } from "@vben/constants";
@@ -38,8 +38,77 @@
const formType = ref<FormType>("create");
const formData = ref<MesProBatchApi.Batch>();
- let palletOptions: PalletOption[] = [];
- let tonBagOptions: TonBagOption[] = [];
+ const BINDING_OPTION_PAGE_SIZE = 50;
+ const BINDING_SCROLL_THRESHOLD = 32;
+ let palletOptionSource: PalletOption[] = [];
+ let tonBagOptionSource: TonBagOption[] = [];
+ const palletOptions = reactive<PalletOption[]>([]);
+ const tonBagOptions = reactive<TonBagOption[]>([]);
+ let palletKeyword = "";
+ let tonBagKeyword = "";
+
+ function filterBindingOptions<T extends PalletOption>(source: T[], keyword: string): T[] {
+ const normalized = keyword.trim().toLowerCase();
+ if (!normalized) return source;
+ return source.filter((option) => option.label.toLowerCase().includes(normalized));
+ }
+
+ function resetBindingOptions<T extends PalletOption>(
+ target: T[],
+ source: T[],
+ keyword = ""
+ ) {
+ const filtered = filterBindingOptions(source, keyword);
+ target.splice(0, target.length, ...filtered.slice(0, BINDING_OPTION_PAGE_SIZE));
+ }
+
+ function appendBindingOptions<T extends PalletOption>(
+ target: T[],
+ source: T[],
+ keyword: string
+ ) {
+ const filtered = filterBindingOptions(source, keyword);
+ if (target.length >= filtered.length) return;
+ target.push(...filtered.slice(target.length, target.length + BINDING_OPTION_PAGE_SIZE));
+ }
+
+ function isPopupNearBottom(event: Event) {
+ const element = event.target as HTMLElement;
+ return element.scrollHeight - element.scrollTop - element.clientHeight <= BINDING_SCROLL_THRESHOLD;
+ }
+
+ function handlePalletSearch(keyword: string) {
+ palletKeyword = keyword;
+ resetBindingOptions(palletOptions, palletOptionSource, keyword);
+ }
+
+ function handleTonBagSearch(keyword: string) {
+ tonBagKeyword = keyword;
+ resetBindingOptions(tonBagOptions, tonBagOptionSource, keyword);
+ }
+
+ function handlePalletPopupScroll(event: Event) {
+ if (isPopupNearBottom(event)) {
+ appendBindingOptions(palletOptions, palletOptionSource, palletKeyword);
+ }
+ }
+
+ function handleTonBagPopupScroll(event: Event) {
+ if (isPopupNearBottom(event)) {
+ appendBindingOptions(tonBagOptions, tonBagOptionSource, tonBagKeyword);
+ }
+ }
+
+ const palletHandlers = {
+ onChange: handlePalletChange,
+ onPopupScroll: handlePalletPopupScroll,
+ onSearch: handlePalletSearch,
+ };
+ const tonBagHandlers = {
+ onChange: handleTonBagChange,
+ onPopupScroll: handleTonBagPopupScroll,
+ onSearch: handleTonBagSearch,
+ };
async function handlePalletChange(ids: number[] = []) {
const values = await formApi.getValues();
if (ids.length && (values.tonBagIds?.length || formData.value?.bindingMode === 'tonBag')) {
@@ -47,7 +116,7 @@
await formApi.setFieldValue('palletIds', []);
return;
}
- const selected = palletOptions.filter(option => ids.includes(option.value));
+ const selected = palletOptionSource.filter(option => ids.includes(option.value));
const source = formData.value?.itemId ? formData.value : selected[0];
if (selected.some(option => !option.itemId || (source?.itemId && option.itemId !== source.itemId))) {
message.warning('鐢熶骇鎵规鍙兘缁戝畾鐩稿悓鍝佺鐨勬墭鐩�');
@@ -65,7 +134,7 @@
await formApi.setFieldValue('tonBagIds', []);
return;
}
- const selected = tonBagOptions.filter(option => ids.includes(option.value));
+ const selected = tonBagOptionSource.filter(option => ids.includes(option.value));
const source = formData.value?.itemId ? formData.value : selected[0];
if (selected.some(option => option.itemId !== source?.itemId)) {
message.warning('鐢熶骇鎵规鍙兘缁戝畾鐩稿悓鍝佺鐨勫惃琚�');
@@ -129,8 +198,9 @@
let workerRowSeq = 0;
/** 娣诲姞浜哄憳琛� */
- function handleAddWorker() {
- workerGridApi.grid.insertAt({ _rowKey: -(++workerRowSeq) }, -1);
+ async function handleAddWorker() {
+ await waitWorkerGridReady();
+ await workerGridApi.grid.insertAt({ _rowKey: -(++workerRowSeq) }, -1);
}
/** 鍒犻櫎浜哄憳琛� */
@@ -250,22 +320,47 @@
const data = modalApi.getData<{ formType: FormType; id?: number }>();
formType.value = data.formType;
// 鏂板/琛ュ綍/缂栬緫鎬佸姞杞芥湭缁戝畾鎵规鐨勬墭鐩橈紝渚涖�岀粦瀹氭墭鐩樸�嶅閫変笅鎷変娇鐢�
- palletOptions = [];
- tonBagOptions = [];
+ palletOptionSource = [];
+ tonBagOptionSource = [];
+ palletOptions.splice(0);
+ tonBagOptions.splice(0);
+ palletKeyword = "";
+ tonBagKeyword = "";
+ // 鍏堟寕杞藉熀纭�琛ㄥ崟锛屽�欓�夋墭鐩�/鍚ㄨ鍦ㄥ悗鍙板姞杞斤紝閬垮厤鍙樉绀轰汉鍛橀厤缃殑绌虹獥鏈�
+ formApi.setState({
+ schema: useFormSchema(
+ formType.value,
+ palletOptions,
+ palletHandlers,
+ tonBagOptions,
+ tonBagHandlers
+ ),
+ });
if (formType.value !== "detail") {
const [pallets, tonBags] = await Promise.all([getUnboundPalletList(), getUnboundTonBags()]);
- palletOptions = pallets.map((pallet) => ({
+ palletOptionSource = pallets.map((pallet) => ({
label: `${pallet.tempCode ?? `鎵樼洏${pallet.id}`} 路 ${pallet.itemName || "寰呭畬鍠勫搧绉�"}锛堝凡瑁� ${pallet.bagCount ?? 0} 琚嬶級`,
value: pallet.id as number,
itemId: pallet.itemId, itemName: pallet.itemName, itemCode: pallet.itemCode,
}));
- tonBagOptions = tonBags.map((bag) => ({
+ tonBagOptionSource = tonBags.map((bag) => ({
label: `${bag.code ?? `鍚ㄨ${bag.id}`} 路 ${bag.itemName || '寰呭畬鍠勫搧绉�'}`,
value: bag.id as number,
itemId: bag.itemId, itemName: bag.itemName, itemCode: bag.itemCode,
}));
+ resetBindingOptions(palletOptions, palletOptionSource);
+ resetBindingOptions(tonBagOptions, tonBagOptionSource);
}
- formApi.setState({ schema: useFormSchema(formType.value, palletOptions, handlePalletChange, tonBagOptions, handleTonBagChange) });
+ // 閲嶆柊鍚屾涓�娆� Schema锛屼娇渚濊禆瀛楁涓殑鍔ㄦ�� options 绔嬪嵆鎷垮埌棣栨壒鍊欓�夐」
+ formApi.setState({
+ schema: useFormSchema(
+ formType.value,
+ palletOptions,
+ palletHandlers,
+ tonBagOptions,
+ tonBagHandlers
+ ),
+ });
if (formType.value !== "detail") {
// 娓呯┖涓婃鎵撳紑鏃跺嬀閫夌殑鎵樼洏锛岄伩鍏嶆畫鐣欏�艰瑙﹀彂銆屾壒娆¤繘鍏ョ敓浜т腑銆�
await formApi.setFieldValue("palletIds", undefined);
@@ -282,7 +377,7 @@
try {
formData.value = await getBatch(data.id);
const existingBinding = formData.value.bindingMode;
- formApi.setState({ schema: useFormSchema(formType.value, palletOptions, handlePalletChange, tonBagOptions, handleTonBagChange, existingBinding) });
+ formApi.setState({ schema: useFormSchema(formType.value, palletOptions, palletHandlers, tonBagOptions, tonBagHandlers, existingBinding) });
await formApi.setValues(formData.value);
const workers = (formData.value.workers ?? []).map(
(worker, index) => ({ ...worker, _rowKey: worker.id ?? index })
@@ -295,6 +390,7 @@
} else {
await waitWorkerGridReady();
await workerGridApi.grid.loadData([]);
+ await handleAddWorker();
}
},
});
--
Gitblit v1.9.3