提交酸扎串联内容以及磨辊间
This commit is contained in:
@@ -414,6 +414,71 @@ public class SqlServerApiClient {
|
|||||||
return multiValueMap;
|
return multiValueMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ExecuteSqlResponse queryRollDataAll() {
|
||||||
|
return executeSql(
|
||||||
|
"oracle",
|
||||||
|
"SELECT * FROM JXPLTCM.ROLL_DATA WHERE STATUS = 'ONLINE' ORDER BY STANDID",
|
||||||
|
emptyParams()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecuteSqlResponse queryRollDataFiltered(String type, String status) {
|
||||||
|
java.util.HashMap<String, Object> params = new java.util.HashMap<>();
|
||||||
|
StringBuilder sql = new StringBuilder("SELECT * FROM JXPLTCM.ROLL_DATA WHERE 1=1");
|
||||||
|
if (type != null && !type.trim().isEmpty()) {
|
||||||
|
sql.append(" AND TYPE = :type");
|
||||||
|
params.put("type", type.trim());
|
||||||
|
}
|
||||||
|
if (status != null && !status.trim().isEmpty()) {
|
||||||
|
sql.append(" AND STATUS = :status");
|
||||||
|
params.put("status", status.trim());
|
||||||
|
}
|
||||||
|
sql.append(" ORDER BY STANDID");
|
||||||
|
return executeSql("oracle", sql.toString(), params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecuteSqlResponse queryRollHistoryByRollId(String rollId) {
|
||||||
|
return executeSql(
|
||||||
|
"oracle",
|
||||||
|
"SELECT * FROM JXPLTCM.ROLL_HISTORY WHERE ROLLID = :rollId ORDER BY CHANGE_TIME DESC",
|
||||||
|
singletonParam("rollId", rollId)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecuteSqlResponse queryRollHistoryList(int page, int pageSize, String rollId, Integer standId) {
|
||||||
|
java.util.HashMap<String, Object> params = new java.util.HashMap<>();
|
||||||
|
StringBuilder inner = new StringBuilder("SELECT * FROM JXPLTCM.ROLL_HISTORY WHERE 1=1");
|
||||||
|
if (rollId != null && !rollId.trim().isEmpty()) {
|
||||||
|
inner.append(" AND ROLLID = :rollId");
|
||||||
|
params.put("rollId", rollId.trim());
|
||||||
|
}
|
||||||
|
if (standId != null) {
|
||||||
|
inner.append(" AND STANDID = :standId");
|
||||||
|
params.put("standId", standId);
|
||||||
|
}
|
||||||
|
inner.append(" ORDER BY CHANGE_TIME DESC");
|
||||||
|
int endRow = page * pageSize;
|
||||||
|
int startRow = endRow - pageSize;
|
||||||
|
params.put("endRow", endRow);
|
||||||
|
params.put("startRow", startRow);
|
||||||
|
String sql = "SELECT * FROM (SELECT t.*, ROWNUM rn FROM (" + inner + ") t WHERE ROWNUM <= :endRow) WHERE rn > :startRow";
|
||||||
|
return executeSql("oracle", sql, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecuteSqlResponse queryRollHistoryCount(String rollId, Integer standId) {
|
||||||
|
java.util.HashMap<String, Object> params = new java.util.HashMap<>();
|
||||||
|
StringBuilder sql = new StringBuilder("SELECT COUNT(*) as total FROM JXPLTCM.ROLL_HISTORY WHERE 1=1");
|
||||||
|
if (rollId != null && !rollId.trim().isEmpty()) {
|
||||||
|
sql.append(" AND ROLLID = :rollId");
|
||||||
|
params.put("rollId", rollId.trim());
|
||||||
|
}
|
||||||
|
if (standId != null) {
|
||||||
|
sql.append(" AND STANDID = :standId");
|
||||||
|
params.put("standId", standId);
|
||||||
|
}
|
||||||
|
return executeSql("oracle", sql.toString(), params);
|
||||||
|
}
|
||||||
|
|
||||||
private Map<String, Object> singletonParam(String key, Object value) {
|
private Map<String, Object> singletonParam(String key, Object value) {
|
||||||
java.util.HashMap<String, Object> params = new java.util.HashMap<String, Object>();
|
java.util.HashMap<String, Object> params = new java.util.HashMap<String, Object>();
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
|
|||||||
@@ -129,6 +129,46 @@ public class SqlServerApiBusinessService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 轧辊数据:返回全部在辊/备辊数据。
|
||||||
|
*/
|
||||||
|
public RollListView getRollData() {
|
||||||
|
return RollListView.fromExecuteSqlResponse(client.queryRollDataAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 轧辊数据:按类型和状态过滤。
|
||||||
|
*/
|
||||||
|
public RollListView getRollDataFiltered(String type, String status) {
|
||||||
|
return RollListView.fromExecuteSqlResponse(client.queryRollDataFiltered(type, status));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 换辊历史:按轧辊号查询(供配辊页内联使用)。
|
||||||
|
*/
|
||||||
|
public List<Map<String, Object>> getRollHistory(String rollId) {
|
||||||
|
return asRowList(client.queryRollHistoryByRollId(rollId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 换辊历史列表(分页 + 可选过滤)。
|
||||||
|
*/
|
||||||
|
public RollHistoryPageView getRollHistoryList(int page, int pageSize, String rollId, Integer standId) {
|
||||||
|
List<Map<String, Object>> rows = asRowList(client.queryRollHistoryList(page, pageSize, rollId, standId));
|
||||||
|
return new RollHistoryPageView(rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 换辊历史总条数(用于前端分页器)。
|
||||||
|
*/
|
||||||
|
public long getRollHistoryCount(String rollId, Integer standId) {
|
||||||
|
SqlServerApiClient.ExecuteSqlResponse resp = client.queryRollHistoryCount(rollId, standId);
|
||||||
|
List<Map<String, Object>> rows = asRowList(resp);
|
||||||
|
if (rows.isEmpty()) return 0L;
|
||||||
|
Number n = asNumber(rows.get(0).get("total"));
|
||||||
|
return n == null ? 0L : n.longValue();
|
||||||
|
}
|
||||||
|
|
||||||
private static PlanListView toPlanListView(SqlServerApiClient.ExecuteSqlResponse response) {
|
private static PlanListView toPlanListView(SqlServerApiClient.ExecuteSqlResponse response) {
|
||||||
return PlanListView.fromExecuteSqlResponse(response);
|
return PlanListView.fromExecuteSqlResponse(response);
|
||||||
}
|
}
|
||||||
@@ -297,6 +337,34 @@ public class SqlServerApiBusinessService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class RollListView {
|
||||||
|
private final List<Map<String, Object>> rows;
|
||||||
|
|
||||||
|
public RollListView(List<Map<String, Object>> rows) {
|
||||||
|
this.rows = rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Map<String, Object>> getRows() {
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RollListView fromExecuteSqlResponse(SqlServerApiClient.ExecuteSqlResponse response) {
|
||||||
|
return new RollListView(asRowList(response));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RollHistoryPageView {
|
||||||
|
private final List<Map<String, Object>> rows;
|
||||||
|
|
||||||
|
public RollHistoryPageView(List<Map<String, Object>> rows) {
|
||||||
|
this.rows = rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Map<String, Object>> getRows() {
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class RealtimeDataBundle {
|
public static class RealtimeDataBundle {
|
||||||
private final SqlServerApiClient.ExecuteSqlResponse gauge;
|
private final SqlServerApiClient.ExecuteSqlResponse gauge;
|
||||||
private final SqlServerApiClient.ExecuteSqlResponse shape;
|
private final SqlServerApiClient.ExecuteSqlResponse shape;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,4 +77,49 @@ public class SqlServerApiController {
|
|||||||
public R<SqlServerApiBusinessService.RealtimeDataBundle> realtime(@PathVariable String matId) {
|
public R<SqlServerApiBusinessService.RealtimeDataBundle> realtime(@PathVariable String matId) {
|
||||||
return R.ok(businessService.getRealtimeData(matId));
|
return R.ok(businessService.getRealtimeData(matId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 轧辊数据:type / status 均可选,不传则返回全量。
|
||||||
|
*/
|
||||||
|
@GetMapping("/rolls")
|
||||||
|
public R<SqlServerApiBusinessService.RollListView> rollList(
|
||||||
|
@RequestParam(required = false) String type,
|
||||||
|
@RequestParam(required = false) String status) {
|
||||||
|
if ((type != null && !type.isEmpty()) || (status != null && !status.isEmpty())) {
|
||||||
|
return R.ok(businessService.getRollDataFiltered(type, status));
|
||||||
|
}
|
||||||
|
return R.ok(businessService.getRollData());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 换辊历史:按轧辊号查询(配辊页内联用)。
|
||||||
|
*/
|
||||||
|
@GetMapping("/rolls/{rollId}/history")
|
||||||
|
public R<List<Map<String, Object>>> rollHistory(@PathVariable String rollId) {
|
||||||
|
return R.ok(businessService.getRollHistory(rollId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 换辊历史列表(分页)。rollId / standId 均可选。
|
||||||
|
*/
|
||||||
|
@GetMapping("/rolls/history")
|
||||||
|
public R<SqlServerApiBusinessService.RollHistoryPageView> rollHistoryList(
|
||||||
|
@RequestParam(defaultValue = "1") int page,
|
||||||
|
@RequestParam(defaultValue = "50") int pageSize,
|
||||||
|
@RequestParam(required = false) String rollId,
|
||||||
|
@RequestParam(required = false) Integer standId) {
|
||||||
|
return R.ok(businessService.getRollHistoryList(page, pageSize, rollId, standId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 换辊历史总条数。
|
||||||
|
*/
|
||||||
|
@GetMapping("/rolls/history/count")
|
||||||
|
public R<Map<String, Long>> rollHistoryCount(
|
||||||
|
@RequestParam(required = false) String rollId,
|
||||||
|
@RequestParam(required = false) Integer standId) {
|
||||||
|
Map<String, Long> result = new HashMap<>();
|
||||||
|
result.put("total", businessService.getRollHistoryCount(rollId, standId));
|
||||||
|
return R.ok(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
-- =====================================================================
|
||||||
|
-- 磨辊记录表
|
||||||
|
-- 记录每次磨削的参数,并通过触发 Service 逻辑同步更新 mes_roll_info
|
||||||
|
-- =====================================================================
|
||||||
|
CREATE TABLE IF NOT EXISTS mes_roll_grind (
|
||||||
|
grind_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '磨削记录ID',
|
||||||
|
roll_id BIGINT NOT NULL COMMENT '关联轧辊ID',
|
||||||
|
roll_no VARCHAR(50) COMMENT '轧辊编号(冗余,方便查询)',
|
||||||
|
grind_time DATETIME COMMENT '磨削时间',
|
||||||
|
team VARCHAR(50) COMMENT '磨削班组/负责人',
|
||||||
|
dia_before DECIMAL(10,2) COMMENT '磨前直径(mm)',
|
||||||
|
dia_after DECIMAL(10,2) COMMENT '磨后直径(mm)',
|
||||||
|
grind_amount DECIMAL(10,2) COMMENT '磨削量(mm) = dia_before - dia_after',
|
||||||
|
roll_shape VARCHAR(100) COMMENT '辊型/辊面状态',
|
||||||
|
flaw_result VARCHAR(200) COMMENT '探伤结果',
|
||||||
|
hardness VARCHAR(50) COMMENT '硬度检测值',
|
||||||
|
operator VARCHAR(50) COMMENT '操作人员',
|
||||||
|
remark VARCHAR(500) COMMENT '备注',
|
||||||
|
|
||||||
|
del_flag INT NOT NULL DEFAULT 0 COMMENT '删除标志(0正常 1删除)',
|
||||||
|
create_by VARCHAR(64) COMMENT '创建人',
|
||||||
|
create_time DATETIME COMMENT '创建时间',
|
||||||
|
update_by VARCHAR(64) COMMENT '更新人',
|
||||||
|
update_time DATETIME COMMENT '更新时间',
|
||||||
|
|
||||||
|
PRIMARY KEY (grind_id),
|
||||||
|
KEY idx_roll_id (roll_id),
|
||||||
|
KEY idx_grind_time (grind_time)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='轧辊磨削记录';
|
||||||
|
|
||||||
|
|
||||||
|
-- =====================================================================
|
||||||
|
-- 菜单:磨辊间
|
||||||
|
-- 运行前请先查询轧辊管理父菜单 ID:
|
||||||
|
-- SELECT menu_id, menu_name, path FROM sys_menu WHERE path LIKE '%roll%';
|
||||||
|
-- 将下方的 @roll_parent 替换为实际的父菜单 ID,再执行。
|
||||||
|
-- =====================================================================
|
||||||
|
-- 示例(请先确认父菜单 ID):
|
||||||
|
--
|
||||||
|
-- SET @roll_parent = (
|
||||||
|
-- SELECT menu_id FROM sys_menu
|
||||||
|
-- WHERE path = 'roll' AND parent_id != 0
|
||||||
|
-- LIMIT 1
|
||||||
|
-- );
|
||||||
|
--
|
||||||
|
-- INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component,
|
||||||
|
-- is_frame, is_cache, menu_type, visible, status, perms, icon,
|
||||||
|
-- create_by, create_time, update_by, update_time, remark)
|
||||||
|
-- VALUES ('磨辊间', @roll_parent, 3, 'grind', 'mes/roll/grind/index',
|
||||||
|
-- 1, 0, 'C', '0', '0', NULL, 'tool',
|
||||||
|
-- 'admin', NOW(), 'admin', NOW(), '磨辊间管理');
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package com.klp.mes.roll.controller;
|
||||||
|
|
||||||
|
import com.klp.common.annotation.Log;
|
||||||
|
import com.klp.common.core.controller.BaseController;
|
||||||
|
import com.klp.common.core.domain.R;
|
||||||
|
import com.klp.common.enums.BusinessType;
|
||||||
|
import com.klp.mes.roll.domain.bo.MesRollGrindBo;
|
||||||
|
import com.klp.mes.roll.domain.vo.MesRollGrindVo;
|
||||||
|
import com.klp.mes.roll.service.IMesRollGrindService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 磨辊记录
|
||||||
|
*/
|
||||||
|
@Validated
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/mes/rollGrind")
|
||||||
|
public class MesRollGrindController extends BaseController {
|
||||||
|
|
||||||
|
private final IMesRollGrindService iMesRollGrindService;
|
||||||
|
|
||||||
|
/** 查询某轧辊的磨削记录列表 */
|
||||||
|
@GetMapping("/list")
|
||||||
|
public R<List<MesRollGrindVo>> list(@NotNull(message = "轧辊ID不能为空") @RequestParam Long rollId) {
|
||||||
|
return R.ok(iMesRollGrindService.listByRoll(rollId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 按年份查询月度汇总 */
|
||||||
|
@GetMapping("/monthlyStats")
|
||||||
|
public R<List<Map<String, Object>>> monthlyStats(
|
||||||
|
@NotNull @RequestParam Long rollId,
|
||||||
|
@RequestParam(defaultValue = "0") int year) {
|
||||||
|
int y = year > 0 ? year : java.time.LocalDate.now().getYear();
|
||||||
|
return R.ok(iMesRollGrindService.monthlyStats(rollId, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 新增磨削记录(同步更新轧辊直径和磨削次数) */
|
||||||
|
@Log(title = "磨辊记录", businessType = BusinessType.INSERT)
|
||||||
|
@PostMapping
|
||||||
|
public R<Long> add(@Validated @RequestBody MesRollGrindBo bo) {
|
||||||
|
return R.ok(iMesRollGrindService.addGrind(bo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 修改磨削记录 */
|
||||||
|
@Log(title = "磨辊记录", businessType = BusinessType.UPDATE)
|
||||||
|
@PutMapping
|
||||||
|
public R<Void> edit(@RequestBody MesRollGrindBo bo) {
|
||||||
|
return toAjax(iMesRollGrindService.updateGrind(bo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除磨削记录 */
|
||||||
|
@Log(title = "磨辊记录", businessType = BusinessType.DELETE)
|
||||||
|
@DeleteMapping("/{grindId}")
|
||||||
|
public R<Void> remove(@NotNull @PathVariable Long grindId) {
|
||||||
|
return toAjax(iMesRollGrindService.deleteGrind(grindId));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package com.klp.mes.roll.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.klp.common.core.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 磨辊记录 mes_roll_grind
|
||||||
|
*
|
||||||
|
* DDL:
|
||||||
|
* CREATE TABLE mes_roll_grind (
|
||||||
|
* grind_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '磨削记录ID',
|
||||||
|
* roll_id BIGINT NOT NULL COMMENT '轧辊ID',
|
||||||
|
* roll_no VARCHAR(50) NOT NULL COMMENT '轧辊编号',
|
||||||
|
* grind_time DATETIME COMMENT '磨削时间',
|
||||||
|
* team VARCHAR(50) COMMENT '班组',
|
||||||
|
* dia_before DECIMAL(10,2) COMMENT '磨前直径(mm)',
|
||||||
|
* dia_after DECIMAL(10,2) COMMENT '磨后直径(mm)',
|
||||||
|
* grind_amount DECIMAL(10,2) COMMENT '磨削量(mm)',
|
||||||
|
* roll_shape VARCHAR(20) COMMENT '辊型(平/凸/凹)',
|
||||||
|
* flaw_result VARCHAR(20) COMMENT '探伤结果',
|
||||||
|
* hardness DECIMAL(6,1) COMMENT '硬度',
|
||||||
|
* operator VARCHAR(50) COMMENT '操作者',
|
||||||
|
* remark VARCHAR(500) COMMENT '备注',
|
||||||
|
* del_flag TINYINT NOT NULL DEFAULT 0,
|
||||||
|
* create_by VARCHAR(64) DEFAULT '',
|
||||||
|
* create_time DATETIME,
|
||||||
|
* update_by VARCHAR(64) DEFAULT '',
|
||||||
|
* update_time DATETIME,
|
||||||
|
* PRIMARY KEY (grind_id)
|
||||||
|
* ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='磨辊记录';
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("mes_roll_grind")
|
||||||
|
public class MesRollGrind extends BaseEntity {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(value = "grind_id")
|
||||||
|
private Long grindId;
|
||||||
|
|
||||||
|
/** 轧辊ID */
|
||||||
|
private Long rollId;
|
||||||
|
|
||||||
|
/** 轧辊编号 */
|
||||||
|
private String rollNo;
|
||||||
|
|
||||||
|
/** 磨削时间 */
|
||||||
|
private Date grindTime;
|
||||||
|
|
||||||
|
/** 班组 */
|
||||||
|
private String team;
|
||||||
|
|
||||||
|
/** 磨前直径(mm) */
|
||||||
|
private BigDecimal diaBefore;
|
||||||
|
|
||||||
|
/** 磨后直径(mm) */
|
||||||
|
private BigDecimal diaAfter;
|
||||||
|
|
||||||
|
/** 磨削量(mm) = diaBefore - diaAfter */
|
||||||
|
private BigDecimal grindAmount;
|
||||||
|
|
||||||
|
/** 辊型:平 / 凸 / 凹 */
|
||||||
|
private String rollShape;
|
||||||
|
|
||||||
|
/** 探伤结果 */
|
||||||
|
private String flawResult;
|
||||||
|
|
||||||
|
/** 硬度 */
|
||||||
|
private BigDecimal hardness;
|
||||||
|
|
||||||
|
/** 操作者 */
|
||||||
|
private String operator;
|
||||||
|
|
||||||
|
@TableLogic
|
||||||
|
private Integer delFlag;
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.klp.mes.roll.domain.bo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.klp.common.core.domain.BaseEntity;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 磨辊记录 业务对象
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class MesRollGrindBo extends BaseEntity {
|
||||||
|
|
||||||
|
private Long grindId;
|
||||||
|
|
||||||
|
@NotNull(message = "轧辊ID不能为空")
|
||||||
|
private Long rollId;
|
||||||
|
|
||||||
|
private String rollNo;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date grindTime;
|
||||||
|
|
||||||
|
private String team;
|
||||||
|
private BigDecimal diaBefore;
|
||||||
|
private BigDecimal diaAfter;
|
||||||
|
private BigDecimal grindAmount;
|
||||||
|
private String rollShape;
|
||||||
|
private String flawResult;
|
||||||
|
private BigDecimal hardness;
|
||||||
|
private String operator;
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.klp.mes.roll.domain.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 磨辊记录 视图对象
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class MesRollGrindVo {
|
||||||
|
|
||||||
|
private Long grindId;
|
||||||
|
private Long rollId;
|
||||||
|
private String rollNo;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date grindTime;
|
||||||
|
|
||||||
|
private String team;
|
||||||
|
private BigDecimal diaBefore;
|
||||||
|
private BigDecimal diaAfter;
|
||||||
|
private BigDecimal grindAmount;
|
||||||
|
private String rollShape;
|
||||||
|
private String flawResult;
|
||||||
|
private BigDecimal hardness;
|
||||||
|
private String operator;
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date createTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.klp.mes.roll.mapper;
|
||||||
|
|
||||||
|
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||||
|
import com.klp.mes.roll.domain.MesRollGrind;
|
||||||
|
import com.klp.mes.roll.domain.vo.MesRollGrindVo;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 磨辊记录 Mapper
|
||||||
|
*/
|
||||||
|
public interface MesRollGrindMapper extends BaseMapperPlus<MesRollGrindMapper, MesRollGrind, MesRollGrindVo> {
|
||||||
|
|
||||||
|
/** 查询某轧辊全部磨削记录(按时间升序) */
|
||||||
|
List<MesRollGrindVo> selectByRollId(@Param("rollId") Long rollId);
|
||||||
|
|
||||||
|
/** 按年份统计每月磨削量 { month, grindCount, totalGrindAmount } */
|
||||||
|
List<Map<String, Object>> selectMonthlyStats(@Param("rollId") Long rollId, @Param("year") int year);
|
||||||
|
}
|
||||||
@@ -39,4 +39,15 @@ public interface MesRollInfoMapper extends BaseMapperPlus<MesRollInfoMapper, Mes
|
|||||||
int updateStatusByRollNoIfStatus(@Param("rollNo") String rollNo,
|
int updateStatusByRollNoIfStatus(@Param("rollNo") String rollNo,
|
||||||
@Param("status") String status,
|
@Param("status") String status,
|
||||||
@Param("onlyIfStatus") String onlyIfStatus);
|
@Param("onlyIfStatus") String onlyIfStatus);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 磨削后同步:当前直径更新 + 磨削次数+1
|
||||||
|
* diaAfter 为 null 时仅 grindCount+1 不更新直径
|
||||||
|
*/
|
||||||
|
int incrementGrindCount(@Param("rollId") Long rollId,
|
||||||
|
@Param("diaAfter") java.math.BigDecimal diaAfter);
|
||||||
|
|
||||||
|
/** 直接更新当前直径(用于修改磨削记录后重新同步) */
|
||||||
|
int updateCurrentDia(@Param("rollId") Long rollId,
|
||||||
|
@Param("currentDia") java.math.BigDecimal currentDia);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.klp.mes.roll.service;
|
||||||
|
|
||||||
|
import com.klp.mes.roll.domain.bo.MesRollGrindBo;
|
||||||
|
import com.klp.mes.roll.domain.vo.MesRollGrindVo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 磨辊记录 Service 接口
|
||||||
|
*/
|
||||||
|
public interface IMesRollGrindService {
|
||||||
|
|
||||||
|
/** 查询某轧辊全部磨削记录 */
|
||||||
|
List<MesRollGrindVo> listByRoll(Long rollId);
|
||||||
|
|
||||||
|
/** 新增磨削记录,同步更新轧辊当前直径和磨削次数 */
|
||||||
|
Long addGrind(MesRollGrindBo bo);
|
||||||
|
|
||||||
|
/** 修改磨削记录 */
|
||||||
|
Boolean updateGrind(MesRollGrindBo bo);
|
||||||
|
|
||||||
|
/** 删除磨削记录 */
|
||||||
|
Boolean deleteGrind(Long grindId);
|
||||||
|
|
||||||
|
/** 按年份统计每月磨削数据 */
|
||||||
|
List<Map<String, Object>> monthlyStats(Long rollId, int year);
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
package com.klp.mes.roll.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import com.klp.common.utils.StringUtils;
|
||||||
|
import com.klp.mes.roll.domain.MesRollGrind;
|
||||||
|
import com.klp.mes.roll.domain.MesRollInfo;
|
||||||
|
import com.klp.mes.roll.domain.bo.MesRollGrindBo;
|
||||||
|
import com.klp.mes.roll.domain.vo.MesRollGrindVo;
|
||||||
|
import com.klp.mes.roll.domain.vo.MesRollInfoVo;
|
||||||
|
import com.klp.mes.roll.mapper.MesRollGrindMapper;
|
||||||
|
import com.klp.mes.roll.mapper.MesRollInfoMapper;
|
||||||
|
import com.klp.mes.roll.service.IMesRollGrindService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 磨辊记录 Service 实现
|
||||||
|
*/
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Service
|
||||||
|
public class MesRollGrindServiceImpl implements IMesRollGrindService {
|
||||||
|
|
||||||
|
private final MesRollGrindMapper baseMapper;
|
||||||
|
private final MesRollInfoMapper rollInfoMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<MesRollGrindVo> listByRoll(Long rollId) {
|
||||||
|
return baseMapper.selectByRollId(rollId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Long addGrind(MesRollGrindBo bo) {
|
||||||
|
MesRollGrind add = BeanUtil.toBean(bo, MesRollGrind.class);
|
||||||
|
|
||||||
|
// 默认磨削时间为当前时间
|
||||||
|
if (add.getGrindTime() == null) {
|
||||||
|
add.setGrindTime(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自动计算磨削量
|
||||||
|
if (add.getDiaBefore() != null && add.getDiaAfter() != null) {
|
||||||
|
add.setGrindAmount(add.getDiaBefore().subtract(add.getDiaAfter()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同步轧辊编号
|
||||||
|
if (StringUtils.isBlank(add.getRollNo())) {
|
||||||
|
MesRollInfoVo info = rollInfoMapper.selectVoById(add.getRollId());
|
||||||
|
if (info != null) {
|
||||||
|
add.setRollNo(info.getRollNo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
baseMapper.insert(add);
|
||||||
|
|
||||||
|
// 同步更新 mes_roll_info:当前直径 + 磨削次数 +1
|
||||||
|
MesRollInfo update = new MesRollInfo();
|
||||||
|
update.setRollId(add.getRollId());
|
||||||
|
if (add.getDiaAfter() != null) {
|
||||||
|
update.setCurrentDia(add.getDiaAfter());
|
||||||
|
}
|
||||||
|
// grindCount = 当前次数 + 1(先查后加,避免并发问题用 SQL UPDATE)
|
||||||
|
rollInfoMapper.incrementGrindCount(add.getRollId(), add.getDiaAfter());
|
||||||
|
|
||||||
|
return add.getGrindId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Boolean updateGrind(MesRollGrindBo bo) {
|
||||||
|
MesRollGrind update = BeanUtil.toBean(bo, MesRollGrind.class);
|
||||||
|
if (update.getDiaBefore() != null && update.getDiaAfter() != null) {
|
||||||
|
update.setGrindAmount(update.getDiaBefore().subtract(update.getDiaAfter()));
|
||||||
|
}
|
||||||
|
boolean ok = baseMapper.updateById(update) > 0;
|
||||||
|
if (ok && update.getDiaAfter() != null) {
|
||||||
|
// 以最新一条磨削记录的磨后直径为准更新当前直径
|
||||||
|
MesRollGrindVo latest = baseMapper.selectByRollId(update.getRollId())
|
||||||
|
.stream().reduce((a, b) -> b).orElse(null);
|
||||||
|
if (latest != null && latest.getDiaAfter() != null) {
|
||||||
|
rollInfoMapper.updateCurrentDia(update.getRollId(), latest.getDiaAfter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean deleteGrind(Long grindId) {
|
||||||
|
return baseMapper.deleteById(grindId) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Map<String, Object>> monthlyStats(Long rollId, int year) {
|
||||||
|
return baseMapper.selectMonthlyStats(rollId, year);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!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.MesRollGrindMapper">
|
||||||
|
|
||||||
|
<select id="selectByRollId" resultType="com.klp.mes.roll.domain.vo.MesRollGrindVo">
|
||||||
|
SELECT grind_id, roll_id, roll_no, grind_time, team,
|
||||||
|
dia_before, dia_after, grind_amount, roll_shape,
|
||||||
|
flaw_result, hardness, operator, remark, create_time
|
||||||
|
FROM mes_roll_grind
|
||||||
|
WHERE del_flag = 0 AND roll_id = #{rollId}
|
||||||
|
ORDER BY grind_time ASC, grind_id ASC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectMonthlyStats" resultType="map">
|
||||||
|
SELECT
|
||||||
|
DATE_FORMAT(grind_time, '%Y-%m') AS month,
|
||||||
|
COUNT(*) AS grindCount,
|
||||||
|
IFNULL(SUM(grind_amount), 0) AS totalGrindAmount
|
||||||
|
FROM mes_roll_grind
|
||||||
|
WHERE del_flag = 0
|
||||||
|
AND roll_id = #{rollId}
|
||||||
|
AND YEAR(grind_time) = #{year}
|
||||||
|
GROUP BY DATE_FORMAT(grind_time, '%Y-%m')
|
||||||
|
ORDER BY month ASC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -42,4 +42,18 @@
|
|||||||
WHERE del_flag = 0 AND roll_no = #{rollNo} AND status = #{onlyIfStatus}
|
WHERE del_flag = 0 AND roll_no = #{rollNo} AND status = #{onlyIfStatus}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
|
<update id="incrementGrindCount">
|
||||||
|
UPDATE mes_roll_info
|
||||||
|
SET grind_count = grind_count + 1,
|
||||||
|
<if test="diaAfter != null">current_dia = #{diaAfter},</if>
|
||||||
|
update_time = NOW()
|
||||||
|
WHERE del_flag = 0 AND roll_id = #{rollId}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="updateCurrentDia">
|
||||||
|
UPDATE mes_roll_info
|
||||||
|
SET current_dia = #{currentDia}, update_time = NOW()
|
||||||
|
WHERE del_flag = 0 AND roll_id = #{rollId}
|
||||||
|
</update>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@@ -48,3 +48,38 @@ export function getTimingRealtimeData(matId) {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 轧辊数据,type/status 可选过滤
|
||||||
|
export function getRollData(type, status) {
|
||||||
|
return request({
|
||||||
|
url: '/sql-server-api/rolls',
|
||||||
|
method: 'get',
|
||||||
|
params: { type, status }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换辊历史(按轧辊号,配辊页用)
|
||||||
|
export function getRollHistory(rollId) {
|
||||||
|
return request({
|
||||||
|
url: '/sql-server-api/rolls/' + rollId + '/history',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换辊历史列表(分页 + 过滤,历史页用)
|
||||||
|
export function getRollHistoryList(page = 1, pageSize = 50, rollId, standId) {
|
||||||
|
return request({
|
||||||
|
url: '/sql-server-api/rolls/history',
|
||||||
|
method: 'get',
|
||||||
|
params: { page, pageSize, rollId, standId }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换辊历史总条数
|
||||||
|
export function getRollHistoryCount(rollId, standId) {
|
||||||
|
return request({
|
||||||
|
url: '/sql-server-api/rolls/history/count',
|
||||||
|
method: 'get',
|
||||||
|
params: { rollId, standId }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
26
klp-ui/src/api/mes/roll/rollGrind.js
Normal file
26
klp-ui/src/api/mes/roll/rollGrind.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 查询轧辊磨削记录列表
|
||||||
|
export function listRollGrind(rollId) {
|
||||||
|
return request({ url: '/mes/rollGrind/list', method: 'get', params: { rollId } })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询月度汇总
|
||||||
|
export function getMonthlyStats(rollId, year) {
|
||||||
|
return request({ url: '/mes/rollGrind/monthlyStats', method: 'get', params: { rollId, year } })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增磨削记录
|
||||||
|
export function addRollGrind(data) {
|
||||||
|
return request({ url: '/mes/rollGrind', method: 'post', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改磨削记录
|
||||||
|
export function updateRollGrind(data) {
|
||||||
|
return request({ url: '/mes/rollGrind', method: 'put', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除磨削记录
|
||||||
|
export function delRollGrind(grindId) {
|
||||||
|
return request({ url: '/mes/rollGrind/' + grindId, method: 'delete' })
|
||||||
|
}
|
||||||
490
klp-ui/src/views/mes/roll/grind/index.vue
Normal file
490
klp-ui/src/views/mes/roll/grind/index.vue
Normal file
@@ -0,0 +1,490 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container grind-page">
|
||||||
|
<div class="grind-layout">
|
||||||
|
|
||||||
|
<!-- ── 左侧:轧辊选择 ── -->
|
||||||
|
<div class="grind-left">
|
||||||
|
<el-card shadow="never" class="grind-card h-full">
|
||||||
|
<div slot="header" class="card-header">
|
||||||
|
<span class="card-title"><i class="el-icon-s-order" /> 轧辊列表</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 搜索过滤 -->
|
||||||
|
<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">
|
||||||
|
<el-radio-button label="">全部</el-radio-button>
|
||||||
|
<el-radio-button label="WR">WR</el-radio-button>
|
||||||
|
<el-radio-button label="BR">BR</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-loading="rollLoading" class="roll-list">
|
||||||
|
<div
|
||||||
|
v-for="r in filteredRolls"
|
||||||
|
:key="r.rollId"
|
||||||
|
:class="['roll-item', selectedRollId === r.rollId ? 'roll-item--active' : '']"
|
||||||
|
@click="selectRoll(r)"
|
||||||
|
>
|
||||||
|
<div class="ri-no">{{ r.rollNo }}</div>
|
||||||
|
<div class="ri-meta">
|
||||||
|
<el-tag size="mini" :type="r.rollType === 'WR' ? 'primary' : 'warning'">{{ r.rollType }}</el-tag>
|
||||||
|
<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>
|
||||||
|
<div v-if="!rollLoading && filteredRolls.length === 0" class="roll-empty">暂无数据</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ── 右侧:台账 ── -->
|
||||||
|
<div class="grind-right">
|
||||||
|
<template v-if="!selectedRoll">
|
||||||
|
<div class="grind-empty"><i class="el-icon-arrow-left" /> 请从左侧选择一个轧辊</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
<!-- 轧辊基本信息头 -->
|
||||||
|
<el-card shadow="never" class="grind-card" style="margin-bottom:12px">
|
||||||
|
<div class="roll-header-grid">
|
||||||
|
<div class="rh-item"><span class="rh-k">轧辊编号</span><span class="rh-v bold">{{ selectedRoll.rollNo }}</span></div>
|
||||||
|
<div class="rh-item"><span class="rh-k">辊型</span><span class="rh-v">{{ selectedRoll.rollType === 'WR' ? '工作辊' : '支撑辊' }}</span></div>
|
||||||
|
<div class="rh-item"><span class="rh-k">材质</span><span class="rh-v">{{ selectedRoll.material || '—' }}</span></div>
|
||||||
|
<div class="rh-item"><span class="rh-k">初始辊径</span><span class="rh-v">{{ selectedRoll.initialDia != null ? selectedRoll.initialDia + ' mm' : '—' }}</span></div>
|
||||||
|
<div class="rh-item"><span class="rh-k">当前辊径</span><span class="rh-v bold accent">{{ selectedRoll.currentDia != null ? selectedRoll.currentDia + ' mm' : '—' }}</span></div>
|
||||||
|
<div class="rh-item"><span class="rh-k">最小辊径</span><span class="rh-v">{{ selectedRoll.minDia != null ? selectedRoll.minDia + ' mm' : '—' }}</span></div>
|
||||||
|
<div class="rh-item"><span class="rh-k">磨削次数</span><span class="rh-v">{{ selectedRoll.grindCount != null ? selectedRoll.grindCount + ' 次' : '0 次' }}</span></div>
|
||||||
|
<div class="rh-item"><span class="rh-k">粗糙度</span><span class="rh-v">{{ selectedRoll.roughness != null ? selectedRoll.roughness + ' μm' : '—' }}</span></div>
|
||||||
|
<div class="rh-item"><span class="rh-k">凸度</span><span class="rh-v">{{ selectedRoll.crown != null ? selectedRoll.crown + ' mm' : '—' }}</span></div>
|
||||||
|
<div class="rh-item"><span class="rh-k">状态</span>
|
||||||
|
<span :class="['rh-v', 'st-' + selectedRoll.status]">{{ statusLabel(selectedRoll.status) }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="rh-item"><span class="rh-k">制造日期</span><span class="rh-v">{{ selectedRoll.manufactureDate || '—' }}</span></div>
|
||||||
|
<div class="rh-item"><span class="rh-k">备注</span><span class="rh-v">{{ selectedRoll.remark || '—' }}</span></div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 磨削台账:行内编辑 -->
|
||||||
|
<el-card shadow="never" class="grind-card">
|
||||||
|
<div slot="header" class="card-header">
|
||||||
|
<span class="card-title"><i class="el-icon-document" /> 磨削台账</span>
|
||||||
|
<el-button type="primary" size="mini" icon="el-icon-plus"
|
||||||
|
style="margin-left:auto" :disabled="!!editRow" @click="startAdd">新增磨削记录</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table v-loading="grindLoading" :data="tableData" size="small" border
|
||||||
|
style="width:100%" :row-class-name="rowClassName">
|
||||||
|
<el-table-column label="序号" type="index" width="46" align="center" />
|
||||||
|
|
||||||
|
<!-- 磨削时间 -->
|
||||||
|
<el-table-column label="磨削时间" align="center" width="200">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-date-picker v-if="isEditing(row)" v-model="editRow.grindTime"
|
||||||
|
type="datetime" size="mini" value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
style="width:182px" placeholder="请选择" />
|
||||||
|
<span v-else>{{ row.grindTime }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 班组 -->
|
||||||
|
<el-table-column label="班组" align="center" width="80">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-input v-if="isEditing(row)" v-model="editRow.team"
|
||||||
|
size="mini" placeholder="甲班" style="width:64px" />
|
||||||
|
<span v-else>{{ row.team || '—' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 磨前直径 -->
|
||||||
|
<el-table-column label="磨前径(mm)" align="center" width="100">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-input v-if="isEditing(row)" v-model.number="editRow.diaBefore"
|
||||||
|
type="number" size="mini" style="width:80px" />
|
||||||
|
<span v-else>{{ row.diaBefore }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 磨后直径 -->
|
||||||
|
<el-table-column label="磨后径(mm)" align="center" width="100">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-input v-if="isEditing(row)" v-model.number="editRow.diaAfter"
|
||||||
|
type="number" size="mini" style="width:80px" />
|
||||||
|
<span v-else>{{ row.diaAfter }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 磨削量(只读计算) -->
|
||||||
|
<el-table-column label="磨削量(mm)" align="center" width="88">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<span v-if="isEditing(row)" class="computed-val">
|
||||||
|
{{ grindAmountOf(editRow) }}
|
||||||
|
</span>
|
||||||
|
<span v-else>{{ row.grindAmount }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 辊型 -->
|
||||||
|
<el-table-column label="辊型" align="center" width="100">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-select v-if="isEditing(row)" v-model="editRow.rollShape"
|
||||||
|
size="mini" style="width:84px">
|
||||||
|
<el-option label="平" value="平" />
|
||||||
|
<el-option label="凸" value="凸" />
|
||||||
|
<el-option label="凹" value="凹" />
|
||||||
|
</el-select>
|
||||||
|
<span v-else>{{ row.rollShape || '—' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 探伤结果 -->
|
||||||
|
<el-table-column label="探伤结果" align="center" width="110">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-select v-if="isEditing(row)" v-model="editRow.flawResult"
|
||||||
|
size="mini" style="width:94px">
|
||||||
|
<el-option label="合格" value="合格" />
|
||||||
|
<el-option label="不合格" value="不合格" />
|
||||||
|
</el-select>
|
||||||
|
<el-tag v-else size="mini" :type="row.flawResult === '合格' ? 'success' : 'danger'">
|
||||||
|
{{ row.flawResult || '—' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 硬度 -->
|
||||||
|
<el-table-column label="硬度" align="center" width="80">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-input v-if="isEditing(row)" v-model.number="editRow.hardness"
|
||||||
|
type="number" size="mini" style="width:64px" />
|
||||||
|
<span v-else>{{ row.hardness || '—' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 操作者(自动填入,仅展示) -->
|
||||||
|
<el-table-column label="操作者" align="center" width="72">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<span :class="isEditing(row) ? 'auto-operator' : ''">
|
||||||
|
{{ isEditing(row) ? currentUserName : (row.operator || '—') }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 备注 -->
|
||||||
|
<el-table-column label="备注" align="left" width="120">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-input v-if="isEditing(row)" v-model="editRow.remark"
|
||||||
|
size="mini" placeholder="选填" />
|
||||||
|
<span v-else class="remark-text">{{ row.remark || '' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 操作列 -->
|
||||||
|
<el-table-column label="操作" align="center" width="100" fixed="right">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<template v-if="isEditing(row)">
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-check"
|
||||||
|
:loading="grindSaving" @click="saveRow">保存</el-button>
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-close"
|
||||||
|
style="color:#909399" @click="cancelEdit">取消</el-button>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-edit"
|
||||||
|
:disabled="!!editRow" @click="startEdit(row)">修改</el-button>
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-delete"
|
||||||
|
style="color:#c5221f" :disabled="!!editRow" @click="handleDelete(row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 月度汇总 -->
|
||||||
|
<div class="monthly-wrap" v-if="grindList.length > 0">
|
||||||
|
<div class="monthly-title">
|
||||||
|
<span>{{ currentYear }} 年月度汇总</span>
|
||||||
|
<el-button-group size="mini" style="margin-left:8px">
|
||||||
|
<el-button icon="el-icon-arrow-left" @click="changeYear(-1)" />
|
||||||
|
<el-button icon="el-icon-arrow-right" @click="changeYear(1)" />
|
||||||
|
</el-button-group>
|
||||||
|
</div>
|
||||||
|
<el-table :data="monthlyList" size="mini" border style="width:100%;margin-top:8px">
|
||||||
|
<el-table-column label="月份" prop="month" align="center" width="90" />
|
||||||
|
<el-table-column label="磨削次数" prop="grindCount" align="center" width="90" />
|
||||||
|
<el-table-column label="累计磨削量(mm)" prop="totalGrindAmount" align="center" min-width="120" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { listRollInfo, getRollInfo } from '@/api/mes/roll/rollInfo'
|
||||||
|
import { listRollGrind, addRollGrind, updateRollGrind, delRollGrind, getMonthlyStats } from '@/api/mes/roll/rollGrind'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'GrindRoom',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 产线定义(暂写死,后续接后端)
|
||||||
|
LINES: [{ label: '双机架产线', value: '双机架' }],
|
||||||
|
|
||||||
|
// 左侧辊列表
|
||||||
|
rollLoading: false,
|
||||||
|
allRolls: [],
|
||||||
|
filteredRolls: [],
|
||||||
|
filterNo: '',
|
||||||
|
filterType: '',
|
||||||
|
filterLine: '',
|
||||||
|
|
||||||
|
// 右侧选中辊
|
||||||
|
selectedRollId: null,
|
||||||
|
selectedRoll: null,
|
||||||
|
|
||||||
|
// 磨削记录
|
||||||
|
grindLoading: false,
|
||||||
|
grindList: [],
|
||||||
|
|
||||||
|
// 月度汇总
|
||||||
|
currentYear: new Date().getFullYear(),
|
||||||
|
monthlyList: [],
|
||||||
|
|
||||||
|
// 行内编辑:editRow 不为 null 时表示当前正在编辑/新增的行数据
|
||||||
|
// __isNew: true → 新增行;存在 grindId → 修改行
|
||||||
|
editRow: null,
|
||||||
|
grindSaving: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
// 当前登录用户名(RuoYi Plus 的 store 路径)
|
||||||
|
currentUserName() {
|
||||||
|
return this.$store.state.user.name || this.$store.getters.name || ''
|
||||||
|
},
|
||||||
|
|
||||||
|
// 表格数据:新增时在顶部插入一个编辑行占位
|
||||||
|
tableData() {
|
||||||
|
if (this.editRow && this.editRow.__isNew) {
|
||||||
|
return [this.editRow, ...this.grindList]
|
||||||
|
}
|
||||||
|
return this.grindList
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.loadRolls()
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
// ── 轧辊列表 ──────────────────────────────────────
|
||||||
|
loadRolls() {
|
||||||
|
this.rollLoading = true
|
||||||
|
listRollInfo({ pageNum: 1, pageSize: 500 }).then(res => {
|
||||||
|
this.allRolls = res.rows || []
|
||||||
|
this.filterRolls()
|
||||||
|
}).finally(() => { this.rollLoading = false })
|
||||||
|
},
|
||||||
|
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
|
||||||
|
})
|
||||||
|
},
|
||||||
|
selectRoll(r) {
|
||||||
|
if (this.editRow) this.cancelEdit()
|
||||||
|
this.selectedRollId = r.rollId
|
||||||
|
getRollInfo(r.rollId).then(res => {
|
||||||
|
this.selectedRoll = res.data || r
|
||||||
|
const idx = this.allRolls.findIndex(x => x.rollId === r.rollId)
|
||||||
|
if (idx !== -1) this.$set(this.allRolls, idx, { ...this.allRolls[idx], ...res.data })
|
||||||
|
}).catch(() => { this.selectedRoll = r })
|
||||||
|
this.loadGrindList(r.rollId)
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── 磨削记录 ──────────────────────────────────────
|
||||||
|
loadGrindList(rollId) {
|
||||||
|
this.grindLoading = true
|
||||||
|
listRollGrind(rollId).then(res => {
|
||||||
|
this.grindList = res.data || []
|
||||||
|
}).finally(() => {
|
||||||
|
this.grindLoading = false
|
||||||
|
this.loadMonthlyStats()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
loadMonthlyStats() {
|
||||||
|
if (!this.selectedRollId) return
|
||||||
|
getMonthlyStats(this.selectedRollId, this.currentYear).then(res => {
|
||||||
|
this.monthlyList = (res.data || []).map(r => ({
|
||||||
|
month: r.month, grindCount: r.grindCount, totalGrindAmount: r.totalGrindAmount
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
},
|
||||||
|
changeYear(delta) {
|
||||||
|
this.currentYear += delta
|
||||||
|
this.loadMonthlyStats()
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── 行内编辑 ──────────────────────────────────────
|
||||||
|
isEditing(row) {
|
||||||
|
if (!this.editRow) return false
|
||||||
|
if (row.__isNew && this.editRow.__isNew) return true
|
||||||
|
return !!row.grindId && row.grindId === this.editRow.grindId
|
||||||
|
},
|
||||||
|
rowClassName({ row }) {
|
||||||
|
return this.isEditing(row) ? 'editing-row' : ''
|
||||||
|
},
|
||||||
|
|
||||||
|
startAdd() {
|
||||||
|
const now = new Date()
|
||||||
|
const pad = n => String(n).padStart(2, '0')
|
||||||
|
const grindTime = `${now.getFullYear()}-${pad(now.getMonth()+1)}-${pad(now.getDate())} ` +
|
||||||
|
`${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`
|
||||||
|
this.editRow = {
|
||||||
|
__isNew: true,
|
||||||
|
rollId: this.selectedRollId,
|
||||||
|
grindTime,
|
||||||
|
team: undefined,
|
||||||
|
diaBefore: this.selectedRoll && this.selectedRoll.currentDia != null
|
||||||
|
? parseFloat(this.selectedRoll.currentDia) : undefined,
|
||||||
|
diaAfter: undefined,
|
||||||
|
rollShape: '平',
|
||||||
|
flawResult: '合格',
|
||||||
|
hardness: undefined,
|
||||||
|
operator: this.currentUserName,
|
||||||
|
remark: undefined
|
||||||
|
}
|
||||||
|
},
|
||||||
|
startEdit(row) {
|
||||||
|
this.editRow = { ...row, operator: row.operator || this.currentUserName }
|
||||||
|
},
|
||||||
|
cancelEdit() {
|
||||||
|
this.editRow = null
|
||||||
|
},
|
||||||
|
|
||||||
|
saveRow() {
|
||||||
|
const r = this.editRow
|
||||||
|
if (!r.grindTime) { this.$modal.msgWarning('请填写磨削时间'); return }
|
||||||
|
if (r.diaBefore == null) { this.$modal.msgWarning('请填写磨前直径'); return }
|
||||||
|
if (r.diaAfter == null) { this.$modal.msgWarning('请填写磨后直径'); return }
|
||||||
|
|
||||||
|
// 自动带入操作人
|
||||||
|
r.operator = this.currentUserName
|
||||||
|
|
||||||
|
this.grindSaving = true
|
||||||
|
const isNew = !!r.__isNew
|
||||||
|
const payload = { ...r }
|
||||||
|
delete payload.__isNew
|
||||||
|
|
||||||
|
const api = isNew ? addRollGrind : updateRollGrind
|
||||||
|
api(payload).then(() => {
|
||||||
|
this.$modal.msgSuccess(isNew ? '新增成功' : '修改成功')
|
||||||
|
this.editRow = null
|
||||||
|
this.loadGrindList(this.selectedRollId)
|
||||||
|
getRollInfo(this.selectedRollId).then(res => {
|
||||||
|
this.selectedRoll = res.data
|
||||||
|
const idx = this.allRolls.findIndex(x => x.rollId === this.selectedRollId)
|
||||||
|
if (idx !== -1) this.$set(this.allRolls, idx, { ...this.allRolls[idx], ...res.data })
|
||||||
|
})
|
||||||
|
}).finally(() => { this.grindSaving = false })
|
||||||
|
},
|
||||||
|
|
||||||
|
handleDelete(row) {
|
||||||
|
this.$modal.confirm('确认删除该磨削记录?').then(() => {
|
||||||
|
return delRollGrind(row.grindId)
|
||||||
|
}).then(() => {
|
||||||
|
this.$modal.msgSuccess('已删除')
|
||||||
|
this.loadGrindList(this.selectedRollId)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// ── 计算磨削量 ──────────────────────────────────────
|
||||||
|
grindAmountOf(row) {
|
||||||
|
const b = parseFloat(row.diaBefore)
|
||||||
|
const a = parseFloat(row.diaAfter)
|
||||||
|
if (!isNaN(b) && !isNaN(a)) return (b - a).toFixed(2)
|
||||||
|
return '—'
|
||||||
|
},
|
||||||
|
|
||||||
|
// 辅助
|
||||||
|
statusLabel(s) {
|
||||||
|
return { Online: '在线', Standby: '备用', Offline: '离线', Scrapped: '报废' }[s] || s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.grind-page { background: #f4f5f7; height: 100%; }
|
||||||
|
.grind-layout { display: flex; gap: 12px; height: 100%; align-items: flex-start; }
|
||||||
|
|
||||||
|
/* 左侧 */
|
||||||
|
.grind-left { width: 240px; flex-shrink: 0; }
|
||||||
|
.grind-right { flex: 1; min-width: 0; }
|
||||||
|
|
||||||
|
.grind-card { border: 1px solid #dcdee0; border-radius: 4px; }
|
||||||
|
.h-full { height: calc(100vh - 120px); display: flex; flex-direction: column; }
|
||||||
|
|
||||||
|
.card-header { display: flex; align-items: center; gap: 8px; }
|
||||||
|
.card-title { font-size: 13px; font-weight: 600; color: #3d4b5c; }
|
||||||
|
|
||||||
|
/* 辊列表 */
|
||||||
|
.roll-filter { padding: 0 0 4px; }
|
||||||
|
.roll-list { overflow-y: auto; flex: 1; margin: 0 -12px; }
|
||||||
|
.roll-item { padding: 8px 12px; cursor: pointer; border-bottom: 1px solid #f0f2f5; }
|
||||||
|
.roll-item:hover { background: #f5f7fa; }
|
||||||
|
.roll-item--active { background: #e8f4ff !important; border-left: 3px solid #409eff; }
|
||||||
|
.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-status { font-size: 11px; }
|
||||||
|
.roll-empty { text-align: center; color: #c0c4cc; padding: 20px 0; font-size: 12px; }
|
||||||
|
|
||||||
|
/* 状态色 */
|
||||||
|
.st-Online { color: #0a7c42; }
|
||||||
|
.st-Standby { color: #d4860a; }
|
||||||
|
.st-Offline { color: #9aa0a6; }
|
||||||
|
.st-Scrapped { color: #c5221f; }
|
||||||
|
|
||||||
|
/* 空状态 */
|
||||||
|
.grind-empty { display: flex; align-items: center; justify-content: center;
|
||||||
|
height: 300px; color: #c0c4cc; font-size: 14px; gap: 6px; }
|
||||||
|
|
||||||
|
/* 辊头信息格 */
|
||||||
|
.roll-header-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px 16px; }
|
||||||
|
.rh-item { display: flex; flex-direction: column; gap: 2px; }
|
||||||
|
.rh-k { font-size: 11px; color: #9aa0a6; }
|
||||||
|
.rh-v { font-size: 13px; color: #3d4b5c; }
|
||||||
|
.rh-v.bold { font-weight: 600; }
|
||||||
|
.rh-v.accent { color: #0a7c42; }
|
||||||
|
|
||||||
|
/* 月度汇总 */
|
||||||
|
.monthly-wrap { margin-top: 16px; border-top: 1px solid #f0f2f5; padding-top: 12px; }
|
||||||
|
.monthly-title { font-size: 12px; color: #5f6368; display: flex; align-items: center; }
|
||||||
|
|
||||||
|
/* 行内编辑 */
|
||||||
|
.computed-val { color: #409eff; font-weight: 600; font-size: 13px; }
|
||||||
|
.auto-operator { color: #0a7c42; font-size: 12px; }
|
||||||
|
.remark-text { font-size: 12px; color: #5f6368; }
|
||||||
|
|
||||||
|
/* 去掉 number input 的默认上下箭头,保持表格整洁 */
|
||||||
|
.el-table :deep(input[type=number]::-webkit-inner-spin-button),
|
||||||
|
.el-table :deep(input[type=number]::-webkit-outer-spin-button) { -webkit-appearance: none; }
|
||||||
|
.el-table :deep(input[type=number]) { -moz-appearance: textfield; }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- 编辑行高亮(非 scoped,作用于 el-table 的 row-class-name) -->
|
||||||
|
<style>
|
||||||
|
.el-table .editing-row { background: #fffbf0 !important; }
|
||||||
|
.el-table .editing-row:hover > td { background: #fffbf0 !important; }
|
||||||
|
</style>
|
||||||
@@ -46,6 +46,12 @@
|
|||||||
|
|
||||||
<!-- 搜索栏 -->
|
<!-- 搜索栏 -->
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
<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-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>
|
||||||
@@ -236,6 +242,7 @@ export default {
|
|||||||
queryParams: {
|
queryParams: {
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 20,
|
pageSize: 20,
|
||||||
|
lineCode: undefined, // 产线筛选(暂写死双机架,后续接字段)
|
||||||
rollNo: undefined,
|
rollNo: undefined,
|
||||||
rollType: undefined,
|
rollType: undefined,
|
||||||
status: undefined
|
status: undefined
|
||||||
@@ -269,6 +276,7 @@ export default {
|
|||||||
this.getList()
|
this.getList()
|
||||||
},
|
},
|
||||||
resetQuery() {
|
resetQuery() {
|
||||||
|
this.queryParams.lineCode = undefined
|
||||||
this.resetForm('queryForm')
|
this.resetForm('queryForm')
|
||||||
this.handleQuery()
|
this.handleQuery()
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -30,6 +30,14 @@
|
|||||||
<i class="el-icon-coin"></i>
|
<i class="el-icon-coin"></i>
|
||||||
<span slot="title">实绩</span>
|
<span slot="title">实绩</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
<el-menu-item index="rollConfig">
|
||||||
|
<i class="el-icon-s-tools"></i>
|
||||||
|
<span slot="title">配辊</span>
|
||||||
|
</el-menu-item>
|
||||||
|
<el-menu-item index="rollHistory">
|
||||||
|
<i class="el-icon-time"></i>
|
||||||
|
<span slot="title">换辊历史</span>
|
||||||
|
</el-menu-item>
|
||||||
<!-- <el-menu-item index="realTime">
|
<!-- <el-menu-item index="realTime">
|
||||||
<i class="el-icon-time"></i>
|
<i class="el-icon-time"></i>
|
||||||
<span slot="title">实时</span>
|
<span slot="title">实时</span>
|
||||||
@@ -50,6 +58,8 @@ import Shipping from './components/Shipping.vue';
|
|||||||
import Quality from './components/Quality.vue';
|
import Quality from './components/Quality.vue';
|
||||||
import Performance from './components/Performance.vue';
|
import Performance from './components/Performance.vue';
|
||||||
import RealTime from './components/RealTime.vue';
|
import RealTime from './components/RealTime.vue';
|
||||||
|
import RollConfig from '@/views/timing/roll/index.vue';
|
||||||
|
import RollHistory from '@/views/timing/roll/history.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AcidSystem',
|
name: 'AcidSystem',
|
||||||
@@ -60,7 +70,9 @@ export default {
|
|||||||
Shipping,
|
Shipping,
|
||||||
Quality,
|
Quality,
|
||||||
Performance,
|
Performance,
|
||||||
RealTime
|
RealTime,
|
||||||
|
RollConfig,
|
||||||
|
RollHistory
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -77,6 +89,8 @@ export default {
|
|||||||
quality: 'Quality',
|
quality: 'Quality',
|
||||||
performance: 'Performance',
|
performance: 'Performance',
|
||||||
realTime: 'RealTime',
|
realTime: 'RealTime',
|
||||||
|
rollConfig: 'RollConfig',
|
||||||
|
rollHistory: 'RollHistory',
|
||||||
};
|
};
|
||||||
return componentMap[this.activeMenu];
|
return componentMap[this.activeMenu];
|
||||||
},
|
},
|
||||||
|
|||||||
222
klp-ui/src/views/timing/roll/history.vue
Normal file
222
klp-ui/src/views/timing/roll/history.vue
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
<template>
|
||||||
|
<div class="roll-history-view">
|
||||||
|
<el-form :inline="true" :model="query" size="small" class="filter-bar">
|
||||||
|
<el-form-item label="轧辊号">
|
||||||
|
<el-input v-model="query.rollId" placeholder="输入轧辊号" clearable style="width: 180px" @keyup.enter.native="handleSearch" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="机架">
|
||||||
|
<el-select v-model="query.standId" placeholder="全部" clearable style="width: 110px">
|
||||||
|
<el-option v-for="s in standOptions" :key="s.value" :label="s.label" :value="s.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="换辊类型">
|
||||||
|
<el-select v-model="query.changeType" placeholder="全部" clearable style="width: 120px">
|
||||||
|
<el-option label="换辊" value="CHANGE" />
|
||||||
|
<el-option label="磨辊" value="GRIND" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" :loading="loading" @click="handleSearch">查询</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" @click="handleReset">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
:data="filteredRows"
|
||||||
|
size="mini"
|
||||||
|
border
|
||||||
|
stripe
|
||||||
|
:height="tableHeight"
|
||||||
|
v-loading="loading"
|
||||||
|
highlight-current-row
|
||||||
|
>
|
||||||
|
<el-table-column type="index" width="50" label="序" fixed />
|
||||||
|
<el-table-column prop="rollid" label="轧辊号" width="120" fixed show-overflow-tooltip />
|
||||||
|
<el-table-column label="机架" width="64">
|
||||||
|
<template slot-scope="{ row }">{{ standName(row.standid) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="位置" width="52">
|
||||||
|
<template slot-scope="{ row }">{{ dispPos(row.position) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="类型" width="72">
|
||||||
|
<template slot-scope="{ row }">{{ dispType(row.type) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="change_type" label="换辊类型" width="82">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-tag :type="changeTypeTag(row.change_type)" size="mini">{{ row.change_type || '—' }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="diameter" label="直径(mm)" width="90" :formatter="fmtNum" />
|
||||||
|
<el-table-column prop="crown" label="凸度" width="72" :formatter="fmtNum" />
|
||||||
|
<el-table-column prop="rough" label="粗糙度" width="72" :formatter="fmtNum" />
|
||||||
|
<el-table-column prop="rolled_length" label="本次长度" width="90" :formatter="fmtInt" />
|
||||||
|
<el-table-column prop="rolled_weight" label="本次重量" width="90" :formatter="fmtInt" />
|
||||||
|
<el-table-column prop="total_rolled_length" label="累计长度" width="90" :formatter="fmtInt" />
|
||||||
|
<el-table-column prop="total_rolled_weight" label="累计重量" width="90" :formatter="fmtInt" />
|
||||||
|
<el-table-column prop="grind_count" label="磨削次数" width="80" />
|
||||||
|
<el-table-column label="安装时间" width="148">
|
||||||
|
<template slot-scope="{ row }">{{ fmtDate(row.instal_time) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="卸辊时间" width="148">
|
||||||
|
<template slot-scope="{ row }">{{ fmtDate(row.deinstal_time) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="换辊时间" width="148">
|
||||||
|
<template slot-scope="{ row }">{{ fmtDate(row.change_time) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="shift" label="班次" width="52" />
|
||||||
|
<el-table-column prop="crew" label="班组" width="52" />
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<div class="pagination-bar">
|
||||||
|
<el-pagination
|
||||||
|
small
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="pagination.total"
|
||||||
|
:page-size="pagination.pageSize"
|
||||||
|
:page-sizes="[50, 100, 200]"
|
||||||
|
:current-page="pagination.page"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handlePageChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getRollHistoryList, getRollHistoryCount } from '@/api/l2/timing'
|
||||||
|
|
||||||
|
const STAND_NAMES = ['一机架', '二机架', '三机架', '四机架', '五机架', '六机架']
|
||||||
|
|
||||||
|
const POS_NORM = {
|
||||||
|
TOP: '上', UPPER: '上', UP: '上', '上': '上',
|
||||||
|
BOTTOM: '下', LOWER: '下', DOWN: '下', '下': '下'
|
||||||
|
}
|
||||||
|
const TYPE_NORM = {
|
||||||
|
WORK: '工作辊', WORK_ROLL: '工作辊', WR: '工作辊', '工作辊': '工作辊',
|
||||||
|
BACKUP: '支撑辊', BUR: '支撑辊', SUPPORT: '支撑辊', BACK_UP: '支撑辊', '支撑辊': '支撑辊',
|
||||||
|
INTERMEDIATE: '中间辊', IMR: '中间辊', INTER: '中间辊', '中间辊': '中间辊'
|
||||||
|
}
|
||||||
|
|
||||||
|
function fmtDateStr(val) {
|
||||||
|
if (!val) return '—'
|
||||||
|
const s = String(val)
|
||||||
|
const m = s.match(/(\d{4})-(\d{2})-(\d{2})[ T](\d{2}):(\d{2}):(\d{2})/)
|
||||||
|
if (m) return `${m[1]}-${m[2]}-${m[3]} ${m[4]}:${m[5]}:${m[6]}`
|
||||||
|
const d = new Date(val)
|
||||||
|
if (isNaN(d.getTime())) return s
|
||||||
|
const pad = n => String(n).padStart(2, '0')
|
||||||
|
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'TimingRollHistoryPage',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
query: { rollId: '', standId: null, changeType: '' },
|
||||||
|
rows: [],
|
||||||
|
pagination: { page: 1, pageSize: 50, total: 0 },
|
||||||
|
tableHeight: 'calc(100vh - 196px)',
|
||||||
|
standOptions: STAND_NAMES.map((label, i) => ({ label, value: i + 1 }))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
filteredRows() {
|
||||||
|
if (!this.query.changeType) return this.rows
|
||||||
|
return this.rows.filter(r => String(r.change_type || '').toUpperCase() === this.query.changeType)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.loadCount()
|
||||||
|
this.loadRows()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async loadCount() {
|
||||||
|
try {
|
||||||
|
const res = await getRollHistoryCount(
|
||||||
|
this.query.rollId || undefined,
|
||||||
|
this.query.standId || undefined
|
||||||
|
)
|
||||||
|
this.pagination.total = res?.data?.total ?? 0
|
||||||
|
} catch (_) {}
|
||||||
|
},
|
||||||
|
async loadRows() {
|
||||||
|
this.loading = true
|
||||||
|
try {
|
||||||
|
const { page, pageSize } = this.pagination
|
||||||
|
const res = await getRollHistoryList(
|
||||||
|
page, pageSize,
|
||||||
|
this.query.rollId || undefined,
|
||||||
|
this.query.standId || undefined
|
||||||
|
)
|
||||||
|
this.rows = res?.data?.rows || []
|
||||||
|
} finally {
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleSearch() {
|
||||||
|
this.pagination.page = 1
|
||||||
|
this.loadCount()
|
||||||
|
this.loadRows()
|
||||||
|
},
|
||||||
|
handleReset() {
|
||||||
|
this.query = { rollId: '', standId: null, changeType: '' }
|
||||||
|
this.pagination.page = 1
|
||||||
|
this.loadCount()
|
||||||
|
this.loadRows()
|
||||||
|
},
|
||||||
|
handlePageChange(page) {
|
||||||
|
this.pagination.page = page
|
||||||
|
this.loadRows()
|
||||||
|
},
|
||||||
|
handleSizeChange(size) {
|
||||||
|
this.pagination.pageSize = size
|
||||||
|
this.pagination.page = 1
|
||||||
|
this.loadCount()
|
||||||
|
this.loadRows()
|
||||||
|
},
|
||||||
|
standName(val) {
|
||||||
|
const idx = Number(val) - 1
|
||||||
|
return STAND_NAMES[idx] || (val != null ? String(val) : '—')
|
||||||
|
},
|
||||||
|
dispPos(v) { return POS_NORM[String(v || '').toUpperCase()] || v || '—' },
|
||||||
|
dispType(v) { return TYPE_NORM[String(v || '').toUpperCase()] || v || '—' },
|
||||||
|
changeTypeTag(type) {
|
||||||
|
const map = { CHANGE: 'primary', GRIND: 'warning' }
|
||||||
|
return map[String(type || '').toUpperCase()] || 'info'
|
||||||
|
},
|
||||||
|
fmtNum(row, col, val) {
|
||||||
|
if (val == null || val === '') return '—'
|
||||||
|
const n = parseFloat(val)
|
||||||
|
return isNaN(n) ? String(val) : n.toFixed(2)
|
||||||
|
},
|
||||||
|
fmtInt(row, col, val) {
|
||||||
|
if (val == null || val === '') return '—'
|
||||||
|
const n = parseFloat(val)
|
||||||
|
return isNaN(n) ? String(val) : Math.round(n).toString()
|
||||||
|
},
|
||||||
|
fmtDate(val) { return fmtDateStr(val) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.roll-history-view {
|
||||||
|
padding: 12px;
|
||||||
|
background: #fff;
|
||||||
|
min-height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.filter-bar {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.pagination-bar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
padding: 8px 0 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
299
klp-ui/src/views/timing/roll/index.vue
Normal file
299
klp-ui/src/views/timing/roll/index.vue
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
<template>
|
||||||
|
<div class="roll-view">
|
||||||
|
<div class="toolbar">
|
||||||
|
<el-button size="small" type="primary" :loading="loading" icon="el-icon-refresh" @click="loadData">刷新</el-button>
|
||||||
|
<el-button size="small" icon="el-icon-search" @click="handleCheck">检查</el-button>
|
||||||
|
<span v-if="lastRefresh" class="refresh-time">上次刷新:{{ lastRefresh }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-wrap" v-loading="loading">
|
||||||
|
<table class="roll-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th rowspan="2" class="th-stand">机架</th>
|
||||||
|
<th rowspan="2" class="th-pos">位置</th>
|
||||||
|
<th colspan="4" class="th-section th-standby">准备辊</th>
|
||||||
|
<th colspan="9" class="th-section th-online">在线辊</th>
|
||||||
|
<th colspan="4" class="th-section th-standard">换辊标准</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="th-sub">轧辊号</th>
|
||||||
|
<th class="th-sub">外径</th>
|
||||||
|
<th class="th-sub">凸度</th>
|
||||||
|
<th class="th-sub">粗糙度</th>
|
||||||
|
<th class="th-sub">轧辊号</th>
|
||||||
|
<th class="th-sub">位置</th>
|
||||||
|
<th class="th-sub">类型</th>
|
||||||
|
<th class="th-sub">直径</th>
|
||||||
|
<th class="th-sub">凸度</th>
|
||||||
|
<th class="th-sub">粗糙度</th>
|
||||||
|
<th class="th-sub">长度</th>
|
||||||
|
<th class="th-sub">重量</th>
|
||||||
|
<th class="th-sub">安装时间</th>
|
||||||
|
<th class="th-sub">本次长度</th>
|
||||||
|
<th class="th-sub">累计长度</th>
|
||||||
|
<th class="th-sub">本次重量</th>
|
||||||
|
<th class="th-sub">累计重量</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<template v-for="(stand, si) in tableData">
|
||||||
|
<tr
|
||||||
|
v-for="(pos, pi) in stand.positions"
|
||||||
|
:key="stand.id + '-' + pi"
|
||||||
|
:class="rowCls(pos)"
|
||||||
|
>
|
||||||
|
<td v-if="pi === 0" :rowspan="stand.positions.length" class="td-stand">
|
||||||
|
{{ stand.name }}
|
||||||
|
</td>
|
||||||
|
<td class="td-pos">{{ pos.label }}</td>
|
||||||
|
|
||||||
|
<!-- 准备辊 -->
|
||||||
|
<td class="td-standby">{{ sv(pos.standby, 'rollid') }}</td>
|
||||||
|
<td class="td-standby">{{ nv(pos.standby, 'diameter') }}</td>
|
||||||
|
<td class="td-standby">{{ nv(pos.standby, 'crown') }}</td>
|
||||||
|
<td class="td-standby">{{ nv(pos.standby, 'rough') }}</td>
|
||||||
|
|
||||||
|
<!-- 在线辊 -->
|
||||||
|
<td class="td-online td-bold">{{ sv(pos.online, 'rollid') }}</td>
|
||||||
|
<td class="td-online">{{ dispPos(pos.online && pos.online.position) }}</td>
|
||||||
|
<td class="td-online">{{ dispType(pos.online && pos.online.type) }}</td>
|
||||||
|
<td class="td-online">{{ nv(pos.online, 'diameter') }}</td>
|
||||||
|
<td class="td-online">{{ nv(pos.online, 'crown') }}</td>
|
||||||
|
<td class="td-online">{{ nv(pos.online, 'rough') }}</td>
|
||||||
|
<td class="td-online">{{ iv(pos.online, 'rolled_length') }}</td>
|
||||||
|
<td class="td-online">{{ iv(pos.online, 'rolled_weight') }}</td>
|
||||||
|
<td class="td-online td-time">{{ dv(pos.online, 'instal_time') }}</td>
|
||||||
|
|
||||||
|
<!-- 换辊标准 -->
|
||||||
|
<td class="td-std">{{ iv(pos.online, 'rolled_length') }}</td>
|
||||||
|
<td class="td-std">{{ iv(pos.online, 'total_rolled_length') }}</td>
|
||||||
|
<td class="td-std">{{ iv(pos.online, 'rolled_weight') }}</td>
|
||||||
|
<td class="td-std">{{ iv(pos.online, 'total_rolled_weight') }}</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getRollData } from '@/api/l2/timing'
|
||||||
|
|
||||||
|
const STAND_NAMES = ['一机架', '二机架', '三机架', '四机架', '五机架', '六机架']
|
||||||
|
|
||||||
|
// 归一化:英文 → 中文,兼容已是中文的情况
|
||||||
|
const POS_NORM = {
|
||||||
|
TOP: '上', UPPER: '上', UP: '上', '上': '上',
|
||||||
|
BOTTOM: '下', LOWER: '下', DOWN: '下', '下': '下'
|
||||||
|
}
|
||||||
|
const TYPE_NORM = {
|
||||||
|
WORK: '工作辊', WORK_ROLL: '工作辊', WR: '工作辊', '工作辊': '工作辊',
|
||||||
|
BACKUP: '支撑辊', BUR: '支撑辊', SUPPORT: '支撑辊', BACK_UP: '支撑辊', '支撑辊': '支撑辊',
|
||||||
|
INTERMEDIATE: '中间辊', IMR: '中间辊', INTER: '中间辊', '中间辊': '中间辊'
|
||||||
|
}
|
||||||
|
|
||||||
|
function normPos(v) { return POS_NORM[String(v || '').toUpperCase()] || String(v || '').trim() }
|
||||||
|
function normType(v) { return TYPE_NORM[String(v || '').toUpperCase()] || String(v || '').trim() }
|
||||||
|
|
||||||
|
const POSITIONS = [
|
||||||
|
{ label: '上支撑辊', position: '上', type: '支撑辊' },
|
||||||
|
{ label: '上中间辊', position: '上', type: '中间辊' },
|
||||||
|
{ label: '上工作辊', position: '上', type: '工作辊' },
|
||||||
|
{ label: '下工作辊', position: '下', type: '工作辊' },
|
||||||
|
{ label: '下中间辊', position: '下', type: '中间辊' },
|
||||||
|
{ label: '下支撑辊', position: '下', type: '支撑辊' }
|
||||||
|
]
|
||||||
|
|
||||||
|
function fmtDateStr(val) {
|
||||||
|
if (!val) return '—'
|
||||||
|
const s = String(val)
|
||||||
|
const m = s.match(/(\d{4})-(\d{2})-(\d{2})[ T](\d{2}):(\d{2}):(\d{2})/)
|
||||||
|
if (m) return `${m[1]}-${m[2]}-${m[3]} ${m[4]}:${m[5]}:${m[6]}`
|
||||||
|
const d = new Date(val)
|
||||||
|
if (isNaN(d.getTime())) return s
|
||||||
|
const pad = n => String(n).padStart(2, '0')
|
||||||
|
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'TimingRollPage',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
lastRefresh: '',
|
||||||
|
tableData: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.loadData()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async loadData() {
|
||||||
|
this.loading = true
|
||||||
|
try {
|
||||||
|
const res = await getRollData()
|
||||||
|
const rows = res?.data?.rows || []
|
||||||
|
this.buildTableData(rows)
|
||||||
|
const now = new Date()
|
||||||
|
const pad = n => String(n).padStart(2, '0')
|
||||||
|
this.lastRefresh = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`
|
||||||
|
} finally {
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
buildTableData(rows) {
|
||||||
|
this.tableData = STAND_NAMES.map((name, idx) => {
|
||||||
|
const standId = idx + 1
|
||||||
|
const standRows = rows.filter(r => Number(r.standid) === standId)
|
||||||
|
const positions = POSITIONS.map(p => {
|
||||||
|
// 同位置下所有 ONLINE 辊,按安装时间升序排列
|
||||||
|
const matches = standRows
|
||||||
|
.filter(r =>
|
||||||
|
normPos(r.position) === p.position &&
|
||||||
|
normType(r.type) === p.type
|
||||||
|
)
|
||||||
|
.sort((a, b) => {
|
||||||
|
const ta = a.instal_time ? new Date(a.instal_time).getTime() : 0
|
||||||
|
const tb = b.instal_time ? new Date(b.instal_time).getTime() : 0
|
||||||
|
return ta - tb
|
||||||
|
})
|
||||||
|
// 安装最早的是当前在线辊,后装的是准备辊(等待换入)
|
||||||
|
const online = matches[0] || null
|
||||||
|
const standby = matches[1] || null
|
||||||
|
return { ...p, online, standby }
|
||||||
|
})
|
||||||
|
return { id: standId, name, positions }
|
||||||
|
})
|
||||||
|
},
|
||||||
|
rowCls(pos) {
|
||||||
|
return pos.online ? '' : 'row-empty'
|
||||||
|
},
|
||||||
|
// 字符串值
|
||||||
|
sv(row, key) {
|
||||||
|
if (!row) return '—'
|
||||||
|
const v = row[key]
|
||||||
|
return v != null && v !== '' ? String(v) : '—'
|
||||||
|
},
|
||||||
|
// 数值(保留两位小数)
|
||||||
|
nv(row, key) {
|
||||||
|
if (!row) return '—'
|
||||||
|
const v = row[key]
|
||||||
|
if (v == null || v === '') return '—'
|
||||||
|
const n = parseFloat(v)
|
||||||
|
return isNaN(n) ? String(v) : n.toFixed(2)
|
||||||
|
},
|
||||||
|
// 整数
|
||||||
|
iv(row, key) {
|
||||||
|
if (!row) return '—'
|
||||||
|
const v = row[key]
|
||||||
|
if (v == null || v === '') return '—'
|
||||||
|
const n = parseFloat(v)
|
||||||
|
return isNaN(n) ? String(v) : Math.round(n).toString()
|
||||||
|
},
|
||||||
|
// 日期
|
||||||
|
dv(row, key) {
|
||||||
|
return row ? fmtDateStr(row[key]) : '—'
|
||||||
|
},
|
||||||
|
dispPos(v) { return POS_NORM[String(v || '').toUpperCase()] || v || '—' },
|
||||||
|
dispType(v) { return TYPE_NORM[String(v || '').toUpperCase()] || v || '—' },
|
||||||
|
handleCheck() {
|
||||||
|
const missing = []
|
||||||
|
this.tableData.forEach(stand => {
|
||||||
|
stand.positions.forEach(pos => {
|
||||||
|
if (pos.online && !pos.standby) missing.push(`${stand.name} ${pos.label}`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if (missing.length === 0) {
|
||||||
|
this.$message.success('检查通过,各机架备辊配置正常')
|
||||||
|
} else {
|
||||||
|
this.$alert(missing.join('\n'), '以下位置缺少备辊', { type: 'warning', confirmButtonText: '知道了' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.roll-view {
|
||||||
|
padding: 12px;
|
||||||
|
background: #fff;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.toolbar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.refresh-time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
.table-wrap {
|
||||||
|
flex: 1;
|
||||||
|
overflow: auto;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
border-radius: 3px;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
.roll-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #303133;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.roll-table th,
|
||||||
|
.roll-table td {
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
padding: 5px 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.roll-table thead tr:first-child th {
|
||||||
|
background: #eef0f3;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.th-section { border-bottom: 2px solid #c0c4cc !important; }
|
||||||
|
.th-standby { background: #f5f7fa !important; }
|
||||||
|
.th-online { background: #ecf5ff !important; color: #1a5276; }
|
||||||
|
.th-standard { background: #fdf6ec !important; color: #7b5c1e; }
|
||||||
|
.th-stand, .th-pos { background: #eef0f3; font-weight: 600; }
|
||||||
|
.th-sub {
|
||||||
|
background: #fafafa;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 11px;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
.td-stand {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 13px;
|
||||||
|
background: #f5f7fa;
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
text-orientation: mixed;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
width: 32px;
|
||||||
|
min-width: 32px;
|
||||||
|
}
|
||||||
|
.td-pos {
|
||||||
|
background: #fafafa;
|
||||||
|
font-weight: 500;
|
||||||
|
width: 62px;
|
||||||
|
text-align: left;
|
||||||
|
padding-left: 6px;
|
||||||
|
}
|
||||||
|
.td-bold { font-weight: 500; }
|
||||||
|
.td-standby { color: #606266; }
|
||||||
|
.td-online { color: #303133; }
|
||||||
|
.td-std { color: #606266; }
|
||||||
|
.td-time { font-size: 11px; color: #606266; }
|
||||||
|
.row-empty td { color: #c0c4cc; background: #fafafa; }
|
||||||
|
.roll-table tbody tr:hover td { background: #f0f7ff; }
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user