更新VSCode配置,启用Maven支持,设置Java 17环境,调整MybatisPlusSaasConfig以开启系统租户控制并添加新租户表。更新pom.xml以包含新模块jeecg-module-xslmes,优化Vue3环境配置以统一API路径,增强代理设置以支持完整的后端路径。修复useForm钩子中的字段重置逻辑,改进axios配置以处理相对URL的上下文路径问题。

This commit is contained in:
geht
2026-04-21 13:41:05 +08:00
parent 73426a7af3
commit 1b06e987dc
114 changed files with 8249 additions and 17 deletions

0
.vscode/launch.json vendored Normal file
View File

17
.vscode/settings.json vendored
View File

@@ -1,5 +1,14 @@
{ {
"java.compile.nullAnalysis.mode": "automatic", "java.compile.nullAnalysis.mode": "automatic",
"java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx4G -Xms100m -Xlog:disable", "java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx4G -Xms100m -Xlog:disable",
"java.configuration.updateBuildConfiguration": "interactive" "java.import.maven.enabled": true,
} "java.configuration.updateBuildConfiguration": "automatic",
"java.jdt.ls.java.home": "C:\\Program Files\\Java\\jdk-17",
"java.configuration.runtimes": [
{
"name": "JavaSE-17",
"path": "C:\\Program Files\\Java\\jdk-17",
"default": true
}
]
}

View File

@@ -0,0 +1,2 @@
com.yomahub.liteflow.springboot.config.LiteflowPropertyAutoConfiguration
com.yomahub.liteflow.springboot.config.LiteflowMainAutoConfiguration

View File

@@ -0,0 +1,220 @@
# MES XSL「客户到仓库」当前实现说明
本文档只描述**当前设计与实现**:数据表、字段含义、后端与前端逻辑、实体间关系、约束与使用方式,不涉及历史变更过程。
---
## 一、涉及的数据表
| 表名 | 作用 |
|------|------|
| `mes_xsl_customer` | 客户主数据 |
| `mes_xsl_warehouse` | 仓库主数据(通过分类 + 客户/供应商字段实现「客户库 / 供应商库」) |
| `mes_xsl_supplier` | 供应商主数据 |
| `mes_xsl_unit` | 单位主数据(分类挂在系统分类字典上) |
| `sys_category` | 系统「分类字典」:仓库分类树根编码 `XSLMES_WH`,单位分类树根编码 `XSLMES_UNIT` |
---
## 二、字段说明
### 2.1 `mes_xsl_customer`
| 字段 | 说明 |
|------|------|
| `id` | 主键 |
| `customer_code` | 客户编码 |
| `customer_name` | 客户名称 |
| `customer_short_name` | 客户简称 |
| `customer_region` | 区域,数据字典 `xslmes_customer_region` |
| `erp_code` | ERP 编码 |
| `status` | 业务状态,字典 `xslmes_customer_status` |
| `del_flag` | 逻辑删除0 正常 1 已删除) |
| `customer_desc` | 描述 |
| `iz_enable` | 是否启用(与状态等业务规则配合) |
| `create_by` / `create_time` / `update_by` / `update_time` | 审计字段(继承 Jeecg 基类) |
| `tenant_id` | 租户 ID |
### 2.2 `mes_xsl_warehouse`(客户 / 供应商与仓库的衔接点)
| 字段 | 说明 |
|------|------|
| `id` | 主键 |
| `warehouse_code` | 仓库编码 |
| `warehouse_name` | 仓库名称 |
| `warehouse_category` | **仓库分类**:存储 **`sys_category.id`**;该分类必须属于根编码 **`XSLMES_WH`** 下的子树 |
| `erp_code` | ERP 编码 |
| `status` | 启用/停用,字典 **`xslmes_unit_status`** |
| `customer_id` | 客户主键;**仅当**分类节点 `code = XSLMES_WH_F2_KH`(客户库)时必填且有意义 |
| `customer_short_name` | 客户简称(展示/冗余) |
| `supplier_id` | 供应商主键;**仅当**分类节点 `code = XSLMES_WH_F2_GYS`(供应商库)时必填且有意义 |
| `supplier_short_name` | 供应商简称(展示/冗余) |
| `del_flag` | 逻辑删除 |
| 审计字段、`tenant_id` | 同 Jeecg 惯例 |
**索引:** `warehouse_code``warehouse_category`
### 2.3 `sys_category`(与仓库、单位相关的用法)
- **仓库**:根节点 `code = XSLMES_WH`(常量 `MesXslWarehouseCategory.ROOT_CODE`)。`mes_xsl_warehouse.warehouse_category` 存任意该树下的 **`id`**(通常选叶子节点)。
- **单位**:根节点 `code = XSLMES_UNIT``mes_xsl_unit.category_id` 存对应 **`id`**。
**与仓库校验相关的分类编码(后端写死):**
| `sys_category.code` | 含义 | 业务规则 |
|---------------------|------|----------|
| `XSLMES_WH_F2_KH` | 客户库 | 保存仓库时 **必须**`customer_id` |
| `XSLMES_WH_F2_GYS` | 供应商库 | 保存仓库时 **必须**`supplier_id` |
当前种子树结构为:**根 `XSLMES_WH` → 一楼库 / 二楼仓库 → 各叶子**(成品库、待检库、客户库、供应商库等);运维可在该根下扩展子节点(需具备分类维护权限)。
### 2.4 `mes_xsl_supplier`
| 字段 | 说明 |
|------|------|
| `id` | 主键 |
| `supplier_code` | 编码 |
| `supplier_name` | 名称 |
| `supplier_short_name` | 简称 |
| `erp_code` | ERP 编码 |
| `remark` | 备注 |
| `status` | 状态,字典 `xslmes_supplier_status` |
| `del_flag` | 逻辑删除 |
| 审计字段、`tenant_id` | 同 Jeecg 惯例 |
### 2.5 `mes_xsl_unit`
| 字段 | 说明 |
|------|------|
| `id` | 主键 |
| `unit_code` / `unit_name` | 单位编码、名称 |
| `erp_code` | ERP 编码 |
| `category_id` | **所属分类**`sys_category.id`,且属于根 **`XSLMES_UNIT`** 子树 |
| `unit_desc` | 描述 |
| `status` | 字典 `xslmes_unit_status` |
| `del_flag` | 逻辑删除 |
| 审计字段、`tenant_id` | 同 Jeecg 惯例 |
---
## 三、实现逻辑
### 3.1 仓库保存与更新(后端)
实现类:`MesXslWarehouseServiceImpl`,在 `save` / `updateById` 时统一处理。
1. **按分类清理客户 / 供应商(`normalizePartners`**
- 未选分类:清空 `customer_id``customer_short_name``supplier_id``supplier_short_name`
- 已选分类:根据 `warehouse_category` 查询 `sys_category.code`
- 若不是 **客户库**`XSLMES_WH_F2_KH`):清空客户相关两字段。
- 若不是 **供应商库**`XSLMES_WH_F2_GYS`):清空供应商相关两字段。
- 目的:切换仓库类型后不留错误的客户或供应商数据。
2. **按分类校验(`validatePartners`**
- **客户库**`customer_id` 为空则抛出业务异常:「仓库分类为客户库时,请选择客户」。
- **供应商库**`supplier_id` 为空则抛出类似提示。
3. **分类编码查询**
- `MesXslWarehouseMapper.queryCategoryCodeById``SELECT code FROM sys_category WHERE id = ?`
### 3.2 字典与展示
- `MesXslWarehouse.warehouse_category` 使用 `@Dict(dictTable = "sys_category", dicText = "name", dicCode = "id")`,列表/详情按 **分类名称** 展示。
- `MesXslUnit.category_id` 同样指向 `sys_category`
### 3.3 前端(仓库)
- 菜单路由:`/xslmes/mesXslWarehouse`,列表组件:`MesXslWarehouseList`
- 左侧分类树:加载根编码 **`XSLMES_WH`** 的分类树(系统分类字典接口,与 `JCategorySelect``pcode` 一致)。
- 列表筛选与查询参数需与后端 `QueryGenerator` 约定一致(如 `warehouseCategory`、多选场景下的 `warehouseCategory_MultiString` 等)。
- 侧栏 **新增 / 编辑 / 删除分类**:调用 `/sys/category` 下标准增删改接口;按钮权限为 `xslmes:mes_xsl_warehouse_category:add|edit|delete`
### 3.4 前端(单位)
- 分类选择:`JCategorySelect``pcode: XSLMES_UNIT`
- 按左侧分类筛选列表时,后端通过 **递归查询子分类 id**`MesXslUnitService.listDescendantCategoryIds` / `MesXslUnitMapper`)过滤数据;依赖 **MySQL 8** 递归 CTE。
### 3.5 接口前缀REST
| 模块 | 路径前缀 |
|------|----------|
| 客户 | `/xslmes/mesXslCustomer` |
| 仓库 | `/xslmes/mesXslWarehouse` |
| 供应商 | `/xslmes/mesXslSupplier` |
| 单位 | `/xslmes/mesXslUnit` |
具体方法为 Jeecg 标准 CRUD如列表、新增、编辑、删除、导入导出等见各 `Controller`
---
## 四、关联关系
数据库层**不强制外键**时,由应用与数据约定保证引用有效。
```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"
```
**语义说明:**
- 一条仓库记录对应 **一个** `warehouse_category``sys_category` 的一行)。
- **客户库**:该仓库在业务上绑定 **一个** 客户(`customer_id``mes_xsl_customer.id`)。
- **供应商库**:绑定 **一个** 供应商(`supplier_id``mes_xsl_supplier.id`)。
- 其它分类:客户、供应商字段应在保存时被清空,不参与当前分类下的业务含义。
---
## 五、功能限制与注意点
1. **`warehouse_category` 必须是有效的 `sys_category.id`**,且业务上应选用 `XSLMES_WH` 树下节点;若 id 不存在或 `code` 查询不到,客户库/供应商库校验可能无法按预期触发。
2. **客户库与供应商库互斥**:非客户库会自动清空客户字段,非供应商库会自动清空供应商字段;不应依赖「改分类后仍保留另一侧 ID」。
3. **每条仓库仅一个客户、一个供应商字段**:与车辆等业务里「多客户 id 逗号拼接」等模型不同,仓库行是单值引用。
4. **多租户**:若启用 SaaS 租户隔离,`mes_xsl_*` 等表需在 MyBatis 租户配置中注册,否则会出现串租或查不到数据。
5. **单位分类树筛选**:依赖 MySQL 8 递归语法;低于 8.0 的环境需调整实现。
6. **前端联调**`VITE_GLOB_API_URL` 必须与后端 `context-path`(如 `/jeecg-boot`)一致,否则接口路径错误。
---
## 六、使用方法
### 6.1 环境
- 后端:`jeecg-system-start` 启动,数据库脚本由项目 **Flyway** 随应用升级自动执行,保证上述表与 `sys_category` 种子存在。
- 浏览器访问前端,使用已配置 **MES XSL** 菜单及仓库、客户、供应商、单位等权限的账号。
### 6.2 维护主数据
1. **客户**:菜单「客户管理」,维护 `mes_xsl_customer`
2. **供应商**:菜单「供应商管理」,维护 `mes_xsl_supplier`
3. **单位**:菜单「单位管理」,分类从 **`XSLMES_UNIT`** 树选择;可在侧栏维护分类(与仓库侧栏模式类似,权限依项目配置)。
### 6.3 维护仓库分类树
1. 打开 **仓库管理**
2. 在左侧分类区域使用新增/编辑/删除(需 `xslmes:mes_xsl_warehouse_category:*` 权限)。
3. 新建分类应挂在 **`XSLMES_WH`** 根之下,避免与其它业务根混淆。
### 6.4 新建「客户库」仓库
1. 新增仓库,**仓库分类** 选择 **客户库**`code``XSLMES_WH_F2_KH` 的节点)。
2. **必须** 选择客户并保存。
3. 若之后改为非客户库分类,保存后客户相关字段会被后端清空。
### 6.5 新建「供应商库」仓库
将分类选为 **供应商库**`XSLMES_WH_F2_GYS`**必须** 选择供应商;改为其它分类时供应商字段会被清空。
### 6.6 权限说明(仓库相关示例)
- 仓库 CRUD 等:`xslmes:mes_xsl_warehouse:add``edit``delete``deleteBatch``exportXls``importExcel``updateStatus` 等。
- 仓库分类维护:`xslmes:mes_xsl_warehouse_category:add``edit``delete`
实际以系统「菜单管理 / 角色授权」中配置为准。
---
*文档描述与当前代码、表结构一致;若常量 `MesXslWarehouseCategory` 或表字段有调整,请以仓库内源码与数据库为准同步更新本文档。*

View File

@@ -0,0 +1,309 @@
# 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` 为准。*

View File

@@ -51,7 +51,7 @@ public class MybatisPlusSaasConfig {
* 3.菜单表、租户表不做租户隔离 * 3.菜单表、租户表不做租户隔离
* 4.通过拦截器MybatisInterceptor实现增删改查数据 自动注入租户ID * 4.通过拦截器MybatisInterceptor实现增删改查数据 自动注入租户ID
*/ */
public static final Boolean OPEN_SYSTEM_TENANT_CONTROL = false; public static final Boolean OPEN_SYSTEM_TENANT_CONTROL = true;
/** /**
* 哪些表需要做多租户 表需要添加一个字段 tenant_id * 哪些表需要做多租户 表需要添加一个字段 tenant_id
@@ -80,6 +80,11 @@ public class MybatisPlusSaasConfig {
TENANT_TABLE.add("airag_knowledge"); TENANT_TABLE.add("airag_knowledge");
TENANT_TABLE.add("airag_knowledge_doc"); TENANT_TABLE.add("airag_knowledge_doc");
TENANT_TABLE.add("airag_model"); TENANT_TABLE.add("airag_model");
TENANT_TABLE.add("mes_xsl_customer");
TENANT_TABLE.add("mes_xsl_vehicle");
TENANT_TABLE.add("mes_xsl_unit");
TENANT_TABLE.add("mes_xsl_supplier");
TENANT_TABLE.add("mes_xsl_instrument");
} }
//2.示例测试 //2.示例测试

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jeecg-boot-module</artifactId>
<groupId>org.jeecgframework.boot3</groupId>
<version>3.9.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jeecg-module-xslmes</artifactId>
<name>jeecg-module-xslmes</name>
<description>MES XSL 业务模块Java 包org.jeecg.modules.xslmes</description>
<dependencies>
<dependency>
<groupId>org.jeecgframework.boot3</groupId>
<artifactId>jeecg-boot-base-core</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,24 @@
package org.jeecg.modules.xslmes.constant;
/**
* 客户业务状态(与「逻辑删除」无关)。删除仅由 del_flag 表示,一般不再写入 status。
* <p>
* 字典 xslmes_customer_status0=启用1=停用2=删除(可选)。
*/
public final class MesXslCustomerBizStatus {
private MesXslCustomerBizStatus() {}
/** 启用 */
public static final String ENABLED = "0";
/** 停用 */
public static final String DISABLED = "1";
/** 删除(字典项,业务上建议仅用 del_flag */
public static final String DELETED = "2";
public static boolean isDisabled(String status) {
return DISABLED.equals(status);
}
}

View File

@@ -0,0 +1,17 @@
package org.jeecg.modules.xslmes.constant;
/**
* MES 仓库分类(分类字典 sys_category根编码 {@link #ROOT_CODE}
*/
public final class MesXslWarehouseCategory {
private MesXslWarehouseCategory() {}
/** 根节点编码,与 JCategorySelect 的 pcode 一致 */
public static final String ROOT_CODE = "XSLMES_WH";
/** 客户库(二楼):须关联客户 */
public static final String CUSTOMER_CATEGORY_CODE = "XSLMES_WH_F2_KH";
/** 供应商库(二楼):须关联供应商 */
public static final String SUPPLIER_CATEGORY_CODE = "XSLMES_WH_F2_GYS";
}

View File

@@ -0,0 +1,154 @@
package org.jeecg.modules.xslmes.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.xslmes.constant.MesXslCustomerBizStatus;
import org.jeecg.modules.xslmes.entity.MesXslCustomer;
import org.jeecg.modules.xslmes.service.IMesXslCustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
import java.util.Objects;
/**
* MES 客户管理
*/
@Tag(name = "MES客户管理")
@RestController
@RequestMapping("/xslmes/mesXslCustomer")
@Slf4j
public class MesXslCustomerController extends JeecgController<MesXslCustomer, IMesXslCustomerService> {
@Autowired
private IMesXslCustomerService mesXslCustomerService;
@Operation(summary = "MES客户管理-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<MesXslCustomer>> queryPageList(
MesXslCustomer mesXslCustomer,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<MesXslCustomer> queryWrapper = QueryGenerator.initQueryWrapper(mesXslCustomer, req.getParameterMap());
Page<MesXslCustomer> page = new Page<>(pageNo, pageSize);
IPage<MesXslCustomer> pageList = mesXslCustomerService.page(page, queryWrapper);
return Result.OK(pageList);
}
@AutoLog(value = "MES客户管理-添加")
@Operation(summary = "MES客户管理-添加")
@RequiresPermissions("xslmes:mes_xsl_customer:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody MesXslCustomer mesXslCustomer) {
// 新增默认启用0空白或未传时写入启用并与 iz_enable 对齐
String st = mesXslCustomer.getStatus();
if (st != null) {
st = st.trim();
mesXslCustomer.setStatus(st.isEmpty() ? null : st);
}
if (mesXslCustomer.getStatus() == null || mesXslCustomer.getStatus().isEmpty()) {
mesXslCustomer.setStatus(MesXslCustomerBizStatus.ENABLED);
}
mesXslCustomerService.syncIzEnableWithStatus(mesXslCustomer);
mesXslCustomerService.save(mesXslCustomer);
return Result.OK("添加成功!");
}
@AutoLog(value = "MES客户管理-编辑")
@Operation(summary = "MES客户管理-编辑")
@RequiresPermissions("xslmes:mes_xsl_customer:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
public Result<String> edit(@RequestBody MesXslCustomer mesXslCustomer) {
if (mesXslCustomer.getStatus() != null) {
String s = mesXslCustomer.getStatus().trim();
mesXslCustomer.setStatus(s.isEmpty() ? null : s);
}
mesXslCustomerService.syncIzEnableWithStatus(mesXslCustomer);
mesXslCustomerService.updateById(mesXslCustomer);
return Result.OK("编辑成功!");
}
@AutoLog(value = "MES客户管理-启用/停用")
@Operation(summary = "MES客户管理-启用/停用(字典 xslmes_customer_status0启用 1停用")
@RequiresPermissions("xslmes:mes_xsl_customer:updateStatus")
@PostMapping(value = "/updateStatus")
public Result<String> updateStatus(
@RequestParam(name = "id", required = true) String id,
@RequestParam(name = "status", required = true) String status) {
if (status != null) {
status = status.trim();
}
if (!MesXslCustomerBizStatus.ENABLED.equals(status) && !MesXslCustomerBizStatus.DISABLED.equals(status)) {
return Result.error("状态参数非法");
}
// 与 MesXslUnitController.updateStatus 一致用 lambdaUpdate并同步 iz_enable字典 1 停用时为 0
int izEnable = MesXslCustomerBizStatus.DISABLED.equals(status) ? 0 : 1;
boolean updated = mesXslCustomerService.lambdaUpdate()
.eq(MesXslCustomer::getId, id)
.set(MesXslCustomer::getStatus, status)
.set(MesXslCustomer::getIzEnable, izEnable)
.update();
if (updated) {
return Result.OK("操作成功");
}
// MySQL 在 SET 值与库中完全一致时可能返回 0 行;或需二次确认是否已是目标状态
MesXslCustomer cur = mesXslCustomerService.getById(id);
if (cur != null && Objects.equals(status, cur.getStatus())) {
return Result.OK("操作成功");
}
return Result.error("操作失败请确认记录存在且租户与当前登录一致tenant_id 勿为空)");
}
@AutoLog(value = "MES客户管理-删除")
@Operation(summary = "MES客户管理-删除")
@RequiresPermissions("xslmes:mes_xsl_customer:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
mesXslCustomerService.removeById(id);
return Result.OK("删除成功!");
}
@AutoLog(value = "MES客户管理-批量删除")
@Operation(summary = "MES客户管理-批量删除")
@RequiresPermissions("xslmes:mes_xsl_customer:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
mesXslCustomerService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
@Operation(summary = "MES客户管理-通过id查询")
@GetMapping(value = "/queryById")
public Result<MesXslCustomer> queryById(@RequestParam(name = "id", required = true) String id) {
MesXslCustomer entity = mesXslCustomerService.getById(id);
if (entity == null) {
return Result.error("未找到对应数据");
}
return Result.OK(entity);
}
@RequiresPermissions("xslmes:mes_xsl_customer:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, MesXslCustomer mesXslCustomer) {
return super.exportXls(request, mesXslCustomer, MesXslCustomer.class, "MES客户管理");
}
@RequiresPermissions("xslmes:mes_xsl_customer:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, MesXslCustomer.class);
}
}

View File

@@ -0,0 +1,126 @@
package org.jeecg.modules.xslmes.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.xslmes.entity.MesXslInstrument;
import org.jeecg.modules.xslmes.service.IMesXslInstrumentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
/**
* MES 器具管理
*/
@Tag(name = "MES器具管理")
@RestController
@RequestMapping("/xslmes/mesXslInstrument")
@Slf4j
public class MesXslInstrumentController extends JeecgController<MesXslInstrument, IMesXslInstrumentService> {
@Autowired
private IMesXslInstrumentService mesXslInstrumentService;
@Operation(summary = "MES器具管理-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<MesXslInstrument>> queryPageList(
MesXslInstrument mesXslInstrument,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<MesXslInstrument> queryWrapper = QueryGenerator.initQueryWrapper(mesXslInstrument, req.getParameterMap());
Page<MesXslInstrument> page = new Page<>(pageNo, pageSize);
IPage<MesXslInstrument> pageList = mesXslInstrumentService.page(page, queryWrapper);
return Result.OK(pageList);
}
@AutoLog(value = "MES器具管理-添加")
@Operation(summary = "MES器具管理-添加")
@RequiresPermissions("xslmes:mes_xsl_instrument:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody MesXslInstrument mesXslInstrument) {
if (mesXslInstrument.getStatus() == null || mesXslInstrument.getStatus().isEmpty()) {
mesXslInstrument.setStatus("0");
}
mesXslInstrumentService.save(mesXslInstrument);
return Result.OK("添加成功!");
}
@AutoLog(value = "MES器具管理-编辑")
@Operation(summary = "MES器具管理-编辑")
@RequiresPermissions("xslmes:mes_xsl_instrument:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
public Result<String> edit(@RequestBody MesXslInstrument mesXslInstrument) {
mesXslInstrumentService.updateById(mesXslInstrument);
return Result.OK("编辑成功!");
}
@AutoLog(value = "MES器具管理-停用/启用")
@Operation(summary = "MES器具管理-停用/启用")
@RequiresPermissions("xslmes:mes_xsl_instrument:updateStatus")
@PostMapping(value = "/updateStatus")
public Result<String> updateStatus(
@RequestParam(name = "id", required = true) String id,
@RequestParam(name = "status", required = true) String status) {
if (!"0".equals(status) && !"1".equals(status)) {
return Result.error("状态参数非法");
}
boolean ok = mesXslInstrumentService.lambdaUpdate()
.eq(MesXslInstrument::getId, id)
.set(MesXslInstrument::getStatus, status)
.update();
return ok ? Result.OK("操作成功") : Result.error("操作失败");
}
@AutoLog(value = "MES器具管理-删除")
@Operation(summary = "MES器具管理-删除")
@RequiresPermissions("xslmes:mes_xsl_instrument:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
mesXslInstrumentService.removeById(id);
return Result.OK("删除成功!");
}
@AutoLog(value = "MES器具管理-批量删除")
@Operation(summary = "MES器具管理-批量删除")
@RequiresPermissions("xslmes:mes_xsl_instrument:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
mesXslInstrumentService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
@Operation(summary = "MES器具管理-通过id查询")
@GetMapping(value = "/queryById")
public Result<MesXslInstrument> queryById(@RequestParam(name = "id", required = true) String id) {
MesXslInstrument entity = mesXslInstrumentService.getById(id);
if (entity == null) {
return Result.error("未找到对应数据");
}
return Result.OK(entity);
}
@RequiresPermissions("xslmes:mes_xsl_instrument:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, MesXslInstrument mesXslInstrument) {
return super.exportXls(request, mesXslInstrument, MesXslInstrument.class, "MES器具管理");
}
@RequiresPermissions("xslmes:mes_xsl_instrument:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, MesXslInstrument.class);
}
}

View File

@@ -0,0 +1,126 @@
package org.jeecg.modules.xslmes.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.xslmes.entity.MesXslSupplier;
import org.jeecg.modules.xslmes.service.IMesXslSupplierService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
/**
* MES 供应商管理
*/
@Tag(name = "MES供应商管理")
@RestController
@RequestMapping("/xslmes/mesXslSupplier")
@Slf4j
public class MesXslSupplierController extends JeecgController<MesXslSupplier, IMesXslSupplierService> {
@Autowired
private IMesXslSupplierService mesXslSupplierService;
@Operation(summary = "MES供应商管理-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<MesXslSupplier>> queryPageList(
MesXslSupplier mesXslSupplier,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<MesXslSupplier> queryWrapper = QueryGenerator.initQueryWrapper(mesXslSupplier, req.getParameterMap());
Page<MesXslSupplier> page = new Page<>(pageNo, pageSize);
IPage<MesXslSupplier> pageList = mesXslSupplierService.page(page, queryWrapper);
return Result.OK(pageList);
}
@AutoLog(value = "MES供应商管理-添加")
@Operation(summary = "MES供应商管理-添加")
@RequiresPermissions("xslmes:mes_xsl_supplier:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody MesXslSupplier mesXslSupplier) {
if (mesXslSupplier.getStatus() == null || mesXslSupplier.getStatus().isEmpty()) {
mesXslSupplier.setStatus("0");
}
mesXslSupplierService.save(mesXslSupplier);
return Result.OK("添加成功!");
}
@AutoLog(value = "MES供应商管理-编辑")
@Operation(summary = "MES供应商管理-编辑")
@RequiresPermissions("xslmes:mes_xsl_supplier:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
public Result<String> edit(@RequestBody MesXslSupplier mesXslSupplier) {
mesXslSupplierService.updateById(mesXslSupplier);
return Result.OK("编辑成功!");
}
@AutoLog(value = "MES供应商管理-停用/启用")
@Operation(summary = "MES供应商管理-停用/启用")
@RequiresPermissions("xslmes:mes_xsl_supplier:updateStatus")
@PostMapping(value = "/updateStatus")
public Result<String> updateStatus(
@RequestParam(name = "id", required = true) String id,
@RequestParam(name = "status", required = true) String status) {
if (!"0".equals(status) && !"1".equals(status)) {
return Result.error("状态参数非法");
}
boolean ok = mesXslSupplierService.lambdaUpdate()
.eq(MesXslSupplier::getId, id)
.set(MesXslSupplier::getStatus, status)
.update();
return ok ? Result.OK("操作成功") : Result.error("操作失败");
}
@AutoLog(value = "MES供应商管理-删除")
@Operation(summary = "MES供应商管理-删除")
@RequiresPermissions("xslmes:mes_xsl_supplier:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
mesXslSupplierService.removeById(id);
return Result.OK("删除成功!");
}
@AutoLog(value = "MES供应商管理-批量删除")
@Operation(summary = "MES供应商管理-批量删除")
@RequiresPermissions("xslmes:mes_xsl_supplier:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
mesXslSupplierService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
@Operation(summary = "MES供应商管理-通过id查询")
@GetMapping(value = "/queryById")
public Result<MesXslSupplier> queryById(@RequestParam(name = "id", required = true) String id) {
MesXslSupplier entity = mesXslSupplierService.getById(id);
if (entity == null) {
return Result.error("未找到对应数据");
}
return Result.OK(entity);
}
@RequiresPermissions("xslmes:mes_xsl_supplier:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, MesXslSupplier mesXslSupplier) {
return super.exportXls(request, mesXslSupplier, MesXslSupplier.class, "MES供应商管理");
}
@RequiresPermissions("xslmes:mes_xsl_supplier:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, MesXslSupplier.class);
}
}

View File

@@ -0,0 +1,133 @@
package org.jeecg.modules.xslmes.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.xslmes.entity.MesXslUnit;
import org.jeecg.modules.xslmes.service.IMesXslUnitService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
import java.util.List;
/**
* MES 单位管理
*/
@Tag(name = "MES单位管理")
@RestController
@RequestMapping("/xslmes/mesXslUnit")
@Slf4j
public class MesXslUnitController extends JeecgController<MesXslUnit, IMesXslUnitService> {
@Autowired
private IMesXslUnitService mesXslUnitService;
@Operation(summary = "MES单位管理-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<MesXslUnit>> queryPageList(
MesXslUnit mesXslUnit,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(name = "treeCategoryId", required = false) String treeCategoryId,
HttpServletRequest req) {
QueryWrapper<MesXslUnit> queryWrapper = QueryGenerator.initQueryWrapper(mesXslUnit, req.getParameterMap());
if (oConvertUtils.isNotEmpty(treeCategoryId)) {
List<String> ids = mesXslUnitService.listDescendantCategoryIds(treeCategoryId);
queryWrapper.in("category_id", ids);
}
Page<MesXslUnit> page = new Page<>(pageNo, pageSize);
IPage<MesXslUnit> pageList = mesXslUnitService.page(page, queryWrapper);
return Result.OK(pageList);
}
@AutoLog(value = "MES单位管理-添加")
@Operation(summary = "MES单位管理-添加")
@RequiresPermissions("xslmes:mes_xsl_unit:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody MesXslUnit mesXslUnit) {
if (mesXslUnit.getStatus() == null || mesXslUnit.getStatus().isEmpty()) {
mesXslUnit.setStatus("0");
}
mesXslUnitService.save(mesXslUnit);
return Result.OK("添加成功!");
}
@AutoLog(value = "MES单位管理-编辑")
@Operation(summary = "MES单位管理-编辑")
@RequiresPermissions("xslmes:mes_xsl_unit:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
public Result<String> edit(@RequestBody MesXslUnit mesXslUnit) {
mesXslUnitService.updateById(mesXslUnit);
return Result.OK("编辑成功!");
}
@AutoLog(value = "MES单位管理-停用/启用")
@Operation(summary = "MES单位管理-停用/启用")
@RequiresPermissions("xslmes:mes_xsl_unit:updateStatus")
@PostMapping(value = "/updateStatus")
public Result<String> updateStatus(
@RequestParam(name = "id", required = true) String id,
@RequestParam(name = "status", required = true) String status) {
if (!"0".equals(status) && !"1".equals(status)) {
return Result.error("状态参数非法");
}
boolean ok = mesXslUnitService.lambdaUpdate()
.eq(MesXslUnit::getId, id)
.set(MesXslUnit::getStatus, status)
.update();
return ok ? Result.OK("操作成功") : Result.error("操作失败");
}
@AutoLog(value = "MES单位管理-删除")
@Operation(summary = "MES单位管理-删除")
@RequiresPermissions("xslmes:mes_xsl_unit:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
mesXslUnitService.removeById(id);
return Result.OK("删除成功!");
}
@AutoLog(value = "MES单位管理-批量删除")
@Operation(summary = "MES单位管理-批量删除")
@RequiresPermissions("xslmes:mes_xsl_unit:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
mesXslUnitService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
@Operation(summary = "MES单位管理-通过id查询")
@GetMapping(value = "/queryById")
public Result<MesXslUnit> queryById(@RequestParam(name = "id", required = true) String id) {
MesXslUnit entity = mesXslUnitService.getById(id);
if (entity == null) {
return Result.error("未找到对应数据");
}
return Result.OK(entity);
}
@RequiresPermissions("xslmes:mes_xsl_unit:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, MesXslUnit mesXslUnit) {
return super.exportXls(request, mesXslUnit, MesXslUnit.class, "MES单位管理");
}
@RequiresPermissions("xslmes:mes_xsl_unit:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, MesXslUnit.class);
}
}

View File

@@ -0,0 +1,188 @@
package org.jeecg.modules.xslmes.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.xslmes.entity.MesXslVehicle;
import org.jeecg.modules.xslmes.service.IMesXslVehicleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
/**
* MES 车辆管理
*/
@Tag(name = "MES车辆管理")
@RestController
@RequestMapping("/xslmes/mesXslVehicle")
@Slf4j
public class MesXslVehicleController extends JeecgController<MesXslVehicle, IMesXslVehicleService> {
@Autowired
private IMesXslVehicleService mesXslVehicleService;
@Operation(summary = "MES车辆管理-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<MesXslVehicle>> queryPageList(
MesXslVehicle mesXslVehicle,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<MesXslVehicle> queryWrapper = QueryGenerator.initQueryWrapper(mesXslVehicle, req.getParameterMap());
Page<MesXslVehicle> page = new Page<>(pageNo, pageSize);
IPage<MesXslVehicle> pageList = mesXslVehicleService.page(page, queryWrapper);
return Result.OK(pageList);
}
@AutoLog(value = "MES车辆管理-添加")
@Operation(summary = "MES车辆管理-添加")
@RequiresPermissions("xslmes:mes_xsl_vehicle:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody MesXslVehicle mesXslVehicle) {
if (oConvertUtils.isEmpty(mesXslVehicle.getVehicleBelong())) {
return Result.error("车辆归属不能为空");
}
if (mesXslVehicle.getStatus() == null || mesXslVehicle.getStatus().isEmpty()) {
mesXslVehicle.setStatus("0");
}
applyVehicleBelong(mesXslVehicle);
mesXslVehicleService.save(mesXslVehicle);
return Result.OK("添加成功!");
}
@AutoLog(value = "MES车辆管理-编辑")
@Operation(summary = "MES车辆管理-编辑")
@RequiresPermissions("xslmes:mes_xsl_vehicle:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
public Result<String> edit(@RequestBody MesXslVehicle mesXslVehicle) {
if (oConvertUtils.isEmpty(mesXslVehicle.getVehicleBelong())) {
return Result.error("车辆归属不能为空");
}
applyVehicleBelong(mesXslVehicle);
mesXslVehicleService.updateById(mesXslVehicle);
// updateById 默认不更新 null 字段,互斥侧需在库中显式置 NULL
forceNullOppositeFieldsInDb(mesXslVehicle.getId(), mesXslVehicle.getVehicleBelong());
return Result.OK("编辑成功!");
}
/**
* 按车辆归属清理互斥字段:客户/供应商/本公司
*/
private void applyVehicleBelong(MesXslVehicle v) {
if (oConvertUtils.isEmpty(v.getVehicleBelong())) {
return;
}
String b = v.getVehicleBelong();
if ("1".equals(b)) {
v.setSupplierId(null);
v.setSupplierName(null);
v.setSupplierShortName(null);
} else if ("2".equals(b)) {
v.setCustomerIds(null);
v.setCustomerShortName(null);
} else if ("3".equals(b)) {
v.setCustomerIds(null);
v.setCustomerShortName(null);
v.setSupplierId(null);
v.setSupplierName(null);
v.setSupplierShortName(null);
}
}
/**
* 将互斥侧客户/供应商字段在数据库中置为 NULLMyBatis-Plus updateById 会忽略 null
*/
private void forceNullOppositeFieldsInDb(String id, String vehicleBelong) {
if (oConvertUtils.isEmpty(id) || oConvertUtils.isEmpty(vehicleBelong)) {
return;
}
LambdaUpdateWrapper<MesXslVehicle> uw = new LambdaUpdateWrapper<MesXslVehicle>().eq(MesXslVehicle::getId, id);
if ("1".equals(vehicleBelong)) {
uw.set(MesXslVehicle::getSupplierId, null)
.set(MesXslVehicle::getSupplierName, null)
.set(MesXslVehicle::getSupplierShortName, null);
} else if ("2".equals(vehicleBelong)) {
uw.set(MesXslVehicle::getCustomerIds, null).set(MesXslVehicle::getCustomerShortName, null);
} else if ("3".equals(vehicleBelong)) {
uw.set(MesXslVehicle::getCustomerIds, null)
.set(MesXslVehicle::getCustomerShortName, null)
.set(MesXslVehicle::getSupplierId, null)
.set(MesXslVehicle::getSupplierName, null)
.set(MesXslVehicle::getSupplierShortName, null);
} else {
return;
}
mesXslVehicleService.update(null, uw);
}
@AutoLog(value = "MES车辆管理-停用/启用")
@Operation(summary = "MES车辆管理-停用/启用")
@RequiresPermissions("xslmes:mes_xsl_vehicle:updateStatus")
@PostMapping(value = "/updateStatus")
public Result<String> updateStatus(
@RequestParam(name = "id", required = true) String id,
@RequestParam(name = "status", required = true) String status) {
if (!"0".equals(status) && !"1".equals(status)) {
return Result.error("状态参数非法");
}
boolean ok = mesXslVehicleService.lambdaUpdate()
.eq(MesXslVehicle::getId, id)
.set(MesXslVehicle::getStatus, status)
.update();
return ok ? Result.OK("操作成功") : Result.error("操作失败");
}
@AutoLog(value = "MES车辆管理-删除")
@Operation(summary = "MES车辆管理-删除")
@RequiresPermissions("xslmes:mes_xsl_vehicle:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
mesXslVehicleService.removeById(id);
return Result.OK("删除成功!");
}
@AutoLog(value = "MES车辆管理-批量删除")
@Operation(summary = "MES车辆管理-批量删除")
@RequiresPermissions("xslmes:mes_xsl_vehicle:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
mesXslVehicleService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
@Operation(summary = "MES车辆管理-通过id查询")
@GetMapping(value = "/queryById")
public Result<MesXslVehicle> queryById(@RequestParam(name = "id", required = true) String id) {
MesXslVehicle entity = mesXslVehicleService.getById(id);
if (entity == null) {
return Result.error("未找到对应数据");
}
return Result.OK(entity);
}
@RequiresPermissions("xslmes:mes_xsl_vehicle:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, MesXslVehicle mesXslVehicle) {
return super.exportXls(request, mesXslVehicle, MesXslVehicle.class, "MES车辆管理");
}
@RequiresPermissions("xslmes:mes_xsl_vehicle:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, MesXslVehicle.class);
}
}

View File

@@ -0,0 +1,131 @@
package org.jeecg.modules.xslmes.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.xslmes.entity.MesXslWarehouse;
import org.jeecg.modules.xslmes.service.IMesXslWarehouseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
/**
* MES 仓库管理
*/
@Tag(name = "MES仓库管理")
@RestController
@RequestMapping("/xslmes/mesXslWarehouse")
@Slf4j
public class MesXslWarehouseController extends JeecgController<MesXslWarehouse, IMesXslWarehouseService> {
@Autowired
private IMesXslWarehouseService mesXslWarehouseService;
@Operation(summary = "MES仓库管理-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<MesXslWarehouse>> queryPageList(
MesXslWarehouse mesXslWarehouse,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(name = "treeCategoryId", required = false) String treeCategoryId,
HttpServletRequest req) {
QueryWrapper<MesXslWarehouse> queryWrapper = QueryGenerator.initQueryWrapper(mesXslWarehouse, req.getParameterMap());
if (oConvertUtils.isNotEmpty(treeCategoryId)) {
queryWrapper.eq("warehouse_category", treeCategoryId);
}
Page<MesXslWarehouse> page = new Page<>(pageNo, pageSize);
IPage<MesXslWarehouse> pageList = mesXslWarehouseService.page(page, queryWrapper);
return Result.OK(pageList);
}
@AutoLog(value = "MES仓库管理-添加")
@Operation(summary = "MES仓库管理-添加")
@RequiresPermissions("xslmes:mes_xsl_warehouse:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody MesXslWarehouse mesXslWarehouse) {
if (mesXslWarehouse.getStatus() == null || mesXslWarehouse.getStatus().isEmpty()) {
mesXslWarehouse.setStatus("0");
}
mesXslWarehouseService.save(mesXslWarehouse);
return Result.OK("添加成功!");
}
@AutoLog(value = "MES仓库管理-编辑")
@Operation(summary = "MES仓库管理-编辑")
@RequiresPermissions("xslmes:mes_xsl_warehouse:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
public Result<String> edit(@RequestBody MesXslWarehouse mesXslWarehouse) {
mesXslWarehouseService.updateById(mesXslWarehouse);
return Result.OK("编辑成功!");
}
@AutoLog(value = "MES仓库管理-停用/启用")
@Operation(summary = "MES仓库管理-停用/启用(字典 xslmes_unit_status0启用 1停用")
@RequiresPermissions("xslmes:mes_xsl_warehouse:updateStatus")
@PostMapping(value = "/updateStatus")
public Result<String> updateStatus(
@RequestParam(name = "id", required = true) String id,
@RequestParam(name = "status", required = true) String status) {
if (!"0".equals(status) && !"1".equals(status)) {
return Result.error("状态参数非法");
}
boolean ok = mesXslWarehouseService.lambdaUpdate()
.eq(MesXslWarehouse::getId, id)
.set(MesXslWarehouse::getStatus, status)
.update();
return ok ? Result.OK("操作成功") : Result.error("操作失败");
}
@AutoLog(value = "MES仓库管理-删除")
@Operation(summary = "MES仓库管理-删除")
@RequiresPermissions("xslmes:mes_xsl_warehouse:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
mesXslWarehouseService.removeById(id);
return Result.OK("删除成功!");
}
@AutoLog(value = "MES仓库管理-批量删除")
@Operation(summary = "MES仓库管理-批量删除")
@RequiresPermissions("xslmes:mes_xsl_warehouse:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
mesXslWarehouseService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}
@Operation(summary = "MES仓库管理-通过id查询")
@GetMapping(value = "/queryById")
public Result<MesXslWarehouse> queryById(@RequestParam(name = "id", required = true) String id) {
MesXslWarehouse entity = mesXslWarehouseService.getById(id);
if (entity == null) {
return Result.error("未找到对应数据");
}
return Result.OK(entity);
}
@RequiresPermissions("xslmes:mes_xsl_warehouse:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, MesXslWarehouse mesXslWarehouse) {
return super.exportXls(request, mesXslWarehouse, MesXslWarehouse.class, "MES仓库管理");
}
@RequiresPermissions("xslmes:mes_xsl_warehouse:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, MesXslWarehouse.class);
}
}

View File

@@ -0,0 +1,69 @@
package org.jeecg.modules.xslmes.entity;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.system.base.entity.JeecgEntity;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecg.common.aspect.annotation.Dict;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
/**
* MES 客户管理
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("mes_xsl_customer")
@Schema(description = "MES客户管理")
public class MesXslCustomer extends JeecgEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Excel(name = "客户编码", width = 20)
@Schema(description = "客户编码")
private String customerCode;
@Excel(name = "客户名称", width = 28)
@Schema(description = "客户名称")
private String customerName;
@Excel(name = "客户简称", width = 18)
@Schema(description = "客户简称")
private String customerShortName;
@Excel(name = "客户区域", width = 15, dicCode = "xslmes_customer_region")
@Dict(dicCode = "xslmes_customer_region")
@Schema(description = "客户区域")
private String customerRegion;
@Excel(name = "ERP编码", width = 18)
@Schema(description = "ERP编码")
private String erpCode;
@Excel(name = "状态", width = 12, dicCode = "xslmes_customer_status")
@Dict(dicCode = "xslmes_customer_status")
@Schema(description = "业务状态(字典 xslmes_customer_status0启用1停用2删除逻辑删除见 del_flag")
private String status;
@Schema(description = "删除状态0正常 1已删除")
@TableLogic
private Integer delFlag;
@Excel(name = "客户描述", width = 36)
@Schema(description = "客户描述")
private String customerDesc;
@Excel(name = "是否启用", width = 10)
@Schema(description = "是否启用:停用(status=1) 为 0否则为 1由服务端同步")
private Integer izEnable;
@Schema(description = "租户ID")
private Integer tenantId;
}

View File

@@ -0,0 +1,51 @@
package org.jeecg.modules.xslmes.entity;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.common.system.base.entity.JeecgEntity;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.io.Serializable;
/**
* MES 器具管理
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("mes_xsl_instrument")
@Schema(description = "MES器具管理")
public class MesXslInstrument extends JeecgEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Excel(name = "编号条码", width = 22)
@Schema(description = "编号/条码")
private String barcode;
@Excel(name = "状态", width = 10, dicCode = "xslmes_instrument_status")
@Dict(dicCode = "xslmes_instrument_status")
@Schema(description = "状态0启用 1停用")
private String status;
@Excel(name = "规格型号", width = 18, dicCode = "xslmes_instrument_spec")
@Dict(dicCode = "xslmes_instrument_spec")
@Schema(description = "规格型号")
private String specModel;
@Excel(name = "备注", width = 28)
@Schema(description = "备注")
private String remark;
@Schema(description = "删除状态0正常 1已删除")
@TableLogic
private Integer delFlag;
@Schema(description = "租户ID")
private Integer tenantId;
}

View File

@@ -0,0 +1,58 @@
package org.jeecg.modules.xslmes.entity;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.common.system.base.entity.JeecgEntity;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.io.Serializable;
/**
* MES 供应商管理
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("mes_xsl_supplier")
@Schema(description = "MES供应商管理")
public class MesXslSupplier extends JeecgEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Excel(name = "编码", width = 18)
@Schema(description = "编码")
private String supplierCode;
@Excel(name = "名称", width = 24)
@Schema(description = "名称")
private String supplierName;
@Excel(name = "简称", width = 16)
@Schema(description = "简称")
private String supplierShortName;
@Excel(name = "ERP编码", width = 18)
@Schema(description = "ERP编码")
private String erpCode;
@Excel(name = "备注", width = 28)
@Schema(description = "备注")
private String remark;
@Excel(name = "状态", width = 10, dicCode = "xslmes_supplier_status")
@Dict(dicCode = "xslmes_supplier_status")
@Schema(description = "状态0启用 1停用")
private String status;
@Schema(description = "删除状态0正常 1已删除")
@TableLogic
private Integer delFlag;
@Schema(description = "租户ID")
private Integer tenantId;
}

View File

@@ -0,0 +1,59 @@
package org.jeecg.modules.xslmes.entity;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.common.system.base.entity.JeecgEntity;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.io.Serializable;
/**
* MES 单位
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("mes_xsl_unit")
@Schema(description = "MES单位")
public class MesXslUnit extends JeecgEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Excel(name = "编码", width = 18)
@Schema(description = "编码")
private String unitCode;
@Excel(name = "名称", width = 20)
@Schema(description = "名称")
private String unitName;
@Excel(name = "ERP编码", width = 18)
@Schema(description = "ERP编码")
private String erpCode;
@Excel(name = "所属分类", width = 20, dictTable = "sys_category", dicText = "name", dicCode = "id")
@Dict(dictTable = "sys_category", dicText = "name", dicCode = "id")
@Schema(description = "所属分类sys_category.id根编码 XSLMES_UNIT")
private String categoryId;
@Excel(name = "描述", width = 40)
@Schema(description = "描述")
private String unitDesc;
@Excel(name = "状态", width = 10, dicCode = "xslmes_unit_status")
@Dict(dicCode = "xslmes_unit_status")
@Schema(description = "状态0启用 1停用")
private String status;
@Schema(description = "删除状态0正常 1已删除")
@TableLogic
private Integer delFlag;
@Schema(description = "租户ID")
private Integer tenantId;
}

View File

@@ -0,0 +1,104 @@
package org.jeecg.modules.xslmes.entity;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.common.system.base.entity.JeecgEntity;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* MES 车辆管理
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("mes_xsl_vehicle")
@Schema(description = "MES车辆管理")
public class MesXslVehicle extends JeecgEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Excel(name = "车牌号", width = 18)
@Schema(description = "车牌号")
private String plateNumber;
@Excel(name = "车辆归属", width = 12, dicCode = "xslmes_vehicle_belong")
@Dict(dicCode = "xslmes_vehicle_belong")
@Schema(description = "车辆归属1客户 2供应商 3本公司")
private String vehicleBelong;
@Excel(name = "车辆皮重KG", width = 14)
@Schema(description = "车辆皮重(KG)")
private BigDecimal tareWeightKg;
@Excel(name = "装载量", width = 14)
@Schema(description = "装载量")
private BigDecimal loadCapacity;
@Excel(name = "单位ID", width = 22)
@Schema(description = "单位IDmes_xsl_unit.id")
private String unitId;
@Excel(name = "单位", width = 10)
@Schema(description = "单位(名称,与所选单位一致)")
private String loadUnit;
@Excel(name = "客户ID", width = 36)
@Schema(description = "客户ID多选逗号分隔")
private String customerIds;
@Excel(name = "客户简称", width = 28)
@Schema(description = "客户简称展示")
private String customerShortName;
@Excel(name = "供应商ID", width = 22)
@Schema(description = "供应商ID")
private String supplierId;
@Excel(name = "供应商名称", width = 24)
@Schema(description = "供应商名称")
private String supplierName;
@Excel(name = "供应商简称", width = 18)
@Schema(description = "供应商简称")
private String supplierShortName;
@Excel(name = "车长", width = 12)
@Schema(description = "车长")
private BigDecimal vehicleLength;
@Excel(name = "车宽", width = 12)
@Schema(description = "车宽")
private BigDecimal vehicleWidth;
@Excel(name = "车高", width = 12)
@Schema(description = "车高")
private BigDecimal vehicleHeight;
@Excel(name = "司机", width = 14)
@Schema(description = "司机")
private String driverName;
@Excel(name = "联系电话", width = 16)
@Schema(description = "联系电话")
private String driverPhone;
@Excel(name = "状态", width = 10, dicCode = "xslmes_vehicle_status")
@Dict(dicCode = "xslmes_vehicle_status")
@Schema(description = "状态0启用 1停用")
private String status;
@Schema(description = "删除状态0正常 1已删除")
@TableLogic
private Integer delFlag;
@Schema(description = "租户ID")
private Integer tenantId;
}

View File

@@ -0,0 +1,69 @@
package org.jeecg.modules.xslmes.entity;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.common.system.base.entity.JeecgEntity;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.io.Serializable;
/**
* MES 仓库管理
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("mes_xsl_warehouse")
@Schema(description = "MES仓库管理")
public class MesXslWarehouse extends JeecgEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Excel(name = "仓库编码", width = 18)
@Schema(description = "仓库编码")
private String warehouseCode;
@Excel(name = "仓库名称", width = 22)
@Schema(description = "仓库名称")
private String warehouseName;
@Excel(name = "仓库分类", width = 14, dictTable = "sys_category", dicText = "name", dicCode = "id")
@Dict(dictTable = "sys_category", dicText = "name", dicCode = "id")
@Schema(description = "仓库分类sys_category.id根编码 XSLMES_WH")
private String warehouseCategory;
@Excel(name = "ERP编码", width = 18)
@Schema(description = "ERP编码")
private String erpCode;
@Excel(name = "状态", width = 10, dicCode = "xslmes_unit_status")
@Dict(dicCode = "xslmes_unit_status")
@Schema(description = "状态0启用 1停用")
private String status;
@Schema(description = "客户ID")
private String customerId;
@Excel(name = "客户简称", width = 16)
@Schema(description = "客户简称")
private String customerShortName;
@Schema(description = "供应商ID")
private String supplierId;
@Excel(name = "供应商简称", width = 14)
@Schema(description = "供应商简称")
private String supplierShortName;
@Schema(description = "删除状态0正常 1已删除")
@TableLogic
private Integer delFlag;
@Schema(description = "租户ID")
private Integer tenantId;
}

View File

@@ -0,0 +1,12 @@
package org.jeecg.modules.xslmes.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.jeecg.modules.xslmes.entity.MesXslCustomer;
/**
* MES 客户管理 Mapper
*/
@Mapper
public interface MesXslCustomerMapper extends BaseMapper<MesXslCustomer> {
}

View File

@@ -0,0 +1,12 @@
package org.jeecg.modules.xslmes.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.jeecg.modules.xslmes.entity.MesXslInstrument;
/**
* MES 器具管理 Mapper
*/
@Mapper
public interface MesXslInstrumentMapper extends BaseMapper<MesXslInstrument> {
}

View File

@@ -0,0 +1,12 @@
package org.jeecg.modules.xslmes.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.jeecg.modules.xslmes.entity.MesXslSupplier;
/**
* MES 供应商管理 Mapper
*/
@Mapper
public interface MesXslSupplierMapper extends BaseMapper<MesXslSupplier> {
}

View File

@@ -0,0 +1,24 @@
package org.jeecg.modules.xslmes.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.xslmes.entity.MesXslUnit;
import java.util.List;
/**
* MES 单位 Mapper
*/
@Mapper
public interface MesXslUnitMapper extends BaseMapper<MesXslUnit> {
/** 分类字典子树:含自身及所有后代 idMySQL 8 递归 CTE */
@Select("WITH RECURSIVE unit_cat_tree AS ( "
+ " SELECT id FROM sys_category WHERE id = #{rootId} "
+ " UNION ALL "
+ " SELECT c.id FROM sys_category c INNER JOIN unit_cat_tree t ON c.pid = t.id "
+ ") SELECT id FROM unit_cat_tree")
List<String> listDescendantCategoryIds(@Param("rootId") String rootId);
}

View File

@@ -0,0 +1,12 @@
package org.jeecg.modules.xslmes.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.jeecg.modules.xslmes.entity.MesXslVehicle;
/**
* MES 车辆管理 Mapper
*/
@Mapper
public interface MesXslVehicleMapper extends BaseMapper<MesXslVehicle> {
}

View File

@@ -0,0 +1,18 @@
package org.jeecg.modules.xslmes.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.xslmes.entity.MesXslWarehouse;
/**
* MES 仓库管理 Mapper
*/
@Mapper
public interface MesXslWarehouseMapper extends BaseMapper<MesXslWarehouse> {
/** 按分类字典主键取编码(用于客户库/供应商库等业务判断) */
@Select("SELECT code FROM sys_category WHERE id = #{id}")
String queryCategoryCodeById(@Param("id") String id);
}

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.xslmes.mapper.MesXslCustomerMapper">
</mapper>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.xslmes.mapper.MesXslSupplierMapper">
</mapper>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.xslmes.mapper.MesXslUnitMapper">
</mapper>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.xslmes.mapper.MesXslVehicleMapper">
</mapper>

View File

@@ -0,0 +1,5 @@
/**
* MES XSL 业务模块Maven 工程名jeecg-module-xslmes
* 包含:客户管理({@link org.jeecg.modules.xslmes.entity.MesXslCustomer})等。
*/
package org.jeecg.modules.xslmes;

View File

@@ -0,0 +1,15 @@
package org.jeecg.modules.xslmes.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.xslmes.entity.MesXslCustomer;
/**
* MES 客户管理
*/
public interface IMesXslCustomerService extends IService<MesXslCustomer> {
/**
* 按业务状态同步 izEnable停用字典值 1为 0其余为 1。删除仅 del_flag与 status 无关。
*/
void syncIzEnableWithStatus(MesXslCustomer entity);
}

View File

@@ -0,0 +1,10 @@
package org.jeecg.modules.xslmes.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.xslmes.entity.MesXslInstrument;
/**
* MES 器具管理
*/
public interface IMesXslInstrumentService extends IService<MesXslInstrument> {
}

View File

@@ -0,0 +1,10 @@
package org.jeecg.modules.xslmes.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.xslmes.entity.MesXslSupplier;
/**
* MES 供应商管理
*/
public interface IMesXslSupplierService extends IService<MesXslSupplier> {
}

View File

@@ -0,0 +1,15 @@
package org.jeecg.modules.xslmes.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.xslmes.entity.MesXslUnit;
import java.util.List;
/**
* MES 单位
*/
public interface IMesXslUnitService extends IService<MesXslUnit> {
/** 单位分类sys_category选中节点及其所有下级 id用于列表筛选 */
List<String> listDescendantCategoryIds(String rootId);
}

View File

@@ -0,0 +1,10 @@
package org.jeecg.modules.xslmes.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.xslmes.entity.MesXslVehicle;
/**
* MES 车辆管理
*/
public interface IMesXslVehicleService extends IService<MesXslVehicle> {
}

View File

@@ -0,0 +1,10 @@
package org.jeecg.modules.xslmes.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.xslmes.entity.MesXslWarehouse;
/**
* MES 仓库管理
*/
public interface IMesXslWarehouseService extends IService<MesXslWarehouse> {
}

View File

@@ -0,0 +1,32 @@
package org.jeecg.modules.xslmes.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.xslmes.constant.MesXslCustomerBizStatus;
import org.jeecg.modules.xslmes.entity.MesXslCustomer;
import org.jeecg.modules.xslmes.mapper.MesXslCustomerMapper;
import org.jeecg.modules.xslmes.service.IMesXslCustomerService;
import org.springframework.stereotype.Service;
/**
* MES 客户管理
*/
@Service
public class MesXslCustomerServiceImpl extends ServiceImpl<MesXslCustomerMapper, MesXslCustomer> implements IMesXslCustomerService {
@Override
public void syncIzEnableWithStatus(MesXslCustomer entity) {
if (entity == null) {
return;
}
String s = entity.getStatus();
if (s != null) {
s = s.trim();
}
// 仅停用(字典值1) 为未启用,其余字典值视为启用
if (MesXslCustomerBizStatus.isDisabled(s)) {
entity.setIzEnable(0);
} else {
entity.setIzEnable(1);
}
}
}

View File

@@ -0,0 +1,14 @@
package org.jeecg.modules.xslmes.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.xslmes.entity.MesXslInstrument;
import org.jeecg.modules.xslmes.mapper.MesXslInstrumentMapper;
import org.jeecg.modules.xslmes.service.IMesXslInstrumentService;
import org.springframework.stereotype.Service;
/**
* MES 器具管理
*/
@Service
public class MesXslInstrumentServiceImpl extends ServiceImpl<MesXslInstrumentMapper, MesXslInstrument> implements IMesXslInstrumentService {
}

View File

@@ -0,0 +1,14 @@
package org.jeecg.modules.xslmes.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.xslmes.entity.MesXslSupplier;
import org.jeecg.modules.xslmes.mapper.MesXslSupplierMapper;
import org.jeecg.modules.xslmes.service.IMesXslSupplierService;
import org.springframework.stereotype.Service;
/**
* MES 供应商管理
*/
@Service
public class MesXslSupplierServiceImpl extends ServiceImpl<MesXslSupplierMapper, MesXslSupplier> implements IMesXslSupplierService {
}

View File

@@ -0,0 +1,21 @@
package org.jeecg.modules.xslmes.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.xslmes.entity.MesXslUnit;
import org.jeecg.modules.xslmes.mapper.MesXslUnitMapper;
import org.jeecg.modules.xslmes.service.IMesXslUnitService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* MES 单位
*/
@Service
public class MesXslUnitServiceImpl extends ServiceImpl<MesXslUnitMapper, MesXslUnit> implements IMesXslUnitService {
@Override
public List<String> listDescendantCategoryIds(String rootId) {
return baseMapper.listDescendantCategoryIds(rootId);
}
}

View File

@@ -0,0 +1,14 @@
package org.jeecg.modules.xslmes.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.xslmes.entity.MesXslVehicle;
import org.jeecg.modules.xslmes.mapper.MesXslVehicleMapper;
import org.jeecg.modules.xslmes.service.IMesXslVehicleService;
import org.springframework.stereotype.Service;
/**
* MES 车辆管理
*/
@Service
public class MesXslVehicleServiceImpl extends ServiceImpl<MesXslVehicleMapper, MesXslVehicle> implements IMesXslVehicleService {
}

View File

@@ -0,0 +1,69 @@
package org.jeecg.modules.xslmes.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.xslmes.constant.MesXslWarehouseCategory;
import org.jeecg.modules.xslmes.entity.MesXslWarehouse;
import org.jeecg.modules.xslmes.mapper.MesXslWarehouseMapper;
import org.jeecg.modules.xslmes.service.IMesXslWarehouseService;
import org.springframework.stereotype.Service;
/**
* MES 仓库管理
*/
@Service
public class MesXslWarehouseServiceImpl extends ServiceImpl<MesXslWarehouseMapper, MesXslWarehouse> implements IMesXslWarehouseService {
@Override
public boolean save(MesXslWarehouse entity) {
normalizePartners(entity);
validatePartners(entity);
return super.save(entity);
}
@Override
public boolean updateById(MesXslWarehouse entity) {
normalizePartners(entity);
validatePartners(entity);
return super.updateById(entity);
}
/**
* 非客户库清空客户;非供应商库清空供应商(切换分类时避免脏数据)
*/
private void normalizePartners(MesXslWarehouse e) {
if (oConvertUtils.isEmpty(e.getWarehouseCategory())) {
e.setCustomerId(null);
e.setCustomerShortName(null);
e.setSupplierId(null);
e.setSupplierShortName(null);
return;
}
String code = baseMapper.queryCategoryCodeById(e.getWarehouseCategory());
if (!MesXslWarehouseCategory.CUSTOMER_CATEGORY_CODE.equals(code)) {
e.setCustomerId(null);
e.setCustomerShortName(null);
}
if (!MesXslWarehouseCategory.SUPPLIER_CATEGORY_CODE.equals(code)) {
e.setSupplierId(null);
e.setSupplierShortName(null);
}
}
private void validatePartners(MesXslWarehouse e) {
if (oConvertUtils.isEmpty(e.getWarehouseCategory())) {
return;
}
String code = baseMapper.queryCategoryCodeById(e.getWarehouseCategory());
if (MesXslWarehouseCategory.CUSTOMER_CATEGORY_CODE.equals(code)) {
if (oConvertUtils.isEmpty(e.getCustomerId())) {
throw new JeecgBootException("仓库分类为客户库时,请选择客户");
}
} else if (MesXslWarehouseCategory.SUPPLIER_CATEGORY_CODE.equals(code)) {
if (oConvertUtils.isEmpty(e.getSupplierId())) {
throw new JeecgBootException("仓库分类为供应商库时,请选择供应商");
}
}
}
}

View File

@@ -16,6 +16,7 @@
<module>jeecg-module-demo</module> <module>jeecg-module-demo</module>
<module>jeecg-boot-module-airag</module> <module>jeecg-boot-module-airag</module>
<module>jeecg-module-print</module> <module>jeecg-module-print</module>
<module>jeecg-module-xslmes</module>
</modules> </modules>

View File

@@ -0,0 +1,47 @@
liteflow:
print-banner: false
parse-mode: PARSE_ONE_ON_FIRST_EXEC
#异步线程最长的等待时间秒(只用于when)默认值为15
# when-max-wait-seconds: 180
rule-source-ext-data-map:
# url: jdbc:mysql://localhost:3306/poseidon
# driverClassName: com.mysql.cj.jdbc.Driver
# username: root
# password: 123456
applicationName: jeecg
#是否开启SQL日志
sqlLogEnabled: true
#是否开启SQL数据轮询自动刷新机制 默认不开启
# pollingEnabled: false
#SQL数据轮询时间间隔(s) 默认为60s
# pollingIntervalSeconds: 60
#规则配置后首次轮询的起始时间(s) 默认为60s
# pollingStartSeconds: 60
#以下是chain表的配置这个一定得有
#编排规则表的表名
chainTableName: airag_flow
#编排规则表中应用名称存储字段名
chainApplicationNameField: application_name
#规则名称存储的字段名
chainNameField: id
#EL表达式的字段(只存EL)
elDataField: chain
#以下是决策路由字段的配置,如果你没用到决策路由,可以不配置
# routeField: route
# namespaceField: namespace
# #是否启用这条规则
# chainEnableField: enable
# #规则表自定义过滤SQL
chainCustomSql: select id, application_name, chain from airag_flow where status = 'enable' and chain is not null
#以下是script表的配置如果你没使用到脚本下面可以不配置
# scriptTableName: script
# scriptApplicationNameField: application_name
# scriptIdField: script_id
# scriptNameField: script_name
# scriptDataField: script_data
# scriptTypeField: script_type
# scriptLanguageField: script_language
# #是否启用这条脚本
# scriptEnableField: enable
# #脚本表自定义过滤SQL
# scriptCustomSql: 这里设置自定义脚本表SQL

File diff suppressed because one or more lines are too long

View File

@@ -30,6 +30,12 @@
<artifactId>jeecg-module-print</artifactId> <artifactId>jeecg-module-print</artifactId>
<version>${jeecgboot.version}</version> <version>${jeecgboot.version}</version>
</dependency> </dependency>
<!-- MES XSL 业务模块 -->
<dependency>
<groupId>org.jeecgframework.boot3</groupId>
<artifactId>jeecg-module-xslmes</artifactId>
<version>${jeecgboot.version}</version>
</dependency>
<!-- flyway 数据库自动升级 --> <!-- flyway 数据库自动升级 -->
<dependency> <dependency>

View File

@@ -0,0 +1,5 @@
-- 车辆管理关联单位主键
ALTER TABLE `mes_xsl_vehicle`
ADD COLUMN `unit_id` varchar(36) DEFAULT NULL COMMENT '单位IDmes_xsl_unit.id' AFTER `load_capacity`,
ADD KEY `idx_mes_xsl_vehicle_unit` (`unit_id`);

View File

@@ -0,0 +1,79 @@
-- MES 供应商管理 + 字典 + 菜单 + 管理员角色授权幂等
CREATE TABLE IF NOT EXISTS `mes_xsl_supplier` (
`id` varchar(36) NOT NULL COMMENT '主键',
`supplier_code` varchar(64) NOT NULL COMMENT '编码',
`supplier_name` varchar(100) NOT NULL COMMENT '名称',
`erp_code` varchar(64) DEFAULT NULL COMMENT 'ERP编码',
`status` varchar(10) DEFAULT '1' COMMENT '状态(字典 xslmes_supplier_status)',
`del_flag` tinyint(1) DEFAULT '0' COMMENT '删除标志(0正常1删除)',
`create_by` varchar(50) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(50) DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`tenant_id` int DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`id`),
KEY `idx_mes_xsl_supplier_code` (`supplier_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES供应商管理';
INSERT INTO `sys_dict` (`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `type`, `tenant_id`)
SELECT REPLACE(UUID(), '-', ''), 'MES供应商状态', 'xslmes_supplier_status', '停用启用', 0, 'admin', NOW(), 0, 0
WHERE NOT EXISTS (SELECT 1 FROM `sys_dict` WHERE `dict_code` = 'xslmes_supplier_status' AND `del_flag` = 0);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '停用', '0', 1, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_supplier_status' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = '0');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '启用', '1', 2, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_supplier_status' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = '1');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000350', '1900000000000000300', '供应商管理', '/xslmes/mesXslSupplier', 'xslmes/mesXslSupplier/MesXslSupplierList', 1, NULL, NULL, 1, NULL, '0', 4.00, 0, 'ant-design:shop-outlined', 1, 1, 0, 0, 'MES供应商管理', 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000350');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000351', '1900000000000000350', '添加', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_supplier:add', '1', 1.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000351');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000352', '1900000000000000350', '编辑', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_supplier:edit', '1', 2.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000352');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000353', '1900000000000000350', '删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_supplier:delete', '1', 3.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000353');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000354', '1900000000000000350', '批量删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_supplier:deleteBatch', '1', 4.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000354');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000355', '1900000000000000350', '导出', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_supplier:exportXls', '1', 5.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000355');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000356', '1900000000000000350', '导入', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_supplier:importExcel', '1', 6.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000356');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000357', '1900000000000000350', '停用启用', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_supplier:updateStatus', '1', 7.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000357');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000430', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000350', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000430');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000431', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000351', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000431');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000432', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000352', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000432');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000433', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000353', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000433');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000434', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000354', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000434');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000435', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000355', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000435');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000436', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000356', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000436');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000437', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000357', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000437');

View File

@@ -0,0 +1,23 @@
-- 车辆管理车辆归属字典 + 供应商/司机字段
INSERT INTO `sys_dict` (`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `type`, `tenant_id`)
SELECT REPLACE(UUID(), '-', ''), 'MES车辆归属', 'xslmes_vehicle_belong', '客户供应商本公司', 0, 'admin', NOW(), 0, 0
WHERE NOT EXISTS (SELECT 1 FROM `sys_dict` WHERE `dict_code` = 'xslmes_vehicle_belong' AND `del_flag` = 0);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '客户', '1', 1, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_vehicle_belong' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = '1');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '供应商', '2', 2, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_vehicle_belong' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = '2');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '本公司', '3', 3, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_vehicle_belong' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = '3');
ALTER TABLE `mes_xsl_vehicle`
ADD COLUMN `vehicle_belong` varchar(10) DEFAULT NULL COMMENT '车辆归属(字典 xslmes_vehicle_belong)' AFTER `plate_number`,
ADD COLUMN `supplier_id` varchar(36) DEFAULT NULL COMMENT '供应商ID' AFTER `customer_short_name`,
ADD COLUMN `supplier_name` varchar(200) DEFAULT NULL COMMENT '供应商名称' AFTER `supplier_id`,
ADD COLUMN `driver_name` varchar(64) DEFAULT NULL COMMENT '司机' AFTER `vehicle_height`,
ADD COLUMN `driver_phone` varchar(32) DEFAULT NULL COMMENT '联系电话' AFTER `driver_name`,
ADD KEY `idx_mes_xsl_vehicle_belong` (`vehicle_belong`);

View File

@@ -0,0 +1,4 @@
-- 车辆管理列注释车辆自重改为车辆皮重字段名不变 tare_weight_kg
ALTER TABLE `mes_xsl_vehicle`
MODIFY COLUMN `tare_weight_kg` decimal(12,3) DEFAULT NULL COMMENT '车辆皮重(KG)';

View File

@@ -0,0 +1,5 @@
-- 单位分类长度组根分类 V3.9.2_9 种子一致已存在 category_code=length_group 则跳过
INSERT INTO `mes_xsl_unit_category` (`id`, `parent_id`, `category_code`, `category_name`, `sort_no`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000504', '0', 'length_group', '长度组', 4, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit_category` WHERE `category_code` = 'length_group');

View File

@@ -0,0 +1,15 @@
-- 单位模块 tenant_id NULL 对齐为 0避免多租户拦截器下查询不到数据
-- 说明MyBatis 租户插件追加 WHERE tenant_id = ?NULL 行不会被命中 左侧分类树缺长度组列表所属分类为空
UPDATE `mes_xsl_unit_category` SET `tenant_id` = 0 WHERE `tenant_id` IS NULL;
UPDATE `mes_xsl_unit` SET `tenant_id` = 0 WHERE `tenant_id` IS NULL;
-- 长度组根分类若不存在tenant_id=0 与默认租户一致
INSERT INTO `mes_xsl_unit_category` (`id`, `parent_id`, `category_code`, `category_name`, `sort_no`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000504', '0', 'length_group', '长度组', 4, '1', 0, 'admin', NOW(), 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit_category` WHERE `category_code` = 'length_group');
-- 常见长度单位若未挂分类挂到长度组
UPDATE `mes_xsl_unit`
SET `category_id` = '1900000000000000504', `tenant_id` = COALESCE(`tenant_id`, 0)
WHERE `unit_code` IN ('m', 'km', 'cm') AND (`category_id` IS NULL OR `category_id` = '');

View File

@@ -0,0 +1,16 @@
-- 供应商简称备注车辆供应商简称选择供应商后展示
ALTER TABLE `mes_xsl_supplier`
ADD COLUMN `supplier_short_name` varchar(64) DEFAULT NULL COMMENT '简称' AFTER `supplier_name`;
ALTER TABLE `mes_xsl_supplier`
ADD COLUMN `remark` varchar(500) DEFAULT NULL COMMENT '备注' AFTER `erp_code`;
ALTER TABLE `mes_xsl_vehicle`
ADD COLUMN `supplier_short_name` varchar(64) DEFAULT NULL COMMENT '供应商简称' AFTER `supplier_name`;
-- 已有车辆从供应商回填简称无简称时用名称
UPDATE `mes_xsl_vehicle` v
INNER JOIN `mes_xsl_supplier` s ON v.`supplier_id` = s.`id`
SET v.`supplier_short_name` = COALESCE(NULLIF(TRIM(s.`supplier_short_name`), ''), s.`supplier_name`)
WHERE v.`supplier_id` IS NOT NULL;

View File

@@ -0,0 +1,91 @@
-- MES 器具管理 + 字典 + 菜单 + 管理员角色授权幂等
CREATE TABLE IF NOT EXISTS `mes_xsl_instrument` (
`id` varchar(36) NOT NULL COMMENT '主键',
`barcode` varchar(64) NOT NULL COMMENT '编号/条码',
`status` varchar(10) DEFAULT '1' COMMENT '状态(字典 xslmes_instrument_status)',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`spec_model` varchar(64) DEFAULT NULL COMMENT '规格型号(字典 xslmes_instrument_spec)',
`del_flag` tinyint(1) DEFAULT '0' COMMENT '删除标志(0正常1删除)',
`create_by` varchar(50) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(50) DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`tenant_id` int DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`id`),
KEY `idx_mes_xsl_instrument_barcode` (`barcode`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES器具管理';
-- 状态启用/停用
INSERT INTO `sys_dict` (`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `type`, `tenant_id`)
SELECT REPLACE(UUID(), '-', ''), 'MES器具状态', 'xslmes_instrument_status', '停用启用', 0, 'admin', NOW(), 0, 0
WHERE NOT EXISTS (SELECT 1 FROM `sys_dict` WHERE `dict_code` = 'xslmes_instrument_status' AND `del_flag` = 0);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '停用', '0', 1, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_instrument_status' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = '0');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '启用', '1', 2, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_instrument_status' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = '1');
-- 规格型号字典示例项可后续在字典管理追加
INSERT INTO `sys_dict` (`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `type`, `tenant_id`)
SELECT REPLACE(UUID(), '-', ''), 'MES器具规格型号', 'xslmes_instrument_spec', '器具规格尺寸等', 0, 'admin', NOW(), 0, 0
WHERE NOT EXISTS (SELECT 1 FROM `sys_dict` WHERE `dict_code` = 'xslmes_instrument_spec' AND `del_flag` = 0);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '130*100*23.6', '130*100*23.6', 1, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_instrument_spec' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = '130*100*23.6');
-- 菜单父级 MES1900000000000000300
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000370', '1900000000000000300', '器具管理', '/xslmes/mesXslInstrument', 'xslmes/mesXslInstrument/MesXslInstrumentList', 1, NULL, NULL, 1, NULL, '0', 5.00, 0, 'ant-design:experiment-outlined', 1, 1, 0, 0, 'MES器具管理', 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000370');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000371', '1900000000000000370', '添加', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_instrument:add', '1', 1.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000371');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000372', '1900000000000000370', '编辑', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_instrument:edit', '1', 2.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000372');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000373', '1900000000000000370', '删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_instrument:delete', '1', 3.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000373');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000374', '1900000000000000370', '批量删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_instrument:deleteBatch', '1', 4.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000374');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000375', '1900000000000000370', '导出', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_instrument:exportXls', '1', 5.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000375');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000376', '1900000000000000370', '导入', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_instrument:importExcel', '1', 6.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000376');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000377', '1900000000000000370', '停用启用', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_instrument:updateStatus', '1', 7.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000377');
-- 管理员角色授权
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000450', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000370', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000450');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000451', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000371', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000451');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000452', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000372', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000452');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000453', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000373', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000453');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000454', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000374', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000454');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000455', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000375', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000455');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000456', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000376', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000456');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000457', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000377', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000457');

View File

@@ -0,0 +1,61 @@
-- MES 各模块启用/停用状态统一为0=启用1=停用客户字典保留 2=删除
-- 说明将原 0=停用1=启用 的业务数据与字典项做互换
-- ========== 业务表 status 互换 ==========
UPDATE `mes_xsl_supplier` SET `status` = CASE `status` WHEN '0' THEN '__T0__' WHEN '1' THEN '__T1__' ELSE `status` END WHERE `status` IN ('0','1');
UPDATE `mes_xsl_supplier` SET `status` = CASE `status` WHEN '__T0__' THEN '1' WHEN '__T1__' THEN '0' ELSE `status` END;
UPDATE `mes_xsl_vehicle` SET `status` = CASE `status` WHEN '0' THEN '__T0__' WHEN '1' THEN '__T1__' ELSE `status` END WHERE `status` IN ('0','1');
UPDATE `mes_xsl_vehicle` SET `status` = CASE `status` WHEN '__T0__' THEN '1' WHEN '__T1__' THEN '0' ELSE `status` END;
UPDATE `mes_xsl_unit` SET `status` = CASE `status` WHEN '0' THEN '__T0__' WHEN '1' THEN '__T1__' ELSE `status` END WHERE `status` IN ('0','1');
UPDATE `mes_xsl_unit` SET `status` = CASE `status` WHEN '__T0__' THEN '1' WHEN '__T1__' THEN '0' ELSE `status` END;
UPDATE `mes_xsl_unit_category` SET `status` = CASE `status` WHEN '0' THEN '__T0__' WHEN '1' THEN '__T1__' ELSE `status` END WHERE `status` IN ('0','1');
UPDATE `mes_xsl_unit_category` SET `status` = CASE `status` WHEN '__T0__' THEN '1' WHEN '__T1__' THEN '0' ELSE `status` END;
UPDATE `mes_xsl_instrument` SET `status` = CASE `status` WHEN '0' THEN '__T0__' WHEN '1' THEN '__T1__' ELSE `status` END WHERE `status` IN ('0','1');
UPDATE `mes_xsl_instrument` SET `status` = CASE `status` WHEN '__T0__' THEN '1' WHEN '__T1__' THEN '0' ELSE `status` END;
-- 客户删除字典值 2 0/1 互换
UPDATE `mes_xsl_customer` SET `status` = CASE `status` WHEN '0' THEN '__T0__' WHEN '1' THEN '__T1__' WHEN '2' THEN '2' ELSE `status` END WHERE `status` IN ('0','1','2');
UPDATE `mes_xsl_customer` SET `status` = CASE `status` WHEN '__T0__' THEN '1' WHEN '__T1__' THEN '0' ELSE `status` END;
-- ========== 字典项 item_value / item_text ==========
-- 二元状态字典
UPDATE `sys_dict_item` i
INNER JOIN `sys_dict` d ON i.`dict_id` = d.`id` AND d.`dict_code` IN ('xslmes_supplier_status', 'xslmes_vehicle_status', 'xslmes_unit_status', 'xslmes_instrument_status')
SET i.`item_value` = CASE i.`item_value` WHEN '0' THEN '__T0__' WHEN '1' THEN '__T1__' ELSE i.`item_value` END
WHERE i.`item_value` IN ('0','1');
UPDATE `sys_dict_item` i
INNER JOIN `sys_dict` d ON i.`dict_id` = d.`id` AND d.`dict_code` IN ('xslmes_supplier_status', 'xslmes_vehicle_status', 'xslmes_unit_status', 'xslmes_instrument_status')
SET i.`item_value` = CASE i.`item_value` WHEN '__T0__' THEN '1' WHEN '__T1__' THEN '0' ELSE i.`item_value` END
WHERE i.`item_value` IN ('__T0__','__T1__');
UPDATE `sys_dict_item` i
INNER JOIN `sys_dict` d ON i.`dict_id` = d.`id` AND d.`dict_code` IN ('xslmes_supplier_status', 'xslmes_vehicle_status', 'xslmes_unit_status', 'xslmes_instrument_status')
SET i.`item_text` = CASE i.`item_value` WHEN '0' THEN '启用' WHEN '1' THEN '停用' ELSE i.`item_text` END;
-- 客户状态0启用 1停用 2删除
UPDATE `sys_dict_item` i
INNER JOIN `sys_dict` d ON i.`dict_id` = d.`id` AND d.`dict_code` = 'xslmes_customer_status'
SET i.`item_value` = CASE i.`item_value` WHEN '0' THEN '__T0__' WHEN '1' THEN '__T1__' WHEN '2' THEN '2' ELSE i.`item_value` END
WHERE i.`item_value` IN ('0','1','2');
UPDATE `sys_dict_item` i
INNER JOIN `sys_dict` d ON i.`dict_id` = d.`id` AND d.`dict_code` = 'xslmes_customer_status'
SET i.`item_value` = CASE i.`item_value` WHEN '__T0__' THEN '1' WHEN '__T1__' THEN '0' ELSE i.`item_value` END
WHERE i.`item_value` IN ('__T0__','__T1__');
UPDATE `sys_dict_item` i
INNER JOIN `sys_dict` d ON i.`dict_id` = d.`id` AND d.`dict_code` = 'xslmes_customer_status'
SET i.`item_text` = CASE i.`item_value` WHEN '0' THEN '启用' WHEN '1' THEN '停用' WHEN '2' THEN '删除' ELSE i.`item_text` END;
-- ========== 列默认值改为启用=0 ==========
ALTER TABLE `mes_xsl_supplier` MODIFY COLUMN `status` varchar(10) DEFAULT '0' COMMENT '状态(字典 xslmes_supplier_status0启用1停用)';
ALTER TABLE `mes_xsl_vehicle` MODIFY COLUMN `status` varchar(10) DEFAULT '0' COMMENT '状态(字典 xslmes_vehicle_status0启用1停用)';
ALTER TABLE `mes_xsl_unit` MODIFY COLUMN `status` varchar(10) DEFAULT '0' COMMENT '状态(字典 xslmes_unit_status0启用1停用)';
ALTER TABLE `mes_xsl_unit_category` MODIFY COLUMN `status` varchar(10) DEFAULT '0' COMMENT '状态(字典 xslmes_unit_status0启用1停用)';
ALTER TABLE `mes_xsl_instrument` MODIFY COLUMN `status` varchar(10) DEFAULT '0' COMMENT '状态(字典 xslmes_instrument_status0启用1停用)';
ALTER TABLE `mes_xsl_customer` MODIFY COLUMN `status` varchar(10) DEFAULT '0' COMMENT '状态(字典 xslmes_customer_status0启用1停用2删除)';

View File

@@ -0,0 +1,3 @@
-- 多租户拦截器按 tenant_id=当前租户查询/更新列为 NULL 时与 tenant_id=0 无法匹配导致列表能展示异常数据或更新 0 视数据与 SQL 而定
-- 将空租户统一为 0与默认租户上下文一致
UPDATE `mes_xsl_customer` SET `tenant_id` = 0 WHERE `tenant_id` IS NULL;

View File

@@ -0,0 +1,12 @@
-- 客户状态字典文案与后端/前端约定对齐item_value 0=启用 1=停用 2=删除
-- 说明早期 V3.9.2_4 曾将启用/停用文案与 value 写反导致库中 status=0 仍显示停用
UPDATE `sys_dict_item` i
INNER JOIN `sys_dict` d ON i.`dict_id` = d.`id` AND d.`dict_code` = 'xslmes_customer_status' AND d.`del_flag` = 0
SET i.`item_text` = CASE i.`item_value`
WHEN '0' THEN '启用'
WHEN '1' THEN '停用'
WHEN '2' THEN '删除'
ELSE i.`item_text`
END
WHERE i.`item_value` IN ('0', '1', '2');

View File

@@ -0,0 +1,21 @@
-- 车辆表补充 supplier_short_name兼容未成功执行 V3.9.2_16 的库幂等
SET @col_exists := (
SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'mes_xsl_vehicle'
AND COLUMN_NAME = 'supplier_short_name'
);
SET @ddl := IF(@col_exists = 0,
'ALTER TABLE `mes_xsl_vehicle` ADD COLUMN `supplier_short_name` varchar(64) DEFAULT NULL COMMENT ''供应商简称'' AFTER `supplier_name`',
'SELECT 1');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 已有车辆用供应商名称回填简称不依赖供应商表是否已有 supplier_short_name
UPDATE `mes_xsl_vehicle` v
INNER JOIN `mes_xsl_supplier` s ON v.`supplier_id` = s.`id`
SET v.`supplier_short_name` = s.`supplier_name`
WHERE v.`supplier_id` IS NOT NULL
AND (v.`supplier_short_name` IS NULL OR TRIM(v.`supplier_short_name`) = '');

View File

@@ -0,0 +1,9 @@
-- 客户管理列表启用/停用按钮权限与供应商管理 xslmes:mes_xsl_supplier:updateStatus 同级
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000317', '1900000000000000301', '停用启用', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_customer:updateStatus', '1', 7.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000317');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000399', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000317', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000399');

View File

@@ -0,0 +1,80 @@
-- MES XSL将各列表菜单下的按钮权限幂等写入/对齐 sys_permissionmenu_type=2parent_id 指向对应页面菜单
-- 覆盖客户车辆单位含分类按钮供应商器具 含编辑删除导出导入停用启用及添加批量删除
-- 若历史数据中 parent_id 错位或缺行本脚本通过 INSERT ... ON DUPLICATE KEY UPDATE 修复便于系统管理-菜单管理-按钮授权中展示与分配
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`) VALUES
-- 客户管理 1900000000000000301
('1900000000000000311', '1900000000000000301', '添加', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_customer:add', '1', 1.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000312', '1900000000000000301', '编辑', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_customer:edit', '1', 2.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000313', '1900000000000000301', '删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_customer:delete', '1', 3.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000314', '1900000000000000301', '批量删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_customer:deleteBatch', '1', 4.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000315', '1900000000000000301', '导出', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_customer:exportXls', '1', 5.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000316', '1900000000000000301', '导入', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_customer:importExcel', '1', 6.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000317', '1900000000000000301', '停用启用', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_customer:updateStatus', '1', 7.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
-- 车辆管理 1900000000000000320
('1900000000000000321', '1900000000000000320', '添加', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_vehicle:add', '1', 1.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000322', '1900000000000000320', '编辑', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_vehicle:edit', '1', 2.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000323', '1900000000000000320', '删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_vehicle:delete', '1', 3.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000324', '1900000000000000320', '批量删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_vehicle:deleteBatch', '1', 4.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000325', '1900000000000000320', '导出', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_vehicle:exportXls', '1', 5.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000326', '1900000000000000320', '导入', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_vehicle:importExcel', '1', 6.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000327', '1900000000000000320', '停用启用', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_vehicle:updateStatus', '1', 7.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
-- 单位管理 1900000000000000330含单位分类相关按钮
('1900000000000000331', '1900000000000000330', '添加', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit:add', '1', 1.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000332', '1900000000000000330', '编辑', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit:edit', '1', 2.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000333', '1900000000000000330', '删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit:delete', '1', 3.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000334', '1900000000000000330', '批量删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit:deleteBatch', '1', 4.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000335', '1900000000000000330', '导出', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit:exportXls', '1', 5.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000336', '1900000000000000330', '导入', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit:importExcel', '1', 6.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000337', '1900000000000000330', '停用启用', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit:updateStatus', '1', 7.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000338', '1900000000000000330', '新增分类', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit_category:add', '1', 8.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000339', '1900000000000000330', '编辑分类', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit_category:edit', '1', 9.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000340', '1900000000000000330', '删除分类', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit_category:delete', '1', 10.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
-- 供应商管理 1900000000000000350
('1900000000000000351', '1900000000000000350', '添加', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_supplier:add', '1', 1.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000352', '1900000000000000350', '编辑', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_supplier:edit', '1', 2.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000353', '1900000000000000350', '删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_supplier:delete', '1', 3.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000354', '1900000000000000350', '批量删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_supplier:deleteBatch', '1', 4.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000355', '1900000000000000350', '导出', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_supplier:exportXls', '1', 5.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000356', '1900000000000000350', '导入', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_supplier:importExcel', '1', 6.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000357', '1900000000000000350', '停用启用', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_supplier:updateStatus', '1', 7.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
-- 器具管理 1900000000000000370
('1900000000000000371', '1900000000000000370', '添加', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_instrument:add', '1', 1.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000372', '1900000000000000370', '编辑', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_instrument:edit', '1', 2.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000373', '1900000000000000370', '删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_instrument:delete', '1', 3.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000374', '1900000000000000370', '批量删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_instrument:deleteBatch', '1', 4.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000375', '1900000000000000370', '导出', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_instrument:exportXls', '1', 5.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000376', '1900000000000000370', '导入', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_instrument:importExcel', '1', 6.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0),
('1900000000000000377', '1900000000000000370', '停用启用', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_instrument:updateStatus', '1', 7.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0)
ON DUPLICATE KEY UPDATE
`parent_id` = VALUES(`parent_id`),
`name` = VALUES(`name`),
`menu_type` = VALUES(`menu_type`),
`perms` = VALUES(`perms`),
`perms_type` = VALUES(`perms_type`),
`sort_no` = VALUES(`sort_no`),
`del_flag` = VALUES(`del_flag`),
`status` = VALUES(`status`),
`update_by` = VALUES(`update_by`),
`update_time` = VALUES(`update_time`);
-- 默认管理员角色为上述按钮补授权已存在 role_id+permission_id 则跳过
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT REPLACE(UUID(), '-', ''), 'f6817f48af4fb3af11b9e8bf182f618b', x.`pid`, NULL, NOW(), '127.0.0.1'
FROM (
SELECT '1900000000000000311' AS `pid` UNION ALL SELECT '1900000000000000312' UNION ALL SELECT '1900000000000000313' UNION ALL SELECT '1900000000000000314'
UNION ALL SELECT '1900000000000000315' UNION ALL SELECT '1900000000000000316' UNION ALL SELECT '1900000000000000317'
UNION ALL SELECT '1900000000000000321' UNION ALL SELECT '1900000000000000322' UNION ALL SELECT '1900000000000000323' UNION ALL SELECT '1900000000000000324'
UNION ALL SELECT '1900000000000000325' UNION ALL SELECT '1900000000000000326' UNION ALL SELECT '1900000000000000327'
UNION ALL SELECT '1900000000000000331' UNION ALL SELECT '1900000000000000332' UNION ALL SELECT '1900000000000000333' UNION ALL SELECT '1900000000000000334'
UNION ALL SELECT '1900000000000000335' UNION ALL SELECT '1900000000000000336' UNION ALL SELECT '1900000000000000337'
UNION ALL SELECT '1900000000000000338' UNION ALL SELECT '1900000000000000339' UNION ALL SELECT '1900000000000000340'
UNION ALL SELECT '1900000000000000351' UNION ALL SELECT '1900000000000000352' UNION ALL SELECT '1900000000000000353' UNION ALL SELECT '1900000000000000354'
UNION ALL SELECT '1900000000000000355' UNION ALL SELECT '1900000000000000356' UNION ALL SELECT '1900000000000000357'
UNION ALL SELECT '1900000000000000371' UNION ALL SELECT '1900000000000000372' UNION ALL SELECT '1900000000000000373' UNION ALL SELECT '1900000000000000374'
UNION ALL SELECT '1900000000000000375' UNION ALL SELECT '1900000000000000376' UNION ALL SELECT '1900000000000000377'
) x
WHERE NOT EXISTS (
SELECT 1 FROM `sys_role_permission` rp
WHERE rp.`role_id` = 'f6817f48af4fb3af11b9e8bf182f618b' AND rp.`permission_id` = x.`pid`
);

View File

@@ -0,0 +1,15 @@
-- 菜单管理权限树不显示子级按钮的原因SysPermissionController#getTreeModelList 仅在节点 is_leaf=0 时继续递归
-- 才能把 parent_id 指向该菜单的 menu_type=2 记录挂到树上MES XSL 各列表页子菜单原先 is_leaf=1递归被跳过按钮永不出现在树下
-- 含按钮子权限的页面菜单应设为 is_leaf=0非叶子节点按钮行本身仍为 is_leaf=1见各按钮 INSERT
UPDATE `sys_permission`
SET `is_leaf` = 0
WHERE `id` IN (
'1900000000000000301',
'1900000000000000320',
'1900000000000000330',
'1900000000000000350',
'1900000000000000370'
)
AND `menu_type` = 1
AND `del_flag` = 0;

View File

@@ -0,0 +1,117 @@
-- MES 仓库管理 + 仓库分类字典 + 菜单 + 管理员角色授权幂等
-- 状态复用字典 xslmes_unit_status0 启用 1 停用
CREATE TABLE IF NOT EXISTS `mes_xsl_warehouse` (
`id` varchar(36) NOT NULL COMMENT '主键',
`warehouse_code` varchar(100) NOT NULL COMMENT '仓库编码',
`warehouse_name` varchar(200) NOT NULL COMMENT '仓库名称',
`warehouse_category` varchar(32) NOT NULL COMMENT '仓库分类(字典 xslmes_warehouse_category)',
`erp_code` varchar(100) DEFAULT NULL COMMENT 'ERP编码',
`status` varchar(10) DEFAULT '0' COMMENT '状态(字典 xslmes_unit_status0启用1停用)',
`customer_id` varchar(36) DEFAULT NULL COMMENT '客户ID分类为客户库时',
`customer_short_name` varchar(200) DEFAULT NULL COMMENT '客户简称',
`supplier_id` varchar(36) DEFAULT NULL COMMENT '供应商ID分类为供应商库时',
`supplier_short_name` varchar(100) DEFAULT NULL COMMENT '供应商简称',
`del_flag` tinyint(1) DEFAULT '0' COMMENT '删除标志(0正常1删除)',
`create_by` varchar(50) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(50) DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`tenant_id` int DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`id`),
KEY `idx_mes_xsl_warehouse_code` (`warehouse_code`),
KEY `idx_mes_xsl_warehouse_category` (`warehouse_category`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES仓库管理';
-- 仓库分类
INSERT INTO `sys_dict` (`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `type`, `tenant_id`)
SELECT REPLACE(UUID(), '-', ''), 'MES仓库分类', 'xslmes_warehouse_category', '原材料库成品库等', 0, 'admin', NOW(), 0, 0
WHERE NOT EXISTS (SELECT 1 FROM `sys_dict` WHERE `dict_code` = 'xslmes_warehouse_category' AND `del_flag` = 0);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '原材料库', 'RAW', 1, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_warehouse_category' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'RAW');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '成品库', 'FINISHED', 2, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_warehouse_category' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'FINISHED');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '待检库', 'PENDING_QC', 3, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_warehouse_category' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'PENDING_QC');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '合格品库', 'QUALIFIED', 4, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_warehouse_category' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'QUALIFIED');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '不合格品库', 'UNQUALIFIED', 5, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_warehouse_category' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'UNQUALIFIED');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '废料库', 'WASTE', 6, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_warehouse_category' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'WASTE');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '烘胶房', 'RUBBER', 7, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_warehouse_category' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'RUBBER');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '客户库', 'CUSTOMER', 8, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_warehouse_category' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'CUSTOMER');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '供应商库', 'SUPPLIER', 9, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_warehouse_category' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'SUPPLIER');
-- 菜单父级 MES1900000000000000300
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000380', '1900000000000000300', '仓库管理', '/xslmes/mesXslWarehouse', 'xslmes/mesXslWarehouse/MesXslWarehouseList', 1, NULL, NULL, 1, NULL, '0', 6.00, 0, 'ant-design:home-outlined', 0, 1, 0, 0, 'MES仓库管理', 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000380');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000381', '1900000000000000380', '添加', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_warehouse:add', '1', 1.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000381');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000382', '1900000000000000380', '编辑', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_warehouse:edit', '1', 2.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000382');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000383', '1900000000000000380', '删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_warehouse:delete', '1', 3.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000383');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000384', '1900000000000000380', '批量删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_warehouse:deleteBatch', '1', 4.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000384');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000385', '1900000000000000380', '导出', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_warehouse:exportXls', '1', 5.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000385');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000386', '1900000000000000380', '导入', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_warehouse:importExcel', '1', 6.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000386');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000387', '1900000000000000380', '停用启用', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_warehouse:updateStatus', '1', 7.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000387');
-- 管理员角色授权
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000460', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000380', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000460');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000461', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000381', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000461');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000462', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000382', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000462');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000463', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000383', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000463');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000464', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000384', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000464');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000465', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000385', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000465');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000466', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000386', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000466');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000467', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000387', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000467');
-- 含按钮子权限的列表菜单 is_leaf=0权限树可展开显示按钮 V3.9.2_25 一致
UPDATE `sys_permission`
SET `is_leaf` = 0
WHERE `id` = '1900000000000000380'
AND `menu_type` = 1
AND `del_flag` = 0;

View File

@@ -0,0 +1,67 @@
-- MES 仓库分类改为分类字典sys_category根编码 XSLMES_WH并迁移原字典 item_value 数据
-- 一楼库成品待检合格品废品不合格品二楼仓库烘胶房原材料废品客户库供应商库
-- 根节点
INSERT INTO `sys_category` (`id`, `pid`, `name`, `code`, `has_child`, `create_by`, `create_time`)
SELECT '1991000000000000001', '0', 'MES仓库分类', 'XSLMES_WH', '1', 'admin', NOW()
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM `sys_category` WHERE `code` = 'XSLMES_WH');
-- 一楼库二楼仓库
INSERT INTO `sys_category` (`id`, `pid`, `name`, `code`, `has_child`, `create_by`, `create_time`)
SELECT '1991000000000000002', '1991000000000000001', '一楼库', 'XSLMES_WH_F1', '1', 'admin', NOW()
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM `sys_category` WHERE `code` = 'XSLMES_WH_F1');
INSERT INTO `sys_category` (`id`, `pid`, `name`, `code`, `has_child`, `create_by`, `create_time`)
SELECT '1991000000000000003', '1991000000000000001', '二楼仓库', 'XSLMES_WH_F2', '1', 'admin', NOW()
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM `sys_category` WHERE `code` = 'XSLMES_WH_F2');
-- 一楼库 子类
INSERT INTO `sys_category` (`id`, `pid`, `name`, `code`, `has_child`, `create_by`, `create_time`)
SELECT '1991000000000000011', '1991000000000000002', '成品库', 'XSLMES_WH_F1_CP', '0', 'admin', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_category` WHERE `code` = 'XSLMES_WH_F1_CP');
INSERT INTO `sys_category` (`id`, `pid`, `name`, `code`, `has_child`, `create_by`, `create_time`)
SELECT '1991000000000000012', '1991000000000000002', '待检库', 'XSLMES_WH_F1_DJ', '0', 'admin', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_category` WHERE `code` = 'XSLMES_WH_F1_DJ');
INSERT INTO `sys_category` (`id`, `pid`, `name`, `code`, `has_child`, `create_by`, `create_time`)
SELECT '1991000000000000013', '1991000000000000002', '合格品库', 'XSLMES_WH_F1_HG', '0', 'admin', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_category` WHERE `code` = 'XSLMES_WH_F1_HG');
INSERT INTO `sys_category` (`id`, `pid`, `name`, `code`, `has_child`, `create_by`, `create_time`)
SELECT '1991000000000000014', '1991000000000000002', '废品库', 'XSLMES_WH_F1_FP', '0', 'admin', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_category` WHERE `code` = 'XSLMES_WH_F1_FP');
INSERT INTO `sys_category` (`id`, `pid`, `name`, `code`, `has_child`, `create_by`, `create_time`)
SELECT '1991000000000000015', '1991000000000000002', '不合格品库', 'XSLMES_WH_F1_BHG', '0', 'admin', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_category` WHERE `code` = 'XSLMES_WH_F1_BHG');
-- 二楼仓库 子类
INSERT INTO `sys_category` (`id`, `pid`, `name`, `code`, `has_child`, `create_by`, `create_time`)
SELECT '1991000000000000021', '1991000000000000003', '烘胶房', 'XSLMES_WH_F2_HJ', '0', 'admin', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_category` WHERE `code` = 'XSLMES_WH_F2_HJ');
INSERT INTO `sys_category` (`id`, `pid`, `name`, `code`, `has_child`, `create_by`, `create_time`)
SELECT '1991000000000000022', '1991000000000000003', '原材料库', 'XSLMES_WH_F2_YCL', '0', 'admin', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_category` WHERE `code` = 'XSLMES_WH_F2_YCL');
INSERT INTO `sys_category` (`id`, `pid`, `name`, `code`, `has_child`, `create_by`, `create_time`)
SELECT '1991000000000000023', '1991000000000000003', '废品库', 'XSLMES_WH_F2_FP', '0', 'admin', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_category` WHERE `code` = 'XSLMES_WH_F2_FP');
INSERT INTO `sys_category` (`id`, `pid`, `name`, `code`, `has_child`, `create_by`, `create_time`)
SELECT '1991000000000000024', '1991000000000000003', '客户库', 'XSLMES_WH_F2_KH', '0', 'admin', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_category` WHERE `code` = 'XSLMES_WH_F2_KH');
INSERT INTO `sys_category` (`id`, `pid`, `name`, `code`, `has_child`, `create_by`, `create_time`)
SELECT '1991000000000000025', '1991000000000000003', '供应商库', 'XSLMES_WH_F2_GYS', '0', 'admin', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_category` WHERE `code` = 'XSLMES_WH_F2_GYS');
-- mes_xsl_warehouse 中原字典 item_value 转为分类字典 id仅当仍为旧值时
UPDATE `mes_xsl_warehouse` SET `warehouse_category` = '1991000000000000011' WHERE `warehouse_category` = 'FINISHED';
UPDATE `mes_xsl_warehouse` SET `warehouse_category` = '1991000000000000012' WHERE `warehouse_category` = 'PENDING_QC';
UPDATE `mes_xsl_warehouse` SET `warehouse_category` = '1991000000000000013' WHERE `warehouse_category` = 'QUALIFIED';
UPDATE `mes_xsl_warehouse` SET `warehouse_category` = '1991000000000000014' WHERE `warehouse_category` = 'WASTE';
UPDATE `mes_xsl_warehouse` SET `warehouse_category` = '1991000000000000015' WHERE `warehouse_category` = 'UNQUALIFIED';
UPDATE `mes_xsl_warehouse` SET `warehouse_category` = '1991000000000000022' WHERE `warehouse_category` = 'RAW';
UPDATE `mes_xsl_warehouse` SET `warehouse_category` = '1991000000000000021' WHERE `warehouse_category` = 'RUBBER';
UPDATE `mes_xsl_warehouse` SET `warehouse_category` = '1991000000000000024' WHERE `warehouse_category` = 'CUSTOMER';
UPDATE `mes_xsl_warehouse` SET `warehouse_category` = '1991000000000000025' WHERE `warehouse_category` = 'SUPPLIER';
ALTER TABLE `mes_xsl_warehouse`
MODIFY COLUMN `warehouse_category` varchar(36) NOT NULL COMMENT '仓库分类(sys_category.id根编码 XSLMES_WH)';

View File

@@ -0,0 +1,25 @@
-- 仓库管理侧栏维护分类字典子树所需按钮权限 /sys/category与系统分类字典一致
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000388', '1900000000000000380', '新增仓库分类', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_warehouse_category:add', '1', 8.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000388');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000389', '1900000000000000380', '编辑仓库分类', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_warehouse_category:edit', '1', 9.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000389');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000390', '1900000000000000380', '删除仓库分类', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_warehouse_category:delete', '1', 10.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000390');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000468', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000388', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000468');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000469', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000389', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000469');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000470', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000390', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000470');

View File

@@ -0,0 +1,44 @@
-- MES 单位分类由独立表 mes_xsl_unit_category 迁入系统分类字典 sys_category根编码 XSLMES_UNIT
-- 保留原分类主键 id无需批量更新 mes_xsl_unit.category_id
-- 根节点
INSERT INTO `sys_category` (`id`, `pid`, `name`, `code`, `has_child`, `create_by`, `create_time`)
SELECT '1992000000000000001', '0', 'MES单位分类', 'XSLMES_UNIT', '1', 'admin', NOW()
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM `sys_category` WHERE `code` = 'XSLMES_UNIT');
-- 从旧表迁入仅当表仍存在时id 与原表一致
INSERT INTO `sys_category` (`id`, `pid`, `name`, `code`, `has_child`, `create_by`, `create_time`)
SELECT
c.`id`,
CASE
WHEN IFNULL(NULLIF(TRIM(c.`parent_id`), ''), '0') IN ('0', '') THEN '1992000000000000001'
ELSE c.`parent_id`
END,
c.`category_name`,
CONCAT('XSLMES_UNIT_', UPPER(REPLACE(REPLACE(c.`category_code`, '-', '_'), ' ', '_'))),
CASE
WHEN EXISTS (
SELECT 1 FROM `mes_xsl_unit_category` c2
WHERE c2.`parent_id` = c.`id` AND IFNULL(c2.`del_flag`, 0) = 0
) THEN '1'
ELSE '0'
END,
IFNULL(c.`create_by`, 'admin'),
IFNULL(c.`create_time`, NOW())
FROM `mes_xsl_unit_category` c
WHERE IFNULL(c.`del_flag`, 0) = 0
AND NOT EXISTS (SELECT 1 FROM `sys_category` sc WHERE sc.`id` = c.`id`);
-- 同步 has_child含根节点
UPDATE `sys_category` p
SET `has_child` = '1'
WHERE EXISTS (SELECT 1 FROM `sys_category` ch WHERE ch.`pid` = p.`id`);
UPDATE `sys_category` p
SET `has_child` = '0'
WHERE NOT EXISTS (SELECT 1 FROM `sys_category` ch WHERE ch.`pid` = p.`id`);
ALTER TABLE `mes_xsl_unit`
MODIFY COLUMN `category_id` varchar(36) NOT NULL COMMENT '所属分类(sys_category.id根编码 XSLMES_UNIT)';
DROP TABLE IF EXISTS `mes_xsl_unit_category`;

View File

@@ -0,0 +1,104 @@
-- MES 客户管理 + 字典 + 菜单 + 管理员角色授权幂等
-- ========== ==========
CREATE TABLE IF NOT EXISTS `mes_xsl_customer` (
`id` varchar(36) NOT NULL COMMENT '主键',
`customer_code` varchar(100) NOT NULL COMMENT '客户编码',
`customer_name` varchar(200) NOT NULL COMMENT '客户名称',
`customer_region` varchar(32) DEFAULT NULL COMMENT '客户区域',
`erp_code` varchar(100) DEFAULT NULL COMMENT 'ERP编码',
`status` varchar(10) DEFAULT '0' COMMENT '状态(字典 xslmes_customer_status0启用1停用)',
`del_flag` tinyint(1) DEFAULT '0' COMMENT '删除标志(0正常1删除)',
`customer_desc` varchar(500) DEFAULT NULL COMMENT '客户描述',
`iz_enable` tinyint(1) DEFAULT '1' COMMENT '是否启用(1是0否)',
`create_by` varchar(50) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(50) DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`tenant_id` int DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`id`),
KEY `idx_mes_xsl_customer_code` (`customer_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES客户管理';
-- ========== 字典客户区域 ==========
INSERT INTO `sys_dict` (`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `type`, `tenant_id`)
SELECT REPLACE(UUID(), '-', ''), 'MES客户区域', 'xslmes_customer_region', 'MES客户区域', 0, 'admin', NOW(), 0, 0
WHERE NOT EXISTS (SELECT 1 FROM `sys_dict` WHERE `dict_code` = 'xslmes_customer_region' AND `del_flag` = 0);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '平度', 'pingdu', 1, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_customer_region' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'pingdu');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '高密', 'gaomi', 2, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_customer_region' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'gaomi');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '青岛', 'qingdao', 3, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_customer_region' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'qingdao');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '烟台', 'yantai', 4, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_customer_region' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'yantai');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '东营', 'dongying', 5, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_customer_region' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'dongying');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '黄岛', 'huangdao', 6, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_customer_region' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'huangdao');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '青州', 'qingzhou', 7, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_customer_region' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'qingzhou');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '嘉兴市', 'jiaxing', 8, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_customer_region' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = 'jiaxing');
-- ========== 字典客户状态启用/停用删除为逻辑删除 del_flag不在此字典选删除 ==========
INSERT INTO `sys_dict` (`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `type`, `tenant_id`)
SELECT REPLACE(UUID(), '-', ''), 'MES客户状态', 'xslmes_customer_status', '启用停用删除删除建议配合逻辑删除', 0, 'admin', NOW(), 0, 0
WHERE NOT EXISTS (SELECT 1 FROM `sys_dict` WHERE `dict_code` = 'xslmes_customer_status' AND `del_flag` = 0);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '启用', '0', 1, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_customer_status' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = '0');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '停用', '1', 2, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_customer_status' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = '1');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '删除', '2', 3, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_customer_status' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = '2');
-- ========== 菜单 ==========
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000300', '', 'MES XSL', '/xslmes', 'layouts/default/index', 1, NULL, '/xslmes/mesXslCustomer', 0, NULL, '0', 80.00, 0, 'ant-design:appstore-outlined', 0, 0, 0, 0, 'MES XSL 业务', 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000300');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000301', '1900000000000000300', '客户管理', '/xslmes/mesXslCustomer', 'xslmes/mesXslCustomer/MesXslCustomerList', 1, NULL, NULL, 1, NULL, '0', 1.00, 0, 'ant-design:team-outlined', 1, 1, 0, 0, 'MES客户管理', 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000301');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000311', '1900000000000000301', '添加', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_customer:add', '1', 1.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000311');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000312', '1900000000000000301', '编辑', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_customer:edit', '1', 2.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000312');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000313', '1900000000000000301', '删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_customer:delete', '1', 3.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000313');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000314', '1900000000000000301', '批量删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_customer:deleteBatch', '1', 4.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000314');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000315', '1900000000000000301', '导出', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_customer:exportXls', '1', 5.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000315');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000316', '1900000000000000301', '导入', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_customer:importExcel', '1', 6.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000316');
-- ========== 管理员角色授权admin 角色 id 与项目一致 ==========
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`) VALUES ('1900000000000000391', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000300', NULL, NOW(), '127.0.0.1');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`) VALUES ('1900000000000000392', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000301', NULL, NOW(), '127.0.0.1');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`) VALUES ('1900000000000000393', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000311', NULL, NOW(), '127.0.0.1');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`) VALUES ('1900000000000000394', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000312', NULL, NOW(), '127.0.0.1');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`) VALUES ('1900000000000000395', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000313', NULL, NOW(), '127.0.0.1');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`) VALUES ('1900000000000000396', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000314', NULL, NOW(), '127.0.0.1');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`) VALUES ('1900000000000000397', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000315', NULL, NOW(), '127.0.0.1');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`) VALUES ('1900000000000000398', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000316', NULL, NOW(), '127.0.0.1');

View File

@@ -0,0 +1,3 @@
-- 客户管理新增客户简称
ALTER TABLE `mes_xsl_customer`
ADD COLUMN `customer_short_name` varchar(100) DEFAULT NULL COMMENT '客户简称' AFTER `customer_name`;

View File

@@ -0,0 +1,4 @@
-- 历史数据status字典 iz_enable 对齐避免列表状态与启用逻辑不一致
UPDATE `mes_xsl_customer`
SET `iz_enable` = CASE WHEN `status` = '1' THEN 1 ELSE 0 END
WHERE `del_flag` = 0;

View File

@@ -0,0 +1,87 @@
-- MES 车辆管理 + 字典 + 菜单 + 管理员角色授权幂等
CREATE TABLE IF NOT EXISTS `mes_xsl_vehicle` (
`id` varchar(36) NOT NULL COMMENT '主键',
`plate_number` varchar(32) NOT NULL COMMENT '车牌号',
`tare_weight_kg` decimal(12,3) DEFAULT NULL COMMENT '车辆自重(KG)',
`load_capacity` decimal(12,3) DEFAULT NULL COMMENT '装载量',
`load_unit` varchar(32) DEFAULT NULL COMMENT '单位',
`customer_ids` varchar(1000) DEFAULT NULL COMMENT '客户ID多选逗号分隔',
`customer_short_name` varchar(1000) DEFAULT NULL COMMENT '客户简称展示',
`vehicle_length` decimal(10,3) DEFAULT NULL COMMENT '车长',
`vehicle_width` decimal(10,3) DEFAULT NULL COMMENT '车宽',
`vehicle_height` decimal(10,3) DEFAULT NULL COMMENT '车高',
`status` varchar(10) DEFAULT '1' COMMENT '状态(字典 xslmes_vehicle_status)',
`del_flag` tinyint(1) DEFAULT '0' COMMENT '删除标志(0正常1删除)',
`create_by` varchar(50) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(50) DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`tenant_id` int DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`id`),
KEY `idx_mes_xsl_vehicle_plate` (`plate_number`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES车辆管理';
-- 字典车辆状态
INSERT INTO `sys_dict` (`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `type`, `tenant_id`)
SELECT REPLACE(UUID(), '-', ''), 'MES车辆状态', 'xslmes_vehicle_status', '停用启用', 0, 'admin', NOW(), 0, 0
WHERE NOT EXISTS (SELECT 1 FROM `sys_dict` WHERE `dict_code` = 'xslmes_vehicle_status' AND `del_flag` = 0);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '停用', '0', 1, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_vehicle_status' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = '0');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '启用', '1', 2, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_vehicle_status' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = '1');
-- 菜单父级 MES XSL
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000320', '1900000000000000300', '车辆管理', '/xslmes/mesXslVehicle', 'xslmes/mesXslVehicle/MesXslVehicleList', 1, NULL, NULL, 1, NULL, '0', 2.00, 0, 'ant-design:car-outlined', 1, 1, 0, 0, 'MES车辆管理', 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000320');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000321', '1900000000000000320', '添加', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_vehicle:add', '1', 1.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000321');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000322', '1900000000000000320', '编辑', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_vehicle:edit', '1', 2.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000322');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000323', '1900000000000000320', '删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_vehicle:delete', '1', 3.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000323');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000324', '1900000000000000320', '批量删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_vehicle:deleteBatch', '1', 4.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000324');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000325', '1900000000000000320', '导出', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_vehicle:exportXls', '1', 5.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000325');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000326', '1900000000000000320', '导入', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_vehicle:importExcel', '1', 6.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000326');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000327', '1900000000000000320', '停用启用', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_vehicle:updateStatus', '1', 7.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000327');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000401', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000320', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000401');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000402', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000321', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000402');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000403', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000322', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000403');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000404', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000323', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000404');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000405', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000324', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000405');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000406', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000325', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000406');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000407', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000326', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000407');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000408', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000327', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000408');

View File

@@ -0,0 +1,122 @@
-- MES 单位分类 + 单位 + 字典 + 菜单 + 管理员角色授权幂等
-- 单位分类
CREATE TABLE IF NOT EXISTS `mes_xsl_unit_category` (
`id` varchar(36) NOT NULL COMMENT '主键',
`parent_id` varchar(36) NOT NULL DEFAULT '0' COMMENT '父级ID0为根',
`category_code` varchar(64) NOT NULL COMMENT '分类编码',
`category_name` varchar(100) NOT NULL COMMENT '分类名称',
`sort_no` int DEFAULT '0' COMMENT '排序号',
`status` varchar(10) DEFAULT '1' COMMENT '状态(字典 xslmes_unit_status)',
`del_flag` tinyint(1) DEFAULT '0' COMMENT '删除标志(0正常1删除)',
`create_by` varchar(50) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(50) DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`tenant_id` int DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`id`),
KEY `idx_mes_xsl_unit_category_parent` (`parent_id`),
KEY `idx_mes_xsl_unit_category_code` (`category_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES单位分类';
-- 单位
CREATE TABLE IF NOT EXISTS `mes_xsl_unit` (
`id` varchar(36) NOT NULL COMMENT '主键',
`unit_code` varchar(64) NOT NULL COMMENT '编码',
`unit_name` varchar(100) NOT NULL COMMENT '名称',
`erp_code` varchar(64) DEFAULT NULL COMMENT 'ERP编码',
`category_id` varchar(36) NOT NULL COMMENT '所属分类ID',
`unit_desc` text COMMENT '描述',
`status` varchar(10) DEFAULT '1' COMMENT '状态(字典 xslmes_unit_status)',
`del_flag` tinyint(1) DEFAULT '0' COMMENT '删除标志(0正常1删除)',
`create_by` varchar(50) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(50) DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`tenant_id` int DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`id`),
KEY `idx_mes_xsl_unit_category` (`category_id`),
KEY `idx_mes_xsl_unit_code` (`unit_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES单位';
-- 字典单位/分类状态启用停用
INSERT INTO `sys_dict` (`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `type`, `tenant_id`)
SELECT REPLACE(UUID(), '-', ''), 'MES单位状态', 'xslmes_unit_status', '停用启用', 0, 'admin', NOW(), 0, 0
WHERE NOT EXISTS (SELECT 1 FROM `sys_dict` WHERE `dict_code` = 'xslmes_unit_status' AND `del_flag` = 0);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '停用', '0', 1, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_unit_status' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = '0');
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '启用', '1', 2, 1, 'admin', NOW() FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_unit_status' AND NOT EXISTS (SELECT 1 FROM `sys_dict_item` i WHERE i.`dict_id` = d.id AND i.`item_value` = '1');
-- 菜单父级 MES XSL
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000330', '1900000000000000300', '单位管理', '/xslmes/mesXslUnit', 'xslmes/mesXslUnit/MesXslUnitList', 1, NULL, NULL, 1, NULL, '0', 3.00, 0, 'ant-design:cluster-outlined', 1, 1, 0, 0, 'MES单位管理', 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000330');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000331', '1900000000000000330', '添加', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit:add', '1', 1.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000331');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000332', '1900000000000000330', '编辑', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit:edit', '1', 2.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000332');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000333', '1900000000000000330', '删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit:delete', '1', 3.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000333');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000334', '1900000000000000330', '批量删除', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit:deleteBatch', '1', 4.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000334');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000335', '1900000000000000330', '导出', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit:exportXls', '1', 5.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000335');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000336', '1900000000000000330', '导入', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit:importExcel', '1', 6.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000336');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000337', '1900000000000000330', '停用启用', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit:updateStatus', '1', 7.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000337');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000338', '1900000000000000330', '新增分类', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit_category:add', '1', 8.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000338');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000339', '1900000000000000330', '编辑分类', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit_category:edit', '1', 9.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000339');
INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `url`, `component`, `is_route`, `component_name`, `redirect`, `menu_type`, `perms`, `perms_type`, `sort_no`, `always_show`, `icon`, `is_leaf`, `keep_alive`, `hidden`, `hide_tab`, `description`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`, `rule_flag`, `status`, `internal_or_external`)
SELECT '1900000000000000340', '1900000000000000330', '删除分类', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_unit_category:delete', '1', 10.00, 0, NULL, 1, 0, 0, 0, NULL, 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000340');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000410', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000330', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000410');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000411', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000331', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000411');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000412', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000332', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000412');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000413', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000333', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000413');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000414', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000334', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000414');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000415', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000335', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000415');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000416', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000336', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000416');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000417', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000337', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000417');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000418', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000338', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000418');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000419', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000339', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000419');
INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`)
SELECT '1900000000000000420', 'f6817f48af4fb3af11b9e8bf182f618b', '1900000000000000340', NULL, NOW(), '127.0.0.1'
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_role_permission` WHERE `id` = '1900000000000000420');

View File

@@ -0,0 +1,85 @@
-- MES 单位分类 + 单位初始化数据来自业务单位清单幂等
-- 固定主键便于关联若已存在同编码则跳过
-- 分类数量组重量组时间组长度组
INSERT INTO `mes_xsl_unit_category` (`id`, `parent_id`, `category_code`, `category_name`, `sort_no`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000501', '0', 'qty_group', '数量组', 1, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit_category` WHERE `category_code` = 'qty_group');
INSERT INTO `mes_xsl_unit_category` (`id`, `parent_id`, `category_code`, `category_name`, `sort_no`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000502', '0', 'weight_group', '重量组', 2, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit_category` WHERE `category_code` = 'weight_group');
INSERT INTO `mes_xsl_unit_category` (`id`, `parent_id`, `category_code`, `category_name`, `sort_no`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000503', '0', 'time_group', '时间组', 3, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit_category` WHERE `category_code` = 'time_group');
INSERT INTO `mes_xsl_unit_category` (`id`, `parent_id`, `category_code`, `category_name`, `sort_no`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000504', '0', 'length_group', '长度组', 4, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit_category` WHERE `category_code` = 'length_group');
-- 单位编码名称ERP编码所属分类状态启用
-- 数量组 1900000000000000501
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000511', 'tuo', '托', NULL, '1900000000000000501', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'tuo');
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000512', 'tao', '套', 'tao', '1900000000000000501', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'tao');
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000513', 'tai', '台', 'tai', '1900000000000000501', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'tai');
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000514', 'Pcs', 'Pcs', 'Pcs', '1900000000000000501', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'Pcs');
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000515', 'ml', '毫升', 'ml', '1900000000000000501', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'ml');
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000516', 'liang', '辆', 'liang', '1900000000000000501', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'liang');
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000517', 'L', '升', 'L', '1900000000000000501', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'L');
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000518', 'dozen', '打', 'dozen', '1900000000000000501', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'dozen');
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000519', 'double', '双', 'double', '1900000000000000501', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'double');
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000520', 'dong', '栋', 'dong', '1900000000000000501', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'dong');
-- 重量组 1900000000000000502
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000521', 'ton', '吨', 'ton', '1900000000000000502', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'ton');
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000522', 'kg', '千克', 'kg', '1900000000000000502', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'kg');
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000523', 'g', '克', 'g', '1900000000000000502', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'g');
-- 时间组 1900000000000000503
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000524', 'second', '秒', 'second', '1900000000000000503', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'second');
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000525', 'minute', '分', 'minute', '1900000000000000503', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'minute');
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000526', 'hour', '时', 'hour', '1900000000000000503', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'hour');
-- 长度组 1900000000000000504
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000527', 'm', '米', 'm', '1900000000000000504', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'm');
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000528', 'km', '千米', 'km', '1900000000000000504', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'km');
INSERT INTO `mes_xsl_unit` (`id`, `unit_code`, `unit_name`, `erp_code`, `category_id`, `unit_desc`, `status`, `del_flag`, `create_by`, `create_time`, `tenant_id`)
SELECT '1900000000000000529', 'cm', '厘米', 'cm', '1900000000000000504', NULL, '1', 0, 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_unit` WHERE `unit_code` = 'cm');

View File

@@ -5,14 +5,15 @@ VITE_USE_MOCK = true
VITE_PUBLIC_PATH = / VITE_PUBLIC_PATH = /
# 跨域代理,您可以配置多个 ,请注意,没有换行符 # 跨域代理:前缀须与 VITE_GLOB_API_URL 一致,且 rewrite 后路径需包含后端 context-path/jeecg-boot
VITE_PROXY = [["/jeecgboot","http://localhost:8080/jeecg-boot"],["/upload","http://localhost:3300/upload"]] # 详见 build/vite/proxy.ts
VITE_PROXY = [["/jeecg-boot","http://localhost:8080/jeecg-boot"],["/upload","http://localhost:3300/upload"]]
#后台接口全路径地址(必填) #后台接口全路径地址(必填)
VITE_GLOB_DOMAIN_URL=http://localhost:8080/jeecg-boot VITE_GLOB_DOMAIN_URL=http://localhost:8080/jeecg-boot
#后台接口父地址(必填) #后台接口父地址(必填),与 server.servlet.context-path 一致,避免仅去掉别名前缀后缺少 /jeecg-boot
VITE_GLOB_API_URL=/jeecgboot VITE_GLOB_API_URL=/jeecg-boot
# 接口前缀 # 接口前缀
VITE_GLOB_API_URL_PREFIX= VITE_GLOB_API_URL_PREFIX=

View File

@@ -13,7 +13,7 @@ VITE_BUILD_COMPRESS = 'gzip'
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
#后台接口父地址(必填) #后台接口父地址(必填)
VITE_GLOB_API_URL=/jeecgboot VITE_GLOB_API_URL=/jeecg-boot
#后台接口全路径地址(必填) #后台接口全路径地址(必填)
VITE_GLOB_DOMAIN_URL=http://jeecg-boot-system:8080/jeecg-boot VITE_GLOB_DOMAIN_URL=http://jeecg-boot-system:8080/jeecg-boot

View File

@@ -13,7 +13,7 @@ VITE_BUILD_COMPRESS = 'gzip'
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
#后台接口父地址(必填) #后台接口父地址(必填)
VITE_GLOB_API_URL=/jeecgboot VITE_GLOB_API_URL=/jeecg-boot
#后台接口全路径地址(必填) #后台接口全路径地址(必填)
VITE_GLOB_DOMAIN_URL=http://jeecg-boot-gateway:9999 VITE_GLOB_DOMAIN_URL=http://jeecg-boot-gateway:9999

View File

@@ -13,7 +13,7 @@ VITE_BUILD_COMPRESS = 'gzip'
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
#后台接口父地址(必填) #后台接口父地址(必填)
VITE_GLOB_API_URL=/jeecgboot VITE_GLOB_API_URL=/jeecg-boot
#后台接口全路径地址(必填) #后台接口全路径地址(必填)
VITE_GLOB_DOMAIN_URL=http://127.0.0.1:8080/jeecg-boot VITE_GLOB_DOMAIN_URL=http://127.0.0.1:8080/jeecg-boot

View File

@@ -20,12 +20,30 @@ export function createProxy(list: ProxyList = []) {
for (const [prefix, target] of list) { for (const [prefix, target] of list) {
const isHttps = httpsRE.test(target); const isHttps = httpsRE.test(target);
// 若 target 带路径(如 http://localhost:8080/jeecg-boot需拼回转发路径
// 否则 rewrite 去掉 /jeecgboot 后只剩 /xslmes/...,缺少 context-path后端会报 No static resource。
let proxyTarget = target;
let targetPathPrefix = '';
try {
const u = new URL(target);
const p = (u.pathname || '').replace(/\/$/, '');
if (p) {
targetPathPrefix = p;
proxyTarget = `${u.protocol}//${u.host}`;
}
} catch {
/* 非标准 URL 时保持原 target */
}
// https://github.com/http-party/node-http-proxy#options // https://github.com/http-party/node-http-proxy#options
ret[prefix] = { ret[prefix] = {
target: target, target: proxyTarget,
changeOrigin: true, changeOrigin: true,
ws: true, ws: true,
rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''), rewrite: (path) => {
const stripped = path.replace(new RegExp(`^${prefix}`), '');
return targetPathPrefix ? `${targetPathPrefix}${stripped}` : stripped;
},
// https is require secure=false // https is require secure=false
...(isHttps ? { secure: false } : {}), ...(isHttps ? { secure: false } : {}),
}; };

View File

@@ -72,9 +72,8 @@ export function useForm(props?: Props): UseFormReturnType {
}, },
resetFields: async () => { resetFields: async () => {
getForm().then(async (form) => { const form = await getForm();
await form.resetFields(); await form.resetFields();
});
}, },
removeSchemaByFiled: async (field: string | string[]) => { removeSchemaByFiled: async (field: string | string[]) => {

View File

@@ -151,6 +151,36 @@ const transform: AxiosTransform = {
} }
} }
/**
* 单体 / 集成部署:页面在 http://host/jeecg-boot/ 下时,若仅用「以 / 开头的相对 URL」
* 浏览器会解析到 http://host/jeecg-boot/... 或误解析到 http://host/xslmes/...(缺少 context-path
* 后端报 No static resource。使用完整 domainUrl 作 axios baseURLurl 只保留 servlet 内路径。
*/
if (
!isStartWithHttp &&
!globSetting.isQiankunMicro &&
globSetting.domainUrl &&
/^https?:\/\//.test(globSetting.domainUrl) &&
config.url &&
typeof config.url === 'string'
) {
try {
const du = new URL(globSetting.domainUrl);
const ctx = (du.pathname || '').replace(/\/$/, '');
config.baseURL = globSetting.domainUrl.replace(/\/$/, '');
let pathOnly = config.url as string;
if (ctx && (pathOnly === ctx || pathOnly.startsWith(ctx + '/'))) {
pathOnly = pathOnly.slice(ctx.length) || '/';
}
if (!pathOnly.startsWith('/')) {
pathOnly = '/' + pathOnly;
}
config.url = pathOnly;
} catch {
/* 忽略 URL 解析异常 */
}
}
return config; return config;
}, },

View File

@@ -0,0 +1,56 @@
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
enum Api {
list = '/xslmes/mesXslCustomer/list',
queryById = '/xslmes/mesXslCustomer/queryById',
save = '/xslmes/mesXslCustomer/add',
edit = '/xslmes/mesXslCustomer/edit',
updateStatus = '/xslmes/mesXslCustomer/updateStatus',
deleteOne = '/xslmes/mesXslCustomer/delete',
deleteBatch = '/xslmes/mesXslCustomer/deleteBatch',
importExcel = '/xslmes/mesXslCustomer/importExcel',
exportXls = '/xslmes/mesXslCustomer/exportXls',
}
export const getExportUrl = Api.exportXls;
export const getImportUrl = Api.importExcel;
export const list = (params) => defHttp.get({ url: Api.list, params });
export const queryById = (params: { id: string }) => defHttp.get({ url: Api.queryById, params });
export const deleteOne = (params, handleSuccess) => {
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
};
export const batchDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
},
});
};
export const saveOrUpdate = (params, isUpdate) => {
const url = isUpdate ? Api.edit : Api.save;
return defHttp.post({ url, params });
};
/** 启用/停用status 0 启用 1 停用(与供应商管理 MesXslSupplier.api.updateStatus 一致) */
export const updateStatus = (params: { id: string; status: string }, handleSuccess?: () => void) => {
return defHttp.post({ url: Api.updateStatus, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess?.();
});
};

View File

@@ -0,0 +1,105 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
export const columns: BasicColumn[] = [
{ title: 'ID', align: 'center', dataIndex: 'id', width: 280, ellipsis: true, defaultHidden: true },
{ title: '客户编码', align: 'center', dataIndex: 'customerCode', width: 140 },
{ title: '客户名称', align: 'center', dataIndex: 'customerName', width: 180 },
{ title: '客户简称', align: 'center', dataIndex: 'customerShortName', width: 120 },
{ title: '客户区域', align: 'center', dataIndex: 'customerRegion_dictText', width: 100 },
{ title: 'ERP编码', align: 'center', dataIndex: 'erpCode', width: 140 },
// 库表 status + 字典 xslmes_customer_status 翻译(后端 DictAspect 填充 status_dictText
{ title: '状态', align: 'center', dataIndex: 'status_dictText', width: 100 },
{ title: '客户描述', align: 'center', dataIndex: 'customerDesc', width: 200, ellipsis: true },
{ title: '创建人', align: 'center', dataIndex: 'createBy', width: 100 },
{
title: '创建时间',
align: 'center',
dataIndex: 'createTime',
width: 165,
customRender: ({ text }) => (!text ? '' : String(text).length > 19 ? String(text).substring(0, 19) : text),
},
{ title: '租户ID', align: 'center', dataIndex: 'tenantId', width: 90, defaultHidden: true },
];
export const searchFormSchema: FormSchema[] = [
{ label: '客户编码', field: 'customerCode', component: 'JInput', colProps: { span: 6 } },
{ label: '客户名称', field: 'customerName', component: 'JInput', colProps: { span: 6 } },
{ label: '客户简称', field: 'customerShortName', component: 'JInput', colProps: { span: 6 } },
{
label: '客户区域',
field: 'customerRegion',
component: 'JDictSelectTag',
componentProps: { dictCode: 'xslmes_customer_region' },
colProps: { span: 6 },
},
{
label: '状态',
field: 'status',
component: 'JDictSelectTag',
componentProps: { dictCode: 'xslmes_customer_status' },
colProps: { span: 6 },
},
];
export const formSchema: FormSchema[] = [
{ label: '', field: 'id', component: 'Input', show: false },
{
label: '客户编码',
field: 'customerCode',
required: true,
component: 'Input',
componentProps: { placeholder: '请输入客户编码' },
},
{
label: '客户名称',
field: 'customerName',
required: true,
component: 'Input',
componentProps: { placeholder: '请输入客户名称' },
},
{
label: '客户简称',
field: 'customerShortName',
component: 'Input',
componentProps: { placeholder: '请输入客户简称' },
},
{
label: '客户区域',
field: 'customerRegion',
component: 'JDictSelectTag',
componentProps: { dictCode: 'xslmes_customer_region', placeholder: '请选择客户区域' },
},
{
label: 'ERP编码',
field: 'erpCode',
component: 'Input',
componentProps: { placeholder: '请输入ERP编码' },
},
{
label: '状态',
field: 'status',
component: 'JDictSelectTag',
componentProps: { dictCode: 'xslmes_customer_status', placeholder: '请选择状态' },
// 默认启用仅在新增弹窗内通过 setFieldsValue 写入,避免编辑时 schema 默认值覆盖接口里的 status
},
{
label: '客户描述',
field: 'customerDesc',
component: 'InputTextArea',
componentProps: { rows: 3, placeholder: '请输入客户描述' },
},
{
label: '租户ID',
field: 'tenantId',
component: 'InputNumber',
componentProps: { placeholder: '租户ID可空' },
},
];
export const superQuerySchema = {
customerCode: { title: '客户编码', order: 0, view: 'text' },
customerName: { title: '客户名称', order: 1, view: 'text' },
customerShortName: { title: '客户简称', order: 2, view: 'text' },
customerRegion: { title: '客户区域', order: 3, view: 'list', dictCode: 'xslmes_customer_region' },
status: { title: '状态', order: 4, view: 'list', dictCode: 'xslmes_customer_status' },
};

View File

@@ -0,0 +1,159 @@
<template>
<div>
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #tableTitle>
<a-button type="primary" v-auth="'xslmes:mes_xsl_customer:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'xslmes:mes_xsl_customer:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'xslmes:mes_xsl_customer:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="batchHandleDelete">
<Icon icon="ant-design:delete-outlined" />
删除
</a-menu-item>
</a-menu>
</template>
<a-button v-auth="'xslmes:mes_xsl_customer:deleteBatch'">
批量操作
<Icon icon="mdi:chevron-down" />
</a-button>
</a-dropdown>
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
</template>
</BasicTable>
<MesXslCustomerModal @register="registerModal" @success="handleSuccess" />
</div>
</template>
<script lang="ts" name="xslmes-mesXslCustomer" setup>
import { reactive } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import MesXslCustomerModal from './components/MesXslCustomerModal.vue';
import { columns, searchFormSchema, superQuerySchema } from './MesXslCustomer.data';
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl, updateStatus } from './MesXslCustomer.api';
import Icon from '/@/components/Icon';
const queryParam = reactive<any>({});
const [registerModal, { openModal }] = useModal();
const { tableContext, onExportXls, onImportXls } = useListPage({
tableProps: {
title: '客户管理',
api: list,
columns,
canResize: true,
formConfig: {
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: true,
},
actionColumn: {
width: 280,
fixed: 'right',
},
beforeFetch: (params) => {
return Object.assign(params, queryParam);
},
},
exportConfig: {
name: '客户管理',
url: getExportUrl,
params: queryParam,
},
importConfig: {
url: getImportUrl,
success: handleSuccess,
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
const superQueryConfig = reactive(superQuerySchema);
function handleSuperQuery(params) {
Object.keys(params).forEach((k) => {
queryParam[k] = params[k];
});
reload();
}
function handleAdd() {
openModal(true, { isUpdate: false, showFooter: true });
}
function handleEdit(record: Recordable) {
openModal(true, { record, isUpdate: true, showFooter: true });
}
function handleDetail(record: Recordable) {
openModal(true, { record, isUpdate: true, showFooter: false });
}
async function handleDelete(record) {
await deleteOne({ id: record.id }, handleSuccess);
}
/** 与供应商管理一致status===0 或 0 为启用 */
function isRecordEnabled(record: Recordable) {
return record.status === '0' || record.status === 0;
}
async function handleToggleStatus(record: Recordable, status: string) {
await updateStatus({ id: record.id, status }, handleSuccess);
}
async function batchHandleDelete() {
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
}
function handleSuccess() {
selectedRowKeys.value = [];
reload();
}
function getTableAction(record) {
const enabled = isRecordEnabled(record);
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'xslmes:mes_xsl_customer:edit',
},
{
label: '启用',
ifShow: !enabled,
onClick: handleToggleStatus.bind(null, record, '0'),
auth: 'xslmes:mes_xsl_customer:updateStatus',
},
{
label: '停用',
ifShow: enabled,
onClick: handleToggleStatus.bind(null, record, '1'),
auth: 'xslmes:mes_xsl_customer:updateStatus',
},
{
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
},
auth: 'xslmes:mes_xsl_customer:delete',
},
];
}
function getDropDownAction(record) {
return [{ label: '详情', onClick: handleDetail.bind(null, record) }];
}
</script>
<style lang="less" scoped>
:deep(.ant-picker-range) {
width: 100%;
}
</style>

View File

@@ -0,0 +1,91 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
<BasicForm @register="registerForm" name="MesXslCustomerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { formSchema } from '../MesXslCustomer.data';
import { saveOrUpdate, queryById } from '../MesXslCustomer.api';
/** 字典下拉 value 与接口一致为字符串,避免 number/string 与选项不一致导致回显成第一项「启用」 */
function normalizeCustomerFormValues(record: Recordable) {
const o = { ...record };
if (o.status !== undefined && o.status !== null && o.status !== '') {
o.status = String(o.status);
}
if (o.customerRegion !== undefined && o.customerRegion !== null && o.customerRegion !== '') {
o.customerRegion = String(o.customerRegion);
}
return o;
}
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
const isDetail = ref(false);
const [registerForm, { setProps, resetFields, setFieldsValue, validate, scrollToField }] = useForm({
labelWidth: 120,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
await resetFields();
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
isUpdate.value = !!data?.isUpdate;
isDetail.value = !data?.showFooter;
if (unref(isUpdate)) {
let row = data?.record;
// 以详情接口为准,避免列表行字段缺失或与字典组件 value 类型不一致(列表仍显示 status_dictText
if (row?.id) {
try {
const res = await queryById({ id: String(row.id) });
const full = (res as any)?.id != null ? res : (res as any)?.result ?? res;
if (full && (full as any).id) {
row = full as Recordable;
}
} catch {
// 仍使用列表行
}
}
await setFieldsValue(normalizeCustomerFormValues(row || {}));
} else {
// 新增默认启用(与后端 MesXslCustomerBizStatus.ENABLED 一致0=启用)
await setFieldsValue({ status: '0' });
}
setProps({ disabled: !data?.showFooter });
});
const title = computed(() => (!unref(isUpdate) ? '新增' : unref(isDetail) ? '详情' : '编辑'));
async function handleSubmit() {
try {
const values = await validate();
setModalProps({ confirmLoading: true });
await saveOrUpdate(values, unref(isUpdate));
closeModal();
emit('success');
} catch (e: any) {
if (e?.errorFields) {
const firstField = e.errorFields[0];
if (firstField) {
scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(e);
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped>
:deep(.ant-input-number) {
width: 100%;
}
</style>

View File

@@ -0,0 +1,56 @@
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
enum Api {
list = '/xslmes/mesXslInstrument/list',
save = '/xslmes/mesXslInstrument/add',
edit = '/xslmes/mesXslInstrument/edit',
updateStatus = '/xslmes/mesXslInstrument/updateStatus',
deleteOne = '/xslmes/mesXslInstrument/delete',
deleteBatch = '/xslmes/mesXslInstrument/deleteBatch',
importExcel = '/xslmes/mesXslInstrument/importExcel',
exportXls = '/xslmes/mesXslInstrument/exportXls',
queryById = '/xslmes/mesXslInstrument/queryById',
}
export const getExportUrl = Api.exportXls;
export const getImportUrl = Api.importExcel;
export const list = (params) => defHttp.get({ url: Api.list, params });
export const queryById = (params: { id: string }) => defHttp.get({ url: Api.queryById, params });
export const deleteOne = (params, handleSuccess) => {
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
};
export const batchDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
},
});
};
export const saveOrUpdate = (params, isUpdate) => {
const url = isUpdate ? Api.edit : Api.save;
return defHttp.post({ url, params });
};
/** 停用/启用status 0 停用 1 启用 */
export const updateStatus = (params: { id: string; status: string }, handleSuccess?: () => void) => {
return defHttp.post({ url: Api.updateStatus, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess?.();
});
};

View File

@@ -0,0 +1,64 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
export const columns: BasicColumn[] = [
{ title: 'ID', align: 'center', dataIndex: 'id', width: 280, ellipsis: true, defaultHidden: true },
{ title: '编号/条码', align: 'center', dataIndex: 'barcode', width: 160 },
{ title: '规格型号', align: 'center', dataIndex: 'specModel_dictText', width: 140, ellipsis: true },
{ title: '状态', align: 'center', dataIndex: 'status_dictText', width: 90 },
{ title: '备注', align: 'center', dataIndex: 'remark', width: 200, ellipsis: true },
{ title: '租户ID', align: 'center', dataIndex: 'tenantId', width: 90, defaultHidden: true },
];
export const searchFormSchema: FormSchema[] = [
{ label: '编号/条码', field: 'barcode', component: 'JInput', colProps: { span: 6 } },
{
label: '规格型号',
field: 'specModel',
component: 'JDictSelectTag',
componentProps: { dictCode: 'xslmes_instrument_spec' },
colProps: { span: 6 },
},
{
label: '状态',
field: 'status',
component: 'JDictSelectTag',
componentProps: { dictCode: 'xslmes_instrument_status' },
colProps: { span: 6 },
},
];
export const formSchema: FormSchema[] = [
{ label: '', field: 'id', component: 'Input', show: false },
{
label: '编号/条码',
field: 'barcode',
required: true,
component: 'Input',
componentProps: { placeholder: '请输入编号或条码' },
},
{
label: '规格型号',
field: 'specModel',
component: 'JDictSelectTag',
componentProps: { dictCode: 'xslmes_instrument_spec', placeholder: '请选择规格型号' },
},
{
label: '状态',
field: 'status',
component: 'JDictSelectTag',
componentProps: { dictCode: 'xslmes_instrument_status', placeholder: '请选择状态' },
defaultValue: '0',
},
{
label: '备注',
field: 'remark',
component: 'InputTextArea',
componentProps: { placeholder: '请输入备注', rows: 3 },
},
];
export const superQuerySchema = {
barcode: { title: '编号/条码', order: 0, view: 'text' },
specModel: { title: '规格型号', order: 1, view: 'list', dictCode: 'xslmes_instrument_spec' },
status: { title: '状态', order: 2, view: 'list', dictCode: 'xslmes_instrument_status' },
};

View File

@@ -0,0 +1,156 @@
<template>
<div>
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #tableTitle>
<a-button type="primary" v-auth="'xslmes:mes_xsl_instrument:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'xslmes:mes_xsl_instrument:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'xslmes:mes_xsl_instrument:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="batchHandleDelete">
<Icon icon="ant-design:delete-outlined" />
删除
</a-menu-item>
</a-menu>
</template>
<a-button v-auth="'xslmes:mes_xsl_instrument:deleteBatch'">
批量操作
<Icon icon="mdi:chevron-down" />
</a-button>
</a-dropdown>
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
</template>
</BasicTable>
<MesXslInstrumentModal @register="registerModal" @success="handleSuccess" />
</div>
</template>
<script lang="ts" name="xslmes-mesXslInstrument" setup>
import { reactive } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import MesXslInstrumentModal from './components/MesXslInstrumentModal.vue';
import { columns, searchFormSchema, superQuerySchema } from './MesXslInstrument.data';
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl, updateStatus } from './MesXslInstrument.api';
import Icon from '/@/components/Icon';
const queryParam = reactive<any>({});
const [registerModal, { openModal }] = useModal();
const { tableContext, onExportXls, onImportXls } = useListPage({
tableProps: {
title: '器具管理',
api: list,
columns,
canResize: true,
formConfig: {
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: true,
},
actionColumn: {
width: 280,
fixed: 'right',
},
beforeFetch: (params) => Object.assign(params, queryParam),
},
exportConfig: {
name: '器具管理',
url: getExportUrl,
params: queryParam,
},
importConfig: {
url: getImportUrl,
success: handleSuccess,
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
const superQueryConfig = reactive(superQuerySchema);
function handleSuperQuery(params) {
Object.keys(params).forEach((k) => {
queryParam[k] = params[k];
});
reload();
}
function handleAdd() {
openModal(true, { isUpdate: false, showFooter: true });
}
function handleEdit(record: Recordable) {
openModal(true, { record, isUpdate: true, showFooter: true });
}
function handleDetail(record: Recordable) {
openModal(true, { record, isUpdate: true, showFooter: false });
}
async function handleDelete(record) {
await deleteOne({ id: record.id }, handleSuccess);
}
function isRecordEnabled(record: Recordable) {
return record.status === '0' || record.status === 0;
}
async function handleToggleStatus(record: Recordable, status: string) {
await updateStatus({ id: record.id, status }, handleSuccess);
}
async function batchHandleDelete() {
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
}
function handleSuccess() {
selectedRowKeys.value = [];
reload();
}
function getTableAction(record) {
const enabled = isRecordEnabled(record);
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'xslmes:mes_xsl_instrument:edit',
},
{
label: '启用',
ifShow: !enabled,
onClick: handleToggleStatus.bind(null, record, '0'),
auth: 'xslmes:mes_xsl_instrument:updateStatus',
},
{
label: '停用',
ifShow: enabled,
onClick: handleToggleStatus.bind(null, record, '1'),
auth: 'xslmes:mes_xsl_instrument:updateStatus',
},
{
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
},
auth: 'xslmes:mes_xsl_instrument:delete',
},
];
}
function getDropDownAction(record) {
return [{ label: '详情', onClick: handleDetail.bind(null, record) }];
}
</script>
<style lang="less" scoped>
:deep(.ant-picker-range) {
width: 100%;
}
</style>

View File

@@ -0,0 +1,63 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="720" @ok="handleSubmit">
<BasicForm @register="registerForm" name="MesXslInstrumentForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { formSchema } from '../MesXslInstrument.data';
import { saveOrUpdate } from '../MesXslInstrument.api';
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
const isDetail = ref(false);
const [registerForm, { setProps, resetFields, setFieldsValue, validate, scrollToField }] = useForm({
labelWidth: 120,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
await resetFields();
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
isUpdate.value = !!data?.isUpdate;
isDetail.value = !data?.showFooter;
if (unref(isUpdate)) {
await setFieldsValue({ ...data.record });
}
setProps({ disabled: !data?.showFooter });
});
const title = computed(() => (!unref(isUpdate) ? '新增器具' : unref(isDetail) ? '器具详情' : '编辑器具'));
async function handleSubmit() {
try {
const values = await validate();
setModalProps({ confirmLoading: true });
await saveOrUpdate(values, unref(isUpdate));
closeModal();
emit('success');
} catch (e: any) {
if (e?.errorFields) {
const firstField = e.errorFields[0];
if (firstField) {
scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(e);
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped>
:deep(.ant-input-number) {
width: 100%;
}
</style>

View File

@@ -0,0 +1,56 @@
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
enum Api {
list = '/xslmes/mesXslSupplier/list',
save = '/xslmes/mesXslSupplier/add',
edit = '/xslmes/mesXslSupplier/edit',
updateStatus = '/xslmes/mesXslSupplier/updateStatus',
deleteOne = '/xslmes/mesXslSupplier/delete',
deleteBatch = '/xslmes/mesXslSupplier/deleteBatch',
importExcel = '/xslmes/mesXslSupplier/importExcel',
exportXls = '/xslmes/mesXslSupplier/exportXls',
queryById = '/xslmes/mesXslSupplier/queryById',
}
export const getExportUrl = Api.exportXls;
export const getImportUrl = Api.importExcel;
export const list = (params) => defHttp.get({ url: Api.list, params });
export const queryById = (params: { id: string }) => defHttp.get({ url: Api.queryById, params });
export const deleteOne = (params, handleSuccess) => {
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
};
export const batchDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
},
});
};
export const saveOrUpdate = (params, isUpdate) => {
const url = isUpdate ? Api.edit : Api.save;
return defHttp.post({ url, params });
};
/** 停用/启用status 0 停用 1 启用 */
export const updateStatus = (params: { id: string; status: string }, handleSuccess?: () => void) => {
return defHttp.post({ url: Api.updateStatus, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess?.();
});
};

View File

@@ -0,0 +1,74 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
export const columns: BasicColumn[] = [
{ title: 'ID', align: 'center', dataIndex: 'id', width: 280, ellipsis: true, defaultHidden: true },
{ title: '编码', align: 'center', dataIndex: 'supplierCode', width: 120 },
{ title: '名称', align: 'center', dataIndex: 'supplierName', width: 160 },
{ title: '简称', align: 'center', dataIndex: 'supplierShortName', width: 120 },
{ title: 'ERP编码', align: 'center', dataIndex: 'erpCode', width: 120 },
{ title: '备注', align: 'center', dataIndex: 'remark', width: 180, ellipsis: true },
{ title: '状态', align: 'center', dataIndex: 'status_dictText', width: 90 },
{ title: '租户ID', align: 'center', dataIndex: 'tenantId', width: 90, defaultHidden: true },
];
export const searchFormSchema: FormSchema[] = [
{ label: '编码', field: 'supplierCode', component: 'JInput', colProps: { span: 6 } },
{ label: '名称', field: 'supplierName', component: 'JInput', colProps: { span: 6 } },
{
label: '状态',
field: 'status',
component: 'JDictSelectTag',
componentProps: { dictCode: 'xslmes_supplier_status' },
colProps: { span: 6 },
},
];
export const formSchema: FormSchema[] = [
{ label: '', field: 'id', component: 'Input', show: false },
{
label: '编码',
field: 'supplierCode',
required: true,
component: 'Input',
componentProps: { placeholder: '请输入编码' },
},
{
label: '名称',
field: 'supplierName',
required: true,
component: 'Input',
componentProps: { placeholder: '请输入名称' },
},
{
label: '简称',
field: 'supplierShortName',
component: 'Input',
componentProps: { placeholder: '请输入简称' },
},
{
label: 'ERP编码',
field: 'erpCode',
component: 'Input',
componentProps: { placeholder: '请输入ERP编码' },
},
{
label: '备注',
field: 'remark',
component: 'InputTextArea',
componentProps: { placeholder: '请输入备注', rows: 3 },
},
{
label: '状态',
field: 'status',
component: 'JDictSelectTag',
componentProps: { dictCode: 'xslmes_supplier_status', placeholder: '请选择状态' },
defaultValue: '0',
},
];
export const superQuerySchema = {
supplierCode: { title: '编码', order: 0, view: 'text' },
supplierName: { title: '名称', order: 1, view: 'text' },
supplierShortName: { title: '简称', order: 2, view: 'text' },
status: { title: '状态', order: 3, view: 'list', dictCode: 'xslmes_supplier_status' },
};

View File

@@ -0,0 +1,156 @@
<template>
<div>
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #tableTitle>
<a-button type="primary" v-auth="'xslmes:mes_xsl_supplier:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'xslmes:mes_xsl_supplier:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'xslmes:mes_xsl_supplier:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="batchHandleDelete">
<Icon icon="ant-design:delete-outlined" />
删除
</a-menu-item>
</a-menu>
</template>
<a-button v-auth="'xslmes:mes_xsl_supplier:deleteBatch'">
批量操作
<Icon icon="mdi:chevron-down" />
</a-button>
</a-dropdown>
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
</template>
</BasicTable>
<MesXslSupplierModal @register="registerModal" @success="handleSuccess" />
</div>
</template>
<script lang="ts" name="xslmes-mesXslSupplier" setup>
import { reactive } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import MesXslSupplierModal from './components/MesXslSupplierModal.vue';
import { columns, searchFormSchema, superQuerySchema } from './MesXslSupplier.data';
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl, updateStatus } from './MesXslSupplier.api';
import Icon from '/@/components/Icon';
const queryParam = reactive<any>({});
const [registerModal, { openModal }] = useModal();
const { tableContext, onExportXls, onImportXls } = useListPage({
tableProps: {
title: '供应商管理',
api: list,
columns,
canResize: true,
formConfig: {
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: true,
},
actionColumn: {
width: 280,
fixed: 'right',
},
beforeFetch: (params) => Object.assign(params, queryParam),
},
exportConfig: {
name: '供应商管理',
url: getExportUrl,
params: queryParam,
},
importConfig: {
url: getImportUrl,
success: handleSuccess,
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
const superQueryConfig = reactive(superQuerySchema);
function handleSuperQuery(params) {
Object.keys(params).forEach((k) => {
queryParam[k] = params[k];
});
reload();
}
function handleAdd() {
openModal(true, { isUpdate: false, showFooter: true });
}
function handleEdit(record: Recordable) {
openModal(true, { record, isUpdate: true, showFooter: true });
}
function handleDetail(record: Recordable) {
openModal(true, { record, isUpdate: true, showFooter: false });
}
async function handleDelete(record) {
await deleteOne({ id: record.id }, handleSuccess);
}
function isRecordEnabled(record: Recordable) {
return record.status === '0' || record.status === 0;
}
async function handleToggleStatus(record: Recordable, status: string) {
await updateStatus({ id: record.id, status }, handleSuccess);
}
async function batchHandleDelete() {
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
}
function handleSuccess() {
selectedRowKeys.value = [];
reload();
}
function getTableAction(record) {
const enabled = isRecordEnabled(record);
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'xslmes:mes_xsl_supplier:edit',
},
{
label: '启用',
ifShow: !enabled,
onClick: handleToggleStatus.bind(null, record, '0'),
auth: 'xslmes:mes_xsl_supplier:updateStatus',
},
{
label: '停用',
ifShow: enabled,
onClick: handleToggleStatus.bind(null, record, '1'),
auth: 'xslmes:mes_xsl_supplier:updateStatus',
},
{
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
},
auth: 'xslmes:mes_xsl_supplier:delete',
},
];
}
function getDropDownAction(record) {
return [{ label: '详情', onClick: handleDetail.bind(null, record) }];
}
</script>
<style lang="less" scoped>
:deep(.ant-picker-range) {
width: 100%;
}
</style>

View File

@@ -0,0 +1,63 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="720" @ok="handleSubmit">
<BasicForm @register="registerForm" name="MesXslSupplierForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { formSchema } from '../MesXslSupplier.data';
import { saveOrUpdate } from '../MesXslSupplier.api';
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
const isDetail = ref(false);
const [registerForm, { setProps, resetFields, setFieldsValue, validate, scrollToField }] = useForm({
labelWidth: 120,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
await resetFields();
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
isUpdate.value = !!data?.isUpdate;
isDetail.value = !data?.showFooter;
if (unref(isUpdate)) {
await setFieldsValue({ ...data.record });
}
setProps({ disabled: !data?.showFooter });
});
const title = computed(() => (!unref(isUpdate) ? '新增供应商' : unref(isDetail) ? '供应商详情' : '编辑供应商'));
async function handleSubmit() {
try {
const values = await validate();
setModalProps({ confirmLoading: true });
await saveOrUpdate(values, unref(isUpdate));
closeModal();
emit('success');
} catch (e: any) {
if (e?.errorFields) {
const firstField = e.errorFields[0];
if (firstField) {
scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(e);
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped>
:deep(.ant-input-number) {
width: 100%;
}
</style>

View File

@@ -0,0 +1,56 @@
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
enum Api {
list = '/xslmes/mesXslUnit/list',
save = '/xslmes/mesXslUnit/add',
edit = '/xslmes/mesXslUnit/edit',
updateStatus = '/xslmes/mesXslUnit/updateStatus',
deleteOne = '/xslmes/mesXslUnit/delete',
deleteBatch = '/xslmes/mesXslUnit/deleteBatch',
importExcel = '/xslmes/mesXslUnit/importExcel',
exportXls = '/xslmes/mesXslUnit/exportXls',
queryById = '/xslmes/mesXslUnit/queryById',
}
export const getExportUrl = Api.exportXls;
export const getImportUrl = Api.importExcel;
export const list = (params) => defHttp.get({ url: Api.list, params });
export const queryById = (params: { id: string }) => defHttp.get({ url: Api.queryById, params });
export const deleteOne = (params, handleSuccess) => {
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
};
export const batchDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
},
});
};
export const saveOrUpdate = (params, isUpdate) => {
const url = isUpdate ? Api.edit : Api.save;
return defHttp.post({ url, params });
};
/** 停用/启用status 0 停用 1 启用 */
export const updateStatus = (params: { id: string; status: string }, handleSuccess?: () => void) => {
return defHttp.post({ url: Api.updateStatus, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess?.();
});
};

View File

@@ -0,0 +1,83 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
export const columns: BasicColumn[] = [
{ title: 'ID', align: 'center', dataIndex: 'id', width: 280, ellipsis: true, defaultHidden: true },
{ title: '编码', align: 'center', dataIndex: 'unitCode', width: 120 },
{ title: '名称', align: 'center', dataIndex: 'unitName', width: 140 },
{ title: 'ERP编码', align: 'center', dataIndex: 'erpCode', width: 120 },
{ title: '所属分类', align: 'center', dataIndex: 'categoryId_dictText', width: 140, ellipsis: true },
{ title: '描述', align: 'center', dataIndex: 'unitDesc', width: 200, ellipsis: true },
{ title: '状态', align: 'center', dataIndex: 'status_dictText', width: 90 },
{ title: '租户ID', align: 'center', dataIndex: 'tenantId', width: 90, defaultHidden: true },
];
export const searchFormSchema: FormSchema[] = [
{ label: '编码', field: 'unitCode', component: 'JInput', colProps: { span: 6 } },
{ label: '名称', field: 'unitName', component: 'JInput', colProps: { span: 6 } },
{
label: '状态',
field: 'status',
component: 'JDictSelectTag',
componentProps: { dictCode: 'xslmes_unit_status' },
colProps: { span: 6 },
},
];
export const formSchema: FormSchema[] = [
{ label: '', field: 'id', component: 'Input', show: false },
{
label: '编码',
field: 'unitCode',
required: true,
component: 'Input',
componentProps: { placeholder: '请输入编码' },
},
{
label: '名称',
field: 'unitName',
required: true,
component: 'Input',
componentProps: { placeholder: '请输入名称' },
},
{
label: 'ERP编码',
field: 'erpCode',
component: 'Input',
componentProps: { placeholder: '请输入ERP编码' },
},
{
label: '所属分类',
field: 'categoryId',
required: true,
component: 'JCategorySelect',
componentProps: {
pcode: 'XSLMES_UNIT',
placeholder: '请选择所属分类(分类字典)',
},
},
{
label: '描述',
field: 'unitDesc',
component: 'InputTextArea',
componentProps: { rows: 3, placeholder: '请输入描述' },
},
{
label: '状态',
field: 'status',
component: 'JDictSelectTag',
componentProps: { dictCode: 'xslmes_unit_status', placeholder: '请选择状态' },
defaultValue: '0',
},
{
label: '租户ID',
field: 'tenantId',
component: 'InputNumber',
componentProps: { placeholder: '租户ID可空' },
},
];
export const superQuerySchema = {
unitCode: { title: '编码', order: 0, view: 'text' },
unitName: { title: '名称', order: 1, view: 'text' },
status: { title: '状态', order: 2, view: 'list', dictCode: 'xslmes_unit_status' },
};

View File

@@ -0,0 +1,618 @@
<template>
<div class="mes-xsl-unit-page">
<div class="mes-xsl-unit-layout">
<div class="mes-xsl-unit-sider-col">
<aside
:class="['mes-xsl-unit-sider', { 'is-collapsed': siderCollapsed, 'is-dragging': siderDragging }]"
:style="siderAsideStyle"
>
<Card class="mes-xsl-unit-sider-card" size="small" title="单位分类" :bordered="true">
<template #extra>
<a-space v-show="!siderCollapsed" size="small" class="mes-xsl-unit-sider-extra">
<a-button type="link" size="small" v-auth="'xslmes:mes_xsl_unit_category:add'" @click="handleAddCategory">新增</a-button>
<a-button
type="link"
size="small"
v-auth="'xslmes:mes_xsl_unit_category:edit'"
:disabled="!categorySelectedId"
@click="handleEditCategory"
>
编辑
</a-button>
<a-button
type="link"
size="small"
danger
v-auth="'xslmes:mes_xsl_unit_category:delete'"
:disabled="!categorySelectedId"
@click="handleDeleteCategory"
>
删除
</a-button>
</a-space>
</template>
<Spin :spinning="treeLoading">
<BasicTree
:treeData="categoryTreeData"
:selectedKeys="selectedKeys"
defaultExpandLevel="2"
@update:selectedKeys="onTreeSelect"
/>
</Spin>
</Card>
</aside>
<!-- 分隔条贴在侧栏右缘三角把手 + 拖拽改宽度 -->
<div
class="mes-xsl-unit-resizer"
:class="{ 'is-dragging': siderDragging }"
role="separator"
aria-orientation="vertical"
:aria-valuenow="siderCollapsed ? 0 : siderWidth"
:aria-valuemin="SIDER_MIN"
:aria-valuemax="SIDER_MAX"
tabindex="0"
@pointerdown="onSiderResizerPointerDown"
@keydown.left.prevent="nudgeSiderWidth(-16)"
@keydown.right.prevent="nudgeSiderWidth(16)"
>
<a-tooltip :title="siderCollapsed ? '展开(可向右拖拽)' : '收起(点击)或左右拖拽调整宽度'">
<span class="mes-xsl-unit-resizer-knob" aria-hidden="true">
<span class="mes-xsl-unit-tri" :class="{ 'mes-xsl-unit-tri--collapsed': siderCollapsed }" />
</span>
</a-tooltip>
</div>
</div>
<div class="mes-xsl-unit-main">
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #tableTitle>
<a-button type="primary" v-auth="'xslmes:mes_xsl_unit:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'xslmes:mes_xsl_unit:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'xslmes:mes_xsl_unit:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="batchHandleDelete">
<Icon icon="ant-design:delete-outlined" />
删除
</a-menu-item>
</a-menu>
</template>
<a-button v-auth="'xslmes:mes_xsl_unit:deleteBatch'">
批量操作
<Icon icon="mdi:chevron-down" />
</a-button>
</a-dropdown>
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
</template>
</BasicTable>
</div>
</div>
<MesXslUnitModal @register="registerModal" @success="handleSuccess" />
<MesXslUnitSysCategoryModal @register="registerCategoryModal" @success="onCategorySuccess" />
</div>
</template>
<script lang="ts" name="xslmes-mesXslUnit" setup>
import { computed, onMounted, onUnmounted, reactive, ref } from 'vue';
import { Card, Spin } from 'ant-design-vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { BasicTree } from '/@/components/Tree';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import { useMessage } from '/@/hooks/web/useMessage';
import { defHttp } from '/@/utils/http/axios';
import MesXslUnitModal from './components/MesXslUnitModal.vue';
import MesXslUnitSysCategoryModal from './components/MesXslUnitSysCategoryModal.vue';
import { columns, searchFormSchema, superQuerySchema } from './MesXslUnit.data';
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl, updateStatus } from './MesXslUnit.api';
import { loadTreeData as loadUnitCategoryTreeRoot } from '/@/views/system/category/category.api';
import { fetchUnitCategoryRoot, deleteUnitSysCategory, UNIT_CATEGORY_ROOT_CODE } from './MesXslUnitSysCategory.api';
import Icon from '/@/components/Icon';
import type { KeyType } from '/@/components/Tree/src/types/tree';
import type { Recordable } from '/@/types/global';
const { createConfirm, createMessage } = useMessage();
const TREE_ALL = 'ALL';
/** 侧栏宽度限制px */
const SIDER_MIN = 200;
const SIDER_MAX = 560;
const SIDER_DEFAULT = 260;
/** 判定为拖拽而非点击的位移阈值px */
const SIDER_DRAG_THRESHOLD = 5;
/** 收起状态下向右拖拽超过此值开始展开 */
const SIDER_EXPAND_DRAG = 12;
/** 左侧分类树是否收起(为表格腾出横向空间) */
const siderCollapsed = ref(false);
/** 展开时的侧栏宽度 */
const siderWidth = ref(SIDER_DEFAULT);
const siderDragging = ref(false);
const siderAsideStyle = computed(() => ({
width: siderCollapsed.value ? '0px' : `${siderWidth.value}px`,
}));
/** 拖拽过程状态(不使用 ref 避免频繁渲染指针位移计算) */
let siderDragStartX = 0;
let siderDragStartW = 0;
let siderDragMaxDelta = 0;
let siderDragCollapsedStart = false;
let siderDragPointerId: number | null = null;
let siderDragEl: HTMLElement | null = null;
function toggleSider() {
if (siderCollapsed.value) {
siderCollapsed.value = false;
} else {
siderCollapsed.value = true;
}
}
function clampSiderW(w: number) {
return Math.min(SIDER_MAX, Math.max(SIDER_MIN, w));
}
/** 键盘微调宽度 */
function nudgeSiderWidth(delta: number) {
if (siderCollapsed.value) {
if (delta > 0) {
siderCollapsed.value = false;
} else {
return;
}
}
siderWidth.value = clampSiderW(siderWidth.value + delta);
}
function onSiderResizerPointerMove(e: PointerEvent) {
if (siderDragPointerId == null || e.pointerId !== siderDragPointerId) return;
const dx = e.clientX - siderDragStartX;
siderDragMaxDelta = Math.max(siderDragMaxDelta, Math.abs(dx));
if (siderDragCollapsedStart) {
if (dx >= SIDER_EXPAND_DRAG) {
siderCollapsed.value = false;
siderWidth.value = clampSiderW(dx);
siderDragStartX = e.clientX;
siderDragStartW = siderWidth.value;
siderDragCollapsedStart = false;
}
} else {
siderWidth.value = clampSiderW(siderDragStartW + dx);
}
}
function endSiderDrag(e: PointerEvent) {
if (siderDragPointerId == null || e.pointerId !== siderDragPointerId) return;
if (siderDragEl) {
try {
siderDragEl.releasePointerCapture(siderDragPointerId);
} catch {
/* ignore */
}
}
document.removeEventListener('pointermove', onSiderResizerPointerMove);
document.removeEventListener('pointerup', endSiderDrag);
document.removeEventListener('pointercancel', endSiderDrag);
document.body.style.cursor = '';
document.body.style.userSelect = '';
siderDragging.value = false;
siderDragPointerId = null;
siderDragEl = null;
// 轻点分隔条:折叠 / 展开
if (siderDragMaxDelta < SIDER_DRAG_THRESHOLD) {
toggleSider();
}
}
function onSiderResizerPointerDown(e: PointerEvent) {
if (e.button !== 0) return;
e.preventDefault();
siderDragEl = e.currentTarget as HTMLElement;
siderDragPointerId = e.pointerId;
siderDragStartX = e.clientX;
siderDragStartW = siderCollapsed.value ? 0 : siderWidth.value;
siderDragMaxDelta = 0;
siderDragCollapsedStart = siderCollapsed.value;
siderDragging.value = true;
document.body.style.cursor = 'col-resize';
document.body.style.userSelect = 'none';
try {
siderDragEl.setPointerCapture(e.pointerId);
} catch {
/* ignore */
}
document.addEventListener('pointermove', onSiderResizerPointerMove);
document.addEventListener('pointerup', endSiderDrag);
document.addEventListener('pointercancel', endSiderDrag);
}
onUnmounted(() => {
document.removeEventListener('pointermove', onSiderResizerPointerMove);
document.removeEventListener('pointerup', endSiderDrag);
document.removeEventListener('pointercancel', endSiderDrag);
document.body.style.cursor = '';
document.body.style.userSelect = '';
});
const queryParam = reactive<any>({});
const treeLoading = ref(false);
const rawUnitCategoryTree = ref<Recordable[]>([]);
const unitCategoryRootId = ref('');
const selectedKeys = ref<KeyType[]>([TREE_ALL]);
function mapUnitCategoryTreeNodes(nodes: Recordable[]): Recordable[] {
return (nodes || []).map((n) => ({
key: n.key,
title: n.title,
children: n.children?.length ? mapUnitCategoryTreeNodes(n.children as Recordable[]) : undefined,
}));
}
const categoryTreeData = computed(() => [
{
key: TREE_ALL,
title: '全部分类',
children: mapUnitCategoryTreeNodes(rawUnitCategoryTree.value || []),
},
]);
const categorySelectedId = computed(() => {
const k = selectedKeys.value[0];
if (!k || k === TREE_ALL) return '';
return String(k);
});
async function loadCategoryTree() {
treeLoading.value = true;
try {
const root = await fetchUnitCategoryRoot();
unitCategoryRootId.value = root?.id != null ? String(root.id) : '';
const res = await loadUnitCategoryTreeRoot({ async: false, pcode: 'XSLMES_UNIT' });
rawUnitCategoryTree.value = Array.isArray(res) ? res : [];
if (!unitCategoryRootId.value || !rawUnitCategoryTree.value.length) {
createMessage.warning('未加载到单位分类树,请确认已执行库脚本且分类字典根编码为 XSLMES_UNIT。');
}
} catch {
unitCategoryRootId.value = '';
rawUnitCategoryTree.value = [];
createMessage.warning('加载单位分类失败,请检查分类根编码 XSLMES_UNIT 是否存在。');
} finally {
treeLoading.value = false;
}
}
const [registerModal, { openModal }] = useModal();
const [registerCategoryModal, { openModal: openCategoryModal }] = useModal();
const { tableContext, onExportXls, onImportXls } = useListPage({
tableProps: {
title: '单位管理',
api: list,
columns,
canResize: true,
formConfig: {
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: true,
},
actionColumn: {
width: 300,
fixed: 'right',
},
beforeFetch: (params) => Object.assign(params, queryParam),
},
exportConfig: {
name: '单位管理',
url: getExportUrl,
params: queryParam,
},
importConfig: {
url: getImportUrl,
success: handleSuccess,
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
const superQueryConfig = reactive(superQuerySchema);
onMounted(async () => {
await loadCategoryTree();
reload();
});
function onTreeSelect(keys: KeyType[]) {
selectedKeys.value = keys;
const k = keys[0];
if (!k || k === TREE_ALL) {
delete queryParam.treeCategoryId;
} else {
queryParam.treeCategoryId = String(k);
}
reload();
}
function handleSuperQuery(params) {
Object.keys(params).forEach((k) => {
queryParam[k] = params[k];
});
reload();
}
function handleAdd() {
openModal(true, { isUpdate: false, showFooter: true, record: {} });
}
function handleEdit(record: Recordable) {
openModal(true, { record, isUpdate: true, showFooter: true });
}
function handleDetail(record: Recordable) {
openModal(true, { record, isUpdate: true, showFooter: false });
}
async function handleDelete(record) {
await deleteOne({ id: record.id }, handleSuccess);
}
function isRecordEnabled(record: Recordable) {
return record.status === '0' || record.status === 0;
}
async function handleToggleStatus(record: Recordable, status: string) {
await updateStatus({ id: record.id, status }, handleSuccess);
}
async function batchHandleDelete() {
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
}
function handleSuccess() {
selectedRowKeys.value = [];
reload();
}
function handleAddCategory() {
const rootId = unitCategoryRootId.value;
if (!rootId) {
createMessage.warning('未找到单位分类根节点请确认分类字典中存在编码「XSLMES_UNIT」');
return;
}
const sel = categorySelectedId.value;
openCategoryModal(true, {
isUpdate: false,
parentId: sel || rootId,
});
}
function handleEditCategory() {
const id = categorySelectedId.value;
if (!id) {
createMessage.warning('请先选择左侧分类');
return;
}
openCategoryModal(true, {
isUpdate: true,
record: { id },
});
}
async function handleDeleteCategory() {
const id = categorySelectedId.value;
if (!id) {
createMessage.warning('请先选择要删除的分类');
return;
}
if (id === unitCategoryRootId.value) {
createMessage.warning('根分类不可删除');
return;
}
let code = '';
try {
const cat = await defHttp.get<Recordable>({ url: '/sys/category/queryById', params: { id } });
code = cat?.code != null ? String(cat.code) : '';
} catch {
createMessage.error('无法读取分类信息');
return;
}
if (code === UNIT_CATEGORY_ROOT_CODE) {
createMessage.warning('根分类不可删除');
return;
}
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '将删除该节点及其下级分类;请确认分类下无单位且无业务依赖。',
onOk: async () => {
await deleteUnitSysCategory(id);
await loadCategoryTree();
selectedKeys.value = [TREE_ALL];
delete queryParam.treeCategoryId;
reload();
},
});
}
function onCategorySuccess() {
loadCategoryTree();
reload();
}
function getTableAction(record) {
const enabled = isRecordEnabled(record);
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'xslmes:mes_xsl_unit:edit',
},
{
label: '启用',
ifShow: !enabled,
onClick: handleToggleStatus.bind(null, record, '0'),
auth: 'xslmes:mes_xsl_unit:updateStatus',
},
{
label: '停用',
ifShow: enabled,
onClick: handleToggleStatus.bind(null, record, '1'),
auth: 'xslmes:mes_xsl_unit:updateStatus',
},
{
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
},
auth: 'xslmes:mes_xsl_unit:delete',
},
];
}
function getDropDownAction(record) {
return [{ label: '详情', onClick: handleDetail.bind(null, record) }];
}
</script>
<style lang="less" scoped>
.mes-xsl-unit-page {
display: flex;
flex-direction: column;
/* 与内容区可视高度对齐,使左侧分类与右侧表格同高 */
min-height: calc(100vh - 160px);
:deep(.ant-picker-range) {
width: 100%;
}
}
.mes-xsl-unit-layout {
display: flex;
flex: 1;
align-items: stretch;
gap: 0;
min-height: 0;
}
.mes-xsl-unit-sider-col {
display: flex;
flex-direction: row;
align-items: stretch;
flex: 0 0 auto;
min-height: 0;
}
.mes-xsl-unit-sider {
flex: 0 0 auto;
min-width: 0;
display: flex;
flex-direction: column;
min-height: 0;
overflow: hidden;
transition: width 0.2s ease;
&.is-dragging {
transition: none;
}
&.is-collapsed {
pointer-events: none;
}
}
.mes-xsl-unit-sider-card {
height: 100%;
display: flex;
flex-direction: column;
min-height: 0;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
:deep(.ant-card-head) {
min-height: 40px;
padding: 0 12px;
}
:deep(.ant-card-body) {
flex: 1;
overflow: auto;
min-height: 0;
padding: 8px 12px;
}
}
.mes-xsl-unit-sider-extra {
flex-wrap: wrap;
justify-content: flex-end;
max-width: 200px;
}
/* 侧栏右缘可拖拽分隔条 + 三角把手 */
.mes-xsl-unit-resizer {
flex: 0 0 8px;
width: 8px;
position: relative;
z-index: 2;
cursor: col-resize;
touch-action: none;
user-select: none;
background: #fafafa;
margin-right: 2px;
&:hover,
&:focus-visible {
background: #f0f0f0;
}
&.is-dragging {
background: #e6f4ff;
}
}
.mes-xsl-unit-resizer-knob {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: center;
width: 10px;
height: 44px;
pointer-events: none;
background: #fff;
border: 1px solid #e8e8e8;
border-radius: 2px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
}
/* 三角箭头:展开时朝左(收起),收起时朝右(展开) */
.mes-xsl-unit-tri {
display: block;
width: 0;
height: 0;
border-style: solid;
border-width: 5px 6px 5px 0;
border-color: transparent #595959 transparent transparent;
margin-left: -1px;
}
.mes-xsl-unit-tri--collapsed {
border-width: 5px 0 5px 6px;
border-color: transparent transparent transparent #595959;
margin-left: 0;
margin-right: -1px;
}
.mes-xsl-unit-main {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
min-height: 0;
}
</style>

View File

@@ -0,0 +1,24 @@
import { defHttp } from '/@/utils/http/axios';
import type { Recordable } from '/@/types/global';
/** 单位分类字典根编码(与 Flyway / 后端一致) */
export const UNIT_CATEGORY_ROOT_CODE = 'XSLMES_UNIT';
export function fetchUnitCategoryRoot() {
return defHttp.get<Recordable>({
url: '/sys/category/loadOne',
params: { field: 'code', val: UNIT_CATEGORY_ROOT_CODE },
});
}
export function saveUnitSysCategory(data: Recordable) {
return defHttp.post({ url: '/sys/category/add', data });
}
export function editUnitSysCategory(data: Recordable) {
return defHttp.post({ url: '/sys/category/edit', data });
}
export function deleteUnitSysCategory(id: string) {
return defHttp.delete({ url: '/sys/category/delete', params: { id } }, { joinParamsToUrl: true });
}

View File

@@ -0,0 +1,36 @@
import { FormSchema } from '/@/components/Table';
/** 单位分类(分类字典)维护表单 */
export const unitSysCategoryFormSchema: FormSchema[] = [
{ label: '', field: 'id', component: 'Input', show: false },
{
label: '父级分类',
field: 'pid',
required: true,
component: 'TreeSelect',
componentProps: {
fieldNames: { label: 'title', value: 'key' },
treeData: [],
showSearch: true,
allowClear: false,
treeDefaultExpandAll: true,
dropdownStyle: { maxHeight: '50vh' },
getPopupContainer: () => document.body,
},
dynamicDisabled: ({ values }) => !!values.id,
},
{
label: '分类编码',
field: 'code',
component: 'Input',
componentProps: { readonly: true },
ifShow: ({ values }) => !!values.id,
},
{
label: '分类名称',
field: 'name',
required: true,
component: 'Input',
componentProps: { placeholder: '请输入分类名称' },
},
];

View File

@@ -0,0 +1,63 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
<BasicForm @register="registerForm" name="MesXslUnitForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { formSchema } from '../MesXslUnit.data';
import { saveOrUpdate } from '../MesXslUnit.api';
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
const isDetail = ref(false);
const [registerForm, { setProps, resetFields, setFieldsValue, validate, scrollToField }] = useForm({
labelWidth: 120,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
await resetFields();
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
isUpdate.value = !!data?.isUpdate;
isDetail.value = !data?.showFooter;
if (unref(isUpdate)) {
await setFieldsValue({ ...data.record });
}
setProps({ disabled: !data?.showFooter });
});
const title = computed(() => (!unref(isUpdate) ? '新增单位' : unref(isDetail) ? '单位详情' : '编辑单位'));
async function handleSubmit() {
try {
const values = await validate();
setModalProps({ confirmLoading: true });
await saveOrUpdate(values, unref(isUpdate));
closeModal();
emit('success');
} catch (e: any) {
if (e?.errorFields) {
const firstField = e.errorFields[0];
if (firstField) {
scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(e);
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped>
:deep(.ant-input-number) {
width: 100%;
}
</style>

View File

@@ -0,0 +1,117 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="560" @ok="handleSubmit">
<BasicForm @register="registerForm" name="MesXslUnitSysCategoryForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form';
import { unitSysCategoryFormSchema } from '../MesXslUnitSysCategory.data';
import { fetchUnitCategoryRoot, saveUnitSysCategory, editUnitSysCategory } from '../MesXslUnitSysCategory.api';
import { loadTreeData } from '/@/views/system/category/category.api';
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
import type { Recordable } from '/@/types/global';
const { createMessage } = useMessage();
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(false);
const [registerForm, { resetFields, setFieldsValue, validate, updateSchema, scrollToField }] = useForm({
labelWidth: 100,
schemas: unitSysCategoryFormSchema,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
function mapTreeNodes(nodes: Recordable[]): Recordable[] {
return (nodes || []).map((n) => ({
key: n.key,
title: n.title,
children: n.children?.length ? mapTreeNodes(n.children as Recordable[]) : undefined,
}));
}
async function buildPidTree(): Promise<Recordable[]> {
const rootRecord = await fetchUnitCategoryRoot();
if (!rootRecord?.id) {
return [];
}
const children = await loadTreeData({ async: false, pcode: 'XSLMES_UNIT' });
return [
{
key: rootRecord.id,
title: rootRecord.name || 'MES单位分类',
children: mapTreeNodes(Array.isArray(children) ? children : []),
},
];
}
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
await resetFields();
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
const tree = await buildPidTree();
if (!tree.length) {
createMessage.warning('未加载到分类树,请确认分类字典中存在根编码 XSLMES_UNIT');
}
await updateSchema([
{
field: 'pid',
componentProps: {
treeData: tree,
fieldNames: { label: 'title', value: 'key' },
showSearch: true,
allowClear: false,
treeDefaultExpandAll: true,
dropdownStyle: { maxHeight: '50vh' },
getPopupContainer: () => document.body,
},
},
]);
if (unref(isUpdate) && data?.record?.id) {
const cat = await defHttp.get<Recordable>({ url: '/sys/category/queryById', params: { id: data.record.id } });
await setFieldsValue({
id: cat.id,
pid: cat.pid,
name: cat.name,
code: cat.code,
});
} else {
const pid = data?.parentId != null && data.parentId !== '' ? String(data.parentId) : '';
await setFieldsValue({
pid: pid || undefined,
name: '',
});
}
});
const title = computed(() => (unref(isUpdate) ? '编辑单位分类' : '新增单位分类'));
async function handleSubmit() {
try {
const values = await validate();
setModalProps({ confirmLoading: true });
if (unref(isUpdate)) {
const full = await defHttp.get<Recordable>({ url: '/sys/category/queryById', params: { id: values.id } });
await editUnitSysCategory({ ...full, pid: values.pid, name: values.name });
} else {
await saveUnitSysCategory({ pid: values.pid, name: values.name });
}
closeModal();
emit('success');
} catch (e: any) {
if (e?.errorFields) {
const firstField = e.errorFields[0];
if (firstField) {
scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(e);
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>

View File

@@ -0,0 +1,53 @@
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
enum Api {
list = '/xslmes/mesXslVehicle/list',
save = '/xslmes/mesXslVehicle/add',
edit = '/xslmes/mesXslVehicle/edit',
updateStatus = '/xslmes/mesXslVehicle/updateStatus',
deleteOne = '/xslmes/mesXslVehicle/delete',
deleteBatch = '/xslmes/mesXslVehicle/deleteBatch',
importExcel = '/xslmes/mesXslVehicle/importExcel',
exportXls = '/xslmes/mesXslVehicle/exportXls',
}
export const getExportUrl = Api.exportXls;
export const getImportUrl = Api.importExcel;
export const list = (params) => defHttp.get({ url: Api.list, params });
export const deleteOne = (params, handleSuccess) => {
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
};
export const batchDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
handleSuccess();
});
},
});
};
export const saveOrUpdate = (params, isUpdate) => {
const url = isUpdate ? Api.edit : Api.save;
return defHttp.post({ url, params });
};
/** 停用/启用status 0 停用 1 启用 */
export const updateStatus = (params: { id: string; status: string }, handleSuccess?: () => void) => {
return defHttp.post({ url: Api.updateStatus, params }, { joinParamsToUrl: true }).then(() => {
handleSuccess?.();
});
};

Some files were not shown because too many files have changed in this diff Show More