From 46624ce480a3c14da21f39cc4ad5f7eecea2bb1e Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 17 九月 2026 16:24:28 +0800
Subject: [PATCH] feat(mes): 优化生产批次和袋码管理功能

---
 src/api/mdm/unit/index.ts                               |    1 
 src/views/wls/transaction/data.ts                       |    3 
 src/views/basicData/mdm/unit/data.ts                    |   24 +
 src/views/mes/pro/batch/index.vue                       |    3 
 src/views/basicData/mdm/components/data.ts              |   24 -
 src/api/mes/pro/pallet/index.ts                         |   11 
 src/views/mes/pro/bagCode/modules/bind-pallet.vue       |    4 
 src/views/erp/purchase/order/modules/item-form.vue      |    2 
 src/views/wls/barcode/components/detail.vue             |    5 
 src/views/mes/pro/pallet/index.vue                      |    4 
 src/views/basicData/mdm/index.vue                       |   54 ----
 src/api/mes/pro/bagCode/index.ts                        |   31 ++
 src/views/mes/pro/pallet/modules/generate-form.vue      |   12 
 src/views/mes/pro/bagCode/modules/generate-form.vue     |  165 +++++++++++-
 src/api/mdm/item/index.ts                               |    4 
 src/views/basicData/mdm/components/select-dialog.vue    |   28 --
 src/views/mes/pro/pallet/data.ts                        |    5 
 src/views/mes/pro/bagCode/index.vue                     |   18 +
 src/views/basicData/mdm/modules/form.vue                |    8 
 src/views/mes/pro/pallet/modules/bind-batch.vue         |    3 
 src/views/erp/purchase/request/modules/item-form.vue    |    2 
 src/views/mes/pro/batch/modules/form.vue                |   18 +
 src/api/mes/pro/batch/index.ts                          |   16 
 src/views/basicData/mdm/data.ts                         |   59 ----
 src/views/mes/pro/bagCode/modules/raw-generate-form.vue |  100 +++++++
 src/views/mes/pro/bagCode/data.ts                       |   22 +
 src/views/mes/pro/batch/data.ts                         |  105 ++++---
 27 files changed, 454 insertions(+), 277 deletions(-)

diff --git a/src/api/mdm/item/index.ts b/src/api/mdm/item/index.ts
index d950b6e..b4fccdb 100644
--- a/src/api/mdm/item/index.ts
+++ b/src/api/mdm/item/index.ts
@@ -10,8 +10,6 @@
     name: string;
     barCode?: string;
     specification?: string;
-    categoryId?: number;
-    categoryName?: string;
     unitMeasureId?: number;
     unitMeasureName?: string;
     unitMeasureId2?: number;
@@ -24,7 +22,6 @@
     brandName?: string;
     itemType: number;
     status: number;
-    purchasePrice?: number;
     salesPrice?: number;
     costPrice?: number;
     safetyStock?: number;
@@ -54,7 +51,6 @@
   export interface PageParams extends PageParam {
     code?: string;
     name?: string;
-    categoryId?: number;
     itemType?: number;
     status?: number;
   }
diff --git a/src/api/mdm/unit/index.ts b/src/api/mdm/unit/index.ts
index 6b437ba..084cdee 100644
--- a/src/api/mdm/unit/index.ts
+++ b/src/api/mdm/unit/index.ts
@@ -8,6 +8,7 @@
     id?: number; // 鍗曚綅缂栧彿
     code: string; // 鍗曚綅缂栫爜
     name: string; // 鍗曚綅鍚嶇О
+    type?: string; // 绫诲瀷锛�48鍗冨厠/100鍗冨厠/鍚級
     primaryFlag?: boolean; // 鏄惁涓诲崟浣�
     primaryId?: number; // 涓诲崟浣嶇紪鍙�
     changeRate?: number; // 涓庝富鍗曚綅鎹㈢畻姣斾緥
diff --git a/src/api/mes/pro/bagCode/index.ts b/src/api/mes/pro/bagCode/index.ts
index 22d4b6e..5504d17 100644
--- a/src/api/mes/pro/bagCode/index.ts
+++ b/src/api/mes/pro/bagCode/index.ts
@@ -15,6 +15,9 @@
     lineName?: string; // 浜х嚎鍚嶇О
     palletId?: number; // 缁戝畾鎵樼洏缂栧彿
     palletCode?: string; // 鎵樼洏鐮�
+    itemId?: number; // 鍝佺锛堢墿鏂欙級缂栧彿
+    itemCode?: string; // 鍝佺缂栫爜
+    itemName?: string; // 鍝佺鍚嶇О
     status?: number; // 鐘舵�侊紙瀛楀吀 mes_pro_bag_code_status锛�
     printTime?: string; // 瀵煎嚭锛堜氦浠樺嵃鍒凤級鏃堕棿
     cancelTime?: string; // 浣滃簾鏃堕棿
@@ -30,18 +33,32 @@
     batchCode?: string;
     uuid?: string;
     palletId?: number;
+    itemId?: number;
     status?: number;
     createTime?: string[];
   }
 
-  /** 鐢熸垚鏁版嵁鍖呰姹� */
+  /** 鐢熸垚鏁版嵁鍖呰姹傦紙鍝佺涓昏閲忓崟浣嶇被鍨嬩负 N鍗冨厠 鏃舵寜鎵樼洏鏁版崲绠楄鏁帮紱涓� 鍚� 鏃舵棤鎵樼洏銆佺洿鎺ヨ緭鍏ヨ鐮佹暟锛� */
   export interface GenerateParams {
-    count: number; // 鐢熸垚琚嬫暟
+    itemId: number; // 鍝佺锛堢墿鏂欙級缂栧彿
+    palletCount?: number; // 鎵樼洏鏁帮紙48鍗冨厠/100鍗冨厠 鍝佺蹇呭~锛�
+    bagCount?: number; // 琚嬬爜鏁帮紙鍚ㄥ搧绉嶅繀濉級
     remark?: string; // 澶囨敞
   }
 
   export interface GenerateResult {
-    uuid?: string;
+    uuid?: string; // 鐢熸垚缁� UUID
+    type?: string; // 鍝佺涓昏閲忓崟浣嶇被鍨嬶紙48鍗冨厠/100鍗冨厠/鍚級
+    perPallet?: number; // 姣忔墭琚嬫暟锛堝惃鍝佺涓� 0锛�
+    totalCount?: number; // 鐢熸垚琚嬬爜鎬绘暟
+    palletIds?: number[]; // 鑷姩鐢熸垚鐨勬墭鐩樼紪鍙峰垪琛紙鍚ㄥ搧绉嶄负绌猴級
+  }
+
+  /** 鐢熸垚鍘熷琚嬬爜璇锋眰锛堜粎鍝佺+琚嬬爜鏁伴噺锛屼笉鍏宠仈璁¢噺鍗曚綅绫诲瀷銆佷笉鐢熸垚鎵樼洏锛� */
+  export interface RawGenerateParams {
+    itemId: number; // 鍝佺锛堢墿鏂欙級缂栧彿
+    count: number; // 琚嬬爜鏁伴噺
+    remark?: string; // 澶囨敞
   }
 
   export interface BindBatchParams {
@@ -125,6 +142,14 @@
   );
 }
 
+/** 鐢熸垚鍘熷琚嬬爜锛堜粎閫夊搧绉嶄笌琚嬬爜鏁伴噺锛屼笉鐢熸垚鎵樼洏锛涜繑鍥炵敓鎴愮粍 UUID锛� */
+export function generateRawBagCodes(data: MesProBagCodeApi.RawGenerateParams) {
+  return requestClient.post<MesProBagCodeApi.GenerateResult>(
+    '/mes/pro/bag-code/raw-generate',
+    data,
+  );
+}
+
 /** 褰曞叆鐢熶骇鎵规 */
 export function bindBagCodeBatch(data: MesProBagCodeApi.BindBatchParams) {
   return requestClient.put('/mes/pro/bag-code/bind-batch', data);
diff --git a/src/api/mes/pro/batch/index.ts b/src/api/mes/pro/batch/index.ts
index 86544c8..0f9aae7 100644
--- a/src/api/mes/pro/batch/index.ts
+++ b/src/api/mes/pro/batch/index.ts
@@ -20,15 +20,12 @@
     id?: number; // 缂栧彿
     code?: string; // 鎵规鍙凤紙琛ュ綍姝e紡淇℃伅鍚庤嚜鍔ㄧ敓鎴愶級
     tempCode?: string; // 涓存椂鎵规鐮侊紙棰勭敓鎴愪簩缁寸爜闃舵浣跨敤锛屾壂鐮佽拷婧吋瀹癸級
-    itemId?: number; // 鍝佺锛堜骇鍝佺墿鏂欙級缂栧彿
-    itemCode?: string; // 鍝佺缂栫爜锛堝悗绔嫾鎺ワ級
-    itemName?: string; // 鍝佺鍚嶇О锛堝悗绔嫾鎺ワ級
-    itemSpecification?: string; // 鍝佺瑙勬牸锛堝悗绔嫾鎺ワ級
-    lineId?: number; // 浜х嚎缂栧彿
-    lineCode?: string; // 浜х嚎缂栫爜锛堝悗绔洖濉級
-    lineName?: string; // 浜х嚎鍚嶇О锛堝悗绔洖濉級
+    lineId?: number; // 浜х嚎缂栧彿锛堥〉闈㈠睍绀轰负銆屽姞宸ュ崟浣嶃�嶏級
+    lineCode?: string; // 浜х嚎缂栫爜锛堝悗绔洖濉紝椤甸潰宸查殣钘忥級
+    lineName?: string; // 浜х嚎鍚嶇О锛堝悗绔洖濉紝椤甸潰灞曠ず涓恒�屽姞宸ュ崟浣嶃�嶏級
+    processingTeam?: string; // 鍔犲伐鐝粍锛堟墜宸ュ~鍐欙級
     produceDate?: string; // 鐢熶骇鏃ユ湡
-    planQuantity?: number; // 璁″垝鏁伴噺
+    planQuantity?: number; // 鍔犲伐鏁伴噺锛堝師璁″垝鏁伴噺锛岄〉闈㈠睍绀轰负銆屽姞宸ユ暟閲忋�嶏級
     ownerUserId?: number; // 璐d换浜虹敤鎴风紪鍙�
     ownerUserName?: string; // 璐d换浜烘樀绉�
     bagQuantity?: number; // 宸茬敓鎴愯鐮佹暟閲�
@@ -37,6 +34,7 @@
     remark?: string; // 澶囨敞
     createTime?: string; // 鍒涘缓鏃堕棿
     workers?: BatchWorker[]; // 鐢熶骇浜哄憳閰嶇疆鍒楄〃
+    palletIds?: number[]; // 缁戝畾鎵樼洏缂栧彿鍒楄〃锛堜粎鏂板/琛ュ綍鎻愪氦鏃朵紶鍏ワ紝缁戝畾鏃舵壒娆$洿鎺ヨ繘鍏ョ敓浜т腑锛�
   }
 
   /** 鐢熶骇鎵规鎵爜杩芥函 */
@@ -68,10 +66,10 @@
   export interface PageParams extends PageParam {
     code?: string;
     tempCode?: string;
-    itemId?: number;
     lineId?: number;
     lineCode?: string;
     lineName?: string;
+    processingTeam?: string;
     ownerUserId?: number;
     status?: number;
     produceDate?: string[];
diff --git a/src/api/mes/pro/pallet/index.ts b/src/api/mes/pro/pallet/index.ts
index 7ae540b..8fca583 100644
--- a/src/api/mes/pro/pallet/index.ts
+++ b/src/api/mes/pro/pallet/index.ts
@@ -12,7 +12,7 @@
     batchId?: number; // 鐢熶骇鎵规缂栧彿
     batchCode?: string; // 鎵规鍙�
     palletNo?: number; // 鎵规鍐呮墭鐩樺簭鍙�
-    capacity?: number; // 鍙琚嬫暟锛堣/鎵樼洏锛�
+    autoGenerated?: boolean; // 鏄惁鑷姩鐢熸垚锛堣鐮佹暟鎹寘鐢熸垚鏃惰嚜鍔ㄥ垱寤猴級
     bagCount?: number; // 宸茬粦瀹氳鐮佹暟閲�
     status?: number; // 鐘舵�侊紙瀛楀吀 mes_pro_pallet_status锛�
     remark?: string; // 澶囨敞
@@ -58,7 +58,6 @@
   export interface BatchCreateParams {
     batchId: number; // 鐢熶骇鎵规缂栧彿
     count: number; // 鐢熸垚鏁伴噺
-    capacity?: number; // 鍙琚嬫暟
     remark?: string; // 澶囨敞
   }
 
@@ -77,7 +76,6 @@
 /** 棰勭敓鎴愭墭鐩樹复鏃朵簩缁寸爜锛堜笉缁戝畾鐢熶骇鎵规锛� */
 export function preGeneratePallet(data: {
   count: number;
-  capacity?: number;
   remark?: string;
 }) {
   return requestClient.post<MesProPalletApi.PreGenerateResult[]>(
@@ -118,6 +116,13 @@
   );
 }
 
+/** 鏌ヨ鏈粦瀹氭壒娆$殑涓存椂鎵樼洏鍒楄〃锛堜緵鎵规鏂板/琛ュ綍缁戝畾鎵樼洏涓嬫媺浣跨敤锛� */
+export function getUnboundPalletList() {
+  return requestClient.get<MesProPalletApi.Pallet[]>(
+    '/mes/pro/pallet/unbound-list',
+  );
+}
+
 /** 瀵煎嚭鎵樼洏鐮� Excel */
 export function exportPalletExcel(params: MesProPalletApi.PageParams) {
   return requestClient.download('/mes/pro/pallet/export-excel', { params });
diff --git a/src/views/basicData/mdm/components/data.ts b/src/views/basicData/mdm/components/data.ts
index d6c8b5a..81648cf 100644
--- a/src/views/basicData/mdm/components/data.ts
+++ b/src/views/basicData/mdm/components/data.ts
@@ -5,8 +5,6 @@
 import { DICT_TYPE } from '@vben/constants';
 import { getDictOptions } from '@vben/hooks';
 
-import { getItemTypeSimpleList } from '#/api/mes/md/item/type';
-
 /** 鐗╂枡閫夋嫨寮圭獥鎼滅储琛ㄥ崟 */
 export function useMdmItemSelectGridFormSchema(): VbenFormSchema[] {
   return [
@@ -26,21 +24,6 @@
       componentProps: {
         allowClear: true,
         placeholder: '璇疯緭鍏ュ搧绉嶅悕绉�',
-      },
-    },
-    {
-      fieldName: 'categoryId',
-      label: '鍝佺鍒嗙被',
-      component: 'ApiSelect',
-      componentProps: {
-        placeholder: '璇烽�夋嫨鍝佺鍒嗙被',
-        allowClear: true,
-        api: async () => {
-          const res = await getItemTypeSimpleList();
-          return res || [];
-        },
-        labelField: 'name',
-        valueField: 'id',
       },
     },
     {
@@ -78,13 +61,6 @@
       title: '瑙勬牸鍨嬪彿',
       minWidth: 150,
       align: 'left',
-    },
-    {
-      field: 'categoryId',
-      title: '鍝佺鍒嗙被',
-      minWidth: 120,
-      align: 'center',
-      slots: { default: 'categoryId' },
     },
     {
       field: 'unitMeasureName',
diff --git a/src/views/basicData/mdm/components/select-dialog.vue b/src/views/basicData/mdm/components/select-dialog.vue
index 2c37055..0ea0443 100644
--- a/src/views/basicData/mdm/components/select-dialog.vue
+++ b/src/views/basicData/mdm/components/select-dialog.vue
@@ -1,7 +1,6 @@
 <script lang="ts" setup>
 import type { VxeTableGridOptions } from '#/adapter/vxe-table';
 import type { MdmItemApi } from '#/api/mdm/item';
-import type { MesMdItemTypeApi } from '#/api/mes/md/item/type';
 
 import { nextTick, ref } from 'vue';
 
@@ -9,7 +8,6 @@
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
 import { getItemPage } from '#/api/mdm/item';
-import { getItemTypeSimpleList } from '#/api/mes/md/item/type';
 
 import {
   useMdmItemSelectGridColumns,
@@ -26,21 +24,6 @@
 const multiple = ref(true); // 鏄惁澶氶��
 const selectedRows = ref<MdmItemApi.Item[]>([]); // 宸查�夌墿鏂欏垪琛�
 const preSelectedIds = ref<number[]>([]); // 棰勯�夌墿鏂欑紪鍙峰垪琛�
-const categoryList = ref<MesMdItemTypeApi.ItemType[]>([]); // 鍒嗙被鍒楄〃缂撳瓨
-
-const TAG_COLORS = ['green', 'orange', 'blue', 'purple', 'cyan', 'magenta', 'geekblue', 'volcano', 'gold', 'lime'] as const;
-
-function getCategoryName(categoryId?: number) {
-  if (!categoryId || !categoryList.value.length) return '';
-  const category = categoryList.value.find((item) => item.id === categoryId);
-  return category?.name || '';
-}
-
-function getCategoryColor(categoryId?: number): string {
-  if (!categoryId) return '';
-  const index = categoryList.value.findIndex((item) => item.id === categoryId);
-  return index >= 0 ? TAG_COLORS[index % TAG_COLORS.length]! : '';
-}
 
 /** 鑾峰彇褰撳墠琛ㄦ牸鏁版嵁 */
 function getTableRows() {
@@ -138,13 +121,6 @@
     proxyConfig: {
       ajax: {
         query: async ({ page }, formValues) => {
-          if (!categoryList.value.length) {
-            try {
-              categoryList.value = await getItemTypeSimpleList();
-            } catch {
-              categoryList.value = [];
-            }
-          }
           return await getItemPage({
             pageNo: page.currentPage,
             pageSize: page.pageSize,
@@ -229,10 +205,6 @@
     @cancel="closeModal"
   >
     <Grid table-title="鍝佺鍒楄〃">
-      <template #categoryId="{ row }">
-        <Tag v-if="getCategoryColor(row.categoryId)" :color="getCategoryColor(row.categoryId)">{{ getCategoryName(row.categoryId) }}</Tag>
-        <span v-else>{{ getCategoryName(row.categoryId) || '-' }}</span>
-      </template>
       <template #isBatchManaged="{ row }">
         <Tag v-if="row.isBatchManaged" color="success">鏄�</Tag>
         <Tag v-else>鍚�</Tag>
diff --git a/src/views/basicData/mdm/data.ts b/src/views/basicData/mdm/data.ts
index 0ec3d1d..94837a7 100644
--- a/src/views/basicData/mdm/data.ts
+++ b/src/views/basicData/mdm/data.ts
@@ -9,7 +9,6 @@
 import { z } from '#/adapter/form';
 import { generateAutoCode } from '#/api/mes/md/autocode/record';
 import { MesAutoCodeRuleCode } from '@vben/constants';
-import { getItemTypeSimpleList } from '#/api/mes/md/item/type';
 import { getUnitPage } from '#/api/mdm/unit';
 import { getWarehouseSimpleList } from '#/api/mes/wm/warehouse';
 
@@ -22,24 +21,6 @@
 // 缂撳瓨浠撳簱鍒楄〃
 let warehouseListCache: any[] | null = null;
 let warehouseListPromise: Promise<any[]> | null = null;
-
-/** 灏嗘墎骞冲垎绫诲垪琛ㄨ浆涓� TreeSelect 鎵�闇�鐨勬爲褰㈢粨鏋� */
-export function buildCategoryTree(list: any[]): any[] {
-  const map = new Map<number, any>();
-  const roots: any[] = [];
-  for (const item of list) {
-    map.set(item.id, { label: item.name, value: item.id, children: [] });
-  }
-  for (const item of list) {
-    const node = map.get(item.id)!;
-    if (item.parentId && map.has(item.parentId)) {
-      map.get(item.parentId)!.children.push(node);
-    } else {
-      roots.push(node);
-    }
-  }
-  return roots;
-}
 
 /** 鑾峰彇鍗曚綅鍒楄〃锛堝甫缂撳瓨锛� */
 async function getUnitListCached() {
@@ -82,7 +63,7 @@
 }
 
 /** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(formApi?: VbenFormApi, categoryTreeData: any[] = []): VbenFormSchema[] {
+export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
   return [
     {
       component: "Input",
@@ -124,19 +105,6 @@
         placeholder: "璇疯緭鍏ュ搧绉嶅悕绉�",
       },
       rules: "required",
-    },
-    {
-      component: "TreeSelect",
-      fieldName: "categoryId",
-      label: "鍝佺鍒嗙被",
-      rules: "selectRequired",
-      componentProps: {
-        placeholder: "璇烽�夋嫨鍝佺鍒嗙被",
-        allowClear: true,
-        treeDefaultExpandAll: true,
-        treeData: categoryTreeData,
-        fieldNames: { label: 'label', value: 'value', children: 'children' },
-      },
     },
     {
       component: "Input",
@@ -242,17 +210,6 @@
       label: "鏉$爜",
       componentProps: {
         placeholder: "璇疯緭鍏ユ潯鐮�",
-      },
-    },
-    {
-      component: "InputNumber",
-      fieldName: "purchasePrice",
-      label: "閲囪喘浠�",
-      componentProps: {
-        class: "!w-full",
-        min: 0,
-        precision: 2,
-        placeholder: "璇疯緭鍏ラ噰璐环",
       },
     },
     {
@@ -541,12 +498,6 @@
       minWidth: 150,
     },
     {
-      field: "categoryName",
-      title: "鍝佺鍒嗙被",
-      minWidth: 120,
-      slots: { default: "categoryName" },
-    },
-    {
       field: "unitMeasureName",
       title: "鍗曚綅",
       minWidth: 80,
@@ -575,14 +526,6 @@
       field: "warehouseName",
       title: "榛樿浠撳簱",
       minWidth: 100,
-    },
-    {
-      field: "purchasePrice",
-      title: "閲囪喘浠�",
-      minWidth: 100,
-      formatter: ({ cellValue }) => {
-        return cellValue != null ? `楼${Number(cellValue).toFixed(2)}` : "";
-      },
     },
     {
       field: "salesPrice",
diff --git a/src/views/basicData/mdm/index.vue b/src/views/basicData/mdm/index.vue
index 7d92251..3a02fe0 100644
--- a/src/views/basicData/mdm/index.vue
+++ b/src/views/basicData/mdm/index.vue
@@ -1,9 +1,8 @@
 <script lang="ts" setup>
 import type { VxeTableGridOptions } from '#/adapter/vxe-table';
 import type { MdmItemApi } from '#/api/mdm/item';
-import type { MesMdItemTypeApi } from '#/api/mes/md/item/type';
 
-import { computed, ref } from 'vue';
+import { ref } from 'vue';
 
 import { confirm, Page, useVbenModal } from '#/packages/effects/common-ui/src';
 import { downloadFileFromBlobPart, isEmpty } from '#/packages/utils/src';
@@ -19,7 +18,6 @@
   updateItemStatus,
   updateItemSync,
 } from '#/api/mdm/item';
-import { getItemTypeSimpleList } from '#/api/mes/md/item/type';
 import { $t } from '#/locales';
 
 import { useGridColumns, useGridFormSchema } from './data';
@@ -31,44 +29,6 @@
   connectedComponent: Form,
   destroyOnClose: true,
 });
-
-// 鍒嗙被鍒楄〃缂撳瓨
-const categoryList = ref<MesMdItemTypeApi.ItemType[]>([]);
-
-const TAG_COLORS = [
-  'green',
-  'orange',
-  'blue',
-  'purple',
-  'cyan',
-  'magenta',
-  'geekblue',
-  'volcano',
-  'gold',
-  'lime',
-] as const;
-
-/** 鍒嗙被ID 鈫� 棰滆壊鏄犲皠锛堝熀浜庡垎绫诲湪鍒楄〃涓殑绱㈠紩寰幆鍒嗛厤锛� */
-const categoryColorMap = computed(() => {
-  const map = new Map<number, string>();
-  categoryList.value.forEach((item, index) => {
-    map.set(item.id!, TAG_COLORS[index % TAG_COLORS.length]!);
-  });
-  return map;
-});
-
-/** 鑾峰彇鍒嗙被Tag棰滆壊 */
-function getCategoryColor(categoryId?: number): string {
-  if (!categoryId) return '';
-  return categoryColorMap.value.get(categoryId) || '';
-}
-
-/** 鑾峰彇鍒嗙被鍚嶇О */
-function getCategoryName(categoryId?: number) {
-  if (!categoryId || !categoryList.value.length) return '';
-  const category = categoryList.value.find((item) => item.id === categoryId);
-  return category?.name || '';
-}
 
 /** 鍒锋柊琛ㄦ牸 */
 function handleRefresh() {
@@ -176,14 +136,6 @@
     proxyConfig: {
       ajax: {
         query: async ({ page }, formValues) => {
-          // 鍔犺浇鍒嗙被鍒楄〃锛堢敤浜庢樉绀哄垎绫诲悕绉帮級
-          if (!categoryList.value.length) {
-            try {
-              categoryList.value = await getItemTypeSimpleList();
-            } catch {
-              categoryList.value = [];
-            }
-          }
           return await getItemPage({
             pageNo: page.currentPage,
             pageSize: page.pageSize,
@@ -240,10 +192,6 @@
             },
           ]"
         />
-      </template>
-      <template #categoryName="{ row }">
-        <Tag v-if="getCategoryColor(row.categoryId)" :color="getCategoryColor(row.categoryId)">{{ getCategoryName(row.categoryId) }}</Tag>
-        <span v-else>{{ getCategoryName(row.categoryId) }}</span>
       </template>
       <template #isBatchManaged="{ row }">
         <Tag v-if="row.isBatchManaged" color="success">鏄�</Tag>
diff --git a/src/views/basicData/mdm/modules/form.vue b/src/views/basicData/mdm/modules/form.vue
index c9578e9..00191f6 100644
--- a/src/views/basicData/mdm/modules/form.vue
+++ b/src/views/basicData/mdm/modules/form.vue
@@ -11,8 +11,7 @@
 import { createItem, getItem, updateItem } from '#/api/mdm/item';
 import { $t } from '#/locales';
 
-import { useFormSchema, clearUnitListCache, buildCategoryTree } from '../data';
-import { getItemTypeSimpleList } from '#/api/mes/md/item/type';
+import { useFormSchema, clearUnitListCache } from '../data';
 
 defineOptions({ name: "ItemForm" });
 
@@ -57,11 +56,8 @@
     const data = modalApi.getData<MdmItemApi.Item>();
     // 娓呴櫎鍗曚綅缂撳瓨锛岀‘淇濊幏鍙栨渶鏂版暟鎹�
     clearUnitListCache();
-    // 鍔犺浇鏈�鏂板垎绫绘暟鎹�
-    const categoryRes = await getItemTypeSimpleList();
-    const categoryTreeData = buildCategoryTree(categoryRes || []);
     // 璁剧疆 schema锛坒ormApi 宸插垵濮嬪寲锛�
-    formApi.setState({ schema: useFormSchema(formApi, categoryTreeData) });
+    formApi.setState({ schema: useFormSchema(formApi) });
     if (data?.id) {
       // 缂栬緫妯″紡
       modalApi.lock();
diff --git a/src/views/basicData/mdm/unit/data.ts b/src/views/basicData/mdm/unit/data.ts
index b9d0be3..aed8206 100644
--- a/src/views/basicData/mdm/unit/data.ts
+++ b/src/views/basicData/mdm/unit/data.ts
@@ -6,6 +6,13 @@
 
 import { z } from '#/adapter/form';
 
+/** 璁¢噺鍗曚綅绫诲瀷閫夐」 */
+export const UNIT_TYPE_OPTIONS = [
+  { label: '48鍗冨厠', value: '48鍗冨厠' },
+  { label: '100鍗冨厠', value: '100鍗冨厠' },
+  { label: '鍚�', value: '鍚�' },
+];
+
 /** 鏂板/淇敼鐨勮〃鍗� */
 export function useFormSchema(): VbenFormSchema[] {
   return [
@@ -33,6 +40,17 @@
       rules: 'required',
       componentProps: {
         placeholder: '璇疯緭鍏ュ崟浣嶅悕绉�',
+      },
+    },
+    {
+      fieldName: 'type',
+      label: '绫诲瀷',
+      component: 'Select',
+      rules: 'required',
+      componentProps: {
+        placeholder: '璇烽�夋嫨绫诲瀷',
+        allowClear: true,
+        options: UNIT_TYPE_OPTIONS,
       },
     },
     {
@@ -107,6 +125,12 @@
       minWidth: 150,
     },
     {
+      field: 'type',
+      title: '绫诲瀷',
+      minWidth: 100,
+      formatter: ({ cellValue }) => cellValue || '-',
+    },
+    {
       field: 'status',
       title: '鐘舵��',
       minWidth: 80,
diff --git a/src/views/erp/purchase/order/modules/item-form.vue b/src/views/erp/purchase/order/modules/item-form.vue
index 009246a..fb5c6a4 100644
--- a/src/views/erp/purchase/order/modules/item-form.vue
+++ b/src/views/erp/purchase/order/modules/item-form.vue
@@ -159,7 +159,7 @@
   row.productUnitId = product.unitMeasureId;
   row.productUnitName = product.unitMeasureName;
   row.productName = product.name;
-  row.productPrice = product.purchasePrice || 0;
+  row.productPrice = 0; // 鍝佺绠$悊宸插幓鎺夐噰璐环锛岄噾棰濋渶鎵嬪伐濉啓
   row.count = row.count || 1;
   handleRowChange(row);
 }
diff --git a/src/views/erp/purchase/request/modules/item-form.vue b/src/views/erp/purchase/request/modules/item-form.vue
index 7cd972a..9e0bc0b 100644
--- a/src/views/erp/purchase/request/modules/item-form.vue
+++ b/src/views/erp/purchase/request/modules/item-form.vue
@@ -121,7 +121,7 @@
   row.productUnitId = product.unitMeasureId;
   row.productUnitName = product.unitMeasureName;
   row.productName = product.name;
-  row.productPrice = product.purchasePrice || 0;
+  row.productPrice = 0; // 鍝佺绠$悊宸插幓鎺夐噰璐环锛岄噾棰濋渶鎵嬪伐濉啓
   row.count = row.count || 1;
   handleRowChange(row);
 }
diff --git a/src/views/mes/pro/bagCode/data.ts b/src/views/mes/pro/bagCode/data.ts
index caacb5f..8af998d 100644
--- a/src/views/mes/pro/bagCode/data.ts
+++ b/src/views/mes/pro/bagCode/data.ts
@@ -2,8 +2,12 @@
 import type { VxeTableGridOptions } from '#/adapter/vxe-table';
 import type { MesProBagCodeApi } from '#/api/mes/pro/bagCode';
 
+import { markRaw } from 'vue';
+
 import { DICT_TYPE } from '@vben/constants';
 import { getDictOptions } from '@vben/hooks';
+
+import { MdmItemSelect } from '#/views/basicData/mdm/components';
 
 import { getRangePickerDefaultProps } from '#/utils';
 
@@ -35,6 +39,14 @@
       componentProps: {
         allowClear: true,
         placeholder: '璇疯緭鍏ョ敓鎴愮粍缂栧彿',
+      },
+    },
+    {
+      fieldName: 'itemId',
+      label: '鍝佺',
+      component: markRaw(MdmItemSelect),
+      componentProps: {
+        placeholder: '璇烽�夋嫨鍝佺锛堜骇鍝佸搧绉嶏級',
       },
     },
     {
@@ -85,6 +97,16 @@
       minWidth: 190,
     },
     {
+      field: 'itemCode',
+      title: '鍝佺缂栫爜',
+      width: 120,
+    },
+    {
+      field: 'itemName',
+      title: '鍝佺鍚嶇О',
+      width: 140,
+    },
+    {
       field: 'lineCode',
       title: '浜х嚎缂栫爜',
       width: 100,
diff --git a/src/views/mes/pro/bagCode/index.vue b/src/views/mes/pro/bagCode/index.vue
index 58621ab..65ae024 100644
--- a/src/views/mes/pro/bagCode/index.vue
+++ b/src/views/mes/pro/bagCode/index.vue
@@ -23,6 +23,7 @@
   import BindBatchModal from "./modules/bind-batch.vue";
   import BindPalletModal from "./modules/bind-pallet.vue";
   import GenerateModal from "./modules/generate-form.vue";
+  import RawGenerateModal from "./modules/raw-generate-form.vue";
   import ReplaceModal from "./modules/replace-form.vue";
   import QrTraceModal from "../components/qr-trace-modal.vue";
 
@@ -30,6 +31,11 @@
 
   const [GenerateFormModal, generateFormModalApi] = useVbenModal({
     connectedComponent: GenerateModal,
+    destroyOnClose: true,
+  });
+
+  const [RawGenerateFormModal, rawGenerateFormModalApi] = useVbenModal({
+    connectedComponent: RawGenerateModal,
     destroyOnClose: true,
   });
 
@@ -61,6 +67,11 @@
   /** 鐢熸垚鏁版嵁鍖� */
   function handleGenerate() {
     generateFormModalApi.open();
+  }
+
+  /** 鐢熸垚鍘熷琚嬬爜 */
+  function handleRawGenerate() {
+    rawGenerateFormModalApi.open();
   }
 
   /** 鏇挎崲鎴愬姛鍚庡睍绀虹粨鏋滃苟鍒锋柊鍒楄〃 */
@@ -303,6 +314,7 @@
 <template>
   <Page auto-content-height>
     <GenerateFormModal @success="handleRefresh" />
+    <RawGenerateFormModal @success="handleRefresh" />
     <BindBatchFormModal @success="handleRefresh" />
     <BindPalletFormModal @success="handleRefresh" />
     <ReplaceFormModal @success="handleReplaceSuccess" />
@@ -318,6 +330,12 @@
               onClick: handleGenerate,
             },
             {
+              label: '鐢熸垚鍘熷琚嬬爜',
+              icon: ACTION_ICON.ADD,
+              auth: ['mes:pro-bag-code:create'],
+              onClick: handleRawGenerate,
+            },
+            {
               label: '褰曞叆鎵规',
               type: 'primary',
               auth: ['mes:pro-bag-code:update'],
diff --git a/src/views/mes/pro/bagCode/modules/bind-pallet.vue b/src/views/mes/pro/bagCode/modules/bind-pallet.vue
index a84abba..fac78f0 100644
--- a/src/views/mes/pro/bagCode/modules/bind-pallet.vue
+++ b/src/views/mes/pro/bagCode/modules/bind-pallet.vue
@@ -97,9 +97,7 @@
             (pallet) => pallet.status !== MesProPalletStatusEnum.CANCELED
           )
           .map((pallet) => ({
-            label: `${pallet.code}锛堝凡瑁� ${pallet.bagCount ?? 0} 琚� / 鍙 ${
-              pallet.capacity ?? "涓嶉檺"
-            } 琚嬶級`,
+            label: `${pallet.code}锛堝凡瑁� ${pallet.bagCount ?? 0} 琚嬶級`,
             value: pallet.id!,
           }));
         await formApi.setState({ schema: buildSchema(options) });
diff --git a/src/views/mes/pro/bagCode/modules/generate-form.vue b/src/views/mes/pro/bagCode/modules/generate-form.vue
index 316e9fd..46ba37e 100644
--- a/src/views/mes/pro/bagCode/modules/generate-form.vue
+++ b/src/views/mes/pro/bagCode/modules/generate-form.vue
@@ -1,6 +1,9 @@
 <script lang="ts" setup>
   import type { VbenFormSchema } from "#/adapter/form";
+  import type { MdmItemApi } from "#/api/mdm/item";
   import type { MesProBagCodeApi } from "#/api/mes/pro/bagCode";
+
+  import { computed, markRaw, ref } from "vue";
 
   import { useVbenModal } from "@vben/common-ui";
 
@@ -8,35 +11,132 @@
 
   import { useVbenForm } from "#/adapter/form";
   import { generateBagCodes } from "#/api/mes/pro/bagCode";
+  import { getUnit } from "#/api/mdm/unit";
+  import { MdmItemSelect } from "#/views/basicData/mdm/components";
 
   defineOptions({ name: "MesProBagCodeGenerateForm" });
 
   const emit = defineEmits(["success"]);
 
+  // 鎵�閫夊搧绉嶄富璁¢噺鍗曚綅绫诲瀷锛�48鍗冨厠/100鍗冨厠 -> 姣忔墭 N 琚嬶紱鍚� -> 鏃犳墭鐩樼洿鎺ヨ緭琚嬬爜鏁�
+  const unitType = ref("");
+  const kgPerPallet = ref<number | null>(null);
+  const isTon = ref(false);
+  const unitTypeError = ref(false);
+  const palletCountVal = ref<number | null>(null);
+  const bagCountVal = ref<number | null>(null);
+
+  /** 鎹㈢畻/閰嶇疆鎻愮ず鏂囨 */
+  const tipText = computed(() => {
+    if (unitTypeError.value) {
+      return "璇ュ搧绉嶄富璁¢噺鍗曚綅鏈厤缃被鍨嬶紙浠呮敮鎸� 48鍗冨厠/100鍗冨厠/鍚級锛岃鍏堝墠寰�銆岃閲忓崟浣嶃�嶇淮鎶ゅ悗閲嶈瘯";
+    }
+    if (!unitType.value) {
+      return "";
+    }
+    if (isTon.value) {
+      return `璁¢噺鍗曚綅绫诲瀷涓恒�屽惃銆嶏細涓嶇敓鎴愭墭鐩橈紝琚嬬爜浠呯粦瀹氱敓浜ф壒娆�${
+        bagCountVal.value ? `锛屽皢鐢熸垚 ${bagCountVal.value} 涓鐮乣 : ""
+      }`;
+    }
+    const per = kgPerPallet.value ?? 0;
+    const count = palletCountVal.value ?? 0;
+    return `璁¢噺鍗曚綅绫诲瀷涓恒��${unitType.value}銆嶏細姣忔墭 ${per} 琚�${
+      count > 0
+        ? ` 脳 ${count} 鎵� = ${per * count} 涓鐮侊紝灏嗚嚜鍔ㄧ敓鎴� ${count} 涓墭鐩樺苟缁戝畾`
+        : "锛岃杈撳叆鎵樼洏鏁�"
+    }`;
+  });
+
   function buildSchema(): VbenFormSchema[] {
-    return [
+    const schema: VbenFormSchema[] = [
       {
-        fieldName: "count",
-        label: "鐢熸垚琚嬫暟",
+        fieldName: "itemId",
+        label: "鍝佺",
+        component: markRaw(MdmItemSelect),
+        componentProps: {
+          placeholder: "璇烽�夋嫨鍝佺锛堜骇鍝佸搧绉嶏級",
+          onChange: handleItemChange,
+        },
+        rules: "selectRequired",
+      },
+    ];
+    if (kgPerPallet.value) {
+      schema.push({
+        fieldName: "palletCount",
+        label: "鎵樼洏鏁�",
         component: "InputNumber",
         componentProps: {
           class: "!w-full",
           min: 1,
-          placeholder: "璇疯緭鍏ラ渶瑕佺敓鎴愮殑琚嬬爜鏁伴噺",
+          placeholder: "璇疯緭鍏ユ墭鐩樻暟锛堢郴缁熻嚜鍔ㄧ敓鎴愭墭鐩樺苟鍧囧垎缁戝畾琚嬬爜锛�",
           precision: 0,
+          onChange: (value: number | string) => {
+            palletCountVal.value = Number(value) || null;
+          },
         },
         rules: "required",
-      },
-      {
-        fieldName: "remark",
-        label: "澶囨敞",
-        component: "Textarea",
+      });
+    }
+    if (isTon.value) {
+      schema.push({
+        fieldName: "bagCount",
+        label: "琚嬬爜鏁�",
+        component: "InputNumber",
         componentProps: {
-          placeholder: "璇疯緭鍏ュ娉�",
-          rows: 2,
+          class: "!w-full",
+          min: 1,
+          placeholder: "璇疯緭鍏ヨ鐮佹暟锛堝惃鍝佺鏃犳墭鐩橈紝琚嬬爜浠呯粦瀹氭壒娆★級",
+          precision: 0,
+          onChange: (value: number | string) => {
+            bagCountVal.value = Number(value) || null;
+          },
         },
+        rules: "required",
+      });
+    }
+    schema.push({
+      fieldName: "remark",
+      label: "澶囨敞",
+      component: "Textarea",
+      componentProps: {
+        placeholder: "璇疯緭鍏ュ娉�",
+        rows: 2,
       },
-    ];
+    });
+    return schema;
+  }
+
+  /** 閫夋嫨鍝佺鍚庤鍙栦富璁¢噺鍗曚綅绫诲瀷锛屽姩鎬佸垏鎹㈡墭鐩樻暟/琚嬬爜鏁拌緭鍏� */
+  async function handleItemChange(item?: MdmItemApi.Item) {
+    unitType.value = "";
+    kgPerPallet.value = null;
+    isTon.value = false;
+    unitTypeError.value = false;
+    palletCountVal.value = null;
+    bagCountVal.value = null;
+    if (item?.unitMeasureId) {
+      try {
+        const unit = await getUnit(item.unitMeasureId);
+        const type = (unit?.type ?? "").trim();
+        unitType.value = type;
+        if (type === "鍚�") {
+          isTon.value = true;
+        } else {
+          const matcher = /^(\d{1,5})鍗冨厠$/.exec(type);
+          if (matcher) {
+            kgPerPallet.value = Number(matcher[1]);
+          } else {
+            unitTypeError.value = true;
+          }
+        }
+      } catch {
+        unitTypeError.value = true;
+      }
+    } else if (item) {
+      unitTypeError.value = true;
+    }
+    await formApi.setState({ schema: buildSchema() });
   }
 
   const [Form, formApi] = useVbenForm({
@@ -55,12 +155,30 @@
     async onConfirm() {
       const { valid } = await formApi.validate();
       if (!valid) return;
+      if (unitTypeError.value) {
+        message.warning(tipText.value);
+        return;
+      }
       modalApi.lock();
       try {
         const values =
           (await formApi.getValues()) as MesProBagCodeApi.GenerateParams;
-        await generateBagCodes(values);
-        message.success(`宸叉垚鍔熺敓鎴� ${values.count} 鏉¤鐮乣);
+        const data: MesProBagCodeApi.GenerateParams = {
+          itemId: values.itemId,
+          remark: values.remark,
+        };
+        if (isTon.value) {
+          data.bagCount = values.bagCount;
+        } else {
+          data.palletCount = values.palletCount;
+        }
+        const result = await generateBagCodes(data);
+        message.success(
+          `宸叉垚鍔熺敓鎴� ${result.totalCount} 鏉¤鐮乣 +
+            (result.palletIds?.length
+              ? `锛屽苟鑷姩鐢熸垚 ${result.palletIds.length} 涓墭鐩榒
+              : ""),
+        );
         emit("success");
         await modalApi.close();
       } finally {
@@ -71,6 +189,18 @@
       if (!isOpen) return;
       modalApi.lock();
       try {
+        unitType.value = "";
+        kgPerPallet.value = null;
+        isTon.value = false;
+        unitTypeError.value = false;
+        palletCountVal.value = null;
+        bagCountVal.value = null;
+        await formApi.setValues({
+          itemId: undefined,
+          palletCount: undefined,
+          bagCount: undefined,
+          remark: undefined,
+        });
         await formApi.setState({ schema: buildSchema() });
       } finally {
         modalApi.unlock();
@@ -82,5 +212,12 @@
 <template>
   <Modal title="鐢熸垚琚嬬爜鏁版嵁鍖�" class="w-2/5">
     <Form class="mx-4" />
+    <div
+      v-if="tipText"
+      class="mx-4 mb-2 rounded bg-gray-50 px-3 py-2 text-sm"
+      :class="unitTypeError ? 'text-red-500' : 'text-gray-500'"
+    >
+      {{ tipText }}
+    </div>
   </Modal>
 </template>
diff --git a/src/views/mes/pro/bagCode/modules/raw-generate-form.vue b/src/views/mes/pro/bagCode/modules/raw-generate-form.vue
new file mode 100644
index 0000000..85c8d2a
--- /dev/null
+++ b/src/views/mes/pro/bagCode/modules/raw-generate-form.vue
@@ -0,0 +1,100 @@
+<script lang="ts" setup>
+  import type { VbenFormSchema } from "#/adapter/form";
+
+  import { markRaw } from "vue";
+
+  import { useVbenModal } from "@vben/common-ui";
+
+  import { message } from "ant-design-vue";
+
+  import { useVbenForm } from "#/adapter/form";
+  import { generateRawBagCodes } from "#/api/mes/pro/bagCode";
+  import { MdmItemSelect } from "#/views/basicData/mdm/components";
+
+  defineOptions({ name: "MesProBagCodeRawGenerateForm" });
+
+  const emit = defineEmits(["success"]);
+
+  const schema: VbenFormSchema[] = [
+    {
+      fieldName: "itemId",
+      label: "鍝佺",
+      component: markRaw(MdmItemSelect),
+      componentProps: {
+        placeholder: "璇烽�夋嫨鍝佺锛堜骇鍝佸搧绉嶏級",
+      },
+      rules: "selectRequired",
+    },
+    {
+      fieldName: "count",
+      label: "琚嬬爜鏁伴噺",
+      component: "InputNumber",
+      componentProps: {
+        class: "!w-full",
+        min: 1,
+        placeholder: "璇疯緭鍏ラ渶瑕佺敓鎴愮殑琚嬬爜鏁伴噺",
+        precision: 0,
+      },
+      rules: "required",
+    },
+    {
+      fieldName: "remark",
+      label: "澶囨敞",
+      component: "Textarea",
+      componentProps: {
+        placeholder: "璇疯緭鍏ュ娉�",
+        rows: 2,
+      },
+    },
+  ];
+
+  const [Form, formApi] = useVbenForm({
+    commonConfig: {
+      componentProps: {
+        class: "w-full",
+      },
+      labelWidth: 100,
+    },
+    layout: "horizontal",
+    schema,
+    showDefaultActions: false,
+  });
+
+  const [Modal, modalApi] = useVbenModal({
+    async onConfirm() {
+      const { valid } = await formApi.validate();
+      if (!valid) return;
+      modalApi.lock();
+      try {
+        const values = await formApi.getValues();
+        const result = await generateRawBagCodes({
+          itemId: values.itemId,
+          count: values.count,
+          remark: values.remark,
+        });
+        message.success(`宸叉垚鍔熺敓鎴� ${result.totalCount} 鏉″師濮嬭鐮乣);
+        emit("success");
+        await modalApi.close();
+      } finally {
+        modalApi.unlock();
+      }
+    },
+    async onOpenChange(isOpen: boolean) {
+      if (!isOpen) return;
+      await formApi.setValues({
+        itemId: undefined,
+        count: undefined,
+        remark: undefined,
+      });
+    },
+  });
+</script>
+
+<template>
+  <Modal title="鐢熸垚鍘熷琚嬬爜" class="w-2/5">
+    <Form class="mx-4" />
+    <div class="mx-4 mb-2 rounded bg-gray-50 px-3 py-2 text-sm text-gray-500">
+      鍘熷琚嬬爜浠呴渶閫夋嫨鍝佺骞惰緭鍏ユ暟閲忥紝涓嶆崲绠楄閲忓崟浣嶇被鍨嬨�佷笉鐢熸垚鎵樼洏锛涘悗缁彲姝e父褰曞叆鎵规鎴栫粦瀹氭墭鐩�
+    </div>
+  </Modal>
+</template>
diff --git a/src/views/mes/pro/batch/data.ts b/src/views/mes/pro/batch/data.ts
index 673aedc..9e0803c 100644
--- a/src/views/mes/pro/batch/data.ts
+++ b/src/views/mes/pro/batch/data.ts
@@ -7,7 +7,6 @@
 import { DICT_TYPE } from '@vben/constants';
 import { getDictOptions } from '@vben/hooks';
 
-import { MdmItemSelect } from '#/views/basicData/mdm/components';
 import { ProLineSelect } from '#/views/mes/pro/line/components';
 import { UserSelect } from '#/views/system/user/components';
 import { getRangePickerDefaultProps } from '#/utils';
@@ -15,8 +14,17 @@
 /** 琛ㄥ崟绫诲瀷锛坒ill锛氫复鏃舵壒娆$爜琛ュ綍姝e紡淇℃伅锛� */
 export type FormType = 'create' | 'detail' | 'update' | 'fill';
 
+/** 鏈粦瀹氭墭鐩樹笅鎷夐�夐」 */
+export interface PalletOption {
+  label: string;
+  value: number;
+}
+
 /** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(formType: FormType): VbenFormSchema[] {
+export function useFormSchema(
+  formType: FormType,
+  palletOptions: PalletOption[] = [],
+): VbenFormSchema[] {
   const disabled = formType === 'detail';
   return [
     {
@@ -67,24 +75,25 @@
       },
     },
     {
-      fieldName: 'itemId',
-      label: '鍝佺',
-      component: markRaw(MdmItemSelect),
+      fieldName: 'lineId',
+      label: '鍔犲伐鍗曚綅',
+      component: markRaw(ProLineSelect),
       componentProps: {
         disabled,
-        placeholder: '璇烽�夋嫨鍝佺锛堜骇鍝佸搧绉嶏級',
+        placeholder: '璇烽�夋嫨鍔犲伐鍗曚綅',
       },
       rules: 'selectRequired',
     },
     {
-      fieldName: 'lineId',
-      label: '浜х嚎',
-      component: markRaw(ProLineSelect),
+      fieldName: 'processingTeam',
+      label: '鍔犲伐鐝粍',
+      component: 'Input',
       componentProps: {
+        allowClear: true,
         disabled,
-        placeholder: '璇烽�夋嫨浜х嚎',
+        maxlength: 64,
+        placeholder: '璇疯緭鍏ュ姞宸ョ彮缁�',
       },
-      rules: 'selectRequired',
     },
     {
       fieldName: 'produceDate',
@@ -102,13 +111,13 @@
     },
     {
       fieldName: 'planQuantity',
-      label: '璁″垝鏁伴噺',
+      label: '鍔犲伐鏁伴噺',
       component: 'InputNumber',
       componentProps: {
         class: '!w-full',
         disabled,
         min: 0,
-        placeholder: '璇疯緭鍏ヨ鍒掓暟閲�',
+        placeholder: '璇疯緭鍏ュ姞宸ユ暟閲�',
         precision: 2,
       },
     },
@@ -121,6 +130,26 @@
         placeholder: '璇烽�夋嫨璐d换浜�',
       },
       rules: 'selectRequired',
+    },
+    {
+      fieldName: 'palletIds',
+      label: '缁戝畾鎵樼洏',
+      component: 'Select',
+      componentProps: {
+        allowClear: true,
+        disabled,
+        maxTagCount: 3,
+        mode: 'multiple',
+        optionFilterProp: 'label',
+        options: palletOptions,
+        placeholder: '璇烽�夋嫨鎵樼洏锛堝彲涓嶉�夛級',
+        showSearch: true,
+      },
+      dependencies: {
+        triggerFields: [''],
+        show: () => formType !== 'detail',
+      },
+      help: '缁戝畾鍚庢壒娆$洿鎺ヨ繘鍏ョ敓浜т腑锛氭墭鐩樼敓鎴愭寮忔墭鐩樼爜锛屾墭鐩樹笅鏈綍鎵规鐨勮鐮佽嚜鍔ㄧ骇鑱斿綍鍏ユ湰鎵规锛堣鐮佸搧绉嶉』涓�鑷达級锛涚紪杈戞椂浠呴渶鍕鹃�夋柊澧炴墭鐩橈紝宸茬粦瀹氱殑涓嶅彲瑙g粦',
     },
     {
       fieldName: 'remark',
@@ -149,29 +178,21 @@
       },
     },
     {
-      fieldName: 'itemId',
-      label: '鍝佺',
-      component: markRaw(MdmItemSelect),
-      componentProps: {
-        placeholder: '璇烽�夋嫨鍝佺',
-      },
-    },
-    {
-      fieldName: 'lineCode',
-      label: '浜х嚎缂栫爜',
-      component: 'Input',
-      componentProps: {
-        allowClear: true,
-        placeholder: '璇疯緭鍏ヤ骇绾跨紪鐮�',
-      },
-    },
-    {
       fieldName: 'lineName',
-      label: '浜х嚎鍚嶇О',
+      label: '鍔犲伐鍗曚綅',
       component: 'Input',
       componentProps: {
         allowClear: true,
-        placeholder: '璇疯緭鍏ヤ骇绾垮悕绉�',
+        placeholder: '璇疯緭鍏ュ姞宸ュ崟浣�',
+      },
+    },
+    {
+      fieldName: 'processingTeam',
+      label: '鍔犲伐鐝粍',
+      component: 'Input',
+      componentProps: {
+        allowClear: true,
+        placeholder: '璇疯緭鍏ュ姞宸ョ彮缁�',
       },
     },
     {
@@ -224,23 +245,13 @@
       slots: { default: 'code' },
     },
     {
-      field: 'itemCode',
-      title: '鍝佺缂栫爜',
+      field: 'lineName',
+      title: '鍔犲伐鍗曚綅',
       width: 120,
     },
     {
-      field: 'itemName',
-      title: '鍝佺鍚嶇О',
-      width: 140,
-    },
-    {
-      field: 'lineCode',
-      title: '浜х嚎缂栫爜',
-      width: 100,
-    },
-    {
-      field: 'lineName',
-      title: '浜х嚎鍚嶇О',
+      field: 'processingTeam',
+      title: '鍔犲伐鐝粍',
       width: 120,
     },
     {
@@ -251,7 +262,7 @@
     },
     {
       field: 'planQuantity',
-      title: '璁″垝鏁伴噺',
+      title: '鍔犲伐鏁伴噺',
       width: 100,
     },
     {
diff --git a/src/views/mes/pro/batch/index.vue b/src/views/mes/pro/batch/index.vue
index 99ff585..3f15dda 100644
--- a/src/views/mes/pro/batch/index.vue
+++ b/src/views/mes/pro/batch/index.vue
@@ -67,8 +67,9 @@
     });
   }
 
-  /** 棰勭敓鎴愭壒娆′簩缁寸爜鎴愬姛锛氬睍绀虹敓鎴愮殑涓存椂鎵规鐮� */
+  /** 棰勭敓鎴愭壒娆′簩缁寸爜鎴愬姛锛氬埛鏂板垪琛ㄥ苟灞曠ず鐢熸垚鐨勪复鏃舵壒娆$爜 */
   function handlePreGenerateSuccess(result: { id: number; tempCode: string }[]) {
+    handleRefresh();
     Modal.success({
       title: "棰勭敓鎴愪复鏃舵壒娆$爜鎴愬姛",
       content: result.map((item) => item.tempCode).join("\n"),
diff --git a/src/views/mes/pro/batch/modules/form.vue b/src/views/mes/pro/batch/modules/form.vue
index 6242291..f08e03d 100644
--- a/src/views/mes/pro/batch/modules/form.vue
+++ b/src/views/mes/pro/batch/modules/form.vue
@@ -1,5 +1,5 @@
 <script lang="ts" setup>
-  import type { FormType } from "../data";
+  import type { FormType, PalletOption } from "../data";
 
   import type { VxeTableGridOptions } from "#/adapter/vxe-table";
   import type { MesProBatchApi } from "#/api/mes/pro/batch";
@@ -21,6 +21,7 @@
     getBatch,
     updateBatch,
   } from "#/api/mes/pro/batch";
+  import { getUnboundPalletList } from "#/api/mes/pro/pallet";
   import { $t } from "#/locales";
   import { UserSelect } from "#/views/system/user/components";
 
@@ -206,7 +207,20 @@
       }
       const data = modalApi.getData<{ formType: FormType; id?: number }>();
       formType.value = data.formType;
-      formApi.setState({ schema: useFormSchema(formType.value) });
+      // 鏂板/琛ュ綍/缂栬緫鎬佸姞杞芥湭缁戝畾鎵规鐨勬墭鐩橈紝渚涖�岀粦瀹氭墭鐩樸�嶅閫変笅鎷変娇鐢�
+      let palletOptions: PalletOption[] = [];
+      if (formType.value !== "detail") {
+        const pallets = await getUnboundPalletList();
+        palletOptions = pallets.map((pallet) => ({
+          label: `${pallet.tempCode ?? `鎵樼洏${pallet.id}`}锛堝凡瑁� ${pallet.bagCount ?? 0} 琚嬶級`,
+          value: pallet.id as number,
+        }));
+      }
+      formApi.setState({ schema: useFormSchema(formType.value, palletOptions) });
+      if (formType.value !== "detail") {
+        // 娓呯┖涓婃鎵撳紑鏃跺嬀閫夌殑鎵樼洏锛岄伩鍏嶆畫鐣欏�艰瑙﹀彂銆屾壒娆¤繘鍏ョ敓浜т腑銆�
+        await formApi.setFieldValue("palletIds", undefined);
+      }
       // 鏍规嵁琛ㄥ崟鎬佸垏鎹汉鍛樺瓙琛ㄥ垪
       workerGridApi.setGridOptions({
         columns: isEditable.value
diff --git a/src/views/mes/pro/pallet/data.ts b/src/views/mes/pro/pallet/data.ts
index 7ac44fb..73f0d69 100644
--- a/src/views/mes/pro/pallet/data.ts
+++ b/src/views/mes/pro/pallet/data.ts
@@ -73,11 +73,6 @@
       slots: { default: 'batchCode' },
     },
     {
-      field: 'capacity',
-      title: '鍙琚嬫暟锛堣/鎵樼洏锛�',
-      width: 150,
-    },
-    {
       field: 'bagCount',
       title: '宸茬粦琚嬬爜鏁伴噺',
       width: 120,
diff --git a/src/views/mes/pro/pallet/index.vue b/src/views/mes/pro/pallet/index.vue
index a34a272..0d2e0f5 100644
--- a/src/views/mes/pro/pallet/index.vue
+++ b/src/views/mes/pro/pallet/index.vue
@@ -49,8 +49,9 @@
     generateFormModalApi.open();
   }
 
-  /** 棰勭敓鎴愭垚鍔燂細灞曠ず鐢熸垚鐨勪复鏃舵墭鐩樼爜 */
+  /** 棰勭敓鎴愭垚鍔燂細鍒锋柊鍒楄〃骞跺睍绀虹敓鎴愮殑涓存椂鎵樼洏鐮� */
   function handlePreGenerateSuccess(result: { id: number; tempCode: string }[]) {
+    handleRefresh();
     Modal.success({
       title: "棰勭敓鎴愪复鏃舵墭鐩樼爜鎴愬姛",
       content: result.map((item) => item.tempCode).join("\n"),
@@ -216,6 +217,7 @@
       <template #code="{ row }">
         <span>{{ getDisplayCode(row) }}</span>
         <Tag v-if="!row.code" color="warning">鏈粦瀹氭壒娆�</Tag>
+        <Tag v-if="row.autoGenerated" color="processing">鑷姩鐢熸垚</Tag>
       </template>
       <template #batchCode="{ row }">
         <span v-if="row.batchCode">{{ row.batchCode }}</span>
diff --git a/src/views/mes/pro/pallet/modules/bind-batch.vue b/src/views/mes/pro/pallet/modules/bind-batch.vue
index 426168d..79cb35c 100644
--- a/src/views/mes/pro/pallet/modules/bind-batch.vue
+++ b/src/views/mes/pro/pallet/modules/bind-batch.vue
@@ -84,5 +84,8 @@
 <template>
   <Modal title="鎵樼洏鐮佺粦瀹氱敓浜ф壒娆�" class="w-2/5">
     <Form class="mx-4" />
+    <div class="mx-4 mb-2 rounded bg-gray-50 px-3 py-2 text-sm text-gray-500">
+      缁戝畾鍚庯紝鎵樼洏涓嬫湭褰曞叆鎵规鐨勮鐮佸皢鑷姩闅忔墭鐩樼粦瀹氳鐢熶骇鎵规锛堣鐮佸搧绉嶉』涓�鑷达級
+    </div>
   </Modal>
 </template>
\ No newline at end of file
diff --git a/src/views/mes/pro/pallet/modules/generate-form.vue b/src/views/mes/pro/pallet/modules/generate-form.vue
index e094e17..fa55534 100644
--- a/src/views/mes/pro/pallet/modules/generate-form.vue
+++ b/src/views/mes/pro/pallet/modules/generate-form.vue
@@ -33,7 +33,6 @@
         const values = await formApi.getValues();
         const result = await preGeneratePallet({
           count: values.count,
-          capacity: values.capacity,
           remark: values.remark,
         });
         message.success(`宸茬敓鎴� ${result.length} 涓复鏃舵墭鐩樼爜`);
@@ -57,17 +56,6 @@
             precision: 0,
           },
           rules: "required",
-        },
-        {
-          fieldName: "capacity",
-          label: "鍙琚嬫暟",
-          component: "InputNumber",
-          componentProps: {
-            class: "!w-full",
-            min: 1,
-            placeholder: "璇疯緭鍏ユ瘡鎵樼洏鍙琚嬫暟锛堣/鎵樼洏锛�",
-            precision: 0,
-          },
         },
         {
           fieldName: "remark",
diff --git a/src/views/wls/barcode/components/detail.vue b/src/views/wls/barcode/components/detail.vue
index c9abe98..a182baf 100644
--- a/src/views/wls/barcode/components/detail.vue
+++ b/src/views/wls/barcode/components/detail.vue
@@ -130,8 +130,9 @@
       return map[val || 1] || 'QR_CODE';
     };
     const getBizTypeText = (val?: number) => {
-      const map: Record<number, string> = { 1: '浠撳簱', 2: '搴撳尯', 3: '搴撲綅', 4: '鐗╂枡', 5: '瀹㈡埛', 6: '渚涘簲鍟�', 7: '宸ュ崟', 8: '璁惧', 9: '宸ュ叿', 10: '浜哄憳', 11: '宸ヤ綔绔�', 12: '杞﹂棿', 13: '搴撳瓨', 14: '娴佽浆鍗�', 15: '瑁呯鍗�', 16: '鎵规' };
-      return map[val || 1] || '-';
+      // 鍙栧�间笌鍚庣 BarcodeBizTypeEnum锛圡esBizTypeConstants 缂栧彿锛変繚鎸佷竴鑷�
+      const map: Record<number, string> = { 102: '浠撳簱', 103: '搴撳尯', 104: '搴撲綅', 105: '瑁呯鍗�', 106: '搴撳瓨', 107: '鎵规', 109: 'SN 鐮�', 300: '娴佽浆鍗�', 301: '宸ュ崟', 302: '娴佽浆鍗�', 400: '璁惧', 500: '宸ュ叿', 600: '鐗╂枡', 601: '渚涘簲鍟�', 602: '宸ヤ綔绔�', 603: '杞﹂棿', 604: '浜哄憳', 605: '瀹㈡埛' };
+      return map[val as number] || '-';
     };
     const getStatusText = (val?: number) => val === 0 ? '绂佺敤' : '鍚敤';
 
diff --git a/src/views/wls/transaction/data.ts b/src/views/wls/transaction/data.ts
index b0a257f..ac9e879 100644
--- a/src/views/wls/transaction/data.ts
+++ b/src/views/wls/transaction/data.ts
@@ -13,9 +13,12 @@
 
 /** 涓氬姟绫诲瀷閫夐」 */
 const bizTypeOptions = [
+  { label: '绉嶅瓙璐ㄦ', value: 5 },
+  { label: '鐩樼偣璋冩暣', value: 107 },
   { label: '鑷畾涔夊叆搴�', value: 126 },
   { label: '鑷畾涔夊嚭搴�', value: 127 },
   { label: '閲囪喘鍏ュ簱', value: 110 },
+  { label: '閲囪喘鍏ュ簱鍙栨秷', value: 111 },
   { label: '閿�鍞嚭搴�', value: 119 },
   { label: '璋冩嫧鍑哄簱', value: 112 },
   { label: '璋冩嫧鍏ュ簱', value: 113 },

--
Gitblit v1.9.3