# MES XSL「客户到仓库」功能模块说明 本文档说明 Git 分支 **`客户到仓库功能模块`** 所承载的 MES XSL 业务能力,重点覆盖 **客户主数据**、**仓库管理(含客户库 / 供应商库)**、以及配套的 **单位分类改造**。文中表结构以 Flyway 脚本与实体类为准;实现逻辑以当前工作区代码为准。 --- ## 1. 分支与代码范围说明 ### 1.1 相对 `main` 已提交的内容 在当前仓库中执行 `git diff main --stat` 可见:分支相对 `main` **已提交**的改动主要集中在 **工程脚手架与环境**,例如: - 后端:`jeecg-boot-module/pom.xml` 引入子模块、`jeecg-system-start/pom.xml` 依赖、`MybatisPlusSaasConfig` 租户表配置等。 - 前端:`jeecgboot-vue3` 的 `.env.*`、`vite` 代理、`axios`、表单 `useForm` 等。 **结论:** 若仅看「已提交到 Git 的差异」,并不会完整反映「客户、仓库、单位」等 MES 业务表与前后端页面;这些能力的**主要交付物**位于工作区中的: | 区域 | 路径(仓库根下) | |------|------------------| | 后端模块 | `jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/` | | 数据库迁移 | `jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_*__mes_xsl_*.sql` | | 前端页面 | `jeecgboot-vue3/src/views/xslmes/` | 文档以下章节按**完整业务能力**描述;合并到 `main` 或发版前请确保上述目录已 **add / commit**,并与 Flyway 版本一致。 ### 1.2 运行与依赖提示 - **MySQL**:建议 **8.0+**(单位列表按分类树筛选时使用递归 CTE,见 `MesXslUnitMapper`)。 - **Flyway**:按版本号顺序执行;仓库分类以 **`V3.9.2_27`** 为界,由字典 `item_value` 迁移为 **`sys_category.id`**(见下文)。 - **API 前缀**:前端 `VITE_GLOB_API_URL` 需与后端 `context-path`(如 `/jeecg-boot`)一致,否则接口 404。 --- ## 2. 数据表与字段 ### 2.1 `mes_xsl_customer`(客户主数据) 客户是「客户库」仓库行的关联目标。 | 字段 | 类型(约) | 说明 | |------|------------|------| | `id` | varchar(36) | 主键 | | `customer_code` | varchar(100) | 客户编码 | | `customer_name` | varchar(200) | 客户名称 | | `customer_short_name` | varchar(…) | 客户简称(后续脚本扩展,与实体一致) | | `customer_region` | varchar(32) | 区域,字典 `xslmes_customer_region` | | `erp_code` | varchar(100) | ERP 编码 | | `status` | varchar(10) | 业务状态,字典 `xslmes_customer_status`(0 启用 1 停用等) | | `del_flag` | tinyint | 逻辑删除(MyBatis-Plus `@TableLogic`) | | `customer_desc` | varchar(500) | 描述 | | `iz_enable` | tinyint | 是否启用(与服务端状态同步) | | `create_by` / `create_time` / `update_by` / `update_time` | 审计字段 | Jeecg 标准 | | `tenant_id` | int | 租户 | **初始化脚本:** `V3.9.2_4__mes_xsl_customer.sql` 及后续 `V3.9.2_5/6/20/21/23` 等补丁。 --- ### 2.2 `mes_xsl_warehouse`(仓库,**客户到仓库的核心表**) | 字段 | 类型(约) | 说明 | |------|------------|------| | `id` | varchar(36) | 主键 | | `warehouse_code` | varchar(100) | 仓库编码 | | `warehouse_name` | varchar(200) | 仓库名称 | | `warehouse_category` | varchar(36) | **仓库分类**:存 **`sys_category.id`**,根节点编码为 **`XSLMES_WH`**(`V3.9.2_27` 后) | | `erp_code` | varchar(100) | ERP 编码 | | `status` | varchar(10) | 状态,字典 **`xslmes_unit_status`**(0 启用 1 停用) | | `customer_id` | varchar(36) | **客户主键**,仅在分类为 **客户库**(`code = XSLMES_WH_F2_KH`)时有意义 | | `customer_short_name` | varchar(200) | 客户简称展示 | | `supplier_id` | varchar(36) | **供应商主键**,仅在分类为 **供应商库**(`code = XSLMES_WH_F2_GYS`)时有意义 | | `supplier_short_name` | varchar(100) | 供应商简称展示 | | `del_flag` | tinyint | 逻辑删除 | | 审计字段、`tenant_id` | | 同 Jeecg 惯例 | **历史说明:** `V3.9.2_26` 建表时 `warehouse_category` 注释为字典 `xslmes_warehouse_category` 的 `item_value`;**`V3.9.2_27` 执行后**,该列已批量 `UPDATE` 为对应 **`sys_category` 主键**,列类型改为 `varchar(36)`。字典 `xslmes_warehouse_category` 可能仍存在于库中,**业务应以 `sys_category` 为准**,避免混用。 **索引:** `warehouse_code`、`warehouse_category`。 --- ### 2.3 `sys_category`(系统分类字典,仓库与单位共用机制) 仓库与单位分类均挂在 **`sys_category`** 树上,通过根节点 **`code`** 区分业务域: | 根编码 | 业务含义 | 典型脚本 | |--------|----------|----------| | **`XSLMES_WH`** | MES 仓库分类整棵树 | `V3.9.2_27__mes_xsl_warehouse_sys_category.sql` | | **`XSLMES_UNIT`** | MES 单位分类整棵树 | `V3.9.2_29__mes_xsl_unit_sys_category.sql` | **仓库侧关键叶子节点编码(业务常量硬编码校验):** | `code` | 名称(种子数据) | 用途 | |--------|------------------|------| | `XSLMES_WH_F2_KH` | 客户库 | 必须绑定 **`customer_id`** | | `XSLMES_WH_F2_GYS` | 供应商库 | 必须绑定 **`supplier_id`** | 其它叶子(如一楼成品库、二楼原材料库等)**不要求**填写客户或供应商;后端在保存前会 **清空** 无关的客户/供应商字段,防止切换分类后残留脏数据。 **树结构(种子):** 根 `XSLMES_WH` → 一楼库 `XSLMES_WH_F1` / 二楼仓库 `XSLMES_WH_F2` → 各叶子分类(成品库、待检库、客户库、供应商库等),详见 `V3.9.2_27` 中 `INSERT`。 --- ### 2.4 `mes_xsl_supplier`(供应商) 供应商主数据,供「供应商库」类型仓库引用。 主要字段:`supplier_code`、`supplier_name`、`supplier_short_name`、`erp_code`、`remark`、`status`(`xslmes_supplier_status`)、`del_flag`、`tenant_id` 及 Jeecg 基类字段。脚本见 `V3.9.2_11` 等。 --- ### 2.5 `mes_xsl_unit`(单位) | 字段 | 说明 | |------|------| | `category_id` | **`sys_category.id`**,根编码 **`XSLMES_UNIT`**(`V3.9.2_29` 后) | **`mes_xsl_unit_category`:** `V3.9.2_29` 将数据迁入 `sys_category` 后 **已 `DROP`**,单位侧栏维护方式与仓库侧一致(分类字典 API)。 --- ### 2.6 其它相关表(同一 MES 模块,扩展阅读) - **`mes_xsl_vehicle`**:车辆;含 `customer_ids`(多选逗号)、`supplier_id` 等,与主数据客户/供应商有关联,但不改变「仓库行绑定单一客户/供应商」的规则。 - **`mes_xsl_instrument`**:仪器等独立主数据。 --- ## 3. 实现逻辑 ### 3.1 仓库保存 / 更新(客户库、供应商库) 类:`MesXslWarehouseServiceImpl`。 1. **`normalizePartners`**(保存前规范化) - 若未选分类:清空客户、供应商相关字段。 - 否则根据 `warehouse_category`(`sys_category.id`)查询 **`code`**: - 非 **客户库**(`XSLMES_WH_F2_KH`):清空 `customer_id`、`customer_short_name`。 - 非 **供应商库**(`XSLMES_WH_F2_GYS`):清空 `supplier_id`、`supplier_short_name`。 - 目的:从「客户库」改成其它分类时,不保留旧客户信息。 2. **`validatePartners`**(校验) - 分类为 **客户库**:`customer_id` 不能为空,否则抛出 `JeecgBootException("仓库分类为客户库时,请选择客户")`。 - 分类为 **供应商库**:`supplier_id` 不能为空,否则抛出类似供应商提示。 3. **分类编码查询** - `MesXslWarehouseMapper.queryCategoryCodeById`:`SELECT code FROM sys_category WHERE id = ?` - 业务判断常量:`MesXslWarehouseCategory.CUSTOMER_CATEGORY_CODE` / `SUPPLIER_CATEGORY_CODE`。 ### 3.2 实体与字典翻译 - `MesXslWarehouse.warehouseCategory` 使用 `@Dict(dictTable = "sys_category", dicText = "name", dicCode = "id")`,列表/表单显示分类名称。 ### 3.3 前端仓库页 - 列表路由:`/xslmes/mesXslWarehouse`(菜单 `V3.9.2_26` 种子)。 - 左侧分类树:调用系统接口加载根编码 **`XSLMES_WH`** 的子树(与 `/sys/category/loadTreeRoot` 等标准分类字典用法一致)。 - 列表查询字段与 `QueryGenerator` 规则一致:如 `warehouseCategory`、`warehouseCategory_MultiString` 等(用于叶子或父级筛选)。 - 侧栏 **新增 / 编辑 / 删除分类**:走 `/sys/category/add|edit|delete`,需按钮权限(见下节)。 ### 3.4 前端单位页(与仓库同模式) - `category_id` 使用 `JCategorySelect`,`pcode: XSLMES_UNIT`。 - 列表树筛选使用 `MesXslUnitService.listDescendantCategoryIds`(递归子分类),依赖 MySQL 8 递归 CTE。 --- ## 4. 关联关系(逻辑模型) 以下为 **逻辑关联**(脚本未强制数据库外键时,由应用层保证)。 ```mermaid erDiagram sys_category_WH["sys_category (根 XSLMES_WH)"] ||--o{ mes_xsl_warehouse : "warehouse_category = id" mes_xsl_customer ||--o{ mes_xsl_warehouse : "customer_id = id (仅客户库)" mes_xsl_supplier ||--o{ mes_xsl_warehouse : "supplier_id = id (仅供应商库)" sys_category_UNIT["sys_category (根 XSLMES_UNIT)"] ||--o{ mes_xsl_unit : "category_id = id" ``` **要点:** - **多对一(N:1)**:多个仓库行可对应同一客户或同一供应商(视业务是否允许重复配置而定);每条仓库行 **最多一个** `customer_id` 与一个 `supplier_id`,且由分类决定哪一侧生效。 - **客户库**:`mes_xsl_warehouse.customer_id` → `mes_xsl_customer.id`。 - **供应商库**:`mes_xsl_warehouse.supplier_id` → `mes_xsl_supplier.id`。 --- ## 5. 权限与菜单 ### 5.1 仓库菜单(节选) - 菜单 ID `1900000000000000380`:仓库管理,前端组件 `xslmes/mesXslWarehouse/MesXslWarehouseList`。 - 按钮权限示例: - `xslmes:mes_xsl_warehouse:add|edit|delete|deleteBatch|exportXls|importExcel|updateStatus` - **分类维护按钮**(`V3.9.2_28`): - `xslmes:mes_xsl_warehouse_category:add` - `xslmes:mes_xsl_warehouse_category:edit` - `xslmes:mes_xsl_warehouse_category:delete` 管理员角色在种子脚本中已授权一批 `sys_role_permission`(以脚本中 `role_id` 为准;生产环境需按实际角色分配)。 ### 5.2 客户菜单 - 父模块「MES XSL」与客户列表、客户 CRUD 按钮权限见 `V3.9.2_4` 及 `V3.9.2_23/24/25` 等。 ### 5.3 后端接口前缀 | 资源 | `@RequestMapping` 前缀 | |------|-------------------------| | 客户 | `/xslmes/mesXslCustomer` | | 仓库 | `/xslmes/mesXslWarehouse` | | 供应商 | `/xslmes/mesXslSupplier` | | 单位 | `/xslmes/mesXslUnit` | | 车辆 | `/xslmes/mesXslVehicle` | (Jeecg 标准 CRUD:`/list`、`/add`、`/edit`、`/delete` 等,具体见各 `Controller`。) --- ## 6. 功能限制与注意点 1. **分类存储形态** - 必须使用 **`sys_category.id`** 写入 `warehouse_category`。若手工写入旧字典值(如 `CUSTOMER`),字典翻译与后端 `code` 判断会不一致。 2. **客户库 / 供应商库互斥展示** - 后端会清掉「当前分类不需要」的一方字段;**不能**指望在「客户库」下仍保留供应商 ID。 3. **单客户 / 单供应商 per 仓库行** - 与车辆表 `customer_ids` 多选逗号不同,**仓库表为单值 `customer_id`**,表示该仓库行归属单一客户(业务设计如此)。 4. **分类 id 非法或缺失** - 若 `warehouse_category` 指向不存在的 `sys_category`,`queryCategoryCodeById` 可能返回 `null`,此时不会按客户库/供应商库做强校验;应避免脏数据,建议在界面只选合法分类。 5. **字典 `xslmes_warehouse_category`** - `V3.9.2_26` 曾用于初始化;**`V3.9.2_27` 后业务以 `sys_category` 为准**。报表或旧报表若仍读字典需改造。 6. **租户** - `MybatisPlusSaasConfig` 中需包含 `mes_xsl_*` 等业务表,否则多租户下数据隔离异常。 7. **单位分类迁移** - 执行 `V3.9.2_29` 后 **`mes_xsl_unit_category` 表删除**,旧代码中依赖该表的接口需已全部移除。 --- ## 7. 使用方法(业务与运维) ### 7.1 初始化数据库 1. 启动带 Flyway 的 `jeecg-system-start`,确保 **`V3.9.2_26` → `V3.9.2_27` → `V3.9.2_28` → `V3.9.2_29`**(及客户相关 `V3.9.2_4` 等)按序成功执行。 2. 验证 `sys_category` 中存在 `code = 'XSLMES_WH'`、`'XSLMES_UNIT'` 的根节点及子节点。 3. 验证 `mes_xsl_warehouse.warehouse_category` 列为 `varchar(36)` 且存量数据已为 **36 位 id**(由 27 脚本迁移)。 ### 7.2 配置客户与供应商主数据 1. 菜单 **MES XSL → 客户管理**:维护 `mes_xsl_customer`。 2. **供应商管理**:维护 `mes_xsl_supplier`。 3. 确保客户/供应商状态与业务规则一致(启用等),以便仓库弹窗可选。 ### 7.3 维护仓库分类树 1. 进入 **仓库管理** 页面。 2. 在侧栏使用 **新增 / 编辑 / 删除分类**(需具备 `xslmes:mes_xsl_warehouse_category:*` 权限)。 3. 新增节点应挂在 **`XSLMES_WH`** 树下,避免与其它根混淆。 ### 7.4 新建「客户库」仓库 1. 新增仓库,**仓库分类** 选择 **客户库**(`XSLMES_WH_F2_KH` 对应节点)。 2. **必须选择客户**;保存后 `customer_id`、`customer_short_name` 写入。 3. 若改为非客户库分类,保存后客户字段会被后端清空。 ### 7.5 新建「供应商库」仓库 与客户库对称:分类选 **供应商库**,**必须选择供应商**。 ### 7.6 开发与联调 1. 后端引入模块:`jeecg-module-xslmes` 已被 `jeecg-system-start` 依赖(以当前 `pom` 为准)。 2. 修改接口后执行 **`mvn compile`** 并重启,避免 Controller 未编译导致 404。 3. 前端 `.env.development` 中 API 地址与后端 `context-path` 一致。 --- ## 8. Flyway 脚本索引(MES XSL 相关) 可按文件名在仓库中搜索;下列为当前常见的 `mes_xsl` 迁移(版本号以实际仓库为准): | 脚本 | 主题 | |------|------| | `V3.9.2_4` | 客户表、字典、菜单 | | `V3.9.2_5` ~ `V3.9.2_7` | 客户简称、同步状态、车辆 | | `V3.9.2_8` ~ `V3.9.2_9` | 单位表、种子 | | `V3.9.2_10` ~ `V3.9.2_18` | 车辆/单位/仪器/状态等补丁 | | `V3.9.2_11` | 供应商 | | `V3.9.2_20` ~ `V3.9.2_25` | 客户租户、字典、菜单按钮、is_leaf 等 | | **`V3.9.2_26`** | **仓库表、仓库字典、菜单与按钮** | | **`V3.9.2_27`** | **仓库分类 → sys_category,数据迁移** | | **`V3.9.2_28`** | **仓库分类维护按钮权限** | | **`V3.9.2_29`** | **单位分类 → sys_category,删除旧表** | --- ## 9. 文档维护 - 若表结构或常量编码变更,请同步修改:`MesXslWarehouseCategory`、`Flyway` 种子、`sys_category` 根/子节点编码。 - 合并分支前建议再执行一次:`git status` 确认 `jeecg-module-xslmes` 与 `V3.9.2_*` 脚本均已纳入版本控制。 --- *文档生成依据:分支 `客户到仓库功能模块` 工作区代码与 Flyway 脚本;相对 `main` 的 Git 提交差异请单独以 `git log` / `git diff` 为准。*