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/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/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/impl/MesXslMillActionServiceImpl.java b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMillActionServiceImpl.java new file mode 100644 index 00000000..5c187948 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMillActionServiceImpl.java @@ -0,0 +1,10 @@ +package org.jeecg.modules.xslmes.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.jeecg.modules.xslmes.entity.MesXslMillAction; +import org.jeecg.modules.xslmes.mapper.MesXslMillActionMapper; +import org.jeecg.modules.xslmes.service.IMesXslMillActionService; +import org.springframework.stereotype.Service; + +@Service +public class MesXslMillActionServiceImpl extends ServiceImpl implements IMesXslMillActionService {} 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-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/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/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/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/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/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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +