酸轧数据同步,轧辊新增产线新增各种产线
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
-- =====================================================================
|
||||
-- 轧辊管理多产线支持:为 4 张轧辊表添加 line_id 外键列
|
||||
-- 存量数据默认为 NULL,业务侧按需补填或忽略(NULL 表示未归属产线)
|
||||
-- =====================================================================
|
||||
|
||||
ALTER TABLE mes_roll_info
|
||||
ADD COLUMN line_id BIGINT NULL COMMENT '产线ID(关联 wms_production_line.line_id)' AFTER roll_id,
|
||||
ADD KEY idx_line_id (line_id);
|
||||
|
||||
ALTER TABLE mes_roll_change
|
||||
ADD COLUMN line_id BIGINT NULL COMMENT '产线ID(关联 wms_production_line.line_id)' AFTER change_id,
|
||||
ADD KEY idx_line_stand (line_id, stand_no);
|
||||
|
||||
ALTER TABLE mes_roll_standby
|
||||
ADD COLUMN line_id BIGINT NULL COMMENT '产线ID(关联 wms_production_line.line_id)' AFTER standby_id,
|
||||
ADD KEY idx_line_stand (line_id, stand_no);
|
||||
|
||||
ALTER TABLE mes_roll_grind
|
||||
ADD COLUMN line_id BIGINT NULL COMMENT '产线ID(关联 wms_production_line.line_id)' AFTER grind_id,
|
||||
ADD KEY idx_line_id (line_id);
|
||||
@@ -38,21 +38,21 @@ public class MesRollChangeController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询指定机架当前在机轧辊(最近一次换辊记录)
|
||||
* GET /mes/rollChange/current?standNo=1%23
|
||||
* 查询指定产线+机架当前在机轧辊(最近一次换辊记录)
|
||||
* GET /mes/rollChange/current?lineId=xxx&standNo=1%23
|
||||
*/
|
||||
@GetMapping("/current")
|
||||
public R<MesRollChangeVo> current(@RequestParam String standNo) {
|
||||
return R.ok(iMesRollChangeService.queryCurrentByStand(standNo));
|
||||
public R<MesRollChangeVo> current(Long lineId, @RequestParam String standNo) {
|
||||
return R.ok(iMesRollChangeService.queryCurrentByStand(lineId, standNo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询各机架各辊位实时工作绩效(工作长度/卷数/重量)
|
||||
* GET /mes/rollChange/performance
|
||||
* 查询指定产线各机架各辊位实时工作绩效(工作长度/卷数/重量)
|
||||
* GET /mes/rollChange/performance?lineId=xxx
|
||||
*/
|
||||
@GetMapping("/performance")
|
||||
public R<Map<String, Map<String, Object>>> performance() {
|
||||
return R.ok(iMesRollChangeService.queryRollPerformance());
|
||||
public R<Map<String, Map<String, Object>>> performance(Long lineId) {
|
||||
return R.ok(iMesRollChangeService.queryRollPerformance(lineId));
|
||||
}
|
||||
|
||||
/** 详情 */
|
||||
|
||||
@@ -41,16 +41,16 @@ public class MesRollInfoController extends BaseController {
|
||||
return iMesRollInfoService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/** 状态统计卡片数据 */
|
||||
/** 状态统计卡片数据(lineId 为空时统计全部产线) */
|
||||
@GetMapping("/stats")
|
||||
public R<Map<String, Object>> stats() {
|
||||
return R.ok(iMesRollInfoService.queryStatusStats());
|
||||
public R<Map<String, Object>> stats(Long lineId) {
|
||||
return R.ok(iMesRollInfoService.queryStatusStats(lineId));
|
||||
}
|
||||
|
||||
/** 轧辊编号下拉列表(按辊型 + 状态过滤,均可为空) */
|
||||
/** 轧辊编号下拉列表(lineId / rollType / status 均可为空) */
|
||||
@GetMapping("/options")
|
||||
public R<List<String>> options(String rollType, String status) {
|
||||
return R.ok(iMesRollInfoService.queryRollNoList(rollType, status));
|
||||
public R<List<String>> options(Long lineId, String rollType, String status) {
|
||||
return R.ok(iMesRollInfoService.queryRollNoList(lineId, rollType, status));
|
||||
}
|
||||
|
||||
/** 详情 */
|
||||
@@ -90,13 +90,13 @@ public class MesRollInfoController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 从换辊记录同步在线状态
|
||||
* 从换辊记录同步在线状态(lineId 为空时同步全部产线)
|
||||
* 将当前各机架在机轧辊的状态强制修正为 Online,解决状态数据不一致问题
|
||||
*/
|
||||
@Log(title = "轧辊库-状态同步", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/syncStatus")
|
||||
public R<Void> syncStatus() {
|
||||
iMesRollInfoService.syncStatusFromChange();
|
||||
public R<Void> syncStatus(Long lineId) {
|
||||
iMesRollInfoService.syncStatusFromChange(lineId);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
||||
@@ -28,12 +28,12 @@ public class MesRollStandbyController extends BaseController {
|
||||
private final IMesRollStandbyService iMesRollStandbyService;
|
||||
|
||||
/**
|
||||
* 查询指定机架的下批轧辊列表
|
||||
* GET /mes/rollStandby/list?standNo=1%23
|
||||
* 查询指定产线+机架的下批轧辊列表
|
||||
* GET /mes/rollStandby/list?lineId=xxx&standNo=1%23
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public R<List<MesRollStandbyVo>> list(@RequestParam String standNo) {
|
||||
return R.ok(iMesRollStandbyService.queryByStand(standNo));
|
||||
public R<List<MesRollStandbyVo>> list(Long lineId, @RequestParam String standNo) {
|
||||
return R.ok(iMesRollStandbyService.queryByStand(lineId, standNo));
|
||||
}
|
||||
|
||||
/** 详情 */
|
||||
@@ -66,12 +66,12 @@ public class MesRollStandbyController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空指定机架的全部下批轧辊
|
||||
* DELETE /mes/rollStandby/clear?standNo=1%23
|
||||
* 清空指定产线+机架的全部下批轧辊
|
||||
* DELETE /mes/rollStandby/clear?lineId=xxx&standNo=1%23
|
||||
*/
|
||||
@Log(title = "下批轧辊", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/clear")
|
||||
public R<Void> clear(@RequestParam String standNo) {
|
||||
return toAjax(iMesRollStandbyService.clearByStand(standNo));
|
||||
public R<Void> clear(Long lineId, @RequestParam String standNo) {
|
||||
return toAjax(iMesRollStandbyService.clearByStand(lineId, standNo));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,7 @@ import java.util.Date;
|
||||
|
||||
/**
|
||||
* 换辊记录 mes_roll_change
|
||||
* 四辊轧机,双机架(1# / 2#)
|
||||
* 每次换辊记录 4 支辊:上工作辊、下工作辊、上支撑辊、下支撑辊
|
||||
* 四辊轧机,支持多产线,每次换辊记录 4 支辊:上工作辊、下工作辊、上支撑辊、下支撑辊
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@@ -25,6 +24,9 @@ public class MesRollChange extends BaseEntity {
|
||||
@TableId(value = "change_id")
|
||||
private Long changeId;
|
||||
|
||||
/** 产线ID */
|
||||
private Long lineId;
|
||||
|
||||
/** 换辊编号 */
|
||||
private String changeNo;
|
||||
|
||||
|
||||
@@ -46,6 +46,9 @@ public class MesRollGrind extends BaseEntity {
|
||||
@TableId(value = "grind_id")
|
||||
private Long grindId;
|
||||
|
||||
/** 产线ID */
|
||||
private Long lineId;
|
||||
|
||||
/** 轧辊ID */
|
||||
private Long rollId;
|
||||
|
||||
|
||||
@@ -23,6 +23,9 @@ public class MesRollInfo extends BaseEntity {
|
||||
@TableId(value = "roll_id")
|
||||
private Long rollId;
|
||||
|
||||
/** 产线ID */
|
||||
private Long lineId;
|
||||
|
||||
/** 轧辊编号 */
|
||||
private String rollNo;
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@ public class MesRollStandby extends BaseEntity {
|
||||
@TableId(value = "standby_id")
|
||||
private Long standbyId;
|
||||
|
||||
/** 产线ID */
|
||||
private Long lineId;
|
||||
|
||||
/** 机架号:1# / 2# */
|
||||
private String standNo;
|
||||
|
||||
|
||||
@@ -18,6 +18,9 @@ public class MesRollChangeBo extends BaseEntity {
|
||||
|
||||
private Long changeId;
|
||||
|
||||
/** 产线ID(查询过滤 / 新增归属) */
|
||||
private Long lineId;
|
||||
|
||||
private String changeNo;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
|
||||
@@ -18,6 +18,9 @@ public class MesRollGrindBo extends BaseEntity {
|
||||
|
||||
private Long grindId;
|
||||
|
||||
/** 产线ID(查询过滤用) */
|
||||
private Long lineId;
|
||||
|
||||
@NotNull(message = "轧辊ID不能为空")
|
||||
private Long rollId;
|
||||
|
||||
|
||||
@@ -22,6 +22,9 @@ public class MesRollInfoBo extends BaseEntity {
|
||||
@NotNull(message = "轧辊ID不能为空", groups = EditGroup.class)
|
||||
private Long rollId;
|
||||
|
||||
/** 产线ID(查询过滤 / 新增归属) */
|
||||
private Long lineId;
|
||||
|
||||
@NotBlank(message = "轧辊编号不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String rollNo;
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@ public class MesRollStandbyBo extends BaseEntity {
|
||||
|
||||
private Long standbyId;
|
||||
|
||||
/** 产线ID(查询过滤 / 新增归属) */
|
||||
private Long lineId;
|
||||
|
||||
/** 机架号:1# / 2# */
|
||||
@NotBlank(message = "机架号不能为空", groups = AddGroup.class)
|
||||
private String standNo;
|
||||
|
||||
@@ -17,6 +17,8 @@ public class MesRollChangeVo {
|
||||
|
||||
private Long changeId;
|
||||
|
||||
private Long lineId;
|
||||
|
||||
private String changeNo;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
|
||||
@@ -19,6 +19,12 @@ public class MesRollInfoVo {
|
||||
@ExcelProperty("轧辊ID")
|
||||
private Long rollId;
|
||||
|
||||
@ExcelProperty("产线ID")
|
||||
private Long lineId;
|
||||
|
||||
@ExcelProperty("产线名称")
|
||||
private String lineName;
|
||||
|
||||
@ExcelProperty("轧辊编号")
|
||||
private String rollNo;
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ public class MesRollStandbyVo {
|
||||
|
||||
private Long standbyId;
|
||||
|
||||
private Long lineId;
|
||||
|
||||
/** 机架号:1# / 2# */
|
||||
private String standNo;
|
||||
|
||||
|
||||
@@ -13,27 +13,30 @@ import java.util.Map;
|
||||
*/
|
||||
public interface MesRollChangeMapper extends BaseMapperPlus<MesRollChangeMapper, MesRollChange, MesRollChangeVo> {
|
||||
|
||||
/** 查询指定机架最新一次换辊记录(当前在机轧辊) */
|
||||
MesRollChangeVo selectLatestByStand(@Param("standNo") String standNo);
|
||||
/** 查询指定产线+机架最新一次换辊记录(当前在机轧辊) */
|
||||
MesRollChangeVo selectLatestByStand(@Param("lineId") Long lineId, @Param("standNo") String standNo);
|
||||
|
||||
/**
|
||||
* 按辊位查询该位置最新一次有记录的换辊(支持部分换辊)
|
||||
* posType: upperWr / lowerWr / upperBr / lowerBr
|
||||
*/
|
||||
MesRollChangeVo selectLatestByStandAndPosition(@Param("standNo") String standNo,
|
||||
MesRollChangeVo selectLatestByStandAndPosition(@Param("lineId") Long lineId,
|
||||
@Param("standNo") String standNo,
|
||||
@Param("posType") String posType);
|
||||
|
||||
/**
|
||||
* 组合查询机架各辊位当前实际在机状态(每个位置独立取最新非空记录)
|
||||
* 组合查询指定产线+机架各辊位当前实际在机状态(每个位置独立取最新非空记录)
|
||||
* 返回 map,key 同 MesRollChangeVo 字段名(camelCase)
|
||||
*/
|
||||
Map<String, Object> selectCurrentStateByStand(@Param("standNo") String standNo);
|
||||
Map<String, Object> selectCurrentStateByStand(@Param("lineId") Long lineId, @Param("standNo") String standNo);
|
||||
|
||||
/**
|
||||
* 查询同机架下一次换辊时间(任意辊位有换辊即触发)
|
||||
* 查询同产线+机架下一次换辊时间(任意辊位有换辊即触发)
|
||||
* 返回 null 表示该辊仍在机
|
||||
*/
|
||||
Date selectNextChangeTime(@Param("standNo") String standNo, @Param("changeTime") Date changeTime);
|
||||
Date selectNextChangeTime(@Param("lineId") Long lineId,
|
||||
@Param("standNo") String standNo,
|
||||
@Param("changeTime") Date changeTime);
|
||||
|
||||
/**
|
||||
* 统计指定时间区间内的卷料生产统计:
|
||||
|
||||
@@ -15,13 +15,17 @@ public interface MesRollInfoMapper extends BaseMapperPlus<MesRollInfoMapper, Mes
|
||||
|
||||
/**
|
||||
* 按状态统计数量(用于总览卡片)
|
||||
* lineId 为 null 时统计全部产线
|
||||
*/
|
||||
List<Map<String, Object>> selectStatusStats();
|
||||
List<Map<String, Object>> selectStatusStats(@Param("lineId") Long lineId);
|
||||
|
||||
/**
|
||||
* 查询轧辊编号列表(用于下拉选择,可按辊型和状态过滤)
|
||||
* 查询轧辊编号列表(用于下拉选择,可按产线、辊型、状态过滤)
|
||||
* lineId 为 null 时不过滤产线
|
||||
*/
|
||||
List<String> selectRollNoList(@Param("rollType") String rollType, @Param("status") String status);
|
||||
List<String> selectRollNoList(@Param("lineId") Long lineId,
|
||||
@Param("rollType") String rollType,
|
||||
@Param("status") String status);
|
||||
|
||||
/**
|
||||
* 按轧辊编号查询(用于换辊时同步状态)
|
||||
|
||||
@@ -12,9 +12,9 @@ import java.util.List;
|
||||
*/
|
||||
public interface MesRollStandbyMapper extends BaseMapperPlus<MesRollStandbyMapper, MesRollStandby, MesRollStandbyVo> {
|
||||
|
||||
/** 按机架查询下批轧辊列表 */
|
||||
List<MesRollStandbyVo> selectByStand(@Param("standNo") String standNo);
|
||||
/** 按产线+机架查询下批轧辊列表 */
|
||||
List<MesRollStandbyVo> selectByStand(@Param("lineId") Long lineId, @Param("standNo") String standNo);
|
||||
|
||||
/** 清空某机架的下批轧辊 */
|
||||
int clearByStand(@Param("standNo") String standNo);
|
||||
/** 清空指定产线+机架的下批轧辊 */
|
||||
int clearByStand(@Param("lineId") Long lineId, @Param("standNo") String standNo);
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ public interface IMesRollChangeService {
|
||||
|
||||
MesRollChangeVo queryById(Long changeId);
|
||||
|
||||
/** 查询指定机架当前在机轧辊(最新一次换辊记录) */
|
||||
MesRollChangeVo queryCurrentByStand(String standNo);
|
||||
/** 查询指定产线+机架当前在机轧辊(最新一次换辊记录) */
|
||||
MesRollChangeVo queryCurrentByStand(Long lineId, String standNo);
|
||||
|
||||
TableDataInfo<MesRollChangeVo> queryPageList(MesRollChangeBo bo, PageQuery pageQuery);
|
||||
|
||||
@@ -28,9 +28,9 @@ public interface IMesRollChangeService {
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 查询各机架各辊位的实时工作绩效(工作长度/卷数/重量)
|
||||
* 查询指定产线各机架各辊位的实时工作绩效(工作长度/卷数/重量)
|
||||
* 返回结构: { posType -> { standNo -> { rollNo, workLength, coilCount, totalWeight } } }
|
||||
* posType: upperBr / upperWr / lowerWr / lowerBr
|
||||
*/
|
||||
Map<String, Map<String, Object>> queryRollPerformance();
|
||||
Map<String, Map<String, Object>> queryRollPerformance(Long lineId);
|
||||
}
|
||||
|
||||
@@ -20,11 +20,16 @@ public interface IMesRollInfoService {
|
||||
|
||||
List<MesRollInfoVo> queryList(MesRollInfoBo bo);
|
||||
|
||||
/** 按状态统计(总览卡片) */
|
||||
Map<String, Object> queryStatusStats();
|
||||
/**
|
||||
* 按状态统计(总览卡片)
|
||||
* lineId 为 null 时统计全部产线
|
||||
*/
|
||||
Map<String, Object> queryStatusStats(Long lineId);
|
||||
|
||||
/** 轧辊编号下拉列表(status 为 null 时不过滤状态) */
|
||||
List<String> queryRollNoList(String rollType, String status);
|
||||
/**
|
||||
* 轧辊编号下拉列表(lineId / rollType / status 均可为 null,不过滤对应维度)
|
||||
*/
|
||||
List<String> queryRollNoList(Long lineId, String rollType, String status);
|
||||
|
||||
Long insertByBo(MesRollInfoBo bo);
|
||||
|
||||
@@ -40,6 +45,7 @@ public interface IMesRollInfoService {
|
||||
* 每个机架最新一次换辊记录中的 4 支辊 → Online;
|
||||
* 下批辊列表中的辊 → Standby(已由 addStandby 维护,此处不重复处理);
|
||||
* 其余不变,仅修正当前在机辊的状态数据不一致问题。
|
||||
* lineId 为 null 时同步全部产线;指定 lineId 时仅同步该产线。
|
||||
*/
|
||||
void syncStatusFromChange();
|
||||
void syncStatusFromChange(Long lineId);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ public interface IMesRollStandbyService {
|
||||
|
||||
MesRollStandbyVo queryById(Long standbyId);
|
||||
|
||||
/** 查询指定机架的下批轧辊列表 */
|
||||
List<MesRollStandbyVo> queryByStand(String standNo);
|
||||
/** 查询指定产线+机架的下批轧辊列表 */
|
||||
List<MesRollStandbyVo> queryByStand(Long lineId, String standNo);
|
||||
|
||||
/** 新增下批轧辊,同步将该辊状态更新为 Standby */
|
||||
Long addStandby(MesRollStandbyBo bo);
|
||||
@@ -24,6 +24,6 @@ public interface IMesRollStandbyService {
|
||||
/** 删除某条下批轧辊,同步将该辊状态恢复为 Offline */
|
||||
Boolean deleteById(Long standbyId);
|
||||
|
||||
/** 清空指定机架的全部下批轧辊,并将对应辊状态恢复为 Offline */
|
||||
Boolean clearByStand(String standNo);
|
||||
/** 清空指定产线+机架的全部下批轧辊,并将对应辊状态恢复为 Offline */
|
||||
Boolean clearByStand(Long lineId, String standNo);
|
||||
}
|
||||
|
||||
@@ -44,11 +44,12 @@ public class MesRollChangeServiceImpl implements IMesRollChangeService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public MesRollChangeVo queryCurrentByStand(String standNo) {
|
||||
public MesRollChangeVo queryCurrentByStand(Long lineId, String standNo) {
|
||||
// 组合各辊位最新状态,转换为 VO
|
||||
Map<String, Object> state = baseMapper.selectCurrentStateByStand(standNo);
|
||||
Map<String, Object> state = baseMapper.selectCurrentStateByStand(lineId, standNo);
|
||||
if (state == null) return null;
|
||||
MesRollChangeVo vo = new MesRollChangeVo();
|
||||
vo.setLineId(lineId);
|
||||
vo.setStandNo(standNo);
|
||||
vo.setUpperWrNo(str(state.get("upperWrNo")));
|
||||
vo.setUpperWrDia(decimal(state.get("upperWrDia")));
|
||||
@@ -70,7 +71,7 @@ public class MesRollChangeServiceImpl implements IMesRollChangeService {
|
||||
Page<MesRollChangeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
// 为每条换辊记录计算:工作长度、卷数、重量
|
||||
for (MesRollChangeVo vo : result.getRecords()) {
|
||||
Date endTime = baseMapper.selectNextChangeTime(vo.getStandNo(), vo.getChangeTime());
|
||||
Date endTime = baseMapper.selectNextChangeTime(vo.getLineId(), vo.getStandNo(), vo.getChangeTime());
|
||||
Map<String, Object> stats = baseMapper.selectCoilStats(vo.getChangeTime(), endTime);
|
||||
fillStatsToVo(vo, stats);
|
||||
}
|
||||
@@ -81,12 +82,12 @@ public class MesRollChangeServiceImpl implements IMesRollChangeService {
|
||||
private static final List<String> STANDS = Arrays.asList("1#", "2#");
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, Object>> queryRollPerformance() {
|
||||
public Map<String, Map<String, Object>> queryRollPerformance(Long lineId) {
|
||||
Map<String, Map<String, Object>> result = new HashMap<>(4);
|
||||
for (String posType : POS_TYPES) {
|
||||
Map<String, Object> byStand = new HashMap<>(2);
|
||||
for (String standNo : STANDS) {
|
||||
MesRollChangeVo rec = baseMapper.selectLatestByStandAndPosition(standNo, posType);
|
||||
MesRollChangeVo rec = baseMapper.selectLatestByStandAndPosition(lineId, standNo, posType);
|
||||
Map<String, Object> cell = new HashMap<>(6);
|
||||
if (rec != null) {
|
||||
cell.put("rollNo", getRollNoByPos(rec, posType));
|
||||
@@ -106,9 +107,9 @@ public class MesRollChangeServiceImpl implements IMesRollChangeService {
|
||||
}
|
||||
|
||||
/** 若该辊位要换新辊,则把当前在机的旧辊下线 */
|
||||
private void offlineIfReplaced(String standNo, String posType, String newRollNo) {
|
||||
private void offlineIfReplaced(Long lineId, String standNo, String posType, String newRollNo) {
|
||||
if (StringUtils.isBlank(newRollNo)) return;
|
||||
MesRollChangeVo cur = baseMapper.selectLatestByStandAndPosition(standNo, posType);
|
||||
MesRollChangeVo cur = baseMapper.selectLatestByStandAndPosition(lineId, standNo, posType);
|
||||
if (cur != null) {
|
||||
String oldRollNo = getRollNoByPos(cur, posType);
|
||||
if (StringUtils.isNotBlank(oldRollNo)) {
|
||||
@@ -158,6 +159,7 @@ public class MesRollChangeServiceImpl implements IMesRollChangeService {
|
||||
|
||||
private LambdaQueryWrapper<MesRollChange> buildQueryWrapper(MesRollChangeBo bo) {
|
||||
LambdaQueryWrapper<MesRollChange> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getLineId() != null, MesRollChange::getLineId, bo.getLineId());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getStandNo()), MesRollChange::getStandNo, bo.getStandNo());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getChangeType()), MesRollChange::getChangeType, bo.getChangeType());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getChangeStatus()), MesRollChange::getChangeStatus, bo.getChangeStatus());
|
||||
@@ -184,10 +186,10 @@ public class MesRollChangeServiceImpl implements IMesRollChangeService {
|
||||
add.setChangeType("三级换辊");
|
||||
}
|
||||
// 按辊位独立换辊:只下线被替换的那个位置的旧辊
|
||||
offlineIfReplaced(add.getStandNo(), "upperWr", add.getUpperWrNo());
|
||||
offlineIfReplaced(add.getStandNo(), "lowerWr", add.getLowerWrNo());
|
||||
offlineIfReplaced(add.getStandNo(), "upperBr", add.getUpperBrNo());
|
||||
offlineIfReplaced(add.getStandNo(), "lowerBr", add.getLowerBrNo());
|
||||
offlineIfReplaced(add.getLineId(), add.getStandNo(), "upperWr", add.getUpperWrNo());
|
||||
offlineIfReplaced(add.getLineId(), add.getStandNo(), "lowerWr", add.getLowerWrNo());
|
||||
offlineIfReplaced(add.getLineId(), add.getStandNo(), "upperBr", add.getUpperBrNo());
|
||||
offlineIfReplaced(add.getLineId(), add.getStandNo(), "lowerBr", add.getLowerBrNo());
|
||||
|
||||
baseMapper.insert(add);
|
||||
|
||||
|
||||
@@ -52,8 +52,8 @@ public class MesRollInfoServiceImpl implements IMesRollInfoService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> queryStatusStats() {
|
||||
List<Map<String, Object>> rows = baseMapper.selectStatusStats();
|
||||
public Map<String, Object> queryStatusStats(Long lineId) {
|
||||
List<Map<String, Object>> rows = baseMapper.selectStatusStats(lineId);
|
||||
Map<String, Object> result = new HashMap<String, Object>(8);
|
||||
int total = 0;
|
||||
for (Map<String, Object> row : rows) {
|
||||
@@ -67,12 +67,13 @@ public class MesRollInfoServiceImpl implements IMesRollInfoService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> queryRollNoList(String rollType, String status) {
|
||||
return baseMapper.selectRollNoList(rollType, status);
|
||||
public List<String> queryRollNoList(Long lineId, String rollType, String status) {
|
||||
return baseMapper.selectRollNoList(lineId, rollType, status);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<MesRollInfo> buildQueryWrapper(MesRollInfoBo bo) {
|
||||
LambdaQueryWrapper<MesRollInfo> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getLineId() != null, MesRollInfo::getLineId, bo.getLineId());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getRollNo()), MesRollInfo::getRollNo, bo.getRollNo());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getRollType()), MesRollInfo::getRollType, bo.getRollType());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), MesRollInfo::getStatus, bo.getStatus());
|
||||
@@ -120,11 +121,11 @@ public class MesRollInfoServiceImpl implements IMesRollInfoService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncStatusFromChange() {
|
||||
public void syncStatusFromChange(Long lineId) {
|
||||
// 按辊位独立取最新在机辊,确保各位置状态正确
|
||||
for (String standNo : Arrays.asList("1#", "2#")) {
|
||||
for (String posType : Arrays.asList("upperWr", "lowerWr", "upperBr", "lowerBr")) {
|
||||
MesRollChangeVo rec = rollChangeMapper.selectLatestByStandAndPosition(standNo, posType);
|
||||
MesRollChangeVo rec = rollChangeMapper.selectLatestByStandAndPosition(lineId, standNo, posType);
|
||||
if (rec == null) continue;
|
||||
String rollNo = getRollNoByPos(rec, posType);
|
||||
if (StringUtils.isNotBlank(rollNo)) {
|
||||
|
||||
@@ -31,8 +31,8 @@ public class MesRollStandbyServiceImpl implements IMesRollStandbyService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MesRollStandbyVo> queryByStand(String standNo) {
|
||||
return baseMapper.selectByStand(standNo);
|
||||
public List<MesRollStandbyVo> queryByStand(Long lineId, String standNo) {
|
||||
return baseMapper.selectByStand(lineId, standNo);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,10 +70,10 @@ public class MesRollStandbyServiceImpl implements IMesRollStandbyService {
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean clearByStand(String standNo) {
|
||||
public Boolean clearByStand(Long lineId, String standNo) {
|
||||
// 先查出所有辊号再清空
|
||||
List<MesRollStandbyVo> list = baseMapper.selectByStand(standNo);
|
||||
int rows = baseMapper.clearByStand(standNo);
|
||||
List<MesRollStandbyVo> list = baseMapper.selectByStand(lineId, standNo);
|
||||
int rows = baseMapper.clearByStand(lineId, standNo);
|
||||
for (MesRollStandbyVo vo : list) {
|
||||
if (StringUtils.isNotBlank(vo.getRollNo())) {
|
||||
// 只有仍处于 Standby 状态时才回退为 Offline(换辊后已变 Online 的不动)
|
||||
|
||||
@@ -2,26 +2,28 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.klp.mes.roll.mapper.MesRollChangeMapper">
|
||||
|
||||
<!-- 查询指定机架最新一次换辊记录(即当前在机轧辊) -->
|
||||
<!-- 查询指定产线+机架最新一次换辊记录(即当前在机轧辊) -->
|
||||
<select id="selectLatestByStand" resultType="com.klp.mes.roll.domain.vo.MesRollChangeVo">
|
||||
SELECT change_id, change_no, change_time, stand_no, change_type, change_status, operator,
|
||||
SELECT change_id, line_id, change_no, change_time, stand_no, change_type, change_status, operator,
|
||||
upper_wr_no, upper_wr_dia, lower_wr_no, lower_wr_dia,
|
||||
upper_br_no, upper_br_dia, lower_br_no, lower_br_dia,
|
||||
remark, create_time
|
||||
FROM mes_roll_change
|
||||
WHERE del_flag = 0
|
||||
AND stand_no = #{standNo}
|
||||
<if test="lineId != null">AND line_id = #{lineId}</if>
|
||||
ORDER BY change_time DESC, change_id DESC
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<!-- 按辊位查最新非空换辊记录(支持部分换辊) -->
|
||||
<select id="selectLatestByStandAndPosition" resultType="com.klp.mes.roll.domain.vo.MesRollChangeVo">
|
||||
SELECT change_id, change_no, change_time, stand_no, operator,
|
||||
SELECT change_id, line_id, change_no, change_time, stand_no, operator,
|
||||
upper_wr_no, upper_wr_dia, lower_wr_no, lower_wr_dia,
|
||||
upper_br_no, upper_br_dia, lower_br_no, lower_br_dia
|
||||
FROM mes_roll_change
|
||||
WHERE del_flag = 0 AND stand_no = #{standNo}
|
||||
<if test="lineId != null">AND line_id = #{lineId}</if>
|
||||
<choose>
|
||||
<when test="posType == 'upperWr'">AND upper_wr_no IS NOT NULL AND upper_wr_no != ''</when>
|
||||
<when test="posType == 'lowerWr'">AND lower_wr_no IS NOT NULL AND lower_wr_no != ''</when>
|
||||
@@ -35,24 +37,25 @@
|
||||
<!-- 组合查询各辊位当前实际在机状态(每个位置独立取最新非空记录) -->
|
||||
<select id="selectCurrentStateByStand" resultType="map">
|
||||
SELECT
|
||||
(SELECT upper_wr_no FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 AND upper_wr_no IS NOT NULL AND upper_wr_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS upperWrNo,
|
||||
(SELECT upper_wr_dia FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 AND upper_wr_no IS NOT NULL AND upper_wr_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS upperWrDia,
|
||||
(SELECT lower_wr_no FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 AND lower_wr_no IS NOT NULL AND lower_wr_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS lowerWrNo,
|
||||
(SELECT lower_wr_dia FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 AND lower_wr_no IS NOT NULL AND lower_wr_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS lowerWrDia,
|
||||
(SELECT upper_br_no FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 AND upper_br_no IS NOT NULL AND upper_br_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS upperBrNo,
|
||||
(SELECT upper_br_dia FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 AND upper_br_no IS NOT NULL AND upper_br_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS upperBrDia,
|
||||
(SELECT lower_br_no FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 AND lower_br_no IS NOT NULL AND lower_br_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS lowerBrNo,
|
||||
(SELECT lower_br_dia FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 AND lower_br_no IS NOT NULL AND lower_br_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS lowerBrDia,
|
||||
(SELECT MAX(change_time) FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0) AS changeTime
|
||||
(SELECT upper_wr_no FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 <if test="lineId != null">AND line_id = #{lineId}</if> AND upper_wr_no IS NOT NULL AND upper_wr_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS upperWrNo,
|
||||
(SELECT upper_wr_dia FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 <if test="lineId != null">AND line_id = #{lineId}</if> AND upper_wr_no IS NOT NULL AND upper_wr_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS upperWrDia,
|
||||
(SELECT lower_wr_no FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 <if test="lineId != null">AND line_id = #{lineId}</if> AND lower_wr_no IS NOT NULL AND lower_wr_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS lowerWrNo,
|
||||
(SELECT lower_wr_dia FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 <if test="lineId != null">AND line_id = #{lineId}</if> AND lower_wr_no IS NOT NULL AND lower_wr_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS lowerWrDia,
|
||||
(SELECT upper_br_no FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 <if test="lineId != null">AND line_id = #{lineId}</if> AND upper_br_no IS NOT NULL AND upper_br_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS upperBrNo,
|
||||
(SELECT upper_br_dia FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 <if test="lineId != null">AND line_id = #{lineId}</if> AND upper_br_no IS NOT NULL AND upper_br_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS upperBrDia,
|
||||
(SELECT lower_br_no FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 <if test="lineId != null">AND line_id = #{lineId}</if> AND lower_br_no IS NOT NULL AND lower_br_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS lowerBrNo,
|
||||
(SELECT lower_br_dia FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 <if test="lineId != null">AND line_id = #{lineId}</if> AND lower_br_no IS NOT NULL AND lower_br_no != '' ORDER BY change_time DESC, change_id DESC LIMIT 1) AS lowerBrDia,
|
||||
(SELECT MAX(change_time) FROM mes_roll_change WHERE stand_no = #{standNo} AND del_flag = 0 <if test="lineId != null">AND line_id = #{lineId}</if>) AS changeTime
|
||||
</select>
|
||||
|
||||
<!-- 查询同机架在本次换辊之后最近一次换辊的时间 -->
|
||||
<!-- 查询同产线+机架在本次换辊之后最近一次换辊的时间 -->
|
||||
<select id="selectNextChangeTime" resultType="java.util.Date">
|
||||
SELECT MIN(change_time)
|
||||
FROM mes_roll_change
|
||||
WHERE del_flag = 0
|
||||
AND stand_no = #{standNo}
|
||||
AND change_time > #{changeTime}
|
||||
<if test="lineId != null">AND line_id = #{lineId}</if>
|
||||
</select>
|
||||
|
||||
<!--
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
SELECT status, COUNT(*) AS cnt
|
||||
FROM mes_roll_info
|
||||
WHERE del_flag = 0
|
||||
<if test="lineId != null">AND line_id = #{lineId}</if>
|
||||
GROUP BY status
|
||||
</select>
|
||||
|
||||
@@ -15,6 +16,7 @@
|
||||
SELECT roll_no FROM mes_roll_info
|
||||
WHERE del_flag = 0
|
||||
AND status != 'Scrapped'
|
||||
<if test="lineId != null">AND line_id = #{lineId}</if>
|
||||
<if test="rollType != null and rollType != ''">
|
||||
AND roll_type = #{rollType}
|
||||
</if>
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.klp.mes.roll.mapper.MesRollStandbyMapper">
|
||||
|
||||
<!-- 按机架查询下批轧辊,附带辊位中文标签 -->
|
||||
<!-- 按产线+机架查询下批轧辊,附带辊位中文标签 -->
|
||||
<select id="selectByStand" resultType="com.klp.mes.roll.domain.vo.MesRollStandbyVo">
|
||||
SELECT
|
||||
standby_id, stand_no, roll_no, roll_type, position,
|
||||
standby_id, line_id, stand_no, roll_no, roll_type, position,
|
||||
CASE
|
||||
WHEN roll_type = 'BR' AND position = 'UP' THEN '上支撑辊'
|
||||
WHEN roll_type = 'WR' AND position = 'UP' THEN '上工作辊'
|
||||
@@ -17,17 +17,19 @@
|
||||
FROM mes_roll_standby
|
||||
WHERE del_flag = 0
|
||||
AND stand_no = #{standNo}
|
||||
<if test="lineId != null">AND line_id = #{lineId}</if>
|
||||
ORDER BY
|
||||
FIELD(roll_type, 'BR', 'WR', 'WR', 'BR'),
|
||||
FIELD(position, 'UP', 'UP', 'DOWN', 'DOWN')
|
||||
</select>
|
||||
|
||||
<!-- 逻辑删除指定机架所有下批轧辊(清空) -->
|
||||
<!-- 逻辑删除指定产线+机架所有下批轧辊(清空) -->
|
||||
<update id="clearByStand">
|
||||
UPDATE mes_roll_standby
|
||||
SET del_flag = 1
|
||||
WHERE del_flag = 0
|
||||
AND stand_no = #{standNo}
|
||||
<if test="lineId != null">AND line_id = #{lineId}</if>
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询换辊记录分页列表(支持按机架、类型、时间筛选)
|
||||
// 查询换辊记录分页列表(支持按产线、机架、类型、时间筛选)
|
||||
export function listRollChange(query) {
|
||||
return request({
|
||||
url: '/mes/rollChange/list',
|
||||
@@ -9,20 +9,21 @@ export function listRollChange(query) {
|
||||
})
|
||||
}
|
||||
|
||||
// 查询指定机架当前在机轧辊(最近一次换辊记录)
|
||||
export function getCurrentRolls(standNo) {
|
||||
// 查询指定产线+机架当前在机轧辊(最近一次换辊记录)
|
||||
export function getCurrentRolls(lineId, standNo) {
|
||||
return request({
|
||||
url: '/mes/rollChange/current',
|
||||
method: 'get',
|
||||
params: { standNo }
|
||||
params: { lineId, standNo }
|
||||
})
|
||||
}
|
||||
|
||||
// 查询各机架各辊位实时工作绩效(workLength/coilCount/totalWeight)
|
||||
export function getRollPerformance() {
|
||||
// 查询指定产线各机架各辊位实时工作绩效(workLength/coilCount/totalWeight)
|
||||
export function getRollPerformance(lineId) {
|
||||
return request({
|
||||
url: '/mes/rollChange/performance',
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
params: { lineId }
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -9,20 +9,21 @@ export function listRollInfo(query) {
|
||||
})
|
||||
}
|
||||
|
||||
// 查询状态统计卡片
|
||||
export function getRollStats() {
|
||||
// 查询状态统计卡片(lineId 为空时统计全部产线)
|
||||
export function getRollStats(lineId) {
|
||||
return request({
|
||||
url: '/mes/rollInfo/stats',
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
params: { lineId }
|
||||
})
|
||||
}
|
||||
|
||||
// 查询轧辊编号下拉(rollType/status 均可为空,不传则不过滤)
|
||||
export function listRollOptions(rollType, status) {
|
||||
// 查询轧辊编号下拉(lineId/rollType/status 均可为空,不传则不过滤)
|
||||
export function listRollOptions(lineId, rollType, status) {
|
||||
return request({
|
||||
url: '/mes/rollInfo/options',
|
||||
method: 'get',
|
||||
params: { rollType, status }
|
||||
params: { lineId, rollType, status }
|
||||
})
|
||||
}
|
||||
|
||||
@@ -68,11 +69,12 @@ export function scrapRollInfo(rollId) {
|
||||
})
|
||||
}
|
||||
|
||||
// 从换辊记录同步在线状态
|
||||
export function syncRollStatus() {
|
||||
// 从换辊记录同步在线状态(lineId 为空时同步全部产线)
|
||||
export function syncRollStatus(lineId) {
|
||||
return request({
|
||||
url: '/mes/rollInfo/syncStatus',
|
||||
method: 'post'
|
||||
method: 'post',
|
||||
params: { lineId }
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询指定机架下批轧辊列表
|
||||
export function listRollStandby(standNo) {
|
||||
// 查询指定产线+机架下批轧辊列表
|
||||
export function listRollStandby(lineId, standNo) {
|
||||
return request({
|
||||
url: '/mes/rollStandby/list',
|
||||
method: 'get',
|
||||
params: { standNo }
|
||||
params: { lineId, standNo }
|
||||
})
|
||||
}
|
||||
|
||||
@@ -43,11 +43,11 @@ export function delRollStandby(standbyId) {
|
||||
})
|
||||
}
|
||||
|
||||
// 清空指定机架全部下批轧辊
|
||||
export function clearRollStandby(standNo) {
|
||||
// 清空指定产线+机架全部下批轧辊
|
||||
export function clearRollStandby(lineId, standNo) {
|
||||
return request({
|
||||
url: '/mes/rollStandby/clear',
|
||||
method: 'delete',
|
||||
params: { standNo }
|
||||
params: { lineId, standNo }
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,7 +2,21 @@
|
||||
<div class="app-container grind-page">
|
||||
<div class="grind-layout">
|
||||
|
||||
<!-- ── 左侧:轧辊选择 ── -->
|
||||
<!-- ── 产线 Tab 列 ── -->
|
||||
<div class="line-tabs">
|
||||
<div
|
||||
:class="['lt-item', filterLineId === null ? 'lt-item--active' : '']"
|
||||
@click="handleLineTab(null)"
|
||||
>全部</div>
|
||||
<div
|
||||
v-for="l in sortedProductionLines"
|
||||
:key="l.lineId"
|
||||
:class="['lt-item', filterLineId === l.lineId ? 'lt-item--active' : '']"
|
||||
@click="handleLineTab(l.lineId)"
|
||||
>{{ l.lineName }}</div>
|
||||
</div>
|
||||
|
||||
<!-- ── 轧辊列表 ── -->
|
||||
<div class="grind-left">
|
||||
<el-card shadow="never" class="grind-card h-full">
|
||||
<div slot="header" class="card-header">
|
||||
@@ -11,12 +25,6 @@
|
||||
|
||||
<!-- 搜索过滤 -->
|
||||
<div class="roll-filter">
|
||||
<!-- 产线筛选(暂时写死双机架) -->
|
||||
<el-select v-model="filterLine" size="small" placeholder="选择产线"
|
||||
style="width:100%;margin-bottom:8px" @change="filterRolls">
|
||||
<el-option label="全部产线" value="" />
|
||||
<el-option label="双机架产线" value="双机架" />
|
||||
</el-select>
|
||||
<el-input v-model="filterNo" size="small" placeholder="编号搜索" prefix-icon="el-icon-search"
|
||||
clearable @input="filterRolls" style="margin-bottom:8px" />
|
||||
<el-radio-group v-model="filterType" size="small" @change="filterRolls" style="margin-bottom:8px">
|
||||
@@ -39,6 +47,7 @@
|
||||
<span :class="['ri-status', 'st-' + r.status]">{{ statusLabel(r.status) }}</span>
|
||||
<span class="ri-dia">φ{{ r.currentDia != null ? r.currentDia : r.initialDia }}</span>
|
||||
</div>
|
||||
<div v-if="filterLineId === null && r.lineName" class="ri-line">{{ r.lineName }}</div>
|
||||
</div>
|
||||
<div v-if="!rollLoading && filteredRolls.length === 0" class="roll-empty">暂无数据</div>
|
||||
</div>
|
||||
@@ -229,13 +238,18 @@
|
||||
<script>
|
||||
import { listRollInfo, getRollInfo } from '@/api/mes/roll/rollInfo'
|
||||
import { listRollGrind, addRollGrind, updateRollGrind, delRollGrind, getMonthlyStats } from '@/api/mes/roll/rollGrind'
|
||||
import { listProductionLine } from '@/api/wms/productionLine'
|
||||
import rollLineMixin from '../rollLineMixin'
|
||||
|
||||
export default {
|
||||
name: 'GrindRoom',
|
||||
mixins: [rollLineMixin],
|
||||
data() {
|
||||
return {
|
||||
// 产线定义(暂写死,后续接后端)
|
||||
LINES: [{ label: '双机架产线', value: '双机架' }],
|
||||
// 产线列表
|
||||
productionLines: [],
|
||||
filterLineId: null,
|
||||
lineTabOrder: [], // 本地记录的点击顺序(最近点过的在前)
|
||||
|
||||
// 左侧辊列表
|
||||
rollLoading: false,
|
||||
@@ -243,7 +257,6 @@ export default {
|
||||
filteredRolls: [],
|
||||
filterNo: '',
|
||||
filterType: '',
|
||||
filterLine: '',
|
||||
|
||||
// 右侧选中辊
|
||||
selectedRollId: null,
|
||||
@@ -270,6 +283,19 @@ export default {
|
||||
return this.$store.state.user.name || this.$store.getters.name || ''
|
||||
},
|
||||
|
||||
// 产线 tab 按本地点击顺序排序
|
||||
sortedProductionLines() {
|
||||
const order = this.lineTabOrder
|
||||
return [...this.productionLines].sort((a, b) => {
|
||||
const ai = order.indexOf(a.lineId)
|
||||
const bi = order.indexOf(b.lineId)
|
||||
if (ai === -1 && bi === -1) return 0
|
||||
if (ai === -1) return 1
|
||||
if (bi === -1) return -1
|
||||
return ai - bi
|
||||
})
|
||||
},
|
||||
|
||||
// 表格数据:新增时在顶部插入一个编辑行占位
|
||||
tableData() {
|
||||
if (this.editRow && this.editRow.__isNew) {
|
||||
@@ -279,26 +305,46 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.loadRolls()
|
||||
},
|
||||
created() {},
|
||||
|
||||
methods: {
|
||||
onLineResolved() {
|
||||
this.filterLineId = this.lineId
|
||||
const uid = this.$store.state.user?.userId || 0
|
||||
try { this.lineTabOrder = JSON.parse(localStorage.getItem(`grind_line_order_${uid}`) || '[]') } catch {}
|
||||
listProductionLine({ pageNum: 1, pageSize: 100 }).then(res => {
|
||||
this.productionLines = res.rows || []
|
||||
})
|
||||
this.loadRolls()
|
||||
},
|
||||
|
||||
// ── 轧辊列表 ──────────────────────────────────────
|
||||
loadRolls() {
|
||||
this.rollLoading = true
|
||||
listRollInfo({ pageNum: 1, pageSize: 500 }).then(res => {
|
||||
listRollInfo({ pageNum: 1, pageSize: 500, lineId: this.filterLineId }).then(res => {
|
||||
this.allRolls = res.rows || []
|
||||
this.filterRolls()
|
||||
}).finally(() => { this.rollLoading = false })
|
||||
},
|
||||
handleLineTab(lineId) {
|
||||
if (this.filterLineId === lineId) return
|
||||
this.filterLineId = lineId
|
||||
if (lineId !== null) {
|
||||
this.lineTabOrder = [lineId, ...this.lineTabOrder.filter(id => id !== lineId)]
|
||||
const uid = this.$store.state.user?.userId || 0
|
||||
localStorage.setItem(`grind_line_order_${uid}`, JSON.stringify(this.lineTabOrder))
|
||||
}
|
||||
if (this.editRow) this.cancelEdit()
|
||||
this.selectedRollId = null
|
||||
this.selectedRoll = null
|
||||
this.grindList = []
|
||||
this.loadRolls()
|
||||
},
|
||||
filterRolls() {
|
||||
this.filteredRolls = this.allRolls.filter(r => {
|
||||
const matchNo = !this.filterNo || r.rollNo.includes(this.filterNo)
|
||||
const matchType = !this.filterType || r.rollType === this.filterType
|
||||
// 后续 mes_roll_info 增加 line_code 字段后改为 r.lineCode === this.filterLine
|
||||
const matchLine = !this.filterLine || this.filterLine === '双机架'
|
||||
return matchNo && matchType && matchLine
|
||||
return matchNo && matchType
|
||||
})
|
||||
},
|
||||
selectRoll(r) {
|
||||
@@ -428,8 +474,38 @@ export default {
|
||||
.grind-page { background: #f4f5f7; height: 100%; }
|
||||
.grind-layout { display: flex; gap: 12px; height: 100%; }
|
||||
|
||||
/* 左侧 */
|
||||
.grind-left { width: 240px; flex-shrink: 0; }
|
||||
/* 产线 Tab 列 */
|
||||
.line-tabs {
|
||||
width: 64px;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
.lt-item {
|
||||
padding: 10px 4px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #5f6368;
|
||||
background: #fff;
|
||||
border: 1px solid #dcdee0;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
word-break: break-all;
|
||||
line-height: 1.4;
|
||||
transition: all .15s;
|
||||
}
|
||||
.lt-item:hover { background: #f0f6ff; color: #409eff; border-color: #c6d9f5; }
|
||||
.lt-item--active {
|
||||
background: #409eff;
|
||||
color: #fff;
|
||||
border-color: #409eff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 轧辊列表 */
|
||||
.grind-left { width: 220px; flex-shrink: 0; }
|
||||
.grind-right { flex: 1; min-width: 0; }
|
||||
|
||||
.grind-card { border: 1px solid #dcdee0; border-radius: 4px; }
|
||||
@@ -451,6 +527,7 @@ export default {
|
||||
.ri-no { font-family: 'Consolas', monospace; font-size: 13px; font-weight: 600; color: #1f2329; }
|
||||
.ri-meta { display: flex; align-items: center; gap: 6px; margin-top: 3px; }
|
||||
.ri-dia { font-size: 11px; color: #9aa0a6; }
|
||||
.ri-line { font-size: 10px; color: #b0b3bb; margin-top: 2px; }
|
||||
.ri-status { font-size: 11px; }
|
||||
.roll-empty { text-align: center; color: #c0c4cc; padding: 20px 0; font-size: 12px; }
|
||||
|
||||
|
||||
@@ -46,14 +46,8 @@
|
||||
|
||||
<!-- 搜索栏 -->
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="所属产线">
|
||||
<!-- 暂时写死双机架,后续接后端 line_code 字段 -->
|
||||
<el-select v-model="queryParams.lineCode" placeholder="全部产线" clearable style="width:130px" @change="handleQuery">
|
||||
<el-option label="双机架产线" value="双机架" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="轧辊编号" prop="rollNo">
|
||||
<el-input v-model="queryParams.rollNo" placeholder="请输入轧辊编号" clearable @keyup.enter.native="handleQuery" />
|
||||
<el-input v-model="queryParams.rollNo" placeholder="请输入轧辊编号" clearable @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="辊型" prop="rollType">
|
||||
<el-select v-model="queryParams.rollType" placeholder="全部" clearable style="width:120px">
|
||||
@@ -225,9 +219,11 @@
|
||||
|
||||
<script>
|
||||
import { listRollInfo, getRollStats, getRollInfo, addRollInfo, updateRollInfo, delRollInfo, scrapRollInfo, syncRollStatus } from '@/api/mes/roll/rollInfo'
|
||||
import rollLineMixin from '../rollLineMixin'
|
||||
|
||||
export default {
|
||||
name: 'RollOverview',
|
||||
mixins: [rollLineMixin],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
@@ -242,7 +238,7 @@ export default {
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
lineCode: undefined, // 产线筛选(暂写死双机架,后续接字段)
|
||||
lineId: undefined,
|
||||
rollNo: undefined,
|
||||
rollType: undefined,
|
||||
status: undefined
|
||||
@@ -255,11 +251,12 @@ export default {
|
||||
ids: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getStats()
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
onLineResolved() {
|
||||
this.queryParams.lineId = this.lineId
|
||||
this.getStats()
|
||||
this.getList()
|
||||
},
|
||||
getList() {
|
||||
this.loading = true
|
||||
listRollInfo(this.queryParams).then(res => {
|
||||
@@ -269,14 +266,14 @@ export default {
|
||||
}).catch(() => { this.loading = false })
|
||||
},
|
||||
getStats() {
|
||||
getRollStats().then(res => { this.stats = res.data || {} })
|
||||
getRollStats(this.lineId).then(res => { this.stats = res.data || {} })
|
||||
},
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1
|
||||
this.getList()
|
||||
},
|
||||
resetQuery() {
|
||||
this.queryParams.lineCode = undefined
|
||||
this.queryParams.lineId = this.lineId
|
||||
this.resetForm('queryForm')
|
||||
this.handleQuery()
|
||||
},
|
||||
@@ -287,6 +284,7 @@ export default {
|
||||
},
|
||||
handleAdd() {
|
||||
this.reset()
|
||||
this.form.lineId = this.lineId
|
||||
this.title = '新增轧辊'
|
||||
this.open = true
|
||||
},
|
||||
@@ -320,7 +318,7 @@ export default {
|
||||
},
|
||||
handleSyncStatus() {
|
||||
this.$modal.confirm('将从换辊记录中重新推算各机架当前在机轧辊的状态,确认执行?').then(() => {
|
||||
return syncRollStatus()
|
||||
return syncRollStatus(this.lineId)
|
||||
}).then(() => {
|
||||
this.getList()
|
||||
this.getStats()
|
||||
|
||||
22
klp-ui/src/views/mes/roll/rollLineMixin.js
Normal file
22
klp-ui/src/views/mes/roll/rollLineMixin.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 从 URL query.lineId 读取产线 ID,供各轧辊页面共用。
|
||||
* 组件覆盖 onLineResolved() 执行初始化加载。
|
||||
*
|
||||
* 菜单路径示例:/mes/roll/overview?lineId=1
|
||||
*/
|
||||
export default {
|
||||
computed: {
|
||||
lineId() {
|
||||
const v = this.$route.query.lineId
|
||||
return v != null ? Number(v) : null
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.onLineResolved()
|
||||
},
|
||||
|
||||
methods: {
|
||||
onLineResolved() {}
|
||||
}
|
||||
}
|
||||
707
klp-ui/src/views/mes/roll/working-single/index.vue
Normal file
707
klp-ui/src/views/mes/roll/working-single/index.vue
Normal file
@@ -0,0 +1,707 @@
|
||||
<template>
|
||||
<div class="app-container working-roll-page">
|
||||
|
||||
<!-- ① 顶部行:作业辊一览(2/3)+ 可用轧辊(1/3) -->
|
||||
<div class="top-row">
|
||||
|
||||
<!-- 作业辊一览 -->
|
||||
<el-card shadow="never" class="roll-table-card top-row__main">
|
||||
<div slot="header" class="card-header">
|
||||
<span class="card-title"><i class="el-icon-s-grid" /> 作业辊一览</span>
|
||||
<span class="header-meta" v-if="current.changeTime">末次换辊:{{ current.changeTime }}</span>
|
||||
<span style="margin-left:auto;display:flex;align-items:center;gap:6px">
|
||||
<el-button size="mini" icon="el-icon-refresh-right" @click="handleOpenChange">换辊</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button type="success" size="mini" icon="el-icon-plus" @click="handleAddStandby">添加下批</el-button>
|
||||
<el-button type="danger" size="mini" icon="el-icon-delete" @click="handleClearStandby"
|
||||
:disabled="!standbyList.length">清空下批</el-button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
ref="mainTable"
|
||||
:data="mergedRows"
|
||||
v-loading="loadingCurrent || loadingStandby"
|
||||
:row-class-name="rowClass"
|
||||
:span-method="mergeParamCol"
|
||||
border
|
||||
size="small"
|
||||
style="width:100%"
|
||||
>
|
||||
<el-table-column label="参数" width="156" align="left">
|
||||
<template slot-scope="scope">
|
||||
<span :class="['param-label', scope.row.group]">{{ scope.row.label }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="当前在机轧辊" align="center" min-width="120">
|
||||
<template slot-scope="scope">
|
||||
<param-cell :data="scope.row.cur" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="下批轧辊" align="center" min-width="120">
|
||||
<template slot-scope="scope">
|
||||
<div
|
||||
:class="['sb-cell',
|
||||
scope.row.sb && scope.row.sb.standbyId ? 'sb-cell--del' :
|
||||
scope.row.rollType ? 'sb-cell--add' : '']"
|
||||
@click="handleSbCellClick(scope.row.sb, scope.row.rollType, scope.row.position)"
|
||||
>
|
||||
<param-cell :data="scope.row.sb" />
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<!-- 右侧:可用辊 + 工作绩效 -->
|
||||
<div class="top-row__aside aside-col">
|
||||
|
||||
<!-- 可用轧辊(离线) -->
|
||||
<el-card shadow="never" class="roll-table-card aside-panel">
|
||||
<div slot="header" class="card-header">
|
||||
<span class="card-title"><i class="el-icon-files" /> 可用轧辊(离线)</span>
|
||||
<el-button size="mini" icon="el-icon-refresh" style="margin-left:auto" @click="loadOfflineRolls">刷新</el-button>
|
||||
</div>
|
||||
<el-table v-loading="offlineLoading" :data="offlineRolls" size="small" :height="asideHalfH" style="width:100%">
|
||||
<el-table-column label="辊型" align="center" prop="rollType" width="52">
|
||||
<template slot-scope="scope">
|
||||
<el-tag size="mini" :type="scope.row.rollType === 'WR' ? 'primary' : 'warning'">{{ scope.row.rollType }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="轧辊编号" align="center" prop="rollNo" min-width="90" show-overflow-tooltip />
|
||||
<el-table-column label="辊径(mm)" align="center" width="76">
|
||||
<template slot-scope="scope">{{ scope.row.currentDia != null ? scope.row.currentDia : scope.row.initialDia }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="粗糙度" align="center" prop="roughness" width="64" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<!-- 工作绩效 -->
|
||||
<el-card shadow="never" class="roll-table-card aside-panel">
|
||||
<div slot="header" class="card-header">
|
||||
<span class="card-title"><i class="el-icon-data-analysis" /> 工作绩效(实时)</span>
|
||||
<el-button size="mini" icon="el-icon-refresh" style="margin-left:auto" @click="loadRollPerformance">刷新</el-button>
|
||||
</div>
|
||||
<el-table v-loading="perfLoading" :data="perfRows" size="small" :height="asideHalfH" border style="width:100%">
|
||||
<el-table-column label="辊位" align="center" prop="label" width="80" />
|
||||
<el-table-column label="轧辊编号" align="center" width="110">
|
||||
<template slot-scope="scope"><span class="perf-roll">{{ scope.row.rollNo || '—' }}</span></template>
|
||||
</el-table-column>
|
||||
<el-table-column label="工作长度(m)" align="center" width="100">
|
||||
<template slot-scope="scope">{{ scope.row.workLength != null ? scope.row.workLength : '—' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="过卷数" align="center" width="70">
|
||||
<template slot-scope="scope">{{ scope.row.coilCount != null ? scope.row.coilCount : '—' }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ② 换辊历史 -->
|
||||
<el-card shadow="never" class="roll-table-card" style="margin-top:16px">
|
||||
<div slot="header" class="card-header">
|
||||
<span class="card-title"><i class="el-icon-document" /> 换辊历史</span>
|
||||
<el-form :inline="true" size="small" style="margin-left:auto;margin-bottom:0">
|
||||
<el-form-item label="类型" style="margin-bottom:0">
|
||||
<el-select v-model="historyQuery.changeType" placeholder="全部" clearable style="width:110px" @change="loadHistory">
|
||||
<el-option label="计划换辊" value="计划换辊" />
|
||||
<el-option label="紧急换辊" value="紧急换辊" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="时间起" style="margin-bottom:0">
|
||||
<el-date-picker v-model="historyQuery.changeTime" type="datetime"
|
||||
value-format="yyyy-MM-dd HH:mm:ss" placeholder="开始时间"
|
||||
style="width:160px" @change="loadHistory" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<KLPTable v-loading="historyLoading" :data="historyList">
|
||||
<el-table-column label="换辊编号" align="center" prop="changeNo" width="130" />
|
||||
<el-table-column label="换辊时间" align="center" prop="changeTime" width="160" />
|
||||
<el-table-column label="类型" align="center" prop="changeType" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-tag size="small" :type="scope.row.changeType === '紧急换辊' ? 'danger' : ''">{{ scope.row.changeType }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作人" align="center" prop="operator" width="80" />
|
||||
<el-table-column label="换辊辊组" align="left" min-width="160">
|
||||
<template slot-scope="scope">
|
||||
<div class="roll-group-cell">
|
||||
<span v-if="scope.row.upperBrNo" class="rg-item"><b>上BR</b> {{ scope.row.upperBrNo }}<em v-if="scope.row.upperBrDia"> φ{{ scope.row.upperBrDia }}</em></span>
|
||||
<span v-if="scope.row.upperWrNo" class="rg-item"><b>上WR</b> {{ scope.row.upperWrNo }}<em v-if="scope.row.upperWrDia"> φ{{ scope.row.upperWrDia }}</em></span>
|
||||
<span v-if="scope.row.lowerWrNo" class="rg-item"><b>下WR</b> {{ scope.row.lowerWrNo }}<em v-if="scope.row.lowerWrDia"> φ{{ scope.row.lowerWrDia }}</em></span>
|
||||
<span v-if="scope.row.lowerBrNo" class="rg-item"><b>下BR</b> {{ scope.row.lowerBrNo }}<em v-if="scope.row.lowerBrDia"> φ{{ scope.row.lowerBrDia }}</em></span>
|
||||
<span v-if="!scope.row.upperBrNo && !scope.row.upperWrNo && !scope.row.lowerWrNo && !scope.row.lowerBrNo" style="color:#c0c4cc">—</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="工作长度(m)" align="center" prop="workLength" width="100" />
|
||||
<el-table-column label="过卷数" align="center" prop="coilCount" width="72" />
|
||||
<el-table-column label="过卷重量" align="center" prop="totalWeight" width="90" />
|
||||
<el-table-column label="备注" align="left" prop="remark" min-width="100" show-overflow-tooltip />
|
||||
<el-table-column label="操作" align="center" width="110" fixed="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleEditHistory(scope.row)">补录</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" style="color:#c5221f"
|
||||
@click="handleDeleteHistory(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</KLPTable>
|
||||
<pagination
|
||||
v-show="historyTotal > 0"
|
||||
:total="historyTotal"
|
||||
:page.sync="historyQuery.pageNum"
|
||||
:limit.sync="historyQuery.pageSize"
|
||||
@pagination="loadHistory"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
<!-- 换辊确认弹窗 -->
|
||||
<el-dialog title="确认换辊" :visible.sync="changeOpen" width="420px" append-to-body @close="resetChangeForm">
|
||||
<div class="roll-preview">
|
||||
<div class="roll-preview__title">以下轧辊将被换入</div>
|
||||
<div class="roll-preview__item">
|
||||
<span class="rp-label">上支撑辊</span>
|
||||
<span class="rp-val">{{ changeForm.upperBrNo || '—' }}</span>
|
||||
<span class="rp-dia" v-if="changeForm.upperBrDia">φ{{ changeForm.upperBrDia }} mm</span>
|
||||
</div>
|
||||
<div class="roll-preview__item">
|
||||
<span class="rp-label">上工作辊</span>
|
||||
<span class="rp-val">{{ changeForm.upperWrNo || '—' }}</span>
|
||||
<span class="rp-dia" v-if="changeForm.upperWrDia">φ{{ changeForm.upperWrDia }} mm</span>
|
||||
</div>
|
||||
<div class="roll-preview__item">
|
||||
<span class="rp-label">下工作辊</span>
|
||||
<span class="rp-val">{{ changeForm.lowerWrNo || '—' }}</span>
|
||||
<span class="rp-dia" v-if="changeForm.lowerWrDia">φ{{ changeForm.lowerWrDia }} mm</span>
|
||||
</div>
|
||||
<div class="roll-preview__item">
|
||||
<span class="rp-label">下支撑辊</span>
|
||||
<span class="rp-val">{{ changeForm.lowerBrNo || '—' }}</span>
|
||||
<span class="rp-dia" v-if="changeForm.lowerBrDia">φ{{ changeForm.lowerBrDia }} mm</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="roll-preview__tip">换辊时间和操作人将由系统自动记录</div>
|
||||
<div slot="footer">
|
||||
<el-button type="primary" :loading="changeSubmitting" @click="submitChange">确认换辊</el-button>
|
||||
<el-button @click="changeOpen = false">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 换辊历史补录/编辑对话框 -->
|
||||
<el-dialog title="换辊记录补录" :visible.sync="historyEditOpen" width="560px" append-to-body @close="historyEditForm = {}">
|
||||
<el-form ref="historyEditForm" :model="historyEditForm" label-width="100px" size="small">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="换辊类型">
|
||||
<el-select v-model="historyEditForm.changeType" style="width:100%">
|
||||
<el-option label="计划换辊" value="计划换辊" />
|
||||
<el-option label="紧急换辊" value="紧急换辊" />
|
||||
<el-option label="三级换辊" value="三级换辊" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="换辊时间">
|
||||
<el-date-picker v-model="historyEditForm.changeTime" type="datetime"
|
||||
value-format="yyyy-MM-dd HH:mm:ss" style="width:100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="操作人">
|
||||
<el-input v-model="historyEditForm.operator" />
|
||||
</el-form-item>
|
||||
<el-divider content-position="left">工作辊</el-divider>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12"><el-form-item label="上工作辊"><el-input v-model="historyEditForm.upperWrNo" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="上工作辊径"><el-input-number v-model="historyEditForm.upperWrDia" :precision="2" :min="0" style="width:100%" /></el-form-item></el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12"><el-form-item label="下工作辊"><el-input v-model="historyEditForm.lowerWrNo" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="下工作辊径"><el-input-number v-model="historyEditForm.lowerWrDia" :precision="2" :min="0" style="width:100%" /></el-form-item></el-col>
|
||||
</el-row>
|
||||
<el-divider content-position="left">支撑辊</el-divider>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12"><el-form-item label="上支撑辊"><el-input v-model="historyEditForm.upperBrNo" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="上支撑辊径"><el-input-number v-model="historyEditForm.upperBrDia" :precision="2" :min="0" style="width:100%" /></el-form-item></el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12"><el-form-item label="下支撑辊"><el-input v-model="historyEditForm.lowerBrNo" /></el-form-item></el-col>
|
||||
<el-col :span="12"><el-form-item label="下支撑辊径"><el-input-number v-model="historyEditForm.lowerBrDia" :precision="2" :min="0" style="width:100%" /></el-form-item></el-col>
|
||||
</el-row>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="historyEditForm.remark" type="textarea" :rows="2" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer">
|
||||
<el-button type="primary" @click="submitHistoryEdit">保 存</el-button>
|
||||
<el-button @click="historyEditOpen = false">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 添加下批轧辊对话框 -->
|
||||
<el-dialog title="添加下批轧辊" :visible.sync="standbyOpen" width="460px" append-to-body @close="resetStandbyForm">
|
||||
<el-form ref="standbyForm" :model="standbyForm" :rules="standbyRules" label-width="100px">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="辊型" prop="rollType">
|
||||
<el-input
|
||||
v-if="standbyFromCell"
|
||||
:value="standbyForm.rollType === 'WR' ? '工作辊 WR' : '支撑辊 BR'"
|
||||
readonly style="width:100%"
|
||||
/>
|
||||
<el-select v-else v-model="standbyForm.rollType" placeholder="请选择" style="width:100%"
|
||||
@change="handleStandbyRollTypeChange">
|
||||
<el-option label="工作辊 WR" value="WR" />
|
||||
<el-option label="支撑辊 BR" value="BR" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="辊位" prop="position">
|
||||
<el-input
|
||||
v-if="standbyFromCell"
|
||||
:value="standbyForm.position === 'UP' ? '上辊' : '下辊'"
|
||||
readonly style="width:100%"
|
||||
/>
|
||||
<el-select v-else v-model="standbyForm.position" placeholder="请选择" style="width:100%">
|
||||
<el-option label="上辊" value="UP" />
|
||||
<el-option label="下辊" value="DOWN" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="轧辊编号" prop="rollNo">
|
||||
<el-select v-model="standbyForm.rollNo" placeholder="请选择" filterable style="width:100%">
|
||||
<el-option
|
||||
v-for="no in standbyForm.rollType === 'WR' ? wrOptions : brOptions"
|
||||
:key="no" :label="no" :value="no"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="就绪时间">
|
||||
<el-date-picker v-model="standbyForm.readyTime" type="datetime"
|
||||
value-format="yyyy-MM-dd HH:mm:ss" placeholder="默认当前时间" style="width:100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="standbyForm.remark" type="textarea" :rows="2" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer">
|
||||
<el-button type="primary" @click="submitStandby">确 定</el-button>
|
||||
<el-button @click="standbyOpen = false">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCurrentRolls, listRollChange, addRollChange, updateRollChange, delRollChange, getRollPerformance } from '@/api/mes/roll/rollChange'
|
||||
import { listRollStandby, addRollStandby, delRollStandby, clearRollStandby } from '@/api/mes/roll/rollStandby'
|
||||
import { listRollOptions, listRollInfo } from '@/api/mes/roll/rollInfo'
|
||||
import rollLineMixin from '../rollLineMixin'
|
||||
|
||||
const STAND_NO = '1#'
|
||||
|
||||
const ParamCell = {
|
||||
name: 'ParamCell',
|
||||
props: { data: { type: Object, default: null } },
|
||||
render(h) {
|
||||
const d = this.data
|
||||
if (!d || d.val == null || d.val === '') return h('span', { class: 'cell-empty' }, '—')
|
||||
return h('span', { class: 'cell-main' }, String(d.val))
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'WorkingRollSingle',
|
||||
components: { ParamCell },
|
||||
mixins: [rollLineMixin],
|
||||
|
||||
data() {
|
||||
return {
|
||||
current: {},
|
||||
loadingCurrent: false,
|
||||
|
||||
standbyList: [],
|
||||
loadingStandby: false,
|
||||
|
||||
rollInfoMap: {},
|
||||
|
||||
historyLoading: false,
|
||||
historyList: [],
|
||||
historyTotal: 0,
|
||||
historyQuery: { pageNum: 1, pageSize: 15, standNo: STAND_NO, changeType: undefined, changeTime: undefined },
|
||||
|
||||
wrOptions: [],
|
||||
brOptions: [],
|
||||
|
||||
historyEditOpen: false,
|
||||
historyEditForm: {},
|
||||
|
||||
offlineRolls: [],
|
||||
offlineLoading: false,
|
||||
|
||||
perfData: {},
|
||||
perfLoading: false,
|
||||
|
||||
asideHalfH: 200,
|
||||
|
||||
changeOpen: false,
|
||||
changeSubmitting: false,
|
||||
changeForm: {},
|
||||
|
||||
standbyOpen: false,
|
||||
standbyForm: {},
|
||||
standbyFromCell: false,
|
||||
standbyRules: {
|
||||
rollType: [{ required: true, message: '请选择辊型', trigger: 'change' }],
|
||||
position: [{ required: true, message: '请选择辊位', trigger: 'change' }],
|
||||
rollNo: [{ required: true, message: '请选择轧辊编号', trigger: 'change' }]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
mergedRows() {
|
||||
const c = this.current || {}
|
||||
const ri = this.rollInfoMap
|
||||
|
||||
const cv = (val, rollNo) => ({
|
||||
val: (val == null || val === '') ? null : val,
|
||||
sub: rollNo || null
|
||||
})
|
||||
const rv = (rollNo, field) => {
|
||||
const info = rollNo ? ri[rollNo] : null
|
||||
const val = info ? info[field] : null
|
||||
return { val: (val == null || val === '') ? null : val, sub: rollNo || null }
|
||||
}
|
||||
const sv = (rollType, pos, field) => {
|
||||
const item = this.standbyList.find(i => i.rollType === rollType && i.position === pos)
|
||||
if (!item) return { val: null, sub: null }
|
||||
let val = item[field]
|
||||
if ((val == null || val === '') && item.rollNo) {
|
||||
const info = ri[item.rollNo]
|
||||
if (info) {
|
||||
val = field === 'diameter'
|
||||
? (info.currentDia != null ? info.currentDia : info.initialDia)
|
||||
: info[field]
|
||||
}
|
||||
}
|
||||
return { val: (val == null || val === '') ? null : val, sub: item.rollNo, standbyId: item.standbyId }
|
||||
}
|
||||
const sm = (rollType, pos) => {
|
||||
const item = this.standbyList.find(i => i.rollType === rollType && i.position === pos)
|
||||
if (!item || !item.rollNo) return { val: null, sub: null }
|
||||
const info = ri[item.rollNo]
|
||||
return { val: info ? (info.material || null) : null, sub: item.rollNo, standbyId: item.standbyId }
|
||||
}
|
||||
|
||||
return [
|
||||
{ label: '上支承辊直径(mm)', group: 'br', rollType: 'BR', position: 'UP',
|
||||
cur: cv(c.upperBrDia, c.upperBrNo), sb: sv('BR', 'UP', 'diameter') },
|
||||
{ label: '上工作辊直径(mm)', group: 'wr', rollType: 'WR', position: 'UP',
|
||||
cur: cv(c.upperWrDia, c.upperWrNo), sb: sv('WR', 'UP', 'diameter') },
|
||||
{ label: '上工作辊凸度', group: 'wr', rollType: 'WR', position: 'UP',
|
||||
cur: rv(c.upperWrNo, 'crown'), sb: sv('WR', 'UP', 'crown') },
|
||||
{ label: '上工作辊粗糙度(μm)', group: 'wr', rollType: 'WR', position: 'UP',
|
||||
cur: rv(c.upperWrNo, 'roughness'), sb: sv('WR', 'UP', 'roughness') },
|
||||
{ label: '工作辊类型', group: 'wr', rollType: 'WR', position: 'UP',
|
||||
cur: rv(c.upperWrNo, 'material'), sb: sm('WR', 'UP') },
|
||||
{ label: '下工作辊直径(mm)', group: 'wr', rollType: 'WR', position: 'DOWN',
|
||||
cur: cv(c.lowerWrDia, c.lowerWrNo), sb: sv('WR', 'DOWN', 'diameter') },
|
||||
{ label: '下工作辊凸度', group: 'wr', rollType: 'WR', position: 'DOWN',
|
||||
cur: rv(c.lowerWrNo, 'crown'), sb: sv('WR', 'DOWN', 'crown') },
|
||||
{ label: '下工作辊粗糙度(μm)', group: 'wr', rollType: 'WR', position: 'DOWN',
|
||||
cur: rv(c.lowerWrNo, 'roughness'), sb: sv('WR', 'DOWN', 'roughness') },
|
||||
{ label: '下支承辊直径(mm)', group: 'br', rollType: 'BR', position: 'DOWN',
|
||||
cur: cv(c.lowerBrDia, c.lowerBrNo), sb: sv('BR', 'DOWN', 'diameter') }
|
||||
]
|
||||
},
|
||||
|
||||
perfRows() {
|
||||
const standData = (this.perfData['upperBr'] || {})
|
||||
const d = (key) => {
|
||||
const obj = (this.perfData[key] || {})[STAND_NO] || {}
|
||||
return { rollNo: obj.rollNo, workLength: obj.workLength, coilCount: obj.coilCount }
|
||||
}
|
||||
return [
|
||||
{ label: '上支撑辊', ...d('upperBr') },
|
||||
{ label: '上工作辊', ...d('upperWr') },
|
||||
{ label: '下工作辊', ...d('lowerWr') },
|
||||
{ label: '下支撑辊', ...d('lowerBr') }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
created() {},
|
||||
|
||||
mounted() {
|
||||
this.$nextTick(this.syncAsideHeight)
|
||||
window.addEventListener('resize', this.syncAsideHeight)
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this.syncAsideHeight)
|
||||
},
|
||||
|
||||
methods: {
|
||||
onLineResolved() {
|
||||
this.loadCurrent()
|
||||
this.loadStandby()
|
||||
this.loadHistory()
|
||||
this.loadOfflineRolls()
|
||||
this.loadRollPerformance()
|
||||
this.loadRollOptions()
|
||||
this.loadRollInfoMap()
|
||||
},
|
||||
|
||||
loadCurrent() {
|
||||
this.loadingCurrent = true
|
||||
getCurrentRolls(this.lineId, STAND_NO).then(res => {
|
||||
this.current = res.data || {}
|
||||
this.$nextTick(this.syncAsideHeight)
|
||||
}).finally(() => { this.loadingCurrent = false })
|
||||
},
|
||||
|
||||
loadStandby() {
|
||||
this.loadingStandby = true
|
||||
listRollStandby(this.lineId, STAND_NO).then(res => {
|
||||
this.standbyList = res.data || []
|
||||
}).finally(() => { this.loadingStandby = false })
|
||||
},
|
||||
|
||||
loadHistory() {
|
||||
this.historyLoading = true
|
||||
listRollChange({ ...this.historyQuery, lineId: this.lineId }).then(res => {
|
||||
this.historyList = res.rows || []
|
||||
this.historyTotal = res.total || 0
|
||||
}).finally(() => { this.historyLoading = false })
|
||||
},
|
||||
|
||||
loadRollOptions() {
|
||||
listRollOptions(this.lineId, 'WR', 'Offline').then(res => { this.wrOptions = res.data || [] })
|
||||
listRollOptions(this.lineId, 'BR', 'Offline').then(res => { this.brOptions = res.data || [] })
|
||||
},
|
||||
|
||||
loadRollInfoMap() {
|
||||
listRollInfo({ lineId: this.lineId, pageNum: 1, pageSize: 500 }).then(res => {
|
||||
const map = {}
|
||||
;(res.rows || []).forEach(r => { map[r.rollNo] = r })
|
||||
this.rollInfoMap = map
|
||||
})
|
||||
},
|
||||
|
||||
loadRollPerformance() {
|
||||
this.perfLoading = true
|
||||
getRollPerformance(this.lineId).then(res => {
|
||||
this.perfData = res.data || {}
|
||||
}).finally(() => { this.perfLoading = false })
|
||||
},
|
||||
|
||||
loadOfflineRolls() {
|
||||
this.offlineLoading = true
|
||||
listRollInfo({ lineId: this.lineId, status: 'Offline', pageNum: 1, pageSize: 30 }).then(res => {
|
||||
this.offlineRolls = res.rows || []
|
||||
}).finally(() => { this.offlineLoading = false })
|
||||
},
|
||||
|
||||
rowClass({ row }) {
|
||||
if (row.group === 'br') return 'row-br'
|
||||
return ''
|
||||
},
|
||||
|
||||
mergeParamCol({ columnIndex }) {
|
||||
if (columnIndex === 0) return [1, 1]
|
||||
},
|
||||
|
||||
handleOpenChange() {
|
||||
const ri = this.rollInfoMap
|
||||
const pick = (rollType, pos) => {
|
||||
const item = this.standbyList.find(i => i.rollType === rollType && i.position === pos)
|
||||
if (!item) return { no: undefined, dia: undefined }
|
||||
const info = ri[item.rollNo]
|
||||
const dia = item.diameter != null ? item.diameter
|
||||
: (info ? (info.currentDia != null ? info.currentDia : info.initialDia) : undefined)
|
||||
return { no: item.rollNo, dia }
|
||||
}
|
||||
const uwr = pick('WR', 'UP'), lwr = pick('WR', 'DOWN')
|
||||
const ubr = pick('BR', 'UP'), lbr = pick('BR', 'DOWN')
|
||||
this.changeForm = {
|
||||
standNo: STAND_NO,
|
||||
lineId: this.lineId,
|
||||
changeType: undefined,
|
||||
upperWrNo: uwr.no, upperWrDia: uwr.dia,
|
||||
lowerWrNo: lwr.no, lowerWrDia: lwr.dia,
|
||||
upperBrNo: ubr.no, upperBrDia: ubr.dia,
|
||||
lowerBrNo: lbr.no, lowerBrDia: lbr.dia
|
||||
}
|
||||
this.changeOpen = true
|
||||
},
|
||||
|
||||
submitChange() {
|
||||
if (this.changeSubmitting) return
|
||||
this.changeSubmitting = true
|
||||
addRollChange(this.changeForm).then(() => {
|
||||
this.$modal.msgSuccess('换辊成功')
|
||||
this.changeOpen = false
|
||||
clearRollStandby(this.lineId, STAND_NO).finally(() => {
|
||||
this.loadCurrent()
|
||||
this.loadStandby()
|
||||
this.loadHistory()
|
||||
this.loadOfflineRolls()
|
||||
this.loadRollPerformance()
|
||||
})
|
||||
}).finally(() => { this.changeSubmitting = false })
|
||||
},
|
||||
|
||||
resetChangeForm() {
|
||||
this.changeForm = {}
|
||||
this.changeSubmitting = false
|
||||
},
|
||||
|
||||
handleSbCellClick(cell, rollType, position) {
|
||||
if (cell && cell.standbyId) {
|
||||
this.handleDelStandby(cell.standbyId)
|
||||
} else if (rollType) {
|
||||
this.standbyForm = { standNo: STAND_NO, rollType, position, rollNo: undefined }
|
||||
this.standbyFromCell = true
|
||||
this.standbyOpen = true
|
||||
}
|
||||
},
|
||||
|
||||
handleAddStandby() {
|
||||
this.standbyForm = { standNo: STAND_NO, rollType: undefined, position: undefined, rollNo: undefined }
|
||||
this.standbyFromCell = false
|
||||
this.standbyOpen = true
|
||||
},
|
||||
|
||||
handleStandbyRollTypeChange() {
|
||||
this.$set(this.standbyForm, 'rollNo', undefined)
|
||||
},
|
||||
|
||||
submitStandby() {
|
||||
this.$refs.standbyForm.validate(valid => {
|
||||
if (!valid) return
|
||||
addRollStandby({ ...this.standbyForm, lineId: this.lineId }).then(() => {
|
||||
this.$modal.msgSuccess('已添加到下批轧辊')
|
||||
this.standbyOpen = false
|
||||
this.loadStandby()
|
||||
this.loadRollOptions()
|
||||
this.loadOfflineRolls()
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
resetStandbyForm() {
|
||||
this.standbyForm = {}
|
||||
this.standbyFromCell = false
|
||||
this.$nextTick(() => { this.$refs.standbyForm && this.$refs.standbyForm.clearValidate() })
|
||||
},
|
||||
|
||||
handleDelStandby(standbyId) {
|
||||
this.$modal.confirm('确认移除该下批轧辊?移除后该辊状态将恢复为"离线"。').then(() => {
|
||||
return delRollStandby(standbyId)
|
||||
}).then(() => {
|
||||
this.$modal.msgSuccess('已移除')
|
||||
this.loadStandby()
|
||||
this.loadRollOptions()
|
||||
this.loadOfflineRolls()
|
||||
})
|
||||
},
|
||||
|
||||
handleClearStandby() {
|
||||
this.$modal.confirm('确认清空全部下批轧辊?').then(() => {
|
||||
return clearRollStandby(this.lineId, STAND_NO)
|
||||
}).then(() => {
|
||||
this.$modal.msgSuccess('已清空')
|
||||
this.loadStandby()
|
||||
})
|
||||
},
|
||||
|
||||
handleEditHistory(row) {
|
||||
this.historyEditForm = { ...row }
|
||||
this.historyEditOpen = true
|
||||
},
|
||||
|
||||
submitHistoryEdit() {
|
||||
updateRollChange(this.historyEditForm).then(() => {
|
||||
this.$modal.msgSuccess('保存成功')
|
||||
this.historyEditOpen = false
|
||||
this.loadHistory()
|
||||
})
|
||||
},
|
||||
|
||||
handleDeleteHistory(row) {
|
||||
this.$modal.confirm('确认删除该换辊记录?此操作不可恢复。').then(() => {
|
||||
return delRollChange(row.changeId)
|
||||
}).then(() => {
|
||||
this.$modal.msgSuccess('已删除')
|
||||
this.loadHistory()
|
||||
})
|
||||
},
|
||||
|
||||
syncAsideHeight() {
|
||||
const el = this.$refs.mainTable && this.$refs.mainTable.$el
|
||||
if (!el) return
|
||||
const totalH = el.offsetHeight
|
||||
const gap = 12
|
||||
const headerH = 48
|
||||
const half = Math.max(100, Math.floor((totalH - gap) / 2) - headerH)
|
||||
this.asideHalfH = half
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.working-roll-page { background: #f4f5f7; }
|
||||
.roll-table-card { border: 1px solid #dcdee0; border-radius: 4px; }
|
||||
|
||||
.top-row { display: flex; gap: 12px; align-items: stretch; }
|
||||
.top-row__main { flex: 2; min-width: 0; }
|
||||
.top-row__aside { flex: 1; min-width: 0; }
|
||||
|
||||
.aside-col { display: flex; flex-direction: column; gap: 12px; }
|
||||
.aside-panel { flex: 1; min-width: 0; }
|
||||
|
||||
.roll-group-cell { display: flex; flex-wrap: wrap; gap: 4px; line-height: 1.5; }
|
||||
.rg-item { font-size: 12px; color: #3d4b5c; }
|
||||
.rg-item b { color: #5f6368; font-weight: 600; margin-right: 2px; }
|
||||
.rg-item em { font-style: normal; color: #9aa0a6; font-size: 11px; }
|
||||
|
||||
.card-header { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
||||
.card-title { font-size: 13px; font-weight: 600; color: #3d4b5c; white-space: nowrap; }
|
||||
.header-meta { font-size: 11px; color: #8f9099; white-space: nowrap; }
|
||||
|
||||
.param-label { font-size: 12px; color: #3d4b5c; }
|
||||
.cell-main { font-family: 'Consolas', 'Courier New', monospace; font-size: 13px; font-weight: 600; color: #1f2329; }
|
||||
.cell-empty { color: #c0c4cc; font-size: 12px; }
|
||||
|
||||
.perf-roll { font-family: 'Consolas', monospace; font-size: 12px; font-weight: 600; color: #1f2329; }
|
||||
|
||||
.roll-preview { background: #f7f8fa; border: 1px solid #e4e6eb; border-radius: 4px; padding: 10px 12px; }
|
||||
.roll-preview__title { font-size: 11px; color: #8f9099; margin-bottom: 8px; letter-spacing: .5px; }
|
||||
.roll-preview__item { display: flex; align-items: center; gap: 6px; padding: 4px 0; }
|
||||
.rp-label { font-size: 12px; color: #8f9099; width: 56px; flex-shrink: 0; }
|
||||
.rp-val { font-size: 13px; font-weight: 600; color: #1f2329; font-family: 'Consolas', monospace; flex: 1; }
|
||||
.rp-dia { font-size: 11px; color: #9aa0a6; }
|
||||
.roll-preview__tip { font-size: 11px; color: #b0b3bb; margin-top: 10px; text-align: center; }
|
||||
|
||||
.sb-cell { display: block; min-height: 24px; border-radius: 2px; cursor: default; }
|
||||
.sb-cell--add { cursor: pointer; background: #f0f9f4; }
|
||||
.sb-cell--add:hover { background: #d4edda; }
|
||||
.sb-cell--del { cursor: pointer; background: #fff7f7; }
|
||||
.sb-cell--del:hover { background: #ffe4e4; }
|
||||
|
||||
::v-deep .row-br td { background: #fafafa !important; }
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.el-table .editing-row { background: #fffbf0 !important; }
|
||||
</style>
|
||||
@@ -381,6 +381,7 @@
|
||||
import { getCurrentRolls, listRollChange, addRollChange, updateRollChange, delRollChange, getRollPerformance } from '@/api/mes/roll/rollChange'
|
||||
import { listRollStandby, addRollStandby, delRollStandby, clearRollStandby } from '@/api/mes/roll/rollStandby'
|
||||
import { listRollOptions, listRollInfo } from '@/api/mes/roll/rollInfo'
|
||||
import rollLineMixin from '../rollLineMixin'
|
||||
|
||||
const ParamCell = {
|
||||
name: 'ParamCell',
|
||||
@@ -409,6 +410,7 @@ const PerfCell = {
|
||||
export default {
|
||||
name: 'WorkingRoll',
|
||||
components: { ParamCell, PerfCell },
|
||||
mixins: [rollLineMixin],
|
||||
data() {
|
||||
return {
|
||||
current: { '1#': {}, '2#': {} },
|
||||
@@ -576,11 +578,7 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.loadAll()
|
||||
this.loadRollOptions()
|
||||
this.loadRollInfoMap()
|
||||
},
|
||||
created() {},
|
||||
|
||||
mounted() {
|
||||
this.$nextTick(this.syncAsideHeight)
|
||||
@@ -592,6 +590,12 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
onLineResolved() {
|
||||
this.loadAll()
|
||||
this.loadRollOptions()
|
||||
this.loadRollInfoMap()
|
||||
},
|
||||
|
||||
getDefaultChangeForm(standNo) {
|
||||
return {
|
||||
standNo: standNo || undefined,
|
||||
@@ -631,14 +635,14 @@ export default {
|
||||
|
||||
loadRollPerformance() {
|
||||
this.perfLoading = true
|
||||
getRollPerformance().then(res => {
|
||||
getRollPerformance(this.lineId).then(res => {
|
||||
this.perfData = res.data || {}
|
||||
}).finally(() => { this.perfLoading = false })
|
||||
},
|
||||
|
||||
loadCurrent(standNo) {
|
||||
this.$set(this.loadingCurrent, standNo, true)
|
||||
getCurrentRolls(standNo).then(res => {
|
||||
getCurrentRolls(this.lineId, standNo).then(res => {
|
||||
this.$set(this.current, standNo, res.data || {})
|
||||
this.$set(this.loadingCurrent, standNo, false)
|
||||
this.$nextTick(this.syncAsideHeight)
|
||||
@@ -647,7 +651,7 @@ export default {
|
||||
|
||||
loadStandby(standNo) {
|
||||
this.$set(this.loadingStandby, standNo, true)
|
||||
listRollStandby(standNo).then(res => {
|
||||
listRollStandby(this.lineId, standNo).then(res => {
|
||||
this.$set(this.standbyList, standNo, res.data || [])
|
||||
this.$set(this.loadingStandby, standNo, false)
|
||||
}).catch(() => { this.$set(this.loadingStandby, standNo, false) })
|
||||
@@ -655,7 +659,7 @@ export default {
|
||||
|
||||
loadHistory() {
|
||||
this.historyLoading = true
|
||||
listRollChange(this.historyQuery).then(res => {
|
||||
listRollChange({ ...this.historyQuery, lineId: this.lineId }).then(res => {
|
||||
this.historyList = res.rows || []
|
||||
this.historyTotal = res.total || 0
|
||||
this.historyLoading = false
|
||||
@@ -663,13 +667,13 @@ export default {
|
||||
},
|
||||
|
||||
loadRollOptions() {
|
||||
// 下批辊选择只显示离线(Offline)状态的轧辊
|
||||
listRollOptions('WR', 'Offline').then(res => { this.wrOptions = res.data || [] })
|
||||
listRollOptions('BR', 'Offline').then(res => { this.brOptions = res.data || [] })
|
||||
// 下批辊选择只显示离线(Offline)状态的轧辊,限定当前产线
|
||||
listRollOptions(this.lineId, 'WR', 'Offline').then(res => { this.wrOptions = res.data || [] })
|
||||
listRollOptions(this.lineId, 'BR', 'Offline').then(res => { this.brOptions = res.data || [] })
|
||||
},
|
||||
|
||||
loadRollInfoMap() {
|
||||
listRollInfo({ pageNum: 1, pageSize: 500 }).then(res => {
|
||||
listRollInfo({ lineId: this.lineId, pageNum: 1, pageSize: 500 }).then(res => {
|
||||
const map = {}
|
||||
;(res.rows || []).forEach(r => { map[r.rollNo] = r })
|
||||
this.rollInfoMap = map
|
||||
@@ -708,6 +712,7 @@ export default {
|
||||
|
||||
this.changeForm = {
|
||||
...this.getDefaultChangeForm(standNo),
|
||||
lineId: this.lineId,
|
||||
upperWrNo: uwr.no, upperWrDia: uwr.dia,
|
||||
lowerWrNo: lwr.no, lowerWrDia: lwr.dia,
|
||||
upperBrNo: ubr.no, upperBrDia: ubr.dia,
|
||||
@@ -722,7 +727,7 @@ export default {
|
||||
addRollChange(this.changeForm).then(() => {
|
||||
this.$modal.msgSuccess('换辊成功')
|
||||
this.changeOpen = false
|
||||
clearRollStandby(standNo).finally(() => {
|
||||
clearRollStandby(this.lineId, standNo).finally(() => {
|
||||
this.loadCurrent(standNo)
|
||||
this.loadStandby(standNo)
|
||||
this.loadHistory()
|
||||
@@ -761,7 +766,7 @@ export default {
|
||||
submitStandby() {
|
||||
this.$refs.standbyForm.validate(valid => {
|
||||
if (!valid) return
|
||||
addRollStandby(this.standbyForm).then(() => {
|
||||
addRollStandby({ ...this.standbyForm, lineId: this.lineId }).then(() => {
|
||||
this.$modal.msgSuccess('已添加到下批轧辊')
|
||||
this.standbyOpen = false
|
||||
this.loadStandby(this.standbyForm.standNo)
|
||||
@@ -787,7 +792,7 @@ export default {
|
||||
},
|
||||
handleClearStandby(standNo) {
|
||||
this.$modal.confirm('确认清空 ' + standNo + ' 机架的全部下批轧辊?').then(() => {
|
||||
return clearRollStandby(standNo)
|
||||
return clearRollStandby(this.lineId, standNo)
|
||||
}).then(() => {
|
||||
this.$modal.msgSuccess('已清空')
|
||||
this.loadStandby(standNo)
|
||||
@@ -818,7 +823,7 @@ export default {
|
||||
// ── 可用离线辊列表 ────────────────────────────────────────
|
||||
loadOfflineRolls() {
|
||||
this.offlineLoading = true
|
||||
listRollInfo({ status: 'Offline', pageNum: 1, pageSize: 30 }).then(res => {
|
||||
listRollInfo({ lineId: this.lineId, status: 'Offline', pageNum: 1, pageSize: 30 }).then(res => {
|
||||
this.offlineRolls = res.rows || []
|
||||
}).finally(() => {
|
||||
this.offlineLoading = false
|
||||
|
||||
247
klp-ui/src/views/wms/coil/do/acid-merge.vue
Normal file
247
klp-ui/src/views/wms/coil/do/acid-merge.vue
Normal file
@@ -0,0 +1,247 @@
|
||||
<template>
|
||||
<div class="app-container acid-op-page">
|
||||
<el-row :gutter="16">
|
||||
|
||||
<!-- ── 左侧:合卷表单 ── -->
|
||||
<el-col :span="15">
|
||||
<div class="op-card">
|
||||
<div class="op-header">
|
||||
<span class="op-title">合卷操作</span>
|
||||
<el-tag size="mini" type="info" style="margin-left:8px">actionType = 200</el-tag>
|
||||
</div>
|
||||
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="110px" size="small">
|
||||
|
||||
<!-- 源卷列表(动态) -->
|
||||
<div class="sub-section-label">源卷列表</div>
|
||||
<div v-for="(item, idx) in form.sourceCoils" :key="idx" class="source-row">
|
||||
<el-form-item
|
||||
:label="'源卷 ' + (idx + 1)"
|
||||
:prop="'sourceCoils.' + idx + '.enterCoilNo'"
|
||||
:rules="[{ required: true, message: '请输入源卷号', trigger: 'blur' }]"
|
||||
style="margin-bottom:8px"
|
||||
>
|
||||
<el-input v-model="item.enterCoilNo" :placeholder="'入场钢卷号 ' + (idx + 1)"
|
||||
clearable style="width:calc(100% - 36px)"
|
||||
@keyup.enter.native="onSourceCoilInput(item)"
|
||||
@blur="onSourceCoilInput(item)" />
|
||||
<el-button icon="el-icon-minus" size="mini" type="danger" circle
|
||||
style="margin-left:6px" :disabled="form.sourceCoils.length <= 1"
|
||||
@click="removeSourceCoil(idx)" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-button size="mini" type="primary" plain icon="el-icon-plus"
|
||||
style="margin-left:110px;margin-bottom:12px" @click="addSourceCoil">
|
||||
添加源卷
|
||||
</el-button>
|
||||
|
||||
<el-divider content-position="left" style="margin:4px 0 12px">合卷结果</el-divider>
|
||||
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="合卷后卷号" prop="targetCoilNo">
|
||||
<el-input v-model="form.targetCoilNo" placeholder="请输入合卷后钢卷号" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="合卷后重量(t)" prop="mergedWeight">
|
||||
<el-input-number v-model="form.mergedWeight" :precision="3" :min="0"
|
||||
:controls="false" style="width:100%" placeholder="—" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="出口厚度(mm)" prop="exitThickness">
|
||||
<el-input-number v-model="form.exitThickness" :precision="3" :min="0"
|
||||
:controls="false" style="width:100%" placeholder="—" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="出口宽度(mm)" prop="exitWidth">
|
||||
<el-input-number v-model="form.exitWidth" :precision="1" :min="0"
|
||||
:controls="false" style="width:100%" placeholder="—" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="班组" prop="team">
|
||||
<el-select v-model="form.team" placeholder="请选择" style="width:100%" clearable>
|
||||
<el-option label="甲班" value="甲" />
|
||||
<el-option label="乙班" value="乙" />
|
||||
<el-option label="丙班" value="丙" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.remark" placeholder="选填" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<div style="text-align:right;padding-top:4px">
|
||||
<el-button @click="resetForm">重置</el-button>
|
||||
<el-button type="primary" :loading="submitting" @click="submitForm">确认合卷</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!-- 历史记录 -->
|
||||
<div class="op-card" style="margin-top:12px">
|
||||
<div class="op-header">
|
||||
<span class="op-title">最近合卷记录</span>
|
||||
<el-button size="mini" icon="el-icon-refresh" style="margin-left:auto" @click="loadHistory">刷新</el-button>
|
||||
</div>
|
||||
<el-table v-loading="historyLoading" :data="historyList" size="mini" border style="width:100%">
|
||||
<el-table-column prop="enterCoilNo" label="源卷号" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="currentCoilNo" label="合卷后卷号" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="exitThickness" label="出口厚(mm)" width="90" align="right" />
|
||||
<el-table-column prop="exitWidth" label="出口宽(mm)" width="90" align="right" />
|
||||
<el-table-column prop="netWeight" label="重量(t)" width="80" align="right" />
|
||||
<el-table-column prop="team" label="班组" width="60" align="center" />
|
||||
<el-table-column prop="createTime" label="录入时间" width="150" />
|
||||
</el-table>
|
||||
<pagination v-show="historyTotal > 0" :total="historyTotal"
|
||||
:page.sync="historyQuery.pageNum" :limit.sync="historyQuery.pageSize"
|
||||
@pagination="loadHistory" style="margin-top:6px" />
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<!-- ── 右侧:L2 匹配面板(以第一个源卷为锚点) ── -->
|
||||
<el-col :span="9">
|
||||
<l2-match-panel :hot-coil-id="l2HotCoilId" @fill="applyL2Fill" />
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { addCoilWarehouseOperationLog, listCoilWarehouseOperationLog } from '@/api/wms/coilWarehouseOperationLog'
|
||||
import L2MatchPanel from '../panels/L2MatchPanel.vue'
|
||||
|
||||
export default {
|
||||
name: 'AcidMerge',
|
||||
components: { L2MatchPanel },
|
||||
data() {
|
||||
return {
|
||||
form: this.defaultForm(),
|
||||
rules: {
|
||||
targetCoilNo: [{ required: true, message: '合卷后卷号不能为空', trigger: 'blur' }],
|
||||
},
|
||||
submitting: false,
|
||||
l2HotCoilId: '',
|
||||
|
||||
historyLoading: false,
|
||||
historyList: [],
|
||||
historyTotal: 0,
|
||||
historyQuery: { pageNum: 1, pageSize: 10, actionType: 200 },
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadHistory()
|
||||
},
|
||||
methods: {
|
||||
defaultForm() {
|
||||
return {
|
||||
sourceCoils: [{ enterCoilNo: '' }],
|
||||
targetCoilNo: '',
|
||||
mergedWeight: undefined,
|
||||
exitThickness: undefined,
|
||||
exitWidth: undefined,
|
||||
team: undefined,
|
||||
remark: '',
|
||||
actionType: 200,
|
||||
}
|
||||
},
|
||||
|
||||
addSourceCoil() {
|
||||
this.form.sourceCoils.push({ enterCoilNo: '' })
|
||||
},
|
||||
removeSourceCoil(idx) {
|
||||
this.form.sourceCoils.splice(idx, 1)
|
||||
// 重新推算锚点
|
||||
this.l2HotCoilId = (this.form.sourceCoils[0]?.enterCoilNo || '').trim()
|
||||
},
|
||||
onSourceCoilInput(item) {
|
||||
// 以列表第一个源卷的卷号作为 L2 查询锚点
|
||||
const first = (this.form.sourceCoils[0]?.enterCoilNo || '').trim()
|
||||
this.l2HotCoilId = first
|
||||
},
|
||||
|
||||
applyL2Fill(data) {
|
||||
if (data.exit_thick != null) this.form.exitThickness = parseFloat(data.exit_thick)
|
||||
if (data.exit_width != null) this.form.exitWidth = parseFloat(data.exit_width)
|
||||
if (data.entry_weight != null) this.form.mergedWeight = parseFloat(data.entry_weight)
|
||||
this.$message.success('L2 数据已写入表单')
|
||||
},
|
||||
|
||||
submitForm() {
|
||||
this.$refs.form.validate(valid => {
|
||||
if (!valid) return
|
||||
this.submitting = true
|
||||
// 将源卷列表序列化放入 remark 或 enterCoilNo(多对一合卷用逗号分隔)
|
||||
const sourceNos = this.form.sourceCoils.map(s => s.enterCoilNo).filter(Boolean).join(',')
|
||||
const payload = {
|
||||
enterCoilNo: sourceNos,
|
||||
currentCoilNo: this.form.targetCoilNo,
|
||||
exitThickness: this.form.exitThickness,
|
||||
exitWidth: this.form.exitWidth,
|
||||
netWeight: this.form.mergedWeight,
|
||||
team: this.form.team,
|
||||
remark: this.form.remark,
|
||||
actionType: 200,
|
||||
}
|
||||
addCoilWarehouseOperationLog(payload).then(() => {
|
||||
this.$modal.msgSuccess('合卷操作已记录')
|
||||
this.resetForm()
|
||||
this.loadHistory()
|
||||
}).finally(() => { this.submitting = false })
|
||||
})
|
||||
},
|
||||
|
||||
resetForm() {
|
||||
this.form = this.defaultForm()
|
||||
this.l2HotCoilId = ''
|
||||
this.$nextTick(() => { this.$refs.form && this.$refs.form.clearValidate() })
|
||||
},
|
||||
|
||||
loadHistory() {
|
||||
this.historyLoading = true
|
||||
listCoilWarehouseOperationLog(this.historyQuery).then(res => {
|
||||
this.historyList = res.rows || []
|
||||
this.historyTotal = res.total || 0
|
||||
}).finally(() => { this.historyLoading = false })
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.acid-op-page { background: #f5f7fa; }
|
||||
.op-card {
|
||||
background: #fff;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
}
|
||||
.op-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 2px solid #67c23a;
|
||||
}
|
||||
.op-title { font-size: 15px; font-weight: 600; color: #303133; }
|
||||
.sub-section-label {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin: 0 0 8px 110px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.source-row { position: relative; }
|
||||
</style>
|
||||
237
klp-ui/src/views/wms/coil/do/acid-normal.vue
Normal file
237
klp-ui/src/views/wms/coil/do/acid-normal.vue
Normal file
@@ -0,0 +1,237 @@
|
||||
<template>
|
||||
<div class="app-container acid-op-page">
|
||||
<el-row :gutter="16">
|
||||
|
||||
<!-- ── 左侧:操作表单 + 历史记录 ── -->
|
||||
<el-col :span="15">
|
||||
|
||||
<!-- 新增表单 -->
|
||||
<div class="op-card">
|
||||
<div class="op-header">
|
||||
<span class="op-title">酸轧操作录入</span>
|
||||
<el-tag size="mini" type="info" style="margin-left:8px">actionType = 11</el-tag>
|
||||
</div>
|
||||
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="110px" size="small">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="入场钢卷号" prop="enterCoilNo">
|
||||
<el-input v-model="form.enterCoilNo" placeholder="回车自动查询 L2"
|
||||
clearable @keyup.enter.native="onEnterCoilInput"
|
||||
@blur="onEnterCoilInput" @clear="clearL2" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="出口钢卷号" prop="currentCoilNo">
|
||||
<el-input v-model="form.currentCoilNo" placeholder="请输入出口钢卷号" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-divider content-position="left" style="margin:8px 0 12px">出口实绩</el-divider>
|
||||
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="出口厚度(mm)" prop="exitThickness">
|
||||
<el-input-number v-model="form.exitThickness" :precision="3" :min="0"
|
||||
:controls="false" style="width:100%" placeholder="—" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="出口宽度(mm)" prop="exitWidth">
|
||||
<el-input-number v-model="form.exitWidth" :precision="1" :min="0"
|
||||
:controls="false" style="width:100%" placeholder="—" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="出口长度(m)" prop="exitLength">
|
||||
<el-input-number v-model="form.exitLength" :precision="1" :min="0"
|
||||
:controls="false" style="width:100%" placeholder="—" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="入口重量(t)" prop="entryWeight">
|
||||
<el-input-number v-model="form.entryWeight" :precision="3" :min="0"
|
||||
:controls="false" style="width:100%" placeholder="—" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="出口重量(t)" prop="exitWeight">
|
||||
<el-input-number v-model="form.exitWeight" :precision="3" :min="0"
|
||||
:controls="false" style="width:100%" placeholder="—" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="工艺编码" prop="processCode">
|
||||
<el-input v-model="form.processCode" placeholder="—" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="班组" prop="team">
|
||||
<el-select v-model="form.team" placeholder="请选择" style="width:100%" clearable>
|
||||
<el-option label="甲班" value="甲" />
|
||||
<el-option label="乙班" value="乙" />
|
||||
<el-option label="丙班" value="丙" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.remark" placeholder="选填" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<div style="text-align:right;padding-top:4px">
|
||||
<el-button @click="resetForm">重置</el-button>
|
||||
<el-button type="primary" :loading="submitting" @click="submitForm">新增录入</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!-- 历史记录 -->
|
||||
<div class="op-card" style="margin-top:12px">
|
||||
<div class="op-header">
|
||||
<span class="op-title">最近录入记录</span>
|
||||
<el-button size="mini" icon="el-icon-refresh" style="margin-left:auto" @click="loadHistory">刷新</el-button>
|
||||
</div>
|
||||
<el-table v-loading="historyLoading" :data="historyList" size="mini" border style="width:100%">
|
||||
<el-table-column prop="enterCoilNo" label="入场钢卷号" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="currentCoilNo" label="出口钢卷号" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="exitThickness" label="出口厚(mm)" width="90" align="right" />
|
||||
<el-table-column prop="exitWidth" label="出口宽(mm)" width="90" align="right" />
|
||||
<el-table-column prop="exitLength" label="长度(m)" width="80" align="right" />
|
||||
<el-table-column prop="entryWeight" label="入口重(t)" width="80" align="right" />
|
||||
<el-table-column prop="team" label="班组" width="60" align="center" />
|
||||
<el-table-column prop="createTime" label="录入时间" width="150" />
|
||||
</el-table>
|
||||
<pagination v-show="historyTotal > 0" :total="historyTotal"
|
||||
:page.sync="historyQuery.pageNum" :limit.sync="historyQuery.pageSize"
|
||||
@pagination="loadHistory" style="margin-top:6px" />
|
||||
</div>
|
||||
|
||||
</el-col>
|
||||
|
||||
<!-- ── 右侧:L2 匹配面板 ── -->
|
||||
<el-col :span="9">
|
||||
<l2-match-panel :hot-coil-id="l2HotCoilId" @fill="applyL2Fill" />
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { addCoilWarehouseOperationLog, listCoilWarehouseOperationLog } from '@/api/wms/coilWarehouseOperationLog'
|
||||
import L2MatchPanel from '../panels/L2MatchPanel.vue'
|
||||
|
||||
export default {
|
||||
name: 'AcidNormal',
|
||||
components: { L2MatchPanel },
|
||||
data() {
|
||||
return {
|
||||
form: this.defaultForm(),
|
||||
rules: {
|
||||
enterCoilNo: [{ required: true, message: '入场钢卷号不能为空', trigger: 'blur' }],
|
||||
},
|
||||
submitting: false,
|
||||
l2HotCoilId: '',
|
||||
|
||||
historyLoading: false,
|
||||
historyList: [],
|
||||
historyTotal: 0,
|
||||
historyQuery: { pageNum: 1, pageSize: 10, actionType: 11 },
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadHistory()
|
||||
},
|
||||
methods: {
|
||||
defaultForm() {
|
||||
return {
|
||||
enterCoilNo: '',
|
||||
currentCoilNo: '',
|
||||
exitThickness: undefined,
|
||||
exitWidth: undefined,
|
||||
exitLength: undefined,
|
||||
entryWeight: undefined,
|
||||
exitWeight: undefined,
|
||||
processCode: '',
|
||||
team: undefined,
|
||||
remark: '',
|
||||
actionType: 11,
|
||||
}
|
||||
},
|
||||
|
||||
onEnterCoilInput() {
|
||||
const v = (this.form.enterCoilNo || '').trim()
|
||||
this.l2HotCoilId = v || ''
|
||||
},
|
||||
|
||||
clearL2() {
|
||||
this.l2HotCoilId = ''
|
||||
},
|
||||
|
||||
applyL2Fill(data) {
|
||||
if (data.exit_thick != null) this.form.exitThickness = parseFloat(data.exit_thick)
|
||||
if (data.exit_width != null) this.form.exitWidth = parseFloat(data.exit_width)
|
||||
if (data.exit_length != null) this.form.exitLength = parseFloat(data.exit_length)
|
||||
if (data.entry_weight != null) this.form.entryWeight = parseFloat(data.entry_weight)
|
||||
if (data.process_code) this.form.processCode = data.process_code
|
||||
this.$message.success('L2 数据已写入表单')
|
||||
},
|
||||
|
||||
submitForm() {
|
||||
this.$refs.form.validate(valid => {
|
||||
if (!valid) return
|
||||
this.submitting = true
|
||||
addCoilWarehouseOperationLog({ ...this.form }).then(() => {
|
||||
this.$modal.msgSuccess('录入成功')
|
||||
this.resetForm()
|
||||
this.loadHistory()
|
||||
}).finally(() => { this.submitting = false })
|
||||
})
|
||||
},
|
||||
|
||||
resetForm() {
|
||||
const coilNo = this.form.enterCoilNo
|
||||
this.form = this.defaultForm()
|
||||
this.$nextTick(() => {
|
||||
this.$refs.form && this.$refs.form.clearValidate()
|
||||
})
|
||||
},
|
||||
|
||||
loadHistory() {
|
||||
this.historyLoading = true
|
||||
listCoilWarehouseOperationLog(this.historyQuery).then(res => {
|
||||
this.historyList = res.rows || []
|
||||
this.historyTotal = res.total || 0
|
||||
}).finally(() => { this.historyLoading = false })
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.acid-op-page { background: #f5f7fa; }
|
||||
.op-card {
|
||||
background: #fff;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
}
|
||||
.op-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 2px solid #409eff;
|
||||
}
|
||||
.op-title { font-size: 15px; font-weight: 600; color: #303133; }
|
||||
</style>
|
||||
280
klp-ui/src/views/wms/coil/do/acid-split.vue
Normal file
280
klp-ui/src/views/wms/coil/do/acid-split.vue
Normal file
@@ -0,0 +1,280 @@
|
||||
<template>
|
||||
<div class="app-container acid-op-page">
|
||||
<el-row :gutter="16">
|
||||
|
||||
<!-- ── 左侧:分卷表单 ── -->
|
||||
<el-col :span="15">
|
||||
<div class="op-card">
|
||||
<div class="op-header">
|
||||
<span class="op-title">分卷操作</span>
|
||||
<el-tag size="mini" type="info" style="margin-left:8px">actionType = 520</el-tag>
|
||||
</div>
|
||||
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="110px" size="small">
|
||||
|
||||
<!-- 源卷 -->
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="源卷号" prop="enterCoilNo">
|
||||
<el-input v-model="form.enterCoilNo" placeholder="回车自动查询 L2" clearable
|
||||
@keyup.enter.native="onEnterCoilInput"
|
||||
@blur="onEnterCoilInput" @clear="clearL2" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="原卷重量(t)">
|
||||
<el-input-number v-model="form.sourceWeight" :precision="3" :min="0"
|
||||
:controls="false" style="width:100%" placeholder="—" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-divider content-position="left" style="margin:4px 0 12px">子卷明细</el-divider>
|
||||
|
||||
<!-- 子卷列表(动态) -->
|
||||
<el-row v-for="(child, idx) in form.children" :key="idx"
|
||||
:gutter="12" style="margin-bottom:8px" align="middle" type="flex">
|
||||
<el-col :span="1" style="text-align:center;color:#909399;font-size:12px">
|
||||
{{ idx + 1 }}
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-form-item
|
||||
:prop="'children.' + idx + '.coilNo'"
|
||||
:rules="[{ required: true, message: '请输入子卷号', trigger: 'blur' }]"
|
||||
style="margin-bottom:0"
|
||||
>
|
||||
<el-input v-model="child.coilNo" :placeholder="'子卷号 ' + (idx + 1)" clearable size="small" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-form-item style="margin-bottom:0">
|
||||
<el-input-number v-model="child.weight" :precision="3" :min="0"
|
||||
:controls="false" style="width:100%" placeholder="重量(t)" size="small" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item style="margin-bottom:0">
|
||||
<el-input-number v-model="child.length" :precision="1" :min="0"
|
||||
:controls="false" style="width:100%" placeholder="长度(m)" size="small" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="1">
|
||||
<el-button icon="el-icon-minus" size="mini" type="danger" circle
|
||||
:disabled="form.children.length <= 1"
|
||||
@click="removeChild(idx)" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<div style="display:flex;align-items:center;margin-left:12px;margin-bottom:12px;gap:12px">
|
||||
<el-button size="mini" type="primary" plain icon="el-icon-plus" @click="addChild">
|
||||
添加子卷
|
||||
</el-button>
|
||||
<span v-if="weightLeft != null" :class="['weight-hint', weightLeft < 0 ? 'over' : '']">
|
||||
已分配 {{ weightAssigned.toFixed(3) }} t
|
||||
<template v-if="form.sourceWeight">
|
||||
/ 剩余 <b>{{ weightLeft.toFixed(3) }} t</b>
|
||||
</template>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="出口厚度(mm)">
|
||||
<el-input-number v-model="form.exitThickness" :precision="3" :min="0"
|
||||
:controls="false" style="width:100%" placeholder="—" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="出口宽度(mm)">
|
||||
<el-input-number v-model="form.exitWidth" :precision="1" :min="0"
|
||||
:controls="false" style="width:100%" placeholder="—" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="班组">
|
||||
<el-select v-model="form.team" placeholder="请选择" style="width:100%" clearable>
|
||||
<el-option label="甲班" value="甲" />
|
||||
<el-option label="乙班" value="乙" />
|
||||
<el-option label="丙班" value="丙" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.remark" placeholder="选填" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<div style="text-align:right;padding-top:4px">
|
||||
<el-button @click="resetForm">重置</el-button>
|
||||
<el-button type="primary" :loading="submitting" @click="submitForm">确认分卷</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!-- 历史记录 -->
|
||||
<div class="op-card" style="margin-top:12px">
|
||||
<div class="op-header">
|
||||
<span class="op-title">最近分卷记录</span>
|
||||
<el-button size="mini" icon="el-icon-refresh" style="margin-left:auto" @click="loadHistory">刷新</el-button>
|
||||
</div>
|
||||
<el-table v-loading="historyLoading" :data="historyList" size="mini" border style="width:100%">
|
||||
<el-table-column prop="enterCoilNo" label="源卷号" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="currentCoilNo" label="子卷号" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="exitThickness" label="出口厚(mm)" width="90" align="right" />
|
||||
<el-table-column prop="exitWidth" label="出口宽(mm)" width="90" align="right" />
|
||||
<el-table-column prop="netWeight" label="重量(t)" width="80" align="right" />
|
||||
<el-table-column prop="team" label="班组" width="60" align="center" />
|
||||
<el-table-column prop="createTime" label="录入时间" width="150" />
|
||||
</el-table>
|
||||
<pagination v-show="historyTotal > 0" :total="historyTotal"
|
||||
:page.sync="historyQuery.pageNum" :limit.sync="historyQuery.pageSize"
|
||||
@pagination="loadHistory" style="margin-top:6px" />
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<!-- ── 右侧:L2 匹配面板 ── -->
|
||||
<el-col :span="9">
|
||||
<l2-match-panel :hot-coil-id="l2HotCoilId" @fill="applyL2Fill" />
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { addCoilWarehouseOperationLog, listCoilWarehouseOperationLog } from '@/api/wms/coilWarehouseOperationLog'
|
||||
import L2MatchPanel from '../panels/L2MatchPanel.vue'
|
||||
|
||||
export default {
|
||||
name: 'AcidSplit',
|
||||
components: { L2MatchPanel },
|
||||
data() {
|
||||
return {
|
||||
form: this.defaultForm(),
|
||||
rules: {
|
||||
enterCoilNo: [{ required: true, message: '源卷号不能为空', trigger: 'blur' }],
|
||||
},
|
||||
submitting: false,
|
||||
l2HotCoilId: '',
|
||||
|
||||
historyLoading: false,
|
||||
historyList: [],
|
||||
historyTotal: 0,
|
||||
historyQuery: { pageNum: 1, pageSize: 10, actionType: 520 },
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
weightAssigned() {
|
||||
return this.form.children.reduce((s, c) => s + (c.weight || 0), 0)
|
||||
},
|
||||
weightLeft() {
|
||||
if (!this.form.sourceWeight) return null
|
||||
return this.form.sourceWeight - this.weightAssigned
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.loadHistory()
|
||||
},
|
||||
methods: {
|
||||
defaultForm() {
|
||||
return {
|
||||
enterCoilNo: '',
|
||||
sourceWeight: undefined,
|
||||
children: [{ coilNo: '', weight: undefined, length: undefined }],
|
||||
exitThickness: undefined,
|
||||
exitWidth: undefined,
|
||||
team: undefined,
|
||||
remark: '',
|
||||
actionType: 520,
|
||||
}
|
||||
},
|
||||
|
||||
addChild() {
|
||||
this.form.children.push({ coilNo: '', weight: undefined, length: undefined })
|
||||
},
|
||||
removeChild(idx) {
|
||||
this.form.children.splice(idx, 1)
|
||||
},
|
||||
|
||||
onEnterCoilInput() {
|
||||
this.l2HotCoilId = (this.form.enterCoilNo || '').trim()
|
||||
},
|
||||
clearL2() {
|
||||
this.l2HotCoilId = ''
|
||||
},
|
||||
|
||||
applyL2Fill(data) {
|
||||
if (data.exit_thick != null) this.form.exitThickness = parseFloat(data.exit_thick)
|
||||
if (data.exit_width != null) this.form.exitWidth = parseFloat(data.exit_width)
|
||||
if (data.entry_weight != null) this.form.sourceWeight = parseFloat(data.entry_weight)
|
||||
this.$message.success('L2 数据已写入表单')
|
||||
},
|
||||
|
||||
submitForm() {
|
||||
this.$refs.form.validate(valid => {
|
||||
if (!valid) return
|
||||
this.submitting = true
|
||||
// 每个子卷提交一条记录
|
||||
const records = this.form.children.map(child => ({
|
||||
enterCoilNo: this.form.enterCoilNo,
|
||||
currentCoilNo: child.coilNo,
|
||||
netWeight: child.weight,
|
||||
exitLength: child.length,
|
||||
exitThickness: this.form.exitThickness,
|
||||
exitWidth: this.form.exitWidth,
|
||||
team: this.form.team,
|
||||
remark: this.form.remark,
|
||||
actionType: 520,
|
||||
}))
|
||||
// 串行提交(也可并行,视后端是否支持批量而定)
|
||||
const submitAll = records.reduce((p, rec) => {
|
||||
return p.then(() => addCoilWarehouseOperationLog(rec))
|
||||
}, Promise.resolve())
|
||||
submitAll.then(() => {
|
||||
this.$modal.msgSuccess(`分卷操作已记录(共 ${records.length} 条子卷)`)
|
||||
this.resetForm()
|
||||
this.loadHistory()
|
||||
}).finally(() => { this.submitting = false })
|
||||
})
|
||||
},
|
||||
|
||||
resetForm() {
|
||||
this.form = this.defaultForm()
|
||||
this.l2HotCoilId = ''
|
||||
this.$nextTick(() => { this.$refs.form && this.$refs.form.clearValidate() })
|
||||
},
|
||||
|
||||
loadHistory() {
|
||||
this.historyLoading = true
|
||||
listCoilWarehouseOperationLog(this.historyQuery).then(res => {
|
||||
this.historyList = res.rows || []
|
||||
this.historyTotal = res.total || 0
|
||||
}).finally(() => { this.historyLoading = false })
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.acid-op-page { background: #f5f7fa; }
|
||||
.op-card {
|
||||
background: #fff;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
}
|
||||
.op-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 2px solid #e6a23c;
|
||||
}
|
||||
.op-title { font-size: 15px; font-weight: 600; color: #303133; }
|
||||
|
||||
.weight-hint { font-size: 12px; color: #606266; }
|
||||
.weight-hint.over { color: #f56c6c; }
|
||||
.weight-hint b { color: #67c23a; }
|
||||
.weight-hint.over b { color: #f56c6c; }
|
||||
</style>
|
||||
188
klp-ui/src/views/wms/coil/panels/L2MatchPanel.vue
Normal file
188
klp-ui/src/views/wms/coil/panels/L2MatchPanel.vue
Normal file
@@ -0,0 +1,188 @@
|
||||
<template>
|
||||
<div class="l2-panel">
|
||||
|
||||
<!-- 最佳匹配 -->
|
||||
<div class="panel-block">
|
||||
<div class="pb-header">
|
||||
<span class="pb-title">最佳匹配</span>
|
||||
<el-tag v-if="bestMatch" size="mini" type="success" style="margin-left:6px">热卷号已找到</el-tag>
|
||||
<el-tag v-else-if="matchLoading" size="mini" type="info" style="margin-left:6px">查询中</el-tag>
|
||||
<el-tag v-else-if="hotCoilId" size="mini" type="warning" style="margin-left:6px">未找到</el-tag>
|
||||
<el-tag v-else size="mini" style="margin-left:6px">待输入</el-tag>
|
||||
</div>
|
||||
|
||||
<template v-if="bestMatch">
|
||||
<div class="match-grid">
|
||||
<div class="mg-item" v-for="f in PLAN_FIELDS" :key="f.key">
|
||||
<span class="mg-label">{{ f.label }}</span>
|
||||
<span class="mg-value">{{ formatPlanField(f.key, bestMatch[f.key]) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-button type="primary" size="small" style="width:100%;margin-top:10px"
|
||||
icon="el-icon-download" @click="$emit('fill', bestMatch)">
|
||||
写入表单
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<div v-else-if="matchLoading" class="pb-empty"><i class="el-icon-loading" /></div>
|
||||
<div v-else class="pb-empty">{{ hotCoilId ? '未找到匹配的 L2 计划记录' : '输入入场钢卷号后自动查询' }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 最近20条 -->
|
||||
<div class="panel-block" style="margin-top:12px">
|
||||
<div class="pb-header">
|
||||
<span class="pb-title">最近 20 条生产记录</span>
|
||||
<el-button type="text" size="mini" icon="el-icon-refresh"
|
||||
style="margin-left:auto" :loading="recentLoading" @click="loadRecentList">刷新</el-button>
|
||||
</div>
|
||||
|
||||
<el-table :data="recentList" size="mini" v-loading="recentLoading"
|
||||
max-height="400" border style="width:100%">
|
||||
<el-table-column label="热卷号" min-width="110" show-overflow-tooltip>
|
||||
<template slot-scope="{ row }">
|
||||
<span :class="(row.hot_coilid || row.encoilid) === hotCoilId ? 'hot-match' : ''">
|
||||
{{ row.hot_coilid || row.encoilid || '—' }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="出口厚" width="72" align="right">
|
||||
<template slot-scope="{ row }">{{ row.exit_thick != null ? row.exit_thick : '—' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="出口宽" width="72" align="right">
|
||||
<template slot-scope="{ row }">{{ row.exit_width != null ? row.exit_width : '—' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="长度(m)" width="76" align="right">
|
||||
<template slot-scope="{ row }">{{ row.exit_length != null ? row.exit_length : '—' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="重量(t)" width="72" align="right">
|
||||
<template slot-scope="{ row }">{{ row.entry_weight != null ? row.entry_weight : '—' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="" width="52" fixed="right" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<el-button type="text" size="mini" @click="$emit('fill', row)">写入</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getTimingPlanDetailByHotcoilId, getExcoilList } from '@/api/l2/timing'
|
||||
|
||||
const PLAN_FIELDS = [
|
||||
{ key: 'hot_coilid', label: '热卷号' },
|
||||
{ key: 'status', label: '状态' },
|
||||
{ key: 'process_code', label: '工艺编码' },
|
||||
{ key: 'entry_thick', label: '入口厚(mm)' },
|
||||
{ key: 'entry_width', label: '入口宽(mm)' },
|
||||
{ key: 'entry_weight', label: '入口重量(t)' },
|
||||
{ key: 'exit_thick', label: '出口厚(mm)' },
|
||||
{ key: 'exit_width', label: '出口宽(mm)' },
|
||||
{ key: 'exit_length', label: '出口长度(m)' },
|
||||
{ key: 'park_type', label: '包装要求' },
|
||||
{ key: 'trimming', label: '切边要求' },
|
||||
]
|
||||
|
||||
export default {
|
||||
name: 'L2MatchPanel',
|
||||
props: {
|
||||
hotCoilId: { type: String, default: '' }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
PLAN_FIELDS,
|
||||
bestMatch: null,
|
||||
matchLoading: false,
|
||||
recentList: [],
|
||||
recentLoading: false,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
hotCoilId(val) {
|
||||
if (val) this.loadBestMatch(val)
|
||||
else this.bestMatch = null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadRecentList()
|
||||
if (this.hotCoilId) this.loadBestMatch(this.hotCoilId)
|
||||
},
|
||||
methods: {
|
||||
loadBestMatch(hotCoilId) {
|
||||
this.bestMatch = null
|
||||
this.matchLoading = true
|
||||
getTimingPlanDetailByHotcoilId(hotCoilId).then(res => {
|
||||
const fr = res?.data?.firstRow
|
||||
this.bestMatch = (fr && Object.keys(fr).length > 0) ? fr : null
|
||||
}).catch(() => {}).finally(() => { this.matchLoading = false })
|
||||
},
|
||||
loadRecentList() {
|
||||
this.recentLoading = true
|
||||
getExcoilList(1, 20).then(res => {
|
||||
const rows = res?.data?.rows || []
|
||||
this.recentList = rows.map(row => this.normalizeExcoilRow(row))
|
||||
}).catch(() => {}).finally(() => { this.recentLoading = false })
|
||||
},
|
||||
formatPlanField(key, val) {
|
||||
if (val == null) return '—'
|
||||
if (key === 'trimming') {
|
||||
if (val === 1 || val === '1') return '净边料'
|
||||
if (val === 0 || val === '0') return '毛边料'
|
||||
}
|
||||
return val
|
||||
},
|
||||
normalizeExcoilRow(row) {
|
||||
const g = k => row[k] != null ? row[k] : (row[k.toUpperCase()] != null ? row[k.toUpperCase()] : null)
|
||||
return {
|
||||
hot_coilid: g('hot_coilid'),
|
||||
encoilid: g('encoilid'),
|
||||
excoilid: g('excoilid'),
|
||||
exit_thick: g('exit_thick'),
|
||||
exit_width: g('exit_width'),
|
||||
exit_length: g('exit_length'),
|
||||
entry_weight: g('used_entry_weight') != null ? g('used_entry_weight')
|
||||
: (g('meas_exit_weight') != null ? g('meas_exit_weight') : g('entry_weight')),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.l2-panel { font-size: 13px; }
|
||||
|
||||
.panel-block {
|
||||
background: #fff;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
}
|
||||
.pb-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #f0f2f5;
|
||||
}
|
||||
.pb-title { font-weight: 600; color: #303133; font-size: 13px; }
|
||||
|
||||
.match-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 6px 12px;
|
||||
}
|
||||
.mg-item { display: flex; flex-direction: column; }
|
||||
.mg-label { font-size: 11px; color: #909399; }
|
||||
.mg-value { font-size: 13px; color: #303133; font-weight: 500; }
|
||||
|
||||
.pb-empty {
|
||||
text-align: center;
|
||||
color: #c0c4cc;
|
||||
padding: 20px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.hot-match { color: #67c23a; font-weight: 600; }
|
||||
</style>
|
||||
@@ -26,25 +26,9 @@
|
||||
|
||||
<!-- 主内容区 - 左右布局 -->
|
||||
<div class="content-wrapper">
|
||||
<!-- 左侧:酸轧信息推荐 -->
|
||||
<!-- 左侧:L2 匹配面板 -->
|
||||
<div>
|
||||
<!-- 酸连轧最近10条记录展示 -->
|
||||
<el-card class="recent-records-card" v-if="acidRecentRecords && acidRecentRecords.length > 0">
|
||||
<div slot="header" class="card-header">
|
||||
<span><i class="el-icon-time"></i> 酸连轧最近记录</span>
|
||||
</div>
|
||||
|
||||
<el-table :data="acidRecentRecords" stripe size="small" @row-click="handleClickRecord">
|
||||
<el-table-column prop="currentCoilNo" label="加工前卷号" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="excoilId" label="出口卷号" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="exitWeight" label="出口重量(t)" width="100">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.exitWeight ? scope.row.exitWeight + ' t' : '—' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="team" label="班组" width="80"></el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
<l2-match-panel :hot-coil-id="l2HotCoilId" @fill="applyL2Fill" />
|
||||
</div>
|
||||
<!-- 右侧:更新表单 -->
|
||||
<div>
|
||||
@@ -138,35 +122,6 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="质量状态" prop="qualityStatus">
|
||||
<el-select v-model="updateForm.qualityStatus" placeholder="请选择质量状态" style="width: 100%">
|
||||
<el-option v-for="item in dict.type.coil_quality_status" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="切边要求" prop="trimmingRequirement">
|
||||
<el-select v-model="updateForm.trimmingRequirement" placeholder="请选择切边要求" style="width: 100%">
|
||||
<el-option label="净边料" value="净边料" />
|
||||
<el-option label="毛边料" value="毛边料" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="包装要求" prop="packagingRequirement">
|
||||
<el-select v-model="updateForm.packagingRequirement" placeholder="请选择包装要求" style="width: 100%">
|
||||
<el-option label="裸包" value="裸包" />
|
||||
<el-option label="普包" value="普包" />
|
||||
<el-option label="简包" value="简包" />
|
||||
<el-option label="精包" value="精包" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="毛重(t)" prop="grossWeight">
|
||||
@@ -361,8 +316,6 @@
|
||||
<script>
|
||||
import { getMaterialCoil, updateMaterialCoil, getFirstHeatCoilMaterial } from '@/api/wms/coil';
|
||||
import { completeAction, getPendingAction } from '@/api/wms/pendingAction';
|
||||
// import { getTimingPlanList } from '@/api/l2/timing'
|
||||
import { getAcidTypingPrefill } from '@/api/pocket/acidTyping';
|
||||
import { saveCoilCache, getCoilCacheByCoilId, delCoilCache } from '@/api/wms/coilCache';
|
||||
import ActualWarehouseSelect from "@/components/KLPService/ActualWarehouseSelect";
|
||||
import RawMaterialSelect from "@/components/KLPService/RawMaterialSelect";
|
||||
@@ -373,6 +326,7 @@ import AbnormalForm from './components/AbnormalForm';
|
||||
import { generateCoilNoPrefix } from "@/utils/coil/coilNo";
|
||||
import { addCoilContractRel } from "@/api/wms/coilContractRel";
|
||||
import ContractSelect from "@/components/KLPService/ContractSelect";
|
||||
import L2MatchPanel from './panels/L2MatchPanel.vue';
|
||||
|
||||
|
||||
export default {
|
||||
@@ -384,7 +338,8 @@ export default {
|
||||
WarehouseSelect,
|
||||
TimeInput,
|
||||
AbnormalForm,
|
||||
ContractSelect
|
||||
ContractSelect,
|
||||
L2MatchPanel,
|
||||
},
|
||||
dicts: ['coil_quality_status', 'coil_abnormal_position', 'coil_abnormal_code', 'coil_abnormal_degree', 'coil_business_purpose'],
|
||||
data() {
|
||||
@@ -479,9 +434,6 @@ export default {
|
||||
type: 'info',
|
||||
title: ''
|
||||
},
|
||||
isAcidRolling: false,
|
||||
// 酸连轧最近记录
|
||||
acidRecentRecords: [],
|
||||
// 异常信息
|
||||
abnormals: [],
|
||||
// 异常表单弹窗
|
||||
@@ -507,6 +459,9 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
l2HotCoilId() {
|
||||
return (this.currentInfo && this.currentInfo.enterCoilNo) || ''
|
||||
},
|
||||
// 动态显示标签
|
||||
getItemLabel() {
|
||||
if (this.updateForm.materialType === '成品') {
|
||||
@@ -530,98 +485,13 @@ export default {
|
||||
// 从路由参数获取coilId和actionId
|
||||
const coilId = this.$route.query.coilId;
|
||||
const actionId = this.$route.query.actionId;
|
||||
let actionType = ''
|
||||
const pendingActionRes = await getPendingAction(actionId)
|
||||
actionType = pendingActionRes.data.actionType
|
||||
|
||||
// 填写生产开始时间
|
||||
this.$set(this.updateForm, 'productionStartTime', pendingActionRes.data.createTime)
|
||||
|
||||
this.isAcidRolling = (actionType == 11)
|
||||
|
||||
if (this.isAcidRolling) {
|
||||
this.acidPrefill.visible = true
|
||||
this.acidPrefill.type = 'info'
|
||||
this.acidPrefill.title = '正在结合酸轧二级系统自动填写部分信息...'
|
||||
}
|
||||
|
||||
if (coilId) {
|
||||
await this.loadCoilInfo(coilId);
|
||||
|
||||
if (this.isAcidRolling) {
|
||||
const currentCoilNo = this.currentInfo && this.currentInfo.currentCoilNo
|
||||
|
||||
if (!currentCoilNo) {
|
||||
this.acidPrefill.type = 'warning'
|
||||
this.acidPrefill.title = '当前钢卷号为空'
|
||||
} else {
|
||||
try {
|
||||
const prefillRes = await getAcidTypingPrefill(currentCoilNo)
|
||||
const prefill = prefillRes && prefillRes.data
|
||||
|
||||
if (!prefill || prefill.length === 0) {
|
||||
this.acidPrefill.type = 'info'
|
||||
this.acidPrefill.title = '未在二级系统中查找到对应信息,请自行填写'
|
||||
} else {
|
||||
// 处理返回的列表数据
|
||||
if (Array.isArray(prefill)) {
|
||||
this.acidRecentRecords = prefill;
|
||||
|
||||
// 使用第一条记录填充表单(保持原有逻辑)
|
||||
const firstRecord = prefill[0];
|
||||
if (firstRecord) {
|
||||
if (firstRecord.exitWeight != null && firstRecord.exitWeight !== '') {
|
||||
const w = Number(firstRecord.exitWeight)
|
||||
if (!Number.isNaN(w)) {
|
||||
this.$set(this.updateForm, 'grossWeight', w)
|
||||
this.$set(this.updateForm, 'netWeight', w)
|
||||
}
|
||||
}
|
||||
|
||||
if (firstRecord.exitLength != null && firstRecord.exitLength !== '') {
|
||||
const len = Number(firstRecord.exitLength)
|
||||
if (!Number.isNaN(len)) {
|
||||
this.$set(this.updateForm, 'length', len)
|
||||
}
|
||||
}
|
||||
|
||||
if (firstRecord.team) {
|
||||
this.$set(this.updateForm, 'team', firstRecord.team)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 为了兼容旧版本的单个对象返回格式
|
||||
if (prefill.exitWeight != null && prefill.exitWeight !== '') {
|
||||
const w = Number(prefill.exitWeight)
|
||||
if (!Number.isNaN(w)) {
|
||||
this.$set(this.updateForm, 'grossWeight', w)
|
||||
this.$set(this.updateForm, 'netWeight', w)
|
||||
}
|
||||
}
|
||||
|
||||
if (prefill.exitLength != null && prefill.exitLength !== '') {
|
||||
const len = Number(prefill.exitLength)
|
||||
if (!Number.isNaN(len)) {
|
||||
this.$set(this.updateForm, 'length', len)
|
||||
}
|
||||
}
|
||||
|
||||
if (prefill.team) {
|
||||
this.$set(this.updateForm, 'team', prefill.team)
|
||||
}
|
||||
}
|
||||
|
||||
this.acidPrefill.type = 'success'
|
||||
this.acidPrefill.title = '已结合酸轧二级系统完成部分信息填写'
|
||||
console.log('[typing] acid rolling prefill applied:', prefill)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[typing] acid rolling prefill request failed:', e)
|
||||
this.acidPrefill.type = 'error'
|
||||
this.acidPrefill.title = '未在二级系统中查找到对应信息,故自动填写失败'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const currentCoilNoPrefix = generateCoilNoPrefix()
|
||||
@@ -653,6 +523,36 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
applyL2Fill(data) {
|
||||
if (data.entry_weight != null) {
|
||||
const w = parseFloat(data.entry_weight)
|
||||
if (!Number.isNaN(w)) {
|
||||
this.$set(this.updateForm, 'grossWeight', w)
|
||||
this.$set(this.updateForm, 'netWeight', w)
|
||||
}
|
||||
}
|
||||
if (data.exit_length != null) {
|
||||
const len = parseFloat(data.exit_length)
|
||||
if (!Number.isNaN(len)) {
|
||||
this.$set(this.updateForm, 'length', len)
|
||||
this.$set(this.updateForm, 'actualLength', len)
|
||||
}
|
||||
}
|
||||
if (data.exit_thick != null) this.$set(this.updateForm, 'actualThickness', parseFloat(data.exit_thick))
|
||||
if (data.exit_width != null) this.$set(this.updateForm, 'actualWidth', parseFloat(data.exit_width))
|
||||
// 包装要求
|
||||
if (data.park_type != null && data.park_type !== '') {
|
||||
this.$set(this.updateForm, 'packagingRequirement', data.park_type)
|
||||
}
|
||||
// 切边要求:1=净边料,0=毛边料
|
||||
if (data.trimming != null) {
|
||||
const t = String(data.trimming)
|
||||
if (t === '1') this.$set(this.updateForm, 'trimmingRequirement', '净边料')
|
||||
else if (t === '0') this.$set(this.updateForm, 'trimmingRequirement', '毛边料')
|
||||
}
|
||||
this.$message.success('L2 数据已写入表单')
|
||||
},
|
||||
|
||||
// 处理材料类型变化
|
||||
handleMaterialTypeChange(value) {
|
||||
// 清空物品选择
|
||||
@@ -667,17 +567,6 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
handleClickRecord(row) {
|
||||
this.updateForm = {
|
||||
...this.updateForm,
|
||||
currentCoilNo: row.excoilId,
|
||||
team: row.team,
|
||||
netWeight: row.exitWeight,
|
||||
grossWeight: row.exitWeight,
|
||||
length: row.exitLength,
|
||||
}
|
||||
},
|
||||
|
||||
// 加载钢卷信息
|
||||
async loadCoilInfo(coilId) {
|
||||
try {
|
||||
@@ -1050,7 +939,7 @@ export default {
|
||||
.content-wrapper {
|
||||
display: grid;
|
||||
margin-top: 10px;
|
||||
grid-template-columns: 600px 1fr;
|
||||
grid-template-columns: 340px 1fr;
|
||||
gap: 10px;
|
||||
align-items: stretch; // 改为stretch,让子元素高度一致
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
-- 轧辊库
|
||||
CREATE TABLE mes_roll_info (
|
||||
roll_id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
line_id BIGINT NULL COMMENT '产线ID(关联 wms_production_line.line_id)',
|
||||
roll_no VARCHAR(50) NOT NULL COMMENT '轧辊编号',
|
||||
roll_type VARCHAR(10) NOT NULL COMMENT '辊型: WR=工作辊 / BR=支撑辊',
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'Offline' COMMENT 'Online/Standby/Offline/Scrapped',
|
||||
@@ -20,12 +21,14 @@ CREATE TABLE mes_roll_info (
|
||||
update_by VARCHAR(64), update_time DATETIME,
|
||||
remark VARCHAR(500),
|
||||
PRIMARY KEY (roll_id),
|
||||
UNIQUE KEY uk_roll_no (roll_no)
|
||||
UNIQUE KEY uk_roll_no (roll_no),
|
||||
KEY idx_line_id (line_id)
|
||||
) ENGINE=InnoDB COMMENT='轧辊库';
|
||||
|
||||
-- 换辊记录(四辊轧机,双机架)
|
||||
-- 换辊记录(四辊轧机,支持多产线)
|
||||
CREATE TABLE mes_roll_change (
|
||||
change_id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
line_id BIGINT NULL COMMENT '产线ID(关联 wms_production_line.line_id)',
|
||||
change_no VARCHAR(50) COMMENT '换辊编号',
|
||||
change_time DATETIME COMMENT '换辊时间',
|
||||
stand_no VARCHAR(10) COMMENT '机架号: 1# / 2#',
|
||||
@@ -46,12 +49,14 @@ CREATE TABLE mes_roll_change (
|
||||
update_by VARCHAR(64), update_time DATETIME,
|
||||
remark VARCHAR(500),
|
||||
PRIMARY KEY (change_id),
|
||||
KEY idx_line_stand (line_id, stand_no),
|
||||
KEY idx_stand_time (stand_no, change_time)
|
||||
) ENGINE=InnoDB COMMENT='换辊记录';
|
||||
|
||||
-- 下批轧辊(每条=一个辊位的备用辊)
|
||||
-- 下批轧辊(每条=一个辊位的备用辊,支持多产线)
|
||||
CREATE TABLE mes_roll_standby (
|
||||
standby_id BIGINT NOT NULL AUTO_INCREMENT,
|
||||
line_id BIGINT NULL COMMENT '产线ID(关联 wms_production_line.line_id)',
|
||||
stand_no VARCHAR(10) COMMENT '机架号: 1# / 2#',
|
||||
roll_no VARCHAR(50) COMMENT '轧辊编号',
|
||||
roll_type VARCHAR(10) COMMENT 'WR=工作辊 / BR=支撑辊',
|
||||
@@ -64,5 +69,6 @@ CREATE TABLE mes_roll_standby (
|
||||
create_by VARCHAR(64), create_time DATETIME,
|
||||
update_by VARCHAR(64), update_time DATETIME,
|
||||
remark VARCHAR(500),
|
||||
PRIMARY KEY (standby_id)
|
||||
PRIMARY KEY (standby_id),
|
||||
KEY idx_line_stand (line_id, stand_no)
|
||||
) ENGINE=InnoDB COMMENT='下批轧辊(待换上)';
|
||||
|
||||
Reference in New Issue
Block a user