diff --git a/doc/MCS_SQLServer_表结构说明.docx b/doc/MCS_SQLServer_表结构说明.docx new file mode 100644 index 00000000..f2dc572c Binary files /dev/null and b/doc/MCS_SQLServer_表结构说明.docx differ diff --git a/doc/MCS_SQLServer_表结构说明.md b/doc/MCS_SQLServer_表结构说明.md new file mode 100644 index 00000000..08191e71 --- /dev/null +++ b/doc/MCS_SQLServer_表结构说明.md @@ -0,0 +1,3550 @@ +# MCS SQL Server 表结构说明 + +- 生成时间:2026-07-14 16:14:35 +- 服务器:`43.108.8.218:1433` +- 登录账号:`sa` +- 说明:指定连接库 `master` 中无用户业务表,以下按实际业务库分别说明。 +- 文档结构:**先数据库 → 再逐表 → 每表写完其全部字段后,再写下一张表**。 +- 字段含义:优先使用库注释;无注释时按英文字段名转译,并标注`(英文转译推测)`。 + +## 命名约定 + +| 前缀 | 含义 | +| --- | --- | +| `MESToMCS_` | MES 下发给 MCS(上辅机)的数据表 | +| `MCSToMES_` | MCS 回传给 MES 的数据表 | +| `IF_` / `If_` | 外围/子系统接口交换表 | +| `Ppt*` | 开炼/挤出相关扫描或过程数据 | + +# 1. 数据库:MESNAC_MCS_ShareDB + +- **数据库名**:`MESNAC_MCS_ShareDB` +- **用途**:密炼/上辅机主中间库(密炼相关) +- **表数量**:58 + +## 1.1 表:Application_Error_Log + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`Application_Error_Log` +- **表含义**:应用错误日志 +- **字段数量**:6 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `tablename` | varchar(50) | YES | | | 表名(英文转译推测) | +| 2 | `userName` | varchar(50) | YES | | | 用户名(英文转译推测) | +| 3 | `errorNumber` | varchar(50) | YES | | | 错误编号(英文转译推测) | +| 4 | `errorSeverity` | varchar(50) | YES | | | 错误严重级别(英文转译推测) | +| 5 | `errorState` | varchar(50) | YES | | | 错误状态(英文转译推测) | +| 6 | `errorMessage` | varchar(5000) | YES | | | 错误信息(英文转译推测) | + +--- + +## 1.2 表:IF_BarcodeLog2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_BarcodeLog2Mes` +- **表含义**:接口:条码日志 -> MES +- **字段数量**:9 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 2 | `Scan_Time` | varchar(50) | YES | | | 扫描时间(英文转译推测) | +| 3 | `Scan_Bar` | varchar(50) | YES | | | 扫描Bar(英文转译推测) | +| 4 | `Material` | varchar(50) | YES | | | 物料(英文转译推测) | +| 5 | `Bin` | int | YES | | | 仓位(英文转译推测) | +| 6 | `Scan_State` | int | YES | | | 扫描状态(英文转译推测) | +| 7 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 8 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 9 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.3 表:IF_BinState2MES + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_BinState2MES` +- **表含义**:接口:料仓状态 -> MES +- **字段数量**:7 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Equip_Code` | varchar(20) | YES | | | 设备编码(英文转译推测) | +| 2 | `Bin_Serial` | int | YES | | | 仓位Serial(英文转译推测) | +| 3 | `level_flag` | int | YES | | | 级别标志(英文转译推测) | +| 4 | `open_flag` | int | YES | | | open标志(英文转译推测) | +| 5 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 6 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 7 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.4 表:IF_EquipState2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_EquipState2Mes` +- **表含义**:接口:设备状态 -> MES +- **字段数量**:9 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `ID` | varchar(50) | NO | | | ID(英文转译推测) | +| 2 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Equip_State` | varchar(50) | YES | | | 设备状态(英文转译推测) | +| 4 | `Alarm_OccurTime` | varchar(50) | YES | | | 报警Occur时间(英文转译推测) | +| 5 | `Alarm_ClearTime` | varchar(50) | YES | | | 报警Clear时间(英文转译推测) | +| 6 | `Equip_AlarmTxt` | varchar(50) | YES | | | 设备报警txt(英文转译推测) | +| 7 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 8 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 9 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.5 表:IF_FeedMaterialInfo2CWSS + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_FeedMaterialInfo2CWSS` +- **表含义**:接口:供料信息 -> CWSS +- **字段数量**:9 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Equip_Code` | varchar(16) | YES | | | 设备编码(英文转译推测) | +| 2 | `Scan_Time` | varchar(50) | YES | | | 扫描时间(英文转译推测) | +| 3 | `Scan_Bar` | int | YES | | | 扫描Bar(英文转译推测) | +| 4 | `Material` | varchar(50) | YES | | | 物料(英文转译推测) | +| 5 | `Bin` | int | YES | | | 仓位(英文转译推测) | +| 6 | `Scan_State` | int | YES | | | 扫描状态(英文转译推测) | +| 7 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 8 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 9 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.6 表:IF_LrAlarmLog2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_LrAlarmLog2Mes` +- **表含义**:接口:小料报警日志 -> MES +- **字段数量**:9 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Equip_code` | varchar(20) | YES | | | 设备编码(英文转译推测) | +| 2 | `Alarm_ID` | int | YES | | | 报警ID(英文转译推测) | +| 3 | `Alarm_OccurTime` | varchar(50) | YES | | | 报警Occur时间(英文转译推测) | +| 4 | `Alarm_ClearTime` | varchar(50) | YES | | | 报警Clear时间(英文转译推测) | +| 5 | `Alarm_Status` | int | YES | | | 报警状态(英文转译推测) | +| 6 | `Alarm_GUID` | char(32) | YES | | | 报警GUID(英文转译推测) | +| 7 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 8 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 9 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.7 表:If_Lrlot2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`If_Lrlot2Mes` +- **表含义**:接口:小料批次 -> MES +- **字段数量**:26 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Plan_id` | varchar(50) | YES | | | 计划ID(英文转译推测) | +| 2 | `Equip_code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Serial_Num` | int | YES | | | Serial Num(英文转译推测) | +| 4 | `Prd_date` | varchar(50) | YES | | | Prd日期(英文转译推测) | +| 5 | `Real_weight` | numeric(9,0) | YES | | | 实际重量(英文转译推测) | +| 6 | `Real_Error` | numeric(9,0) | YES | | | Real错误(英文转译推测) | +| 7 | `Waste_Time` | int | YES | | | Waste时间(英文转译推测) | +| 8 | `WarnIng_Sgn` | int | YES | | | Warn Ing Sgn(英文转译推测) | +| 9 | `Net_Weight` | numeric(9,0) | YES | | | 净重(英文转译推测) | +| 10 | `Group_BarCode` | varchar(50) | YES | | | 组条码(英文转译推测) | +| 11 | `Lot_BarCode` | varchar(50) | YES | | | 批次条码(英文转译推测) | +| 12 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 13 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 14 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | +| 15 | `BG_SetTemp` | int | YES | | | BGSet温度(英文转译推测) | +| 16 | `BG_RealTemp` | int | YES | | | BGReal温度(英文转译推测) | +| 17 | `BG_SetPress` | int | YES | | | BG Set Press(英文转译推测) | +| 18 | `BG_RealPress` | int | YES | | | BG Real Press(英文转译推测) | +| 19 | `BG_SetTime` | int | YES | | | BGSet时间(英文转译推测) | +| 20 | `BG_RealTime` | int | YES | | | BGReal时间(英文转译推测) | +| 21 | `BW_SetTemp` | int | YES | | | BWSet温度(英文转译推测) | +| 22 | `BW_RealTemp` | int | YES | | | BWReal温度(英文转译推测) | +| 23 | `BW_SetPress` | int | YES | | | BW Set Press(英文转译推测) | +| 24 | `BW_RealPress` | int | YES | | | BW Real Press(英文转译推测) | +| 25 | `BW_SetTime` | int | YES | | | BWSet时间(英文转译推测) | +| 26 | `BW_RealTime` | int | YES | | | BWReal时间(英文转译推测) | + +--- + +## 1.8 表:IF_LrPlan2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_LrPlan2Mes` +- **表含义**:接口:小料计划 -> MES +- **字段数量**:20 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Plan_Id` | varchar(50) | NO | 是 | | 计划ID(英文转译推测) | +| 2 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Plan_Serial` | int | YES | | | 计划Serial(英文转译推测) | +| 4 | `Recipe_ID` | varchar(50) | YES | | | 配方ID(英文转译推测) | +| 5 | `Recipe_Code` | varchar(50) | YES | | | 配方编码(英文转译推测) | +| 6 | `Recipe_Name` | varchar(50) | YES | | | 配方名称(英文转译推测) | +| 7 | `Version` | varchar(50) | YES | | | 版本(英文转译推测) | +| 8 | `Mixer_Line` | varchar(50) | YES | | | Mixer行(英文转译推测) | +| 9 | `Shift_Id` | varchar(10) | YES | | | 班次ID(英文转译推测) | +| 10 | `Plan_Num` | int | YES | | | 计划Num(英文转译推测) | +| 11 | `real_num` | int | YES | | | real num(英文转译推测) | +| 12 | `Start_Date` | varchar(50) | YES | | | 开始日期(英文转译推测) | +| 13 | `End_Date` | varchar(50) | YES | | | 结束日期(英文转译推测) | +| 14 | `Weight_Man` | varchar(50) | YES | | | 重量Man(英文转译推测) | +| 15 | `Plan_Batch` | varchar(50) | YES | | | 计划批次(英文转译推测) | +| 16 | `Plan_State` | int | YES | | | 计划状态(英文转译推测) | +| 17 | `Plan_Date` | varchar(50) | YES | | | 计划日期(英文转译推测) | +| 18 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 19 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 20 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.9 表:IF_LrPlanGroup2MES + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_LrPlanGroup2MES` +- **表含义**:接口:小料计划组 -> MES +- **字段数量**:16 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `ID` | varchar(50) | NO | 是 | | ID(英文转译推测) | +| 2 | `Plan_Id` | varchar(50) | YES | | | 计划ID(英文转译推测) | +| 3 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 4 | `Recipe_Code` | varchar(50) | YES | | | 配方编码(英文转译推测) | +| 5 | `Recipe_Name` | varchar(50) | YES | | | 配方名称(英文转译推测) | +| 6 | `Total_weight` | numeric(9,3) | YES | | | 总重量(英文转译推测) | +| 7 | `Total_Error` | numeric(9,3) | YES | | | 合计错误(英文转译推测) | +| 8 | `TrolleyBags` | int | YES | | | Trolley Bags(英文转译推测) | +| 9 | `TrolleyNumber` | int | YES | | | Trolley编号(英文转译推测) | +| 10 | `StartNum` | int | YES | | | 开始Num(英文转译推测) | +| 11 | `EndNum` | int | YES | | | 结束Num(英文转译推测) | +| 12 | `Prd_date` | varchar(50) | YES | | | Prd日期(英文转译推测) | +| 13 | `Group_BarCode` | varchar(50) | YES | | | 组条码(英文转译推测) | +| 14 | `Write_Time` | varchar(50) | YES | | | 写入时间(英文转译推测) | +| 15 | `Read_Time` | varchar(50) | YES | | | 读取时间(英文转译推测) | +| 16 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.10 表:IF_LrRecipe2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_LrRecipe2Mes` +- **表含义**:接口:小料配方 -> MES +- **字段数量**:13 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Plan_id` | varchar(50) | NO | 是 | | 计划ID(英文转译推测) | +| 2 | `Equip_code` | varchar(50) | NO | 是 | | 设备编码(英文转译推测) | +| 3 | `Weight_ID` | int | NO | 是 | | 重量ID(英文转译推测) | +| 4 | `Material_Code` | varchar(50) | YES | | | 物料编码(英文转译推测) | +| 5 | `Material_Name` | varchar(50) | YES | | | 物料名称(英文转译推测) | +| 6 | `Set_Weight` | numeric(9,4) | YES | | | 设定重量(英文转译推测) | +| 7 | `Set_Error` | numeric(9,4) | YES | | | Set错误(英文转译推测) | +| 8 | `CPK_Error` | numeric(9,4) | YES | | | CPK错误(英文转译推测) | +| 9 | `Batch_number` | varchar(50) | YES | | | 批次号(英文转译推测) | +| 10 | `Actual_Mater` | varchar(50) | YES | | | Actual物料(英文转译推测) | +| 11 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 12 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 13 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.11 表:IF_LrWeigh2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_LrWeigh2Mes` +- **表含义**:接口:小料称重 -> MES +- **字段数量**:15 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Plan_id` | varchar(50) | YES | | | 计划ID(英文转译推测) | +| 2 | `Equip_code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Serial_Num` | int | YES | | | Serial Num(英文转译推测) | +| 4 | `Weight_ID` | int | YES | | | 重量ID(英文转译推测) | +| 5 | `Material_Code` | varchar(50) | YES | | | 物料编码(英文转译推测) | +| 6 | `Set_Weight` | numeric(9,4) | YES | | | 设定重量(英文转译推测) | +| 7 | `Set_Error` | numeric(9,4) | YES | | | Set错误(英文转译推测) | +| 8 | `Real_Weight` | numeric(9,4) | YES | | | 实际重量(英文转译推测) | +| 9 | `Real_Error` | numeric(9,4) | YES | | | Real错误(英文转译推测) | +| 10 | `Warning_Sign` | int | YES | | | Warning Sign(英文转译推测) | +| 11 | `Batch_Number` | varchar(50) | YES | | | 批次号(英文转译推测) | +| 12 | `Recipe_code` | varchar(50) | YES | | | 配方编码(英文转译推测) | +| 13 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 14 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 15 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.12 表:IF_MaterialBatchNumber2CWSS + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_MaterialBatchNumber2CWSS` +- **表含义**:接口:物料批次号 -> CWSS +- **字段数量**:13 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `ID` | varchar(50) | NO | 是 | | ID(英文转译推测) | +| 2 | `Batch_Number` | varchar(50) | YES | | | 批次号(英文转译推测) | +| 3 | `Material_ID` | varchar(50) | YES | | | 物料ID(英文转译推测) | +| 4 | `Material_Name` | varchar(50) | YES | | | 物料名称(英文转译推测) | +| 5 | `Material_Specifica` | varchar(50) | YES | | | 物料Specifica(英文转译推测) | +| 6 | `Qty` | numeric(18,4) | YES | | | 数量(英文转译推测) | +| 7 | `ProductDate` | datetime | YES | | | Product日期(英文转译推测) | +| 8 | `ExpiryDate` | datetime | YES | | | Expiry日期(英文转译推测) | +| 9 | `Unit` | varchar(10) | YES | | | 单位(英文转译推测) | +| 10 | `ChukuId` | varchar(60) | YES | | | Chuku Id(英文转译推测) | +| 11 | `write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 12 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 13 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.13 表:IF_MESShift2CWSS + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_MESShift2CWSS` +- **表含义**:接口:MES班次 -> CWSS +- **字段数量**:6 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Equip_code` | varchar(20) | YES | | | 设备编码(英文转译推测) | +| 2 | `ShiftDate` | varchar(20) | YES | | | 班次日期(英文转译推测) | +| 3 | `ShiftID` | int | YES | | | 班次ID(英文转译推测) | +| 4 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 5 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 6 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.14 表:IF_PmtBin2CWSS + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_PmtBin2CWSS` +- **表含义**:接口:炭黑/粉料仓位 -> CWSS +- **字段数量**:8 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 2 | `Bin_Serial` | int | YES | | | 仓位Serial(英文转译推测) | +| 3 | `Material_ID` | varchar(50) | YES | | | 物料ID(英文转译推测) | +| 4 | `ID` | varchar(50) | YES | | | ID(英文转译推测) | +| 5 | `Bin_UseFlag` | bit | YES | | | 仓位使用标志(英文转译推测) | +| 6 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 7 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 8 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.15 表:IF_PmtBin2MES + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_PmtBin2MES` +- **表含义**:接口:炭黑/粉料仓位 -> MES +- **字段数量**:7 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Equip_Code` | varchar(50) | NO | 是 | | 设备编码(英文转译推测) | +| 2 | `Bin_Serial` | int | NO | 是 | | 仓位Serial(英文转译推测) | +| 3 | `Material_ID` | varchar(50) | YES | | | 物料ID(英文转译推测) | +| 4 | `Bin_UseFlag` | varchar(20) | YES | | | 仓位使用标志(英文转译推测) | +| 5 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 6 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 7 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.16 表:IF_PmtMaterial2CWSS + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_PmtMaterial2CWSS` +- **表含义**:接口:炭黑/粉料物料 -> CWSS +- **字段数量**:7 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `ID` | varchar(50) | YES | | | ID(英文转译推测) | +| 2 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Material_code` | varchar(50) | YES | | | 物料编码(英文转译推测) | +| 4 | `Material_name` | varchar(50) | YES | | | 物料名称(英文转译推测) | +| 5 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 6 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 7 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.17 表:IF_PmtRecipe2CWSS + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_PmtRecipe2CWSS` +- **表含义**:接口:炭黑/粉料配方 -> CWSS +- **字段数量**:17 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Id` | varchar(50) | YES | | | ID(英文转译推测) | +| 2 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Recipe_Code` | varchar(50) | YES | | | 配方编码(英文转译推测) | +| 4 | `Version` | varchar(50) | YES | | | 版本(英文转译推测) | +| 5 | `Recipe_Name` | varchar(50) | YES | | | 配方名称(英文转译推测) | +| 6 | `Mixer_line` | varchar(50) | YES | | | Mixer行(英文转译推测) | +| 7 | `Recipe_Verify` | int | YES | | | 配方版本ify(英文转译推测) | +| 8 | `Total_Weight` | numeric(12,4) | YES | | | 总重量(英文转译推测) | +| 9 | `Total_Error` | numeric(12,4) | YES | | | 合计错误(英文转译推测) | +| 10 | `End_datetime` | varchar(19) | YES | | | 结束日期时间(英文转译推测) | +| 11 | `Remark` | varchar(200) | YES | | | 备注(英文转译推测) | +| 12 | `GroupBags` | int | YES | | | 组Bags(英文转译推测) | +| 13 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 14 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 15 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | +| 16 | `Validity` | int | YES | | | Validity(英文转译推测) | +| 17 | `BagWeight` | int | YES | | | Bag重量(英文转译推测) | + +--- + +## 1.18 表:IF_Pmtweigh2CWSS + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_Pmtweigh2CWSS` +- **表含义**:接口:炭黑/粉料称重 -> CWSS +- **字段数量**:10 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Id` | varchar(50) | YES | | | ID(英文转译推测) | +| 2 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Recipe_ID` | varchar(50) | YES | | | 配方ID(英文转译推测) | +| 4 | `Weight_Id` | int | YES | | | 重量ID(英文转译推测) | +| 5 | `Material_ID` | varchar(50) | YES | | | 物料ID(英文转译推测) | +| 6 | `Set_Weight` | numeric(9,3) | YES | | | 设定重量(英文转译推测) | +| 7 | `Set_Error` | numeric(9,3) | YES | | | Set错误(英文转译推测) | +| 8 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 9 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 10 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.19 表:IF_RtPlan2CWSS + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_RtPlan2CWSS` +- **表含义**:接口:生胶计划 -> CWSS +- **字段数量**:18 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Plan_Id` | varchar(50) | YES | | | 计划ID(英文转译推测) | +| 2 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Plan_Serial` | int | YES | | | 计划Serial(英文转译推测) | +| 4 | `Recipe_ID` | varchar(50) | YES | | | 配方ID(英文转译推测) | +| 5 | `Recipe_Code` | varchar(50) | YES | | | 配方编码(英文转译推测) | +| 6 | `Recipe_Name` | varchar(50) | YES | | | 配方名称(英文转译推测) | +| 7 | `Version` | varchar(50) | YES | | | 版本(英文转译推测) | +| 8 | `Mixer_Line` | varchar(50) | YES | | | Mixer行(英文转译推测) | +| 9 | `Shift_Id` | varchar(10) | YES | | | 班次ID(英文转译推测) | +| 10 | `Plan_Num` | int | YES | | | 计划Num(英文转译推测) | +| 11 | `Start_Date` | varchar(50) | YES | | | 开始日期(英文转译推测) | +| 12 | `End_Date` | varchar(50) | YES | | | 结束日期(英文转译推测) | +| 13 | `Plan_Batch` | varchar(50) | YES | | | 计划批次(英文转译推测) | +| 14 | `Plan_State` | int | YES | | | 计划状态(英文转译推测) | +| 15 | `Plan_Date` | varchar(50) | YES | | | 计划日期(英文转译推测) | +| 16 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 17 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 18 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.20 表:IF_RtPlan2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`IF_RtPlan2Mes` +- **表含义**:接口:生胶计划 -> MES +- **字段数量**:21 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Plan_Id` | varchar(50) | NO | 是 | | 计划ID(英文转译推测) | +| 2 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Plan_Serial` | int | YES | | | 计划Serial(英文转译推测) | +| 4 | `Recipe_ID` | varchar(50) | YES | | | 配方ID(英文转译推测) | +| 5 | `Recipe_Code` | varchar(50) | YES | | | 配方编码(英文转译推测) | +| 6 | `Recipe_Name` | varchar(50) | YES | | | 配方名称(英文转译推测) | +| 7 | `Version` | varchar(50) | YES | | | 版本(英文转译推测) | +| 8 | `Mixer_Line` | varchar(50) | YES | | | Mixer行(英文转译推测) | +| 9 | `Shift_Id` | varchar(10) | YES | | | 班次ID(英文转译推测) | +| 10 | `Plan_Num` | int | YES | | | 计划Num(英文转译推测) | +| 11 | `real_num` | int | YES | | | real num(英文转译推测) | +| 12 | `Start_Date` | varchar(50) | YES | | | 开始日期(英文转译推测) | +| 13 | `End_Date` | varchar(50) | YES | | | 结束日期(英文转译推测) | +| 14 | `Plan_Batch` | varchar(50) | YES | | | 计划批次(英文转译推测) | +| 15 | `Plan_State` | int | YES | | | 计划状态(英文转译推测) | +| 16 | `Plan_Date` | varchar(50) | YES | | | 计划日期(英文转译推测) | +| 17 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 18 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 19 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | +| 20 | `Weight_Man` | varchar(50) | YES | | | 重量Man(英文转译推测) | +| 21 | `Stock_Man` | nvarchar(50) | YES | | | Stock Man(英文转译推测) | + +--- + +## 1.21 表:MCCToMES_PptBarScan + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCCToMES_PptBarScan` +- **表含义**:MCC->MES:挤出/开炼条码扫描 +- **字段数量**:19 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | NO | 是 | | GUID(英文转译推测) | +| 2 | `SaveTime` | varchar(20) | YES | | | Save时间(英文转译推测) | +| 3 | `Barcode` | varchar(50) | YES | | | 条码(英文转译推测) | +| 4 | `EquipID` | int | YES | | | 设备ID(英文转译推测) | +| 5 | `Plan_ID` | varchar(50) | YES | | | 计划ID(英文转译推测) | +| 6 | `RpCode` | varchar(50) | YES | | | Rp编码(英文转译推测) | +| 7 | `RpName` | varchar(50) | YES | | | Rp名称(英文转译推测) | +| 8 | `PlanSet` | int | YES | | | 计划Set(英文转译推测) | +| 9 | `PlanComplete` | int | YES | | | 计划完成(英文转译推测) | +| 10 | `ScaleComplete` | int | YES | | | 秤完成(英文转译推测) | +| 11 | `PlanShift` | int | YES | | | 计划班次(英文转译推测) | +| 12 | `MaterCode` | varchar(50) | YES | | | 物料编码(英文转译推测) | +| 13 | `MaterName` | varchar(50) | YES | | | 物料名称(英文转译推测) | +| 14 | `MaterTypeID` | int | YES | | | 物料类型ID(英文转译推测) | +| 15 | `MaterType` | varchar(20) | YES | | | 物料类型(英文转译推测) | +| 16 | `Mater_Barcode` | varchar(50) | YES | | | 物料条码(英文转译推测) | +| 17 | `BarScanResult` | int | YES | | | Bar扫描结果(英文转译推测) | +| 18 | `Oper` | varchar(50) | YES | | | Oper(英文转译推测) | +| 19 | `Flg` | char(1) | YES | | | Flg(英文转译推测) | + +--- + +## 1.22 表:MCSToMES_Act_Mill + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_Act_Mill` +- **表含义**:MCS->MES:开炼机动作 +- **字段数量**:9 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | NO | | | GUID(英文转译推测) | +| 2 | `act_addr` | int | YES | | | 动作addr(英文转译推测) | +| 3 | `act_name` | varchar(50) | YES | | | 动作名称(英文转译推测) | +| 4 | `act_name_en` | varchar(50) | YES | | | 动作名称en(英文转译推测) | +| 5 | `act_memo` | varchar(20) | YES | | | 动作备注(英文转译推测) | +| 6 | `act_Repaddr` | int | YES | | | 动作Repaddr(英文转译推测) | +| 7 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 8 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 9 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 1.23 表:MCSToMES_BinToMater + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_BinToMater` +- **表含义**:MCS->MES:仓位与物料对应关系 +- **字段数量**:14 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 3 | `EquipName` | varchar(20) | YES | | | 设备名称(英文转译推测) | +| 4 | `EquipType` | varchar(10) | NO | 是 | | 设备类型(英文转译推测) | +| 5 | `ScaleNum` | int | NO | 是 | | 秤Num(英文转译推测) | +| 6 | `ScaleClass` | varchar(20) | YES | | | 秤Class(英文转译推测) | +| 7 | `ScaleName` | varchar(20) | YES | | | 秤名称(英文转译推测) | +| 8 | `BinNo` | int | NO | 是 | | 仓号(英文转译推测) | +| 9 | `MatCode` | varchar(30) | YES | | | 物料编码(英文转译推测) | +| 10 | `MatName` | varchar(50) | YES | | | 物料名称(英文转译推测) | +| 11 | `UseYN` | varchar(1) | YES | | | Use YN(英文转译推测) | +| 12 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 13 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 14 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | + +--- + +## 1.24 表:MCSToMES_CurrEquipState + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_CurrEquipState` +- **表含义**:MCS->MES:当前设备状态 +- **字段数量**:13 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | NO | 是 | | GUID(英文转译推测) | +| 2 | `EquipID` | int | YES | | | 设备ID(英文转译推测) | +| 3 | `EquipName` | varchar(10) | YES | | | 设备名称(英文转译推测) | +| 4 | `EquipType` | varchar(10) | YES | | | 设备类型(英文转译推测) | +| 5 | `SaveTime` | varchar(20) | YES | | | Save时间(英文转译推测) | +| 6 | `RpName` | varchar(40) | YES | | | Rp名称(英文转译推测) | +| 7 | `SetNum` | int | YES | | | Set Num(英文转译推测) | +| 8 | `Serial` | int | YES | | | Serial(英文转译推测) | +| 9 | `MixSpeed` | decimal(18,3) | YES | | | 密炼速度(英文转译推测) | +| 10 | `MixPower` | decimal(10,3) | YES | | | 密炼功率(英文转译推测) | +| 11 | `MixEngery` | decimal(18,3) | YES | | | 密炼Engery(英文转译推测) | +| 12 | `MixTime` | int | YES | | | 密炼时间(英文转译推测) | +| 13 | `MES_Flag` | int | YES | | (0) | MES标志(英文转译推测) | + +--- + +## 1.25 表:MCSToMES_CurrVarData_Convey + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_CurrVarData_Convey` +- **表含义**:MCS->MES:输送线过程变量 +- **字段数量**:7 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | NO | 是 | | GUID(英文转译推测) | +| 2 | `VarName` | varchar(50) | YES | | | Var名称(英文转译推测) | +| 3 | `DataName` | varchar(50) | YES | | | 数据名称(英文转译推测) | +| 4 | `DataValue` | decimal(18,3) | YES | | | 数据数值(英文转译推测) | +| 5 | `CreateTime` | varchar(19) | YES | | | 创建时间(英文转译推测) | +| 6 | `UpdateTime` | varchar(19) | YES | | | 更新时间(英文转译推测) | +| 7 | `MESReadTime` | varchar(19) | YES | | | MES读取时间(英文转译推测) | + +--- + +## 1.26 表:MCSToMES_MixAct + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixAct` +- **表含义**:MCS->MES:密炼动作记录 +- **字段数量**:8 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 2 | `EquipName` | varchar(10) | YES | | | 设备名称(英文转译推测) | +| 3 | `EquipType` | varchar(10) | NO | 是 | | 设备类型(英文转译推测) | +| 4 | `MixActAddress` | int | NO | 是 | | 动作地址 | +| 5 | `MixActName` | varchar(30) | YES | | | 动作名称 | +| 6 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 7 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 8 | `RW_Flag` | int | YES | | (0) | RW标志(英文转译推测) | + +--- + +## 1.27 表:MCSToMES_MixAlarm + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixAlarm` +- **表含义**:MCS->MES:密炼报警 +- **字段数量**:12 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | NO | 是 | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | | | 机台编号 | +| 3 | `EquipName` | varchar(10) | NO | | | 机台名称 | +| 4 | `EquipType` | varchar(10) | NO | | | 机台类型 | +| 5 | `SaveTime` | varchar(19) | YES | | | Save时间(英文转译推测) | +| 6 | `EndTime` | varchar(19) | YES | | | 结束时间(英文转译推测) | +| 7 | `Barcode` | varchar(30) | NO | | | Barcode | +| 8 | `AlmCode` | varchar(6) | YES | | | 报警代码 | +| 9 | `AlarmInf` | varchar(50) | YES | | | 报警内容 | +| 10 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 11 | `ReadTime` | datetime | YES | | (0) | 读取时间(英文转译推测) | +| 12 | `MES_Flag` | int | YES | | (0) | MES标志(英文转译推测) | + +--- + +## 1.28 表:MCSToMES_MixBatch + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixBatch` +- **表含义**:MCS->MES:密炼批次 +- **字段数量**:41 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 机台编号 | +| 3 | `EquipName` | varchar(10) | YES | | | 机台名称 | +| 4 | `EquipType` | varchar(10) | YES | | | 机台类型 | +| 5 | `Barcode` | varchar(30) | NO | 是 | | 计划编号+车次 | +| 6 | `RecipCode` | varchar(30) | YES | | | 配方代码 | +| 7 | `RecipName` | varchar(30) | YES | | | 配方名称 | +| 8 | `MaterCode` | varchar(40) | YES | | | 物料编码(英文转译推测) | +| 9 | `MaterName` | varchar(80) | YES | | | 物料名称(英文转译推测) | +| 10 | `SaveDate` | varchar(10) | YES | | | 保存日期 | +| 11 | `SaveDateTime` | varchar(20) | YES | | | 保存时间 | +| 12 | `ShiftId` | varchar(1) | YES | | | 班次;1:Night 2: Morning 3:Noon | +| 13 | `ShiftClass` | varchar(1) | YES | | | 班组;1:A 2:B 3:C 4:D | +| 14 | `PlanID` | varchar(20) | YES | | | 计划编号 | +| 15 | `SetNum` | int | YES | | | 设定车次 | +| 16 | `StartTim` | varchar(20) | YES | | | 开始时间 | +| 17 | `EndTim` | varchar(20) | YES | | | 结束时间 | +| 18 | `BatchNum` | int | YES | | | 当前车次 | +| 19 | `MixMode` | int | YES | | | 密炼模式1:遥控自动;2:遥控手动;3:本控 | +| 20 | `BatchCycleTim` | int | YES | | | 密炼循环时间(预留) | +| 21 | `CurTim` | int | YES | | | 密炼时间 | +| 22 | `MixTim` | int | YES | | | 预留 | +| 23 | `UsefulMixTim` | int | YES | | | 有效时间 | +| 24 | `IntervalTime` | int | YES | | | 间隔时间 | +| 25 | `DiscTemp` | decimal(18,3) | YES | | | 排胶温度 | +| 26 | `DiscEnergy` | decimal(18,3) | YES | | | 排胶能量 | +| 27 | `DiscTime` | int | YES | | | 排胶时间 | +| 28 | `DiscPower` | int | YES | | | 排胶功率 | +| 29 | `EmgyDiscFlag` | int | YES | | | 排胶方式;0:正常;1:超时;2:超温;3:超能量 | +| 30 | `TCU1Temp` | decimal(18,3) | YES | | | 三区温度1(预留) | +| 31 | `TCU2Temp` | decimal(18,3) | YES | | | 三区温度2(预留) | +| 32 | `TCU3Temp` | decimal(18,3) | YES | | | 三区温度3(预留) | +| 33 | `TCU4Temp` | decimal(18,3) | YES | | | 三区温度4(预留) | +| 34 | `TCUTemp` | decimal(18,3) | YES | | | 三区温度(预留) | +| 35 | `BatchWei` | decimal(18,3) | YES | | | 批次Wei(英文转译推测) | +| 36 | `oper` | varchar(20) | YES | | | oper(英文转译推测) | +| 37 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 38 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 39 | `MES_Flag` | int | YES | | (0) | MES标志(英文转译推测) | +| 40 | `WEIGHT` | decimal(18,3) | YES | | | 重量(英文转译推测) | +| 41 | `MoCode` | varchar(40) | YES | | | Mo编码(英文转译推测) | + +--- + +## 1.29 表:MCSToMES_MixCon + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixCon` +- **表含义**:MCS->MES:密炼消耗/配料明细 +- **字段数量**:8 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 2 | `EquipName` | varchar(10) | YES | | | 设备名称(英文转译推测) | +| 3 | `EquipType` | varchar(10) | NO | 是 | | 设备类型(英文转译推测) | +| 4 | `MixConAddress` | int | NO | 是 | | 密炼ConAddress(英文转译推测) | +| 5 | `MixConName` | varchar(30) | YES | | | 密炼Con名称(英文转译推测) | +| 6 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 7 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 8 | `RW_Flag` | int | YES | | (0) | RW标志(英文转译推测) | + +--- + +## 1.30 表:MCSToMES_MixCurve + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixCurve` +- **表含义**:MCS->MES:密炼曲线数据 +- **字段数量**:9 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 3 | `EquipName` | varchar(10) | YES | | | 设备名称(英文转译推测) | +| 4 | `EquipType` | varchar(10) | NO | 是 | | 设备类型(英文转译推测) | +| 5 | `Barcode` | varchar(30) | NO | 是 | | 条码(英文转译推测) | +| 6 | `CurveData` | ntext(1073741823) | YES | | | Curve数据(英文转译推测) | +| 7 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 8 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 9 | `MES_Flag` | int | YES | | (0) | MES标志(英文转译推测) | + +--- + +## 1.31 表:MCSToMES_mixdata_Mill + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_mixdata_Mill` +- **表含义**:MCS->MES:开炼机混炼数据 +- **字段数量**:14 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Barcode` | varchar(40) | YES | | | 条码(英文转译推测) | +| 2 | `Serial_id` | int | YES | | | Serial id(英文转译推测) | +| 3 | `Equip_code` | varchar(20) | YES | | | 设备编码(英文转译推测) | +| 4 | `ID` | int | YES | | | ID(英文转译推测) | +| 5 | `StepActAddress` | int | YES | | | 步骤动作Address(英文转译推测) | +| 6 | `StepMixTime` | int | YES | | | 步骤密炼时间(英文转译推测) | +| 7 | `StepMixCoolSpeed` | numeric(18,3) | YES | | | 步骤密炼Cool速度(英文转译推测) | +| 8 | `StepOpenMixSpeed` | numeric(18,3) | YES | | | 步骤Open密炼速度(英文转译推测) | +| 9 | `StepRollor` | numeric(18,3) | YES | | | 步骤Rollor(英文转译推测) | +| 10 | `StepWaterTemp` | numeric(18,3) | YES | | | 步骤Water温度(英文转译推测) | +| 11 | `StepRubTemp` | numeric(18,3) | YES | | | 步骤Rub温度(英文转译推测) | +| 12 | `StepPower` | numeric(18,3) | YES | | | 步骤功率(英文转译推测) | +| 13 | `WaterIn` | numeric(18,3) | YES | | | Water In(英文转译推测) | +| 14 | `Remarks` | varchar(50) | YES | | | 备注s(英文转译推测) | + +--- + +## 1.32 表:MCSToMES_MixExePlan + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixExePlan` +- **表含义**:MCS->MES:密炼执行计划回传 +- **字段数量**:25 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `PlanID` | varchar(20) | NO | 是 | | 计划编号 | +| 3 | `PlanSource` | varchar(1) | NO | 是 | | 计划来源(英文转译推测) | +| 4 | `EquipID` | int | NO | 是 | | 机台编号 | +| 5 | `EquipName` | varchar(10) | YES | | | 机台名称 | +| 6 | `EquipType` | varchar(10) | YES | | | 机台类型CWS:小料;MCS:上辅机 | +| 7 | `PlanDate` | varchar(10) | YES | | | 计划日期 | +| 8 | `ShiftID` | varchar(1) | YES | | | 班次1:Night 2: Morning 3 | +| 9 | `ShiftClass` | varchar(1) | YES | | | 班组1:A 2:B 3:C 4:D | +| 10 | `WorkOrder` | int | YES | | | 计划顺序 | +| 11 | `RecipCode` | varchar(40) | YES | | | 配方代码 | +| 12 | `RecipName` | varchar(40) | YES | | | 配方名称 | +| 13 | `SetNum` | int | YES | | | 设定车次 | +| 14 | `DoneNum` | int | YES | | | 完成车次 | +| 15 | `PlanState` | int | YES | | | 计划状态2:运行;4终止;5:完成 | +| 16 | `PlanStateChange` | int | YES | | | 计划状态有变化 | +| 17 | `StartTime` | datetime | YES | | | 开始时间(英文转译推测) | +| 18 | `EndTime` | datetime | YES | | | 结束时间(英文转译推测) | +| 19 | `WriteTime` | datetime | YES | | | 写入时间 | +| 20 | `ReadTime` | datetime | YES | | | 读取时间 | +| 21 | `MES_Flag` | int | YES | | (0) | 交互标识 | +| 22 | `Remark` | varchar(50) | YES | | | 备注 | +| 23 | `MaterCode` | varchar(50) | YES | | | 物料编码(英文转译推测) | +| 24 | `MaterName` | varchar(50) | YES | | | 物料名称(英文转译推测) | +| 25 | `UploadRunFlag` | int | YES | | ((0)) | UploadRun标志(英文转译推测) | + +--- + +## 1.33 表:MCSToMES_MixStep + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixStep` +- **表含义**:MCS->MES:密炼步骤执行记录 +- **字段数量**:35 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 机台编号 | +| 3 | `EquipName` | varchar(10) | YES | | | 设备名称(英文转译推测) | +| 4 | `EquipType` | varchar(10) | NO | 是 | | 机台类型 | +| 5 | `Barcode` | varchar(30) | NO | 是 | | 条码(英文转译推测) | +| 6 | `SaveTime` | varchar(20) | YES | | | 保存时间 | +| 7 | `MixID` | int | NO | 是 | | 密炼步序 | +| 8 | `Cond` | int | YES | | | 条件地址 | +| 9 | `CondName` | varchar(40) | YES | | | 条件名称 | +| 10 | `Tim` | int | YES | | | 设定时间(预留) | +| 11 | `TimProtect` | int | YES | | | 时间保护(预留) | +| 12 | `TimAct` | int | YES | | | 实际时间 | +| 13 | `Tempe` | decimal(18,3) | YES | | | 设定温度(预留) | +| 14 | `TempProtect` | decimal(18,3) | YES | | | 温度保护(预留) | +| 15 | `TempAct` | decimal(18,3) | YES | | | 温度实际 | +| 16 | `Power` | decimal(18,3) | YES | | | 设定功率(预留) | +| 17 | `PowerProtect` | decimal(18,3) | YES | | | 功率保护(预留) | +| 18 | `PowerAct` | decimal(18,3) | YES | | | 实际功率 | +| 19 | `Energy` | decimal(18,3) | YES | | | 设定能量(预留) | +| 20 | `EnergyProtect` | decimal(18,3) | YES | | | 能量保护(预留) | +| 21 | `EnergyAct` | decimal(18,3) | YES | | | 实际能量 | +| 22 | `Act` | int | YES | | | 动作地址 | +| 23 | `ActName` | varchar(40) | YES | | | 动作名称 | +| 24 | `RamPress` | decimal(18,3) | YES | | | 设定压力(预留) | +| 25 | `RamPressAct` | decimal(18,3) | YES | | | 实际压力 | +| 26 | `RotorSpd` | decimal(18,3) | YES | | | 转速设定(预留) | +| 27 | `RotorSpdAct` | decimal(18,3) | YES | | | 实际转速 | +| 28 | `RamPos` | decimal(18,3) | YES | | | 栓位置设定(预留) | +| 29 | `RamPosAct` | decimal(18,3) | YES | | | 实际栓位置 | +| 30 | `RollGap` | decimal(18,3) | YES | | | 辊距设定(预留) | +| 31 | `RollGapAct` | decimal(18,3) | YES | | | 实际辊距(预留) | +| 32 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 33 | `CtrlMode` | int | YES | | | Ctrl模式(英文转译推测) | +| 34 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 35 | `MES_Flag` | int | YES | | (0) | MES标志(英文转译推测) | + +--- + +## 1.34 表:MCSToMES_MixWeight + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixWeight` +- **表含义**:MCS->MES:密炼称重记录 +- **字段数量**:26 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | NO | 是 | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | | | 机台编号 | +| 3 | `EquipName` | varchar(10) | YES | | | 机台名称 | +| 4 | `EquipType` | varchar(50) | NO | | | 机台类型 | +| 5 | `Barcode` | varchar(30) | NO | | | 条码(英文转译推测) | +| 6 | `SaveTime` | varchar(20) | YES | | | 存储时间 | +| 7 | `MatCode` | varchar(30) | YES | | | 物料代码 | +| 8 | `MatName` | varchar(30) | YES | | | 物料名称 | +| 9 | `ScaleNum` | int | NO | | | 秤编号101:炭黑秤1;102:炭黑秤2;103:炭黑秤3;201:油料秤1;202:油料秤2;203:油料秤3 +301:胶料秤1;302:胶料秤2;401:小料秤1;402:小料秤2 | +| 10 | `BatchNum` | int | YES | | | 车次 | +| 11 | `Act` | int | YES | | | 动作(英文转译推测) | +| 12 | `Idx` | int | NO | | | 序号 | +| 13 | `ShiftNum` | int | YES | | | 第几批称量 | +| 14 | `SetWei` | decimal(18,3) | YES | | | 设定重量 | +| 15 | `SetTol` | decimal(18,3) | YES | | | 设定误差 | +| 16 | `ActWei` | decimal(18,3) | YES | | | 实际重量 | +| 17 | `ActTol` | decimal(18,3) | YES | | | 实际误差 | +| 18 | `StepTim` | int | YES | | | 步时间 | +| 19 | `StepMode` | int | YES | | | 步骤模式(英文转译推测) | +| 20 | `RecipeName` | varchar(30) | YES | | | 配方名称 | +| 21 | `PlanID` | varchar(20) | YES | | | 计划编号 | +| 22 | `SetBatchNum` | int | YES | | | 计划设定 | +| 23 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 24 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 25 | `MES_Flag` | int | YES | | ((0)) | MES标志(英文转译推测) | +| 26 | `MOCode` | varchar(40) | YES | | | MOCode(英文转译推测) | + +--- + +## 1.35 表:MCSToMES_MixWeiRelate + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixWeiRelate` +- **表含义**:MCS->MES:称重关联关系 +- **字段数量**:11 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | NO | 是 | | GUID(英文转译推测) | +| 2 | `Barcode` | varchar(40) | YES | | | 条码(英文转译推测) | +| 3 | `EquipID` | int | YES | | | 设备ID(英文转译推测) | +| 4 | `SaveTime` | varchar(20) | YES | | | Save时间(英文转译推测) | +| 5 | `ScaleType` | int | YES | | | 秤类型(英文转译推测) | +| 6 | `ScaleNum` | int | YES | | | 秤Num(英文转译推测) | +| 7 | `BatchNum` | int | YES | | | 批次Num(英文转译推测) | +| 8 | `ShiftNum` | int | YES | | | 班次Num(英文转译推测) | +| 9 | `FeedTim` | int | YES | | | 供料Tim(英文转译推测) | +| 10 | `PlanID` | varchar(30) | YES | | | 计划ID(英文转译推测) | +| 11 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | + +--- + +## 1.36 表:MCSToMES_Ppt_Log + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_Ppt_Log` +- **表含义**:MCS->MES:开炼/挤出日志 +- **字段数量**:9 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | YES | | | 设备ID(英文转译推测) | +| 3 | `EquipType` | varchar(10) | YES | | | 设备类型(英文转译推测) | +| 4 | `WorkType` | varchar(20) | YES | | | Work类型(英文转译推测) | +| 5 | `OperDest` | varchar(50) | YES | | | Oper Dest(英文转译推测) | +| 6 | `OccurrenTime` | varchar(20) | YES | | | Occurren时间(英文转译推测) | +| 7 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 8 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 9 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | + +--- + +## 1.37 表:MCSToMES_Ppt_Shutdown + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_Ppt_Shutdown` +- **表含义**:MCS->MES:停机记录 +- **字段数量**:12 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | YES | | | 设备ID(英文转译推测) | +| 3 | `EquipType` | varchar(10) | YES | | | 设备类型(英文转译推测) | +| 4 | `ShutdownType` | varchar(50) | YES | | | 停机类型(英文转译推测) | +| 5 | `StartTime` | varchar(10) | YES | | | 开始时间(英文转译推测) | +| 6 | `EndTime` | varchar(10) | YES | | | 结束时间(英文转译推测) | +| 7 | `StopTimeSecond` | int | YES | | | Stop时间Second(英文转译推测) | +| 8 | `Memo` | varchar(50) | YES | | | 备注(英文转译推测) | +| 9 | `Auto` | int | YES | | | 自动(英文转译推测) | +| 10 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 11 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 12 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | + +--- + +## 1.38 表:MCSToMES_PptShiftConfig + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_PptShiftConfig` +- **表含义**:MCS->MES:开炼班次配置 +- **字段数量**:20 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 3 | `EquipName` | varchar(10) | YES | | | 设备名称(英文转译推测) | +| 4 | `EquipType` | varchar(10) | NO | 是 | | 设备类型(英文转译推测) | +| 5 | `Barcode` | varchar(30) | NO | 是 | | 条码(英文转译推测) | +| 6 | `PlanDate` | datetime | YES | | | 计划日期(英文转译推测) | +| 7 | `PlanID` | varchar(20) | NO | | | 计划ID(英文转译推测) | +| 8 | `ShiftID` | int | YES | | | 班次ID(英文转译推测) | +| 9 | `ClassID` | int | YES | | | Class ID(英文转译推测) | +| 10 | `RecipCode` | varchar(30) | YES | | | Recip编码(英文转译推测) | +| 11 | `RecipName` | varchar(30) | YES | | | Recip名称(英文转译推测) | +| 12 | `BarcodeStart` | int | NO | | | 条码开始(英文转译推测) | +| 13 | `BarcodeEnd` | int | YES | | | 条码结束(英文转译推测) | +| 14 | `TotalWeight` | decimal(18,3) | YES | | | 总重量(英文转译推测) | +| 15 | `RealWeight` | decimal(18,3) | YES | | | 实际重量(英文转译推测) | +| 16 | `Set_ShelfNum` | int | YES | | | Set Shelf Num(英文转译推测) | +| 17 | `ShelfNum` | int | YES | | | Shelf Num(英文转译推测) | +| 18 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 19 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 20 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | + +--- + +## 1.39 表:MCSToMES_RBWeight + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_RBWeight` +- **表含义**:MCS->MES:生胶称重 +- **字段数量**:15 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | NO | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | | | 机台编号 | +| 3 | `MatCode` | varchar(50) | NO | 是 | | 物料代码 | +| 4 | `MatName` | varchar(50) | YES | | | 物料名称 | +| 5 | `ScaleNum` | int | NO | | | 秤编号101:炭黑秤1;102:炭黑秤2;103:炭黑秤3;201:油料秤1;202:油料秤2;203:油料秤3 +301:胶料秤1;302:胶料秤2;401:小料秤1;402:小料秤2 | +| 6 | `SetBatchNum` | int | YES | | | 计划设定 | +| 7 | `BatchNum` | int | NO | 是 | | 车次 | +| 8 | `ActWei` | decimal(18,3) | YES | | | 实际重量 | +| 9 | `ActTol` | decimal(18,3) | YES | | | 实际误差 | +| 10 | `RecipeName` | varchar(30) | YES | | | 配方名称 | +| 11 | `PlanID` | varchar(20) | NO | 是 | | 计划编号 | +| 12 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 13 | `MES_Flag` | int | YES | | ((0)) | MES标志(英文转译推测) | +| 14 | `StartTim` | varchar(20) | YES | | | 开始时间 | +| 15 | `EndTim` | varchar(20) | YES | | | 结束时间 | + +--- + +## 1.40 表:MCSToMES_RepBatchoff + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_RepBatchoff` +- **表含义**:MCS->MES:排出/落盘回报 +- **字段数量**:30 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | NO | 是 | | GUID(英文转译推测) | +| 2 | `EquipID` | int | YES | | | 设备ID(英文转译推测) | +| 3 | `RpCode` | varchar(50) | YES | | | Rp编码(英文转译推测) | +| 4 | `PlanID` | varchar(40) | YES | | | 计划ID(英文转译推测) | +| 5 | `RFIDCode` | varchar(50) | YES | | | RFIDCode(英文转译推测) | +| 6 | `BOEquipName` | varchar(40) | YES | | | BOEquip名称(英文转译推测) | +| 7 | `RubberType` | int | YES | | | Rubber类型(英文转译推测) | +| 8 | `RubWeight` | decimal(18,3) | YES | | | Rub重量(英文转译推测) | +| 9 | `MinSaveTime` | int | YES | | | 最小Save时间(英文转译推测) | +| 10 | `MaxSaveTime` | int | YES | | | 最大Save时间(英文转译推测) | +| 11 | `ReRubberType` | int | YES | | | ReRubber类型(英文转译推测) | +| 12 | `ReRubberPersion` | int | YES | | | Re Rubber Persion(英文转译推测) | +| 13 | `RubberTrayState` | int | YES | | | RubberTray状态(英文转译推测) | +| 14 | `ReStartTime` | varchar(20) | YES | | | Re开始时间(英文转译推测) | +| 15 | `ReEndTime` | varchar(20) | YES | | | Re结束时间(英文转译推测) | +| 16 | `TrayCount` | int | YES | | | Tray数量(英文转译推测) | +| 17 | `StartSerial` | int | YES | | | 开始Serial(英文转译推测) | +| 18 | `EndSerial` | int | YES | | | 结束Serial(英文转译推测) | +| 19 | `ReRubberWeight` | decimal(18,3) | YES | | | ReRubber重量(英文转译推测) | +| 20 | `ReRubberLength` | decimal(18,3) | YES | | | Re Rubber Length(英文转译推测) | +| 21 | `ReRubberError` | decimal(18,3) | YES | | | ReRubber错误(英文转译推测) | +| 22 | `MDErrorCount` | int | YES | | | MDError数量(英文转译推测) | +| 23 | `SampleCount` | int | YES | | | Sample数量(英文转译推测) | +| 24 | `Re1Length` | decimal(18,3) | YES | | | Re 1 Length(英文转译推测) | +| 25 | `Re2Length` | decimal(18,3) | YES | | | Re 2 Length(英文转译推测) | +| 26 | `Re3Length` | decimal(18,3) | YES | | | Re 3 Length(英文转译推测) | +| 27 | `Re4Length` | decimal(18,3) | YES | | | Re 4 Length(英文转译推测) | +| 28 | `Re5Length` | decimal(18,3) | YES | | | Re 5 Length(英文转译推测) | +| 29 | `SaveTime` | varchar(20) | YES | | | Save时间(英文转译推测) | +| 30 | `MES_Flag` | int | YES | | ((0)) | MES标志(英文转译推测) | + +--- + +## 1.41 表:MCSToMES_Scale_Calibration + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MCSToMES_Scale_Calibration` +- **表含义**:MCS->MES:秤标定记录 +- **字段数量**:11 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `ScaleNum` | int | YES | | | 秤Num(英文转译推测) | +| 3 | `ScaleClass` | varchar(20) | YES | | | 秤Class(英文转译推测) | +| 4 | `ScaleName` | varchar(20) | YES | | | 秤名称(英文转译推测) | +| 5 | `SetValue` | numeric(8,3) | YES | | | Set数值(英文转译推测) | +| 6 | `RealValue` | numeric(8,3) | YES | | | Real数值(英文转译推测) | +| 7 | `ErrValue` | numeric(8,3) | YES | | | Err数值(英文转译推测) | +| 8 | `RealTime` | datetime | YES | | | Real时间(英文转译推测) | +| 9 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 10 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 11 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | + +--- + +## 1.42 表:MesDownVerificationStatusTab + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MesDownVerificationStatusTab` +- **表含义**:MES下传校验状态表 +- **字段数量**:11 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `uuid` | nvarchar(60) | NO | 是 | | 唯一标识(英文转译推测) | +| 2 | `Version` | bigint | YES | | | 版本(英文转译推测) | +| 3 | `DeviceId` | nvarchar(30) | YES | | | Device Id(英文转译推测) | +| 4 | `PositionId` | nvarchar(20) | NO | | | 1小料 2胶料 | +| 5 | `Status` | int | NO | | ((0)) | 0通过 1不通过 | +| 6 | `UpdateFlag` | int | NO | | ((0)) | MES写1,MCC获取后写9 | +| 7 | `MESDateTime` | datetime | YES | | | MES日期时间(英文转译推测) | +| 8 | `CSWDateTime` | datetime | YES | | | CSWDate时间(英文转译推测) | +| 9 | `Remark` | nvarchar(60) | YES | | | 备注(英文转译推测) | +| 10 | `Remark1` | nvarchar(60) | YES | | | 备注1(英文转译推测) | +| 11 | `Remark2` | nvarchar(60) | YES | | | 备注2(英文转译推测) | + +--- + +## 1.43 表:MESToMCS_BarCodeInfo + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MESToMCS_BarCodeInfo` +- **表含义**:MES->MCS:条码信息下发 +- **字段数量**:12 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(64) | YES | | | GUID(英文转译推测) | +| 2 | `BarCode` | varchar(32) | YES | | | 条码(英文转译推测) | +| 3 | `MatCode` | varchar(32) | YES | | | 物料编码(英文转译推测) | +| 4 | `MatName` | varchar(32) | YES | | | 物料名称(英文转译推测) | +| 5 | `MatCategory` | varchar(32) | YES | | | Mat Category(英文转译推测) | +| 6 | `MatSubcategory` | varchar(32) | YES | | | Mat Subcategory(英文转译推测) | +| 7 | `MatWeight` | numeric(18,2) | YES | | | Mat重量(英文转译推测) | +| 8 | `MatAmount` | numeric(18,2) | YES | | | Mat Amount(英文转译推测) | +| 9 | `IsOutStore` | int | YES | | | Is Out Store(英文转译推测) | +| 10 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 11 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 12 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | + +--- + +## 1.44 表:MESToMCS_Material + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Material` +- **表含义**:MES->MCS:物料主数据下发 +- **字段数量**:17 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 机台号 | +| 3 | `EquipType` | varchar(10) | YES | | | 机台类型,CWS:小料;MCS:上辅机; | +| 4 | `MatCode` | varchar(30) | NO | 是 | | 物料代码 | +| 5 | `MatName` | varchar(30) | YES | | | 物料名称 | +| 6 | `MatBarcode` | varchar(50) | YES | | | 物料条码扫描判断信息 | +| 7 | `MatTypeID` | int | YES | | | Mat类型ID(英文转译推测) | +| 8 | `MatType` | varchar(50) | YES | | | 物料类别 | +| 9 | `MatRubTypeID` | int | YES | | | MatRub类型ID(英文转译推测) | +| 10 | `MatRubType` | varchar(10) | YES | | | 胶料类别,0:胶块;1:胶片;2:胶粒 | +| 11 | `ScaleID` | int | YES | | | 秤ID(英文转译推测) | +| 12 | `ScaleName` | varchar(20) | YES | | | 秤名称(英文转译推测) | +| 13 | `CWSID` | int | YES | | | 小料设备号 | +| 14 | `WriteTime` | datetime | YES | | | 写入时间 | +| 15 | `ReadTime` | datetime | YES | | | 读取时间 | +| 16 | `MES_Flag` | int | YES | | (0) | 交互标识 | +| 17 | `UseBar` | int | YES | | ((0)) | Use Bar(英文转译推测) | + +--- + +## 1.45 表:MESToMCS_MatSendInf + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MESToMCS_MatSendInf` +- **表含义**:MES->MCS:物料发送信息 +- **字段数量**:20 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | YES | | | 设备ID(英文转译推测) | +| 3 | `EquipType` | varchar(10) | YES | | | 设备类型(英文转译推测) | +| 4 | `MatCode` | varchar(30) | YES | | | 物料编码(英文转译推测) | +| 5 | `MatName` | varchar(30) | YES | | | 物料名称(英文转译推测) | +| 6 | `OrderID` | varchar(30) | YES | | | 订单ID(英文转译推测) | +| 7 | `MatID` | varchar(30) | YES | | | Mat ID(英文转译推测) | +| 8 | `Weight` | numeric(18,3) | YES | | | 重量(英文转译推测) | +| 9 | `MatBarcode` | varchar(30) | YES | | | Mat条码(英文转译推测) | +| 10 | `MatKey` | int | YES | | | Mat键(英文转译推测) | +| 11 | `Result` | int | YES | | | 结果(英文转译推测) | +| 12 | `MatTypeID` | int | YES | | | Mat类型ID(英文转译推测) | +| 13 | `MatType` | int | YES | | | Mat类型(英文转译推测) | +| 14 | `ScaleID` | int | YES | | | 秤ID(英文转译推测) | +| 15 | `ScaleName` | varchar(20) | YES | | | 秤名称(英文转译推测) | +| 16 | `MatRubType` | varchar(1) | YES | | | MatRub类型(英文转译推测) | +| 17 | `CWSID` | int | YES | | | CWSID(英文转译推测) | +| 18 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 19 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 20 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | + +--- + +## 1.46 表:MESToMCS_MixPlan + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MESToMCS_MixPlan` +- **表含义**:MES->MCS:密炼计划下发 +- **字段数量**:29 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `PlanId` | varchar(20) | NO | 是 | | 计划编号 | +| 3 | `PlanSource` | varchar(1) | NO | 是 | | 计划来源(英文转译推测) | +| 4 | `EquipId` | int | NO | 是 | | 机台编号 | +| 5 | `EquipName` | varchar(20) | YES | | | 机台名称 | +| 6 | `EquipType` | varchar(10) | YES | | | 机台类型 | +| 7 | `PlanDate` | varchar(10) | YES | | | 计划日期 | +| 8 | `ShiftId` | varchar(1) | YES | | | 班次1:Night 2: Morning 3:Noon | +| 9 | `ShiftClass` | varchar(1) | YES | | | 班组1:A 2:B 3:C 4:D | +| 10 | `WorkOrder` | int | YES | | | 计划顺序 | +| 11 | `RecipCode` | varchar(30) | YES | | | 配方代码 | +| 12 | `RecipName` | varchar(30) | YES | | | 配方名称 | +| 13 | `MaterCode` | varchar(40) | YES | | | 物料编码(英文转译推测) | +| 14 | `MaterName` | varchar(80) | YES | | | 物料名称(英文转译推测) | +| 15 | `MOCode` | varchar(40) | YES | | | MOCode(英文转译推测) | +| 16 | `RcipVersion` | int | YES | | | 配方版本 | +| 17 | `ProType` | int | YES | | | 配方类型1:正式 2:试验 | +| 18 | `SetNum` | int | YES | | | 计划车次 | +| 19 | `DoneNum` | int | YES | | | 完成车次 | +| 20 | `PlanState` | int | YES | | | 计划状态 | +| 21 | `MESPlanChange` | int | YES | | | MES计划变化 | +| 22 | `MCSUpdateTime` | datetime | YES | | | MCS更新时间(英文转译推测) | +| 23 | `MCSPlanChange` | int | YES | | | MCSPlan Change(英文转译推测) | +| 24 | `MESUPdateTime` | datetime | YES | | | MES更新时间(英文转译推测) | +| 25 | `WriteTime` | datetime | YES | | | 写入时间 | +| 26 | `ReadTime` | datetime | YES | | | 读取时间 | +| 27 | `MES_Flag` | int | YES | | ((0)) | MES标志(英文转译推测) | +| 28 | `Remark` | varchar(200) | YES | | | 备注 | +| 29 | `TR_STATE` | int | YES | | | TR状态(英文转译推测) | + +--- + +## 1.47 表:MESToMCS_Recipe + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe` +- **表含义**:MES->MCS:配方主数据下发 +- **字段数量**:49 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | ('') | GUID(英文转译推测) | +| 2 | `EquipId` | int | NO | 是 | | 机台编号 | +| 3 | `EquipName` | varchar(20) | YES | | ('') | 机台名称 | +| 4 | `EquipType` | varchar(10) | NO | 是 | | 机台类型;CWS:小料;MCS:上辅机; | +| 5 | `RecipCode` | varchar(40) | NO | 是 | | 配方代码 | +| 6 | `RecipName` | varchar(40) | YES | | ('') | 配方名称 | +| 7 | `RecipVersion` | int | NO | 是 | | 配方版本 | +| 8 | `ProType` | varchar(10) | NO | 是 | | 配方类型;1:正式 2:试验 3:批量试验 4:1段母炼 5: 2段母炼6:终炼胶 | +| 9 | `IsUse` | int | YES | | | 使用状态1:使用 0:停用 | +| 10 | `Weight` | decimal(18,3) | YES | | ((0)) | 配方总重 | +| 11 | `Dust1RecycleMode` | int | YES | | ((0)) | 回收方式1;0:不回收;1:时间回收;2:重量回收 | +| 12 | `Dust1RecycleVal` | decimal(18,3) | YES | | ((0)) | 回收参数1 | +| 13 | `Dust2RecycleMode` | int | YES | | ((0)) | 回收方式2;0:不回收;1:时间回收;2:重量回收 | +| 14 | `Dust2RecycleVal` | decimal(18,0) | YES | | ((0)) | 回收参数1 | +| 15 | `SetOverTempMinTimVal` | int | YES | | ((0)) | 超温排胶最短时间 | +| 16 | `SetOverTimVal` | int | YES | | ((0)) | 超时排胶时间 | +| 17 | `SetOverTempVal` | decimal(18,2) | YES | | ((0)) | 超温排胶温度 | +| 18 | `SetOverEnergyVal` | decimal(18,3) | YES | | ((0)) | 超能排胶能量 | +| 19 | `FeedLowTempLimit` | decimal(18,3) | YES | | ((0)) | 进胶最低温度 | +| 20 | `FeedHighTempLimit` | decimal(18,3) | YES | | ((0)) | 进胶最高温度 | +| 21 | `FeedRotorSetSpd` | decimal(18,3) | YES | | ((0)) | 备用 | +| 22 | `FeedRotorSetTol` | decimal(18,3) | YES | | ((0)) | 备用 | +| 23 | `IntervalTim` | int | YES | | ((0)) | 最小间隔时间 | +| 24 | `SetTCU1` | decimal(18,3) | YES | | ((0)) | 混炼室温度 | +| 25 | `SetTCU2` | decimal(18,3) | YES | | ((0)) | 转子温度 | +| 26 | `SetTCU3` | decimal(18,3) | YES | | ((0)) | 卸料门温度 | +| 27 | `SetTCU4` | decimal(18,3) | YES | | ((0)) | 备用 | +| 28 | `SetTCU5` | decimal(18,3) | YES | | ((0)) | 备用 | +| 29 | `CtcMaxSpd` | decimal(18,3) | YES | | ((0)) | 最大转速 | +| 30 | `CtcMinSpd` | decimal(18,3) | YES | | ((0)) | 最小转速 | +| 31 | `CtcMaxPress` | decimal(18,0) | YES | | ((0)) | 最大压力 | +| 32 | `CtcMinPress` | decimal(18,3) | YES | | ((0)) | 最小压力 | +| 33 | `CtcLimitTemp` | decimal(18,3) | YES | | ((0)) | 温度保护 | +| 34 | `CtcLimitTim` | int | YES | | ((0)) | 时间保护 | +| 35 | `ShelfLotCount` | int | YES | | ((0)) | Shelf批次数量(英文转译推测) | +| 36 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 37 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 38 | `MES_Flag` | int | YES | | ((0)) | MES标志(英文转译推测) | +| 39 | `Remark` | varchar(50) | YES | | ('') | 备注(英文转译推测) | +| 40 | `AbnormalFeedBack` | varchar(50) | YES | | ('') | Abnormal供料Back(英文转译推测) | +| 41 | `AbortId` | int | YES | | ((0)) | Abort Id(英文转译推测) | +| 42 | `ThreeTemp1` | decimal(18,3) | YES | | ((0)) | Three温度1(英文转译推测) | +| 43 | `ThreeTemp2` | decimal(18,3) | YES | | ((0)) | Three温度2(英文转译推测) | +| 44 | `ThreeTemp3` | decimal(18,3) | YES | | ((0)) | Three温度3(英文转译推测) | +| 45 | `ThreeTemp4` | decimal(18,3) | YES | | ((0)) | Three温度4(英文转译推测) | +| 46 | `DisTemp` | numeric(18,3) | YES | | ((0)) | Dis温度(英文转译推测) | +| 47 | `RepVersionTxt` | varchar(40) | YES | | | Rep版本Txt(英文转译推测) | +| 48 | `RpType` | int | YES | | | Rp类型(英文转译推测) | +| 49 | `ReRubberWeight` | numeric(18,3) | YES | | | ReRubber重量(英文转译推测) | + +--- + +## 1.48 表:MESToMCS_Recipe_BatchOff + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe_BatchOff` +- **表含义**:MES->MCS:配方排出参数下发 +- **字段数量**:27 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | NO | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 3 | `RpCode` | varchar(50) | NO | 是 | | Rp编码(英文转译推测) | +| 4 | `RubberType` | int | YES | | | Rubber类型(英文转译推测) | +| 5 | `ReRubberType` | int | YES | | | ReRubber类型(英文转译推测) | +| 6 | `ReRubberWeight` | decimal(9,3) | YES | | | ReRubber重量(英文转译推测) | +| 7 | `ReRubberLength` | decimal(9,3) | YES | | | Re Rubber Length(英文转译推测) | +| 8 | `ReRubberCount` | int | YES | | | ReRubber数量(英文转译推测) | +| 9 | `ReRubberHeight` | decimal(9,3) | YES | | | Re Rubber Height(英文转译推测) | +| 10 | `ReRubberSpeed` | decimal(9,3) | YES | | | ReRubber速度(英文转译推测) | +| 11 | `RubberMWeight` | decimal(9,3) | YES | | | Rubber MWeight(英文转译推测) | +| 12 | `ReRubberLimitTemp` | decimal(9,3) | YES | | | ReRubberLimit温度(英文转译推测) | +| 13 | `ReRubberLead` | decimal(9,3) | YES | | | Re Rubber Lead(英文转译推测) | +| 14 | `MinSaveTime` | int | YES | | | 最小Save时间(英文转译推测) | +| 15 | `MaxSaveTime` | int | YES | | | 最大Save时间(英文转译推测) | +| 16 | `PerWeight` | decimal(9,3) | YES | | | Per重量(英文转译推测) | +| 17 | `SampleType` | int | YES | | | Sample类型(英文转译推测) | +| 18 | `SampleWeight` | decimal(9,3) | YES | | | Sample重量(英文转译推测) | +| 19 | `SampleLength` | decimal(9,3) | YES | | | Sample Length(英文转译推测) | +| 20 | `SampleCount` | int | YES | | | Sample数量(英文转译推测) | +| 21 | `RpVersion` | varchar(50) | YES | | | Rp版本(英文转译推测) | +| 22 | `RpVersionID` | int | NO | 是 | | Rp版本ID(英文转译推测) | +| 23 | `HangRubberHeight` | decimal(9,3) | YES | | | Hang Rubber Height(英文转译推测) | +| 24 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | +| 25 | `RecipVersionID` | int | YES | | | Recip版本ID(英文转译推测) | +| 26 | `ReRubberPos` | int | YES | | | Re Rubber Pos(英文转译推测) | +| 27 | `RecipVersion` | varchar(50) | YES | | | Recip版本(英文转译推测) | + +--- + +## 1.49 表:MESToMCS_Recipe_Delete + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe_Delete` +- **表含义**:MES->MCS:配方删除指令 +- **字段数量**:11 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipId` | int | NO | 是 | | 机台编号 | +| 3 | `EquipName` | varchar(10) | YES | | | 机台名称 | +| 4 | `EquipType` | varchar(10) | NO | 是 | | 机台类型;CWS:小料;MCS:上辅机 | +| 5 | `RecipCode` | varchar(30) | NO | 是 | | 配方(物料)代码 | +| 6 | `RecipVersion` | int | NO | 是 | | 配方(物料)版本 | +| 7 | `User` | varchar(10) | YES | | | 操作人 | +| 8 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 9 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 10 | `MES_Flag` | int | YES | | (0) | MES标志(英文转译推测) | +| 11 | `Remark` | varchar(50) | YES | | | 备注(英文转译推测) | + +--- + +## 1.50 表:MESToMCS_Recipe_MillStep + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe_MillStep` +- **表含义**:MES->MCS:配方开炼步骤下发 +- **字段数量**:21 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 3 | `MillID` | int | NO | 是 | | 开炼ID(英文转译推测) | +| 4 | `RpCode` | varchar(50) | NO | 是 | | Rp编码(英文转译推测) | +| 5 | `StepID` | int | NO | 是 | | 步骤ID(英文转译推测) | +| 6 | `MillAction` | int | YES | | | 开炼动作(英文转译推测) | +| 7 | `ActName` | varchar(40) | YES | | | 动作名称(英文转译推测) | +| 8 | `ActName_EN` | varchar(40) | YES | | | 动作名称en(英文转译推测) | +| 9 | `MillTime` | int | YES | | | 开炼时间(英文转译推测) | +| 10 | `MillSpeed` | decimal(18,3) | YES | | | 开炼速度(英文转译推测) | +| 11 | `CoolDeviceSpeed` | decimal(18,3) | YES | | | CoolDevice速度(英文转译推测) | +| 12 | `RollGap` | decimal(18,3) | YES | | | Roll Gap(英文转译推测) | +| 13 | `WaterTemper` | decimal(18,3) | YES | | | Water Temper(英文转译推测) | +| 14 | `RubTemper` | decimal(18,3) | YES | | | Rub Temper(英文转译推测) | +| 15 | `SpeedRatio` | decimal(18,3) | YES | | | 速度Ratio(英文转译推测) | +| 16 | `Spare1` | int | YES | | ((0)) | Spare 1(英文转译推测) | +| 17 | `Spare2` | int | YES | | ((0)) | Spare 2(英文转译推测) | +| 18 | `RpVersionID` | int | NO | 是 | | Rp版本ID(英文转译推测) | +| 19 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 20 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 21 | `MES_Flag` | int | YES | | ((0)) | MES标志(英文转译推测) | + +--- + +## 1.51 表:MESToMCS_Recipe_MixDown + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe_MixDown` +- **表含义**:MES->MCS:配方混炼下传数据 +- **字段数量**:29 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | NO | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 3 | `EquipType` | varchar(20) | NO | 是 | | 设备类型(英文转译推测) | +| 4 | `EquipName` | varchar(20) | YES | | | 设备名称(英文转译推测) | +| 5 | `RpCode` | varchar(50) | NO | 是 | | Rp编码(英文转译推测) | +| 6 | `RpName` | varchar(50) | YES | | | Rp名称(英文转译推测) | +| 7 | `RpVersion` | varchar(50) | YES | | | Rp版本(英文转译推测) | +| 8 | `SetOverTempMinTimVal` | int | YES | | | SetOver温度最小TimVal(英文转译推测) | +| 9 | `SetOverTimVal` | int | YES | | | Set Over Tim Val(英文转译推测) | +| 10 | `SetOverTempVal` | decimal(9,3) | YES | | | SetOver温度Val(英文转译推测) | +| 11 | `SetOverEnergyVal` | decimal(9,3) | YES | | | SetOver能耗Val(英文转译推测) | +| 12 | `FeedLowTempLimit` | decimal(9,3) | YES | | | 供料Low温度Limit(英文转译推测) | +| 13 | `FeedHighTempLimit` | decimal(9,3) | YES | | | 供料High温度Limit(英文转译推测) | +| 14 | `IntervalTim` | int | YES | | | Interval Tim(英文转译推测) | +| 15 | `SetTCU1` | decimal(9,3) | YES | | | Set TCU 1(英文转译推测) | +| 16 | `SetTCU2` | decimal(9,3) | YES | | | Set TCU 2(英文转译推测) | +| 17 | `SetTCU3` | decimal(9,3) | YES | | | Set TCU 3(英文转译推测) | +| 18 | `SetTCU4` | decimal(9,3) | YES | | | Set TCU 4(英文转译推测) | +| 19 | `SetTCU5` | decimal(9,3) | YES | | | Set TCU 5(英文转译推测) | +| 20 | `CtcMaxSpd` | decimal(9,3) | YES | | | Ctc最大Spd(英文转译推测) | +| 21 | `CtcMinSpd` | decimal(9,3) | YES | | | Ctc最小Spd(英文转译推测) | +| 22 | `CtcMaxPress` | decimal(9,3) | YES | | | Ctc最大Press(英文转译推测) | +| 23 | `CtcMinPress` | decimal(9,3) | YES | | | Ctc最小Press(英文转译推测) | +| 24 | `CtcLimitTemp` | decimal(9,3) | YES | | | CtcLimit温度(英文转译推测) | +| 25 | `CtcLimitTim` | int | YES | | | Ctc Limit Tim(英文转译推测) | +| 26 | `SaveTime` | varchar(20) | YES | | | Save时间(英文转译推测) | +| 27 | `LastOper` | varchar(20) | YES | | | Last Oper(英文转译推测) | +| 28 | `RpVersionID` | int | YES | | | Rp版本ID(英文转译推测) | +| 29 | `RecipVersion` | varchar(20) | YES | | | Recip版本(英文转译推测) | + +--- + +## 1.52 表:MESToMCS_Recipe_MixStep + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe_MixStep` +- **表含义**:MES->MCS:配方密炼步骤下发 +- **字段数量**:26 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | ('') | GUID(英文转译推测) | +| 2 | `EquipId` | int | NO | 是 | | 机台编号 | +| 3 | `EquipName` | varchar(20) | YES | | ('') | 机台名称 | +| 4 | `EquipType` | varchar(10) | NO | 是 | | 机台类型 | +| 5 | `RecipCode` | varchar(30) | NO | 是 | | 配方代码 | +| 6 | `Serial` | int | NO | 是 | | 密炼步序 | +| 7 | `Act` | int | YES | | ((0)) | 动作地址 | +| 8 | `Cond` | int | YES | | ((0)) | 条件地址 | +| 9 | `Time` | int | NO | | ((0)) | 设定时间 | +| 10 | `TimeLimit` | int | YES | | ((0)) | 时间保护 | +| 11 | `Temp` | decimal(18,3) | YES | | ((0)) | 温度 | +| 12 | `TempLimit` | decimal(18,3) | YES | | ((0)) | 温度保护 | +| 13 | `Energy` | decimal(18,3) | YES | | ((0)) | 能量 | +| 14 | `EnergyLimit` | decimal(18,3) | YES | | ((0)) | 能量保护 | +| 15 | `Power` | decimal(18,3) | YES | | ((0)) | 功率 | +| 16 | `PowerLimit` | decimal(18,3) | YES | | ((0)) | 功率保护 | +| 17 | `Press` | decimal(18,3) | YES | | ((0)) | 压力 | +| 18 | `Speed` | decimal(18,3) | YES | | ((0)) | 转速 | +| 19 | `RotorGap` | decimal(18,3) | YES | | ((0)) | 辊距 | +| 20 | `RamPos` | decimal(18,3) | YES | | ((0)) | 栓位置 | +| 21 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 22 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 23 | `MES_Flag` | int | YES | | ((0)) | MES标志(英文转译推测) | +| 24 | `Remark` | varchar(200) | YES | | ('') | 备注(英文转译推测) | +| 25 | `AbnormalFeedBack` | varchar(50) | YES | | ('') | Abnormal供料Back(英文转译推测) | +| 26 | `RecipVersion` | int | NO | 是 | | Recip版本(英文转译推测) | + +--- + +## 1.53 表:MESToMCS_Recipe_MixStep_Down + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe_MixStep_Down` +- **表含义**:MES->MCS:配方密炼步骤下传明细 +- **字段数量**:21 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | NO | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 3 | `RpCode` | varchar(50) | NO | 是 | | Rp编码(英文转译推测) | +| 4 | `MixID` | int | NO | 是 | | 密炼ID(英文转译推测) | +| 5 | `Cond` | int | YES | | | Cond(英文转译推测) | +| 6 | `Tim` | int | YES | | | Tim(英文转译推测) | +| 7 | `TimLimit` | int | YES | | | Tim Limit(英文转译推测) | +| 8 | `Tempe` | decimal(18,3) | YES | | | 温度e(英文转译推测) | +| 9 | `TempLimit` | decimal(18,3) | YES | | | 温度Limit(英文转译推测) | +| 10 | `Energy` | decimal(18,3) | YES | | | 能耗(英文转译推测) | +| 11 | `EnergyLimit` | decimal(18,3) | YES | | | 能耗Limit(英文转译推测) | +| 12 | `Power` | int | YES | | | 功率(英文转译推测) | +| 13 | `PowerLimit` | int | YES | | | 功率Limit(英文转译推测) | +| 14 | `Act` | int | YES | | | 动作(英文转译推测) | +| 15 | `Press` | decimal(18,3) | YES | | | Press(英文转译推测) | +| 16 | `RotorSpd` | decimal(18,3) | YES | | | Rotor Spd(英文转译推测) | +| 17 | `RollGap` | decimal(18,3) | YES | | | Roll Gap(英文转译推测) | +| 18 | `RamPos` | decimal(18,3) | YES | | | Ram Pos(英文转译推测) | +| 19 | `RpVersion` | varchar(40) | YES | | | Rp版本(英文转译推测) | +| 20 | `RpVersionID` | int | YES | | | Rp版本ID(英文转译推测) | +| 21 | `Torque` | decimal(18,3) | YES | | | Torque(英文转译推测) | + +--- + +## 1.54 表:MESToMCS_Recipe_Weight + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe_Weight` +- **表含义**:MES->MCS:配方称重物料明细下发 +- **字段数量**:26 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipId` | int | NO | 是 | | 机台编号 | +| 3 | `EquipName` | varchar(20) | YES | | ('') | 机台名称 | +| 4 | `EquipType` | varchar(10) | NO | 是 | ('') | 机台类型 | +| 5 | `RecipCode` | varchar(30) | NO | 是 | ('') | 配方代码 | +| 6 | `ScaleType` | int | NO | 是 | ((0)) | 秤类型1:炭黑 2:油料 3:胶料 4:小料 | +| 7 | `ScaleId` | int | NO | 是 | ((0)) | 秤编号,101:炭黑秤1;102:炭黑秤2;103:炭黑秤3 + 201:油料秤1;202:油料秤2;203:油料秤3;301:胶料秤1;302:胶料秤2;401:小料秤1;402:小料秤2 | +| 8 | `Serial` | int | NO | 是 | ((0)) | 称量步序 | +| 9 | `Action` | int | YES | | ((0)) | 动作;1:称量 2:称到 3:卸料,默认值0 | +| 10 | `BinNo` | int | YES | | ((0)) | 仓号(英文转译推测) | +| 11 | `MatCode` | varchar(30) | YES | | ('') | 物料代码 | +| 12 | `MatName` | varchar(30) | YES | | ('') | 物料名称 | +| 13 | `SetWeight` | decimal(18,3) | YES | | ((0)) | 设定重量 | +| 14 | `Tolerance` | decimal(18,3) | YES | | ((0)) | 设定误差 | +| 15 | `SFNum` | int | YES | | ((0)) | 导切机编号 | +| 16 | `MatType` | varchar(10) | YES | | ('') | 炭黑、油料、胶料、小料 | +| 17 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 18 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 19 | `MES_Flag` | int | YES | | ((0)) | MES标志(英文转译推测) | +| 20 | `Remark` | varchar(50) | YES | | ('') | 备注(英文转译推测) | +| 21 | `RubTypeID` | int | YES | | ((0)) | Rub类型ID(英文转译推测) | +| 22 | `MixID` | int | NO | 是 | | 密炼ID(英文转译推测) | +| 23 | `AbnormalFeedBack` | varchar(50) | YES | | ('') | Abnormal供料Back(英文转译推测) | +| 24 | `AbortId` | int | YES | | ((0)) | Abort Id(英文转译推测) | +| 25 | `RecipVersion` | int | NO | 是 | | Recip版本(英文转译推测) | +| 26 | `SetDnTol` | decimal(18,3) | YES | | ((0)) | SetDn容差(英文转译推测) | + +--- + +## 1.55 表:MESToMCS_Verify + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Verify` +- **表含义**:MES->MCS:校验/核对数据 +- **字段数量**:12 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | NO | 是 | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | | | 机台编号 | +| 3 | `EquipName` | varchar(10) | YES | | | 机台名称 | +| 4 | `EquipType` | varchar(10) | NO | | | 机台类型 | +| 5 | `ScaleNum` | int | NO | | | 秤编号 | +| 6 | `PlanId` | varchar(20) | YES | | | 计划编号 | +| 7 | `MatCode` | varchar(30) | YES | | | 物料代码 | +| 8 | `MatName` | varchar(30) | YES | | | 物料名称 | +| 9 | `Judge` | int | YES | | | 判断结果 | +| 10 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 11 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 12 | `MES_Flag` | int | YES | | (0) | MES标志(英文转译推测) | + +--- + +## 1.56 表:PptScanBarcode + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`PptScanBarcode` +- **表含义**:条码扫描当前表 +- **字段数量**:13 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `SerialID` | int | NO | 是 | | Serial ID(英文转译推测) | +| 2 | `Barcode` | varchar(25) | NO | 是 | | 条码(英文转译推测) | +| 3 | `EquipCode` | char(5) | NO | 是 | | 设备编码(英文转译推测) | +| 4 | `MaterCode` | char(13) | NO | 是 | | 物料编码(英文转译推测) | +| 5 | `MaterName` | nvarchar(80) | YES | | | 物料名称(英文转译推测) | +| 6 | `MaterType` | char(1) | YES | | | 物料类型(英文转译推测) | +| 7 | `MaterTypeName` | char(10) | YES | | | 物料类型名称(英文转译推测) | +| 8 | `BarchNo` | varchar(50) | YES | | | Barch编号(英文转译推测) | +| 9 | `ScanWeight` | decimal(18,2) | YES | | ((0)) | 扫描重量(英文转译推测) | +| 10 | `UsedWeight` | decimal(18,2) | YES | | | Used重量(英文转译推测) | +| 11 | `QueueIndex` | int | YES | | | Queue索引(英文转译推测) | +| 12 | `IsUsed` | char(1) | YES | | | Is Used(英文转译推测) | +| 13 | `ScanDateTime` | datetime | YES | | | 扫描日期时间(英文转译推测) | + +--- + +## 1.57 表:PptScanBarcodeHis + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`PptScanBarcodeHis` +- **表含义**:条码扫描历史表 +- **字段数量**:15 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `ObjId` | int | NO | 是 | | Obj Id(英文转译推测) | +| 2 | `SerialID` | int | NO | | | Serial ID(英文转译推测) | +| 3 | `Barcode` | varchar(25) | NO | | | 条码(英文转译推测) | +| 4 | `EquipCode` | char(5) | NO | | | 设备编码(英文转译推测) | +| 5 | `MaterCode` | char(13) | NO | | | 物料编码(英文转译推测) | +| 6 | `MaterName` | nvarchar(80) | YES | | | 物料名称(英文转译推测) | +| 7 | `MaterType` | char(1) | YES | | | 物料类型(英文转译推测) | +| 8 | `MaterTypeName` | char(10) | YES | | | 物料类型名称(英文转译推测) | +| 9 | `BarchNo` | varchar(50) | YES | | | Barch编号(英文转译推测) | +| 10 | `ScanWeight` | decimal(18,2) | YES | | | 扫描重量(英文转译推测) | +| 11 | `UsedWeight` | decimal(18,2) | YES | | | Used重量(英文转译推测) | +| 12 | `QueueIndex` | int | YES | | | Queue索引(英文转译推测) | +| 13 | `IsUsed` | char(1) | YES | | | Is Used(英文转译推测) | +| 14 | `ScanDateTime` | datetime | YES | | | 扫描日期时间(英文转译推测) | +| 15 | `UpdateDateTime` | datetime | YES | | | 更新日期时间(英文转译推测) | + +--- + +## 1.58 表:PptScanBarcodeLog + +- **所属数据库**:`MESNAC_MCS_ShareDB` +- **Schema**:`dbo` +- **表名**:`PptScanBarcodeLog` +- **表含义**:条码扫描日志表 +- **字段数量**:12 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `dt` | datetime | NO | 是 | (getdate()) | dt(英文转译推测) | +| 2 | `EquipCode` | char(5) | NO | 是 | | 设备编码(英文转译推测) | +| 3 | `RecipeCode` | varchar(20) | YES | | | 配方编码(英文转译推测) | +| 4 | `scanBarcode` | varchar(30) | YES | | | 扫描条码(英文转译推测) | +| 5 | `ScanMaterCode` | char(13) | YES | | | 扫描物料编码(英文转译推测) | +| 6 | `msg` | varchar(200) | YES | | | msg(英文转译推测) | +| 7 | `Usercode` | varchar(10) | YES | | | 用户编码(英文转译推测) | +| 8 | `shiftid` | varchar(4) | YES | | | 班次ID(英文转译推测) | +| 9 | `shiftclass` | varchar(4) | YES | | | shiftclass(英文转译推测) | +| 10 | `scanflag` | varchar(1) | YES | | | 扫描标志(英文转译推测) | +| 11 | `ScanLogSignal` | int | YES | | | 扫描日志Signal(英文转译推测) | +| 12 | `ScanUsedBarMsg` | varchar(500) | YES | | | 扫描UsedBarMsg(英文转译推测) | + +--- + +# 2. 数据库:MESNAC_MCS_ShareDB_XL + +- **数据库名**:`MESNAC_MCS_ShareDB_XL` +- **用途**:小料(XL)相关中间库 +- **表数量**:54 + +## 2.1 表:Application_Error_Log + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`Application_Error_Log` +- **表含义**:应用错误日志 +- **字段数量**:6 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `tablename` | varchar(50) | YES | | | 表名(英文转译推测) | +| 2 | `userName` | varchar(50) | YES | | | 用户名(英文转译推测) | +| 3 | `errorNumber` | varchar(50) | YES | | | 错误编号(英文转译推测) | +| 4 | `errorSeverity` | varchar(50) | YES | | | 错误严重级别(英文转译推测) | +| 5 | `errorState` | varchar(50) | YES | | | 错误状态(英文转译推测) | +| 6 | `errorMessage` | varchar(5000) | YES | | | 错误信息(英文转译推测) | + +--- + +## 2.2 表:IF_BarcodeLog2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_BarcodeLog2Mes` +- **表含义**:接口:条码日志 -> MES +- **字段数量**:10 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `ID` | bigint | NO | 是 | | ID(英文转译推测) | +| 2 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Scan_Time` | varchar(50) | YES | | | 扫描时间(英文转译推测) | +| 4 | `Scan_Bar` | varchar(50) | YES | | | 扫描Bar(英文转译推测) | +| 5 | `Material` | varchar(50) | YES | | | 物料(英文转译推测) | +| 6 | `Bin` | int | YES | | | 仓位(英文转译推测) | +| 7 | `Scan_State` | int | YES | | | 扫描状态(英文转译推测) | +| 8 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 9 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 10 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 2.3 表:IF_BinState2MES + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_BinState2MES` +- **表含义**:接口:料仓状态 -> MES +- **字段数量**:7 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Equip_Code` | varchar(20) | YES | | | 设备编码(英文转译推测) | +| 2 | `Bin_Serial` | int | YES | | | 仓位Serial(英文转译推测) | +| 3 | `level_flag` | int | YES | | | 级别标志(英文转译推测) | +| 4 | `open_flag` | int | YES | | | open标志(英文转译推测) | +| 5 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 6 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 7 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 2.4 表:IF_EquipState2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_EquipState2Mes` +- **表含义**:接口:设备状态 -> MES +- **字段数量**:9 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `ID` | varchar(50) | NO | | | ID(英文转译推测) | +| 2 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Equip_State` | varchar(50) | YES | | | 设备状态(英文转译推测) | +| 4 | `Alarm_OccurTime` | varchar(50) | YES | | | 报警Occur时间(英文转译推测) | +| 5 | `Alarm_ClearTime` | varchar(50) | YES | | | 报警Clear时间(英文转译推测) | +| 6 | `Equip_AlarmTxt` | varchar(50) | YES | | | 设备报警txt(英文转译推测) | +| 7 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 8 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 9 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 2.5 表:IF_FeedMaterialInfo2CWSS + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_FeedMaterialInfo2CWSS` +- **表含义**:接口:供料信息 -> CWSS +- **字段数量**:8 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Equip_Code` | varchar(16) | YES | | | 设备编码(英文转译推测) | +| 2 | `Scan_Bar` | varchar(50) | YES | | | 扫描Bar(英文转译推测) | +| 3 | `Bin_Serial` | int | YES | | | 仓位Serial(英文转译推测) | +| 4 | `Material_code` | varchar(50) | YES | | | 物料编码(英文转译推测) | +| 5 | `Material_name` | varchar(50) | YES | | | 物料名称(英文转译推测) | +| 6 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 7 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 8 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 2.6 表:IF_LrAlarmLog2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_LrAlarmLog2Mes` +- **表含义**:接口:小料报警日志 -> MES +- **字段数量**:12 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Equip_code` | varchar(20) | YES | | | 设备编码(英文转译推测) | +| 2 | `Alarm_ID` | int | YES | | | 报警ID(英文转译推测) | +| 3 | `Alarm_OccurTime` | varchar(50) | YES | | | 报警Occur时间(英文转译推测) | +| 4 | `Alarm_ClearTime` | varchar(50) | YES | | | 报警Clear时间(英文转译推测) | +| 5 | `Alarm_Status` | int | YES | | | 报警状态(英文转译推测) | +| 6 | `Alarm_GUID` | char(32) | YES | | | 报警GUID(英文转译推测) | +| 7 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 8 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 9 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | +| 10 | `Alarm_Level` | int | YES | | | 报警级别(英文转译推测) | +| 11 | `Alarm_Type` | nvarchar(50) | YES | | | 报警类型(英文转译推测) | +| 12 | `Alarm_Cn_Info` | varchar(50) | YES | | | 报警Cn信息(英文转译推测) | + +--- + +## 2.7 表:If_Lrlot2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`If_Lrlot2Mes` +- **表含义**:接口:小料批次 -> MES +- **字段数量**:26 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Plan_id` | varchar(50) | YES | | | 计划ID(英文转译推测) | +| 2 | `Equip_code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Serial_Num` | int | YES | | | Serial Num(英文转译推测) | +| 4 | `Prd_date` | varchar(50) | YES | | | Prd日期(英文转译推测) | +| 5 | `Real_weight` | numeric(9,0) | YES | | | 实际重量(英文转译推测) | +| 6 | `Real_Error` | numeric(9,0) | YES | | | Real错误(英文转译推测) | +| 7 | `Waste_Time` | int | YES | | | Waste时间(英文转译推测) | +| 8 | `WarnIng_Sgn` | int | YES | | | Warn Ing Sgn(英文转译推测) | +| 9 | `Net_Weight` | numeric(9,0) | YES | | | 净重(英文转译推测) | +| 10 | `Group_BarCode` | varchar(50) | YES | | | 组条码(英文转译推测) | +| 11 | `Lot_BarCode` | varchar(50) | YES | | | 批次条码(英文转译推测) | +| 12 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 13 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 14 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | +| 15 | `BG_SetTemp` | int | YES | | | BGSet温度(英文转译推测) | +| 16 | `BG_RealTemp` | int | YES | | | BGReal温度(英文转译推测) | +| 17 | `BG_SetPress` | int | YES | | | BG Set Press(英文转译推测) | +| 18 | `BG_RealPress` | int | YES | | | BG Real Press(英文转译推测) | +| 19 | `BG_SetTime` | int | YES | | | BGSet时间(英文转译推测) | +| 20 | `BG_RealTime` | int | YES | | | BGReal时间(英文转译推测) | +| 21 | `BW_SetTemp` | int | YES | | | BWSet温度(英文转译推测) | +| 22 | `BW_RealTemp` | int | YES | | | BWReal温度(英文转译推测) | +| 23 | `BW_SetPress` | int | YES | | | BW Set Press(英文转译推测) | +| 24 | `BW_RealPress` | int | YES | | | BW Real Press(英文转译推测) | +| 25 | `BW_SetTime` | int | YES | | | BWSet时间(英文转译推测) | +| 26 | `BW_RealTime` | int | YES | | | BWReal时间(英文转译推测) | + +--- + +## 2.8 表:IF_LrPlan2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_LrPlan2Mes` +- **表含义**:接口:小料计划 -> MES +- **字段数量**:20 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Plan_Id` | varchar(50) | NO | 是 | | 计划ID(英文转译推测) | +| 2 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Plan_Serial` | int | YES | | | 计划Serial(英文转译推测) | +| 4 | `Recipe_ID` | varchar(50) | YES | | | 配方ID(英文转译推测) | +| 5 | `Recipe_Code` | varchar(50) | YES | | | 配方编码(英文转译推测) | +| 6 | `Recipe_Name` | varchar(50) | YES | | | 配方名称(英文转译推测) | +| 7 | `Version` | varchar(50) | YES | | | 版本(英文转译推测) | +| 8 | `Mixer_Line` | varchar(50) | YES | | | Mixer行(英文转译推测) | +| 9 | `Shift_Id` | varchar(10) | YES | | | 班次ID(英文转译推测) | +| 10 | `Plan_Num` | int | YES | | | 计划Num(英文转译推测) | +| 11 | `real_num` | int | YES | | | real num(英文转译推测) | +| 12 | `Start_Date` | varchar(50) | YES | | | 开始日期(英文转译推测) | +| 13 | `End_Date` | varchar(50) | YES | | | 结束日期(英文转译推测) | +| 14 | `Weight_Man` | varchar(50) | YES | | | 重量Man(英文转译推测) | +| 15 | `Plan_Batch` | varchar(50) | YES | | | 计划批次(英文转译推测) | +| 16 | `Plan_State` | int | YES | | | 计划状态(英文转译推测) | +| 17 | `Plan_Date` | varchar(50) | YES | | | 计划日期(英文转译推测) | +| 18 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 19 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 20 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 2.9 表:IF_LrPlanGroup2MES + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_LrPlanGroup2MES` +- **表含义**:接口:小料计划组 -> MES +- **字段数量**:16 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `ID` | varchar(50) | NO | 是 | | ID(英文转译推测) | +| 2 | `Plan_Id` | varchar(50) | YES | | | 计划ID(英文转译推测) | +| 3 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 4 | `Recipe_Code` | varchar(50) | YES | | | 配方编码(英文转译推测) | +| 5 | `Recipe_Name` | varchar(50) | YES | | | 配方名称(英文转译推测) | +| 6 | `Total_weight` | numeric(9,3) | YES | | | 总重量(英文转译推测) | +| 7 | `Total_Error` | numeric(9,3) | YES | | | 合计错误(英文转译推测) | +| 8 | `TrolleyBags` | int | YES | | | Trolley Bags(英文转译推测) | +| 9 | `TrolleyNumber` | int | YES | | | Trolley编号(英文转译推测) | +| 10 | `StartNum` | int | YES | | | 开始Num(英文转译推测) | +| 11 | `EndNum` | int | YES | | | 结束Num(英文转译推测) | +| 12 | `Prd_date` | varchar(50) | YES | | | Prd日期(英文转译推测) | +| 13 | `Group_BarCode` | varchar(50) | YES | | | 组条码(英文转译推测) | +| 14 | `Write_Time` | varchar(50) | YES | | | 写入时间(英文转译推测) | +| 15 | `Read_Time` | varchar(50) | YES | | | 读取时间(英文转译推测) | +| 16 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 2.10 表:IF_LrRecipe2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_LrRecipe2Mes` +- **表含义**:接口:小料配方 -> MES +- **字段数量**:13 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Plan_id` | varchar(50) | NO | 是 | | 计划ID(英文转译推测) | +| 2 | `Equip_code` | varchar(50) | NO | 是 | | 设备编码(英文转译推测) | +| 3 | `Weight_ID` | int | NO | 是 | | 重量ID(英文转译推测) | +| 4 | `Material_Code` | varchar(50) | YES | | | 物料编码(英文转译推测) | +| 5 | `Material_Name` | varchar(50) | YES | | | 物料名称(英文转译推测) | +| 6 | `Set_Weight` | numeric(9,4) | YES | | | 设定重量(英文转译推测) | +| 7 | `Set_Error` | numeric(9,4) | YES | | | Set错误(英文转译推测) | +| 8 | `CPK_Error` | numeric(9,4) | YES | | | CPK错误(英文转译推测) | +| 9 | `Batch_number` | varchar(50) | YES | | | 批次号(英文转译推测) | +| 10 | `Actual_Mater` | varchar(50) | YES | | | Actual物料(英文转译推测) | +| 11 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 12 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 13 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 2.11 表:IF_LrWeigh2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_LrWeigh2Mes` +- **表含义**:接口:小料称重 -> MES +- **字段数量**:17 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Plan_id` | varchar(50) | YES | | | 计划ID(英文转译推测) | +| 2 | `Equip_code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Serial_Num` | int | YES | | | Serial Num(英文转译推测) | +| 4 | `Weight_ID` | int | YES | | | 重量ID(英文转译推测) | +| 5 | `Material_Code` | varchar(50) | YES | | | 物料编码(英文转译推测) | +| 6 | `Set_Weight` | numeric(9,4) | YES | | | 设定重量(英文转译推测) | +| 7 | `Set_Error` | numeric(9,4) | YES | | | Set错误(英文转译推测) | +| 8 | `Real_Weight` | numeric(9,4) | YES | | | 实际重量(英文转译推测) | +| 9 | `Real_Error` | numeric(9,4) | YES | | | Real错误(英文转译推测) | +| 10 | `Warning_Sign` | int | YES | | | Warning Sign(英文转译推测) | +| 11 | `Batch_Number` | varchar(50) | YES | | | 批次号(英文转译推测) | +| 12 | `Recipe_code` | varchar(50) | YES | | | 配方编码(英文转译推测) | +| 13 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 14 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 15 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | +| 16 | `Start_Date` | varchar(20) | YES | | | 开始日期(英文转译推测) | +| 17 | `End_Date` | varchar(20) | YES | | | 结束日期(英文转译推测) | + +--- + +## 2.12 表:IF_MESShift2CWSS + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_MESShift2CWSS` +- **表含义**:接口:MES班次 -> CWSS +- **字段数量**:6 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Equip_code` | varchar(20) | YES | | | 设备编码(英文转译推测) | +| 2 | `ShiftDate` | varchar(20) | YES | | | 班次日期(英文转译推测) | +| 3 | `ShiftID` | int | YES | | | 班次ID(英文转译推测) | +| 4 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 5 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 6 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 2.13 表:IF_PmtBin2CWSS + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_PmtBin2CWSS` +- **表含义**:接口:炭黑/粉料仓位 -> CWSS +- **字段数量**:8 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 2 | `Bin_Serial` | int | YES | | | 仓位Serial(英文转译推测) | +| 3 | `Material_ID` | varchar(50) | YES | | | 物料ID(英文转译推测) | +| 4 | `ID` | varchar(50) | YES | | | ID(英文转译推测) | +| 5 | `Bin_UseFlag` | bit | YES | | | 仓位使用标志(英文转译推测) | +| 6 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 7 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 8 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 2.14 表:IF_PmtBin2MES + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_PmtBin2MES` +- **表含义**:接口:炭黑/粉料仓位 -> MES +- **字段数量**:7 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Equip_Code` | varchar(50) | NO | 是 | | 设备编码(英文转译推测) | +| 2 | `Bin_Serial` | int | NO | 是 | | 仓位Serial(英文转译推测) | +| 3 | `Material_ID` | varchar(50) | YES | | | 物料ID(英文转译推测) | +| 4 | `Bin_UseFlag` | varchar(20) | YES | | | 仓位使用标志(英文转译推测) | +| 5 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 6 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 7 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 2.15 表:IF_PmtMaterial2CWSS + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_PmtMaterial2CWSS` +- **表含义**:接口:炭黑/粉料物料 -> CWSS +- **字段数量**:7 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `ID` | varchar(50) | YES | | | ID(英文转译推测) | +| 2 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Material_code` | varchar(50) | YES | | | 物料编码(英文转译推测) | +| 4 | `Material_name` | varchar(50) | YES | | | 物料名称(英文转译推测) | +| 5 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 6 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 7 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 2.16 表:IF_PmtRecipe2CWSS + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_PmtRecipe2CWSS` +- **表含义**:接口:炭黑/粉料配方 -> CWSS +- **字段数量**:17 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Id` | varchar(50) | YES | | | ID(英文转译推测) | +| 2 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Recipe_Code` | varchar(50) | YES | | | 配方编码(英文转译推测) | +| 4 | `Version` | varchar(50) | YES | | | 版本(英文转译推测) | +| 5 | `Recipe_Name` | varchar(50) | YES | | | 配方名称(英文转译推测) | +| 6 | `Mixer_line` | varchar(50) | YES | | | Mixer行(英文转译推测) | +| 7 | `Recipe_Verify` | int | YES | | | 配方版本ify(英文转译推测) | +| 8 | `Total_Weight` | numeric(12,4) | YES | | | 总重量(英文转译推测) | +| 9 | `Total_Error` | numeric(12,4) | YES | | | 合计错误(英文转译推测) | +| 10 | `End_datetime` | varchar(19) | YES | | | 结束日期时间(英文转译推测) | +| 11 | `Remark` | varchar(200) | YES | | | 备注(英文转译推测) | +| 12 | `GroupBags` | int | YES | | | 组Bags(英文转译推测) | +| 13 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 14 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 15 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | +| 16 | `Validity` | int | YES | | | Validity(英文转译推测) | +| 17 | `BagWeight` | int | YES | | | Bag重量(英文转译推测) | + +--- + +## 2.17 表:IF_Pmtweigh2CWSS + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_Pmtweigh2CWSS` +- **表含义**:接口:炭黑/粉料称重 -> CWSS +- **字段数量**:10 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Id` | varchar(50) | YES | | | ID(英文转译推测) | +| 2 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Recipe_ID` | varchar(50) | YES | | | 配方ID(英文转译推测) | +| 4 | `Weight_Id` | int | YES | | | 重量ID(英文转译推测) | +| 5 | `Material_ID` | varchar(50) | YES | | | 物料ID(英文转译推测) | +| 6 | `Set_Weight` | numeric(9,3) | YES | | | 设定重量(英文转译推测) | +| 7 | `Set_Error` | numeric(9,3) | YES | | | Set错误(英文转译推测) | +| 8 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 9 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 10 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 2.18 表:IF_RtPlan2CWSS + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_RtPlan2CWSS` +- **表含义**:接口:生胶计划 -> CWSS +- **字段数量**:18 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Plan_Id` | varchar(50) | YES | | | 计划ID(英文转译推测) | +| 2 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Plan_Serial` | int | YES | | | 计划Serial(英文转译推测) | +| 4 | `Recipe_ID` | varchar(50) | YES | | | 配方ID(英文转译推测) | +| 5 | `Recipe_Code` | varchar(50) | YES | | | 配方编码(英文转译推测) | +| 6 | `Recipe_Name` | varchar(50) | YES | | | 配方名称(英文转译推测) | +| 7 | `Version` | varchar(50) | YES | | | 版本(英文转译推测) | +| 8 | `Mixer_Line` | varchar(50) | YES | | | Mixer行(英文转译推测) | +| 9 | `Shift_Id` | varchar(10) | YES | | | 班次ID(英文转译推测) | +| 10 | `Plan_Num` | int | YES | | | 计划Num(英文转译推测) | +| 11 | `Start_Date` | varchar(50) | YES | | | 开始日期(英文转译推测) | +| 12 | `End_Date` | varchar(50) | YES | | | 结束日期(英文转译推测) | +| 13 | `Plan_Batch` | varchar(50) | YES | | | 计划批次(英文转译推测) | +| 14 | `Plan_State` | int | YES | | | 计划状态(英文转译推测) | +| 15 | `Plan_Date` | varchar(50) | YES | | | 计划日期(英文转译推测) | +| 16 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 17 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 18 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 2.19 表:IF_RtPlan2Mes + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`IF_RtPlan2Mes` +- **表含义**:接口:生胶计划 -> MES +- **字段数量**:21 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Plan_Id` | varchar(50) | NO | 是 | | 计划ID(英文转译推测) | +| 2 | `Equip_Code` | varchar(50) | YES | | | 设备编码(英文转译推测) | +| 3 | `Plan_Serial` | int | YES | | | 计划Serial(英文转译推测) | +| 4 | `Recipe_ID` | varchar(50) | YES | | | 配方ID(英文转译推测) | +| 5 | `Recipe_Code` | varchar(50) | YES | | | 配方编码(英文转译推测) | +| 6 | `Recipe_Name` | varchar(50) | YES | | | 配方名称(英文转译推测) | +| 7 | `Version` | varchar(50) | YES | | | 版本(英文转译推测) | +| 8 | `Mixer_Line` | varchar(50) | YES | | | Mixer行(英文转译推测) | +| 9 | `Shift_Id` | varchar(10) | YES | | | 班次ID(英文转译推测) | +| 10 | `Plan_Num` | int | YES | | | 计划Num(英文转译推测) | +| 11 | `real_num` | int | YES | | | real num(英文转译推测) | +| 12 | `Start_Date` | varchar(50) | YES | | | 开始日期(英文转译推测) | +| 13 | `End_Date` | varchar(50) | YES | | | 结束日期(英文转译推测) | +| 14 | `Plan_Batch` | varchar(50) | YES | | | 计划批次(英文转译推测) | +| 15 | `Plan_State` | int | YES | | | 计划状态(英文转译推测) | +| 16 | `Plan_Date` | varchar(50) | YES | | | 计划日期(英文转译推测) | +| 17 | `Write_Time` | varchar(20) | YES | | | 写入时间(英文转译推测) | +| 18 | `Read_Time` | varchar(20) | YES | | | 读取时间(英文转译推测) | +| 19 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | +| 20 | `Weight_Man` | varchar(50) | YES | | | 重量Man(英文转译推测) | +| 21 | `Stock_Man` | nvarchar(50) | YES | | | Stock Man(英文转译推测) | + +--- + +## 2.20 表:MCSToMES_Act_Mill + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_Act_Mill` +- **表含义**:MCS->MES:开炼机动作 +- **字段数量**:9 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | NO | | | GUID(英文转译推测) | +| 2 | `act_addr` | int | YES | | | 动作addr(英文转译推测) | +| 3 | `act_name` | varchar(50) | YES | | | 动作名称(英文转译推测) | +| 4 | `act_name_en` | varchar(50) | YES | | | 动作名称en(英文转译推测) | +| 5 | `act_memo` | varchar(20) | YES | | | 动作备注(英文转译推测) | +| 6 | `act_Repaddr` | int | YES | | | 动作Repaddr(英文转译推测) | +| 7 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 8 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 9 | `RW_Flag` | int | YES | | | RW标志(英文转译推测) | + +--- + +## 2.21 表:MCSToMES_BinToMater + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_BinToMater` +- **表含义**:MCS->MES:仓位与物料对应关系 +- **字段数量**:14 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 3 | `EquipName` | varchar(20) | YES | | | 设备名称(英文转译推测) | +| 4 | `EquipType` | varchar(10) | NO | 是 | | 设备类型(英文转译推测) | +| 5 | `ScaleNum` | int | NO | 是 | | 秤Num(英文转译推测) | +| 6 | `ScaleClass` | varchar(20) | YES | | | 秤Class(英文转译推测) | +| 7 | `ScaleName` | varchar(20) | YES | | | 秤名称(英文转译推测) | +| 8 | `BinNo` | int | NO | 是 | | 仓号(英文转译推测) | +| 9 | `MatCode` | varchar(30) | YES | | | 物料编码(英文转译推测) | +| 10 | `MatName` | varchar(50) | YES | | | 物料名称(英文转译推测) | +| 11 | `UseYN` | varchar(1) | YES | | | Use YN(英文转译推测) | +| 12 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 13 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 14 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | + +--- + +## 2.22 表:MCSToMES_CurrEquipState + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_CurrEquipState` +- **表含义**:MCS->MES:当前设备状态 +- **字段数量**:13 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | NO | 是 | | GUID(英文转译推测) | +| 2 | `EquipID` | int | YES | | | 设备ID(英文转译推测) | +| 3 | `EquipName` | varchar(10) | YES | | | 设备名称(英文转译推测) | +| 4 | `EquipType` | varchar(10) | YES | | | 设备类型(英文转译推测) | +| 5 | `SaveTime` | varchar(20) | YES | | | Save时间(英文转译推测) | +| 6 | `RpName` | varchar(40) | YES | | | Rp名称(英文转译推测) | +| 7 | `SetNum` | int | YES | | | Set Num(英文转译推测) | +| 8 | `Serial` | int | YES | | | Serial(英文转译推测) | +| 9 | `MixSpeed` | decimal(18,3) | YES | | | 密炼速度(英文转译推测) | +| 10 | `MixPower` | decimal(10,3) | YES | | | 密炼功率(英文转译推测) | +| 11 | `MixEngery` | decimal(18,3) | YES | | | 密炼Engery(英文转译推测) | +| 12 | `MixTime` | int | YES | | | 密炼时间(英文转译推测) | +| 13 | `MES_Flag` | int | YES | | (0) | MES标志(英文转译推测) | + +--- + +## 2.23 表:MCSToMES_CurrVarData_Convey + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_CurrVarData_Convey` +- **表含义**:MCS->MES:输送线过程变量 +- **字段数量**:7 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | NO | 是 | | GUID(英文转译推测) | +| 2 | `VarName` | varchar(50) | YES | | | Var名称(英文转译推测) | +| 3 | `DataName` | varchar(50) | YES | | | 数据名称(英文转译推测) | +| 4 | `DataValue` | decimal(18,3) | YES | | | 数据数值(英文转译推测) | +| 5 | `CreateTime` | varchar(19) | YES | | | 创建时间(英文转译推测) | +| 6 | `UpdateTime` | varchar(19) | YES | | | 更新时间(英文转译推测) | +| 7 | `MESReadTime` | varchar(19) | YES | | | MES读取时间(英文转译推测) | + +--- + +## 2.24 表:MCSToMES_MixAct + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixAct` +- **表含义**:MCS->MES:密炼动作记录 +- **字段数量**:8 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 2 | `EquipName` | varchar(10) | YES | | | 设备名称(英文转译推测) | +| 3 | `EquipType` | varchar(10) | NO | 是 | | 设备类型(英文转译推测) | +| 4 | `MixActAddress` | int | NO | 是 | | 动作地址 | +| 5 | `MixActName` | varchar(30) | YES | | | 动作名称 | +| 6 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 7 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 8 | `RW_Flag` | int | YES | | (0) | RW标志(英文转译推测) | + +--- + +## 2.25 表:MCSToMES_MixAlarm + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixAlarm` +- **表含义**:MCS->MES:密炼报警 +- **字段数量**:12 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | NO | 是 | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | | | 机台编号 | +| 3 | `EquipName` | varchar(10) | NO | | | 机台名称 | +| 4 | `EquipType` | varchar(10) | NO | | | 机台类型 | +| 5 | `SaveTime` | varchar(19) | YES | | | Save时间(英文转译推测) | +| 6 | `EndTime` | varchar(19) | YES | | | 结束时间(英文转译推测) | +| 7 | `Barcode` | varchar(30) | NO | | | Barcode | +| 8 | `AlmCode` | varchar(6) | YES | | | 报警代码 | +| 9 | `AlarmInf` | varchar(50) | YES | | | 报警内容 | +| 10 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 11 | `ReadTime` | datetime | YES | | (0) | 读取时间(英文转译推测) | +| 12 | `MES_Flag` | int | YES | | (0) | MES标志(英文转译推测) | + +--- + +## 2.26 表:MCSToMES_MixBatch + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixBatch` +- **表含义**:MCS->MES:密炼批次 +- **字段数量**:41 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 机台编号 | +| 3 | `EquipName` | varchar(10) | YES | | | 机台名称 | +| 4 | `EquipType` | varchar(10) | YES | | | 机台类型 | +| 5 | `Barcode` | varchar(30) | NO | 是 | | 计划编号+车次 | +| 6 | `RecipCode` | varchar(30) | YES | | | 配方代码 | +| 7 | `RecipName` | varchar(30) | YES | | | 配方名称 | +| 8 | `MaterCode` | varchar(40) | YES | | | 物料编码(英文转译推测) | +| 9 | `MaterName` | varchar(80) | YES | | | 物料名称(英文转译推测) | +| 10 | `SaveDate` | varchar(10) | YES | | | 保存日期 | +| 11 | `SaveDateTime` | varchar(20) | YES | | | 保存时间 | +| 12 | `ShiftId` | varchar(1) | YES | | | 班次;1:Night 2: Morning 3:Noon | +| 13 | `ShiftClass` | varchar(1) | YES | | | 班组;1:A 2:B 3:C 4:D | +| 14 | `PlanID` | varchar(20) | YES | | | 计划编号 | +| 15 | `SetNum` | int | YES | | | 设定车次 | +| 16 | `StartTim` | varchar(20) | YES | | | 开始时间 | +| 17 | `EndTim` | varchar(20) | YES | | | 结束时间 | +| 18 | `BatchNum` | int | YES | | | 当前车次 | +| 19 | `MixMode` | int | YES | | | 密炼模式1:遥控自动;2:遥控手动;3:本控 | +| 20 | `BatchCycleTim` | int | YES | | | 密炼循环时间(预留) | +| 21 | `CurTim` | int | YES | | | 密炼时间 | +| 22 | `MixTim` | int | YES | | | 预留 | +| 23 | `UsefulMixTim` | int | YES | | | 有效时间 | +| 24 | `IntervalTime` | int | YES | | | 间隔时间 | +| 25 | `DiscTemp` | decimal(18,3) | YES | | | 排胶温度 | +| 26 | `DiscEnergy` | decimal(18,3) | YES | | | 排胶能量 | +| 27 | `DiscTime` | int | YES | | | 排胶时间 | +| 28 | `DiscPower` | int | YES | | | 排胶功率 | +| 29 | `EmgyDiscFlag` | int | YES | | | 排胶方式;0:正常;1:超时;2:超温;3:超能量 | +| 30 | `TCU1Temp` | decimal(18,3) | YES | | | 三区温度1(预留) | +| 31 | `TCU2Temp` | decimal(18,3) | YES | | | 三区温度2(预留) | +| 32 | `TCU3Temp` | decimal(18,3) | YES | | | 三区温度3(预留) | +| 33 | `TCU4Temp` | decimal(18,3) | YES | | | 三区温度4(预留) | +| 34 | `TCUTemp` | decimal(18,3) | YES | | | 三区温度(预留) | +| 35 | `BatchWei` | decimal(18,3) | YES | | | 批次Wei(英文转译推测) | +| 36 | `oper` | varchar(20) | YES | | | oper(英文转译推测) | +| 37 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 38 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 39 | `MES_Flag` | int | YES | | (0) | MES标志(英文转译推测) | +| 40 | `WEIGHT` | decimal(18,3) | YES | | | 重量(英文转译推测) | +| 41 | `MoCode` | varchar(40) | YES | | | Mo编码(英文转译推测) | + +--- + +## 2.27 表:MCSToMES_MixCon + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixCon` +- **表含义**:MCS->MES:密炼消耗/配料明细 +- **字段数量**:8 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 2 | `EquipName` | varchar(10) | YES | | | 设备名称(英文转译推测) | +| 3 | `EquipType` | varchar(10) | NO | 是 | | 设备类型(英文转译推测) | +| 4 | `MixConAddress` | int | NO | 是 | | 密炼ConAddress(英文转译推测) | +| 5 | `MixConName` | varchar(30) | YES | | | 密炼Con名称(英文转译推测) | +| 6 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 7 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 8 | `RW_Flag` | int | YES | | (0) | RW标志(英文转译推测) | + +--- + +## 2.28 表:MCSToMES_MixCurve + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixCurve` +- **表含义**:MCS->MES:密炼曲线数据 +- **字段数量**:9 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 3 | `EquipName` | varchar(10) | YES | | | 设备名称(英文转译推测) | +| 4 | `EquipType` | varchar(10) | NO | 是 | | 设备类型(英文转译推测) | +| 5 | `Barcode` | varchar(30) | NO | 是 | | 条码(英文转译推测) | +| 6 | `CurveData` | ntext(1073741823) | YES | | | Curve数据(英文转译推测) | +| 7 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 8 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 9 | `MES_Flag` | int | YES | | (0) | MES标志(英文转译推测) | + +--- + +## 2.29 表:MCSToMES_mixdata_Mill + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_mixdata_Mill` +- **表含义**:MCS->MES:开炼机混炼数据 +- **字段数量**:14 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `Barcode` | varchar(40) | YES | | | 条码(英文转译推测) | +| 2 | `Serial_id` | int | YES | | | Serial id(英文转译推测) | +| 3 | `Equip_code` | varchar(20) | YES | | | 设备编码(英文转译推测) | +| 4 | `ID` | int | YES | | | ID(英文转译推测) | +| 5 | `StepActAddress` | int | YES | | | 步骤动作Address(英文转译推测) | +| 6 | `StepMixTime` | int | YES | | | 步骤密炼时间(英文转译推测) | +| 7 | `StepMixCoolSpeed` | numeric(18,3) | YES | | | 步骤密炼Cool速度(英文转译推测) | +| 8 | `StepOpenMixSpeed` | numeric(18,3) | YES | | | 步骤Open密炼速度(英文转译推测) | +| 9 | `StepRollor` | numeric(18,3) | YES | | | 步骤Rollor(英文转译推测) | +| 10 | `StepWaterTemp` | numeric(18,3) | YES | | | 步骤Water温度(英文转译推测) | +| 11 | `StepRubTemp` | numeric(18,3) | YES | | | 步骤Rub温度(英文转译推测) | +| 12 | `StepPower` | numeric(18,3) | YES | | | 步骤功率(英文转译推测) | +| 13 | `WaterIn` | numeric(18,3) | YES | | | Water In(英文转译推测) | +| 14 | `Remarks` | varchar(50) | YES | | | 备注s(英文转译推测) | + +--- + +## 2.30 表:MCSToMES_MixExePlan + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixExePlan` +- **表含义**:MCS->MES:密炼执行计划回传 +- **字段数量**:25 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `PlanID` | varchar(20) | NO | 是 | | 计划编号 | +| 3 | `PlanSource` | varchar(1) | NO | 是 | | 计划来源(英文转译推测) | +| 4 | `EquipID` | int | NO | 是 | | 机台编号 | +| 5 | `EquipName` | varchar(10) | YES | | | 机台名称 | +| 6 | `EquipType` | varchar(10) | YES | | | 机台类型CWS:小料;MCS:上辅机 | +| 7 | `PlanDate` | varchar(10) | YES | | | 计划日期 | +| 8 | `ShiftID` | varchar(1) | YES | | | 班次1:Night 2: Morning 3 | +| 9 | `ShiftClass` | varchar(1) | YES | | | 班组1:A 2:B 3:C 4:D | +| 10 | `WorkOrder` | int | YES | | | 计划顺序 | +| 11 | `RecipCode` | varchar(40) | YES | | | 配方代码 | +| 12 | `RecipName` | varchar(40) | YES | | | 配方名称 | +| 13 | `SetNum` | int | YES | | | 设定车次 | +| 14 | `DoneNum` | int | YES | | | 完成车次 | +| 15 | `PlanState` | int | YES | | | 计划状态2:运行;4终止;5:完成 | +| 16 | `PlanStateChange` | int | YES | | | 计划状态有变化 | +| 17 | `StartTime` | datetime | YES | | | 开始时间(英文转译推测) | +| 18 | `EndTime` | datetime | YES | | | 结束时间(英文转译推测) | +| 19 | `WriteTime` | datetime | YES | | | 写入时间 | +| 20 | `ReadTime` | datetime | YES | | | 读取时间 | +| 21 | `MES_Flag` | int | YES | | (0) | 交互标识 | +| 22 | `Remark` | varchar(50) | YES | | | 备注 | +| 23 | `MaterCode` | varchar(50) | YES | | | 物料编码(英文转译推测) | +| 24 | `MaterName` | varchar(50) | YES | | | 物料名称(英文转译推测) | +| 25 | `UploadRunFlag` | int | YES | | ((0)) | UploadRun标志(英文转译推测) | + +--- + +## 2.31 表:MCSToMES_MixStep + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixStep` +- **表含义**:MCS->MES:密炼步骤执行记录 +- **字段数量**:35 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 机台编号 | +| 3 | `EquipName` | varchar(10) | YES | | | 设备名称(英文转译推测) | +| 4 | `EquipType` | varchar(10) | NO | 是 | | 机台类型 | +| 5 | `Barcode` | varchar(30) | NO | 是 | | 条码(英文转译推测) | +| 6 | `SaveTime` | varchar(20) | YES | | | 保存时间 | +| 7 | `MixID` | int | NO | 是 | | 密炼步序 | +| 8 | `Cond` | int | YES | | | 条件地址 | +| 9 | `CondName` | varchar(40) | YES | | | 条件名称 | +| 10 | `Tim` | int | YES | | | 设定时间(预留) | +| 11 | `TimProtect` | int | YES | | | 时间保护(预留) | +| 12 | `TimAct` | int | YES | | | 实际时间 | +| 13 | `Tempe` | decimal(18,3) | YES | | | 设定温度(预留) | +| 14 | `TempProtect` | decimal(18,3) | YES | | | 温度保护(预留) | +| 15 | `TempAct` | decimal(18,3) | YES | | | 温度实际 | +| 16 | `Power` | decimal(18,3) | YES | | | 设定功率(预留) | +| 17 | `PowerProtect` | decimal(18,3) | YES | | | 功率保护(预留) | +| 18 | `PowerAct` | decimal(18,3) | YES | | | 实际功率 | +| 19 | `Energy` | decimal(18,3) | YES | | | 设定能量(预留) | +| 20 | `EnergyProtect` | decimal(18,3) | YES | | | 能量保护(预留) | +| 21 | `EnergyAct` | decimal(18,3) | YES | | | 实际能量 | +| 22 | `Act` | int | YES | | | 动作地址 | +| 23 | `ActName` | varchar(40) | YES | | | 动作名称 | +| 24 | `RamPress` | decimal(18,3) | YES | | | 设定压力(预留) | +| 25 | `RamPressAct` | decimal(18,3) | YES | | | 实际压力 | +| 26 | `RotorSpd` | decimal(18,3) | YES | | | 转速设定(预留) | +| 27 | `RotorSpdAct` | decimal(18,3) | YES | | | 实际转速 | +| 28 | `RamPos` | decimal(18,3) | YES | | | 栓位置设定(预留) | +| 29 | `RamPosAct` | decimal(18,3) | YES | | | 实际栓位置 | +| 30 | `RollGap` | decimal(18,3) | YES | | | 辊距设定(预留) | +| 31 | `RollGapAct` | decimal(18,3) | YES | | | 实际辊距(预留) | +| 32 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 33 | `CtrlMode` | int | YES | | | Ctrl模式(英文转译推测) | +| 34 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 35 | `MES_Flag` | int | YES | | (0) | MES标志(英文转译推测) | + +--- + +## 2.32 表:MCSToMES_MixWeight + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixWeight` +- **表含义**:MCS->MES:密炼称重记录 +- **字段数量**:26 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | NO | 是 | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | | | 机台编号 | +| 3 | `EquipName` | varchar(10) | YES | | | 机台名称 | +| 4 | `EquipType` | varchar(50) | NO | | | 机台类型 | +| 5 | `Barcode` | varchar(30) | NO | | | 条码(英文转译推测) | +| 6 | `SaveTime` | varchar(20) | YES | | | 存储时间 | +| 7 | `MatCode` | varchar(30) | YES | | | 物料代码 | +| 8 | `MatName` | varchar(30) | YES | | | 物料名称 | +| 9 | `ScaleNum` | int | NO | | | 秤编号101:炭黑秤1;102:炭黑秤2;103:炭黑秤3;201:油料秤1;202:油料秤2;203:油料秤3 +301:胶料秤1;302:胶料秤2;401:小料秤1;402:小料秤2 | +| 10 | `BatchNum` | int | YES | | | 车次 | +| 11 | `Act` | int | YES | | | 动作(英文转译推测) | +| 12 | `Idx` | int | NO | | | 序号 | +| 13 | `ShiftNum` | int | YES | | | 第几批称量 | +| 14 | `SetWei` | decimal(18,3) | YES | | | 设定重量 | +| 15 | `SetTol` | decimal(18,3) | YES | | | 设定误差 | +| 16 | `ActWei` | decimal(18,3) | YES | | | 实际重量 | +| 17 | `ActTol` | decimal(18,3) | YES | | | 实际误差 | +| 18 | `StepTim` | int | YES | | | 步时间 | +| 19 | `StepMode` | int | YES | | | 步骤模式(英文转译推测) | +| 20 | `RecipeName` | varchar(30) | YES | | | 配方名称 | +| 21 | `PlanID` | varchar(20) | YES | | | 计划编号 | +| 22 | `SetBatchNum` | int | YES | | | 计划设定 | +| 23 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 24 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 25 | `MES_Flag` | int | YES | | ((0)) | MES标志(英文转译推测) | +| 26 | `MOCode` | varchar(40) | YES | | | MOCode(英文转译推测) | + +--- + +## 2.33 表:MCSToMES_MixWeiRelate + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_MixWeiRelate` +- **表含义**:MCS->MES:称重关联关系 +- **字段数量**:11 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | NO | 是 | | GUID(英文转译推测) | +| 2 | `Barcode` | varchar(40) | YES | | | 条码(英文转译推测) | +| 3 | `EquipID` | int | YES | | | 设备ID(英文转译推测) | +| 4 | `SaveTime` | varchar(20) | YES | | | Save时间(英文转译推测) | +| 5 | `ScaleType` | int | YES | | | 秤类型(英文转译推测) | +| 6 | `ScaleNum` | int | YES | | | 秤Num(英文转译推测) | +| 7 | `BatchNum` | int | YES | | | 批次Num(英文转译推测) | +| 8 | `ShiftNum` | int | YES | | | 班次Num(英文转译推测) | +| 9 | `FeedTim` | int | YES | | | 供料Tim(英文转译推测) | +| 10 | `PlanID` | varchar(30) | YES | | | 计划ID(英文转译推测) | +| 11 | `Mes_Flag` | char(1) | YES | | | MES标志(英文转译推测) | + +--- + +## 2.34 表:MCSToMES_Ppt_Log + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_Ppt_Log` +- **表含义**:MCS->MES:开炼/挤出日志 +- **字段数量**:9 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | YES | | | 设备ID(英文转译推测) | +| 3 | `EquipType` | varchar(10) | YES | | | 设备类型(英文转译推测) | +| 4 | `WorkType` | varchar(20) | YES | | | Work类型(英文转译推测) | +| 5 | `OperDest` | varchar(50) | YES | | | Oper Dest(英文转译推测) | +| 6 | `OccurrenTime` | varchar(20) | YES | | | Occurren时间(英文转译推测) | +| 7 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 8 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 9 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | + +--- + +## 2.35 表:MCSToMES_Ppt_Shutdown + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_Ppt_Shutdown` +- **表含义**:MCS->MES:停机记录 +- **字段数量**:12 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | YES | | | 设备ID(英文转译推测) | +| 3 | `EquipType` | varchar(10) | YES | | | 设备类型(英文转译推测) | +| 4 | `ShutdownType` | varchar(50) | YES | | | 停机类型(英文转译推测) | +| 5 | `StartTime` | varchar(10) | YES | | | 开始时间(英文转译推测) | +| 6 | `EndTime` | varchar(10) | YES | | | 结束时间(英文转译推测) | +| 7 | `StopTimeSecond` | int | YES | | | Stop时间Second(英文转译推测) | +| 8 | `Memo` | varchar(50) | YES | | | 备注(英文转译推测) | +| 9 | `Auto` | int | YES | | | 自动(英文转译推测) | +| 10 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 11 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 12 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | + +--- + +## 2.36 表:MCSToMES_PptShiftConfig + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_PptShiftConfig` +- **表含义**:MCS->MES:开炼班次配置 +- **字段数量**:20 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 3 | `EquipName` | varchar(10) | YES | | | 设备名称(英文转译推测) | +| 4 | `EquipType` | varchar(10) | NO | 是 | | 设备类型(英文转译推测) | +| 5 | `Barcode` | varchar(30) | NO | 是 | | 条码(英文转译推测) | +| 6 | `PlanDate` | datetime | YES | | | 计划日期(英文转译推测) | +| 7 | `PlanID` | varchar(20) | NO | | | 计划ID(英文转译推测) | +| 8 | `ShiftID` | int | YES | | | 班次ID(英文转译推测) | +| 9 | `ClassID` | int | YES | | | Class ID(英文转译推测) | +| 10 | `RecipCode` | varchar(30) | YES | | | Recip编码(英文转译推测) | +| 11 | `RecipName` | varchar(30) | YES | | | Recip名称(英文转译推测) | +| 12 | `BarcodeStart` | int | NO | | | 条码开始(英文转译推测) | +| 13 | `BarcodeEnd` | int | YES | | | 条码结束(英文转译推测) | +| 14 | `TotalWeight` | decimal(18,3) | YES | | | 总重量(英文转译推测) | +| 15 | `RealWeight` | decimal(18,3) | YES | | | 实际重量(英文转译推测) | +| 16 | `Set_ShelfNum` | int | YES | | | Set Shelf Num(英文转译推测) | +| 17 | `ShelfNum` | int | YES | | | Shelf Num(英文转译推测) | +| 18 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 19 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 20 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | + +--- + +## 2.37 表:MCSToMES_RepBatchoff + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_RepBatchoff` +- **表含义**:MCS->MES:排出/落盘回报 +- **字段数量**:30 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | NO | 是 | | GUID(英文转译推测) | +| 2 | `EquipID` | int | YES | | | 设备ID(英文转译推测) | +| 3 | `RpCode` | varchar(50) | YES | | | Rp编码(英文转译推测) | +| 4 | `PlanID` | varchar(40) | YES | | | 计划ID(英文转译推测) | +| 5 | `RFIDCode` | varchar(50) | YES | | | RFIDCode(英文转译推测) | +| 6 | `BOEquipName` | varchar(40) | YES | | | BOEquip名称(英文转译推测) | +| 7 | `RubberType` | int | YES | | | Rubber类型(英文转译推测) | +| 8 | `RubWeight` | decimal(18,3) | YES | | | Rub重量(英文转译推测) | +| 9 | `MinSaveTime` | int | YES | | | 最小Save时间(英文转译推测) | +| 10 | `MaxSaveTime` | int | YES | | | 最大Save时间(英文转译推测) | +| 11 | `ReRubberType` | int | YES | | | ReRubber类型(英文转译推测) | +| 12 | `ReRubberPersion` | int | YES | | | Re Rubber Persion(英文转译推测) | +| 13 | `RubberTrayState` | int | YES | | | RubberTray状态(英文转译推测) | +| 14 | `ReStartTime` | varchar(20) | YES | | | Re开始时间(英文转译推测) | +| 15 | `ReEndTime` | varchar(20) | YES | | | Re结束时间(英文转译推测) | +| 16 | `TrayCount` | int | YES | | | Tray数量(英文转译推测) | +| 17 | `StartSerial` | int | YES | | | 开始Serial(英文转译推测) | +| 18 | `EndSerial` | int | YES | | | 结束Serial(英文转译推测) | +| 19 | `ReRubberWeight` | decimal(18,3) | YES | | | ReRubber重量(英文转译推测) | +| 20 | `ReRubberLength` | decimal(18,3) | YES | | | Re Rubber Length(英文转译推测) | +| 21 | `ReRubberError` | decimal(18,3) | YES | | | ReRubber错误(英文转译推测) | +| 22 | `MDErrorCount` | int | YES | | | MDError数量(英文转译推测) | +| 23 | `SampleCount` | int | YES | | | Sample数量(英文转译推测) | +| 24 | `Re1Length` | decimal(18,3) | YES | | | Re 1 Length(英文转译推测) | +| 25 | `Re2Length` | decimal(18,3) | YES | | | Re 2 Length(英文转译推测) | +| 26 | `Re3Length` | decimal(18,3) | YES | | | Re 3 Length(英文转译推测) | +| 27 | `Re4Length` | decimal(18,3) | YES | | | Re 4 Length(英文转译推测) | +| 28 | `Re5Length` | decimal(18,3) | YES | | | Re 5 Length(英文转译推测) | +| 29 | `SaveTime` | varchar(20) | YES | | | Save时间(英文转译推测) | +| 30 | `MES_Flag` | int | YES | | ((0)) | MES标志(英文转译推测) | + +--- + +## 2.38 表:MCSToMES_Scale_Calibration + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MCSToMES_Scale_Calibration` +- **表含义**:MCS->MES:秤标定记录 +- **字段数量**:11 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `ScaleNum` | int | YES | | | 秤Num(英文转译推测) | +| 3 | `ScaleClass` | varchar(20) | YES | | | 秤Class(英文转译推测) | +| 4 | `ScaleName` | varchar(20) | YES | | | 秤名称(英文转译推测) | +| 5 | `SetValue` | numeric(8,3) | YES | | | Set数值(英文转译推测) | +| 6 | `RealValue` | numeric(8,3) | YES | | | Real数值(英文转译推测) | +| 7 | `ErrValue` | numeric(8,3) | YES | | | Err数值(英文转译推测) | +| 8 | `RealTime` | datetime | YES | | | Real时间(英文转译推测) | +| 9 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 10 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 11 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | + +--- + +## 2.39 表:MESToMCS_BarCodeInfo + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MESToMCS_BarCodeInfo` +- **表含义**:MES->MCS:条码信息下发 +- **字段数量**:12 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(64) | YES | | | GUID(英文转译推测) | +| 2 | `BarCode` | varchar(32) | YES | | | 条码(英文转译推测) | +| 3 | `MatCode` | varchar(32) | YES | | | 物料编码(英文转译推测) | +| 4 | `MatName` | varchar(32) | YES | | | 物料名称(英文转译推测) | +| 5 | `MatCategory` | varchar(32) | YES | | | Mat Category(英文转译推测) | +| 6 | `MatSubcategory` | varchar(32) | YES | | | Mat Subcategory(英文转译推测) | +| 7 | `MatWeight` | numeric(18,2) | YES | | | Mat重量(英文转译推测) | +| 8 | `MatAmount` | numeric(18,2) | YES | | | Mat Amount(英文转译推测) | +| 9 | `IsOutStore` | int | YES | | | Is Out Store(英文转译推测) | +| 10 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 11 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 12 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | + +--- + +## 2.40 表:MESToMCS_Material + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Material` +- **表含义**:MES->MCS:物料主数据下发 +- **字段数量**:17 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 机台号 | +| 3 | `EquipType` | varchar(10) | YES | | | 机台类型,CWS:小料;MCS:上辅机; | +| 4 | `MatCode` | varchar(30) | NO | 是 | | 物料代码 | +| 5 | `MatName` | varchar(30) | YES | | | 物料名称 | +| 6 | `MatBarcode` | varchar(50) | YES | | | 物料条码扫描判断信息 | +| 7 | `MatTypeID` | int | YES | | | Mat类型ID(英文转译推测) | +| 8 | `MatType` | varchar(50) | YES | | | 物料类别 | +| 9 | `MatRubTypeID` | int | YES | | | MatRub类型ID(英文转译推测) | +| 10 | `MatRubType` | varchar(10) | YES | | | 胶料类别,0:胶块;1:胶片;2:胶粒 | +| 11 | `ScaleID` | int | YES | | | 秤ID(英文转译推测) | +| 12 | `ScaleName` | varchar(20) | YES | | | 秤名称(英文转译推测) | +| 13 | `CWSID` | int | YES | | | 小料设备号 | +| 14 | `WriteTime` | datetime | YES | | | 写入时间 | +| 15 | `ReadTime` | datetime | YES | | | 读取时间 | +| 16 | `MES_Flag` | int | YES | | (0) | 交互标识 | +| 17 | `UseBar` | int | YES | | ((0)) | Use Bar(英文转译推测) | + +--- + +## 2.41 表:MESToMCS_MatSendInf + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MESToMCS_MatSendInf` +- **表含义**:MES->MCS:物料发送信息 +- **字段数量**:20 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | YES | | | 设备ID(英文转译推测) | +| 3 | `EquipType` | varchar(10) | YES | | | 设备类型(英文转译推测) | +| 4 | `MatCode` | varchar(30) | YES | | | 物料编码(英文转译推测) | +| 5 | `MatName` | varchar(30) | YES | | | 物料名称(英文转译推测) | +| 6 | `OrderID` | varchar(30) | YES | | | 订单ID(英文转译推测) | +| 7 | `MatID` | varchar(30) | YES | | | Mat ID(英文转译推测) | +| 8 | `Weight` | numeric(18,3) | YES | | | 重量(英文转译推测) | +| 9 | `MatBarcode` | varchar(30) | YES | | | Mat条码(英文转译推测) | +| 10 | `MatKey` | int | YES | | | Mat键(英文转译推测) | +| 11 | `Result` | int | YES | | | 结果(英文转译推测) | +| 12 | `MatTypeID` | int | YES | | | Mat类型ID(英文转译推测) | +| 13 | `MatType` | int | YES | | | Mat类型(英文转译推测) | +| 14 | `ScaleID` | int | YES | | | 秤ID(英文转译推测) | +| 15 | `ScaleName` | varchar(20) | YES | | | 秤名称(英文转译推测) | +| 16 | `MatRubType` | varchar(1) | YES | | | MatRub类型(英文转译推测) | +| 17 | `CWSID` | int | YES | | | CWSID(英文转译推测) | +| 18 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 19 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 20 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | + +--- + +## 2.42 表:MESToMCS_MixPlan + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MESToMCS_MixPlan` +- **表含义**:MES->MCS:密炼计划下发 +- **字段数量**:29 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `PlanId` | varchar(20) | NO | 是 | | 计划编号 | +| 3 | `PlanSource` | varchar(1) | NO | 是 | | 计划来源(英文转译推测) | +| 4 | `EquipId` | int | NO | 是 | | 机台编号 | +| 5 | `EquipName` | varchar(20) | YES | | | 机台名称 | +| 6 | `EquipType` | varchar(10) | YES | | | 机台类型 | +| 7 | `PlanDate` | varchar(10) | YES | | | 计划日期 | +| 8 | `ShiftId` | varchar(1) | YES | | | 班次1:Night 2: Morning 3:Noon | +| 9 | `ShiftClass` | varchar(1) | YES | | | 班组1:A 2:B 3:C 4:D | +| 10 | `WorkOrder` | int | YES | | | 计划顺序 | +| 11 | `RecipCode` | varchar(30) | YES | | | 配方代码 | +| 12 | `RecipName` | varchar(30) | YES | | | 配方名称 | +| 13 | `MaterCode` | varchar(40) | YES | | | 物料编码(英文转译推测) | +| 14 | `MaterName` | varchar(80) | YES | | | 物料名称(英文转译推测) | +| 15 | `MOCode` | varchar(40) | YES | | | MOCode(英文转译推测) | +| 16 | `RcipVersion` | int | YES | | | 配方版本 | +| 17 | `ProType` | int | YES | | | 配方类型1:正式 2:试验 | +| 18 | `SetNum` | int | YES | | | 计划车次 | +| 19 | `DoneNum` | int | YES | | | 完成车次 | +| 20 | `PlanState` | int | YES | | | 计划状态 | +| 21 | `MESPlanChange` | int | YES | | | MES计划变化 | +| 22 | `MCSUpdateTime` | datetime | YES | | | MCS更新时间(英文转译推测) | +| 23 | `MCSPlanChange` | int | YES | | | MCSPlan Change(英文转译推测) | +| 24 | `MESUPdateTime` | datetime | YES | | | MES更新时间(英文转译推测) | +| 25 | `WriteTime` | datetime | YES | | | 写入时间 | +| 26 | `ReadTime` | datetime | YES | | | 读取时间 | +| 27 | `MES_Flag` | int | YES | | ((0)) | MES标志(英文转译推测) | +| 28 | `Remark` | varchar(200) | YES | | | 备注 | +| 29 | `TR_STATE` | int | YES | | | TR状态(英文转译推测) | + +--- + +## 2.43 表:MESToMCS_Recipe + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe` +- **表含义**:MES->MCS:配方主数据下发 +- **字段数量**:49 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | ('') | GUID(英文转译推测) | +| 2 | `EquipId` | int | NO | 是 | | 机台编号 | +| 3 | `EquipName` | varchar(20) | YES | | ('') | 机台名称 | +| 4 | `EquipType` | varchar(10) | NO | 是 | | 机台类型;CWS:小料;MCS:上辅机; | +| 5 | `RecipCode` | varchar(40) | NO | 是 | | 配方代码 | +| 6 | `RecipName` | varchar(40) | YES | | ('') | 配方名称 | +| 7 | `RecipVersion` | int | NO | 是 | | 配方版本 | +| 8 | `ProType` | varchar(10) | NO | 是 | | 配方类型;1:正式 2:试验 3:批量试验 4:1段母炼 5: 2段母炼6:终炼胶 | +| 9 | `IsUse` | int | YES | | | 使用状态1:使用 0:停用 | +| 10 | `Weight` | decimal(18,3) | YES | | ((0)) | 配方总重 | +| 11 | `Dust1RecycleMode` | int | YES | | ((0)) | 回收方式1;0:不回收;1:时间回收;2:重量回收 | +| 12 | `Dust1RecycleVal` | decimal(18,3) | YES | | ((0)) | 回收参数1 | +| 13 | `Dust2RecycleMode` | int | YES | | ((0)) | 回收方式2;0:不回收;1:时间回收;2:重量回收 | +| 14 | `Dust2RecycleVal` | decimal(18,0) | YES | | ((0)) | 回收参数1 | +| 15 | `SetOverTempMinTimVal` | int | YES | | ((0)) | 超温排胶最短时间 | +| 16 | `SetOverTimVal` | int | YES | | ((0)) | 超时排胶时间 | +| 17 | `SetOverTempVal` | decimal(18,2) | YES | | ((0)) | 超温排胶温度 | +| 18 | `SetOverEnergyVal` | decimal(18,3) | YES | | ((0)) | 超能排胶能量 | +| 19 | `FeedLowTempLimit` | decimal(18,3) | YES | | ((0)) | 进胶最低温度 | +| 20 | `FeedHighTempLimit` | decimal(18,3) | YES | | ((0)) | 进胶最高温度 | +| 21 | `FeedRotorSetSpd` | decimal(18,3) | YES | | ((0)) | 备用 | +| 22 | `FeedRotorSetTol` | decimal(18,3) | YES | | ((0)) | 备用 | +| 23 | `IntervalTim` | int | YES | | ((0)) | 最小间隔时间 | +| 24 | `SetTCU1` | decimal(18,3) | YES | | ((0)) | 混炼室温度 | +| 25 | `SetTCU2` | decimal(18,3) | YES | | ((0)) | 转子温度 | +| 26 | `SetTCU3` | decimal(18,3) | YES | | ((0)) | 卸料门温度 | +| 27 | `SetTCU4` | decimal(18,3) | YES | | ((0)) | 备用 | +| 28 | `SetTCU5` | decimal(18,3) | YES | | ((0)) | 备用 | +| 29 | `CtcMaxSpd` | decimal(18,3) | YES | | ((0)) | 最大转速 | +| 30 | `CtcMinSpd` | decimal(18,3) | YES | | ((0)) | 最小转速 | +| 31 | `CtcMaxPress` | decimal(18,0) | YES | | ((0)) | 最大压力 | +| 32 | `CtcMinPress` | decimal(18,3) | YES | | ((0)) | 最小压力 | +| 33 | `CtcLimitTemp` | decimal(18,3) | YES | | ((0)) | 温度保护 | +| 34 | `CtcLimitTim` | int | YES | | ((0)) | 时间保护 | +| 35 | `ShelfLotCount` | int | YES | | ((0)) | Shelf批次数量(英文转译推测) | +| 36 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 37 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 38 | `MES_Flag` | int | YES | | ((0)) | MES标志(英文转译推测) | +| 39 | `Remark` | varchar(50) | YES | | ('') | 备注(英文转译推测) | +| 40 | `AbnormalFeedBack` | varchar(50) | YES | | ('') | Abnormal供料Back(英文转译推测) | +| 41 | `AbortId` | int | YES | | ((0)) | Abort Id(英文转译推测) | +| 42 | `ThreeTemp1` | decimal(18,3) | YES | | ((0)) | Three温度1(英文转译推测) | +| 43 | `ThreeTemp2` | decimal(18,3) | YES | | ((0)) | Three温度2(英文转译推测) | +| 44 | `ThreeTemp3` | decimal(18,3) | YES | | ((0)) | Three温度3(英文转译推测) | +| 45 | `ThreeTemp4` | decimal(18,3) | YES | | ((0)) | Three温度4(英文转译推测) | +| 46 | `RepVersionTxt` | varchar(40) | YES | | | Rep版本Txt(英文转译推测) | +| 47 | `RpType` | int | YES | | ((0)) | Rp类型(英文转译推测) | +| 48 | `ReRubberWeight` | numeric(18,3) | YES | | ((0)) | ReRubber重量(英文转译推测) | +| 49 | `DisTemp` | numeric(18,3) | YES | | ((0)) | Dis温度(英文转译推测) | + +--- + +## 2.44 表:MESToMCS_Recipe_BatchOff + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe_BatchOff` +- **表含义**:MES->MCS:配方排出参数下发 +- **字段数量**:27 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | NO | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 3 | `RpCode` | varchar(50) | NO | 是 | | Rp编码(英文转译推测) | +| 4 | `RubberType` | int | YES | | | Rubber类型(英文转译推测) | +| 5 | `ReRubberType` | int | YES | | | ReRubber类型(英文转译推测) | +| 6 | `ReRubberWeight` | decimal(9,3) | YES | | | ReRubber重量(英文转译推测) | +| 7 | `ReRubberLength` | decimal(9,3) | YES | | | Re Rubber Length(英文转译推测) | +| 8 | `ReRubberCount` | int | YES | | | ReRubber数量(英文转译推测) | +| 9 | `ReRubberHeight` | decimal(9,3) | YES | | | Re Rubber Height(英文转译推测) | +| 10 | `ReRubberSpeed` | decimal(9,3) | YES | | | ReRubber速度(英文转译推测) | +| 11 | `RubberMWeight` | decimal(9,3) | YES | | | Rubber MWeight(英文转译推测) | +| 12 | `ReRubberLimitTemp` | decimal(9,3) | YES | | | ReRubberLimit温度(英文转译推测) | +| 13 | `ReRubberLead` | decimal(9,3) | YES | | | Re Rubber Lead(英文转译推测) | +| 14 | `MinSaveTime` | int | YES | | | 最小Save时间(英文转译推测) | +| 15 | `MaxSaveTime` | int | YES | | | 最大Save时间(英文转译推测) | +| 16 | `PerWeight` | decimal(9,3) | YES | | | Per重量(英文转译推测) | +| 17 | `SampleType` | int | YES | | | Sample类型(英文转译推测) | +| 18 | `SampleWeight` | decimal(9,3) | YES | | | Sample重量(英文转译推测) | +| 19 | `SampleLength` | decimal(9,3) | YES | | | Sample Length(英文转译推测) | +| 20 | `SampleCount` | int | YES | | | Sample数量(英文转译推测) | +| 21 | `RpVersion` | varchar(50) | YES | | | Rp版本(英文转译推测) | +| 22 | `RpVersionID` | int | NO | 是 | | Rp版本ID(英文转译推测) | +| 23 | `HangRubberHeight` | decimal(9,3) | YES | | | Hang Rubber Height(英文转译推测) | +| 24 | `MES_Flag` | int | YES | | | MES标志(英文转译推测) | +| 25 | `RecipVersionID` | int | YES | | | Recip版本ID(英文转译推测) | +| 26 | `ReRubberPos` | int | YES | | | Re Rubber Pos(英文转译推测) | +| 27 | `RecipVersion` | varchar(50) | YES | | | Recip版本(英文转译推测) | + +--- + +## 2.45 表:MESToMCS_Recipe_Delete + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe_Delete` +- **表含义**:MES->MCS:配方删除指令 +- **字段数量**:11 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipId` | int | NO | 是 | | 机台编号 | +| 3 | `EquipName` | varchar(10) | YES | | | 机台名称 | +| 4 | `EquipType` | varchar(10) | NO | 是 | | 机台类型;CWS:小料;MCS:上辅机 | +| 5 | `RecipCode` | varchar(30) | NO | 是 | | 配方(物料)代码 | +| 6 | `RecipVersion` | int | NO | 是 | | 配方(物料)版本 | +| 7 | `User` | varchar(10) | YES | | | 操作人 | +| 8 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 9 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 10 | `MES_Flag` | int | YES | | (0) | MES标志(英文转译推测) | +| 11 | `Remark` | varchar(50) | YES | | | 备注(英文转译推测) | + +--- + +## 2.46 表:MESToMCS_Recipe_MillStep + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe_MillStep` +- **表含义**:MES->MCS:配方开炼步骤下发 +- **字段数量**:21 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | YES | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 3 | `MillID` | int | NO | 是 | | 开炼ID(英文转译推测) | +| 4 | `RpCode` | varchar(50) | NO | 是 | | Rp编码(英文转译推测) | +| 5 | `StepID` | int | NO | 是 | | 步骤ID(英文转译推测) | +| 6 | `MillAction` | int | YES | | | 开炼动作(英文转译推测) | +| 7 | `ActName` | varchar(40) | YES | | | 动作名称(英文转译推测) | +| 8 | `ActName_EN` | varchar(40) | YES | | | 动作名称en(英文转译推测) | +| 9 | `MillTime` | int | YES | | | 开炼时间(英文转译推测) | +| 10 | `MillSpeed` | decimal(18,3) | YES | | | 开炼速度(英文转译推测) | +| 11 | `CoolDeviceSpeed` | decimal(18,3) | YES | | | CoolDevice速度(英文转译推测) | +| 12 | `RollGap` | decimal(18,3) | YES | | | Roll Gap(英文转译推测) | +| 13 | `WaterTemper` | decimal(18,3) | YES | | | Water Temper(英文转译推测) | +| 14 | `RubTemper` | decimal(18,3) | YES | | | Rub Temper(英文转译推测) | +| 15 | `SpeedRatio` | decimal(18,3) | YES | | | 速度Ratio(英文转译推测) | +| 16 | `Spare1` | int | YES | | ((0)) | Spare 1(英文转译推测) | +| 17 | `Spare2` | int | YES | | ((0)) | Spare 2(英文转译推测) | +| 18 | `RpVersionID` | int | NO | 是 | | Rp版本ID(英文转译推测) | +| 19 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 20 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 21 | `MES_Flag` | int | YES | | ((0)) | MES标志(英文转译推测) | + +--- + +## 2.47 表:MESToMCS_Recipe_MixDown + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe_MixDown` +- **表含义**:MES->MCS:配方混炼下传数据 +- **字段数量**:28 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | NO | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 3 | `EquipType` | varchar(20) | NO | 是 | | 设备类型(英文转译推测) | +| 4 | `EquipName` | varchar(20) | YES | | | 设备名称(英文转译推测) | +| 5 | `RpCode` | varchar(50) | NO | 是 | | Rp编码(英文转译推测) | +| 6 | `RpName` | varchar(50) | YES | | | Rp名称(英文转译推测) | +| 7 | `RpVersion` | varchar(50) | YES | | | Rp版本(英文转译推测) | +| 8 | `SetOverTempMinTimVal` | int | YES | | | SetOver温度最小TimVal(英文转译推测) | +| 9 | `SetOverTimVal` | int | YES | | | Set Over Tim Val(英文转译推测) | +| 10 | `SetOverTempVal` | decimal(9,3) | YES | | | SetOver温度Val(英文转译推测) | +| 11 | `SetOverEnergyVal` | decimal(9,3) | YES | | | SetOver能耗Val(英文转译推测) | +| 12 | `FeedLowTempLimit` | decimal(9,3) | YES | | | 供料Low温度Limit(英文转译推测) | +| 13 | `FeedHighTempLimit` | decimal(9,3) | YES | | | 供料High温度Limit(英文转译推测) | +| 14 | `IntervalTim` | int | YES | | | Interval Tim(英文转译推测) | +| 15 | `SetTCU1` | decimal(9,3) | YES | | | Set TCU 1(英文转译推测) | +| 16 | `SetTCU2` | decimal(9,3) | YES | | | Set TCU 2(英文转译推测) | +| 17 | `SetTCU3` | decimal(9,3) | YES | | | Set TCU 3(英文转译推测) | +| 18 | `SetTCU4` | decimal(9,3) | YES | | | Set TCU 4(英文转译推测) | +| 19 | `SetTCU5` | decimal(9,3) | YES | | | Set TCU 5(英文转译推测) | +| 20 | `CtcMaxSpd` | decimal(9,3) | YES | | | Ctc最大Spd(英文转译推测) | +| 21 | `CtcMinSpd` | decimal(9,3) | YES | | | Ctc最小Spd(英文转译推测) | +| 22 | `CtcMaxPress` | decimal(9,3) | YES | | | Ctc最大Press(英文转译推测) | +| 23 | `CtcMinPress` | decimal(9,3) | YES | | | Ctc最小Press(英文转译推测) | +| 24 | `CtcLimitTemp` | decimal(9,3) | YES | | | CtcLimit温度(英文转译推测) | +| 25 | `CtcLimitTim` | int | YES | | | Ctc Limit Tim(英文转译推测) | +| 26 | `SaveTime` | varchar(20) | YES | | | Save时间(英文转译推测) | +| 27 | `LastOper` | varchar(20) | YES | | | Last Oper(英文转译推测) | +| 28 | `RpVersionID` | int | YES | | | Rp版本ID(英文转译推测) | + +--- + +## 2.48 表:MESToMCS_Recipe_MixStep + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe_MixStep` +- **表含义**:MES->MCS:配方密炼步骤下发 +- **字段数量**:26 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | ('') | GUID(英文转译推测) | +| 2 | `EquipId` | int | NO | 是 | | 机台编号 | +| 3 | `EquipName` | varchar(20) | YES | | ('') | 机台名称 | +| 4 | `EquipType` | varchar(10) | NO | 是 | | 机台类型 | +| 5 | `RecipCode` | varchar(30) | NO | 是 | | 配方代码 | +| 6 | `Serial` | int | NO | 是 | | 密炼步序 | +| 7 | `Act` | int | YES | | ((0)) | 动作地址 | +| 8 | `Cond` | int | YES | | ((0)) | 条件地址 | +| 9 | `Time` | int | NO | | ((0)) | 设定时间 | +| 10 | `TimeLimit` | int | YES | | ((0)) | 时间保护 | +| 11 | `Temp` | decimal(18,3) | YES | | ((0)) | 温度 | +| 12 | `TempLimit` | decimal(18,3) | YES | | ((0)) | 温度保护 | +| 13 | `Energy` | decimal(18,3) | YES | | ((0)) | 能量 | +| 14 | `EnergyLimit` | decimal(18,3) | YES | | ((0)) | 能量保护 | +| 15 | `Power` | decimal(18,3) | YES | | ((0)) | 功率 | +| 16 | `PowerLimit` | decimal(18,3) | YES | | ((0)) | 功率保护 | +| 17 | `Press` | decimal(18,3) | YES | | ((0)) | 压力 | +| 18 | `Speed` | decimal(18,3) | YES | | ((0)) | 转速 | +| 19 | `RotorGap` | decimal(18,3) | YES | | ((0)) | 辊距 | +| 20 | `RamPos` | decimal(18,3) | YES | | ((0)) | 栓位置 | +| 21 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 22 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 23 | `MES_Flag` | int | YES | | ((0)) | MES标志(英文转译推测) | +| 24 | `Remark` | varchar(200) | YES | | ('') | 备注(英文转译推测) | +| 25 | `AbnormalFeedBack` | varchar(50) | YES | | ('') | Abnormal供料Back(英文转译推测) | +| 26 | `RecipVersion` | int | NO | 是 | | Recip版本(英文转译推测) | + +--- + +## 2.49 表:MESToMCS_Recipe_MixStep_Down + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe_MixStep_Down` +- **表含义**:MES->MCS:配方密炼步骤下传明细 +- **字段数量**:21 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(50) | NO | | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | 是 | | 设备ID(英文转译推测) | +| 3 | `RpCode` | varchar(50) | NO | 是 | | Rp编码(英文转译推测) | +| 4 | `MixID` | int | NO | 是 | | 密炼ID(英文转译推测) | +| 5 | `Cond` | int | YES | | | Cond(英文转译推测) | +| 6 | `Tim` | int | YES | | | Tim(英文转译推测) | +| 7 | `TimLimit` | int | YES | | | Tim Limit(英文转译推测) | +| 8 | `Tempe` | decimal(18,3) | YES | | | 温度e(英文转译推测) | +| 9 | `TempLimit` | decimal(18,3) | YES | | | 温度Limit(英文转译推测) | +| 10 | `Energy` | decimal(18,3) | YES | | | 能耗(英文转译推测) | +| 11 | `EnergyLimit` | decimal(18,3) | YES | | | 能耗Limit(英文转译推测) | +| 12 | `Power` | int | YES | | | 功率(英文转译推测) | +| 13 | `PowerLimit` | int | YES | | | 功率Limit(英文转译推测) | +| 14 | `Act` | int | YES | | | 动作(英文转译推测) | +| 15 | `Press` | decimal(18,3) | YES | | | Press(英文转译推测) | +| 16 | `RotorSpd` | decimal(18,3) | YES | | | Rotor Spd(英文转译推测) | +| 17 | `RollGap` | decimal(18,3) | YES | | | Roll Gap(英文转译推测) | +| 18 | `RamPos` | decimal(18,3) | YES | | | Ram Pos(英文转译推测) | +| 19 | `RpVersion` | varchar(40) | YES | | | Rp版本(英文转译推测) | +| 20 | `RpVersionID` | int | YES | | | Rp版本ID(英文转译推测) | +| 21 | `Torque` | decimal(18,3) | YES | | | Torque(英文转译推测) | + +--- + +## 2.50 表:MESToMCS_Recipe_Weight + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Recipe_Weight` +- **表含义**:MES->MCS:配方称重物料明细下发 +- **字段数量**:26 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | YES | | | GUID(英文转译推测) | +| 2 | `EquipId` | int | NO | 是 | | 机台编号 | +| 3 | `EquipName` | varchar(20) | YES | | ('') | 机台名称 | +| 4 | `EquipType` | varchar(10) | NO | 是 | ('') | 机台类型 | +| 5 | `RecipCode` | varchar(30) | NO | 是 | ('') | 配方代码 | +| 6 | `ScaleType` | int | NO | 是 | ((0)) | 秤类型1:炭黑 2:油料 3:胶料 4:小料 | +| 7 | `ScaleId` | int | NO | 是 | ((0)) | 秤编号,101:炭黑秤1;102:炭黑秤2;103:炭黑秤3 + 201:油料秤1;202:油料秤2;203:油料秤3;301:胶料秤1;302:胶料秤2;401:小料秤1;402:小料秤2 | +| 8 | `Serial` | int | NO | 是 | ((0)) | 称量步序 | +| 9 | `Action` | int | YES | | ((0)) | 动作;1:称量 2:称到 3:卸料,默认值0 | +| 10 | `BinNo` | int | YES | | ((0)) | 仓号(英文转译推测) | +| 11 | `MatCode` | varchar(30) | YES | | ('') | 物料代码 | +| 12 | `MatName` | varchar(30) | YES | | ('') | 物料名称 | +| 13 | `SetWeight` | decimal(18,3) | YES | | ((0)) | 设定重量 | +| 14 | `Tolerance` | decimal(18,3) | YES | | ((0)) | 设定误差 | +| 15 | `SFNum` | int | YES | | ((0)) | 导切机编号 | +| 16 | `MatType` | varchar(10) | YES | | ('') | 炭黑、油料、胶料、小料 | +| 17 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 18 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 19 | `MES_Flag` | int | YES | | ((0)) | MES标志(英文转译推测) | +| 20 | `Remark` | varchar(50) | YES | | ('') | 备注(英文转译推测) | +| 21 | `RubTypeID` | int | YES | | ((0)) | Rub类型ID(英文转译推测) | +| 22 | `MixID` | int | NO | 是 | | 密炼ID(英文转译推测) | +| 23 | `AbnormalFeedBack` | varchar(50) | YES | | ('') | Abnormal供料Back(英文转译推测) | +| 24 | `AbortId` | int | YES | | ((0)) | Abort Id(英文转译推测) | +| 25 | `RecipVersion` | int | NO | 是 | | Recip版本(英文转译推测) | +| 26 | `SetDnTol` | decimal(18,3) | YES | | ((0)) | SetDn容差(英文转译推测) | + +--- + +## 2.51 表:MESToMCS_Verify + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`MESToMCS_Verify` +- **表含义**:MES->MCS:校验/核对数据 +- **字段数量**:12 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `GUID` | varchar(40) | NO | 是 | | GUID(英文转译推测) | +| 2 | `EquipID` | int | NO | | | 机台编号 | +| 3 | `EquipName` | varchar(10) | YES | | | 机台名称 | +| 4 | `EquipType` | varchar(10) | NO | | | 机台类型 | +| 5 | `ScaleNum` | int | NO | | | 秤编号 | +| 6 | `PlanId` | varchar(20) | YES | | | 计划编号 | +| 7 | `MatCode` | varchar(30) | YES | | | 物料代码 | +| 8 | `MatName` | varchar(30) | YES | | | 物料名称 | +| 9 | `Judge` | int | YES | | | 判断结果 | +| 10 | `WriteTime` | datetime | YES | | | 写入时间(英文转译推测) | +| 11 | `ReadTime` | datetime | YES | | | 读取时间(英文转译推测) | +| 12 | `MES_Flag` | int | YES | | (0) | MES标志(英文转译推测) | + +--- + +## 2.52 表:PptScanBarcode + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`PptScanBarcode` +- **表含义**:条码扫描当前表 +- **字段数量**:13 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `SerialID` | int | NO | 是 | | Serial ID(英文转译推测) | +| 2 | `Barcode` | varchar(25) | NO | 是 | | 条码(英文转译推测) | +| 3 | `EquipCode` | char(5) | NO | 是 | | 设备编码(英文转译推测) | +| 4 | `MaterCode` | char(13) | NO | 是 | | 物料编码(英文转译推测) | +| 5 | `MaterName` | nvarchar(80) | YES | | | 物料名称(英文转译推测) | +| 6 | `MaterType` | char(1) | YES | | | 物料类型(英文转译推测) | +| 7 | `MaterTypeName` | char(10) | YES | | | 物料类型名称(英文转译推测) | +| 8 | `BarchNo` | varchar(50) | YES | | | Barch编号(英文转译推测) | +| 9 | `ScanWeight` | decimal(18,2) | YES | | ((0)) | 扫描重量(英文转译推测) | +| 10 | `UsedWeight` | decimal(18,2) | YES | | | Used重量(英文转译推测) | +| 11 | `QueueIndex` | int | YES | | | Queue索引(英文转译推测) | +| 12 | `IsUsed` | char(1) | YES | | | Is Used(英文转译推测) | +| 13 | `ScanDateTime` | datetime | YES | | | 扫描日期时间(英文转译推测) | + +--- + +## 2.53 表:PptScanBarcodeHis + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`PptScanBarcodeHis` +- **表含义**:条码扫描历史表 +- **字段数量**:15 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `ObjId` | int | NO | 是 | | Obj Id(英文转译推测) | +| 2 | `SerialID` | int | NO | | | Serial ID(英文转译推测) | +| 3 | `Barcode` | varchar(25) | NO | | | 条码(英文转译推测) | +| 4 | `EquipCode` | char(5) | NO | | | 设备编码(英文转译推测) | +| 5 | `MaterCode` | char(13) | NO | | | 物料编码(英文转译推测) | +| 6 | `MaterName` | nvarchar(80) | YES | | | 物料名称(英文转译推测) | +| 7 | `MaterType` | char(1) | YES | | | 物料类型(英文转译推测) | +| 8 | `MaterTypeName` | char(10) | YES | | | 物料类型名称(英文转译推测) | +| 9 | `BarchNo` | varchar(50) | YES | | | Barch编号(英文转译推测) | +| 10 | `ScanWeight` | decimal(18,2) | YES | | | 扫描重量(英文转译推测) | +| 11 | `UsedWeight` | decimal(18,2) | YES | | | Used重量(英文转译推测) | +| 12 | `QueueIndex` | int | YES | | | Queue索引(英文转译推测) | +| 13 | `IsUsed` | char(1) | YES | | | Is Used(英文转译推测) | +| 14 | `ScanDateTime` | datetime | YES | | | 扫描日期时间(英文转译推测) | +| 15 | `UpdateDateTime` | datetime | YES | | | 更新日期时间(英文转译推测) | + +--- + +## 2.54 表:PptScanBarcodeLog + +- **所属数据库**:`MESNAC_MCS_ShareDB_XL` +- **Schema**:`dbo` +- **表名**:`PptScanBarcodeLog` +- **表含义**:条码扫描日志表 +- **字段数量**:12 + +### 字段说明 + +| 序号 | 字段名 | 数据类型 | 可空 | 主键 | 默认值 | 字段含义 | +| --- | --- | --- | --- | --- | --- | --- | +| 1 | `dt` | datetime | NO | 是 | (getdate()) | dt(英文转译推测) | +| 2 | `EquipCode` | char(5) | NO | 是 | | 设备编码(英文转译推测) | +| 3 | `RecipeCode` | varchar(20) | YES | | | 配方编码(英文转译推测) | +| 4 | `scanBarcode` | varchar(30) | YES | | | 扫描条码(英文转译推测) | +| 5 | `ScanMaterCode` | char(13) | YES | | | 扫描物料编码(英文转译推测) | +| 6 | `msg` | varchar(200) | YES | | | msg(英文转译推测) | +| 7 | `Usercode` | varchar(10) | YES | | | 用户编码(英文转译推测) | +| 8 | `shiftid` | varchar(4) | YES | | | 班次ID(英文转译推测) | +| 9 | `shiftclass` | varchar(4) | YES | | | shiftclass(英文转译推测) | +| 10 | `scanflag` | varchar(1) | YES | | | 扫描标志(英文转译推测) | +| 11 | `ScanLogSignal` | int | YES | | | 扫描日志Signal(英文转译推测) | +| 12 | `ScanUsedBarMsg` | varchar(500) | YES | | | 扫描UsedBarMsg(英文转译推测) | + +--- diff --git a/doc/MCS_SQLServer_表结构说明.xlsx b/doc/MCS_SQLServer_表结构说明.xlsx new file mode 100644 index 00000000..ec41c49a Binary files /dev/null and b/doc/MCS_SQLServer_表结构说明.xlsx differ diff --git a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java index 874d9b1c..57f3cb3c 100644 --- a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java +++ b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java @@ -230,6 +230,10 @@ public class ShiroConfig { filterChainDefinitionMap.put("/sys/category/anon/**", "anon"); // 桌面端用户反同步批量上报(Outbox -> /sys/sync/batch) filterChainDefinitionMap.put("/sys/sync/batch", "anon"); + //update-begin---author:cursor ---date:2026-07-20 for:【设备库桥接】桌面代理免密接口----------- + filterChainDefinitionMap.put("/sys/device/agent/**", "anon"); + filterChainDefinitionMap.put("/xslmes/deviceAgent/anon/**", "anon"); + //update-end---author:cursor ---date:2026-07-20 for:【设备库桥接】桌面代理免密接口----------- // 添加自己的过滤器并且取名为jwt Map filterMap = new HashMap(1); diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 index 20e28ec2..0e4c8fdd 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/doc/代码修改日志 @@ -1258,7 +1258,111 @@ JeecgUniapp-master/src/pages/rawMaterialInspect/rawMaterialInspect.vue JeecgUniapp-master/src/pages/rawMaterialInspect/inspectResult.vue JeecgUniapp-master/src/common/work.ts --- author:GHT---date:20260730--for: XSLMES-20260730-DING-PULLֶ̨ȡǿܼ --- +-- author:jiangxh---date:20260728--for: ����������������������/�����Ϊͬһ�豸��Ψһ --- +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslMixerConditionService.java +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixerConditionServiceImpl.java +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslMixerConditionController.java +jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/MesXslMixerCondition.api.ts +jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/MesXslMixerCondition.data.ts + +-- author:jiangxh---date:20260729--for: �����ʾ������ϸ������%/���������λС�� --- +jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.data.ts +jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaSpecModal.vue +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java + +-- author:jiangxh---date:20260729--for: ������ʾ��������ϵ��3λ��ĸ������3λ��������2λ --- +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java + +-- author:jiangxh---date:20260729--for: ������ʾ�������������ر�����λС�� --- +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts +jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java + +-- author:jiangxh---date:20260729--for: �����ϲ�ѯ����������/���ϼ�ʾ��ѡ�ϸ�Ϊģ����ѯ --- +jeecgboot-vue3/src/views/mes/material/materialQuery.util.ts +jeecgboot-vue3/src/views/mes/material/MesMixerMaterialList.vue +jeecgboot-vue3/src/views/mes/material/MesMaterialList.vue +jeecgboot-vue3/src/views/mes/material/modules/MesMixerMaterialSelectModal.vue +jeecgboot-vue3/src/views/mes/material/modules/MesMaterialSelectModal.vue +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue + +-- author:jiangxh---date:20260729--for: ����������/���ϡ������༭У�����������Ψһ --- +jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.api.ts +jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.data.ts +jeecgboot-vue3/src/views/mes/material/MesMaterial.api.ts +jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts + +-- author:jiangxh---date:20260729--for: ���������ϡ�����Ĭ�ϱ�����365�� --- +jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.data.ts +yy-admin-master/YY.Admin/ViewModels/MixerMaterial/MixerMaterialEditDialogViewModel.cs + +-- author:jiangxh---date:20260729--for: �����ʾ������ϸ����%/���ͳһ������λС�� --- +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java +jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_171__mes_xsl_formula_spec_line_decimal3.sql +jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.data.ts +jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaSpecModal.vue + +-- author:jiangxh---date:20260729--for: ��WebSocket��pongTimeout 1s��10s ���������������� --- +jeecgboot-vue3/src/hooks/web/useWebSocket.ts + +-- author:jiangxh---date:20260729--for: ��WebSocket���޸�������Redis�ذ���ʱ����Ƶ���������� --- +jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/websocket/WebSocket.java +jeecgboot-vue3/src/hooks/web/useWebSocket.ts + +-- author:jiangxh---date:20260729--for: ��HTTP��Ĭ�ϳ�ʱ10s��60s�����ʾ������120s --- +jeecgboot-vue3/src/utils/http/axios/index.ts +jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.api.ts + +-- author:jiangxh---date:20260729--for: ������ʾ�����ɡ�B/F���ϸ�Ϊ�����б�ƥ�䣬��������ʾ��ά�� --- +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java + +-- author:jiangxh---date:20260729--for: ������ʾ�����ɡ��ս���ϸĸ���д��뽺������ --- +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java + +-- author:jiangxh---date:20260729--for: ��ѡ�ϵ��������ʾ��/����ʾ��ѡ����ȥ�����ϱ�� --- +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue +jeecgboot-vue3/src/views/mes/material/modules/MesMaterialSelectModal.vue +jeecgboot-vue3/src/views/mes/material/materialQuery.util.ts + +-- author:jiangxh---date:20260730--for: ������ʾ�����ɡ��б������ɻ���ʾ��Ԥ��ʱ��ƥ�佺���б� --- +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java +jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaGenerateMixingModal.vue + +-- author:jiangxh---date:20260730--for: ������ʾ�����ɡ�B/Fƥ���Ž�ǰ׺+����������ƴSA01�Ȱ汾��׺ --- +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java + +-- author:jiangxh---date:20260730--for: �����ϡ�ȥ�����ϱ��ҵ���ֶΣ�ƥ������������� --- +jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/entity/MesMaterial.java +jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMaterialController.java +jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMaterialService.java +jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMaterialServiceImpl.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixingSpecServiceImpl.java +jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts +jeecgboot-vue3/src/views/mes/material/MesMaterial.api.ts +jeecgboot-vue3/src/views/mes/material/modules/MesMaterialSelectModal.vue +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts + +-- author:jiangxh---date:20260730--for: �����ϡ��ָ�������������������һ��ȥ����ŸĶ� --- +jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/entity/MesMaterial.java +jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMaterialController.java +jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMaterialService.java +jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMaterialServiceImpl.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslFormulaSpecServiceImpl.java +jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixingSpecServiceImpl.java +jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts +jeecgboot-vue3/src/views/mes/material/MesMaterial.api.ts +jeecgboot-vue3/src/views/mes/material/modules/MesMaterialSelectModal.vue +jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts + +-- author:jiangxh---date:20260730--for: �����ϡ�����б�/�������أ�����ʱ�Զ��뽺������һ�� --- +jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMaterialController.java +jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts + +-- author:GHT---date:20260730--for: ��XSLMES-20260730-DING-PULL������̨���ֶ���ȡ���������ǿ�����ܼ��� --- jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/approval/integration/engine/IntegrationForceReplayHolder.java jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/approval/integration/engine/IntegrationOrchestrator.java jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/dingtalk/stream/DingApprovalManualPullService.java @@ -1267,4 +1371,4 @@ jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/app jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_164__mes_xsl_approval_record_pull_ding_result.sql jeecgboot-vue3/src/views/xslmes/approval/mesXslApprovalRecord/MesXslApprovalRecordList.vue jeecgboot-vue3/src/views/xslmes/approval/mesXslApprovalRecord/MesXslApprovalRecord.api.ts --- author:GHT---date:20260730--for: XSLMES-20260730-DING-PULLֶ̨ȡǿܼ --- +-- author:GHT---date:20260730--for: ��XSLMES-20260730-DING-PULL������̨���ֶ���ȡ���������ǿ�����ܼ��� --- diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/pom.xml b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/pom.xml index d6825359..085807f0 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/pom.xml +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/pom.xml @@ -36,5 +36,11 @@ jeecg-module-print ${jeecgboot.version} + + + org.jeecgframework.boot3 + jeecg-module-device-sync + ${jeecgboot.version} + diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslAutoSmallMaterialDemandPlanController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslAutoSmallMaterialDemandPlanController.java index 68ee8818..bf72f3c5 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslAutoSmallMaterialDemandPlanController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslAutoSmallMaterialDemandPlanController.java @@ -130,6 +130,7 @@ public class MesXslAutoSmallMaterialDemandPlanController { } sql.append("GROUP BY "); + sql.append(statDateExpr).append(", "); if (groupedByMachine) { sql.append(machineExpr).append(", "); } @@ -160,14 +161,20 @@ public class MesXslAutoSmallMaterialDemandPlanController { private String buildOrderBy(boolean groupedByMachine) { if (groupedByMachine) { - return " ORDER BY machineName, rawMaterialName"; + return " ORDER BY statDate DESC, machineName, rawMaterialName"; } - return " ORDER BY rawMaterialName"; + return " ORDER BY statDate DESC, rawMaterialName"; } private String buildRowId(MesXslSmallMaterialDemandPlanSummary row, boolean groupedByMachine, int seq) { String machine = groupedByMachine ? StringUtils.defaultString(row.getMachineName()) : "ALL"; - return machine + "_" + StringUtils.defaultString(row.getRawMaterialName()) + "_" + seq; + return StringUtils.defaultString(row.getStatDate()) + + "_" + + machine + + "_" + + StringUtils.defaultString(row.getRawMaterialName()) + + "_" + + seq; } private String trim(String value) { diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslManualSmallMaterialDemandPlanController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslManualSmallMaterialDemandPlanController.java index 6e31ea70..868a7d1d 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslManualSmallMaterialDemandPlanController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslManualSmallMaterialDemandPlanController.java @@ -130,6 +130,7 @@ public class MesXslManualSmallMaterialDemandPlanController { } sql.append("GROUP BY "); + sql.append(statDateExpr).append(", "); if (groupedByMachine) { sql.append(machineExpr).append(", "); } @@ -160,14 +161,20 @@ public class MesXslManualSmallMaterialDemandPlanController { private String buildOrderBy(boolean groupedByMachine) { if (groupedByMachine) { - return " ORDER BY machineName, rawMaterialName"; + return " ORDER BY statDate DESC, machineName, rawMaterialName"; } - return " ORDER BY rawMaterialName"; + return " ORDER BY statDate DESC, rawMaterialName"; } private String buildRowId(MesXslSmallMaterialDemandPlanSummary row, boolean groupedByMachine, int seq) { String machine = groupedByMachine ? StringUtils.defaultString(row.getMachineName()) : "ALL"; - return machine + "_" + StringUtils.defaultString(row.getRawMaterialName()) + "_" + seq; + return StringUtils.defaultString(row.getStatDate()) + + "_" + + machine + + "_" + + StringUtils.defaultString(row.getRawMaterialName()) + + "_" + + seq; } private String trim(String value) { diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslMillActionController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslMillActionController.java new file mode 100644 index 00000000..351f7739 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslMillActionController.java @@ -0,0 +1,60 @@ +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 org.apache.shiro.authz.annotation.RequiresPermissions; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.base.controller.JeecgController; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.modules.xslmes.entity.MesXslMillAction; +import org.jeecg.modules.xslmes.service.IMesXslMillActionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.ModelAndView; + +/** + * MES 开炼机动作接收表 + */ +@Tag(name = "开炼机动作接收") +@RestController +@RequestMapping("/xslmes/mesXslMillAction") +public class MesXslMillActionController extends JeecgController { + + @Autowired private IMesXslMillActionService mesXslMillActionService; + + @Operation(summary = "开炼机动作接收-分页列表查询") + @GetMapping("/list") + public Result> queryPageList( + MesXslMillAction model, + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, + HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(model, req.getParameterMap()); + queryWrapper.orderByDesc("update_time"); + IPage pageList = mesXslMillActionService.page(new Page<>(pageNo, pageSize), queryWrapper); + return Result.OK(pageList); + } + + @Operation(summary = "开炼机动作接收-通过id查询") + @GetMapping("/queryById") + public Result queryById(@RequestParam(name = "id", required = true) String id) { + MesXslMillAction entity = mesXslMillActionService.getById(id); + if (entity == null) { + return Result.error("未找到对应数据"); + } + return Result.OK(entity); + } + + @RequiresPermissions("xslmes:mes_xsl_mill_action:exportXls") + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, MesXslMillAction model) { + return super.exportXls(request, model, MesXslMillAction.class, "开炼机动作接收"); + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslMixerConditionController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslMixerConditionController.java index 90dfc038..f30ebd8d 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslMixerConditionController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslMixerConditionController.java @@ -110,31 +110,43 @@ public class MesXslMixerConditionController return Result.OK(entity); } - @Operation(summary = "校验条件名称是否重复") + @Operation(summary = "校验条件名称是否重复(同一设备下)") @GetMapping("/checkConditionName") public Result checkConditionName( @RequestParam(name = "conditionName", required = true) String conditionName, + @RequestParam(name = "equipmentId", required = false) String equipmentId, @RequestParam(name = "dataId", required = false) String dataId) { if (oConvertUtils.isEmpty(conditionName) || conditionName.trim().isEmpty()) { return Result.OK("该值可用!"); } - if (mesXslMixerConditionService.isConditionNameDuplicated(conditionName, dataId)) { - return Result.error("条件名称不能重复"); + //update-begin---author:jiangxh ---date:20260728 for:【密炼机条件】条件名称按设备唯一----------- + if (oConvertUtils.isEmpty(equipmentId) || equipmentId.trim().isEmpty()) { + return Result.OK("该值可用!"); } + if (mesXslMixerConditionService.isConditionNameDuplicated(conditionName, equipmentId, dataId)) { + return Result.error("同一设备下条件名称不能重复"); + } + //update-end---author:jiangxh ---date:20260728 for:【密炼机条件】条件名称按设备唯一----------- return Result.OK("该值可用!"); } - @Operation(summary = "校验条件代码是否重复") + @Operation(summary = "校验条件代码是否重复(同一设备下)") @GetMapping("/checkConditionCode") public Result checkConditionCode( @RequestParam(name = "conditionCode", required = true) String conditionCode, + @RequestParam(name = "equipmentId", required = false) String equipmentId, @RequestParam(name = "dataId", required = false) String dataId) { if (oConvertUtils.isEmpty(conditionCode) || conditionCode.trim().isEmpty()) { return Result.OK("该值可用!"); } - if (mesXslMixerConditionService.isConditionCodeDuplicated(conditionCode, dataId)) { - return Result.error("条件代码不能重复"); + //update-begin---author:jiangxh ---date:20260728 for:【密炼机条件】条件代码按设备唯一----------- + if (oConvertUtils.isEmpty(equipmentId) || equipmentId.trim().isEmpty()) { + return Result.OK("该值可用!"); } + if (mesXslMixerConditionService.isConditionCodeDuplicated(conditionCode, equipmentId, dataId)) { + return Result.error("同一设备下条件代码不能重复"); + } + //update-end---author:jiangxh ---date:20260728 for:【密炼机条件】条件代码按设备唯一----------- return Result.OK("该值可用!"); } @@ -153,16 +165,20 @@ public class MesXslMixerConditionController return "条件名称不能为空"; } model.setConditionName(model.getConditionName().trim()); - if (mesXslMixerConditionService.isConditionNameDuplicated(model.getConditionName(), excludeId)) { - return "条件名称不能重复"; + //update-begin---author:jiangxh ---date:20260728 for:【密炼机条件】条件名称/代码按设备唯一----------- + if (mesXslMixerConditionService.isConditionNameDuplicated( + model.getConditionName(), model.getEquipmentId(), excludeId)) { + return "同一设备下条件名称不能重复"; } if (oConvertUtils.isEmpty(model.getConditionCode()) || StringUtils.isBlank(model.getConditionCode())) { return "条件代码不能为空"; } model.setConditionCode(model.getConditionCode().trim()); - if (mesXslMixerConditionService.isConditionCodeDuplicated(model.getConditionCode(), excludeId)) { - return "条件代码不能重复"; + if (mesXslMixerConditionService.isConditionCodeDuplicated( + model.getConditionCode(), model.getEquipmentId(), excludeId)) { + return "同一设备下条件代码不能重复"; } + //update-end---author:jiangxh ---date:20260728 for:【密炼机条件】条件名称/代码按设备唯一----------- return null; } } diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslRawMaterialDemandPlanController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslRawMaterialDemandPlanController.java index c3974483..da757aca 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslRawMaterialDemandPlanController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslRawMaterialDemandPlanController.java @@ -95,9 +95,12 @@ public class MesXslRawMaterialDemandPlanController { private String buildGroupedSql( MesXslRawMaterialDemandPlanSummary query, boolean groupedByMachine, List params) { - String planDateExpr = "DATE(t.plan_date)"; + boolean hasPlanDate = hasColumn("mes_xsl_raw_material_demand_plan", "plan_date"); + boolean hasMaterialId = hasColumn("mes_xsl_raw_material_demand_plan", "material_id"); + String planDateExpr = hasPlanDate ? "t.plan_date" : "DATE(t.create_time)"; String machineExpr = "COALESCE(NULLIF(TRIM(t.machine_name),''), '')"; - String materialIdExpr = "COALESCE(NULLIF(TRIM(t.material_id),''), '')"; + String materialIdExpr = + hasMaterialId ? "COALESCE(NULLIF(TRIM(t.material_id),''), '')" : "''"; String erpCodeExpr = "COALESCE(NULLIF(TRIM(t.erp_code),''), '')"; String rawMaterialExpr = "COALESCE(NULLIF(TRIM(t.raw_material_name),''), '')"; @@ -192,4 +195,12 @@ public class MesXslRawMaterialDemandPlanController { private String trim(String value) { return value == null ? "" : value.trim(); } + + private boolean hasColumn(String tableName, String columnName) { + String sql = + "SELECT COUNT(1) FROM information_schema.COLUMNS " + + "WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?"; + Long count = jdbcTemplate.queryForObject(sql, Long.class, tableName, columnName); + return count != null && count > 0; + } } diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/deviceagent/MesXslDeviceAgentAnonController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/deviceagent/MesXslDeviceAgentAnonController.java new file mode 100644 index 00000000..bb91843c --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/deviceagent/MesXslDeviceAgentAnonController.java @@ -0,0 +1,113 @@ +package org.jeecg.modules.xslmes.deviceagent; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.jeecg.common.api.vo.Result; +import org.jeecg.modules.device.sync.agent.DeviceAgentCommandService; +import org.jeecg.modules.device.sync.agent.DeviceAgentResult; +import org.jeecg.modules.device.sync.agent.DeviceAgentSession; +import org.jeecg.modules.device.sync.agent.DeviceAgentSessionRegistry; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 桌面设备代理免密接口(注册/心跳/分块回传)。 + */ +@Tag(name = "桌面设备代理") +@Slf4j +@RestController +@RequestMapping("/xslmes/deviceAgent/anon") +@RequiredArgsConstructor +public class MesXslDeviceAgentAnonController { + + private final DeviceAgentSessionRegistry sessionRegistry; + private final DeviceAgentCommandService commandService; + + @Operation(summary = "注册/心跳") + @PostMapping("/register") + public Result> register(@RequestBody Map body) { + String deviceId = str(body, "deviceId"); + if (StringUtils.isBlank(deviceId)) { + return Result.error("deviceId不能为空"); + } + String hostName = str(body, "hostName"); + Boolean dbConnected = bool(body.get("dbConnected")); + String dbMessage = str(body, "dbMessage"); + sessionRegistry.registerOrHeartbeat(deviceId, hostName, dbConnected, dbMessage); + Map data = new HashMap<>(); + data.put("deviceId", deviceId); + data.put("accepted", true); + return Result.OK(data); + } + + @Operation(summary = "心跳") + @PostMapping("/heartbeat") + public Result heartbeat(@RequestBody Map body) { + String deviceId = str(body, "deviceId"); + if (StringUtils.isBlank(deviceId)) { + return Result.error("deviceId不能为空"); + } + sessionRegistry.registerOrHeartbeat(deviceId, str(body, "hostName"), bool(body.get("dbConnected")), str(body, "dbMessage")); + return Result.OK("ok"); + } + + @Operation(summary = "命令结果分块回传(大数据量)") + @PostMapping("/resultChunk") + public Result resultChunk(@RequestBody DeviceAgentResult result) { + if (result == null || StringUtils.isBlank(result.getRequestId())) { + return Result.error("requestId不能为空"); + } + // 当前实现:整包完成;桌面可在单次 chunk 中带 lastChunk=true 直接完成 + if (Boolean.TRUE.equals(result.getLastChunk()) || result.getChunkTotal() == null || result.getChunkTotal() <= 1) { + commandService.completeResult(result); + } else { + log.info("收到分块回传 requestId={} chunk={}/{}", result.getRequestId(), result.getChunkIndex(), result.getChunkTotal()); + // 简化:仅最后一块完成;中间块忽略合并(桌面端大结果优先走单次 STOMP 或一次 REST 全量) + if (Boolean.TRUE.equals(result.getLastChunk())) { + commandService.completeResult(result); + } + } + return Result.OK("ok"); + } + + @Operation(summary = "在线代理列表") + @GetMapping("/online") + public Result> online() { + return Result.OK(sessionRegistry.listOnline()); + } + + @Operation(summary = "查询代理状态") + @GetMapping("/status") + public Result status(@RequestParam(name = "deviceId", required = false) String deviceId) { + return Result.OK(sessionRegistry.pickOnlineAgent(deviceId)); + } + + private static String str(Map body, String key) { + if (body == null || body.get(key) == null) { + return null; + } + String v = String.valueOf(body.get(key)).trim(); + return v.isEmpty() || "null".equalsIgnoreCase(v) ? null : v; + } + + private static Boolean bool(Object v) { + if (v == null) { + return null; + } + if (v instanceof Boolean) { + return (Boolean) v; + } + return Boolean.parseBoolean(String.valueOf(v)); + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslMillAction.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslMillAction.java new file mode 100644 index 00000000..9e50eee1 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslMillAction.java @@ -0,0 +1,86 @@ +package org.jeecg.modules.xslmes.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.Serializable; +import java.util.Date; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +/** + * MES 开炼机动作接收表(采集自 MCSToMES_Act_Mill) + */ +@Data +@TableName("mes_xsl_mill_action") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@Schema(description = "MES开炼机动作接收表") +public class MesXslMillAction implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_ID) + private String id; + + @Excel(name = "GUID", width = 36) + @Schema(description = "源表GUID") + private String guid; + + @Excel(name = "动作地址", width = 10) + @Schema(description = "动作地址") + private Integer actAddr; + + @Excel(name = "动作名称", width = 20) + @Schema(description = "动作名称") + private String actName; + + @Excel(name = "动作名称(英)", width = 20) + @Schema(description = "动作名称(英)") + private String actNameEn; + + @Excel(name = "动作备注", width = 15) + @Schema(description = "动作备注") + private String actMemo; + + @Excel(name = "动作关联地址", width = 12) + @Schema(description = "动作关联地址") + private Integer actRepaddr; + + @Excel(name = "写入时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Schema(description = "写入时间") + private Date writeTime; + + @Excel(name = "读取时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Schema(description = "读取时间") + private Date readTime; + + @Excel(name = "读写标识", width = 10) + @Schema(description = "读写标识") + private Integer rwFlag; + + private Integer tenantId; + private String sysOrgCode; + private String createBy; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + private String updateBy; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + private Integer delFlag; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mapper/MesXslMillActionMapper.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mapper/MesXslMillActionMapper.java new file mode 100644 index 00000000..1ba4300c --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mapper/MesXslMillActionMapper.java @@ -0,0 +1,6 @@ +package org.jeecg.modules.xslmes.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.jeecg.modules.xslmes.entity.MesXslMillAction; + +public interface MesXslMillActionMapper extends BaseMapper {} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/DesktopAgentMcsDataAccess.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/DesktopAgentMcsDataAccess.java new file mode 100644 index 00000000..6f4f336a --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/DesktopAgentMcsDataAccess.java @@ -0,0 +1,85 @@ +package org.jeecg.modules.xslmes.mcs.access; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.jeecg.modules.device.sync.agent.DeviceAgentCommandService; +import org.jeecg.modules.device.sync.agent.DeviceAgentResult; +import org.jeecg.modules.device.sync.agent.DeviceAgentSession; +import org.jeecg.modules.device.sync.agent.DeviceAgentSessionRegistry; +import org.jeecg.modules.xslmes.mcs.datasource.McsDataSourceManager; +import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsDbConfig; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 经桌面端代理访问设备库。 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class DesktopAgentMcsDataAccess implements IMcsDataAccess { + + private final DeviceAgentCommandService commandService; + private final DeviceAgentSessionRegistry sessionRegistry; + private final McsDataSourceManager mcsDataSourceManager; + + @Override + public boolean isAgentMode() { + return true; + } + + @Override + public String resolveAgentDeviceId() { + MesXslMcsDbConfig cfg = mcsDataSourceManager.getCachedConfig(); + String preferred = cfg == null ? null : cfg.getAgentDeviceId(); + DeviceAgentSession session = sessionRegistry.pickOnlineAgent(preferred); + if (session == null) { + throw new IllegalStateException("无在线桌面设备代理,无法访问设备库"); + } + return session.getDeviceId(); + } + + @Override + public List> query(String sql, List params) { + String deviceId = resolveAgentDeviceId(); + DeviceAgentResult result = commandService.query(deviceId, sql, params, 60_000); + return result.getRows() == null ? List.of() : result.getRows(); + } + + @Override + public int execute(String sql, List params) { + String deviceId = resolveAgentDeviceId(); + DeviceAgentResult result = commandService.write(deviceId, sql, params, 60_000); + return result.getAffected() == null ? 0 : result.getAffected(); + } + + @Override + public int pushRows(String table, String mode, List keys, List> rows) { + String deviceId = resolveAgentDeviceId(); + Map payload = new HashMap<>(); + payload.put("mode", StringUtils.defaultIfBlank(mode, "insert")); + if (keys != null) { + payload.put("keys", keys); + } + payload.put("rows", rows == null ? new ArrayList<>() : rows); + DeviceAgentResult result = commandService.syncPush(deviceId, table, payload, 60_000); + return result.getAffected() == null ? 0 : result.getAffected(); + } + + @Override + public boolean testConnection() { + try { + String deviceId = resolveAgentDeviceId(); + DeviceAgentResult result = commandService.test(deviceId, 10_000); + return result != null && result.isSuccess(); + } catch (Exception e) { + log.warn("桌面代理中间库测试失败: {}", e.getMessage()); + return false; + } + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/DirectJdbcMcsDataAccess.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/DirectJdbcMcsDataAccess.java new file mode 100644 index 00000000..f7901a07 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/DirectJdbcMcsDataAccess.java @@ -0,0 +1,159 @@ +package org.jeecg.modules.xslmes.mcs.access; + +import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.jeecg.modules.xslmes.mcs.datasource.McsDataSourceManager; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Component; + +import javax.sql.DataSource; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * 服务端直连 SQL Server(调试/兼容保留)。 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class DirectJdbcMcsDataAccess implements IMcsDataAccess { + + private final DataSource dataSource; + private final McsDataSourceManager mcsDataSourceManager; + + @Override + public boolean isAgentMode() { + return false; + } + + @Override + public String resolveAgentDeviceId() { + return null; + } + + @Override + public List> query(String sql, List params) { + JdbcTemplate jt = new JdbcTemplate(requireDs()); + if (params == null || params.isEmpty()) { + return jt.queryForList(sql); + } + return jt.queryForList(sql, params.toArray()); + } + + @Override + public int execute(String sql, List params) { + JdbcTemplate jt = new JdbcTemplate(requireDs()); + if (params == null || params.isEmpty()) { + return jt.update(sql); + } + return jt.update(sql, params.toArray()); + } + + @Override + public int pushRows(String table, String mode, List keys, List> rows) { + if (rows == null || rows.isEmpty()) { + return 0; + } + int affected = 0; + for (Map row : rows) { + if ("update".equalsIgnoreCase(mode) || "upsert".equalsIgnoreCase(mode)) { + int u = updateByKeys(table, keys, row); + if (u > 0) { + affected += u; + continue; + } + if ("update".equalsIgnoreCase(mode)) { + continue; + } + } + affected += insertRow(table, row); + } + return affected; + } + + @Override + public boolean testConnection() { + try { + query("SELECT 1", null); + return true; + } catch (Exception e) { + log.warn("直连中间库测试失败: {}", e.getMessage()); + return false; + } + } + + private int insertRow(String table, Map row) { + List cols = new ArrayList<>(row.keySet()); + StringBuilder sql = new StringBuilder("INSERT INTO [").append(table).append("] ("); + StringBuilder values = new StringBuilder(" VALUES ("); + List params = new ArrayList<>(); + for (int i = 0; i < cols.size(); i++) { + if (i > 0) { + sql.append(','); + values.append(','); + } + sql.append('[').append(cols.get(i)).append(']'); + values.append('?'); + params.add(row.get(cols.get(i))); + } + sql.append(')').append(values).append(')'); + return execute(sql.toString(), params); + } + + private int updateByKeys(String table, List keys, Map row) { + if (keys == null || keys.isEmpty()) { + return 0; + } + List setCols = new ArrayList<>(); + for (String c : row.keySet()) { + boolean isKey = keys.stream().anyMatch(k -> k.equalsIgnoreCase(c)); + if (!isKey) { + setCols.add(c); + } + } + if (setCols.isEmpty()) { + return 0; + } + StringBuilder sql = new StringBuilder("UPDATE [").append(table).append("] SET "); + List params = new ArrayList<>(); + for (int i = 0; i < setCols.size(); i++) { + if (i > 0) { + sql.append(','); + } + sql.append('[').append(setCols.get(i)).append("]=?"); + params.add(getIgnoreCase(row, setCols.get(i))); + } + sql.append(" WHERE "); + for (int i = 0; i < keys.size(); i++) { + if (i > 0) { + sql.append(" AND "); + } + sql.append('[').append(keys.get(i)).append("]=?"); + params.add(getIgnoreCase(row, keys.get(i))); + } + return execute(sql.toString(), params); + } + + private Object getIgnoreCase(Map row, String key) { + if (row.containsKey(key)) { + return row.get(key); + } + for (Map.Entry e : row.entrySet()) { + if (e.getKey() != null && e.getKey().equalsIgnoreCase(key)) { + return e.getValue(); + } + } + return null; + } + + private DataSource requireDs() { + DynamicRoutingDataSource routing = (DynamicRoutingDataSource) dataSource; + DataSource src = routing.getDataSources().get(McsDataSourceManager.DS_KEY); + if (src == null) { + throw new IllegalStateException("中间库数据源 " + McsDataSourceManager.DS_KEY + " 未注册"); + } + return src; + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/IMcsDataAccess.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/IMcsDataAccess.java new file mode 100644 index 00000000..da39a732 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/IMcsDataAccess.java @@ -0,0 +1,31 @@ +package org.jeecg.modules.xslmes.mcs.access; + +import java.util.List; +import java.util.Map; + +/** + * MCS 中间库访问抽象:直连 JDBC 或经桌面代理。 + */ +public interface IMcsDataAccess { + + boolean isAgentMode(); + + String resolveAgentDeviceId(); + + List> query(String sql, List params); + + int execute(String sql, List params); + + /** + * 批量写入中间表(EQ_SYNC_PUSH)。 + * + * @param table 白名单表名 + * @param mode insert / update / upsert + * @param keys 匹配键(update/upsert) + * @param rows 行数据 + * @return 影响行数 + */ + int pushRows(String table, String mode, List keys, List> rows); + + boolean testConnection(); +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/McsDataAccessFacade.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/McsDataAccessFacade.java new file mode 100644 index 00000000..0519b9cb --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/McsDataAccessFacade.java @@ -0,0 +1,65 @@ +package org.jeecg.modules.xslmes.mcs.access; + +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.jeecg.modules.xslmes.mcs.datasource.McsDataSourceManager; +import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsDbConfig; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * 按配置在「桌面代理 / 直连」之间切换。 + */ +@Service +@RequiredArgsConstructor +public class McsDataAccessFacade implements IMcsDataAccess { + + public static final String MODE_DESKTOP_AGENT = "DESKTOP_AGENT"; + public static final String MODE_DIRECT = "DIRECT"; + + private final McsDataSourceManager mcsDataSourceManager; + private final DesktopAgentMcsDataAccess desktopAgentMcsDataAccess; + private final DirectJdbcMcsDataAccess directJdbcMcsDataAccess; + + public IMcsDataAccess current() { + return isAgentMode() ? desktopAgentMcsDataAccess : directJdbcMcsDataAccess; + } + + @Override + public boolean isAgentMode() { + MesXslMcsDbConfig cfg = mcsDataSourceManager.getCachedConfig(); + if (cfg == null) { + // 默认优先桌面代理 + return true; + } + String mode = StringUtils.defaultIfBlank(cfg.getAccessMode(), MODE_DESKTOP_AGENT).trim().toUpperCase(); + return MODE_DESKTOP_AGENT.equals(mode); + } + + @Override + public String resolveAgentDeviceId() { + return current().resolveAgentDeviceId(); + } + + @Override + public List> query(String sql, List params) { + return current().query(sql, params); + } + + @Override + public int execute(String sql, List params) { + return current().execute(sql, params); + } + + @Override + public int pushRows(String table, String mode, List keys, List> rows) { + return current().pushRows(table, mode, keys, rows); + } + + @Override + public boolean testConnection() { + return current().testConnection(); + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/MesToMcsPushService.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/MesToMcsPushService.java new file mode 100644 index 00000000..d745f9a4 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/MesToMcsPushService.java @@ -0,0 +1,30 @@ +package org.jeecg.modules.xslmes.mcs.access; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * MES → MCS 经桌面代理下发(EQ_SYNC_PUSH)。 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class MesToMcsPushService { + + private final McsDataAccessFacade mcsDataAccessFacade; + + public int push(String table, String mode, List keys, List> rows) { + if (StringUtils.isBlank(table)) { + throw new IllegalArgumentException("table 不能为空"); + } + int affected = mcsDataAccessFacade.pushRows(table, mode, keys, rows); + log.info("MES→MCS 下发完成 table={} mode={} rows={} affected={}", + table, mode, rows == null ? 0 : rows.size(), affected); + return affected; + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/proxy/AgentProxyConnection.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/proxy/AgentProxyConnection.java new file mode 100644 index 00000000..5209628a --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/proxy/AgentProxyConnection.java @@ -0,0 +1,290 @@ +package org.jeecg.modules.xslmes.mcs.access.proxy; + +import org.jeecg.modules.xslmes.mcs.access.IMcsDataAccess; + +import java.sql.Array; +import java.sql.Blob; +import java.sql.CallableStatement; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.NClob; +import java.sql.PreparedStatement; +import java.sql.SQLClientInfoException; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Savepoint; +import java.sql.Statement; +import java.sql.Struct; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.Executor; + +public class AgentProxyConnection implements Connection { + + private final IMcsDataAccess dataAccess; + private boolean closed; + + public AgentProxyConnection(IMcsDataAccess dataAccess) { + this.dataAccess = dataAccess; + } + + @Override + public Statement createStatement() { + return new AgentProxyStatement(dataAccess, null); + } + + @Override + public PreparedStatement prepareStatement(String sql) { + return new AgentProxyPreparedStatement(dataAccess, sql); + } + + @Override + public CallableStatement prepareCall(String sql) throws SQLException { + throw new SQLException("CallableStatement not supported by agent proxy"); + } + + @Override + public String nativeSQL(String sql) { + return sql; + } + + @Override + public void setAutoCommit(boolean autoCommit) { + } + + @Override + public boolean getAutoCommit() { + return true; + } + + @Override + public void commit() { + } + + @Override + public void rollback() { + } + + @Override + public void close() { + closed = true; + } + + @Override + public boolean isClosed() { + return closed; + } + + @Override + public DatabaseMetaData getMetaData() throws SQLException { + throw new SQLException("DatabaseMetaData not supported by agent proxy"); + } + + @Override + public void setReadOnly(boolean readOnly) { + } + + @Override + public boolean isReadOnly() { + return false; + } + + @Override + public void setCatalog(String catalog) { + } + + @Override + public String getCatalog() { + return null; + } + + @Override + public void setTransactionIsolation(int level) { + } + + @Override + public int getTransactionIsolation() { + return Connection.TRANSACTION_READ_COMMITTED; + } + + @Override + public SQLWarning getWarnings() { + return null; + } + + @Override + public void clearWarnings() { + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency) { + return createStatement(); + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) { + return prepareStatement(sql); + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { + throw new SQLException("CallableStatement not supported"); + } + + @Override + public Map> getTypeMap() { + return Map.of(); + } + + @Override + public void setTypeMap(Map> map) { + } + + @Override + public void setHoldability(int holdability) { + } + + @Override + public int getHoldability() { + return 0; + } + + @Override + public Savepoint setSavepoint() throws SQLException { + throw new SQLException("Savepoint not supported"); + } + + @Override + public Savepoint setSavepoint(String name) throws SQLException { + throw new SQLException("Savepoint not supported"); + } + + @Override + public void rollback(Savepoint savepoint) { + } + + @Override + public void releaseSavepoint(Savepoint savepoint) { + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) { + return createStatement(); + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) { + return prepareStatement(sql); + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + throw new SQLException("CallableStatement not supported"); + } + + @Override + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) { + return prepareStatement(sql); + } + + @Override + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) { + return prepareStatement(sql); + } + + @Override + public PreparedStatement prepareStatement(String sql, String[] columnNames) { + return prepareStatement(sql); + } + + @Override + public Clob createClob() throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public Blob createBlob() throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public NClob createNClob() throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public SQLXML createSQLXML() throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public boolean isValid(int timeout) { + return !closed; + } + + @Override + public void setClientInfo(String name, String value) throws SQLClientInfoException { + } + + @Override + public void setClientInfo(Properties properties) throws SQLClientInfoException { + } + + @Override + public String getClientInfo(String name) { + return null; + } + + @Override + public Properties getClientInfo() { + return new Properties(); + } + + @Override + public Array createArrayOf(String typeName, Object[] elements) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public Struct createStruct(String typeName, Object[] attributes) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setSchema(String schema) { + } + + @Override + public String getSchema() { + return null; + } + + @Override + public void abort(Executor executor) { + close(); + } + + @Override + public void setNetworkTimeout(Executor executor, int milliseconds) { + } + + @Override + public int getNetworkTimeout() { + return 0; + } + + @Override + public T unwrap(Class iface) throws SQLException { + if (iface.isInstance(this)) { + return iface.cast(this); + } + throw new SQLException("Not a wrapper"); + } + + @Override + public boolean isWrapperFor(Class iface) { + return iface.isInstance(this); + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/proxy/AgentProxyDataSource.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/proxy/AgentProxyDataSource.java new file mode 100644 index 00000000..2d711b5c --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/proxy/AgentProxyDataSource.java @@ -0,0 +1,68 @@ +package org.jeecg.modules.xslmes.mcs.access.proxy; + +import org.jeecg.modules.xslmes.mcs.access.IMcsDataAccess; + +import javax.sql.DataSource; +import java.io.PrintWriter; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.util.logging.Logger; + +/** + * 将 JDBC 调用转发到桌面设备代理的 DataSource,供 @DS("sqlserver_mcs") 复用。 + */ +public class AgentProxyDataSource implements DataSource { + + private final IMcsDataAccess dataAccess; + + public AgentProxyDataSource(IMcsDataAccess dataAccess) { + this.dataAccess = dataAccess; + } + + @Override + public Connection getConnection() { + return new AgentProxyConnection(dataAccess); + } + + @Override + public Connection getConnection(String username, String password) { + return getConnection(); + } + + @Override + public T unwrap(Class iface) throws SQLException { + if (iface.isInstance(this)) { + return iface.cast(this); + } + throw new SQLException("Not a wrapper for " + iface); + } + + @Override + public boolean isWrapperFor(Class iface) { + return iface.isInstance(this); + } + + @Override + public PrintWriter getLogWriter() { + return null; + } + + @Override + public void setLogWriter(PrintWriter out) { + } + + @Override + public void setLoginTimeout(int seconds) { + } + + @Override + public int getLoginTimeout() { + return 0; + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + throw new SQLFeatureNotSupportedException(); + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/proxy/AgentProxyPreparedStatement.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/proxy/AgentProxyPreparedStatement.java new file mode 100644 index 00000000..00429133 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/proxy/AgentProxyPreparedStatement.java @@ -0,0 +1,565 @@ +package org.jeecg.modules.xslmes.mcs.access.proxy; + +import org.jeecg.modules.xslmes.mcs.access.IMcsDataAccess; + +import java.io.InputStream; +import java.io.Reader; +import java.math.BigDecimal; +import java.net.URL; +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.Date; +import java.sql.NClob; +import java.sql.ParameterMetaData; +import java.sql.PreparedStatement; +import java.sql.Ref; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.RowId; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.Map; + +public class AgentProxyPreparedStatement implements PreparedStatement { + + private final IMcsDataAccess dataAccess; + private final String sql; + private final List params = new ArrayList<>(); + private ResultSet currentRs; + private int updateCount = -1; + + public AgentProxyPreparedStatement(IMcsDataAccess dataAccess, String sql) { + this.dataAccess = dataAccess; + this.sql = sql; + ensureCapacity(16); + } + + private void ensureCapacity(int index1Based) { + while (params.size() < index1Based) { + params.add(null); + } + } + + private void setParam(int parameterIndex, Object value) { + ensureCapacity(parameterIndex); + params.set(parameterIndex - 1, value); + } + + @Override + public ResultSet executeQuery() throws SQLException { + try { + List> rows = dataAccess.query(sql, new ArrayList<>(params)); + currentRs = new MapListResultSet(rows); + updateCount = -1; + return currentRs; + } catch (Exception e) { + throw new SQLException(e.getMessage(), e); + } + } + + @Override + public int executeUpdate() throws SQLException { + try { + updateCount = dataAccess.execute(sql, new ArrayList<>(params)); + currentRs = null; + return updateCount; + } catch (Exception e) { + throw new SQLException(e.getMessage(), e); + } + } + + @Override + public boolean execute() throws SQLException { + String trimmed = sql == null ? "" : sql.trim(); + if (trimmed.regionMatches(true, 0, "SELECT", 0, 6)) { + executeQuery(); + return true; + } + executeUpdate(); + return false; + } + + @Override + public void setNull(int parameterIndex, int sqlType) { + setParam(parameterIndex, null); + } + + @Override + public void setBoolean(int parameterIndex, boolean x) { + setParam(parameterIndex, x); + } + + @Override + public void setByte(int parameterIndex, byte x) { + setParam(parameterIndex, x); + } + + @Override + public void setShort(int parameterIndex, short x) { + setParam(parameterIndex, x); + } + + @Override + public void setInt(int parameterIndex, int x) { + setParam(parameterIndex, x); + } + + @Override + public void setLong(int parameterIndex, long x) { + setParam(parameterIndex, x); + } + + @Override + public void setFloat(int parameterIndex, float x) { + setParam(parameterIndex, x); + } + + @Override + public void setDouble(int parameterIndex, double x) { + setParam(parameterIndex, x); + } + + @Override + public void setBigDecimal(int parameterIndex, BigDecimal x) { + setParam(parameterIndex, x); + } + + @Override + public void setString(int parameterIndex, String x) { + setParam(parameterIndex, x); + } + + @Override + public void setBytes(int parameterIndex, byte[] x) { + setParam(parameterIndex, x); + } + + @Override + public void setDate(int parameterIndex, Date x) { + setParam(parameterIndex, x); + } + + @Override + public void setTime(int parameterIndex, Time x) { + setParam(parameterIndex, x); + } + + @Override + public void setTimestamp(int parameterIndex, Timestamp x) { + setParam(parameterIndex, x); + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { + throw new SQLException("setAsciiStream not supported"); + } + + @Override + @Deprecated + public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void clearParameters() { + params.clear(); + } + + @Override + public void setObject(int parameterIndex, Object x, int targetSqlType) { + setParam(parameterIndex, x); + } + + @Override + public void setObject(int parameterIndex, Object x) { + setParam(parameterIndex, x); + } + + @Override + public void addBatch() { + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setRef(int parameterIndex, Ref x) { + setParam(parameterIndex, x); + } + + @Override + public void setBlob(int parameterIndex, Blob x) { + setParam(parameterIndex, x); + } + + @Override + public void setClob(int parameterIndex, Clob x) { + setParam(parameterIndex, x); + } + + @Override + public void setArray(int parameterIndex, Array x) { + setParam(parameterIndex, x); + } + + @Override + public ResultSetMetaData getMetaData() { + return currentRs == null ? null : safeMeta(); + } + + private ResultSetMetaData safeMeta() { + try { + return currentRs.getMetaData(); + } catch (SQLException e) { + return null; + } + } + + @Override + public void setDate(int parameterIndex, Date x, Calendar cal) { + setParam(parameterIndex, x); + } + + @Override + public void setTime(int parameterIndex, Time x, Calendar cal) { + setParam(parameterIndex, x); + } + + @Override + public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) { + setParam(parameterIndex, x); + } + + @Override + public void setNull(int parameterIndex, int sqlType, String typeName) { + setParam(parameterIndex, null); + } + + @Override + public void setURL(int parameterIndex, URL x) { + setParam(parameterIndex, x); + } + + @Override + public ParameterMetaData getParameterMetaData() throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setRowId(int parameterIndex, RowId x) { + setParam(parameterIndex, x); + } + + @Override + public void setNString(int parameterIndex, String value) { + setParam(parameterIndex, value); + } + + @Override + public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setNClob(int parameterIndex, NClob value) { + setParam(parameterIndex, value); + } + + @Override + public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setSQLXML(int parameterIndex, SQLXML xmlObject) { + setParam(parameterIndex, xmlObject); + } + + @Override + public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) { + setParam(parameterIndex, x); + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setClob(int parameterIndex, Reader reader) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public void setNClob(int parameterIndex, Reader reader) throws SQLException { + throw new SQLException("not supported"); + } + + // Statement methods + @Override + public ResultSet executeQuery(String sql) throws SQLException { + throw new SQLException("use executeQuery()"); + } + + @Override + public int executeUpdate(String sql) throws SQLException { + throw new SQLException("use executeUpdate()"); + } + + @Override + public void close() { + currentRs = null; + } + + @Override + public int getMaxFieldSize() { + return 0; + } + + @Override + public void setMaxFieldSize(int max) { + } + + @Override + public int getMaxRows() { + return 0; + } + + @Override + public void setMaxRows(int max) { + } + + @Override + public void setEscapeProcessing(boolean enable) { + } + + @Override + public int getQueryTimeout() { + return 0; + } + + @Override + public void setQueryTimeout(int seconds) { + } + + @Override + public void cancel() { + } + + @Override + public SQLWarning getWarnings() { + return null; + } + + @Override + public void clearWarnings() { + } + + @Override + public void setCursorName(String name) { + } + + @Override + public boolean execute(String sql) throws SQLException { + throw new SQLException("use execute()"); + } + + @Override + public ResultSet getResultSet() { + return currentRs; + } + + @Override + public int getUpdateCount() { + return updateCount; + } + + @Override + public boolean getMoreResults() { + return false; + } + + @Override + public void setFetchDirection(int direction) { + } + + @Override + public int getFetchDirection() { + return ResultSet.FETCH_FORWARD; + } + + @Override + public void setFetchSize(int rows) { + } + + @Override + public int getFetchSize() { + return 0; + } + + @Override + public int getResultSetConcurrency() { + return ResultSet.CONCUR_READ_ONLY; + } + + @Override + public int getResultSetType() { + return ResultSet.TYPE_FORWARD_ONLY; + } + + @Override + public void addBatch(String sql) { + } + + @Override + public void clearBatch() { + } + + @Override + public int[] executeBatch() { + return new int[0]; + } + + @Override + public Connection getConnection() { + return null; + } + + @Override + public boolean getMoreResults(int current) { + return false; + } + + @Override + public ResultSet getGeneratedKeys() { + return null; + } + + @Override + public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public int executeUpdate(String sql, String[] columnNames) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public boolean execute(String sql, int[] columnIndexes) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public boolean execute(String sql, String[] columnNames) throws SQLException { + throw new SQLException("not supported"); + } + + @Override + public int getResultSetHoldability() { + return 0; + } + + @Override + public boolean isClosed() { + return false; + } + + @Override + public void setPoolable(boolean poolable) { + } + + @Override + public boolean isPoolable() { + return false; + } + + @Override + public void closeOnCompletion() { + } + + @Override + public boolean isCloseOnCompletion() { + return false; + } + + @Override + public T unwrap(Class iface) throws SQLException { + throw new SQLException("not a wrapper"); + } + + @Override + public boolean isWrapperFor(Class iface) { + return false; + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/proxy/AgentProxyStatement.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/proxy/AgentProxyStatement.java new file mode 100644 index 00000000..03995183 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/proxy/AgentProxyStatement.java @@ -0,0 +1,249 @@ +package org.jeecg.modules.xslmes.mcs.access.proxy; + +import org.jeecg.modules.xslmes.mcs.access.IMcsDataAccess; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class AgentProxyStatement implements Statement { + + private final IMcsDataAccess dataAccess; + private ResultSet currentRs; + private int updateCount = -1; + + public AgentProxyStatement(IMcsDataAccess dataAccess, String ignored) { + this.dataAccess = dataAccess; + } + + @Override + public ResultSet executeQuery(String sql) throws SQLException { + try { + List> rows = dataAccess.query(sql, new ArrayList<>()); + currentRs = new MapListResultSet(rows); + updateCount = -1; + return currentRs; + } catch (Exception e) { + throw new SQLException(e.getMessage(), e); + } + } + + @Override + public int executeUpdate(String sql) throws SQLException { + try { + updateCount = dataAccess.execute(sql, new ArrayList<>()); + currentRs = null; + return updateCount; + } catch (Exception e) { + throw new SQLException(e.getMessage(), e); + } + } + + @Override + public void close() { + currentRs = null; + } + + @Override + public int getMaxFieldSize() { + return 0; + } + + @Override + public void setMaxFieldSize(int max) { + } + + @Override + public int getMaxRows() { + return 0; + } + + @Override + public void setMaxRows(int max) { + } + + @Override + public void setEscapeProcessing(boolean enable) { + } + + @Override + public int getQueryTimeout() { + return 0; + } + + @Override + public void setQueryTimeout(int seconds) { + } + + @Override + public void cancel() { + } + + @Override + public SQLWarning getWarnings() { + return null; + } + + @Override + public void clearWarnings() { + } + + @Override + public void setCursorName(String name) { + } + + @Override + public boolean execute(String sql) throws SQLException { + String trimmed = sql == null ? "" : sql.trim(); + if (trimmed.regionMatches(true, 0, "SELECT", 0, 6)) { + executeQuery(sql); + return true; + } + executeUpdate(sql); + return false; + } + + @Override + public ResultSet getResultSet() { + return currentRs; + } + + @Override + public int getUpdateCount() { + return updateCount; + } + + @Override + public boolean getMoreResults() { + return false; + } + + @Override + public void setFetchDirection(int direction) { + } + + @Override + public int getFetchDirection() { + return ResultSet.FETCH_FORWARD; + } + + @Override + public void setFetchSize(int rows) { + } + + @Override + public int getFetchSize() { + return 0; + } + + @Override + public int getResultSetConcurrency() { + return ResultSet.CONCUR_READ_ONLY; + } + + @Override + public int getResultSetType() { + return ResultSet.TYPE_FORWARD_ONLY; + } + + @Override + public void addBatch(String sql) { + } + + @Override + public void clearBatch() { + } + + @Override + public int[] executeBatch() { + return new int[0]; + } + + @Override + public Connection getConnection() { + return null; + } + + @Override + public boolean getMoreResults(int current) { + return false; + } + + @Override + public ResultSet getGeneratedKeys() { + return null; + } + + @Override + public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { + return executeUpdate(sql); + } + + @Override + public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { + return executeUpdate(sql); + } + + @Override + public int executeUpdate(String sql, String[] columnNames) throws SQLException { + return executeUpdate(sql); + } + + @Override + public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { + return execute(sql); + } + + @Override + public boolean execute(String sql, int[] columnIndexes) throws SQLException { + return execute(sql); + } + + @Override + public boolean execute(String sql, String[] columnNames) throws SQLException { + return execute(sql); + } + + @Override + public int getResultSetHoldability() { + return 0; + } + + @Override + public boolean isClosed() { + return false; + } + + @Override + public void setPoolable(boolean poolable) { + } + + @Override + public boolean isPoolable() { + return false; + } + + @Override + public void closeOnCompletion() { + } + + @Override + public boolean isCloseOnCompletion() { + return false; + } + + @Override + public T unwrap(Class iface) throws SQLException { + throw new SQLException("not a wrapper"); + } + + @Override + public boolean isWrapperFor(Class iface) { + return false; + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/proxy/MapListResultSet.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/proxy/MapListResultSet.java new file mode 100644 index 00000000..942dd49c --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/access/proxy/MapListResultSet.java @@ -0,0 +1,1240 @@ +package org.jeecg.modules.xslmes.mcs.access.proxy; + +import java.io.InputStream; +import java.io.Reader; +import java.math.BigDecimal; +import java.net.URL; +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Date; +import java.sql.NClob; +import java.sql.Ref; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.RowId; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Statement; +import java.sql.Time; +import java.sql.Timestamp; +import java.sql.Types; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.Map; + +/** + * 将 List<Map> 包装为只读 ResultSet,供 MyBatis 消费。 + */ +public class MapListResultSet implements ResultSet { + + private final List> rows; + private final List columns; + private int cursor = -1; + private boolean closed; + + public MapListResultSet(List> rows) { + this.rows = rows == null ? List.of() : rows; + this.columns = new ArrayList<>(); + if (!this.rows.isEmpty()) { + columns.addAll(this.rows.get(0).keySet()); + } + } + + private Map current() throws SQLException { + if (cursor < 0 || cursor >= rows.size()) { + throw new SQLException("cursor out of range"); + } + return rows.get(cursor); + } + + private Object byIndex(int columnIndex) throws SQLException { + if (columnIndex < 1 || columnIndex > columns.size()) { + throw new SQLException("invalid column index " + columnIndex); + } + String name = columns.get(columnIndex - 1); + return getIgnoreCase(current(), name); + } + + private Object getIgnoreCase(Map row, String label) { + if (row.containsKey(label)) { + return row.get(label); + } + for (Map.Entry e : row.entrySet()) { + if (e.getKey() != null && e.getKey().equalsIgnoreCase(label)) { + return e.getValue(); + } + } + return null; + } + + @Override + public boolean next() { + if (cursor + 1 >= rows.size()) { + cursor = rows.size(); + return false; + } + cursor++; + return true; + } + + @Override + public void close() { + closed = true; + } + + @Override + public boolean wasNull() { + return false; + } + + @Override + public String getString(int columnIndex) throws SQLException { + Object v = byIndex(columnIndex); + return v == null ? null : String.valueOf(v); + } + + @Override + public boolean getBoolean(int columnIndex) throws SQLException { + Object v = byIndex(columnIndex); + if (v == null) { + return false; + } + if (v instanceof Boolean) { + return (Boolean) v; + } + return Boolean.parseBoolean(String.valueOf(v)); + } + + @Override + public byte getByte(int columnIndex) throws SQLException { + return (byte) getInt(columnIndex); + } + + @Override + public short getShort(int columnIndex) throws SQLException { + return (short) getInt(columnIndex); + } + + @Override + public int getInt(int columnIndex) throws SQLException { + Object v = byIndex(columnIndex); + if (v == null) { + return 0; + } + if (v instanceof Number) { + return ((Number) v).intValue(); + } + return Integer.parseInt(String.valueOf(v)); + } + + @Override + public long getLong(int columnIndex) throws SQLException { + Object v = byIndex(columnIndex); + if (v == null) { + return 0L; + } + if (v instanceof Number) { + return ((Number) v).longValue(); + } + return Long.parseLong(String.valueOf(v)); + } + + @Override + public float getFloat(int columnIndex) throws SQLException { + Object v = byIndex(columnIndex); + if (v == null) { + return 0f; + } + if (v instanceof Number) { + return ((Number) v).floatValue(); + } + return Float.parseFloat(String.valueOf(v)); + } + + @Override + public double getDouble(int columnIndex) throws SQLException { + Object v = byIndex(columnIndex); + if (v == null) { + return 0d; + } + if (v instanceof Number) { + return ((Number) v).doubleValue(); + } + return Double.parseDouble(String.valueOf(v)); + } + + @Override + @Deprecated + public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { + return getBigDecimal(columnIndex); + } + + @Override + public byte[] getBytes(int columnIndex) throws SQLException { + Object v = byIndex(columnIndex); + return v instanceof byte[] ? (byte[]) v : null; + } + + @Override + public Date getDate(int columnIndex) throws SQLException { + Object v = byIndex(columnIndex); + if (v == null) { + return null; + } + if (v instanceof Date) { + return (Date) v; + } + if (v instanceof java.util.Date) { + return new Date(((java.util.Date) v).getTime()); + } + return Date.valueOf(String.valueOf(v).substring(0, 10)); + } + + @Override + public Time getTime(int columnIndex) throws SQLException { + Object v = byIndex(columnIndex); + return v == null ? null : Time.valueOf(String.valueOf(v)); + } + + @Override + public Timestamp getTimestamp(int columnIndex) throws SQLException { + Object v = byIndex(columnIndex); + if (v == null) { + return null; + } + if (v instanceof Timestamp) { + return (Timestamp) v; + } + if (v instanceof java.util.Date) { + return new Timestamp(((java.util.Date) v).getTime()); + } + return Timestamp.valueOf(String.valueOf(v)); + } + + @Override + public InputStream getAsciiStream(int columnIndex) { + return null; + } + + @Override + @Deprecated + public InputStream getUnicodeStream(int columnIndex) { + return null; + } + + @Override + public InputStream getBinaryStream(int columnIndex) { + return null; + } + + @Override + public String getString(String columnLabel) throws SQLException { + Object v = getIgnoreCase(current(), columnLabel); + return v == null ? null : String.valueOf(v); + } + + @Override + public boolean getBoolean(String columnLabel) throws SQLException { + return getBoolean(findColumn(columnLabel)); + } + + @Override + public byte getByte(String columnLabel) throws SQLException { + return getByte(findColumn(columnLabel)); + } + + @Override + public short getShort(String columnLabel) throws SQLException { + return getShort(findColumn(columnLabel)); + } + + @Override + public int getInt(String columnLabel) throws SQLException { + return getInt(findColumn(columnLabel)); + } + + @Override + public long getLong(String columnLabel) throws SQLException { + return getLong(findColumn(columnLabel)); + } + + @Override + public float getFloat(String columnLabel) throws SQLException { + return getFloat(findColumn(columnLabel)); + } + + @Override + public double getDouble(String columnLabel) throws SQLException { + return getDouble(findColumn(columnLabel)); + } + + @Override + @Deprecated + public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException { + return getBigDecimal(columnLabel); + } + + @Override + public byte[] getBytes(String columnLabel) throws SQLException { + return getBytes(findColumn(columnLabel)); + } + + @Override + public Date getDate(String columnLabel) throws SQLException { + return getDate(findColumn(columnLabel)); + } + + @Override + public Time getTime(String columnLabel) throws SQLException { + return getTime(findColumn(columnLabel)); + } + + @Override + public Timestamp getTimestamp(String columnLabel) throws SQLException { + return getTimestamp(findColumn(columnLabel)); + } + + @Override + public InputStream getAsciiStream(String columnLabel) { + return null; + } + + @Override + @Deprecated + public InputStream getUnicodeStream(String columnLabel) { + return null; + } + + @Override + public InputStream getBinaryStream(String columnLabel) { + return null; + } + + @Override + public SQLWarning getWarnings() { + return null; + } + + @Override + public void clearWarnings() { + } + + @Override + public String getCursorName() { + return null; + } + + @Override + public ResultSetMetaData getMetaData() { + return new ResultSetMetaData() { + @Override + public int getColumnCount() { + return columns.size(); + } + + @Override + public boolean isAutoIncrement(int column) { + return false; + } + + @Override + public boolean isCaseSensitive(int column) { + return false; + } + + @Override + public boolean isSearchable(int column) { + return true; + } + + @Override + public boolean isCurrency(int column) { + return false; + } + + @Override + public int isNullable(int column) { + return columnNullable; + } + + @Override + public boolean isSigned(int column) { + return true; + } + + @Override + public int getColumnDisplaySize(int column) { + return 64; + } + + @Override + public String getColumnLabel(int column) { + return columns.get(column - 1); + } + + @Override + public String getColumnName(int column) { + return columns.get(column - 1); + } + + @Override + public String getSchemaName(int column) { + return ""; + } + + @Override + public int getPrecision(int column) { + return 0; + } + + @Override + public int getScale(int column) { + return 0; + } + + @Override + public String getTableName(int column) { + return ""; + } + + @Override + public String getCatalogName(int column) { + return ""; + } + + @Override + public int getColumnType(int column) { + return Types.VARCHAR; + } + + @Override + public String getColumnTypeName(int column) { + return "VARCHAR"; + } + + @Override + public boolean isReadOnly(int column) { + return true; + } + + @Override + public boolean isWritable(int column) { + return false; + } + + @Override + public boolean isDefinitelyWritable(int column) { + return false; + } + + @Override + public String getColumnClassName(int column) { + return String.class.getName(); + } + + @Override + public T unwrap(Class iface) throws SQLException { + throw new SQLException("not a wrapper"); + } + + @Override + public boolean isWrapperFor(Class iface) { + return false; + } + }; + } + + @Override + public Object getObject(int columnIndex) throws SQLException { + return byIndex(columnIndex); + } + + @Override + public Object getObject(String columnLabel) throws SQLException { + return getIgnoreCase(current(), columnLabel); + } + + @Override + public int findColumn(String columnLabel) throws SQLException { + for (int i = 0; i < columns.size(); i++) { + if (columns.get(i).equalsIgnoreCase(columnLabel)) { + return i + 1; + } + } + // dynamic: add missing label from current row + Object v = getIgnoreCase(current(), columnLabel); + if (v != null || current().keySet().stream().anyMatch(k -> k.equalsIgnoreCase(columnLabel))) { + columns.add(columnLabel); + return columns.size(); + } + throw new SQLException("column not found: " + columnLabel); + } + + // Remaining methods: delegate minimally / unsupported + @Override + public Reader getCharacterStream(int columnIndex) { + return null; + } + + @Override + public Reader getCharacterStream(String columnLabel) { + return null; + } + + @Override + public BigDecimal getBigDecimal(int columnIndex) throws SQLException { + Object v = byIndex(columnIndex); + if (v == null) { + return null; + } + if (v instanceof BigDecimal) { + return (BigDecimal) v; + } + return new BigDecimal(String.valueOf(v)); + } + + @Override + public BigDecimal getBigDecimal(String columnLabel) throws SQLException { + return getBigDecimal(findColumn(columnLabel)); + } + + @Override + public boolean isBeforeFirst() { + return cursor < 0; + } + + @Override + public boolean isAfterLast() { + return cursor >= rows.size(); + } + + @Override + public boolean isFirst() { + return cursor == 0; + } + + @Override + public boolean isLast() { + return cursor == rows.size() - 1; + } + + @Override + public void beforeFirst() { + cursor = -1; + } + + @Override + public void afterLast() { + cursor = rows.size(); + } + + @Override + public boolean first() { + if (rows.isEmpty()) { + return false; + } + cursor = 0; + return true; + } + + @Override + public boolean last() { + if (rows.isEmpty()) { + return false; + } + cursor = rows.size() - 1; + return true; + } + + @Override + public int getRow() { + return cursor + 1; + } + + @Override + public boolean absolute(int row) { + if (row < 1 || row > rows.size()) { + return false; + } + cursor = row - 1; + return true; + } + + @Override + public boolean relative(int rows) { + return absolute(cursor + 1 + rows); + } + + @Override + public boolean previous() { + if (cursor <= 0) { + cursor = -1; + return false; + } + cursor--; + return true; + } + + @Override + public void setFetchDirection(int direction) { + } + + @Override + public int getFetchDirection() { + return FETCH_FORWARD; + } + + @Override + public void setFetchSize(int rows) { + } + + @Override + public int getFetchSize() { + return 0; + } + + @Override + public int getType() { + return TYPE_FORWARD_ONLY; + } + + @Override + public int getConcurrency() { + return CONCUR_READ_ONLY; + } + + @Override + public boolean rowUpdated() { + return false; + } + + @Override + public boolean rowInserted() { + return false; + } + + @Override + public boolean rowDeleted() { + return false; + } + + @Override + public void updateNull(int columnIndex) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBoolean(int columnIndex, boolean x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateByte(int columnIndex, byte x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateShort(int columnIndex, short x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateInt(int columnIndex, int x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateLong(int columnIndex, long x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateFloat(int columnIndex, float x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateDouble(int columnIndex, double x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateString(int columnIndex, String x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBytes(int columnIndex, byte[] x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateDate(int columnIndex, Date x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateTime(int columnIndex, Time x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateObject(int columnIndex, Object x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateNull(String columnLabel) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBoolean(String columnLabel, boolean x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateByte(String columnLabel, byte x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateShort(String columnLabel, short x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateInt(String columnLabel, int x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateLong(String columnLabel, long x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateFloat(String columnLabel, float x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateDouble(String columnLabel, double x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateString(String columnLabel, String x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBytes(String columnLabel, byte[] x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateDate(String columnLabel, Date x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateTime(String columnLabel, Time x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateCharacterStream(String columnLabel, Reader reader, int length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateObject(String columnLabel, Object x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void insertRow() throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateRow() throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void deleteRow() throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void refreshRow() { + } + + @Override + public void cancelRowUpdates() { + } + + @Override + public void moveToInsertRow() throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void moveToCurrentRow() { + } + + @Override + public Statement getStatement() { + return null; + } + + @Override + public Object getObject(int columnIndex, Map> map) throws SQLException { + return getObject(columnIndex); + } + + @Override + public Ref getRef(int columnIndex) { + return null; + } + + @Override + public Blob getBlob(int columnIndex) { + return null; + } + + @Override + public Clob getClob(int columnIndex) { + return null; + } + + @Override + public Array getArray(int columnIndex) { + return null; + } + + @Override + public Object getObject(String columnLabel, Map> map) throws SQLException { + return getObject(columnLabel); + } + + @Override + public Ref getRef(String columnLabel) { + return null; + } + + @Override + public Blob getBlob(String columnLabel) { + return null; + } + + @Override + public Clob getClob(String columnLabel) { + return null; + } + + @Override + public Array getArray(String columnLabel) { + return null; + } + + @Override + public Date getDate(int columnIndex, Calendar cal) throws SQLException { + return getDate(columnIndex); + } + + @Override + public Date getDate(String columnLabel, Calendar cal) throws SQLException { + return getDate(columnLabel); + } + + @Override + public Time getTime(int columnIndex, Calendar cal) throws SQLException { + return getTime(columnIndex); + } + + @Override + public Time getTime(String columnLabel, Calendar cal) throws SQLException { + return getTime(columnLabel); + } + + @Override + public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { + return getTimestamp(columnIndex); + } + + @Override + public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException { + return getTimestamp(columnLabel); + } + + @Override + public URL getURL(int columnIndex) { + return null; + } + + @Override + public URL getURL(String columnLabel) { + return null; + } + + @Override + public void updateRef(int columnIndex, Ref x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateRef(String columnLabel, Ref x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBlob(int columnIndex, Blob x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBlob(String columnLabel, Blob x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateClob(int columnIndex, Clob x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateClob(String columnLabel, Clob x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateArray(int columnIndex, Array x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateArray(String columnLabel, Array x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public RowId getRowId(int columnIndex) { + return null; + } + + @Override + public RowId getRowId(String columnLabel) { + return null; + } + + @Override + public void updateRowId(int columnIndex, RowId x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateRowId(String columnLabel, RowId x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public int getHoldability() { + return HOLD_CURSORS_OVER_COMMIT; + } + + @Override + public boolean isClosed() { + return closed; + } + + @Override + public void updateNString(int columnIndex, String nString) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateNString(String columnLabel, String nString) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateNClob(int columnIndex, NClob nClob) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateNClob(String columnLabel, NClob nClob) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public NClob getNClob(int columnIndex) { + return null; + } + + @Override + public NClob getNClob(String columnLabel) { + return null; + } + + @Override + public SQLXML getSQLXML(int columnIndex) { + return null; + } + + @Override + public SQLXML getSQLXML(String columnLabel) { + return null; + } + + @Override + public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public String getNString(int columnIndex) throws SQLException { + return getString(columnIndex); + } + + @Override + public String getNString(String columnLabel) throws SQLException { + return getString(columnLabel); + } + + @Override + public Reader getNCharacterStream(int columnIndex) { + return null; + } + + @Override + public Reader getNCharacterStream(String columnLabel) { + return null; + } + + @Override + public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateCharacterStream(int columnIndex, Reader x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateClob(int columnIndex, Reader reader) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateClob(String columnLabel, Reader reader) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateNClob(int columnIndex, Reader reader) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public void updateNClob(String columnLabel, Reader reader) throws SQLException { + throw new SQLException("read-only"); + } + + @Override + public T getObject(int columnIndex, Class type) throws SQLException { + return type.cast(getObject(columnIndex)); + } + + @Override + public T getObject(String columnLabel, Class type) throws SQLException { + return type.cast(getObject(columnLabel)); + } + + @Override + public T unwrap(Class iface) throws SQLException { + throw new SQLException("not a wrapper"); + } + + @Override + public boolean isWrapperFor(Class iface) { + return false; + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/controller/McsToMesActMillController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/controller/McsToMesActMillController.java new file mode 100644 index 00000000..708434fa --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/controller/McsToMesActMillController.java @@ -0,0 +1,59 @@ +package org.jeecg.modules.xslmes.mcs.controller; + +import jakarta.servlet.http.HttpServletRequest; +import org.jeecg.common.api.vo.Result; +import org.jeecg.modules.xslmes.mcs.util.McsQueryHelper; +import org.jeecg.modules.xslmes.mcs.entity.McsToMesActMill; +import org.jeecg.modules.xslmes.mcs.service.IMcsToMesActMillService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.system.base.controller.JeecgController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import org.apache.shiro.authz.annotation.RequiresPermissions; + +/** + * 开炼机动作(中间库 MCSToMES_Act_Mill) + */ +@Tag(name = "开炼机动作(中间库)") +@RestController +@RequestMapping("/xslmes/mcs/mcsToMesActMill") +@Slf4j +public class McsToMesActMillController extends JeecgController { + + @Autowired + private IMcsToMesActMillService mcsToMesActMillService; + + @Operation(summary = "开炼机动作(中间库)-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(McsToMesActMill mcsToMesActMill, + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, + HttpServletRequest req) { + QueryWrapper queryWrapper = McsQueryHelper.buildWrapper(mcsToMesActMill, req.getParameterMap()); + Page page = new Page<>(pageNo, pageSize); + IPage pageList = mcsToMesActMillService.page(page, queryWrapper); + return Result.OK(pageList); + } + + @Operation(summary = "开炼机动作(中间库)-通过id查询") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name = "id", required = true) String id) { + McsToMesActMill entity = mcsToMesActMillService.getById(id); + if (entity == null) { + return Result.error("未找到对应数据"); + } + return Result.OK(entity); + } + + @RequiresPermissions("xslmes:mcsToMesActMill:exportXls") + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, McsToMesActMill mcsToMesActMill) { + return super.exportXls(request, mcsToMesActMill, McsToMesActMill.class, "开炼机动作(中间库)"); + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/controller/MesToMcsPushController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/controller/MesToMcsPushController.java new file mode 100644 index 00000000..89c858cf --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/controller/MesToMcsPushController.java @@ -0,0 +1,41 @@ +package org.jeecg.modules.xslmes.mcs.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.jeecg.common.api.vo.Result; +import org.jeecg.modules.xslmes.mcs.access.MesToMcsPushService; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * MES → MCS 经桌面代理下发。 + */ +@Tag(name = "MES上辅机下发") +@RestController +@RequestMapping("/xslmes/mcs/push") +@RequiredArgsConstructor +public class MesToMcsPushController { + + private final MesToMcsPushService mesToMcsPushService; + + @Operation(summary = "经桌面代理写入中间表") + @PostMapping("/rows") + @SuppressWarnings("unchecked") + public Result> pushRows(@RequestBody Map body) { + String table = body == null ? null : String.valueOf(body.getOrDefault("table", "")); + String mode = body == null ? "insert" : String.valueOf(body.getOrDefault("mode", "insert")); + List keys = body == null ? null : (List) body.get("keys"); + List> rows = body == null ? null : (List>) body.get("rows"); + int affected = mesToMcsPushService.push(table, mode, keys, rows); + Map data = new HashMap<>(); + data.put("affected", affected); + return Result.OK(data); + } +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/controller/MesXslMcsDbConfigController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/controller/MesXslMcsDbConfigController.java index 7bbb9188..ebc0944d 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/controller/MesXslMcsDbConfigController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/controller/MesXslMcsDbConfigController.java @@ -29,6 +29,9 @@ public class MesXslMcsDbConfigController { @Autowired private McsDataSourceManager mcsDataSourceManager; + @Autowired + private org.jeecg.modules.device.sync.agent.DeviceAgentSessionRegistry agentSessionRegistry; + private Integer resolveTenantId(Integer tenantId) { if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) { if (tenantId == null) { @@ -75,11 +78,21 @@ public class MesXslMcsDbConfigController { data.put("dbConfigActive", mcsDataSourceManager.isDbConfigActive()); data.put("readEnabled", mcsDataSourceManager.isReadEnabled()); data.put("writeEnabled", mcsDataSourceManager.isWriteEnabled()); + boolean agentMode = mcsDataSourceManager.isDesktopAgentMode(); + data.put("accessMode", agentMode ? "DESKTOP_AGENT" : "DIRECT"); + data.put("agentMode", agentMode); if (cfg != null) { data.put("serverHost", cfg.getServerHost()); data.put("serverPort", cfg.getServerPort()); data.put("dbName", cfg.getDbName()); + data.put("agentDeviceId", cfg.getAgentDeviceId()); } + var agent = agentSessionRegistry.pickOnlineAgent(cfg == null ? null : cfg.getAgentDeviceId()); + data.put("agentOnline", agent != null && agent.isOnline()); + data.put("agentDbConnected", agent != null && agent.isDbConnected()); + data.put("agentHostName", agent == null ? null : agent.getHostName()); + data.put("agentDbMessage", agent == null ? null : agent.getDbMessage()); + data.put("agentLastSeenAt", agent == null ? null : agent.getLastSeenAt()); return Result.OK(data); } } diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/datasource/McsDataSourceManager.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/datasource/McsDataSourceManager.java index 40e1b68a..85a15a46 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/datasource/McsDataSourceManager.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/datasource/McsDataSourceManager.java @@ -9,7 +9,11 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.jeecg.common.util.dynamic.db.DataSourceCachePool; import org.jeecg.modules.system.util.SecurityUtil; +import org.jeecg.modules.xslmes.mcs.access.DesktopAgentMcsDataAccess; +import org.jeecg.modules.xslmes.mcs.access.McsDataAccessFacade; +import org.jeecg.modules.xslmes.mcs.access.proxy.AgentProxyDataSource; import org.jeecg.modules.xslmes.mcs.entity.MesXslMcsDbConfig; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -37,6 +41,9 @@ public class McsDataSourceManager { @Autowired private DruidDataSourceCreator dataSourceCreator; + @Autowired + private ObjectProvider desktopAgentMcsDataAccessProvider; + @Value("${spring.datasource.dynamic.datasource.sqlserver_mcs.url:}") private String ymlUrl; @@ -98,6 +105,17 @@ public class McsDataSourceManager { } if (Integer.valueOf(1).equals(config.getStatus())) { try { + if (isDesktopAgentMode(config)) { + DesktopAgentMcsDataAccess agent = desktopAgentMcsDataAccessProvider.getIfAvailable(); + if (agent == null) { + throw new IllegalStateException("桌面代理访问组件未就绪"); + } + routing.addDataSource(DS_KEY, new AgentProxyDataSource(agent)); + cachedConfig.set(config); + log.info("[MCS中间库] 已切换为桌面代理模式 sqlserver_mcs -> AgentProxy, deviceId={}", + config.getAgentDeviceId()); + return; + } String plainPassword = decryptPassword(config.getDbPassword()); DataSourceProperty property = buildDataSourceProperty(config, plainPassword); DataSource mcsDs = dataSourceCreator.createDataSource(property); @@ -117,6 +135,21 @@ public class McsDataSourceManager { log.info("[MCS中间库] 连接未启用,读写开关仍按页面配置生效"); } + public boolean isDesktopAgentMode(MesXslMcsDbConfig config) { + MesXslMcsDbConfig cfg = config != null ? config : cachedConfig.get(); + if (cfg == null) { + return true; + } + String mode = StringUtils.isBlank(cfg.getAccessMode()) + ? McsDataAccessFacade.MODE_DESKTOP_AGENT + : cfg.getAccessMode().trim().toUpperCase(); + return McsDataAccessFacade.MODE_DESKTOP_AGENT.equals(mode); + } + + public boolean isDesktopAgentMode() { + return isDesktopAgentMode(null); + } + private void closeAndRemoveDataSource(DynamicRoutingDataSource routing) { if (!routing.getDataSources().containsKey(DS_KEY)) { return; diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/entity/McsToMesActMill.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/entity/McsToMesActMill.java new file mode 100644 index 00000000..91461a97 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/entity/McsToMesActMill.java @@ -0,0 +1,76 @@ +package org.jeecg.modules.xslmes.mcs.entity; + +import java.io.Serializable; +import java.util.Date; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 开炼机动作(中间库 MCSToMES_Act_Mill) + */ +@Data +@TableName("MCSToMES_Act_Mill") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@Schema(description = "开炼机动作(中间库)") +public class McsToMesActMill implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(value = "GUID", type = IdType.INPUT) + @Schema(description = "GUID") + @Excel(name = "GUID", width = 36) + private String guid; + + @Excel(name = "动作地址", width = 10) + @Schema(description = "动作地址") + @TableField("act_addr") + private Integer actAddr; + + @Excel(name = "动作名称", width = 20) + @Schema(description = "动作名称") + @TableField("act_name") + private String actName; + + @Excel(name = "动作名称(英)", width = 20) + @Schema(description = "动作名称(英)") + @TableField("act_name_en") + private String actNameEn; + + @Excel(name = "动作备注", width = 15) + @Schema(description = "动作备注") + @TableField("act_memo") + private String actMemo; + + @Excel(name = "动作关联地址", width = 12) + @Schema(description = "动作关联地址") + @TableField("act_Repaddr") + private Integer actRepaddr; + + @Excel(name = "写入时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Schema(description = "写入时间") + @TableField("WriteTime") + private Date writeTime; + + @Excel(name = "读取时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Schema(description = "读取时间") + @TableField("ReadTime") + private Date readTime; + + @Excel(name = "读写标识", width = 10) + @Schema(description = "读写标识") + @TableField("RW_Flag") + private Integer rwFlag; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/entity/MesXslMcsDbConfig.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/entity/MesXslMcsDbConfig.java index ebda2f5a..bd9f0968 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/entity/MesXslMcsDbConfig.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/entity/MesXslMcsDbConfig.java @@ -66,6 +66,14 @@ public class MesXslMcsDbConfig implements Serializable { @Schema(description = "备注") private String remark; + //update-begin---author:cursor ---date:2026-07-20 for:【设备库桥接】访问模式与绑定桌面代理----------- + @Schema(description = "访问模式:DESKTOP_AGENT=桌面代理,DIRECT=服务端直连") + private String accessMode; + + @Schema(description = "绑定的桌面代理 deviceId") + private String agentDeviceId; + //update-end---author:cursor ---date:2026-07-20 for:【设备库桥接】访问模式与绑定桌面代理----------- + private String createBy; @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/mapper/McsToMesActMillMapper.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/mapper/McsToMesActMillMapper.java new file mode 100644 index 00000000..a0c5a449 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/mapper/McsToMesActMillMapper.java @@ -0,0 +1,10 @@ +package org.jeecg.modules.xslmes.mcs.mapper; + +import org.jeecg.modules.xslmes.mcs.entity.McsToMesActMill; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 开炼机动作(中间库) + */ +public interface McsToMesActMillMapper extends BaseMapper { +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/IMcsToMesActMillService.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/IMcsToMesActMillService.java new file mode 100644 index 00000000..9522afec --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/IMcsToMesActMillService.java @@ -0,0 +1,10 @@ +package org.jeecg.modules.xslmes.mcs.service; + +import org.jeecg.modules.xslmes.mcs.entity.McsToMesActMill; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * 开炼机动作(中间库) + */ +public interface IMcsToMesActMillService extends IService { +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/impl/McsToMesActMillServiceImpl.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/impl/McsToMesActMillServiceImpl.java new file mode 100644 index 00000000..0ef4a5d5 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/impl/McsToMesActMillServiceImpl.java @@ -0,0 +1,16 @@ +package org.jeecg.modules.xslmes.mcs.service.impl; + +import org.jeecg.modules.xslmes.mcs.entity.McsToMesActMill; +import org.jeecg.modules.xslmes.mcs.mapper.McsToMesActMillMapper; +import org.jeecg.modules.xslmes.mcs.service.IMcsToMesActMillService; +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.baomidou.dynamic.datasource.annotation.DS; + +/** + * 开炼机动作(中间库) + */ +@Service +@DS("sqlserver_mcs") +public class McsToMesActMillServiceImpl extends ServiceImpl implements IMcsToMesActMillService { +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/impl/MesXslMcsDbConfigServiceImpl.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/impl/MesXslMcsDbConfigServiceImpl.java index 61815579..92d7b527 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/impl/MesXslMcsDbConfigServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/impl/MesXslMcsDbConfigServiceImpl.java @@ -30,6 +30,9 @@ public class MesXslMcsDbConfigServiceImpl extends ServiceImpl fields) { String sourceTable = trim(cfg.getSourceTable()); @@ -91,7 +94,6 @@ public class GenericMcsSyncEngine { } String mode = StringUtils.isBlank(cfg.getSyncMode()) ? MODE_FULL : cfg.getSyncMode().trim().toUpperCase(); - JdbcTemplate sourceJt = new JdbcTemplate(getSourceDataSource()); JdbcTemplate targetJt = new JdbcTemplate(dataSource); // 目标表标准字段探测 + 自动填充列 @@ -134,7 +136,7 @@ public class GenericMcsSyncEngine { String predicate = flagPredicate(flagCol, cfg.getFlagCondition(), cfg.getFlagMatchValue()); String sql = "SELECT TOP " + limit + " " + colList(srcCols) + " FROM [" + sourceTable + "]" + " WHERE (" + predicate + ")"; - rows = sourceJt.queryForList(sql); + rows = mcsDataAccessFacade.query(sql, null); if (rows.isEmpty()) { return "增量采集:无待采集数据"; } @@ -149,10 +151,10 @@ public class GenericMcsSyncEngine { sql.append(" AND [").append(incrCol).append("] < ?"); args.add(window[1]); } - rows = sourceJt.queryForList(sql.toString(), args.toArray()); + rows = mcsDataAccessFacade.query(sql.toString(), args); } else { // FULL - rows = sourceJt.queryForList("SELECT " + colList(srcCols) + " FROM [" + sourceTable + "]"); + rows = mcsDataAccessFacade.query("SELECT " + colList(srcCols) + " FROM [" + sourceTable + "]", null); } if (rows.isEmpty()) { @@ -209,7 +211,7 @@ public class GenericMcsSyncEngine { // INCR(标记回写):对本批所有源行回写标记值,下轮不再采集 if (flagMode) { String writeValue = StringUtils.isBlank(cfg.getFlagWriteValue()) ? FLAG_SYNCED : cfg.getFlagWriteValue(); - int marked = writeBackFlag(sourceJt, sourceTable, flagCol, cfg.getFlagCondition(), cfg.getFlagMatchValue(), writeValue, keyMaps, rows); + int marked = writeBackFlag(sourceTable, flagCol, cfg.getFlagCondition(), cfg.getFlagMatchValue(), writeValue, keyMaps, rows); return String.format("增量采集:新增%d,更新%d,未变%d,回写标记%d,源%d条", ins, upd, unchanged, marked, rows.size()); } @@ -252,14 +254,14 @@ public class GenericMcsSyncEngine { * 避免误标在本轮 SELECT 之后才进入中间库、尚未采集的新数据; * 并以采集条件谓词做守卫,避开本轮已被其他进程改动的行。

*/ - private int writeBackFlag(JdbcTemplate sourceJt, String sourceTable, String flagCol, String condition, + private int writeBackFlag(String sourceTable, String flagCol, String condition, String matchValue, String writeValue, List keyMaps, List> rows) { validateIdent(flagCol); StringBuilder sql = new StringBuilder("UPDATE [").append(sourceTable).append("] SET [") .append(flagCol).append("] = ? WHERE "); sql.append(keyMaps.stream().map(k -> "[" + k.getSourceField() + "] = ?").collect(Collectors.joining(" AND "))); sql.append(" AND (").append(flagPredicate(flagCol, condition, matchValue)).append(")"); - List argsList = new ArrayList<>(); + int total = 0; Set handled = new HashSet<>(); for (Map row : rows) { Map rci = ci(row); @@ -272,9 +274,9 @@ public class GenericMcsSyncEngine { for (MesXslMcsSyncField k : keyMaps) { args.add(rci.get(k.getSourceField())); } - argsList.add(args.toArray()); + total += mcsDataAccessFacade.execute(sql.toString(), args); } - return batch(sourceJt, sql.toString(), argsList); + return total; } //update-end---author:GHT ---date:20260617 for:【MES上辅机】增量匹配改为标记位回写----------- @@ -502,15 +504,6 @@ public class GenericMcsSyncEngine { return maps.stream().anyMatch(m -> m.getTargetField() != null && m.getTargetField().equalsIgnoreCase(targetCol)); } - private DataSource getSourceDataSource() { - DynamicRoutingDataSource routing = (DynamicRoutingDataSource) dataSource; - DataSource src = routing.getDataSources().get(McsDataSourceManager.DS_KEY); - if (src == null) { - throw new IllegalStateException("中间库数据源 " + McsDataSourceManager.DS_KEY + " 未注册"); - } - return src; - } - private void validateIdent(String name) { if (name == null || !IDENT.matcher(name).matches()) { throw new IllegalArgumentException("非法的表名或字段名: " + name); diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslMillActionService.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslMillActionService.java new file mode 100644 index 00000000..28641df0 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslMillActionService.java @@ -0,0 +1,6 @@ +package org.jeecg.modules.xslmes.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.modules.xslmes.entity.MesXslMillAction; + +public interface IMesXslMillActionService extends IService {} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslMixerConditionService.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslMixerConditionService.java index 76952369..79d9eab2 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslMixerConditionService.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslMixerConditionService.java @@ -7,7 +7,9 @@ public interface IMesXslMixerConditionService extends IService items = new ArrayList<>(); int aIndex = 0; @@ -551,16 +575,24 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl syncedRubberSpecCodes = new HashSet<>(); + //update-begin---author:jiangxh ---date:20260729 for:【混炼示方生成】B/F胶料改为胶料列表匹配,不存在则提示先维护----------- Map categoryIdCache = new HashMap<>(); - //update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A48】生成混炼示方同步B/F段胶至密炼物料----------- + assertRequiredRubberMaterialsExist(request.getRows(), formula, lines); + //update-end---author:jiangxh ---date:20260729 for:【混炼示方生成】B/F胶料改为胶料列表匹配,不存在则提示先维护----------- for (MesXslFormulaMixingGenerateRowVO row : request.getRows()) { if (row == null || oConvertUtils.isEmpty(row.getSpecCode()) || row.getStageIndex() == null) { continue; @@ -609,11 +641,6 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl materials = buildMixingMaterials( @@ -647,11 +674,15 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl toGenerateRowsFromPreviewItems( + List items) { + List rows = new ArrayList<>(); + if (CollectionUtils.isEmpty(items)) { + return rows; + } + for (MesXslFormulaMixingGeneratePreviewItemVO item : items) { + if (item == null) { + continue; + } + MesXslFormulaMixingGenerateRowVO row = new MesXslFormulaMixingGenerateRowVO(); + row.setSpecCode(item.getSpecCode()); + row.setStageIndex(item.getStageIndex()); + row.setASegmentIndex(item.getASegmentIndex()); + row.setStepType(item.getStepType()); + rows.add(row); + } + return rows; + } + //update-end---author:jiangxh ---date:20260730 for:【混炼示方生成】预览项转生成行供胶料匹配校验----------- + /** - * 生成混炼示方时,将 B 段/F 段胶料同步写入「胶料信息」(mes_material): - * 除 ERP 编号留空、编码/名称为示方编号外,其余字段按配合示方所选原胶料信息赋值。 + * 生成前校验:按 B段序号/F + 胶料名 拼出的示方编号,必须已在胶料信息中存在;不再自动新建。 + * 在列表点击「生成混炼示方」预览时即调用,确认生成时再次校验。 */ + private void assertRequiredRubberMaterialsExist( + List rows, + MesXslFormulaSpec formula, + List lines) { + if (CollectionUtils.isEmpty(rows)) { + return; + } + LinkedHashSet requiredCodes = new LinkedHashSet<>(); + String rubberName = resolveRubberName(formula); + for (MesXslFormulaMixingGenerateRowVO row : rows) { + if (row == null || StringUtils.isBlank(row.getSpecCode())) { + continue; + } + requiredCodes.add(row.getSpecCode().trim()); + String stepFilter = resolveMixingMaterialStep(row); + int mixingColumn = resolveMixingColumn(row, formula); + if ("Q".equalsIgnoreCase(stepFilter)) { + int lastBSegment = resolveLastBSegmentIndex(formula, lines); + if (lastBSegment > 0 && StringUtils.isNotBlank(rubberName)) { + //update-begin---author:jiangxh ---date:20260730 for:【混炼示方生成】母胶匹配不拼版本后缀----------- + requiredCodes.add(buildBfRubberSpecCode("B" + lastBSegment, rubberName)); + //update-end---author:jiangxh ---date:20260730 for:【混炼示方生成】母胶匹配不拼版本后缀----------- + } + } else if (mixingColumn > 1 && StringUtils.isNotBlank(rubberName)) { + //update-begin---author:jiangxh ---date:20260730 for:【混炼示方生成】母胶匹配不拼版本后缀----------- + requiredCodes.add(buildBfRubberSpecCode("B" + (mixingColumn - 1), rubberName)); + //update-end---author:jiangxh ---date:20260730 for:【混炼示方生成】母胶匹配不拼版本后缀----------- + } + } + List missing = new ArrayList<>(); + for (String code : requiredCodes) { + if (StringUtils.isBlank(code)) { + continue; + } + if (findRubberMaterialByCodeOrName(code.trim()) == null) { + missing.add(code.trim()); + } + } + if (!missing.isEmpty()) { + throw new IllegalArgumentException("请先维护母胶和终胶信息:" + String.join("、", missing)); + } + } + + /** + * @deprecated 已改为仅匹配胶料列表,保留方法避免历史调用编译缺口;生成流程不再自动写入胶料。 + */ + @Deprecated private void syncGeneratedRubberMixerMaterial( MesXslFormulaMixingGenerateRowVO row, MesXslFormulaSpec formula, @@ -784,60 +888,9 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl lines) { if (CollectionUtils.isEmpty(lines)) { return false; @@ -1071,10 +1141,11 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl 0) { - String motherSpecCode = appendFormulaCodeSuffix("B" + lastBSegment + rubberName, codeSuffix); + //update-begin---author:jiangxh ---date:20260730 for:【混炼示方生成】母胶编号不拼版本后缀----------- + String motherSpecCode = buildBfRubberSpecCode("B" + lastBSegment, rubberName); + //update-end---author:jiangxh ---date:20260730 for:【混炼示方生成】母胶编号不拼版本后缀----------- BigDecimal motherWeight = resolveStageCumulativeTotal(formula, lines, lastBSegment); materials.add( createMotherRubberMaterial( @@ -1095,7 +1166,6 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl implements IMesXslMillActionService {} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixerConditionServiceImpl.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixerConditionServiceImpl.java index c6d60a4e..1ef87ca8 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixerConditionServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixerConditionServiceImpl.java @@ -18,13 +18,16 @@ public class MesXslMixerConditionServiceImpl @Autowired private MesXslEquipmentLedgerMapper equipmentLedgerMapper; + //update-begin---author:jiangxh ---date:20260728 for:【密炼机条件】条件名称/代码按设备唯一----------- @Override - public boolean isConditionNameDuplicated(String conditionName, String excludeId) { - if (StringUtils.isBlank(conditionName)) { + public boolean isConditionNameDuplicated(String conditionName, String equipmentId, String excludeId) { + if (StringUtils.isBlank(conditionName) || StringUtils.isBlank(equipmentId)) { return false; } LambdaQueryWrapper wrapper = - new LambdaQueryWrapper().eq(MesXslMixerCondition::getConditionName, conditionName.trim()); + new LambdaQueryWrapper() + .eq(MesXslMixerCondition::getEquipmentId, equipmentId.trim()) + .eq(MesXslMixerCondition::getConditionName, conditionName.trim()); if (StringUtils.isNotBlank(excludeId)) { wrapper.ne(MesXslMixerCondition::getId, excludeId.trim()); } @@ -32,17 +35,20 @@ public class MesXslMixerConditionServiceImpl } @Override - public boolean isConditionCodeDuplicated(String conditionCode, String excludeId) { - if (StringUtils.isBlank(conditionCode)) { + public boolean isConditionCodeDuplicated(String conditionCode, String equipmentId, String excludeId) { + if (StringUtils.isBlank(conditionCode) || StringUtils.isBlank(equipmentId)) { return false; } LambdaQueryWrapper wrapper = - new LambdaQueryWrapper().eq(MesXslMixerCondition::getConditionCode, conditionCode.trim()); + new LambdaQueryWrapper() + .eq(MesXslMixerCondition::getEquipmentId, equipmentId.trim()) + .eq(MesXslMixerCondition::getConditionCode, conditionCode.trim()); if (StringUtils.isNotBlank(excludeId)) { wrapper.ne(MesXslMixerCondition::getId, excludeId.trim()); } return this.count(wrapper) > 0; } + //update-end---author:jiangxh ---date:20260728 for:【密炼机条件】条件名称/代码按设备唯一----------- @Override public void fillEquipmentName(MesXslMixerCondition model) { diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixingProductionPlanServiceImpl.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixingProductionPlanServiceImpl.java index 373eac33..66268c56 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixingProductionPlanServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixingProductionPlanServiceImpl.java @@ -103,6 +103,8 @@ public class MesXslMixingProductionPlanServiceImpl private void rebuildRawMaterialDemandPlan(List savedPlans) { jdbcTemplate.update("DELETE FROM mes_xsl_raw_material_demand_plan"); + jdbcTemplate.update("DELETE FROM mes_xsl_auto_small_material_demand_plan"); + jdbcTemplate.update("DELETE FROM mes_xsl_manual_small_material_demand_plan"); if (CollectionUtils.isEmpty(savedPlans)) { return; } @@ -184,6 +186,8 @@ public class MesXslMixingProductionPlanServiceImpl } Map aggregateMap = new HashMap<>(); + Map autoAggregateMap = new HashMap<>(); + Map manualAggregateMap = new HashMap<>(); for (MesXslMixingProductionPlan plan : validPlans) { String specId = specIdByName.get(StringUtils.trimToEmpty(plan.getFormulaName())); if (StringUtils.isBlank(specId)) { @@ -241,19 +245,39 @@ public class MesXslMixingProductionPlanServiceImpl StringUtils.defaultString(erpCode), rawMaterialName)); aggregate.demandWeight = aggregate.demandWeight.add(demandWeight); + + String smallKey = + String.join( + "|", + planDateKey, + StringUtils.defaultString(plan.getMachineId()), + StringUtils.defaultString(plan.getMachineName()), + rawMaterialName); + boolean isAutoKind = StringUtils.contains(StringUtils.trimToEmpty(detail.getMaterialKind()), "自动"); + Map targetSmallMap = isAutoKind ? autoAggregateMap : manualAggregateMap; + SmallDemandAggregate smallAggregate = + targetSmallMap.computeIfAbsent( + smallKey, + k -> + new SmallDemandAggregate( + plan.getPlanDate(), + StringUtils.trimToNull(plan.getMachineId()), + StringUtils.trimToNull(plan.getMachineName()), + rawMaterialName)); + smallAggregate.demandWeight = smallAggregate.demandWeight.add(demandWeight); } } - if (aggregateMap.isEmpty()) { + if (aggregateMap.isEmpty() && autoAggregateMap.isEmpty() && manualAggregateMap.isEmpty()) { return; } - List batchArgs = new ArrayList<>(); + List rawBatchArgs = new ArrayList<>(); Date now = new Date(); for (RawDemandAggregate aggregate : aggregateMap.values()) { if (aggregate.demandWeight.compareTo(BigDecimal.ZERO) <= 0) { continue; } - batchArgs.add( + rawBatchArgs.add( new Object[] { IdWorker.getIdStr(), aggregate.machineId, @@ -270,14 +294,53 @@ public class MesXslMixingProductionPlanServiceImpl CommonConstant.DEL_FLAG_0 }); } - if (batchArgs.isEmpty()) { - return; + if (!rawBatchArgs.isEmpty()) { + jdbcTemplate.batchUpdate( + "INSERT INTO mes_xsl_raw_material_demand_plan " + + "(id, machine_id, machine_name, material_id, erp_code, raw_material_name, demand_weight, standard_weight, actual_weight, plan_date, create_time, update_time, del_flag) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + rawBatchArgs); } - jdbcTemplate.batchUpdate( - "INSERT INTO mes_xsl_raw_material_demand_plan " - + "(id, machine_id, machine_name, material_id, erp_code, raw_material_name, demand_weight, standard_weight, actual_weight, plan_date, create_time, update_time, del_flag) " - + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - batchArgs); + + List autoBatchArgs = buildSmallDemandBatchArgs(autoAggregateMap, now); + if (!autoBatchArgs.isEmpty()) { + jdbcTemplate.batchUpdate( + "INSERT INTO mes_xsl_auto_small_material_demand_plan " + + "(id, stat_date, machine_id, machine_name, raw_material_name, demand_weight, create_time, update_time, del_flag) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", + autoBatchArgs); + } + List manualBatchArgs = buildSmallDemandBatchArgs(manualAggregateMap, now); + if (!manualBatchArgs.isEmpty()) { + jdbcTemplate.batchUpdate( + "INSERT INTO mes_xsl_manual_small_material_demand_plan " + + "(id, stat_date, machine_id, machine_name, raw_material_name, demand_weight, create_time, update_time, del_flag) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", + manualBatchArgs); + } + } + + private List buildSmallDemandBatchArgs( + Map aggregateMap, Date now) { + List batchArgs = new ArrayList<>(); + for (SmallDemandAggregate aggregate : aggregateMap.values()) { + if (aggregate.demandWeight.compareTo(BigDecimal.ZERO) <= 0) { + continue; + } + batchArgs.add( + new Object[] { + IdWorker.getIdStr(), + aggregate.statDate, + aggregate.machineId, + aggregate.machineName, + aggregate.rawMaterialName, + aggregate.demandWeight, + now, + now, + CommonConstant.DEL_FLAG_0 + }); + } + return batchArgs; } private static class RawDemandAggregate { @@ -305,6 +368,22 @@ public class MesXslMixingProductionPlanServiceImpl } } + private static class SmallDemandAggregate { + private final Date statDate; + private final String machineId; + private final String machineName; + private final String rawMaterialName; + private BigDecimal demandWeight = BigDecimal.ZERO; + + private SmallDemandAggregate( + Date statDate, String machineId, String machineName, String rawMaterialName) { + this.statDate = statDate; + this.machineId = machineId; + this.machineName = machineName; + this.rawMaterialName = rawMaterialName; + } + } + private boolean hasBusinessData(MesXslMixingProductionPlan row) { return StringUtils.isNotBlank(row.getMachineId()) || StringUtils.isNotBlank(row.getPlanId()) diff --git a/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/agent/DeviceAgentCommand.java b/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/agent/DeviceAgentCommand.java new file mode 100644 index 00000000..17f640a7 --- /dev/null +++ b/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/agent/DeviceAgentCommand.java @@ -0,0 +1,34 @@ +package org.jeecg.modules.device.sync.agent; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * MES → 桌面设备库命令。 + */ +@Data +public class DeviceAgentCommand implements Serializable { + private static final long serialVersionUID = 1L; + + public static final String CMD_QUERY = "EQ_QUERY"; + public static final String CMD_WRITE = "EQ_WRITE"; + public static final String CMD_SYNC_PULL = "EQ_SYNC_PULL"; + public static final String CMD_SYNC_PUSH = "EQ_SYNC_PUSH"; + public static final String CMD_TEST = "EQ_TEST"; + + private String requestId; + private String cmd; + private String deviceId; + /** 白名单表名(可选,与 sql 二选一或同时校验) */ + private String table; + /** 已登记 sqlKey 或受限 SQL(桌面端白名单校验) */ + private String sql; + private String sqlKey; + private List params; + private Map payload; + private Integer timeoutMs; + private Long sentAt; +} diff --git a/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/agent/DeviceAgentCommandService.java b/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/agent/DeviceAgentCommandService.java new file mode 100644 index 00000000..442d9ab2 --- /dev/null +++ b/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/agent/DeviceAgentCommandService.java @@ -0,0 +1,166 @@ +package org.jeecg.modules.device.sync.agent; + +import com.alibaba.fastjson.JSON; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * 设备代理命令总线:下发 EQ_* 并等待回执。 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class DeviceAgentCommandService { + + public static final int DEFAULT_TIMEOUT_MS = 30_000; + + private final SimpMessagingTemplate messagingTemplate; + private final DeviceAgentSessionRegistry sessionRegistry; + + private final ConcurrentHashMap> pending = new ConcurrentHashMap<>(); + + public DeviceAgentResult sendAndWait(DeviceAgentCommand command) { + if (command == null) { + throw new IllegalArgumentException("command 不能为空"); + } + if (StringUtils.isBlank(command.getRequestId())) { + command.setRequestId(UUID.randomUUID().toString().replace("-", "")); + } + if (StringUtils.isBlank(command.getDeviceId())) { + DeviceAgentSession picked = sessionRegistry.pickOnlineAgent(null); + if (picked == null) { + throw new IllegalStateException("无在线桌面设备代理,无法访问设备库"); + } + command.setDeviceId(picked.getDeviceId()); + } + if (!sessionRegistry.isOnline(command.getDeviceId())) { + throw new IllegalStateException("桌面设备代理不在线: " + command.getDeviceId()); + } + int timeout = command.getTimeoutMs() != null && command.getTimeoutMs() > 0 + ? command.getTimeoutMs() : DEFAULT_TIMEOUT_MS; + command.setSentAt(System.currentTimeMillis()); + + CompletableFuture future = new CompletableFuture<>(); + CompletableFuture previous = pending.putIfAbsent(command.getRequestId(), future); + if (previous != null) { + throw new IllegalStateException("重复的 requestId: " + command.getRequestId()); + } + + try { + String destination = "/topic/device/" + command.getDeviceId() + "/cmd"; + messagingTemplate.convertAndSend(destination, JSON.toJSONString(command)); + log.info("已下发设备库命令 cmd={} requestId={} deviceId={}", + command.getCmd(), command.getRequestId(), command.getDeviceId()); + return future.get(timeout, TimeUnit.MILLISECONDS); + } catch (TimeoutException e) { + pending.remove(command.getRequestId(), future); + throw new IllegalStateException("等待桌面设备库回执超时(" + timeout + "ms), requestId=" + command.getRequestId()); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + pending.remove(command.getRequestId(), future); + throw new IllegalStateException("等待桌面设备库回执被中断", e); + } catch (Exception e) { + pending.remove(command.getRequestId(), future); + if (e instanceof IllegalStateException) { + throw (IllegalStateException) e; + } + throw new IllegalStateException("下发设备库命令失败: " + e.getMessage(), e); + } + } + + public void completeResult(DeviceAgentResult result) { + if (result == null || StringUtils.isBlank(result.getRequestId())) { + return; + } + if (StringUtils.isNotBlank(result.getDeviceId())) { + sessionRegistry.registerOrHeartbeat( + result.getDeviceId(), + null, + result.getDbConnected(), + result.getDbMessage()); + } + CompletableFuture future = pending.remove(result.getRequestId()); + if (future != null) { + future.complete(result); + } else { + log.debug("收到无等待方的设备库回执 requestId={}", result.getRequestId()); + } + } + + public DeviceAgentResult query(String deviceId, String sql, List params, Integer timeoutMs) { + DeviceAgentCommand cmd = new DeviceAgentCommand(); + cmd.setCmd(DeviceAgentCommand.CMD_QUERY); + cmd.setDeviceId(deviceId); + cmd.setSql(sql); + cmd.setParams(params); + cmd.setTimeoutMs(timeoutMs); + DeviceAgentResult result = sendAndWait(cmd); + ensureSuccess(result); + return result; + } + + public DeviceAgentResult write(String deviceId, String sql, List params, Integer timeoutMs) { + DeviceAgentCommand cmd = new DeviceAgentCommand(); + cmd.setCmd(DeviceAgentCommand.CMD_WRITE); + cmd.setDeviceId(deviceId); + cmd.setSql(sql); + cmd.setParams(params); + cmd.setTimeoutMs(timeoutMs); + DeviceAgentResult result = sendAndWait(cmd); + ensureSuccess(result); + return result; + } + + public DeviceAgentResult test(String deviceId, Integer timeoutMs) { + DeviceAgentCommand cmd = new DeviceAgentCommand(); + cmd.setCmd(DeviceAgentCommand.CMD_TEST); + cmd.setDeviceId(deviceId); + cmd.setTimeoutMs(timeoutMs != null ? timeoutMs : 10_000); + return sendAndWait(cmd); + } + + public DeviceAgentResult syncPull(String deviceId, String table, String sql, List params, Integer timeoutMs) { + DeviceAgentCommand cmd = new DeviceAgentCommand(); + cmd.setCmd(DeviceAgentCommand.CMD_SYNC_PULL); + cmd.setDeviceId(deviceId); + cmd.setTable(table); + cmd.setSql(sql); + cmd.setParams(params); + cmd.setTimeoutMs(timeoutMs != null ? timeoutMs : 60_000); + DeviceAgentResult result = sendAndWait(cmd); + ensureSuccess(result); + return result; + } + + public DeviceAgentResult syncPush(String deviceId, String table, Map payload, Integer timeoutMs) { + DeviceAgentCommand cmd = new DeviceAgentCommand(); + cmd.setCmd(DeviceAgentCommand.CMD_SYNC_PUSH); + cmd.setDeviceId(deviceId); + cmd.setTable(table); + cmd.setPayload(payload); + cmd.setTimeoutMs(timeoutMs != null ? timeoutMs : 60_000); + DeviceAgentResult result = sendAndWait(cmd); + ensureSuccess(result); + return result; + } + + private void ensureSuccess(DeviceAgentResult result) { + if (result == null) { + throw new IllegalStateException("桌面设备库无回执"); + } + if (!result.isSuccess()) { + throw new IllegalStateException(StringUtils.defaultIfBlank(result.getError(), "桌面设备库执行失败")); + } + } +} diff --git a/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/agent/DeviceAgentResult.java b/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/agent/DeviceAgentResult.java new file mode 100644 index 00000000..43f16291 --- /dev/null +++ b/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/agent/DeviceAgentResult.java @@ -0,0 +1,30 @@ +package org.jeecg.modules.device.sync.agent; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * 桌面 → MES 设备库命令回执。 + */ +@Data +public class DeviceAgentResult implements Serializable { + private static final long serialVersionUID = 1L; + + private String requestId; + private String deviceId; + private String cmd; + private boolean success; + private String error; + private Integer affected; + private List> rows; + private Boolean dbConnected; + private String dbMessage; + private Long respondedAt; + /** 分块回传时使用 */ + private Integer chunkIndex; + private Integer chunkTotal; + private Boolean lastChunk; +} diff --git a/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/agent/DeviceAgentSession.java b/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/agent/DeviceAgentSession.java new file mode 100644 index 00000000..7161e6b7 --- /dev/null +++ b/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/agent/DeviceAgentSession.java @@ -0,0 +1,22 @@ +package org.jeecg.modules.device.sync.agent; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 桌面设备代理在线会话(内存)。 + */ +@Data +public class DeviceAgentSession implements Serializable { + private static final long serialVersionUID = 1L; + + private String deviceId; + private String hostName; + private boolean online; + /** 设备库(SQL Server)是否连通 */ + private boolean dbConnected; + private String dbMessage; + private long lastSeenAt; + private long registeredAt; +} diff --git a/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/agent/DeviceAgentSessionRegistry.java b/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/agent/DeviceAgentSessionRegistry.java new file mode 100644 index 00000000..aecdb1c6 --- /dev/null +++ b/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/agent/DeviceAgentSessionRegistry.java @@ -0,0 +1,121 @@ +package org.jeecg.modules.device.sync.agent; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 桌面设备代理会话注册表。 + */ +@Slf4j +@Component +public class DeviceAgentSessionRegistry { + + private static final long ONLINE_TTL_MS = 60_000L; + + private final ConcurrentHashMap sessions = new ConcurrentHashMap<>(); + + public void registerOrHeartbeat(String deviceId, String hostName, Boolean dbConnected, String dbMessage) { + if (StringUtils.isBlank(deviceId)) { + return; + } + long now = System.currentTimeMillis(); + sessions.compute(deviceId, (id, old) -> { + DeviceAgentSession s = old == null ? new DeviceAgentSession() : old; + if (old == null) { + s.setRegisteredAt(now); + } + s.setDeviceId(deviceId); + if (StringUtils.isNotBlank(hostName)) { + s.setHostName(hostName); + } + s.setOnline(true); + if (dbConnected != null) { + s.setDbConnected(dbConnected); + } + if (dbMessage != null) { + s.setDbMessage(dbMessage); + } + s.setLastSeenAt(now); + return s; + }); + } + + public void markOffline(String deviceId) { + if (StringUtils.isBlank(deviceId)) { + return; + } + DeviceAgentSession s = sessions.get(deviceId); + if (s != null) { + s.setOnline(false); + s.setLastSeenAt(System.currentTimeMillis()); + } + } + + public DeviceAgentSession get(String deviceId) { + if (StringUtils.isBlank(deviceId)) { + return null; + } + DeviceAgentSession s = sessions.get(deviceId); + if (s == null) { + return null; + } + refreshOnlineFlag(s); + return s; + } + + public boolean isOnline(String deviceId) { + DeviceAgentSession s = get(deviceId); + return s != null && s.isOnline(); + } + + /** + * 选取一个在线代理:优先指定 deviceId,否则取最近心跳的在线设备。 + */ + public DeviceAgentSession pickOnlineAgent(String preferredDeviceId) { + if (StringUtils.isNotBlank(preferredDeviceId)) { + DeviceAgentSession preferred = get(preferredDeviceId); + if (preferred != null && preferred.isOnline()) { + return preferred; + } + } + return listOnline().stream() + .max(Comparator.comparingLong(DeviceAgentSession::getLastSeenAt)) + .orElse(null); + } + + public List listOnline() { + List list = new ArrayList<>(); + for (Map.Entry e : sessions.entrySet()) { + DeviceAgentSession s = e.getValue(); + refreshOnlineFlag(s); + if (s.isOnline()) { + list.add(s); + } + } + list.sort(Comparator.comparingLong(DeviceAgentSession::getLastSeenAt).reversed()); + return list; + } + + public List listAll() { + List list = new ArrayList<>(sessions.values()); + list.forEach(this::refreshOnlineFlag); + list.sort(Comparator.comparingLong(DeviceAgentSession::getLastSeenAt).reversed()); + return list; + } + + private void refreshOnlineFlag(DeviceAgentSession s) { + if (s == null) { + return; + } + if (System.currentTimeMillis() - s.getLastSeenAt() > ONLINE_TTL_MS) { + s.setOnline(false); + } + } +} diff --git a/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/controller/DeviceWebSocketController.java b/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/controller/DeviceWebSocketController.java index eb672dd5..fd6eb17b 100644 --- a/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/controller/DeviceWebSocketController.java +++ b/jeecg-boot/jeecg-module-device-sync/src/main/java/org/jeecg/modules/device/sync/controller/DeviceWebSocketController.java @@ -1,20 +1,29 @@ package org.jeecg.modules.device.sync.controller; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.jeecg.common.api.vo.Result; +import org.jeecg.modules.device.sync.agent.DeviceAgentCommand; +import org.jeecg.modules.device.sync.agent.DeviceAgentCommandService; +import org.jeecg.modules.device.sync.agent.DeviceAgentResult; +import org.jeecg.modules.device.sync.agent.DeviceAgentSession; +import org.jeecg.modules.device.sync.agent.DeviceAgentSessionRegistry; import org.jeecg.modules.device.sync.entity.DeviceStatus; import org.jeecg.modules.device.sync.mapper.DeviceStatusMapper; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; @@ -29,6 +38,8 @@ public class DeviceWebSocketController { private final DeviceStatusMapper deviceStatusMapper; private final SimpMessagingTemplate messagingTemplate; + private final DeviceAgentSessionRegistry agentSessionRegistry; + private final DeviceAgentCommandService agentCommandService; @MessageMapping("/device/status") public void receiveDeviceStatus(DeviceStatus payload) { @@ -70,6 +81,8 @@ public class DeviceWebSocketController { if (deviceId.isBlank()) { return; } + // 心跳同时刷新设备代理在线状态 + agentSessionRegistry.registerOrHeartbeat(deviceId, null, null, null); Map pong = new HashMap<>(); pong.put("cmd", "PONG_DEVICE"); pong.put("deviceId", deviceId); @@ -91,6 +104,8 @@ public class DeviceWebSocketController { commandPayload.put("sentAt", System.currentTimeMillis()); messagingTemplate.convertAndSendToUser(deviceId, "/queue/command", commandPayload); + // 匿名桌面同样订阅 /topic/device/{id}/cmd + messagingTemplate.convertAndSend("/topic/device/" + deviceId + "/cmd", commandJson); log.info("下发设备指令成功, deviceId={}", deviceId); Map result = new HashMap<>(); @@ -98,4 +113,87 @@ public class DeviceWebSocketController { result.put("queued", true); return Result.OK(result); } + + //update-begin---author:cursor ---date:2026-07-20 for:【设备库桥接】代理状态/回执/在线列表----------- + /** + * 桌面代理上报在线与设备库连通状态。 + * destination: /app/device/agent/status + */ + @MessageMapping("/device/agent/status") + public void receiveAgentStatus(@org.springframework.messaging.handler.annotation.Payload(required = false) Map payload) { + if (payload == null) { + return; + } + String deviceId = String.valueOf(payload.getOrDefault("deviceId", "")).trim(); + if (deviceId.isBlank()) { + return; + } + String hostName = payload.get("hostName") == null ? null : String.valueOf(payload.get("hostName")); + Boolean dbConnected = null; + if (payload.get("dbConnected") instanceof Boolean) { + dbConnected = (Boolean) payload.get("dbConnected"); + } else if (payload.get("dbConnected") != null) { + dbConnected = Boolean.parseBoolean(String.valueOf(payload.get("dbConnected"))); + } + String dbMessage = payload.get("dbMessage") == null ? null : String.valueOf(payload.get("dbMessage")); + agentSessionRegistry.registerOrHeartbeat(deviceId, hostName, dbConnected, dbMessage); + messagingTemplate.convertAndSend("/topic/device/" + deviceId + "/status", payload); + log.debug("设备代理状态已更新 deviceId={} dbConnected={}", deviceId, dbConnected); + } + + /** + * 桌面代理回传设备库命令结果。 + * destination: /app/device/agent/result + */ + @MessageMapping("/device/agent/result") + public void receiveAgentResult(@org.springframework.messaging.handler.annotation.Payload(required = false) Map payload) { + if (payload == null) { + return; + } + DeviceAgentResult result = JSON.parseObject(JSON.toJSONString(payload), DeviceAgentResult.class); + agentCommandService.completeResult(result); + } + + @GetMapping("/agent/online") + public Result> listOnlineAgents() { + return Result.OK(agentSessionRegistry.listOnline()); + } + + @GetMapping("/agent/list") + public Result> listAgents() { + return Result.OK(agentSessionRegistry.listAll()); + } + + @PostMapping("/agent/test") + public Result testAgentDb(@RequestBody(required = false) Map body) { + String deviceId = body == null ? null : String.valueOf(body.getOrDefault("deviceId", "")).trim(); + if (deviceId == null || deviceId.isBlank()) { + DeviceAgentSession picked = agentSessionRegistry.pickOnlineAgent(null); + if (picked == null) { + return Result.error("无在线桌面代理"); + } + deviceId = picked.getDeviceId(); + } + try { + return Result.OK(agentCommandService.test(deviceId, 10_000)); + } catch (Exception e) { + return Result.error(e.getMessage()); + } + } + + @PostMapping("/agent/command") + public Result sendAgentCommand(@RequestBody DeviceAgentCommand command) { + try { + return Result.OK(agentCommandService.sendAndWait(command)); + } catch (Exception e) { + return Result.error(e.getMessage()); + } + } + + @GetMapping("/agent/status") + public Result agentStatus(@RequestParam(name = "deviceId", required = false) String deviceId) { + DeviceAgentSession session = agentSessionRegistry.pickOnlineAgent(deviceId); + return Result.OK(session); + } + //update-end---author:cursor ---date:2026-07-20 for:【设备库桥接】代理状态/回执/在线列表----------- } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/docs/代码修改日志 b/jeecg-boot/jeecg-module-system/jeecg-system-biz/docs/代码修改日志 index 1a5ec7ff..e9272ac2 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/docs/代码修改日志 +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/docs/代码修改日志 @@ -606,3 +606,26 @@ jeecgboot-vue3/src/views/xslmes/mesXslRubberQuickTestRecord/components/MesXslRub jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/im/service/impl/SysImChatServiceImpl.java jeecgboot-vue3/src/views/system/im/imCache.ts jeecgboot-vue3/src/views/system/im/ImChat.vue + +-- author:jiangxh---date:20260729--for: /ϡ༭УΨһ --- +jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMixerMaterialService.java +jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMixerMaterialServiceImpl.java +jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMixerMaterialController.java +jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMaterialService.java +jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMaterialServiceImpl.java +jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMaterialController.java +jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.api.ts +jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.data.ts +jeecgboot-vue3/src/views/mes/material/MesMaterial.api.ts +jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts + +-- author:jiangxh---date:20260729--for: ϡĬϱ365 --- +jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.data.ts + +-- author:jiangxh---date:20260729--for: WebSocket޸RedisذʱƵ --- +jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/websocket/WebSocket.java +jeecgboot-vue3/src/hooks/web/useWebSocket.ts + +-- author:jiangxh---date:20260729--for: ϡб/ȥϱֶ --- +jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts +jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMaterialController.java diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMaterialController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMaterialController.java index d87669d7..a29c13f5 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMaterialController.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMaterialController.java @@ -10,11 +10,13 @@ import jakarta.servlet.http.HttpServletResponse; import java.util.Arrays; import java.util.List; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; 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.mes.material.entity.MesMaterial; import org.jeecg.modules.mes.material.service.IMesMaterialService; import org.springframework.beans.factory.annotation.Autowired; @@ -59,6 +61,12 @@ public class MesMaterialController extends JeecgController add(@RequestBody MesMaterial model) { + //update-begin---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验----------- + String err = validateUnique(model, null); + if (err != null) { + return Result.error(err); + } + //update-end---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验----------- mesMaterialService.save(model); mesMaterialService.notifyMaterialChanged("material.created", model); return Result.OK("添加成功!"); @@ -69,6 +77,12 @@ public class MesMaterialController extends JeecgController edit(@RequestBody MesMaterial model) { + //update-begin---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验----------- + String err = validateUnique(model, model.getId()); + if (err != null) { + return Result.error(err); + } + //update-end---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验----------- mesMaterialService.updateById(model); mesMaterialService.notifyMaterialChanged("material.updated", model); return Result.OK("编辑成功!"); @@ -106,6 +120,57 @@ public class MesMaterialController extends JeecgController checkMaterialCode( + @RequestParam(name = "materialCode", required = true) String materialCode, + @RequestParam(name = "dataId", required = false) String dataId) { + if (oConvertUtils.isEmpty(materialCode) || materialCode.trim().isEmpty()) { + return Result.OK("该值可用!"); + } + if (mesMaterialService.isMaterialCodeDuplicated(materialCode, dataId)) { + return Result.error("胶料编码不能重复"); + } + return Result.OK("该值可用!"); + } + + @Operation(summary = "校验胶料名称是否重复") + @GetMapping("/checkMaterialName") + public Result checkMaterialName( + @RequestParam(name = "materialName", required = true) String materialName, + @RequestParam(name = "dataId", required = false) String dataId) { + if (oConvertUtils.isEmpty(materialName) || materialName.trim().isEmpty()) { + return Result.OK("该值可用!"); + } + if (mesMaterialService.isMaterialNameDuplicated(materialName, dataId)) { + return Result.error("胶料名称不能重复"); + } + return Result.OK("该值可用!"); + } + + private String validateUnique(MesMaterial model, String excludeId) { + if (model == null) { + return "数据不能为空"; + } + if (oConvertUtils.isEmpty(model.getMaterialName()) || StringUtils.isBlank(model.getMaterialName())) { + return "胶料名称不能为空"; + } + model.setMaterialName(model.getMaterialName().trim()); + //update-begin---author:jiangxh ---date:20260730 for:【胶料】保存时编号与名称保持一致(界面隐藏编号)----------- + // 表单/列表不展示编号,保存时自动用胶料名称回填胶料编号 + model.setMaterialCode(model.getMaterialName()); + //update-end---author:jiangxh ---date:20260730 for:【胶料】保存时编号与名称保持一致(界面隐藏编号)----------- + if (mesMaterialService.isMaterialNameDuplicated(model.getMaterialName(), excludeId)) { + return "胶料名称不能重复"; + } + if (mesMaterialService.isMaterialCodeDuplicated(model.getMaterialCode(), excludeId)) { + return "胶料编码不能重复"; + } + return null; + } + //update-end---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验接口----------- + @RequiresPermissions("mes:mes_material:exportXls") @RequestMapping("/exportXls") public ModelAndView exportXls(HttpServletRequest request, MesMaterial model) { diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMixerMaterialController.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMixerMaterialController.java index 093bfe5e..a8d2de2e 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMixerMaterialController.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/controller/MesMixerMaterialController.java @@ -11,11 +11,13 @@ import jakarta.servlet.http.HttpServletResponse; import java.util.Arrays; import java.util.List; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; 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.mes.material.entity.MesMixerMaterial; import org.jeecg.modules.mes.material.service.IMesMixerMaterialService; import org.springframework.messaging.simp.SimpMessagingTemplate; @@ -52,6 +54,12 @@ public class MesMixerMaterialController extends JeecgController add(@RequestBody MesMixerMaterial model) { + //update-begin---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验----------- + String err = validateUnique(model, null); + if (err != null) { + return Result.error(err); + } + //update-end---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验----------- service.save(model); publishChanged("add", model.getId()); return Result.OK("添加成功!"); @@ -62,6 +70,12 @@ public class MesMixerMaterialController extends JeecgController edit(@RequestBody MesMixerMaterial model) { + //update-begin---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验----------- + String err = validateUnique(model, model.getId()); + if (err != null) { + return Result.error(err); + } + //update-end---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验----------- service.updateById(model); publishChanged("edit", model.getId()); return Result.OK("编辑成功!"); @@ -110,6 +124,12 @@ public class MesMixerMaterialController extends JeecgController anonAdd(@RequestBody MesMixerMaterial model) { + //update-begin---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验----------- + String err = validateUnique(model, null); + if (err != null) { + return Result.error(err); + } + //update-end---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验----------- service.save(model); publishChanged("add", model.getId()); return Result.OK("添加成功!"); @@ -118,6 +138,12 @@ public class MesMixerMaterialController extends JeecgController anonEdit(@RequestBody MesMixerMaterial model) { + //update-begin---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验----------- + String err = validateUnique(model, model.getId()); + if (err != null) { + return Result.error(err); + } + //update-end---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验----------- boolean ok = service.updateById(model); if (!ok) { return Result.error("数据已被他人修改,请刷新后重试"); @@ -148,6 +174,57 @@ public class MesMixerMaterialController extends JeecgController checkMaterialCode( + @RequestParam(name = "materialCode", required = true) String materialCode, + @RequestParam(name = "dataId", required = false) String dataId) { + if (oConvertUtils.isEmpty(materialCode) || materialCode.trim().isEmpty()) { + return Result.OK("该值可用!"); + } + if (service.isMaterialCodeDuplicated(materialCode, dataId)) { + return Result.error("物料编码不能重复"); + } + return Result.OK("该值可用!"); + } + + @Operation(summary = "校验物料名称是否重复") + @GetMapping("/checkMaterialName") + public Result checkMaterialName( + @RequestParam(name = "materialName", required = true) String materialName, + @RequestParam(name = "dataId", required = false) String dataId) { + if (oConvertUtils.isEmpty(materialName) || materialName.trim().isEmpty()) { + return Result.OK("该值可用!"); + } + if (service.isMaterialNameDuplicated(materialName, dataId)) { + return Result.error("物料名称不能重复"); + } + return Result.OK("该值可用!"); + } + + private String validateUnique(MesMixerMaterial model, String excludeId) { + if (model == null) { + return "数据不能为空"; + } + if (oConvertUtils.isEmpty(model.getMaterialCode()) || StringUtils.isBlank(model.getMaterialCode())) { + return "物料编码不能为空"; + } + model.setMaterialCode(model.getMaterialCode().trim()); + if (service.isMaterialCodeDuplicated(model.getMaterialCode(), excludeId)) { + return "物料编码不能重复"; + } + if (oConvertUtils.isEmpty(model.getMaterialName()) || StringUtils.isBlank(model.getMaterialName())) { + return "物料名称不能为空"; + } + model.setMaterialName(model.getMaterialName().trim()); + if (service.isMaterialNameDuplicated(model.getMaterialName(), excludeId)) { + return "物料名称不能重复"; + } + return null; + } + //update-end---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验接口----------- + @RequiresPermissions("mes:mes_mixer_material:exportXls") @RequestMapping("/exportXls") public ModelAndView exportXls(HttpServletRequest request, MesMixerMaterial model) { diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMaterialService.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMaterialService.java index 76cb934a..5450255d 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMaterialService.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMaterialService.java @@ -5,4 +5,10 @@ import org.jeecg.modules.mes.material.entity.MesMaterial; public interface IMesMaterialService extends IService { void notifyMaterialChanged(String eventType, MesMaterial material); + + //update-begin---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验----------- + boolean isMaterialCodeDuplicated(String materialCode, String excludeId); + + boolean isMaterialNameDuplicated(String materialName, String excludeId); + //update-end---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验----------- } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMixerMaterialService.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMixerMaterialService.java index 50dceede..dde48275 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMixerMaterialService.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/IMesMixerMaterialService.java @@ -3,4 +3,11 @@ package org.jeecg.modules.mes.material.service; import com.baomidou.mybatisplus.extension.service.IService; import org.jeecg.modules.mes.material.entity.MesMixerMaterial; -public interface IMesMixerMaterialService extends IService {} +public interface IMesMixerMaterialService extends IService { + + //update-begin---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验----------- + boolean isMaterialCodeDuplicated(String materialCode, String excludeId); + + boolean isMaterialNameDuplicated(String materialName, String excludeId); + //update-end---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验----------- +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMaterialServiceImpl.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMaterialServiceImpl.java index bf564df5..8dbd2aca 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMaterialServiceImpl.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMaterialServiceImpl.java @@ -1,9 +1,11 @@ package org.jeecg.modules.mes.material.service.impl; import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import java.util.HashMap; import java.util.Map; +import org.apache.commons.lang3.StringUtils; import org.jeecg.modules.mes.material.entity.MesMaterial; import org.jeecg.modules.mes.material.mapper.MesMaterialMapper; import org.jeecg.modules.mes.material.service.IMesMaterialService; @@ -25,4 +27,32 @@ public class MesMaterialServiceImpl extends ServiceImpl wrapper = + new LambdaQueryWrapper().eq(MesMaterial::getMaterialCode, materialCode.trim()); + if (StringUtils.isNotBlank(excludeId)) { + wrapper.ne(MesMaterial::getId, excludeId.trim()); + } + return this.count(wrapper) > 0; + } + + @Override + public boolean isMaterialNameDuplicated(String materialName, String excludeId) { + if (StringUtils.isBlank(materialName)) { + return false; + } + LambdaQueryWrapper wrapper = + new LambdaQueryWrapper().eq(MesMaterial::getMaterialName, materialName.trim()); + if (StringUtils.isNotBlank(excludeId)) { + wrapper.ne(MesMaterial::getId, excludeId.trim()); + } + return this.count(wrapper) > 0; + } + //update-end---author:jiangxh ---date:20260729 for:【胶料】名称/编码唯一校验----------- } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMixerMaterialServiceImpl.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMixerMaterialServiceImpl.java index 604d69ad..ae7f5be2 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMixerMaterialServiceImpl.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mes/material/service/impl/MesMixerMaterialServiceImpl.java @@ -1,6 +1,8 @@ package org.jeecg.modules.mes.material.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.apache.commons.lang3.StringUtils; import org.jeecg.modules.mes.material.entity.MesMixerMaterial; import org.jeecg.modules.mes.material.mapper.MesMixerMaterialMapper; import org.jeecg.modules.mes.material.service.IMesMixerMaterialService; @@ -8,4 +10,33 @@ import org.springframework.stereotype.Service; @Service public class MesMixerMaterialServiceImpl extends ServiceImpl - implements IMesMixerMaterialService {} + implements IMesMixerMaterialService { + + //update-begin---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验----------- + @Override + public boolean isMaterialCodeDuplicated(String materialCode, String excludeId) { + if (StringUtils.isBlank(materialCode)) { + return false; + } + LambdaQueryWrapper wrapper = + new LambdaQueryWrapper().eq(MesMixerMaterial::getMaterialCode, materialCode.trim()); + if (StringUtils.isNotBlank(excludeId)) { + wrapper.ne(MesMixerMaterial::getId, excludeId.trim()); + } + return this.count(wrapper) > 0; + } + + @Override + public boolean isMaterialNameDuplicated(String materialName, String excludeId) { + if (StringUtils.isBlank(materialName)) { + return false; + } + LambdaQueryWrapper wrapper = + new LambdaQueryWrapper().eq(MesMixerMaterial::getMaterialName, materialName.trim()); + if (StringUtils.isNotBlank(excludeId)) { + wrapper.ne(MesMixerMaterial::getId, excludeId.trim()); + } + return this.count(wrapper) > 0; + } + //update-end---author:jiangxh ---date:20260729 for:【密炼物料】名称/编码唯一校验----------- +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/websocket/WebSocket.java b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/websocket/WebSocket.java index b450c275..82bdf506 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/websocket/WebSocket.java +++ b/jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/message/websocket/WebSocket.java @@ -61,16 +61,30 @@ public class WebSocket { @OnOpen public void onOpen(Session session, @PathParam(value = "userId") String userId) { try { - sessionPool.put(userId, session); + //update-begin---author:jiangxh ---date:20260729 for:【WebSocket】同 userId 新连接顶替旧连接,避免双连接互踢----------- + Session previous = sessionPool.put(userId, session); + if (previous != null && previous.isOpen() && !previous.getId().equals(session.getId())) { + try { + previous.close(); + } catch (Exception ignore) { + // ignore + } + } + //update-end---author:jiangxh ---date:20260729 for:【WebSocket】同 userId 新连接顶替旧连接,避免双连接互踢----------- log.info("【系统 WebSocket】连接建立 userId={}, sessionId={}, online={}", userId, session.getId(), sessionPool.size()); } catch (Exception e) { } } @OnClose - public void onClose(@PathParam("userId") String userId) { + public void onClose(Session session, @PathParam("userId") String userId) { try { - sessionPool.remove(userId); + //update-begin---author:jiangxh ---date:20260729 for:【WebSocket】仅移除当前 session,避免旧连接 onClose 清掉新连接----------- + Session current = sessionPool.get(userId); + if (current != null && session != null && current.getId().equals(session.getId())) { + sessionPool.remove(userId, current); + } + //update-end---author:jiangxh ---date:20260729 for:【WebSocket】仅移除当前 session,避免旧连接 onClose 清掉新连接----------- log.info("【系统 WebSocket】连接断开 userId={}, online={}", userId, sessionPool.size()); } catch (Exception e) { e.printStackTrace(); @@ -155,13 +169,24 @@ public class WebSocket { * ws接受客户端消息 */ @OnMessage - public void onMessage(String message, @PathParam(value = "userId") String userId) { + public void onMessage(String message, Session session, @PathParam(value = "userId") String userId) { String normalized = message == null ? "" : message.trim(); if (isHeartbeatOrBlank(normalized)) { log.debug("【系统 WebSocket】收到客户端心跳/空消息:{}", normalized); if ("ping".equalsIgnoreCase(normalized) || WebsocketConst.CMD_CHECK.equalsIgnoreCase(normalized)) { + //update-begin---author:jiangxh ---date:20260729 for:【WebSocket】心跳直接回包,避免走 Redis 导致 pong 超时断线----------- // 代码逻辑说明: 【issues/1161】前端websocket因心跳导致监听不起作用--- - this.sendMessage(userId, "ping"); + // 心跳必须同连接即时回包;走 Redis 发布订阅可能延迟/失败,触发前端 pongTimeout 断线重连 + try { + if (session != null && session.isOpen()) { + synchronized (session) { + session.getBasicRemote().sendText("ping"); + } + } + } catch (Exception e) { + log.warn("【系统 WebSocket】心跳回包失败 userId={}, err={}", userId, e.getMessage()); + } + //update-end---author:jiangxh ---date:20260729 for:【WebSocket】心跳直接回包,避免走 Redis 导致 pong 超时断线----------- } return; } diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/common/blob.ftl b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/common/blob.ftl new file mode 100644 index 00000000..eb85ea9c --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/common/blob.ftl @@ -0,0 +1,67 @@ +<#if po.fieldDbType=='Blob'> + private transient java.lang.String ${po.fieldName}String; + + private byte[] ${po.fieldName}; + + public byte[] get${po.fieldName?cap_first}(){ + if(${po.fieldName}String==null){ + return null; + } + try { + return ${po.fieldName}String.getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return null; + } + + public String get${po.fieldName?cap_first}String(){ + if(${po.fieldName}==null || ${po.fieldName}.length==0){ + return ""; + } + try { + return new String(${po.fieldName},"UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return ""; + } +<#elseif po.classType=='switch'> + <#assign switch_extend_arr=['Y','N']> + <#if po.dictField?default("")?contains("[")> + <#assign switch_extend_arr=po.dictField?eval> + + <#list switch_extend_arr as a> + <#if a_index == 0> + <#assign switch_extend_arr1=a> + <#else> + <#assign switch_extend_arr2=a> + + + @Excel(name = "${po.filedComment}", width = 15,replace = {"是_${switch_extend_arr1}","否_${switch_extend_arr2}"} ) + @Schema(description = "${po.filedComment}") + private ${po.fieldType} ${po.fieldName}; +<#elseif po.classType=='pca'> + @Excel(name = "${po.filedComment}", width = 15,exportConvert=true,importConvert = true ) + @Schema(description = "${po.filedComment}") + private ${po.fieldType} ${po.fieldName}; + + public String convertis${po.fieldName?cap_first}() { + return SpringContextUtils.getBean(ProvinceCityArea.class).getText(${po.fieldName}); + } + + public void convertset${po.fieldName?cap_first}(String text) { + this.${po.fieldName} = SpringContextUtils.getBean(ProvinceCityArea.class).getCode(text); + } +<#elseif po.classType=='cat_tree'> + <#assign list_field_dictCode=', dictTable = "sys_category", dicText = "name", dicCode = "id"'> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + @Schema(description = "${po.filedComment}") + private ${po.fieldType} ${po.fieldName}; +<#else> + @Schema(description = "${po.filedComment}") + <#if po.fieldDbName == 'del_flag'> + @TableLogic + + private ${po.fieldType} ${po.fieldName}; + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/common/form/native/vue3NativeComponents.ftl b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/common/form/native/vue3NativeComponents.ftl new file mode 100644 index 00000000..30a4861f --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/common/form/native/vue3NativeComponents.ftl @@ -0,0 +1,53 @@ +<#if need_select_tag> + JDictSelectTag, + +<#if need_switch> + JSwitch, + +<#if need_multi> + JSelectMultiple, + +<#if need_search> + JSearchSelect, + +<#if need_popup> + JPopup, + +<#if need_popup_dict> + JPopupDict, + +<#if need_category> + JCategorySelect, + +<#if need_dept> + JSelectDept, + +<#if need_dept_user> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + JSelectUser, +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + +<#if need_select_tree> + JTreeSelect, + +<#if need_time> + TimePicker, + +<#if need_pca> + JAreaLinkage, + +<#if need_upload> + JUpload, + +<#if need_image_upload> + JImageUpload, + +<#if need_markdown> + JMarkdownEditor, + +<#if need_editor> + JEditor, + +<#if need_checkbox> + JCheckbox, + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/common/form/native/vue3NativeForm.ftl b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/common/form/native/vue3NativeForm.ftl new file mode 100644 index 00000000..519ecb5a --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/common/form/native/vue3NativeForm.ftl @@ -0,0 +1,119 @@ +<#include "/common/utils.ftl"> +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if po.isShow =='Y' && po.fieldName != 'id' && po.fieldName !='delFlag' && isNotPidField(tableVo, po.fieldDbName)> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#assign form_field_dictCode=""> + <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictField}"> + + + + <#if po.classType =='date'> + picker="${po.extendParams.picker}" v-model:value="formData.${po.fieldName}" value-format="YYYY-MM-DD" style="width: 100%" <#if po.readonly=='Y'>disabled allow-clear /> + <#elseif po.classType =='datetime'> + disabled allow-clear /> + <#elseif po.classType =='time'> + <#assign need_time = true> + disabled allow-clear /> + <#elseif po.classType =='popup'> + <#assign need_popup = true> + <#assign sourceFields = po.dictField?default("")?trim?split(",")/> + <#assign targetFields = po.dictText?default("")?trim?split(",")/> + disabled<#rt> allow-clear /> + <#elseif po.classType =='popup_dict'> + <#assign need_popup_dict = true> + <#assign sourceFields = po.dictField?default("")?trim?split(",")/> + <#assign targetFields = po.dictText?default("")?trim?split(",")/> + disabled /> + <#elseif po.classType =='sel_depart'> + <#assign need_dept = true> + labelKey="${po.extendParams.text}" <#if po.extendParams?exists && po.extendParams.store?exists>rowKey="${po.extendParams.store}" <#if po.readonly=='Y'>disabled :multiple="${po.extendParams.multi?default('true')}" checkStrictly <#if po.readonly=='Y'>disabled allow-clear /> + <#elseif po.classType =='switch'> + <#assign need_switch = true> + :options="${po.dictField}" <#if po.readonly=='Y'>disabled> + <#elseif po.classType =='pca'> + <#assign need_pca = true> + disabled allow-clear /> + <#elseif po.classType =='markdown'> + <#assign need_markdown = true> + disabled> + <#elseif po.classType =='password'> + disabled allow-clear /> + <#elseif po.classType =='sel_user'> + <#assign need_dept_user = true> + <#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + labelKey="${po.extendParams.text}" <#if po.extendParams?exists && po.extendParams.store?exists>rowKey="${po.extendParams.store}" <#if po.readonly=='Y'>disabled allow-clear /> + <#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + <#elseif po.classType =='textarea'> + disabled/> + <#elseif po.classType=='radio'> + <#assign need_select_tag = true> + disabled allow-clear /> + <#elseif po.classType=='list'> + <#assign need_select_tag = true> + disabled allow-clear /> + <#elseif po.classType=='list_multi'> + <#assign need_multi = true> + disabled :triggerChange="false"/> + <#elseif po.classType=='checkbox'> + <#assign need_checkbox = true> + disabled allow-clear /> + <#elseif po.classType=='sel_search'> + <#assign need_search = true> + disabled allow-clear /> + <#elseif po.classType=='cat_tree'> + <#assign need_category = true> + back="${dashedToCamel(po.dictText)}" <#if po.readonly=='Y'>disabled @change="(value) => handleFormChange('${po.fieldName}', value)" allow-clear /> + <#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + disabled/> + <#elseif po.classType=='file'> + <#assign need_upload = true> + disabled <#if po.uploadnum??>:maxCount=${po.uploadnum}> + <#elseif po.classType=='image'> + <#assign need_image_upload = true> + :fileMax=${po.uploadnum}<#else>:fileMax="0" v-model:value="formData.${po.fieldName}" <#if po.readonly=='Y'>disabled> + <#elseif po.classType=='umeditor'> + <#assign need_editor = true> + disabled :autoFocus="false"/> + <#elseif po.fieldDbType=='Blob'> + disabled allow-clear > + <#elseif po.classType == 'sel_tree'> + <#assign need_select_tree = true> + + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> + dict="${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}" + <#elseif po.dictText?split(',')[1]??> + pidField="${po.dictText?split(',')[1]}" + <#elseif po.dictText?split(',')[3]??> + hasChildField="${po.dictText?split(',')[3]}" + + + pidValue="${po.dictField}" + <#if po.readonly=='Y'>disabled + v-model:value="formData.${po.fieldName}" + @change="(value) => handleFormChange('${po.fieldName}', value)" allow-clear > + + <#else> + disabled allow-clear > + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/common/form/native/vue3NativeImport.ftl b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/common/form/native/vue3NativeImport.ftl new file mode 100644 index 00000000..b770ae9f --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/common/form/native/vue3NativeImport.ftl @@ -0,0 +1,59 @@ +<#if need_select_tag> + import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue'; + +<#if need_switch> + import JSwitch from '/@/components/Form/src/jeecg/components/JSwitch.vue'; + +<#if need_multi> + import JSelectMultiple from '/@/components/Form/src/jeecg/components/JSelectMultiple.vue'; + +<#if need_search> + import JSearchSelect from '/@/components/Form/src/jeecg/components/JSearchSelect.vue'; + +<#if need_popup> + import JPopup from '/@/components/Form/src/jeecg/components/JPopup.vue'; + +<#if need_popup_dict> + import JPopupDict from '/@/components/Form/src/jeecg/components/JPopupDict.vue'; + +<#if need_category> + import JCategorySelect from '/@/components/Form/src/jeecg/components/JCategorySelect.vue'; + +<#if need_dept> + import JSelectDept from '/@/components/Form/src/jeecg/components/JSelectDept.vue'; + +<#if need_dept_user> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + import JSelectUser from '/@/components/Form/src/jeecg/components/JSelectUser.vue'; +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + +<#if need_select_tree> + import JTreeSelect from '/@/components/Form/src/jeecg/components/JTreeSelect.vue'; + +<#if need_time> + import { TimePicker } from 'ant-design-vue'; + +<#if need_pca> + import JAreaLinkage from '/@/components/Form/src/jeecg/components/JAreaLinkage.vue'; + +<#if need_upload> + import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue'; + +<#if need_image_upload> + import JImageUpload from '/@/components/Form/src/jeecg/components/JImageUpload.vue'; + +<#if need_markdown> + import JMarkdownEditor from '/@/components/Form/src/jeecg/components/JMarkdownEditor.vue'; + +<#if need_editor> + import JEditor from '/@/components/Form/src/jeecg/components/JEditor.vue'; + +<#if need_checkbox> + import JCheckbox from "/@/components/Form/src/jeecg/components/JCheckbox.vue"; + +<#if need_range_number> + import JRangeNumber from "/@/components/Form/src/jeecg/components/JRangeNumber.vue"; + +<#if is_like> + import JInput from "/@/components/Form/src/jeecg/components/JInput.vue"; + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/common/form/native/vue3NativeSearch.ftl b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/common/form/native/vue3NativeSearch.ftl new file mode 100644 index 00000000..f947b00d --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/common/form/native/vue3NativeSearch.ftl @@ -0,0 +1,108 @@ +<#include "/common/utils.ftl"> +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if po.isQuery=='Y' && po.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#assign query_flag=true> + <#if query_field_no==2> + + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi new file mode 100644 index 00000000..61acd7f6 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi @@ -0,0 +1,72 @@ +import { defHttp } from '/@/utils/http/axios'; +import { useMessage } from "/@/hooks/web/useMessage"; + +const { createConfirm } = useMessage(); + +enum Api { + list = '/${entityPackagePath}/${entityName?uncap_first}/list', + save='/${entityPackagePath}/${entityName?uncap_first}/add', + edit='/${entityPackagePath}/${entityName?uncap_first}/edit', + deleteOne = '/${entityPackagePath}/${entityName?uncap_first}/delete', + deleteBatch = '/${entityPackagePath}/${entityName?uncap_first}/deleteBatch', + importExcel = '/${entityPackagePath}/${entityName?uncap_first}/importExcel', + exportXls = '/${entityPackagePath}/${entityName?uncap_first}/exportXls', +} + +/** + * 导出api + * @param params + */ +export const getExportUrl = Api.exportXls; + +/** + * 导入api + */ +export const getImportUrl = Api.importExcel; + +/** + * 列表接口 + * @param params + */ +export const list = (params) => defHttp.get({ url: Api.list, params }); + +/** + * 删除单个 + * @param params + * @param handleSuccess + */ +export const deleteOne = (params,handleSuccess) => { + return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => { + handleSuccess(); + }); +} + +/** + * 批量删除 + * @param params + * @param 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(); + }); + } + }); +} + +/** + * 保存或者更新 + * @param params + * @param isUpdate + */ +export const saveOrUpdate = (params, isUpdate) => { + let url = isUpdate ? Api.edit : Api.save; + return defHttp.post({ url: url, params }, { isTransformResponse: false }); +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi new file mode 100644 index 00000000..03bf054d --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi @@ -0,0 +1,90 @@ +<#include "/common/utils.ftl"> +import {BasicColumn} from '/@/components/Table'; +import {FormSchema} from '/@/components/Table'; +import { rules} from '/@/utils/helper/validator'; +import { render } from '/@/utils/common/renderUtils'; +import { getWeekMonthQuarterYear } from '/@/utils'; +//列表数据 +export const columns: BasicColumn[] = [ + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + { + title: '${po.filedComment}', + align: "center", + <#if po.sort=='Y'> + sorter: true, + + <#if po.classType=='date'> + dataIndex: '${po.fieldName}', + customRender:({text}) =>{ + text = !text ? "" : (text.length > 10 ? text.substr(0,10) : text); + <#if po.extendParams?exists && po.extendParams.picker?exists> + if(text) { + return getWeekMonthQuarterYear(text)['${po.extendParams.picker}']; + } else { + return text; + } + <#else> + return text; + + }, + <#elseif po.fieldDbType=='Blob'> + dataIndex: '${po.fieldName}String' + <#elseif po.classType=='umeditor'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='pca'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='file'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='image'> + dataIndex: '${po.fieldName}', + customRender: render.renderImage, + <#elseif po.classType=='switch'> + dataIndex: '${po.fieldName}', +<#assign switch_extend_arr=['Y','N']> +<#if po.dictField?default("")?contains("[")> +<#assign switch_extend_arr=po.dictField?eval> + +<#list switch_extend_arr as a> +<#if a_index == 0> +<#assign switch_extend_arr1=a> +<#else> +<#assign switch_extend_arr2=a> + + + customRender:({text}) => { + return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]); + }, + <#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user' || po.classType=='popup_dict'> + dataIndex: '${po.fieldName}_dictText' + <#elseif po.classType=='cat_tree'> + dataIndex: '${po.fieldName}', + <#if po.dictText?default("")?trim?length == 0> + customRender:({text}) => { + return render.renderCategoryTree(text,'${po.dictField?default("")}'); + }, + <#else> + customRender: ({text, record}) => (text ? record['${po.dictText}'] : ''); + + <#else> + dataIndex: '${po.fieldName}' + + }, + + +]; + +<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> +// 高级查询数据 +export const superQuerySchema = { + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + ${superQueryFieldListForVue3(po,po_index)}, + + +}; +<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/V${currentDate}_1__menu_insert_${entityName}.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/V${currentDate}_1__menu_insert_${entityName}.sql new file mode 100644 index 00000000..5396d5d5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/V${currentDate}_1__menu_insert_${entityName}.sql @@ -0,0 +1 @@ +<#include "/common/sql/menu_insert.ftl"> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei new file mode 100644 index 00000000..0c3f5ee7 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei @@ -0,0 +1,256 @@ +<#include "/common/utils.ftl"> + + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei new file mode 100644 index 00000000..29dc0766 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei @@ -0,0 +1,102 @@ +<#include "/common/utils.ftl"> + + + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai new file mode 100644 index 00000000..9192569c --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -0,0 +1,286 @@ +package ${bussiPackage}.${entityPackage}.controller; + +import java.io.UnsupportedEncodingException; +import java.io.IOException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.jeecg.common.system.vo.LoginUser; +import org.apache.shiro.SecurityUtils; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.common.util.oConvertUtils; +import org.jeecgframework.poi.excel.entity.enmus.ExcelType; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import ${bussiPackage}.${entityPackage}.vo.${entityName}Page; +import ${bussiPackage}.${entityPackage}.service.I${entityName}Service; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.service.I${sub.entityName}Service; + +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import com.alibaba.fastjson.JSON; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.apache.shiro.authz.annotation.RequiresPermissions; +<#assign bpm_flag=false> +<#list originalColumns as po> +<#if po.fieldDbName=='bpm_status'> + <#assign bpm_flag=true> + + + + /** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Tag(name="${tableVo.ftlDescription}") +@RestController +@RequestMapping("/${entityPackagePath}/${entityName?uncap_first}") +@Slf4j +public class ${entityName}Controller { + @Autowired + private I${entityName}Service ${entityName?uncap_first}Service; + <#list subTables as sub> + @Autowired + private I${sub.entityName}Service ${sub.entityName?uncap_first}Service; + + + /** + * 分页列表查询 + * + * @param ${entityName?uncap_first} + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "${tableVo.ftlDescription}-分页列表查询") + @Operation(summary="${tableVo.ftlDescription}-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(${entityName} ${entityName?uncap_first}, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap()); + Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize); + IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper); + return Result.OK(pageList); + } + + /** + * 添加 + * + * @param ${entityName?uncap_first}Page + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-添加") + @Operation(summary="${tableVo.ftlDescription}-添加") + @RequiresPermissions("${entityPackage}:${tableName}:add") + @PostMapping(value = "/add") + public Result add(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { + ${entityName} ${entityName?uncap_first} = new ${entityName}(); + BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first}); + <#if bpm_flag> + ${entityName?uncap_first}.setBpmStatus("1"); + + ${entityName?uncap_first}Service.saveMain(${entityName?uncap_first}, <#list subTables as sub>${entityName?uncap_first}Page.get${sub.entityName}List()<#if sub_has_next>,); + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * + * @param ${entityName?uncap_first}Page + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-编辑") + @Operation(summary="${tableVo.ftlDescription}-编辑") + @RequiresPermissions("${entityPackage}:${tableName}:edit") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) + public Result edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { + ${entityName} ${entityName?uncap_first} = new ${entityName}(); + BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first}); + ${entityName} ${entityName?uncap_first}Entity = ${entityName?uncap_first}Service.getById(${entityName?uncap_first}.getId()); + if(${entityName?uncap_first}Entity==null) { + return Result.error("未找到对应数据"); + } + ${entityName?uncap_first}Service.updateMain(${entityName?uncap_first}, <#list subTables as sub>${entityName?uncap_first}Page.get${sub.entityName}List()<#if sub_has_next>,); + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-通过id删除") + @Operation(summary="${tableVo.ftlDescription}-通过id删除") + @RequiresPermissions("${entityPackage}:${tableName}:delete") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name="id",required=true) String id) { + ${entityName?uncap_first}Service.delMain(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-批量删除") + @Operation(summary="${tableVo.ftlDescription}-批量删除") + @RequiresPermissions("${entityPackage}:${tableName}:deleteBatch") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + this.${entityName?uncap_first}Service.delBatchMain(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "${tableVo.ftlDescription}-通过id查询") + @Operation(summary="${tableVo.ftlDescription}-通过id查询") + @GetMapping(value = "/queryById") + public Result<${entityName}> queryById(@RequestParam(name="id",required=true) String id) { + ${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id); + if(${entityName?uncap_first}==null) { + return Result.error("未找到对应数据"); + } + return Result.OK(${entityName?uncap_first}); + + } + + <#list subTables as sub> + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "${sub.ftlDescription}通过主表ID查询") + @Operation(summary="${sub.ftlDescription}主表ID查询") + @GetMapping(value = "/query${sub.entityName}ByMainId") + public Result> query${sub.entityName}ListByMainId(@RequestParam(name="id",required=true) String id) { + List<${sub.entityName}> ${sub.entityName?uncap_first}List = ${sub.entityName?uncap_first}Service.selectByMainId(id); + return Result.OK(${sub.entityName?uncap_first}List); + } + + + /** + * 导出excel + * + * @param request + * @param ${entityName?uncap_first} + */ + @RequiresPermissions("${entityPackage}:${tableName}:exportXls") + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) { + // Step.1 组装查询条件查询数据 + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap()); + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + + //配置选中数据查询条件 + String selections = request.getParameter("selections"); + if(oConvertUtils.isNotEmpty(selections)) { + List selectionList = Arrays.asList(selections.split(",")); + queryWrapper.in("id",selectionList); + } + //Step.2 获取导出数据 + List<${entityName}> ${entityName?uncap_first}List = ${entityName?uncap_first}Service.list(queryWrapper); + + // Step.3 组装pageList + List<${entityName}Page> pageList = new ArrayList<${entityName}Page>(); + for (${entityName} main : ${entityName?uncap_first}List) { + ${entityName}Page vo = new ${entityName}Page(); + BeanUtils.copyProperties(main, vo); + <#list subTables as sub> + List<${sub.entityName}> ${sub.entityName?uncap_first}List = ${sub.entityName?uncap_first}Service.selectByMainId(main.getId()); + vo.set${sub.entityName}List(${sub.entityName?uncap_first}List); + + pageList.add(vo); + } + + // Step.4 AutoPoi 导出Excel + ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); + mv.addObject(NormalExcelConstants.FILE_NAME, "${tableVo.ftlDescription}列表"); + mv.addObject(NormalExcelConstants.CLASS, ${entityName}Page.class); + mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("${tableVo.ftlDescription}数据", "导出人:"+sysUser.getRealname(), "${tableVo.ftlDescription}", ExcelType.XSSF)); + mv.addObject(NormalExcelConstants.DATA_LIST, pageList); + return mv; + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequiresPermissions("${entityPackage}:${tableName}:importExcel") + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map fileMap = multipartRequest.getFileMap(); + for (Map.Entry entity : fileMap.entrySet()) { + // 获取上传文件对象 + MultipartFile file = entity.getValue(); + ImportParams params = new ImportParams(); + params.setTitleRows(2); + params.setHeadRows(1); + params.setNeedSave(true); + try { + List<${entityName}Page> list = ExcelImportUtil.importExcel(file.getInputStream(), ${entityName}Page.class, params); + for (${entityName}Page page : list) { + ${entityName} po = new ${entityName}(); + BeanUtils.copyProperties(page, po); + ${entityName?uncap_first}Service.saveMain(po, <#list subTables as sub>page.get${sub.entityName}List()<#if sub_has_next>,); + } + return Result.OK("文件导入成功!数据行数:" + list.size()); + } catch (Exception e) { + log.error(e.getMessage(),e); + return Result.error("文件导入失败:"+e.getMessage()); + } finally { + try { + file.getInputStream().close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return Result.OK("文件导入失败!"); + } + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai new file mode 100644 index 00000000..d5e992bf --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai @@ -0,0 +1,77 @@ +<#include "/common/utils.ftl"> +package ${bussiPackage}.${entityPackage}.entity; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecg.common.aspect.annotation.Dict; +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Schema(description="${tableVo.ftlDescription}") +@Data +@TableName("${tableName}") +public class ${entityName} implements Serializable { + private static final long serialVersionUID = 1L; + +<#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']> + <#list originalColumns as po> + <#-- 生成字典Code --> + <#assign list_field_dictCode=""> + <#if po.classType='sel_user'> + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> + <#elseif po.classType='sel_depart'> + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> + <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dicCode = "${po.dictField}"'> + + <#elseif po.classType=='sel_tree'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'> + + /**${po.filedComment}*/ + <#if po.fieldName == primaryKeyField> + @TableId(type = IdType.ASSIGN_ID) + <#else> + <#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'> + <#if po.classType=='date'> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + + + <#if list_field_dictCode?length gt 1> + @Dict(${list_field_dictCode?substring(2)}) + + + <#-- 大字段转换 --> + <#include "/common/blob.ftl"> + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai new file mode 100644 index 00000000..e4b78b96 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai @@ -0,0 +1,76 @@ +<#include "/common/utils.ftl"> +<#list subTables as subTab> +#segment#${subTab.entityName}.java +package ${bussiPackage}.${entityPackage}.entity; + +import java.io.Serializable; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import java.util.Date; +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.UnsupportedEncodingException; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Schema(description="${subTab.ftlDescription}") +@Data +@TableName("${subTab.tableName}") +public class ${subTab.entityName} implements Serializable { + private static final long serialVersionUID = 1L; + +<#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']> + <#list subTab.originalColumns as po> + <#-- 生成字典Code --> + <#assign list_field_dictCode=""> + <#if po.classType='sel_user'> + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> + <#elseif po.classType='sel_depart'> + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> + <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dicCode = "${po.dictField}"'> + <#elseif po.classType=='sel_tree'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'> + + + /**${po.filedComment}*/ + <#if po.fieldName == primaryKeyField> + @TableId(type = IdType.ASSIGN_ID) + <#else> + <#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'> + <#if po.classType=='date'> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + + <#elseif !subTab.foreignKeys?seq_contains(po.fieldName?cap_first)> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + + + + <#-- 大字段转换 --> + <#include "/common/blob.ftl"> + +} + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai new file mode 100644 index 00000000..c31b9bfd --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai @@ -0,0 +1,17 @@ +package ${bussiPackage}.${entityPackage}.mapper; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface ${entityName}Mapper extends BaseMapper<${entityName}> { + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/mapper/[1-n]Mapper.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/mapper/[1-n]Mapper.javai new file mode 100644 index 00000000..a33449b4 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/mapper/[1-n]Mapper.javai @@ -0,0 +1,34 @@ +<#list subTables as subTab> +#segment#${subTab.entityName}Mapper.java +package ${bussiPackage}.${entityPackage}.mapper; + +import java.util.List; +import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName}; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface ${subTab.entityName}Mapper extends BaseMapper<${subTab.entityName}> { + + /** + * 通过主表id删除子表数据 + * + * @param mainId 主表id + * @return boolean + */ + public boolean deleteByMainId(@Param("mainId") String mainId); + + /** + * 通过主表id查询子表数据 + * + * @param mainId 主表id + * @return List<${subTab.entityName}> + */ + public List<${subTab.entityName}> selectByMainId(@Param("mainId") String mainId); +} + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml new file mode 100644 index 00000000..16f3d653 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/[1-n]Mapper.xml b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/[1-n]Mapper.xml new file mode 100644 index 00000000..117c9b6f --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/[1-n]Mapper.xml @@ -0,0 +1,26 @@ +<#list subTables as subTab> +<#assign originalForeignKeys = subTab.originalForeignKeys> +#segment#${subTab.entityName}Mapper.xml + + + + + + DELETE + FROM ${subTab.tableName} + WHERE + <#list originalForeignKeys as key> + ${key} = ${r'#'}{mainId} <#rt/> + + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai new file mode 100644 index 00000000..d56db205 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai @@ -0,0 +1,54 @@ +package ${bussiPackage}.${entityPackage}.service; + +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import com.baomidou.mybatisplus.extension.service.IService; +import java.io.Serializable; +import java.util.Collection; +import java.util.List; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface I${entityName}Service extends IService<${entityName}> { + + /** + * 添加一对多 + * + * @param ${entityName?uncap_first} + <#list subTables as sub> + * @param ${sub.entityName?uncap_first}List + + */ + public void saveMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,) ; + + /** + * 修改一对多 + * + * @param ${entityName?uncap_first} + <#list subTables as sub> + * @param ${sub.entityName?uncap_first}List + + */ + public void updateMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,); + + /** + * 删除一对多 + * + * @param id + */ + public void delMain (String id); + + /** + * 批量删除一对多 + * + * @param idList + */ + public void delBatchMain (Collection idList); + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/service/[1-n]Service.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/service/[1-n]Service.javai new file mode 100644 index 00000000..3d45c9fb --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/service/[1-n]Service.javai @@ -0,0 +1,25 @@ +<#list subTables as subTab> +#segment#I${subTab.entityName}Service.java +package ${bussiPackage}.${entityPackage}.service; + +import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName}; +import com.baomidou.mybatisplus.extension.service.IService; +import java.util.List; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface I${subTab.entityName}Service extends IService<${subTab.entityName}> { + + /** + * 通过主表id查询子表数据 + * + * @param mainId 主表id + * @return List<${subTab.entityName}> + */ + public List<${subTab.entityName}> selectByMainId(String mainId); +} + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai new file mode 100644 index 00000000..7f99d42e --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai @@ -0,0 +1,105 @@ +package ${bussiPackage}.${entityPackage}.service.impl; + +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.mapper.${sub.entityName}Mapper; + +import ${bussiPackage}.${entityPackage}.mapper.${entityName}Mapper; +import ${bussiPackage}.${entityPackage}.service.I${entityName}Service; +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import java.io.Serializable; +import java.util.List; +import java.util.Collection; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Service +public class ${entityName}ServiceImpl extends ServiceImpl<${entityName}Mapper, ${entityName}> implements I${entityName}Service { + + @Autowired + private ${entityName}Mapper ${entityName?uncap_first}Mapper; + <#list subTables as sub> + @Autowired + private ${sub.entityName}Mapper ${sub.entityName?uncap_first}Mapper; + + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveMain(${entityName} ${entityName?uncap_first}, <#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,) { + ${entityName?uncap_first}Mapper.insert(${entityName?uncap_first}); + <#list subTables as sub> + if(${sub.entityName?uncap_first}List!=null && ${sub.entityName?uncap_first}List.size()>0) { + for(${sub.entityName} entity:${sub.entityName?uncap_first}List) { + <#list sub.foreignKeys as key> + //外键设置 + <#if key?lower_case?index_of("${primaryKeyField}")!=-1> + entity.set${key?cap_first}(${entityName?uncap_first}.get${primaryKeyField?cap_first}()); + <#else> + entity.set${key?cap_first}(${entityName?uncap_first}.get${key}()); + + + ${sub.entityName?uncap_first}Mapper.insert(entity); + } + } + + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,) { + ${entityName?uncap_first}Mapper.updateById(${entityName?uncap_first}); + + //1.先删除子表数据 + <#list subTables as sub> + ${sub.entityName?uncap_first}Mapper.deleteByMainId(${entityName?uncap_first}.getId()); + + + //2.子表数据重新插入 + <#list subTables as sub> + if(${sub.entityName?uncap_first}List!=null && ${sub.entityName?uncap_first}List.size()>0) { + for(${sub.entityName} entity:${sub.entityName?uncap_first}List) { + <#list sub.foreignKeys as key> + //外键设置 + <#if key?lower_case?index_of("${primaryKeyField}")!=-1> + entity.set${key?cap_first}(${entityName?uncap_first}.get${primaryKeyField?cap_first}()); + <#else> + entity.set${key?cap_first}(${entityName?uncap_first}.get${key}()); + + + ${sub.entityName?uncap_first}Mapper.insert(entity); + } + } + + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delMain(String id) { + <#list subTables as sub> + ${sub.entityName?uncap_first}Mapper.deleteByMainId(id); + + ${entityName?uncap_first}Mapper.deleteById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delBatchMain(Collection idList) { + for(Serializable id:idList) { + <#list subTables as sub> + ${sub.entityName?uncap_first}Mapper.deleteByMainId(id.toString()); + + ${entityName?uncap_first}Mapper.deleteById(id); + } + } + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/[1-n]ServiceImpl.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/[1-n]ServiceImpl.javai new file mode 100644 index 00000000..0ce41d36 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/[1-n]ServiceImpl.javai @@ -0,0 +1,30 @@ +<#list subTables as subTab> +#segment#${subTab.entityName}ServiceImpl.java +package ${bussiPackage}.${entityPackage}.service.impl; + +import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName}; +import ${bussiPackage}.${entityPackage}.mapper.${subTab.entityName}Mapper; +import ${bussiPackage}.${entityPackage}.service.I${subTab.entityName}Service; +import org.springframework.stereotype.Service; +import java.util.List; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Service +public class ${subTab.entityName}ServiceImpl extends ServiceImpl<${subTab.entityName}Mapper, ${subTab.entityName}> implements I${subTab.entityName}Service { + + @Autowired + private ${subTab.entityName}Mapper ${subTab.entityName?uncap_first}Mapper; + + @Override + public List<${subTab.entityName}> selectByMainId(String mainId) { + return ${subTab.entityName?uncap_first}Mapper.selectByMainId(mainId); + } +} + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vo/${entityName}Page.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vo/${entityName}Page.javai new file mode 100644 index 00000000..b34674e2 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vo/${entityName}Page.javai @@ -0,0 +1,83 @@ +package ${bussiPackage}.${entityPackage}.vo; + +import java.util.List; +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +import lombok.Data; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecgframework.poi.excel.annotation.ExcelEntity; +import org.jeecgframework.poi.excel.annotation.ExcelCollection; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import java.util.Date; +import org.jeecg.common.aspect.annotation.Dict; +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Data +@Schema(description="${tableVo.ftlDescription}") +public class ${entityName}Page { + + <#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']> + <#list originalColumns as po> + <#-- 生成字典Code --> + <#assign list_field_dictCode=""> + <#if po.classType='sel_user'> + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'> + <#elseif po.classType='sel_depart'> + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "depart_name", dicCode = "id"'> + <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dicCode = "${po.dictField}"'> + + + /**${po.filedComment}*/ + <#if po.fieldName == primaryKeyField> + <#else> + <#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'> + <#if po.classType=='date'> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + + + <#if list_field_dictCode?length gt 1> + @Dict(${list_field_dictCode?substring(2)}) + + + @Schema(description = "${po.filedComment}") + <#if po.fieldDbType=='Blob'> + private java.lang.String ${po.fieldName}String; + <#else> + private ${po.fieldType} ${po.fieldName}; + + + + <#list subTables as sub> + @ExcelCollection(name="${sub.ftlDescription}") + @Schema(description = "${sub.ftlDescription}") + private List<${sub.entityName}> ${sub.entityName?uncap_first}List; + + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei new file mode 100644 index 00000000..6605f0c7 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei @@ -0,0 +1,397 @@ + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql new file mode 100644 index 00000000..5396d5d5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql @@ -0,0 +1 @@ +<#include "/common/sql/menu_insert.ftl"> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei new file mode 100644 index 00000000..89518375 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei @@ -0,0 +1,562 @@ +<#include "/common/utils.ftl"> + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei new file mode 100644 index 00000000..8021bb83 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei @@ -0,0 +1,65 @@ +<#include "/common/utils.ftl"> + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei new file mode 100644 index 00000000..e625f88a --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei @@ -0,0 +1,197 @@ +<#include "/common/utils.ftl"> +<#list subTables as sub> +<#if sub.foreignRelationType=='1'> +#segment#${sub.entityName}Form.vue + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai new file mode 100644 index 00000000..468ef47b --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -0,0 +1,372 @@ +package ${bussiPackage}.${entityPackage}.controller; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.common.system.vo.SelectTreeModel; +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import ${bussiPackage}.${entityPackage}.service.I${entityName}Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; + +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.jeecg.common.system.base.controller.JeecgController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.servlet.ModelAndView; +import com.alibaba.fastjson.JSON; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.apache.shiro.authz.annotation.RequiresPermissions; + + /** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +<#assign pidFieldName = ""> +<#list originalColumns as po> +<#if po.fieldDbName == tableVo.extendParams.pidField> +<#assign pidFieldName = po.fieldName> + + +<#assign enhanceJavaList=[]> +<#if tableVo.extendParams?? && tableVo.extendParams.enhanceJavaList??> + <#assign enhanceJavaList = tableVo.extendParams.enhanceJavaList?filter(enhance -> enhance??)> + +@Tag(name="${tableVo.ftlDescription}") +@RestController +@RequestMapping("/${entityPackagePath}/${entityName?uncap_first}") +@Slf4j +public class ${entityName}Controller extends JeecgController<${entityName}, I${entityName}Service>{ + @Autowired + private I${entityName}Service ${entityName?uncap_first}Service; + + /** + * 分页列表查询 + * + * @param ${entityName?uncap_first} + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "${tableVo.ftlDescription}-分页列表查询") + @Operation(summary="${tableVo.ftlDescription}-分页列表查询") + @GetMapping(value = "/rootList") + public Result> queryPageList(${entityName} ${entityName?uncap_first}, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='query' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 查询前触发的方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeQuery() + + + + String hasQuery = req.getParameter("hasQuery"); + if(hasQuery != null && "true".equals(hasQuery)){ + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap()); + List<${entityName}> list = ${entityName?uncap_first}Service.queryTreeListNoPage(queryWrapper); + IPage<${entityName}> pageList = new Page<>(1, 10, list.size()); + pageList.setRecords(list); + return Result.OK(pageList); + }else{ + String parentId = ${entityName?uncap_first}.get${pidFieldName?cap_first}(); + if (oConvertUtils.isEmpty(parentId)) { + parentId = "0"; + } + ${entityName?uncap_first}.set${pidFieldName?cap_first}(null); + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap()); + // 使用 eq 防止模糊查询 + queryWrapper.eq("${Format.humpToUnderline(pidFieldName)}", parentId); + Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize); + IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper); + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='query' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'> + //TODO 查询后触发的方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.afterQuery() + + + + return Result.OK(pageList); + } + } + + /** + * 【vue3专用】加载节点的子数据 + * + * @param pid + * @return + */ + @RequestMapping(value = "/loadTreeChildren", method = RequestMethod.GET) + public Result> loadTreeChildren(@RequestParam(name = "pid") String pid) { + Result> result = new Result<>(); + try { + List ls = ${entityName?uncap_first}Service.queryListByPid(pid); + result.setResult(ls); + result.setSuccess(true); + } catch (Exception e) { + e.printStackTrace(); + result.setMessage(e.getMessage()); + result.setSuccess(false); + } + return result; + } + + /** + * 【vue3专用】加载一级节点/如果是同步 则所有数据 + * + * @param async + * @param pcode + * @return + */ + @RequestMapping(value = "/loadTreeRoot", method = RequestMethod.GET) + public Result> loadTreeRoot(@RequestParam(name = "async") Boolean async, @RequestParam(name = "pcode") String pcode) { + Result> result = new Result<>(); + try { + List ls = ${entityName?uncap_first}Service.queryListByCode(pcode); + if (!async) { + loadAllChildren(ls); + } + result.setResult(ls); + result.setSuccess(true); + } catch (Exception e) { + e.printStackTrace(); + result.setMessage(e.getMessage()); + result.setSuccess(false); + } + return result; + } + + /** + * 【vue3专用】递归求子节点 同步加载用到 + * + * @param ls + */ + private void loadAllChildren(List ls) { + for (SelectTreeModel tsm : ls) { + List temp = ${entityName?uncap_first}Service.queryListByPid(tsm.getKey()); + if (temp != null && temp.size() > 0) { + tsm.setChildren(temp); + loadAllChildren(temp); + } + } + } + + /** + * 获取子数据 + * @param ${entityName?uncap_first} + * @param req + * @return + */ + //@AutoLog(value = "${tableVo.ftlDescription}-获取子数据") + @Operation(summary="${tableVo.ftlDescription}-获取子数据") + @GetMapping(value = "/childList") + public Result> queryPageList(${entityName} ${entityName?uncap_first},HttpServletRequest req) { + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap()); + List<${entityName}> list = ${entityName?uncap_first}Service.list(queryWrapper); + IPage<${entityName}> pageList = new Page<>(1, 10, list.size()); + pageList.setRecords(list); + return Result.OK(pageList); + } + + /** + * 批量查询子节点 + * @param parentIds 父ID(多个采用半角逗号分割) + * @return 返回 IPage + * @param parentIds + * @return + */ + //@AutoLog(value = "${tableVo.ftlDescription}-批量获取子数据") + @Operation(summary="${tableVo.ftlDescription}-批量获取子数据") + @GetMapping("/getChildListBatch") + public Result getChildListBatch(@RequestParam("parentIds") String parentIds) { + try { + QueryWrapper<${entityName}> queryWrapper = new QueryWrapper<>(); + List parentIdList = Arrays.asList(parentIds.split(",")); + queryWrapper.in("${Format.humpToUnderline(pidFieldName)}", parentIdList); + List<${entityName}> list = ${entityName?uncap_first}Service.list(queryWrapper); + IPage<${entityName}> pageList = new Page<>(1, 10, list.size()); + pageList.setRecords(list); + return Result.OK(pageList); + } catch (Exception e) { + log.error(e.getMessage(), e); + return Result.error("批量查询子节点失败:" + e.getMessage()); + } + } + + /** + * 添加 + * + * @param ${entityName?uncap_first} + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-添加") + @Operation(summary="${tableVo.ftlDescription}-添加") + @RequiresPermissions("${entityPackage}:${tableName}:add") + @PostMapping(value = "/add") + public Result add(@RequestBody ${entityName} ${entityName?uncap_first}) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='add' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 新增前的处理方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeAdd() + + + + ${entityName?uncap_first}Service.add${entityName}(${entityName?uncap_first}); + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='add' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'> + //TODO 新增后的处理方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.afterAdd() + + + + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * + * @param ${entityName?uncap_first} + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-编辑") + @Operation(summary="${tableVo.ftlDescription}-编辑") + @RequiresPermissions("${entityPackage}:${tableName}:edit") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) + public Result edit(@RequestBody ${entityName} ${entityName?uncap_first}) { +<#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 编辑前,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeEdit() + + + + ${entityName?uncap_first}Service.update${entityName}(${entityName?uncap_first}); +<#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'> + //TODO 编辑后,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.afterEdit() + + + + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-通过id删除") + @Operation(summary="${tableVo.ftlDescription}-通过id删除") + @RequiresPermissions("${entityPackage}:${tableName}:delete") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name="id",required=true) String id) { + ${entityName?uncap_first}Service.delete${entityName}(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-批量删除") + @Operation(summary="${tableVo.ftlDescription}-批量删除") + @RequiresPermissions("${entityPackage}:${tableName}:deleteBatch") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + this.${entityName?uncap_first}Service.removeByIds(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "${tableVo.ftlDescription}-通过id查询") + @Operation(summary="${tableVo.ftlDescription}-通过id查询") + @GetMapping(value = "/queryById") + public Result<${entityName}> queryById(@RequestParam(name="id",required=true) String id) { + ${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id); + if(${entityName?uncap_first}==null) { + return Result.error("未找到对应数据"); + } + return Result.OK(${entityName?uncap_first}); + } + + /** + * 导出excel + * + * @param request + * @param ${entityName?uncap_first} + */ + @RequiresPermissions("${entityPackage}:${tableName}:exportXls") + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) { +<#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='export' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 导出前,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeExport() + + + + return super.exportXls(request, ${entityName?uncap_first}, ${entityName}.class, "${tableVo.ftlDescription}"); + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequiresPermissions("${entityPackage}:${tableName}:importExcel") + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { +<#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='import' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 导入前,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeImport() + + + + return super.importExcel(request, response, ${entityName}.class); + } + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai new file mode 100644 index 00000000..b634f67a --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai @@ -0,0 +1,91 @@ +<#include "/common/utils.ftl"> +package ${bussiPackage}.${entityPackage}.entity; + +import java.io.Serializable; +import java.util.Date; +import java.math.BigDecimal; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecg.common.aspect.annotation.Dict; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.UnsupportedEncodingException; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Data +@TableName("${tableName}") +@Schema(description="${tableVo.ftlDescription}") +public class ${entityName} implements Serializable { + private static final long serialVersionUID = 1L; + +<#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']> +<#assign excel_ignore_classType_arr=['pca','switch','cat_tree']> + <#list originalColumns as po> + <#-- 生成字典Code --> + <#assign list_field_dictCode=""> + <#if po.classType='sel_user'> + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> + <#elseif po.classType='sel_depart'> + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> + <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dicCode = "${po.dictField}"'> + + <#elseif po.classType=='sel_tree'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'> + <#elseif po.classType=='link_table'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicCode = "${po.dictField}", dicText = "${po.dictText?split(",")[0]}"'> + + /**${po.filedComment}*/ + <#if po.fieldName == primaryKeyField> + @TableId(type = IdType.ASSIGN_ID) + <#else> + <#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'> + <#if po.classType=='date'> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + + + <#-- <#if po.classType!='popup'> + <#if po.dictTable?default("")?trim?length gt 1> + @Dict(dicCode="${po.dictField}",dicText="${po.dictText}",dictTable="${po.dictTable}") + <#elseif po.dictField?default("")?trim?length gt 1> + @Dict(dicCode="${po.dictField}") + + --> + <#if list_field_dictCode?length gt 1> + @Dict(${list_field_dictCode?substring(2)}) + + + <#-- 大字段转换 --> + <#include "/common/blob.ftl"> + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai new file mode 100644 index 00000000..d894ff1b --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai @@ -0,0 +1,35 @@ +package ${bussiPackage}.${entityPackage}.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import org.jeecg.common.system.vo.SelectTreeModel; +import ${bussiPackage}.${entityPackage}.entity.${entityName}; + +import java.util.List; +import java.util.Map; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface ${entityName}Mapper extends BaseMapper<${entityName}> { + + /** + * 编辑节点状态 + * @param id + * @param status + */ + void updateTreeNodeStatus(@Param("id") String id,@Param("status") String status); + + /** + * 【vue3专用】根据父级ID查询树节点数据 + * + * @param pid + * @param query + * @return + */ + List queryListByPid(@Param("pid") String pid, @Param("query") Map query); + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml new file mode 100644 index 00000000..d61443b6 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml @@ -0,0 +1,45 @@ +<#assign hasChildrenField = ""> +<#assign pidFieldName = ""> +<#assign textFieldName = ""> +<#assign textDbFieldName = ""> +<#assign pidDbFieldName = ""> +<#list originalColumns as po> + <#if po.fieldDbName == tableVo.extendParams.hasChildren> + <#assign hasChildrenField = po.fieldName> + + <#-- begin 【vue3专用】 --> + <#if po.fieldDbName == tableVo.extendParams.pidField> + <#assign pidFieldName = po.fieldName> + <#assign pidDbFieldName = po.fieldDbName> + + <#if po.fieldDbName == tableVo.extendParams.textField> + <#assign textFieldName = po.fieldName> + <#assign textDbFieldName = po.fieldDbName> + + <#-- end 【vue3专用】 --> + + + + + + + update ${tableName} set ${Format.humpToUnderline(hasChildrenField)} = ${r'#'}{status} where id = ${r'#'}{id} + + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai new file mode 100644 index 00000000..701da1a9 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai @@ -0,0 +1,74 @@ +package ${bussiPackage}.${entityPackage}.service; + +import org.jeecg.common.system.vo.SelectTreeModel; +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.common.exception.JeecgBootException; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import java.util.List; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface I${entityName}Service extends IService<${entityName}> { + + /**根节点父ID的值*/ + public static final String ROOT_PID_VALUE = "0"; + + /**树节点有子节点状态值*/ + public static final String HASCHILD = "1"; + + /**树节点无子节点状态值*/ + public static final String NOCHILD = "0"; + + /** + * 新增节点 + * + * @param ${entityName?uncap_first} + */ + void add${entityName}(${entityName} ${entityName?uncap_first}); + + /** + * 修改节点 + * + * @param ${entityName?uncap_first} + * @throws JeecgBootException + */ + void update${entityName}(${entityName} ${entityName?uncap_first}) throws JeecgBootException; + + /** + * 删除节点 + * + * @param id + * @throws JeecgBootException + */ + void delete${entityName}(String id) throws JeecgBootException; + + /** + * 查询所有数据,无分页 + * + * @param queryWrapper + * @return List<${entityName}> + */ + List<${entityName}> queryTreeListNoPage(QueryWrapper<${entityName}> queryWrapper); + + /** + * 【vue3专用】根据父级编码加载分类字典的数据 + * + * @param parentCode + * @return + */ + List queryListByCode(String parentCode); + + /** + * 【vue3专用】根据pid查询子节点集合 + * + * @param pid + * @return + */ + List queryListByPid(String pid); + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai new file mode 100644 index 00000000..6372a2c2 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai @@ -0,0 +1,229 @@ +package ${bussiPackage}.${entityPackage}.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.jeecg.common.exception.JeecgBootException; +import org.jeecg.common.util.oConvertUtils; +import org.jeecg.common.system.vo.SelectTreeModel; +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import ${bussiPackage}.${entityPackage}.mapper.${entityName}Mapper; +import ${bussiPackage}.${entityPackage}.service.I${entityName}Service; +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +<#assign pidFieldName = ""> +<#assign hasChildrenField = ""> +<#list originalColumns as po> +<#if po.fieldDbName == tableVo.extendParams.pidField> +<#assign pidFieldName = po.fieldName> + +<#if po.fieldDbName == tableVo.extendParams.hasChildren> +<#assign hasChildrenField = po.fieldName> + + + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Service +public class ${entityName}ServiceImpl extends ServiceImpl<${entityName}Mapper, ${entityName}> implements I${entityName}Service { + + @Override + public void add${entityName}(${entityName} ${entityName?uncap_first}) { + //新增时设置hasChild为0 + ${entityName?uncap_first}.set${hasChildrenField?cap_first}(I${entityName}Service.NOCHILD); + if(oConvertUtils.isEmpty(${entityName?uncap_first}.get${pidFieldName?cap_first}())){ + ${entityName?uncap_first}.set${pidFieldName?cap_first}(I${entityName}Service.ROOT_PID_VALUE); + }else{ + //如果当前节点父ID不为空 则设置父节点的hasChildren 为1 + ${entityName} parent = baseMapper.selectById(${entityName?uncap_first}.get${pidFieldName?cap_first}()); + if(parent!=null && !"1".equals(parent.get${hasChildrenField?cap_first}())){ + parent.set${hasChildrenField?cap_first}("1"); + baseMapper.updateById(parent); + } + } + baseMapper.insert(${entityName?uncap_first}); + } + + @Override + public void update${entityName}(${entityName} ${entityName?uncap_first}) { + ${entityName} entity = this.getById(${entityName?uncap_first}.getId()); + if(entity==null) { + throw new JeecgBootException("未找到对应实体"); + } + String old_pid = entity.get${pidFieldName?cap_first}(); + String new_pid = ${entityName?uncap_first}.get${pidFieldName?cap_first}(); + if(!old_pid.equals(new_pid)) { + updateOldParentNode(old_pid); + if(oConvertUtils.isEmpty(new_pid)){ + ${entityName?uncap_first}.set${pidFieldName?cap_first}(I${entityName}Service.ROOT_PID_VALUE); + } + if(!I${entityName}Service.ROOT_PID_VALUE.equals(${entityName?uncap_first}.get${pidFieldName?cap_first}())) { + baseMapper.updateTreeNodeStatus(${entityName?uncap_first}.get${pidFieldName?cap_first}(), I${entityName}Service.HASCHILD); + } + } + baseMapper.updateById(${entityName?uncap_first}); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete${entityName}(String id) throws JeecgBootException { + //查询选中节点下所有子节点一并删除 + id = this.queryTreeChildIds(id); + if(id.indexOf(",")>0) { + StringBuffer sb = new StringBuffer(); + String[] idArr = id.split(","); + for (String idVal : idArr) { + if(idVal != null){ + ${entityName} ${entityName?uncap_first} = this.getById(idVal); + String pidVal = ${entityName?uncap_first}.get${pidFieldName?cap_first}(); + //查询此节点上一级是否还有其他子节点 + List<${entityName}> dataList = baseMapper.selectList(new QueryWrapper<${entityName}>().eq("${tableVo.extendParams.pidField}", pidVal).notIn("id",Arrays.asList(idArr))); + boolean flag = (dataList == null || dataList.size() == 0) && !Arrays.asList(idArr).contains(pidVal) && !sb.toString().contains(pidVal); + if(flag){ + //如果当前节点原本有子节点 现在木有了,更新状态 + sb.append(pidVal).append(","); + } + } + } + //批量删除节点 + baseMapper.deleteBatchIds(Arrays.asList(idArr)); + //修改已无子节点的标识 + String[] pidArr = sb.toString().split(","); + for(String pid : pidArr){ + this.updateOldParentNode(pid); + } + }else{ + ${entityName} ${entityName?uncap_first} = this.getById(id); + if(${entityName?uncap_first}==null) { + throw new JeecgBootException("未找到对应实体"); + } + updateOldParentNode(${entityName?uncap_first}.get${pidFieldName?cap_first}()); + baseMapper.deleteById(id); + } + } + + @Override + public List<${entityName}> queryTreeListNoPage(QueryWrapper<${entityName}> queryWrapper) { + List<${entityName}> dataList = baseMapper.selectList(queryWrapper); + List<${entityName}> mapList = new ArrayList<>(); + for(${entityName} data : dataList){ + String pidVal = data.get${pidFieldName?cap_first}(); + //递归查询子节点的根节点 + if(pidVal != null && !I${entityName}Service.NOCHILD.equals(pidVal)){ + ${entityName} rootVal = this.getTreeRoot(pidVal); + if(rootVal != null && !mapList.contains(rootVal)){ + mapList.add(rootVal); + } + }else{ + if(!mapList.contains(data)){ + mapList.add(data); + } + } + } + return mapList; + } + + @Override + public List queryListByCode(String parentCode) { + String pid = ROOT_PID_VALUE; + if (oConvertUtils.isNotEmpty(parentCode)) { + LambdaQueryWrapper<${entityName}> queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(${entityName}::get${pidFieldName?cap_first}, parentCode); + List<${entityName}> list = baseMapper.selectList(queryWrapper); + if (list == null || list.size() == 0) { + throw new JeecgBootException("该编码【" + parentCode + "】不存在,请核实!"); + } + if (list.size() > 1) { + throw new JeecgBootException("该编码【" + parentCode + "】存在多个,请核实!"); + } + pid = list.get(0).getId(); + } + return baseMapper.queryListByPid(pid, null); + } + + @Override + public List queryListByPid(String pid) { + if (oConvertUtils.isEmpty(pid)) { + pid = ROOT_PID_VALUE; + } + return baseMapper.queryListByPid(pid, null); + } + + /** + * 根据所传pid查询旧的父级节点的子节点并修改相应状态值 + * @param pid + */ + private void updateOldParentNode(String pid) { + if(!I${entityName}Service.ROOT_PID_VALUE.equals(pid)) { + Long count = baseMapper.selectCount(new QueryWrapper<${entityName}>().eq("${tableVo.extendParams.pidField}", pid)); + if(count==null || count<=1) { + baseMapper.updateTreeNodeStatus(pid, I${entityName}Service.NOCHILD); + } + } + } + + /** + * 递归查询节点的根节点 + * @param pidVal + * @return + */ + private ${entityName} getTreeRoot(String pidVal){ + ${entityName} data = baseMapper.selectById(pidVal); + if(data != null && !I${entityName}Service.ROOT_PID_VALUE.equals(data.get${pidFieldName?cap_first}()) && !data.get${pidFieldName?cap_first}().equals(data.getId())){ + return this.getTreeRoot(data.get${pidFieldName?cap_first}()); + }else{ + return data; + } + } + + /** + * 根据id查询所有子节点id + * @param ids + * @return + */ + private String queryTreeChildIds(String ids) { + //获取id数组 + String[] idArr = ids.split(","); + StringBuffer sb = new StringBuffer(); + for (String pidVal : idArr) { + if(pidVal != null){ + if(!sb.toString().contains(pidVal)){ + if(sb.toString().length() > 0){ + sb.append(","); + } + sb.append(pidVal); + this.getTreeChildIds(pidVal,sb); + } + } + } + return sb.toString(); + } + + /** + * 递归查询所有子节点 + * @param pidVal + * @param sb + * @return + */ + private StringBuffer getTreeChildIds(String pidVal,StringBuffer sb){ + List<${entityName}> dataList = baseMapper.selectList(new QueryWrapper<${entityName}>().eq("${tableVo.extendParams.pidField}", pidVal)); + if(dataList != null && dataList.size()>0){ + for(${entityName} tree : dataList) { + if(!sb.toString().contains(tree.getId())){ + sb.append(",").append(tree.getId()); + } + this.getTreeChildIds(tree.getId(),sb); + } + } + return sb; + } + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei new file mode 100644 index 00000000..b5758a20 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei @@ -0,0 +1,523 @@ +<#assign pidFieldName = ""> +<#assign hasChildrenField = ""> +<#list originalColumns as po> +<#if po.fieldDbName == tableVo.extendParams.pidField> +<#assign pidFieldName = po.fieldName> + +<#if po.fieldDbName == tableVo.extendParams.hasChildren> +<#assign hasChildrenField = po.fieldName> + + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql new file mode 100644 index 00000000..5396d5d5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql @@ -0,0 +1 @@ +<#include "/common/sql/menu_insert.ftl"> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei new file mode 100644 index 00000000..1a4fa5a3 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei @@ -0,0 +1,246 @@ +<#include "/common/utils.ftl"> + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei new file mode 100644 index 00000000..acead0b6 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei @@ -0,0 +1,564 @@ +<#include "/common/utils.ftl"> +<#assign pidFieldName = ""> +<#assign hasChildrenField = ""> +<#assign bpm_flag=false> +<#assign list_has_popup_dict=false> +<#list originalColumns as po> + <#if po.fieldDbName == tableVo.extendParams.pidField> + <#assign pidFieldName = po.fieldName> + + <#if po.fieldDbName == tableVo.extendParams.hasChildren> + <#assign hasChildrenField = po.fieldName> + + +<#assign list_need_pca=false> +<#assign buttonList=[]> +<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??> + <#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)> + +<#-- 开始循环 --> +<#list columns as po> + <#if po.fieldDbName=='bpm_status'> + <#assign bpm_flag=true> + +<#if po.classType=='pca'> +<#assign list_need_pca=true> + +<#if po.classType=='popup_dict'> +<#assign list_has_popup_dict=true> + + + + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi new file mode 100644 index 00000000..b1fd11da --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi @@ -0,0 +1,85 @@ +import {defHttp} from "/@/utils/http/axios"; +import { useMessage } from "/@/hooks/web/useMessage"; + +const { createConfirm } = useMessage(); + +enum Api { + list = '/${entityPackagePath}/${entityName?uncap_first}/rootList', + save='/${entityPackagePath}/${entityName?uncap_first}/add', + edit='/${entityPackagePath}/${entityName?uncap_first}/edit', + delete${entityName} = '/${entityPackagePath}/${entityName?uncap_first}/delete', + importExcel = '/${entityPackagePath}/${entityName?uncap_first}/importExcel', + exportXls = '/${entityPackagePath}/${entityName?uncap_first}/exportXls', + loadTreeData = '/${entityPackagePath}/${entityName?uncap_first}/loadTreeRoot', + getChildList = '/${entityPackagePath}/${entityName?uncap_first}/childList', + getChildListBatch = '/${entityPackagePath}/${entityName?uncap_first}/getChildListBatch', +} + +/** + * 导出api + * @param params + */ +export const getExportUrl = Api.exportXls; +/** + * 导入api + * @param params + */ +export const getImportUrl = Api.importExcel; +/** + * 列表接口 + * @param params + */ +export const list = (params) => + defHttp.get({url: Api.list, params}); +/** + * 删除 + */ +export const delete${entityName} = (params,handleSuccess) => { + return defHttp.delete({url: Api.delete${entityName}, params}, {joinParamsToUrl: true}).then(() => { + handleSuccess(); + }); +} +/** + * 批量删除 + * @param params + */ +export const batchDelete${entityName} = (params, handleSuccess) => { + createConfirm({ + iconType: 'warning', + title: '确认删除', + content: '是否删除选中数据', + okText: '确认', + cancelText: '取消', + onOk: () => { + return defHttp.delete({url: Api.delete${entityName}, data: params}, {joinParamsToUrl: true}).then(() => { + handleSuccess(); + }); + } + }); +} +/** + * 保存或者更新 + * @param params + */ +export const saveOrUpdateDict = (params, isUpdate) => { + let url = isUpdate ? Api.edit : Api.save; + return defHttp.post({url: url, params}); +} +/** + * 查询全部树形节点数据 + * @param params + */ +export const loadTreeData = (params) => + defHttp.get({url: Api.loadTreeData,params}); +/** + * 查询子节点数据 + * @param params + */ +export const getChildList = (params) => + defHttp.get({url: Api.getChildList, params}); +/** + * 批量查询子节点数据 + * @param params + */ +export const getChildListBatch = (params) => + defHttp.get({url: Api.getChildListBatch, params},{isTransformResponse:false}); diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi new file mode 100644 index 00000000..dec5d763 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi @@ -0,0 +1,560 @@ +<#include "/common/utils.ftl"> +import {BasicColumn} from '/@/components/Table'; +import {FormSchema} from '/@/components/Table'; +import { rules} from '/@/utils/helper/validator'; +import { render } from '/@/utils/common/renderUtils'; +import { getWeekMonthQuarterYear } from '/@/utils'; +//列表数据 +export const columns: BasicColumn[] = [ + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + { + title: '${po.filedComment}', + <#if po.fieldDbName == tableVo.extendParams.textField> + align: 'left', + <#else> + align: 'center', + + <#if po.sort=='Y'> + sorter: true, + + <#if po.classType=='date'> + dataIndex: '${po.fieldName}', + customRender:({text}) =>{ + text = !text ? "" : (text.length > 10 ? text.substr(0,10) : text); + <#if po.extendParams?exists && po.extendParams.picker?exists> + if(text) { + return getWeekMonthQuarterYear(text)['${po.extendParams.picker}']; + } else { + return text; + } + <#else> + return text; + + }, + <#elseif po.fieldDbType=='Blob'> + dataIndex: '${po.fieldName}String' + <#elseif po.classType=='umeditor'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='pca'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='file'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='image'> + dataIndex: '${po.fieldName}', + customRender:render.renderImage, + <#elseif po.classType=='switch'> + dataIndex: '${po.fieldName}', +<#assign switch_extend_arr=['Y','N']> +<#if po.dictField?default("")?contains("[")> +<#assign switch_extend_arr=po.dictField?eval> + +<#list switch_extend_arr as a> +<#if a_index == 0> +<#assign switch_extend_arr1=a> +<#else> +<#assign switch_extend_arr2=a> + + + customRender:({text}) => { + return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]) + }, + <#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user' || po.classType=='popup_dict' || po.classType=='link_table'> + dataIndex: '${po.fieldName}_dictText' + <#elseif po.classType=='cat_tree'> + dataIndex: '${po.fieldName}', + <#if po.dictText?default("")?trim?length == 0> + customRender:({text}) => { + return render.renderCategoryTree(text,'${po.dictField?default("")}') + }, + <#else> + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') + + <#else> + dataIndex: '${po.fieldName}' + + }, + + +]; +//查询数据 +export const searchFormSchema: FormSchema[] = [ +<#-- 开始循环 --> +<#list columns as po> +<#if po.fieldDbName=='bpm_status'> + <#assign bpm_flag=true> + +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if po.isQuery=='Y' && po.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#assign query_flag=true> + <#assign query_field_dictCode=""> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign query_field_dictCode="${po.dictField}"> + +<#if po.queryMode=='single'> + { + label: "${po.filedComment}", + field: "${po.fieldName}", +<#if po.classType=='sel_search'> + component: 'JSearchSelect', + componentProps:{ + dict:"${query_field_dictCode}" + }, +<#elseif po.classType=='sel_user'> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + component: 'JSelectUser', +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, +<#elseif po.classType=='switch'> + component: 'JSwitch', + componentProps:{ + <#if po.dictField != 'is_open'> + options:"${po.dictField}" + + }, + <#elseif po.classType=='sel_depart'> + component: 'JSelectDept', + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType=='list_multi'> + component: 'JSelectMultiple', + componentProps:{ + <#if po.dictTable?default("")?trim?length gt 1> + dictCode:"${po.dictTable},${po.dictText},${po.dictField}", + <#elseif po.dictField?default("")?trim?length gt 1> + dictCode:"${po.dictField}", + + triggerChange: true + }, + <#elseif po.classType=='cat_tree'> + component: 'JCategorySelect', + componentProps:{ + pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题 + }, +<#elseif po.classType=='date'> + component: 'DatePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueFormat: 'YYYY-MM-DD' + }, +<#elseif po.classType=='datetime'> + component: 'DatePicker', + componentProps: { + showTime:true + }, +<#elseif po.classType=='datetime'> + component: 'DatePicker', + componentProps: { + showTime:true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, +<#elseif po.classType=='pca'> + component: 'JAreaLinkage', + componentProps: { + saveCode: 'region', + }, +<#elseif po.classType=='popup'> + <#include "/common/form/vue3popup.ftl"> +<#elseif po.classType=='popup_dict'> + component: 'JPopupDict', + componentProps: { + placeholder: '请选择${po.filedComment}', + dictCode: '${po.dictTable},${po.dictText},${po.dictField}', + multi: ${po.extendParams.popupMulti?c} + }, +<#elseif po.classType == 'sel_tree'> + component: 'JTreeSelect', + componentProps:{ + <#if po.dictText??> + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", + + <#if po.dictText?split(',')[1]??> + pidField:"${po.dictText?split(',')[1]}", + + <#if po.dictText?split(',')[3]??> + hasChildField:"${po.dictText?split(',')[3]}", + + + pidValue:"${po.dictField}", + }, +<#elseif po.classType=='link_table'> + component: 'JLinkTableCard', + componentProps: { + valueField: '${po.dictField}', + textField: '${po.dictText}', + tableName: '${po.dictTable}', + multi: <#if (po.queryMode!"") == "multi">true<#else>false + }, +<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'> +<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- --> + component: 'JSelectMultiple', + componentProps:{ + <#if po.dictTable?default("")?trim?length gt 1> + dictCode:"${po.dictTable},${po.dictText},${po.dictField}" + <#elseif po.dictField?default("")?trim?length gt 1> + dictCode:"${po.dictField}" + + }, +<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'InputNumber', +<#else> + component: 'Input', + + //colProps: {span: 6}, + }, +<#elseif po.queryMode=='like'> + { + label: "${po.filedComment}", + field: "${po.fieldName}", + component: 'JInput', + }, +<#else> + { + label: "${po.filedComment}", + field: "${po.fieldName}", +<#if po.classType=='date'> + component: 'RangePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueType: 'Date', + }, +<#elseif po.classType=='datetime'> + component: 'RangePicker', + componentProps: { + valueType: 'Date', + showTime:true + }, +<#elseif po.classType == 'time'> + component: 'TimePicker', + componentProps:{ + valueFormat: 'HH:mm:ss', + }, +<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'JRangeNumber', +<#-- update-begin---author:chenrui ---date:20240527 for:[TV360X-388]时间范围查询控件---------- --> +<#elseif po.classType=='time'> + component: 'RangeTime', +<#-- update-end---author:chenrui ---date:20240527 for:[TV360X-388]时间范围查询控件---------- --> +<#else> + component: 'Input', //TODO 范围查询 + + //colProps: {span: 6}, + }, + + + +<#-- 结束循环 --> +]; +//表单数据 +export const formSchema: FormSchema[] = [ +<#assign form_cat_tree = false> +<#assign form_cat_back = ""> +<#assign bpm_flag=false> +<#assign id_exists = false> +<#list columns as po><#rt/> +<#if po.fieldDbName=='bpm_status'> + <#assign bpm_flag=true> + +<#if po.fieldDbName == 'id'> + <#assign id_exists = true> + +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if po.isShow =='Y' && po.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#assign form_field_dictCode=""> + <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictField}"> + + { + label: '${po.filedComment}', + field: ${autoStringSuffix(po)}, +<#-- update-begin-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.defaultVal??> + <#if po.fieldDbType=="BigDecimal" || po.fieldDbType=="double" || po.fieldDbType=="int"> + defaultValue: ${po.defaultVal}, + <#else> + defaultValue: "${po.defaultVal}", + + +<#-- update-end-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.fieldDbName == tableVo.extendParams.pidField> + component: 'JTreeSelect', + componentProps: { + dict: "${tableVo.tableName},${tableVo.extendParams.textField},id", + pidField: "${tableVo.extendParams.pidField}", + pidValue: "0", + hasChildField: "${tableVo.extendParams.hasChildren}", + }, + <#elseif po.classType =='date'> + component: 'DatePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueFormat: 'YYYY-MM-DD' + }, + <#elseif po.classType =='datetime'> + component: 'DatePicker', + componentProps: { + showTime:true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, + <#elseif po.classType =='time'> + component: 'TimePicker', + componentProps:{ + valueFormat: 'HH:mm:ss', + }, + <#elseif po.classType =='popup'> + <#include "/common/form/vue3popup.ftl"> + <#elseif po.classType=='popup_dict'> + component: 'JPopupDict', + componentProps: { + placeholder: '请选择${po.filedComment}', + dictCode: '${po.dictTable},${po.dictText},${po.dictField}', + multi: ${po.extendParams.popupMulti?c} + }, + <#elseif po.classType =='sel_depart'> + component: 'JSelectDept', + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='switch'> + component: 'JSwitch', + componentProps:{ + <#if po.dictField != 'is_open'> + options:${po.dictField} + + }, + <#elseif po.classType =='pca'> + component: 'JAreaLinkage', + componentProps: { + saveCode: 'region', + }, + <#elseif po.classType =='markdown'> + component: 'JMarkdownEditor',//注意string转换问题 + <#elseif po.classType =='password'> + component: 'InputPassword', + <#elseif po.classType =='sel_user'> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + component: 'JSelectUser', +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='textarea'> + component: 'InputTextArea', + <#elseif po.classType=='list'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#elseif po.classType=='radio'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + type: "radio", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='list_multi'> + component: 'JSelectMultiple', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#elseif po.classType=='checkbox'> + component: 'JCheckbox', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='sel_search'> + component: 'JSearchSelect', + componentProps:{ + dict:"${form_field_dictCode}" + }, +<#elseif po.classType=='cat_tree'> + <#assign form_cat_tree = true> + component: 'JCategorySelect', + componentProps:{ + pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题 + }, + <#if po.dictText?default("")?trim?length gt 1> + <#assign form_cat_back = "${po.dictText}"> + + <#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'InputNumber', + <#elseif po.classType=='file'> + component: 'JUpload', + componentProps:{ + <#if po.uploadnum??> + maxCount:${po.uploadnum} + + }, + <#elseif po.classType=='image'> + component: 'JImageUpload', + componentProps:{ + <#if po.uploadnum??> + fileMax:${po.uploadnum} + <#else> + fileMax: 0 + + }, + <#elseif po.classType=='umeditor'> + component: 'JEditor', + <#elseif po.classType == 'sel_tree'> + component: 'JTreeSelect', + componentProps:{ + <#if po.dictText??> + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", + + <#if po.dictText?split(',')[1]??> + pidField:"${po.dictText?split(',')[1]}", + + <#if po.dictText?split(',')[3]??> + hasChildField:"${po.dictText?split(',')[3]}", + + + pidValue:"${po.dictField}", + }, + <#else> + component: 'Input', + + <#include "/common/utils.ftl"> + <#if po.isShow == 'Y' && poHasCheck(po)> + dynamicRules: ({model,schema}) => { + <#if po.fieldName != 'id'> + <#assign fieldValidType = po.fieldValidType!''> + return [ + <#-- 非空校验 --> + <#if po.nullable == 'N' || fieldValidType == '*'> + { required: true, message: '请输入${po.filedComment}!'}, + <#elseif fieldValidType!=''> + { required: false}, + + <#-- 唯一校验 --> + <#if fieldValidType == 'only'> + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}', '${po.fieldDbName}',model,schema)[0]}, + <#-- 6到16位数字 --> + <#elseif fieldValidType == 'n6-16'> + { pattern: /^\d{6,16}$|^(?=\d+\.\d+)[\d.]{7,17}$/, message: '请输入6到16位数字!'}, + <#-- 6到16位任意字符 --> + <#elseif fieldValidType == '*6-16'> + { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, + <#-- 6到18位字母 --> + <#elseif fieldValidType == 's6-18'> + { pattern:/^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, + <#-- 网址 --> + <#elseif fieldValidType == 'url'> + { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, + <#-- 电子邮件 --> + <#elseif fieldValidType == 'e'> + { pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'}, + <#-- 手机号码 --> + <#elseif fieldValidType == 'm'> + { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}, + <#-- 邮政编码 --> + <#elseif fieldValidType == 'p'> + { pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'}, + <#-- 字母 --> + <#elseif fieldValidType == 's'> + { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}, + <#-- 数字 --> + <#elseif fieldValidType == 'n'> + { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'}, + <#-- 整数 --> + <#elseif fieldValidType == 'z'> + { pattern: /^-?\d+$/, message: '请输入整数!'}, + <#-- 金额 --> + <#elseif fieldValidType == 'money'> + { pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'}, + <#-- 正则校验 --> + <#elseif fieldValidType != '' && fieldValidType != '*'> + { pattern: '${fieldValidType}', message: '不符合校验规则!'}, + <#-- 无校验 --> + <#else> + <#t> + + ]; + + }, + + <#if po.readonly=='Y'> + dynamicDisabled:true + + }, + + +<#if id_exists == false> + // TODO 主键隐藏字段,目前写死为ID + { + label: '', + field: 'id', + component: 'Input', + show: false + }, + +]; + +<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> +// 高级查询数据 +export const superQuerySchema = { + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + ${superQueryFieldListForVue3(po,po_index)}, + + +}; +<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> + + +/** +* 流程表单调用这个方法获取formSchema +* @param param +*/ +export function getBpmFormSchema(_formData): FormSchema[]{ + // 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema + return formSchema; +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql new file mode 100644 index 00000000..5396d5d5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql @@ -0,0 +1 @@ +<#include "/common/sql/menu_insert.ftl"> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Form.vuei new file mode 100644 index 00000000..3b5b65e4 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Form.vuei @@ -0,0 +1,72 @@ +<#include "/common/utils.ftl"> + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei new file mode 100644 index 00000000..531645c7 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei @@ -0,0 +1,191 @@ +<#include "/common/utils.ftl"> +<#assign pidFieldName = ""> +<#assign hasChildrenField = ""> +<#list originalColumns as po> + <#if po.fieldDbName == tableVo.extendParams.pidField> + <#assign pidFieldName = po.fieldName> + + <#if po.fieldDbName == tableVo.extendParams.hasChildren> + <#assign hasChildrenField = po.fieldName> + + +<#assign buttonList=[]> +<#if tableVo.extendParams?? && tableVo.extendParams.cgButtonList??> + <#assign buttonList = tableVo.extendParams.cgButtonList?filter(btn -> btn??)> + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei new file mode 100644 index 00000000..01decc77 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei @@ -0,0 +1,738 @@ +<#include "/common/utils.ftl"> + + +<#if query_flag> + + + + 查询 + 重置 + + {{ toggleSearchStatus ? '收起' : '展开' }} + + + + + + + + + +<#-- 结束循环 --> + + + + + + + + + + + <${entityName}Modal ref="registerModal" @success="handleSuccess"> + <#if bpm_flag==true> + + + + + + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi new file mode 100644 index 00000000..7944cae2 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi @@ -0,0 +1,93 @@ +import { defHttp } from "/@/utils/http/axios"; +import { useMessage } from "/@/hooks/web/useMessage"; + +const { createConfirm } = useMessage(); + +enum Api { + list = '/${entityPackagePath}/${entityName?uncap_first}/rootList', + save='/${entityPackagePath}/${entityName?uncap_first}/add', + edit='/${entityPackagePath}/${entityName?uncap_first}/edit', + delete${entityName} = '/${entityPackagePath}/${entityName?uncap_first}/delete', + importExcel = '/${entityPackagePath}/${entityName?uncap_first}/importExcel', + exportXls = '/${entityPackagePath}/${entityName?uncap_first}/exportXls', + loadTreeData = '/${entityPackagePath}/${entityName?uncap_first}/loadTreeRoot', + getChildList = '/${entityPackagePath}/${entityName?uncap_first}/childList', + getChildListBatch = '/${entityPackagePath}/${entityName?uncap_first}/getChildListBatch', +} + +/** + * 导出api + * @param params + */ +export const getExportUrl = Api.exportXls; + +/** + * 导入api + * @param params + */ +export const getImportUrl = Api.importExcel; + +/** + * 列表接口 + * @param params + */ +export const list = (params) => defHttp.get({ url: Api.list, params }); + +/** + * 删除 + * @param params + * @param handleSuccess + */ +export const delete${entityName} = (params,handleSuccess) => { + return defHttp.delete({ url: Api.delete${entityName}, params }, { joinParamsToUrl: true }).then(() => { + handleSuccess(); + }); +} + +/** + * 批量删除 + * @param params + * @param handleSuccess + */ +export const batchDelete${entityName} = (params, handleSuccess) => { + createConfirm({ + iconType: 'warning', + title: '确认删除', + content: '是否删除选中数据', + okText: '确认', + cancelText: '取消', + onOk: () => { + return defHttp.delete({ url: Api.delete${entityName}, data: params }, { joinParamsToUrl: true }).then(() => { + handleSuccess(); + }); + } + }); +} + +/** + * 保存或者更新 + * @param params + * @param isUpdate + */ +export const saveOrUpdateDict = (params, isUpdate) => { + let url = isUpdate ? Api.edit : Api.save; + return defHttp.post({ url: url, params },{ isTransformResponse:false }); +} + +/** + * 查询全部树形节点数据 + * @param params + */ +export const loadTreeData = (params) => defHttp.get({ url: Api.loadTreeData,params }); + +/** + * 查询子节点数据 + * @param params + */ +export const getChildList = (params) => defHttp.get({ url: Api.getChildList, params }); + +/** + * 批量查询子节点数据 + * @param params + */ +export const getChildListBatch = (params) => defHttp.get({ url: Api.getChildListBatch, params },{ isTransformResponse:false }); diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi new file mode 100644 index 00000000..e6c34471 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi @@ -0,0 +1,94 @@ +<#include "/common/utils.ftl"> +import {BasicColumn} from '/@/components/Table'; +import {FormSchema} from '/@/components/Table'; +import { rules} from '/@/utils/helper/validator'; +import { render } from '/@/utils/common/renderUtils'; +import { getWeekMonthQuarterYear } from '/@/utils'; +//列表数据 +export const columns: BasicColumn[] = [ + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + { + title: '${po.filedComment}', + <#if po.fieldDbName == tableVo.extendParams.textField> + align: 'left', + <#else> + align: 'center', + + <#if po.sort=='Y'> + sorter: true, + + <#if po.classType=='date'> + dataIndex: '${po.fieldName}', + customRender:({text}) =>{ + text = !text ? "" : (text.length > 10 ? text.substr(0,10) : text); + <#if po.extendParams?exists && po.extendParams.picker?exists> + if(text) { + return getWeekMonthQuarterYear(text)['${po.extendParams.picker}']; + } else { + return text; + } + <#else> + return text; + + }, + <#elseif po.fieldDbType=='Blob'> + dataIndex: '${po.fieldName}String' + <#elseif po.classType=='umeditor'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='pca'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='file'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='image'> + dataIndex: '${po.fieldName}', + customRender: render.renderImage, + <#elseif po.classType=='switch'> + dataIndex: '${po.fieldName}', +<#assign switch_extend_arr=['Y','N']> +<#if po.dictField?default("")?contains("[")> +<#assign switch_extend_arr=po.dictField?eval> + +<#list switch_extend_arr as a> +<#if a_index == 0> +<#assign switch_extend_arr1=a> +<#else> +<#assign switch_extend_arr2=a> + + + customRender:({text}) => { + return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]); + }, + <#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user' || po.classType=='popup_dict'> + dataIndex: '${po.fieldName}_dictText' + <#elseif po.classType=='cat_tree'> + dataIndex: '${po.fieldName}', + <#if po.dictText?default("")?trim?length == 0> + customRender:({text}) => { + return render.renderCategoryTree(text,'${po.dictField?default("")}'); + }, + <#else> + customRender: ({text, record}) => (text ? record['${po.dictText}'] : ''); + + <#else> + dataIndex: '${po.fieldName}' + + }, + + +]; + +<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> +// 高级查询数据 +export const superQuerySchema = { + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + ${superQueryFieldListForVue3(po,po_index)}, + + +}; +<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/V${currentDate}_1__menu_insert_${entityName}.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/V${currentDate}_1__menu_insert_${entityName}.sql new file mode 100644 index 00000000..5396d5d5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/V${currentDate}_1__menu_insert_${entityName}.sql @@ -0,0 +1 @@ +<#include "/common/sql/menu_insert.ftl"> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei new file mode 100644 index 00000000..12dfa603 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei @@ -0,0 +1,316 @@ +<#include "/common/utils.ftl"> + + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei new file mode 100644 index 00000000..7242007c --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei @@ -0,0 +1,101 @@ +<#include "/common/utils.ftl"> + + + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai new file mode 100644 index 00000000..4c143dea --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -0,0 +1,403 @@ +package ${bussiPackage}.${entityPackage}.controller; + +import org.jeecg.common.system.query.QueryGenerator; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.jeecg.common.system.query.QueryRuleEnum; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.system.base.controller.JeecgController; +import org.jeecg.common.api.vo.Result; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.web.servlet.ModelAndView; +import java.util.Arrays; +import java.util.HashMap; +import org.jeecg.common.util.oConvertUtils; +import org.jeecgframework.poi.excel.entity.enmus.ExcelType; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import ${bussiPackage}.${entityPackage}.service.I${entityName}Service; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.service.I${sub.entityName}Service; + +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.apache.shiro.SecurityUtils; +import org.jeecg.common.system.vo.LoginUser; +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.apache.shiro.authz.annotation.RequiresPermissions; +<#assign has_multi_query_field=false> +<#list originalColumns as po> +<#if po.isQuery=='Y' && (po.classType=='list' || po.classType=='list_multi' || po.classType=='radio' || po.classType=='checkbox')> + <#assign has_multi_query_field=true> + + +<#assign enhanceJavaList=[]> +<#if tableVo.extendParams?? && tableVo.extendParams.enhanceJavaList??> + <#assign enhanceJavaList = tableVo.extendParams.enhanceJavaList?filter(enhance -> enhance??)> + + /** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Tag(name="${tableVo.ftlDescription}") +@RestController +@RequestMapping("/${entityPackagePath}/${entityName?uncap_first}") +@Slf4j +public class ${entityName}Controller extends JeecgController<${entityName}, I${entityName}Service> { + + @Autowired + private I${entityName}Service ${entityName?uncap_first}Service; + <#list subTables as sub> + + @Autowired + private I${sub.entityName}Service ${sub.entityName?uncap_first}Service; + + + + /*---------------------------------主表处理-begin-------------------------------------*/ + + /** + * 分页列表查询 + * @param ${entityName?uncap_first} + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "${tableVo.ftlDescription}-分页列表查询") + @Operation(summary="${tableVo.ftlDescription}-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(${entityName} ${entityName?uncap_first}, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='query' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 查询前触发的方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeQuery() + + + + <#if has_multi_query_field> + // 自定义查询规则 + Map customeRuleMap = new HashMap<>(); + // 自定义多选的查询规则为:LIKE_WITH_OR + <#list originalColumns as po> + <#if po.isQuery=='Y' && (po.classType=='list' || po.classType=='list_multi' || po.classType=='radio' || po.classType=='checkbox')> + customeRuleMap.put("${po.fieldName}", QueryRuleEnum.LIKE_WITH_OR); + + + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap(),customeRuleMap); + <#else> + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap()); + + Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize); + IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper); +<#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='query' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'> + //TODO 查询后触发的方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.afterQuery() + + + + return Result.OK(pageList); + } + + /** + * 添加 + * @param ${entityName?uncap_first} + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-添加") + @Operation(summary="${tableVo.ftlDescription}-添加") + @RequiresPermissions("${entityPackage}:${tableName}:add") + @PostMapping(value = "/add") + public Result add(@RequestBody ${entityName} ${entityName?uncap_first}) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='add' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 新增前的处理方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeAdd() + + + + ${entityName?uncap_first}Service.save(${entityName?uncap_first}); +<#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='add' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'> + //TODO 新增后的处理方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.afterAdd() + + + + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * @param ${entityName?uncap_first} + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-编辑") + @Operation(summary="${tableVo.ftlDescription}-编辑") + @RequiresPermissions("${entityPackage}:${tableName}:edit") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) + public Result edit(@RequestBody ${entityName} ${entityName?uncap_first}) { +<#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 编辑前,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeEdit() + + + + ${entityName?uncap_first}Service.updateById(${entityName?uncap_first}); +<#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'> + //TODO 编辑后,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.afterEdit() + + + + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * @param id + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-通过id删除") + @Operation(summary="${tableVo.ftlDescription}-通过id删除") + @RequiresPermissions("${entityPackage}:${tableName}:delete") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name="id",required=true) String id) { + ${entityName?uncap_first}Service.delMain(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * @param ids + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-批量删除") + @Operation(summary="${tableVo.ftlDescription}-批量删除") + @RequiresPermissions("${entityPackage}:${tableName}:deleteBatch") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + this.${entityName?uncap_first}Service.delBatchMain(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 导出 + * @return + */ + @RequiresPermissions("${entityPackage}:${tableName}:exportXls") + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='export' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 导出前,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeExport() + + + + return super.exportXls(request, ${entityName?uncap_first}, ${entityName}.class, "${tableVo.ftlDescription}"); + } + + /** + * 导入 + * @return + */ + @RequiresPermissions("${entityPackage}:${tableName}:importExcel") + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='import' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 导入前,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeImport() + + + + return super.importExcel(request, response, ${entityName}.class); + } + /*---------------------------------主表处理-end-------------------------------------*/ + + <#list subTables as sub> + + /*--------------------------------子表处理-${sub.ftlDescription}-begin----------------------------------------------*/ + /** + * 通过主表ID查询 + * @return + */ + //@AutoLog(value = "${sub.ftlDescription}-通过主表ID查询") + @Operation(summary="${sub.ftlDescription}-通过主表ID查询") + @GetMapping(value = "/list${sub.entityName}ByMainId") + public Result> list${sub.entityName}ByMainId(${sub.entityName} ${sub.entityName?uncap_first}, + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, + HttpServletRequest req) { + QueryWrapper<${sub.entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${sub.entityName?uncap_first}, req.getParameterMap()); + Page<${sub.entityName}> page = new Page<${sub.entityName}>(pageNo, pageSize); + IPage<${sub.entityName}> pageList = ${sub.entityName?uncap_first}Service.page(page, queryWrapper); + return Result.OK(pageList); + } + + /** + * 添加 + * @param ${sub.entityName?uncap_first} + * @return + */ + @AutoLog(value = "${sub.ftlDescription}-添加") + @Operation(summary="${sub.ftlDescription}-添加") + @PostMapping(value = "/add${sub.entityName}") + public Result add${sub.entityName}(@RequestBody ${sub.entityName} ${sub.entityName?uncap_first}) { + ${sub.entityName?uncap_first}Service.save(${sub.entityName?uncap_first}); + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * @param ${sub.entityName?uncap_first} + * @return + */ + @AutoLog(value = "${sub.ftlDescription}-编辑") + @Operation(summary="${sub.ftlDescription}-编辑") + @RequestMapping(value = "/edit${sub.entityName}", method = {RequestMethod.PUT,RequestMethod.POST}) + public Result edit${sub.entityName}(@RequestBody ${sub.entityName} ${sub.entityName?uncap_first}) { + ${sub.entityName?uncap_first}Service.updateById(${sub.entityName?uncap_first}); + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * @param id + * @return + */ + @AutoLog(value = "${sub.ftlDescription}-通过id删除") + @Operation(summary="${sub.ftlDescription}-通过id删除") + @DeleteMapping(value = "/delete${sub.entityName}") + public Result delete${sub.entityName}(@RequestParam(name="id",required=true) String id) { + ${sub.entityName?uncap_first}Service.removeById(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * @param ids + * @return + */ + @AutoLog(value = "${sub.ftlDescription}-批量删除") + @Operation(summary="${sub.ftlDescription}-批量删除") + @DeleteMapping(value = "/deleteBatch${sub.entityName}") + public Result deleteBatch${sub.entityName}(@RequestParam(name="ids",required=true) String ids) { + this.${sub.entityName?uncap_first}Service.removeByIds(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 导出 + * @return + */ + @RequestMapping(value = "/export${sub.entityName}") + public ModelAndView export${sub.entityName}(HttpServletRequest request, ${sub.entityName} ${sub.entityName?uncap_first}) { + // Step.1 组装查询条件 + QueryWrapper<${sub.entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${sub.entityName?uncap_first}, request.getParameterMap()); + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + + // Step.2 获取导出数据 + List<${sub.entityName}> pageList = ${sub.entityName?uncap_first}Service.list(queryWrapper); + List<${sub.entityName}> exportList = null; + + // 过滤选中数据 + String selections = request.getParameter("selections"); + if (oConvertUtils.isNotEmpty(selections)) { + List selectionList = Arrays.asList(selections.split(",")); + exportList = pageList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList()); + } else { + exportList = pageList; + } + + // Step.3 AutoPoi 导出Excel + ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); + //此处设置的filename无效,前端会重更新设置一下 + mv.addObject(NormalExcelConstants.FILE_NAME, "${sub.ftlDescription}"); + mv.addObject(NormalExcelConstants.CLASS, ${sub.entityName}.class); + mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("${sub.ftlDescription}报表", "导出人:" + sysUser.getRealname(), "${sub.ftlDescription}", ExcelType.XSSF)); + mv.addObject(NormalExcelConstants.DATA_LIST, exportList); + return mv; + } + + /** + * 导入 + * @return + */ + @RequestMapping(value = "/import${sub.entityName}/{mainId}") + public Result import${sub.entityName}(HttpServletRequest request, HttpServletResponse response, @PathVariable("mainId") String mainId) { + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map fileMap = multipartRequest.getFileMap(); + for (Map.Entry entity : fileMap.entrySet()) { + // 获取上传文件对象 + MultipartFile file = entity.getValue(); + ImportParams params = new ImportParams(); + params.setTitleRows(2); + params.setHeadRows(1); + params.setNeedSave(true); + try { + List<${sub.entityName}> list = ExcelImportUtil.importExcel(file.getInputStream(), ${sub.entityName}.class, params); + for (${sub.entityName} temp : list) { + <#list sub.foreignKeys as key> + temp.set${key?cap_first}(mainId); + + } + long start = System.currentTimeMillis(); + ${sub.entityName?uncap_first}Service.saveBatch(list); + log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒"); + return Result.OK("文件导入成功!数据行数:" + list.size()); + } catch (Exception e) { + log.error(e.getMessage(), e); + return Result.error("文件导入失败:" + e.getMessage()); + } finally { + try { + file.getInputStream().close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return Result.error("文件导入失败!"); + } + + /*--------------------------------子表处理-${sub.ftlDescription}-end----------------------------------------------*/ + + + + + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai new file mode 100644 index 00000000..f68b1f8e --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai @@ -0,0 +1,82 @@ +<#include "/common/utils.ftl"> +package ${bussiPackage}.${entityPackage}.entity; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecg.common.aspect.annotation.Dict; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Data +@TableName("${tableName}") +@Schema(description="${tableVo.ftlDescription}") +public class ${entityName} implements Serializable { + private static final long serialVersionUID = 1L; + + <#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']> + <#assign excel_ignore_classType_arr=['pca','switch','cat_tree']> + <#list originalColumns as po> + <#-- 生成字典Code --> + <#assign list_field_dictCode=""> + <#if po.classType='sel_user'> + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> + <#elseif po.classType='sel_depart'> + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> + <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dicCode = "${po.dictField}"'> + + <#elseif po.classType=='sel_tree'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'> + <#elseif po.classType=='link_table'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicCode = "${po.dictField}", dicText = "${po.dictText?split(",")[0]}"'> + + /**${po.filedComment}*/ + <#if po.fieldName == primaryKeyField> + @TableId(type = IdType.ASSIGN_ID) + <#else> + <#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'> + <#if po.classType=='date'> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + + + <#if list_field_dictCode?length gt 1> + @Dict(${list_field_dictCode?substring(2)}) + + + <#include "/common/blob.ftl"> + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai new file mode 100644 index 00000000..2108b249 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai @@ -0,0 +1,86 @@ +<#include "/common/utils.ftl"> +<#list subTables as subTab> +#segment#${subTab.entityName}.java +package ${bussiPackage}.${entityPackage}.entity; + +import java.io.Serializable; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import org.jeecg.common.aspect.annotation.Dict; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import java.util.Date; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.UnsupportedEncodingException; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Data +@TableName("${subTab.tableName}") +@Schema(description="${subTab.ftlDescription}") +public class ${subTab.entityName} implements Serializable { + private static final long serialVersionUID = 1L; + + <#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']> + <#assign excel_ignore_classType_arr=['pca','switch','cat_tree']> +<#list subTab.originalColumns as po> + <#-- 生成字典Code --> + <#assign list_field_dictCode=""> + <#if po.classType='sel_user'> + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> + <#elseif po.classType='sel_depart'> + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> + <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dicCode = "${po.dictField}"'> + <#elseif po.classType=='sel_tree'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'> + + <#elseif po.classType=='link_table'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicCode = "${po.dictField}", dicText = "${po.dictText?split(",")[0]}"'> + + /**${po.filedComment}*/ +<#if po.fieldName == primaryKeyField> + @TableId(type = IdType.ASSIGN_ID) +<#else> + <#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'> + <#if po.classType=='date'> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + + <#elseif !subTab.foreignKeys?seq_contains(po.fieldName?cap_first)> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + + + + <#if list_field_dictCode?length gt 1> + @Dict(${list_field_dictCode?substring(2)}) + + <#-- 大字段转换 --> + <#include "/common/blob.ftl"> + +} + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai new file mode 100644 index 00000000..c31b9bfd --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai @@ -0,0 +1,17 @@ +package ${bussiPackage}.${entityPackage}.mapper; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface ${entityName}Mapper extends BaseMapper<${entityName}> { + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/mapper/[1-n]Mapper.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/mapper/[1-n]Mapper.javai new file mode 100644 index 00000000..6b6736d0 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/mapper/[1-n]Mapper.javai @@ -0,0 +1,35 @@ +<#list subTables as subTab> +#segment#${subTab.entityName}Mapper.java +package ${bussiPackage}.${entityPackage}.mapper; + +import java.util.List; +import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName}; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface ${subTab.entityName}Mapper extends BaseMapper<${subTab.entityName}> { + + /** + * 通过主表id删除子表数据 + * + * @param mainId 主表id + * @return boolean + */ + public boolean deleteByMainId(@Param("mainId") String mainId); + + /** + * 通过主表id查询子表数据 + * + * @param mainId 主表id + * @return List<${subTab.entityName}> + */ + public List<${subTab.entityName}> selectByMainId(@Param("mainId") String mainId); + +} + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml new file mode 100644 index 00000000..16f3d653 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/[1-n]Mapper.xml b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/[1-n]Mapper.xml new file mode 100644 index 00000000..1dc58027 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/[1-n]Mapper.xml @@ -0,0 +1,28 @@ +<#list subTables as subTab> +<#assign originalForeignKeys = subTab.originalForeignKeys> +#segment#${subTab.entityName}Mapper.xml + + + + + + DELETE + FROM ${subTab.tableName} + WHERE + <#list originalForeignKeys as key> + ${key} = ${r'#'}{mainId} <#rt/> + + + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai new file mode 100644 index 00000000..e22b54c5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai @@ -0,0 +1,36 @@ +package ${bussiPackage}.${entityPackage}.service; + +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import com.baomidou.mybatisplus.extension.service.IService; +import org.springframework.beans.factory.annotation.Autowired; +import java.io.Serializable; +import java.util.Collection; +import java.util.List; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface I${entityName}Service extends IService<${entityName}> { + + /** + * 删除一对多 + * + * @param id + */ + public void delMain (String id); + + /** + * 批量删除一对多 + * + * @param idList + */ + public void delBatchMain (Collection idList); + + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/service/[1-n]Service.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/service/[1-n]Service.javai new file mode 100644 index 00000000..74ad5a72 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/service/[1-n]Service.javai @@ -0,0 +1,25 @@ +<#list subTables as subTab> +#segment#I${subTab.entityName}Service.java +package ${bussiPackage}.${entityPackage}.service; + +import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName}; +import com.baomidou.mybatisplus.extension.service.IService; +import java.util.List; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface I${subTab.entityName}Service extends IService<${subTab.entityName}> { + + /** + * 通过主表id查询子表数据 + * + * @param mainId + * @return List<${subTab.entityName}> + */ + public List<${subTab.entityName}> selectByMainId(String mainId); +} + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai new file mode 100644 index 00000000..a98cfee6 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai @@ -0,0 +1,56 @@ +package ${bussiPackage}.${entityPackage}.service.impl; + +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.mapper.${sub.entityName}Mapper; + +import ${bussiPackage}.${entityPackage}.mapper.${entityName}Mapper; +import ${bussiPackage}.${entityPackage}.service.I${entityName}Service; +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import java.io.Serializable; +import java.util.List; +import java.util.Collection; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Service +public class ${entityName}ServiceImpl extends ServiceImpl<${entityName}Mapper, ${entityName}> implements I${entityName}Service { + + @Autowired + private ${entityName}Mapper ${entityName?uncap_first}Mapper; + <#list subTables as sub> + @Autowired + private ${sub.entityName}Mapper ${sub.entityName?uncap_first}Mapper; + + + @Override + @Transactional(rollbackFor = Exception.class) + public void delMain(String id) { + <#list subTables as sub> + ${sub.entityName?uncap_first}Mapper.deleteByMainId(id); + + ${entityName?uncap_first}Mapper.deleteById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delBatchMain(Collection idList) { + for(Serializable id:idList) { + <#list subTables as sub> + ${sub.entityName?uncap_first}Mapper.deleteByMainId(id.toString()); + + ${entityName?uncap_first}Mapper.deleteById(id); + } + } + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/[1-n]ServiceImpl.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/[1-n]ServiceImpl.javai new file mode 100644 index 00000000..0ce41d36 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/[1-n]ServiceImpl.javai @@ -0,0 +1,30 @@ +<#list subTables as subTab> +#segment#${subTab.entityName}ServiceImpl.java +package ${bussiPackage}.${entityPackage}.service.impl; + +import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName}; +import ${bussiPackage}.${entityPackage}.mapper.${subTab.entityName}Mapper; +import ${bussiPackage}.${entityPackage}.service.I${subTab.entityName}Service; +import org.springframework.stereotype.Service; +import java.util.List; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Service +public class ${subTab.entityName}ServiceImpl extends ServiceImpl<${subTab.entityName}Mapper, ${subTab.entityName}> implements I${subTab.entityName}Service { + + @Autowired + private ${subTab.entityName}Mapper ${subTab.entityName?uncap_first}Mapper; + + @Override + public List<${subTab.entityName}> selectByMainId(String mainId) { + return ${subTab.entityName?uncap_first}Mapper.selectByMainId(mainId); + } +} + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei new file mode 100644 index 00000000..9d2cbbb5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei @@ -0,0 +1,457 @@ +<#include "/common/utils.ftl"> + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql new file mode 100644 index 00000000..5396d5d5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql @@ -0,0 +1 @@ +<#include "/common/sql/menu_insert.ftl"> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/[1-n]List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/[1-n]List.vuei new file mode 100644 index 00000000..dae14454 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/[1-n]List.vuei @@ -0,0 +1,327 @@ +<#list subTables as sub> +#segment#${sub.entityName}List.vue + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei new file mode 100644 index 00000000..f20d9887 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei @@ -0,0 +1,212 @@ +<#include "/common/utils.ftl"> + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Modal.vuei new file mode 100644 index 00000000..f5e31a97 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Modal.vuei @@ -0,0 +1,208 @@ +<#include "/common/utils.ftl"> +<#list subTables as sub> +#segment#${sub.entityName}Modal.vue + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei new file mode 100644 index 00000000..a3d1c2b0 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei @@ -0,0 +1,473 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi new file mode 100644 index 00000000..c1300749 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi @@ -0,0 +1,133 @@ +import {defHttp} from '/@/utils/http/axios'; +import { useMessage } from "/@/hooks/web/useMessage"; + +const { createConfirm } = useMessage(); + +enum Api { + list = '/${entityPackagePath}/${entityName?uncap_first}/list', + save='/${entityPackagePath}/${entityName?uncap_first}/add', + edit='/${entityPackagePath}/${entityName?uncap_first}/edit', + deleteOne = '/${entityPackagePath}/${entityName?uncap_first}/delete', + deleteBatch = '/${entityPackagePath}/${entityName?uncap_first}/deleteBatch', + importExcel = '/${entityPackagePath}/${entityName?uncap_first}/importExcel', + exportXls = '/${entityPackagePath}/${entityName?uncap_first}/exportXls', +<#list subTables as sub><#rt/> + ${sub.entityName?uncap_first}List = '/${entityPackagePath}/${entityName?uncap_first}/list${sub.entityName}ByMainId', + ${sub.entityName?uncap_first}Save='/${entityPackagePath}/${entityName?uncap_first}/add${sub.entityName}', + ${sub.entityName?uncap_first}Edit='/${entityPackagePath}/${entityName?uncap_first}/edit${sub.entityName}', + ${sub.entityName?uncap_first}Delete = '/${entityPackagePath}/${entityName?uncap_first}/delete${sub.entityName}', + ${sub.entityName?uncap_first}DeleteBatch = '/${entityPackagePath}/${entityName?uncap_first}/deleteBatch${sub.entityName}', + +} +/** + * 导出api + * @param params + */ +export const getExportUrl = Api.exportXls; + +/** + * 导入api + */ +export const getImportUrl = Api.importExcel; +/** + * 列表接口 + * @param params + */ +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(); + }); +} +/** + * 批量删除 + * @param params + */ +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(); + }); + } + }); +} +/** + * 保存或者更新 + * @param params + */ +export const saveOrUpdate = (params, isUpdate) => { + let url = isUpdate ? Api.edit : Api.save; + return defHttp.post({url: url, params}); +} +<#list subTables as sub><#rt/> + <#assign myForeignKeys=''> + <#list sub.foreignKeys as key> + <#assign myForeignKeys='${key?uncap_first}'> + +/** + * 列表接口 + * @param params + */ +export const ${sub.entityName?uncap_first}List = (params) => { + if(params['${myForeignKeys}']){ + return defHttp.get({url: Api.${sub.entityName?uncap_first}List, params}); + } + return Promise.resolve({}); +} + + +/** + * 删除单个 + */ +export const ${sub.entityName?uncap_first}Delete = (params,handleSuccess) => { + return defHttp.delete({url: Api.${sub.entityName?uncap_first}Delete, params}, {joinParamsToUrl: true}).then(() => { + handleSuccess(); + }); +} +/** + * 批量删除 + * @param params + */ +export const ${sub.entityName?uncap_first}DeleteBatch = (params, handleSuccess) => { + createConfirm({ + iconType: 'warning', + title: '确认删除', + content: '是否删除选中数据', + okText: '确认', + cancelText: '取消', + onOk: () => { + return defHttp.delete({url: Api.${sub.entityName?uncap_first}DeleteBatch, data: params}, {joinParamsToUrl: true}).then(() => { + handleSuccess(); + }); + } + }); +} +/** + * 保存或者更新 + * @param params + */ +export const ${sub.entityName?uncap_first}SaveOrUpdate = (params, isUpdate) => { + let url = isUpdate ? Api.${sub.entityName?uncap_first}Edit : Api.${sub.entityName?uncap_first}Save; + return defHttp.post({url: url, params}); +} +/** + * 导入 + */ +export const ${sub.entityName?uncap_first}ImportUrl = '/${entityPackagePath}/${entityName?uncap_first}/import${sub.entityName}' + +/** + * 导出 + */ +export const ${sub.entityName?uncap_first}ExportXlsUrl = '/${entityPackagePath}/${entityName?uncap_first}/export${sub.entityName}' + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi new file mode 100644 index 00000000..25b8e2ac --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi @@ -0,0 +1,850 @@ +<#include "/common/utils.ftl"> +import {BasicColumn} from '/@/components/Table'; +import {FormSchema} from '/@/components/Table'; +import { rules} from '/@/utils/helper/validator'; +import { render } from '/@/utils/common/renderUtils'; +import { getWeekMonthQuarterYear } from '/@/utils'; +//列表数据 +export const columns: BasicColumn[] = [ + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + { + title: '${po.filedComment}', + align:"center", + <#if po.sort=='Y'> + sorter: true, + + <#if po.classType=='date'> + dataIndex: '${po.fieldName}', + customRender:({text}) =>{ + text = !text ? "" : (text.length > 10 ? text.substr(0,10) : text); + <#if po.extendParams?exists && po.extendParams.picker?exists> + if(text) { + return getWeekMonthQuarterYear(text)['${po.extendParams.picker}']; + } else { + return text; + } + <#else> + return text; + + }, + <#elseif po.fieldDbType=='Blob'> + dataIndex: '${po.fieldName}String' + <#elseif po.classType=='umeditor'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='pca'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='file'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='image'> + dataIndex: '${po.fieldName}', + customRender:render.renderImage, + <#elseif po.classType=='switch'> + dataIndex: '${po.fieldName}', +<#assign switch_extend_arr=['Y','N']> +<#if po.dictField?default("")?contains("[")> +<#assign switch_extend_arr=po.dictField?eval> + +<#list switch_extend_arr as a> +<#if a_index == 0> +<#assign switch_extend_arr1=a> +<#else> +<#assign switch_extend_arr2=a> + + + customRender:({text}) => { + return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]) + }, + <#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user' || po.classType=='popup_dict' || po.classType=='link_table'> + dataIndex: '${po.fieldName}_dictText' + <#elseif po.classType=='cat_tree'> + dataIndex: '${po.fieldName}', + <#if po.dictText?default("")?trim?length == 0> + customRender:({text}) => { + return render.renderCategoryTree(text,'${po.dictField?default("")}') + }, + <#else> + customRender: (text, record) => (text ? record['${po.dictText}'] : '') + + <#else> + dataIndex: '${po.fieldName}' + + }, + + +]; +//查询数据 +export const searchFormSchema: FormSchema[] = [ +<#-- 开始循环 --> +<#list columns as po> +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if po.isQuery=='Y' && po.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#assign query_flag=true> + <#assign query_field_dictCode=""> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign query_field_dictCode="${po.dictField}"> + +<#if po.queryMode=='single'> + { + label: "${po.filedComment}", + field: "${po.fieldName}", +<#if po.classType=='sel_search'> + component: 'JSearchSelect', + componentProps:{ + dict:"${query_field_dictCode}" + }, +<#elseif po.classType=='sel_user'> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + component: 'JSelectUser', +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, +<#elseif po.classType=='switch'> + component: 'JSwitch', + componentProps:{ + query:true, + <#if po.dictField != 'is_open'> + options:${po.dictField} + + }, + <#elseif po.classType=='sel_depart'> + component: 'JSelectDept', + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType=='list_multi'> + component: 'JSelectMultiple', + componentProps:{ + <#if po.dictTable?default("")?trim?length gt 1> + dictCode:"${po.dictTable},${po.dictText},${po.dictField}", + <#elseif po.dictField?default("")?trim?length gt 1> + dictCode:"${po.dictField}", + + triggerChange: true + }, + <#elseif po.classType=='cat_tree'> + component: 'JCategorySelect', + componentProps:{ + pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题 + }, +<#elseif po.classType=='date'> + component: 'DatePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueFormat: 'YYYY-MM-DD' + }, +<#elseif po.classType=='datetime'> + component: 'DatePicker', + componentProps: { + showTime:true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, +<#elseif po.classType=='pca'> + component: 'JAreaLinkage', + componentProps: { + saveCode: 'region', + }, +<#elseif po.classType=='popup'> + <#include "/common/form/vue3popup.ftl"> +<#elseif po.classType=='popup_dict'> + component: 'JPopupDict', + componentProps: { + placeholder: '请选择${po.filedComment}', + dictCode: '${po.dictTable},${po.dictText},${po.dictField}', + multi: ${po.extendParams.popupMulti?c} + }, +<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'> +<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- --> + component: 'JSelectMultiple', + componentProps:{ + <#if po.dictTable?default("")?trim?length gt 1> + dictCode:"${po.dictTable},${po.dictText},${po.dictField}" + <#elseif po.dictField?default("")?trim?length gt 1> + dictCode:"${po.dictField}" + + }, +<#elseif po.classType == 'sel_tree'> + component: 'JTreeSelect', + componentProps:{ + <#if po.dictText??> + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", + <#elseif po.dictText?split(',')[1]??> + pidField:"${po.dictText?split(',')[1]}", + <#elseif po.dictText?split(',')[3]??> + hasChildField:"${po.dictText?split(',')[3]}", + + + pidValue:"${po.dictField}", + }, +<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'InputNumber', +<#else> + component: 'Input', + + //colProps: {span: 6}, + }, +<#elseif po.queryMode=='like'> + { + label: "${po.filedComment}", + field: "${po.fieldName}", + component: 'JInput', + }, +<#else> + { + label: "${po.filedComment}", + field: "${po.fieldName}", +<#if po.classType=='date'> + component: 'RangePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueType: 'Date', + }, +<#elseif po.classType=='datetime'> + component: 'RangePicker', + componentProps: { + valueType: 'Date', + showTime:true + }, +<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'JRangeNumber', +<#-- update-begin---author:chenrui ---date:20240527 for:[TV360X-388]时间范围查询控件---------- --> +<#elseif po.classType=='time'> + component: 'RangeTime', +<#-- update-end---author:chenrui ---date:20240527 for:[TV360X-388]时间范围查询控件---------- --> +<#else> + component: 'Input', //TODO 范围查询 + + //colProps: {span: 6}, + }, + + + +<#-- 结束循环 --> +]; + +//表单数据 +export const formSchema: FormSchema[] = [ +<#assign form_cat_tree = false> +<#assign form_cat_back = ""> +<#assign bpm_flag=false> +<#assign id_exists = false> +<#list columns as po><#rt/> +<#if po.fieldDbName=='bpm_status'> + <#assign bpm_flag=true> + +<#if po.fieldDbName == 'id'> + <#assign id_exists = true> + +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if po.isShow =='Y' && po.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#assign form_field_dictCode=""> + <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictField}"> + + { + label: '${po.filedComment}', + field: ${autoStringSuffix(po)}, +<#-- update-begin-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.defaultVal??> + <#if po.fieldDbType=="BigDecimal" || po.fieldDbType=="double" || po.fieldDbType=="int"> + defaultValue: ${po.defaultVal}, + <#else> + defaultValue: "${po.defaultVal}", + + +<#-- update-end-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.classType =='date'> + component: 'DatePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueFormat: 'YYYY-MM-DD' + }, + <#elseif po.classType =='datetime'> + component: 'DatePicker', + componentProps: { + showTime:true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, + <#elseif po.classType =='time'> + component: 'TimePicker', + componentProps: { + valueFormat: 'HH:mm:ss' + }, + <#elseif po.classType =='popup'> + <#include "/common/form/vue3popup.ftl"> + <#elseif po.classType=='popup_dict'> + component: 'JPopupDict', + componentProps: { + placeholder: '请选择${po.filedComment}', + dictCode: '${po.dictTable},${po.dictText},${po.dictField}', + multi: ${po.extendParams.popupMulti?c} + }, + <#elseif po.classType =='sel_depart'> + component: 'JSelectDept', + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='switch'> + component: 'JSwitch', + componentProps:{ + <#if po.dictField != 'is_open'> + options:${po.dictField} + + }, + <#elseif po.classType =='pca'> + component: 'JAreaLinkage', + componentProps: { + saveCode: 'region', + }, + <#elseif po.classType =='markdown'> + component: 'JMarkdownEditor',//注意string转换问题 + <#elseif po.classType =='password'> + component: 'InputPassword', + <#elseif po.classType =='sel_user'> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + component: 'JSelectUser', +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + <#else> + labelKey:'realname', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='textarea'> + component: 'InputTextArea',//TODO 注意string转换问题 + <#elseif po.classType=='list'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#elseif po.classType=='radio'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + type: "radio", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='list_multi'> + component: 'JSelectMultiple', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#elseif po.classType=='checkbox'> + component: 'JCheckbox', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='sel_search'> + component: 'JSearchSelect', + componentProps:{ + dict:"${form_field_dictCode}" + }, +<#elseif po.classType=='cat_tree'> + <#assign form_cat_tree = true> + component: 'JCategorySelect', + componentProps:{ + pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题 + }, + <#if po.dictText?default("")?trim?length gt 1> + <#assign form_cat_back = "${po.dictText}"> + + <#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'InputNumber', + <#elseif po.classType=='file'> + component: 'JUpload', + componentProps:{ + <#if po.uploadnum??> + maxCount:${po.uploadnum} + + }, + <#elseif po.classType=='image'> + component: 'JImageUpload', + componentProps:{ + <#if po.uploadnum??> + fileMax:${po.uploadnum} + <#else> + fileMax: 0 + + }, + <#elseif po.classType=='umeditor'> + component: 'JEditor', + <#elseif po.classType == 'sel_tree'> + component: 'JTreeSelect', + componentProps:{ + <#if po.dictText??> + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", + <#elseif po.dictText?split(',')[1]??> + pidField:"${po.dictText?split(',')[1]}", + <#elseif po.dictText?split(',')[3]??> + hasChildField:"${po.dictText?split(',')[3]}", + + + pidValue:"${po.dictField}", + }, + <#elseif po.classType=='link_table'> + component: 'JLinkTableCard', + componentProps: { + valueField: '${po.dictField}', + textField: '${po.dictText}', + tableName: '${po.dictTable}', + multi: <#if (po.queryMode!"") == "multi">true<#else>false + }, + <#else> + component: 'Input', + + <#include "/common/utils.ftl"> + <#if po.isShow == 'Y' && poHasCheck(po)> + dynamicRules: ({model,schema}) => { + <#if po.fieldName != 'id'> + <#assign fieldValidType = po.fieldValidType!''> + return [ + <#-- 非空校验 --> + <#if po.nullable == 'N' || fieldValidType == '*'> + { required: true, message: '请输入${po.filedComment}!'}, + <#elseif fieldValidType!=''> + { required: false}, + + <#-- 唯一校验 --> + <#if fieldValidType == 'only'> + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}', '${po.fieldDbName}',model,schema)[0]}, + <#-- 6到16位数字 --> + <#elseif fieldValidType == 'n6-16'> + { pattern: /^\d{6,16}$|^(?=\d+\.\d+)[\d.]{7,17}$/, message: '请输入6到16位数字!'}, + <#-- 6到16位任意字符 --> + <#elseif fieldValidType == '*6-16'> + { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, + <#-- 6到18位字母 --> + <#elseif fieldValidType == 's6-18'> + { pattern:/^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, + <#-- 网址 --> + <#elseif fieldValidType == 'url'> + { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, + <#-- 电子邮件 --> + <#elseif fieldValidType == 'e'> + { pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'}, + <#-- 手机号码 --> + <#elseif fieldValidType == 'm'> + { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}, + <#-- 邮政编码 --> + <#elseif fieldValidType == 'p'> + { pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'}, + <#-- 字母 --> + <#elseif fieldValidType == 's'> + { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}, + <#-- 数字 --> + <#elseif fieldValidType == 'n'> + { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'}, + <#-- 整数 --> + <#elseif fieldValidType == 'z'> + { pattern: /^-?\d+$/, message: '请输入整数!'}, + <#-- 金额 --> + <#elseif fieldValidType == 'money'> + { pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'}, + <#-- 正则校验 --> + <#elseif fieldValidType != '' && fieldValidType != '*'> + { pattern: '${fieldValidType}', message: '不符合校验规则!'}, + <#-- 无校验 --> + <#else> + <#t> + + ]; + + }, + + <#if po.readonly=='Y'> + dynamicDisabled:true, + + }, + + +<#if id_exists == false> + // TODO 主键隐藏字段,目前写死为ID + { + label: '', + field: 'id', + component: 'Input', + show: false + }, + +]; + +<#list subTables as sub> +//子表列表数据 +export const ${sub.entityName?uncap_first}Columns: BasicColumn[] = [ + <#list sub.originalColumns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + { + title: '${po.filedComment}', + align:"center", + <#if po.sort=='Y'> + sorter: true, + + <#if po.classType=='date'> + dataIndex: '${po.fieldName}', + customRender:({text}) =>{ + text = !text ? "" : (text.length > 10 ? text.substr(0,10) : text); + <#if po.extendParams?exists && po.extendParams.picker?exists> + if(text) { + return getWeekMonthQuarterYear(text)['${po.extendParams.picker}']; + } else { + return text; + } + <#else> + return text; + + }, + <#elseif po.fieldDbType=='Blob'> + dataIndex: '${po.fieldName}String' + <#elseif po.classType=='umeditor'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='pca'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='file'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='image'> + dataIndex: '${po.fieldName}', + customRender:render.renderImage, + <#elseif po.classType=='switch'> + dataIndex: '${po.fieldName}', +<#assign switch_extend_arr=['Y','N']> +<#if po.dictField?default("")?contains("[")> +<#assign switch_extend_arr=po.dictField?eval> + +<#list switch_extend_arr as a> +<#if a_index == 0> +<#assign switch_extend_arr1=a> +<#else> +<#assign switch_extend_arr2=a> + + + customRender:({text}) => { + return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]) + }, + <#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user' || po.classType=='link_table'> + dataIndex: '${po.fieldName}_dictText' + <#elseif po.classType=='cat_tree'> + dataIndex: '${po.fieldName}', + <#if po.dictText?default("")?trim?length == 0> + customRender:({text}) => { + return render.renderCategoryTree(text,'${po.dictField?default("")}') + }, + <#else> + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') + + <#else> + dataIndex: '${po.fieldName}' + + }, + + +]; +//子表表单数据 +export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ +<#assign form_cat_tree = false> +<#assign form_cat_back = ""> +<#assign bpm_flag=false> +<#list sub.originalColumns as po><#rt/> +<#if po.fieldName == 'id'> + // TODO 子表隐藏字段,目前写死为ID + { + label: '', + field: 'id', + component: 'Input', + show: false + }, + +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if po.isShow =='Y' && po.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#assign form_field_dictCode=""> + <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictField}"> + + { + label: '${po.filedComment}', + field: ${autoStringSuffix(po)}, +<#-- update-begin-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.defaultVal??> + <#if po.fieldDbType=="BigDecimal" || po.fieldDbType=="double" || po.fieldDbType=="int"> + defaultValue: ${po.defaultVal}, + <#else> + defaultValue: "${po.defaultVal}", + + +<#-- update-end-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.classType =='date'> + component: 'DatePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueFormat: 'YYYY-MM-DD' + }, + <#elseif po.classType =='datetime'> + component: 'DatePicker', + componentProps: { + showTime:true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, + <#elseif po.classType =='time'> + component: 'TimePicker', + componentProps: { + valueFormat: 'HH:mm:ss' + }, + <#elseif po.classType =='popup'> + <#include "/common/form/vue3popup.ftl"> + <#elseif po.classType=='popup_dict'> + component: 'JPopupDict', + componentProps: { + placeholder: '请选择${po.filedComment}', + dictCode: '${po.dictTable},${po.dictText},${po.dictField}', + multi: ${po.extendParams.popupMulti?c} + }, + <#elseif po.classType =='sel_depart'> + component: 'JSelectDept', + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='switch'> + component: 'JSwitch', + componentProps:{ + <#if po.dictField != 'is_open'> + options:${po.dictField} + + }, + <#elseif po.classType =='pca'> + component: 'JAreaLinkage', + componentProps: { + saveCode: 'region', + }, + <#elseif po.classType =='markdown'> + component: 'JMarkdownEditor',//注意string转换问题 + <#elseif po.classType =='password'> + component: 'InputPassword', + <#elseif po.classType =='sel_user'> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + component: 'JSelectUser', +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + <#else> + labelKey:'realname', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='textarea'> + component: 'InputTextArea', + <#elseif po.classType=='list' || po.classType=='radio'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='list_multi'> + component: 'JSelectMultiple', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#elseif po.classType=='checkbox'> + component: 'JCheckbox', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='sel_search'> + component: 'JSearchSelect', + componentProps:{ + dict:"${form_field_dictCode}" + }, +<#elseif po.classType=='cat_tree'> + <#assign form_cat_tree = true> + component: 'JCategorySelect', + componentProps:{ + pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题 + }, + <#if po.dictText?default("")?trim?length gt 1> + <#assign form_cat_back = "${po.dictText}"> + + <#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'InputNumber', + <#elseif po.classType=='file'> + component: 'JUpload', + componentProps:{ + <#if po.uploadnum??> + maxCount:${po.uploadnum} + + }, + <#elseif po.classType=='image'> + component: 'JImageUpload', + componentProps:{ + <#if po.uploadnum??> + fileMax:${po.uploadnum} + <#else> + fileMax: 0 + + }, + <#elseif po.classType=='umeditor'> + component: 'JEditor', + <#elseif po.classType == 'sel_tree'> + component: 'JTreeSelect', + componentProps:{ + <#if po.dictText??> + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", + <#elseif po.dictText?split(',')[1]??> + pidField:"${po.dictText?split(',')[1]}", + <#elseif po.dictText?split(',')[3]??> + hasChildField:"${po.dictText?split(',')[3]}", + + + pidValue:"${po.dictField}", + }, + <#elseif po.classType=='link_table'> + component: 'JLinkTableCard', + componentProps: { + valueField: '${po.dictField}', + textField: '${po.dictText}', + tableName: '${po.dictTable}', + multi: <#if (po.queryMode!"") == "multi">true<#else>false + }, + <#else> + component: 'Input', + + <#include "/common/utils.ftl"> + <#if po.isShow == 'Y' && poHasCheck(po)> + dynamicRules: ({model,schema}) => { + <#if po.fieldName != 'id'> + <#assign fieldValidType = po.fieldValidType!''> + return [ + <#-- 非空校验 --> + <#if po.nullable == 'N' || fieldValidType == '*'> + { required: true, message: '请输入${po.filedComment}!'}, + <#elseif fieldValidType!=''> + { required: false}, + + <#-- 唯一校验 --> + <#if fieldValidType == 'only'> + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}', '${po.fieldDbName}',model,schema)[0]}, + <#-- 6到16位数字 --> + <#elseif fieldValidType == 'n6-16'> + { pattern: /^\d{6,16}$|^(?=\d+\.\d+)[\d.]{7,17}$/, message: '请输入6到16位数字!'}, + <#-- 6到16位任意字符 --> + <#elseif fieldValidType == '*6-16'> + { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, + <#-- 6到18位字母 --> + <#elseif fieldValidType == 's6-18'> + { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, + <#-- 网址 --> + <#elseif fieldValidType == 'url'> + { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, + <#-- 电子邮件 --> + <#elseif fieldValidType == 'e'> + { pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'}, + <#-- 手机号码 --> + <#elseif fieldValidType == 'm'> + { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}, + <#-- 邮政编码 --> + <#elseif fieldValidType == 'p'> + { pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'}, + <#-- 字母 --> + <#elseif fieldValidType == 's'> + { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}, + <#-- 数字 --> + <#elseif fieldValidType == 'n'> + { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'}, + <#-- 整数 --> + <#elseif fieldValidType == 'z'> + { pattern: /^-?\d+$/, message: '请输入整数!'}, + <#-- 金额 --> + <#elseif fieldValidType == 'money'> + { pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'}, + <#-- 正则校验 --> + <#elseif fieldValidType != '' && fieldValidType != '*'> + { pattern: '${fieldValidType}', message: '不符合校验规则!'}, + <#-- 无校验 --> + <#else> + <#t> + + ]; + + }, + + <#if po.readonly=='Y'> + dynamicDisabled:true, + + }, + + +]; + + +<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> +// 高级查询数据 +export const superQuerySchema = { + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + ${superQueryFieldListForVue3(po,po_index)}, + + +}; +<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql new file mode 100644 index 00000000..5396d5d5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql @@ -0,0 +1 @@ +<#include "/common/sql/menu_insert.ftl"> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/[1-n]List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/[1-n]List.vuei new file mode 100644 index 00000000..d882ad56 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/[1-n]List.vuei @@ -0,0 +1,189 @@ +<#list subTables as sub> +#segment#${sub.entityName}List.vue + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei new file mode 100644 index 00000000..54e87d06 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei @@ -0,0 +1,129 @@ +<#include "/common/utils.ftl"> + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Modal.vuei new file mode 100644 index 00000000..526b1821 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Modal.vuei @@ -0,0 +1,114 @@ +<#include "/common/utils.ftl"> +<#list subTables as sub> +#segment#${sub.entityName}Modal.vue + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei new file mode 100644 index 00000000..09c1a614 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei @@ -0,0 +1,613 @@ +<#include "/common/utils.ftl"> + + +<#if query_flag> + + + + 查询 + 重置 + + {{ toggleSearchStatus ? '收起' : '展开' }} + + + + + + + + + +<#-- 结束循环 --> +
+ + + + + + + + + + + + <#assign sub_seq=1> + <#list subTables as sub> + forceRender> + <${sub.entityName}List /> + + <#assign sub_seq=sub_seq+1> + + +
+ + <${entityName}Modal ref="registerModal" @success="handleSuccess" /> + <#if bpm_flag==true> + + + + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi new file mode 100644 index 00000000..e40d27c8 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi @@ -0,0 +1,139 @@ +import {defHttp} from '/@/utils/http/axios'; +import { useMessage } from "/@/hooks/web/useMessage"; + +const { createConfirm } = useMessage(); + +enum Api { + list = '/${entityPackagePath}/${entityName?uncap_first}/list', + save= '/${entityPackagePath}/${entityName?uncap_first}/add', + edit= '/${entityPackagePath}/${entityName?uncap_first}/edit', + deleteOne = '/${entityPackagePath}/${entityName?uncap_first}/delete', + deleteBatch = '/${entityPackagePath}/${entityName?uncap_first}/deleteBatch', + importExcel = '/${entityPackagePath}/${entityName?uncap_first}/importExcel', + exportXls = '/${entityPackagePath}/${entityName?uncap_first}/exportXls', +<#list subTables as sub><#rt/> + ${sub.entityName?uncap_first}List = '/${entityPackagePath}/${entityName?uncap_first}/list${sub.entityName}ByMainId', + ${sub.entityName?uncap_first}Save= '/${entityPackagePath}/${entityName?uncap_first}/add${sub.entityName}', + ${sub.entityName?uncap_first}Edit= '/${entityPackagePath}/${entityName?uncap_first}/edit${sub.entityName}', + ${sub.entityName?uncap_first}Delete = '/${entityPackagePath}/${entityName?uncap_first}/delete${sub.entityName}', + ${sub.entityName?uncap_first}DeleteBatch = '/${entityPackagePath}/${entityName?uncap_first}/deleteBatch${sub.entityName}', + +} +/** + * 导出api + * @param params + */ +export const getExportUrl = Api.exportXls; + +/** + * 导入api + */ +export const getImportUrl = Api.importExcel; + +/** + * 列表接口 + * @param params + */ +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(); + }); +} + +/** + * 批量删除 + * @param params + */ +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(); + }); + } + }); +} + +/** + * 保存或者更新 + * @param params + */ +export const saveOrUpdate = (params, isUpdate) => { + let url = isUpdate ? Api.edit : Api.save; + return defHttp.post({ url: url, params },{ isTransformResponse: false }); +} +<#list subTables as sub><#rt/> + <#assign myForeignKeys=''> + <#list sub.foreignKeys as key> + <#assign myForeignKeys='${key?uncap_first}'> + + +/** + * 列表接口 + * @param params + */ +export const ${sub.entityName?uncap_first}List = (params) => { + if(params['${myForeignKeys}']){ + return defHttp.get({ url: Api.${sub.entityName?uncap_first}List, params }); + } + return Promise.resolve({}); +} + +/** + * 删除单个 + */ +export const ${sub.entityName?uncap_first}Delete = (params,handleSuccess) => { + return defHttp.delete({ url: Api.${sub.entityName?uncap_first}Delete, params }, { joinParamsToUrl: true }).then(() => { + handleSuccess(); + }); +} + +/** + * 批量删除 + * @param params + */ +export const ${sub.entityName?uncap_first}DeleteBatch = (params, handleSuccess) => { + createConfirm({ + iconType: 'warning', + title: '确认删除', + content: '是否删除选中数据', + okText: '确认', + cancelText: '取消', + onOk: () => { + return defHttp.delete({ url: Api.${sub.entityName?uncap_first}DeleteBatch, data: params }, { joinParamsToUrl: true }).then(() => { + handleSuccess(); + }); + } + }); +} + +/** + * 保存或者更新 + * @param params + */ +export const ${sub.entityName?uncap_first}SaveOrUpdate = (params, isUpdate) => { + let url = isUpdate ? Api.${sub.entityName?uncap_first}Edit : Api.${sub.entityName?uncap_first}Save; + return defHttp.post({ url: url, params },{ isTransformResponse: false }); +} + +/** + * 导入 + */ +export const ${sub.entityName?uncap_first}ImportUrl = '/${entityPackagePath}/${entityName?uncap_first}/import${sub.entityName}' + +/** + * 导出 + */ +export const ${sub.entityName?uncap_first}ExportXlsUrl = '/${entityPackagePath}/${entityName?uncap_first}/export${sub.entityName}' + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi new file mode 100644 index 00000000..bd01e278 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi @@ -0,0 +1,155 @@ +<#include "/common/utils.ftl"> +import {BasicColumn} from '/@/components/Table'; +import {FormSchema} from '/@/components/Table'; +import { rules} from '/@/utils/helper/validator'; +import { render } from '/@/utils/common/renderUtils'; +import { getWeekMonthQuarterYear } from '/@/utils'; +//列表数据 +export const columns: BasicColumn[] = [ + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + { + title: '${po.filedComment}', + align:"center", + <#if po.sort=='Y'> + sorter: true, + + <#if po.classType=='date'> + dataIndex: '${po.fieldName}', + customRender:({text}) =>{ + text = !text ? "" : (text.length > 10 ? text.substr(0,10) : text); + <#if po.extendParams?exists && po.extendParams.picker?exists> + if(text) { + return getWeekMonthQuarterYear(text)['${po.extendParams.picker}']; + } else { + return text; + } + <#else> + return text; + + }, + <#elseif po.fieldDbType=='Blob'> + dataIndex: '${po.fieldName}String' + <#elseif po.classType=='umeditor'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='pca'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='file'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='image'> + dataIndex: '${po.fieldName}', + customRender:render.renderImage, + <#elseif po.classType=='switch'> + dataIndex: '${po.fieldName}', +<#assign switch_extend_arr=['Y','N']> +<#if po.dictField?default("")?contains("[")> +<#assign switch_extend_arr=po.dictField?eval> + +<#list switch_extend_arr as a> +<#if a_index == 0> +<#assign switch_extend_arr1=a> +<#else> +<#assign switch_extend_arr2=a> + + + customRender:({text}) => { + return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]) + }, + <#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user' || po.classType=='popup_dict'> + dataIndex: '${po.fieldName}_dictText' + <#elseif po.classType=='cat_tree'> + dataIndex: '${po.fieldName}', + <#if po.dictText?default("")?trim?length == 0> + customRender:({text}) => { + return render.renderCategoryTree(text,'${po.dictField?default("")}') + }, + <#else> + customRender: (text, record) => (text ? record['${po.dictText}'] : '') + + <#else> + dataIndex: '${po.fieldName}' + + }, + + +]; + +<#list subTables as sub> +//子表列表数据 +export const ${sub.entityName?uncap_first}Columns: BasicColumn[] = [ + <#list sub.originalColumns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + { + title: '${po.filedComment}', + align:"center", + <#if po.sort=='Y'> + sorter: true, + + <#if po.classType=='date'> + dataIndex: '${po.fieldName}', + customRender:({text}) =>{ + return !text?"":(text.length>10?text.substr(0,10):text) + }, + <#elseif po.fieldDbType=='Blob'> + dataIndex: '${po.fieldName}String' + <#elseif po.classType=='umeditor'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='pca'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='file'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='image'> + dataIndex: '${po.fieldName}', + customRender:render.renderImage, + <#elseif po.classType=='switch'> + dataIndex: '${po.fieldName}', +<#assign switch_extend_arr=['Y','N']> +<#if po.dictField?default("")?contains("[")> +<#assign switch_extend_arr=po.dictField?eval> + +<#list switch_extend_arr as a> +<#if a_index == 0> +<#assign switch_extend_arr1=a> +<#else> +<#assign switch_extend_arr2=a> + + + customRender:({text}) => { + return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]) + }, + <#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user' || po.classType=='popup_dict'> + dataIndex: '${po.fieldName}_dictText' + <#elseif po.classType=='cat_tree'> + dataIndex: '${po.fieldName}', + <#if po.dictText?default("")?trim?length == 0> + customRender:({text}) => { + return render.renderCategoryTree(text,'${po.dictField?default("")}') + }, + <#else> + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') + + <#else> + dataIndex: '${po.fieldName}' + + }, + + +]; + + +<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> +// 高级查询数据 +export const superQuerySchema = { + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + ${superQueryFieldListForVue3(po,po_index)}, + + +}; +<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/V${currentDate}_1__menu_insert_${entityName}.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/V${currentDate}_1__menu_insert_${entityName}.sql new file mode 100644 index 00000000..5396d5d5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/V${currentDate}_1__menu_insert_${entityName}.sql @@ -0,0 +1 @@ +<#include "/common/sql/menu_insert.ftl"> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/[1-n]List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/[1-n]List.vuei new file mode 100644 index 00000000..39ea595c --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/[1-n]List.vuei @@ -0,0 +1,250 @@ +<#list subTables as sub> +#segment#${sub.entityName}List.vue +<#assign need_pca = false> +<#assign is_like = false> + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei new file mode 100644 index 00000000..abd2775e --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei @@ -0,0 +1,252 @@ +<#include "/common/utils.ftl"> + + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei new file mode 100644 index 00000000..2bc88163 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei @@ -0,0 +1,105 @@ +<#include "/common/utils.ftl"> + + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/[1-n]Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/[1-n]Form.vuei new file mode 100644 index 00000000..87511dc6 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/[1-n]Form.vuei @@ -0,0 +1,228 @@ +<#list subTables as sub> +#segment#${sub.entityName}Form.vue +<#include "/common/utils.ftl"> +<#assign need_category = false> +<#assign bpm_flag=false> +<#assign need_pca = false> +<#assign need_search = false> +<#assign need_dept_user = false> +<#assign need_switch = false> +<#assign need_dept = false> +<#assign need_multi = false> +<#assign need_popup = false> +<#assign need_popup_dict = false> +<#assign need_select_tag = false> +<#assign need_select_tree = false> +<#assign need_time = false> +<#assign need_markdown = false> +<#assign need_upload = false> +<#assign need_image_upload = false> +<#assign need_editor = false> +<#assign need_checkbox = false> +<#assign need_range_number = false> +<#assign is_like = false> +<#assign form_span = 24> +<#if tableVo.fieldRowNum==2> + <#assign form_span = 12> +<#elseif tableVo.fieldRowNum==3> + <#assign form_span = 8> +<#elseif tableVo.fieldRowNum==4> + <#assign form_span = 6> + + <#assign hasOnlyValidate = false> + + + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/[1-n]Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/[1-n]Modal.vuei new file mode 100644 index 00000000..2218e926 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/[1-n]Modal.vuei @@ -0,0 +1,79 @@ +<#include "/common/utils.ftl"> +<#list subTables as sub> +#segment#${sub.entityName}Modal.vue + + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai new file mode 100644 index 00000000..932ba94a --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -0,0 +1,368 @@ +package ${bussiPackage}.${entityPackage}.controller; + +import java.io.UnsupportedEncodingException; +import java.io.IOException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.stream.Collectors; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.jeecg.common.system.vo.LoginUser; +import org.apache.shiro.SecurityUtils; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.common.system.query.QueryRuleEnum; +import org.jeecg.common.util.oConvertUtils; +import org.jeecgframework.poi.excel.entity.enmus.ExcelType; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import ${bussiPackage}.${entityPackage}.vo.${entityName}Page; +import ${bussiPackage}.${entityPackage}.service.I${entityName}Service; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.service.I${sub.entityName}Service; + +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import com.alibaba.fastjson.JSON; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.apache.shiro.authz.annotation.RequiresPermissions; +<#assign has_multi_query_field=false> +<#list originalColumns as po> +<#if po.isQuery=='Y' && (po.classType=='list' || po.classType=='list_multi' || po.classType=='radio' || po.classType=='checkbox')> + <#assign has_multi_query_field=true> + + +<#assign enhanceJavaList=[]> +<#if tableVo.extendParams?? && tableVo.extendParams.enhanceJavaList??> + <#assign enhanceJavaList = tableVo.extendParams.enhanceJavaList?filter(enhance -> enhance??)> + + /** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Tag(name="${tableVo.ftlDescription}") +@RestController +@RequestMapping("/${entityPackagePath}/${entityName?uncap_first}") +@Slf4j +public class ${entityName}Controller { + @Autowired + private I${entityName}Service ${entityName?uncap_first}Service; + <#list subTables as sub> + @Autowired + private I${sub.entityName}Service ${sub.entityName?uncap_first}Service; + + + /** + * 分页列表查询 + * + * @param ${entityName?uncap_first} + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "${tableVo.ftlDescription}-分页列表查询") + @Operation(summary="${tableVo.ftlDescription}-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(${entityName} ${entityName?uncap_first}, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='query' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 查询前触发的方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeQuery() + + + + <#if has_multi_query_field> + // 自定义查询规则 + Map customeRuleMap = new HashMap<>(); + // 自定义多选的查询规则为:LIKE_WITH_OR + <#list originalColumns as po> + <#if po.isQuery=='Y' && (po.classType=='list' || po.classType=='list_multi' || po.classType=='radio' || po.classType=='checkbox')> + customeRuleMap.put("${po.fieldName}", QueryRuleEnum.LIKE_WITH_OR); + + + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap(),customeRuleMap); + <#else> + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap()); + + Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize); + IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper); + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='query' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'> + //TODO 查询后触发的方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.afterQuery() + + + + return Result.OK(pageList); + } + + /** + * 添加 + * + * @param ${entityName?uncap_first}Page + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-添加") + @Operation(summary="${tableVo.ftlDescription}-添加") + @RequiresPermissions("${entityPackage}:${tableName}:add") + @PostMapping(value = "/add") + public Result add(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='add' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 新增前的处理方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeAdd() + + + + ${entityName} ${entityName?uncap_first} = new ${entityName}(); + BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first}); + ${entityName?uncap_first}Service.saveMain(${entityName?uncap_first}, <#list subTables as sub>${entityName?uncap_first}Page.get${sub.entityName}List()<#if sub_has_next>,); + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='add' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'> + //TODO 新增后的处理方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.afterAdd() + + + + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * + * @param ${entityName?uncap_first}Page + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-编辑") + @Operation(summary="${tableVo.ftlDescription}-编辑") + @RequiresPermissions("${entityPackage}:${tableName}:edit") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) + public Result edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 编辑前,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeEdit() + + + + ${entityName} ${entityName?uncap_first} = new ${entityName}(); + BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first}); + ${entityName} ${entityName?uncap_first}Entity = ${entityName?uncap_first}Service.getById(${entityName?uncap_first}.getId()); + if(${entityName?uncap_first}Entity==null) { + return Result.error("未找到对应数据"); + } + ${entityName?uncap_first}Service.updateMain(${entityName?uncap_first}, <#list subTables as sub>${entityName?uncap_first}Page.get${sub.entityName}List()<#if sub_has_next>,); + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'> + //TODO 编辑后,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.afterEdit() + + + + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-通过id删除") + @Operation(summary="${tableVo.ftlDescription}-通过id删除") + @RequiresPermissions("${entityPackage}:${tableName}:delete") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name="id",required=true) String id) { + ${entityName?uncap_first}Service.delMain(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-批量删除") + @Operation(summary="${tableVo.ftlDescription}-批量删除") + @RequiresPermissions("${entityPackage}:${tableName}:deleteBatch") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + this.${entityName?uncap_first}Service.delBatchMain(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "${tableVo.ftlDescription}-通过id查询") + @Operation(summary="${tableVo.ftlDescription}-通过id查询") + @GetMapping(value = "/queryById") + public Result<${entityName}> queryById(@RequestParam(name="id",required=true) String id) { + ${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id); + if(${entityName?uncap_first}==null) { + return Result.error("未找到对应数据"); + } + return Result.OK(${entityName?uncap_first}); + + } + + <#list subTables as sub> + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "${sub.ftlDescription}-通过主表ID查询") + @Operation(summary="${sub.ftlDescription}-通过主表ID查询") + @GetMapping(value = "/query${sub.entityName}ByMainId") + public Result> query${sub.entityName}ListByMainId(@RequestParam(name="id",required=true) String id) { + List<${sub.entityName}> ${sub.entityName?uncap_first}List = ${sub.entityName?uncap_first}Service.selectByMainId(id); + <#-- 包裹分页对象,用于翻译注解 --> + IPage <${sub.entityName}> page = new Page<>(); + page.setRecords(${sub.entityName?uncap_first}List); + page.setTotal(${sub.entityName?uncap_first}List.size()); + return Result.OK(page); + } + + + /** + * 导出excel + * + * @param request + * @param ${entityName?uncap_first} + */ + @RequiresPermissions("${entityPackage}:${tableName}:exportXls") + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='export' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 导出前,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeExport() + + + + // Step.1 组装查询条件查询数据 + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap()); + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + + //配置选中数据查询条件 + String selections = request.getParameter("selections"); + if(oConvertUtils.isNotEmpty(selections)) { + List selectionList = Arrays.asList(selections.split(",")); + queryWrapper.in("id",selectionList); + } + //Step.2 获取导出数据 + List<${entityName}> ${entityName?uncap_first}List = ${entityName?uncap_first}Service.list(queryWrapper); + + // Step.3 组装pageList + List<${entityName}Page> pageList = new ArrayList<${entityName}Page>(); + for (${entityName} main : ${entityName?uncap_first}List) { + ${entityName}Page vo = new ${entityName}Page(); + BeanUtils.copyProperties(main, vo); + <#list subTables as sub> + List<${sub.entityName}> ${sub.entityName?uncap_first}List = ${sub.entityName?uncap_first}Service.selectByMainId(main.getId()); + vo.set${sub.entityName}List(${sub.entityName?uncap_first}List); + + pageList.add(vo); + } + + // Step.4 AutoPoi 导出Excel + ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); + mv.addObject(NormalExcelConstants.FILE_NAME, "${tableVo.ftlDescription}列表"); + mv.addObject(NormalExcelConstants.CLASS, ${entityName}Page.class); + mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("${tableVo.ftlDescription}数据", "导出人:"+sysUser.getRealname(), "${tableVo.ftlDescription}", ExcelType.XSSF)); + mv.addObject(NormalExcelConstants.DATA_LIST, pageList); + return mv; + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequiresPermissions("${entityPackage}:${tableName}:importExcel") + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='import' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 导入前,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeImport() + + + + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map fileMap = multipartRequest.getFileMap(); + for (Map.Entry entity : fileMap.entrySet()) { + // 获取上传文件对象 + MultipartFile file = entity.getValue(); + ImportParams params = new ImportParams(); + params.setTitleRows(2); + params.setHeadRows(1); + params.setNeedSave(true); + try { + List<${entityName}Page> list = ExcelImportUtil.importExcel(file.getInputStream(), ${entityName}Page.class, params); + for (${entityName}Page page : list) { + ${entityName} po = new ${entityName}(); + BeanUtils.copyProperties(page, po); + ${entityName?uncap_first}Service.saveMain(po, <#list subTables as sub>page.get${sub.entityName}List()<#if sub_has_next>,); + } + return Result.OK("文件导入成功!数据行数:" + list.size()); + } catch (Exception e) { + log.error(e.getMessage(),e); + return Result.error("文件导入失败:"+e.getMessage()); + } finally { + try { + file.getInputStream().close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return Result.OK("文件导入失败!"); + } + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai new file mode 100644 index 00000000..5762ece1 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai @@ -0,0 +1,82 @@ +<#include "/common/utils.ftl"> +package ${bussiPackage}.${entityPackage}.entity; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecg.common.aspect.annotation.Dict; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Schema(description="${tableVo.ftlDescription}") +@Data +@TableName("${tableName}") +public class ${entityName} implements Serializable { + private static final long serialVersionUID = 1L; + + <#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']> + <#assign excel_ignore_classType_arr=['pca','switch','cat_tree']> + <#list originalColumns as po> + <#-- 生成字典Code --> + <#assign list_field_dictCode=""> + <#if po.classType='sel_user'> + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> + <#elseif po.classType='sel_depart'> + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> + <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dicCode = "${po.dictField}"'> + + <#elseif po.classType=='sel_tree'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'> + <#elseif po.classType=='link_table'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicCode = "${po.dictField}", dicText = "${po.dictText?split(",")[0]}"'> + + /**${po.filedComment}*/ + <#if po.fieldName == primaryKeyField> + @TableId(type = IdType.ASSIGN_ID) + <#else> + <#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'> + <#if po.classType=='date'> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + + + <#if list_field_dictCode?length gt 1> + @Dict(${list_field_dictCode?substring(2)}) + + + <#include "/common/blob.ftl"> + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai new file mode 100644 index 00000000..a81400f1 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai @@ -0,0 +1,86 @@ +<#include "/common/utils.ftl"> +<#list subTables as subTab> +#segment#${subTab.entityName}.java +package ${bussiPackage}.${entityPackage}.entity; + +import java.io.Serializable; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import java.util.Date; +import org.jeecg.common.aspect.annotation.Dict; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.UnsupportedEncodingException; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Schema(description="${subTab.ftlDescription}") +@Data +@TableName("${subTab.tableName}") +public class ${subTab.entityName} implements Serializable { + private static final long serialVersionUID = 1L; + +<#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']> + <#assign excel_ignore_classType_arr=['pca','switch','cat_tree']> + <#list subTab.originalColumns as po> + <#-- 生成字典Code --> + <#assign list_field_dictCode=""> + <#if po.classType='sel_user'> + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> + <#elseif po.classType='sel_depart'> + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> + <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dicCode = "${po.dictField}"'> + <#elseif po.classType=='sel_tree'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'> + + <#elseif po.classType=='link_table'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicCode = "${po.dictField}", dicText = "${po.dictText?split(",")[0]}"'> + + /**${po.filedComment}*/ + <#if po.fieldName == primaryKeyField> + @TableId(type = IdType.ASSIGN_ID) + <#else> + <#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'> + <#if po.classType=='date'> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + + <#elseif !subTab.foreignKeys?seq_contains(po.fieldName?cap_first)> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + + + + <#if list_field_dictCode?length gt 1> + @Dict(${list_field_dictCode?substring(2)}) + + <#-- 大字段转换 --> + <#include "/common/blob.ftl"> + +} + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai new file mode 100644 index 00000000..c31b9bfd --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai @@ -0,0 +1,17 @@ +package ${bussiPackage}.${entityPackage}.mapper; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface ${entityName}Mapper extends BaseMapper<${entityName}> { + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/mapper/[1-n]Mapper.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/mapper/[1-n]Mapper.javai new file mode 100644 index 00000000..10b27644 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/mapper/[1-n]Mapper.javai @@ -0,0 +1,34 @@ +<#list subTables as subTab> +#segment#${subTab.entityName}Mapper.java +package ${bussiPackage}.${entityPackage}.mapper; + +import java.util.List; +import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName}; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface ${subTab.entityName}Mapper extends BaseMapper<${subTab.entityName}> { + + /** + * 通过主表id删除子表数据 + * + * @param mainId 主表id + * @return boolean + */ + public boolean deleteByMainId(@Param("mainId") String mainId); + + /** + * 通过主表id查询子表数据 + * + * @param mainId 主表id + * @return List<${subTab.entityName}> + */ + public List<${subTab.entityName}> selectByMainId(@Param("mainId") String mainId); +} + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml new file mode 100644 index 00000000..16f3d653 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/[1-n]Mapper.xml b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/[1-n]Mapper.xml new file mode 100644 index 00000000..117c9b6f --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/[1-n]Mapper.xml @@ -0,0 +1,26 @@ +<#list subTables as subTab> +<#assign originalForeignKeys = subTab.originalForeignKeys> +#segment#${subTab.entityName}Mapper.xml + + + + + + DELETE + FROM ${subTab.tableName} + WHERE + <#list originalForeignKeys as key> + ${key} = ${r'#'}{mainId} <#rt/> + + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai new file mode 100644 index 00000000..d80c0290 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai @@ -0,0 +1,54 @@ +package ${bussiPackage}.${entityPackage}.service; + +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import com.baomidou.mybatisplus.extension.service.IService; +import java.io.Serializable; +import java.util.Collection; +import java.util.List; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface I${entityName}Service extends IService<${entityName}> { + + /** + * 添加一对多 + * + * @param ${entityName?uncap_first} + <#list subTables as sub> + * @param ${sub.entityName?uncap_first}List + + */ + public void saveMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,) ; + + /** + * 修改一对多 + * + * @param ${entityName?uncap_first} + <#list subTables as sub> + * @param ${sub.entityName?uncap_first}List + + */ + public void updateMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,); + + /** + * 删除一对多 + * + * @param id + */ + public void delMain (String id); + + /** + * 批量删除一对多 + * + * @param idList + */ + public void delBatchMain (Collection idList); + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/service/[1-n]Service.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/service/[1-n]Service.javai new file mode 100644 index 00000000..cbc72ff4 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/service/[1-n]Service.javai @@ -0,0 +1,25 @@ +<#list subTables as subTab> +#segment#I${subTab.entityName}Service.java +package ${bussiPackage}.${entityPackage}.service; + +import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName}; +import com.baomidou.mybatisplus.extension.service.IService; +import java.util.List; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface I${subTab.entityName}Service extends IService<${subTab.entityName}> { + + /** + * 通过主表id查询子表数据 + * + * @param mainId 主表id + * @return List<${subTab.entityName}> + */ + public List<${subTab.entityName}> selectByMainId(String mainId); +} + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai new file mode 100644 index 00000000..7f99d42e --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai @@ -0,0 +1,105 @@ +package ${bussiPackage}.${entityPackage}.service.impl; + +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.mapper.${sub.entityName}Mapper; + +import ${bussiPackage}.${entityPackage}.mapper.${entityName}Mapper; +import ${bussiPackage}.${entityPackage}.service.I${entityName}Service; +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import java.io.Serializable; +import java.util.List; +import java.util.Collection; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Service +public class ${entityName}ServiceImpl extends ServiceImpl<${entityName}Mapper, ${entityName}> implements I${entityName}Service { + + @Autowired + private ${entityName}Mapper ${entityName?uncap_first}Mapper; + <#list subTables as sub> + @Autowired + private ${sub.entityName}Mapper ${sub.entityName?uncap_first}Mapper; + + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveMain(${entityName} ${entityName?uncap_first}, <#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,) { + ${entityName?uncap_first}Mapper.insert(${entityName?uncap_first}); + <#list subTables as sub> + if(${sub.entityName?uncap_first}List!=null && ${sub.entityName?uncap_first}List.size()>0) { + for(${sub.entityName} entity:${sub.entityName?uncap_first}List) { + <#list sub.foreignKeys as key> + //外键设置 + <#if key?lower_case?index_of("${primaryKeyField}")!=-1> + entity.set${key?cap_first}(${entityName?uncap_first}.get${primaryKeyField?cap_first}()); + <#else> + entity.set${key?cap_first}(${entityName?uncap_first}.get${key}()); + + + ${sub.entityName?uncap_first}Mapper.insert(entity); + } + } + + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,) { + ${entityName?uncap_first}Mapper.updateById(${entityName?uncap_first}); + + //1.先删除子表数据 + <#list subTables as sub> + ${sub.entityName?uncap_first}Mapper.deleteByMainId(${entityName?uncap_first}.getId()); + + + //2.子表数据重新插入 + <#list subTables as sub> + if(${sub.entityName?uncap_first}List!=null && ${sub.entityName?uncap_first}List.size()>0) { + for(${sub.entityName} entity:${sub.entityName?uncap_first}List) { + <#list sub.foreignKeys as key> + //外键设置 + <#if key?lower_case?index_of("${primaryKeyField}")!=-1> + entity.set${key?cap_first}(${entityName?uncap_first}.get${primaryKeyField?cap_first}()); + <#else> + entity.set${key?cap_first}(${entityName?uncap_first}.get${key}()); + + + ${sub.entityName?uncap_first}Mapper.insert(entity); + } + } + + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delMain(String id) { + <#list subTables as sub> + ${sub.entityName?uncap_first}Mapper.deleteByMainId(id); + + ${entityName?uncap_first}Mapper.deleteById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delBatchMain(Collection idList) { + for(Serializable id:idList) { + <#list subTables as sub> + ${sub.entityName?uncap_first}Mapper.deleteByMainId(id.toString()); + + ${entityName?uncap_first}Mapper.deleteById(id); + } + } + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/[1-n]ServiceImpl.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/[1-n]ServiceImpl.javai new file mode 100644 index 00000000..0ce41d36 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/[1-n]ServiceImpl.javai @@ -0,0 +1,30 @@ +<#list subTables as subTab> +#segment#${subTab.entityName}ServiceImpl.java +package ${bussiPackage}.${entityPackage}.service.impl; + +import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName}; +import ${bussiPackage}.${entityPackage}.mapper.${subTab.entityName}Mapper; +import ${bussiPackage}.${entityPackage}.service.I${subTab.entityName}Service; +import org.springframework.stereotype.Service; +import java.util.List; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Service +public class ${subTab.entityName}ServiceImpl extends ServiceImpl<${subTab.entityName}Mapper, ${subTab.entityName}> implements I${subTab.entityName}Service { + + @Autowired + private ${subTab.entityName}Mapper ${subTab.entityName?uncap_first}Mapper; + + @Override + public List<${subTab.entityName}> selectByMainId(String mainId) { + return ${subTab.entityName?uncap_first}Mapper.selectByMainId(mainId); + } +} + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vo/${entityName}Page.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vo/${entityName}Page.javai new file mode 100644 index 00000000..218e4899 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vo/${entityName}Page.javai @@ -0,0 +1,117 @@ +package ${bussiPackage}.${entityPackage}.vo; + +import java.util.List; +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +import lombok.Data; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecgframework.poi.excel.annotation.ExcelEntity; +import org.jeecgframework.poi.excel.annotation.ExcelCollection; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import java.util.Date; +import org.jeecg.common.aspect.annotation.Dict; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Data +@Schema(description="${tableVo.ftlDescription}") +public class ${entityName}Page { + +<#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']> +<#assign excel_ignore_classType_arr=['pca','switch','cat_tree']> + <#list originalColumns as po> + <#-- 生成字典Code --> + <#assign list_field_dictCode=""> + <#if po.classType='sel_user'> + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'> + <#elseif po.classType='sel_depart'> + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "depart_name", dicCode = "id"'> + <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dicCode = "${po.dictField}"'> + <#elseif po.classType=='cat_tree'> + <#assign list_field_dictCode=', dictTable = "sys_category", dicText = "name", dicCode = "id"'> + + + /**${po.filedComment}*/ + <#if po.fieldName == primaryKeyField> + <#else> + <#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'> + <#if po.classType=='date'> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + + <#if list_field_dictCode?length gt 1 && !excel_ignore_classType_arr?seq_contains("${po.classType}")> + @Dict(${list_field_dictCode?substring(2)}) + + + + @Schema(description = "${po.filedComment}") + <#if po.fieldDbType=='Blob'> + private java.lang.String ${po.fieldName}String; + <#elseif po.classType=='pca'> + @Excel(name = "${po.filedComment}", width = 15,exportConvert=true,importConvert = true ) + private ${po.fieldType} ${po.fieldName}; + + public String convertis${po.fieldName?cap_first}() { + return SpringContextUtils.getBean(ProvinceCityArea.class).getText(${po.fieldName}); + } + + public void convertset${po.fieldName?cap_first}(String text) { + this.${po.fieldName} = SpringContextUtils.getBean(ProvinceCityArea.class).getCode(text); + } + <#elseif po.classType=='cat_tree'> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + private ${po.fieldType} ${po.fieldName}; + <#elseif po.classType=='switch'> + <#assign switch_extend_arr=['Y','N']> + <#if po.dictField?default("")?contains("[")> + <#assign switch_extend_arr=po.dictField?eval> + + <#list switch_extend_arr as a> + <#if a_index == 0> + <#assign switch_extend_arr1=a> + <#else> + <#assign switch_extend_arr2=a> + + + @Excel(name = "${po.filedComment}", width = 15,replace = {"是_${switch_extend_arr1}","否_${switch_extend_arr2}"} ) + private ${po.fieldType} ${po.fieldName}; + <#else> + private ${po.fieldType} ${po.fieldName}; + + + + <#list subTables as sub> + @ExcelCollection(name="${sub.ftlDescription}") + @Schema(description = "${sub.ftlDescription}") + private List<${sub.entityName}> ${sub.entityName?uncap_first}List; + + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei new file mode 100644 index 00000000..aa402355 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei @@ -0,0 +1,509 @@ +<#-- noinspection JSDuplicatedDeclaration,RequiredAttributes,NpmUsedModulesInstalled --> +<#-- ** 引入全局工具方法 ** --> +<#include "/common/utils.ftl"> +<#-- ** 定义全局使用的变量 ** --> +<#-- 是否有查询条件 --> +<#assign query_flag=false> +<#-- 是否有下拉查询条件 --> +<#assign query_field_select=false> +<#-- 是否有日期查询条件 --> +<#assign query_field_date=false> +<#-- 是否有字典 --> +<#assign list_need_dict=false> +<#-- 是否有分类字典 --> +<#assign list_need_category=false> +<#-- 是否有省市区 --> +<#assign list_need_pca=false> +<#-- 是否有用户选择 --> +<#assign query_sel_user=false> +<#-- 是否有部门选择 --> +<#assign query_sel_dep=false> +<#-- 是否有下拉多选框 --> +<#assign query_sel_multi=false> +<#-- 是否有下拉搜索框 --> +<#assign query_sel_search=false> +<#-- 是否有省市区组件 --> +<#assign query_field_pca=false> +<#-- 是否有分类字典树 --> +<#assign query_sel_cat=false> + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql new file mode 100644 index 00000000..5396d5d5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql @@ -0,0 +1 @@ +<#include "/common/sql/menu_insert.ftl"> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei new file mode 100644 index 00000000..d2d6ac6c --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei @@ -0,0 +1,545 @@ +<#include "/common/utils.ftl"> + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei new file mode 100644 index 00000000..5d789e93 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei @@ -0,0 +1,62 @@ +<#include "/common/utils.ftl"> + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei new file mode 100644 index 00000000..9b697c66 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei @@ -0,0 +1,167 @@ +<#include "/common/utils.ftl"> +<#list subTables as sub> +<#if sub.foreignRelationType=='1'> +#segment#${sub.entityName}Form.vue + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/subTables/[1-n]SubTable.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/subTables/[1-n]SubTable.vuei new file mode 100644 index 00000000..a68776e7 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/subTables/[1-n]SubTable.vuei @@ -0,0 +1,146 @@ +<#--noinspection JSDuplicatedDeclaration--> +<#list subTables as sub> +#segment#${sub.entityName}SubTable.vue + + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei new file mode 100644 index 00000000..8b086409 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei @@ -0,0 +1,470 @@ +<#-- ** 引入全局工具方法 ** --> +<#include "/common/utils.ftl"> + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi new file mode 100644 index 00000000..a22734b2 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi @@ -0,0 +1,83 @@ +import {defHttp} from '/@/utils/http/axios'; +import { useMessage } from "/@/hooks/web/useMessage"; + +const { createConfirm } = useMessage(); + +enum Api { + list = '/${entityPackagePath}/${entityName?uncap_first}/list', + save='/${entityPackagePath}/${entityName?uncap_first}/add', + edit='/${entityPackagePath}/${entityName?uncap_first}/edit', + deleteOne = '/${entityPackagePath}/${entityName?uncap_first}/delete', + deleteBatch = '/${entityPackagePath}/${entityName?uncap_first}/deleteBatch', + importExcel = '/${entityPackagePath}/${entityName?uncap_first}/importExcel', + exportXls = '/${entityPackagePath}/${entityName?uncap_first}/exportXls', +<#list subTables as sub><#rt/> + ${sub.entityName?uncap_first}List = '/${entityPackagePath}/${entityName?uncap_first}/query${sub.entityName}ByMainId', + +} +/** + * 导出api + * @param params + */ +export const getExportUrl = Api.exportXls; + +/** + * 导入api + */ +export const getImportUrl = Api.importExcel; +<#list subTables as sub><#rt/> +/** + * 子表单查询接口 + * @param params + */ +export const query${sub.entityName} = Api.${sub.entityName?uncap_first}List + +/** + * 列表接口 + * @param params + */ +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(); + }); +} +/** + * 批量删除 + * @param params + */ +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(); + }); + } + }); +} +/** + * 保存或者更新 + * @param params + */ +export const saveOrUpdate = (params, isUpdate) => { + let url = isUpdate ? Api.edit : Api.save; + return defHttp.post({url: url, params}); +} +<#list subTables as sub><#rt/> +/** + * 子表列表接口 + * @param params + */ +export const ${sub.entityName?uncap_first}List = (params) => + defHttp.get({url: Api.${sub.entityName?uncap_first}List, params},{isTransformResponse:false}); + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi new file mode 100644 index 00000000..2d744b30 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi @@ -0,0 +1,1060 @@ +<#include "/common/utils.ftl"> +import {BasicColumn} from '/@/components/Table'; +import {FormSchema} from '/@/components/Table'; +import { rules} from '/@/utils/helper/validator'; +import { render } from '/@/utils/common/renderUtils'; +import {JVxeTypes,JVxeColumn} from '/@/components/jeecg/JVxeTable/types' +import { getWeekMonthQuarterYear } from '/@/utils'; +//列表数据 +export const columns: BasicColumn[] = [ + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + { + title: '${po.filedComment}', + align:"center", + <#if po.sort=='Y'> + sorter: true, + + <#if po.classType=='date'> + dataIndex: '${po.fieldName}', + customRender:({text}) =>{ + text = !text ? "" : (text.length > 10 ? text.substr(0,10) : text); + <#if po.extendParams?exists && po.extendParams.picker?exists> + if(text) { + return getWeekMonthQuarterYear(text)['${po.extendParams.picker}']; + } else { + return text; + } + <#else> + return text; + + }, + <#elseif po.fieldDbType=='Blob'> + dataIndex: '${po.fieldName}String' + <#elseif po.classType=='umeditor'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='pca'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='file'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='image'> + dataIndex: '${po.fieldName}', + customRender:render.renderImage, + <#elseif po.classType=='switch'> + dataIndex: '${po.fieldName}', +<#assign switch_extend_arr=['Y','N']> +<#if po.dictField?default("")?contains("[")> +<#assign switch_extend_arr=po.dictField?eval> + +<#list switch_extend_arr as a> +<#if a_index == 0> +<#assign switch_extend_arr1=a> +<#else> +<#assign switch_extend_arr2=a> + + + customRender:({text}) => { + return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]) + }, + <#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user' || po.classType=='popup_dict' || po.classType=='link_table'> + dataIndex: '${po.fieldName}_dictText' + <#elseif po.classType=='cat_tree'> + dataIndex: '${po.fieldName}', + <#if po.dictText?default("")?trim?length == 0> + customRender:({text}) => { + return render.renderCategoryTree(text,'${po.dictField?default("")}') + }, + <#else> + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') + + <#else> + dataIndex: '${po.fieldName}' + + }, + + +]; +//查询数据 +export const searchFormSchema: FormSchema[] = [ +<#-- 开始循环 --> +<#list columns as po> +<#if po.fieldDbName=='bpm_status'> + <#assign bpm_flag=true> + +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if po.isQuery=='Y' && po.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#assign query_flag=true> + <#assign query_field_dictCode=""> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign query_field_dictCode="${po.dictField}"> + +<#if po.queryMode=='single'> + { + label: "${po.filedComment}", + field: ${autoStringSuffix(po)}, +<#if po.classType=='sel_search'> + component: 'JSearchSelect', + componentProps:{ + dict:"${query_field_dictCode}" + }, +<#elseif po.classType=='sel_user'> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + component: 'JSelectUser', +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, +<#elseif po.classType=='switch'> + component: 'JSwitch', + componentProps:{ + query:true, + <#if po.dictField != 'is_open'> + options:${po.dictField} + + }, + <#elseif po.classType=='sel_depart'> + component: 'JSelectDept', + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType=='list_multi'> + component: 'JSelectMultiple', + componentProps:{ + <#if po.dictTable?default("")?trim?length gt 1> + dictCode:"${po.dictTable},${po.dictText},${po.dictField}", + <#elseif po.dictField?default("")?trim?length gt 1> + dictCode:"${po.dictField}", + + triggerChange: true + }, + <#elseif po.classType=='cat_tree'> + component: 'JCategorySelect', + componentProps:{ + pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题 + }, +<#elseif po.classType=='date'> + component: 'DatePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueFormat: 'YYYY-MM-DD' + }, +<#elseif po.classType=='datetime'> + component: 'DatePicker', + componentProps: { + showTime:true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, +<#elseif po.classType=='pca'> + component: 'JAreaLinkage', + componentProps: { + saveCode: 'region', + }, +<#elseif po.classType=='popup'> + <#include "/common/form/vue3popup.ftl"> +<#elseif po.classType=='popup_dict'> + component: 'JPopupDict', + componentProps: { + placeholder: '请选择${po.filedComment}', + dictCode: '${po.dictTable},${po.dictText},${po.dictField}', + multi: ${po.extendParams.popupMulti?c} + }, +<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'> +<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- --> + component: 'JSelectMultiple', + componentProps:{ + <#if po.dictTable?default("")?trim?length gt 1> + dictCode:"${po.dictTable},${po.dictText},${po.dictField}" + <#elseif po.dictField?default("")?trim?length gt 1> + dictCode:"${po.dictField}" + + }, +<#elseif po.classType == 'sel_tree'> + component: 'JTreeSelect', + componentProps:{ + <#if po.dictText??> + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", + <#elseif po.dictText?split(',')[1]??> + pidField:"${po.dictText?split(',')[1]}", + <#elseif po.dictText?split(',')[3]??> + hasChildField:"${po.dictText?split(',')[3]}", + + + pidValue:"${po.dictField}", + }, +<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'InputNumber', +<#else> + component: 'Input', + + //colProps: {span: 6}, + }, +<#elseif po.queryMode=='like'> + { + label: "${po.filedComment}", + field: "${po.fieldName}", + component: 'JInput', + }, +<#else> + { + label: "${po.filedComment}", + field: "${po.fieldName}", +<#if po.classType=='date'> + component: 'RangePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueType: 'Date', + }, +<#elseif po.classType=='datetime'> + component: 'RangePicker', + componentProps: { + valueType: 'Date', + showTime:true + }, +<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'JRangeNumber', +<#-- update-begin---author:chenrui ---date:20240527 for:[TV360X-388]时间范围查询控件---------- --> +<#elseif po.classType=='time'> + component: 'RangeTime', +<#-- update-end---author:chenrui ---date:20240527 for:[TV360X-388]时间范围查询控件---------- --> +<#else> + component: 'Input', //TODO 范围查询 + + //colProps: {span: 6}, + }, + + + +<#-- 结束循环 --> +]; +//表单数据 +export const formSchema: FormSchema[] = [ +<#assign form_cat_tree = false> +<#assign form_cat_back = ""> +<#assign bpm_flag=false> +<#assign id_exists = false> +<#list columns as po><#rt/> +<#if po.fieldDbName=='bpm_status'> + <#assign bpm_flag=true> + +<#if po.fieldDbName == 'id'> + <#assign id_exists = true> + +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if po.isShow =='Y' && po.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#assign form_field_dictCode=""> + <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictField}"> + + { + label: '${po.filedComment}', + field: ${autoStringSuffix(po)}, +<#-- update-begin-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.defaultVal??> + <#if po.fieldDbType=="BigDecimal" || po.fieldDbType=="double" || po.fieldDbType=="int"> + defaultValue: ${po.defaultVal}, + <#else> + defaultValue: "${po.defaultVal}", + + +<#-- update-end-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.classType =='date'> + component: 'DatePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueFormat: 'YYYY-MM-DD' + }, + <#elseif po.classType =='datetime'> + component: 'DatePicker', + componentProps: { + showTime:true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, + <#elseif po.classType =='time'> + component: 'TimePicker', + componentProps: { + valueFormat: 'HH:mm:ss' + }, + <#elseif po.classType =='popup'> + <#include "/common/form/vue3popup.ftl"> + <#elseif po.classType=='popup_dict'> + component: 'JPopupDict', + componentProps: { + placeholder: '请选择${po.filedComment}', + dictCode: '${po.dictTable},${po.dictText},${po.dictField}', + multi: ${po.extendParams.popupMulti?c} + }, + <#elseif po.classType =='sel_depart'> + component: 'JSelectDept', + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='switch'> + component: 'JSwitch', + componentProps:{ + <#if po.dictField != 'is_open'> + options:${po.dictField} + + }, + <#elseif po.classType =='pca'> + component: 'JAreaLinkage', + componentProps: { + saveCode: 'region', + }, + <#elseif po.classType =='markdown'> + component: 'JMarkdownEditor',//注意string转换问题 + <#elseif po.classType =='password'> + component: 'InputPassword', + <#elseif po.classType =='sel_user'> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + component: 'JSelectUser', +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='textarea'> + component: 'InputTextArea', + <#elseif po.classType=='list'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#elseif po.classType=='radio'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + type: "radio", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='list_multi'> + component: 'JSelectMultiple', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#elseif po.classType=='checkbox'> + component: 'JCheckbox', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='sel_search'> + component: 'JSearchSelect', + componentProps:{ + dict:"${form_field_dictCode}" + }, +<#elseif po.classType=='cat_tree'> + <#assign form_cat_tree = true> + component: 'JCategorySelect', + componentProps:{ + pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题 + }, + <#if po.dictText?default("")?trim?length gt 1> + <#assign form_cat_back = "${po.dictText}"> + + <#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'InputNumber', + <#elseif po.classType=='file'> + component: 'JUpload', + componentProps:{ + <#if po.uploadnum??> + maxCount:${po.uploadnum} + + }, + <#elseif po.classType=='image'> + component: 'JImageUpload', + componentProps:{ + <#if po.uploadnum??> + fileMax:${po.uploadnum} + <#else> + fileMax: 0 + + }, + <#elseif po.classType=='umeditor'> + component: 'JEditor', + <#elseif po.classType == 'sel_tree'> + component: 'JTreeSelect', + componentProps:{ + <#if po.dictText??> + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", + <#elseif po.dictText?split(',')[1]??> + pidField:"${po.dictText?split(',')[1]}", + <#elseif po.dictText?split(',')[3]??> + hasChildField:"${po.dictText?split(',')[3]}", + + + pidValue:"${po.dictField}", + }, +<#elseif po.classType=='link_table'> + component: 'JLinkTableCard', + componentProps: { + valueField: '${po.dictField}', + textField: '${po.dictText}', + tableName: '${po.dictTable}', + multi: <#if (po.queryMode!"") == "multi">true<#else>false + }, + <#else> + component: 'Input', + + <#include "/common/utils.ftl"> + <#if po.isShow == 'Y' && poHasCheck(po)> + dynamicRules: ({model,schema}) => { + <#if po.fieldName != 'id'> + <#assign fieldValidType = po.fieldValidType!''> + return [ + <#-- 非空校验 --> + <#if po.nullable == 'N' || fieldValidType == '*'> + { required: true, message: '请输入${po.filedComment}!'}, + <#elseif fieldValidType!=''> + { required: false}, + + <#-- 唯一校验 --> + <#if fieldValidType == 'only'> + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}', '${po.fieldDbName}',model,schema)[0]}, + <#-- 6到16位数字 --> + <#elseif fieldValidType == 'n6-16'> + { pattern: /^\d{6,16}$|^(?=\d+\.\d+)[\d.]{7,17}$/, message: '请输入6到16位数字!'}, + <#-- 6到16位任意字符 --> + <#elseif fieldValidType == '*6-16'> + { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, + <#-- 6到18位字母 --> + <#elseif fieldValidType == 's6-18'> + { pattern:/^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, + <#-- 网址 --> + <#elseif fieldValidType == 'url'> + { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, + <#-- 电子邮件 --> + <#elseif fieldValidType == 'e'> + { pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'}, + <#-- 手机号码 --> + <#elseif fieldValidType == 'm'> + { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}, + <#-- 邮政编码 --> + <#elseif fieldValidType == 'p'> + { pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'}, + <#-- 字母 --> + <#elseif fieldValidType == 's'> + { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}, + <#-- 数字 --> + <#elseif fieldValidType == 'n'> + { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'}, + <#-- 整数 --> + <#elseif fieldValidType == 'z'> + { pattern: /^-?\d+$/, message: '请输入整数!'}, + <#-- 金额 --> + <#elseif fieldValidType == 'money'> + { pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'}, + <#-- 正则校验 --> + <#elseif fieldValidType != '' && fieldValidType != '*'> + { pattern: '${fieldValidType}', message: '不符合校验规则!'}, + <#-- 无校验 --> + <#else> + <#t> + + ]; + + }, + + <#if po.readonly=='Y'> + dynamicDisabled:true + + }, + + +<#if id_exists == false> + // TODO 主键隐藏字段,目前写死为ID + { + label: '', + field: 'id', + component: 'Input', + show: false + }, + +]; +//子表单数据 +<#list subTables as sub> +//子表列表数据 +export const ${sub.entityName?uncap_first}Columns: BasicColumn[] = [ + <#list sub.originalColumns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + { + title: '${po.filedComment}', + align:"center", + <#if po.sort=='Y'> + sorter: true, + + <#if po.classType=='date'> + dataIndex: '${po.fieldName}', + customRender:({text}) =>{ + return !text?"":(text.length>10?text.substr(0,10):text) + }, + <#elseif po.fieldDbType=='Blob'> + dataIndex: '${po.fieldName}String' + <#elseif po.classType=='umeditor'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='pca'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='file'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='image'> + dataIndex: '${po.fieldName}', + customRender:render.renderImage, + <#elseif po.classType=='switch'> + dataIndex: '${po.fieldName}', +<#assign switch_extend_arr=['Y','N']> +<#if po.dictField?default("")?contains("[")> +<#assign switch_extend_arr=po.dictField?eval> + +<#list switch_extend_arr as a> +<#if a_index == 0> +<#assign switch_extend_arr1=a> +<#else> +<#assign switch_extend_arr2=a> + + + customRender:({text}) => { + return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]) + }, + <#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user' || po.classType=='popup_dict' || po.classType=='link_table'> + dataIndex: '${po.fieldName}_dictText' + <#elseif po.classType=='cat_tree'> + dataIndex: '${po.fieldName}', + <#if po.dictText?default("")?trim?length == 0> + customRender:({text}) => { + return render.renderCategoryTree(text,'${po.dictField?default("")}') + }, + <#else> + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') + + <#else> + dataIndex: '${po.fieldName}' + + }, + + +]; +<#if sub.foreignRelationType =='1'> +export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ +<#assign form_cat_tree = false> +<#assign form_cat_back = ""> +<#assign bpm_flag=false> +<#assign sub_id_exists=false> +<#list sub.colums as po><#rt/> +<#if po.fieldDbName=='bpm_status'> + <#assign bpm_flag=true> + +<#if po.fieldDbName=='id'> + <#assign sub_id_exists=true> + +<#if po.isShow =='Y'> +<#assign form_field_dictCode=""> + <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictField}"> + + { + label: '${po.filedComment}', + field: ${autoStringSuffix(po)}, +<#-- update-begin-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.defaultVal??> + <#if po.fieldDbType=="BigDecimal" || po.fieldDbType=="double" || po.fieldDbType=="int"> + defaultValue: ${po.defaultVal}, + <#else> + defaultValue: "${po.defaultVal}", + + +<#-- update-end-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.classType =='date'> + component: 'DatePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueFormat: 'YYYY-MM-DD' + }, + <#elseif po.classType =='datetime'> + component: 'DatePicker', + componentProps: { + showTime:true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, + <#elseif po.classType =='time'> + component: 'TimePicker', + componentProps: { + valueFormat: 'HH:mm:ss' + }, + <#elseif po.classType =='popup'> + <#include "/common/form/vue3popup.ftl"> + <#elseif po.classType=='popup_dict'> + component: 'JPopupDict', + componentProps: { + placeholder: '请选择${po.filedComment}', + dictCode: '${po.dictTable},${po.dictText},${po.dictField}', + multi: ${po.extendParams.popupMulti?c} + }, + <#elseif po.classType =='sel_depart'> + component: 'JSelectDept', + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='switch'> + component: 'JSwitch', + componentProps:{ + <#if po.dictField != 'is_open'> + options:${po.dictField} + + }, + <#elseif po.classType =='pca'> + component: 'JAreaLinkage', + componentProps: { + saveCode: 'region', + }, + <#elseif po.classType =='markdown'> + component: 'JMarkdownEditor',//注意string转换问题 + <#elseif po.classType =='password'> + component: 'InputPassword', + <#elseif po.classType =='sel_user'> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + component: 'JSelectUser', +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='textarea'> + component: 'InputTextArea', + <#elseif po.classType=='list'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#elseif po.classType=='radio'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + type: "radio", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='list_multi'> + component: 'JSelectMultiple', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#elseif po.classType=='checkbox'> + component: 'JCheckbox', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='sel_search'> + component: 'JSearchSelect', + componentProps:{ + dict:"${form_field_dictCode}" + }, +<#elseif po.classType=='cat_tree'> + <#assign form_cat_tree = true> + component: 'JCategorySelect', + componentProps:{ + pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题 + }, + <#if po.dictText?default("")?trim?length gt 1> + <#assign form_cat_back = "${po.dictText}"> + + <#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'InputNumber', + <#elseif po.classType=='file'> + component: 'JUpload', + componentProps:{ + <#if po.uploadnum??> + maxCount:${po.uploadnum} + + }, + <#elseif po.classType=='image'> + component: 'JImageUpload', + componentProps:{ + <#if po.uploadnum??> + fileMax:${po.uploadnum} + <#else> + fileMax: 0 + + }, + <#elseif po.classType=='umeditor'> + component: 'JEditor', + <#elseif po.classType == 'sel_tree'> + component: 'JTreeSelect', + componentProps:{ + <#if po.dictText??> + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", + <#elseif po.dictText?split(',')[1]??> + pidField:"${po.dictText?split(',')[1]}", + <#elseif po.dictText?split(',')[3]??> + hasChildField:"${po.dictText?split(',')[3]}", + + + pidValue:"${po.dictField}", + }, +<#elseif po.classType=='link_table'> + component: 'JLinkTableCard', + componentProps: { + valueField: '${po.dictField}', + textField: '${po.dictText}', + tableName: '${po.dictTable}', + multi: <#if (po.queryMode!"") == "multi">true<#else>false + }, + <#else> + component: 'Input', + + <#include "/common/utils.ftl"> + <#if po.isShow == 'Y' && poHasCheck(po)> + dynamicRules: ({model,schema}) => { + <#if po.fieldName != 'id'> + <#assign fieldValidType = po.fieldValidType!''> + return [ + <#-- 非空校验 --> + <#if po.nullable == 'N' || fieldValidType == '*'> + { required: true, message: '请输入${po.filedComment}!'}, + <#elseif fieldValidType!=''> + { required: false}, + + <#-- 唯一校验 --> + <#if fieldValidType == 'only'> + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}', '${po.fieldDbName}',model,schema)[0]}, + <#-- 6到16位数字 --> + <#elseif fieldValidType == 'n6-16'> + { pattern: /^\d{6,16}$|^(?=\d+\.\d+)[\d.]{7,17}$/, message: '请输入6到16位数字!'}, + <#-- 6到16位任意字符 --> + <#elseif fieldValidType == '*6-16'> + { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, + <#-- 6到18位字母 --> + <#elseif fieldValidType == 's6-18'> + { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, + <#-- 网址 --> + <#elseif fieldValidType == 'url'> + { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, + <#-- 电子邮件 --> + <#elseif fieldValidType == 'e'> + { pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'}, + <#-- 手机号码 --> + <#elseif fieldValidType == 'm'> + { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}, + <#-- 邮政编码 --> + <#elseif fieldValidType == 'p'> + { pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'}, + <#-- 字母 --> + <#elseif fieldValidType == 's'> + { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}, + <#-- 数字 --> + <#elseif fieldValidType == 'n'> + { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'}, + <#-- 整数 --> + <#elseif fieldValidType == 'z'> + { pattern: /^-?\d+$/, message: '请输入整数!'}, + <#-- 金额 --> + <#elseif fieldValidType == 'money'> + { pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'}, + <#-- 正则校验 --> + <#elseif fieldValidType != '' && fieldValidType != '*'> + { pattern: '${fieldValidType}', message: '不符合校验规则!'}, + <#-- 无校验 --> + <#else> + <#t> + + ]; + + }, + + <#if po.readonly=='Y'> + dynamicDisabled:true + + }, + + +<#if sub_id_exists == false> + { + label: '', + field: 'id', + component: 'Input', + show: false + }, + +]; + + +//子表表格配置 +<#list subTables as sub> +<#if sub.foreignRelationType =='0'> +export const ${sub.entityName?uncap_first}JVxeColumns: JVxeColumn[] = [ +<#assign popupBackFields = ""> + +<#-- 循环子表的列 开始 --> +<#list sub.colums as col><#rt/> +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if col.isShow =='Y' && col.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if col.filedComment !='外键' > + { + title: '${col.filedComment}', + key: '${autoStringSuffixForModel(col)}', +<#if col.classType =='date'> + type: JVxeTypes.date, + <#if col.extendParams?exists && col.extendParams.picker?exists> + picker: '${col.extendParams.picker}', + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='datetime'> + type: JVxeTypes.datetime, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='time'> + type: JVxeTypes.time, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='textarea'> + type: JVxeTypes.textarea, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='list' || col.classType =='radio'> + type: JVxeTypes.select, + options:[], + <#if col.dictTable?default("")?trim?length gt 1> + dictCode:"${col.dictTable},${col.dictText},${col.dictField}", + <#else> + dictCode:"${col.dictField}", + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='list_multi' || col.classType =='checkbox'> + type: JVxeTypes.selectMultiple, + options:[], + <#if col.dictTable?default("")?trim?length gt 1> + dictCode:"${col.dictTable},${col.dictText},${col.dictField}", + <#else> + dictCode:"${col.dictField}", + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='sel_search'> + type: JVxeTypes.selectSearch, + <#if col.dictTable?default("")?trim?length gt 1> + dictCode:"${col.dictTable},${col.dictText},${col.dictField}", + <#else> + dictCode:"${col.dictField}", + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='sel_depart'> + type: JVxeTypes.departSelect, + props:{ + <#if col.extendParams?exists && col.extendParams.text?exists> + labelKey: '${col.extendParams.text}', + + <#if col.extendParams?exists && col.extendParams.store?exists> + rowKey: '${col.extendParams.store}', + + }, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='sel_user'> + type: JVxeTypes.userSelect, + props:{ + <#if col.extendParams?exists && col.extendParams.text?exists> + labelKey: '${col.extendParams.text}', + + <#if col.extendParams?exists && col.extendParams.store?exists> + rowKey: '${col.extendParams.store}', + + }, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='image'> + type: JVxeTypes.image, + token:true, + responseName:"message", + <#if col.readonly=='Y'> + disabled:true, + + <#if col.uploadnum??> + number: ${col.uploadnum}, + +<#elseif col.classType =='file'> + type: JVxeTypes.file, + token:true, + responseName:"message", + <#if col.readonly=='Y'> + disabled:true, + + <#if col.uploadnum??> + number: ${col.uploadnum}, + +<#elseif col.classType =='switch'> + type: JVxeTypes.checkbox, + <#if col.dictField == 'is_open'> + customValue: ['Y', 'N'], + <#else> + customValue: ${col.dictField}, + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType=='pca'> + type: JVxeTypes.pca, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='popup'> +<#if popupBackFields?length gt 0> + <#assign popupBackFields = "${popupBackFields}"+","+"${col.dictText}"> +<#else> + <#assign popupBackFields = "${col.dictText}"> + + <#include "/common/form/vue3Jvxepopup.ftl"> +<#-- update-begin-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> +<#-- elseif "int,decimal,double,"?contains(col.classType) --> +<#elseif col.fieldDbType=='int' || col.fieldDbType=='long' || col.fieldDbType=='double' || col.fieldDbType=='BigDecimal'> +<#-- update-end-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> + type: JVxeTypes.inputNumber, + <#if col.readonly=='Y'> + disabled:true, + +<#else> + type: JVxeTypes.input, + <#if col.readonly=='Y'> + disabled:true, + + +<#if col.classType =='list_multi' || col.classType =='checkbox'> + width:"250px", +<#else> + width:"200px", + +<#if col.classType =='file'> + placeholder: '请选择文件', +<#else> + placeholder: '请输入${'$'}{title}', + +<#if col.defaultVal??> +<#if col.fieldDbType=="BigDecimal" || col.fieldDbType=="double" || col.fieldDbType=="int"> + defaultValue:${col.defaultVal}, + <#else> + defaultValue:"${col.defaultVal}", + +<#else> + defaultValue:'', + +<#-- 子表的校验 --> + <#include "/common/validatorRulesTemplate/sub-vue3.ftl"> + }, + + + +<#-- 循环子表的列 结束 --> + ] + + + +<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> +// 高级查询数据 +export const superQuerySchema = { + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + ${superQueryFieldListForVue3(po,po_index)}, + + + //子表高级查询 + <#list subTables as sub> + ${sub.entityName?uncap_first}: { + title: '${sub.ftlDescription}', + view: 'table', + fields: { + <#list sub.colums as subCol> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if subCol.isShowList =='Y' && subCol.fieldName !='id' && subCol.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + ${superQueryFieldListForVue3(subCol,subCol_index)}, + + + } + }, + +}; +<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> + +/** +* 流程表单调用这个方法获取formSchema +* @param param +*/ +export function getBpmFormSchema(_formData): FormSchema[]{ + // 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema + return formSchema; +} \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql new file mode 100644 index 00000000..5396d5d5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql @@ -0,0 +1 @@ +<#include "/common/sql/menu_insert.ftl"> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Form.vuei new file mode 100644 index 00000000..b5e8c33c --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Form.vuei @@ -0,0 +1,212 @@ +<#include "/common/utils.ftl"> + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei new file mode 100644 index 00000000..d25bb5a5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei @@ -0,0 +1,278 @@ +<#include "/common/utils.ftl"> + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei new file mode 100644 index 00000000..a2c7a582 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei @@ -0,0 +1,89 @@ +<#include "/common/utils.ftl"> +<#list subTables as sub> +<#if sub.foreignRelationType=='1'> +#segment#${sub.entityName}Form.vue + + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/subTables/[1-n]SubTable.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/subTables/[1-n]SubTable.vuei new file mode 100644 index 00000000..dc2ed4ae --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/subTables/[1-n]SubTable.vuei @@ -0,0 +1,80 @@ +<#--noinspection JSDuplicatedDeclaration--> +<#list subTables as sub> +#segment#${sub.entityName}SubTable.vue + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai new file mode 100644 index 00000000..c4665557 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -0,0 +1,377 @@ +package ${bussiPackage}.${entityPackage}.controller; + +import java.io.UnsupportedEncodingException; +import java.io.IOException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.HashMap; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.jeecg.common.system.vo.LoginUser; +import org.apache.shiro.SecurityUtils; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.common.system.query.QueryRuleEnum; +import org.jeecg.common.util.oConvertUtils; +import org.jeecgframework.poi.excel.entity.enmus.ExcelType; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import ${bussiPackage}.${entityPackage}.vo.${entityName}Page; +import ${bussiPackage}.${entityPackage}.service.I${entityName}Service; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.service.I${sub.entityName}Service; + +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import com.alibaba.fastjson.JSON; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.apache.shiro.authz.annotation.RequiresPermissions; + +<#assign bpm_flag=false> +<#assign has_multi_query_field=false> +<#list originalColumns as po> +<#if po.fieldDbName=='bpm_status'> + <#assign bpm_flag=true> + + + +<#assign has_multi_query_field=false> +<#list originalColumns as po> +<#if po.isQuery=='Y' && (po.classType=='list' || po.classType=='list_multi' || po.classType=='radio' || po.classType=='checkbox')> + <#assign has_multi_query_field=true> + + +<#assign enhanceJavaList=[]> +<#if tableVo.extendParams?? && tableVo.extendParams.enhanceJavaList??> + <#assign enhanceJavaList = tableVo.extendParams.enhanceJavaList?filter(enhance -> enhance??)> + + /** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Tag(name="${tableVo.ftlDescription}") +@RestController +@RequestMapping("/${entityPackagePath}/${entityName?uncap_first}") +@Slf4j +public class ${entityName}Controller { + @Autowired + private I${entityName}Service ${entityName?uncap_first}Service; + <#list subTables as sub> + @Autowired + private I${sub.entityName}Service ${sub.entityName?uncap_first}Service; + + + /** + * 分页列表查询 + * + * @param ${entityName?uncap_first} + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "${tableVo.ftlDescription}-分页列表查询") + @Operation(summary="${tableVo.ftlDescription}-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(${entityName} ${entityName?uncap_first}, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='query' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 查询前触发的方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeQuery() + + + + <#if has_multi_query_field> + // 自定义查询规则 + Map customeRuleMap = new HashMap<>(); + // 自定义多选的查询规则为:LIKE_WITH_OR + <#list originalColumns as po> + <#if po.isQuery=='Y' && (po.classType=='list' || po.classType=='list_multi' || po.classType=='radio' || po.classType=='checkbox')> + customeRuleMap.put("${po.fieldName}", QueryRuleEnum.LIKE_WITH_OR); + + + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap(),customeRuleMap); + <#else> + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap()); + + Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize); + IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper); + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='query' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'> + //TODO 查询后触发的方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.afterQuery() + + + + return Result.OK(pageList); + } + + /** + * 添加 + * + * @param ${entityName?uncap_first}Page + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-添加") + @Operation(summary="${tableVo.ftlDescription}-添加") + @RequiresPermissions("${entityPackage}:${tableName}:add") + @PostMapping(value = "/add") + public Result add(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='add' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 新增前的处理方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeAdd() + + + + ${entityName} ${entityName?uncap_first} = new ${entityName}(); + BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first}); + <#if bpm_flag> + ${entityName?uncap_first}.setBpmStatus("1"); + + ${entityName?uncap_first}Service.saveMain(${entityName?uncap_first}, <#list subTables as sub>${entityName?uncap_first}Page.get${sub.entityName}List()<#if sub_has_next>,); + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='add' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'> + //TODO 新增后的处理方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.afterAdd() + + + + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * + * @param ${entityName?uncap_first}Page + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-编辑") + @Operation(summary="${tableVo.ftlDescription}-编辑") + @RequiresPermissions("${entityPackage}:${tableName}:edit") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) + public Result edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 编辑前,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeEdit() + + + + ${entityName} ${entityName?uncap_first} = new ${entityName}(); + BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first}); + ${entityName} ${entityName?uncap_first}Entity = ${entityName?uncap_first}Service.getById(${entityName?uncap_first}.getId()); + if(${entityName?uncap_first}Entity==null) { + return Result.error("未找到对应数据"); + } + ${entityName?uncap_first}Service.updateMain(${entityName?uncap_first}, <#list subTables as sub>${entityName?uncap_first}Page.get${sub.entityName}List()<#if sub_has_next>,); + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'> + //TODO 编辑后,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.afterEdit() + + + + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-通过id删除") + @Operation(summary="${tableVo.ftlDescription}-通过id删除") + @RequiresPermissions("${entityPackage}:${tableName}:delete") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name="id",required=true) String id) { + ${entityName?uncap_first}Service.delMain(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-批量删除") + @Operation(summary="${tableVo.ftlDescription}-批量删除") + @RequiresPermissions("${entityPackage}:${tableName}:deleteBatch") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + this.${entityName?uncap_first}Service.delBatchMain(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "${tableVo.ftlDescription}-通过id查询") + @Operation(summary="${tableVo.ftlDescription}-通过id查询") + @GetMapping(value = "/queryById") + public Result<${entityName}> queryById(@RequestParam(name="id",required=true) String id) { + ${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id); + if(${entityName?uncap_first}==null) { + return Result.error("未找到对应数据"); + } + return Result.OK(${entityName?uncap_first}); + + } + + <#list subTables as sub> + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "${sub.ftlDescription}通过主表ID查询") + @Operation(summary="${sub.ftlDescription}主表ID查询") + @GetMapping(value = "/query${sub.entityName}ByMainId") + public Result> query${sub.entityName}ListByMainId(@RequestParam(name="id",required=true) String id) { + List<${sub.entityName}> ${sub.entityName?uncap_first}List = ${sub.entityName?uncap_first}Service.selectByMainId(id); + return Result.OK(${sub.entityName?uncap_first}List); + } + + + /** + * 导出excel + * + * @param request + * @param ${entityName?uncap_first} + */ + @RequiresPermissions("${entityPackage}:${tableName}:exportXls") + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='export' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 导出前,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeExport() + + + + + // Step.1 组装查询条件查询数据 + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap()); + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + + //配置选中数据查询条件 + String selections = request.getParameter("selections"); + if(oConvertUtils.isNotEmpty(selections)) { + List selectionList = Arrays.asList(selections.split(",")); + queryWrapper.in("id",selectionList); + } + //Step.2 获取导出数据 + List<${entityName}> ${entityName?uncap_first}List = ${entityName?uncap_first}Service.list(queryWrapper); + + // Step.3 组装pageList + List<${entityName}Page> pageList = new ArrayList<${entityName}Page>(); + for (${entityName} main : ${entityName?uncap_first}List) { + ${entityName}Page vo = new ${entityName}Page(); + BeanUtils.copyProperties(main, vo); + <#list subTables as sub> + List<${sub.entityName}> ${sub.entityName?uncap_first}List = ${sub.entityName?uncap_first}Service.selectByMainId(main.getId()); + vo.set${sub.entityName}List(${sub.entityName?uncap_first}List); + + pageList.add(vo); + } + + // Step.4 AutoPoi 导出Excel + ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); + mv.addObject(NormalExcelConstants.FILE_NAME, "${tableVo.ftlDescription}列表"); + mv.addObject(NormalExcelConstants.CLASS, ${entityName}Page.class); + mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("${tableVo.ftlDescription}数据", "导出人:"+sysUser.getRealname(), "${tableVo.ftlDescription}", ExcelType.XSSF)); + mv.addObject(NormalExcelConstants.DATA_LIST, pageList); + return mv; + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequiresPermissions("${entityPackage}:${tableName}:importExcel") + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='import' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 导入前,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeImport() + + + + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map fileMap = multipartRequest.getFileMap(); + for (Map.Entry entity : fileMap.entrySet()) { + // 获取上传文件对象 + MultipartFile file = entity.getValue(); + ImportParams params = new ImportParams(); + params.setTitleRows(2); + params.setHeadRows(1); + params.setNeedSave(true); + try { + List<${entityName}Page> list = ExcelImportUtil.importExcel(file.getInputStream(), ${entityName}Page.class, params); + for (${entityName}Page page : list) { + ${entityName} po = new ${entityName}(); + BeanUtils.copyProperties(page, po); + ${entityName?uncap_first}Service.saveMain(po, <#list subTables as sub>page.get${sub.entityName}List()<#if sub_has_next>,); + } + return Result.OK("文件导入成功!数据行数:" + list.size()); + } catch (Exception e) { + log.error(e.getMessage(),e); + return Result.error("文件导入失败:"+e.getMessage()); + } finally { + try { + file.getInputStream().close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return Result.OK("文件导入失败!"); + } + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai new file mode 100644 index 00000000..385ea9df --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai @@ -0,0 +1,82 @@ +<#include "/common/utils.ftl"> +package ${bussiPackage}.${entityPackage}.entity; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecg.common.aspect.annotation.Dict; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Schema(description="${tableVo.ftlDescription}") +@Data +@TableName("${tableName}") +public class ${entityName} implements Serializable { + private static final long serialVersionUID = 1L; + +<#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']> +<#assign excel_ignore_classType_arr=['pca','switch','cat_tree']> + <#list originalColumns as po> + <#-- 生成字典Code --> + <#assign list_field_dictCode=""> + <#if po.classType='sel_user'> + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> + <#elseif po.classType='sel_depart'> + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> + <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dicCode = "${po.dictField}"'> + + <#elseif po.classType=='sel_tree'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'> + <#elseif po.classType=='link_table'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicCode = "${po.dictField}", dicText = "${po.dictText?split(",")[0]}"'> + + /**${po.filedComment}*/ + <#if po.fieldName == primaryKeyField> + @TableId(type = IdType.ASSIGN_ID) + <#else> + <#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'> + <#if po.classType=='date'> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + + + <#if list_field_dictCode?length gt 1> + @Dict(${list_field_dictCode?substring(2)}) + + + <#include "/common/blob.ftl"> + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai new file mode 100644 index 00000000..f9ab598c --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai @@ -0,0 +1,81 @@ +<#include "/common/utils.ftl"> +<#list subTables as subTab> +#segment#${subTab.entityName}.java +package ${bussiPackage}.${entityPackage}.entity; + +import java.io.Serializable; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import java.util.Date; +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.UnsupportedEncodingException; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Schema(description="${subTab.ftlDescription}") +@Data +@TableName("${subTab.tableName}") +public class ${subTab.entityName} implements Serializable { + private static final long serialVersionUID = 1L; + +<#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']> + <#assign excel_ignore_classType_arr=['pca','switch','cat_tree']> + <#list subTab.originalColumns as po> + <#-- 生成字典Code --> + <#assign list_field_dictCode=""> + <#if po.classType='sel_user'> + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> + <#elseif po.classType='sel_depart'> + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> + <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dicCode = "${po.dictField}"'> + <#elseif po.classType=='sel_tree'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'> + + <#elseif po.classType=='link_table'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicCode = "${po.dictField}", dicText = "${po.dictText?split(",")[0]}"'> + + /**${po.filedComment}*/ + <#if po.fieldName == primaryKeyField> + @TableId(type = IdType.ASSIGN_ID) + <#else> + <#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'> + <#if po.classType=='date'> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + + <#elseif !subTab.foreignKeys?seq_contains(po.fieldName?cap_first)> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + + + + <#-- 大字段转换 --> + <#include "/common/blob.ftl"> + +} + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai new file mode 100644 index 00000000..c31b9bfd --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai @@ -0,0 +1,17 @@ +package ${bussiPackage}.${entityPackage}.mapper; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface ${entityName}Mapper extends BaseMapper<${entityName}> { + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/mapper/[1-n]Mapper.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/mapper/[1-n]Mapper.javai new file mode 100644 index 00000000..10b27644 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/mapper/[1-n]Mapper.javai @@ -0,0 +1,34 @@ +<#list subTables as subTab> +#segment#${subTab.entityName}Mapper.java +package ${bussiPackage}.${entityPackage}.mapper; + +import java.util.List; +import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName}; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface ${subTab.entityName}Mapper extends BaseMapper<${subTab.entityName}> { + + /** + * 通过主表id删除子表数据 + * + * @param mainId 主表id + * @return boolean + */ + public boolean deleteByMainId(@Param("mainId") String mainId); + + /** + * 通过主表id查询子表数据 + * + * @param mainId 主表id + * @return List<${subTab.entityName}> + */ + public List<${subTab.entityName}> selectByMainId(@Param("mainId") String mainId); +} + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml new file mode 100644 index 00000000..16f3d653 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/[1-n]Mapper.xml b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/[1-n]Mapper.xml new file mode 100644 index 00000000..117c9b6f --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/[1-n]Mapper.xml @@ -0,0 +1,26 @@ +<#list subTables as subTab> +<#assign originalForeignKeys = subTab.originalForeignKeys> +#segment#${subTab.entityName}Mapper.xml + + + + + + DELETE + FROM ${subTab.tableName} + WHERE + <#list originalForeignKeys as key> + ${key} = ${r'#'}{mainId} <#rt/> + + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai new file mode 100644 index 00000000..43ef9dc4 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai @@ -0,0 +1,54 @@ +package ${bussiPackage}.${entityPackage}.service; + +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import com.baomidou.mybatisplus.extension.service.IService; +import java.io.Serializable; +import java.util.Collection; +import java.util.List; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface I${entityName}Service extends IService<${entityName}> { + + /** + * 添加一对多 + * + * @param ${entityName?uncap_first} + <#list subTables as sub> + * @param ${sub.entityName?uncap_first}List + + */ + public void saveMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,) ; + + /** + * 修改一对多 + * + * @param ${entityName?uncap_first} + <#list subTables as sub> + * @param ${sub.entityName?uncap_first}List + + */ + public void updateMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,); + + /** + * 删除一对多 + * + * @param id + */ + public void delMain (String id); + + /** + * 批量删除一对多 + * + * @param idList + */ + public void delBatchMain (Collection idList); + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/service/[1-n]Service.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/service/[1-n]Service.javai new file mode 100644 index 00000000..cbc72ff4 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/service/[1-n]Service.javai @@ -0,0 +1,25 @@ +<#list subTables as subTab> +#segment#I${subTab.entityName}Service.java +package ${bussiPackage}.${entityPackage}.service; + +import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName}; +import com.baomidou.mybatisplus.extension.service.IService; +import java.util.List; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface I${subTab.entityName}Service extends IService<${subTab.entityName}> { + + /** + * 通过主表id查询子表数据 + * + * @param mainId 主表id + * @return List<${subTab.entityName}> + */ + public List<${subTab.entityName}> selectByMainId(String mainId); +} + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai new file mode 100644 index 00000000..7f99d42e --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai @@ -0,0 +1,105 @@ +package ${bussiPackage}.${entityPackage}.service.impl; + +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.mapper.${sub.entityName}Mapper; + +import ${bussiPackage}.${entityPackage}.mapper.${entityName}Mapper; +import ${bussiPackage}.${entityPackage}.service.I${entityName}Service; +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import java.io.Serializable; +import java.util.List; +import java.util.Collection; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Service +public class ${entityName}ServiceImpl extends ServiceImpl<${entityName}Mapper, ${entityName}> implements I${entityName}Service { + + @Autowired + private ${entityName}Mapper ${entityName?uncap_first}Mapper; + <#list subTables as sub> + @Autowired + private ${sub.entityName}Mapper ${sub.entityName?uncap_first}Mapper; + + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveMain(${entityName} ${entityName?uncap_first}, <#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,) { + ${entityName?uncap_first}Mapper.insert(${entityName?uncap_first}); + <#list subTables as sub> + if(${sub.entityName?uncap_first}List!=null && ${sub.entityName?uncap_first}List.size()>0) { + for(${sub.entityName} entity:${sub.entityName?uncap_first}List) { + <#list sub.foreignKeys as key> + //外键设置 + <#if key?lower_case?index_of("${primaryKeyField}")!=-1> + entity.set${key?cap_first}(${entityName?uncap_first}.get${primaryKeyField?cap_first}()); + <#else> + entity.set${key?cap_first}(${entityName?uncap_first}.get${key}()); + + + ${sub.entityName?uncap_first}Mapper.insert(entity); + } + } + + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,) { + ${entityName?uncap_first}Mapper.updateById(${entityName?uncap_first}); + + //1.先删除子表数据 + <#list subTables as sub> + ${sub.entityName?uncap_first}Mapper.deleteByMainId(${entityName?uncap_first}.getId()); + + + //2.子表数据重新插入 + <#list subTables as sub> + if(${sub.entityName?uncap_first}List!=null && ${sub.entityName?uncap_first}List.size()>0) { + for(${sub.entityName} entity:${sub.entityName?uncap_first}List) { + <#list sub.foreignKeys as key> + //外键设置 + <#if key?lower_case?index_of("${primaryKeyField}")!=-1> + entity.set${key?cap_first}(${entityName?uncap_first}.get${primaryKeyField?cap_first}()); + <#else> + entity.set${key?cap_first}(${entityName?uncap_first}.get${key}()); + + + ${sub.entityName?uncap_first}Mapper.insert(entity); + } + } + + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delMain(String id) { + <#list subTables as sub> + ${sub.entityName?uncap_first}Mapper.deleteByMainId(id); + + ${entityName?uncap_first}Mapper.deleteById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delBatchMain(Collection idList) { + for(Serializable id:idList) { + <#list subTables as sub> + ${sub.entityName?uncap_first}Mapper.deleteByMainId(id.toString()); + + ${entityName?uncap_first}Mapper.deleteById(id); + } + } + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/[1-n]ServiceImpl.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/[1-n]ServiceImpl.javai new file mode 100644 index 00000000..0ce41d36 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/[1-n]ServiceImpl.javai @@ -0,0 +1,30 @@ +<#list subTables as subTab> +#segment#${subTab.entityName}ServiceImpl.java +package ${bussiPackage}.${entityPackage}.service.impl; + +import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName}; +import ${bussiPackage}.${entityPackage}.mapper.${subTab.entityName}Mapper; +import ${bussiPackage}.${entityPackage}.service.I${subTab.entityName}Service; +import org.springframework.stereotype.Service; +import java.util.List; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Service +public class ${subTab.entityName}ServiceImpl extends ServiceImpl<${subTab.entityName}Mapper, ${subTab.entityName}> implements I${subTab.entityName}Service { + + @Autowired + private ${subTab.entityName}Mapper ${subTab.entityName?uncap_first}Mapper; + + @Override + public List<${subTab.entityName}> selectByMainId(String mainId) { + return ${subTab.entityName?uncap_first}Mapper.selectByMainId(mainId); + } +} + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vo/${entityName}Page.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vo/${entityName}Page.javai new file mode 100644 index 00000000..c34e18bd --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vo/${entityName}Page.javai @@ -0,0 +1,117 @@ +package ${bussiPackage}.${entityPackage}.vo; + +import java.util.List; +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +import lombok.Data; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecgframework.poi.excel.annotation.ExcelEntity; +import org.jeecgframework.poi.excel.annotation.ExcelCollection; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import java.util.Date; +import org.jeecg.common.aspect.annotation.Dict; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Data +@Schema(description="${tableVo.ftlDescription}") +public class ${entityName}Page { + + <#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']> + <#assign excel_ignore_classType_arr=['pca','switch','cat_tree']> + <#list originalColumns as po> + <#-- 生成字典Code --> + <#assign list_field_dictCode=""> + <#if po.classType='sel_user'> + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'> + <#elseif po.classType='sel_depart'> + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "depart_name", dicCode = "id"'> + <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dicCode = "${po.dictField}"'> + + <#elseif po.classType=='cat_tree'> + <#assign list_field_dictCode=', dictTable = "sys_category", dicText = "name", dicCode = "id"'> + + /**${po.filedComment}*/ + <#if po.fieldName == primaryKeyField> + <#else> + <#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'> + <#if po.classType=='date'> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + + + <#if list_field_dictCode?length gt 1 && !excel_ignore_classType_arr?seq_contains("${po.classType}")> + @Dict(${list_field_dictCode?substring(2)}) + + + @Schema(description = "${po.filedComment}") + <#if po.fieldDbType=='Blob'> + private java.lang.String ${po.fieldName}String; + <#elseif po.classType=='pca'> + @Excel(name = "${po.filedComment}", width = 15,exportConvert=true,importConvert = true ) + private ${po.fieldType} ${po.fieldName}; + + public String convertis${po.fieldName?cap_first}() { + return SpringContextUtils.getBean(ProvinceCityArea.class).getText(${po.fieldName}); + } + + public void convertset${po.fieldName?cap_first}(String text) { + this.${po.fieldName} = SpringContextUtils.getBean(ProvinceCityArea.class).getCode(text); + } + <#elseif po.classType=='cat_tree'> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + private ${po.fieldType} ${po.fieldName}; + <#elseif po.classType=='switch'> + <#assign switch_extend_arr=['Y','N']> + <#if po.dictField?default("")?contains("[")> + <#assign switch_extend_arr=po.dictField?eval> + + <#list switch_extend_arr as a> + <#if a_index == 0> + <#assign switch_extend_arr1=a> + <#else> + <#assign switch_extend_arr2=a> + + + @Excel(name = "${po.filedComment}", width = 15,replace = {"是_${switch_extend_arr1}","否_${switch_extend_arr2}"} ) + private ${po.fieldType} ${po.fieldName}; + <#else> + private ${po.fieldType} ${po.fieldName}; + + + + <#list subTables as sub> + @ExcelCollection(name="${sub.ftlDescription}") + @Schema(description = "${sub.ftlDescription}") + private List<${sub.entityName}> ${sub.entityName?uncap_first}List; + + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei new file mode 100644 index 00000000..1df3deea --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei @@ -0,0 +1,397 @@ + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql new file mode 100644 index 00000000..5396d5d5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql @@ -0,0 +1 @@ +<#include "/common/sql/menu_insert.ftl"> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei new file mode 100644 index 00000000..e54b9a89 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei @@ -0,0 +1,568 @@ +<#include "/common/utils.ftl"> + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei new file mode 100644 index 00000000..8021bb83 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei @@ -0,0 +1,65 @@ +<#include "/common/utils.ftl"> + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei new file mode 100644 index 00000000..50472872 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei @@ -0,0 +1,196 @@ +<#include "/common/utils.ftl"> +<#list subTables as sub> +<#if sub.foreignRelationType=='1'> +#segment#${sub.entityName}Form.vue + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei new file mode 100644 index 00000000..862b931f --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei @@ -0,0 +1,445 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi new file mode 100644 index 00000000..a3c1bb7c --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi @@ -0,0 +1,75 @@ +import {defHttp} from '/@/utils/http/axios'; +import { useMessage } from "/@/hooks/web/useMessage"; + +const { createConfirm } = useMessage(); + +enum Api { + list = '/${entityPackagePath}/${entityName?uncap_first}/list', + save='/${entityPackagePath}/${entityName?uncap_first}/add', + edit='/${entityPackagePath}/${entityName?uncap_first}/edit', + deleteOne = '/${entityPackagePath}/${entityName?uncap_first}/delete', + deleteBatch = '/${entityPackagePath}/${entityName?uncap_first}/deleteBatch', + importExcel = '/${entityPackagePath}/${entityName?uncap_first}/importExcel', + exportXls = '/${entityPackagePath}/${entityName?uncap_first}/exportXls', +<#list subTables as sub><#rt/> + ${sub.entityName?uncap_first}List = '/${entityPackagePath}/${entityName?uncap_first}/query${sub.entityName}ByMainId', + +} +/** + * 导出api + * @param params + */ +export const getExportUrl = Api.exportXls; + +/** + * 导入api + */ +export const getImportUrl = Api.importExcel; +<#list subTables as sub><#rt/> +/** + * 查询子表数据 + * @param params + */ +export const ${sub.entityName?uncap_first}List = Api.${sub.entityName?uncap_first}List; + +/** + * 列表接口 + * @param params + */ +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(); + }); +} +/** + * 批量删除 + * @param params + */ +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(); + }); + } + }); +} +/** + * 保存或者更新 + * @param params + */ +export const saveOrUpdate = (params, isUpdate,showTip = true) => { + let url = isUpdate ? Api.edit : Api.save; + return defHttp.post({url: url, params},{ successMessageMode :showTip?'success':'none'}); +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi new file mode 100644 index 00000000..b3245add --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi @@ -0,0 +1,988 @@ +<#include "/common/utils.ftl"> +import {BasicColumn} from '/@/components/Table'; +import {FormSchema} from '/@/components/Table'; +import { rules} from '/@/utils/helper/validator'; +import { render } from '/@/utils/common/renderUtils'; +import {JVxeTypes,JVxeColumn} from '/@/components/jeecg/JVxeTable/types' +import { getWeekMonthQuarterYear } from '/@/utils'; +//列表数据 +export const columns: BasicColumn[] = [ + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + { + title: '${po.filedComment}', + align:"center", + <#if po.sort=='Y'> + sorter: true, + + <#if po.classType=='date'> + dataIndex: '${po.fieldName}', + customRender:({text}) =>{ + text = !text ? "" : (text.length > 10 ? text.substr(0,10) : text); + <#if po.extendParams?exists && po.extendParams.picker?exists> + if(text) { + return getWeekMonthQuarterYear(text)['${po.extendParams.picker}']; + } else { + return text; + } + <#else> + return text; + + }, + <#elseif po.fieldDbType=='Blob'> + dataIndex: '${po.fieldName}String' + <#elseif po.classType=='umeditor'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='pca'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='file'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='image'> + dataIndex: '${po.fieldName}', + customRender:render.renderImage, + <#elseif po.classType=='switch'> + dataIndex: '${po.fieldName}', +<#assign switch_extend_arr=['Y','N']> +<#if po.dictField?default("")?contains("[")> +<#assign switch_extend_arr=po.dictField?eval> + +<#list switch_extend_arr as a> +<#if a_index == 0> +<#assign switch_extend_arr1=a> +<#else> +<#assign switch_extend_arr2=a> + + + customRender:({text}) => { + return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]) + }, + <#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user' || po.classType=='popup_dict'> + dataIndex: '${po.fieldName}_dictText' + <#elseif po.classType=='cat_tree'> + dataIndex: '${po.fieldName}', + <#if po.dictText?default("")?trim?length == 0> + customRender:({text}) => { + return render.renderCategoryTree(text,'${po.dictField?default("")}') + }, + <#else> + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') + + <#else> + dataIndex: '${po.fieldName}' + + }, + + +]; +//查询数据 +export const searchFormSchema: FormSchema[] = [ +<#-- 开始循环 --> +<#list columns as po> +<#if po.fieldDbName=='bpm_status'> + <#assign bpm_flag=true> + +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if po.isQuery=='Y' && po.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#assign query_flag=true> + <#assign query_field_dictCode=""> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign query_field_dictCode="${po.dictField}"> + +<#if po.queryMode=='single'> + { + label: "${po.filedComment}", + field: "${po.fieldName}", +<#if po.classType=='sel_search'> + component: 'JSearchSelect', + componentProps:{ + dict:"${query_field_dictCode}" + }, +<#elseif po.classType=='sel_user'> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + component: 'JSelectUser', +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, +<#elseif po.classType=='switch'> + component: 'JSwitch', + componentProps:{ + query:true, + <#if po.dictField != 'is_open'> + options:${po.dictField} + + }, + <#elseif po.classType=='sel_depart'> + component: 'JSelectDept', + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType=='list_multi'> + component: 'JSelectMultiple', + componentProps:{ + <#if po.dictTable?default("")?trim?length gt 1> + dictCode:"${po.dictTable},${po.dictText},${po.dictField}", + <#elseif po.dictField?default("")?trim?length gt 1> + dictCode:"${po.dictField}", + + triggerChange: true + }, + <#elseif po.classType=='cat_tree'> + component: 'JCategorySelect', + componentProps:{ + pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题 + }, +<#elseif po.classType=='date'> + component: 'DatePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueFormat: 'YYYY-MM-DD' + }, +<#elseif po.classType=='datetime'> + component: 'DatePicker', + componentProps: { + showTime:true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, +<#elseif po.classType=='pca'> + component: 'JAreaLinkage', + componentProps: { + saveCode: 'region', + }, +<#elseif po.classType=='popup'> + <#include "/common/form/vue3popup.ftl"> +<#elseif po.classType=='popup_dict'> + component: 'JPopupDict', + componentProps: { + placeholder: '请选择${po.filedComment}', + dictCode: '${po.dictTable},${po.dictText},${po.dictField}', + multi: ${po.extendParams.popupMulti?c} + }, +<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'> +<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- --> + component: 'JSelectMultiple', + componentProps:{ + <#if po.dictTable?default("")?trim?length gt 1> + dictCode:"${po.dictTable},${po.dictText},${po.dictField}" + <#elseif po.dictField?default("")?trim?length gt 1> + dictCode:"${po.dictField}" + + }, +<#elseif po.classType == 'sel_tree'> + component: 'JTreeSelect', + componentProps:{ + <#if po.dictText??> + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", + <#elseif po.dictText?split(',')[1]??> + pidField:"${po.dictText?split(',')[1]}", + <#elseif po.dictText?split(',')[3]??> + hasChildField:"${po.dictText?split(',')[3]}", + + + pidValue:"${po.dictField}", + }, +<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'InputNumber', +<#else> + component: 'Input', + + //colProps: {span: 6}, + }, +<#elseif po.queryMode=='like'> + { + label: "${po.filedComment}", + field: "${po.fieldName}", + component: 'JInput', + }, +<#else> + { + label: "${po.filedComment}", + field: "${po.fieldName}", +<#if po.classType=='date'> + component: 'RangePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueType: 'Date', + }, +<#elseif po.classType=='datetime'> + component: 'RangePicker', + componentProps: { + valueType: 'Date', + showTime:true + }, +<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'JRangeNumber', +<#-- update-begin---author:chenrui ---date:20240527 for:[TV360X-388]时间范围查询控件---------- --> +<#elseif po.classType=='time'> + component: 'RangeTime', +<#-- update-end---author:chenrui ---date:20240527 for:[TV360X-388]时间范围查询控件---------- --> +<#else> + component: 'Input', //TODO 范围查询 + + //colProps: {span: 6}, + }, + + + +<#-- 结束循环 --> +]; +//表单数据 +export const formSchema: FormSchema[] = [ +<#assign form_cat_tree = false> +<#assign form_cat_back = ""> +<#assign bpm_flag=false> +<#assign id_exists = false> +<#list columns as po><#rt/> +<#if po.fieldDbName=='bpm_status'> + <#assign bpm_flag=true> + +<#if po.fieldDbName == 'id'> + <#assign id_exists = true> + +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if po.isShow =='Y' && po.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#assign form_field_dictCode=""> + <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictField}"> + + { + label: '${po.filedComment}', + field: ${autoStringSuffix(po)}, +<#-- update-begin-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.defaultVal??> + <#if po.fieldDbType=="BigDecimal" || po.fieldDbType=="double" || po.fieldDbType=="int"> + defaultValue: ${po.defaultVal}, + <#else> + defaultValue: "${po.defaultVal}", + + +<#-- update-end-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.classType =='date'> + component: 'DatePicker', + componentProps:{ + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueFormat: 'YYYY-MM-DD' + }, + <#elseif po.classType =='datetime'> + component: 'DatePicker', + componentProps: { + showTime:true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, + <#elseif po.classType =='time'> + component: 'TimePicker', + componentProps: { + valueFormat: 'HH:mm:ss' + }, + <#elseif po.classType =='popup'> + <#include "/common/form/vue3popup.ftl"> + <#elseif po.classType=='popup_dict'> + component: 'JPopupDict', + componentProps: { + placeholder: '请选择${po.filedComment}', + dictCode: '${po.dictTable},${po.dictText},${po.dictField}', + multi: ${po.extendParams.popupMulti?c} + }, + <#elseif po.classType =='sel_depart'> + component: 'JSelectDept', + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='switch'> + component: 'JSwitch', + componentProps:{ + <#if po.dictField != 'is_open'> + options:${po.dictField} + + }, + <#elseif po.classType =='pca'> + component: 'JAreaLinkage', + componentProps: { + saveCode: 'region', + }, + <#elseif po.classType =='markdown'> + component: 'JMarkdownEditor',//注意string转换问题 + <#elseif po.classType =='password'> + component: 'InputPassword', + <#elseif po.classType =='sel_user'> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件------------- --> + component: 'JSelectUser', +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件------------- --> + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='textarea'> + component: 'InputTextArea', + <#elseif po.classType=='list'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#elseif po.classType=='radio'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + type: "radio", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='list_multi'> + component: 'JSelectMultiple', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#elseif po.classType=='checkbox'> + component: 'JCheckbox', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='sel_search'> + component: 'JSearchSelect', + componentProps:{ + dict:"${form_field_dictCode}" + }, +<#elseif po.classType=='cat_tree'> + <#assign form_cat_tree = true> + component: 'JCategorySelect', + componentProps:{ + pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题 + }, + <#if po.dictText?default("")?trim?length gt 1> + <#assign form_cat_back = "${po.dictText}"> + + <#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'InputNumber', + <#elseif po.classType=='file'> + component: 'JUpload', + componentProps:{ + <#if po.uploadnum??> + maxCount:${po.uploadnum} + + }, + <#elseif po.classType=='image'> + component: 'JImageUpload', + componentProps:{ + <#if po.uploadnum??> + fileMax:${po.uploadnum} + <#else> + fileMax: 0 + + }, + <#elseif po.classType=='umeditor'> + component: 'JEditor', + <#elseif po.classType == 'sel_tree'> + component: 'JTreeSelect', + componentProps:{ + <#if po.dictText??> + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", + <#elseif po.dictText?split(',')[1]??> + pidField:"${po.dictText?split(',')[1]}", + <#elseif po.dictText?split(',')[3]??> + hasChildField:"${po.dictText?split(',')[3]}", + + + pidValue:"${po.dictField}", + }, + <#elseif po.classType=='link_table'> + component: 'JLinkTableCard', + componentProps: { + valueField: '${po.dictField}', + textField: '${po.dictText}', + tableName: '${po.dictTable}', + multi: <#if (po.queryMode!"") == "multi">true<#else>false + }, + <#else> + component: 'Input', + + <#include "/common/utils.ftl"> + <#if po.isShow == 'Y' && poHasCheck(po)> + dynamicRules: ({model,schema}) => { + <#if po.fieldName != 'id'> + <#assign fieldValidType = po.fieldValidType!''> + return [ + <#-- 非空校验 --> + <#if po.nullable == 'N' || fieldValidType == '*'> + { required: true, message: '请输入${po.filedComment}!'}, + <#elseif fieldValidType!=''> + { required: false}, + + <#-- 唯一校验 --> + <#if fieldValidType == 'only'> + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}', '${po.fieldDbName}',model,schema)[0]}, + <#-- 6到16位数字 --> + <#elseif fieldValidType == 'n6-16'> + { pattern: /^\d{6,16}$|^(?=\d+\.\d+)[\d.]{7,17}$/, message: '请输入6到16位数字!'}, + <#-- 6到16位任意字符 --> + <#elseif fieldValidType == '*6-16'> + { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, + <#-- 6到18位字母 --> + <#elseif fieldValidType == 's6-18'> + { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, + <#-- 网址 --> + <#elseif fieldValidType == 'url'> + { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, + <#-- 电子邮件 --> + <#elseif fieldValidType == 'e'> + { pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'}, + <#-- 手机号码 --> + <#elseif fieldValidType == 'm'> + { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}, + <#-- 邮政编码 --> + <#elseif fieldValidType == 'p'> + { pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'}, + <#-- 字母 --> + <#elseif fieldValidType == 's'> + { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}, + <#-- 数字 --> + <#elseif fieldValidType == 'n'> + { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'}, + <#-- 整数 --> + <#elseif fieldValidType == 'z'> + { pattern: /^-?\d+$/, message: '请输入整数!'}, + <#-- 金额 --> + <#elseif fieldValidType == 'money'> + { pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'}, + <#-- 正则校验 --> + <#elseif fieldValidType != '' && fieldValidType != '*'> + { pattern: '${fieldValidType}', message: '不符合校验规则!'}, + <#-- 无校验 --> + <#else> + <#t> + + ]; + + }, + + <#if po.readonly=='Y'> + dynamicDisabled:true + + }, + + +<#if id_exists == false> + // TODO 主键隐藏字段,目前写死为ID + { + label: '', + field: 'id', + component: 'Input', + show: false + }, + +]; +//子表单数据 +<#list subTables as sub> +<#if sub.foreignRelationType =='1'> +export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ +<#assign form_cat_tree = false> +<#assign form_cat_back = ""> +<#assign bpm_flag=false> +<#assign sub_id_exists=false> +<#list sub.colums as po><#rt/> +<#if po.fieldDbName=='bpm_status'> + <#assign bpm_flag=true> + +<#if po.fieldDbName=='id'> + <#assign sub_id_exists=true> + +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if po.isShow =='Y' && po.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#assign form_field_dictCode=""> + <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictField}"> + + { + label: '${po.filedComment}', + field: ${autoStringSuffix(po)}, +<#-- update-begin-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.defaultVal??> + <#if po.fieldDbType=="BigDecimal" || po.fieldDbType=="double" || po.fieldDbType=="int"> + defaultValue: ${po.defaultVal}, + <#else> + defaultValue: "${po.defaultVal}", + + +<#-- update-end-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.classType =='date'> + component: 'DatePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueFormat: 'YYYY-MM-DD' + }, + <#elseif po.classType =='datetime'> + component: 'DatePicker', + componentProps: { + showTime:true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, + <#elseif po.classType =='time'> + component: 'TimePicker', + componentProps: { + valueFormat: 'HH:mm:ss' + }, + <#elseif po.classType =='popup'> + <#include "/common/form/vue3popup.ftl"> + <#elseif po.classType=='popup_dict'> + component: 'JPopupDict', + componentProps: { + placeholder: '请选择${po.filedComment}', + dictCode: '${po.dictTable},${po.dictText},${po.dictField}', + multi: ${po.extendParams.popupMulti?c} + }, + <#elseif po.classType =='sel_depart'> + component: 'JSelectDept', + <#elseif po.classType =='switch'> + component: 'JSwitch', + componentProps:{ + <#if po.dictField != 'is_open'> + options:${po.dictField} + + }, + <#elseif po.classType =='pca'> + component: 'JAreaLinkage', + componentProps: { + saveCode: 'region', + }, + <#elseif po.classType =='markdown'> + component: 'JMarkdownEditor',//注意string转换问题 + <#elseif po.classType =='password'> + component: 'InputPassword', + <#elseif po.classType =='sel_user'> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件------------- --> + component: 'JSelectUser', +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件------------- --> + componentProps:{ + labelKey:'realname', + }, + <#elseif po.classType =='textarea'> + component: 'InputTextArea', + <#elseif po.classType=='list'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#elseif po.classType=='radio'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + type: "radio", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='list_multi'> + component: 'JSelectMultiple', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#elseif po.classType=='checkbox'> + component: 'JCheckbox', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='sel_search'> + component: 'JSearchSelect', + componentProps:{ + dict:"${form_field_dictCode}" + }, +<#elseif po.classType=='cat_tree'> + <#assign form_cat_tree = true> + component: 'JCategorySelect', + componentProps:{ + pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题 + }, + <#if po.dictText?default("")?trim?length gt 1> + <#assign form_cat_back = "${po.dictText}"> + + <#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'InputNumber', + <#elseif po.classType=='file'> + component: 'JUpload', + componentProps:{ + <#if po.uploadnum??> + maxCount:${po.uploadnum} + + }, + <#elseif po.classType=='image'> + component: 'JImageUpload', + componentProps:{ + <#if po.uploadnum??> + fileMax:${po.uploadnum} + <#else> + fileMax: 0 + + }, + <#elseif po.classType=='umeditor'> + component: 'JEditor', + <#elseif po.classType == 'sel_tree'> + component: 'JTreeSelect', + componentProps:{ + <#if po.dictText??> + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", + <#elseif po.dictText?split(',')[1]??> + pidField:"${po.dictText?split(',')[1]}", + <#elseif po.dictText?split(',')[3]??> + hasChildField:"${po.dictText?split(',')[3]}", + + + pidValue:"${po.dictField}", + }, + <#elseif po.classType=='link_table'> + component: 'JLinkTableCard', + componentProps: { + valueField: '${po.dictField}', + textField: '${po.dictText}', + tableName: '${po.dictTable}', + multi: <#if (po.queryMode!"") == "multi">true<#else>false + }, + <#else> + component: 'Input', + + <#include "/common/utils.ftl"> + <#if po.isShow == 'Y' && poHasCheck(po)> + dynamicRules: ({model,schema}) => { + <#if po.fieldName != 'id'> + <#assign fieldValidType = po.fieldValidType!''> + return [ + <#-- 非空校验 --> + <#if po.nullable == 'N' || fieldValidType == '*'> + { required: true, message: '请输入${po.filedComment}!'}, + <#elseif fieldValidType!=''> + { required: false}, + + <#-- 唯一校验 --> + <#if fieldValidType == 'only'> + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}', '${po.fieldDbName}',model,schema)[0]}, + <#-- 6到16位数字 --> + <#elseif fieldValidType == 'n6-16'> + { pattern: /^\d{6,16}$|^(?=\d+\.\d+)[\d.]{7,17}$/, message: '请输入6到16位数字!'}, + <#-- 6到16位任意字符 --> + <#elseif fieldValidType == '*6-16'> + { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, + <#-- 6到18位字母 --> + <#elseif fieldValidType == 's6-18'> + { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, + <#-- 网址 --> + <#elseif fieldValidType == 'url'> + { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, + <#-- 电子邮件 --> + <#elseif fieldValidType == 'e'> + { pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'}, + <#-- 手机号码 --> + <#elseif fieldValidType == 'm'> + { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}, + <#-- 邮政编码 --> + <#elseif fieldValidType == 'p'> + { pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'}, + <#-- 字母 --> + <#elseif fieldValidType == 's'> + { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}, + <#-- 数字 --> + <#elseif fieldValidType == 'n'> + { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'}, + <#-- 整数 --> + <#elseif fieldValidType == 'z'> + { pattern: /^-?\d+$/, message: '请输入整数!'}, + <#-- 金额 --> + <#elseif fieldValidType == 'money'> + { pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'}, + <#-- 正则校验 --> + <#elseif fieldValidType != '' && fieldValidType != '*'> + { pattern: '${fieldValidType}', message: '不符合校验规则!'}, + <#-- 无校验 --> + <#else> + <#t> + + ]; + + }, + + <#if po.readonly=='Y'> + dynamicDisabled:true + + }, + + +<#if sub_id_exists == false> + { + label: '', + field: 'id', + component: 'Input', + show: false + }, + +]; + + +//子表表格配置 +<#list subTables as sub> +<#if sub.foreignRelationType =='0'> +export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [ +<#assign popupBackFields = ""> + +<#-- 循环子表的列 开始 --> +<#list sub.colums as col><#rt/> +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if col.isShow =='Y' && col.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if col.filedComment !='外键' > + { + title: '${col.filedComment}', + key: '${autoStringSuffixForModel(col)}', +<#if col.classType =='date'> + type: JVxeTypes.date, + <#if col.extendParams?exists && col.extendParams.picker?exists> + picker: '${col.extendParams.picker}', + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='datetime'> + type: JVxeTypes.datetime, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='time'> + type: JVxeTypes.time, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='textarea'> + type: JVxeTypes.textarea, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='list' || col.classType =='radio'> + type: JVxeTypes.select, + options:[], + <#if col.dictTable?default("")?trim?length gt 1> + dictCode:"${col.dictTable},${col.dictText},${col.dictField}", + <#else> + dictCode:"${col.dictField}", + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='list_multi' || col.classType =='checkbox'> + type: JVxeTypes.selectMultiple, + options:[], + <#if col.dictTable?default("")?trim?length gt 1> + dictCode:"${col.dictTable},${col.dictText},${col.dictField}", + <#else> + dictCode:"${col.dictField}", + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='sel_search'> + type: JVxeTypes.selectSearch, + <#if col.dictTable?default("")?trim?length gt 1> + dictCode:"${col.dictTable},${col.dictText},${col.dictField}", + <#else> + dictCode:"${col.dictField}", + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='sel_depart'> + type: JVxeTypes.departSelect, + props:{ + <#if col.extendParams?exists && col.extendParams.text?exists> + labelKey: '${col.extendParams.text}', + + <#if col.extendParams?exists && col.extendParams.store?exists> + rowKey: '${col.extendParams.store}', + + }, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='sel_user'> + type: JVxeTypes.userSelect, + props:{ + <#if col.extendParams?exists && col.extendParams.text?exists> + labelKey: '${col.extendParams.text}', + + <#if col.extendParams?exists && col.extendParams.store?exists> + rowKey: '${col.extendParams.store}', + + }, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='image'> + type: JVxeTypes.image, + token:true, + responseName:"message", + <#if col.readonly=='Y'> + disabled:true, + + <#if col.uploadnum??> + number: ${col.uploadnum}, + +<#elseif col.classType =='file'> + type: JVxeTypes.file, + token:true, + responseName:"message", + <#if col.readonly=='Y'> + disabled:true, + + <#if col.uploadnum??> + number: ${col.uploadnum}, + +<#elseif col.classType =='switch'> + type: JVxeTypes.checkbox, + <#if col.dictField == 'is_open'> + customValue: ['Y', 'N'], + <#else> + customValue: ${col.dictField}, + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType=='pca'> + type: JVxeTypes.pca, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='popup'> +<#if popupBackFields?length gt 0> + <#assign popupBackFields = "${popupBackFields}"+","+"${col.dictText}"> +<#else> + <#assign popupBackFields = "${col.dictText}"> + + <#include "/common/form/vue3Jvxepopup.ftl"> +<#-- update-begin-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> +<#-- elseif "int,decimal,double,"?contains(col.classType) --> +<#elseif col.fieldDbType=='int' || col.fieldDbType=='long' || col.fieldDbType=='double' || col.fieldDbType=='BigDecimal'> +<#-- update-end-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> + type: JVxeTypes.inputNumber, + <#if col.readonly=='Y'> + disabled:true, + +<#else> + type: JVxeTypes.input, + <#if col.readonly=='Y'> + disabled:true, + + +<#if col.classType =='list_multi' || col.classType =='checkbox'> + width:"250px", +<#else> + width:"200px", + +<#if col.classType =='file'> + placeholder: '请选择文件', +<#else> + placeholder: '请输入${'$'}{title}', + +<#if col.defaultVal??> +<#if col.fieldDbType=="BigDecimal" || col.fieldDbType=="double" || col.fieldDbType=="int"> + defaultValue:${col.defaultVal}, + <#else> + defaultValue:"${col.defaultVal}", + +<#else> + defaultValue:'', + +<#-- 子表的校验 --> + <#include "/common/validatorRulesTemplate/sub-vue3.ftl"> + }, + + + +<#-- 循环子表的列 结束 --> + ] + + + + +<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> +// 高级查询数据 +export const superQuerySchema = { + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + ${superQueryFieldListForVue3(po,po_index)}, + + + //子表高级查询 + <#list subTables as sub> + ${sub.entityName?uncap_first}: { + title: '${sub.ftlDescription}', + view: 'table', + fields: { + <#list sub.colums as subCol> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if subCol.isShowList =='Y' && subCol.fieldName !='id' && subCol.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + ${superQueryFieldListForVue3(subCol,subCol_index)}, + + + } + }, + +}; +<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> + +/** +* 流程表单调用这个方法获取formSchema +* @param param +*/ +export function getBpmFormSchema(_formData): FormSchema[]{ +// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema + return formSchema; +} \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql new file mode 100644 index 00000000..7292339d --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql @@ -0,0 +1 @@ +<#include "/common/sql/menu_insert.ftl"> diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Form.vuei new file mode 100644 index 00000000..eff0ab39 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Form.vuei @@ -0,0 +1,209 @@ +<#include "/common/utils.ftl"> + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei new file mode 100644 index 00000000..a3698d0b --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei @@ -0,0 +1,278 @@ +<#include "/common/utils.ftl"> + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei new file mode 100644 index 00000000..9bf73fa0 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei @@ -0,0 +1,87 @@ +<#include "/common/utils.ftl"> +<#list subTables as sub> +<#if sub.foreignRelationType=='1'> +#segment#${sub.entityName}Form.vue + + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei new file mode 100644 index 00000000..95ff8e5f --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei @@ -0,0 +1,582 @@ +<#include "/common/utils.ftl"> + + +<#if query_flag> + + + + 查询 + 重置 + + {{ toggleSearchStatus ? '收起' : '展开' }} + + + + + + + + + +<#-- 结束循环 --> + + + + + + + + + + + <${entityName}Modal @register="registerModal" @success="handleSuccess"> + <#if bpm_flag==true> + + + + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi new file mode 100644 index 00000000..6762659f --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi @@ -0,0 +1,85 @@ +import {defHttp} from '/@/utils/http/axios'; +import { useMessage } from "/@/hooks/web/useMessage"; + +const { createConfirm } = useMessage(); + +enum Api { + list = '/${entityPackagePath}/${entityName?uncap_first}/list', + save='/${entityPackagePath}/${entityName?uncap_first}/add', + edit='/${entityPackagePath}/${entityName?uncap_first}/edit', + deleteOne = '/${entityPackagePath}/${entityName?uncap_first}/delete', + deleteBatch = '/${entityPackagePath}/${entityName?uncap_first}/deleteBatch', + importExcel = '/${entityPackagePath}/${entityName?uncap_first}/importExcel', + exportXls = '/${entityPackagePath}/${entityName?uncap_first}/exportXls', + queryDataById = '/${entityPackagePath}/${entityName?uncap_first}/queryById', +<#list subTables as sub><#rt/> + ${sub.entityName?uncap_first}List = '/${entityPackagePath}/${entityName?uncap_first}/query${sub.entityName}ByMainId', + +} +/** + * 导出api + * @param params + */ +export const getExportUrl = Api.exportXls; + +/** + * 导入api + */ +export const getImportUrl = Api.importExcel; + +<#list subTables as sub><#rt/> +/** + * 查询子表数据 + * @param params + */ +export const query${sub.entityName}ListByMainId = (id) => defHttp.get({url: Api.${sub.entityName?uncap_first}List, params:{ id }}); + + +/** + * 列表接口 + * @param params + */ +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(); + }); +} +/** + * 批量删除 + * @param params + */ +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(); + }); + } + }); +} +/** + * 保存或者更新 + * @param params + */ +export const saveOrUpdate = (params, isUpdate) => { + let url = isUpdate ? Api.edit : Api.save; + return defHttp.post({url: url, params}); +} + +/** +* 根据id查询数据 +* @param params +*/ +export const queryDataById = (id) => defHttp.get({url: Api.queryDataById, params:{ id }}); + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi new file mode 100644 index 00000000..89ec48cd --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi @@ -0,0 +1,273 @@ +<#include "/common/utils.ftl"> +import {BasicColumn} from '/@/components/Table'; +import {FormSchema} from '/@/components/Table'; +import { rules} from '/@/utils/helper/validator'; +import { render } from '/@/utils/common/renderUtils'; +import {JVxeTypes,JVxeColumn} from '/@/components/jeecg/JVxeTable/types' +import { getWeekMonthQuarterYear } from '/@/utils'; +//列表数据 +export const columns: BasicColumn[] = [ + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + { + title: '${po.filedComment}', + align:"center", + <#if po.sort=='Y'> + sorter: true, + + <#if po.classType=='date'> + dataIndex: '${po.fieldName}', + customRender:({text}) =>{ + text = !text ? "" : (text.length > 10 ? text.substr(0,10) : text); + <#if po.extendParams?exists && po.extendParams.picker?exists> + if(text) { + return getWeekMonthQuarterYear(text)['${po.extendParams.picker}']; + } else { + return text; + } + <#else> + return text; + + }, + <#elseif po.fieldDbType=='Blob'> + dataIndex: '${po.fieldName}String' + <#elseif po.classType=='umeditor'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='pca'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='file'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='image'> + dataIndex: '${po.fieldName}', + customRender:render.renderImage, + <#elseif po.classType=='switch'> + dataIndex: '${po.fieldName}', +<#assign switch_extend_arr=['Y','N']> +<#if po.dictField?default("")?contains("[")> +<#assign switch_extend_arr=po.dictField?eval> + +<#list switch_extend_arr as a> +<#if a_index == 0> +<#assign switch_extend_arr1=a> +<#else> +<#assign switch_extend_arr2=a> + + + customRender:({text}) => { + return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]) + }, + <#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user' || po.classType=='popup_dict'> + dataIndex: '${po.fieldName}_dictText' + <#elseif po.classType=='cat_tree'> + dataIndex: '${po.fieldName}', + <#if po.dictText?default("")?trim?length == 0> + customRender:({text}) => { + return render.renderCategoryTree(text,'${po.dictField?default("")}') + }, + <#else> + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') + + <#else> + dataIndex: '${po.fieldName}' + + }, + + +]; + +//子表表格配置 +<#list subTables as sub> +<#if sub.foreignRelationType =='0'> +export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [ +<#assign popupBackFields = ""> + +<#-- 循环子表的列 开始 --> +<#list sub.colums as col><#rt/> +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if col.isShow =='Y' && col.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if col.filedComment !='外键' > + { + title: '${col.filedComment}', + key: '${autoStringSuffixForModel(col)}', +<#if col.classType =='date'> + type: JVxeTypes.date, + <#if col.extendParams?exists && col.extendParams.picker?exists> + picker: '${col.extendParams.picker}', + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='datetime'> + type: JVxeTypes.datetime, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='time'> + type: JVxeTypes.time, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='textarea'> + type: JVxeTypes.textarea, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='list' || col.classType =='radio'> + type: JVxeTypes.select, + options:[], + <#if col.dictTable?default("")?trim?length gt 1> + dictCode:"${col.dictTable},${col.dictText},${col.dictField}", + <#else> + dictCode:"${col.dictField}", + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='list_multi' || col.classType =='checkbox'> + type: JVxeTypes.selectMultiple, + options:[], + <#if col.dictTable?default("")?trim?length gt 1> + dictCode:"${col.dictTable},${col.dictText},${col.dictField}", + <#else> + dictCode:"${col.dictField}", + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='sel_search'> + type: JVxeTypes.selectSearch, + <#if col.dictTable?default("")?trim?length gt 1> + dictCode:"${col.dictTable},${col.dictText},${col.dictField}", + <#else> + dictCode:"${col.dictField}", + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='sel_depart'> + type: JVxeTypes.departSelect, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='sel_user'> + type: JVxeTypes.userSelect, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='image'> + type: JVxeTypes.image, + token:true, + responseName:"message", + <#if col.readonly=='Y'> + disabled:true, + + <#if col.uploadnum??> + number: ${col.uploadnum}, + +<#elseif col.classType =='file'> + type: JVxeTypes.file, + token:true, + responseName:"message", + <#if col.readonly=='Y'> + disabled:true, + + <#if col.uploadnum??> + number: ${col.uploadnum}, + +<#elseif col.classType =='switch'> + type: JVxeTypes.checkbox, + <#if col.dictField == 'is_open'> + customValue: ['Y', 'N'], + <#else> + customValue: ${col.dictField}, + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType=='pca'> + type: JVxeTypes.pca, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='popup'> +<#if popupBackFields?length gt 0> + <#assign popupBackFields = "${popupBackFields}"+","+"${col.dictText}"> +<#else> + <#assign popupBackFields = "${col.dictText}"> + + <#include "/common/form/vue3Jvxepopup.ftl"> +<#-- update-begin-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> +<#-- elseif "int,decimal,double,"?contains(col.classType) --> +<#elseif col.fieldDbType=='int' || col.fieldDbType=='long' || col.fieldDbType=='double' || col.fieldDbType=='BigDecimal'> +<#-- update-end-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> + type: JVxeTypes.inputNumber, + <#if col.readonly=='Y'> + disabled:true, + +<#else> + type: JVxeTypes.input, + <#if col.readonly=='Y'> + disabled:true, + + +<#if col.classType =='list_multi' || col.classType =='checkbox'> + width:"250px", +<#else> + width:"200px", + +<#if col.classType =='file'> + placeholder: '请选择文件', +<#else> + placeholder: '请输入${'$'}{title}', + +<#if col.defaultVal??> +<#if col.fieldDbType=="BigDecimal" || col.fieldDbType=="double" || col.fieldDbType=="int"> + defaultValue:${col.defaultVal}, + <#else> + defaultValue:"${col.defaultVal}", + +<#else> + defaultValue:'', + +<#-- 子表的校验 --> + <#include "/common/validatorRulesTemplate/sub-vue3.ftl"> + }, + + + +<#-- 循环子表的列 结束 --> + ] + + + +<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> +// 高级查询数据 +export const superQuerySchema = { + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + ${superQueryFieldListForVue3(po,po_index)}, + + + //子表高级查询 + <#list subTables as sub> + ${sub.entityName?uncap_first}: { + title: '${sub.ftlDescription}', + view: 'table', + fields: { + <#list sub.colums as subCol> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if subCol.isShowList =='Y' && subCol.fieldName !='id' && subCol.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + ${superQueryFieldListForVue3(subCol,subCol_index)}, + + + } + }, + +}; +<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/V${currentDate}_1__menu_insert_${entityName}.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/V${currentDate}_1__menu_insert_${entityName}.sql new file mode 100644 index 00000000..5396d5d5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/V${currentDate}_1__menu_insert_${entityName}.sql @@ -0,0 +1 @@ +<#include "/common/sql/menu_insert.ftl"> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei new file mode 100644 index 00000000..24cbc013 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei @@ -0,0 +1,412 @@ +<#include "/common/utils.ftl"> +<#assign need_category = false> +<#assign bpm_flag=false> +<#assign need_pca = false> +<#assign need_search = false> +<#assign need_dept_user = false> +<#assign need_switch = false> +<#assign need_dept = false> +<#assign need_multi = false> +<#assign need_popup = false> +<#assign need_popup_dict = false> +<#assign need_select_tag = false> +<#assign need_select_tree = false> +<#assign need_time = false> +<#assign need_markdown = false> +<#assign need_upload = false> +<#assign need_image_upload = false> +<#assign need_editor = false> +<#assign need_checkbox = false> +<#assign need_range_number = false> +<#assign is_like = false> +<#assign form_span = 24> +<#if tableVo.fieldRowNum==2> + <#assign form_span = 12> +<#elseif tableVo.fieldRowNum==3> + <#assign form_span = 8> +<#elseif tableVo.fieldRowNum==4> + <#assign form_span = 6> + +<#assign hasOne2manyTable = false> +<#assign subTabActiveKey = ''> +<#assign subMainFieldMap={}> +<#assign subTableColumnsKey=[]> +<#assign hasOnlyValidate = false> + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei new file mode 100644 index 00000000..1a3a8dde --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei @@ -0,0 +1,97 @@ +<#include "/common/utils.ftl"> + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/[1-n]Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/[1-n]Form.vuei new file mode 100644 index 00000000..4a2e3697 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/[1-n]Form.vuei @@ -0,0 +1,185 @@ +<#include "/common/utils.ftl"> +<#list subTables as sub> +<#if sub.foreignRelationType=='1'> +#segment#${sub.entityName}Form.vue +<#include "/common/utils.ftl"> +<#assign need_category = false> +<#assign bpm_flag=false> +<#assign need_pca = false> +<#assign need_search = false> +<#assign need_dept_user = false> +<#assign need_switch = false> +<#assign need_dept = false> +<#assign need_multi = false> +<#assign need_popup = false> +<#assign need_popup_dict = false> +<#assign need_select_tag = false> +<#assign need_select_tree = false> +<#assign need_time = false> +<#assign need_markdown = false> +<#assign need_upload = false> +<#assign need_image_upload = false> +<#assign need_editor = false> +<#assign need_checkbox = false> +<#assign need_range_number = false> +<#assign is_like = false> +<#assign form_span = 24> +<#if tableVo.fieldRowNum==2> + <#assign form_span = 12> +<#elseif tableVo.fieldRowNum==3> + <#assign form_span = 8> +<#elseif tableVo.fieldRowNum==4> + <#assign form_span = 6> + + <#assign hasOnlyValidate = false> + + + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai new file mode 100644 index 00000000..3c513ee7 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -0,0 +1,365 @@ +package ${bussiPackage}.${entityPackage}.controller; + +import java.io.UnsupportedEncodingException; +import java.io.IOException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.HashMap; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.jeecg.common.system.vo.LoginUser; +import org.apache.shiro.SecurityUtils; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.common.system.query.QueryRuleEnum; +import org.jeecg.common.util.oConvertUtils; +import org.jeecgframework.poi.excel.entity.enmus.ExcelType; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import ${bussiPackage}.${entityPackage}.vo.${entityName}Page; +import ${bussiPackage}.${entityPackage}.service.I${entityName}Service; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.service.I${sub.entityName}Service; + +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import com.alibaba.fastjson.JSON; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import org.jeecg.common.aspect.annotation.AutoLog; +import org.apache.shiro.authz.annotation.RequiresPermissions; +<#assign has_multi_query_field=false> +<#list originalColumns as po> +<#if po.isQuery=='Y' && (po.classType=='list' || po.classType=='list_multi' || po.classType=='radio' || po.classType=='checkbox')> + <#assign has_multi_query_field=true> + + +<#assign enhanceJavaList=[]> +<#if tableVo.extendParams?? && tableVo.extendParams.enhanceJavaList??> + <#assign enhanceJavaList = tableVo.extendParams.enhanceJavaList?filter(enhance -> enhance??)> + + /** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Tag(name="${tableVo.ftlDescription}") +@RestController +@RequestMapping("/${entityPackagePath}/${entityName?uncap_first}") +@Slf4j +public class ${entityName}Controller { + @Autowired + private I${entityName}Service ${entityName?uncap_first}Service; + <#list subTables as sub> + @Autowired + private I${sub.entityName}Service ${sub.entityName?uncap_first}Service; + + + /** + * 分页列表查询 + * + * @param ${entityName?uncap_first} + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "${tableVo.ftlDescription}-分页列表查询") + @Operation(summary="${tableVo.ftlDescription}-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(${entityName} ${entityName?uncap_first}, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='query' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 查询前触发的方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeQuery() + + + + <#if has_multi_query_field> + // 自定义查询规则 + Map customeRuleMap = new HashMap<>(); + // 自定义多选的查询规则为:LIKE_WITH_OR + <#list originalColumns as po> + <#if po.isQuery=='Y' && (po.classType=='list' || po.classType=='list_multi' || po.classType=='radio' || po.classType=='checkbox')> + customeRuleMap.put("${po.fieldName}", QueryRuleEnum.LIKE_WITH_OR); + + + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap(),customeRuleMap); + <#else> + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap()); + + Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize); + IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper); + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='query' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'> + //TODO 查询后触发的方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.afterQuery() + + + + return Result.OK(pageList); + } + + /** + * 添加 + * + * @param ${entityName?uncap_first}Page + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-添加") + @Operation(summary="${tableVo.ftlDescription}-添加") + @RequiresPermissions("${entityPackage}:${tableName}:add") + @PostMapping(value = "/add") + public Result add(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='add' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 新增前的处理方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeAdd() + + + + ${entityName} ${entityName?uncap_first} = new ${entityName}(); + BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first}); + ${entityName?uncap_first}Service.saveMain(${entityName?uncap_first}, <#list subTables as sub>${entityName?uncap_first}Page.get${sub.entityName}List()<#if sub_has_next>,); + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='add' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'> + //TODO 新增后的处理方法,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.afterAdd() + + + + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * + * @param ${entityName?uncap_first}Page + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-编辑") + @Operation(summary="${tableVo.ftlDescription}-编辑") + @RequiresPermissions("${entityPackage}:${tableName}:edit") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) + public Result edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 编辑前,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeEdit() + + + + ${entityName} ${entityName?uncap_first} = new ${entityName}(); + BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first}); + ${entityName} ${entityName?uncap_first}Entity = ${entityName?uncap_first}Service.getById(${entityName?uncap_first}.getId()); + if(${entityName?uncap_first}Entity==null) { + return Result.error("未找到对应数据"); + } + ${entityName?uncap_first}Service.updateMain(${entityName?uncap_first}, <#list subTables as sub>${entityName?uncap_first}Page.get${sub.entityName}List()<#if sub_has_next>,); + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='edit' && enhanceJava.event=='end' && enhanceJava.activeStatus=='1'> + //TODO 编辑后,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.afterEdit() + + + + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-通过id删除") + @Operation(summary="${tableVo.ftlDescription}-通过id删除") + @RequiresPermissions("${entityPackage}:${tableName}:delete") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name="id",required=true) String id) { + ${entityName?uncap_first}Service.delMain(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "${tableVo.ftlDescription}-批量删除") + @Operation(summary="${tableVo.ftlDescription}-批量删除") + @RequiresPermissions("${entityPackage}:${tableName}:deleteBatch") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + this.${entityName?uncap_first}Service.delBatchMain(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "${tableVo.ftlDescription}-通过id查询") + @Operation(summary="${tableVo.ftlDescription}-通过id查询") + @GetMapping(value = "/queryById") + public Result<${entityName}> queryById(@RequestParam(name="id",required=true) String id) { + ${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id); + if(${entityName?uncap_first}==null) { + return Result.error("未找到对应数据"); + } + return Result.OK(${entityName?uncap_first}); + + } + + <#list subTables as sub> + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "${sub.ftlDescription}通过主表ID查询") + @Operation(summary="${sub.ftlDescription}主表ID查询") + @GetMapping(value = "/query${sub.entityName}ByMainId") + public Result> query${sub.entityName}ListByMainId(@RequestParam(name="id",required=true) String id) { + List<${sub.entityName}> ${sub.entityName?uncap_first}List = ${sub.entityName?uncap_first}Service.selectByMainId(id); + return Result.OK(${sub.entityName?uncap_first}List); + } + + + /** + * 导出excel + * + * @param request + * @param ${entityName?uncap_first} + */ + @RequiresPermissions("${entityPackage}:${tableName}:exportXls") + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='export' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 导出前,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeExport() + + + + + // Step.1 组装查询条件查询数据 + QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap()); + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + + //配置选中数据查询条件 + String selections = request.getParameter("selections"); + if(oConvertUtils.isNotEmpty(selections)) { + List selectionList = Arrays.asList(selections.split(",")); + queryWrapper.in("id",selectionList); + } + //Step.2 获取导出数据 + List<${entityName}> ${entityName?uncap_first}List = ${entityName?uncap_first}Service.list(queryWrapper); + + // Step.3 组装pageList + List<${entityName}Page> pageList = new ArrayList<${entityName}Page>(); + for (${entityName} main : ${entityName?uncap_first}List) { + ${entityName}Page vo = new ${entityName}Page(); + BeanUtils.copyProperties(main, vo); + <#list subTables as sub> + List<${sub.entityName}> ${sub.entityName?uncap_first}List = ${sub.entityName?uncap_first}Service.selectByMainId(main.getId()); + vo.set${sub.entityName}List(${sub.entityName?uncap_first}List); + + pageList.add(vo); + } + + // Step.4 AutoPoi 导出Excel + ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); + mv.addObject(NormalExcelConstants.FILE_NAME, "${tableVo.ftlDescription}列表"); + mv.addObject(NormalExcelConstants.CLASS, ${entityName}Page.class); + mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("${tableVo.ftlDescription}数据", "导出人:"+sysUser.getRealname(), "${tableVo.ftlDescription}", ExcelType.XSSF)); + mv.addObject(NormalExcelConstants.DATA_LIST, pageList); + return mv; + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequiresPermissions("${entityPackage}:${tableName}:importExcel") + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + <#if enhanceJavaList?size gt 0> + <#list enhanceJavaList as enhanceJava> + <#if enhanceJava.buttonCode=='import' && enhanceJava.event=='start' && enhanceJava.activeStatus=='1'> + //TODO 导入前,代码生成后,请手工实现增强类逻辑; + //${entityName?uncap_first}Service.beforeImport() + + + + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map fileMap = multipartRequest.getFileMap(); + for (Map.Entry entity : fileMap.entrySet()) { + // 获取上传文件对象 + MultipartFile file = entity.getValue(); + ImportParams params = new ImportParams(); + params.setTitleRows(2); + params.setHeadRows(1); + params.setNeedSave(true); + try { + List<${entityName}Page> list = ExcelImportUtil.importExcel(file.getInputStream(), ${entityName}Page.class, params); + for (${entityName}Page page : list) { + ${entityName} po = new ${entityName}(); + BeanUtils.copyProperties(page, po); + ${entityName?uncap_first}Service.saveMain(po, <#list subTables as sub>page.get${sub.entityName}List()<#if sub_has_next>,); + } + return Result.OK("文件导入成功!数据行数:" + list.size()); + } catch (Exception e) { + log.error(e.getMessage(),e); + return Result.error("文件导入失败:"+e.getMessage()); + } finally { + try { + file.getInputStream().close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return Result.OK("文件导入失败!"); + } + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai new file mode 100644 index 00000000..b45dbe91 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai @@ -0,0 +1,82 @@ +<#include "/common/utils.ftl"> +package ${bussiPackage}.${entityPackage}.entity; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecg.common.aspect.annotation.Dict; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Schema(description="${tableVo.ftlDescription}") +@Data +@TableName("${tableName}") +public class ${entityName} implements Serializable { + private static final long serialVersionUID = 1L; + +<#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']> + <#assign excel_ignore_classType_arr=['pca','switch','cat_tree']> + <#list originalColumns as po> + <#-- 生成字典Code --> + <#assign list_field_dictCode=""> + <#if po.classType='sel_user'> + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> + <#elseif po.classType='sel_depart'> + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> + <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dicCode = "${po.dictField}"'> + + <#elseif po.classType=='sel_tree'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'> + <#elseif po.classType=='link_table'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicCode = "${po.dictField}", dicText = "${po.dictText?split(",")[0]}"'> + + /**${po.filedComment}*/ + <#if po.fieldName == primaryKeyField> + @TableId(type = IdType.ASSIGN_ID) + <#else> + <#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'> + <#if po.classType=='date'> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + + + <#if list_field_dictCode?length gt 1> + @Dict(${list_field_dictCode?substring(2)}) + + + <#include "/common/blob.ftl"> + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai new file mode 100644 index 00000000..f85ed30c --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai @@ -0,0 +1,82 @@ +<#include "/common/utils.ftl"> +<#list subTables as subTab> +#segment#${subTab.entityName}.java +package ${bussiPackage}.${entityPackage}.entity; + +import java.io.Serializable; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import java.util.Date; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.io.UnsupportedEncodingException; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Schema(description="${subTab.ftlDescription}") +@Data +@TableName("${subTab.tableName}") +public class ${subTab.entityName} implements Serializable { + private static final long serialVersionUID = 1L; + +<#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']> + <#assign excel_ignore_classType_arr=['pca','switch','cat_tree']> + <#list subTab.originalColumns as po> + <#-- 生成字典Code --> + <#assign list_field_dictCode=""> + <#if po.classType='sel_user'> + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> + <#elseif po.classType='sel_depart'> + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> + <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dicCode = "${po.dictField}"'> + <#elseif po.classType=='sel_tree'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText?split(",")[2]}", dicCode = "${po.dictText?split(",")[0]}"'> + + <#elseif po.classType=='link_table'> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicCode = "${po.dictField}", dicText = "${po.dictText?split(",")[0]}"'> + + /**${po.filedComment}*/ + <#if po.fieldName == primaryKeyField> + @TableId(type = IdType.ASSIGN_ID) + <#else> + <#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'> + <#if po.classType=='date'> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + + <#elseif !subTab.foreignKeys?seq_contains(po.fieldName?cap_first)> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + + + + <#-- 大字段转换 --> + <#include "/common/blob.ftl"> + +} + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai new file mode 100644 index 00000000..c31b9bfd --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/mapper/${entityName}Mapper.javai @@ -0,0 +1,17 @@ +package ${bussiPackage}.${entityPackage}.mapper; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface ${entityName}Mapper extends BaseMapper<${entityName}> { + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/mapper/[1-n]Mapper.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/mapper/[1-n]Mapper.javai new file mode 100644 index 00000000..10b27644 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/mapper/[1-n]Mapper.javai @@ -0,0 +1,34 @@ +<#list subTables as subTab> +#segment#${subTab.entityName}Mapper.java +package ${bussiPackage}.${entityPackage}.mapper; + +import java.util.List; +import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName}; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface ${subTab.entityName}Mapper extends BaseMapper<${subTab.entityName}> { + + /** + * 通过主表id删除子表数据 + * + * @param mainId 主表id + * @return boolean + */ + public boolean deleteByMainId(@Param("mainId") String mainId); + + /** + * 通过主表id查询子表数据 + * + * @param mainId 主表id + * @return List<${subTab.entityName}> + */ + public List<${subTab.entityName}> selectByMainId(@Param("mainId") String mainId); +} + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml new file mode 100644 index 00000000..16f3d653 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/${entityName}Mapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/[1-n]Mapper.xml b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/[1-n]Mapper.xml new file mode 100644 index 00000000..117c9b6f --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/mapper/xml/[1-n]Mapper.xml @@ -0,0 +1,26 @@ +<#list subTables as subTab> +<#assign originalForeignKeys = subTab.originalForeignKeys> +#segment#${subTab.entityName}Mapper.xml + + + + + + DELETE + FROM ${subTab.tableName} + WHERE + <#list originalForeignKeys as key> + ${key} = ${r'#'}{mainId} <#rt/> + + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai new file mode 100644 index 00000000..d80c0290 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/service/I${entityName}Service.javai @@ -0,0 +1,54 @@ +package ${bussiPackage}.${entityPackage}.service; + +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +import com.baomidou.mybatisplus.extension.service.IService; +import java.io.Serializable; +import java.util.Collection; +import java.util.List; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface I${entityName}Service extends IService<${entityName}> { + + /** + * 添加一对多 + * + * @param ${entityName?uncap_first} + <#list subTables as sub> + * @param ${sub.entityName?uncap_first}List + + */ + public void saveMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,) ; + + /** + * 修改一对多 + * + * @param ${entityName?uncap_first} + <#list subTables as sub> + * @param ${sub.entityName?uncap_first}List + + */ + public void updateMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,); + + /** + * 删除一对多 + * + * @param id + */ + public void delMain (String id); + + /** + * 批量删除一对多 + * + * @param idList + */ + public void delBatchMain (Collection idList); + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/service/[1-n]Service.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/service/[1-n]Service.javai new file mode 100644 index 00000000..cbc72ff4 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/service/[1-n]Service.javai @@ -0,0 +1,25 @@ +<#list subTables as subTab> +#segment#I${subTab.entityName}Service.java +package ${bussiPackage}.${entityPackage}.service; + +import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName}; +import com.baomidou.mybatisplus.extension.service.IService; +import java.util.List; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +public interface I${subTab.entityName}Service extends IService<${subTab.entityName}> { + + /** + * 通过主表id查询子表数据 + * + * @param mainId 主表id + * @return List<${subTab.entityName}> + */ + public List<${subTab.entityName}> selectByMainId(String mainId); +} + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai new file mode 100644 index 00000000..7f99d42e --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/${entityName}ServiceImpl.javai @@ -0,0 +1,105 @@ +package ${bussiPackage}.${entityPackage}.service.impl; + +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.mapper.${sub.entityName}Mapper; + +import ${bussiPackage}.${entityPackage}.mapper.${entityName}Mapper; +import ${bussiPackage}.${entityPackage}.service.I${entityName}Service; +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import java.io.Serializable; +import java.util.List; +import java.util.Collection; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Service +public class ${entityName}ServiceImpl extends ServiceImpl<${entityName}Mapper, ${entityName}> implements I${entityName}Service { + + @Autowired + private ${entityName}Mapper ${entityName?uncap_first}Mapper; + <#list subTables as sub> + @Autowired + private ${sub.entityName}Mapper ${sub.entityName?uncap_first}Mapper; + + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveMain(${entityName} ${entityName?uncap_first}, <#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,) { + ${entityName?uncap_first}Mapper.insert(${entityName?uncap_first}); + <#list subTables as sub> + if(${sub.entityName?uncap_first}List!=null && ${sub.entityName?uncap_first}List.size()>0) { + for(${sub.entityName} entity:${sub.entityName?uncap_first}List) { + <#list sub.foreignKeys as key> + //外键设置 + <#if key?lower_case?index_of("${primaryKeyField}")!=-1> + entity.set${key?cap_first}(${entityName?uncap_first}.get${primaryKeyField?cap_first}()); + <#else> + entity.set${key?cap_first}(${entityName?uncap_first}.get${key}()); + + + ${sub.entityName?uncap_first}Mapper.insert(entity); + } + } + + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,) { + ${entityName?uncap_first}Mapper.updateById(${entityName?uncap_first}); + + //1.先删除子表数据 + <#list subTables as sub> + ${sub.entityName?uncap_first}Mapper.deleteByMainId(${entityName?uncap_first}.getId()); + + + //2.子表数据重新插入 + <#list subTables as sub> + if(${sub.entityName?uncap_first}List!=null && ${sub.entityName?uncap_first}List.size()>0) { + for(${sub.entityName} entity:${sub.entityName?uncap_first}List) { + <#list sub.foreignKeys as key> + //外键设置 + <#if key?lower_case?index_of("${primaryKeyField}")!=-1> + entity.set${key?cap_first}(${entityName?uncap_first}.get${primaryKeyField?cap_first}()); + <#else> + entity.set${key?cap_first}(${entityName?uncap_first}.get${key}()); + + + ${sub.entityName?uncap_first}Mapper.insert(entity); + } + } + + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delMain(String id) { + <#list subTables as sub> + ${sub.entityName?uncap_first}Mapper.deleteByMainId(id); + + ${entityName?uncap_first}Mapper.deleteById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delBatchMain(Collection idList) { + for(Serializable id:idList) { + <#list subTables as sub> + ${sub.entityName?uncap_first}Mapper.deleteByMainId(id.toString()); + + ${entityName?uncap_first}Mapper.deleteById(id); + } + } + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/[1-n]ServiceImpl.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/[1-n]ServiceImpl.javai new file mode 100644 index 00000000..0ce41d36 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/service/impl/[1-n]ServiceImpl.javai @@ -0,0 +1,30 @@ +<#list subTables as subTab> +#segment#${subTab.entityName}ServiceImpl.java +package ${bussiPackage}.${entityPackage}.service.impl; + +import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName}; +import ${bussiPackage}.${entityPackage}.mapper.${subTab.entityName}Mapper; +import ${bussiPackage}.${entityPackage}.service.I${subTab.entityName}Service; +import org.springframework.stereotype.Service; +import java.util.List; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @Description: ${subTab.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Service +public class ${subTab.entityName}ServiceImpl extends ServiceImpl<${subTab.entityName}Mapper, ${subTab.entityName}> implements I${subTab.entityName}Service { + + @Autowired + private ${subTab.entityName}Mapper ${subTab.entityName?uncap_first}Mapper; + + @Override + public List<${subTab.entityName}> selectByMainId(String mainId) { + return ${subTab.entityName?uncap_first}Mapper.selectByMainId(mainId); + } +} + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vo/${entityName}Page.javai b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vo/${entityName}Page.javai new file mode 100644 index 00000000..c8550f84 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vo/${entityName}Page.javai @@ -0,0 +1,117 @@ +package ${bussiPackage}.${entityPackage}.vo; + +import java.util.List; +import ${bussiPackage}.${entityPackage}.entity.${entityName}; +<#list subTables as sub> +import ${bussiPackage}.${entityPackage}.entity.${sub.entityName}; + +import lombok.Data; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecgframework.poi.excel.annotation.ExcelEntity; +import org.jeecgframework.poi.excel.annotation.ExcelCollection; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import java.util.Date; +import org.jeecg.common.aspect.annotation.Dict; +import org.jeecg.common.constant.ProvinceCityArea; +import org.jeecg.common.util.SpringContextUtils; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * @Description: ${tableVo.ftlDescription} + * @Author: jeecg-boot + * @Date: ${.now?string["yyyy-MM-dd"]} + * @Version: V1.0 + */ +@Data +@Schema(description="${tableVo.ftlDescription}") +public class ${entityName}Page { + + <#assign excel_ignore_arr=['createBy','createTime','updateBy','updateTime','sysOrgCode']> + <#assign excel_ignore_classType_arr=['pca','switch','cat_tree']> + <#list originalColumns as po> + <#-- 生成字典Code --> + <#assign list_field_dictCode=""> + <#if po.classType='sel_user'> + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'> + <#elseif po.classType='sel_depart'> + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "depart_name", dicCode = "id"'> + <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign list_field_dictCode=', dicCode = "${po.dictField}"'> + <#elseif po.classType=='cat_tree'> + <#assign list_field_dictCode=', dictTable = "sys_category", dicText = "name", dicCode = "id"'> + + + /**${po.filedComment}*/ + <#if po.fieldName == primaryKeyField> + <#else> + <#if po.fieldDbType =='Date' || po.fieldDbType =='Datetime'> + <#if po.classType=='date'> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}")> + @Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss") + + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + + <#else> + <#if !excel_ignore_arr?seq_contains("${po.fieldName}") && !excel_ignore_classType_arr?seq_contains("${po.classType}")> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + + + <#if list_field_dictCode?length gt 1 && !excel_ignore_classType_arr?seq_contains("${po.classType}")> + @Dict(${list_field_dictCode?substring(2)}) + + + @Schema(description = "${po.filedComment}") + <#if po.fieldDbType=='Blob'> + private java.lang.String ${po.fieldName}String; + <#elseif po.classType=='pca'> + @Excel(name = "${po.filedComment}", width = 15,exportConvert=true,importConvert = true ) + private ${po.fieldType} ${po.fieldName}; + + public String convertis${po.fieldName?cap_first}() { + return SpringContextUtils.getBean(ProvinceCityArea.class).getText(${po.fieldName}); + } + + public void convertset${po.fieldName?cap_first}(String text) { + this.${po.fieldName} = SpringContextUtils.getBean(ProvinceCityArea.class).getCode(text); + } + <#elseif po.classType=='cat_tree'> + @Excel(name = "${po.filedComment}", width = 15${list_field_dictCode}) + private ${po.fieldType} ${po.fieldName}; + <#elseif po.classType=='switch'> + <#assign switch_extend_arr=['Y','N']> + <#if po.dictField?default("")?contains("[")> + <#assign switch_extend_arr=po.dictField?eval> + + <#list switch_extend_arr as a> + <#if a_index == 0> + <#assign switch_extend_arr1=a> + <#else> + <#assign switch_extend_arr2=a> + + + @Excel(name = "${po.filedComment}", width = 15,replace = {"是_${switch_extend_arr1}","否_${switch_extend_arr2}"} ) + private ${po.fieldType} ${po.fieldName}; + <#else> + private ${po.fieldType} ${po.fieldName}; + + + + <#list subTables as sub> + @ExcelCollection(name="${sub.ftlDescription}") + @Schema(description = "${sub.ftlDescription}") + private List<${sub.entityName}> ${sub.entityName?uncap_first}List; + + +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei new file mode 100644 index 00000000..e440c054 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei @@ -0,0 +1,351 @@ + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql new file mode 100644 index 00000000..5396d5d5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/V${currentDate}_1__menu_insert_${entityName}.sql @@ -0,0 +1 @@ +<#include "/common/sql/menu_insert.ftl"> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei new file mode 100644 index 00000000..1e84cd72 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei @@ -0,0 +1,509 @@ +<#include "/common/utils.ftl"> + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei new file mode 100644 index 00000000..c666aa4c --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei @@ -0,0 +1,62 @@ +<#include "/common/utils.ftl"> + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei new file mode 100644 index 00000000..7b69d6d9 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei @@ -0,0 +1,199 @@ +<#include "/common/utils.ftl"> +<#list subTables as sub> +<#if sub.foreignRelationType=='1'> +#segment#${sub.entityName}Form.vue + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei new file mode 100644 index 00000000..14c7d9f7 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei @@ -0,0 +1,444 @@ + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi new file mode 100644 index 00000000..ffe92f57 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi @@ -0,0 +1,75 @@ +import {defHttp} from '/@/utils/http/axios'; +import { useMessage } from "/@/hooks/web/useMessage"; + +const { createConfirm } = useMessage(); + +enum Api { + list = '/${entityPackagePath}/${entityName?uncap_first}/list', + save='/${entityPackagePath}/${entityName?uncap_first}/add', + edit='/${entityPackagePath}/${entityName?uncap_first}/edit', + deleteOne = '/${entityPackagePath}/${entityName?uncap_first}/delete', + deleteBatch = '/${entityPackagePath}/${entityName?uncap_first}/deleteBatch', + importExcel = '/${entityPackagePath}/${entityName?uncap_first}/importExcel', + exportXls = '/${entityPackagePath}/${entityName?uncap_first}/exportXls', +<#list subTables as sub><#rt/> + ${sub.entityName?uncap_first}List = '/${entityPackagePath}/${entityName?uncap_first}/query${sub.entityName}ByMainId', + +} +/** + * 导出api + * @param params + */ +export const getExportUrl = Api.exportXls; + +/** + * 导入api + */ +export const getImportUrl = Api.importExcel; +<#list subTables as sub><#rt/> +/** + * 查询子表数据 + * @param params + */ +export const ${sub.entityName?uncap_first}List = Api.${sub.entityName?uncap_first}List; + +/** + * 列表接口 + * @param params + */ +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(); + }); +} +/** + * 批量删除 + * @param params + */ +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(); + }); + } + }); +} +/** + * 保存或者更新 + * @param params + */ +export const saveOrUpdate = (params, isUpdate) => { + let url = isUpdate ? Api.edit : Api.save; + return defHttp.post({url: url, params}); +} diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi new file mode 100644 index 00000000..e6a50f95 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi @@ -0,0 +1,991 @@ +<#include "/common/utils.ftl"> +import {BasicColumn} from '/@/components/Table'; +import {FormSchema} from '/@/components/Table'; +import { rules} from '/@/utils/helper/validator'; +import { render } from '/@/utils/common/renderUtils'; +import {JVxeTypes,JVxeColumn} from '/@/components/jeecg/JVxeTable/types' +import { getWeekMonthQuarterYear } from '/@/utils'; +//列表数据 +export const columns: BasicColumn[] = [ + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + { + title: '${po.filedComment}', + align:"center", + <#if po.sort=='Y'> + sorter: true, + + <#if po.classType=='date'> + dataIndex: '${po.fieldName}', + customRender:({text}) =>{ + text = !text ? "" : (text.length > 10 ? text.substr(0,10) : text); + <#if po.extendParams?exists && po.extendParams.picker?exists> + if(text) { + return getWeekMonthQuarterYear(text)['${po.extendParams.picker}']; + } else { + return text; + } + <#else> + return text; + + }, + <#elseif po.fieldDbType=='Blob'> + dataIndex: '${po.fieldName}String' + <#elseif po.classType=='umeditor'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='pca'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='file'> + dataIndex: '${po.fieldName}', + <#elseif po.classType=='image'> + dataIndex: '${po.fieldName}', + customRender:render.renderImage, + <#elseif po.classType=='switch'> + dataIndex: '${po.fieldName}', +<#assign switch_extend_arr=['Y','N']> +<#if po.dictField?default("")?contains("[")> +<#assign switch_extend_arr=po.dictField?eval> + +<#list switch_extend_arr as a> +<#if a_index == 0> +<#assign switch_extend_arr1=a> +<#else> +<#assign switch_extend_arr2=a> + + + customRender:({text}) => { + return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]) + }, + <#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user' || po.classType=='popup_dict' || po.classType=='link_table'> + dataIndex: '${po.fieldName}_dictText' + <#elseif po.classType=='cat_tree'> + dataIndex: '${po.fieldName}', + <#if po.dictText?default("")?trim?length == 0> + customRender:({text}) => { + return render.renderCategoryTree(text,'${po.dictField?default("")}') + }, + <#else> + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') + + <#else> + dataIndex: '${po.fieldName}' + + }, + + +]; +//查询数据 +export const searchFormSchema: FormSchema[] = [ +<#-- 开始循环 --> +<#list columns as po> +<#if po.fieldDbName=='bpm_status'> + <#assign bpm_flag=true> + +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if po.isQuery=='Y' && po.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#assign query_flag=true> + <#assign query_field_dictCode=""> + <#if po.dictTable?default("")?trim?length gt 1> + <#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign query_field_dictCode="${po.dictField}"> + +<#if po.queryMode=='single'> + { + label: "${po.filedComment}", + field: "${po.fieldName}", +<#if po.classType=='sel_search'> + component: 'JSearchSelect', + componentProps:{ + dict:"${query_field_dictCode}" + }, +<#elseif po.classType=='sel_user'> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + component: 'JSelectUser', +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, +<#elseif po.classType=='switch'> + component: 'JSwitch', + componentProps:{ + query:true, + <#if po.dictField != 'is_open'> + options:${po.dictField} + + }, + <#elseif po.classType=='sel_depart'> + component: 'JSelectDept', + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType=='list_multi'> + component: 'JSelectMultiple', + componentProps:{ + <#if po.dictTable?default("")?trim?length gt 1> + dictCode:"${po.dictTable},${po.dictText},${po.dictField}", + <#elseif po.dictField?default("")?trim?length gt 1> + dictCode:"${po.dictField}", + + triggerChange: true + }, + <#elseif po.classType=='cat_tree'> + component: 'JCategorySelect', + componentProps:{ + pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题 + }, +<#elseif po.classType=='date'> + component: 'DatePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueFormat: 'YYYY-MM-DD' + }, +<#elseif po.classType=='datetime'> + component: 'DatePicker', + componentProps: { + showTime:true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, +<#elseif po.classType=='pca'> + component: 'JAreaLinkage', + componentProps: { + saveCode: 'region', + }, +<#elseif po.classType=='popup'> + <#include "/common/form/vue3popup.ftl"> +<#elseif po.classType=='popup_dict'> + component: 'JPopupDict', + componentProps: { + placeholder: '请选择${po.filedComment}', + dictCode: '${po.dictTable},${po.dictText},${po.dictField}', + multi: ${po.extendParams.popupMulti?c} + }, +<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'> +<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- --> + component: 'JSelectMultiple', + componentProps:{ + <#if po.dictTable?default("")?trim?length gt 1> + dictCode:"${po.dictTable},${po.dictText},${po.dictField}" + <#elseif po.dictField?default("")?trim?length gt 1> + dictCode:"${po.dictField}" + + }, +<#elseif po.classType == 'sel_tree'> + component: 'JTreeSelect', + componentProps:{ + <#if po.dictText??> + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", + <#elseif po.dictText?split(',')[1]??> + pidField:"${po.dictText?split(',')[1]}", + <#elseif po.dictText?split(',')[3]??> + hasChildField:"${po.dictText?split(',')[3]}", + + + pidValue:"${po.dictField}", + }, +<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'InputNumber', +<#else> + component: 'Input', + + //colProps: {span: 6}, + }, +<#elseif po.queryMode=='like'> + { + label: "${po.filedComment}", + field: "${po.fieldName}", + component: 'JInput', + }, +<#else> + { + label: "${po.filedComment}", + field: "${po.fieldName}", +<#if po.classType=='date'> + component: 'RangePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueType: 'Date', + }, +<#elseif po.classType=='datetime'> + component: 'RangePicker', + componentProps: { + valueType: 'Date', + showTime:true + }, +<#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'JRangeNumber', +<#-- update-begin---author:chenrui ---date:20240527 for:[TV360X-388]时间范围查询控件---------- --> +<#elseif po.classType=='time'> + component: 'RangeTime', +<#-- update-end---author:chenrui ---date:20240527 for:[TV360X-388]时间范围查询控件---------- --> +<#else> + component: 'Input', //TODO 范围查询 + + //colProps: {span: 6}, + }, + + + +<#-- 结束循环 --> +]; +//表单数据 +export const formSchema: FormSchema[] = [ +<#assign form_cat_tree = false> +<#assign form_cat_back = ""> +<#assign bpm_flag=false> +<#assign id_exists = false> +<#list columns as po><#rt/> +<#if po.fieldDbName=='bpm_status'> + <#assign bpm_flag=true> + +<#if po.fieldDbName == 'id'> + <#assign id_exists = true> + +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if po.isShow =='Y' && po.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#assign form_field_dictCode=""> + <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictField}"> + + { + label: '${po.filedComment}', + field: ${autoStringSuffix(po)}, +<#-- update-begin-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.defaultVal??> + <#if po.fieldDbType=="BigDecimal" || po.fieldDbType=="double" || po.fieldDbType=="int"> + defaultValue: ${po.defaultVal}, + <#else> + defaultValue: "${po.defaultVal}", + + +<#-- update-end-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.classType =='date'> + component: 'DatePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueFormat: 'YYYY-MM-DD' + }, + <#elseif po.classType =='datetime'> + component: 'DatePicker', + componentProps: { + showTime:true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, + <#elseif po.classType =='time'> + component: 'TimePicker', + componentProps: { + valueFormat: 'HH:mm:ss' + }, + <#elseif po.classType =='popup'> + <#include "/common/form/vue3popup.ftl"> + <#elseif po.classType=='popup_dict'> + component: 'JPopupDict', + componentProps: { + placeholder: '请选择${po.filedComment}', + dictCode: '${po.dictTable},${po.dictText},${po.dictField}', + multi: ${po.extendParams.popupMulti?c} + }, + <#elseif po.classType =='sel_depart'> + component: 'JSelectDept', + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='switch'> + component: 'JSwitch', + componentProps:{ + <#if po.dictField != 'is_open'> + options:${po.dictField} + + }, + <#elseif po.classType =='pca'> + component: 'JAreaLinkage', + componentProps: { + saveCode: 'region', + }, + <#elseif po.classType =='markdown'> + component: 'JMarkdownEditor',//注意string转换问题 + <#elseif po.classType =='password'> + component: 'InputPassword', + <#elseif po.classType =='sel_user'> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + component: 'JSelectUser', +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='textarea'> + component: 'InputTextArea', + <#elseif po.classType=='list'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#elseif po.classType=='radio'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + type: "radio", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='list_multi'> + component: 'JSelectMultiple', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#elseif po.classType=='checkbox'> + component: 'JCheckbox', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='sel_search'> + component: 'JSearchSelect', + componentProps:{ + dict:"${form_field_dictCode}" + }, +<#elseif po.classType=='cat_tree'> + <#assign form_cat_tree = true> + component: 'JCategorySelect', + componentProps:{ + pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题 + }, + <#if po.dictText?default("")?trim?length gt 1> + <#assign form_cat_back = "${po.dictText}"> + + <#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'InputNumber', + <#elseif po.classType=='file'> + component: 'JUpload', + componentProps:{ + <#if po.uploadnum??> + maxCount:${po.uploadnum} + + }, + <#elseif po.classType=='image'> + component: 'JImageUpload', + componentProps:{ + <#if po.uploadnum??> + fileMax:${po.uploadnum} + <#else> + fileMax: 0 + + }, + <#elseif po.classType=='umeditor'> + component: 'JEditor', + <#elseif po.classType == 'sel_tree'> + component: 'JTreeSelect', + componentProps:{ + <#if po.dictText??> + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", + <#elseif po.dictText?split(',')[1]??> + pidField:"${po.dictText?split(',')[1]}", + <#elseif po.dictText?split(',')[3]??> + hasChildField:"${po.dictText?split(',')[3]}", + + + pidValue:"${po.dictField}", + }, + <#elseif po.classType=='link_table'> + component: 'JLinkTableCard', + componentProps: { + valueField: '${po.dictField}', + textField: '${po.dictText}', + tableName: '${po.dictTable}', + multi: <#if (po.queryMode!"") == "multi">true<#else>false + }, + <#else> + component: 'Input', + + <#include "/common/utils.ftl"> + <#if po.isShow == 'Y' && poHasCheck(po)> + dynamicRules: ({model,schema}) => { + <#if po.fieldName != 'id'> + <#assign fieldValidType = po.fieldValidType!''> + return [ + <#-- 非空校验 --> + <#if po.nullable == 'N' || fieldValidType == '*'> + { required: true, message: '请输入${po.filedComment}!'}, + <#elseif fieldValidType!=''> + { required: false}, + + <#-- 唯一校验 --> + <#if fieldValidType == 'only'> + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}', '${po.fieldDbName}',model,schema)[0]}, + <#-- 6到16位数字 --> + <#elseif fieldValidType == 'n6-16'> + { pattern: /^\d{6,16}$|^(?=\d+\.\d+)[\d.]{7,17}$/, message: '请输入6到16位数字!'}, + <#-- 6到16位任意字符 --> + <#elseif fieldValidType == '*6-16'> + { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, + <#-- 6到18位字母 --> + <#elseif fieldValidType == 's6-18'> + { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, + <#-- 网址 --> + <#elseif fieldValidType == 'url'> + { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, + <#-- 电子邮件 --> + <#elseif fieldValidType == 'e'> + { pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'}, + <#-- 手机号码 --> + <#elseif fieldValidType == 'm'> + { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}, + <#-- 邮政编码 --> + <#elseif fieldValidType == 'p'> + { pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'}, + <#-- 字母 --> + <#elseif fieldValidType == 's'> + { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}, + <#-- 数字 --> + <#elseif fieldValidType == 'n'> + { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'}, + <#-- 整数 --> + <#elseif fieldValidType == 'z'> + { pattern: /^-?\d+$/, message: '请输入整数!'}, + <#-- 金额 --> + <#elseif fieldValidType == 'money'> + { pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'}, + <#-- 正则校验 --> + <#elseif fieldValidType != '' && fieldValidType != '*'> + { pattern: '${fieldValidType}', message: '不符合校验规则!'}, + <#-- 无校验 --> + <#else> + <#t> + + ]; + + }, + + <#if po.readonly=='Y'> + dynamicDisabled:true + + }, + + +<#if id_exists == false> + // TODO 主键隐藏字段,目前写死为ID + { + label: '', + field: 'id', + component: 'Input', + show: false + }, + +]; +//子表单数据 +<#list subTables as sub> +<#if sub.foreignRelationType =='1'> +export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ +<#assign form_cat_tree = false> +<#assign form_cat_back = ""> +<#assign bpm_flag=false> +<#assign sub_id_exists = false> +<#list sub.colums as po><#rt/> +<#if po.fieldDbName=='bpm_status'> + <#assign bpm_flag=true> + +<#if po.fieldDbName == 'id'> + <#assign sub_id_exists = true> + +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if po.isShow =='Y' && po.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#assign form_field_dictCode=""> + <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> + <#elseif po.dictField?default("")?trim?length gt 1> + <#assign form_field_dictCode="${po.dictField}"> + + { + label: '${po.filedComment}', + field: ${autoStringSuffix(po)}, +<#-- update-begin-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.defaultVal??> + <#if po.fieldDbType=="BigDecimal" || po.fieldDbType=="double" || po.fieldDbType=="int"> + defaultValue: ${po.defaultVal}, + <#else> + defaultValue: "${po.defaultVal}", + + +<#-- update-end-author:taoyan date:2022-6-24 for: VUEN-1190【代码生成】默认值未生成 --> + <#if po.classType =='date'> + component: 'DatePicker', + componentProps: { + <#if po.extendParams?exists && po.extendParams.picker?exists> + picker: '${po.extendParams.picker}', + + valueFormat: 'YYYY-MM-DD' + }, + <#elseif po.classType =='datetime'> + component: 'DatePicker', + componentProps: { + showTime:true, + valueFormat: 'YYYY-MM-DD HH:mm:ss' + }, + <#elseif po.classType =='time'> + component: 'TimePicker', + componentProps: { + valueFormat: 'HH:mm:ss' + }, + <#elseif po.classType =='popup'> + <#include "/common/form/vue3popup.ftl"> + <#elseif po.classType=='popup_dict'> + component: 'JPopupDict', + componentProps: { + placeholder: '请选择${po.filedComment}', + dictCode: '${po.dictTable},${po.dictText},${po.dictField}', + multi: ${po.extendParams.popupMulti?c} + }, + <#elseif po.classType =='sel_depart'> + component: 'JSelectDept', + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='switch'> + component: 'JSwitch', + componentProps:{ + <#if po.dictField != 'is_open'> + options:${po.dictField} + + }, + <#elseif po.classType =='pca'> + component: 'JAreaLinkage', + componentProps: { + saveCode: 'region', + }, + <#elseif po.classType =='markdown'> + component: 'JMarkdownEditor',//注意string转换问题 + <#elseif po.classType =='password'> + component: 'InputPassword', + <#elseif po.classType =='sel_user'> +<#-- update-begin---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + component: 'JSelectUser', +<#-- update-end---author:chenrui ---date:20240102 for:[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- --> + componentProps:{ + <#if po.extendParams?exists && po.extendParams.text?exists> + labelKey: '${po.extendParams.text}', + + <#if po.extendParams?exists && po.extendParams.store?exists> + rowKey: '${po.extendParams.store}', + + }, + <#elseif po.classType =='textarea'> + component: 'InputTextArea', + <#elseif po.classType=='list'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#elseif po.classType=='radio'> + component: 'JDictSelectTag', + componentProps:{ + dictCode:"${form_field_dictCode}", + type: "radio", + <#if po.fieldDbType=='int'> + stringToNumber: true + + }, + <#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选---------- --> + <#elseif po.classType=='list_multi'> + component: 'JSelectMultiple', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#elseif po.classType=='checkbox'> + component: 'JCheckbox', + componentProps:{ + dictCode:"${form_field_dictCode}" + }, + <#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7583] Vue3风格表单页面多选控件渲染成了下拉多选----------- --> + <#elseif po.classType=='sel_search'> + component: 'JSearchSelect', + componentProps:{ + dict:"${form_field_dictCode}" + }, +<#elseif po.classType=='cat_tree'> + <#assign form_cat_tree = true> + component: 'JCategorySelect', + componentProps:{ + pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题 + }, + <#if po.dictText?default("")?trim?length gt 1> + <#assign form_cat_back = "${po.dictText}"> + + <#elseif po.fieldDbType=='int' || po.fieldDbType=='long' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> + component: 'InputNumber', + <#elseif po.classType=='file'> + component: 'JUpload', + componentProps:{ + <#if po.uploadnum??> + maxCount:${po.uploadnum} + + }, + <#elseif po.classType=='image'> + component: 'JImageUpload', + componentProps:{ + <#if po.uploadnum??> + fileMax:${po.uploadnum} + <#else> + fileMax: 0 + + }, + <#elseif po.classType=='umeditor'> + component: 'JEditor', + <#elseif po.classType == 'sel_tree'> + component: 'JTreeSelect', + componentProps:{ + <#if po.dictText??> + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", + <#elseif po.dictText?split(',')[1]??> + pidField:"${po.dictText?split(',')[1]}", + <#elseif po.dictText?split(',')[3]??> + hasChildField:"${po.dictText?split(',')[3]}", + + + pidValue:"${po.dictField}", + }, + <#elseif po.classType=='link_table'> + component: 'JLinkTableCard', + componentProps: { + valueField: '${po.dictField}', + textField: '${po.dictText}', + tableName: '${po.dictTable}', + multi: <#if (po.queryMode!"") == "multi">true<#else>false + }, + <#else> + component: 'Input', + + <#include "/common/utils.ftl"> + <#if po.isShow == 'Y' && poHasCheck(po)> + dynamicRules: ({model,schema}) => { + <#if po.fieldName != 'id'> + <#assign fieldValidType = po.fieldValidType!''> + return [ + <#-- 非空校验 --> + <#if po.nullable == 'N' || fieldValidType == '*'> + { required: true, message: '请输入${po.filedComment}!'}, + <#elseif fieldValidType!=''> + { required: false}, + + <#-- 唯一校验 --> + <#if fieldValidType == 'only'> + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}', '${po.fieldDbName}',model,schema)[0]}, + <#-- 6到16位数字 --> + <#elseif fieldValidType == 'n6-16'> + { pattern: /^\d{6,16}$|^(?=\d+\.\d+)[\d.]{7,17}$/, message: '请输入6到16位数字!'}, + <#-- 6到16位任意字符 --> + <#elseif fieldValidType == '*6-16'> + { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, + <#-- 6到18位字母 --> + <#elseif fieldValidType == 's6-18'> + { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, + <#-- 网址 --> + <#elseif fieldValidType == 'url'> + { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, + <#-- 电子邮件 --> + <#elseif fieldValidType == 'e'> + { pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'}, + <#-- 手机号码 --> + <#elseif fieldValidType == 'm'> + { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}, + <#-- 邮政编码 --> + <#elseif fieldValidType == 'p'> + { pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'}, + <#-- 字母 --> + <#elseif fieldValidType == 's'> + { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}, + <#-- 数字 --> + <#elseif fieldValidType == 'n'> + { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'}, + <#-- 整数 --> + <#elseif fieldValidType == 'z'> + { pattern: /^-?\d+$/, message: '请输入整数!'}, + <#-- 金额 --> + <#elseif fieldValidType == 'money'> + { pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'}, + <#-- 正则校验 --> + <#elseif fieldValidType != '' && fieldValidType != '*'> + { pattern: '${fieldValidType}', message: '不符合校验规则!'}, + <#-- 无校验 --> + <#else> + <#t> + + ]; + + }, + + <#if po.readonly=='Y'> + dynamicDisabled:true + + }, + + +<#if sub_id_exists == false> + { + label: '', + field: 'id', + component: 'Input', + show: false + }, + +]; + + +//子表表格配置 +<#list subTables as sub> +<#if sub.foreignRelationType =='0'> +export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [ +<#assign popupBackFields = ""> + +<#-- 循环子表的列 开始 --> +<#list sub.colums as col><#rt/> +<#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if col.isShow =='Y' && col.fieldName !='delFlag'> +<#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> +<#if col.filedComment !='外键' > + { + title: '${col.filedComment}', + key: '${autoStringSuffixForModel(col)}', +<#if col.classType =='date'> + type: JVxeTypes.date, + <#if col.extendParams?exists && col.extendParams.picker?exists> + picker: '${col.extendParams.picker}', + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='datetime'> + type: JVxeTypes.datetime, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='time'> + type: JVxeTypes.time, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='textarea'> + type: JVxeTypes.textarea, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='list' || col.classType =='radio'> + type: JVxeTypes.select, + options:[], + <#if col.dictTable?default("")?trim?length gt 1> + dictCode:"${col.dictTable},${col.dictText},${col.dictField}", + <#else> + dictCode:"${col.dictField}", + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='list_multi' || col.classType =='checkbox'> + type: JVxeTypes.selectMultiple, + options:[], + <#if col.dictTable?default("")?trim?length gt 1> + dictCode:"${col.dictTable},${col.dictText},${col.dictField}", + <#else> + dictCode:"${col.dictField}", + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='sel_search'> + type: JVxeTypes.selectSearch, + <#if col.dictTable?default("")?trim?length gt 1> + dictCode:"${col.dictTable},${col.dictText},${col.dictField}", + <#else> + dictCode:"${col.dictField}", + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='sel_depart'> + type: JVxeTypes.departSelect, + props:{ + <#if col.extendParams?exists && col.extendParams.text?exists> + labelKey: '${col.extendParams.text}', + + <#if col.extendParams?exists && col.extendParams.store?exists> + rowKey: '${col.extendParams.store}', + + }, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='sel_user'> + type: JVxeTypes.userSelect, + props:{ + <#if col.extendParams?exists && col.extendParams.text?exists> + labelKey: '${col.extendParams.text}', + + <#if col.extendParams?exists && col.extendParams.store?exists> + rowKey: '${col.extendParams.store}', + + }, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='image'> + type: JVxeTypes.image, + token:true, + responseName:"message", + <#if col.readonly=='Y'> + disabled:true, + + <#if col.uploadnum??> + number: ${col.uploadnum}, + +<#elseif col.classType =='file'> + type: JVxeTypes.file, + token:true, + responseName:"message", + <#if col.readonly=='Y'> + disabled:true, + + <#if col.uploadnum??> + number: ${col.uploadnum}, + +<#elseif col.classType =='switch'> + type: JVxeTypes.checkbox, + <#if col.dictField == 'is_open'> + customValue: ['Y', 'N'], + <#else> + customValue: ${col.dictField}, + + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType=='pca'> + type: JVxeTypes.pca, + <#if col.readonly=='Y'> + disabled:true, + +<#elseif col.classType =='popup'> +<#if popupBackFields?length gt 0> + <#assign popupBackFields = "${popupBackFields}"+","+"${col.dictText}"> +<#else> + <#assign popupBackFields = "${col.dictText}"> + + <#include "/common/form/vue3Jvxepopup.ftl"> +<#-- update-begin-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> +<#-- elseif "int,decimal,double,"?contains(col.classType) --> +<#elseif col.fieldDbType=='int' || col.fieldDbType=='long' || col.fieldDbType=='double' || col.fieldDbType=='BigDecimal'> +<#-- update-end-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> + type: JVxeTypes.inputNumber, + <#if col.readonly=='Y'> + disabled:true, + +<#else> + type: JVxeTypes.input, + <#if col.readonly=='Y'> + disabled:true, + + +<#if col.classType =='list_multi' || col.classType =='checkbox'> + width:"250px", +<#else> + width:"200px", + +<#if col.classType =='file'> + placeholder: '请选择文件', +<#else> + placeholder: '请输入${'$'}{title}', + +<#if col.defaultVal??> +<#if col.fieldDbType=="BigDecimal" || col.fieldDbType=="double" || col.fieldDbType=="int"> + defaultValue:${col.defaultVal}, + <#else> + defaultValue:"${col.defaultVal}", + +<#else> + defaultValue:'', + +<#-- 子表的校验 --> + <#include "/common/validatorRulesTemplate/sub-vue3.ftl"> + }, + + + +<#-- 循环子表的列 结束 --> + ] + + + +<#-- update-begin---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> +// 高级查询数据 +export const superQuerySchema = { + <#list columns as po> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if po.isShowList =='Y' && po.fieldName !='id' && po.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + ${superQueryFieldListForVue3(po,po_index)}, + + + //子表高级查询 + <#list subTables as sub> + ${sub.entityName?uncap_first}: { + title: '${sub.ftlDescription}', + view: 'table', + fields: { + <#list sub.colums as subCol> + <#-- update-begin---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + <#if subCol.isShowList =='Y' && subCol.fieldName !='id' && subCol.fieldName !='delFlag'> + <#-- update-end---author:chenrui ---date:20240108 for:[issues/5755]vue代码不加入逻辑删除字段---------- --> + ${superQueryFieldListForVue3(subCol,subCol_index)}, + + + } + }, + +}; +<#-- update-end---author:chenrui ---date:20231228 for:[QQYUN-7527]vue3代码生成默认带上高级查询---------- --> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql new file mode 100644 index 00000000..5396d5d5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/V${currentDate}_1__menu_insert_${entityName}.sql @@ -0,0 +1 @@ +<#include "/common/sql/menu_insert.ftl"> \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Form.vuei new file mode 100644 index 00000000..b3080bd5 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Form.vuei @@ -0,0 +1,251 @@ +<#include "/common/utils.ftl"> + + + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei new file mode 100644 index 00000000..34a5ac15 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei @@ -0,0 +1,366 @@ +<#include "/common/utils.ftl"> + + + + + + + \ No newline at end of file diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei new file mode 100644 index 00000000..c02ad27e --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/config/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei @@ -0,0 +1,87 @@ +<#include "/common/utils.ftl"> +<#list subTables as sub> +<#if sub.foreignRelationType=='1'> +#segment#${sub.entityName}Form.vue + + + + + diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_164__mes_xsl_mcs_db_config_agent.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_164__mes_xsl_mcs_db_config_agent.sql new file mode 100644 index 00000000..b4b63a39 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_164__mes_xsl_mcs_db_config_agent.sql @@ -0,0 +1,4 @@ +-- 【设备库桥接】中间库配置增加桌面代理访问模式 +ALTER TABLE `mes_xsl_mcs_db_config` + ADD COLUMN `access_mode` varchar(32) DEFAULT 'DESKTOP_AGENT' COMMENT '访问模式 DESKTOP_AGENT/DIRECT' AFTER `remark`, + ADD COLUMN `agent_device_id` varchar(100) DEFAULT NULL COMMENT '绑定桌面代理deviceId' AFTER `access_mode`; diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_165__mes_xsl_mill_action_act_mill.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_165__mes_xsl_mill_action_act_mill.sql new file mode 100644 index 00000000..2dee9a54 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_165__mes_xsl_mill_action_act_mill.sql @@ -0,0 +1,105 @@ +-- 【MES上辅机】开炼机动作 MCSToMES_Act_Mill → mes_xsl_mill_action +-- 1. MES 接收表 +-- 2. 采集配置(FULL / 30秒 / GUID 匹配)+ 字段映射 +-- 3. 中间库原表菜单 + 接收表菜单 + admin 授权 + +SET NAMES utf8mb4; + +-- ===================== 1. MES 接收表 ===================== +CREATE TABLE IF NOT EXISTS `mes_xsl_mill_action` ( + `id` varchar(32) NOT NULL COMMENT '主键', + `guid` varchar(50) NOT NULL COMMENT '源表GUID(匹配键)', + `act_addr` int DEFAULT NULL COMMENT '动作地址', + `act_name` varchar(50) DEFAULT NULL COMMENT '动作名称', + `act_name_en` varchar(50) DEFAULT NULL COMMENT '动作名称(英)', + `act_memo` varchar(20) DEFAULT NULL COMMENT '动作备注', + `act_repaddr` int DEFAULT NULL COMMENT '动作关联地址', + `write_time` datetime DEFAULT NULL COMMENT '写入时间(源)', + `read_time` datetime DEFAULT NULL COMMENT '读取时间(源)', + `rw_flag` int DEFAULT NULL COMMENT '读写标识', + `tenant_id` int DEFAULT '0' COMMENT '租户', + `sys_org_code` varchar(64) DEFAULT NULL COMMENT '部门', + `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 '更新时间', + `del_flag` int DEFAULT '0' COMMENT '删除标记(0正常1删除)', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_mma_guid` (`guid`), + KEY `idx_mma_act_name` (`act_name`), + KEY `idx_mma_write_time` (`write_time`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES开炼机动作接收表(采集自MCSToMES_Act_Mill)'; + +-- ===================== 2. 采集配置 + 字段映射 ===================== +INSERT INTO `mes_xsl_mcs_sync_config` + (`id`, `biz_type`, `config_name`, `biz_name`, `source_table`, `source_table_comment`, + `target_table`, `target_table_comment`, `interval_seconds`, `status`, `sync_mode`, + `remark`, `tenant_id`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`) +SELECT '1900000000000000880', 'MILL_ACT', '开炼机动作采集', '开炼机动作', 'MCSToMES_Act_Mill', '开炼机动作', + 'mes_xsl_mill_action', 'MES开炼机动作接收表', 30, '0', 'FULL', + '开炼机动作 FULL 按GUID Upsert,默认30秒', 0, 'admin', NOW(), 'admin', NOW(), 0 +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_mcs_sync_config` WHERE `biz_type` = 'MILL_ACT' AND `tenant_id` = 0); + +INSERT INTO `mes_xsl_mcs_sync_field` + (`id`, `config_id`, `source_field`, `source_field_comment`, `source_field_type`, + `target_field`, `target_field_comment`, `match_key`, `sort_no`, + `tenant_id`, `create_by`, `create_time`, `update_by`, `update_time`, `del_flag`) +SELECT * FROM ( + SELECT '1900000000000000881' id, '1900000000000000880' config_id, 'GUID' sf, 'GUID' sfc, 'varchar' sft, 'guid' tf, '源表GUID' tfc, '1' mk, 1 sn, 0 tid, 'admin' cb, NOW() ct, 'admin' ub, NOW() ut, 0 df + UNION ALL SELECT '1900000000000000882', '1900000000000000880', 'act_addr', '动作地址', 'int', 'act_addr', '动作地址', '0', 2, 0, 'admin', NOW(), 'admin', NOW(), 0 + UNION ALL SELECT '1900000000000000883', '1900000000000000880', 'act_name', '动作名称', 'varchar', 'act_name', '动作名称', '0', 3, 0, 'admin', NOW(), 'admin', NOW(), 0 + UNION ALL SELECT '1900000000000000884', '1900000000000000880', 'act_name_en', '动作名称(英)', 'varchar', 'act_name_en', '动作名称(英)', '0', 4, 0, 'admin', NOW(), 'admin', NOW(), 0 + UNION ALL SELECT '1900000000000000885', '1900000000000000880', 'act_memo', '动作备注', 'varchar', 'act_memo', '动作备注', '0', 5, 0, 'admin', NOW(), 'admin', NOW(), 0 + UNION ALL SELECT '1900000000000000886', '1900000000000000880', 'act_Repaddr', '动作关联地址', 'int', 'act_repaddr', '动作关联地址', '0', 6, 0, 'admin', NOW(), 'admin', NOW(), 0 + UNION ALL SELECT '1900000000000000887', '1900000000000000880', 'WriteTime', '写入时间', 'datetime', 'write_time', '写入时间', '0', 7, 0, 'admin', NOW(), 'admin', NOW(), 0 + UNION ALL SELECT '1900000000000000888', '1900000000000000880', 'ReadTime', '读取时间', 'datetime', 'read_time', '读取时间', '0', 8, 0, 'admin', NOW(), 'admin', NOW(), 0 + UNION ALL SELECT '1900000000000000889', '1900000000000000880', 'RW_Flag', '读写标识', 'int', 'rw_flag', '读写标识', '0', 9, 0, 'admin', NOW(), 'admin', NOW(), 0 +) t +WHERE NOT EXISTS (SELECT 1 FROM `mes_xsl_mcs_sync_field` WHERE `config_id` = '1900000000000000880'); + +-- ===================== 3. 中间库原表菜单(上辅机数据) ===================== +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 '1900000000000000890', '1900000000000000830', '开炼机动作', '/xslmesMcs/mcsToMesActMill', 'xslmesMcs/mcsToMesActMill/index', 1, NULL, NULL, 1, NULL, '0', 5.50, 0, 'ant-design:apartment-outlined', 1, 1, 0, 0, 'MCSToMES_Act_Mill 开炼机动作中间表', 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0 +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000890'); + +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 '1900000000000000891', '1900000000000000890', '采集设置', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mcsSyncConfig:setting', '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` = '1900000000000000891'); + +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 '1900000000000000892', '1900000000000000890', '导出', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mcsToMesActMill:exportXls', '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` = '1900000000000000892'); + +-- ===================== 4. MES 接收表菜单(技术管理) ===================== +UPDATE `sys_permission` +SET `is_leaf` = 0, `update_time` = NOW() +WHERE `id` = '1900000000000000810' AND `is_leaf` = 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 '1900000000000000894', '1900000000000000810', '开炼机动作接收', '/xslmes/mesXslMillAction', 'xslmes/mesXslMillAction/MesXslMillActionList', 1, 'MesXslMillActionList', NULL, 1, NULL, '0', 1.10, 0, 'ant-design:cluster-outlined', 1, 1, 0, 0, 'mes_xsl_mill_action 开炼机动作接收表', 'admin', NOW(), 'admin', NOW(), 0, 0, '1', 0 +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000894'); + +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 '1900000000000000895', '1900000000000000894', '采集设置', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mcsSyncConfig:setting', '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` = '1900000000000000895'); + +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 '1900000000000000896', '1900000000000000894', '导出', NULL, NULL, 0, NULL, NULL, 2, 'xslmes:mes_xsl_mill_action:exportXls', '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` = '1900000000000000896'); + +-- admin 授权 +INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`) +SELECT REPLACE(UUID(), '-', ''), r.id, p.id, NULL, NOW(), '127.0.0.1' +FROM `sys_role` r +JOIN ( + SELECT id FROM `sys_permission` + WHERE id IN ( + '1900000000000000890','1900000000000000891','1900000000000000892', + '1900000000000000894','1900000000000000895','1900000000000000896' + ) +) p ON 1 = 1 +WHERE r.`role_code` = 'admin' + AND NOT EXISTS ( + SELECT 1 FROM `sys_role_permission` rp + WHERE rp.`role_id` = r.id AND rp.`permission_id` = p.id + ); diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_166__hide_mcs_act_mill_web_menu.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_166__hide_mcs_act_mill_web_menu.sql new file mode 100644 index 00000000..5fed0047 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_166__hide_mcs_act_mill_web_menu.sql @@ -0,0 +1,14 @@ +-- 开炼机动作中间库原表改由桌面端展示,隐藏 MES Web 中间库菜单 +SET NAMES utf8mb4; + +UPDATE `sys_permission` +SET `del_flag` = 1, `status` = '0', `update_time` = NOW() +WHERE `id` IN ('1900000000000000890', '1900000000000000891', '1900000000000000892') + AND `del_flag` = 0; + +-- 接收表菜单名称保持「开炼机动作接收」,仅查 MySQL 接收数据 +UPDATE `sys_permission` +SET `name` = '开炼机动作接收', + `description` = 'mes_xsl_mill_action 开炼机动作接收表(仅展示采集入库数据)', + `update_time` = NOW() +WHERE `id` = '1900000000000000894'; diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_167__restore_raw_material_inspect_std_menu.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_167__restore_raw_material_inspect_std_menu.sql new file mode 100644 index 00000000..71a73945 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_167__restore_raw_material_inspect_std_menu.sql @@ -0,0 +1,74 @@ +-- 修复原材料检验标准菜单(避开已被人工小料占用的 0730/0750 等 ID) +SET NAMES utf8mb4; + +-- 1) 新建页面菜单:MES原料仓储 下,与送检记录同级 +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 + '1900000000000000897', '1900000000000000700', '原材料检验标准', '/mes/rawMaterialInspectStd', + 'mes/rawmaterialinspectstd/index', 1, NULL, NULL, + 1, NULL, '0', 21.50, 0, 'ant-design:safety-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` = '1900000000000000897'); + +-- 2) 按钮权限改挂到新菜单(从误挂的人工小料计划维护下挪回) +UPDATE `sys_permission` +SET `parent_id` = '1900000000000000897', `update_time` = NOW() +WHERE `id` IN ( + '1900000000000000732','1900000000000000733','1900000000000000734', + '1900000000000000735','1900000000000000736','1900000000000000737' +) +AND `perms` LIKE 'mes:mes_raw_material_inspect_std:%'; + +-- 3) 添加按钮 +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 + '1900000000000000898', '1900000000000000897', '添加', NULL, NULL, 0, NULL, NULL, + 2, 'mes:mes_raw_material_inspect_std: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` = '1900000000000000898'); + +-- 4) admin 授权 +INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`) +SELECT REPLACE(UUID(), '-', ''), r.id, p.id, NULL, NOW(), '127.0.0.1' +FROM `sys_role` r +JOIN ( + SELECT id FROM `sys_permission` + WHERE id IN ( + '1900000000000000897','1900000000000000898', + '1900000000000000732','1900000000000000733','1900000000000000734', + '1900000000000000735','1900000000000000736','1900000000000000737' + ) +) p ON 1 = 1 +WHERE r.`role_code` = 'admin' + AND NOT EXISTS ( + SELECT 1 FROM `sys_role_permission` rp + WHERE rp.`role_id` = r.id AND rp.`permission_id` = p.id + ); + +-- 5) 打印实体映射 +INSERT INTO `print_biz_perm_entity` (`perm_id`, `entity_class`) +SELECT '1900000000000000897', 'org.jeecg.modules.mes.material.entity.MesRawMaterialInspectStd' +FROM DUAL +WHERE NOT EXISTS ( + SELECT 1 FROM `print_biz_perm_entity` + WHERE `perm_id` = '1900000000000000897' + AND `entity_class` = 'org.jeecg.modules.mes.material.entity.MesRawMaterialInspectStd' +); + +SELECT p.id, pp.name AS parent_name, p.name, p.url, p.component +FROM sys_permission p +LEFT JOIN sys_permission pp ON pp.id = p.parent_id +WHERE p.id = '1900000000000000897' OR p.parent_id = '1900000000000000897'; diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_168__restore_raw_material_log_menus.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_168__restore_raw_material_log_menus.sql new file mode 100644 index 00000000..d490efc4 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_168__restore_raw_material_log_menus.sql @@ -0,0 +1,123 @@ +-- 补回被需求计划菜单 ID 占用挤掉的两个日志菜单(新 ID,不改动现有需求计划) +-- 1) 原材料卡片修改日志 +-- 2) 原料入场删除日志 +SET NAMES utf8mb4; + +-- ===================== 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 + '1900000000000000899', '1900000000000000700', '原材料卡片修改日志', + '/xslmes/mesXslRawMaterialCardEditLog', + 'xslmes/mesXslRawMaterialCardEditLog/MesXslRawMaterialCardEditLogList', + 1, NULL, NULL, 1, NULL, '0', 13.00, 0, 'ant-design:history-outlined', 1, 1, + 0, 0, '记录 Web/桌面端编辑原材料卡片剩余量与库区', 'admin', NOW(), 'admin', NOW(), + 0, 0, '1', 0 +FROM DUAL +WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000899') + AND NOT EXISTS ( + SELECT 1 FROM `sys_permission` + WHERE `del_flag` = 0 AND `menu_type` = 1 AND `name` = '原材料卡片修改日志' + ); + +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 + '1900000000000000900', '1900000000000000899', '查询', NULL, NULL, 0, NULL, NULL, + 2, 'xslmes:mes_xsl_raw_material_card_edit_log:list', '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` = '1900000000000000900'); + +-- 原 0712 仍是卡片修改日志导出权限,挪到新菜单下 +UPDATE `sys_permission` +SET `parent_id` = '1900000000000000899', `name` = '导出', `update_time` = NOW() +WHERE `id` = '1900000000000000712' + AND `perms` = 'xslmes:mes_xsl_raw_material_card_edit_log:exportXls'; + +-- 若 0712 已被改成别的权限,则新建导出按钮 +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 + '1900000000000000901', '1900000000000000899', '导出', NULL, NULL, 0, NULL, NULL, + 2, 'xslmes:mes_xsl_raw_material_card_edit_log:exportXls', '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` = '1900000000000000901') + AND NOT EXISTS ( + SELECT 1 FROM `sys_permission` + WHERE `parent_id` = '1900000000000000899' + AND `perms` = 'xslmes:mes_xsl_raw_material_card_edit_log:exportXls' + ); + +-- ===================== 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 + '1900000000000000902', '1900000000000000700', '原料入场删除日志', + '/xslmes/mesXslRawMaterialEntryDeleteLog', + 'xslmes/mesXslRawMaterialEntryDeleteLog/MesXslRawMaterialEntryDeleteLogList', + 1, NULL, NULL, 1, NULL, '0', 14.00, 0, 'ant-design:delete-row-outlined', 1, 1, + 0, 0, '查询已逻辑删除的原料入场记录', 'admin', NOW(), 'admin', NOW(), + 0, 0, '1', 0 +FROM DUAL +WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000902') + AND NOT EXISTS ( + SELECT 1 FROM `sys_permission` + WHERE `del_flag` = 0 AND `menu_type` = 1 AND `name` = '原料入场删除日志' + ); + +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 + '1900000000000000903', '1900000000000000902', '查询', NULL, NULL, 0, NULL, NULL, + 2, 'xslmes:mes_xsl_raw_material_entry_delete_log:list', '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` = '1900000000000000903'); + +-- ===================== 3. admin 授权 ===================== +INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`) +SELECT REPLACE(UUID(), '-', ''), r.id, p.id, NULL, NOW(), '127.0.0.1' +FROM `sys_role` r +JOIN ( + SELECT id FROM `sys_permission` + WHERE id IN ( + '1900000000000000899','1900000000000000900','1900000000000000901', + '1900000000000000712', + '1900000000000000902','1900000000000000903' + ) +) p ON 1 = 1 +WHERE r.`role_code` = 'admin' + AND NOT EXISTS ( + SELECT 1 FROM `sys_role_permission` rp + WHERE rp.`role_id` = r.id AND rp.`permission_id` = p.id + ); + +SELECT p.id, pp.name AS parent_name, p.name, p.url, p.component, p.perms +FROM sys_permission p +LEFT JOIN sys_permission pp ON pp.id = p.parent_id +WHERE p.id IN ( + '1900000000000000899','1900000000000000900','1900000000000000901','1900000000000000712', + '1900000000000000902','1900000000000000903' +) +OR p.parent_id IN ('1900000000000000899','1900000000000000902') +ORDER BY p.id; diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_169__fix_misparented_menu_buttons.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_169__fix_misparented_menu_buttons.sql new file mode 100644 index 00000000..589955a3 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_169__fix_misparented_menu_buttons.sql @@ -0,0 +1,149 @@ +-- 修复挂错父菜单的按钮,并补回被 ID 占用挤掉的页面 +-- A) 胶料小料锁定日志(0215 被设备对应部位占用) +-- B) 清理工序管理/设备类别「新增」按钮上误写的页面 url/component +-- C) 原材料检验项目(导入按钮 0067 误挂在工序「新增」下) +SET NAMES utf8mb4; + +-- ===================== A. 胶料小料锁定日志 ===================== +INSERT INTO `sys_permission` ( + `id`, `parent_id`, `name`, `url`, `component`, `component_name`, `is_route`, `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 + '1900000000000000904', '1860000000000000162', '胶料小料锁定日志', + '/xslmes/mesXslRubberSmallLockLog', + 'xslmes/mesXslRubberSmallLockLog/MesXslRubberSmallLockLogList', + 'MesXslRubberSmallLockLogList', 1, NULL, + 1, NULL, '0', 7.00, 0, 'ant-design:file-text-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` = '1900000000000000904') + AND NOT EXISTS ( + SELECT 1 FROM `sys_permission` + WHERE `del_flag` = 0 AND `menu_type` = 1 AND `name` = '胶料小料锁定日志' + ); + +-- 锁定日志按钮从「设备对应部位」挪回 +UPDATE `sys_permission` +SET `parent_id` = '1900000000000000904', `update_time` = NOW() +WHERE `id` IN ( + '1860000000000000217','1860000000000000218','1860000000000000219', + '1860000000000000220','1860000000000000221' +) +AND `perms` LIKE 'mes:mes_xsl_rubber_small_lock_log:%'; + +-- 补「新增」(原 0216 已被设备对应部位导出占用) +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 + '1900000000000000905', '1900000000000000904', '新增', NULL, NULL, 0, NULL, NULL, + 2, 'mes:mes_xsl_rubber_small_lock_log: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` = '1900000000000000905') + AND NOT EXISTS ( + SELECT 1 FROM `sys_permission` + WHERE `parent_id` = '1900000000000000904' + AND `perms` = 'mes:mes_xsl_rubber_small_lock_log:add' + ); + +-- ===================== B. 清理按钮上误写的页面路由 ===================== +UPDATE `sys_permission` +SET `url` = NULL, `component` = NULL, `component_name` = NULL, `is_route` = 0, `update_time` = NOW() +WHERE `id` IN ('1860000000000000061', '1860000000000000071') + AND `menu_type` = 2; + +-- ===================== C. 原材料检验项目 ===================== +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 + '1900000000000000906', '1900000000000000700', '原材料检验项目', + '/mes/rawMaterialInspectItem', 'mes/rawmaterialinspectitem/index', + 1, NULL, NULL, 1, NULL, '0', 21.40, 0, 'ant-design:check-square-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` = '1900000000000000906') + AND NOT EXISTS ( + SELECT 1 FROM `sys_permission` + WHERE `del_flag` = 0 AND `menu_type` = 1 AND `name` = '原材料检验项目' + ); + +-- 导入按钮从工序「新增」下挪到检验项目 +UPDATE `sys_permission` +SET `parent_id` = '1900000000000000906', `name` = '导入', `update_time` = NOW() +WHERE `id` = '1860000000000000067' + AND `perms` = 'mes:mes_raw_material_inspect_item:importExcel'; + +INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `menu_type`, `perms`, `perms_type`, `sort_no`, `is_route`, `is_leaf`, `hidden`, `status`, `del_flag`, `create_by`, `create_time`) +SELECT '1900000000000000907', '1900000000000000906', '新增', 2, 'mes:mes_raw_material_inspect_item:add', '1', 1.00, 0, 1, 0, '1', 0, 'admin', NOW() +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000907'); + +INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `menu_type`, `perms`, `perms_type`, `sort_no`, `is_route`, `is_leaf`, `hidden`, `status`, `del_flag`, `create_by`, `create_time`) +SELECT '1900000000000000908', '1900000000000000906', '编辑', 2, 'mes:mes_raw_material_inspect_item:edit', '1', 2.00, 0, 1, 0, '1', 0, 'admin', NOW() +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000908'); + +INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `menu_type`, `perms`, `perms_type`, `sort_no`, `is_route`, `is_leaf`, `hidden`, `status`, `del_flag`, `create_by`, `create_time`) +SELECT '1900000000000000909', '1900000000000000906', '删除', 2, 'mes:mes_raw_material_inspect_item:delete', '1', 3.00, 0, 1, 0, '1', 0, 'admin', NOW() +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000909'); + +INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `menu_type`, `perms`, `perms_type`, `sort_no`, `is_route`, `is_leaf`, `hidden`, `status`, `del_flag`, `create_by`, `create_time`) +SELECT '1900000000000000910', '1900000000000000906', '批量删除', 2, 'mes:mes_raw_material_inspect_item:deleteBatch', '1', 4.00, 0, 1, 0, '1', 0, 'admin', NOW() +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000910'); + +INSERT INTO `sys_permission` (`id`, `parent_id`, `name`, `menu_type`, `perms`, `perms_type`, `sort_no`, `is_route`, `is_leaf`, `hidden`, `status`, `del_flag`, `create_by`, `create_time`) +SELECT '1900000000000000911', '1900000000000000906', '导出', 2, 'mes:mes_raw_material_inspect_item:exportXls', '1', 5.00, 0, 1, 0, '1', 0, 'admin', NOW() +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_permission` WHERE `id` = '1900000000000000911'); + +-- ===================== D. admin 授权 ===================== +INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `data_rule_ids`, `operate_date`, `operate_ip`) +SELECT REPLACE(UUID(), '-', ''), r.id, p.id, NULL, NOW(), '127.0.0.1' +FROM `sys_role` r +JOIN ( + SELECT id FROM `sys_permission` + WHERE id IN ( + '1900000000000000904','1900000000000000905', + '1860000000000000217','1860000000000000218','1860000000000000219', + '1860000000000000220','1860000000000000221', + '1900000000000000906','1860000000000000067', + '1900000000000000907','1900000000000000908','1900000000000000909', + '1900000000000000910','1900000000000000911' + ) +) p ON 1 = 1 +WHERE r.`role_code` = 'admin' + AND NOT EXISTS ( + SELECT 1 FROM `sys_role_permission` rp + WHERE rp.`role_id` = r.id AND rp.`permission_id` = p.id + ); + +-- 校验输出 +SELECT 'lock_log' AS kind, p.id, pp.name AS parent_name, p.name, p.perms, p.url +FROM sys_permission p +LEFT JOIN sys_permission pp ON pp.id = p.parent_id +WHERE p.id = '1900000000000000904' OR p.parent_id = '1900000000000000904' +UNION ALL +SELECT 'inspect_item', p.id, pp.name, p.name, p.perms, p.url +FROM sys_permission p +LEFT JOIN sys_permission pp ON pp.id = p.parent_id +WHERE p.id = '1900000000000000906' OR p.parent_id = '1900000000000000906' +UNION ALL +SELECT 'cleaned_btn', p.id, pp.name, p.name, p.perms, p.url +FROM sys_permission p +LEFT JOIN sys_permission pp ON pp.id = p.parent_id +WHERE p.id IN ('1860000000000000061','1860000000000000071') +UNION ALL +SELECT 'equip_part', p.id, pp.name, p.name, p.perms, p.url +FROM sys_permission p +LEFT JOIN sys_permission pp ON pp.id = p.parent_id +WHERE p.id = '1860000000000000215' OR p.parent_id = '1860000000000000215'; diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_170__grant_raw_material_inspect_role_perms.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_170__grant_raw_material_inspect_role_perms.sql new file mode 100644 index 00000000..94f8f8f4 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_170__grant_raw_material_inspect_role_perms.sql @@ -0,0 +1,17 @@ +-- 原材料检验项目/标准:补授权给 admin/system/vue3/zuhuadmin(菜单恢复后按钮权限未同步到各角色) +SET NAMES utf8mb4; + +INSERT INTO `sys_role_permission` (`id`, `role_id`, `permission_id`, `operate_date`, `operate_ip`) +SELECT REPLACE(UUID(), '-', ''), r.id, p.id, NOW(), '127.0.0.1' +FROM `sys_role` r +CROSS JOIN `sys_permission` p +WHERE r.role_code IN ('admin', 'system', 'vue3', 'zuhuadmin') + AND ( + p.perms LIKE 'mes:mes_raw_material_inspect_item:%' + OR p.perms LIKE 'mes:mes_raw_material_inspect_std:%' + OR p.id IN ('1900000000000000897', '1900000000000000906') + ) + AND NOT EXISTS ( + SELECT 1 FROM `sys_role_permission` rp + WHERE rp.role_id = r.id AND rp.permission_id = p.id + ); diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_171__mes_xsl_formula_spec_line_decimal3.sql b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_171__mes_xsl_formula_spec_line_decimal3.sql new file mode 100644 index 00000000..a8e3a440 --- /dev/null +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_171__mes_xsl_formula_spec_line_decimal3.sql @@ -0,0 +1,12 @@ +-- 配合示方明细:重量%、体积统一为三位小数 +ALTER TABLE `mes_xsl_formula_spec_line` + MODIFY COLUMN `weight_percent` decimal(18,3) DEFAULT NULL COMMENT '重量%', + MODIFY COLUMN `volume` decimal(18,3) DEFAULT NULL COMMENT '体积'; + +UPDATE `mes_xsl_formula_spec_line` +SET `weight_percent` = ROUND(`weight_percent`, 3) +WHERE `weight_percent` IS NOT NULL; + +UPDATE `mes_xsl_formula_spec_line` +SET `volume` = ROUND(`volume`, 3) +WHERE `volume` IS NOT NULL; diff --git a/jeecgboot-vue3/package.json b/jeecgboot-vue3/package.json index 5944ea23..b4ea6926 100644 --- a/jeecgboot-vue3/package.json +++ b/jeecgboot-vue3/package.json @@ -34,7 +34,7 @@ "@traptitech/markdown-it-katex": "^3.6.0", "@vant/area-data": "^1.5.2", "@vue/shared": "^3.5.22", - "@vueuse/core": "^10.11.1", + "@vueuse/core": "^10.11.1", "@zxcvbn-ts/core": "^3.0.4", "ant-design-vue": "^4.2.6", "axios": "^1.12.2", diff --git a/jeecgboot-vue3/src/hooks/web/useWebSocket.ts b/jeecgboot-vue3/src/hooks/web/useWebSocket.ts index 91c6cd6c..c2be2e04 100644 --- a/jeecgboot-vue3/src/hooks/web/useWebSocket.ts +++ b/jeecgboot-vue3/src/hooks/web/useWebSocket.ts @@ -48,9 +48,12 @@ export function ensureWebSocketConnected(): void { if (!url) { return; } - if (result?.status?.value === 'OPEN' && connectedUrl === url) { + //update-begin---author:jiangxh ---date:20260729 for:【WebSocket】已连接/连接中则复用,避免重复建连----------- + const status = result?.status?.value; + if (connectedUrl === url && (status === 'OPEN' || status === 'CONNECTING')) { return; } + //update-end---author:jiangxh ---date:20260729 for:【WebSocket】已连接/连接中则复用,避免重复建连----------- connectWebSocket(url); } @@ -59,20 +62,34 @@ export function ensureWebSocketConnected(): void { * @param url */ export function connectWebSocket(url: string) { + //update-begin---author:jiangxh ---date:20260729 for:【WebSocket】单例连接:关闭旧实例后再建,防止多路 autoReconnect 互踢----------- + const status = result?.status?.value; + if (connectedUrl === url && (status === 'OPEN' || status === 'CONNECTING')) { + return; + } + try { + result?.close?.(); + } catch { + // ignore + } connectedUrl = url; + //update-end---author:jiangxh ---date:20260729 for:【WebSocket】单例连接:关闭旧实例后再建,防止多路 autoReconnect 互踢----------- // 代码逻辑说明: v2.4.6 的 websocket 服务端,存在性能和安全问题。 #3278 const token = (getToken() || '') as string; result = useWebSocket(url, { // 自动重连 (遇到错误最多重复连接10次) autoReconnect: { - retries : 10, - delay : 5000 + retries: 10, + delay: 5000, }, - // 心跳检测 + // 心跳检测:服务端同连接直接回 ping;pongTimeout 需大于网络抖动 + //update-begin---author:jiangxh ---date:20260729 for:【WebSocket】稳定心跳参数,避免 pong 超时频繁断线----------- heartbeat: { - message: "ping", - interval: 55000 + message: 'ping', + interval: 30000, + pongTimeout: 20000, }, + //update-end---author:jiangxh ---date:20260729 for:【WebSocket】稳定心跳参数,避免 pong 超时频繁断线----------- protocols: [token], // 代码逻辑说明: [issues/6662] 演示系统socket总断,换一个写法 onConnected: function (ws) { @@ -81,7 +98,11 @@ export function connectWebSocket(url: string) { //update-begin---author:xsl ---date:20260528 for:【IM聊天】WS 重连后通知监听方重新拉取消息----------- if (wsConnectionCount > 1) { reconnectListeners.forEach((cb) => { - try { cb(); } catch (err) { console.error(err); } + try { + cb(); + } catch (err) { + console.error(err); + } }); } //update-end---author:xsl ---date:20260528 for:【IM聊天】WS 重连后通知监听方重新拉取消息----------- @@ -112,54 +133,8 @@ export function connectWebSocket(url: string) { } }, }); - // if (result) { - // result.open = onOpen; - // result.close = onClose; - - // const ws = unref(result.ws); - // if(ws!=null){ - // ws.onerror = onError; - // ws.onmessage = onMessage; - // ws.onopen = onOpen; - // ws.onclose = onClose; - // - // } - // } } -function onOpen() { - console.log('[WebSocket] 连接成功'); -} - -function onClose(e) { - console.log('[WebSocket] 连接断开:', e); -} - -function onError(e) { - console.log('[WebSocket] 连接发生错误: ', e); -} - -function onMessage(e) { - console.debug('[WebSocket] -----接收消息-------', e.data); - try { - // 代码逻辑说明: 【issues/1161】前端websocket因心跳导致监听不起作用--- - if(e==='ping'){ - return; - } - const data = JSON.parse(e.data); - for (const callback of listeners.keys()) { - try { - callback(data); - } catch (err) { - console.error(err); - } - } - } catch (err) { - console.error('[WebSocket] data解析失败:', err); - } -} - - /** * 添加 WebSocket 消息监听 * @param callback diff --git a/jeecgboot-vue3/src/utils/http/axios/index.ts b/jeecgboot-vue3/src/utils/http/axios/index.ts index 757affcb..6c75f6b1 100644 --- a/jeecgboot-vue3/src/utils/http/axios/index.ts +++ b/jeecgboot-vue3/src/utils/http/axios/index.ts @@ -293,7 +293,9 @@ function createAxios(opt?: Partial) { // authenticationScheme: 'Bearer', authenticationScheme: '', //接口超时设置 - timeout: 10 * 1000, + //update-begin---author:jiangxh ---date:20260729 for:【HTTP】远程库场景默认超时10s过短,调整为60s----------- + timeout: 60 * 1000, + //update-end---author:jiangxh ---date:20260729 for:【HTTP】远程库场景默认超时10s过短,调整为60s----------- // 基础接口地址 // baseURL: globSetting.apiUrl, headers: { 'Content-Type': ContentTypeEnum.JSON }, diff --git a/jeecgboot-vue3/src/views/mes/material/MesMaterial.api.ts b/jeecgboot-vue3/src/views/mes/material/MesMaterial.api.ts index 256b2c9e..073728b8 100644 --- a/jeecgboot-vue3/src/views/mes/material/MesMaterial.api.ts +++ b/jeecgboot-vue3/src/views/mes/material/MesMaterial.api.ts @@ -10,6 +10,8 @@ enum Api { importExcel = '/mes/material/material/importExcel', exportXls = '/mes/material/material/exportXls', queryById = '/mes/material/material/queryById', + checkMaterialCode = '/mes/material/material/checkMaterialCode', + checkMaterialName = '/mes/material/material/checkMaterialName', } export const getExportUrl = Api.exportXls; @@ -17,6 +19,12 @@ export const getImportUrl = Api.importExcel; export const list = (params) => defHttp.get({ url: Api.list, params }); export const queryById = (params) => defHttp.get({ url: Api.queryById, params }, { successMessageMode: 'none' }); +export const checkMaterialCode = (params: { materialCode: string; dataId?: string }) => + defHttp.get({ url: Api.checkMaterialCode, params }, { successMessageMode: 'none', errorMessageMode: 'none' }); + +export const checkMaterialName = (params: { materialName: string; dataId?: string }) => + defHttp.get({ url: Api.checkMaterialName, params }, { successMessageMode: 'none', errorMessageMode: 'none' }); + export const deleteOne = (params, handleSuccess) => defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => handleSuccess()); diff --git a/jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts b/jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts index 8e862af3..71952304 100644 --- a/jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts +++ b/jeecgboot-vue3/src/views/mes/material/MesMaterial.data.ts @@ -1,5 +1,6 @@ import { BasicColumn, FormSchema } from '/@/components/Table'; import { loadTreeData } from '/@/api/common/api'; +import { checkMaterialName } from './MesMaterial.api'; function useStatusText(v: unknown) { if (v === 1) return '使用中'; @@ -32,6 +33,7 @@ const glueCategoryProps = { placeholder: '请选择胶料类别', }; +//update-begin---author:jiangxh ---date:20260729 for:【胶料】列表/表单去掉胶料编码展示----------- export const columns: BasicColumn[] = [ { title: '胶料名称', align: 'center', width: 160, dataIndex: 'materialName' }, { title: '胶料类别', align: 'center', width: 140, dataIndex: 'categoryId_dictText' }, @@ -92,7 +94,32 @@ export const searchFormSchema: FormSchema[] = [ export const formSchema: FormSchema[] = [ { label: '', field: 'id', component: 'Input', show: false }, - { label: '胶料名称', field: 'materialName', component: 'Input', required: true }, + //update-begin---author:jiangxh ---date:20260730 for:【胶料】编号隐藏,保存由后端按名称回填----------- + // 列表/表单均不展示;新增编辑保存后后端将 materialCode = materialName + { label: '', field: 'materialCode', component: 'Input', show: false }, + //update-end---author:jiangxh ---date:20260730 for:【胶料】编号隐藏,保存由后端按名称回填----------- + { + label: '胶料名称', + field: 'materialName', + component: 'Input', + required: true, + dynamicRules: ({ model }) => [ + { required: true, message: '请输入胶料名称' }, + { + validator: async (_rule, value) => { + const v = value == null ? '' : String(value).trim(); + if (!v) return Promise.resolve(); + try { + await checkMaterialName({ materialName: v, dataId: model?.id }); + return Promise.resolve(); + } catch (e: any) { + return Promise.reject(e?.response?.data?.message || e?.message || '胶料名称不能重复'); + } + }, + trigger: 'blur', + }, + ], + }, { label: '胶料类别', field: 'categoryId', @@ -141,3 +168,4 @@ export const formSchema: FormSchema[] = [ componentProps: { options: specialRubberOptions }, }, ]; +//update-end---author:jiangxh ---date:20260729 for:【胶料】列表/表单去掉胶料编码展示----------- diff --git a/jeecgboot-vue3/src/views/mes/material/MesMaterialList.vue b/jeecgboot-vue3/src/views/mes/material/MesMaterialList.vue index b6c74ff3..875031d1 100644 --- a/jeecgboot-vue3/src/views/mes/material/MesMaterialList.vue +++ b/jeecgboot-vue3/src/views/mes/material/MesMaterialList.vue @@ -29,6 +29,7 @@ import { useListPage } from '/@/hooks/system/useListPage'; import MesMaterialModal from './modules/MesMaterialModal.vue'; import { columns, searchFormSchema } from './MesMaterial.data'; import { batchDelete, deleteOne, getExportUrl, getImportUrl, list } from './MesMaterial.api'; +import { applyJeecgLikeQuery, RUBBER_MATERIAL_LIKE_FIELDS } from './materialQuery.util'; const [registerModal, { openModal }] = useModal(); const { tableContext, onExportXls, onImportXls } = useListPage({ @@ -39,6 +40,7 @@ const { tableContext, onExportXls, onImportXls } = useListPage({ canResize: true, formConfig: { labelWidth: 120, schemas: searchFormSchema, autoSubmitOnEnter: true, showAdvancedButton: true }, actionColumn: { width: 120 }, + beforeFetch: (params) => applyJeecgLikeQuery(params, RUBBER_MATERIAL_LIKE_FIELDS), }, exportConfig: { name: '胶料信息', url: getExportUrl }, importConfig: { url: getImportUrl, success: handleSuccess }, diff --git a/jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.api.ts b/jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.api.ts index 811931a2..151a17dd 100644 --- a/jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.api.ts +++ b/jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.api.ts @@ -4,6 +4,8 @@ import { Modal } from 'ant-design-vue'; enum Api { list = '/mes/material/mixerMaterial/list', queryById = '/mes/material/mixerMaterial/queryById', + checkMaterialCode = '/mes/material/mixerMaterial/checkMaterialCode', + checkMaterialName = '/mes/material/mixerMaterial/checkMaterialName', save = '/mes/material/mixerMaterial/add', edit = '/mes/material/mixerMaterial/edit', deleteOne = '/mes/material/mixerMaterial/delete', @@ -17,6 +19,12 @@ export const getImportUrl = Api.importExcel; export const list = (params) => defHttp.get({ url: Api.list, params }); export const queryById = (params) => defHttp.get({ url: Api.queryById, params }); +export const checkMaterialCode = (params: { materialCode: string; dataId?: string }) => + defHttp.get({ url: Api.checkMaterialCode, params }, { successMessageMode: 'none', errorMessageMode: 'none' }); + +export const checkMaterialName = (params: { materialName: string; dataId?: string }) => + defHttp.get({ url: Api.checkMaterialName, params }, { successMessageMode: 'none', errorMessageMode: 'none' }); + export const deleteOne = (params, handleSuccess) => defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => handleSuccess()); diff --git a/jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.data.ts b/jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.data.ts index 36770bd3..a5bb269c 100644 --- a/jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.data.ts +++ b/jeecgboot-vue3/src/views/mes/material/MesMixerMaterial.data.ts @@ -1,5 +1,6 @@ import { BasicColumn, FormSchema } from '/@/components/Table'; import { loadTreeData } from '/@/api/common/api'; +import { checkMaterialCode, checkMaterialName } from './MesMixerMaterial.api'; function feedManageStatusText(v: unknown) { if (v === 1) return '在投管'; @@ -93,8 +94,50 @@ const useStatusOptions = [ export const formSchema: FormSchema[] = [ { label: '', field: 'id', component: 'Input', show: false }, - { label: '物料编码', field: 'materialCode', component: 'Input', required: true }, - { label: '物料名称', field: 'materialName', component: 'Input', required: true }, + { + label: '物料编码', + field: 'materialCode', + component: 'Input', + required: true, + dynamicRules: ({ model }) => [ + { required: true, message: '请输入物料编码' }, + { + validator: async (_rule, value) => { + const v = value == null ? '' : String(value).trim(); + if (!v) return Promise.resolve(); + try { + await checkMaterialCode({ materialCode: v, dataId: model?.id }); + return Promise.resolve(); + } catch (e: any) { + return Promise.reject(e?.response?.data?.message || e?.message || '物料编码不能重复'); + } + }, + trigger: 'blur', + }, + ], + }, + { + label: '物料名称', + field: 'materialName', + component: 'Input', + required: true, + dynamicRules: ({ model }) => [ + { required: true, message: '请输入物料名称' }, + { + validator: async (_rule, value) => { + const v = value == null ? '' : String(value).trim(); + if (!v) return Promise.resolve(); + try { + await checkMaterialName({ materialName: v, dataId: model?.id }); + return Promise.resolve(); + } catch (e: any) { + return Promise.reject(e?.response?.data?.message || e?.message || '物料名称不能重复'); + } + }, + trigger: 'blur', + }, + ], + }, { label: 'ERP编号', field: 'erpCode', component: 'Input' }, { label: '物料大类', @@ -127,7 +170,9 @@ export const formSchema: FormSchema[] = [ componentProps: { options: useStatusOptions }, }, { label: '比重', field: 'specificGravity', component: 'InputNumber', componentProps: { min: 0, step: 0.001, precision: 6 } }, - { label: '保质期(天)', field: 'shelfLifeDays', component: 'InputNumber', componentProps: { min: 0, precision: 0 } }, + //update-begin---author:jiangxh ---date:20260729 for:【密炼物料】新增默认保质期365天----------- + { label: '保质期(天)', field: 'shelfLifeDays', component: 'InputNumber', defaultValue: 365, componentProps: { min: 0, precision: 0 } }, + //update-end---author:jiangxh ---date:20260729 for:【密炼物料】新增默认保质期365天----------- { label: '最短烘胶时间(分钟)', field: 'minBakeMinutes', component: 'InputNumber', componentProps: { min: 0, precision: 0 } }, { label: '总安全库存KG', diff --git a/jeecgboot-vue3/src/views/mes/material/MesMixerMaterialList.vue b/jeecgboot-vue3/src/views/mes/material/MesMixerMaterialList.vue index 06bb3b0c..888298d2 100644 --- a/jeecgboot-vue3/src/views/mes/material/MesMixerMaterialList.vue +++ b/jeecgboot-vue3/src/views/mes/material/MesMixerMaterialList.vue @@ -77,6 +77,7 @@ import MesMixerMaterialModal from './modules/MesMixerMaterialModal.vue'; import MesMixerMaterialSysCategoryModal from './modules/MesMixerMaterialSysCategoryModal.vue'; import { columns, searchFormSchema } from './MesMixerMaterial.data'; import { batchDelete, deleteOne, getExportUrl, getImportUrl, list } from './MesMixerMaterial.api'; +import { applyJeecgLikeQuery, MIXER_MATERIAL_LIKE_FIELDS } from './materialQuery.util'; import { loadTreeData as loadCategoryTreeRoot } from '/@/views/system/category/category.api'; import type { KeyType } from '/@/components/Tree/src/types/tree'; import { deleteMaterialSysCategory, fetchMaterialCategoryRoot } from './MesMixerMaterialSysCategory.api'; @@ -119,7 +120,10 @@ const { tableContext, onExportXls, onImportXls } = useListPage({ canResize: true, formConfig: { labelWidth: 120, schemas: searchFormSchema, autoSubmitOnEnter: true, showAdvancedButton: true }, actionColumn: { width: 120 }, - beforeFetch: (params) => Object.assign(params, queryParam), + beforeFetch: (params) => { + Object.assign(params, queryParam); + return applyJeecgLikeQuery(params, MIXER_MATERIAL_LIKE_FIELDS); + }, }, exportConfig: { name: '密炼物料信息', url: getExportUrl, params: queryParam }, importConfig: { url: getImportUrl, success: handleSuccess }, diff --git a/jeecgboot-vue3/src/views/mes/material/materialQuery.util.ts b/jeecgboot-vue3/src/views/mes/material/materialQuery.util.ts new file mode 100644 index 00000000..0b788e86 --- /dev/null +++ b/jeecgboot-vue3/src/views/mes/material/materialQuery.util.ts @@ -0,0 +1,52 @@ +/** + * Jeecg QueryGenerator 模糊查询工具: + * - 普通字段:值两侧加 * 转为 LIKE + * - 关键字多字段 OR:走 superQueryParams + */ + +/** 给指定字符串查询字段追加 *value*(已含 * 则不重复处理) */ +export function applyJeecgLikeQuery(params: Recordable, fields: string[]): Recordable { + if (!params || !fields?.length) { + return params; + } + for (const field of fields) { + const raw = params[field]; + if (raw == null || raw === '') { + continue; + } + const text = String(raw).trim(); + if (!text || text.includes('*')) { + continue; + } + params[field] = `*${text}*`; + } + return params; +} + +/** 构造多字段 OR 模糊高级查询参数 */ +export function buildOrLikeSuperQuery(fields: string[], keyword: string): { + superQueryMatchType: string; + superQueryParams: string; +} | null { + const kw = keyword?.trim(); + if (!kw || !fields?.length) { + return null; + } + const conditions = fields.map((field) => ({ + field, + rule: 'like', + val: kw, + })); + return { + superQueryMatchType: 'or', + superQueryParams: encodeURI(JSON.stringify(conditions)), + }; +} + +/** 密炼物料文本查询字段 */ +export const MIXER_MATERIAL_LIKE_FIELDS = ['materialCode', 'materialName', 'erpCode', 'materialDesc', 'aliasName']; + +/** 胶料文本查询字段(已去掉胶料编码) */ +//update-begin---author:jiangxh ---date:20260729 for:【选料弹窗】胶料关键字查询去掉编码----------- +export const RUBBER_MATERIAL_LIKE_FIELDS = ['materialName', 'erpCode', 'aliasName', 'shortName']; +//update-end---author:jiangxh ---date:20260729 for:【选料弹窗】胶料关键字查询去掉编码----------- diff --git a/jeecgboot-vue3/src/views/mes/material/modules/MesMaterialSelectModal.vue b/jeecgboot-vue3/src/views/mes/material/modules/MesMaterialSelectModal.vue index 57e9660d..68c7a9ef 100644 --- a/jeecgboot-vue3/src/views/mes/material/modules/MesMaterialSelectModal.vue +++ b/jeecgboot-vue3/src/views/mes/material/modules/MesMaterialSelectModal.vue @@ -10,6 +10,7 @@ import { BasicTable, useTable } from '/@/components/Table'; import { list as materialList, queryById as queryMaterialById } from '../MesMaterial.api'; import { columns as materialColumns, searchFormSchema as materialSearch } from '../MesMaterial.data'; + import { applyJeecgLikeQuery, RUBBER_MATERIAL_LIKE_FIELDS } from '../materialQuery.util'; import { useMessage } from '/@/hooks/web/useMessage'; const emit = defineEmits(['register', 'select']); @@ -21,7 +22,9 @@ const [registerTable, { reload, getSelectRowKeys, getSelectRows, setSelectedRowKeys, clearSelectedRowKeys }] = useTable({ api: materialList, - columns: materialColumns.slice(0, 6), + //update-begin---author:jiangxh ---date:20260729 for:【选料弹窗】配合示方选胶料不展示胶料编码----------- + columns: materialColumns.filter((col) => col.dataIndex !== 'materialCode').slice(0, 6), + //update-end---author:jiangxh ---date:20260729 for:【选料弹窗】配合示方选胶料不展示胶料编码----------- rowKey: 'id', useSearchForm: true, formConfig: { @@ -32,12 +35,15 @@ canResize: false, showIndexColumn: false, immediate: true, - beforeFetch: (params) => ({ - ...params, - enableFlag: params.enableFlag ?? 1, - onlySales: onlySales.value ? 1 : undefined, - excludeProductionFB1: excludeProductionFB1.value ? 1 : undefined, - }), + beforeFetch: (params) => { + const next = { + ...params, + enableFlag: params.enableFlag ?? 1, + onlySales: onlySales.value ? 1 : undefined, + excludeProductionFB1: excludeProductionFB1.value ? 1 : undefined, + }; + return applyJeecgLikeQuery(next, RUBBER_MATERIAL_LIKE_FIELDS); + }, rowSelection: { type: 'radio', columnWidth: 48, diff --git a/jeecgboot-vue3/src/views/mes/material/modules/MesMixerMaterialSelectModal.vue b/jeecgboot-vue3/src/views/mes/material/modules/MesMixerMaterialSelectModal.vue index 5ebbc299..f2b4f592 100644 --- a/jeecgboot-vue3/src/views/mes/material/modules/MesMixerMaterialSelectModal.vue +++ b/jeecgboot-vue3/src/views/mes/material/modules/MesMixerMaterialSelectModal.vue @@ -10,6 +10,7 @@ import { BasicTable, useTable } from '/@/components/Table'; import { list as mixerList, queryById as queryMixerById } from '../MesMixerMaterial.api'; import { columns as mixerColumns, searchFormSchema as mixerSearch } from '../MesMixerMaterial.data'; + import { applyJeecgLikeQuery, MIXER_MATERIAL_LIKE_FIELDS } from '../materialQuery.util'; import { useMessage } from '/@/hooks/web/useMessage'; //update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A53】通用密炼物料选料弹窗种类改读配置表----------- import { @@ -40,6 +41,7 @@ canResize: false, showIndexColumn: false, immediate: true, + beforeFetch: (params) => applyJeecgLikeQuery(params, MIXER_MATERIAL_LIKE_FIELDS), rowSelection: { type: 'radio', columnWidth: 48, diff --git a/jeecgboot-vue3/src/views/system/appconfig/McsDbConfig.data.ts b/jeecgboot-vue3/src/views/system/appconfig/McsDbConfig.data.ts index 213b9d37..15ddf856 100644 --- a/jeecgboot-vue3/src/views/system/appconfig/McsDbConfig.data.ts +++ b/jeecgboot-vue3/src/views/system/appconfig/McsDbConfig.data.ts @@ -3,12 +3,35 @@ import { FormSchema } from '/@/components/Form'; export const mcsDbConfigFormSchema: FormSchema[] = [ { label: 'id', field: 'id', component: 'Input', show: false }, { label: 'tenantId', field: 'tenantId', component: 'InputNumber', show: false }, + { + label: '访问模式', + field: 'accessMode', + component: 'Select', + defaultValue: 'DESKTOP_AGENT', + required: true, + helpMessage: '桌面代理:由厂区桌面端直连设备库;直连:MES 服务器 JDBC(仅调试)', + componentProps: { + options: [ + { label: '桌面代理(推荐)', value: 'DESKTOP_AGENT' }, + { label: '服务端直连', value: 'DIRECT' }, + ], + }, + }, + { + label: '绑定桌面代理 ID', + field: 'agentDeviceId', + component: 'Input', + helpMessage: '与桌面端「设备 ID」一致;留空则自动选用当前在线代理', + componentProps: { placeholder: '例如工控机计算机名' }, + ifShow: ({ values }) => values.accessMode !== 'DIRECT', + }, { label: '服务器地址', field: 'serverHost', component: 'Input', required: true, componentProps: { placeholder: 'IP 或域名,例如 192.168.1.10 或 xxx.vicp.fun' }, + ifShow: ({ values }) => values.accessMode === 'DIRECT', }, { label: '端口', @@ -17,6 +40,7 @@ export const mcsDbConfigFormSchema: FormSchema[] = [ defaultValue: 1433, required: true, componentProps: { min: 1, max: 65535, style: { width: '100%' } }, + ifShow: ({ values }) => values.accessMode === 'DIRECT', }, { label: '数据库名', @@ -24,6 +48,7 @@ export const mcsDbConfigFormSchema: FormSchema[] = [ component: 'Input', defaultValue: 'MES_ShareDB', required: true, + ifShow: ({ values }) => values.accessMode === 'DIRECT', }, { label: '用户名', @@ -31,12 +56,14 @@ export const mcsDbConfigFormSchema: FormSchema[] = [ component: 'Input', required: true, componentProps: { placeholder: '例如 sa' }, + ifShow: ({ values }) => values.accessMode === 'DIRECT', }, { label: '密码', field: 'dbPassword', component: 'InputPassword', componentProps: { placeholder: '编辑时留空表示不修改密码' }, + ifShow: ({ values }) => values.accessMode === 'DIRECT', }, { label: '读取开关', @@ -68,7 +95,7 @@ export const mcsDbConfigFormSchema: FormSchema[] = [ label: '启用连接', field: 'status', component: 'Switch', - helpMessage: '开启后立即连接中间库并热刷新数据源,无需重启后端', + helpMessage: '开启后立即生效(桌面代理模式无需 MES 直连 SQL Server)', componentProps: { checkedChildren: '启用', checkedValue: 1, @@ -83,6 +110,7 @@ export const mcsDbConfigFormSchema: FormSchema[] = [ component: 'InputNumber', defaultValue: 120, componentProps: { min: 10, max: 600, style: { width: '100%' } }, + ifShow: ({ values }) => values.accessMode === 'DIRECT', }, { label: '连接超时(毫秒)', @@ -90,6 +118,7 @@ export const mcsDbConfigFormSchema: FormSchema[] = [ component: 'InputNumber', defaultValue: 120000, componentProps: { min: 5000, max: 600000, style: { width: '100%' } }, + ifShow: ({ values }) => values.accessMode === 'DIRECT', }, { label: '备注', diff --git a/jeecgboot-vue3/src/views/system/appconfig/McsDbConfigModal.vue b/jeecgboot-vue3/src/views/system/appconfig/McsDbConfigModal.vue index b6c745fb..7eb939d9 100644 --- a/jeecgboot-vue3/src/views/system/appconfig/McsDbConfigModal.vue +++ b/jeecgboot-vue3/src/views/system/appconfig/McsDbConfigModal.vue @@ -33,15 +33,15 @@ const values = await getMcsDbConfig({ tenantId }); setModalProps({ confirmLoading: false }); if (values) { - await setFieldsValue({ ...values, dbPassword: '' }); + await setFieldsValue({ ...values, dbPassword: '', accessMode: values.accessMode || 'DESKTOP_AGENT' }); } else { - await setFieldsValue({ tenantId, readEnabled: 1, writeEnabled: 1, status: 0, serverPort: 1433, dbName: 'MES_ShareDB' }); + await setFieldsValue({ tenantId, readEnabled: 1, writeEnabled: 1, status: 0, serverPort: 1433, dbName: 'MES_ShareDB', accessMode: 'DESKTOP_AGENT' }); } }); async function handleSubmit() { const values = await validate(); - if (!values.id && !values.dbPassword) { + if (!values.id && values.accessMode === 'DIRECT' && !values.dbPassword) { createMessage.warning('请输入数据库密码'); return; } diff --git a/jeecgboot-vue3/src/views/system/appconfig/ThirdAppMcsDbConfigForm.vue b/jeecgboot-vue3/src/views/system/appconfig/ThirdAppMcsDbConfigForm.vue index 69f2d468..1991dfe1 100644 --- a/jeecgboot-vue3/src/views/system/appconfig/ThirdAppMcsDbConfigForm.vue +++ b/jeecgboot-vue3/src/views/system/appconfig/ThirdAppMcsDbConfigForm.vue @@ -7,8 +7,8 @@
1.配置说明
- 在此配置 SQL Server 中间库(MES_ShareDB)连接信息。保存后立即生效,无需重启后端,也无需修改 application.yml。 - 读取开关控制 MCS→MES 方向数据查询;写入开关控制 MES→MCS 方向数据写入。 + 推荐使用桌面代理模式:厂区桌面端直连设备 SQL Server,MES 通过 STOMP 命令读写。 + 也可切换为服务端直连(仅调试)。读取/写入开关仍控制 MCS↔MES 方向。
@@ -22,18 +22,32 @@
+
访问模式
+
+ {{ runtimeStatus.agentMode ? '桌面代理' : '服务端直连' }} +
+
+
+
桌面代理
+
+ {{ runtimeStatus.agentOnline ? '在线' : '离线' }} + {{ runtimeStatus.agentDbConnected ? '库已连通' : '库未连通' }} + {{ runtimeStatus.agentHostName || configData.agentDeviceId }} +
+
+
服务器
-
+
数据库
-
+
用户名
@@ -52,14 +66,14 @@
-
连接状态
+
配置状态
- {{ runtimeStatus.dbConfigActive ? '已启用数据库配置' : '使用 yml 默认配置' }} + {{ runtimeStatus.dbConfigActive ? '已启用' : '未启用/回退 yml' }}
编辑配置 - 连接测试 + {{ runtimeStatus.agentMode ? '请求桌面探测' : '连接测试' }} 删除配置
@@ -97,9 +111,12 @@ const connStatus = computed(() => { const s = runtimeStatus.value; if (!configData.value.id) { - return '尚未保存数据库配置,当前使用 application.yml 中的 sqlserver_mcs 默认连接。'; + return '尚未保存配置。推荐使用桌面代理模式:桌面端连接设备库后,MES 即可读写。'; } - return `读取:${s.readEnabled ? '开' : '关'} | 写入:${s.writeEnabled ? '开' : '关'} | 连接:${s.dbConfigActive ? '已启用数据库配置' : '使用 yml 默认配置'}`; + const mode = s.agentMode ? '桌面代理' : '服务端直连'; + const agent = s.agentOnline ? '代理在线' : '代理离线'; + const db = s.agentDbConnected ? '库连通' : '库未连通'; + return `模式:${mode} | ${agent} | ${db} | 读取:${s.readEnabled ? '开' : '关'} | 写入:${s.writeEnabled ? '开' : '关'}${s.agentDbMessage ? ' | ' + s.agentDbMessage : ''}`; }); async function reload() { diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslAutoSmallMaterialDemandPlan/MesXslAutoSmallMaterialDemandPlan.data.ts b/jeecgboot-vue3/src/views/xslmes/mesXslAutoSmallMaterialDemandPlan/MesXslAutoSmallMaterialDemandPlan.data.ts index 225c8e51..16506723 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslAutoSmallMaterialDemandPlan/MesXslAutoSmallMaterialDemandPlan.data.ts +++ b/jeecgboot-vue3/src/views/xslmes/mesXslAutoSmallMaterialDemandPlan/MesXslAutoSmallMaterialDemandPlan.data.ts @@ -1,13 +1,18 @@ import { BasicColumn, FormSchema } from '/@/components/Table'; export const baseColumns: BasicColumn[] = [ + { title: '日期', align: 'center', dataIndex: 'statDate', width: 140 }, { title: '原材料名称', align: 'center', dataIndex: 'rawMaterialName', width: 260, ellipsis: true }, { title: '需求重量(KG)', align: 'center', dataIndex: 'demandWeight', width: 180 }, ]; -export const machineColumns: BasicColumn[] = [{ title: '机台', align: 'center', dataIndex: 'machineName', width: 180 }, ...baseColumns]; +export const machineColumns: BasicColumn[] = [ + baseColumns[0], + { title: '机台', align: 'center', dataIndex: 'machineName', width: 180 }, + ...baseColumns.slice(1), +]; -export const searchFormSchema: FormSchema[] = [ +export const baseSearchFormSchema: FormSchema[] = [ { label: '日期', field: 'statDate', @@ -18,6 +23,12 @@ export const searchFormSchema: FormSchema[] = [ { label: '原材料名称', field: 'rawMaterialName', component: 'JInput', colProps: { span: 6 } }, ]; +export const machineSearchFormSchema: FormSchema[] = [ + baseSearchFormSchema[0], + { label: '机台', field: 'machineName', component: 'JInput', colProps: { span: 6 } }, + ...baseSearchFormSchema.slice(1), +]; + export const superQuerySchema = { machineName: { title: '机台', order: 0, view: 'text' }, statDate: { title: '日期', order: 1, view: 'date' }, diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslAutoSmallMaterialDemandPlan/MesXslAutoSmallMaterialDemandPlanList.vue b/jeecgboot-vue3/src/views/xslmes/mesXslAutoSmallMaterialDemandPlan/MesXslAutoSmallMaterialDemandPlanList.vue index 7c4941f8..f26dcac9 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslAutoSmallMaterialDemandPlan/MesXslAutoSmallMaterialDemandPlanList.vue +++ b/jeecgboot-vue3/src/views/xslmes/mesXslAutoSmallMaterialDemandPlan/MesXslAutoSmallMaterialDemandPlanList.vue @@ -25,7 +25,8 @@ import { baseColumns, machineColumns, - searchFormSchema, + baseSearchFormSchema, + machineSearchFormSchema, superQuerySchema, } from './MesXslAutoSmallMaterialDemandPlan.data'; import { list, getExportUrl } from './MesXslAutoSmallMaterialDemandPlan.api'; @@ -40,7 +41,7 @@ columns: baseColumns, canResize: true, formConfig: { - schemas: searchFormSchema, + schemas: baseSearchFormSchema, autoSubmitOnEnter: true, showAdvancedButton: true, }, @@ -57,20 +58,33 @@ }, }); - const [registerTable, { reload, setColumns }] = tableContext; + const [registerTable, { reload, setColumns, setProps }] = tableContext; const superQueryConfig = reactive(superQuerySchema); onMounted(() => { applyColumns(); + applySearchSchemas(); }); function applyColumns() { setColumns(groupByMachine.value ? machineColumns : baseColumns); } + function applySearchSchemas() { + setProps({ + formConfig: { + schemas: groupByMachine.value ? machineSearchFormSchema : baseSearchFormSchema, + }, + }); + } + function onGroupByMachineChange() { queryParam.groupByMachine = groupByMachine.value ? 1 : 0; + if (!groupByMachine.value) { + delete queryParam.machineName; + } applyColumns(); + applySearchSchemas(); reload(); } diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/MesXslEquipmentLedger.data.ts b/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/MesXslEquipmentLedger.data.ts index 70318c1f..b5459a70 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/MesXslEquipmentLedger.data.ts +++ b/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/MesXslEquipmentLedger.data.ts @@ -4,7 +4,7 @@ import { checkEquipmentCode, checkEquipmentName } from './MesXslEquipmentLedger. const colHalf = { span: 12 }; export const columns: BasicColumn[] = [ - { title: '系统编号', align: 'center', dataIndex: 'ledgerNo', width: 100 }, + { title: '系统编号', align: 'center', dataIndex: 'ledgerNo', width: 100, defaultHidden: true }, { title: '设备编号', align: 'center', dataIndex: 'equipmentCode', width: 130 }, { title: '设备名称', align: 'center', dataIndex: 'equipmentName', width: 160 }, { title: '工序', align: 'center', dataIndex: 'processOperationName', width: 120 }, @@ -12,6 +12,8 @@ export const columns: BasicColumn[] = [ { title: '设备类型', align: 'center', dataIndex: 'equipmentTypeName', width: 110 }, { title: '设备厂家', align: 'center', dataIndex: 'manufacturerName', width: 120 }, { title: '所属工厂', align: 'center', dataIndex: 'factoryName', width: 120 }, + { title: '设备描述', align: 'left', dataIndex: 'equipmentDesc', width: 200, ellipsis: true }, + { title: '受控PDA', align: 'center', dataIndex: 'controlledPda', width: 120 }, { title: '设备状态', align: 'center', dataIndex: 'equipmentStatus_dictText', width: 90 }, { title: '是否启用', align: 'center', dataIndex: 'enabledFlag_dictText', width: 90 }, { title: '设备型号', align: 'center', dataIndex: 'equipmentModel', width: 110, defaultHidden: true }, @@ -85,14 +87,6 @@ export const formSchema: FormSchema[] = [ { label: '', field: 'equipmentCategoryId', component: 'Input', show: false, dynamicRules: () => [{ required: true, message: '请选择设备类别' }] }, { label: '', field: 'equipmentTypeId', component: 'Input', show: false, dynamicRules: () => [{ required: true, message: '请选择设备类型' }] }, { label: '', field: 'factoryId', component: 'Input', show: false }, - { - label: '所属工序', - field: 'processOperationName', - component: 'Input', - slot: 'processOperationPicker', - colProps: colHalf, - dynamicRules: () => [{ required: true, message: '请选择所属工序' }], - }, { label: '系统编号', field: 'ledgerNo', @@ -100,6 +94,30 @@ export const formSchema: FormSchema[] = [ colProps: colHalf, componentProps: { readonly: true, placeholder: '保存时从001起自动生成' }, }, + { + label: '设备类型', + field: 'equipmentTypeName', + component: 'Input', + slot: 'equipmentTypePicker', + colProps: colHalf, + dynamicRules: () => [{ required: true, message: '请选择设备类型' }], + }, + { + label: '所属工序', + field: 'processOperationName', + component: 'Input', + colProps: colHalf, + componentProps: { readonly: true, placeholder: '选择设备类型后自动带出' }, + dynamicRules: () => [{ required: true, message: '请先选择设备类型' }], + }, + { + label: '设备类别', + field: 'equipmentCategoryName', + component: 'Input', + colProps: colHalf, + componentProps: { readonly: true, placeholder: '选择设备类型后自动带出' }, + dynamicRules: () => [{ required: true, message: '请先选择设备类型' }], + }, { label: '设备编号', field: 'equipmentCode', @@ -153,22 +171,6 @@ export const formSchema: FormSchema[] = [ slot: 'manufacturerPicker', colProps: colHalf, }, - { - label: '设备类别', - field: 'equipmentCategoryName', - component: 'Input', - slot: 'equipmentCategoryPicker', - colProps: colHalf, - dynamicRules: () => [{ required: true, message: '请选择设备类别' }], - }, - { - label: '设备类型', - field: 'equipmentTypeName', - component: 'Input', - slot: 'equipmentTypePicker', - colProps: colHalf, - dynamicRules: () => [{ required: true, message: '请选择设备类型' }], - }, { label: '所属工厂', field: 'factoryName', diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/components/MesXslEquipmentLedgerModal.vue b/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/components/MesXslEquipmentLedgerModal.vue index 63f9dc77..4f1d6329 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/components/MesXslEquipmentLedgerModal.vue +++ b/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/components/MesXslEquipmentLedgerModal.vue @@ -10,13 +10,6 @@ @ok="handleSubmit" > - - - - @@ -61,14 +45,14 @@ import { computed, ref, unref, onMounted } from 'vue'; import { BasicModal, useModalInner, useModal } from '/@/components/Modal'; import { BasicForm, useForm } from '/@/components/Form/index'; + import { useMessage } from '/@/hooks/web/useMessage'; import { formSchema } from '../MesXslEquipmentLedger.data'; import { fetchNextLedgerNo, saveOrUpdate } from '../MesXslEquipmentLedger.api'; - import MesXslProcessOperationSelectModal from '/@/views/xslmes/mesXslEquipmentCategory/components/MesXslProcessOperationSelectModal.vue'; import MesXslManufacturerSelectModal from './MesXslManufacturerSelectModal.vue'; - import MesXslEquipmentCategorySelectModal from '/@/views/xslmes/mesXslEquipmentType/components/MesXslEquipmentCategorySelectModal.vue'; import MesXslEquipmentTypeSelectModal from './MesXslEquipmentTypeSelectModal.vue'; const emit = defineEmits(['register', 'success']); + const { createMessage } = useMessage(); const isUpdate = ref(true); const isDetail = ref(false); @@ -89,9 +73,7 @@ manufacturerPickTarget.value === 'factory' ? '选择所属工厂' : '选择设备厂家', ); - const [registerProcessModal, { openModal: openProcessModal }] = useModal(); const [registerManufacturerModal, { openModal: openManufacturerModal }] = useModal(); - const [registerCategoryModal, { openModal: openCategoryModal }] = useModal(); const [registerTypeModal, { openModal: openTypeModal }] = useModal(); const [registerForm, { resetFields, setFieldsValue, validate, setProps, getFieldsValue }] = useForm({ @@ -127,11 +109,6 @@ !unref(isUpdate) ? '新增设备台账' : unref(isDetail) ? '设备台账详情' : '编辑设备台账', ); - function openProcessSelect() { - const v = getFieldsValue(); - openProcessModal(true, { processOperationId: v?.processOperationId }); - } - function openManufacturerSelect(target: 'manufacturer' | 'factory') { manufacturerPickTarget.value = target; const v = getFieldsValue(); @@ -140,23 +117,11 @@ }); } - function openCategorySelect() { - const v = getFieldsValue(); - openCategoryModal(true, { equipmentCategoryId: v?.equipmentCategoryId }); - } - function openTypeSelect() { const v = getFieldsValue(); openTypeModal(true, { equipmentTypeId: v?.equipmentTypeId }); } - function onProcessSelect(payload: Recordable) { - setFieldsValue({ - processOperationId: payload.processOperationId, - processOperationName: payload.processOperationName, - }); - } - function onManufacturerSelect(payload: Recordable) { if (manufacturerPickTarget.value === 'factory') { setFieldsValue({ @@ -171,27 +136,17 @@ } } - function onCategorySelect(payload: Recordable) { - setFieldsValue({ - equipmentCategoryId: payload.equipmentCategoryId, - equipmentCategoryName: payload.equipmentCategoryName, - }); - } - function onTypeSelect(payload: Recordable) { setFieldsValue({ - equipmentTypeId: payload.equipmentTypeId, - equipmentTypeName: payload.equipmentTypeName, - equipmentCategoryId: payload.equipmentCategoryId || getFieldsValue()?.equipmentCategoryId, - equipmentCategoryName: payload.equipmentCategoryName || getFieldsValue()?.equipmentCategoryName, + equipmentTypeId: payload.equipmentTypeId || '', + equipmentTypeName: payload.equipmentTypeName || '', + equipmentCategoryId: payload.equipmentCategoryId || '', + equipmentCategoryName: payload.equipmentCategoryName || '', + processOperationId: payload.processOperationId || '', + processOperationName: payload.processOperationName || '', }); } - function clearProcess(model: Recordable) { - model.processOperationId = ''; - model.processOperationName = ''; - } - function clearManufacturer(model: Recordable) { model.manufacturerId = ''; model.manufacturerName = ''; @@ -202,26 +157,38 @@ model.factoryName = ''; } - function clearCategory(model: Recordable) { - model.equipmentCategoryId = ''; - model.equipmentCategoryName = ''; - } - function clearType(model: Recordable) { model.equipmentTypeId = ''; model.equipmentTypeName = ''; + model.equipmentCategoryId = ''; + model.equipmentCategoryName = ''; + model.processOperationId = ''; + model.processOperationName = ''; } async function handleSubmit() { try { - const values = await validate(); + // validate 结果可能不含隐藏字段最新值,与 getFieldsValue 合并 + const values = { ...(getFieldsValue() || {}), ...(await validate()) }; + if (!values.equipmentTypeId) { + createMessage.warning('请选择设备类型'); + return; + } if (!values.processOperationId) { + createMessage.warning('所选设备类型未绑定工序,请先维护设备类型'); + return; + } + if (!values.equipmentCategoryId) { + createMessage.warning('所选设备类型未绑定设备类别,请先维护设备类型'); return; } setModalProps({ confirmLoading: true }); await saveOrUpdate(values, isUpdate.value); closeModal(); emit('success'); + } catch (e) { + // 表单校验失败时 ant-design 会标红;此处避免未捕获异常导致“点保存无反应” + console.warn('[设备台账] 保存校验未通过', e); } finally { setModalProps({ confirmLoading: false }); } diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/components/MesXslEquipmentTypeSelectModal.vue b/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/components/MesXslEquipmentTypeSelectModal.vue index 9ce6537f..57951dc0 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/components/MesXslEquipmentTypeSelectModal.vue +++ b/jeecgboot-vue3/src/views/xslmes/mesXslEquipmentLedger/components/MesXslEquipmentTypeSelectModal.vue @@ -79,6 +79,8 @@ equipmentTypeName: '', equipmentCategoryId: '', equipmentCategoryName: '', + processOperationId: '', + processOperationName: '', }); closeModal(); return; @@ -88,6 +90,8 @@ equipmentTypeName: row.typeName || '', equipmentCategoryId: row.equipmentCategoryId || '', equipmentCategoryName: row.equipmentCategoryName || '', + processOperationId: row.processOperationId || '', + processOperationName: row.processOperationName || '', }); closeModal(); } diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.api.ts b/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.api.ts index bfa34cf7..a91bb8f5 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.api.ts +++ b/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.api.ts @@ -42,7 +42,10 @@ export const batchDelete = (params, handleSuccess) => { }); }; -export const saveOrUpdate = (params, isUpdate) => defHttp.post({ url: isUpdate ? Api.edit : Api.save, params }); +export const saveOrUpdate = (params, isUpdate) => + //update-begin---author:jiangxh ---date:20260729 for:【配合示方】保存延长超时,避免远程库慢导致误报超时----------- + defHttp.post({ url: isUpdate ? Api.edit : Api.save, params, timeout: 120 * 1000 }); + //update-end---author:jiangxh ---date:20260729 for:【配合示方】保存延长超时,避免远程库慢导致误报超时----------- //update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A38】配合示方生成混炼示方----------- export const buildMixingGeneratePreview = (params) => diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.data.ts b/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.data.ts index b12c7b2e..83aee11b 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.data.ts +++ b/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/MesXslFormulaSpec.data.ts @@ -111,7 +111,7 @@ export function applyWeightPercentToLines(lines: Recordable[]): void { row.weightPercent = null; return; } - row.weightPercent = Number(((phr / totalPhr) * 100).toFixed(1)); + row.weightPercent = Number(((phr / totalPhr) * 100).toFixed(3)); }); } @@ -429,9 +429,25 @@ export function createEmptyLineRows(count = DEFAULT_LINE_ROW_COUNT): Recordable[ return Array.from({ length: count }, () => ({ id: buildUUID() })); } +/** 明细数值保留三位小数 */ +export function roundFormulaLineDecimal3(value: unknown): number | null { + if (value == null || value === '') { + return null; + } + const n = Number(value); + return Number.isFinite(n) ? Number(n.toFixed(3)) : null; +} + /** 确保每行有唯一 id(JVxeTable rowKey 依赖 id,否则单元格无法渲染) */ export function normalizeLineRows(rows: Recordable[]): Recordable[] { - return (rows || []).map((r) => ({ ...r, id: r?.id || buildUUID() })); + //update-begin---author:jiangxh ---date:20260729 for:【配合示方】明细重量%/体积保留三位小数----------- + return (rows || []).map((r) => ({ + ...r, + id: r?.id || buildUUID(), + weightPercent: roundFormulaLineDecimal3(r?.weightPercent), + volume: roundFormulaLineDecimal3(r?.volume), + })); + //update-end---author:jiangxh ---date:20260729 for:【配合示方】明细重量%/体积保留三位小数----------- } function sectionTitle(label: string, field: string): FormSchema { @@ -931,6 +947,7 @@ export function buildLineJVxeColumns(mixingStages?: number | null, tableDisabled type: JVxeTypes.inputNumber, minWidth: 90, align: 'center', + props: { precision: 3 }, }, { title: '体积', @@ -939,6 +956,7 @@ export function buildLineJVxeColumns(mixingStages?: number | null, tableDisabled minWidth: 90, align: 'center', placeholder: '自动计算', + props: { precision: 3 }, }, { title: '备注', diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaGenerateMixingModal.vue b/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaGenerateMixingModal.vue index 8bd6e269..22de543c 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaGenerateMixingModal.vue +++ b/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaGenerateMixingModal.vue @@ -92,6 +92,7 @@ } loading.value = true; try { + //update-begin---author:jiangxh ---date:20260730 for:【混炼示方生成】打开预览即匹配胶料,失败则关闭弹窗----------- const preview = await buildMixingGeneratePreview({ formulaSpecId: formulaSpecId.value }); rubberName.value = preview?.rubberName || ''; mixingStages.value = preview?.mixingStages || 0; @@ -106,9 +107,13 @@ if (!tableRows.value.length) { createMessage.warning('无可生成的混炼段,请检查混合段数'); } + } catch (_e) { + // 预览阶段胶料匹配失败等错误由全局提示,关闭弹窗避免空表继续操作 + closeModal(); } finally { loading.value = false; } + //update-end---author:jiangxh ---date:20260730 for:【混炼示方生成】打开预览即匹配胶料,失败则关闭弹窗----------- }); function formatMachineNames(machines: Recordable[] = []) { diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaSpecModal.vue b/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaSpecModal.vue index a1e55aa0..c57d6b18 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaSpecModal.vue +++ b/jeecgboot-vue3/src/views/xslmes/mesXslFormulaSpec/components/MesXslFormulaSpecModal.vue @@ -441,6 +441,7 @@ createEmptyLineRows, getActiveStageCount, normalizeLineRows, + roundFormulaLineDecimal3, stageTotalNumberProps, SUMMARY_FOOTER_FIELD_KEYS, SUMMARY_METRICS_FIELD_KEYS, @@ -1464,7 +1465,7 @@ const material = (raw as Recordable)?.id != null ? raw : (raw as Recordable)?.result; const sg = Number(material?.specificGravity); if (sg > 0) { - row.volume = Number((Number(row.phr) / sg).toFixed(6)); + row.volume = Number((Number(row.phr) / sg).toFixed(3)); } else { row.volume = null; } @@ -1505,6 +1506,10 @@ .filter((r) => r && (r.mixerMaterialId || r.phr != null)) .map((r, index) => ({ ...stripFormulaLineDisplayFields(r), + //update-begin---author:jiangxh ---date:20260729 for:【配合示方】明细重量%/体积提交保留三位小数----------- + weightPercent: roundFormulaLineDecimal3(r.weightPercent), + volume: roundFormulaLineDecimal3(r.volume), + //update-end---author:jiangxh ---date:20260729 for:【配合示方】明细重量%/体积提交保留三位小数----------- sortNo: index, })); diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslManualSmallMaterialDemandPlan/MesXslManualSmallMaterialDemandPlan.data.ts b/jeecgboot-vue3/src/views/xslmes/mesXslManualSmallMaterialDemandPlan/MesXslManualSmallMaterialDemandPlan.data.ts index 225c8e51..16506723 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslManualSmallMaterialDemandPlan/MesXslManualSmallMaterialDemandPlan.data.ts +++ b/jeecgboot-vue3/src/views/xslmes/mesXslManualSmallMaterialDemandPlan/MesXslManualSmallMaterialDemandPlan.data.ts @@ -1,13 +1,18 @@ import { BasicColumn, FormSchema } from '/@/components/Table'; export const baseColumns: BasicColumn[] = [ + { title: '日期', align: 'center', dataIndex: 'statDate', width: 140 }, { title: '原材料名称', align: 'center', dataIndex: 'rawMaterialName', width: 260, ellipsis: true }, { title: '需求重量(KG)', align: 'center', dataIndex: 'demandWeight', width: 180 }, ]; -export const machineColumns: BasicColumn[] = [{ title: '机台', align: 'center', dataIndex: 'machineName', width: 180 }, ...baseColumns]; +export const machineColumns: BasicColumn[] = [ + baseColumns[0], + { title: '机台', align: 'center', dataIndex: 'machineName', width: 180 }, + ...baseColumns.slice(1), +]; -export const searchFormSchema: FormSchema[] = [ +export const baseSearchFormSchema: FormSchema[] = [ { label: '日期', field: 'statDate', @@ -18,6 +23,12 @@ export const searchFormSchema: FormSchema[] = [ { label: '原材料名称', field: 'rawMaterialName', component: 'JInput', colProps: { span: 6 } }, ]; +export const machineSearchFormSchema: FormSchema[] = [ + baseSearchFormSchema[0], + { label: '机台', field: 'machineName', component: 'JInput', colProps: { span: 6 } }, + ...baseSearchFormSchema.slice(1), +]; + export const superQuerySchema = { machineName: { title: '机台', order: 0, view: 'text' }, statDate: { title: '日期', order: 1, view: 'date' }, diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslManualSmallMaterialDemandPlan/MesXslManualSmallMaterialDemandPlanList.vue b/jeecgboot-vue3/src/views/xslmes/mesXslManualSmallMaterialDemandPlan/MesXslManualSmallMaterialDemandPlanList.vue index 8fae95f1..a8084552 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslManualSmallMaterialDemandPlan/MesXslManualSmallMaterialDemandPlanList.vue +++ b/jeecgboot-vue3/src/views/xslmes/mesXslManualSmallMaterialDemandPlan/MesXslManualSmallMaterialDemandPlanList.vue @@ -25,7 +25,8 @@ import { baseColumns, machineColumns, - searchFormSchema, + baseSearchFormSchema, + machineSearchFormSchema, superQuerySchema, } from './MesXslManualSmallMaterialDemandPlan.data'; import { list, getExportUrl } from './MesXslManualSmallMaterialDemandPlan.api'; @@ -40,7 +41,7 @@ columns: baseColumns, canResize: true, formConfig: { - schemas: searchFormSchema, + schemas: baseSearchFormSchema, autoSubmitOnEnter: true, showAdvancedButton: true, }, @@ -57,20 +58,33 @@ }, }); - const [registerTable, { reload, setColumns }] = tableContext; + const [registerTable, { reload, setColumns, setProps }] = tableContext; const superQueryConfig = reactive(superQuerySchema); onMounted(() => { applyColumns(); + applySearchSchemas(); }); function applyColumns() { setColumns(groupByMachine.value ? machineColumns : baseColumns); } + function applySearchSchemas() { + setProps({ + formConfig: { + schemas: groupByMachine.value ? machineSearchFormSchema : baseSearchFormSchema, + }, + }); + } + function onGroupByMachineChange() { queryParam.groupByMachine = groupByMachine.value ? 1 : 0; + if (!groupByMachine.value) { + delete queryParam.machineName; + } applyColumns(); + applySearchSchemas(); reload(); } diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMillAction/MesXslMillAction.api.ts b/jeecgboot-vue3/src/views/xslmes/mesXslMillAction/MesXslMillAction.api.ts new file mode 100644 index 00000000..2a5d6119 --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMillAction/MesXslMillAction.api.ts @@ -0,0 +1,13 @@ +import { defHttp } from '/@/utils/http/axios'; + +enum Api { + list = '/xslmes/mesXslMillAction/list', + queryById = '/xslmes/mesXslMillAction/queryById', + exportXls = '/xslmes/mesXslMillAction/exportXls', +} + +export const getExportUrl = Api.exportXls; + +export const list = (params) => defHttp.get({ url: Api.list, params }); + +export const queryById = (params) => defHttp.get({ url: Api.queryById, params }); diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMillAction/MesXslMillAction.data.ts b/jeecgboot-vue3/src/views/xslmes/mesXslMillAction/MesXslMillAction.data.ts new file mode 100644 index 00000000..a2767a29 --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMillAction/MesXslMillAction.data.ts @@ -0,0 +1,33 @@ +import { BasicColumn, FormSchema } from '/@/components/Table'; + +export const columns: BasicColumn[] = [ + { title: 'GUID', align: 'center', dataIndex: 'guid', width: 280 }, + { title: '动作地址', align: 'center', dataIndex: 'actAddr', width: 100 }, + { title: '动作名称', align: 'center', dataIndex: 'actName', width: 140 }, + { title: '动作名称(英)', align: 'center', dataIndex: 'actNameEn', width: 140 }, + { title: '动作备注', align: 'center', dataIndex: 'actMemo', width: 120 }, + { title: '关联地址', align: 'center', dataIndex: 'actRepaddr', width: 100 }, + { title: '写入时间', align: 'center', dataIndex: 'writeTime', width: 170 }, + { title: '读写标识', align: 'center', dataIndex: 'rwFlag', width: 90 }, + { title: '更新时间', align: 'center', dataIndex: 'updateTime', width: 170 }, +]; + +export const searchFormSchema: FormSchema[] = [ + { label: '动作名称', field: 'actName', component: 'Input', colProps: { span: 6 } }, + { label: '动作地址', field: 'actAddr', component: 'InputNumber', colProps: { span: 6 } }, + { label: 'GUID', field: 'guid', component: 'Input', colProps: { span: 6 } }, +]; + +export const formSchema: FormSchema[] = [ + { label: '', field: 'id', component: 'Input', show: false }, + { label: 'GUID', field: 'guid', component: 'Input', componentProps: { disabled: true }, colProps: { span: 24 } }, + { label: '动作地址', field: 'actAddr', component: 'InputNumber', componentProps: { disabled: true }, colProps: { span: 12 } }, + { label: '关联地址', field: 'actRepaddr', component: 'InputNumber', componentProps: { disabled: true }, colProps: { span: 12 } }, + { label: '动作名称', field: 'actName', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } }, + { label: '动作名称(英)', field: 'actNameEn', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } }, + { label: '动作备注', field: 'actMemo', component: 'Input', componentProps: { disabled: true }, colProps: { span: 24 } }, + { label: '写入时间', field: 'writeTime', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } }, + { label: '读取时间', field: 'readTime', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } }, + { label: '读写标识', field: 'rwFlag', component: 'InputNumber', componentProps: { disabled: true }, colProps: { span: 12 } }, + { label: '更新时间', field: 'updateTime', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } }, +]; diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMillAction/MesXslMillActionList.vue b/jeecgboot-vue3/src/views/xslmes/mesXslMillAction/MesXslMillActionList.vue new file mode 100644 index 00000000..5a66e75d --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMillAction/MesXslMillActionList.vue @@ -0,0 +1,81 @@ + + + + + diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMillAction/components/MesXslMillActionModal.vue b/jeecgboot-vue3/src/views/xslmes/mesXslMillAction/components/MesXslMillActionModal.vue new file mode 100644 index 00000000..1574dce0 --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMillAction/components/MesXslMillActionModal.vue @@ -0,0 +1,30 @@ + + + diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/MesXslMixerCondition.api.ts b/jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/MesXslMixerCondition.api.ts index a381d3ec..f857e08c 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/MesXslMixerCondition.api.ts +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/MesXslMixerCondition.api.ts @@ -14,10 +14,10 @@ enum Api { export const list = (params) => defHttp.get({ url: Api.list, params }); -export const checkConditionName = (params: { conditionName: string; dataId?: string }) => +export const checkConditionName = (params: { conditionName: string; equipmentId?: string; dataId?: string }) => defHttp.get({ url: Api.checkConditionName, params }, { successMessageMode: 'none', errorMessageMode: 'none' }); -export const checkConditionCode = (params: { conditionCode: string; dataId?: string }) => +export const checkConditionCode = (params: { conditionCode: string; equipmentId?: string; dataId?: string }) => defHttp.get({ url: Api.checkConditionCode, params }, { successMessageMode: 'none', errorMessageMode: 'none' }); export const deleteOne = (params, handleSuccess) => diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/MesXslMixerCondition.data.ts b/jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/MesXslMixerCondition.data.ts index 3de40e0a..aac08657 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/MesXslMixerCondition.data.ts +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMixerCondition/MesXslMixerCondition.data.ts @@ -42,11 +42,13 @@ export const formSchema: FormSchema[] = [ validator: async (_rule, value) => { const v = value == null ? '' : String(value).trim(); if (!v) return Promise.resolve(); + // 未选设备时不做跨设备校验,保存时仍会强制校验 + if (!model?.equipmentId) return Promise.resolve(); try { - await checkConditionName({ conditionName: v, dataId: model?.id }); + await checkConditionName({ conditionName: v, equipmentId: model.equipmentId, dataId: model?.id }); return Promise.resolve(); } catch (e: any) { - return Promise.reject(e?.response?.data?.message || e?.message || '条件名称不能重复'); + return Promise.reject(e?.response?.data?.message || e?.message || '同一设备下条件名称不能重复'); } }, trigger: 'blur', @@ -64,11 +66,12 @@ export const formSchema: FormSchema[] = [ validator: async (_rule, value) => { const v = value == null ? '' : String(value).trim(); if (!v) return Promise.resolve(); + if (!model?.equipmentId) return Promise.resolve(); try { - await checkConditionCode({ conditionCode: v, dataId: model?.id }); + await checkConditionCode({ conditionCode: v, equipmentId: model.equipmentId, dataId: model?.id }); return Promise.resolve(); } catch (e: any) { - return Promise.reject(e?.response?.data?.message || e?.message || '条件代码不能重复'); + return Promise.reject(e?.response?.data?.message || e?.message || '同一设备下条件代码不能重复'); } }, trigger: 'blur', diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts index 1b156e96..68b368c0 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/MesXslMixingSpec.data.ts @@ -79,11 +79,11 @@ export const mainSchema: FormSchema[] = [ rules: [{ required: true, message: '请选择发行编号' }], }, //update-end---author:cursor ---date:20260522 for:【XSLMES-20260522-A33】混炼示方基本信息字段优化----------- - { label: '换算系数', field: 'convertFactor', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 2, style: { width: '100%' } } }, - { label: '填充体积', field: 'fillVolume', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 6, style: { width: '100%' } } }, + { label: '换算系数', field: 'convertFactor', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 3, style: { width: '100%' } } }, + { label: '填充体积', field: 'fillVolume', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 2, style: { width: '100%' } } }, { label: '回收炭黑(秒)', field: 'recycleCarbonSec', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 0, style: { width: '100%' } } }, - { label: '母胶比重', field: 'motherRubberSg', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 6, style: { width: '100%' } } }, - { label: '终炼胶比重', field: 'finalRubberSg', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 6, style: { width: '100%' } } }, + { label: '母胶比重', field: 'motherRubberSg', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 3, style: { width: '100%' } } }, + { label: '终炼胶比重', field: 'finalRubberSg', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 3, style: { width: '100%' } } }, { label: '适用工厂', field: 'applyFactory', component: 'Input', colProps: { span: 8 } }, { label: '段数', field: 'stageCount', component: 'Input', colProps: { span: 8 }, componentProps: { placeholder: '如 2/3' } }, { label: '纯混炼时间(秒)', field: 'pureMixSec', component: 'InputNumber', colProps: { span: 8 }, componentProps: { precision: 0, style: { width: '100%' } } }, @@ -319,7 +319,13 @@ const MIXING_MATERIAL_WEIGHT_SCALE = 6; //update-begin---author:cursor ---date:20260526 for:【XSLMES-20260526-A60】换算系数/配方参数数值展示优化----------- /** 换算系数展示小数位 */ -export const MIXING_CONVERT_FACTOR_SCALE = 2; +export const MIXING_CONVERT_FACTOR_SCALE = 3; + +/** 母胶比重展示小数位 */ +export const MIXING_MOTHER_RUBBER_SG_SCALE = 3; + +/** 填充体积展示小数位 */ +export const MIXING_FILL_VOLUME_SCALE = 2; /** 配方参数设定允许的小数精度 */ export const MIXING_RECIPE_PARAM_DECIMAL_SCALE = 6; @@ -333,7 +339,7 @@ export const MIXING_RECIPE_PARAM_DECIMAL_FIELDS = [ 'maxFeedTemp', ] as const; -/** 换算系数展示:固定保留两位小数 */ +/** 换算系数展示:固定保留三位小数 */ export function formatMixingConvertFactorDisplay(value: unknown): string { if (value === null || value === undefined || value === '') { return ''; @@ -536,7 +542,7 @@ export function calcMixingFillVolume(totalWeight: unknown, specificGravity: unkn return null; } const materialVolume = weight / sg; - return Number(((materialVolume / volume) * 100).toFixed(6)); + return Number(((materialVolume / volume) * 100).toFixed(MIXING_FILL_VOLUME_SCALE)); } //update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A46】填充体积按单重/比重/机台有效体积自动计算----------- @@ -1311,8 +1317,9 @@ export function applyMixingMaterialFromSelection(row: Recordable, material: Reco //update-begin---author:cursor ---date:20260601 for:【XSLMES-20260601-A62】选料弹窗新增胶料页签(查询胶料信息)----------- /** 选料弹窗「胶料」页签表格列(数据源为胶料信息 mes_material) */ export const mixingRubberPickerTableColumns: BasicColumn[] = [ - { title: '胶料编码', align: 'center', width: 140, dataIndex: 'materialCode' }, + //update-begin---author:jiangxh ---date:20260729 for:【选料弹窗】胶料页签去掉胶料编码----------- { title: '胶料名称', align: 'center', width: 180, dataIndex: 'materialName' }, + //update-end---author:jiangxh ---date:20260729 for:【选料弹窗】胶料页签去掉胶料编码----------- //update-begin---author:cursor ---date:20260601 for:【XSLMES-20260601-A62】胶料页签补齐自动/人工称量列----------- { title: '自动/人工称量', align: 'center', width: 132, dataIndex: 'pickerWeighMode' }, //update-end---author:cursor ---date:20260601 for:【XSLMES-20260601-A62】胶料页签补齐自动/人工称量列----------- diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue index 2866c07a..764a5dca 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingMaterialSelectModal.vue @@ -13,7 +13,7 @@ @@ -105,6 +105,11 @@ import { list as rubberList, queryById as queryRubberById } from '/@/views/mes/material/MesMaterial.api'; import { loadTreeData } from '/@/api/common/api'; //update-end---author:cursor ---date:20260601 for:【XSLMES-20260601-A62】胶料页签查询胶料信息(mes_material)-------------> + import { + buildOrLikeSuperQuery, + MIXER_MATERIAL_LIKE_FIELDS, + RUBBER_MATERIAL_LIKE_FIELDS, + } from '/@/views/mes/material/materialQuery.util'; import { useMessage } from '/@/hooks/web/useMessage'; import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue'; import MesXslMixingMaterialCategorySetting from './MesXslMixingMaterialCategorySetting.vue'; @@ -133,6 +138,11 @@ const RUBBER_TREE_ALL = 'ALL'; const RUBBER_CATEGORY_PCODE = 'XSLMES_RUBBER'; const pickerType = ref<'mixer' | 'rubber'>('mixer'); + //update-begin---author:jiangxh ---date:20260729 for:【选料弹窗】胶料页签关键字提示去掉编码----------- + const keywordPlaceholder = computed(() => + pickerType.value === 'rubber' ? '关键字(名称/别名/ERP)' : '关键字(编码/名称/描述)', + ); + //update-end---author:jiangxh ---date:20260729 for:【选料弹窗】胶料页签关键字提示去掉编码----------- const rubberTreeLoading = ref(false); const rubberCategoryTree = ref([]); /** 胶料类别 id -> { code, title },用于按种类配置编码匹配 */ @@ -256,14 +266,20 @@ const kw = keyword.value?.trim(); if (pickerType.value === 'rubber') { const rubberParams = { ...params, ...selectedRubberCategoryFilter.value }; - if (kw) { - rubberParams.materialName = `*${kw}*`; + //update-begin---author:jiangxh ---date:20260729 for:【选料弹窗】胶料关键字按名称/ERP/别名模糊查询----------- + // 关键字按名称/ERP/别名模糊 OR 查询(不含编码) + const orQuery = buildOrLikeSuperQuery(RUBBER_MATERIAL_LIKE_FIELDS, kw || ''); + //update-end---author:jiangxh ---date:20260729 for:【选料弹窗】胶料关键字按名称/ERP/别名模糊查询----------- + if (orQuery) { + Object.assign(rubberParams, orQuery); } return rubberParams; } const next = { ...params, ...selectedCategoryFilter.value }; - if (kw) { - next.materialName = `*${kw}*`; + // 关键字按编码/名称/描述/ERP/别名模糊 OR 查询 + const orQuery = buildOrLikeSuperQuery(MIXER_MATERIAL_LIKE_FIELDS, kw || ''); + if (orQuery) { + Object.assign(next, orQuery); } return next; }, diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue index 49ebd2ca..e270cd16 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue +++ b/jeecgboot-vue3/src/views/xslmes/mesXslMixingSpec/components/MesXslMixingSpecModal.vue @@ -67,7 +67,7 @@ 填充体积 - + 回收炭黑(秒) @@ -99,7 +99,7 @@ 母胶比重 - + 段数 @@ -123,7 +123,7 @@ 终炼胶比重 - + 适用工厂 diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslRawMaterialDemandPlan/MesXslRawMaterialDemandPlan.data.ts b/jeecgboot-vue3/src/views/xslmes/mesXslRawMaterialDemandPlan/MesXslRawMaterialDemandPlan.data.ts index ea838df8..0930c4fb 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslRawMaterialDemandPlan/MesXslRawMaterialDemandPlan.data.ts +++ b/jeecgboot-vue3/src/views/xslmes/mesXslRawMaterialDemandPlan/MesXslRawMaterialDemandPlan.data.ts @@ -10,16 +10,23 @@ export const baseColumns: BasicColumn[] = [ ]; export const machineColumns: BasicColumn[] = [ + baseColumns[0], { title: '机台', align: 'center', dataIndex: 'machineName', width: 160 }, - ...baseColumns, + ...baseColumns.slice(1), ]; -export const searchFormSchema: FormSchema[] = [ +export const baseSearchFormSchema: FormSchema[] = [ { label: '计划日期', field: 'planDate', component: 'DatePicker', colProps: { span: 6 } }, { label: 'ERP编号', field: 'erpCode', component: 'JInput', colProps: { span: 6 } }, { label: '原材料名称', field: 'rawMaterialName', component: 'JInput', colProps: { span: 6 } }, ]; +export const machineSearchFormSchema: FormSchema[] = [ + baseSearchFormSchema[0], + { label: '机台', field: 'machineName', component: 'JInput', colProps: { span: 6 } }, + ...baseSearchFormSchema.slice(1), +]; + export const superQuerySchema = { planDate: { title: '计划日期', order: 0, view: 'date' }, machineName: { title: '机台', order: 1, view: 'text' }, diff --git a/jeecgboot-vue3/src/views/xslmes/mesXslRawMaterialDemandPlan/MesXslRawMaterialDemandPlanList.vue b/jeecgboot-vue3/src/views/xslmes/mesXslRawMaterialDemandPlan/MesXslRawMaterialDemandPlanList.vue index e2fb2c10..1401ef1d 100644 --- a/jeecgboot-vue3/src/views/xslmes/mesXslRawMaterialDemandPlan/MesXslRawMaterialDemandPlanList.vue +++ b/jeecgboot-vue3/src/views/xslmes/mesXslRawMaterialDemandPlan/MesXslRawMaterialDemandPlanList.vue @@ -25,7 +25,8 @@ import { baseColumns, machineColumns, - searchFormSchema, + baseSearchFormSchema, + machineSearchFormSchema, superQuerySchema, } from './MesXslRawMaterialDemandPlan.data'; import { list, getExportUrl } from './MesXslRawMaterialDemandPlan.api'; @@ -40,7 +41,7 @@ columns: baseColumns, canResize: true, formConfig: { - schemas: searchFormSchema, + schemas: baseSearchFormSchema, autoSubmitOnEnter: true, showAdvancedButton: true, }, @@ -57,20 +58,33 @@ }, }); - const [registerTable, { reload, setColumns }] = tableContext; + const [registerTable, { reload, setColumns, setProps }] = tableContext; const superQueryConfig = reactive(superQuerySchema); onMounted(() => { applyColumns(); + applySearchSchemas(); }); function applyColumns() { setColumns(groupByMachine.value ? machineColumns : baseColumns); } + function applySearchSchemas() { + setProps({ + formConfig: { + schemas: groupByMachine.value ? machineSearchFormSchema : baseSearchFormSchema, + }, + }); + } + function onGroupByMachineChange() { queryParam.groupByMachine = groupByMachine.value ? 1 : 0; + if (!groupByMachine.value) { + delete queryParam.machineName; + } applyColumns(); + applySearchSchemas(); reload(); } diff --git a/jeecgboot-vue3/src/views/xslmesMcs/mcsToMesActMill/McsToMesActMill.api.ts b/jeecgboot-vue3/src/views/xslmesMcs/mcsToMesActMill/McsToMesActMill.api.ts new file mode 100644 index 00000000..eef2b9cb --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmesMcs/mcsToMesActMill/McsToMesActMill.api.ts @@ -0,0 +1,13 @@ +import { defHttp } from '/@/utils/http/axios'; + +enum Api { + list = '/xslmes/mcs/mcsToMesActMill/list', + queryById = '/xslmes/mcs/mcsToMesActMill/queryById', + exportXls = '/xslmes/mcs/mcsToMesActMill/exportXls', +} + +export const getExportUrl = Api.exportXls; + +export const list = (params) => defHttp.get({ url: Api.list, params }); + +export const queryById = (params) => defHttp.get({ url: Api.queryById, params }); diff --git a/jeecgboot-vue3/src/views/xslmesMcs/mcsToMesActMill/McsToMesActMill.data.ts b/jeecgboot-vue3/src/views/xslmesMcs/mcsToMesActMill/McsToMesActMill.data.ts new file mode 100644 index 00000000..6e830996 --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmesMcs/mcsToMesActMill/McsToMesActMill.data.ts @@ -0,0 +1,29 @@ +import { BasicColumn, FormSchema } from '/@/components/Table'; + +export const columns: BasicColumn[] = [ + { title: 'GUID', align: 'center', dataIndex: 'guid', width: 280 }, + { title: '动作地址', align: 'center', dataIndex: 'actAddr', width: 100 }, + { title: '动作名称', align: 'center', dataIndex: 'actName', width: 140 }, + { title: '动作名称(英)', align: 'center', dataIndex: 'actNameEn', width: 140 }, + { title: '动作备注', align: 'center', dataIndex: 'actMemo', width: 120 }, + { title: '关联地址', align: 'center', dataIndex: 'actRepaddr', width: 100 }, + { title: '写入时间', align: 'center', dataIndex: 'writeTime', width: 170 }, + { title: '读写标识', align: 'center', dataIndex: 'rwFlag', width: 90 }, +]; + +export const searchFormSchema: FormSchema[] = [ + { label: '动作名称', field: 'actName', component: 'JInput', colProps: { span: 6 } }, + { label: '动作地址', field: 'actAddr', component: 'InputNumber', colProps: { span: 6 } }, +]; + +export const formSchema: FormSchema[] = [ + { label: 'GUID', field: 'guid', component: 'Input', componentProps: { disabled: true }, colProps: { span: 24 } }, + { label: '动作地址', field: 'actAddr', component: 'InputNumber', componentProps: { disabled: true }, colProps: { span: 12 } }, + { label: '关联地址', field: 'actRepaddr', component: 'InputNumber', componentProps: { disabled: true }, colProps: { span: 12 } }, + { label: '动作名称', field: 'actName', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } }, + { label: '动作名称(英)', field: 'actNameEn', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } }, + { label: '动作备注', field: 'actMemo', component: 'Input', componentProps: { disabled: true }, colProps: { span: 24 } }, + { label: '写入时间', field: 'writeTime', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } }, + { label: '读取时间', field: 'readTime', component: 'Input', componentProps: { disabled: true }, colProps: { span: 12 } }, + { label: '读写标识', field: 'rwFlag', component: 'InputNumber', componentProps: { disabled: true }, colProps: { span: 12 } }, +]; diff --git a/jeecgboot-vue3/src/views/xslmesMcs/mcsToMesActMill/components/McsToMesActMillModal.vue b/jeecgboot-vue3/src/views/xslmesMcs/mcsToMesActMill/components/McsToMesActMillModal.vue new file mode 100644 index 00000000..d99e7424 --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmesMcs/mcsToMesActMill/components/McsToMesActMillModal.vue @@ -0,0 +1,30 @@ + + + diff --git a/jeecgboot-vue3/src/views/xslmesMcs/mcsToMesActMill/index.vue b/jeecgboot-vue3/src/views/xslmesMcs/mcsToMesActMill/index.vue new file mode 100644 index 00000000..2133388e --- /dev/null +++ b/jeecgboot-vue3/src/views/xslmesMcs/mcsToMesActMill/index.vue @@ -0,0 +1,71 @@ + + + diff --git a/yy-admin-master/YY.Admin.Core/Core/Services/IEquipmentDbStompSender.cs b/yy-admin-master/YY.Admin.Core/Core/Services/IEquipmentDbStompSender.cs new file mode 100644 index 00000000..8e88e754 --- /dev/null +++ b/yy-admin-master/YY.Admin.Core/Core/Services/IEquipmentDbStompSender.cs @@ -0,0 +1,11 @@ +namespace YY.Admin.Core.Services; + +/// +/// 设备库代理 STOMP 发送扩展(由 StompWebSocketService 实现)。 +/// +public interface IEquipmentDbStompSender +{ + Task SendAgentStatusAsync(object status, CancellationToken cancellationToken = default); + Task SendAgentResultAsync(object result, CancellationToken cancellationToken = default); + string CurrentDeviceId { get; } +} diff --git a/yy-admin-master/YY.Admin.Core/SeedData/SysConfigSeedData.cs b/yy-admin-master/YY.Admin.Core/SeedData/SysConfigSeedData.cs index f3083247..60398216 100644 --- a/yy-admin-master/YY.Admin.Core/SeedData/SysConfigSeedData.cs +++ b/yy-admin-master/YY.Admin.Core/SeedData/SysConfigSeedData.cs @@ -32,7 +32,7 @@ public class SysConfigSeedData : ISqlSugarEntitySeedData new SysConfig{ Id=1300000000191, Name="RefreshToken过期时间", Code=ConfigConst.SysRefreshTokenExpire, Value="20160", SysFlag=YesNoEnum.Y, Remark="刷新Token过期时间(分钟)(一般 refresh_token 的有效时间 > 2 * access_token 的有效时间)", OrderNo=110, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") }, new SysConfig{ Id=1300000000192, Name="会话续期阈值", Code=ConfigConst.SysTokenIdleExtendMinutes, Value="20", SysFlag=YesNoEnum.Y, Remark="桌面端:用户有操作时,若会话剩余不足该分钟数则续期为「Token过期时间」整段", OrderNo=115, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") }, new SysConfig{ Id=1300000000193, Name="登录状态检查间隔", Code=ConfigConst.SysTokenCheckIntervalMinutes, Value="1", SysFlag=YesNoEnum.Y, Remark="桌面端:定时检查登录是否过期的间隔(分钟)", OrderNo=118, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") }, - new SysConfig{ Id=1300000000194, Name="登录永不过期", Code=ConfigConst.SysTokenNeverExpire, Value="False", SysFlag=YesNoEnum.Y, Remark="桌面端:开启后不触发登录过期提示与自动踢回登录页", OrderNo=119, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") }, + new SysConfig{ Id=1300000000194, Name="登录永不过期", Code=ConfigConst.SysTokenNeverExpire, Value="True", SysFlag=YesNoEnum.Y, Remark="桌面端:开启后不触发登录过期提示与自动踢回登录页", OrderNo=119, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") }, new SysConfig{ Id=1300000000201, Name="发送异常日志邮件", Code=ConfigConst.SysErrorMail, Value="False", SysFlag=YesNoEnum.Y, Remark="是否发送异常日志邮件", OrderNo=120, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") }, new SysConfig{ Id=1300000000211, Name="域登录验证", Code=ConfigConst.SysDomainLogin, Value="False", SysFlag=YesNoEnum.Y, Remark="是否开启域登录验证", OrderNo=130, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") }, new SysConfig{ Id=1300000000221, Name="数据校验日志", Code=ConfigConst.SysValidationLog, Value="True", SysFlag=YesNoEnum.Y, Remark="是否数据校验日志", OrderNo=140, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") }, diff --git a/yy-admin-master/YY.Admin.Core/SeedData/SysMenuSeedData.cs b/yy-admin-master/YY.Admin.Core/SeedData/SysMenuSeedData.cs index c19295a9..87cd8396 100644 --- a/yy-admin-master/YY.Admin.Core/SeedData/SysMenuSeedData.cs +++ b/yy-admin-master/YY.Admin.Core/SeedData/SysMenuSeedData.cs @@ -54,6 +54,21 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData new SysMenu{ Id=1300150011201, Pid=1300150000101, Title="胶料快检记录", Path="/xslmes/rubberQuickTestRecord", Name="rubberQuickTestRecord", Component="RubberQuickTestRecordListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=113 }, // 密炼计划 new SysMenu{ Id=1300150011401, Pid=1300150000101, Title="密炼计划", Path="/xslmes/mesXslMixingProductionPlan", Name="mesXslMixingProductionPlan", Component="MixingProductionPlanListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=114 }, + // 开炼机动作中间表(设备库 MCSToMES_Act_Mill 只读) + new SysMenu{ Id=1300150011501, Pid=1300150000101, Title="开炼机动作中间表", Path="/xslmes/mcsActMill", Name="mcsActMill", Component="McsActMillListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=115 }, + + #endregion + + #region 上辅机mes功能 + + new SysMenu{ Id=1300160000101, Pid=0, Title="上辅机mes功能", Path="/upperMes", Name="upperMes", Component="Layout", Icon="", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=9500 }, + new SysMenu{ Id=1300160010101, Pid=1300160000101, Title="交接班", Path="/xslmes/shiftHandover", Name="shiftHandover", Component="ShiftHandoverListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 }, + new SysMenu{ Id=1300160010201, Pid=1300160000101, Title="bom验证", Path="/xslmes/bomValidation", Name="bomValidation", Component="BomValidationListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=101 }, + new SysMenu{ Id=1300160010301, Pid=1300160000101, Title="配方维护", Path="/xslmes/formulaMaintain", Name="formulaMaintain", Component="FormulaMaintainListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=102 }, + new SysMenu{ Id=1300160010401, Pid=1300160000101, Title="计划管理", Path="/xslmes/planManage", Name="planManage", Component="PlanManageListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=103 }, + new SysMenu{ Id=1300160010501, Pid=1300160000101, Title="报表查询", Path="/xslmes/reportQuery", Name="reportQuery", Component="ReportQueryListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=104 }, + new SysMenu{ Id=1300160010601, Pid=1300160000101, Title="设备停机记录", Path="/xslmes/equipmentDowntime", Name="equipmentDowntime", Component="EquipmentDowntimeListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=105 }, + new SysMenu{ Id=1300160010701, Pid=1300160000101, Title="生产日志", Path="/xslmes/productionLog", Name="productionLog", Component="ProductionLogListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=106 }, #endregion diff --git a/yy-admin-master/YY.Admin.Core/SeedData/SysTenantMenuSeedData.cs b/yy-admin-master/YY.Admin.Core/SeedData/SysTenantMenuSeedData.cs index cc3bb0bb..e791e035 100644 --- a/yy-admin-master/YY.Admin.Core/SeedData/SysTenantMenuSeedData.cs +++ b/yy-admin-master/YY.Admin.Core/SeedData/SysTenantMenuSeedData.cs @@ -35,6 +35,15 @@ public class SysTenantMenuSeedData : ISqlSugarEntitySeedData new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300150011201}, new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300150011301}, new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300150011401}, + new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300150011501}, + new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300160000101}, + new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300160010101}, + new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300160010201}, + new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300160010301}, + new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300160010401}, + new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300160010501}, + new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300160010601}, + new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300160010701}, new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300200012101}, new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300200012111}, new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300200012121}, diff --git a/yy-admin-master/YY.Admin.Services/Configuration/appsettings.json b/yy-admin-master/YY.Admin.Services/Configuration/appsettings.json index 0d646546..6bef26a8 100644 --- a/yy-admin-master/YY.Admin.Services/Configuration/appsettings.json +++ b/yy-admin-master/YY.Admin.Services/Configuration/appsettings.json @@ -95,5 +95,15 @@ "DefaultTenantId": 1002, // 自动创建本地用户时使用的默认租户ID "Captcha": "", // 如启用登录验证码,在此传入验证码 "CheckKey": "" // 如启用登录验证码,在此传入验证码key + }, + "EquipmentDb": { + "Enabled": true, + "DeviceId": "", + "ServerHost": "43.108.8.218", + "ServerPort": 1433, + "DbName": "MESNAC_MCS_ShareDB", + "Username": "sa", + "Password": "xsl@123456", + "ConnectTimeoutSeconds": 15 } } diff --git a/yy-admin-master/YY.Admin.Services/Service/Auth/SysAuthService.cs b/yy-admin-master/YY.Admin.Services/Service/Auth/SysAuthService.cs index 310964f0..c71af1a8 100644 --- a/yy-admin-master/YY.Admin.Services/Service/Auth/SysAuthService.cs +++ b/yy-admin-master/YY.Admin.Services/Service/Auth/SysAuthService.cs @@ -2331,11 +2331,23 @@ namespace YY.Admin.Services.Service.Auth } /// - /// 是否开启永不过期 + /// 是否开启永不过期(缺省或读失败时视为开启,避免误踢登录) /// private async Task getSysTokenNeverExpireAsync() { - return await _sysConfigService.GetConfigValue(ConfigConst.SysTokenNeverExpire); + try + { + var raw = await _sysConfigService.GetConfigValue(ConfigConst.SysTokenNeverExpire); + if (string.IsNullOrWhiteSpace(raw)) + return true; + if (bool.TryParse(raw, out var b)) + return b; + return raw.Trim() is "1" or "Y" or "y" or "yes" or "YES" or "on" or "ON"; + } + catch + { + return true; + } } diff --git a/yy-admin-master/YY.Admin.Services/Service/Config/SysConfigService.cs b/yy-admin-master/YY.Admin.Services/Service/Config/SysConfigService.cs index 31388229..3d246a7d 100644 --- a/yy-admin-master/YY.Admin.Services/Service/Config/SysConfigService.cs +++ b/yy-admin-master/YY.Admin.Services/Service/Config/SysConfigService.cs @@ -27,7 +27,37 @@ namespace YY.Admin.Services.Service.Config _sysCacheService.Set($"{CacheConst.KeyConfig}{code}", value); } if (string.IsNullOrWhiteSpace(value)) return default; - return (T)Convert.ChangeType(value, typeof(T)); + + // bool:Convert.ChangeType 对 "1"/"Y" 等会抛异常,统一稳健解析 + var targetType = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T); + if (targetType == typeof(bool)) + { + var b = ParseConfigBool(value); + return (T)(object)b; + } + + return (T)Convert.ChangeType(value, targetType); + } + + private static bool ParseConfigBool(string value) + { + if (bool.TryParse(value, out var b)) + return b; + switch (value.Trim().ToLowerInvariant()) + { + case "1": + case "y": + case "yes": + case "on": + return true; + case "0": + case "n": + case "no": + case "off": + return false; + default: + return false; + } } /// diff --git a/yy-admin-master/YY.Admin.Services/Service/EquipmentDb/EquipmentDbCommandHandler.cs b/yy-admin-master/YY.Admin.Services/Service/EquipmentDb/EquipmentDbCommandHandler.cs new file mode 100644 index 00000000..4f271e6e --- /dev/null +++ b/yy-admin-master/YY.Admin.Services/Service/EquipmentDb/EquipmentDbCommandHandler.cs @@ -0,0 +1,486 @@ +using System.Net.Http; +using System.Net.Http.Json; +using System.Text; +using System.Text.Json; +using System.Text.RegularExpressions; +using Microsoft.Data.SqlClient; +using Microsoft.Extensions.Configuration; +using Prism.Events; +using YY.Admin.Core.Events; +using YY.Admin.Core.Services; + +namespace YY.Admin.Services.Service.EquipmentDb; + +/// +/// 订阅 MES 下发的 EQ_* 命令,执行设备库 SQL 并回传结果。 +/// +public sealed class EquipmentDbCommandHandler +{ + private static readonly JsonSerializerOptions JsonOptions = new() + { + PropertyNameCaseInsensitive = true, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + private readonly IEquipmentDbConnectionFactory _connectionFactory; + private readonly IHttpClientFactory _httpClientFactory; + private readonly IConfiguration _configuration; + private readonly ISignalRService _signalRService; + private readonly HashSet _processedRequestIds = new(); + private readonly object _dedupeLock = new(); + + public EquipmentDbCommandHandler( + IEventAggregator eventAggregator, + IEquipmentDbConnectionFactory connectionFactory, + IHttpClientFactory httpClientFactory, + IConfiguration configuration, + ISignalRService signalRService) + { + _connectionFactory = connectionFactory; + _httpClientFactory = httpClientFactory; + _configuration = configuration; + _signalRService = signalRService; + + eventAggregator.GetEvent() + .Subscribe(OnRemoteCommand, ThreadOption.BackgroundThread); + } + + private void OnRemoteCommand(RemoteCommandPayload payload) + { + if (payload == null || string.IsNullOrWhiteSpace(payload.CommandJson)) + { + return; + } + try + { + using var doc = JsonDocument.Parse(payload.CommandJson); + if (!doc.RootElement.TryGetProperty("cmd", out var cmdEl)) + { + return; + } + var cmd = cmdEl.GetString() ?? string.Empty; + if (!cmd.StartsWith("EQ_", StringComparison.OrdinalIgnoreCase)) + { + return; + } + var request = JsonSerializer.Deserialize(payload.CommandJson, JsonOptions); + if (request == null) + { + return; + } + _ = Task.Run(() => HandleAsync(request, CancellationToken.None)); + } + catch + { + // ignore non-EQ payloads + } + } + + public async Task HandleAsync(EquipmentDbCommandDto request, CancellationToken cancellationToken) + { + if (request == null || string.IsNullOrWhiteSpace(request.RequestId)) + { + return; + } + lock (_dedupeLock) + { + if (!_processedRequestIds.Add(request.RequestId)) + { + return; + } + if (_processedRequestIds.Count > 2000) + { + _processedRequestIds.Clear(); + _processedRequestIds.Add(request.RequestId); + } + } + + var result = new EquipmentDbResultDto + { + RequestId = request.RequestId, + DeviceId = ResolveDeviceId(request.DeviceId), + Cmd = request.Cmd, + RespondedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + }; + + try + { + switch ((request.Cmd ?? string.Empty).ToUpperInvariant()) + { + case "EQ_TEST": + await HandleTestAsync(result, cancellationToken).ConfigureAwait(false); + break; + case "EQ_QUERY": + case "EQ_SYNC_PULL": + await HandleQueryAsync(request, result, cancellationToken).ConfigureAwait(false); + break; + case "EQ_WRITE": + await HandleWriteAsync(request, result, cancellationToken).ConfigureAwait(false); + break; + case "EQ_SYNC_PUSH": + await HandleSyncPushAsync(request, result, cancellationToken).ConfigureAwait(false); + break; + default: + result.Success = false; + result.Error = "未知命令: " + request.Cmd; + break; + } + } + catch (Exception ex) + { + result.Success = false; + result.Error = ex.Message; + result.DbConnected = false; + result.DbMessage = ex.Message; + } + + await SendResultAsync(result, cancellationToken).ConfigureAwait(false); + } + + private async Task HandleTestAsync(EquipmentDbResultDto result, CancellationToken cancellationToken) + { + var (ok, message) = await _connectionFactory.TestAsync(cancellationToken).ConfigureAwait(false); + result.Success = ok; + result.DbConnected = ok; + result.DbMessage = message; + result.Error = ok ? null : message; + await ReportStatusAsync(ok, message, cancellationToken).ConfigureAwait(false); + } + + private async Task HandleQueryAsync(EquipmentDbCommandDto request, EquipmentDbResultDto result, CancellationToken cancellationToken) + { + EquipmentDbWhitelist.ValidateSql(request.Sql, request.Table); + await using var conn = _connectionFactory.CreateConnection(); + await conn.OpenAsync(cancellationToken).ConfigureAwait(false); + await using var cmd = conn.CreateCommand(); + cmd.CommandText = request.Sql!; + cmd.CommandTimeout = 60; + BindParams(cmd, request.Params); + var rows = new List>(); + await using var reader = await cmd.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false); + while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false)) + { + var row = new Dictionary(StringComparer.OrdinalIgnoreCase); + for (var i = 0; i < reader.FieldCount; i++) + { + object? val = reader.IsDBNull(i) ? null : reader.GetValue(i); + if (val is DateTime dt) + { + val = dt.ToString("yyyy-MM-dd HH:mm:ss"); + } + row[reader.GetName(i)] = val; + } + rows.Add(row); + } + result.Success = true; + result.Rows = rows; + result.Affected = rows.Count; + result.DbConnected = true; + result.DbMessage = "ok"; + } + + private async Task HandleWriteAsync(EquipmentDbCommandDto request, EquipmentDbResultDto result, CancellationToken cancellationToken) + { + EquipmentDbWhitelist.ValidateSql(request.Sql, request.Table); + await using var conn = _connectionFactory.CreateConnection(); + await conn.OpenAsync(cancellationToken).ConfigureAwait(false); + await using var cmd = conn.CreateCommand(); + cmd.CommandText = request.Sql!; + cmd.CommandTimeout = 60; + BindParams(cmd, request.Params); + var affected = await cmd.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false); + result.Success = true; + result.Affected = affected; + result.DbConnected = true; + result.DbMessage = "ok"; + } + + private async Task HandleSyncPushAsync(EquipmentDbCommandDto request, EquipmentDbResultDto result, CancellationToken cancellationToken) + { + if (string.IsNullOrWhiteSpace(request.Table) || !EquipmentDbWhitelist.IsAllowedTable(request.Table)) + { + throw new InvalidOperationException("EQ_SYNC_PUSH 表不在白名单"); + } + if (request.Payload == null || request.Payload.Count == 0) + { + throw new InvalidOperationException("EQ_SYNC_PUSH payload 为空"); + } + + request.Payload.TryGetValue("mode", out var modeObj); + var mode = Convert.ToString(modeObj)?.ToLowerInvariant() ?? "insert"; + var rows = ExtractRows(request.Payload); + if (rows.Count == 0) + { + result.Success = true; + result.Affected = 0; + result.DbConnected = true; + return; + } + + List? keys = null; + if (request.Payload.TryGetValue("keys", out var keysObj) && keysObj != null) + { + keys = JsonSerializer.Deserialize>(JsonSerializer.Serialize(keysObj), JsonOptions); + } + + await using var conn = _connectionFactory.CreateConnection(); + await conn.OpenAsync(cancellationToken).ConfigureAwait(false); + var affected = 0; + foreach (var row in rows) + { + if (mode == "upsert" && keys != null && keys.Count > 0) + { + affected += await UpsertRowAsync(conn, request.Table!, row, keys, cancellationToken).ConfigureAwait(false); + } + else if (mode == "update" && keys != null && keys.Count > 0) + { + affected += await UpdateRowAsync(conn, request.Table!, row, keys, cancellationToken).ConfigureAwait(false); + } + else + { + affected += await InsertRowAsync(conn, request.Table!, row, cancellationToken).ConfigureAwait(false); + } + } + result.Success = true; + result.Affected = affected; + result.DbConnected = true; + result.DbMessage = "ok"; + } + + private static List> ExtractRows(Dictionary payload) + { + if (!payload.TryGetValue("rows", out var rowsObj) || rowsObj == null) + { + throw new InvalidOperationException("EQ_SYNC_PUSH 缺少 rows"); + } + if (rowsObj is JsonElement je) + { + return JsonSerializer.Deserialize>>(je.GetRawText(), JsonOptions) + ?? new List>(); + } + return JsonSerializer.Deserialize>>(JsonSerializer.Serialize(rowsObj), JsonOptions) + ?? new List>(); + } + + private static async Task InsertRowAsync( + SqlConnection conn, string table, Dictionary row, CancellationToken cancellationToken) + { + var cols = row.Keys.ToList(); + foreach (var c in cols) + { + if (!Regex.IsMatch(c, @"^[A-Za-z0-9_]+$")) + { + throw new InvalidOperationException("非法列名: " + c); + } + } + var colList = string.Join(",", cols.Select(c => "[" + c + "]")); + var paramList = string.Join(",", cols.Select((_, i) => "@p" + i)); + await using var cmd = conn.CreateCommand(); + cmd.CommandText = $"INSERT INTO [{table}] ({colList}) VALUES ({paramList})"; + for (var i = 0; i < cols.Count; i++) + { + cmd.Parameters.AddWithValue("@p" + i, ToDbValue(row[cols[i]])); + } + return await cmd.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false); + } + + private static async Task UpdateRowAsync( + SqlConnection conn, string table, Dictionary row, List keys, CancellationToken cancellationToken) + { + var setCols = row.Keys.Where(k => !keys.Contains(k, StringComparer.OrdinalIgnoreCase)).ToList(); + if (setCols.Count == 0) + { + return 0; + } + var sets = string.Join(",", setCols.Select((c, i) => $"[{c}]=@s{i}")); + var wheres = string.Join(" AND ", keys.Select((k, i) => $"[{k}]=@k{i}")); + await using var cmd = conn.CreateCommand(); + cmd.CommandText = $"UPDATE [{table}] SET {sets} WHERE {wheres}"; + for (var i = 0; i < setCols.Count; i++) + { + cmd.Parameters.AddWithValue("@s" + i, ToDbValue(GetIgnoreCase(row, setCols[i]))); + } + for (var i = 0; i < keys.Count; i++) + { + cmd.Parameters.AddWithValue("@k" + i, ToDbValue(GetIgnoreCase(row, keys[i]))); + } + return await cmd.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false); + } + + private static async Task UpsertRowAsync( + SqlConnection conn, string table, Dictionary row, List keys, CancellationToken cancellationToken) + { + var updated = await UpdateRowAsync(conn, table, row, keys, cancellationToken).ConfigureAwait(false); + if (updated > 0) + { + return updated; + } + return await InsertRowAsync(conn, table, row, cancellationToken).ConfigureAwait(false); + } + + private static object? GetIgnoreCase(Dictionary row, string key) + { + if (row.TryGetValue(key, out var v)) + { + return v; + } + foreach (var kv in row) + { + if (string.Equals(kv.Key, key, StringComparison.OrdinalIgnoreCase)) + { + return kv.Value; + } + } + return null; + } + + private static object ToDbValue(object? value) + { + if (value == null) + { + return DBNull.Value; + } + if (value is JsonElement je) + { + return je.ValueKind switch + { + JsonValueKind.Null => DBNull.Value, + JsonValueKind.String => je.GetString() ?? (object)DBNull.Value, + JsonValueKind.Number => je.TryGetInt64(out var l) ? l : je.GetDouble(), + JsonValueKind.True => true, + JsonValueKind.False => false, + _ => je.ToString() + }; + } + return value; + } + + private static void BindParams(SqlCommand cmd, List? parameters) + { + if (parameters == null) + { + return; + } + for (var i = 0; i < parameters.Count; i++) + { + cmd.Parameters.AddWithValue("@p" + i, ToDbValue(parameters[i])); + } + if (cmd.CommandText.Contains('?')) + { + var sb = new StringBuilder(); + var idx = 0; + foreach (var ch in cmd.CommandText) + { + if (ch == '?') + { + sb.Append("@p").Append(idx++); + } + else + { + sb.Append(ch); + } + } + cmd.CommandText = sb.ToString(); + } + } + + private async Task SendResultAsync(EquipmentDbResultDto result, CancellationToken cancellationToken) + { + var json = JsonSerializer.Serialize(result, JsonOptions); + var useRest = json.Length > 200_000 || (result.Rows?.Count ?? 0) > 500; + if (useRest) + { + try + { + var client = _httpClientFactory.CreateClient("JeecgApi"); + result.LastChunk = true; + result.ChunkIndex = 0; + result.ChunkTotal = 1; + var resp = await client.PostAsJsonAsync("/xslmes/deviceAgent/anon/resultChunk", result, cancellationToken) + .ConfigureAwait(false); + resp.EnsureSuccessStatusCode(); + return; + } + catch + { + // fall through + } + } + + if (_signalRService is IEquipmentDbStompSender sender) + { + await sender.SendAgentResultAsync(result, cancellationToken).ConfigureAwait(false); + } + } + + public async Task ReportStatusAsync(bool dbConnected, string? dbMessage, CancellationToken cancellationToken = default) + { + var deviceId = ResolveDeviceId(null); + var status = new Dictionary + { + ["deviceId"] = deviceId, + ["hostName"] = Environment.MachineName, + ["dbConnected"] = dbConnected, + ["dbMessage"] = dbMessage, + ["ts"] = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + }; + if (_signalRService is IEquipmentDbStompSender sender) + { + await sender.SendAgentStatusAsync(status, cancellationToken).ConfigureAwait(false); + } + try + { + var client = _httpClientFactory.CreateClient("JeecgApi"); + await client.PostAsJsonAsync("/xslmes/deviceAgent/anon/heartbeat", status, cancellationToken).ConfigureAwait(false); + } + catch + { + // ignore + } + } + + private string ResolveDeviceId(string? fromRequest) + { + if (!string.IsNullOrWhiteSpace(fromRequest)) + { + return fromRequest!; + } + var settings = _connectionFactory.CurrentSettings; + if (!string.IsNullOrWhiteSpace(settings.DeviceId)) + { + return settings.DeviceId; + } + return _configuration.GetValue("EquipmentDb:DeviceId") + ?? Environment.MachineName; + } +} + +public sealed class EquipmentDbCommandDto +{ + public string? RequestId { get; set; } + public string? Cmd { get; set; } + public string? DeviceId { get; set; } + public string? Table { get; set; } + public string? Sql { get; set; } + public string? SqlKey { get; set; } + public List? Params { get; set; } + public Dictionary? Payload { get; set; } + public int? TimeoutMs { get; set; } +} + +public sealed class EquipmentDbResultDto +{ + public string? RequestId { get; set; } + public string? DeviceId { get; set; } + public string? Cmd { get; set; } + public bool Success { get; set; } + public string? Error { get; set; } + public int? Affected { get; set; } + public List>? Rows { get; set; } + public bool? DbConnected { get; set; } + public string? DbMessage { get; set; } + public long? RespondedAt { get; set; } + public int? ChunkIndex { get; set; } + public int? ChunkTotal { get; set; } + public bool? LastChunk { get; set; } +} diff --git a/yy-admin-master/YY.Admin.Services/Service/EquipmentDb/EquipmentDbConnectionFactory.cs b/yy-admin-master/YY.Admin.Services/Service/EquipmentDb/EquipmentDbConnectionFactory.cs new file mode 100644 index 00000000..d1d66d57 --- /dev/null +++ b/yy-admin-master/YY.Admin.Services/Service/EquipmentDb/EquipmentDbConnectionFactory.cs @@ -0,0 +1,51 @@ +using Microsoft.Data.SqlClient; + +namespace YY.Admin.Services.Service.EquipmentDb; + +public interface IEquipmentDbConnectionFactory +{ + SqlConnection CreateConnection(); + Task<(bool Ok, string Message)> TestAsync(CancellationToken cancellationToken = default); + EquipmentDbSettingsStore.EquipmentDbSettings CurrentSettings { get; } + void Reload(); +} + +public sealed class EquipmentDbConnectionFactory : IEquipmentDbConnectionFactory +{ + private EquipmentDbSettingsStore.EquipmentDbSettings _settings = EquipmentDbSettingsStore.Load(); + + public EquipmentDbSettingsStore.EquipmentDbSettings CurrentSettings => _settings; + + public void Reload() + { + _settings = EquipmentDbSettingsStore.Load(); + } + + public SqlConnection CreateConnection() + { + if (!_settings.Enabled) + { + throw new InvalidOperationException("设备库连接未启用"); + } + return new SqlConnection(EquipmentDbSettingsStore.BuildConnectionString(_settings)); + } + + public async Task<(bool Ok, string Message)> TestAsync(CancellationToken cancellationToken = default) + { + try + { + Reload(); + await using var conn = CreateConnection(); + await conn.OpenAsync(cancellationToken).ConfigureAwait(false); + await using var cmd = conn.CreateCommand(); + cmd.CommandText = "SELECT 1"; + cmd.CommandTimeout = Math.Max(5, _settings.ConnectTimeoutSeconds); + var scalar = await cmd.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false); + return (true, "连接成功: " + scalar); + } + catch (Exception ex) + { + return (false, ex.Message); + } + } +} diff --git a/yy-admin-master/YY.Admin.Services/Service/EquipmentDb/EquipmentDbSettingsStore.cs b/yy-admin-master/YY.Admin.Services/Service/EquipmentDb/EquipmentDbSettingsStore.cs new file mode 100644 index 00000000..c8e6a580 --- /dev/null +++ b/yy-admin-master/YY.Admin.Services/Service/EquipmentDb/EquipmentDbSettingsStore.cs @@ -0,0 +1,110 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System.IO; +using YY.Admin.Core.Util; + +namespace YY.Admin.Services.Service.EquipmentDb; + +/// +/// 设备库(SQL Server 中间库)本地连接配置。 +/// +public static class EquipmentDbSettingsStore +{ + public class EquipmentDbSettings + { + public bool Enabled { get; set; } = true; + public string DeviceId { get; set; } = string.Empty; + public string ServerHost { get; set; } = "127.0.0.1"; + public int ServerPort { get; set; } = 1433; + public string DbName { get; set; } = "MES_ShareDB"; + public string Username { get; set; } = "sa"; + public string Password { get; set; } = string.Empty; + public int ConnectTimeoutSeconds { get; set; } = 15; + } + + public static string GetUserConfigPath() + { + var dir = AppWritablePaths.EnsureDirectoryExists(AppWritablePaths.ConfigurationDirectory); + return Path.Combine(dir, "equipment-db.json"); + } + + public static EquipmentDbSettings Load() + { + var path = GetUserConfigPath(); + if (!File.Exists(path)) + { + return new EquipmentDbSettings + { + DeviceId = Environment.MachineName + }; + } + try + { + var settings = JsonConvert.DeserializeObject(File.ReadAllText(path)) + ?? new EquipmentDbSettings(); + if (string.IsNullOrWhiteSpace(settings.DeviceId)) + { + settings.DeviceId = Environment.MachineName; + } + return settings; + } + catch + { + return new EquipmentDbSettings { DeviceId = Environment.MachineName }; + } + } + + public static void Save(EquipmentDbSettings settings) + { + if (settings == null) + { + throw new ArgumentNullException(nameof(settings)); + } + if (string.IsNullOrWhiteSpace(settings.DeviceId)) + { + settings.DeviceId = Environment.MachineName; + } + var path = GetUserConfigPath(); + File.WriteAllText(path, JsonConvert.SerializeObject(settings, Formatting.Indented)); + } + + public static string BuildConnectionString(EquipmentDbSettings s) + { + var timeout = s.ConnectTimeoutSeconds > 0 ? s.ConnectTimeoutSeconds : 15; + return $"Server={s.ServerHost},{s.ServerPort};Database={s.DbName};User Id={s.Username};Password={s.Password};" + + $"Encrypt=False;TrustServerCertificate=True;Connect Timeout={timeout};"; + } + + /// + /// 从 bundled appsettings 的 EquipmentDb 节点合并默认值(若有)。 + /// + public static EquipmentDbSettings LoadMergedWithAppSettings(JObject? root) + { + var settings = Load(); + if (root?["EquipmentDb"] is not JObject eq) + { + return settings; + } + if (string.IsNullOrWhiteSpace(settings.ServerHost) || settings.ServerHost == "127.0.0.1") + { + settings.ServerHost = eq.Value("ServerHost") ?? settings.ServerHost; + } + if (settings.ServerPort == 1433 && eq.Value("ServerPort") is int p) + { + settings.ServerPort = p; + } + if (string.IsNullOrWhiteSpace(settings.DbName) || settings.DbName == "MES_ShareDB") + { + settings.DbName = eq.Value("DbName") ?? settings.DbName; + } + if (string.IsNullOrWhiteSpace(settings.Username) || settings.Username == "sa") + { + settings.Username = eq.Value("Username") ?? settings.Username; + } + if (string.IsNullOrWhiteSpace(settings.Password)) + { + settings.Password = eq.Value("Password") ?? settings.Password; + } + return settings; + } +} diff --git a/yy-admin-master/YY.Admin.Services/Service/EquipmentDb/EquipmentDbWhitelist.cs b/yy-admin-master/YY.Admin.Services/Service/EquipmentDb/EquipmentDbWhitelist.cs new file mode 100644 index 00000000..2217eb35 --- /dev/null +++ b/yy-admin-master/YY.Admin.Services/Service/EquipmentDb/EquipmentDbWhitelist.cs @@ -0,0 +1,78 @@ +using System.Text.RegularExpressions; + +namespace YY.Admin.Services.Service.EquipmentDb; + +/// +/// 设备库 SQL 白名单:仅允许访问 MCS 中间表白名单表。 +/// +public static class EquipmentDbWhitelist +{ + private static readonly HashSet AllowedTables = new(StringComparer.OrdinalIgnoreCase) + { + "MCSToMES_Alarm", "MCSToMES_MixAlarm", "MCSToMES_MixAct", "MCSToMES_Act_Mill", "MCSToMES_MixBatch", + "MCSToMES_MixCon", "MCSToMES_MixCurve", "MCSToMES_MixStep", "MCSToMES_MixWeight", + "MCSToMES_MixExePlan", "MCSToMES_BinToMater", "MCSToMES_AutoXLLog", "MCSToMES_CheckScaleLog", + "MESToMCS_Material", "MESToMCS_MixPlan", "MESToMCS_Recipe", + "MESToMCS_Recipe_MixStep", "MESToMCS_Recipe_Weight" + }; + + private static readonly Regex Dangerous = new( + @"\b(DROP|ALTER|TRUNCATE|EXEC|EXECUTE|xp_|sp_|INTO\s+OUTFILE|OPENROWSET|OPENDATASOURCE)\b", + RegexOptions.IgnoreCase | RegexOptions.Compiled); + + private static readonly Regex TableRef = new( + @"\b(?:FROM|INTO|UPDATE|JOIN)\s+\[?(?[A-Za-z0-9_]+)\]?", + RegexOptions.IgnoreCase | RegexOptions.Compiled); + + public static bool IsAllowedTable(string? table) + { + if (string.IsNullOrWhiteSpace(table)) + { + return false; + } + return AllowedTables.Contains(table.Trim()); + } + + public static void ValidateSql(string? sql, string? tableHint = null) + { + if (string.IsNullOrWhiteSpace(sql)) + { + throw new InvalidOperationException("SQL 不能为空"); + } + if (Dangerous.IsMatch(sql)) + { + throw new InvalidOperationException("SQL 包含禁止关键字"); + } + var trimmed = sql.TrimStart(); + var isSelect = trimmed.StartsWith("SELECT", StringComparison.OrdinalIgnoreCase); + var isInsert = trimmed.StartsWith("INSERT", StringComparison.OrdinalIgnoreCase); + var isUpdate = trimmed.StartsWith("UPDATE", StringComparison.OrdinalIgnoreCase); + var isDelete = trimmed.StartsWith("DELETE", StringComparison.OrdinalIgnoreCase); + if (!(isSelect || isInsert || isUpdate || isDelete)) + { + throw new InvalidOperationException("仅允许 SELECT/INSERT/UPDATE/DELETE"); + } + + if (!string.IsNullOrWhiteSpace(tableHint) && !IsAllowedTable(tableHint)) + { + throw new InvalidOperationException($"表不在白名单: {tableHint}"); + } + + foreach (Match m in TableRef.Matches(sql)) + { + var t = m.Groups["t"].Value; + if (string.Equals(t, "TOP", StringComparison.OrdinalIgnoreCase) + || string.Equals(t, "SELECT", StringComparison.OrdinalIgnoreCase) + || string.Equals(t, "SET", StringComparison.OrdinalIgnoreCase) + || string.Equals(t, "VALUES", StringComparison.OrdinalIgnoreCase) + || string.Equals(t, "WHERE", StringComparison.OrdinalIgnoreCase)) + { + continue; + } + if (!IsAllowedTable(t)) + { + throw new InvalidOperationException($"SQL 引用了未授权表: {t}"); + } + } + } +} diff --git a/yy-admin-master/YY.Admin.Services/Service/EquipmentDb/McsActMillService.cs b/yy-admin-master/YY.Admin.Services/Service/EquipmentDb/McsActMillService.cs new file mode 100644 index 00000000..d84b8401 --- /dev/null +++ b/yy-admin-master/YY.Admin.Services/Service/EquipmentDb/McsActMillService.cs @@ -0,0 +1,125 @@ +using System.Data; +using Microsoft.Data.SqlClient; + +namespace YY.Admin.Services.Service.EquipmentDb; + +/// +/// 开炼机动作中间表 MCSToMES_Act_Mill 只读查询(直连设备库)。 +/// +public interface IMcsActMillService +{ + Task<(IReadOnlyList Records, long Total)> PageAsync( + int pageNo, + int pageSize, + string? actName = null, + int? actAddr = null, + CancellationToken cancellationToken = default); +} + +public sealed class McsActMillRow +{ + public string? Guid { get; set; } + public int? ActAddr { get; set; } + public string? ActName { get; set; } + public string? ActNameEn { get; set; } + public string? ActMemo { get; set; } + public int? ActRepaddr { get; set; } + public DateTime? WriteTime { get; set; } + public DateTime? ReadTime { get; set; } + public int? RwFlag { get; set; } +} + +public sealed class McsActMillService : IMcsActMillService +{ + private const string TableName = "MCSToMES_Act_Mill"; + private readonly IEquipmentDbConnectionFactory _factory; + + public McsActMillService(IEquipmentDbConnectionFactory factory) + { + _factory = factory; + } + + public async Task<(IReadOnlyList Records, long Total)> PageAsync( + int pageNo, + int pageSize, + string? actName = null, + int? actAddr = null, + CancellationToken cancellationToken = default) + { + if (pageNo < 1) pageNo = 1; + if (pageSize < 1) pageSize = 20; + + _factory.Reload(); + await using var conn = _factory.CreateConnection(); + await conn.OpenAsync(cancellationToken).ConfigureAwait(false); + + var where = new List(); + var parameters = new List(); + if (!string.IsNullOrWhiteSpace(actName)) + { + where.Add("act_name LIKE @actName"); + parameters.Add(new SqlParameter("@actName", SqlDbType.NVarChar, 50) { Value = "%" + actName.Trim() + "%" }); + } + if (actAddr.HasValue) + { + where.Add("act_addr = @actAddr"); + parameters.Add(new SqlParameter("@actAddr", SqlDbType.Int) { Value = actAddr.Value }); + } + var whereSql = where.Count == 0 ? "" : " WHERE " + string.Join(" AND ", where); + + var countSql = $"SELECT COUNT(1) FROM [{TableName}]{whereSql}"; + EquipmentDbWhitelist.ValidateSql(countSql, TableName); + long total; + await using (var countCmd = conn.CreateCommand()) + { + countCmd.CommandText = countSql; + countCmd.Parameters.AddRange(CloneParams(parameters)); + var scalar = await countCmd.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false); + total = Convert.ToInt64(scalar ?? 0); + } + + var offset = (pageNo - 1) * pageSize; + var listSql = $@" +SELECT [GUID], [act_addr], [act_name], [act_name_en], [act_memo], [act_Repaddr], [WriteTime], [ReadTime], [RW_Flag] +FROM [{TableName}]{whereSql} +ORDER BY [WriteTime] DESC, [GUID] +OFFSET @offset ROWS FETCH NEXT @pageSize ROWS ONLY"; + EquipmentDbWhitelist.ValidateSql(listSql, TableName); + + var rows = new List(); + await using (var listCmd = conn.CreateCommand()) + { + listCmd.CommandText = listSql; + listCmd.Parameters.AddRange(CloneParams(parameters)); + listCmd.Parameters.Add(new SqlParameter("@offset", SqlDbType.Int) { Value = offset }); + listCmd.Parameters.Add(new SqlParameter("@pageSize", SqlDbType.Int) { Value = pageSize }); + await using var reader = await listCmd.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false); + while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false)) + { + rows.Add(new McsActMillRow + { + Guid = reader["GUID"] as string, + ActAddr = reader["act_addr"] == DBNull.Value ? null : Convert.ToInt32(reader["act_addr"]), + ActName = reader["act_name"] as string, + ActNameEn = reader["act_name_en"] as string, + ActMemo = reader["act_memo"] as string, + ActRepaddr = reader["act_Repaddr"] == DBNull.Value ? null : Convert.ToInt32(reader["act_Repaddr"]), + WriteTime = reader["WriteTime"] == DBNull.Value ? null : Convert.ToDateTime(reader["WriteTime"]), + ReadTime = reader["ReadTime"] == DBNull.Value ? null : Convert.ToDateTime(reader["ReadTime"]), + RwFlag = reader["RW_Flag"] == DBNull.Value ? null : Convert.ToInt32(reader["RW_Flag"]), + }); + } + } + + return (rows, total); + } + + private static SqlParameter[] CloneParams(List source) + { + return source.Select(p => new SqlParameter(p.ParameterName, p.SqlDbType) + { + Size = p.Size, + Value = p.Value ?? DBNull.Value + }).ToArray(); + } +} diff --git a/yy-admin-master/YY.Admin.Services/YY.Admin.Services.csproj b/yy-admin-master/YY.Admin.Services/YY.Admin.Services.csproj index d9924e04..428f79de 100644 --- a/yy-admin-master/YY.Admin.Services/YY.Admin.Services.csproj +++ b/yy-admin-master/YY.Admin.Services/YY.Admin.Services.csproj @@ -20,6 +20,7 @@ + diff --git a/yy-admin-master/YY.Admin/Infrastructure/Hubs/StompWebSocketService.cs b/yy-admin-master/YY.Admin/Infrastructure/Hubs/StompWebSocketService.cs index d5a809da..4963f242 100644 --- a/yy-admin-master/YY.Admin/Infrastructure/Hubs/StompWebSocketService.cs +++ b/yy-admin-master/YY.Admin/Infrastructure/Hubs/StompWebSocketService.cs @@ -9,10 +9,11 @@ using YY.Admin.Core.Services; using YY.Admin.Core.Session; using YY.Admin.Helper; using YY.Admin.Infrastructure.Storage; +using YY.Admin.Services.Service.EquipmentDb; namespace YY.Admin.Infrastructure.Hubs; -public class StompWebSocketService : ISignalRService +public class StompWebSocketService : ISignalRService, IEquipmentDbStompSender { // STOMP heart-beat: send \n every 10 s, declare we want to receive every 10 s private const int HeartbeatMs = 10_000; @@ -188,6 +189,11 @@ public class StompWebSocketService : ISignalRService BuildSubscribeFrame("sub-device-pong", $"/topic/device/{_deviceId}/pong"), cancellationToken).ConfigureAwait(false); + // 设备库命令通道(匿名/登录均订阅) + await SendFrameAsync( + BuildSubscribeFrame("sub-device-eq-cmd", $"/topic/device/{_deviceId}/cmd"), + cancellationToken).ConfigureAwait(false); + if (!anonymous && !string.IsNullOrWhiteSpace(_token)) { await SendFrameAsync( @@ -207,6 +213,25 @@ public class StompWebSocketService : ISignalRService _networkMonitor.SetStompTransportOnline(true); _ = Task.Run(() => ReceiveLoopAsync(cts.Token), cts.Token); + // 连接成功后上报设备代理状态 + _ = Task.Run(async () => + { + try + { + await SendAgentStatusAsync(new + { + deviceId = _deviceId, + hostName = Environment.MachineName, + dbConnected = false, + dbMessage = "pending", + ts = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + }, CancellationToken.None).ConfigureAwait(false); + } + catch + { + // ignore + } + }); return; } catch @@ -232,6 +257,38 @@ public class StompWebSocketService : ISignalRService await SendFrameAsync(frame, cancellationToken).ConfigureAwait(false); } + public string CurrentDeviceId => _deviceId; + + public async Task SendAgentStatusAsync(object status, CancellationToken cancellationToken = default) + { + if (IsDisconnectedByUser() || _socket == null || _socket.State != WebSocketState.Open) + { + return; + } + var json = System.Text.Json.JsonSerializer.Serialize(status); + var frame = "SEND\n" + + "destination:/app/device/agent/status\n" + + "content-type:application/json\n" + + $"content-length:{Encoding.UTF8.GetByteCount(json)}\n\n" + + $"{json}\0"; + await SendFrameAsync(frame, cancellationToken).ConfigureAwait(false); + } + + public async Task SendAgentResultAsync(object result, CancellationToken cancellationToken = default) + { + if (IsDisconnectedByUser() || _socket == null || _socket.State != WebSocketState.Open) + { + return; + } + var json = System.Text.Json.JsonSerializer.Serialize(result); + var frame = "SEND\n" + + "destination:/app/device/agent/result\n" + + "content-type:application/json\n" + + $"content-length:{Encoding.UTF8.GetByteCount(json)}\n\n" + + $"{json}\0"; + await SendFrameAsync(frame, cancellationToken).ConfigureAwait(false); + } + public async Task DisconnectAsync(CancellationToken cancellationToken = default) { var cts = Interlocked.Exchange(ref _connectionCts, null); @@ -437,8 +494,29 @@ public class StompWebSocketService : ISignalRService return "ws://" + baseUrl["http://".Length..] + "/ws/device"; } - private static string ResolveDeviceId(string token) + private string ResolveDeviceId(string token) { + try + { + var fromConfig = EquipmentDbSettingsStore.Load().DeviceId; + if (!string.IsNullOrWhiteSpace(fromConfig)) + { + return fromConfig.Trim(); + } + } + catch + { + // ignore + } + var configured = _configuration.GetValue("EquipmentDb:DeviceId"); + if (!string.IsNullOrWhiteSpace(configured)) + { + return configured.Trim(); + } + if (!string.IsNullOrWhiteSpace(Environment.MachineName)) + { + return Environment.MachineName; + } try { var parts = token.Split('.'); diff --git a/yy-admin-master/YY.Admin/Module/NavigationExtensions.cs b/yy-admin-master/YY.Admin/Module/NavigationExtensions.cs index b96bc61a..9f580f7b 100644 --- a/yy-admin-master/YY.Admin/Module/NavigationExtensions.cs +++ b/yy-admin-master/YY.Admin/Module/NavigationExtensions.cs @@ -21,6 +21,8 @@ using YY.Admin.Views.MixerMaterialTareStrategy; using YY.Admin.Views.RubberQuickTest; using YY.Admin.Views.RubberQuickTestStd; using YY.Admin.Views.MixingProductionPlan; +using YY.Admin.Views.McsActMill; +using YY.Admin.Views.UpperMes; namespace YY.Admin { @@ -105,6 +107,15 @@ namespace YY.Admin containerRegistry.RegisterForNavigation(); // 密炼计划(只读) containerRegistry.RegisterForNavigation(); + containerRegistry.RegisterForNavigation(); + // 上辅机mes功能(占位) + containerRegistry.RegisterForNavigation(); + containerRegistry.RegisterForNavigation(); + containerRegistry.RegisterForNavigation(); + containerRegistry.RegisterForNavigation(); + containerRegistry.RegisterForNavigation(); + containerRegistry.RegisterForNavigation(); + containerRegistry.RegisterForNavigation(); // 打印设置 containerRegistry.RegisterForNavigation(); // 打印模板列表 diff --git a/yy-admin-master/YY.Admin/Module/SyncModule.cs b/yy-admin-master/YY.Admin/Module/SyncModule.cs index 45a81f89..f4c2dc63 100644 --- a/yy-admin-master/YY.Admin/Module/SyncModule.cs +++ b/yy-admin-master/YY.Admin/Module/SyncModule.cs @@ -30,6 +30,7 @@ using YY.Admin.Services.Service.Print; using YY.Admin.Services.Service.RubberQuickTest; using YY.Admin.Services.Service.RubberQuickTestStd; using YY.Admin.Services.Service.MixingProductionPlan; +using YY.Admin.Services.Service.EquipmentDb; namespace YY.Admin.Module; @@ -103,6 +104,11 @@ public class SyncModule : IModule containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); + // 设备库代理(厂区 SQL Server 直连 + EQ_* 命令执行) + containerRegistry.RegisterSingleton(); + containerRegistry.RegisterSingleton(); + containerRegistry.RegisterSingleton(); + var serviceCollection = new ServiceCollection(); serviceCollection.AddTransient(); serviceCollection.AddHttpClient("JeecgApi", (sp, client) => @@ -179,6 +185,21 @@ public class SyncModule : IModule _ = containerProvider.Resolve(); // 密炼计划只读同步协调器 _ = containerProvider.Resolve(); + // 设备库命令处理器(订阅 EQ_*) + var eqHandler = containerProvider.Resolve(); + _ = Task.Run(async () => + { + try + { + var factory = containerProvider.Resolve(); + var (ok, msg) = await factory.TestAsync(CancellationToken.None).ConfigureAwait(false); + await eqHandler.ReportStatusAsync(ok, msg, CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + await eqHandler.ReportStatusAsync(false, ex.Message, CancellationToken.None).ConfigureAwait(false); + } + }); } private static IAsyncPolicy GetRetryPolicy() diff --git a/yy-admin-master/YY.Admin/ViewModels/Base/BaseViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/Base/BaseViewModel.cs index c5861d0f..1cc6e519 100644 --- a/yy-admin-master/YY.Admin/ViewModels/Base/BaseViewModel.cs +++ b/yy-admin-master/YY.Admin/ViewModels/Base/BaseViewModel.cs @@ -110,33 +110,69 @@ namespace YY.Admin.ViewModels _tokenCheckTimer.Interval = TimeSpan.FromMinutes(minutes); } + /// 登录永不过期缓存,避免定时器在 UI 线程同步读库失败后回落到 30 分钟过期。 + private static bool? _tokenNeverExpireCached; + /// /// 是否开启登录永不过期 /// private static bool IsTokenNeverExpireEnabled() { + if (_tokenNeverExpireCached.HasValue) + return _tokenNeverExpireCached.Value; + try { var cfg = Prism.Ioc.ContainerLocator.Current.Resolve(); - return cfg.GetConfigValue(ConfigConst.SysTokenNeverExpire).GetAwaiter().GetResult(); + // 用 string 读取再解析,避免 Convert.ChangeType(bool) 异常被吞掉后误判为未开启 + var raw = cfg.GetConfigValue(ConfigConst.SysTokenNeverExpire).GetAwaiter().GetResult(); + var enabled = ParseNeverExpireFlag(raw); + _tokenNeverExpireCached = enabled; + return enabled; } catch { - return false; + // 读配置失败时按「永不过期」处理,避免误踢回登录页 + return true; } } + private static bool ParseNeverExpireFlag(string? raw) + { + if (string.IsNullOrWhiteSpace(raw)) + return true; + if (bool.TryParse(raw, out var b)) + return b; + return raw.Trim() is "1" or "Y" or "y" or "yes" or "YES" or "on" or "ON"; + } + /// - /// 登录设置保存后刷新检查间隔(已启动定时器时立即生效) + /// 登录设置保存后刷新检查间隔 / 永不过期策略(已启动定时器时立即生效) /// public static void RefreshTokenCheckIntervalFromConfig() { + _tokenNeverExpireCached = null; + if (IsTokenNeverExpireEnabled()) + { + StopTokenCheckTimer(); + return; + } + ApplyTokenCheckIntervalFromConfig(); + if (_tokenCheckTimer != null && !_tokenCheckTimer.IsEnabled && UserContext?.Token != null) + _tokenCheckTimer.Start(); } // 启动定时器的方法 public static void StartTokenCheckTimer() { + _tokenNeverExpireCached = null; + if (IsTokenNeverExpireEnabled()) + { + StopTokenCheckTimer(); + return; + } + if (_tokenCheckTimer == null) { _tokenCheckTimer = new DispatcherTimer(); diff --git a/yy-admin-master/YY.Admin/ViewModels/Control/MenuTreeViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/Control/MenuTreeViewModel.cs index 96c56d63..f4c9da48 100644 --- a/yy-admin-master/YY.Admin/ViewModels/Control/MenuTreeViewModel.cs +++ b/yy-admin-master/YY.Admin/ViewModels/Control/MenuTreeViewModel.cs @@ -170,6 +170,33 @@ namespace YY.Admin.ViewModels.Control ["/xslmes/mesXslMixingProductionPlan"] = "MixingProductionPlanListView", ["mesXslMixingProductionPlan"] = "MixingProductionPlanListView", + ["McsActMillListView"] = "McsActMillListView", + ["/xslmes/mcsActMill"] = "McsActMillListView", + ["mcsActMill"] = "McsActMillListView", + + // 上辅机mes功能(占位) + ["ShiftHandoverListView"] = "ShiftHandoverListView", + ["/xslmes/shiftHandover"] = "ShiftHandoverListView", + ["shiftHandover"] = "ShiftHandoverListView", + ["BomValidationListView"] = "BomValidationListView", + ["/xslmes/bomValidation"] = "BomValidationListView", + ["bomValidation"] = "BomValidationListView", + ["FormulaMaintainListView"] = "FormulaMaintainListView", + ["/xslmes/formulaMaintain"] = "FormulaMaintainListView", + ["formulaMaintain"] = "FormulaMaintainListView", + ["PlanManageListView"] = "PlanManageListView", + ["/xslmes/planManage"] = "PlanManageListView", + ["planManage"] = "PlanManageListView", + ["ReportQueryListView"] = "ReportQueryListView", + ["/xslmes/reportQuery"] = "ReportQueryListView", + ["reportQuery"] = "ReportQueryListView", + ["EquipmentDowntimeListView"] = "EquipmentDowntimeListView", + ["/xslmes/equipmentDowntime"] = "EquipmentDowntimeListView", + ["equipmentDowntime"] = "EquipmentDowntimeListView", + ["ProductionLogListView"] = "ProductionLogListView", + ["/xslmes/productionLog"] = "ProductionLogListView", + ["productionLog"] = "ProductionLogListView", + // 已实现页面:打印设置 ["PrintSettingsView"] = "PrintSettingsView", ["/system/printSettings"] = "PrintSettingsView", diff --git a/yy-admin-master/YY.Admin/ViewModels/Dialogs/ServerSettingsDialogViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/Dialogs/ServerSettingsDialogViewModel.cs index f484305e..1d05c3c9 100644 --- a/yy-admin-master/YY.Admin/ViewModels/Dialogs/ServerSettingsDialogViewModel.cs +++ b/yy-admin-master/YY.Admin/ViewModels/Dialogs/ServerSettingsDialogViewModel.cs @@ -1,4 +1,5 @@ using YY.Admin.Helper; +using YY.Admin.Services.Service.EquipmentDb; namespace YY.Admin.ViewModels.Dialogs { @@ -45,9 +46,6 @@ namespace YY.Admin.ViewModels.Dialogs } private bool _disconnectConnection; - /// - /// 是否断开连接(true=断开,false=连接) - /// public bool DisconnectConnection { get => _disconnectConnection; @@ -60,11 +58,50 @@ namespace YY.Admin.ViewModels.Dialogs } } - /// - /// 连接参数是否可编辑(勾选断开连接后禁用)。 - /// public bool IsConnectionFieldsEnabled => !DisconnectConnection; + private string _eqDeviceId = string.Empty; + public string EqDeviceId + { + get => _eqDeviceId; + set => SetProperty(ref _eqDeviceId, value); + } + + private string _eqServerHost = "127.0.0.1"; + public string EqServerHost + { + get => _eqServerHost; + set => SetProperty(ref _eqServerHost, value); + } + + private int _eqServerPort = 1433; + public int EqServerPort + { + get => _eqServerPort; + set => SetProperty(ref _eqServerPort, value); + } + + private string _eqDbName = "MES_ShareDB"; + public string EqDbName + { + get => _eqDbName; + set => SetProperty(ref _eqDbName, value); + } + + private string _eqUsername = "sa"; + public string EqUsername + { + get => _eqUsername; + set => SetProperty(ref _eqUsername, value); + } + + private string _eqPassword = string.Empty; + public string EqPassword + { + get => _eqPassword; + set => SetProperty(ref _eqPassword, value); + } + public DelegateCommand SaveCommand { get; } public DelegateCommand CancelCommand { get; } public DialogCloseListener RequestClose { get; private set; } @@ -91,6 +128,14 @@ namespace YY.Admin.ViewModels.Dialogs BasePath = string.IsNullOrWhiteSpace(settings.BasePath) ? "/jeecg-boot" : settings.BasePath; DisconnectConnection = settings.DisconnectConnection; ErrorMessage = string.Empty; + + var eq = EquipmentDbSettingsStore.Load(); + EqDeviceId = string.IsNullOrWhiteSpace(eq.DeviceId) ? Environment.MachineName : eq.DeviceId; + EqServerHost = eq.ServerHost; + EqServerPort = eq.ServerPort; + EqDbName = eq.DbName; + EqUsername = eq.Username; + EqPassword = eq.Password; } private void Save() @@ -106,6 +151,11 @@ namespace YY.Admin.ViewModels.Dialogs ErrorMessage = "端口号必须在 1-65535 之间"; return; } + if (EqServerPort <= 0 || EqServerPort > 65535) + { + ErrorMessage = "设备库端口号必须在 1-65535 之间"; + return; + } try { @@ -127,6 +177,19 @@ namespace YY.Admin.ViewModels.Dialogs WebSocketPath = DefaultWebSocketPath, DisconnectConnection = DisconnectConnection }); + + EquipmentDbSettingsStore.Save(new EquipmentDbSettingsStore.EquipmentDbSettings + { + Enabled = true, + DeviceId = string.IsNullOrWhiteSpace(EqDeviceId) ? Environment.MachineName : EqDeviceId.Trim(), + ServerHost = EqServerHost?.Trim() ?? "127.0.0.1", + ServerPort = EqServerPort, + DbName = EqDbName?.Trim() ?? "MES_ShareDB", + Username = EqUsername?.Trim() ?? "sa", + Password = EqPassword ?? string.Empty, + ConnectTimeoutSeconds = 15 + }); + RequestClose.Invoke(new DialogResult(ButtonResult.OK)); } catch (Exception ex) diff --git a/yy-admin-master/YY.Admin/ViewModels/McsActMill/McsActMillListViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/McsActMill/McsActMillListViewModel.cs new file mode 100644 index 00000000..fce00994 --- /dev/null +++ b/yy-admin-master/YY.Admin/ViewModels/McsActMill/McsActMillListViewModel.cs @@ -0,0 +1,100 @@ +using System.Collections.ObjectModel; +using System.Diagnostics; +using HandyControl.Controls; +using YY.Admin.Core; +using YY.Admin.Core.Helper; +using YY.Admin.Services.Service.EquipmentDb; + +namespace YY.Admin.ViewModels.McsActMill; + +public class McsActMillListViewModel : BaseViewModel +{ + private readonly IMcsActMillService _service; + + private ObservableCollection _items = new(); + public ObservableCollection Items + { + get => _items; + set => SetProperty(ref _items, value); + } + + private long _total; + public long Total { get => _total; set => SetProperty(ref _total, value); } + + private int _pageNo = 1; + public int PageNo { get => _pageNo; set => SetProperty(ref _pageNo, value); } + + private int _pageSize = 20; + public int PageSize { get => _pageSize; set => SetProperty(ref _pageSize, value); } + + private string? _filterActName; + public string? FilterActName { get => _filterActName; set => SetProperty(ref _filterActName, value); } + + private string? _filterActAddrText; + public string? FilterActAddrText { get => _filterActAddrText; set => SetProperty(ref _filterActAddrText, value); } + + public DelegateCommand SearchCommand { get; } + public DelegateCommand ResetCommand { get; } + public DelegateCommand PrevPageCommand { get; } + public DelegateCommand NextPageCommand { get; } + + public McsActMillListViewModel( + IMcsActMillService service, + IContainerExtension container, + IRegionManager regionManager) : base(container, regionManager) + { + _service = service; + + SearchCommand = new DelegateCommand(async () => { PageNo = 1; await LoadAsync(); }); + ResetCommand = new DelegateCommand(async () => + { + FilterActName = null; + FilterActAddrText = null; + PageNo = 1; + await LoadAsync(); + }); + PrevPageCommand = new DelegateCommand(async () => { if (PageNo > 1) { PageNo--; await LoadAsync(); } }); + NextPageCommand = new DelegateCommand(async () => { if ((long)PageNo * PageSize < Total) { PageNo++; await LoadAsync(); } }); + + _ = InitializeAsync(); + } + + private async Task InitializeAsync() + { + try + { + await UIHelper.WaitForRenderAsync(); + await LoadAsync(); + } + catch (Exception ex) + { + Debug.WriteLine($"开炼机动作中间表初始化失败: {ex.Message}"); + } + } + + public async Task LoadAsync() + { + try + { + IsLoading = true; + int? actAddr = null; + if (!string.IsNullOrWhiteSpace(FilterActAddrText) + && int.TryParse(FilterActAddrText.Trim(), out var parsed)) + { + actAddr = parsed; + } + + var result = await _service.PageAsync(PageNo, PageSize, FilterActName, actAddr); + Items = new ObservableCollection(result.Records); + Total = result.Total; + } + catch (Exception ex) + { + Growl.Error($"加载开炼机动作中间表失败:{ex.Message}"); + } + finally + { + IsLoading = false; + } + } +} diff --git a/yy-admin-master/YY.Admin/ViewModels/MixerMaterial/MixerMaterialEditDialogViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/MixerMaterial/MixerMaterialEditDialogViewModel.cs index 684c6369..b6ffacf9 100644 --- a/yy-admin-master/YY.Admin/ViewModels/MixerMaterial/MixerMaterialEditDialogViewModel.cs +++ b/yy-admin-master/YY.Admin/ViewModels/MixerMaterial/MixerMaterialEditDialogViewModel.cs @@ -56,11 +56,14 @@ public class MixerMaterialEditDialogViewModel : BaseViewModel, IDialogResultable public void InitializeForAdd() { + //update-begin---author:jiangxh ---date:20260729 for:【密炼物料】新增默认保质期365天----------- Material = new MesMixerMaterial { FeedManageStatus = 1, - UseStatus = 1 + UseStatus = 1, + ShelfLifeDays = 365 }; + //update-end---author:jiangxh ---date:20260729 for:【密炼物料】新增默认保质期365天----------- MinorCategoryOptions.Clear(); RaisePropertyChanged(nameof(IsAddMode)); RaisePropertyChanged(nameof(DialogTitle)); diff --git a/yy-admin-master/YY.Admin/ViewModels/UpperMes/BomValidationListViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/UpperMes/BomValidationListViewModel.cs new file mode 100644 index 00000000..b945e83b --- /dev/null +++ b/yy-admin-master/YY.Admin/ViewModels/UpperMes/BomValidationListViewModel.cs @@ -0,0 +1,13 @@ +using Prism.Ioc; +using Prism.Navigation.Regions; + +namespace YY.Admin.ViewModels.UpperMes; + +public class BomValidationListViewModel : BaseViewModel +{ + public BomValidationListViewModel(IContainerExtension container, IRegionManager regionManager) + : base(container, regionManager) + { + Title = "bom验证"; + } +} diff --git a/yy-admin-master/YY.Admin/ViewModels/UpperMes/EquipmentDowntimeListViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/UpperMes/EquipmentDowntimeListViewModel.cs new file mode 100644 index 00000000..2c6d9c67 --- /dev/null +++ b/yy-admin-master/YY.Admin/ViewModels/UpperMes/EquipmentDowntimeListViewModel.cs @@ -0,0 +1,13 @@ +using Prism.Ioc; +using Prism.Navigation.Regions; + +namespace YY.Admin.ViewModels.UpperMes; + +public class EquipmentDowntimeListViewModel : BaseViewModel +{ + public EquipmentDowntimeListViewModel(IContainerExtension container, IRegionManager regionManager) + : base(container, regionManager) + { + Title = "设备停机记录"; + } +} diff --git a/yy-admin-master/YY.Admin/ViewModels/UpperMes/FormulaMaintainListViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/UpperMes/FormulaMaintainListViewModel.cs new file mode 100644 index 00000000..9a93f447 --- /dev/null +++ b/yy-admin-master/YY.Admin/ViewModels/UpperMes/FormulaMaintainListViewModel.cs @@ -0,0 +1,13 @@ +using Prism.Ioc; +using Prism.Navigation.Regions; + +namespace YY.Admin.ViewModels.UpperMes; + +public class FormulaMaintainListViewModel : BaseViewModel +{ + public FormulaMaintainListViewModel(IContainerExtension container, IRegionManager regionManager) + : base(container, regionManager) + { + Title = "配方维护"; + } +} diff --git a/yy-admin-master/YY.Admin/ViewModels/UpperMes/PlanManageListViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/UpperMes/PlanManageListViewModel.cs new file mode 100644 index 00000000..1342040a --- /dev/null +++ b/yy-admin-master/YY.Admin/ViewModels/UpperMes/PlanManageListViewModel.cs @@ -0,0 +1,13 @@ +using Prism.Ioc; +using Prism.Navigation.Regions; + +namespace YY.Admin.ViewModels.UpperMes; + +public class PlanManageListViewModel : BaseViewModel +{ + public PlanManageListViewModel(IContainerExtension container, IRegionManager regionManager) + : base(container, regionManager) + { + Title = "计划管理"; + } +} diff --git a/yy-admin-master/YY.Admin/ViewModels/UpperMes/ProductionLogListViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/UpperMes/ProductionLogListViewModel.cs new file mode 100644 index 00000000..894b5ff9 --- /dev/null +++ b/yy-admin-master/YY.Admin/ViewModels/UpperMes/ProductionLogListViewModel.cs @@ -0,0 +1,13 @@ +using Prism.Ioc; +using Prism.Navigation.Regions; + +namespace YY.Admin.ViewModels.UpperMes; + +public class ProductionLogListViewModel : BaseViewModel +{ + public ProductionLogListViewModel(IContainerExtension container, IRegionManager regionManager) + : base(container, regionManager) + { + Title = "生产日志"; + } +} diff --git a/yy-admin-master/YY.Admin/ViewModels/UpperMes/ReportQueryListViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/UpperMes/ReportQueryListViewModel.cs new file mode 100644 index 00000000..3a6b5ed9 --- /dev/null +++ b/yy-admin-master/YY.Admin/ViewModels/UpperMes/ReportQueryListViewModel.cs @@ -0,0 +1,13 @@ +using Prism.Ioc; +using Prism.Navigation.Regions; + +namespace YY.Admin.ViewModels.UpperMes; + +public class ReportQueryListViewModel : BaseViewModel +{ + public ReportQueryListViewModel(IContainerExtension container, IRegionManager regionManager) + : base(container, regionManager) + { + Title = "报表查询"; + } +} diff --git a/yy-admin-master/YY.Admin/ViewModels/UpperMes/ShiftHandoverListViewModel.cs b/yy-admin-master/YY.Admin/ViewModels/UpperMes/ShiftHandoverListViewModel.cs new file mode 100644 index 00000000..e84715d9 --- /dev/null +++ b/yy-admin-master/YY.Admin/ViewModels/UpperMes/ShiftHandoverListViewModel.cs @@ -0,0 +1,13 @@ +using Prism.Ioc; +using Prism.Navigation.Regions; + +namespace YY.Admin.ViewModels.UpperMes; + +public class ShiftHandoverListViewModel : BaseViewModel +{ + public ShiftHandoverListViewModel(IContainerExtension container, IRegionManager regionManager) + : base(container, regionManager) + { + Title = "交接班"; + } +} diff --git a/yy-admin-master/YY.Admin/Views/Dialogs/ServerSettingsDialogView.xaml b/yy-admin-master/YY.Admin/Views/Dialogs/ServerSettingsDialogView.xaml index 2f2bc058..18554425 100644 --- a/yy-admin-master/YY.Admin/Views/Dialogs/ServerSettingsDialogView.xaml +++ b/yy-admin-master/YY.Admin/Views/Dialogs/ServerSettingsDialogView.xaml @@ -38,6 +38,20 @@ Style="{StaticResource ToggleButtonSwitch}"/> + + + + + + + + + + + + + + diff --git a/yy-admin-master/YY.Admin/Views/Dialogs/ServerSettingsDialogView.xaml.cs b/yy-admin-master/YY.Admin/Views/Dialogs/ServerSettingsDialogView.xaml.cs index d5e2b3dd..27ad0e47 100644 --- a/yy-admin-master/YY.Admin/Views/Dialogs/ServerSettingsDialogView.xaml.cs +++ b/yy-admin-master/YY.Admin/Views/Dialogs/ServerSettingsDialogView.xaml.cs @@ -1,4 +1,6 @@ +using System.Windows; using System.Windows.Controls; +using YY.Admin.ViewModels.Dialogs; namespace YY.Admin.Views.Dialogs { @@ -10,6 +12,23 @@ namespace YY.Admin.Views.Dialogs public ServerSettingsDialogView() { InitializeComponent(); + DataContextChanged += OnDataContextChanged; + } + + private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) + { + if (DataContext is ServerSettingsDialogViewModel vm && !string.IsNullOrEmpty(vm.EqPassword)) + { + EqPasswordBox.Password = vm.EqPassword; + } + } + + private void EqPasswordBox_OnPasswordChanged(object sender, RoutedEventArgs e) + { + if (DataContext is ServerSettingsDialogViewModel vm) + { + vm.EqPassword = EqPasswordBox.Password; + } } } } diff --git a/yy-admin-master/YY.Admin/Views/McsActMill/McsActMillListView.xaml b/yy-admin-master/YY.Admin/Views/McsActMill/McsActMillListView.xaml new file mode 100644 index 00000000..1a8b9372 --- /dev/null +++ b/yy-admin-master/YY.Admin/Views/McsActMill/McsActMillListView.xaml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +