Merge branch 'main' of http://27.223.88.102:33000/chenx/qhmes
This commit is contained in:
@@ -217,6 +217,12 @@ public class ShiroConfig {
|
|||||||
filterChainDefinitionMap.put("/xslmes/mesXslUnit/anon/**", "anon");
|
filterChainDefinitionMap.put("/xslmes/mesXslUnit/anon/**", "anon");
|
||||||
// MES密炼物料管理免密接口(供桌面端调用)
|
// MES密炼物料管理免密接口(供桌面端调用)
|
||||||
filterChainDefinitionMap.put("/mes/material/mixerMaterial/anon/**", "anon");
|
filterChainDefinitionMap.put("/mes/material/mixerMaterial/anon/**", "anon");
|
||||||
|
// MES密炼生产计划维护免密接口(供桌面端快检记录调用)
|
||||||
|
filterChainDefinitionMap.put("/xslmes/mesXslMixingProductionPlan/anon/**", "anon");
|
||||||
|
// MES胶料快检实验标准免密接口(供桌面端快检记录调用)
|
||||||
|
filterChainDefinitionMap.put("/xslmes/mesXslRubberQuickTestStd/anon/**", "anon");
|
||||||
|
// MES胶料快检记录免密接口(供桌面端快检记录调用)
|
||||||
|
filterChainDefinitionMap.put("/xslmes/mesXslRubberQuickTestRecord/anon/**", "anon");
|
||||||
// 打印模板免密接口(供桌面端调用)
|
// 打印模板免密接口(供桌面端调用)
|
||||||
filterChainDefinitionMap.put("/print/template/anon/**", "anon");
|
filterChainDefinitionMap.put("/print/template/anon/**", "anon");
|
||||||
filterChainDefinitionMap.put("/print/bizTemplateBind/anon/**", "anon");
|
filterChainDefinitionMap.put("/print/bizTemplateBind/anon/**", "anon");
|
||||||
|
|||||||
@@ -1093,8 +1093,20 @@ jeecgboot-vue3/src/views/xslmes/mesXslEquipDowntimeRecord/MesXslEquipDowntimeRec
|
|||||||
jeecgboot-vue3/src/views/xslmes/mesXslEquipDowntimeRecord/MesXslEquipDowntimeRecordList.vue
|
jeecgboot-vue3/src/views/xslmes/mesXslEquipDowntimeRecord/MesXslEquipDowntimeRecordList.vue
|
||||||
jeecgboot-vue3/src/views/xslmes/mesXslEquipDowntimeRecord/components/MesXslEquipDowntimeRecordModal.vue
|
jeecgboot-vue3/src/views/xslmes/mesXslEquipDowntimeRecord/components/MesXslEquipDowntimeRecordModal.vue
|
||||||
|
|
||||||
-- author:GHT---date:20260616--for: 【MES上辅机】生产环境 SQL Server 中间库连接池校验 DUAL 报错修复 ---
|
|
||||||
原因:application-prod.yml 全局 druid.validationQuery 为 SELECT 1 FROM DUAL,动态创建的 sqlserver_mcs 数据源继承该配置后在 SQL Server 上报「对象名 DUAL 无效」。
|
|
||||||
修改:prod 全局改为 SELECT 1;McsDataSourceManager 创建/恢复 SQL Server 数据源时显式设置 validationQuery=SELECT 1。
|
|
||||||
jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml
|
|
||||||
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/datasource/McsDataSourceManager.java
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/datasource/McsDataSourceManager.java
|
||||||
|
|
||||||
|
-- author:GHT---date:20260616--for: 【MES上辅机】重启后中间库配置未自动加载(租户ID硬编码为0)---
|
||||||
|
原因:McsDataSourceInitializer 启动时只查 tenant_id=0,页面保存用当前租户(如1002),重启后查不到配置,连接状态回退为 yml。
|
||||||
|
修改:新增 loadStartupConfig 按最近更新时间加载任意租户配置;isDbConfigActive 同时校验数据源是否已注册。
|
||||||
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/IMesXslMcsDbConfigService.java
|
||||||
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/service/impl/MesXslMcsDbConfigServiceImpl.java
|
||||||
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/config/McsDataSourceInitializer.java
|
||||||
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/mcs/datasource/McsDataSourceManager.java
|
||||||
|
|
||||||
|
-- author:jiangxh---date:20260617--for: 【快检实验标准】补齐 tenant_id 为空的历史数据并恢复租户过滤 ---
|
||||||
|
原因:一条快检实验标准 tenant_id 为 NULL,桌面端按 tenantId=1002 拉取时漏掉该条。
|
||||||
|
修改:Flyway 将 NULL tenant_id 对齐为 1002;新增保存时自动写入 tenant_id;恢复 anon/list 与桌面端 tenantId 查询参数。
|
||||||
|
jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_152__mes_xsl_rubber_quick_test_std_tenant_backfill.sql
|
||||||
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslDesktopAnonController.java
|
||||||
|
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslRubberQuickTestStdServiceImpl.java
|
||||||
|
yy-admin-master/YY.Admin.Services/Service/RubberQuickTestStd/RubberQuickTestStdService.cs
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import org.jeecg.modules.xslmes.approval.callback.IApprovalBizCallback;
|
|||||||
import org.jeecg.modules.xslmes.common.XslMesBizConstants;
|
import org.jeecg.modules.xslmes.common.XslMesBizConstants;
|
||||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestStd;
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestStd;
|
||||||
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestStdService;
|
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestStdService;
|
||||||
|
import org.jeecg.modules.xslmes.service.MesXslStompNotifyService;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,9 +26,13 @@ import org.springframework.stereotype.Component;
|
|||||||
public class RubberQuickTestStdApprovalCallback implements IApprovalBizCallback {
|
public class RubberQuickTestStdApprovalCallback implements IApprovalBizCallback {
|
||||||
|
|
||||||
private final IMesXslRubberQuickTestStdService stdService;
|
private final IMesXslRubberQuickTestStdService stdService;
|
||||||
|
private final MesXslStompNotifyService stompNotify;
|
||||||
|
|
||||||
public RubberQuickTestStdApprovalCallback(IMesXslRubberQuickTestStdService stdService) {
|
public RubberQuickTestStdApprovalCallback(
|
||||||
|
IMesXslRubberQuickTestStdService stdService,
|
||||||
|
MesXslStompNotifyService stompNotify) {
|
||||||
this.stdService = stdService;
|
this.stdService = stdService;
|
||||||
|
this.stompNotify = stompNotify;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -55,5 +60,8 @@ public class RubberQuickTestStdApprovalCallback implements IApprovalBizCallback
|
|||||||
.eq(MesXslRubberQuickTestStd::getId, bizDataId)
|
.eq(MesXslRubberQuickTestStd::getId, bizDataId)
|
||||||
.set(MesXslRubberQuickTestStd::getAuditStatus, auditStatus)
|
.set(MesXslRubberQuickTestStd::getAuditStatus, auditStatus)
|
||||||
.update();
|
.update();
|
||||||
|
//update-begin---author:jiangxh ---date:20260617 for:【快检实验标准】审批联动 STOMP 同步桌面端-----------
|
||||||
|
stompNotify.publishRubberQuickTestStdChanged("audit", bizDataId);
|
||||||
|
//update-end---author:jiangxh ---date:20260617 for:【快检实验标准】审批联动 STOMP 同步桌面端-----------
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.jeecg.modules.xslmes.controller;
|
package org.jeecg.modules.xslmes.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
@@ -21,6 +22,7 @@ import org.jeecg.modules.print.entity.PrintTemplate;
|
|||||||
import org.jeecg.modules.print.service.IPrintBizTemplateBindService;
|
import org.jeecg.modules.print.service.IPrintBizTemplateBindService;
|
||||||
import org.jeecg.modules.print.service.IPrintTemplateService;
|
import org.jeecg.modules.print.service.IPrintTemplateService;
|
||||||
import org.jeecg.modules.print.util.PrintBizDataMappingUtil;
|
import org.jeecg.modules.print.util.PrintBizDataMappingUtil;
|
||||||
|
import org.jeecg.modules.xslmes.common.XslMesBizConstants;
|
||||||
import org.jeecg.modules.xslmes.constant.MesXslCustomerBizStatus;
|
import org.jeecg.modules.xslmes.constant.MesXslCustomerBizStatus;
|
||||||
import org.jeecg.modules.xslmes.constant.MesXslPrintConstants;
|
import org.jeecg.modules.xslmes.constant.MesXslPrintConstants;
|
||||||
import org.jeecg.modules.xslmes.entity.MesXslCustomer;
|
import org.jeecg.modules.xslmes.entity.MesXslCustomer;
|
||||||
@@ -32,6 +34,11 @@ import org.jeecg.modules.xslmes.entity.MesXslUnit;
|
|||||||
import org.jeecg.modules.xslmes.entity.MesXslVehicle;
|
import org.jeecg.modules.xslmes.entity.MesXslVehicle;
|
||||||
import org.jeecg.modules.xslmes.entity.MesXslWarehouse;
|
import org.jeecg.modules.xslmes.entity.MesXslWarehouse;
|
||||||
import org.jeecg.modules.xslmes.entity.MesXslWarehouseArea;
|
import org.jeecg.modules.xslmes.entity.MesXslWarehouseArea;
|
||||||
|
import org.jeecg.modules.xslmes.entity.MesXslMixingProductionPlan;
|
||||||
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecord;
|
||||||
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordLine;
|
||||||
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestStd;
|
||||||
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestStdLine;
|
||||||
import org.jeecg.modules.xslmes.entity.MesXslWeightRecord;
|
import org.jeecg.modules.xslmes.entity.MesXslWeightRecord;
|
||||||
import org.jeecg.modules.xslmes.service.IMesXslCustomerService;
|
import org.jeecg.modules.xslmes.service.IMesXslCustomerService;
|
||||||
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialCardService;
|
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialCardService;
|
||||||
@@ -42,6 +49,9 @@ import org.jeecg.modules.xslmes.service.IMesXslUnitService;
|
|||||||
import org.jeecg.modules.xslmes.service.IMesXslVehicleService;
|
import org.jeecg.modules.xslmes.service.IMesXslVehicleService;
|
||||||
import org.jeecg.modules.xslmes.service.IMesXslWarehouseAreaService;
|
import org.jeecg.modules.xslmes.service.IMesXslWarehouseAreaService;
|
||||||
import org.jeecg.modules.xslmes.service.IMesXslWarehouseService;
|
import org.jeecg.modules.xslmes.service.IMesXslWarehouseService;
|
||||||
|
import org.jeecg.modules.xslmes.service.IMesXslMixingProductionPlanService;
|
||||||
|
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestRecordService;
|
||||||
|
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestStdService;
|
||||||
import org.jeecg.modules.xslmes.service.IMesXslWeightRecordService;
|
import org.jeecg.modules.xslmes.service.IMesXslWeightRecordService;
|
||||||
import org.jeecg.modules.xslmes.service.MesXslStompNotifyService;
|
import org.jeecg.modules.xslmes.service.MesXslStompNotifyService;
|
||||||
import org.jeecg.modules.xslmes.vo.MesXslRawMaterialCardBriefVO;
|
import org.jeecg.modules.xslmes.vo.MesXslRawMaterialCardBriefVO;
|
||||||
@@ -87,6 +97,9 @@ public class MesXslDesktopAnonController {
|
|||||||
private final IPrintBizTemplateBindService printBizTemplateBindService;
|
private final IPrintBizTemplateBindService printBizTemplateBindService;
|
||||||
private final IPrintTemplateService printTemplateService;
|
private final IPrintTemplateService printTemplateService;
|
||||||
private final ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
|
private final IMesXslMixingProductionPlanService mixingProductionPlanService;
|
||||||
|
private final IMesXslRubberQuickTestStdService rubberQuickTestStdService;
|
||||||
|
private final IMesXslRubberQuickTestRecordService rubberQuickTestRecordService;
|
||||||
|
|
||||||
// ═══════════════════════════ 车辆管理 ═══════════════════════════
|
// ═══════════════════════════ 车辆管理 ═══════════════════════════
|
||||||
|
|
||||||
@@ -925,6 +938,105 @@ public class MesXslDesktopAnonController {
|
|||||||
}
|
}
|
||||||
//update-end---author:cursor ---date:20250602 for:【密炼物料皮重策略】桌面端单位下拉只读-----------
|
//update-end---author:cursor ---date:20250602 for:【密炼物料皮重策略】桌面端单位下拉只读-----------
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:2026-06-17 for:【快检记录】桌面端密炼生产计划只读-----------
|
||||||
|
@Operation(summary = "密炼生产计划维护-免密分页列表查询(供桌面端快检记录筛选)")
|
||||||
|
@GetMapping("/xslmes/mesXslMixingProductionPlan/anon/list")
|
||||||
|
public Result<IPage<MesXslMixingProductionPlan>> mixingProductionPlanAnonList(
|
||||||
|
MesXslMixingProductionPlan model,
|
||||||
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(name = "pageSize", defaultValue = "500") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
QueryWrapper<MesXslMixingProductionPlan> qw = QueryGenerator.initQueryWrapper(model, req.getParameterMap());
|
||||||
|
qw.orderByAsc("sort_no").orderByAsc("create_time");
|
||||||
|
IPage<MesXslMixingProductionPlan> page =
|
||||||
|
mixingProductionPlanService.page(new Page<>(pageNo, pageSize), qw);
|
||||||
|
return Result.OK(page);
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:2026-06-17 for:【快检记录】桌面端密炼生产计划只读-----------
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:2026-06-17 for:【快检实验标准】桌面端只读列表与详情-----------
|
||||||
|
@Operation(summary = "胶料快检实验标准-免密分页列表")
|
||||||
|
@GetMapping("/xslmes/mesXslRubberQuickTestStd/anon/list")
|
||||||
|
public Result<IPage<MesXslRubberQuickTestStd>> rubberQuickTestStdAnonList(
|
||||||
|
MesXslRubberQuickTestStd model,
|
||||||
|
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||||
|
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||||
|
HttpServletRequest req) {
|
||||||
|
QueryWrapper<MesXslRubberQuickTestStd> qw = QueryGenerator.initQueryWrapper(model, req.getParameterMap());
|
||||||
|
qw.orderByDesc("create_time");
|
||||||
|
IPage<MesXslRubberQuickTestStd> page = rubberQuickTestStdService.page(new Page<>(pageNo, pageSize), qw);
|
||||||
|
return Result.OK(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "胶料快检实验标准-免密通过id查询(含明细)")
|
||||||
|
@GetMapping("/xslmes/mesXslRubberQuickTestStd/anon/queryById")
|
||||||
|
public Result<MesXslRubberQuickTestStd> rubberQuickTestStdAnonQueryById(@RequestParam(name = "id") String id) {
|
||||||
|
MesXslRubberQuickTestStd entity = rubberQuickTestStdService.getById(id);
|
||||||
|
if (entity == null) {
|
||||||
|
return Result.error("未找到对应数据");
|
||||||
|
}
|
||||||
|
entity.setLineList(rubberQuickTestStdService.selectLinesByStdId(id));
|
||||||
|
return Result.OK(entity);
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:2026-06-17 for:【快检实验标准】桌面端只读列表与详情-----------
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:2026-06-17 for:【快检记录】桌面端胶料快检实验标准查询-----------
|
||||||
|
private static final String RUBBER_QUICK_TEST_STD_ENABLE_IN_USE = "1";
|
||||||
|
|
||||||
|
@Operation(summary = "胶料快检实验标准-免密按胶料名称查询使用中标准及明细")
|
||||||
|
@GetMapping("/xslmes/mesXslRubberQuickTestStd/anon/queryByRubberMaterialName")
|
||||||
|
public Result<MesXslRubberQuickTestStd> rubberQuickTestStdAnonQueryByRubberMaterialName(
|
||||||
|
@RequestParam(name = "rubberMaterialName") String rubberMaterialName) {
|
||||||
|
if (oConvertUtils.isEmpty(rubberMaterialName)) {
|
||||||
|
return Result.error("胶料名称不能为空");
|
||||||
|
}
|
||||||
|
String name = rubberMaterialName.trim();
|
||||||
|
LambdaQueryWrapper<MesXslRubberQuickTestStd> qw = new LambdaQueryWrapper<>();
|
||||||
|
qw.eq(MesXslRubberQuickTestStd::getRubberMaterialName, name);
|
||||||
|
qw.eq(MesXslRubberQuickTestStd::getEnableStatus, RUBBER_QUICK_TEST_STD_ENABLE_IN_USE);
|
||||||
|
qw.eq(MesXslRubberQuickTestStd::getAuditStatus, XslMesBizConstants.RUBBER_QUICK_TEST_STD_AUDIT_APPROVED);
|
||||||
|
qw.orderByDesc(MesXslRubberQuickTestStd::getCreateTime);
|
||||||
|
MesXslRubberQuickTestStd std = rubberQuickTestStdService.getOne(qw, false);
|
||||||
|
if (std == null) {
|
||||||
|
return Result.error("未找到胶料「" + name + "」对应的使用中且已批准的快检实验标准");
|
||||||
|
}
|
||||||
|
std.setLineList(rubberQuickTestStdService.selectLinesByStdId(std.getId()));
|
||||||
|
return Result.OK(std);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "胶料快检实验标准-免密查询明细")
|
||||||
|
@GetMapping("/xslmes/mesXslRubberQuickTestStd/anon/queryLineListByStdId")
|
||||||
|
public Result<List<MesXslRubberQuickTestStdLine>> rubberQuickTestStdAnonQueryLineListByStdId(
|
||||||
|
@RequestParam(name = "id") String id) {
|
||||||
|
return Result.OK(rubberQuickTestStdService.selectLinesByStdId(id));
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:2026-06-17 for:【快检记录】桌面端胶料快检实验标准查询-----------
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:2026-06-17 for:【快检记录】桌面端胶料快检记录保存-----------
|
||||||
|
@Operation(summary = "胶料快检记录-免密添加")
|
||||||
|
@PostMapping("/xslmes/mesXslRubberQuickTestRecord/anon/add")
|
||||||
|
public Result<String> rubberQuickTestRecordAnonAdd(@RequestBody MesXslRubberQuickTestRecord record) {
|
||||||
|
if (record == null) {
|
||||||
|
return Result.error("参数不能为空");
|
||||||
|
}
|
||||||
|
if (oConvertUtils.isEmpty(record.getRubberMaterialName())) {
|
||||||
|
return Result.error("胶料名称不能为空");
|
||||||
|
}
|
||||||
|
List<MesXslRubberQuickTestRecordLine> lineList = record.getLineList();
|
||||||
|
if (lineList == null || lineList.isEmpty()) {
|
||||||
|
return Result.error("请维护检验明细");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
rubberQuickTestRecordService.saveMain(record, lineList);
|
||||||
|
stompNotify.publishRubberQuickTestRecordChanged("add", record.getId());
|
||||||
|
return Result.OK("添加成功!");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:2026-06-17 for:【快检记录】桌面端胶料快检记录保存-----------
|
||||||
|
|
||||||
// ─────────────────────────── 车辆私有辅助 ────────────────────────────
|
// ─────────────────────────── 车辆私有辅助 ────────────────────────────
|
||||||
|
|
||||||
private void applyWeightNetAndBillType(MesXslWeightRecord record) {
|
private void applyWeightNetAndBillType(MesXslWeightRecord record) {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import org.jeecg.modules.system.entity.SysUser;
|
|||||||
import org.jeecg.modules.system.service.ISysUserService;
|
import org.jeecg.modules.system.service.ISysUserService;
|
||||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecord;
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecord;
|
||||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordLine;
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordLine;
|
||||||
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordRawLine;
|
||||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestType;
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestType;
|
||||||
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestRecordService;
|
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestRecordService;
|
||||||
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestTypeService;
|
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestTypeService;
|
||||||
@@ -163,6 +164,15 @@ public class MesXslRubberQuickTestRecordController
|
|||||||
return Result.OK(mesXslRubberQuickTestRecordService.selectLinesByRecordId(id));
|
return Result.OK(mesXslRubberQuickTestRecordService.selectLinesByRecordId(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:2026-06-17 for:【快检记录】查询原始数据明细-----------
|
||||||
|
@Operation(summary = "MES胶料快检记录-查询原始数据明细")
|
||||||
|
@GetMapping(value = "/queryRawLineListByRecordId")
|
||||||
|
public Result<List<MesXslRubberQuickTestRecordRawLine>> queryRawLineListByRecordId(
|
||||||
|
@RequestParam(name = "id", required = true) String id) {
|
||||||
|
return Result.OK(mesXslRubberQuickTestRecordService.selectRawLinesByRecordId(id));
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:2026-06-17 for:【快检记录】查询原始数据明细-----------
|
||||||
|
|
||||||
@RequiresPermissions("mes:mes_xsl_rubber_quick_test_record:exportXls")
|
@RequiresPermissions("mes:mes_xsl_rubber_quick_test_record:exportXls")
|
||||||
@RequestMapping(value = "/exportXls")
|
@RequestMapping(value = "/exportXls")
|
||||||
public ModelAndView exportXls(HttpServletRequest request, MesXslRubberQuickTestRecord model) {
|
public ModelAndView exportXls(HttpServletRequest request, MesXslRubberQuickTestRecord model) {
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import org.jeecg.modules.xslmes.service.IMesXslMixerPsCompileService;
|
|||||||
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestMethodService;
|
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestMethodService;
|
||||||
import org.jeecg.modules.xslmes.service.IMesXslDeleteReferenceService;
|
import org.jeecg.modules.xslmes.service.IMesXslDeleteReferenceService;
|
||||||
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestStdService;
|
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestStdService;
|
||||||
|
import org.jeecg.modules.xslmes.service.MesXslStompNotifyService;
|
||||||
import org.jeecg.modules.xslmes.vo.MesXslRubberQuickTestStdPage;
|
import org.jeecg.modules.xslmes.vo.MesXslRubberQuickTestStdPage;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -73,6 +74,9 @@ public class MesXslRubberQuickTestStdController
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IMesXslDeleteReferenceService mesXslDeleteReferenceService;
|
private IMesXslDeleteReferenceService mesXslDeleteReferenceService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MesXslStompNotifyService stompNotify;
|
||||||
|
|
||||||
@Operation(summary = "MES胶料快检实验标准-分页列表查询")
|
@Operation(summary = "MES胶料快检实验标准-分页列表查询")
|
||||||
@GetMapping(value = "/list")
|
@GetMapping(value = "/list")
|
||||||
public Result<IPage<MesXslRubberQuickTestStd>> queryPageList(
|
public Result<IPage<MesXslRubberQuickTestStd>> queryPageList(
|
||||||
@@ -107,6 +111,9 @@ public class MesXslRubberQuickTestStdController
|
|||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
return Result.error(e.getMessage());
|
return Result.error(e.getMessage());
|
||||||
}
|
}
|
||||||
|
//update-begin---author:jiangxh ---date:20260617 for:【快检实验标准】桌面端 STOMP 同步-----------
|
||||||
|
stompNotify.publishRubberQuickTestStdChanged("add", main.getId());
|
||||||
|
//update-end---author:jiangxh ---date:20260617 for:【快检实验标准】桌面端 STOMP 同步-----------
|
||||||
return Result.OK("添加成功!");
|
return Result.OK("添加成功!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +136,9 @@ public class MesXslRubberQuickTestStdController
|
|||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
return Result.error(e.getMessage());
|
return Result.error(e.getMessage());
|
||||||
}
|
}
|
||||||
|
//update-begin---author:jiangxh ---date:20260617 for:【快检实验标准】桌面端 STOMP 同步-----------
|
||||||
|
stompNotify.publishRubberQuickTestStdChanged("edit", main.getId());
|
||||||
|
//update-end---author:jiangxh ---date:20260617 for:【快检实验标准】桌面端 STOMP 同步-----------
|
||||||
return Result.OK("编辑成功!");
|
return Result.OK("编辑成功!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,6 +152,9 @@ public class MesXslRubberQuickTestStdController
|
|||||||
return Result.error(refErr);
|
return Result.error(refErr);
|
||||||
}
|
}
|
||||||
mesXslRubberQuickTestStdService.delMain(id);
|
mesXslRubberQuickTestStdService.delMain(id);
|
||||||
|
//update-begin---author:jiangxh ---date:20260617 for:【快检实验标准】桌面端 STOMP 同步-----------
|
||||||
|
stompNotify.publishRubberQuickTestStdChanged("delete", id);
|
||||||
|
//update-end---author:jiangxh ---date:20260617 for:【快检实验标准】桌面端 STOMP 同步-----------
|
||||||
return Result.OK("删除成功!");
|
return Result.OK("删除成功!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +168,9 @@ public class MesXslRubberQuickTestStdController
|
|||||||
return Result.error(refErr);
|
return Result.error(refErr);
|
||||||
}
|
}
|
||||||
mesXslRubberQuickTestStdService.delBatchMain(Arrays.asList(ids.split(",")));
|
mesXslRubberQuickTestStdService.delBatchMain(Arrays.asList(ids.split(",")));
|
||||||
|
//update-begin---author:jiangxh ---date:20260617 for:【快检实验标准】桌面端 STOMP 同步-----------
|
||||||
|
stompNotify.publishRubberQuickTestStdChanged("batchDelete", ids);
|
||||||
|
//update-end---author:jiangxh ---date:20260617 for:【快检实验标准】桌面端 STOMP 同步-----------
|
||||||
return Result.OK("批量删除成功!");
|
return Result.OK("批量删除成功!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,6 +212,9 @@ public class MesXslRubberQuickTestStdController
|
|||||||
.set(MesXslRubberQuickTestStd::getEnableStatus, enableStatus)
|
.set(MesXslRubberQuickTestStd::getEnableStatus, enableStatus)
|
||||||
.update();
|
.update();
|
||||||
if (updated) {
|
if (updated) {
|
||||||
|
//update-begin---author:jiangxh ---date:20260617 for:【快检实验标准】桌面端 STOMP 同步-----------
|
||||||
|
stompNotify.publishRubberQuickTestStdChanged("status", id);
|
||||||
|
//update-end---author:jiangxh ---date:20260617 for:【快检实验标准】桌面端 STOMP 同步-----------
|
||||||
return Result.OK("操作成功");
|
return Result.OK("操作成功");
|
||||||
}
|
}
|
||||||
MesXslRubberQuickTestStd cur = mesXslRubberQuickTestStdService.getById(id);
|
MesXslRubberQuickTestStd cur = mesXslRubberQuickTestStdService.getById(id);
|
||||||
@@ -272,6 +291,18 @@ public class MesXslRubberQuickTestStdController
|
|||||||
if (!XslMesBizConstants.PS_TYPE_RAW_INSPECT_STD.equals(ps.getPsType())) {
|
if (!XslMesBizConstants.PS_TYPE_RAW_INSPECT_STD.equals(ps.getPsType())) {
|
||||||
return "发行编号须选择类型为原材料检验标准的密炼PS";
|
return "发行编号须选择类型为原材料检验标准的密炼PS";
|
||||||
}
|
}
|
||||||
|
//update-begin---author:jiangxh ---date:20260617 for:【快检实验标准】发行编号仅允许选择编制状态密炼PS-----------
|
||||||
|
boolean psCompileIdChanged = true;
|
||||||
|
if (oConvertUtils.isNotEmpty(excludeId)) {
|
||||||
|
MesXslRubberQuickTestStd existingStd = mesXslRubberQuickTestStdService.getById(excludeId);
|
||||||
|
if (existingStd != null && oConvertUtils.isNotEmpty(existingStd.getPsCompileId())) {
|
||||||
|
psCompileIdChanged = !existingStd.getPsCompileId().equals(main.getPsCompileId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (psCompileIdChanged && !"compile".equals(ps.getStatus())) {
|
||||||
|
return "发行编号须选择编制状态的密炼PS";
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260617 for:【快检实验标准】发行编号仅允许选择编制状态密炼PS-----------
|
||||||
main.setIssueNumber(ps.getPsCode());
|
main.setIssueNumber(ps.getPsCode());
|
||||||
if (main.getIssueDate() == null && ps.getIssueDate() != null) {
|
if (main.getIssueDate() == null && ps.getIssueDate() != null) {
|
||||||
main.setIssueDate(ps.getIssueDate());
|
main.setIssueDate(ps.getIssueDate());
|
||||||
|
|||||||
@@ -130,4 +130,8 @@ public class MesXslRubberQuickTestRecord implements Serializable {
|
|||||||
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private List<MesXslRubberQuickTestRecordLine> lineList;
|
private List<MesXslRubberQuickTestRecordLine> lineList;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
@Schema(description = "原始数据明细(试验结果全部检测值)")
|
||||||
|
private List<MesXslRubberQuickTestRecordRawLine> rawLineList;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
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.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MES 胶料快检记录原始数据明细(试验结果全部检测值)
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("mes_xsl_rubber_quick_test_record_raw_line")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Schema(description = "MES胶料快检记录原始数据明细")
|
||||||
|
public class MesXslRubberQuickTestRecordRawLine implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "主表ID mes_xsl_rubber_quick_test_record.id")
|
||||||
|
private String recordId;
|
||||||
|
|
||||||
|
@Excel(name = "编号", width = 14)
|
||||||
|
@Schema(description = "试验结果编号(如1_1)")
|
||||||
|
private String rowNo;
|
||||||
|
|
||||||
|
@Schema(description = "数据点ID")
|
||||||
|
private String dataPointId;
|
||||||
|
|
||||||
|
@Excel(name = "数据点", width = 18)
|
||||||
|
private String inspectItem;
|
||||||
|
|
||||||
|
@Excel(name = "下限值", width = 12, type = 10)
|
||||||
|
private BigDecimal lowerLimit;
|
||||||
|
|
||||||
|
@Excel(name = "上限值", width = 12, type = 10)
|
||||||
|
private BigDecimal upperLimit;
|
||||||
|
|
||||||
|
@Excel(name = "检测值", width = 12, type = 10)
|
||||||
|
private BigDecimal inspectValue;
|
||||||
|
|
||||||
|
@Excel(name = "行检验结果", width = 10, dicCode = "xslmes_rubber_quick_test_record_result")
|
||||||
|
@Dict(dicCode = "xslmes_rubber_quick_test_record_result")
|
||||||
|
@Schema(description = "行检验结果(1合格0不合格)")
|
||||||
|
private String rowInspectResult;
|
||||||
|
|
||||||
|
private Integer sortNo;
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package org.jeecg.modules.xslmes.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordRawLine;
|
||||||
|
|
||||||
|
public interface MesXslRubberQuickTestRecordRawLineMapper extends BaseMapper<MesXslRubberQuickTestRecordRawLine> {}
|
||||||
@@ -28,20 +28,16 @@ public class McsDataSourceInitializer implements ApplicationRunner {
|
|||||||
@Override
|
@Override
|
||||||
public void run(ApplicationArguments args) {
|
public void run(ApplicationArguments args) {
|
||||||
try {
|
try {
|
||||||
MesXslMcsDbConfig config = mcsDbConfigService.getOne(
|
MesXslMcsDbConfig config = mcsDbConfigService.loadStartupConfig();
|
||||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<MesXslMcsDbConfig>()
|
|
||||||
.eq(MesXslMcsDbConfig::getTenantId, 0)
|
|
||||||
.orderByDesc(MesXslMcsDbConfig::getUpdateTime)
|
|
||||||
.last("LIMIT 1"),
|
|
||||||
false);
|
|
||||||
if (config != null) {
|
if (config != null) {
|
||||||
mcsDataSourceManager.applyConfig(config);
|
mcsDataSourceManager.applyConfig(config);
|
||||||
log.info("[MCS中间库] 已加载数据库中的中间库配置(含读写开关)");
|
log.info("[MCS中间库] 已加载数据库中的中间库配置 tenantId={}, status={}, host={}:{}",
|
||||||
|
config.getTenantId(), config.getStatus(), config.getServerHost(), config.getServerPort());
|
||||||
} else {
|
} else {
|
||||||
log.info("[MCS中间库] 未找到已启用的数据库配置,继续使用 application.yml 中的 sqlserver_mcs");
|
log.info("[MCS中间库] 数据库中无中间库配置,继续使用 application.yml 中的 sqlserver_mcs");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("[MCS中间库] 启动加载配置失败,将使用 yml 默认连接: {}", e.getMessage());
|
log.error("[MCS中间库] 启动加载配置失败,将使用 yml 默认连接", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//update-end---author:GHT ---date:20260616 for:【MES上辅机】启动时加载中间库可视化配置-----------
|
//update-end---author:GHT ---date:20260616 for:【MES上辅机】启动时加载中间库可视化配置-----------
|
||||||
|
|||||||
@@ -59,7 +59,11 @@ public class McsDataSourceManager {
|
|||||||
|
|
||||||
public boolean isDbConfigActive() {
|
public boolean isDbConfigActive() {
|
||||||
MesXslMcsDbConfig cfg = cachedConfig.get();
|
MesXslMcsDbConfig cfg = cachedConfig.get();
|
||||||
return cfg != null && Integer.valueOf(1).equals(cfg.getStatus());
|
if (cfg == null || !Integer.valueOf(1).equals(cfg.getStatus())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DynamicRoutingDataSource routing = (DynamicRoutingDataSource) dataSource;
|
||||||
|
return routing.getDataSources().containsKey(DS_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isReadEnabled() {
|
public boolean isReadEnabled() {
|
||||||
@@ -83,11 +87,11 @@ public class McsDataSourceManager {
|
|||||||
* 将配置应用到动态数据源(启用时注册/更新,禁用时移除)
|
* 将配置应用到动态数据源(启用时注册/更新,禁用时移除)
|
||||||
*/
|
*/
|
||||||
public void applyConfig(MesXslMcsDbConfig config) {
|
public void applyConfig(MesXslMcsDbConfig config) {
|
||||||
cachedConfig.set(config);
|
|
||||||
DynamicRoutingDataSource routing = (DynamicRoutingDataSource) dataSource;
|
DynamicRoutingDataSource routing = (DynamicRoutingDataSource) dataSource;
|
||||||
closeAndRemoveDataSource(routing);
|
closeAndRemoveDataSource(routing);
|
||||||
DataSourceCachePool.removeCache(DS_KEY);
|
DataSourceCachePool.removeCache(DS_KEY);
|
||||||
if (config == null) {
|
if (config == null) {
|
||||||
|
cachedConfig.set(null);
|
||||||
restoreYmlDataSource(routing);
|
restoreYmlDataSource(routing);
|
||||||
log.info("[MCS中间库] 已清除页面配置");
|
log.info("[MCS中间库] 已清除页面配置");
|
||||||
return;
|
return;
|
||||||
@@ -98,6 +102,7 @@ public class McsDataSourceManager {
|
|||||||
DataSourceProperty property = buildDataSourceProperty(config, plainPassword);
|
DataSourceProperty property = buildDataSourceProperty(config, plainPassword);
|
||||||
DataSource mcsDs = dataSourceCreator.createDataSource(property);
|
DataSource mcsDs = dataSourceCreator.createDataSource(property);
|
||||||
routing.addDataSource(DS_KEY, mcsDs);
|
routing.addDataSource(DS_KEY, mcsDs);
|
||||||
|
cachedConfig.set(config);
|
||||||
log.info("[MCS中间库] 动态数据源 {} 已热刷新(无需重启): {}:{}/{}", DS_KEY,
|
log.info("[MCS中间库] 动态数据源 {} 已热刷新(无需重启): {}:{}/{}", DS_KEY,
|
||||||
config.getServerHost(), config.getServerPort(), config.getDbName());
|
config.getServerHost(), config.getServerPort(), config.getDbName());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -107,6 +112,7 @@ public class McsDataSourceManager {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
cachedConfig.set(config);
|
||||||
restoreYmlDataSource(routing);
|
restoreYmlDataSource(routing);
|
||||||
log.info("[MCS中间库] 连接未启用,读写开关仍按页面配置生效");
|
log.info("[MCS中间库] 连接未启用,读写开关仍按页面配置生效");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,4 +28,9 @@ public interface IMesXslMcsDbConfigService extends IService<MesXslMcsDbConfig> {
|
|||||||
* 删除配置并移除动态数据源
|
* 删除配置并移除动态数据源
|
||||||
*/
|
*/
|
||||||
Result<String> deleteConfig(String id);
|
Result<String> deleteConfig(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启动时加载中间库配置(不限定租户,取最近更新的一条)
|
||||||
|
*/
|
||||||
|
MesXslMcsDbConfig loadStartupConfig();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,16 @@ public class MesXslMcsDbConfigServiceImpl extends ServiceImpl<MesXslMcsDbConfigM
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//update-begin---author:GHT ---date:20260616 for:【MES上辅机】启动时加载中间库配置(不限定租户)-----------
|
||||||
|
@Override
|
||||||
|
public MesXslMcsDbConfig loadStartupConfig() {
|
||||||
|
LambdaQueryWrapper<MesXslMcsDbConfig> qw = new LambdaQueryWrapper<>();
|
||||||
|
qw.orderByDesc(MesXslMcsDbConfig::getUpdateTime);
|
||||||
|
qw.last("LIMIT 1");
|
||||||
|
return getOne(qw, false);
|
||||||
|
}
|
||||||
|
//update-end---author:GHT ---date:20260616 for:【MES上辅机】启动时加载中间库配置(不限定租户)-----------
|
||||||
|
|
||||||
//update-begin---author:GHT ---date:20260616 for:【MES上辅机】SQL Server中间库可视化配置-----------
|
//update-begin---author:GHT ---date:20260616 for:【MES上辅机】SQL Server中间库可视化配置-----------
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecord;
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecord;
|
||||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordLine;
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordLine;
|
||||||
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordRawLine;
|
||||||
import org.jeecg.modules.xslmes.vo.MesXslRubberQuickTestRecordBatchFromMaterialVO;
|
import org.jeecg.modules.xslmes.vo.MesXslRubberQuickTestRecordBatchFromMaterialVO;
|
||||||
|
|
||||||
public interface IMesXslRubberQuickTestRecordService extends IService<MesXslRubberQuickTestRecord> {
|
public interface IMesXslRubberQuickTestRecordService extends IService<MesXslRubberQuickTestRecord> {
|
||||||
@@ -20,6 +21,8 @@ public interface IMesXslRubberQuickTestRecordService extends IService<MesXslRubb
|
|||||||
|
|
||||||
List<MesXslRubberQuickTestRecordLine> selectLinesByRecordId(String recordId);
|
List<MesXslRubberQuickTestRecordLine> selectLinesByRecordId(String recordId);
|
||||||
|
|
||||||
|
List<MesXslRubberQuickTestRecordRawLine> selectRawLinesByRecordId(String recordId);
|
||||||
|
|
||||||
String generateRecordNo(MesXslRubberQuickTestRecord context);
|
String generateRecordNo(MesXslRubberQuickTestRecord context);
|
||||||
|
|
||||||
List<String> batchFromMaterial(MesXslRubberQuickTestRecordBatchFromMaterialVO vo);
|
List<String> batchFromMaterial(MesXslRubberQuickTestRecordBatchFromMaterialVO vo);
|
||||||
|
|||||||
@@ -83,6 +83,22 @@ public class MesXslStompNotifyService {
|
|||||||
}
|
}
|
||||||
//update-end---author:cursor ---date:20250602 for:【密炼物料皮重策略】桌面端同步-----------
|
//update-end---author:cursor ---date:20250602 for:【密炼物料皮重策略】桌面端同步-----------
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:2026-06-17 for:【快检记录】桌面端胶料快检记录同步-----------
|
||||||
|
/** 广播胶料快检记录变更事件到 /topic/sync/mes-rubber-quick-test-records */
|
||||||
|
public void publishRubberQuickTestRecordChanged(String action, String recordId) {
|
||||||
|
publish("/topic/sync/mes-rubber-quick-test-records", "MES_RUBBER_QUICK_TEST_RECORD_CHANGED",
|
||||||
|
"recordId", recordId, action);
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260525 for:【MES】原材料检验标准密炼PS批准时关联实验标准置已批准-----------
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:20260617 for:【快检实验标准】桌面端只读同步 STOMP-----------
|
||||||
|
/** 广播胶料快检实验标准变更事件到 /topic/sync/mes-rubber-quick-test-stds */
|
||||||
|
public void publishRubberQuickTestStdChanged(String action, String stdId) {
|
||||||
|
publish("/topic/sync/mes-rubber-quick-test-stds", "MES_RUBBER_QUICK_TEST_STD_CHANGED",
|
||||||
|
"stdId", stdId, action);
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260617 for:【快检实验标准】桌面端只读同步 STOMP-----------
|
||||||
|
|
||||||
// ─────────────────────────── 私有辅助 ────────────────────────────
|
// ─────────────────────────── 私有辅助 ────────────────────────────
|
||||||
|
|
||||||
private void publish(String topic, String cmd, String idKey, String idValue, String action) {
|
private void publish(String topic, String cmd, String idKey, String idValue, String action) {
|
||||||
|
|||||||
@@ -20,11 +20,13 @@ import org.jeecg.modules.xslmes.common.XslMesBizConstants;
|
|||||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestMethod;
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestMethod;
|
||||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecord;
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecord;
|
||||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordLine;
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordLine;
|
||||||
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordRawLine;
|
||||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestStd;
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestStd;
|
||||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestStdLine;
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestStdLine;
|
||||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestType;
|
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestType;
|
||||||
import org.jeecg.modules.xslmes.mapper.MesXslRubberQuickTestRecordLineMapper;
|
import org.jeecg.modules.xslmes.mapper.MesXslRubberQuickTestRecordLineMapper;
|
||||||
import org.jeecg.modules.xslmes.mapper.MesXslRubberQuickTestRecordMapper;
|
import org.jeecg.modules.xslmes.mapper.MesXslRubberQuickTestRecordMapper;
|
||||||
|
import org.jeecg.modules.xslmes.mapper.MesXslRubberQuickTestRecordRawLineMapper;
|
||||||
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestMethodService;
|
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestMethodService;
|
||||||
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestRecordService;
|
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestRecordService;
|
||||||
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestStdService;
|
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestStdService;
|
||||||
@@ -45,6 +47,9 @@ public class MesXslRubberQuickTestRecordServiceImpl
|
|||||||
@Autowired
|
@Autowired
|
||||||
private MesXslRubberQuickTestRecordLineMapper mesXslRubberQuickTestRecordLineMapper;
|
private MesXslRubberQuickTestRecordLineMapper mesXslRubberQuickTestRecordLineMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MesXslRubberQuickTestRecordRawLineMapper mesXslRubberQuickTestRecordRawLineMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IMesXslRubberQuickTestStdService mesXslRubberQuickTestStdService;
|
private IMesXslRubberQuickTestStdService mesXslRubberQuickTestStdService;
|
||||||
|
|
||||||
@@ -65,6 +70,9 @@ public class MesXslRubberQuickTestRecordServiceImpl
|
|||||||
}
|
}
|
||||||
this.save(main);
|
this.save(main);
|
||||||
insertLines(main.getId(), lineList);
|
insertLines(main.getId(), lineList);
|
||||||
|
//update-begin---author:jiangxh ---date:2026-06-17 for:【快检记录】保存试验结果原始数据明细-----------
|
||||||
|
insertRawLines(main.getId(), main.getRawLineList());
|
||||||
|
//update-end---author:jiangxh ---date:2026-06-17 for:【快检记录】保存试验结果原始数据明细-----------
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -81,6 +89,12 @@ public class MesXslRubberQuickTestRecordServiceImpl
|
|||||||
new LambdaQueryWrapper<MesXslRubberQuickTestRecordLine>()
|
new LambdaQueryWrapper<MesXslRubberQuickTestRecordLine>()
|
||||||
.eq(MesXslRubberQuickTestRecordLine::getRecordId, main.getId()));
|
.eq(MesXslRubberQuickTestRecordLine::getRecordId, main.getId()));
|
||||||
insertLines(main.getId(), lineList);
|
insertLines(main.getId(), lineList);
|
||||||
|
//update-begin---author:jiangxh ---date:2026-06-17 for:【快检记录】更新时同步原始数据明细-----------
|
||||||
|
mesXslRubberQuickTestRecordRawLineMapper.delete(
|
||||||
|
new LambdaQueryWrapper<MesXslRubberQuickTestRecordRawLine>()
|
||||||
|
.eq(MesXslRubberQuickTestRecordRawLine::getRecordId, main.getId()));
|
||||||
|
insertRawLines(main.getId(), main.getRawLineList());
|
||||||
|
//update-end---author:jiangxh ---date:2026-06-17 for:【快检记录】更新时同步原始数据明细-----------
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insertLines(String recordId, List<MesXslRubberQuickTestRecordLine> lineList) {
|
private void insertLines(String recordId, List<MesXslRubberQuickTestRecordLine> lineList) {
|
||||||
@@ -96,11 +110,31 @@ public class MesXslRubberQuickTestRecordServiceImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//update-begin---author:jiangxh ---date:2026-06-17 for:【快检记录】原始数据明细入库-----------
|
||||||
|
private void insertRawLines(String recordId, List<MesXslRubberQuickTestRecordRawLine> rawLineList) {
|
||||||
|
if (CollectionUtils.isEmpty(rawLineList)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int sort = 0;
|
||||||
|
for (MesXslRubberQuickTestRecordRawLine line : rawLineList) {
|
||||||
|
if (line == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
line.setId(null);
|
||||||
|
line.setRecordId(recordId);
|
||||||
|
line.setSortNo(sort++);
|
||||||
|
mesXslRubberQuickTestRecordRawLineMapper.insert(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:2026-06-17 for:【快检记录】原始数据明细入库-----------
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void delMain(String id) {
|
public void delMain(String id) {
|
||||||
mesXslRubberQuickTestRecordLineMapper.delete(
|
mesXslRubberQuickTestRecordLineMapper.delete(
|
||||||
new LambdaQueryWrapper<MesXslRubberQuickTestRecordLine>().eq(MesXslRubberQuickTestRecordLine::getRecordId, id));
|
new LambdaQueryWrapper<MesXslRubberQuickTestRecordLine>().eq(MesXslRubberQuickTestRecordLine::getRecordId, id));
|
||||||
|
mesXslRubberQuickTestRecordRawLineMapper.delete(
|
||||||
|
new LambdaQueryWrapper<MesXslRubberQuickTestRecordRawLine>().eq(MesXslRubberQuickTestRecordRawLine::getRecordId, id));
|
||||||
this.removeById(id);
|
this.removeById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,6 +154,14 @@ public class MesXslRubberQuickTestRecordServiceImpl
|
|||||||
.orderByAsc(MesXslRubberQuickTestRecordLine::getSortNo));
|
.orderByAsc(MesXslRubberQuickTestRecordLine::getSortNo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<MesXslRubberQuickTestRecordRawLine> selectRawLinesByRecordId(String recordId) {
|
||||||
|
return mesXslRubberQuickTestRecordRawLineMapper.selectList(
|
||||||
|
new LambdaQueryWrapper<MesXslRubberQuickTestRecordRawLine>()
|
||||||
|
.eq(MesXslRubberQuickTestRecordRawLine::getRecordId, recordId)
|
||||||
|
.orderByAsc(MesXslRubberQuickTestRecordRawLine::getSortNo));
|
||||||
|
}
|
||||||
|
|
||||||
//update-begin---author:jiangxh ---date:20260528 for:【MES】胶料快检记录单号JL+日期+4位流水自动生成-----------
|
//update-begin---author:jiangxh ---date:20260528 for:【MES】胶料快检记录单号JL+日期+4位流水自动生成-----------
|
||||||
@Override
|
@Override
|
||||||
public String generateRecordNo(MesXslRubberQuickTestRecord context) {
|
public String generateRecordNo(MesXslRubberQuickTestRecord context) {
|
||||||
|
|||||||
@@ -87,6 +87,11 @@ public class MesXslRubberQuickTestStdServiceImpl
|
|||||||
if (oConvertUtils.isEmpty(main.getAuditStatus())) {
|
if (oConvertUtils.isEmpty(main.getAuditStatus())) {
|
||||||
main.setAuditStatus("0");
|
main.setAuditStatus("0");
|
||||||
}
|
}
|
||||||
|
//update-begin---author:jiangxh ---date:20260617 for:【快检实验标准】新增时补齐 tenant_id-----------
|
||||||
|
if (main.getTenantId() == null) {
|
||||||
|
main.setTenantId(MesXslTenantUtils.resolveTenantId(null));
|
||||||
|
}
|
||||||
|
//update-end---author:jiangxh ---date:20260617 for:【快检实验标准】新增时补齐 tenant_id-----------
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insertLines(String stdId, List<MesXslRubberQuickTestStdLine> lineList) {
|
private void insertLines(String stdId, List<MesXslRubberQuickTestStdLine> lineList) {
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
-- MES 胶料快检记录原始数据明细(存储桌面端试验结果全部检测值)
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `mes_xsl_rubber_quick_test_record_raw_line` (
|
||||||
|
`id` varchar(32) NOT NULL COMMENT '主键',
|
||||||
|
`record_id` varchar(32) NOT NULL COMMENT '主表 mes_xsl_rubber_quick_test_record.id',
|
||||||
|
`row_no` varchar(32) DEFAULT NULL COMMENT '试验结果编号(如1_1)',
|
||||||
|
`data_point_id` varchar(32) DEFAULT NULL COMMENT '数据点ID',
|
||||||
|
`inspect_item` varchar(128) DEFAULT NULL COMMENT '数据点名称',
|
||||||
|
`lower_limit` decimal(18,6) DEFAULT NULL COMMENT '下限值',
|
||||||
|
`upper_limit` decimal(18,6) DEFAULT NULL COMMENT '上限值',
|
||||||
|
`inspect_value` decimal(18,6) DEFAULT NULL COMMENT '检测值',
|
||||||
|
`row_inspect_result` varchar(2) DEFAULT NULL COMMENT '行检验结果(字典xslmes_rubber_quick_test_record_result:1合格0不合格)',
|
||||||
|
`sort_no` int DEFAULT NULL COMMENT '排序号',
|
||||||
|
`create_by` varchar(32) DEFAULT NULL COMMENT '创建人',
|
||||||
|
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||||
|
`update_by` varchar(32) DEFAULT NULL COMMENT '更新人',
|
||||||
|
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `idx_rubber_quick_test_record_raw_record_id` (`record_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES胶料快检记录原始数据明细';
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
-- 胶料快检实验标准:补齐 tenant_id 为空的记录(与 MES 默认租户 1002 一致)
|
||||||
|
-- 说明:桌面端按 tenantId 拉取列表,tenant_id 为 NULL 的记录会被过滤导致条数不一致
|
||||||
|
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
|
||||||
|
SET @mes_tenant_id = 1002;
|
||||||
|
|
||||||
|
UPDATE `mes_xsl_rubber_quick_test_std`
|
||||||
|
SET `tenant_id` = @mes_tenant_id
|
||||||
|
WHERE `tenant_id` IS NULL
|
||||||
|
AND (`del_flag` = 0 OR `del_flag` IS NULL);
|
||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
/** 密炼PS类型:原材料检验标准 */
|
/** 密炼PS类型:原材料检验标准 */
|
||||||
const PS_TYPE_RAW_INSPECT_STD = 'raw_inspect_std';
|
const PS_TYPE_RAW_INSPECT_STD = 'raw_inspect_std';
|
||||||
|
/** 密炼PS状态:编制 */
|
||||||
|
const COMPILE_STATUS = 'compile';
|
||||||
|
|
||||||
const selectSearchSchema: FormSchema[] = [
|
const selectSearchSchema: FormSchema[] = [
|
||||||
{ label: 'PS编码', field: 'psCode', component: 'JInput', colProps: { span: 8 } },
|
{ label: 'PS编码', field: 'psCode', component: 'JInput', colProps: { span: 8 } },
|
||||||
@@ -42,6 +44,7 @@
|
|||||||
beforeFetch: (params) => ({
|
beforeFetch: (params) => ({
|
||||||
...params,
|
...params,
|
||||||
psType: PS_TYPE_RAW_INSPECT_STD,
|
psType: PS_TYPE_RAW_INSPECT_STD,
|
||||||
|
status: COMPILE_STATUS,
|
||||||
}),
|
}),
|
||||||
rowSelection: {
|
rowSelection: {
|
||||||
type: 'radio',
|
type: 'radio',
|
||||||
@@ -85,7 +88,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!row?.id) {
|
if (!row?.id) {
|
||||||
createMessage.warning('请选择一条密炼PS');
|
createMessage.warning('请选择一条编制状态的密炼PS');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (row.status && row.status !== COMPILE_STATUS) {
|
||||||
|
createMessage.warning('仅可选择编制状态的密炼PS');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (row.psType && row.psType !== PS_TYPE_RAW_INSPECT_STD) {
|
if (row.psType && row.psType !== PS_TYPE_RAW_INSPECT_STD) {
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using Prism.Events;
|
||||||
|
|
||||||
|
namespace YY.Admin.Core.Events;
|
||||||
|
|
||||||
|
public class RubberQuickTestStdChangedPayload
|
||||||
|
{
|
||||||
|
public string Action { get; set; } = string.Empty;
|
||||||
|
public string? StdId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RubberQuickTestStdChangedEvent : PubSubEvent<RubberQuickTestStdChangedPayload> { }
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using YY.Admin.Core.Entity;
|
||||||
|
|
||||||
|
namespace YY.Admin.Core.Services;
|
||||||
|
|
||||||
|
/// <summary>胶料快检记录操作台:密炼计划筛选、实验标准匹配、记录保存</summary>
|
||||||
|
public interface IRubberQuickTestOperationService
|
||||||
|
{
|
||||||
|
Task<List<MesXslMixingProductionPlan>> GetMixingProductionPlansAsync(CancellationToken ct = default);
|
||||||
|
|
||||||
|
Task<MesXslRubberQuickTestStd?> GetStdByRubberMaterialNameAsync(string rubberMaterialName, CancellationToken ct = default);
|
||||||
|
|
||||||
|
Task<string?> SaveRecordAsync(MesXslRubberQuickTestRecord record, CancellationToken ct = default);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using YY.Admin.Core.Entity;
|
||||||
|
|
||||||
|
namespace YY.Admin.Core.Services;
|
||||||
|
|
||||||
|
/// <summary>胶料快检实验标准(MES 只读同步)</summary>
|
||||||
|
public interface IRubberQuickTestStdService
|
||||||
|
{
|
||||||
|
Task<RubberQuickTestStdPageResult> PageAsync(
|
||||||
|
int pageNo, int pageSize,
|
||||||
|
string? stdName = null,
|
||||||
|
string? rubberMaterialName = null,
|
||||||
|
string? enableStatus = null,
|
||||||
|
CancellationToken ct = default);
|
||||||
|
|
||||||
|
Task<MesXslRubberQuickTestStd?> GetByIdAsync(string id, CancellationToken ct = default);
|
||||||
|
|
||||||
|
Task SyncFromRemoteAsync(CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
|
||||||
|
public record RubberQuickTestStdPageResult(
|
||||||
|
List<MesXslRubberQuickTestStd> Records,
|
||||||
|
long Total,
|
||||||
|
int PageNo,
|
||||||
|
int PageSize);
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
namespace YY.Admin.Core.Entity;
|
||||||
|
|
||||||
|
/// <summary>密炼生产计划维护(桌面端快检记录筛选用)</summary>
|
||||||
|
public class MesXslMixingProductionPlan
|
||||||
|
{
|
||||||
|
public string? Id { get; set; }
|
||||||
|
public int? SortNo { get; set; }
|
||||||
|
public string? MachineId { get; set; }
|
||||||
|
public string? MachineName { get; set; }
|
||||||
|
|
||||||
|
public string? MorningPlanId { get; set; }
|
||||||
|
public string? MorningPlanType { get; set; }
|
||||||
|
public string? MorningOrderNo { get; set; }
|
||||||
|
public DateTime? MorningOrderDate { get; set; }
|
||||||
|
public string? MorningFormulaName { get; set; }
|
||||||
|
|
||||||
|
public string? NoonPlanId { get; set; }
|
||||||
|
public string? NoonPlanType { get; set; }
|
||||||
|
public string? NoonOrderNo { get; set; }
|
||||||
|
public DateTime? NoonOrderDate { get; set; }
|
||||||
|
public string? NoonFormulaName { get; set; }
|
||||||
|
|
||||||
|
public string? NightPlanId { get; set; }
|
||||||
|
public string? NightPlanType { get; set; }
|
||||||
|
public string? NightOrderNo { get; set; }
|
||||||
|
public DateTime? NightOrderDate { get; set; }
|
||||||
|
public string? NightFormulaName { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
namespace YY.Admin.Core.Entity;
|
||||||
|
|
||||||
|
public class MesXslRubberQuickTestRecord
|
||||||
|
{
|
||||||
|
public string? Id { get; set; }
|
||||||
|
public string? RecordNo { get; set; }
|
||||||
|
public string? RubberMaterialId { get; set; }
|
||||||
|
public string? RubberMaterialName { get; set; }
|
||||||
|
public string? StdId { get; set; }
|
||||||
|
public string? ProdEquipmentLedgerId { get; set; }
|
||||||
|
public string? ProdEquipmentName { get; set; }
|
||||||
|
public DateTime? ProductionDate { get; set; }
|
||||||
|
public string? TrainNo { get; set; }
|
||||||
|
public string? WorkShift { get; set; }
|
||||||
|
public int? InspectTimes { get; set; }
|
||||||
|
public DateTime? InspectTime { get; set; }
|
||||||
|
public string? InspectorUserId { get; set; }
|
||||||
|
public string? InspectorUsername { get; set; }
|
||||||
|
public string? InspectorRealname { get; set; }
|
||||||
|
public string? InspectResult { get; set; }
|
||||||
|
public string? ProductionPlanNo { get; set; }
|
||||||
|
public List<MesXslRubberQuickTestRecordLine>? LineList { get; set; }
|
||||||
|
public List<MesXslRubberQuickTestRecordRawLine>? RawLineList { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
namespace YY.Admin.Core.Entity;
|
||||||
|
|
||||||
|
public class MesXslRubberQuickTestRecordLine
|
||||||
|
{
|
||||||
|
public string? Id { get; set; }
|
||||||
|
public string? RecordId { get; set; }
|
||||||
|
public string? DataPointId { get; set; }
|
||||||
|
public string? InspectItem { get; set; }
|
||||||
|
public decimal? LowerLimit { get; set; }
|
||||||
|
public decimal? InspectValue { get; set; }
|
||||||
|
public decimal? UpperLimit { get; set; }
|
||||||
|
public int? SortNo { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
namespace YY.Admin.Core.Entity;
|
||||||
|
|
||||||
|
/// <summary>MES 胶料快检记录原始数据明细</summary>
|
||||||
|
public class MesXslRubberQuickTestRecordRawLine
|
||||||
|
{
|
||||||
|
public string? Id { get; set; }
|
||||||
|
public string? RecordId { get; set; }
|
||||||
|
public string? RowNo { get; set; }
|
||||||
|
public string? DataPointId { get; set; }
|
||||||
|
public string? InspectItem { get; set; }
|
||||||
|
public decimal? LowerLimit { get; set; }
|
||||||
|
public decimal? UpperLimit { get; set; }
|
||||||
|
public decimal? InspectValue { get; set; }
|
||||||
|
/// <summary>行检验结果:1合格 0不合格</summary>
|
||||||
|
public string? RowInspectResult { get; set; }
|
||||||
|
public int? SortNo { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace YY.Admin.Core.Entity;
|
||||||
|
|
||||||
|
/// <summary>MES 胶料快检实验标准主表(桌面端只读同步)</summary>
|
||||||
|
public class MesXslRubberQuickTestStd
|
||||||
|
{
|
||||||
|
public string? Id { get; set; }
|
||||||
|
public string? StdName { get; set; }
|
||||||
|
public string? TestMethodId { get; set; }
|
||||||
|
public string? TestMethodName { get; set; }
|
||||||
|
public string? MixerType { get; set; }
|
||||||
|
public string? RubberMaterialId { get; set; }
|
||||||
|
public string? RubberMaterialName { get; set; }
|
||||||
|
public string? PsCompileId { get; set; }
|
||||||
|
public string? IssueNumber { get; set; }
|
||||||
|
public DateTime? IssueDate { get; set; }
|
||||||
|
public string? IssueDeptId { get; set; }
|
||||||
|
public string? IssueDeptName { get; set; }
|
||||||
|
public string? EnableStatus { get; set; }
|
||||||
|
public string? AuditStatus { get; set; }
|
||||||
|
public int? TenantId { get; set; }
|
||||||
|
public string? SysOrgCode { get; set; }
|
||||||
|
public string? CreateBy { get; set; }
|
||||||
|
public DateTime? CreateTime { get; set; }
|
||||||
|
public string? UpdateBy { get; set; }
|
||||||
|
public DateTime? UpdateTime { get; set; }
|
||||||
|
public List<MesXslRubberQuickTestStdLine>? LineList { get; set; }
|
||||||
|
|
||||||
|
public string EnableStatusText => EnableStatus == "0" ? "已停用" : EnableStatus == "1" ? "使用中" : EnableStatus ?? string.Empty;
|
||||||
|
public string AuditStatusText => AuditStatus == "1" ? "已批准" : AuditStatus == "0" ? "草稿" : AuditStatus ?? string.Empty;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
namespace YY.Admin.Core.Entity;
|
||||||
|
|
||||||
|
public class MesXslRubberQuickTestStdLine
|
||||||
|
{
|
||||||
|
public string? Id { get; set; }
|
||||||
|
public string? StdId { get; set; }
|
||||||
|
public string? DataPointId { get; set; }
|
||||||
|
public string? PointName { get; set; }
|
||||||
|
public decimal? LowerLimit { get; set; }
|
||||||
|
public decimal? UpperLimit { get; set; }
|
||||||
|
public decimal? LowerWarn { get; set; }
|
||||||
|
public decimal? UpperWarn { get; set; }
|
||||||
|
public decimal? TargetValue { get; set; }
|
||||||
|
public int? SortNo { get; set; }
|
||||||
|
}
|
||||||
@@ -48,6 +48,10 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
|
|||||||
new SysMenu{ Id=1300150011001, Pid=1300150000101, Title="库区管理", Path="/xslmes/mesXslWarehouseArea", Name="mesXslWarehouseArea", Component="WarehouseAreaListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=109 },
|
new SysMenu{ Id=1300150011001, Pid=1300150000101, Title="库区管理", Path="/xslmes/mesXslWarehouseArea", Name="mesXslWarehouseArea", Component="WarehouseAreaListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=109 },
|
||||||
// 密炼物料皮重策略
|
// 密炼物料皮重策略
|
||||||
new SysMenu{ Id=1300150011101, Pid=1300150000101, Title="密炼物料皮重策略", Path="/xslmes/mesXslMixerMaterialTareStrategy", Name="mesXslMixerMaterialTareStrategy", Component="MixerMaterialTareStrategyListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
|
new SysMenu{ Id=1300150011101, Pid=1300150000101, Title="密炼物料皮重策略", Path="/xslmes/mesXslMixerMaterialTareStrategy", Name="mesXslMixerMaterialTareStrategy", Component="MixerMaterialTareStrategyListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
|
||||||
|
// 快检记录
|
||||||
|
new SysMenu{ Id=1300150011201, Pid=1300150000101, Title="快检记录", Path="/xslmes/rubberQuickTestOperation", Name="rubberQuickTestOperation", Component="RubberQuickTestOperationView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=111 },
|
||||||
|
// 胶料快检实验标准(桌面端只读)
|
||||||
|
new SysMenu{ Id=1300150011301, Pid=1300150000101, Title="胶料快检实验标准", Path="/xslmes/mesXslRubberQuickTestStd", Name="mesXslRubberQuickTestStd", Component="RubberQuickTestStdListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=112 },
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ public class SysTenantMenuSeedData : ISqlSugarEntitySeedData<SysTenantMenu>
|
|||||||
new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300150010901},
|
new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300150010901},
|
||||||
new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300150011001},
|
new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300150011001},
|
||||||
new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300150011101},
|
new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300150011101},
|
||||||
|
new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300150011201},
|
||||||
|
new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300150011301},
|
||||||
new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300200012101},
|
new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300200012101},
|
||||||
new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300200012111},
|
new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300200012111},
|
||||||
new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300200012121},
|
new SysTenantMenu(){ TenantId=1300000000001,MenuId=1300200012121},
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using YY.Admin.Core;
|
||||||
|
using YY.Admin.Core.Entity;
|
||||||
|
using YY.Admin.Core.Services;
|
||||||
|
|
||||||
|
namespace YY.Admin.Services.Service.RubberQuickTest;
|
||||||
|
|
||||||
|
public class RubberQuickTestOperationService : IRubberQuickTestOperationService, ISingletonDependency
|
||||||
|
{
|
||||||
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
private readonly INetworkMonitor _networkMonitor;
|
||||||
|
private readonly ILoggerService _logger;
|
||||||
|
|
||||||
|
private static readonly JsonSerializerOptions _jsonOpts = new()
|
||||||
|
{
|
||||||
|
PropertyNameCaseInsensitive = true,
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||||
|
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
|
||||||
|
};
|
||||||
|
|
||||||
|
public RubberQuickTestOperationService(
|
||||||
|
IHttpClientFactory httpClientFactory,
|
||||||
|
IConfiguration configuration,
|
||||||
|
INetworkMonitor networkMonitor,
|
||||||
|
ILoggerService logger)
|
||||||
|
{
|
||||||
|
_httpClientFactory = httpClientFactory;
|
||||||
|
_configuration = configuration;
|
||||||
|
_networkMonitor = networkMonitor;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string BaseUrl => (_configuration.GetValue<string>("JeecgIntegration:BaseUrl") ?? "http://localhost:8080/jeecg-boot").TrimEnd('/');
|
||||||
|
private int DefaultTenantId => (int?)_configuration.GetValue<long?>("JeecgIntegration:DefaultTenantId") ?? 1002;
|
||||||
|
|
||||||
|
public async Task<List<MesXslMixingProductionPlan>> GetMixingProductionPlansAsync(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
if (!_networkMonitor.IsOnline)
|
||||||
|
throw new InvalidOperationException("网络未连接,无法加载密炼生产计划");
|
||||||
|
|
||||||
|
var result = new List<MesXslMixingProductionPlan>();
|
||||||
|
int pageNo = 1;
|
||||||
|
const int pageSize = 500;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var url = $"{BaseUrl}/xslmes/mesXslMixingProductionPlan/anon/list?pageNo={pageNo}&pageSize={pageSize}&tenantId={DefaultTenantId}";
|
||||||
|
using var client = _httpClientFactory.CreateClient("JeecgApi");
|
||||||
|
var resp = await client.GetAsync(url, ct).ConfigureAwait(false);
|
||||||
|
resp.EnsureSuccessStatusCode();
|
||||||
|
var json = await resp.Content.ReadAsStringAsync(ct).ConfigureAwait(false);
|
||||||
|
using var doc = JsonDocument.Parse(json);
|
||||||
|
if (!doc.RootElement.TryGetProperty("result", out var resultEl)) break;
|
||||||
|
if (resultEl.TryGetProperty("records", out var recordsEl))
|
||||||
|
{
|
||||||
|
var page = recordsEl.Deserialize<List<MesXslMixingProductionPlan>>(_jsonOpts);
|
||||||
|
if (page != null) result.AddRange(page);
|
||||||
|
}
|
||||||
|
long total = 0;
|
||||||
|
if (resultEl.TryGetProperty("total", out var totalEl)) total = totalEl.GetInt64();
|
||||||
|
if (result.Count >= total || (resultEl.TryGetProperty("records", out var r2) && r2.GetArrayLength() < pageSize)) break;
|
||||||
|
pageNo++;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Information($"[快检记录] 加载密炼生产计划 {result.Count} 条");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<MesXslRubberQuickTestStd?> GetStdByRubberMaterialNameAsync(string rubberMaterialName, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(rubberMaterialName))
|
||||||
|
return null;
|
||||||
|
if (!_networkMonitor.IsOnline)
|
||||||
|
throw new InvalidOperationException("网络未连接,无法加载实验标准");
|
||||||
|
|
||||||
|
var encoded = Uri.EscapeDataString(rubberMaterialName.Trim());
|
||||||
|
var url = $"{BaseUrl}/xslmes/mesXslRubberQuickTestStd/anon/queryByRubberMaterialName?rubberMaterialName={encoded}";
|
||||||
|
using var client = _httpClientFactory.CreateClient("JeecgApi");
|
||||||
|
var resp = await client.GetAsync(url, ct).ConfigureAwait(false);
|
||||||
|
var json = await resp.Content.ReadAsStringAsync(ct).ConfigureAwait(false);
|
||||||
|
using var doc = JsonDocument.Parse(json);
|
||||||
|
if (!doc.RootElement.TryGetProperty("success", out var successEl) || !successEl.GetBoolean())
|
||||||
|
{
|
||||||
|
var msg = doc.RootElement.TryGetProperty("message", out var msgEl) ? msgEl.GetString() : "查询实验标准失败";
|
||||||
|
_logger.Warning($"[快检记录] 实验标准查询失败: {msg}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!doc.RootElement.TryGetProperty("result", out var resultEl) || resultEl.ValueKind == JsonValueKind.Null)
|
||||||
|
return null;
|
||||||
|
return resultEl.Deserialize<MesXslRubberQuickTestStd>(_jsonOpts);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string?> SaveRecordAsync(MesXslRubberQuickTestRecord record, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
if (!_networkMonitor.IsOnline)
|
||||||
|
throw new InvalidOperationException("网络未连接,无法保存快检记录");
|
||||||
|
|
||||||
|
var url = $"{BaseUrl}/xslmes/mesXslRubberQuickTestRecord/anon/add";
|
||||||
|
using var client = _httpClientFactory.CreateClient("JeecgApi");
|
||||||
|
var body = JsonSerializer.Serialize(record, _jsonOpts);
|
||||||
|
using var content = new StringContent(body, Encoding.UTF8, "application/json");
|
||||||
|
var resp = await client.PostAsync(url, content, ct).ConfigureAwait(false);
|
||||||
|
var json = await resp.Content.ReadAsStringAsync(ct).ConfigureAwait(false);
|
||||||
|
using var doc = JsonDocument.Parse(json);
|
||||||
|
if (!doc.RootElement.TryGetProperty("success", out var successEl) || !successEl.GetBoolean())
|
||||||
|
{
|
||||||
|
var msg = doc.RootElement.TryGetProperty("message", out var msgEl) ? msgEl.GetString() : "保存失败";
|
||||||
|
throw new InvalidOperationException(msg ?? "保存失败");
|
||||||
|
}
|
||||||
|
_logger.Information($"[快检记录] 保存成功 recordNo={record.RecordNo}");
|
||||||
|
return doc.RootElement.TryGetProperty("message", out var m) ? m.GetString() : "保存成功";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,302 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Prism.Events;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Web;
|
||||||
|
using YY.Admin.Core;
|
||||||
|
using YY.Admin.Core.Entity;
|
||||||
|
using YY.Admin.Core.Events;
|
||||||
|
using YY.Admin.Core.Services;
|
||||||
|
|
||||||
|
namespace YY.Admin.Services.Service.RubberQuickTestStd;
|
||||||
|
|
||||||
|
/// <summary>胶料快检实验标准:MES 只读拉取 + 本地缓存,断网读缓存,联网刷新</summary>
|
||||||
|
public class RubberQuickTestStdService : IRubberQuickTestStdService, ISingletonDependency
|
||||||
|
{
|
||||||
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
private readonly INetworkMonitor _networkMonitor;
|
||||||
|
private readonly IEventAggregator _eventAggregator;
|
||||||
|
private readonly ILoggerService _logger;
|
||||||
|
private readonly SemaphoreSlim _syncLock = new(1, 1);
|
||||||
|
private readonly object _cacheLock = new();
|
||||||
|
private readonly string _cacheFilePath;
|
||||||
|
private List<MesXslRubberQuickTestStd> _localCache = new();
|
||||||
|
|
||||||
|
private static readonly JsonSerializerOptions _jsonOpts = new()
|
||||||
|
{
|
||||||
|
PropertyNameCaseInsensitive = true,
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||||
|
Converters = { new NullableDateTimeJsonConverter() }
|
||||||
|
};
|
||||||
|
|
||||||
|
public RubberQuickTestStdService(
|
||||||
|
IHttpClientFactory httpClientFactory,
|
||||||
|
IConfiguration configuration,
|
||||||
|
INetworkMonitor networkMonitor,
|
||||||
|
IEventAggregator eventAggregator,
|
||||||
|
ILoggerService logger)
|
||||||
|
{
|
||||||
|
_httpClientFactory = httpClientFactory;
|
||||||
|
_configuration = configuration;
|
||||||
|
_networkMonitor = networkMonitor;
|
||||||
|
_eventAggregator = eventAggregator;
|
||||||
|
_logger = logger;
|
||||||
|
|
||||||
|
var appDataDir = Path.Combine(
|
||||||
|
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||||
|
"YY.Admin", "sync-cache");
|
||||||
|
Directory.CreateDirectory(appDataDir);
|
||||||
|
_cacheFilePath = Path.Combine(appDataDir, "mes-xsl-rubber-quick-test-std-cache.json");
|
||||||
|
|
||||||
|
LoadCacheFromDisk();
|
||||||
|
_logger.Information($"[快检实验标准] 服务初始化,缓存={_localCache.Count},在线={_networkMonitor.IsOnline}");
|
||||||
|
|
||||||
|
_networkMonitor.StatusChanged += OnNetworkStatusChanged;
|
||||||
|
if (_networkMonitor.IsOnline)
|
||||||
|
_ = Task.Run(() => SyncFromRemoteAsync(CancellationToken.None));
|
||||||
|
}
|
||||||
|
|
||||||
|
private string BaseUrl => (_configuration.GetValue<string>("JeecgIntegration:BaseUrl") ?? "http://localhost:8080/jeecg-boot").TrimEnd('/');
|
||||||
|
private int DefaultTenantId => (int?)_configuration.GetValue<long?>("JeecgIntegration:DefaultTenantId") ?? 1002;
|
||||||
|
private HttpClient CreateClient() => _httpClientFactory.CreateClient("JeecgApi");
|
||||||
|
|
||||||
|
public async Task<RubberQuickTestStdPageResult> PageAsync(
|
||||||
|
int pageNo, int pageSize,
|
||||||
|
string? stdName = null,
|
||||||
|
string? rubberMaterialName = null,
|
||||||
|
string? enableStatus = null,
|
||||||
|
CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
if (_networkMonitor.IsOnline)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await SyncFromRemoteAsync(ct).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Warning($"[快检实验标准] 列表拉取失败,使用本地缓存:{ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<MesXslRubberQuickTestStd> source;
|
||||||
|
lock (_cacheLock)
|
||||||
|
source = _localCache.Select(CloneMain).ToList();
|
||||||
|
|
||||||
|
var filtered = ApplyFilters(source, stdName, rubberMaterialName, enableStatus);
|
||||||
|
var total = filtered.Count;
|
||||||
|
var records = filtered
|
||||||
|
.Skip(Math.Max(0, (pageNo - 1) * pageSize))
|
||||||
|
.Take(pageSize)
|
||||||
|
.ToList();
|
||||||
|
return new RubberQuickTestStdPageResult(records, total, pageNo, pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<MesXslRubberQuickTestStd?> GetByIdAsync(string id, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(id)) return null;
|
||||||
|
|
||||||
|
if (_networkMonitor.IsOnline)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var url = $"{BaseUrl}/xslmes/mesXslRubberQuickTestStd/anon/queryById?id={Uri.EscapeDataString(id)}";
|
||||||
|
using var client = CreateClient();
|
||||||
|
var resp = await client.GetAsync(url, ct).ConfigureAwait(false);
|
||||||
|
if (resp.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
var json = await resp.Content.ReadAsStringAsync(ct).ConfigureAwait(false);
|
||||||
|
using var doc = JsonDocument.Parse(json);
|
||||||
|
if (doc.RootElement.TryGetProperty("result", out var resultEl))
|
||||||
|
{
|
||||||
|
var entity = resultEl.Deserialize<MesXslRubberQuickTestStd>(_jsonOpts);
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
UpsertLocalCacheMain(entity);
|
||||||
|
return CloneMain(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Warning($"[快检实验标准] 详情拉取失败 id={id},回退缓存:{ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (_cacheLock)
|
||||||
|
{
|
||||||
|
var found = _localCache.FirstOrDefault(x => string.Equals(x.Id, id, StringComparison.OrdinalIgnoreCase));
|
||||||
|
return found != null ? CloneMain(found) : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SyncFromRemoteAsync(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
await _syncLock.WaitAsync(ct).ConfigureAwait(false);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!_networkMonitor.IsOnline)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var query = HttpUtility.ParseQueryString(string.Empty);
|
||||||
|
query["pageNo"] = "1";
|
||||||
|
query["pageSize"] = "10000";
|
||||||
|
query["tenantId"] = DefaultTenantId.ToString();
|
||||||
|
var url = $"{BaseUrl}/xslmes/mesXslRubberQuickTestStd/anon/list?{query}";
|
||||||
|
|
||||||
|
using var client = CreateClient();
|
||||||
|
var resp = await client.GetAsync(url, ct).ConfigureAwait(false);
|
||||||
|
resp.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
|
var json = await resp.Content.ReadAsStringAsync(ct).ConfigureAwait(false);
|
||||||
|
using var doc = JsonDocument.Parse(json);
|
||||||
|
var records = doc.RootElement.GetProperty("result").GetProperty("records")
|
||||||
|
.Deserialize<List<MesXslRubberQuickTestStd>>(_jsonOpts) ?? new();
|
||||||
|
|
||||||
|
lock (_cacheLock)
|
||||||
|
{
|
||||||
|
_localCache = records.Select(CloneMain).ToList();
|
||||||
|
SaveCacheToDiskUnsafe();
|
||||||
|
}
|
||||||
|
_logger.Information($"[快检实验标准] 同步完成 count={records.Count}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Warning($"[快检实验标准] 远程同步失败:{ex.Message}");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_syncLock.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnNetworkStatusChanged(bool isOnline)
|
||||||
|
{
|
||||||
|
if (!isOnline) return;
|
||||||
|
_ = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await SyncFromRemoteAsync(CancellationToken.None).ConfigureAwait(false);
|
||||||
|
_eventAggregator.GetEvent<RubberQuickTestStdChangedEvent>()
|
||||||
|
.Publish(new RubberQuickTestStdChangedPayload { Action = "reconnect" });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<MesXslRubberQuickTestStd> ApplyFilters(
|
||||||
|
List<MesXslRubberQuickTestStd> source,
|
||||||
|
string? stdName,
|
||||||
|
string? rubberMaterialName,
|
||||||
|
string? enableStatus)
|
||||||
|
{
|
||||||
|
IEnumerable<MesXslRubberQuickTestStd> q = source;
|
||||||
|
if (!string.IsNullOrWhiteSpace(stdName))
|
||||||
|
q = q.Where(x => (x.StdName ?? "").Contains(stdName.Trim(), StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (!string.IsNullOrWhiteSpace(rubberMaterialName))
|
||||||
|
q = q.Where(x => (x.RubberMaterialName ?? "").Contains(rubberMaterialName.Trim(), StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (!string.IsNullOrWhiteSpace(enableStatus))
|
||||||
|
q = q.Where(x => string.Equals(x.EnableStatus, enableStatus.Trim(), StringComparison.OrdinalIgnoreCase));
|
||||||
|
return q.OrderByDescending(x => x.CreateTime ?? DateTime.MinValue).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpsertLocalCacheMain(MesXslRubberQuickTestStd entity)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(entity.Id)) return;
|
||||||
|
lock (_cacheLock)
|
||||||
|
{
|
||||||
|
var idx = _localCache.FindIndex(x => string.Equals(x.Id, entity.Id, StringComparison.OrdinalIgnoreCase));
|
||||||
|
var copy = CloneMain(entity);
|
||||||
|
if (idx >= 0) _localCache[idx] = copy;
|
||||||
|
else _localCache.Insert(0, copy);
|
||||||
|
SaveCacheToDiskUnsafe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadCacheFromDisk()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!File.Exists(_cacheFilePath)) return;
|
||||||
|
_localCache = JsonSerializer.Deserialize<List<MesXslRubberQuickTestStd>>(
|
||||||
|
File.ReadAllText(_cacheFilePath), _jsonOpts) ?? new();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
_localCache = new();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveCacheToDiskUnsafe() =>
|
||||||
|
File.WriteAllText(_cacheFilePath, JsonSerializer.Serialize(_localCache, _jsonOpts));
|
||||||
|
|
||||||
|
private static MesXslRubberQuickTestStd CloneMain(MesXslRubberQuickTestStd x) => new()
|
||||||
|
{
|
||||||
|
Id = x.Id,
|
||||||
|
StdName = x.StdName,
|
||||||
|
TestMethodId = x.TestMethodId,
|
||||||
|
TestMethodName = x.TestMethodName,
|
||||||
|
MixerType = x.MixerType,
|
||||||
|
RubberMaterialId = x.RubberMaterialId,
|
||||||
|
RubberMaterialName = x.RubberMaterialName,
|
||||||
|
PsCompileId = x.PsCompileId,
|
||||||
|
IssueNumber = x.IssueNumber,
|
||||||
|
IssueDate = x.IssueDate,
|
||||||
|
IssueDeptId = x.IssueDeptId,
|
||||||
|
IssueDeptName = x.IssueDeptName,
|
||||||
|
EnableStatus = x.EnableStatus,
|
||||||
|
AuditStatus = x.AuditStatus,
|
||||||
|
TenantId = x.TenantId,
|
||||||
|
SysOrgCode = x.SysOrgCode,
|
||||||
|
CreateBy = x.CreateBy,
|
||||||
|
CreateTime = x.CreateTime,
|
||||||
|
UpdateBy = x.UpdateBy,
|
||||||
|
UpdateTime = x.UpdateTime,
|
||||||
|
LineList = x.LineList?.Select(l => new MesXslRubberQuickTestStdLine
|
||||||
|
{
|
||||||
|
Id = l.Id,
|
||||||
|
StdId = l.StdId,
|
||||||
|
DataPointId = l.DataPointId,
|
||||||
|
PointName = l.PointName,
|
||||||
|
LowerLimit = l.LowerLimit,
|
||||||
|
UpperLimit = l.UpperLimit,
|
||||||
|
LowerWarn = l.LowerWarn,
|
||||||
|
UpperWarn = l.UpperWarn,
|
||||||
|
TargetValue = l.TargetValue,
|
||||||
|
SortNo = l.SortNo
|
||||||
|
}).ToList()
|
||||||
|
};
|
||||||
|
|
||||||
|
private sealed class NullableDateTimeJsonConverter : JsonConverter<DateTime?>
|
||||||
|
{
|
||||||
|
private static readonly string[] Formats =
|
||||||
|
[
|
||||||
|
"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss.fff",
|
||||||
|
"yyyy-MM-ddTHH:mm:ss", "yyyy-MM-ddTHH:mm:ss.fff",
|
||||||
|
"yyyy-MM-ddTHH:mm:ssZ", "yyyy-MM-ddTHH:mm:ss.fffZ",
|
||||||
|
"yyyy-MM-dd"
|
||||||
|
];
|
||||||
|
|
||||||
|
public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == JsonTokenType.Null) return null;
|
||||||
|
if (reader.TokenType == JsonTokenType.String)
|
||||||
|
{
|
||||||
|
var raw = reader.GetString();
|
||||||
|
if (string.IsNullOrWhiteSpace(raw)) return null;
|
||||||
|
if (DateTime.TryParseExact(raw, Formats, System.Globalization.CultureInfo.InvariantCulture,
|
||||||
|
System.Globalization.DateTimeStyles.AssumeLocal, out var dt)) return dt;
|
||||||
|
if (DateTime.TryParse(raw, out var fb)) return fb;
|
||||||
|
}
|
||||||
|
throw new JsonException($"无法转换为 DateTime?,token={reader.TokenType}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (value.HasValue) writer.WriteStringValue(value.Value.ToString("yyyy-MM-dd HH:mm:ss"));
|
||||||
|
else writer.WriteNullValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
using Prism.Events;
|
||||||
|
using System.Text.Json;
|
||||||
|
using YY.Admin.Core;
|
||||||
|
using YY.Admin.Core.Events;
|
||||||
|
using YY.Admin.Core.Events;
|
||||||
|
|
||||||
|
namespace YY.Admin.Services.Service.RubberQuickTestStd;
|
||||||
|
|
||||||
|
public class RubberQuickTestStdSyncCoordinator : ISingletonDependency
|
||||||
|
{
|
||||||
|
private readonly IEventAggregator _eventAggregator;
|
||||||
|
private readonly ILoggerService _logger;
|
||||||
|
|
||||||
|
public RubberQuickTestStdSyncCoordinator(
|
||||||
|
IEventAggregator eventAggregator,
|
||||||
|
SyncPollManager pollManager,
|
||||||
|
ILoggerService logger)
|
||||||
|
{
|
||||||
|
_eventAggregator = eventAggregator;
|
||||||
|
_logger = logger;
|
||||||
|
|
||||||
|
_eventAggregator.GetEvent<RemoteCommandReceivedEvent>()
|
||||||
|
.Subscribe(OnRemoteCommand, ThreadOption.BackgroundThread);
|
||||||
|
_eventAggregator.GetEvent<NetworkStatusChangedEvent>()
|
||||||
|
.Subscribe(OnNetworkStatusChanged, ThreadOption.BackgroundThread);
|
||||||
|
|
||||||
|
pollManager.Register("胶料快检实验标准", () =>
|
||||||
|
{
|
||||||
|
_eventAggregator.GetEvent<RubberQuickTestStdChangedEvent>()
|
||||||
|
.Publish(new RubberQuickTestStdChangedPayload { Action = "poll" });
|
||||||
|
return Task.CompletedTask;
|
||||||
|
});
|
||||||
|
|
||||||
|
_logger.Information("[快检实验标准] RubberQuickTestStdSyncCoordinator 已启动");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnNetworkStatusChanged(NetworkStatusChangedPayload payload)
|
||||||
|
{
|
||||||
|
if (!payload.IsOnline) return;
|
||||||
|
_logger.Information("[快检实验标准] 网络恢复,触发补偿刷新");
|
||||||
|
_eventAggregator.GetEvent<RubberQuickTestStdChangedEvent>()
|
||||||
|
.Publish(new RubberQuickTestStdChangedPayload { Action = "reconnect" });
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnRemoteCommand(RemoteCommandPayload payload)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var json = payload.CommandJson ?? string.Empty;
|
||||||
|
if (string.IsNullOrWhiteSpace(json)) return;
|
||||||
|
|
||||||
|
using var doc = JsonDocument.Parse(json);
|
||||||
|
if (!doc.RootElement.TryGetProperty("cmd", out var cmdEl)) return;
|
||||||
|
if (!cmdEl.GetString()?.Equals("MES_RUBBER_QUICK_TEST_STD_CHANGED", StringComparison.OrdinalIgnoreCase) ?? true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
doc.RootElement.TryGetProperty("action", out var actionEl);
|
||||||
|
doc.RootElement.TryGetProperty("stdId", out var idEl);
|
||||||
|
|
||||||
|
var changed = new RubberQuickTestStdChangedPayload
|
||||||
|
{
|
||||||
|
Action = actionEl.GetString() ?? string.Empty,
|
||||||
|
StdId = idEl.ValueKind == JsonValueKind.String ? idEl.GetString() : null
|
||||||
|
};
|
||||||
|
_logger.Information($"[快检实验标准] STOMP action={changed.Action}, stdId={changed.StdId}");
|
||||||
|
_eventAggregator.GetEvent<RubberQuickTestStdChangedEvent>().Publish(changed);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Warning($"[快检实验标准] 处理 STOMP 命令失败:{ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -174,6 +174,10 @@ public class StompWebSocketService : ISignalRService
|
|||||||
await SendFrameAsync(
|
await SendFrameAsync(
|
||||||
BuildSubscribeFrame("sub-print-biz-binds", "/topic/sync/print-biz-binds"),
|
BuildSubscribeFrame("sub-print-biz-binds", "/topic/sync/print-biz-binds"),
|
||||||
cancellationToken).ConfigureAwait(false);
|
cancellationToken).ConfigureAwait(false);
|
||||||
|
// 胶料快检实验标准变更:订阅 /topic/sync/mes-rubber-quick-test-stds
|
||||||
|
await SendFrameAsync(
|
||||||
|
BuildSubscribeFrame("sub-mes-rubber-quick-test-stds", "/topic/sync/mes-rubber-quick-test-stds"),
|
||||||
|
cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
// 订阅服务端 PONG 回复(应用层假在线检测)
|
// 订阅服务端 PONG 回复(应用层假在线检测)
|
||||||
await SendFrameAsync(
|
await SendFrameAsync(
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ using YY.Admin.Views.WarehouseArea;
|
|||||||
using YY.Admin.Views.RawMaterialEntry;
|
using YY.Admin.Views.RawMaterialEntry;
|
||||||
using YY.Admin.Views.Print;
|
using YY.Admin.Views.Print;
|
||||||
using YY.Admin.Views.MixerMaterialTareStrategy;
|
using YY.Admin.Views.MixerMaterialTareStrategy;
|
||||||
|
using YY.Admin.Views.RubberQuickTest;
|
||||||
|
using YY.Admin.Views.RubberQuickTestStd;
|
||||||
|
|
||||||
namespace YY.Admin
|
namespace YY.Admin
|
||||||
{
|
{
|
||||||
@@ -95,6 +97,10 @@ namespace YY.Admin
|
|||||||
containerRegistry.RegisterForNavigation<WarehouseAreaListView>();
|
containerRegistry.RegisterForNavigation<WarehouseAreaListView>();
|
||||||
// 密炼物料皮重策略
|
// 密炼物料皮重策略
|
||||||
containerRegistry.RegisterForNavigation<MixerMaterialTareStrategyListView>();
|
containerRegistry.RegisterForNavigation<MixerMaterialTareStrategyListView>();
|
||||||
|
// 快检记录操作台
|
||||||
|
containerRegistry.RegisterForNavigation<RubberQuickTestOperationView>();
|
||||||
|
// 胶料快检实验标准(只读)
|
||||||
|
containerRegistry.RegisterForNavigation<RubberQuickTestStdListView>();
|
||||||
// 打印设置
|
// 打印设置
|
||||||
containerRegistry.RegisterForNavigation<PrintSettingsView>();
|
containerRegistry.RegisterForNavigation<PrintSettingsView>();
|
||||||
// 打印模板列表
|
// 打印模板列表
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ using YY.Admin.Services.Service.Warehouse;
|
|||||||
using YY.Admin.Services.Service.WarehouseArea;
|
using YY.Admin.Services.Service.WarehouseArea;
|
||||||
using YY.Admin.Services.Service.WeightRecord;
|
using YY.Admin.Services.Service.WeightRecord;
|
||||||
using YY.Admin.Services.Service.Print;
|
using YY.Admin.Services.Service.Print;
|
||||||
|
using YY.Admin.Services.Service.RubberQuickTest;
|
||||||
|
using YY.Admin.Services.Service.RubberQuickTestStd;
|
||||||
|
|
||||||
namespace YY.Admin.Module;
|
namespace YY.Admin.Module;
|
||||||
|
|
||||||
@@ -86,6 +88,13 @@ public class SyncModule : IModule
|
|||||||
containerRegistry.RegisterSingleton<PrintTemplateSyncCoordinator>();
|
containerRegistry.RegisterSingleton<PrintTemplateSyncCoordinator>();
|
||||||
containerRegistry.RegisterSingleton<PrintBizTemplateBindSyncCoordinator>();
|
containerRegistry.RegisterSingleton<PrintBizTemplateBindSyncCoordinator>();
|
||||||
|
|
||||||
|
// 胶料快检记录操作台
|
||||||
|
containerRegistry.RegisterSingleton<IRubberQuickTestOperationService, RubberQuickTestOperationService>();
|
||||||
|
|
||||||
|
// 胶料快检实验标准(MES 只读同步)
|
||||||
|
containerRegistry.RegisterSingleton<IRubberQuickTestStdService, RubberQuickTestStdService>();
|
||||||
|
containerRegistry.RegisterSingleton<RubberQuickTestStdSyncCoordinator>();
|
||||||
|
|
||||||
var serviceCollection = new ServiceCollection();
|
var serviceCollection = new ServiceCollection();
|
||||||
serviceCollection.AddTransient<DisconnectGuardHandler>();
|
serviceCollection.AddTransient<DisconnectGuardHandler>();
|
||||||
serviceCollection.AddHttpClient("JeecgApi", (sp, client) =>
|
serviceCollection.AddHttpClient("JeecgApi", (sp, client) =>
|
||||||
@@ -156,6 +165,8 @@ public class SyncModule : IModule
|
|||||||
// 强制实例化打印模板同步协调器
|
// 强制实例化打印模板同步协调器
|
||||||
_ = containerProvider.Resolve<PrintTemplateSyncCoordinator>();
|
_ = containerProvider.Resolve<PrintTemplateSyncCoordinator>();
|
||||||
_ = containerProvider.Resolve<PrintBizTemplateBindSyncCoordinator>();
|
_ = containerProvider.Resolve<PrintBizTemplateBindSyncCoordinator>();
|
||||||
|
// 胶料快检实验标准只读同步协调器
|
||||||
|
_ = containerProvider.Resolve<RubberQuickTestStdSyncCoordinator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
|
private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
|
||||||
|
|||||||
@@ -152,6 +152,16 @@ namespace YY.Admin.ViewModels.Control
|
|||||||
["/xslmes/mesXslMixerMaterialTareStrategy"] = "MixerMaterialTareStrategyListView",
|
["/xslmes/mesXslMixerMaterialTareStrategy"] = "MixerMaterialTareStrategyListView",
|
||||||
["mesXslMixerMaterialTareStrategy"] = "MixerMaterialTareStrategyListView",
|
["mesXslMixerMaterialTareStrategy"] = "MixerMaterialTareStrategyListView",
|
||||||
|
|
||||||
|
// 已实现页面:快检记录操作台
|
||||||
|
["RubberQuickTestOperationView"] = "RubberQuickTestOperationView",
|
||||||
|
["/xslmes/rubberQuickTestOperation"] = "RubberQuickTestOperationView",
|
||||||
|
["rubberQuickTestOperation"] = "RubberQuickTestOperationView",
|
||||||
|
|
||||||
|
// 已实现页面:胶料快检实验标准(只读)
|
||||||
|
["RubberQuickTestStdListView"] = "RubberQuickTestStdListView",
|
||||||
|
["/xslmes/mesXslRubberQuickTestStd"] = "RubberQuickTestStdListView",
|
||||||
|
["mesXslRubberQuickTestStd"] = "RubberQuickTestStdListView",
|
||||||
|
|
||||||
// 已实现页面:打印设置
|
// 已实现页面:打印设置
|
||||||
["PrintSettingsView"] = "PrintSettingsView",
|
["PrintSettingsView"] = "PrintSettingsView",
|
||||||
["/system/printSettings"] = "PrintSettingsView",
|
["/system/printSettings"] = "PrintSettingsView",
|
||||||
|
|||||||
@@ -0,0 +1,755 @@
|
|||||||
|
using HandyControl.Controls;
|
||||||
|
using LiveChartsCore;
|
||||||
|
using LiveChartsCore.SkiaSharpView;
|
||||||
|
using LiveChartsCore.SkiaSharpView.Painting;
|
||||||
|
using Prism.Mvvm;
|
||||||
|
using SkiaSharp;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using YY.Admin.Core;
|
||||||
|
using YY.Admin.Core.Entity;
|
||||||
|
using YY.Admin.Core.Services;
|
||||||
|
using YY.Admin.Core.Session;
|
||||||
|
|
||||||
|
namespace YY.Admin.ViewModels.RubberQuickTest;
|
||||||
|
|
||||||
|
/// <summary>密炼生产计划班次展开项(桌面端筛选用)</summary>
|
||||||
|
public class MixingPlanShiftOption
|
||||||
|
{
|
||||||
|
public string PlanRowId { get; set; } = string.Empty;
|
||||||
|
public string? MachineId { get; set; }
|
||||||
|
public string? MachineName { get; set; }
|
||||||
|
public string ShiftKey { get; set; } = string.Empty;
|
||||||
|
public string ShiftCode { get; set; } = string.Empty;
|
||||||
|
public string ShiftName { get; set; } = string.Empty;
|
||||||
|
public DateTime? OrderDate { get; set; }
|
||||||
|
public string? PlanId { get; set; }
|
||||||
|
public string? OrderNo { get; set; }
|
||||||
|
public string? FormulaName { get; set; }
|
||||||
|
public string DisplayText => string.IsNullOrWhiteSpace(OrderNo)
|
||||||
|
? FormulaName ?? string.Empty
|
||||||
|
: $"{OrderNo} | {FormulaName}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class QuickTestInspectCellViewModel : BindableBase
|
||||||
|
{
|
||||||
|
public string? DataPointId { get; set; }
|
||||||
|
public string PointName { get; set; } = string.Empty;
|
||||||
|
public decimal? LowerLimit { get; set; }
|
||||||
|
public decimal? UpperLimit { get; set; }
|
||||||
|
|
||||||
|
private decimal? _value;
|
||||||
|
public decimal? Value
|
||||||
|
{
|
||||||
|
get => _value;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (SetProperty(ref _value, value))
|
||||||
|
ValueChanged?.Invoke(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public event Action<QuickTestInspectCellViewModel>? ValueChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class QuickTestInspectRowViewModel : BindableBase
|
||||||
|
{
|
||||||
|
public string RowNo { get; set; } = string.Empty;
|
||||||
|
public ObservableCollection<QuickTestInspectCellViewModel> Cells { get; } = new();
|
||||||
|
|
||||||
|
private string _inspectResultText = string.Empty;
|
||||||
|
public string InspectResultText
|
||||||
|
{
|
||||||
|
get => _inspectResultText;
|
||||||
|
set => SetProperty(ref _inspectResultText, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string InspectResultCode { get; private set; } = "0";
|
||||||
|
|
||||||
|
public void RecalculateResult()
|
||||||
|
{
|
||||||
|
if (Cells.Count == 0)
|
||||||
|
{
|
||||||
|
InspectResultCode = "0";
|
||||||
|
InspectResultText = string.Empty;
|
||||||
|
RaisePropertyChanged(nameof(InspectResultText));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Cells.Any(c => c.Value == null))
|
||||||
|
{
|
||||||
|
InspectResultCode = "0";
|
||||||
|
InspectResultText = "待填写";
|
||||||
|
RaisePropertyChanged(nameof(InspectResultText));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pass = Cells.All(c =>
|
||||||
|
{
|
||||||
|
if (c.LowerLimit != null && c.Value < c.LowerLimit) return false;
|
||||||
|
if (c.UpperLimit != null && c.Value > c.UpperLimit) return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
InspectResultCode = pass ? "1" : "0";
|
||||||
|
InspectResultText = pass ? "合格" : "不合格";
|
||||||
|
RaisePropertyChanged(nameof(InspectResultText));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>胶料快检记录操作台 ViewModel</summary>
|
||||||
|
public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||||
|
{
|
||||||
|
private readonly IRubberQuickTestOperationService _operationService;
|
||||||
|
private readonly Random _rnd = new();
|
||||||
|
private List<MesXslMixingProductionPlan> _allPlans = new();
|
||||||
|
private List<MixingPlanShiftOption> _allShiftOptions = new();
|
||||||
|
private MesXslRubberQuickTestStd? _currentStd;
|
||||||
|
private const int ChartPointCount = 5;
|
||||||
|
|
||||||
|
public event Action? InspectColumnsChanged;
|
||||||
|
|
||||||
|
public RubberQuickTestOperationViewModel(
|
||||||
|
IRubberQuickTestOperationService operationService,
|
||||||
|
IContainerExtension container,
|
||||||
|
IRegionManager regionManager) : base(container, regionManager)
|
||||||
|
{
|
||||||
|
_operationService = operationService;
|
||||||
|
|
||||||
|
_inspectTimesText = "1";
|
||||||
|
|
||||||
|
AddInspectRowCommand = new DelegateCommand(AddInspectRow, () => DataPointColumns.Count > 0);
|
||||||
|
RemoveInspectRowCommand = new DelegateCommand(() => RemoveInspectRow(SelectedInspectRow), () => SelectedInspectRow != null);
|
||||||
|
SaveCommand = new DelegateCommand(async () => await SaveAsync(), () => InspectRows.Count > 0);
|
||||||
|
RefreshPlansCommand = new DelegateCommand(async () => await LoadPlansAsync());
|
||||||
|
RefreshChartDemoCommand = new DelegateCommand(FillRandomChartData);
|
||||||
|
|
||||||
|
TemperatureSeries = new ObservableCollection<ISeries>
|
||||||
|
{
|
||||||
|
new LineSeries<double> { Name = "上模温度", Values = UpperTempValues, GeometrySize = 4, LineSmoothness = 0.3 },
|
||||||
|
new LineSeries<double> { Name = "下模温度", Values = LowerTempValues, GeometrySize = 4, LineSmoothness = 0.3 }
|
||||||
|
};
|
||||||
|
TorqueSeries = new ObservableCollection<ISeries>
|
||||||
|
{
|
||||||
|
new LineSeries<double> { Name = "S'(dNm)", Values = TorqueValues, GeometrySize = 4, LineSmoothness = 0.3 }
|
||||||
|
};
|
||||||
|
|
||||||
|
FillRandomChartData();
|
||||||
|
_ = LoadPlansAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>中间库未接入时的曲线演示说明</summary>
|
||||||
|
public string ChartDemoHint => "演示数据(中间库未接入,打开页面自动生成;接入后将显示实测曲线)";
|
||||||
|
|
||||||
|
public ObservableCollection<ISeries> TemperatureSeries { get; }
|
||||||
|
public ObservableCollection<ISeries> TorqueSeries { get; }
|
||||||
|
public ObservableCollection<double> UpperTempValues { get; } = new();
|
||||||
|
public ObservableCollection<double> LowerTempValues { get; } = new();
|
||||||
|
public ObservableCollection<double> TorqueValues { get; } = new();
|
||||||
|
|
||||||
|
public Axis[] TemperatureXAxes { get; } = BuildTimeAxis();
|
||||||
|
public Axis[] TemperatureYAxes { get; } = BuildTempYAxis();
|
||||||
|
public Axis[] TorqueXAxes { get; } = BuildTimeAxis();
|
||||||
|
public Axis[] TorqueYAxes { get; } = BuildTorqueYAxis();
|
||||||
|
|
||||||
|
public ObservableCollection<string> MachineOptions { get; } = new();
|
||||||
|
public ObservableCollection<WorkShiftOption> ShiftOptions { get; } = new();
|
||||||
|
public ObservableCollection<MixingPlanShiftOption> PlanOptions { get; } = new();
|
||||||
|
public ObservableCollection<MesXslRubberQuickTestStdLine> DataPointColumns { get; } = new();
|
||||||
|
public ObservableCollection<QuickTestInspectRowViewModel> InspectRows { get; } = new();
|
||||||
|
|
||||||
|
private QuickTestInspectRowViewModel? _selectedInspectRow;
|
||||||
|
public QuickTestInspectRowViewModel? SelectedInspectRow
|
||||||
|
{
|
||||||
|
get => _selectedInspectRow;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (SetProperty(ref _selectedInspectRow, value))
|
||||||
|
RemoveInspectRowCommand.RaiseCanExecuteChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DateTime _mixingDate = DateTime.Today;
|
||||||
|
public DateTime MixingDate
|
||||||
|
{
|
||||||
|
get => _mixingDate;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (!SetProperty(ref _mixingDate, value)) return;
|
||||||
|
RefreshMachineOptions();
|
||||||
|
ClearPlanSelection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? _selectedMachine;
|
||||||
|
public string? SelectedMachine
|
||||||
|
{
|
||||||
|
get => _selectedMachine;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (!SetProperty(ref _selectedMachine, value)) return;
|
||||||
|
RefreshShiftOptions();
|
||||||
|
ClearPlanSelection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private WorkShiftOption? _selectedShift;
|
||||||
|
public WorkShiftOption? SelectedShift
|
||||||
|
{
|
||||||
|
get => _selectedShift;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (!SetProperty(ref _selectedShift, value)) return;
|
||||||
|
RefreshPlanOptions();
|
||||||
|
ClearPlanSelection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MixingPlanShiftOption? _selectedPlan;
|
||||||
|
public MixingPlanShiftOption? SelectedPlan
|
||||||
|
{
|
||||||
|
get => _selectedPlan;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (!SetProperty(ref _selectedPlan, value)) return;
|
||||||
|
ApplySelectedPlan();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string? ProductionOrderNo => _selectedPlan?.OrderNo;
|
||||||
|
public string? MachineName => _selectedPlan?.MachineName ?? SelectedMachine;
|
||||||
|
public string? WorkShiftDisplay => SelectedShift?.Name ?? string.Empty;
|
||||||
|
public string? RubberMaterialName => _selectedPlan?.FormulaName;
|
||||||
|
|
||||||
|
private string? _trainNo;
|
||||||
|
public string? TrainNo
|
||||||
|
{
|
||||||
|
get => _trainNo;
|
||||||
|
set => SetProperty(ref _trainNo, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? _inspectTimesText;
|
||||||
|
/// <summary>试验次数(手填正整数)</summary>
|
||||||
|
public string? InspectTimesText
|
||||||
|
{
|
||||||
|
get => _inspectTimesText;
|
||||||
|
set => SetProperty(ref _inspectTimesText, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double _upperMoldTemp;
|
||||||
|
public double UpperMoldTemp
|
||||||
|
{
|
||||||
|
get => _upperMoldTemp;
|
||||||
|
set => SetProperty(ref _upperMoldTemp, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double _lowerMoldTemp;
|
||||||
|
public double LowerMoldTemp
|
||||||
|
{
|
||||||
|
get => _lowerMoldTemp;
|
||||||
|
set => SetProperty(ref _lowerMoldTemp, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double _torqueS;
|
||||||
|
public double TorqueS
|
||||||
|
{
|
||||||
|
get => _torqueS;
|
||||||
|
set => SetProperty(ref _torqueS, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DelegateCommand AddInspectRowCommand { get; }
|
||||||
|
public DelegateCommand RemoveInspectRowCommand { get; }
|
||||||
|
public DelegateCommand SaveCommand { get; }
|
||||||
|
public DelegateCommand RefreshPlansCommand { get; }
|
||||||
|
public DelegateCommand RefreshChartDemoCommand { get; }
|
||||||
|
|
||||||
|
private async Task LoadPlansAsync()
|
||||||
|
{
|
||||||
|
IsLoading = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_allPlans = await _operationService.GetMixingProductionPlansAsync();
|
||||||
|
BuildAllShiftOptions();
|
||||||
|
RefreshMachineOptions();
|
||||||
|
Growl.Success("密炼生产计划已刷新");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Growl.Error($"加载密炼生产计划失败:{ex.Message}");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IsLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BuildAllShiftOptions()
|
||||||
|
{
|
||||||
|
_allShiftOptions.Clear();
|
||||||
|
foreach (var row in _allPlans)
|
||||||
|
{
|
||||||
|
AddShiftOption(row, "morning", "1", "早班", row.MorningPlanId, row.MorningOrderDate, row.MorningOrderNo, row.MorningFormulaName);
|
||||||
|
AddShiftOption(row, "noon", "2", "中班", row.NoonPlanId, row.NoonOrderDate, row.NoonOrderNo, row.NoonFormulaName);
|
||||||
|
AddShiftOption(row, "night", "3", "晚班", row.NightPlanId, row.NightOrderDate, row.NightOrderNo, row.NightFormulaName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddShiftOption(
|
||||||
|
MesXslMixingProductionPlan row, string shiftKey, string shiftCode, string shiftName,
|
||||||
|
string? planId, DateTime? orderDate, string? orderNo, string? formulaName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(planId) || string.IsNullOrWhiteSpace(orderNo)) return;
|
||||||
|
_allShiftOptions.Add(new MixingPlanShiftOption
|
||||||
|
{
|
||||||
|
PlanRowId = row.Id ?? string.Empty,
|
||||||
|
MachineId = row.MachineId,
|
||||||
|
MachineName = row.MachineName,
|
||||||
|
ShiftKey = shiftKey,
|
||||||
|
ShiftCode = shiftCode,
|
||||||
|
ShiftName = shiftName,
|
||||||
|
OrderDate = orderDate,
|
||||||
|
PlanId = planId,
|
||||||
|
OrderNo = orderNo,
|
||||||
|
FormulaName = formulaName
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<MixingPlanShiftOption> FilteredByDate =>
|
||||||
|
_allShiftOptions.Where(o => o.OrderDate?.Date == MixingDate.Date);
|
||||||
|
|
||||||
|
private void RefreshMachineOptions()
|
||||||
|
{
|
||||||
|
MachineOptions.Clear();
|
||||||
|
foreach (var name in FilteredByDate.Select(o => o.MachineName).Where(n => !string.IsNullOrWhiteSpace(n)).Distinct().OrderBy(n => n))
|
||||||
|
MachineOptions.Add(name!);
|
||||||
|
if (SelectedMachine != null && !MachineOptions.Contains(SelectedMachine))
|
||||||
|
SelectedMachine = null;
|
||||||
|
if (SelectedMachine == null && MachineOptions.Count > 0)
|
||||||
|
SelectedMachine = MachineOptions[0];
|
||||||
|
else
|
||||||
|
RefreshShiftOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshShiftOptions()
|
||||||
|
{
|
||||||
|
ShiftOptions.Clear();
|
||||||
|
var machine = SelectedMachine;
|
||||||
|
var shifts = FilteredByDate
|
||||||
|
.Where(o => string.IsNullOrWhiteSpace(machine) || o.MachineName == machine)
|
||||||
|
.GroupBy(o => o.ShiftCode)
|
||||||
|
.Select(g => g.First())
|
||||||
|
.OrderBy(o => o.ShiftCode);
|
||||||
|
foreach (var s in shifts)
|
||||||
|
ShiftOptions.Add(new WorkShiftOption(s.ShiftCode, s.ShiftName));
|
||||||
|
if (SelectedShift != null && !ShiftOptions.Any(x => x.Code == SelectedShift.Code))
|
||||||
|
SelectedShift = null;
|
||||||
|
if (SelectedShift == null && ShiftOptions.Count > 0)
|
||||||
|
SelectedShift = ShiftOptions[0];
|
||||||
|
else
|
||||||
|
RefreshPlanOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshPlanOptions()
|
||||||
|
{
|
||||||
|
PlanOptions.Clear();
|
||||||
|
var machine = SelectedMachine;
|
||||||
|
var shiftCode = SelectedShift?.Code;
|
||||||
|
foreach (var o in FilteredByDate
|
||||||
|
.Where(x => string.IsNullOrWhiteSpace(machine) || x.MachineName == machine)
|
||||||
|
.Where(x => string.IsNullOrWhiteSpace(shiftCode) || x.ShiftCode == shiftCode)
|
||||||
|
.OrderBy(x => x.OrderNo))
|
||||||
|
PlanOptions.Add(o);
|
||||||
|
if (SelectedPlan != null && PlanOptions.All(p => p.PlanId != SelectedPlan.PlanId))
|
||||||
|
SelectedPlan = null;
|
||||||
|
if (SelectedPlan == null && PlanOptions.Count > 0)
|
||||||
|
SelectedPlan = PlanOptions[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearPlanSelection()
|
||||||
|
{
|
||||||
|
_selectedPlan = null;
|
||||||
|
RaisePropertyChanged(nameof(SelectedPlan));
|
||||||
|
RaisePropertyChanged(nameof(ProductionOrderNo));
|
||||||
|
RaisePropertyChanged(nameof(MachineName));
|
||||||
|
RaisePropertyChanged(nameof(WorkShiftDisplay));
|
||||||
|
RaisePropertyChanged(nameof(RubberMaterialName));
|
||||||
|
ClearStdAndResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplySelectedPlan()
|
||||||
|
{
|
||||||
|
RaisePropertyChanged(nameof(ProductionOrderNo));
|
||||||
|
RaisePropertyChanged(nameof(MachineName));
|
||||||
|
RaisePropertyChanged(nameof(WorkShiftDisplay));
|
||||||
|
RaisePropertyChanged(nameof(RubberMaterialName));
|
||||||
|
_ = LoadStdAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadStdAsync()
|
||||||
|
{
|
||||||
|
DataPointColumns.Clear();
|
||||||
|
InspectRows.Clear();
|
||||||
|
_currentStd = null;
|
||||||
|
InspectColumnsChanged?.Invoke();
|
||||||
|
|
||||||
|
var rubberName = RubberMaterialName;
|
||||||
|
if (string.IsNullOrWhiteSpace(rubberName)) return;
|
||||||
|
|
||||||
|
IsLoading = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_currentStd = await _operationService.GetStdByRubberMaterialNameAsync(rubberName);
|
||||||
|
if (_currentStd?.LineList == null || _currentStd.LineList.Count == 0)
|
||||||
|
{
|
||||||
|
Growl.Warning($"未找到胶料「{rubberName}」的使用中且已批准的快检实验标准");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
foreach (var line in _currentStd.LineList.OrderBy(l => l.SortNo ?? 0))
|
||||||
|
DataPointColumns.Add(line);
|
||||||
|
InspectColumnsChanged?.Invoke();
|
||||||
|
AddInspectRow();
|
||||||
|
AddInspectRowCommand.RaiseCanExecuteChanged();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Growl.Error($"加载实验标准失败:{ex.Message}");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IsLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearStdAndResults()
|
||||||
|
{
|
||||||
|
DataPointColumns.Clear();
|
||||||
|
InspectRows.Clear();
|
||||||
|
_currentStd = null;
|
||||||
|
InspectColumnsChanged?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>打开页面或中间库无数据时填充曲线演示数据(5 点对应 0~2min)</summary>
|
||||||
|
private void FillRandomChartData()
|
||||||
|
{
|
||||||
|
UpperTempValues.Clear();
|
||||||
|
LowerTempValues.Clear();
|
||||||
|
TorqueValues.Clear();
|
||||||
|
|
||||||
|
for (int i = 0; i < ChartPointCount; i++)
|
||||||
|
{
|
||||||
|
var upper = 192 + _rnd.NextDouble() * 8;
|
||||||
|
var lower = upper - 2 - _rnd.NextDouble() * 2;
|
||||||
|
var torque = Math.Min(14, i * 2.5 + _rnd.NextDouble() * 2.5);
|
||||||
|
UpperTempValues.Add(Math.Round(upper, 2));
|
||||||
|
LowerTempValues.Add(Math.Round(lower, 2));
|
||||||
|
TorqueValues.Add(Math.Round(torque, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
UpperMoldTemp = UpperTempValues[^1];
|
||||||
|
LowerMoldTemp = LowerTempValues[^1];
|
||||||
|
TorqueS = TorqueValues[^1];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddInspectRow()
|
||||||
|
{
|
||||||
|
var rowIndex = InspectRows.Count + 1;
|
||||||
|
var row = new QuickTestInspectRowViewModel { RowNo = $"{rowIndex}_1" };
|
||||||
|
foreach (var col in DataPointColumns)
|
||||||
|
{
|
||||||
|
var cell = new QuickTestInspectCellViewModel
|
||||||
|
{
|
||||||
|
DataPointId = col.DataPointId,
|
||||||
|
PointName = col.PointName ?? string.Empty,
|
||||||
|
LowerLimit = col.LowerLimit,
|
||||||
|
UpperLimit = col.UpperLimit
|
||||||
|
};
|
||||||
|
cell.ValueChanged += _ => row.RecalculateResult();
|
||||||
|
row.Cells.Add(cell);
|
||||||
|
}
|
||||||
|
row.RecalculateResult();
|
||||||
|
InspectRows.Add(row);
|
||||||
|
SaveCommand.RaiseCanExecuteChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveInspectRow(QuickTestInspectRowViewModel? row)
|
||||||
|
{
|
||||||
|
if (row == null) return;
|
||||||
|
InspectRows.Remove(row);
|
||||||
|
SelectedInspectRow = null;
|
||||||
|
SaveCommand.RaiseCanExecuteChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SaveAsync()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(TrainNo))
|
||||||
|
{
|
||||||
|
Growl.Warning("请填写车次");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (string.IsNullOrWhiteSpace(ProductionOrderNo))
|
||||||
|
{
|
||||||
|
Growl.Warning("请选择密炼计划以带出生产订单号");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (string.IsNullOrWhiteSpace(RubberMaterialName))
|
||||||
|
{
|
||||||
|
Growl.Warning("请先选择密炼计划以带出胶料名称");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_currentStd == null)
|
||||||
|
{
|
||||||
|
Growl.Warning("未加载实验标准,无法保存");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InspectRows.Any(r => r.InspectResultText == "待填写" || string.IsNullOrWhiteSpace(r.InspectResultText)))
|
||||||
|
{
|
||||||
|
Growl.Warning("请手填全部检验行的检测值后再保存");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TryParseInspectTimes(out var inspectTimes, out var inspectTimesError))
|
||||||
|
{
|
||||||
|
Growl.Warning(inspectTimesError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lineList = BuildAveragedLineList();
|
||||||
|
if (lineList.Count == 0)
|
||||||
|
{
|
||||||
|
Growl.Warning("无法根据试验结果计算明细数据");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var rawLineList = BuildRawLineList();
|
||||||
|
if (rawLineList.Count == 0)
|
||||||
|
{
|
||||||
|
Growl.Warning("无法生成试验结果原始数据");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = AppSession.CurrentUser;
|
||||||
|
IsLoading = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var record = BuildSaveRecord(lineList, rawLineList, inspectTimes, user);
|
||||||
|
await _operationService.SaveRecordAsync(record);
|
||||||
|
Growl.Success("快检记录已保存到 MES");
|
||||||
|
InspectRows.Clear();
|
||||||
|
SaveCommand.RaiseCanExecuteChanged();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Growl.Error($"保存失败:{ex.Message}");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IsLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryParseInspectTimes(out int value, out string error)
|
||||||
|
{
|
||||||
|
error = string.Empty;
|
||||||
|
var text = string.IsNullOrWhiteSpace(InspectTimesText) ? "1" : InspectTimesText.Trim();
|
||||||
|
if (!int.TryParse(text, out var n) || n <= 0)
|
||||||
|
{
|
||||||
|
error = "试验次数须填写正整数";
|
||||||
|
value = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = n;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>试验结果各数据点检测值取平均,写入快检记录明细</summary>
|
||||||
|
private List<MesXslRubberQuickTestRecordLine> BuildAveragedLineList()
|
||||||
|
{
|
||||||
|
var lines = new List<MesXslRubberQuickTestRecordLine>();
|
||||||
|
for (int i = 0; i < DataPointColumns.Count; i++)
|
||||||
|
{
|
||||||
|
var col = DataPointColumns[i];
|
||||||
|
var values = InspectRows
|
||||||
|
.Where(r => i < r.Cells.Count && r.Cells[i].Value != null)
|
||||||
|
.Select(r => r.Cells[i].Value!.Value)
|
||||||
|
.ToList();
|
||||||
|
if (values.Count == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var avg = values.Average(v => (double)v);
|
||||||
|
var avgDecimal = Math.Round((decimal)avg, 6);
|
||||||
|
|
||||||
|
var line = new MesXslRubberQuickTestRecordLine { SortNo = i };
|
||||||
|
if (!string.IsNullOrWhiteSpace(col.DataPointId))
|
||||||
|
line.DataPointId = col.DataPointId;
|
||||||
|
if (!string.IsNullOrWhiteSpace(col.PointName))
|
||||||
|
line.InspectItem = col.PointName;
|
||||||
|
if (col.LowerLimit != null)
|
||||||
|
line.LowerLimit = col.LowerLimit;
|
||||||
|
if (col.UpperLimit != null)
|
||||||
|
line.UpperLimit = col.UpperLimit;
|
||||||
|
line.InspectValue = avgDecimal;
|
||||||
|
lines.Add(line);
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>试验结果全部检测值写入原始数据明细</summary>
|
||||||
|
private List<MesXslRubberQuickTestRecordRawLine> BuildRawLineList()
|
||||||
|
{
|
||||||
|
var rawLines = new List<MesXslRubberQuickTestRecordRawLine>();
|
||||||
|
int sort = 0;
|
||||||
|
foreach (var row in InspectRows)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < row.Cells.Count; i++)
|
||||||
|
{
|
||||||
|
var cell = row.Cells[i];
|
||||||
|
if (cell.Value == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var raw = new MesXslRubberQuickTestRecordRawLine { SortNo = sort++ };
|
||||||
|
if (!string.IsNullOrWhiteSpace(row.RowNo))
|
||||||
|
raw.RowNo = row.RowNo;
|
||||||
|
if (!string.IsNullOrWhiteSpace(cell.DataPointId))
|
||||||
|
raw.DataPointId = cell.DataPointId;
|
||||||
|
if (!string.IsNullOrWhiteSpace(cell.PointName))
|
||||||
|
raw.InspectItem = cell.PointName;
|
||||||
|
if (cell.LowerLimit != null)
|
||||||
|
raw.LowerLimit = cell.LowerLimit;
|
||||||
|
if (cell.UpperLimit != null)
|
||||||
|
raw.UpperLimit = cell.UpperLimit;
|
||||||
|
raw.InspectValue = cell.Value;
|
||||||
|
raw.RowInspectResult = row.InspectResultCode;
|
||||||
|
rawLines.Add(raw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rawLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>主表检验结果:任一行不合格则不合格</summary>
|
||||||
|
private static string JudgeInspectResultFromRows(IEnumerable<QuickTestInspectRowViewModel> rows)
|
||||||
|
{
|
||||||
|
if (!rows.Any())
|
||||||
|
return "0";
|
||||||
|
return rows.Any(r => r.InspectResultCode != "1") ? "0" : "1";
|
||||||
|
}
|
||||||
|
|
||||||
|
private MesXslRubberQuickTestRecord BuildSaveRecord(
|
||||||
|
List<MesXslRubberQuickTestRecordLine> lineList,
|
||||||
|
List<MesXslRubberQuickTestRecordRawLine> rawLineList,
|
||||||
|
int inspectTimes,
|
||||||
|
SysUser? user)
|
||||||
|
{
|
||||||
|
var record = new MesXslRubberQuickTestRecord
|
||||||
|
{
|
||||||
|
LineList = lineList,
|
||||||
|
RawLineList = rawLineList,
|
||||||
|
InspectTime = DateTime.Now,
|
||||||
|
InspectResult = JudgeInspectResultFromRows(InspectRows)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(_currentStd?.RubberMaterialId))
|
||||||
|
record.RubberMaterialId = _currentStd.RubberMaterialId;
|
||||||
|
if (!string.IsNullOrWhiteSpace(RubberMaterialName))
|
||||||
|
record.RubberMaterialName = RubberMaterialName;
|
||||||
|
if (!string.IsNullOrWhiteSpace(_currentStd?.Id))
|
||||||
|
record.StdId = _currentStd.Id;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(_selectedPlan?.MachineId))
|
||||||
|
record.ProdEquipmentLedgerId = _selectedPlan.MachineId;
|
||||||
|
if (!string.IsNullOrWhiteSpace(MachineName))
|
||||||
|
record.ProdEquipmentName = MachineName;
|
||||||
|
|
||||||
|
record.ProductionDate = MixingDate;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(TrainNo))
|
||||||
|
record.TrainNo = TrainNo.Trim();
|
||||||
|
|
||||||
|
if (SelectedShift != null && !string.IsNullOrWhiteSpace(SelectedShift.Code))
|
||||||
|
record.WorkShift = SelectedShift.Code;
|
||||||
|
|
||||||
|
record.InspectTimes = inspectTimes;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(ProductionOrderNo))
|
||||||
|
record.ProductionPlanNo = ProductionOrderNo;
|
||||||
|
|
||||||
|
var inspectorId = user?.JeecgBizUserId ?? (user != null ? user.Id.ToString() : null);
|
||||||
|
if (!string.IsNullOrWhiteSpace(inspectorId))
|
||||||
|
record.InspectorUserId = inspectorId;
|
||||||
|
if (!string.IsNullOrWhiteSpace(user?.Account))
|
||||||
|
record.InspectorUsername = user.Account;
|
||||||
|
if (!string.IsNullOrWhiteSpace(user?.RealName))
|
||||||
|
record.InspectorRealname = user.RealName;
|
||||||
|
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Axis[] BuildTimeAxis() => new[]
|
||||||
|
{
|
||||||
|
new Axis
|
||||||
|
{
|
||||||
|
Name = "时间(min)",
|
||||||
|
MinLimit = 0,
|
||||||
|
MaxLimit = 2,
|
||||||
|
Labels = new[] { "0", "0.5", "1", "1.5", "2" },
|
||||||
|
LabelsPaint = new SolidColorPaint(SKColors.Gray),
|
||||||
|
NamePaint = new SolidColorPaint(SKColors.Gray)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static Axis[] BuildTempYAxis() => new[]
|
||||||
|
{
|
||||||
|
new Axis
|
||||||
|
{
|
||||||
|
Name = "温度(℃)",
|
||||||
|
MinLimit = 189,
|
||||||
|
MaxLimit = 201,
|
||||||
|
Labeler = v => v switch
|
||||||
|
{
|
||||||
|
189 => "189",
|
||||||
|
192 => "192",
|
||||||
|
195 => "195",
|
||||||
|
198 => "198",
|
||||||
|
201 => "201",
|
||||||
|
_ => string.Empty
|
||||||
|
},
|
||||||
|
LabelsPaint = new SolidColorPaint(SKColors.Gray),
|
||||||
|
NamePaint = new SolidColorPaint(SKColors.Gray)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static Axis[] BuildTorqueYAxis() => new[]
|
||||||
|
{
|
||||||
|
new Axis
|
||||||
|
{
|
||||||
|
Name = "S'(dNm)",
|
||||||
|
MinLimit = 0,
|
||||||
|
MaxLimit = 14,
|
||||||
|
Labeler = v => v switch
|
||||||
|
{
|
||||||
|
0 => "0",
|
||||||
|
3 => "3",
|
||||||
|
6 => "6",
|
||||||
|
8 => "8",
|
||||||
|
11 => "11",
|
||||||
|
14 => "14",
|
||||||
|
_ => string.Empty
|
||||||
|
},
|
||||||
|
LabelsPaint = new SolidColorPaint(SKColors.Gray),
|
||||||
|
NamePaint = new SolidColorPaint(SKColors.Gray)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public new void Destroy() => base.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WorkShiftOption
|
||||||
|
{
|
||||||
|
public WorkShiftOption(string code, string name)
|
||||||
|
{
|
||||||
|
Code = code;
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Code { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
using HandyControl.Tools.Extension;
|
||||||
|
using Prism.Commands;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using YY.Admin.Core.Entity;
|
||||||
|
using YY.Admin.ViewModels;
|
||||||
|
|
||||||
|
namespace YY.Admin.ViewModels.RubberQuickTestStd;
|
||||||
|
|
||||||
|
public class RubberQuickTestStdDetailDialogViewModel : BaseViewModel, IDialogResultable<bool>
|
||||||
|
{
|
||||||
|
private MesXslRubberQuickTestStd? _std;
|
||||||
|
public MesXslRubberQuickTestStd? Std
|
||||||
|
{
|
||||||
|
get => _std;
|
||||||
|
private set => SetProperty(ref _std, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableCollection<MesXslRubberQuickTestStdLine> Lines { get; } = new();
|
||||||
|
|
||||||
|
private bool _result;
|
||||||
|
public bool Result { get => _result; set => SetProperty(ref _result, value); }
|
||||||
|
public Action? CloseAction { get; set; }
|
||||||
|
|
||||||
|
public RubberQuickTestStdDetailDialogViewModel(
|
||||||
|
IContainerExtension container,
|
||||||
|
IRegionManager regionManager) : base(container, regionManager)
|
||||||
|
{
|
||||||
|
CloseCommand = new DelegateCommand(() => CloseAction?.Invoke());
|
||||||
|
}
|
||||||
|
|
||||||
|
public DelegateCommand CloseCommand { get; }
|
||||||
|
|
||||||
|
public void Initialize(MesXslRubberQuickTestStd std)
|
||||||
|
{
|
||||||
|
Std = std;
|
||||||
|
Lines.Clear();
|
||||||
|
foreach (var line in std.LineList ?? [])
|
||||||
|
Lines.Add(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
using HandyControl.Controls;
|
||||||
|
using HandyControl.Tools.Extension;
|
||||||
|
using Prism.Events;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using YY.Admin.Core;
|
||||||
|
using YY.Admin.Core.Entity;
|
||||||
|
using YY.Admin.Core.Events;
|
||||||
|
using YY.Admin.Core.Helper;
|
||||||
|
using YY.Admin.Core.Services;
|
||||||
|
using YY.Admin.Services.Service;
|
||||||
|
using YY.Admin.Views.RubberQuickTestStd;
|
||||||
|
|
||||||
|
namespace YY.Admin.ViewModels.RubberQuickTestStd;
|
||||||
|
|
||||||
|
public class RubberQuickTestStdListViewModel : BaseViewModel
|
||||||
|
{
|
||||||
|
private readonly IRubberQuickTestStdService _stdService;
|
||||||
|
private readonly IJeecgDictSyncService _dictSyncService;
|
||||||
|
private SubscriptionToken? _changedToken;
|
||||||
|
|
||||||
|
private ObservableCollection<MesXslRubberQuickTestStd> _items = new();
|
||||||
|
public ObservableCollection<MesXslRubberQuickTestStd> 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? _filterStdName;
|
||||||
|
public string? FilterStdName { get => _filterStdName; set => SetProperty(ref _filterStdName, value); }
|
||||||
|
|
||||||
|
private string? _filterRubberMaterialName;
|
||||||
|
public string? FilterRubberMaterialName { get => _filterRubberMaterialName; set => SetProperty(ref _filterRubberMaterialName, value); }
|
||||||
|
|
||||||
|
private string? _filterEnableStatus;
|
||||||
|
public string? FilterEnableStatus { get => _filterEnableStatus; set => SetProperty(ref _filterEnableStatus, value); }
|
||||||
|
|
||||||
|
public ObservableCollection<KeyValuePair<string, string>> EnableStatusOptions { get; } = new();
|
||||||
|
|
||||||
|
public DelegateCommand SearchCommand { get; }
|
||||||
|
public DelegateCommand ResetCommand { get; }
|
||||||
|
public DelegateCommand<MesXslRubberQuickTestStd> ViewDetailCommand { get; }
|
||||||
|
public DelegateCommand PrevPageCommand { get; }
|
||||||
|
public DelegateCommand NextPageCommand { get; }
|
||||||
|
|
||||||
|
public RubberQuickTestStdListViewModel(
|
||||||
|
IRubberQuickTestStdService stdService,
|
||||||
|
IJeecgDictSyncService dictSyncService,
|
||||||
|
IContainerExtension container,
|
||||||
|
IRegionManager regionManager) : base(container, regionManager)
|
||||||
|
{
|
||||||
|
_stdService = stdService;
|
||||||
|
_dictSyncService = dictSyncService;
|
||||||
|
|
||||||
|
SearchCommand = new DelegateCommand(async () => { PageNo = 1; await LoadAsync(); });
|
||||||
|
ResetCommand = new DelegateCommand(async () =>
|
||||||
|
{
|
||||||
|
FilterStdName = null;
|
||||||
|
FilterRubberMaterialName = null;
|
||||||
|
FilterEnableStatus = null;
|
||||||
|
PageNo = 1;
|
||||||
|
await LoadAsync();
|
||||||
|
});
|
||||||
|
ViewDetailCommand = new DelegateCommand<MesXslRubberQuickTestStd>(async x => await ShowDetailAsync(x));
|
||||||
|
PrevPageCommand = new DelegateCommand(async () => { if (PageNo > 1) { PageNo--; await LoadAsync(); } });
|
||||||
|
NextPageCommand = new DelegateCommand(async () => { if ((long)PageNo * PageSize < Total) { PageNo++; await LoadAsync(); } });
|
||||||
|
|
||||||
|
_changedToken = _eventAggregator.GetEvent<RubberQuickTestStdChangedEvent>()
|
||||||
|
.Subscribe(async _ => await LoadAsync(), ThreadOption.UIThread);
|
||||||
|
|
||||||
|
_ = InitializeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task InitializeAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await LoadDictOptionsAsync();
|
||||||
|
await UIHelper.WaitForRenderAsync();
|
||||||
|
await LoadAsync();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"快检实验标准列表初始化失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadDictOptionsAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var opts = await _dictSyncService.GetDictOptionsAsync("xslmes_rubber_quick_test_std_enable_status", includeAll: true);
|
||||||
|
EnableStatusOptions.Clear();
|
||||||
|
foreach (var item in opts) EnableStatusOptions.Add(item);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
EnableStatusOptions.Clear();
|
||||||
|
EnableStatusOptions.Add(new KeyValuePair<string, string>("全部", ""));
|
||||||
|
EnableStatusOptions.Add(new KeyValuePair<string, string>("使用中", "1"));
|
||||||
|
EnableStatusOptions.Add(new KeyValuePair<string, string>("已停用", "0"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task LoadAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IsLoading = true;
|
||||||
|
var result = await _stdService.PageAsync(
|
||||||
|
PageNo, PageSize, FilterStdName, FilterRubberMaterialName, FilterEnableStatus);
|
||||||
|
Items = new ObservableCollection<MesXslRubberQuickTestStd>(result.Records);
|
||||||
|
Total = result.Total;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Growl.Error($"加载快检实验标准失败:{ex.Message}");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IsLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ShowDetailAsync(MesXslRubberQuickTestStd? row)
|
||||||
|
{
|
||||||
|
if (row?.Id == null) return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var detail = await _stdService.GetByIdAsync(row.Id);
|
||||||
|
if (detail == null)
|
||||||
|
{
|
||||||
|
Growl.Warning("未找到该实验标准,可能已被删除");
|
||||||
|
await LoadAsync();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await HandyControl.Controls.Dialog.Show<RubberQuickTestStdDetailDialogView>()
|
||||||
|
.Initialize<RubberQuickTestStdDetailDialogViewModel>(vm => vm.Initialize(detail))
|
||||||
|
.GetResultAsync<bool>();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Growl.Error($"打开详情失败:{ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void CleanUp()
|
||||||
|
{
|
||||||
|
base.CleanUp();
|
||||||
|
if (_changedToken != null)
|
||||||
|
{
|
||||||
|
_eventAggregator.GetEvent<RubberQuickTestStdChangedEvent>().Unsubscribe(_changedToken);
|
||||||
|
_changedToken = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,301 @@
|
|||||||
|
<UserControl x:Class="YY.Admin.Views.RubberQuickTest.RubberQuickTestOperationView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||||
|
xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
|
||||||
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<UserControl.Resources>
|
||||||
|
<Style x:Key="SectionBorderStyle" TargetType="Border">
|
||||||
|
<Setter Property="CornerRadius" Value="8"/>
|
||||||
|
<Setter Property="Background" Value="{DynamicResource ThirdlyRegionBrush}"/>
|
||||||
|
<Setter Property="Padding" Value="12"/>
|
||||||
|
<Setter Property="Margin" Value="0,0,0,10"/>
|
||||||
|
</Style>
|
||||||
|
<Style x:Key="SectionTitleStyle" TargetType="TextBlock">
|
||||||
|
<Setter Property="FontSize" Value="14"/>
|
||||||
|
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||||
|
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}"/>
|
||||||
|
<Setter Property="Margin" Value="8,0,0,0"/>
|
||||||
|
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||||
|
</Style>
|
||||||
|
</UserControl.Resources>
|
||||||
|
|
||||||
|
<Grid Margin="12">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="64"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
<RowDefinition Height="56"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- 标题 -->
|
||||||
|
<Border Grid.Row="0" Background="{DynamicResource RegionBrush}"
|
||||||
|
BorderBrush="{DynamicResource BorderBrush}" BorderThickness="0,0,0,1" Margin="-12,0,-12,8">
|
||||||
|
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="20,0">
|
||||||
|
<Border Width="40" Height="40" CornerRadius="8" Background="{DynamicResource PrimaryBrush}" Margin="0,0,12,0">
|
||||||
|
<md:PackIcon Kind="Flask" Width="22" Height="22" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||||
|
</Border>
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock Text="快检记录" FontSize="18" FontWeight="Bold"/>
|
||||||
|
<TextBlock Text="密炼快检试验操作台" FontSize="12" Foreground="{DynamicResource SecondaryTextBrush}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<!-- 主体 2:1 -->
|
||||||
|
<Grid Grid.Row="1">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="2*"/>
|
||||||
|
<ColumnDefinition Width="12"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<!-- 左侧:曲线 + 试验结果 -->
|
||||||
|
<ScrollViewer Grid.Column="0" VerticalScrollBarVisibility="Auto">
|
||||||
|
<StackPanel>
|
||||||
|
<Border Style="{StaticResource SectionBorderStyle}">
|
||||||
|
<StackPanel>
|
||||||
|
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
|
||||||
|
<Border Width="4" Height="18" CornerRadius="2" Background="#1890ff"/>
|
||||||
|
<TextBlock Text="温度(℃)曲线" Style="{StaticResource SectionTitleStyle}"/>
|
||||||
|
<Button Content="刷新演示" Command="{Binding RefreshChartDemoCommand}" Style="{StaticResource ButtonDefault}" Height="28" Padding="10,0" Margin="12,0,0,0"/>
|
||||||
|
</StackPanel>
|
||||||
|
<TextBlock Text="{Binding ChartDemoHint}" FontSize="11" Foreground="{DynamicResource SecondaryTextBrush}" Margin="0,0,0,6"/>
|
||||||
|
<Border Height="220" CornerRadius="4">
|
||||||
|
<lvc:CartesianChart Series="{Binding TemperatureSeries}"
|
||||||
|
XAxes="{Binding TemperatureXAxes}"
|
||||||
|
YAxes="{Binding TemperatureYAxes}"
|
||||||
|
LegendPosition="Top"/>
|
||||||
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<Border Style="{StaticResource SectionBorderStyle}">
|
||||||
|
<StackPanel>
|
||||||
|
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
|
||||||
|
<Border Width="4" Height="18" CornerRadius="2" Background="#1890ff"/>
|
||||||
|
<TextBlock Text="S'(dNm)曲线" Style="{StaticResource SectionTitleStyle}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<Border Height="200" CornerRadius="4">
|
||||||
|
<lvc:CartesianChart Series="{Binding TorqueSeries}"
|
||||||
|
XAxes="{Binding TorqueXAxes}"
|
||||||
|
YAxes="{Binding TorqueYAxes}"
|
||||||
|
LegendPosition="Top"/>
|
||||||
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<Border Style="{StaticResource SectionBorderStyle}">
|
||||||
|
<StackPanel>
|
||||||
|
<Grid Margin="0,0,0,8">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Border Width="4" Height="18" CornerRadius="2" Background="#1890ff"/>
|
||||||
|
<TextBlock Text="试验结果" Style="{StaticResource SectionTitleStyle}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||||
|
<Button Content="新增检验行" Command="{Binding AddInspectRowCommand}" Style="{StaticResource ButtonPrimary}" Height="28" Padding="10,0" Margin="0,0,8,0"/>
|
||||||
|
<Button Content="删除选中行" Command="{Binding RemoveInspectRowCommand}" Style="{StaticResource ButtonDanger}" Height="28" Padding="10,0"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
<DataGrid x:Name="InspectResultGrid"
|
||||||
|
ItemsSource="{Binding InspectRows}"
|
||||||
|
AutoGenerateColumns="False"
|
||||||
|
CanUserAddRows="False"
|
||||||
|
CanUserDeleteRows="False"
|
||||||
|
HeadersVisibility="Column"
|
||||||
|
MinHeight="160"
|
||||||
|
SelectionMode="Single"
|
||||||
|
IsReadOnly="False"
|
||||||
|
SelectionChanged="InspectResultGrid_SelectionChanged">
|
||||||
|
</DataGrid>
|
||||||
|
<TextBlock Text="请手填各数据点检测值,系统将根据数据标准上下限自动判定合格/不合格" FontSize="11" Foreground="{DynamicResource SecondaryTextBrush}" Margin="0,6,0,0"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
</ScrollViewer>
|
||||||
|
|
||||||
|
<!-- 右侧 -->
|
||||||
|
<ScrollViewer Grid.Column="2" VerticalScrollBarVisibility="Auto">
|
||||||
|
<StackPanel>
|
||||||
|
<!-- 实时数据 -->
|
||||||
|
<Border Style="{StaticResource SectionBorderStyle}">
|
||||||
|
<StackPanel>
|
||||||
|
<StackPanel Orientation="Horizontal" Margin="0,0,0,12">
|
||||||
|
<Border Width="4" Height="18" CornerRadius="2" Background="#52c41a"/>
|
||||||
|
<TextBlock Text="实时数据" Style="{StaticResource SectionTitleStyle}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock Text="上模温度(℃)" Foreground="{DynamicResource SecondaryTextBrush}" Margin="0,0,0,4"/>
|
||||||
|
<TextBlock Grid.Row="1" Text="{Binding UpperMoldTemp, StringFormat={}{0:N2}}" FontSize="28" FontWeight="Bold" FontFamily="Consolas"/>
|
||||||
|
<TextBlock Grid.Column="1" Text="下模温度(℃)" Foreground="{DynamicResource SecondaryTextBrush}" Margin="0,0,0,4"/>
|
||||||
|
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding LowerMoldTemp, StringFormat={}{0:N2}}" FontSize="28" FontWeight="Bold" FontFamily="Consolas"/>
|
||||||
|
<TextBlock Grid.Row="2" Grid.Column="0" Text="S'(dNm)" Foreground="{DynamicResource SecondaryTextBrush}" Margin="0,12,0,4"/>
|
||||||
|
<TextBlock Grid.Row="2" Grid.Column="0" Margin="0,32,0,0" Text="{Binding TorqueS, StringFormat={}{0:N2}}" FontSize="28" FontWeight="Bold" FontFamily="Consolas"/>
|
||||||
|
</Grid>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<!-- 试验信息 -->
|
||||||
|
<Border Style="{StaticResource SectionBorderStyle}">
|
||||||
|
<StackPanel>
|
||||||
|
<Grid Margin="0,0,0,12">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Border Width="4" Height="18" CornerRadius="2" Background="#1890ff"/>
|
||||||
|
<TextBlock Text="试验信息" Style="{StaticResource SectionTitleStyle}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<Button Content="刷新计划" Command="{Binding RefreshPlansCommand}"
|
||||||
|
Style="{StaticResource ButtonDefault}" Height="26" Padding="8,0"
|
||||||
|
HorizontalAlignment="Right" VerticalAlignment="Center"/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<hc:Row Gutter="10">
|
||||||
|
<!-- 密炼日期 -->
|
||||||
|
<hc:Col Span="12">
|
||||||
|
<hc:DatePicker SelectedDate="{Binding MixingDate}"
|
||||||
|
hc:InfoElement.Title="密炼日期"
|
||||||
|
hc:InfoElement.TitleWidth="90"
|
||||||
|
hc:InfoElement.TitlePlacement="Left"
|
||||||
|
hc:InfoElement.Necessary="True"
|
||||||
|
hc:InfoElement.Symbol="*"
|
||||||
|
Margin="0,0,0,8"/>
|
||||||
|
</hc:Col>
|
||||||
|
<!-- 密炼机台 -->
|
||||||
|
<hc:Col Span="12">
|
||||||
|
<hc:ComboBox ItemsSource="{Binding MachineOptions}"
|
||||||
|
SelectedItem="{Binding SelectedMachine}"
|
||||||
|
hc:InfoElement.Title="密炼机台"
|
||||||
|
hc:InfoElement.TitleWidth="90"
|
||||||
|
hc:InfoElement.TitlePlacement="Left"
|
||||||
|
hc:InfoElement.Placeholder="请先选择密炼日期"
|
||||||
|
hc:InfoElement.Necessary="True"
|
||||||
|
hc:InfoElement.Symbol="*"
|
||||||
|
Margin="0,0,0,8"/>
|
||||||
|
</hc:Col>
|
||||||
|
<!-- 班次 -->
|
||||||
|
<hc:Col Span="12">
|
||||||
|
<hc:ComboBox ItemsSource="{Binding ShiftOptions}"
|
||||||
|
SelectedItem="{Binding SelectedShift}"
|
||||||
|
DisplayMemberPath="Name"
|
||||||
|
hc:InfoElement.Title="班次"
|
||||||
|
hc:InfoElement.TitleWidth="90"
|
||||||
|
hc:InfoElement.TitlePlacement="Left"
|
||||||
|
hc:InfoElement.Placeholder="请先选择机台"
|
||||||
|
hc:InfoElement.Necessary="True"
|
||||||
|
hc:InfoElement.Symbol="*"
|
||||||
|
Margin="0,0,0,8"/>
|
||||||
|
</hc:Col>
|
||||||
|
<!-- 密炼生产计划 -->
|
||||||
|
<hc:Col Span="24">
|
||||||
|
<hc:ComboBox ItemsSource="{Binding PlanOptions}"
|
||||||
|
SelectedItem="{Binding SelectedPlan}"
|
||||||
|
DisplayMemberPath="DisplayText"
|
||||||
|
hc:InfoElement.Title="密炼计划"
|
||||||
|
hc:InfoElement.TitleWidth="90"
|
||||||
|
hc:InfoElement.TitlePlacement="Left"
|
||||||
|
hc:InfoElement.Placeholder="按日期、机台、班次筛选后选择"
|
||||||
|
hc:InfoElement.Necessary="True"
|
||||||
|
hc:InfoElement.Symbol="*"
|
||||||
|
Margin="0,0,0,8"/>
|
||||||
|
</hc:Col>
|
||||||
|
<!-- 生产订单号 -->
|
||||||
|
<hc:Col Span="12">
|
||||||
|
<hc:TextBox Text="{Binding ProductionOrderNo, Mode=OneWay}"
|
||||||
|
IsReadOnly="True"
|
||||||
|
hc:InfoElement.Title="生产订单号"
|
||||||
|
hc:InfoElement.TitleWidth="90"
|
||||||
|
hc:InfoElement.TitlePlacement="Left"
|
||||||
|
hc:InfoElement.Placeholder="选择计划后自动带出"
|
||||||
|
hc:InfoElement.Necessary="True"
|
||||||
|
hc:InfoElement.Symbol="*"
|
||||||
|
Margin="0,0,0,8"/>
|
||||||
|
</hc:Col>
|
||||||
|
<!-- 胶料名称 -->
|
||||||
|
<hc:Col Span="12">
|
||||||
|
<hc:TextBox Text="{Binding RubberMaterialName, Mode=OneWay}"
|
||||||
|
IsReadOnly="True"
|
||||||
|
hc:InfoElement.Title="胶料名称"
|
||||||
|
hc:InfoElement.TitleWidth="90"
|
||||||
|
hc:InfoElement.TitlePlacement="Left"
|
||||||
|
hc:InfoElement.Placeholder="选择计划后自动带出"
|
||||||
|
Margin="0,0,0,8"/>
|
||||||
|
</hc:Col>
|
||||||
|
<!-- 车次 -->
|
||||||
|
<hc:Col Span="12">
|
||||||
|
<hc:TextBox Text="{Binding TrainNo, UpdateSourceTrigger=PropertyChanged}"
|
||||||
|
hc:InfoElement.Title="车次"
|
||||||
|
hc:InfoElement.TitleWidth="90"
|
||||||
|
hc:InfoElement.TitlePlacement="Left"
|
||||||
|
hc:InfoElement.Placeholder="手填车次"
|
||||||
|
hc:InfoElement.Necessary="True"
|
||||||
|
hc:InfoElement.Symbol="*"
|
||||||
|
hc:InfoElement.ShowClearButton="True"
|
||||||
|
Margin="0,0,0,8"/>
|
||||||
|
</hc:Col>
|
||||||
|
<!-- 试验次数 -->
|
||||||
|
<hc:Col Span="12">
|
||||||
|
<hc:TextBox Text="{Binding InspectTimesText, UpdateSourceTrigger=PropertyChanged}"
|
||||||
|
hc:InfoElement.Title="试验次数"
|
||||||
|
hc:InfoElement.TitleWidth="90"
|
||||||
|
hc:InfoElement.TitlePlacement="Left"
|
||||||
|
hc:InfoElement.Placeholder="默认 1,可修改"
|
||||||
|
hc:InfoElement.Necessary="True"
|
||||||
|
hc:InfoElement.Symbol="*"
|
||||||
|
hc:InfoElement.ShowClearButton="True"
|
||||||
|
Margin="0,0,0,0"/>
|
||||||
|
</hc:Col>
|
||||||
|
</hc:Row>
|
||||||
|
|
||||||
|
<TextBlock Text="按密炼日期 → 机台 → 班次筛选生产计划;胶料名称用于匹配快检实验标准"
|
||||||
|
FontSize="11"
|
||||||
|
Foreground="{DynamicResource SecondaryTextBrush}"
|
||||||
|
Margin="0,8,0,0"
|
||||||
|
TextWrapping="Wrap"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<!-- 数据标准 -->
|
||||||
|
<Border Style="{StaticResource SectionBorderStyle}">
|
||||||
|
<StackPanel>
|
||||||
|
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
|
||||||
|
<Border Width="4" Height="18" CornerRadius="2" Background="#faad14"/>
|
||||||
|
<TextBlock Text="数据标准" Style="{StaticResource SectionTitleStyle}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<DataGrid ItemsSource="{Binding DataPointColumns}"
|
||||||
|
AutoGenerateColumns="False"
|
||||||
|
IsReadOnly="True"
|
||||||
|
HeadersVisibility="Column"
|
||||||
|
MaxHeight="240">
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn Header="数据点" Binding="{Binding PointName}" Width="*"/>
|
||||||
|
<DataGridTextColumn Header="下限值" Binding="{Binding LowerLimit}" Width="70"/>
|
||||||
|
<DataGridTextColumn Header="上限值" Binding="{Binding UpperLimit}" Width="70"/>
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<!-- 底部操作 -->
|
||||||
|
<Border Grid.Row="2" Background="{DynamicResource RegionBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="0,1,0,0" Margin="-12,8,-12,-12">
|
||||||
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="20,0">
|
||||||
|
<Button Content="保存快检记录" Command="{Binding SaveCommand}" Style="{StaticResource ButtonPrimary}" Height="36" Width="140"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
using System.Windows.Controls;
|
||||||
|
using YY.Admin.ViewModels.RubberQuickTest;
|
||||||
|
|
||||||
|
namespace YY.Admin.Views.RubberQuickTest;
|
||||||
|
|
||||||
|
public partial class RubberQuickTestOperationView : UserControl
|
||||||
|
{
|
||||||
|
private RubberQuickTestOperationViewModel? _vm;
|
||||||
|
|
||||||
|
public RubberQuickTestOperationView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
DataContextChanged += OnDataContextChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDataContextChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (_vm != null)
|
||||||
|
_vm.InspectColumnsChanged -= RebuildInspectColumns;
|
||||||
|
_vm = DataContext as RubberQuickTestOperationViewModel;
|
||||||
|
if (_vm != null)
|
||||||
|
{
|
||||||
|
_vm.InspectColumnsChanged += RebuildInspectColumns;
|
||||||
|
RebuildInspectColumns();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RebuildInspectColumns()
|
||||||
|
{
|
||||||
|
if (_vm == null) return;
|
||||||
|
|
||||||
|
InspectResultGrid.Columns.Clear();
|
||||||
|
InspectResultGrid.Columns.Add(new DataGridTextColumn
|
||||||
|
{
|
||||||
|
Header = "编号",
|
||||||
|
Binding = new System.Windows.Data.Binding("RowNo"),
|
||||||
|
IsReadOnly = true,
|
||||||
|
Width = 80
|
||||||
|
});
|
||||||
|
|
||||||
|
for (int i = 0; i < _vm.DataPointColumns.Count; i++)
|
||||||
|
{
|
||||||
|
var col = _vm.DataPointColumns[i];
|
||||||
|
var binding = new System.Windows.Data.Binding($"Cells[{i}].Value")
|
||||||
|
{
|
||||||
|
UpdateSourceTrigger = System.Windows.Data.UpdateSourceTrigger.PropertyChanged,
|
||||||
|
Mode = System.Windows.Data.BindingMode.TwoWay
|
||||||
|
};
|
||||||
|
InspectResultGrid.Columns.Add(new DataGridTextColumn
|
||||||
|
{
|
||||||
|
Header = col.PointName ?? $"点{i + 1}",
|
||||||
|
Binding = binding,
|
||||||
|
Width = 90,
|
||||||
|
IsReadOnly = false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
InspectResultGrid.Columns.Add(new DataGridTextColumn
|
||||||
|
{
|
||||||
|
Header = "实验结果",
|
||||||
|
Binding = new System.Windows.Data.Binding("InspectResultText"),
|
||||||
|
IsReadOnly = true,
|
||||||
|
Width = 90
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InspectResultGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (_vm == null) return;
|
||||||
|
_vm.SelectedInspectRow = InspectResultGrid.SelectedItem as QuickTestInspectRowViewModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
<UserControl x:Class="YY.Admin.Views.RubberQuickTestStd.RubberQuickTestStdDetailDialogView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Width="900"
|
||||||
|
MinHeight="520">
|
||||||
|
|
||||||
|
<Grid Background="{DynamicResource ThirdlyRegionBrush}">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<hc:SimplePanel Margin="20">
|
||||||
|
<TextBlock FontSize="18" Foreground="{DynamicResource PrimaryTextBrush}"
|
||||||
|
Text="胶料快检实验标准详情" HorizontalAlignment="Left"/>
|
||||||
|
<Button Width="22" Height="22" Command="hc:ControlCommands.Close"
|
||||||
|
Style="{StaticResource ButtonIcon}" Foreground="{DynamicResource PrimaryBrush}"
|
||||||
|
hc:IconElement.Geometry="{StaticResource ErrorGeometry}"
|
||||||
|
Padding="0" HorizontalAlignment="Right" VerticalAlignment="Top"/>
|
||||||
|
</hc:SimplePanel>
|
||||||
|
|
||||||
|
<hc:ScrollViewer Grid.Row="1" IsInertiaEnabled="True">
|
||||||
|
<StackPanel Margin="20,0,20,0">
|
||||||
|
<hc:Row Gutter="10">
|
||||||
|
<hc:Col Span="12">
|
||||||
|
<hc:TextBox Text="{Binding Std.StdName, Mode=OneWay}" IsReadOnly="True"
|
||||||
|
hc:InfoElement.Title="标准名称" hc:InfoElement.TitleWidth="90" hc:InfoElement.TitlePlacement="Left"
|
||||||
|
Margin="0,0,0,12"/>
|
||||||
|
</hc:Col>
|
||||||
|
<hc:Col Span="12">
|
||||||
|
<hc:TextBox Text="{Binding Std.TestMethodName, Mode=OneWay}" IsReadOnly="True"
|
||||||
|
hc:InfoElement.Title="实验方法" hc:InfoElement.TitleWidth="90" hc:InfoElement.TitlePlacement="Left"
|
||||||
|
Margin="0,0,0,12"/>
|
||||||
|
</hc:Col>
|
||||||
|
<hc:Col Span="12">
|
||||||
|
<hc:TextBox Text="{Binding Std.RubberMaterialName, Mode=OneWay}" IsReadOnly="True"
|
||||||
|
hc:InfoElement.Title="胶料名称" hc:InfoElement.TitleWidth="90" hc:InfoElement.TitlePlacement="Left"
|
||||||
|
Margin="0,0,0,12"/>
|
||||||
|
</hc:Col>
|
||||||
|
<hc:Col Span="12">
|
||||||
|
<hc:TextBox Text="{Binding Std.IssueNumber, Mode=OneWay}" IsReadOnly="True"
|
||||||
|
hc:InfoElement.Title="发行编号" hc:InfoElement.TitleWidth="90" hc:InfoElement.TitlePlacement="Left"
|
||||||
|
Margin="0,0,0,12"/>
|
||||||
|
</hc:Col>
|
||||||
|
<hc:Col Span="12">
|
||||||
|
<hc:TextBox Text="{Binding Std.IssueDate, Mode=OneWay, StringFormat={}{0:yyyy-MM-dd}}" IsReadOnly="True"
|
||||||
|
hc:InfoElement.Title="发行日期" hc:InfoElement.TitleWidth="90" hc:InfoElement.TitlePlacement="Left"
|
||||||
|
Margin="0,0,0,12"/>
|
||||||
|
</hc:Col>
|
||||||
|
<hc:Col Span="12">
|
||||||
|
<hc:TextBox Text="{Binding Std.IssueDeptName, Mode=OneWay}" IsReadOnly="True"
|
||||||
|
hc:InfoElement.Title="发行部门" hc:InfoElement.TitleWidth="90" hc:InfoElement.TitlePlacement="Left"
|
||||||
|
Margin="0,0,0,12"/>
|
||||||
|
</hc:Col>
|
||||||
|
<hc:Col Span="12">
|
||||||
|
<hc:TextBox Text="{Binding Std.EnableStatusText, Mode=OneWay}" IsReadOnly="True"
|
||||||
|
hc:InfoElement.Title="启用状态" hc:InfoElement.TitleWidth="90" hc:InfoElement.TitlePlacement="Left"
|
||||||
|
Margin="0,0,0,12"/>
|
||||||
|
</hc:Col>
|
||||||
|
<hc:Col Span="12">
|
||||||
|
<hc:TextBox Text="{Binding Std.AuditStatusText, Mode=OneWay}" IsReadOnly="True"
|
||||||
|
hc:InfoElement.Title="审核状态" hc:InfoElement.TitleWidth="90" hc:InfoElement.TitlePlacement="Left"
|
||||||
|
Margin="0,0,0,12"/>
|
||||||
|
</hc:Col>
|
||||||
|
</hc:Row>
|
||||||
|
|
||||||
|
<TextBlock Text="标准明细(数据点上下限)" FontWeight="SemiBold" Margin="0,8,0,8"/>
|
||||||
|
<DataGrid ItemsSource="{Binding Lines}"
|
||||||
|
AutoGenerateColumns="False"
|
||||||
|
IsReadOnly="True"
|
||||||
|
HeadersVisibility="Column"
|
||||||
|
MaxHeight="280"
|
||||||
|
CanUserAddRows="False">
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn Header="数据点" Binding="{Binding PointName}" Width="*"/>
|
||||||
|
<DataGridTextColumn Header="下限值" Binding="{Binding LowerLimit}" Width="90"/>
|
||||||
|
<DataGridTextColumn Header="下警告" Binding="{Binding LowerWarn}" Width="90"/>
|
||||||
|
<DataGridTextColumn Header="目标值" Binding="{Binding TargetValue}" Width="90"/>
|
||||||
|
<DataGridTextColumn Header="上警告" Binding="{Binding UpperWarn}" Width="90"/>
|
||||||
|
<DataGridTextColumn Header="上限值" Binding="{Binding UpperLimit}" Width="90"/>
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
</StackPanel>
|
||||||
|
</hc:ScrollViewer>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="20">
|
||||||
|
<Button Content="关闭" Command="{Binding CloseCommand}" Style="{StaticResource ButtonPrimary}" Width="100"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace YY.Admin.Views.RubberQuickTestStd;
|
||||||
|
|
||||||
|
public partial class RubberQuickTestStdDetailDialogView : UserControl
|
||||||
|
{
|
||||||
|
public RubberQuickTestStdDetailDialogView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
<UserControl x:Class="YY.Admin.Views.RubberQuickTestStd.RubberQuickTestStdListView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||||
|
xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid Style="{StaticResource BaseViewStyle}">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Border Grid.Row="0" CornerRadius="4" Margin="0 0 -10 0">
|
||||||
|
<hc:Row>
|
||||||
|
<hc:Col Layout="{hc:ColLayout Xs=12, Sm=8, Md=6, Lg=6, Xl=4}">
|
||||||
|
<hc:TextBox Text="{Binding FilterStdName, UpdateSourceTrigger=PropertyChanged}"
|
||||||
|
Margin="0 0 10 10"
|
||||||
|
hc:InfoElement.Title="标准名称"
|
||||||
|
hc:InfoElement.TitlePlacement="Left"
|
||||||
|
hc:InfoElement.TitleWidth="75"
|
||||||
|
hc:InfoElement.Placeholder="实验标准名称"
|
||||||
|
hc:InfoElement.ShowClearButton="True"/>
|
||||||
|
</hc:Col>
|
||||||
|
<hc:Col Layout="{hc:ColLayout Xs=12, Sm=8, Md=6, Lg=6, Xl=4}">
|
||||||
|
<hc:TextBox Text="{Binding FilterRubberMaterialName, UpdateSourceTrigger=PropertyChanged}"
|
||||||
|
Margin="0 0 10 10"
|
||||||
|
hc:InfoElement.Title="胶料名称"
|
||||||
|
hc:InfoElement.TitlePlacement="Left"
|
||||||
|
hc:InfoElement.TitleWidth="75"
|
||||||
|
hc:InfoElement.Placeholder="胶料名称"
|
||||||
|
hc:InfoElement.ShowClearButton="True"/>
|
||||||
|
</hc:Col>
|
||||||
|
<hc:Col Layout="{hc:ColLayout Xs=12, Sm=8, Md=6, Lg=6, Xl=4}">
|
||||||
|
<hc:ComboBox SelectedValuePath="Value"
|
||||||
|
DisplayMemberPath="Key"
|
||||||
|
ItemsSource="{Binding EnableStatusOptions}"
|
||||||
|
SelectedValue="{Binding FilterEnableStatus}"
|
||||||
|
Margin="0 0 10 10"
|
||||||
|
hc:InfoElement.Title="启用状态"
|
||||||
|
hc:InfoElement.TitlePlacement="Left"
|
||||||
|
hc:InfoElement.TitleWidth="75"
|
||||||
|
hc:InfoElement.Placeholder="全部"
|
||||||
|
hc:InfoElement.ShowClearButton="True"/>
|
||||||
|
</hc:Col>
|
||||||
|
</hc:Row>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<Border Grid.Row="1" Margin="0,10">
|
||||||
|
<hc:UniformSpacingPanel Spacing="10">
|
||||||
|
<Button Style="{StaticResource ButtonPrimary}" Command="{Binding SearchCommand}">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<md:PackIcon Kind="Search"/>
|
||||||
|
<TextBlock Text="搜索" Style="{StaticResource IconButtonStyle}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
|
<Button Style="{StaticResource ButtonDefault}" Command="{Binding ResetCommand}">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<md:PackIcon Kind="Refresh"/>
|
||||||
|
<TextBlock Text="重置" Style="{StaticResource IconButtonStyle}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
|
<TextBlock Text="数据来自 MES,桌面端只读;断网时显示本地缓存"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Foreground="{DynamicResource SecondaryTextBrush}"
|
||||||
|
FontSize="12"/>
|
||||||
|
</hc:UniformSpacingPanel>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<DataGrid Grid.Row="2"
|
||||||
|
ItemsSource="{Binding Items}"
|
||||||
|
AutoGenerateColumns="False"
|
||||||
|
IsReadOnly="True"
|
||||||
|
CanUserAddRows="False"
|
||||||
|
SelectionMode="Single"
|
||||||
|
GridLinesVisibility="Horizontal"
|
||||||
|
HorizontalGridLinesBrush="#FFEDEDED"
|
||||||
|
VerticalGridLinesBrush="Transparent"
|
||||||
|
HeadersVisibility="All"
|
||||||
|
ColumnHeaderStyle="{StaticResource CusDataGridColumnHeaderStyle}"
|
||||||
|
Style="{StaticResource CusDataGridStyle}"
|
||||||
|
VerticalScrollBarVisibility="Auto"
|
||||||
|
HorizontalScrollBarVisibility="Auto">
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn Header="实验标准名称" Binding="{Binding StdName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="180"/>
|
||||||
|
<DataGridTextColumn Header="实验方法" Binding="{Binding TestMethodName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="140"/>
|
||||||
|
<DataGridTextColumn Header="胶料名称" Binding="{Binding RubberMaterialName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="140"/>
|
||||||
|
<DataGridTextColumn Header="发行编号" Binding="{Binding IssueNumber}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
|
||||||
|
<DataGridTextColumn Header="发行部门" Binding="{Binding IssueDeptName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
|
||||||
|
<DataGridTextColumn Header="启用状态" Binding="{Binding EnableStatusText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="90"/>
|
||||||
|
<DataGridTextColumn Header="审核状态" Binding="{Binding AuditStatusText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="90"/>
|
||||||
|
<DataGridTextColumn Header="创建人" Binding="{Binding CreateBy}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="100"/>
|
||||||
|
<DataGridTextColumn Header="创建时间" Binding="{Binding CreateTime, StringFormat={}{0:yyyy-MM-dd HH:mm}}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="150"/>
|
||||||
|
<DataGridTemplateColumn Header="操作" Width="100" CellStyle="{StaticResource CusOperDataGridCellStyle}">
|
||||||
|
<DataGridTemplateColumn.CellTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Border Style="{DynamicResource DataGridOpeButtonStyle}">
|
||||||
|
<Border.InputBindings>
|
||||||
|
<MouseBinding Command="{Binding DataContext.ViewDetailCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"
|
||||||
|
CommandParameter="{Binding}" MouseAction="LeftClick"/>
|
||||||
|
</Border.InputBindings>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<md:PackIcon Kind="EyeOutline" VerticalAlignment="Center"/>
|
||||||
|
<TextBlock Text="详情" VerticalAlignment="Center"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</DataTemplate>
|
||||||
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
|
</DataGridTemplateColumn>
|
||||||
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,0,0">
|
||||||
|
<TextBlock Text="{Binding Total, StringFormat=共 {0} 条}" VerticalAlignment="Center" Margin="0,0,16,0"
|
||||||
|
Foreground="{DynamicResource SecondaryTextBrush}"/>
|
||||||
|
<Button Content="上一页" Command="{Binding PrevPageCommand}" Style="{StaticResource ButtonDefault}" Margin="0,0,4,0" Width="80"/>
|
||||||
|
<TextBlock Text="{Binding PageNo, StringFormat=第 {0} 页}" VerticalAlignment="Center" Margin="8,0"
|
||||||
|
Foreground="{DynamicResource PrimaryTextBrush}"/>
|
||||||
|
<Button Content="下一页" Command="{Binding NextPageCommand}" Style="{StaticResource ButtonDefault}" Width="80"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace YY.Admin.Views.RubberQuickTestStd;
|
||||||
|
|
||||||
|
public partial class RubberQuickTestStdListView : UserControl
|
||||||
|
{
|
||||||
|
public RubberQuickTestStdListView()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user