桌面端快检记录新增列表及同步mes
This commit is contained in:
@@ -57,6 +57,7 @@ import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestStdService;
|
||||
import org.jeecg.modules.xslmes.service.IMesXslWeightRecordService;
|
||||
import org.jeecg.modules.xslmes.service.MesXslStompNotifyService;
|
||||
import org.jeecg.modules.xslmes.vo.MesXslRawMaterialCardBriefVO;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@@ -1021,6 +1022,30 @@ public class MesXslDesktopAnonController {
|
||||
//update-end---author:jiangxh ---date:2026-06-17 for:【快检记录】桌面端胶料快检实验标准查询-----------
|
||||
|
||||
//update-begin---author:jiangxh ---date:2026-06-17 for:【快检记录】桌面端胶料快检记录保存-----------
|
||||
@Operation(summary = "胶料快检记录-免密分页列表")
|
||||
@GetMapping("/xslmes/mesXslRubberQuickTestRecord/anon/list")
|
||||
public Result<IPage<MesXslRubberQuickTestRecord>> rubberQuickTestRecordAnonList(
|
||||
MesXslRubberQuickTestRecord model,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "20") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
QueryWrapper<MesXslRubberQuickTestRecord> qw = QueryGenerator.initQueryWrapper(model, req.getParameterMap());
|
||||
qw.orderByDesc("create_time");
|
||||
IPage<MesXslRubberQuickTestRecord> page = rubberQuickTestRecordService.page(new Page<>(pageNo, pageSize), qw);
|
||||
return Result.OK(page);
|
||||
}
|
||||
|
||||
@Operation(summary = "胶料快检记录-免密通过id查询(含明细)")
|
||||
@GetMapping("/xslmes/mesXslRubberQuickTestRecord/anon/queryById")
|
||||
public Result<MesXslRubberQuickTestRecord> rubberQuickTestRecordAnonQueryById(@RequestParam(name = "id") String id) {
|
||||
MesXslRubberQuickTestRecord entity = rubberQuickTestRecordService.getById(id);
|
||||
if (entity == null) {
|
||||
return Result.error("未找到对应数据");
|
||||
}
|
||||
fillRubberQuickTestRecordDetails(entity);
|
||||
return Result.OK(entity);
|
||||
}
|
||||
|
||||
@Operation(summary = "胶料快检记录-免密添加")
|
||||
@PostMapping("/xslmes/mesXslRubberQuickTestRecord/anon/add")
|
||||
public Result<String> rubberQuickTestRecordAnonAdd(@RequestBody MesXslRubberQuickTestRecord record) {
|
||||
@@ -1030,16 +1055,23 @@ public class MesXslDesktopAnonController {
|
||||
if (oConvertUtils.isEmpty(record.getRubberMaterialName())) {
|
||||
return Result.error("胶料名称不能为空");
|
||||
}
|
||||
List<MesXslRubberQuickTestRecordLine> lineList = record.getLineList();
|
||||
if (lineList == null || lineList.isEmpty()) {
|
||||
return Result.error("请维护检验明细");
|
||||
if (CollectionUtils.isEmpty(record.getStdLineList())) {
|
||||
return Result.error("请维护数据标准明细");
|
||||
}
|
||||
if (CollectionUtils.isEmpty(record.getRawLineList())) {
|
||||
return Result.error("请维护试验结果明细");
|
||||
}
|
||||
//update-begin---author:jiangxh ---date:20260617 for:【快检记录】桌面端同步须含曲线图数据-----------
|
||||
if (CollectionUtils.isEmpty(record.getChartPointList())) {
|
||||
return Result.error("请维护曲线图数据");
|
||||
}
|
||||
//update-end---author:jiangxh ---date:20260617 for:【快检记录】桌面端同步须含曲线图数据-----------
|
||||
try {
|
||||
if (oConvertUtils.isEmpty(record.getRecordNo())) {
|
||||
record.setRecordNo(rubberQuickTestRecordService.generateDesktopRecordNo(record));
|
||||
}
|
||||
rubberQuickTestRecordService.fillQuickTestTypeForRecord(record);
|
||||
rubberQuickTestRecordService.saveMain(record, lineList);
|
||||
rubberQuickTestRecordService.fillStdAndTypeForRecord(record);
|
||||
rubberQuickTestRecordService.saveMain(record, record.getLineList());
|
||||
stompNotify.publishRubberQuickTestRecordChanged("add", record.getId());
|
||||
return Result.OK(record.getRecordNo());
|
||||
} catch (Exception e) {
|
||||
@@ -1047,6 +1079,17 @@ public class MesXslDesktopAnonController {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void fillRubberQuickTestRecordDetails(MesXslRubberQuickTestRecord entity) {
|
||||
if (entity == null || oConvertUtils.isEmpty(entity.getId())) {
|
||||
return;
|
||||
}
|
||||
String id = entity.getId();
|
||||
entity.setStdLineList(rubberQuickTestRecordService.selectStdLinesByRecordId(id));
|
||||
entity.setRawLineList(rubberQuickTestRecordService.selectRawLinesByRecordId(id));
|
||||
entity.setChartPointList(rubberQuickTestRecordService.selectChartPointsByRecordId(id));
|
||||
entity.setLineList(rubberQuickTestRecordService.selectLinesByRecordId(id));
|
||||
}
|
||||
//update-end---author:jiangxh ---date:2026-06-17 for:【快检记录】桌面端胶料快检记录保存-----------
|
||||
|
||||
//update-begin---author:jiangxh ---date:20260618 for:【快检实验标准】桌面端回填实验方法关联实验类型-----------
|
||||
|
||||
@@ -23,8 +23,10 @@ import org.jeecg.modules.mes.material.service.IMesMaterialService;
|
||||
import org.jeecg.modules.system.entity.SysUser;
|
||||
import org.jeecg.modules.system.service.ISysUserService;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecord;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordChartPoint;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordLine;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordRawLine;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordStdLine;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestType;
|
||||
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestRecordService;
|
||||
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestTypeService;
|
||||
@@ -32,6 +34,7 @@ import org.jeecg.modules.xslmes.vo.MesXslRubberQuickTestRecordBatchFromMaterialV
|
||||
import org.jeecg.modules.xslmes.vo.MesXslRubberQuickTestRecordPage;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
@@ -117,16 +120,9 @@ public class MesXslRubberQuickTestRecordController
|
||||
@RequiresPermissions("mes:mes_material:rubberQuickTestInspect")
|
||||
@PostMapping(value = "/batchFromMaterial")
|
||||
public Result<List<String>> batchFromMaterial(@RequestBody MesXslRubberQuickTestRecordBatchFromMaterialVO vo) {
|
||||
try {
|
||||
//update-begin---author:jiangxh ---date:20260616 for:【MES】胶料快检记录批量生成默认带出当前登录检验人-----------
|
||||
fillInspectorIfEmpty(vo);
|
||||
//update-end---author:jiangxh ---date:20260616 for:【MES】胶料快检记录批量生成默认带出当前登录检验人-----------
|
||||
List<String> ids = mesXslRubberQuickTestRecordService.batchFromMaterial(vo);
|
||||
return Result.OK("成功生成 " + ids.size() + " 条快检记录", ids);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
//update-begin---author:jiangxh ---date:2026-06-22 for:【快检记录】取消胶料列表批量生成,改由桌面端同步-----------
|
||||
return Result.error("该功能已停用,请通过桌面端新增并同步胶料快检记录");
|
||||
//update-end---author:jiangxh ---date:2026-06-22 for:【快检记录】取消胶料列表批量生成,改由桌面端同步-----------
|
||||
}
|
||||
|
||||
@AutoLog(value = "MES胶料快检记录-删除")
|
||||
@@ -154,6 +150,12 @@ public class MesXslRubberQuickTestRecordController
|
||||
if (entity == null) {
|
||||
return Result.error("未找到对应数据");
|
||||
}
|
||||
//update-begin---author:jiangxh ---date:2026-06-22 for:【快检记录】查询含数据标准/试验结果/曲线图明细-----------
|
||||
entity.setStdLineList(mesXslRubberQuickTestRecordService.selectStdLinesByRecordId(id));
|
||||
entity.setRawLineList(mesXslRubberQuickTestRecordService.selectRawLinesByRecordId(id));
|
||||
entity.setChartPointList(mesXslRubberQuickTestRecordService.selectChartPointsByRecordId(id));
|
||||
entity.setLineList(mesXslRubberQuickTestRecordService.selectLinesByRecordId(id));
|
||||
//update-end---author:jiangxh ---date:2026-06-22 for:【快检记录】查询含数据标准/试验结果/曲线图明细-----------
|
||||
return Result.OK(entity);
|
||||
}
|
||||
|
||||
@@ -173,6 +175,22 @@ public class MesXslRubberQuickTestRecordController
|
||||
}
|
||||
//update-end---author:jiangxh ---date:2026-06-17 for:【快检记录】查询原始数据明细-----------
|
||||
|
||||
//update-begin---author:jiangxh ---date:2026-06-22 for:【快检记录】查询数据标准明细与曲线图-----------
|
||||
@Operation(summary = "MES胶料快检记录-查询数据标准明细")
|
||||
@GetMapping(value = "/queryStdLineListByRecordId")
|
||||
public Result<List<MesXslRubberQuickTestRecordStdLine>> queryStdLineListByRecordId(
|
||||
@RequestParam(name = "id", required = true) String id) {
|
||||
return Result.OK(mesXslRubberQuickTestRecordService.selectStdLinesByRecordId(id));
|
||||
}
|
||||
|
||||
@Operation(summary = "MES胶料快检记录-查询曲线图数据点")
|
||||
@GetMapping(value = "/queryChartPointListByRecordId")
|
||||
public Result<List<MesXslRubberQuickTestRecordChartPoint>> queryChartPointListByRecordId(
|
||||
@RequestParam(name = "id", required = true) String id) {
|
||||
return Result.OK(mesXslRubberQuickTestRecordService.selectChartPointsByRecordId(id));
|
||||
}
|
||||
//update-end---author:jiangxh ---date:2026-06-22 for:【快检记录】查询数据标准明细与曲线图-----------
|
||||
|
||||
@RequiresPermissions("mes:mes_xsl_rubber_quick_test_record:exportXls")
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, MesXslRubberQuickTestRecord model) {
|
||||
@@ -189,14 +207,22 @@ public class MesXslRubberQuickTestRecordController
|
||||
if (main == null) {
|
||||
return "参数不能为空";
|
||||
}
|
||||
if (oConvertUtils.isEmpty(main.getRubberMaterialId())) {
|
||||
return "请选择胶料";
|
||||
}
|
||||
//update-begin---author:jiangxh ---date:2026-06-22 for:【快检记录】Web保存校验支持桌面端三类明细-----------
|
||||
if (oConvertUtils.isNotEmpty(main.getRubberMaterialId())) {
|
||||
MesMaterial material = mesMaterialService.getById(main.getRubberMaterialId());
|
||||
if (material == null) {
|
||||
return "所选胶料不存在";
|
||||
}
|
||||
main.setRubberMaterialName(material.getMaterialName());
|
||||
} else if (oConvertUtils.isEmpty(main.getRubberMaterialName())) {
|
||||
return "胶料名称不能为空";
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(main.getStdLineList()) && !CollectionUtils.isEmpty(main.getRawLineList())) {
|
||||
resolveInspector(main);
|
||||
return null;
|
||||
}
|
||||
//update-end---author:jiangxh ---date:2026-06-22 for:【快检记录】Web保存校验支持桌面端三类明细-----------
|
||||
|
||||
if (oConvertUtils.isNotEmpty(main.getQuickTestTypeId())) {
|
||||
MesXslRubberQuickTestType type = mesXslRubberQuickTestTypeService.getById(main.getQuickTestTypeId());
|
||||
|
||||
@@ -32,8 +32,8 @@ public class MesXslRubberQuickTestRecord implements Serializable {
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
@Excel(name = "单号", width = 16)
|
||||
@Schema(description = "单号(JL+yyyyMMdd+4位流水)")
|
||||
@Excel(name = "快检记录号", width = 16)
|
||||
@Schema(description = "快检记录号(yyyyMMdd+4位流水+胶料名称)")
|
||||
private String recordNo;
|
||||
|
||||
@Schema(description = "胶料ID mes_material.id")
|
||||
@@ -46,14 +46,25 @@ public class MesXslRubberQuickTestRecord implements Serializable {
|
||||
@Schema(description = "引用的实验标准ID")
|
||||
private String stdId;
|
||||
|
||||
@Schema(description = "生产机台ID")
|
||||
@Excel(name = "实验标准", width = 20)
|
||||
@Schema(description = "实验标准名称冗余")
|
||||
private String stdName;
|
||||
|
||||
@Schema(description = "实验方法ID")
|
||||
private String testMethodId;
|
||||
|
||||
@Excel(name = "实验方法", width = 20)
|
||||
@Schema(description = "实验方法名称冗余")
|
||||
private String testMethodName;
|
||||
|
||||
@Schema(description = "炼机台ID")
|
||||
private String prodEquipmentLedgerId;
|
||||
|
||||
@Excel(name = "生产机台", width = 16)
|
||||
@Schema(description = "生产机台名称冗余")
|
||||
@Excel(name = "炼机台", width = 16)
|
||||
@Schema(description = "炼机台名称冗余")
|
||||
private String prodEquipmentName;
|
||||
|
||||
@Excel(name = "生产日期", width = 12, format = "yyyy-MM-dd")
|
||||
@Excel(name = "密炼日期", width = 12, format = "yyyy-MM-dd")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private Date productionDate;
|
||||
@@ -69,7 +80,7 @@ public class MesXslRubberQuickTestRecord implements Serializable {
|
||||
@Dict(dicCode = "xslmes_rubber_quick_test_work_team")
|
||||
private String workTeam;
|
||||
|
||||
@Excel(name = "检验次数", width = 10)
|
||||
@Excel(name = "试验次数", width = 10)
|
||||
private Integer inspectTimes;
|
||||
|
||||
@Excel(name = "检验时间", width = 18, format = "yyyy-MM-dd HH:mm:ss")
|
||||
@@ -86,17 +97,17 @@ public class MesXslRubberQuickTestRecord implements Serializable {
|
||||
@Excel(name = "检验人", width = 12)
|
||||
private String inspectorRealname;
|
||||
|
||||
@Schema(description = "检验类型ID")
|
||||
@Schema(description = "实验类型ID")
|
||||
private String quickTestTypeId;
|
||||
|
||||
@Excel(name = "检验类型", width = 16)
|
||||
@Excel(name = "实验类型", width = 16)
|
||||
private String quickTestTypeName;
|
||||
|
||||
@Excel(name = "检验结果", width = 10, dicCode = "xslmes_rubber_quick_test_record_result")
|
||||
@Dict(dicCode = "xslmes_rubber_quick_test_record_result")
|
||||
private String inspectResult;
|
||||
|
||||
@Excel(name = "生产计划号", width = 16)
|
||||
@Excel(name = "密炼计划", width = 16)
|
||||
private String productionPlanNo;
|
||||
|
||||
@Schema(description = "检验机台ID")
|
||||
@@ -134,4 +145,14 @@ public class MesXslRubberQuickTestRecord implements Serializable {
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "原始数据明细(试验结果全部检测值)")
|
||||
private List<MesXslRubberQuickTestRecordRawLine> rawLineList;
|
||||
|
||||
//update-begin---author:jiangxh ---date:2026-06-22 for:【快检记录】数据标准明细与曲线图-----------
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "数据标准明细(实验标准快照)")
|
||||
private List<MesXslRubberQuickTestRecordStdLine> stdLineList;
|
||||
|
||||
@TableField(exist = false)
|
||||
@Schema(description = "曲线图数据点")
|
||||
private List<MesXslRubberQuickTestRecordChartPoint> chartPointList;
|
||||
//update-end---author:jiangxh ---date:2026-06-22 for:【快检记录】数据标准明细与曲线图-----------
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
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.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
/**
|
||||
* MES 胶料快检记录曲线图数据点
|
||||
*/
|
||||
@Data
|
||||
@TableName("mes_xsl_rubber_quick_test_record_chart_point")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description = "MES胶料快检记录曲线图数据点")
|
||||
public class MesXslRubberQuickTestRecordChartPoint 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 = "时间(min)", width = 12, type = 10)
|
||||
private BigDecimal timeMin;
|
||||
|
||||
@Excel(name = "上模温度", width = 12, type = 10)
|
||||
private BigDecimal upperTemp;
|
||||
|
||||
@Excel(name = "下模温度", width = 12, type = 10)
|
||||
private BigDecimal lowerTemp;
|
||||
|
||||
@Excel(name = "S'(dNm)", width = 12, type = 10)
|
||||
private BigDecimal torqueS;
|
||||
|
||||
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,68 @@
|
||||
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.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
/**
|
||||
* MES 胶料快检记录数据标准明细(实验标准快照)
|
||||
*/
|
||||
@Data
|
||||
@TableName("mes_xsl_rubber_quick_test_record_std_line")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description = "MES胶料快检记录数据标准明细")
|
||||
public class MesXslRubberQuickTestRecordStdLine 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;
|
||||
|
||||
@Schema(description = "数据点ID")
|
||||
private String dataPointId;
|
||||
|
||||
@Excel(name = "数据点", width = 18)
|
||||
private String pointName;
|
||||
|
||||
@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 lowerWarn;
|
||||
|
||||
@Excel(name = "上限预警", width = 12, type = 10)
|
||||
private BigDecimal upperWarn;
|
||||
|
||||
@Excel(name = "目标值", width = 12, type = 10)
|
||||
private BigDecimal targetValue;
|
||||
|
||||
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.MesXslRubberQuickTestRecordChartPoint;
|
||||
|
||||
public interface MesXslRubberQuickTestRecordChartPointMapper extends BaseMapper<MesXslRubberQuickTestRecordChartPoint> {}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.jeecg.modules.xslmes.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordStdLine;
|
||||
|
||||
public interface MesXslRubberQuickTestRecordStdLineMapper extends BaseMapper<MesXslRubberQuickTestRecordStdLine> {
|
||||
}
|
||||
@@ -5,8 +5,10 @@ import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecord;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordChartPoint;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordLine;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordRawLine;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordStdLine;
|
||||
import org.jeecg.modules.xslmes.vo.MesXslRubberQuickTestRecordBatchFromMaterialVO;
|
||||
|
||||
public interface IMesXslRubberQuickTestRecordService extends IService<MesXslRubberQuickTestRecord> {
|
||||
@@ -23,6 +25,15 @@ public interface IMesXslRubberQuickTestRecordService extends IService<MesXslRubb
|
||||
|
||||
List<MesXslRubberQuickTestRecordRawLine> selectRawLinesByRecordId(String recordId);
|
||||
|
||||
//update-begin---author:jiangxh ---date:2026-06-22 for:【快检记录】数据标准明细与曲线图查询-----------
|
||||
List<MesXslRubberQuickTestRecordStdLine> selectStdLinesByRecordId(String recordId);
|
||||
|
||||
List<MesXslRubberQuickTestRecordChartPoint> selectChartPointsByRecordId(String recordId);
|
||||
|
||||
/** 桌面端保存前:按实验标准回填标准名、方法名、实验类型 */
|
||||
void fillStdAndTypeForRecord(MesXslRubberQuickTestRecord record);
|
||||
//update-end---author:jiangxh ---date:2026-06-22 for:【快检记录】数据标准明细与曲线图查询-----------
|
||||
|
||||
String generateRecordNo(MesXslRubberQuickTestRecord context);
|
||||
|
||||
//update-begin---author:jiangxh ---date:20260618 for:【快检记录】桌面端快检记录号生成-----------
|
||||
|
||||
@@ -19,14 +19,18 @@ import org.jeecg.modules.mes.material.service.IMesMaterialService;
|
||||
import org.jeecg.modules.xslmes.common.XslMesBizConstants;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestMethod;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecord;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordChartPoint;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordLine;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordRawLine;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestRecordStdLine;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestStd;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestStdLine;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRubberQuickTestType;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslRubberQuickTestRecordChartPointMapper;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslRubberQuickTestRecordLineMapper;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslRubberQuickTestRecordMapper;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslRubberQuickTestRecordRawLineMapper;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslRubberQuickTestRecordStdLineMapper;
|
||||
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestMethodService;
|
||||
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestRecordService;
|
||||
import org.jeecg.modules.xslmes.service.IMesXslRubberQuickTestStdService;
|
||||
@@ -50,6 +54,12 @@ public class MesXslRubberQuickTestRecordServiceImpl
|
||||
@Autowired
|
||||
private MesXslRubberQuickTestRecordRawLineMapper mesXslRubberQuickTestRecordRawLineMapper;
|
||||
|
||||
@Autowired
|
||||
private MesXslRubberQuickTestRecordStdLineMapper mesXslRubberQuickTestRecordStdLineMapper;
|
||||
|
||||
@Autowired
|
||||
private MesXslRubberQuickTestRecordChartPointMapper mesXslRubberQuickTestRecordChartPointMapper;
|
||||
|
||||
@Autowired
|
||||
private IMesXslRubberQuickTestStdService mesXslRubberQuickTestStdService;
|
||||
|
||||
@@ -73,6 +83,10 @@ public class MesXslRubberQuickTestRecordServiceImpl
|
||||
//update-begin---author:jiangxh ---date:2026-06-17 for:【快检记录】保存试验结果原始数据明细-----------
|
||||
insertRawLines(main.getId(), main.getRawLineList());
|
||||
//update-end---author:jiangxh ---date:2026-06-17 for:【快检记录】保存试验结果原始数据明细-----------
|
||||
//update-begin---author:jiangxh ---date:2026-06-22 for:【快检记录】保存数据标准明细与曲线图-----------
|
||||
insertStdLines(main.getId(), main.getStdLineList());
|
||||
insertChartPoints(main.getId(), main.getChartPointList());
|
||||
//update-end---author:jiangxh ---date:2026-06-22 for:【快检记录】保存数据标准明细与曲线图-----------
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -95,6 +109,16 @@ public class MesXslRubberQuickTestRecordServiceImpl
|
||||
.eq(MesXslRubberQuickTestRecordRawLine::getRecordId, main.getId()));
|
||||
insertRawLines(main.getId(), main.getRawLineList());
|
||||
//update-end---author:jiangxh ---date:2026-06-17 for:【快检记录】更新时同步原始数据明细-----------
|
||||
//update-begin---author:jiangxh ---date:2026-06-22 for:【快检记录】更新时同步数据标准与曲线图-----------
|
||||
mesXslRubberQuickTestRecordStdLineMapper.delete(
|
||||
new LambdaQueryWrapper<MesXslRubberQuickTestRecordStdLine>()
|
||||
.eq(MesXslRubberQuickTestRecordStdLine::getRecordId, main.getId()));
|
||||
insertStdLines(main.getId(), main.getStdLineList());
|
||||
mesXslRubberQuickTestRecordChartPointMapper.delete(
|
||||
new LambdaQueryWrapper<MesXslRubberQuickTestRecordChartPoint>()
|
||||
.eq(MesXslRubberQuickTestRecordChartPoint::getRecordId, main.getId()));
|
||||
insertChartPoints(main.getId(), main.getChartPointList());
|
||||
//update-end---author:jiangxh ---date:2026-06-22 for:【快检记录】更新时同步数据标准与曲线图-----------
|
||||
}
|
||||
|
||||
private void insertLines(String recordId, List<MesXslRubberQuickTestRecordLine> lineList) {
|
||||
@@ -128,6 +152,40 @@ public class MesXslRubberQuickTestRecordServiceImpl
|
||||
}
|
||||
//update-end---author:jiangxh ---date:2026-06-17 for:【快检记录】原始数据明细入库-----------
|
||||
|
||||
//update-begin---author:jiangxh ---date:2026-06-22 for:【快检记录】数据标准明细与曲线图入库-----------
|
||||
private void insertStdLines(String recordId, List<MesXslRubberQuickTestRecordStdLine> stdLineList) {
|
||||
if (CollectionUtils.isEmpty(stdLineList)) {
|
||||
return;
|
||||
}
|
||||
int sort = 0;
|
||||
for (MesXslRubberQuickTestRecordStdLine line : stdLineList) {
|
||||
if (line == null) {
|
||||
continue;
|
||||
}
|
||||
line.setId(null);
|
||||
line.setRecordId(recordId);
|
||||
line.setSortNo(sort++);
|
||||
mesXslRubberQuickTestRecordStdLineMapper.insert(line);
|
||||
}
|
||||
}
|
||||
|
||||
private void insertChartPoints(String recordId, List<MesXslRubberQuickTestRecordChartPoint> chartPointList) {
|
||||
if (CollectionUtils.isEmpty(chartPointList)) {
|
||||
return;
|
||||
}
|
||||
int sort = 0;
|
||||
for (MesXslRubberQuickTestRecordChartPoint point : chartPointList) {
|
||||
if (point == null) {
|
||||
continue;
|
||||
}
|
||||
point.setId(null);
|
||||
point.setRecordId(recordId);
|
||||
point.setSortNo(sort++);
|
||||
mesXslRubberQuickTestRecordChartPointMapper.insert(point);
|
||||
}
|
||||
}
|
||||
//update-end---author:jiangxh ---date:2026-06-22 for:【快检记录】数据标准明细与曲线图入库-----------
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delMain(String id) {
|
||||
@@ -135,6 +193,10 @@ public class MesXslRubberQuickTestRecordServiceImpl
|
||||
new LambdaQueryWrapper<MesXslRubberQuickTestRecordLine>().eq(MesXslRubberQuickTestRecordLine::getRecordId, id));
|
||||
mesXslRubberQuickTestRecordRawLineMapper.delete(
|
||||
new LambdaQueryWrapper<MesXslRubberQuickTestRecordRawLine>().eq(MesXslRubberQuickTestRecordRawLine::getRecordId, id));
|
||||
mesXslRubberQuickTestRecordStdLineMapper.delete(
|
||||
new LambdaQueryWrapper<MesXslRubberQuickTestRecordStdLine>().eq(MesXslRubberQuickTestRecordStdLine::getRecordId, id));
|
||||
mesXslRubberQuickTestRecordChartPointMapper.delete(
|
||||
new LambdaQueryWrapper<MesXslRubberQuickTestRecordChartPoint>().eq(MesXslRubberQuickTestRecordChartPoint::getRecordId, id));
|
||||
this.removeById(id);
|
||||
}
|
||||
|
||||
@@ -162,6 +224,22 @@ public class MesXslRubberQuickTestRecordServiceImpl
|
||||
.orderByAsc(MesXslRubberQuickTestRecordRawLine::getSortNo));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MesXslRubberQuickTestRecordStdLine> selectStdLinesByRecordId(String recordId) {
|
||||
return mesXslRubberQuickTestRecordStdLineMapper.selectList(
|
||||
new LambdaQueryWrapper<MesXslRubberQuickTestRecordStdLine>()
|
||||
.eq(MesXslRubberQuickTestRecordStdLine::getRecordId, recordId)
|
||||
.orderByAsc(MesXslRubberQuickTestRecordStdLine::getSortNo));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MesXslRubberQuickTestRecordChartPoint> selectChartPointsByRecordId(String recordId) {
|
||||
return mesXslRubberQuickTestRecordChartPointMapper.selectList(
|
||||
new LambdaQueryWrapper<MesXslRubberQuickTestRecordChartPoint>()
|
||||
.eq(MesXslRubberQuickTestRecordChartPoint::getRecordId, recordId)
|
||||
.orderByAsc(MesXslRubberQuickTestRecordChartPoint::getSortNo));
|
||||
}
|
||||
|
||||
//update-begin---author:jiangxh ---date:20260528 for:【MES】胶料快检记录单号JL+日期+4位流水自动生成-----------
|
||||
@Override
|
||||
public String generateRecordNo(MesXslRubberQuickTestRecord context) {
|
||||
@@ -256,69 +334,52 @@ public class MesXslRubberQuickTestRecordServiceImpl
|
||||
|
||||
@Override
|
||||
public void fillQuickTestTypeForRecord(MesXslRubberQuickTestRecord record) {
|
||||
if (record == null || oConvertUtils.isNotEmpty(record.getQuickTestTypeId())) {
|
||||
fillStdAndTypeForRecord(record);
|
||||
}
|
||||
|
||||
//update-begin---author:jiangxh ---date:2026-06-22 for:【快检记录】回填实验标准/方法/类型-----------
|
||||
@Override
|
||||
public void fillStdAndTypeForRecord(MesXslRubberQuickTestRecord record) {
|
||||
if (record == null) {
|
||||
return;
|
||||
}
|
||||
String testMethodId = null;
|
||||
String testMethodId = record.getTestMethodId();
|
||||
if (oConvertUtils.isNotEmpty(record.getStdId())) {
|
||||
MesXslRubberQuickTestStd std = mesXslRubberQuickTestStdService.getById(record.getStdId());
|
||||
if (std != null) {
|
||||
testMethodId = std.getTestMethodId();
|
||||
}
|
||||
if (oConvertUtils.isEmpty(record.getStdName())) {
|
||||
record.setStdName(std.getStdName());
|
||||
}
|
||||
if (oConvertUtils.isEmpty(testMethodId)) {
|
||||
return;
|
||||
testMethodId = std.getTestMethodId();
|
||||
record.setTestMethodId(testMethodId);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oConvertUtils.isNotEmpty(testMethodId) && oConvertUtils.isEmpty(record.getTestMethodName())) {
|
||||
MesXslRubberQuickTestMethod method = mesXslRubberQuickTestMethodService.getById(testMethodId);
|
||||
if (method != null && oConvertUtils.isNotEmpty(method.getQuickTestTypeId())) {
|
||||
if (method != null) {
|
||||
record.setTestMethodName(method.getMethodName());
|
||||
if (oConvertUtils.isEmpty(record.getQuickTestTypeId())
|
||||
&& oConvertUtils.isNotEmpty(method.getQuickTestTypeId())) {
|
||||
fillQuickTestType(record, method.getQuickTestTypeId());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oConvertUtils.isNotEmpty(record.getQuickTestTypeId()) && oConvertUtils.isEmpty(record.getQuickTestTypeName())) {
|
||||
fillQuickTestType(record, record.getQuickTestTypeId());
|
||||
}
|
||||
}
|
||||
//update-end---author:jiangxh ---date:2026-06-22 for:【快检记录】回填实验标准/方法/类型-----------
|
||||
//update-end---author:jiangxh ---date:20260618 for:【快检记录】桌面端快检记录号 yyyyMMdd+流水+胶料号-----------
|
||||
|
||||
//update-begin---author:jiangxh ---date:20260525 for:【MES】胶料信息多选按实验标准批量生成快检记录-----------
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public List<String> batchFromMaterial(MesXslRubberQuickTestRecordBatchFromMaterialVO vo) {
|
||||
if (vo == null || CollectionUtils.isEmpty(vo.getMaterialIds())) {
|
||||
throw new JeecgBootException("请至少选择一条胶料信息");
|
||||
}
|
||||
List<String> createdIds = new ArrayList<>();
|
||||
for (String materialId : vo.getMaterialIds()) {
|
||||
if (oConvertUtils.isEmpty(materialId)) {
|
||||
continue;
|
||||
}
|
||||
String mid = materialId.trim();
|
||||
MesMaterial material = mesMaterialService.getById(mid);
|
||||
if (material == null) {
|
||||
throw new JeecgBootException("胶料不存在:" + mid);
|
||||
}
|
||||
MesXslRubberQuickTestStd std = findApprovedStdForMaterial(mid);
|
||||
if (std == null) {
|
||||
throw new JeecgBootException(
|
||||
"胶料【" + material.getMaterialName() + "】未找到已启用且已批准的实验标准,请先在胶料快检实验标准中维护");
|
||||
}
|
||||
List<MesXslRubberQuickTestStdLine> stdLines = mesXslRubberQuickTestStdService.selectLinesByStdId(std.getId());
|
||||
if (CollectionUtils.isEmpty(stdLines)) {
|
||||
throw new JeecgBootException("胶料【" + material.getMaterialName() + "】关联的实验标准无明细数据");
|
||||
}
|
||||
MesXslRubberQuickTestRecord main = buildMainFromMaterial(material, std, vo);
|
||||
List<MesXslRubberQuickTestRecordLine> recordLines = new ArrayList<>();
|
||||
for (MesXslRubberQuickTestStdLine stdLine : stdLines) {
|
||||
MesXslRubberQuickTestRecordLine rl = new MesXslRubberQuickTestRecordLine();
|
||||
rl.setDataPointId(stdLine.getDataPointId());
|
||||
rl.setInspectItem(stdLine.getPointName());
|
||||
rl.setLowerLimit(stdLine.getLowerLimit());
|
||||
rl.setUpperLimit(stdLine.getUpperLimit());
|
||||
recordLines.add(rl);
|
||||
}
|
||||
saveMain(main, recordLines);
|
||||
createdIds.add(main.getId());
|
||||
}
|
||||
if (createdIds.isEmpty()) {
|
||||
throw new JeecgBootException("未生成任何快检记录");
|
||||
}
|
||||
return createdIds;
|
||||
//update-begin---author:jiangxh ---date:2026-06-22 for:【快检记录】取消胶料列表批量生成,改由桌面端同步-----------
|
||||
throw new JeecgBootException("胶料快检记录已改为由桌面端同步创建,请使用桌面端「胶料快检记录」功能");
|
||||
//update-end---author:jiangxh ---date:2026-06-22 for:【快检记录】取消胶料列表批量生成,改由桌面端同步-----------
|
||||
}
|
||||
|
||||
private MesXslRubberQuickTestStd findApprovedStdForMaterial(String materialId) {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
-- MES 胶料快检记录:主表扩展实验标准/方法字段;新增数据标准明细与曲线图明细
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
ALTER TABLE `mes_xsl_rubber_quick_test_record`
|
||||
ADD COLUMN `std_name` varchar(200) DEFAULT NULL COMMENT '实验标准名称冗余' AFTER `std_id`,
|
||||
ADD COLUMN `test_method_id` varchar(32) DEFAULT NULL COMMENT '实验方法ID' AFTER `std_name`,
|
||||
ADD COLUMN `test_method_name` varchar(200) DEFAULT NULL COMMENT '实验方法名称冗余' AFTER `test_method_id`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `mes_xsl_rubber_quick_test_record_std_line` (
|
||||
`id` varchar(32) NOT NULL COMMENT '主键',
|
||||
`record_id` varchar(32) NOT NULL COMMENT '主表 mes_xsl_rubber_quick_test_record.id',
|
||||
`data_point_id` varchar(32) DEFAULT NULL COMMENT '数据点ID',
|
||||
`point_name` varchar(128) DEFAULT NULL COMMENT '数据点名称',
|
||||
`lower_limit` decimal(18,6) DEFAULT NULL COMMENT '下限值',
|
||||
`lower_warn` decimal(18,6) DEFAULT NULL COMMENT '下警告值',
|
||||
`target_value` decimal(18,6) DEFAULT NULL COMMENT '目标值',
|
||||
`upper_warn` decimal(18,6) DEFAULT NULL COMMENT '上警告值',
|
||||
`upper_limit` decimal(18,6) DEFAULT NULL COMMENT '上限值',
|
||||
`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_std_record_id` (`record_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES胶料快检记录数据标准明细';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `mes_xsl_rubber_quick_test_record_chart_point` (
|
||||
`id` varchar(32) NOT NULL COMMENT '主键',
|
||||
`record_id` varchar(32) NOT NULL COMMENT '主表 mes_xsl_rubber_quick_test_record.id',
|
||||
`time_min` decimal(10,4) DEFAULT NULL COMMENT '时间(min)',
|
||||
`upper_temp` decimal(18,6) DEFAULT NULL COMMENT '上模温度',
|
||||
`lower_temp` decimal(18,6) DEFAULT NULL COMMENT '下模温度',
|
||||
`torque_s` decimal(18,6) DEFAULT NULL COMMENT 'S''(dNm)',
|
||||
`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_chart_record_id` (`record_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MES胶料快检记录曲线图数据点';
|
||||
@@ -5,15 +5,6 @@
|
||||
<a-button type="primary" v-auth="'mes:mes_material:add'" @click="handleAdd" preIcon="ant-design:plus-outlined">新增</a-button>
|
||||
<a-button type="primary" v-auth="'mes:mes_material:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls">导出</a-button>
|
||||
<j-upload-button type="primary" v-auth="'mes:mes_material:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
v-auth="'mes:mes_material:rubberQuickTestInspect'"
|
||||
preIcon="ant-design:experiment-outlined"
|
||||
:disabled="selectedRowKeys.length === 0"
|
||||
@click="handleRubberQuickTest"
|
||||
>
|
||||
检验
|
||||
</a-button>
|
||||
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
@@ -38,10 +29,7 @@ import { useListPage } from '/@/hooks/system/useListPage';
|
||||
import MesMaterialModal from './modules/MesMaterialModal.vue';
|
||||
import { columns, searchFormSchema } from './MesMaterial.data';
|
||||
import { batchDelete, deleteOne, getExportUrl, getImportUrl, list } from './MesMaterial.api';
|
||||
import { batchFromMaterial } from '/@/views/xslmes/mesXslRubberQuickTestRecord/MesXslRubberQuickTestRecord.api';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
const { tableContext, onExportXls, onImportXls } = useListPage({
|
||||
tableProps: {
|
||||
@@ -75,18 +63,6 @@ async function batchHandleDelete() {
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
async function handleRubberQuickTest() {
|
||||
if (!selectedRowKeys.value?.length) {
|
||||
createMessage.warning('请至少选择一条胶料');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await batchFromMaterial({ materialIds: [...selectedRowKeys.value] });
|
||||
createMessage.success('快检记录已生成,请到「胶料快检记录」中编辑');
|
||||
} catch (e: any) {
|
||||
createMessage.error(e?.message || '生成失败');
|
||||
}
|
||||
}
|
||||
function getTableAction(record) {
|
||||
return [{ label: '编辑', onClick: handleEdit.bind(null, record), auth: 'mes:mes_material:edit' }];
|
||||
}
|
||||
|
||||
@@ -13,7 +13,9 @@ enum Api {
|
||||
exportXls = '/xslmes/mesXslRubberQuickTestRecord/exportXls',
|
||||
queryById = '/xslmes/mesXslRubberQuickTestRecord/queryById',
|
||||
queryLineList = '/xslmes/mesXslRubberQuickTestRecord/queryLineListByRecordId',
|
||||
batchFromMaterial = '/xslmes/mesXslRubberQuickTestRecord/batchFromMaterial',
|
||||
queryStdLineList = '/xslmes/mesXslRubberQuickTestRecord/queryStdLineListByRecordId',
|
||||
queryRawLineList = '/xslmes/mesXslRubberQuickTestRecord/queryRawLineListByRecordId',
|
||||
queryChartPointList = '/xslmes/mesXslRubberQuickTestRecord/queryChartPointListByRecordId',
|
||||
}
|
||||
|
||||
export const getExportUrl = Api.exportXls;
|
||||
@@ -25,7 +27,11 @@ export const queryById = (params: { id: string }) => defHttp.get({ url: Api.quer
|
||||
|
||||
export const queryLineListByRecordId = (params: { id: string }) => defHttp.get({ url: Api.queryLineList, params });
|
||||
|
||||
export const batchFromMaterial = (params) => defHttp.post({ url: Api.batchFromMaterial, params });
|
||||
export const queryStdLineListByRecordId = (params: { id: string }) => defHttp.get({ url: Api.queryStdLineList, params });
|
||||
|
||||
export const queryRawLineListByRecordId = (params: { id: string }) => defHttp.get({ url: Api.queryRawLineList, params });
|
||||
|
||||
export const queryChartPointListByRecordId = (params: { id: string }) => defHttp.get({ url: Api.queryChartPointList, params });
|
||||
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
|
||||
|
||||
@@ -4,14 +4,13 @@ import { JVxeColumn, JVxeTypes } from '/@/components/jeecg/JVxeTable/types';
|
||||
const numProps = { style: { width: '100%' }, precision: 6 };
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{ title: '单号', align: 'center', dataIndex: 'recordNo', width: 150 },
|
||||
{ title: '快检记录号', align: 'center', dataIndex: 'recordNo', width: 150 },
|
||||
{ title: '胶料名称', align: 'center', dataIndex: 'rubberMaterialName', width: 140 },
|
||||
{ title: '生产机台', align: 'center', dataIndex: 'prodEquipmentName', width: 120 },
|
||||
{ title: '生产日期', align: 'center', dataIndex: 'productionDate', width: 110 },
|
||||
{ title: '炼机台', align: 'center', dataIndex: 'prodEquipmentName', width: 120 },
|
||||
{ title: '密炼日期', align: 'center', dataIndex: 'productionDate', width: 110 },
|
||||
{ title: '车次编号', align: 'center', dataIndex: 'trainNo', width: 100 },
|
||||
{ title: '班次', align: 'center', dataIndex: 'workShift_dictText', width: 80 },
|
||||
{ title: '班组', align: 'center', dataIndex: 'workTeam_dictText', width: 80 },
|
||||
{ title: '检验次数', align: 'center', dataIndex: 'inspectTimes', width: 90 },
|
||||
{ title: '试验次数', align: 'center', dataIndex: 'inspectTimes', width: 90 },
|
||||
{ title: '检验时间', align: 'center', dataIndex: 'inspectTime', width: 165 },
|
||||
{
|
||||
title: '检验人',
|
||||
@@ -20,22 +19,24 @@ export const columns: BasicColumn[] = [
|
||||
width: 100,
|
||||
customRender: ({ record }) => record?.inspectorRealname || record?.inspectorUserId_dictText || '',
|
||||
},
|
||||
{ title: '检验类型', align: 'center', dataIndex: 'quickTestTypeName', width: 120 },
|
||||
{ title: '实验标准', align: 'center', dataIndex: 'stdName', width: 120 },
|
||||
{ title: '实验方法', align: 'center', dataIndex: 'testMethodName', width: 120 },
|
||||
{ title: '实验类型', align: 'center', dataIndex: 'quickTestTypeName', width: 120 },
|
||||
{ title: '检验结果', align: 'center', dataIndex: 'inspectResult_dictText', width: 90 },
|
||||
{ title: '生产计划号', align: 'center', dataIndex: 'productionPlanNo', width: 120 },
|
||||
{ title: '密炼计划', align: 'center', dataIndex: 'productionPlanNo', width: 120 },
|
||||
{ title: '检验机台', align: 'center', dataIndex: 'inspectEquipmentName', width: 120 },
|
||||
{ title: '胶料卡片号', align: 'center', dataIndex: 'rubberCardNo', width: 120 },
|
||||
{ title: '胶料批次', align: 'center', dataIndex: 'rubberBatchNo', width: 120 },
|
||||
];
|
||||
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{ label: '单号', field: 'recordNo', component: 'Input', colProps: { span: 6 } },
|
||||
{ label: '快检记录号', field: 'recordNo', component: 'Input', colProps: { span: 6 } },
|
||||
{ label: '胶料名称', field: 'rubberMaterialName', component: 'Input', colProps: { span: 6 } },
|
||||
{
|
||||
label: '生产机台',
|
||||
label: '炼机台',
|
||||
field: 'prodEquipmentLedgerId',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: { dictCode: 'mes_xsl_equipment_ledger,equipment_name,id', placeholder: '请选择生产机台' },
|
||||
componentProps: { dictCode: 'mes_xsl_equipment_ledger,equipment_name,id', placeholder: '请选择炼机台' },
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
{
|
||||
@@ -53,20 +54,13 @@ export const searchFormSchema: FormSchema[] = [
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
{
|
||||
label: '班组',
|
||||
field: 'workTeam',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: { dictCode: 'xslmes_rubber_quick_test_work_team', placeholder: '请选择班组' },
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
{
|
||||
label: '检验类型',
|
||||
label: '实验类型',
|
||||
field: 'quickTestTypeId',
|
||||
component: 'JSearchSelect',
|
||||
componentProps: {
|
||||
dict: 'mes_xsl_rubber_quick_test_type,type_name,id',
|
||||
async: true,
|
||||
placeholder: '请选择检验类型',
|
||||
placeholder: '请选择实验类型',
|
||||
},
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
@@ -82,7 +76,7 @@ export const searchFormSchema: FormSchema[] = [
|
||||
},
|
||||
colProps: { span: 6 },
|
||||
},
|
||||
{ label: '生产计划号', field: 'productionPlanNo', component: 'Input', colProps: { span: 6 } },
|
||||
{ label: '密炼计划', field: 'productionPlanNo', component: 'Input', colProps: { span: 6 } },
|
||||
{ label: '胶料批次', field: 'rubberBatchNo', component: 'Input', colProps: { span: 6 } },
|
||||
{
|
||||
label: '检验结果',
|
||||
@@ -103,7 +97,7 @@ export const formSchema: FormSchema[] = [
|
||||
{ label: '', field: 'inspectorUsername', component: 'Input', show: false },
|
||||
{ label: '', field: 'quickTestTypeId', component: 'Input', show: false },
|
||||
{
|
||||
label: '单号',
|
||||
label: '快检记录号',
|
||||
field: 'recordNo',
|
||||
component: 'Input',
|
||||
componentProps: { readonly: true, placeholder: '保存时自动生成' },
|
||||
@@ -115,13 +109,31 @@ export const formSchema: FormSchema[] = [
|
||||
componentProps: { readonly: true },
|
||||
},
|
||||
{
|
||||
label: '生产机台',
|
||||
label: '实验标准',
|
||||
field: 'stdName',
|
||||
component: 'Input',
|
||||
componentProps: { readonly: true },
|
||||
},
|
||||
{
|
||||
label: '实验方法',
|
||||
field: 'testMethodName',
|
||||
component: 'Input',
|
||||
componentProps: { readonly: true },
|
||||
},
|
||||
{
|
||||
label: '实验类型',
|
||||
field: 'quickTestTypeName',
|
||||
component: 'Input',
|
||||
componentProps: { readonly: true },
|
||||
},
|
||||
{
|
||||
label: '炼机台',
|
||||
field: 'prodEquipmentName',
|
||||
component: 'Input',
|
||||
slot: 'prodEquipmentPicker',
|
||||
},
|
||||
{
|
||||
label: '生产日期',
|
||||
label: '密炼日期',
|
||||
field: 'productionDate',
|
||||
component: 'DatePicker',
|
||||
componentProps: { valueFormat: 'YYYY-MM-DD', style: { width: '100%' } },
|
||||
@@ -134,13 +146,7 @@ export const formSchema: FormSchema[] = [
|
||||
componentProps: { dictCode: 'xslmes_rubber_quick_test_work_shift', placeholder: '请选择班次' },
|
||||
},
|
||||
{
|
||||
label: '班组',
|
||||
field: 'workTeam',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: { dictCode: 'xslmes_rubber_quick_test_work_team', placeholder: '请选择班组' },
|
||||
},
|
||||
{
|
||||
label: '检验次数',
|
||||
label: '试验次数',
|
||||
field: 'inspectTimes',
|
||||
component: 'InputNumber',
|
||||
componentProps: { style: { width: '100%' }, min: 0, precision: 0 },
|
||||
@@ -176,23 +182,13 @@ export const formSchema: FormSchema[] = [
|
||||
}),
|
||||
},
|
||||
{ label: '', field: 'inspectorRealname', component: 'Input', show: false },
|
||||
{
|
||||
label: '检验类型',
|
||||
field: 'quickTestTypeId',
|
||||
component: 'JSearchSelect',
|
||||
componentProps: {
|
||||
dict: 'mes_xsl_rubber_quick_test_type,type_name,id',
|
||||
async: true,
|
||||
placeholder: '请选择检验类型',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '检验结果',
|
||||
field: 'inspectResult',
|
||||
component: 'JDictSelectTag',
|
||||
componentProps: { dictCode: 'xslmes_rubber_quick_test_record_result', placeholder: '合格/不合格' },
|
||||
},
|
||||
{ label: '生产计划号', field: 'productionPlanNo', component: 'Input' },
|
||||
{ label: '密炼计划', field: 'productionPlanNo', component: 'Input' },
|
||||
{
|
||||
label: '检验机台',
|
||||
field: 'inspectEquipmentName',
|
||||
@@ -203,6 +199,40 @@ export const formSchema: FormSchema[] = [
|
||||
{ label: '胶料批次', field: 'rubberBatchNo', component: 'Input' },
|
||||
];
|
||||
|
||||
export const stdLineJVxeColumns: JVxeColumn[] = [
|
||||
{ title: '', key: 'dataPointId', type: JVxeTypes.hidden },
|
||||
{ title: '数据点', key: 'pointName', type: JVxeTypes.normal, width: 160, disabled: true },
|
||||
{ title: '下限值', key: 'lowerLimit', type: JVxeTypes.normal, width: 100, disabled: true },
|
||||
{ title: '下警告值', key: 'lowerWarn', type: JVxeTypes.normal, width: 100, disabled: true },
|
||||
{ title: '目标值', key: 'targetValue', type: JVxeTypes.normal, width: 100, disabled: true },
|
||||
{ title: '上警告值', key: 'upperWarn', type: JVxeTypes.normal, width: 100, disabled: true },
|
||||
{ title: '上限值', key: 'upperLimit', type: JVxeTypes.normal, width: 100, disabled: true },
|
||||
];
|
||||
|
||||
export const rawLineJVxeColumns: JVxeColumn[] = [
|
||||
{ title: '', key: 'dataPointId', type: JVxeTypes.hidden },
|
||||
{ title: '编号', key: 'rowNo', type: JVxeTypes.normal, width: 90, disabled: true },
|
||||
{ title: '数据点', key: 'inspectItem', type: JVxeTypes.normal, width: 140, disabled: true },
|
||||
{ title: '下限值', key: 'lowerLimit', type: JVxeTypes.normal, width: 90, disabled: true },
|
||||
{ title: '上限值', key: 'upperLimit', type: JVxeTypes.normal, width: 90, disabled: true },
|
||||
{
|
||||
title: '检测值',
|
||||
key: 'inspectValue',
|
||||
type: JVxeTypes.inputNumber,
|
||||
width: 100,
|
||||
componentProps: numProps,
|
||||
},
|
||||
{
|
||||
title: '行检验结果',
|
||||
key: 'rowInspectResult',
|
||||
type: JVxeTypes.select,
|
||||
width: 110,
|
||||
disabled: true,
|
||||
dictCode: 'xslmes_rubber_quick_test_record_result',
|
||||
},
|
||||
];
|
||||
|
||||
/** @deprecated 历史汇总明细,仅兼容旧数据 */
|
||||
export const lineJVxeColumns: JVxeColumn[] = [
|
||||
{ title: '', key: 'dataPointId', type: JVxeTypes.hidden },
|
||||
{ title: '检验项目', key: 'inspectItem', type: JVxeTypes.normal, width: 180, disabled: true },
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
v-bind="$attrs"
|
||||
destroyOnClose
|
||||
:title="title"
|
||||
width="1100px"
|
||||
width="1200px"
|
||||
@register="registerModal"
|
||||
@ok="handleSubmit"
|
||||
>
|
||||
<BasicForm @register="registerForm">
|
||||
<template #prodEquipmentPicker="{ model, field }">
|
||||
<a-input-group compact style="display: flex; width: 100%">
|
||||
<a-input v-model:value="model[field]" read-only placeholder="请选择生产机台" style="flex: 1" />
|
||||
<a-input v-model:value="model[field]" read-only placeholder="请选择炼机台" style="flex: 1" />
|
||||
<a-button type="primary" :disabled="isDetail" @click="openProdEquipmentSelect">选择</a-button>
|
||||
<a-button v-if="model.prodEquipmentLedgerId && !isDetail" @click="clearProdEquipment(model)">清除</a-button>
|
||||
</a-input-group>
|
||||
@@ -23,34 +23,86 @@
|
||||
</a-input-group>
|
||||
</template>
|
||||
</BasicForm>
|
||||
<a-divider orientation="left">检验明细(由实验标准带出,不可增删)</a-divider>
|
||||
|
||||
<template v-if="useNewDetail">
|
||||
<a-divider orientation="left">数据标准明细</a-divider>
|
||||
<JVxeTable
|
||||
v-if="tableReady"
|
||||
row-number
|
||||
keep-source
|
||||
:toolbar="false"
|
||||
:insert-row="false"
|
||||
:remove-btn="false"
|
||||
:max-height="260"
|
||||
:loading="detailLoading"
|
||||
:columns="stdLineJVxeColumns"
|
||||
:dataSource="stdLineDataSource"
|
||||
disabled
|
||||
/>
|
||||
|
||||
<a-divider orientation="left">试验结果明细</a-divider>
|
||||
<JVxeTable
|
||||
v-if="tableReady"
|
||||
row-number
|
||||
keep-source
|
||||
:toolbar="false"
|
||||
:insert-row="false"
|
||||
:remove-btn="false"
|
||||
:max-height="320"
|
||||
:loading="detailLoading"
|
||||
:columns="rawLineJVxeColumns"
|
||||
:dataSource="rawLineDataSource"
|
||||
:disabled="isDetail"
|
||||
/>
|
||||
|
||||
<a-divider orientation="left">曲线图</a-divider>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<div class="chart-title">温度曲线(上模/下模)</div>
|
||||
<div ref="tempChartRef" class="chart-box"></div>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<div class="chart-title">S'(dNm) 曲线</div>
|
||||
<div ref="torqueChartRef" class="chart-box"></div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<a-divider orientation="left">检验明细(历史数据)</a-divider>
|
||||
<JVxeTable
|
||||
v-if="tableReady"
|
||||
ref="lineTableRef"
|
||||
row-number
|
||||
keep-source
|
||||
:toolbar="false"
|
||||
:insert-row="false"
|
||||
:remove-btn="false"
|
||||
:max-height="380"
|
||||
:loading="lineLoading"
|
||||
:loading="detailLoading"
|
||||
:columns="lineJVxeColumns"
|
||||
:dataSource="lineDataSource"
|
||||
:disabled="isDetail"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<MesXslEquipmentLedgerSelectModal @register="registerLedgerModal" @select="onLedgerSelect" />
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, unref } from 'vue';
|
||||
import { computed, nextTick, ref, unref, watch, type Ref } from 'vue';
|
||||
import { BasicModal, useModalInner, useModal } from '/@/components/Modal';
|
||||
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||
import type { JVxeTableInstance } from '/@/components/jeecg/JVxeTable/types';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { formSchema, lineJVxeColumns } from '../MesXslRubberQuickTestRecord.data';
|
||||
import { saveOrUpdate, queryById, queryLineListByRecordId } from '../MesXslRubberQuickTestRecord.api';
|
||||
import { useECharts } from '/@/hooks/web/useECharts';
|
||||
import {
|
||||
formSchema,
|
||||
lineJVxeColumns,
|
||||
stdLineJVxeColumns,
|
||||
rawLineJVxeColumns,
|
||||
} from '../MesXslRubberQuickTestRecord.data';
|
||||
import { saveOrUpdate, queryById, queryChartPointListByRecordId } from '../MesXslRubberQuickTestRecord.api';
|
||||
import MesXslEquipmentLedgerSelectModal from '/@/views/xslmes/mesXslEquipInspectConfig/components/MesXslEquipmentLedgerSelectModal.vue';
|
||||
|
||||
const emit = defineEmits(['register', 'success']);
|
||||
@@ -59,9 +111,19 @@
|
||||
|
||||
const isDetail = ref(false);
|
||||
const tableReady = ref(false);
|
||||
const lineLoading = ref(false);
|
||||
const detailLoading = ref(false);
|
||||
const useNewDetail = ref(false);
|
||||
|
||||
const stdLineDataSource = ref<Recordable[]>([]);
|
||||
const rawLineDataSource = ref<Recordable[]>([]);
|
||||
const chartPointDataSource = ref<Recordable[]>([]);
|
||||
const lineDataSource = ref<Recordable[]>([]);
|
||||
const lineTableRef = ref<JVxeTableInstance>();
|
||||
|
||||
const tempChartRef = ref<HTMLDivElement | null>(null);
|
||||
const torqueChartRef = ref<HTMLDivElement | null>(null);
|
||||
const { setOptions: setTempChartOptions, resize: resizeTempChart } = useECharts(tempChartRef as Ref<HTMLDivElement>);
|
||||
const { setOptions: setTorqueChartOptions, resize: resizeTorqueChart } = useECharts(torqueChartRef as Ref<HTMLDivElement>);
|
||||
|
||||
const ledgerPickTarget = ref<'prod' | 'inspect'>('prod');
|
||||
|
||||
const [registerForm, { resetFields, setFieldsValue, validate, setProps, getFieldsValue }] = useForm({
|
||||
@@ -75,19 +137,21 @@
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
tableReady.value = false;
|
||||
stdLineDataSource.value = [];
|
||||
rawLineDataSource.value = [];
|
||||
chartPointDataSource.value = [];
|
||||
lineDataSource.value = [];
|
||||
useNewDetail.value = false;
|
||||
await resetFields();
|
||||
setModalProps({ confirmLoading: false, showCancelBtn: data?.showFooter, showOkBtn: data?.showFooter });
|
||||
isDetail.value = !data?.showFooter;
|
||||
setProps({ disabled: !data?.showFooter });
|
||||
|
||||
if (data?.record?.id) {
|
||||
lineLoading.value = true;
|
||||
detailLoading.value = true;
|
||||
try {
|
||||
const mainRaw = await queryById({ id: data.record.id });
|
||||
const m = (mainRaw as any)?.id != null ? mainRaw : (mainRaw as any)?.result ?? mainRaw;
|
||||
const linesRaw = await queryLineListByRecordId({ id: data.record.id });
|
||||
const list = Array.isArray(linesRaw) ? linesRaw : (linesRaw as any)?.result ?? [];
|
||||
const patch: Recordable = { ...m };
|
||||
if (data?.showFooter && !patch.inspectorRealname && !patch.inspectorUserId) {
|
||||
const user = userStore.getUserInfo || {};
|
||||
@@ -96,16 +160,95 @@
|
||||
patch.inspectorRealname = user.realname;
|
||||
}
|
||||
await setFieldsValue(patch);
|
||||
lineDataSource.value = list || [];
|
||||
|
||||
const stdLines = m?.stdLineList ?? [];
|
||||
const rawLines = m?.rawLineList ?? [];
|
||||
let chartPoints = m?.chartPointList ?? [];
|
||||
const legacyLines = m?.lineList ?? [];
|
||||
|
||||
if (stdLines.length > 0 || rawLines.length > 0 || chartPoints.length > 0) {
|
||||
useNewDetail.value = true;
|
||||
stdLineDataSource.value = stdLines;
|
||||
rawLineDataSource.value = rawLines;
|
||||
if (!chartPoints.length && data?.record?.id) {
|
||||
try {
|
||||
const chartRes = await queryChartPointListByRecordId({ id: data.record.id });
|
||||
chartPoints = Array.isArray(chartRes) ? chartRes : (chartRes as any)?.result ?? [];
|
||||
} catch (_) {
|
||||
chartPoints = [];
|
||||
}
|
||||
}
|
||||
chartPointDataSource.value = chartPoints;
|
||||
} else {
|
||||
lineDataSource.value = legacyLines;
|
||||
}
|
||||
} finally {
|
||||
lineLoading.value = false;
|
||||
detailLoading.value = false;
|
||||
}
|
||||
}
|
||||
tableReady.value = true;
|
||||
if (useNewDetail.value) {
|
||||
await scheduleRenderCharts(chartPointDataSource.value);
|
||||
}
|
||||
});
|
||||
|
||||
async function scheduleRenderCharts(points: Recordable[]) {
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
window.setTimeout(() => {
|
||||
renderCharts(points);
|
||||
resizeTempChart();
|
||||
resizeTorqueChart();
|
||||
}, 120);
|
||||
}
|
||||
|
||||
watch(useNewDetail, async (visible) => {
|
||||
if (visible && chartPointDataSource.value.length) {
|
||||
await scheduleRenderCharts(chartPointDataSource.value);
|
||||
}
|
||||
});
|
||||
|
||||
const title = computed(() => (unref(isDetail) ? '快检记录详情' : '编辑胶料快检记录'));
|
||||
|
||||
function toChartNumber(value: unknown) {
|
||||
if (value === null || value === undefined || value === '') return null;
|
||||
const num = Number(value);
|
||||
return Number.isFinite(num) ? num : null;
|
||||
}
|
||||
|
||||
function renderCharts(points: Recordable[]) {
|
||||
if (!points?.length) {
|
||||
setTempChartOptions({ title: { text: '暂无曲线数据', left: 'center', top: 'center', textStyle: { fontSize: 14 } } });
|
||||
setTorqueChartOptions({ title: { text: '暂无曲线数据', left: 'center', top: 'center', textStyle: { fontSize: 14 } } });
|
||||
return;
|
||||
}
|
||||
const sorted = [...points].sort((a, b) => (a.sortNo ?? 0) - (b.sortNo ?? 0));
|
||||
const times = sorted.map((p) => toChartNumber(p.timeMin) ?? 0);
|
||||
|
||||
setTempChartOptions({
|
||||
title: undefined,
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { data: ['上模温度', '下模温度'] },
|
||||
grid: { left: 48, right: 24, top: 40, bottom: 32 },
|
||||
xAxis: { type: 'category', name: '时间(min)', data: times },
|
||||
yAxis: { type: 'value', name: '温度(℃)', min: 189, max: 201, interval: 3 },
|
||||
series: [
|
||||
{ name: '上模温度', type: 'line', smooth: true, data: sorted.map((p) => toChartNumber(p.upperTemp)) },
|
||||
{ name: '下模温度', type: 'line', smooth: true, data: sorted.map((p) => toChartNumber(p.lowerTemp)) },
|
||||
],
|
||||
});
|
||||
|
||||
setTorqueChartOptions({
|
||||
title: undefined,
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: { data: ["S'(dNm)"] },
|
||||
grid: { left: 48, right: 24, top: 40, bottom: 32 },
|
||||
xAxis: { type: 'category', name: '时间(min)', data: times },
|
||||
yAxis: { type: 'value', name: "S'(dNm)", min: 0, max: 14.8 },
|
||||
series: [{ name: "S'(dNm)", type: 'line', smooth: true, data: sorted.map((p) => toChartNumber(p.torqueS)) }],
|
||||
});
|
||||
}
|
||||
|
||||
function openProdEquipmentSelect() {
|
||||
ledgerPickTarget.value = 'prod';
|
||||
const vals = getFieldsValue();
|
||||
@@ -149,8 +292,18 @@
|
||||
}
|
||||
try {
|
||||
const values = await validate();
|
||||
const lineRef = lineTableRef.value as any;
|
||||
const tableData = (lineRef?.getTableData?.() || lineDataSource.value || []) as Recordable[];
|
||||
const payload: Recordable = { ...values };
|
||||
|
||||
if (unref(useNewDetail)) {
|
||||
payload.stdLineList = stdLineDataSource.value || [];
|
||||
payload.rawLineList = rawLineDataSource.value || [];
|
||||
payload.chartPointList = chartPointDataSource.value || [];
|
||||
if (!payload.stdLineList.length || !payload.rawLineList.length) {
|
||||
createMessage.warning('数据标准明细与试验结果明细不能为空');
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
const tableData = lineDataSource.value || [];
|
||||
const lineList = tableData
|
||||
.filter((r) => r && r.inspectItem)
|
||||
.map((r) => ({
|
||||
@@ -164,8 +317,11 @@
|
||||
createMessage.warning('检验明细不能为空');
|
||||
return;
|
||||
}
|
||||
payload.lineList = lineList;
|
||||
}
|
||||
|
||||
setModalProps({ confirmLoading: true });
|
||||
await saveOrUpdate({ ...values, lineList }, true);
|
||||
await saveOrUpdate(payload, true);
|
||||
closeModal();
|
||||
emit('success');
|
||||
} finally {
|
||||
@@ -173,3 +329,15 @@
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.chart-title {
|
||||
font-size: 13px;
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.chart-box {
|
||||
width: 100%;
|
||||
height: 220px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using Prism.Events;
|
||||
|
||||
namespace YY.Admin.Core.Events;
|
||||
|
||||
public class RubberQuickTestRecordChangedPayload
|
||||
{
|
||||
public string Action { get; set; } = string.Empty;
|
||||
public string? RecordId { get; set; }
|
||||
}
|
||||
|
||||
public class RubberQuickTestRecordChangedEvent : PubSubEvent<RubberQuickTestRecordChangedPayload> { }
|
||||
@@ -0,0 +1,31 @@
|
||||
using YY.Admin.Core.Entity;
|
||||
|
||||
namespace YY.Admin.Core.Services;
|
||||
|
||||
public interface IRubberQuickTestRecordService
|
||||
{
|
||||
Task<RubberQuickTestRecordPageResult> PageAsync(
|
||||
int pageNo,
|
||||
int pageSize,
|
||||
string? filterRecordNo = null,
|
||||
string? filterRubberMaterialName = null,
|
||||
string? filterPlanNo = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
Task<MesXslRubberQuickTestRecord?> GetByIdAsync(string id, CancellationToken ct = default);
|
||||
|
||||
RubberQuickTestRecordLocalItem? GetByLocalId(string localId);
|
||||
|
||||
Task<RubberQuickTestRecordSaveResult> SaveAsync(MesXslRubberQuickTestRecord entity, CancellationToken ct = default);
|
||||
|
||||
/// <summary>删除本地同步失败的快检记录(已同步或待同步不可删)</summary>
|
||||
bool DeleteFailedLocal(string localId);
|
||||
|
||||
string GenerateRecordNo(string rubberMaterialName);
|
||||
}
|
||||
|
||||
public record RubberQuickTestRecordPageResult(
|
||||
List<RubberQuickTestRecordListRow> Records,
|
||||
long Total,
|
||||
int PageNo,
|
||||
int PageSize);
|
||||
@@ -7,6 +7,9 @@ public class MesXslRubberQuickTestRecord
|
||||
public string? RubberMaterialId { get; set; }
|
||||
public string? RubberMaterialName { get; set; }
|
||||
public string? StdId { get; set; }
|
||||
public string? StdName { get; set; }
|
||||
public string? TestMethodId { get; set; }
|
||||
public string? TestMethodName { get; set; }
|
||||
public string? ProdEquipmentLedgerId { get; set; }
|
||||
public string? ProdEquipmentName { get; set; }
|
||||
public DateTime? ProductionDate { get; set; }
|
||||
@@ -17,8 +20,18 @@ public class MesXslRubberQuickTestRecord
|
||||
public string? InspectorUserId { get; set; }
|
||||
public string? InspectorUsername { get; set; }
|
||||
public string? InspectorRealname { get; set; }
|
||||
public string? QuickTestTypeId { get; set; }
|
||||
public string? QuickTestTypeName { get; set; }
|
||||
public string? InspectResult { get; set; }
|
||||
public string? ProductionPlanNo { get; set; }
|
||||
public List<MesXslRubberQuickTestRecordLine>? LineList { get; set; }
|
||||
public DateTime? CreateTime { get; set; }
|
||||
public List<MesXslRubberQuickTestRecordStdLine>? StdLineList { get; set; }
|
||||
public List<MesXslRubberQuickTestRecordRawLine>? RawLineList { get; set; }
|
||||
public List<MesXslRubberQuickTestRecordChartPoint>? ChartPointList { get; set; }
|
||||
|
||||
/// <summary>列表展示:班次文本</summary>
|
||||
public string? WorkShiftText { get; set; }
|
||||
|
||||
/// <summary>列表展示:是否合格</summary>
|
||||
public string? InspectResultText { get; set; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace YY.Admin.Core.Entity;
|
||||
|
||||
/// <summary>胶料快检记录曲线图数据点</summary>
|
||||
public class MesXslRubberQuickTestRecordChartPoint
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? RecordId { get; set; }
|
||||
public decimal? TimeMin { get; set; }
|
||||
public decimal? UpperTemp { get; set; }
|
||||
public decimal? LowerTemp { get; set; }
|
||||
public decimal? TorqueS { get; set; }
|
||||
public int? SortNo { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace YY.Admin.Core.Entity;
|
||||
|
||||
/// <summary>胶料快检记录数据标准明细(实验标准快照)</summary>
|
||||
public class MesXslRubberQuickTestRecordStdLine
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public string? RecordId { 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; }
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
namespace YY.Admin.Core.Entity;
|
||||
|
||||
/// <summary>胶料快检记录列表行</summary>
|
||||
public class RubberQuickTestRecordListRow
|
||||
{
|
||||
public string? LocalId { get; set; }
|
||||
public string? MesId { get; set; }
|
||||
public string? RecordNo { get; set; }
|
||||
public DateTime? ProductionDate { get; set; }
|
||||
public string? ProdEquipmentName { get; set; }
|
||||
public string? WorkShiftDisplay { get; set; }
|
||||
public string? ProductionPlanNo { get; set; }
|
||||
public string? RubberMaterialName { get; set; }
|
||||
public string? StdName { get; set; }
|
||||
public string? TestMethodName { get; set; }
|
||||
public string? QuickTestTypeName { get; set; }
|
||||
public string? TrainNo { get; set; }
|
||||
public int? InspectTimes { get; set; }
|
||||
public string? InspectorRealname { get; set; }
|
||||
public DateTime? InspectDate { get; set; }
|
||||
public string? InspectResultDisplay { get; set; }
|
||||
public string SyncStatus { get; set; } = "Pending";
|
||||
public string SyncStatusDisplay => SyncStatus switch
|
||||
{
|
||||
"Synced" => "已同步",
|
||||
"Failed" => "失败",
|
||||
_ => "待同步"
|
||||
};
|
||||
|
||||
/// <summary>仅本地同步失败记录可删除</summary>
|
||||
public bool CanDelete => SyncStatus == "Failed" && !string.IsNullOrWhiteSpace(LocalId);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace YY.Admin.Core.Entity;
|
||||
|
||||
/// <summary>桌面端本地胶料快检记录包装(含同步状态)</summary>
|
||||
public class RubberQuickTestRecordLocalItem
|
||||
{
|
||||
public string LocalId { get; set; } = Guid.NewGuid().ToString("N");
|
||||
public string? MesId { get; set; }
|
||||
/// <summary>Pending / Synced / Failed</summary>
|
||||
public string SyncStatus { get; set; } = "Pending";
|
||||
public string? SyncError { get; set; }
|
||||
public DateTime LocalCreateTime { get; set; } = DateTime.Now;
|
||||
public MesXslRubberQuickTestRecord Record { get; set; } = new();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace YY.Admin.Core.Entity;
|
||||
|
||||
public class RubberQuickTestRecordSaveResult
|
||||
{
|
||||
public MesXslRubberQuickTestRecord Record { get; set; } = new();
|
||||
public string LocalId { get; set; } = string.Empty;
|
||||
public string SyncStatus { get; set; } = "Pending";
|
||||
}
|
||||
@@ -51,7 +51,7 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
|
||||
// 胶料快检实验标准(桌面端只读)
|
||||
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 },
|
||||
// 胶料快检记录(紧接实验标准之后)
|
||||
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=113 },
|
||||
new SysMenu{ Id=1300150011201, Pid=1300150000101, Title="胶料快检记录", Path="/xslmes/rubberQuickTestRecord", Name="rubberQuickTestRecord", Component="RubberQuickTestRecordListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=113 },
|
||||
// 密炼计划
|
||||
new SysMenu{ Id=1300150011401, Pid=1300150000101, Title="密炼计划", Path="/xslmes/mesXslMixingProductionPlan", Name="mesXslMixingProductionPlan", Component="MixingProductionPlanListView", Icon="", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=114 },
|
||||
|
||||
|
||||
@@ -518,6 +518,9 @@ namespace YY.Admin.Core.SqlSugar
|
||||
|
||||
dbProvider.Updateable<SysMenu>()
|
||||
.SetColumns(m => m.Title == "胶料快检记录")
|
||||
.SetColumns(m => m.Path == "/xslmes/rubberQuickTestRecord")
|
||||
.SetColumns(m => m.Name == "rubberQuickTestRecord")
|
||||
.SetColumns(m => m.Component == "RubberQuickTestRecordListView")
|
||||
.SetColumns(m => m.OrderNo == 113)
|
||||
.Where(m => m.Id == quickTestRecordMenuId)
|
||||
.ExecuteCommand();
|
||||
|
||||
@@ -0,0 +1,502 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Prism.Events;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
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.RubberQuickTest;
|
||||
|
||||
public class RubberQuickTestRecordService : IRubberQuickTestRecordService, 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<RubberQuickTestRecordLocalItem> _localItems = new();
|
||||
|
||||
private static readonly JsonSerializerOptions _jsonOpts = new()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
||||
Converters = { new NullableDateTimeJsonConverter() }
|
||||
};
|
||||
|
||||
public RubberQuickTestRecordService(
|
||||
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, "rubber-quick-test-record-items.json");
|
||||
|
||||
LoadCacheFromDisk();
|
||||
_logger.Information($"[快检记录同步] 初始化完成,本地记录={_localItems.Count}");
|
||||
|
||||
_networkMonitor.StatusChanged += OnNetworkStatusChanged;
|
||||
if (_networkMonitor.IsOnline)
|
||||
_ = Task.Run(() => PushPendingAsync(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<RubberQuickTestRecordPageResult> PageAsync(
|
||||
int pageNo, int pageSize,
|
||||
string? filterRecordNo = null,
|
||||
string? filterRubberMaterialName = null,
|
||||
string? filterPlanNo = null,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
var rows = await BuildAllRowsAsync(ct).ConfigureAwait(false);
|
||||
var filtered = ApplyFilters(rows, filterRecordNo, filterRubberMaterialName, filterPlanNo);
|
||||
var total = filtered.Count;
|
||||
var records = filtered
|
||||
.OrderByDescending(r => r.InspectDate ?? DateTime.MinValue)
|
||||
.Skip(Math.Max(0, (pageNo - 1) * pageSize))
|
||||
.Take(pageSize)
|
||||
.ToList();
|
||||
return new RubberQuickTestRecordPageResult(records, total, pageNo, pageSize);
|
||||
}
|
||||
|
||||
public async Task<MesXslRubberQuickTestRecord?> GetByIdAsync(string id, CancellationToken ct = default)
|
||||
{
|
||||
RubberQuickTestRecordLocalItem? local = null;
|
||||
lock (_cacheLock)
|
||||
{
|
||||
local = _localItems.FirstOrDefault(x =>
|
||||
string.Equals(x.LocalId, id, StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(x.MesId, id, StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(x.Record.RecordNo, id, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
if (local != null)
|
||||
return CloneRecord(local.Record);
|
||||
|
||||
if (_networkMonitor.IsOnline)
|
||||
{
|
||||
try
|
||||
{
|
||||
var url = $"{BaseUrl}/xslmes/mesXslRubberQuickTestRecord/anon/queryById?id={Uri.EscapeDataString(id)}&tenantId={DefaultTenantId}";
|
||||
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))
|
||||
return resultEl.Deserialize<MesXslRubberQuickTestRecord>(_jsonOpts);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warning($"[快检记录详情] 远端查询异常 id={id}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public RubberQuickTestRecordLocalItem? GetByLocalId(string localId)
|
||||
{
|
||||
lock (_cacheLock)
|
||||
{
|
||||
var item = _localItems.FirstOrDefault(x => string.Equals(x.LocalId, localId, StringComparison.OrdinalIgnoreCase));
|
||||
return item == null ? null : CloneLocalItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RubberQuickTestRecordSaveResult> SaveAsync(MesXslRubberQuickTestRecord entity, CancellationToken ct = default)
|
||||
{
|
||||
var record = CloneRecord(entity);
|
||||
record.CreateTime ??= DateTime.Now;
|
||||
record.InspectTime ??= record.CreateTime;
|
||||
|
||||
var item = new RubberQuickTestRecordLocalItem
|
||||
{
|
||||
LocalId = Guid.NewGuid().ToString("N"),
|
||||
LocalCreateTime = DateTime.Now,
|
||||
SyncStatus = "Pending",
|
||||
Record = record
|
||||
};
|
||||
|
||||
if (_networkMonitor.IsOnline)
|
||||
{
|
||||
try
|
||||
{
|
||||
var recordNo = await RemoteAddAsync(record, ct).ConfigureAwait(false);
|
||||
if (!string.IsNullOrWhiteSpace(recordNo))
|
||||
{
|
||||
item.Record.RecordNo = recordNo;
|
||||
item.SyncStatus = "Synced";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
item.SyncStatus = "Failed";
|
||||
item.SyncError = ex.Message;
|
||||
_logger.Warning($"[快检记录新增] 远端失败,保留本地:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
lock (_cacheLock)
|
||||
{
|
||||
_localItems.Add(CloneLocalItem(item));
|
||||
SaveCacheToDiskUnsafe();
|
||||
}
|
||||
|
||||
_eventAggregator.GetEvent<RubberQuickTestRecordChangedEvent>()
|
||||
.Publish(new RubberQuickTestRecordChangedPayload { Action = "add", RecordId = item.LocalId });
|
||||
|
||||
return new RubberQuickTestRecordSaveResult
|
||||
{
|
||||
LocalId = item.LocalId,
|
||||
SyncStatus = item.SyncStatus,
|
||||
Record = CloneRecord(item.Record)
|
||||
};
|
||||
}
|
||||
|
||||
public bool DeleteFailedLocal(string localId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(localId)) return false;
|
||||
|
||||
bool removed;
|
||||
lock (_cacheLock)
|
||||
{
|
||||
var item = _localItems.FirstOrDefault(x =>
|
||||
string.Equals(x.LocalId, localId.Trim(), StringComparison.OrdinalIgnoreCase));
|
||||
if (item == null || !string.Equals(item.SyncStatus, "Failed", StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
|
||||
removed = _localItems.Remove(item);
|
||||
if (removed)
|
||||
SaveCacheToDiskUnsafe();
|
||||
}
|
||||
|
||||
if (!removed) return false;
|
||||
|
||||
_eventAggregator.GetEvent<RubberQuickTestRecordChangedEvent>()
|
||||
.Publish(new RubberQuickTestRecordChangedPayload { Action = "delete", RecordId = localId });
|
||||
_logger.Information($"[快检记录删除] 已删除同步失败本地记录 localId={localId}");
|
||||
return true;
|
||||
}
|
||||
|
||||
public string GenerateRecordNo(string rubberMaterialName)
|
||||
{
|
||||
var dateStr = DateTime.Now.ToString("yyyyMMdd");
|
||||
var material = rubberMaterialName.Trim();
|
||||
int maxSeq = 0;
|
||||
lock (_cacheLock)
|
||||
{
|
||||
foreach (var item in _localItems)
|
||||
{
|
||||
var no = item.Record.RecordNo;
|
||||
if (string.IsNullOrWhiteSpace(no) || !no.StartsWith(dateStr, StringComparison.Ordinal) || !no.EndsWith(material, StringComparison.Ordinal))
|
||||
continue;
|
||||
var seqPart = no.Substring(dateStr.Length, Math.Min(4, no.Length - dateStr.Length - material.Length));
|
||||
if (int.TryParse(seqPart, out var seq))
|
||||
maxSeq = Math.Max(maxSeq, seq);
|
||||
}
|
||||
}
|
||||
return dateStr + (maxSeq + 1).ToString("D4") + material;
|
||||
}
|
||||
|
||||
private async Task<List<RubberQuickTestRecordListRow>> BuildAllRowsAsync(CancellationToken ct)
|
||||
{
|
||||
var rows = new List<RubberQuickTestRecordListRow>();
|
||||
var seenRecordNos = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
lock (_cacheLock)
|
||||
{
|
||||
foreach (var item in _localItems)
|
||||
{
|
||||
rows.Add(ToListRow(item));
|
||||
if (!string.IsNullOrWhiteSpace(item.Record.RecordNo))
|
||||
seenRecordNos.Add(item.Record.RecordNo);
|
||||
}
|
||||
}
|
||||
|
||||
if (_networkMonitor.IsOnline)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var remote in await FetchRemoteListAsync(ct).ConfigureAwait(false))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(remote.RecordNo) && seenRecordNos.Contains(remote.RecordNo))
|
||||
continue;
|
||||
rows.Add(ToListRow(remote, "Synced", remote.Id));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warning($"[快检记录列表] 远端拉取失败:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
private static RubberQuickTestRecordListRow ToListRow(RubberQuickTestRecordLocalItem item) =>
|
||||
ToListRow(item.Record, item.SyncStatus, item.MesId, item.LocalId);
|
||||
|
||||
private static RubberQuickTestRecordListRow ToListRow(
|
||||
MesXslRubberQuickTestRecord r,
|
||||
string syncStatus,
|
||||
string? mesId = null,
|
||||
string? localId = null) => new()
|
||||
{
|
||||
LocalId = localId,
|
||||
MesId = mesId ?? r.Id,
|
||||
RecordNo = r.RecordNo,
|
||||
ProductionDate = r.ProductionDate,
|
||||
ProdEquipmentName = r.ProdEquipmentName,
|
||||
WorkShiftDisplay = r.WorkShiftText ?? r.WorkShift,
|
||||
ProductionPlanNo = r.ProductionPlanNo,
|
||||
RubberMaterialName = r.RubberMaterialName,
|
||||
StdName = r.StdName,
|
||||
TestMethodName = r.TestMethodName,
|
||||
QuickTestTypeName = r.QuickTestTypeName,
|
||||
TrainNo = r.TrainNo,
|
||||
InspectTimes = r.InspectTimes,
|
||||
InspectorRealname = r.InspectorRealname,
|
||||
InspectDate = r.CreateTime ?? r.InspectTime,
|
||||
InspectResultDisplay = r.InspectResultText ?? (r.InspectResult == "1" ? "合格" : r.InspectResult == "0" ? "不合格" : ""),
|
||||
SyncStatus = syncStatus
|
||||
};
|
||||
|
||||
private async Task<string?> RemoteAddAsync(MesXslRubberQuickTestRecord entity, CancellationToken ct)
|
||||
{
|
||||
var url = $"{BaseUrl}/xslmes/mesXslRubberQuickTestRecord/anon/add?tenantId={DefaultTenantId}";
|
||||
var payload = CloneRecord(entity);
|
||||
payload.Id = null;
|
||||
|
||||
using var client = CreateClient();
|
||||
var body = JsonSerializer.Serialize(payload, _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 ?? "保存失败");
|
||||
}
|
||||
|
||||
if (doc.RootElement.TryGetProperty("result", out var resultEl) && resultEl.ValueKind == JsonValueKind.String)
|
||||
return resultEl.GetString();
|
||||
return entity.RecordNo;
|
||||
}
|
||||
|
||||
private async Task<List<MesXslRubberQuickTestRecord>> FetchRemoteListAsync(CancellationToken ct)
|
||||
{
|
||||
var query = HttpUtility.ParseQueryString(string.Empty);
|
||||
query["pageNo"] = "1";
|
||||
query["pageSize"] = "10000";
|
||||
query["tenantId"] = DefaultTenantId.ToString();
|
||||
var url = $"{BaseUrl}/xslmes/mesXslRubberQuickTestRecord/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 result = doc.RootElement.GetProperty("result");
|
||||
return result.GetProperty("records").Deserialize<List<MesXslRubberQuickTestRecord>>(_jsonOpts) ?? new();
|
||||
}
|
||||
|
||||
private void OnNetworkStatusChanged(bool isOnline)
|
||||
{
|
||||
if (!isOnline) return;
|
||||
_ = Task.Run(() => PushPendingAsync(CancellationToken.None));
|
||||
}
|
||||
|
||||
private async Task PushPendingAsync(CancellationToken ct)
|
||||
{
|
||||
if (!await _syncLock.WaitAsync(0, ct).ConfigureAwait(false)) return;
|
||||
try
|
||||
{
|
||||
List<RubberQuickTestRecordLocalItem> pending;
|
||||
lock (_cacheLock)
|
||||
{
|
||||
pending = _localItems.Where(x => x.SyncStatus != "Synced").Select(CloneLocalItem).ToList();
|
||||
}
|
||||
|
||||
foreach (var item in pending)
|
||||
{
|
||||
if (!_networkMonitor.IsOnline) break;
|
||||
try
|
||||
{
|
||||
var recordNo = await RemoteAddAsync(item.Record, ct).ConfigureAwait(false);
|
||||
lock (_cacheLock)
|
||||
{
|
||||
var target = _localItems.FirstOrDefault(x => x.LocalId == item.LocalId);
|
||||
if (target == null) continue;
|
||||
if (!string.IsNullOrWhiteSpace(recordNo))
|
||||
target.Record.RecordNo = recordNo;
|
||||
target.SyncStatus = "Synced";
|
||||
target.SyncError = null;
|
||||
SaveCacheToDiskUnsafe();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
lock (_cacheLock)
|
||||
{
|
||||
var target = _localItems.FirstOrDefault(x => x.LocalId == item.LocalId);
|
||||
if (target != null)
|
||||
{
|
||||
target.SyncStatus = "Failed";
|
||||
target.SyncError = ex.Message;
|
||||
SaveCacheToDiskUnsafe();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_syncLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
private static List<RubberQuickTestRecordListRow> ApplyFilters(
|
||||
List<RubberQuickTestRecordListRow> source,
|
||||
string? filterRecordNo,
|
||||
string? filterRubberMaterialName,
|
||||
string? filterPlanNo)
|
||||
{
|
||||
IEnumerable<RubberQuickTestRecordListRow> q = source;
|
||||
if (!string.IsNullOrWhiteSpace(filterRecordNo))
|
||||
q = q.Where(r => (r.RecordNo ?? "").Contains(filterRecordNo.Trim(), StringComparison.OrdinalIgnoreCase));
|
||||
if (!string.IsNullOrWhiteSpace(filterRubberMaterialName))
|
||||
q = q.Where(r => (r.RubberMaterialName ?? "").Contains(filterRubberMaterialName.Trim(), StringComparison.OrdinalIgnoreCase));
|
||||
if (!string.IsNullOrWhiteSpace(filterPlanNo))
|
||||
q = q.Where(r => (r.ProductionPlanNo ?? "").Contains(filterPlanNo.Trim(), StringComparison.OrdinalIgnoreCase));
|
||||
return q.ToList();
|
||||
}
|
||||
|
||||
private void LoadCacheFromDisk()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(_cacheFilePath)) return;
|
||||
var data = JsonSerializer.Deserialize<List<RubberQuickTestRecordLocalItem>>(File.ReadAllText(_cacheFilePath), _jsonOpts);
|
||||
_localItems = data ?? new();
|
||||
}
|
||||
catch { _localItems = new(); }
|
||||
}
|
||||
|
||||
private void SaveCacheToDiskUnsafe() =>
|
||||
File.WriteAllText(_cacheFilePath, JsonSerializer.Serialize(_localItems, _jsonOpts));
|
||||
|
||||
private static RubberQuickTestRecordLocalItem CloneLocalItem(RubberQuickTestRecordLocalItem src) => new()
|
||||
{
|
||||
LocalId = src.LocalId,
|
||||
MesId = src.MesId,
|
||||
SyncStatus = src.SyncStatus,
|
||||
SyncError = src.SyncError,
|
||||
LocalCreateTime = src.LocalCreateTime,
|
||||
Record = CloneRecord(src.Record)
|
||||
};
|
||||
|
||||
private static MesXslRubberQuickTestRecord CloneRecord(MesXslRubberQuickTestRecord src) => new()
|
||||
{
|
||||
Id = src.Id,
|
||||
RecordNo = src.RecordNo,
|
||||
RubberMaterialId = src.RubberMaterialId,
|
||||
RubberMaterialName = src.RubberMaterialName,
|
||||
StdId = src.StdId,
|
||||
StdName = src.StdName,
|
||||
TestMethodId = src.TestMethodId,
|
||||
TestMethodName = src.TestMethodName,
|
||||
ProdEquipmentLedgerId = src.ProdEquipmentLedgerId,
|
||||
ProdEquipmentName = src.ProdEquipmentName,
|
||||
ProductionDate = src.ProductionDate,
|
||||
TrainNo = src.TrainNo,
|
||||
WorkShift = src.WorkShift,
|
||||
InspectTimes = src.InspectTimes,
|
||||
InspectTime = src.InspectTime,
|
||||
InspectorUserId = src.InspectorUserId,
|
||||
InspectorUsername = src.InspectorUsername,
|
||||
InspectorRealname = src.InspectorRealname,
|
||||
QuickTestTypeId = src.QuickTestTypeId,
|
||||
QuickTestTypeName = src.QuickTestTypeName,
|
||||
InspectResult = src.InspectResult,
|
||||
ProductionPlanNo = src.ProductionPlanNo,
|
||||
CreateTime = src.CreateTime,
|
||||
StdLineList = src.StdLineList?.Select(l => new MesXslRubberQuickTestRecordStdLine
|
||||
{
|
||||
Id = l.Id, RecordId = l.RecordId, 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(),
|
||||
RawLineList = src.RawLineList?.Select(l => new MesXslRubberQuickTestRecordRawLine
|
||||
{
|
||||
Id = l.Id, RecordId = l.RecordId, RowNo = l.RowNo, DataPointId = l.DataPointId,
|
||||
InspectItem = l.InspectItem, LowerLimit = l.LowerLimit, UpperLimit = l.UpperLimit,
|
||||
InspectValue = l.InspectValue, RowInspectResult = l.RowInspectResult, SortNo = l.SortNo
|
||||
}).ToList(),
|
||||
ChartPointList = src.ChartPointList?.Select(p => new MesXslRubberQuickTestRecordChartPoint
|
||||
{
|
||||
Id = p.Id, RecordId = p.RecordId, TimeMin = p.TimeMin, UpperTemp = p.UpperTemp,
|
||||
LowerTemp = p.LowerTemp, TorqueS = p.TorqueS, SortNo = p.SortNo
|
||||
}).ToList(),
|
||||
WorkShiftText = src.WorkShiftText,
|
||||
InspectResultText = src.InspectResultText
|
||||
};
|
||||
|
||||
private sealed class NullableDateTimeJsonConverter : JsonConverter<DateTime?>
|
||||
{
|
||||
private static readonly string[] SupportedFormats =
|
||||
[
|
||||
"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, SupportedFormats,
|
||||
System.Globalization.CultureInfo.InvariantCulture,
|
||||
System.Globalization.DateTimeStyles.AssumeLocal, out var exact)) return exact;
|
||||
if (DateTime.TryParse(raw, out var fallback)) return fallback;
|
||||
}
|
||||
throw new JsonException($"无法转换为 DateTime?,token={reader.TokenType}");
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options)
|
||||
{
|
||||
if (value == null) writer.WriteNullValue();
|
||||
else writer.WriteStringValue(value.Value.ToString("yyyy-MM-dd HH:mm:ss"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,6 +99,7 @@ namespace YY.Admin
|
||||
// 密炼物料皮重策略
|
||||
containerRegistry.RegisterForNavigation<MixerMaterialTareStrategyListView>();
|
||||
// 胶料快检记录操作台
|
||||
containerRegistry.RegisterForNavigation<RubberQuickTestRecordListView>();
|
||||
containerRegistry.RegisterForNavigation<RubberQuickTestOperationView>();
|
||||
// 胶料快检实验标准(只读)
|
||||
containerRegistry.RegisterForNavigation<RubberQuickTestStdListView>();
|
||||
|
||||
@@ -89,7 +89,8 @@ public class SyncModule : IModule
|
||||
containerRegistry.RegisterSingleton<PrintTemplateSyncCoordinator>();
|
||||
containerRegistry.RegisterSingleton<PrintBizTemplateBindSyncCoordinator>();
|
||||
|
||||
// 胶料快检记录操作台
|
||||
// 胶料快检记录:本地存储 + MES 同步
|
||||
containerRegistry.RegisterSingleton<IRubberQuickTestRecordService, RubberQuickTestRecordService>();
|
||||
containerRegistry.RegisterSingleton<IRubberQuickTestOperationService, RubberQuickTestOperationService>();
|
||||
|
||||
// 胶料快检实验标准(MES 只读同步)
|
||||
|
||||
@@ -153,6 +153,9 @@ namespace YY.Admin.ViewModels.Control
|
||||
["mesXslMixerMaterialTareStrategy"] = "MixerMaterialTareStrategyListView",
|
||||
|
||||
// 已实现页面:胶料快检记录操作台
|
||||
["RubberQuickTestRecordListView"] = "RubberQuickTestRecordListView",
|
||||
["/xslmes/rubberQuickTestRecord"] = "RubberQuickTestRecordListView",
|
||||
["rubberQuickTestRecord"] = "RubberQuickTestRecordListView",
|
||||
["RubberQuickTestOperationView"] = "RubberQuickTestOperationView",
|
||||
["/xslmes/rubberQuickTestOperation"] = "RubberQuickTestOperationView",
|
||||
["rubberQuickTestOperation"] = "RubberQuickTestOperationView",
|
||||
|
||||
@@ -10,9 +10,12 @@ using Prism.Events;
|
||||
|
||||
using Prism.Mvvm;
|
||||
|
||||
using Prism.Navigation;
|
||||
|
||||
using SkiaSharp;
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading;
|
||||
|
||||
using YY.Admin.Core;
|
||||
|
||||
@@ -165,11 +168,11 @@ public class QuickTestInspectRowViewModel : BindableBase
|
||||
|
||||
/// <summary>胶料快检记录操作台 ViewModel(密炼计划、实验标准均读本地缓存)</summary>
|
||||
|
||||
public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||
public class RubberQuickTestOperationViewModel : BaseViewModel, INavigationAware
|
||||
|
||||
{
|
||||
|
||||
private readonly IRubberQuickTestOperationService _operationService;
|
||||
private readonly IRubberQuickTestRecordService _recordService;
|
||||
|
||||
private readonly IMixingProductionPlanService _planService;
|
||||
|
||||
@@ -177,6 +180,12 @@ public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||
|
||||
private readonly Random _rnd = new();
|
||||
|
||||
private bool _saveInProgress;
|
||||
|
||||
private string? _loadedDetailLocalId;
|
||||
private string? _loadedDetailMesId;
|
||||
private int _navigationApplyVersion;
|
||||
|
||||
private List<MesXslMixingProductionPlan> _allPlans = new();
|
||||
|
||||
private List<MesXslRubberQuickTestStd> _allStds = new();
|
||||
@@ -200,7 +209,7 @@ public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||
|
||||
public RubberQuickTestOperationViewModel(
|
||||
|
||||
IRubberQuickTestOperationService operationService,
|
||||
IRubberQuickTestRecordService recordService,
|
||||
|
||||
IMixingProductionPlanService planService,
|
||||
|
||||
@@ -212,7 +221,7 @@ public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||
|
||||
{
|
||||
|
||||
_operationService = operationService;
|
||||
_recordService = recordService;
|
||||
|
||||
_planService = planService;
|
||||
|
||||
@@ -228,7 +237,7 @@ public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||
|
||||
RemoveInspectRowCommand = new DelegateCommand(() => RemoveInspectRow(SelectedInspectRow), () => SelectedInspectRow != null);
|
||||
|
||||
SaveCommand = new DelegateCommand(async () => await SaveAsync(), () => InspectRows.Count > 0);
|
||||
SaveCommand = new DelegateCommand(async () => await SaveAsync(), () => CanSave);
|
||||
|
||||
RefreshPlansCommand = new DelegateCommand(async () => await LoadLocalDataAsync(showSuccess: true));
|
||||
|
||||
@@ -259,13 +268,104 @@ public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||
_stdChangedToken = _eventAggregator.GetEvent<RubberQuickTestStdChangedEvent>()
|
||||
.Subscribe(async _ => await ReloadLocalDataQuietAsync(), ThreadOption.UIThread);
|
||||
|
||||
|
||||
|
||||
_ = LoadLocalDataAsync(showSuccess: false);
|
||||
|
||||
RecalculateOverallInspectResult();
|
||||
}
|
||||
|
||||
private bool _isReadOnly;
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get => _isReadOnly;
|
||||
private set
|
||||
{
|
||||
if (!SetProperty(ref _isReadOnly, value)) return;
|
||||
RaisePropertyChanged(nameof(IsEditable));
|
||||
RaisePropertyChanged(nameof(ShowSaveButton));
|
||||
NotifySaveStateChanged();
|
||||
InspectColumnsChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEditable => !IsReadOnly;
|
||||
public bool ShowSaveButton => !IsReadOnly;
|
||||
public bool CanSave => InspectRows.Count > 0 && !_saveInProgress && !IsReadOnly;
|
||||
|
||||
private void NotifySaveStateChanged()
|
||||
{
|
||||
RaisePropertyChanged(nameof(CanSave));
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
protected override void OnIsLoadingChanged()
|
||||
{
|
||||
base.OnIsLoadingChanged();
|
||||
NotifySaveStateChanged();
|
||||
}
|
||||
|
||||
public void OnNavigatedTo(NavigationContext navigationContext)
|
||||
{
|
||||
_ = ApplyNavigationAsync(navigationContext.Parameters);
|
||||
}
|
||||
|
||||
private async Task ApplyNavigationAsync(INavigationParameters parameters)
|
||||
{
|
||||
var version = Interlocked.Increment(ref _navigationApplyVersion);
|
||||
|
||||
if (parameters.TryGetValue<bool>("readOnly", out var readOnly) && readOnly)
|
||||
{
|
||||
if (parameters.TryGetValue<string>("localId", out var localId) && !string.IsNullOrWhiteSpace(localId))
|
||||
{
|
||||
_loadedDetailLocalId = localId;
|
||||
_loadedDetailMesId = null;
|
||||
await LoadFromLocalItemAsync(localId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (parameters.TryGetValue<string>("mesId", out var mesId) && !string.IsNullOrWhiteSpace(mesId))
|
||||
{
|
||||
_loadedDetailMesId = mesId;
|
||||
_loadedDetailLocalId = null;
|
||||
await LoadFromMesIdAsync(mesId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (version != _navigationApplyVersion) return;
|
||||
|
||||
_loadedDetailLocalId = null;
|
||||
_loadedDetailMesId = null;
|
||||
IsReadOnly = false;
|
||||
ResetFormForNewEntry();
|
||||
await LoadLocalDataAsync(showSuccess: false);
|
||||
}
|
||||
|
||||
public bool IsNavigationTarget(NavigationContext navigationContext)
|
||||
{
|
||||
var parameters = navigationContext.Parameters;
|
||||
if (parameters.TryGetValue<bool>("readOnly", out var readOnly) && readOnly)
|
||||
{
|
||||
if (parameters.TryGetValue<string>("localId", out var localId) && !string.IsNullOrWhiteSpace(localId))
|
||||
return IsReadOnly && string.Equals(_loadedDetailLocalId, localId, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (parameters.TryGetValue<string>("mesId", out var mesId) && !string.IsNullOrWhiteSpace(mesId))
|
||||
return IsReadOnly && string.Equals(_loadedDetailMesId, mesId, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return !IsReadOnly && _loadedDetailLocalId == null && _loadedDetailMesId == null;
|
||||
}
|
||||
|
||||
private void ResetFormForNewEntry()
|
||||
{
|
||||
RecordNo = null;
|
||||
TrainNo = null;
|
||||
InspectTimesText = "1";
|
||||
ClearPlanAndStdSelection();
|
||||
RecalculateOverallInspectResult();
|
||||
NotifySaveStateChanged();
|
||||
}
|
||||
public void OnNavigatedFrom(NavigationContext navigationContext) { }
|
||||
|
||||
|
||||
|
||||
private static string ResolveInspectorDisplay()
|
||||
@@ -648,8 +748,8 @@ public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||
|
||||
|
||||
private async Task ReloadLocalDataQuietAsync()
|
||||
|
||||
{
|
||||
if (IsReadOnly) return;
|
||||
|
||||
try
|
||||
|
||||
@@ -1070,7 +1170,7 @@ public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||
|
||||
InspectRows.Add(row);
|
||||
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
NotifySaveStateChanged();
|
||||
|
||||
RecalculateOverallInspectResult();
|
||||
|
||||
@@ -1090,7 +1190,7 @@ public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||
|
||||
RenumberInspectRows();
|
||||
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
NotifySaveStateChanged();
|
||||
|
||||
RecalculateOverallInspectResult();
|
||||
|
||||
@@ -1099,145 +1199,90 @@ public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||
|
||||
|
||||
private async Task SaveAsync()
|
||||
|
||||
{
|
||||
if (_saveInProgress) return;
|
||||
|
||||
_saveInProgress = true;
|
||||
NotifySaveStateChanged();
|
||||
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(TrainNo))
|
||||
|
||||
{
|
||||
|
||||
Growl.Warning("请填写车次");
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (SelectedPlan == null)
|
||||
|
||||
{
|
||||
|
||||
Growl.Warning("请选择密炼计划");
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(RubberMaterialName))
|
||||
|
||||
{
|
||||
|
||||
Growl.Warning("请先选择密炼计划以带出胶料名称");
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (SelectedStd == null || _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 stdLineList = BuildStdLineList();
|
||||
if (stdLineList.Count == 0)
|
||||
{
|
||||
Growl.Warning("无法生成数据标准明细");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var chartPointList = BuildChartPointList();
|
||||
var user = AppSession.CurrentUser;
|
||||
|
||||
IsLoading = true;
|
||||
var record = BuildSaveRecord(stdLineList, rawLineList, chartPointList, inspectTimes, user);
|
||||
var saved = await _recordService.SaveAsync(record);
|
||||
RecordNo = saved.Record.RecordNo;
|
||||
|
||||
try
|
||||
|
||||
{
|
||||
|
||||
var record = BuildSaveRecord(lineList, rawLineList, inspectTimes, user);
|
||||
|
||||
var recordNo = await _operationService.SaveRecordAsync(record);
|
||||
|
||||
RecordNo = recordNo;
|
||||
|
||||
Growl.Success(string.IsNullOrWhiteSpace(recordNo)
|
||||
|
||||
? "胶料快检记录已保存到 MES"
|
||||
|
||||
: $"胶料快检记录已保存,单号:{recordNo}");
|
||||
var syncHint = saved.SyncStatus == "Synced" ? "并已同步到 MES" : "(MES 同步待重试)";
|
||||
Growl.Success(string.IsNullOrWhiteSpace(RecordNo)
|
||||
? $"胶料快检记录已保存到本地{syncHint}"
|
||||
: $"胶料快检记录已保存,快检记录号:{RecordNo}{syncHint}");
|
||||
|
||||
InspectRows.Clear();
|
||||
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
|
||||
NotifySaveStateChanged();
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
|
||||
{
|
||||
|
||||
Growl.Error($"保存失败:{ex.Message}");
|
||||
|
||||
}
|
||||
|
||||
finally
|
||||
|
||||
{
|
||||
|
||||
IsLoading = false;
|
||||
|
||||
_saveInProgress = false;
|
||||
NotifySaveStateChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1432,10 +1477,12 @@ public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||
|
||||
private MesXslRubberQuickTestRecord BuildSaveRecord(
|
||||
|
||||
List<MesXslRubberQuickTestRecordLine> lineList,
|
||||
List<MesXslRubberQuickTestRecordStdLine> stdLineList,
|
||||
|
||||
List<MesXslRubberQuickTestRecordRawLine> rawLineList,
|
||||
|
||||
List<MesXslRubberQuickTestRecordChartPoint> chartPointList,
|
||||
|
||||
int inspectTimes,
|
||||
|
||||
SysUser? user)
|
||||
@@ -1446,13 +1493,19 @@ public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||
|
||||
{
|
||||
|
||||
LineList = lineList,
|
||||
StdLineList = stdLineList,
|
||||
|
||||
RawLineList = rawLineList,
|
||||
|
||||
ChartPointList = chartPointList,
|
||||
|
||||
InspectTime = DateTime.Now,
|
||||
|
||||
InspectResult = OverallInspectResultCode
|
||||
CreateTime = DateTime.Now,
|
||||
|
||||
InspectResult = OverallInspectResultCode,
|
||||
|
||||
RecordNo = _recordService.GenerateRecordNo(RubberMaterialName ?? string.Empty)
|
||||
|
||||
};
|
||||
|
||||
@@ -1470,6 +1523,26 @@ public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||
|
||||
record.StdId = _currentStd.Id;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_currentStd?.StdName))
|
||||
|
||||
record.StdName = _currentStd.StdName;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_currentStd?.TestMethodId))
|
||||
|
||||
record.TestMethodId = _currentStd.TestMethodId;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(TestMethodName))
|
||||
|
||||
record.TestMethodName = TestMethodName;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_currentStd?.QuickTestTypeId))
|
||||
|
||||
record.QuickTestTypeId = _currentStd.QuickTestTypeId;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_currentStd?.QuickTestTypeName))
|
||||
|
||||
record.QuickTestTypeName = _currentStd.QuickTestTypeName;
|
||||
|
||||
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_selectedPlan?.MachineId))
|
||||
@@ -1502,9 +1575,9 @@ public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||
|
||||
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_selectedPlan?.PlanMaterialNo))
|
||||
if (!string.IsNullOrWhiteSpace(_selectedPlan?.PlanNo))
|
||||
|
||||
record.ProductionPlanNo = _selectedPlan.PlanMaterialNo;
|
||||
record.ProductionPlanNo = _selectedPlan.PlanNo;
|
||||
|
||||
|
||||
|
||||
@@ -1528,6 +1601,169 @@ public class RubberQuickTestOperationViewModel : BaseViewModel
|
||||
|
||||
}
|
||||
|
||||
private List<MesXslRubberQuickTestRecordStdLine> BuildStdLineList()
|
||||
{
|
||||
var lines = new List<MesXslRubberQuickTestRecordStdLine>();
|
||||
int sort = 0;
|
||||
foreach (var col in DataPointColumns)
|
||||
{
|
||||
lines.Add(new MesXslRubberQuickTestRecordStdLine
|
||||
{
|
||||
DataPointId = col.DataPointId,
|
||||
PointName = col.PointName,
|
||||
LowerLimit = col.LowerLimit,
|
||||
LowerWarn = col.LowerWarn,
|
||||
TargetValue = col.TargetValue,
|
||||
UpperWarn = col.UpperWarn,
|
||||
UpperLimit = col.UpperLimit,
|
||||
SortNo = sort++
|
||||
});
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
private List<MesXslRubberQuickTestRecordChartPoint> BuildChartPointList()
|
||||
{
|
||||
var points = new List<MesXslRubberQuickTestRecordChartPoint>();
|
||||
int sort = 0;
|
||||
for (int i = 0; i < ChartPointCount && i < UpperTempValues.Count; i++)
|
||||
{
|
||||
points.Add(new MesXslRubberQuickTestRecordChartPoint
|
||||
{
|
||||
TimeMin = (decimal)(UpperTempValues[i].X ?? ChartTimeMinutes[i]),
|
||||
UpperTemp = UpperTempValues[i].Y.HasValue ? (decimal)UpperTempValues[i].Y!.Value : null,
|
||||
LowerTemp = i < LowerTempValues.Count && LowerTempValues[i].Y.HasValue ? (decimal)LowerTempValues[i].Y!.Value : null,
|
||||
TorqueS = i < TorqueValues.Count && TorqueValues[i].Y.HasValue ? (decimal)TorqueValues[i].Y!.Value : null,
|
||||
SortNo = sort++
|
||||
});
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
private async Task LoadFromLocalItemAsync(string localId)
|
||||
{
|
||||
var item = _recordService.GetByLocalId(localId);
|
||||
if (item == null)
|
||||
{
|
||||
Growl.Warning("未找到快检记录");
|
||||
return;
|
||||
}
|
||||
|
||||
await ApplyRecordDetailAsync(item.Record);
|
||||
}
|
||||
|
||||
private async Task LoadFromMesIdAsync(string mesId)
|
||||
{
|
||||
var record = await _recordService.GetByIdAsync(mesId);
|
||||
if (record == null)
|
||||
{
|
||||
Growl.Warning("未找到快检记录");
|
||||
return;
|
||||
}
|
||||
|
||||
await ApplyRecordDetailAsync(record);
|
||||
}
|
||||
|
||||
private async Task ApplyRecordDetailAsync(MesXslRubberQuickTestRecord r)
|
||||
{
|
||||
IsReadOnly = true;
|
||||
RecordNo = r.RecordNo;
|
||||
MixingDate = r.ProductionDate ?? DateTime.Today;
|
||||
SelectedMachine = r.ProdEquipmentName;
|
||||
TrainNo = r.TrainNo;
|
||||
InspectTimesText = r.InspectTimes?.ToString() ?? "1";
|
||||
InspectorDisplay = r.InspectorRealname ?? ResolveInspectorDisplay();
|
||||
OverallInspectResultCode = r.InspectResult ?? "0";
|
||||
OverallInspectResultDisplay = string.Equals(r.InspectResult, "1", StringComparison.Ordinal) ? "合格" : "不合格";
|
||||
TestMethodName = r.TestMethodName;
|
||||
|
||||
MachineOptions.Clear();
|
||||
if (!string.IsNullOrWhiteSpace(r.ProdEquipmentName))
|
||||
MachineOptions.Add(r.ProdEquipmentName);
|
||||
|
||||
ShiftOptions.Clear();
|
||||
var shift = new WorkShiftOption(r.WorkShift ?? "", r.WorkShift ?? "");
|
||||
ShiftOptions.Add(shift);
|
||||
SelectedShift = shift;
|
||||
|
||||
PlanOptions.Clear();
|
||||
var plan = new MesXslMixingProductionPlan
|
||||
{
|
||||
PlanNo = r.ProductionPlanNo,
|
||||
MaterialName = r.RubberMaterialName,
|
||||
MachineName = r.ProdEquipmentName
|
||||
};
|
||||
PlanOptions.Add(plan);
|
||||
_selectedPlan = plan;
|
||||
RaisePropertyChanged(nameof(SelectedPlan));
|
||||
RaisePropertyChanged(nameof(MachineName));
|
||||
RaisePropertyChanged(nameof(RubberMaterialName));
|
||||
|
||||
StdOptions.Clear();
|
||||
var std = new MesXslRubberQuickTestStd { Id = r.StdId, StdName = r.StdName, TestMethodName = r.TestMethodName };
|
||||
StdOptions.Add(std);
|
||||
_selectedStd = std;
|
||||
RaisePropertyChanged(nameof(SelectedStd));
|
||||
|
||||
DataPointColumns.Clear();
|
||||
InspectRows.Clear();
|
||||
foreach (var sl in (r.StdLineList ?? new List<MesXslRubberQuickTestRecordStdLine>()).OrderBy(x => x.SortNo ?? 0))
|
||||
{
|
||||
DataPointColumns.Add(new MesXslRubberQuickTestStdLine
|
||||
{
|
||||
DataPointId = sl.DataPointId,
|
||||
PointName = sl.PointName,
|
||||
LowerLimit = sl.LowerLimit,
|
||||
LowerWarn = sl.LowerWarn,
|
||||
TargetValue = sl.TargetValue,
|
||||
UpperWarn = sl.UpperWarn,
|
||||
UpperLimit = sl.UpperLimit,
|
||||
SortNo = sl.SortNo
|
||||
});
|
||||
}
|
||||
InspectColumnsChanged?.Invoke();
|
||||
|
||||
var grouped = (r.RawLineList ?? new List<MesXslRubberQuickTestRecordRawLine>())
|
||||
.GroupBy(x => x.RowNo ?? string.Empty)
|
||||
.OrderBy(g => g.Key, StringComparer.Ordinal);
|
||||
foreach (var g in grouped)
|
||||
{
|
||||
var row = new QuickTestInspectRowViewModel { RowNo = g.Key };
|
||||
for (int i = 0; i < DataPointColumns.Count; i++)
|
||||
{
|
||||
var col = DataPointColumns[i];
|
||||
var raw = g.FirstOrDefault(x => x.DataPointId == col.DataPointId || x.InspectItem == col.PointName);
|
||||
var cell = new QuickTestInspectCellViewModel
|
||||
{
|
||||
DataPointId = col.DataPointId,
|
||||
PointName = col.PointName ?? string.Empty,
|
||||
LowerLimit = col.LowerLimit,
|
||||
UpperLimit = col.UpperLimit,
|
||||
Value = raw?.InspectValue
|
||||
};
|
||||
row.Cells.Add(cell);
|
||||
}
|
||||
row.RecalculateResult();
|
||||
InspectRows.Add(row);
|
||||
}
|
||||
|
||||
UpperTempValues.Clear();
|
||||
LowerTempValues.Clear();
|
||||
TorqueValues.Clear();
|
||||
foreach (var pt in (r.ChartPointList ?? new List<MesXslRubberQuickTestRecordChartPoint>()).OrderBy(x => x.SortNo ?? 0))
|
||||
{
|
||||
var time = (double)(pt.TimeMin ?? 0);
|
||||
if (pt.UpperTemp != null) UpperTempValues.Add(new ObservablePoint(time, (double)pt.UpperTemp.Value));
|
||||
if (pt.LowerTemp != null) LowerTempValues.Add(new ObservablePoint(time, (double)pt.LowerTemp.Value));
|
||||
if (pt.TorqueS != null) TorqueValues.Add(new ObservablePoint(time, (double)pt.TorqueS.Value));
|
||||
}
|
||||
if (UpperTempValues.Count > 0) UpperMoldTemp = UpperTempValues[^1].Y ?? 0;
|
||||
if (LowerTempValues.Count > 0) LowerMoldTemp = LowerTempValues[^1].Y ?? 0;
|
||||
if (TorqueValues.Count > 0) TorqueS = TorqueValues[^1].Y ?? 0;
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static Axis[] BuildTimeAxis() => new[]
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
using LiveChartsCore;
|
||||
using LiveChartsCore.Defaults;
|
||||
using LiveChartsCore.SkiaSharpView;
|
||||
using Prism.Mvvm;
|
||||
using System.Collections.ObjectModel;
|
||||
using YY.Admin.Core.Entity;
|
||||
|
||||
namespace YY.Admin.ViewModels.RubberQuickTest;
|
||||
|
||||
public class RubberQuickTestRecordDetailDialogViewModel : BindableBase
|
||||
{
|
||||
private MesXslRubberQuickTestRecord? _record;
|
||||
public MesXslRubberQuickTestRecord? Record
|
||||
{
|
||||
get => _record;
|
||||
private set => SetProperty(ref _record, value);
|
||||
}
|
||||
|
||||
private string? _inspectResultDisplay;
|
||||
public string? InspectResultDisplay
|
||||
{
|
||||
get => _inspectResultDisplay;
|
||||
private set => SetProperty(ref _inspectResultDisplay, value);
|
||||
}
|
||||
|
||||
public ObservableCollection<MesXslRubberQuickTestRecordStdLine> StdLines { get; } = new();
|
||||
public ObservableCollection<MesXslRubberQuickTestRecordRawLine> RawLines { get; } = new();
|
||||
|
||||
public ObservableCollection<ISeries> TemperatureSeries { get; }
|
||||
public ObservableCollection<ISeries> TorqueSeries { get; }
|
||||
public ObservableCollection<ObservablePoint> UpperTempValues { get; } = new();
|
||||
public ObservableCollection<ObservablePoint> LowerTempValues { get; } = new();
|
||||
public ObservableCollection<ObservablePoint> TorqueValues { get; } = new();
|
||||
|
||||
public Axis[] TemperatureXAxes { get; } = BuildTimeAxis();
|
||||
public Axis[] TemperatureYAxes { get; } = BuildTempYAxis();
|
||||
public Axis[] TorqueXAxes { get; } = BuildTimeAxis();
|
||||
public Axis[] TorqueYAxes { get; } = BuildTorqueYAxis();
|
||||
|
||||
public RubberQuickTestRecordDetailDialogViewModel()
|
||||
{
|
||||
TemperatureSeries = new ObservableCollection<ISeries>
|
||||
{
|
||||
new LineSeries<ObservablePoint> { Name = "上模温度", Values = UpperTempValues, GeometrySize = 4, LineSmoothness = 0.3 },
|
||||
new LineSeries<ObservablePoint> { Name = "下模温度", Values = LowerTempValues, GeometrySize = 4, LineSmoothness = 0.3 }
|
||||
};
|
||||
TorqueSeries = new ObservableCollection<ISeries>
|
||||
{
|
||||
new LineSeries<ObservablePoint> { Name = "S'(dNm)", Values = TorqueValues, GeometrySize = 4, LineSmoothness = 0.3 }
|
||||
};
|
||||
}
|
||||
|
||||
public void Initialize(MesXslRubberQuickTestRecord record)
|
||||
{
|
||||
Record = record;
|
||||
InspectResultDisplay = record.InspectResult switch
|
||||
{
|
||||
"1" => "合格",
|
||||
"0" => "不合格",
|
||||
_ => record.InspectResultText ?? record.InspectResult ?? ""
|
||||
};
|
||||
StdLines.Clear();
|
||||
foreach (var line in record.StdLineList ?? [])
|
||||
StdLines.Add(line);
|
||||
|
||||
RawLines.Clear();
|
||||
foreach (var line in record.RawLineList ?? [])
|
||||
RawLines.Add(line);
|
||||
|
||||
UpperTempValues.Clear();
|
||||
LowerTempValues.Clear();
|
||||
TorqueValues.Clear();
|
||||
foreach (var p in (record.ChartPointList ?? []).OrderBy(x => x.SortNo ?? 0))
|
||||
{
|
||||
var time = (double)(p.TimeMin ?? 0);
|
||||
UpperTempValues.Add(new ObservablePoint(time, (double)(p.UpperTemp ?? 0)));
|
||||
LowerTempValues.Add(new ObservablePoint(time, (double)(p.LowerTemp ?? 0)));
|
||||
TorqueValues.Add(new ObservablePoint(time, (double)(p.TorqueS ?? 0)));
|
||||
}
|
||||
}
|
||||
|
||||
private static Axis[] BuildTimeAxis() => new[]
|
||||
{
|
||||
new Axis { Name = "时间(min)", MinLimit = 0, MaxLimit = 2, Labeler = v => v.ToString("0.0#") }
|
||||
};
|
||||
|
||||
private static Axis[] BuildTempYAxis() => new[]
|
||||
{
|
||||
new Axis { Name = "温度(℃)", MinLimit = 189, MaxLimit = 201 }
|
||||
};
|
||||
|
||||
private static readonly double[] TorqueYTicks = { 0.0, 3.0, 5.9, 8.9, 11.8, 14.8 };
|
||||
|
||||
private static Axis[] BuildTorqueYAxis() => new[]
|
||||
{
|
||||
new Axis
|
||||
{
|
||||
Name = "S'(dNm)",
|
||||
MinLimit = 0,
|
||||
MaxLimit = 14.8,
|
||||
CustomSeparators = TorqueYTicks
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
using HandyControl.Controls;
|
||||
using Prism.Events;
|
||||
using Prism.Navigation;
|
||||
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.Event;
|
||||
using YY.Admin.Module;
|
||||
using YY.Admin.Services.Service;
|
||||
|
||||
namespace YY.Admin.ViewModels.RubberQuickTest;
|
||||
|
||||
public class RubberQuickTestRecordListViewModel : BaseViewModel
|
||||
{
|
||||
private readonly IRubberQuickTestRecordService _recordService;
|
||||
private readonly IJeecgDictSyncService _dictSyncService;
|
||||
private SubscriptionToken? _changedToken;
|
||||
|
||||
private ObservableCollection<RubberQuickTestRecordListRow> _records = new();
|
||||
public ObservableCollection<RubberQuickTestRecordListRow> Records
|
||||
{
|
||||
get => _records;
|
||||
set => SetProperty(ref _records, 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? _filterRecordNo;
|
||||
public string? FilterRecordNo { get => _filterRecordNo; set => SetProperty(ref _filterRecordNo, value); }
|
||||
|
||||
private string? _filterRubberMaterialName;
|
||||
public string? FilterRubberMaterialName { get => _filterRubberMaterialName; set => SetProperty(ref _filterRubberMaterialName, value); }
|
||||
|
||||
private string? _filterPlanNo;
|
||||
public string? FilterPlanNo { get => _filterPlanNo; set => SetProperty(ref _filterPlanNo, value); }
|
||||
|
||||
public DelegateCommand SearchCommand { get; }
|
||||
public DelegateCommand ResetCommand { get; }
|
||||
public DelegateCommand AddCommand { get; }
|
||||
public DelegateCommand<RubberQuickTestRecordListRow> ViewDetailCommand { get; }
|
||||
public DelegateCommand<RubberQuickTestRecordListRow> DeleteCommand { get; }
|
||||
public DelegateCommand PrevPageCommand { get; }
|
||||
public DelegateCommand NextPageCommand { get; }
|
||||
|
||||
public RubberQuickTestRecordListViewModel(
|
||||
IRubberQuickTestRecordService recordService,
|
||||
IJeecgDictSyncService dictSyncService,
|
||||
IContainerExtension container,
|
||||
IRegionManager regionManager) : base(container, regionManager)
|
||||
{
|
||||
_recordService = recordService;
|
||||
_dictSyncService = dictSyncService;
|
||||
|
||||
SearchCommand = new DelegateCommand(async () => { PageNo = 1; await LoadAsync(); });
|
||||
ResetCommand = new DelegateCommand(async () =>
|
||||
{
|
||||
FilterRecordNo = null;
|
||||
FilterRubberMaterialName = null;
|
||||
FilterPlanNo = null;
|
||||
PageNo = 1;
|
||||
await LoadAsync();
|
||||
});
|
||||
AddCommand = new DelegateCommand(OpenAddPage);
|
||||
ViewDetailCommand = new DelegateCommand<RubberQuickTestRecordListRow>(async r => await ShowDetailAsync(r));
|
||||
DeleteCommand = new DelegateCommand<RubberQuickTestRecordListRow>(
|
||||
async r => await DeleteAsync(r),
|
||||
r => r != null && r.CanDelete);
|
||||
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<RubberQuickTestRecordChangedEvent>()
|
||||
.Subscribe(async _ => await LoadAsync(), ThreadOption.UIThread);
|
||||
|
||||
_ = InitializeAsync();
|
||||
}
|
||||
|
||||
private async Task InitializeAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
await UIHelper.WaitForRenderAsync();
|
||||
await LoadAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"快检记录列表初始化失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LoadAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
IsLoading = true;
|
||||
var result = await _recordService.PageAsync(
|
||||
PageNo, PageSize, FilterRecordNo, FilterRubberMaterialName, FilterPlanNo);
|
||||
|
||||
var shiftMap = (await _dictSyncService.GetDictOptionsAsync("xslmes_rubber_quick_test_work_shift", includeAll: false))
|
||||
.ToDictionary(x => x.Value, x => x.Key);
|
||||
foreach (var r in result.Records)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(r.WorkShiftDisplay) && shiftMap.TryGetValue(r.WorkShiftDisplay, out var txt))
|
||||
r.WorkShiftDisplay = txt;
|
||||
}
|
||||
|
||||
Records = new ObservableCollection<RubberQuickTestRecordListRow>(result.Records);
|
||||
Total = result.Total;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Growl.Error($"加载快检记录失败:{ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenAddPage()
|
||||
{
|
||||
_eventAggregator.GetEvent<TabSourceSelectedEvent>().Publish(new TabSource
|
||||
{
|
||||
Name = "新增胶料快检记录",
|
||||
Icon = "\ue7de",
|
||||
ViewName = "RubberQuickTestOperationView"
|
||||
});
|
||||
}
|
||||
|
||||
private async Task DeleteAsync(RubberQuickTestRecordListRow? row)
|
||||
{
|
||||
if (row == null || !row.CanDelete || string.IsNullOrWhiteSpace(row.LocalId))
|
||||
return;
|
||||
|
||||
var label = row.RecordNo ?? row.LocalId;
|
||||
var confirm = System.Windows.MessageBox.Show(
|
||||
$"确定删除同步失败的快检记录「{label}」?\n此操作仅删除本地记录,不可恢复。",
|
||||
"确认删除",
|
||||
System.Windows.MessageBoxButton.YesNo,
|
||||
System.Windows.MessageBoxImage.Warning);
|
||||
if (confirm != System.Windows.MessageBoxResult.Yes)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
if (_recordService.DeleteFailedLocal(row.LocalId))
|
||||
{
|
||||
Growl.Success("删除成功");
|
||||
await LoadAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
Growl.Warning("仅同步失败的本地记录可删除");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Growl.Error($"删除失败:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ShowDetailAsync(RubberQuickTestRecordListRow? row)
|
||||
{
|
||||
if (row == null) return;
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(row.LocalId))
|
||||
{
|
||||
if (_recordService.GetByLocalId(row.LocalId) == null)
|
||||
{
|
||||
Growl.Warning("未找到快检记录详情");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(row.MesId))
|
||||
{
|
||||
var remote = await _recordService.GetByIdAsync(row.MesId);
|
||||
if (remote == null)
|
||||
{
|
||||
Growl.Warning("未找到快检记录详情");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Growl.Warning("无法定位快检记录");
|
||||
return;
|
||||
}
|
||||
|
||||
var parameters = new NavigationParameters { { "readOnly", true } };
|
||||
if (!string.IsNullOrWhiteSpace(row.LocalId))
|
||||
parameters.Add("localId", row.LocalId);
|
||||
else
|
||||
parameters.Add("mesId", row.MesId!);
|
||||
|
||||
var title = row.RecordNo ?? row.LocalId ?? row.MesId ?? "详情";
|
||||
_eventAggregator.GetEvent<TabSourceSelectedEvent>().Publish(new TabSource
|
||||
{
|
||||
Name = $"快检记录 {title}",
|
||||
Icon = "\ue7de",
|
||||
ViewName = "RubberQuickTestOperationView",
|
||||
NavigationParameter = parameters
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Growl.Error($"打开详情失败:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CleanUp()
|
||||
{
|
||||
base.CleanUp();
|
||||
if (_changedToken != null)
|
||||
_eventAggregator.GetEvent<RubberQuickTestRecordChangedEvent>().Unsubscribe(_changedToken);
|
||||
}
|
||||
}
|
||||
@@ -24,25 +24,34 @@
|
||||
<Setter Property="Margin" Value="8,0,0,0"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
<Style x:Key="DataGridCellCenterTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter Property="TextAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
<Style x:Key="DataGridCellCenterEditStyle" TargetType="TextBox">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Margin="12">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="80"/>
|
||||
<RowDefinition Height="52"/>
|
||||
<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"/>
|
||||
BorderBrush="{DynamicResource BorderBrush}" BorderThickness="0,0,0,1" Margin="-12,0,-12,6">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="16,0">
|
||||
<Border Width="32" Height="32" CornerRadius="6" Background="{DynamicResource PrimaryBrush}" Margin="0,0,10,0">
|
||||
<md:PackIcon Kind="Flask" Width="18" Height="18" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<StackPanel VerticalAlignment="Center">
|
||||
<TextBlock Text="无转子流变仪 MDR S3L" FontSize="24" FontWeight="Bold"/>
|
||||
<TextBlock Text="胶料快检记录 · 密炼快检试验操作台" FontSize="12" Foreground="{DynamicResource SecondaryTextBrush}" Margin="0,4,0,0"/>
|
||||
<TextBlock Text="无转子流变仪 MDR S3L" FontSize="18" FontWeight="Bold"/>
|
||||
<TextBlock Text="胶料快检记录 · 密炼快检试验操作台" FontSize="11" Foreground="{DynamicResource SecondaryTextBrush}" Margin="0,2,0,0"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
@@ -55,44 +64,70 @@
|
||||
<ColumnDefinition Width="2*"/>
|
||||
</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"/>
|
||||
<!-- 左侧:曲线图 : 试验结果 ≈ 3 : 2 -->
|
||||
<Grid Grid.Column="0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="3*"/>
|
||||
<RowDefinition Height="2*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border Grid.Row="0" Style="{StaticResource SectionBorderStyle}" Padding="10,10,10,6" Margin="0,0,0,6">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,0,0,4">
|
||||
<Border Width="4" Height="16" 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"/>
|
||||
<Button Content="刷新演示" Command="{Binding RefreshChartDemoCommand}" Style="{StaticResource ButtonDefault}" Height="26" Padding="8,0" Margin="10,0,0,0"/>
|
||||
</StackPanel>
|
||||
<TextBlock Text="{Binding ChartDemoHint}" FontSize="11" Foreground="{DynamicResource SecondaryTextBrush}" Margin="0,0,0,6"/>
|
||||
<Border Height="220" CornerRadius="4">
|
||||
<TextBlock Grid.Row="1" Text="{Binding ChartDemoHint}" FontSize="10" Foreground="{DynamicResource SecondaryTextBrush}" Margin="0,0,0,4"
|
||||
TextTrimming="CharacterEllipsis"/>
|
||||
<Border Grid.Row="2" CornerRadius="4">
|
||||
<lvc:CartesianChart Series="{Binding TemperatureSeries}"
|
||||
XAxes="{Binding TemperatureXAxes}"
|
||||
YAxes="{Binding TemperatureYAxes}"
|
||||
LegendPosition="Top"/>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Border Style="{StaticResource SectionBorderStyle}">
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
|
||||
<Border Width="4" Height="18" CornerRadius="2" Background="#1890ff"/>
|
||||
<Border Grid.Row="1" Style="{StaticResource SectionBorderStyle}" Padding="10,10,10,6" Margin="0,0,0,0">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,0,0,4">
|
||||
<Border Width="4" Height="16" CornerRadius="2" Background="#1890ff"/>
|
||||
<TextBlock Text="S'(dNm)曲线图" Style="{StaticResource SectionTitleStyle}"/>
|
||||
</StackPanel>
|
||||
<Border Height="200" CornerRadius="4">
|
||||
<Border Grid.Row="1" CornerRadius="4">
|
||||
<lvc:CartesianChart Series="{Binding TorqueSeries}"
|
||||
XAxes="{Binding TorqueXAxes}"
|
||||
YAxes="{Binding TorqueYAxes}"
|
||||
LegendPosition="Top"/>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<Border Style="{StaticResource SectionBorderStyle}">
|
||||
<StackPanel>
|
||||
<Grid Margin="0,0,0,8">
|
||||
<Border Grid.Row="1" Style="{StaticResource SectionBorderStyle}" Margin="0" Padding="10,10,10,8">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0" Margin="0,0,0,8">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Border Width="4" Height="18" CornerRadius="2" Background="#1890ff"/>
|
||||
<TextBlock Text="试验结果" Style="{StaticResource SectionTitleStyle}"/>
|
||||
@@ -102,55 +137,75 @@
|
||||
<Button Content="删除选中行" Command="{Binding RemoveInspectRowCommand}" Style="{StaticResource ButtonDanger}" Height="28" Padding="10,0"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<DataGrid x:Name="InspectResultGrid"
|
||||
<DataGrid Grid.Row="1"
|
||||
x:Name="InspectResultGrid"
|
||||
ItemsSource="{Binding InspectRows}"
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
CanUserDeleteRows="False"
|
||||
HeadersVisibility="Column"
|
||||
MinHeight="160"
|
||||
SelectionMode="Single"
|
||||
IsReadOnly="False"
|
||||
SelectionChanged="InspectResultGrid_SelectionChanged">
|
||||
RowHeight="30"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
SelectionChanged="InspectResultGrid_SelectionChanged"
|
||||
Style="{StaticResource CusDataGridStyle}"
|
||||
ColumnHeaderStyle="{StaticResource CusDataGridColumnHeaderStyle}">
|
||||
</DataGrid>
|
||||
<TextBlock Text="请手填各数据点检测值,系统将根据数据标准上下限自动判定合格/不合格" FontSize="11" Foreground="{DynamicResource SecondaryTextBrush}" Margin="0,6,0,0"/>
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Row="2" Text="请手填各数据点检测值,系统将根据数据标准上下限自动判定合格/不合格" FontSize="11" Foreground="{DynamicResource SecondaryTextBrush}" Margin="0,6,0,0"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
|
||||
<!-- 右侧 -->
|
||||
<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"/>
|
||||
<!-- 右侧:实时数据 + 试验信息(上)与 数据标准(下 2*,与左侧试验结果同高) -->
|
||||
<Grid Grid.Column="2">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="3*"/>
|
||||
<RowDefinition Height="2*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 实时数据(占用上部剩余空间) -->
|
||||
<Border Grid.Row="0" Style="{StaticResource SectionBorderStyle}" Padding="10,8" Margin="0,0,0,8">
|
||||
<Grid VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,0,0,8">
|
||||
<Border Width="4" Height="16" CornerRadius="2" Background="#52c41a"/>
|
||||
<TextBlock Text="实时数据" Style="{StaticResource SectionTitleStyle}"/>
|
||||
</StackPanel>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="1" VerticalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<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 Grid.Column="0" Margin="0,0,6,0" VerticalAlignment="Center">
|
||||
<TextBlock Text="上模温度(℃)" FontSize="12" Foreground="{DynamicResource SecondaryTextBrush}" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding UpperMoldTemp, StringFormat={}{0:N2}}" FontSize="28" FontWeight="Bold" FontFamily="Consolas" Margin="0,6,0,0" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1" Margin="0,0,6,0" VerticalAlignment="Center">
|
||||
<TextBlock Text="下模温度(℃)" FontSize="12" Foreground="{DynamicResource SecondaryTextBrush}" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding LowerMoldTemp, StringFormat={}{0:N2}}" FontSize="28" FontWeight="Bold" FontFamily="Consolas" Margin="0,6,0,0" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="2" VerticalAlignment="Center">
|
||||
<TextBlock Text="S'(dNm)" FontSize="12" Foreground="{DynamicResource SecondaryTextBrush}" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding TorqueS, StringFormat={}{0:N2}}" FontSize="28" FontWeight="Bold" FontFamily="Consolas" Margin="0,6,0,0" HorizontalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- 试验信息 -->
|
||||
<Border Style="{StaticResource SectionBorderStyle}">
|
||||
<Border Grid.Row="1" Style="{StaticResource SectionBorderStyle}" Margin="0,0,0,0">
|
||||
<StackPanel>
|
||||
<Grid Margin="0,0,0,12">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
@@ -310,48 +365,50 @@
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<!-- 数据标准 -->
|
||||
<Border Style="{StaticResource SectionBorderStyle}">
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
|
||||
<!-- 数据标准(高度与左侧试验结果一致) -->
|
||||
<Border Grid.Row="1" Style="{StaticResource SectionBorderStyle}" Margin="0" Padding="10,10,10,8">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Grid.Row="0" 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}"
|
||||
<DataGrid Grid.Row="1"
|
||||
ItemsSource="{Binding DataPointColumns}"
|
||||
AutoGenerateColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="Column"
|
||||
MaxHeight="240"
|
||||
ColumnWidth="*">
|
||||
RowHeight="30"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
ColumnWidth="*"
|
||||
Style="{StaticResource CusDataGridStyle}"
|
||||
ColumnHeaderStyle="{StaticResource CusDataGridColumnHeaderStyle}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="数据点" Binding="{Binding PointName}" Width="5*"/>
|
||||
<DataGridTextColumn Header="下限值" Binding="{Binding LowerLimit}" Width="2.5*">
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Header="上限值" Binding="{Binding UpperLimit}" Width="2.5*">
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Header="数据点" Binding="{Binding PointName}" Width="5*"
|
||||
ElementStyle="{StaticResource DataGridCellCenterTextStyle}"/>
|
||||
<DataGridTextColumn Header="下限值" Binding="{Binding LowerLimit, StringFormat={}{0:N2}}" Width="2.5*"
|
||||
ElementStyle="{StaticResource DataGridCellCenterTextStyle}"/>
|
||||
<DataGridTextColumn Header="上限值" Binding="{Binding UpperLimit, StringFormat={}{0:N2}}" Width="2.5*"
|
||||
ElementStyle="{StaticResource DataGridCellCenterTextStyle}"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</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="160"/>
|
||||
<Button Content="保存胶料快检记录" Command="{Binding SaveCommand}" Style="{StaticResource ButtonPrimary}" Height="36" Width="160"
|
||||
IsEnabled="{Binding CanSave}"
|
||||
Visibility="{Binding ShowSaveButton, Converter={StaticResource Boolean2VisibilityConverter}}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
@@ -62,6 +62,9 @@ public partial class RubberQuickTestOperationView : UserControl
|
||||
var vm = _vm ?? DataContext as RubberQuickTestOperationViewModel;
|
||||
if (vm == null) return;
|
||||
|
||||
var centerTextStyle = (Style)FindResource("DataGridCellCenterTextStyle");
|
||||
var centerEditStyle = (Style)FindResource("DataGridCellCenterEditStyle");
|
||||
|
||||
InspectResultGrid.Columns.Clear();
|
||||
|
||||
InspectResultGrid.Columns.Add(new DataGridTextColumn
|
||||
@@ -72,7 +75,8 @@ public partial class RubberQuickTestOperationView : UserControl
|
||||
Mode = BindingMode.OneWay
|
||||
},
|
||||
IsReadOnly = true,
|
||||
Width = 80
|
||||
Width = 80,
|
||||
ElementStyle = centerTextStyle
|
||||
});
|
||||
|
||||
for (int i = 0; i < vm.DataPointColumns.Count; i++)
|
||||
@@ -83,17 +87,23 @@ public partial class RubberQuickTestOperationView : UserControl
|
||||
? $"数据点{columnIndex + 1}"
|
||||
: col.PointName;
|
||||
|
||||
var valueBinding = new Binding($"Cells[{columnIndex}].Value")
|
||||
{
|
||||
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
|
||||
Mode = vm.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay,
|
||||
TargetNullValue = string.Empty
|
||||
};
|
||||
if (vm.IsReadOnly)
|
||||
valueBinding.StringFormat = "N2";
|
||||
|
||||
InspectResultGrid.Columns.Add(new DataGridTextColumn
|
||||
{
|
||||
Header = header,
|
||||
Binding = new Binding($"Cells[{columnIndex}].Value")
|
||||
{
|
||||
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
|
||||
Mode = BindingMode.TwoWay,
|
||||
TargetNullValue = string.Empty
|
||||
},
|
||||
Binding = valueBinding,
|
||||
Width = 100,
|
||||
IsReadOnly = false
|
||||
IsReadOnly = vm.IsReadOnly,
|
||||
ElementStyle = centerTextStyle,
|
||||
EditingElementStyle = centerEditStyle
|
||||
});
|
||||
}
|
||||
|
||||
@@ -105,7 +115,8 @@ public partial class RubberQuickTestOperationView : UserControl
|
||||
Mode = BindingMode.OneWay
|
||||
},
|
||||
IsReadOnly = true,
|
||||
Width = 90
|
||||
Width = 90,
|
||||
ElementStyle = centerTextStyle
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
<UserControl x:Class="YY.Admin.Views.RubberQuickTest.RubberQuickTestRecordDetailDialogView"
|
||||
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/"
|
||||
xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||
mc:Ignorable="d"
|
||||
Width="1100"
|
||||
MinHeight="680">
|
||||
|
||||
<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="8">
|
||||
<hc:TextBox Text="{Binding Record.RecordNo, Mode=OneWay}" IsReadOnly="True"
|
||||
hc:InfoElement.Title="快检记录号" hc:InfoElement.TitleWidth="90" Margin="0,0,0,8"/>
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<hc:TextBox Text="{Binding Record.ProductionDate, Mode=OneWay, StringFormat={}{0:yyyy-MM-dd}}" IsReadOnly="True"
|
||||
hc:InfoElement.Title="密炼日期" hc:InfoElement.TitleWidth="90" Margin="0,0,0,8"/>
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<hc:TextBox Text="{Binding Record.ProdEquipmentName, Mode=OneWay}" IsReadOnly="True"
|
||||
hc:InfoElement.Title="密炼机台" hc:InfoElement.TitleWidth="90" Margin="0,0,0,8"/>
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<hc:TextBox Text="{Binding Record.ProductionPlanNo, Mode=OneWay}" IsReadOnly="True"
|
||||
hc:InfoElement.Title="密炼计划" hc:InfoElement.TitleWidth="90" Margin="0,0,0,8"/>
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<hc:TextBox Text="{Binding Record.RubberMaterialName, Mode=OneWay}" IsReadOnly="True"
|
||||
hc:InfoElement.Title="胶料名称" hc:InfoElement.TitleWidth="90" Margin="0,0,0,8"/>
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<hc:TextBox Text="{Binding Record.StdName, Mode=OneWay}" IsReadOnly="True"
|
||||
hc:InfoElement.Title="实验标准" hc:InfoElement.TitleWidth="90" Margin="0,0,0,8"/>
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<hc:TextBox Text="{Binding Record.TestMethodName, Mode=OneWay}" IsReadOnly="True"
|
||||
hc:InfoElement.Title="实验方法" hc:InfoElement.TitleWidth="90" Margin="0,0,0,8"/>
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<hc:TextBox Text="{Binding Record.QuickTestTypeName, Mode=OneWay}" IsReadOnly="True"
|
||||
hc:InfoElement.Title="实验类型" hc:InfoElement.TitleWidth="90" Margin="0,0,0,8"/>
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<hc:TextBox Text="{Binding Record.TrainNo, Mode=OneWay}" IsReadOnly="True"
|
||||
hc:InfoElement.Title="车次" hc:InfoElement.TitleWidth="90" Margin="0,0,0,8"/>
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<hc:TextBox Text="{Binding Record.InspectTimes, Mode=OneWay}" IsReadOnly="True"
|
||||
hc:InfoElement.Title="试验次数" hc:InfoElement.TitleWidth="90" Margin="0,0,0,8"/>
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<hc:TextBox Text="{Binding Record.InspectorRealname, Mode=OneWay}" IsReadOnly="True"
|
||||
hc:InfoElement.Title="检验人" hc:InfoElement.TitleWidth="90" Margin="0,0,0,8"/>
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<hc:TextBox Text="{Binding Record.CreateTime, Mode=OneWay, StringFormat={}{0:yyyy-MM-dd HH:mm}}" IsReadOnly="True"
|
||||
hc:InfoElement.Title="检验日期" hc:InfoElement.TitleWidth="90" Margin="0,0,0,8"/>
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<hc:TextBox Text="{Binding InspectResultDisplay, Mode=OneWay}" IsReadOnly="True"
|
||||
hc:InfoElement.Title="是否合格" hc:InfoElement.TitleWidth="90" Margin="0,0,0,8"/>
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
|
||||
<TextBlock Text="温度曲线" FontWeight="SemiBold" Margin="0,8,0,6"/>
|
||||
<Border Height="200" Margin="0,0,0,12">
|
||||
<lvc:CartesianChart Series="{Binding TemperatureSeries}"
|
||||
XAxes="{Binding TemperatureXAxes}"
|
||||
YAxes="{Binding TemperatureYAxes}"
|
||||
LegendPosition="Top"/>
|
||||
</Border>
|
||||
|
||||
<TextBlock Text="S'曲线" FontWeight="SemiBold" Margin="0,0,0,6"/>
|
||||
<Border Height="200" Margin="0,0,0,12">
|
||||
<lvc:CartesianChart Series="{Binding TorqueSeries}"
|
||||
XAxes="{Binding TorqueXAxes}"
|
||||
YAxes="{Binding TorqueYAxes}"
|
||||
LegendPosition="Top"/>
|
||||
</Border>
|
||||
|
||||
<TextBlock Text="数据标准" FontWeight="SemiBold" Margin="0,0,0,6"/>
|
||||
<DataGrid ItemsSource="{Binding StdLines}" AutoGenerateColumns="False" IsReadOnly="True"
|
||||
MaxHeight="180" Margin="0,0,0,12">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="数据点" Binding="{Binding PointName}" Width="*"/>
|
||||
<DataGridTextColumn Header="下限值" Binding="{Binding LowerLimit}" Width="100"/>
|
||||
<DataGridTextColumn Header="上限值" Binding="{Binding UpperLimit}" Width="100"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<TextBlock Text="试验结果" FontWeight="SemiBold" Margin="0,0,0,6"/>
|
||||
<DataGrid ItemsSource="{Binding RawLines}" AutoGenerateColumns="False" IsReadOnly="True"
|
||||
MaxHeight="220">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="编号" Binding="{Binding RowNo}" Width="80"/>
|
||||
<DataGridTextColumn Header="数据点" Binding="{Binding InspectItem}" Width="*"/>
|
||||
<DataGridTextColumn Header="检测值" Binding="{Binding InspectValue}" Width="100"/>
|
||||
<DataGridTextColumn Header="行结果" Binding="{Binding RowInspectResult}" Width="80"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</StackPanel>
|
||||
</hc:ScrollViewer>
|
||||
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="20">
|
||||
<Button Content="关闭" Command="hc:ControlCommands.Close" Style="{StaticResource ButtonDefault}" Width="90"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace YY.Admin.Views.RubberQuickTest;
|
||||
|
||||
public partial class RubberQuickTestRecordDetailDialogView
|
||||
{
|
||||
public RubberQuickTestRecordDetailDialogView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<UserControl x:Class="YY.Admin.Views.RubberQuickTest.RubberQuickTestRecordListView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||
xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True">
|
||||
<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=4, Xl=4}">
|
||||
<hc:TextBox Text="{Binding FilterRecordNo, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0 0 10 10" hc:InfoElement.Title="快检记录号"
|
||||
hc:InfoElement.TitlePlacement="Left" hc:InfoElement.TitleWidth="80"
|
||||
hc:InfoElement.ShowClearButton="True">
|
||||
<hc:TextBox.InputBindings>
|
||||
<KeyBinding Key="Enter" Command="{Binding SearchCommand}"/>
|
||||
</hc:TextBox.InputBindings>
|
||||
</hc:TextBox>
|
||||
</hc:Col>
|
||||
<hc:Col Layout="{hc:ColLayout Xs=12, Sm=8, Md=6, Lg=4, Xl=4}">
|
||||
<hc:TextBox Text="{Binding FilterRubberMaterialName, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0 0 10 10" hc:InfoElement.Title="胶料名称"
|
||||
hc:InfoElement.TitlePlacement="Left" hc:InfoElement.TitleWidth="80"
|
||||
hc:InfoElement.ShowClearButton="True"/>
|
||||
</hc:Col>
|
||||
<hc:Col Layout="{hc:ColLayout Xs=12, Sm=8, Md=6, Lg=4, Xl=4}">
|
||||
<hc:TextBox Text="{Binding FilterPlanNo, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0 0 10 10" hc:InfoElement.Title="密炼计划"
|
||||
hc:InfoElement.TitlePlacement="Left" hc:InfoElement.TitleWidth="80"
|
||||
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>
|
||||
<Button Style="{StaticResource ButtonSuccess}" Command="{Binding AddCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<md:PackIcon Kind="Plus"/>
|
||||
<TextBlock Text="新增" Style="{StaticResource IconButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</hc:UniformSpacingPanel>
|
||||
</Border>
|
||||
|
||||
<DataGrid Grid.Row="2" ItemsSource="{Binding Records}" AutoGenerateColumns="False" IsReadOnly="True"
|
||||
CanUserAddRows="False" SelectionMode="Single" HeadersVisibility="All"
|
||||
Style="{StaticResource CusDataGridStyle}" ColumnHeaderStyle="{StaticResource CusDataGridColumnHeaderStyle}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="快检记录号" Binding="{Binding RecordNo}" Width="160"/>
|
||||
<DataGridTextColumn Header="密炼日期" Binding="{Binding ProductionDate, StringFormat='yyyy-MM-dd'}" Width="100"/>
|
||||
<DataGridTextColumn Header="密炼机台" Binding="{Binding ProdEquipmentName}" Width="100"/>
|
||||
<DataGridTextColumn Header="班次" Binding="{Binding WorkShiftDisplay}" Width="70"/>
|
||||
<DataGridTextColumn Header="密炼计划" Binding="{Binding ProductionPlanNo}" Width="110"/>
|
||||
<DataGridTextColumn Header="胶料名称" Binding="{Binding RubberMaterialName}" Width="120"/>
|
||||
<DataGridTextColumn Header="实验标准" Binding="{Binding StdName}" Width="120"/>
|
||||
<DataGridTextColumn Header="实验方法" Binding="{Binding TestMethodName}" Width="100"/>
|
||||
<DataGridTextColumn Header="实验类型" Binding="{Binding QuickTestTypeName}" Width="100"/>
|
||||
<DataGridTextColumn Header="车次" Binding="{Binding TrainNo}" Width="70"/>
|
||||
<DataGridTextColumn Header="试验次数" Binding="{Binding InspectTimes}" Width="80"/>
|
||||
<DataGridTextColumn Header="检验人" Binding="{Binding InspectorRealname}" Width="80"/>
|
||||
<DataGridTextColumn Header="检验日期" Binding="{Binding InspectDate, StringFormat='yyyy-MM-dd HH:mm'}" Width="130"/>
|
||||
<DataGridTextColumn Header="是否合格" Binding="{Binding InspectResultDisplay}" Width="80"/>
|
||||
<DataGridTextColumn Header="同步状态" Binding="{Binding SyncStatusDisplay}" Width="80"/>
|
||||
<DataGridTemplateColumn Header="操作" Width="150">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Content="详情" Command="{Binding DataContext.ViewDetailCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"
|
||||
CommandParameter="{Binding}" Style="{StaticResource ButtonPrimary}" Height="26" Padding="8,0" Margin="0,0,6,0"/>
|
||||
<Button Content="删除" Command="{Binding DataContext.DeleteCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"
|
||||
CommandParameter="{Binding}" Style="{StaticResource ButtonDanger}" Height="26" Padding="8,0"
|
||||
Visibility="{Binding CanDelete, Converter={StaticResource Boolean2VisibilityConverter}}"/>
|
||||
</StackPanel>
|
||||
</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"/>
|
||||
<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.RubberQuickTest;
|
||||
|
||||
public partial class RubberQuickTestRecordListView : UserControl
|
||||
{
|
||||
public RubberQuickTestRecordListView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user