Compare commits
8 Commits
1f1397b116
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73ede33466 | ||
|
|
2798133412 | ||
|
|
8ea6894552 | ||
| 6acb7b4b40 | |||
| 21a1d339d5 | |||
| c47da2f443 | |||
| 53f0fcefb4 | |||
| e07387132b |
@@ -104,14 +104,12 @@ public class MesRollStandbyController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空指定机架所有备辊,同时回退轧辊状态
|
||||
* 清空指定产线+机架的全部下批轧辊
|
||||
* DELETE /mill/standby/clear?lineId=xxx&standNo=1%23
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('mill:standby:remove')")
|
||||
@Log(title = "下批轧辊(待换上)", businessType = BusinessType.DELETE)
|
||||
@Log(title = "下批轧辊", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/clear")
|
||||
public AjaxResult clearByStand(@RequestParam Long lineId, @RequestParam String standNo)
|
||||
{
|
||||
public AjaxResult clear(Long lineId, @RequestParam String standNo) {
|
||||
return toAjax(mesRollStandbyService.clearByStand(lineId, standNo));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,14 @@ public class MesRollStandbyVo {
|
||||
private String rollNo;
|
||||
private String rollType;
|
||||
private String position;
|
||||
/** 辊位中文标签(上支撑辊/上工作辊/下工作辊/下支撑辊) */
|
||||
private String positionLabel;
|
||||
private BigDecimal diameter;
|
||||
private BigDecimal roughness;
|
||||
private BigDecimal crown;
|
||||
private Date readyTime;
|
||||
private String remark;
|
||||
private Date createTime;
|
||||
|
||||
public Long getStandbyId() { return standbyId; }
|
||||
public void setStandbyId(Long standbyId) { this.standbyId = standbyId; }
|
||||
@@ -37,6 +41,9 @@ public class MesRollStandbyVo {
|
||||
public String getPosition() { return position; }
|
||||
public void setPosition(String position) { this.position = position; }
|
||||
|
||||
public String getPositionLabel() { return positionLabel; }
|
||||
public void setPositionLabel(String positionLabel) { this.positionLabel = positionLabel; }
|
||||
|
||||
public BigDecimal getDiameter() { return diameter; }
|
||||
public void setDiameter(BigDecimal diameter) { this.diameter = diameter; }
|
||||
|
||||
@@ -48,4 +55,10 @@ public class MesRollStandbyVo {
|
||||
|
||||
public Date getReadyTime() { return readyTime; }
|
||||
public void setReadyTime(Date readyTime) { this.readyTime = readyTime; }
|
||||
|
||||
public String getRemark() { return remark; }
|
||||
public void setRemark(String remark) { this.remark = remark; }
|
||||
|
||||
public Date getCreateTime() { return createTime; }
|
||||
public void setCreateTime(Date createTime) { this.createTime = createTime; }
|
||||
}
|
||||
|
||||
@@ -126,18 +126,18 @@ public class MillProductionActual extends BaseEntity
|
||||
private String customer;
|
||||
|
||||
/** 上线时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Excel(name = "上线时间", width = 30, dateFormat = "yyyy-MM-dd")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "上线时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date onlineTime;
|
||||
|
||||
/** 开始时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date startTime;
|
||||
|
||||
/** 结束时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date endTime;
|
||||
|
||||
/** 机组号 */
|
||||
|
||||
@@ -36,10 +36,9 @@ public interface MesRollInfoMapper {
|
||||
int updateCurrentDia(@Param("rollId") Long rollId, @Param("currentDia") BigDecimal currentDia);
|
||||
|
||||
/**
|
||||
* 条件更新轧辊状态 — 仅当当前状态为 oldStatus 时才更新为 newStatus
|
||||
* 用于清空备辊时安全回退:避免把已上机的轧辊状态改错
|
||||
* 条件更新:仅当辊当前状态等于 onlyIfStatus 时才更新(用于避免误覆盖已 Online 的辊)
|
||||
*/
|
||||
int updateStatusByRollNoIfStatus(@Param("rollNo") String rollNo,
|
||||
@Param("newStatus") String newStatus,
|
||||
@Param("oldStatus") String oldStatus);
|
||||
@Param("status") String status,
|
||||
@Param("onlyIfStatus") String onlyIfStatus);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.ruoyi.mill.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.mill.domain.MesRollStandby;
|
||||
import com.ruoyi.mill.domain.MesRollStandbyVo;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
@@ -67,7 +68,7 @@ public interface MesRollStandbyMapper
|
||||
* @param standNo 机架号
|
||||
* @return 备辊列表 (VO)
|
||||
*/
|
||||
public List<MesRollStandby> selectByStand(@Param("lineId") Long lineId, @Param("standNo") String standNo);
|
||||
public List<MesRollStandbyVo> selectByStand(@Param("lineId") Long lineId, @Param("standNo") String standNo);
|
||||
|
||||
/**
|
||||
* 清空指定机架的所有备辊记录
|
||||
|
||||
@@ -27,6 +27,14 @@ public interface MillProductionActualMapper
|
||||
*/
|
||||
public List<MillProductionActual> selectMillProductionActualList(MillProductionActual millProductionActual);
|
||||
|
||||
/**
|
||||
* 查询某计划是否已生成实绩
|
||||
*
|
||||
* @param planId 计划ID
|
||||
* @return 数量
|
||||
*/
|
||||
public int countByPlanId(Long planId);
|
||||
|
||||
/**
|
||||
* 新增轧线生产实绩
|
||||
*
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import com.ruoyi.mill.mapper.MesRollStandbyMapper;
|
||||
import com.ruoyi.mill.domain.MesRollStandby;
|
||||
import com.ruoyi.mill.domain.MesRollStandbyVo;
|
||||
import com.ruoyi.mill.service.IMesRollStandbyService;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
@@ -113,9 +114,9 @@ public class MesRollStandbyServiceImpl implements IMesRollStandbyService
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean clearByStand(Long lineId, String standNo) {
|
||||
// 先查出所有辊号再清空
|
||||
List<MesRollStandby> list = mesRollStandbyMapper.selectByStand(lineId, standNo);
|
||||
List<MesRollStandbyVo> list = mesRollStandbyMapper.selectByStand(lineId, standNo);
|
||||
int rows = mesRollStandbyMapper.clearByStand(lineId, standNo);
|
||||
for (MesRollStandby vo : list) {
|
||||
for (MesRollStandbyVo vo : list) {
|
||||
if (StringUtils.isNotBlank(vo.getRollNo())) {
|
||||
// 只有仍处于 Standby 状态时才回退为 Offline(换辊后已变 Online 的不动)
|
||||
rollInfoMapper.updateStatusByRollNoIfStatus(vo.getRollNo(), "Offline", "Standby");
|
||||
|
||||
@@ -96,28 +96,32 @@ public class MillProductionPlanServiceImpl implements IMillProductionPlanService
|
||||
throw new RuntimeException("计划不存在: " + planId);
|
||||
}
|
||||
|
||||
// 2. 更新计划状态为完成(2)
|
||||
plan.setProdStatus("Done");
|
||||
plan.setUpdateBy(SecurityUtils.getUsername());
|
||||
int updateResult = planMapper.update(plan);
|
||||
if (updateResult <= 0) {
|
||||
throw new RuntimeException("更新计划状态失败");
|
||||
// 2. 更新计划状态为完成(幂等)
|
||||
if (!"Done".equals(plan.getProdStatus())) {
|
||||
plan.setProdStatus("Done");
|
||||
plan.setUpdateBy(SecurityUtils.getUsername());
|
||||
int updateResult = planMapper.update(plan);
|
||||
if (updateResult <= 0) {
|
||||
throw new RuntimeException("更新计划状态失败");
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 创建生产实绩记录
|
||||
MillProductionActual actual = new MillProductionActual();
|
||||
actual.setPlanId(plan.getPlanId());
|
||||
actual.setPlanNo(plan.getPlanNo());
|
||||
actual.setEntryMatId(plan.getInMatNo()); // 来料卷号 = 生产计划钢卷号
|
||||
actual.setSteelGrade(plan.getAlloyNo()); // 钢种
|
||||
actual.setStatus("已完成"); // 实绩状态:已完成
|
||||
actual.setEndTime(new Date()); // 结束时间
|
||||
actual.setCreateBy(SecurityUtils.getUsername());
|
||||
actual.setDelFlag("0"); // 正常状态
|
||||
// 3. 创建生产实绩记录(幂等)
|
||||
if (actualMapper.countByPlanId(planId) <= 0) {
|
||||
MillProductionActual actual = new MillProductionActual();
|
||||
actual.setPlanId(plan.getPlanId());
|
||||
actual.setPlanNo(plan.getPlanNo());
|
||||
actual.setEntryMatId(plan.getInMatNo());
|
||||
actual.setSteelGrade(plan.getAlloyNo());
|
||||
actual.setStatus("已完成");
|
||||
actual.setEndTime(new Date());
|
||||
actual.setCreateBy(SecurityUtils.getUsername());
|
||||
actual.setDelFlag("0");
|
||||
|
||||
int actualResult = actualMapper.insertMillProductionActual(actual);
|
||||
if (actualResult <= 0) {
|
||||
throw new RuntimeException("创建生产实绩记录失败");
|
||||
int actualResult = actualMapper.insertMillProductionActual(actual);
|
||||
if (actualResult <= 0) {
|
||||
throw new RuntimeException("创建生产实绩记录失败");
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -148,33 +148,34 @@
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<!-- 查询指定机架当前各辊位状态(最近一次换辊记录) -->
|
||||
<!-- 组合查询各辊位当前实际在机状态(每个位置独立取最新非空记录) -->
|
||||
<select id="selectCurrentStateByStand" resultType="map">
|
||||
SELECT change_time AS changeTime,
|
||||
upper_wr_no AS upperWrNo,
|
||||
upper_wr_dia AS upperWrDia,
|
||||
lower_wr_no AS lowerWrNo,
|
||||
lower_wr_dia AS lowerWrDia,
|
||||
upper_br_no AS upperBrNo,
|
||||
upper_br_dia AS upperBrDia,
|
||||
lower_br_no AS lowerBrNo,
|
||||
lower_br_dia AS lowerBrDia
|
||||
FROM mes_roll_change
|
||||
WHERE line_id = #{lineId} AND stand_no = #{standNo}
|
||||
ORDER BY change_id DESC
|
||||
LIMIT 1
|
||||
SELECT
|
||||
(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="selectLatestByStandAndPosition" resultMap="MesRollChangeResult">
|
||||
<include refid="selectMesRollChangeVo"/>
|
||||
WHERE line_id = #{lineId} AND stand_no = #{standNo} AND del_flag = 0
|
||||
AND (
|
||||
(#{posType} = 'upperWr' AND upper_wr_no IS NOT NULL)
|
||||
OR (#{posType} = 'lowerWr' AND lower_wr_no IS NOT NULL)
|
||||
OR (#{posType} = 'upperBr' AND upper_br_no IS NOT NULL)
|
||||
OR (#{posType} = 'lowerBr' AND lower_br_no IS NOT NULL)
|
||||
)
|
||||
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>
|
||||
<when test="posType == 'upperBr'">AND upper_br_no IS NOT NULL AND upper_br_no != ''</when>
|
||||
<when test="posType == 'lowerBr'">AND lower_br_no IS NOT NULL AND lower_br_no != ''</when>
|
||||
</choose>
|
||||
ORDER BY change_time DESC, change_id DESC
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
@@ -171,13 +171,10 @@
|
||||
WHERE del_flag = 0 AND roll_id = #{rollId}
|
||||
</update>
|
||||
|
||||
<!-- 条件更新轧辊状态 — 仅当当前状态为 oldStatus 时才更新 -->
|
||||
<update id="updateStatusByRollNoIfStatus">
|
||||
UPDATE mes_roll_info
|
||||
SET status = #{newStatus}, update_time = NOW()
|
||||
WHERE del_flag = 0
|
||||
AND roll_no = #{rollNo}
|
||||
AND status = #{oldStatus}
|
||||
SET status = #{status}, update_time = NOW()
|
||||
WHERE del_flag = 0 AND roll_no = #{rollNo} AND status = #{onlyIfStatus}
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -118,13 +118,33 @@
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<select id="selectByStand" resultMap="MesRollStandbyResult">
|
||||
<include refid="selectMesRollStandbyVo"/>
|
||||
where line_id = #{lineId} and stand_no = #{standNo}
|
||||
<select id="selectByStand" resultType="com.ruoyi.mill.domain.MesRollStandbyVo">
|
||||
SELECT
|
||||
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 '上工作辊'
|
||||
WHEN roll_type = 'WR' AND position = 'DOWN' THEN '下工作辊'
|
||||
WHEN roll_type = 'BR' AND position = 'DOWN' THEN '下支撑辊'
|
||||
ELSE CONCAT(position, roll_type)
|
||||
END AS position_label,
|
||||
diameter, roughness, crown, ready_time, remark, create_time
|
||||
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>
|
||||
|
||||
<delete id="clearByStand">
|
||||
delete from mes_roll_standby
|
||||
where line_id = #{lineId} and stand_no = #{standNo}
|
||||
</delete>
|
||||
<!-- 逻辑删除指定产线+机架所有下批轧辊(清空) -->
|
||||
<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>
|
||||
|
||||
@@ -29,12 +29,22 @@
|
||||
SELECT <include refid="cols"/>
|
||||
FROM mill_process_recipe
|
||||
WHERE del_flag = '0'
|
||||
<if test="recipeNo != null and recipeNo != ''">
|
||||
AND recipe_no LIKE CONCAT('%', #{recipeNo}, '%')
|
||||
</if>
|
||||
<if test="alloyNo != null and alloyNo != ''">
|
||||
AND alloy_no LIKE CONCAT('%', #{alloyNo}, '%')
|
||||
</if>
|
||||
<choose>
|
||||
<when test="recipeNo != null and recipeNo != '' and alloyNo != null and alloyNo != '' and recipeNo == alloyNo">
|
||||
AND (
|
||||
recipe_no LIKE CONCAT('%', #{recipeNo}, '%')
|
||||
OR alloy_no LIKE CONCAT('%', #{alloyNo}, '%')
|
||||
)
|
||||
</when>
|
||||
<otherwise>
|
||||
<if test="recipeNo != null and recipeNo != ''">
|
||||
AND recipe_no LIKE CONCAT('%', #{recipeNo}, '%')
|
||||
</if>
|
||||
<if test="alloyNo != null and alloyNo != ''">
|
||||
AND alloy_no LIKE CONCAT('%', #{alloyNo}, '%')
|
||||
</if>
|
||||
</otherwise>
|
||||
</choose>
|
||||
<if test="status != null and status != ''">
|
||||
AND status = #{status}
|
||||
</if>
|
||||
|
||||
@@ -101,6 +101,10 @@
|
||||
where actual_id = #{actualId}
|
||||
</select>
|
||||
|
||||
<select id="countByPlanId" parameterType="Long" resultType="int">
|
||||
select count(1) from mill_production_actual where plan_id = #{planId} and del_flag = '0'
|
||||
</select>
|
||||
|
||||
<insert id="insertMillProductionActual" parameterType="MillProductionActual" useGeneratedKeys="true" keyProperty="actualId">
|
||||
insert into mill_production_actual
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
<if test="planStatus != null and planStatus != ''">
|
||||
AND plan_status = #{planStatus}
|
||||
</if>
|
||||
<if test="params != null and (params.excludeDone == true or params.excludeDone == 'true')">
|
||||
AND prod_status != 'Done'
|
||||
</if>
|
||||
<if test="params != null and params.beginTime != null and params.beginTime != ''">
|
||||
AND DATE(create_time) >= #{params.beginTime}
|
||||
</if>
|
||||
|
||||
@@ -89,9 +89,9 @@
|
||||
}
|
||||
|
||||
.el-menu-item.is-active {
|
||||
background-color: #1d4e89 !important;
|
||||
background-color: rgba(93, 173, 226, 0.24) !important;
|
||||
color: #ffffff !important;
|
||||
border-left: 3px solid #5dade2;
|
||||
border-left: 3px solid #85c1e9;
|
||||
}
|
||||
|
||||
& .nest-menu .el-submenu>.el-submenu__title,
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
|
||||
<div class="sidebar-logo-inner">
|
||||
<img v-if="logo" :src="logo" class="sidebar-logo" />
|
||||
<h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }}</h1>
|
||||
<h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">
|
||||
<span v-for="(line, index) in titleLines" :key="index" class="sidebar-title-line">{{ line }}</span>
|
||||
</h1>
|
||||
</div>
|
||||
</router-link>
|
||||
</transition>
|
||||
@@ -32,6 +34,12 @@ export default {
|
||||
},
|
||||
sideTheme() {
|
||||
return this.$store.state.settings.sideTheme
|
||||
},
|
||||
titleLines() {
|
||||
if (this.title === '科伦普冷轧双机架控制平台') {
|
||||
return ['科伦普冷轧', '双机架控制平台']
|
||||
}
|
||||
return [this.title]
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -72,10 +80,14 @@ export default {
|
||||
text-decoration: none;
|
||||
|
||||
& .sidebar-logo-inner {
|
||||
display: flex;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
width: auto;
|
||||
max-width: calc(100% - 20px);
|
||||
margin: 0 auto;
|
||||
transform: translate(-6px, 5px);
|
||||
}
|
||||
|
||||
& .sidebar-logo {
|
||||
@@ -87,19 +99,26 @@ export default {
|
||||
}
|
||||
|
||||
& .sidebar-title {
|
||||
display: inline-block;
|
||||
display: block;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
line-height: 56px;
|
||||
font-size: 15px;
|
||||
font-size: 13px;
|
||||
font-family: Avenir, Helvetica Neue, Arial, 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
vertical-align: middle;
|
||||
letter-spacing: 0.5px;
|
||||
letter-spacing: 0.2px;
|
||||
text-align: center;
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
& .sidebar-title-line {
|
||||
display: block;
|
||||
line-height: 18px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 140px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,328 +1,329 @@
|
||||
<template>
|
||||
<div id="tags-view-container" class="tags-view-container">
|
||||
<scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll">
|
||||
<router-link
|
||||
v-for="tag in visitedViews"
|
||||
ref="tag"
|
||||
:key="tag.path"
|
||||
:class="isActive(tag)?'active':''"
|
||||
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
|
||||
tag="span"
|
||||
class="tags-view-item"
|
||||
:style="activeStyle(tag)"
|
||||
@click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
|
||||
@contextmenu.prevent.native="openMenu(tag,$event)"
|
||||
>
|
||||
{{ tag.title }}
|
||||
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
|
||||
</router-link>
|
||||
</scroll-pane>
|
||||
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
|
||||
<li @click="refreshSelectedTag(selectedTag)"><i class="el-icon-refresh-right"></i> 刷新页面</li>
|
||||
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"><i class="el-icon-close"></i> 关闭当前</li>
|
||||
<li @click="closeOthersTags"><i class="el-icon-circle-close"></i> 关闭其他</li>
|
||||
<li v-if="!isFirstView()" @click="closeLeftTags"><i class="el-icon-back"></i> 关闭左侧</li>
|
||||
<li v-if="!isLastView()" @click="closeRightTags"><i class="el-icon-right"></i> 关闭右侧</li>
|
||||
<li @click="closeAllTags(selectedTag)"><i class="el-icon-circle-close"></i> 全部关闭</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ScrollPane from './ScrollPane'
|
||||
import path from 'path'
|
||||
|
||||
export default {
|
||||
components: { ScrollPane },
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
top: 0,
|
||||
left: 0,
|
||||
selectedTag: {},
|
||||
affixTags: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visitedViews() {
|
||||
return this.$store.state.tagsView.visitedViews
|
||||
},
|
||||
routes() {
|
||||
return this.$store.state.permission.routes
|
||||
},
|
||||
theme() {
|
||||
return this.$store.state.settings.theme;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.addTags()
|
||||
this.moveToCurrentTag()
|
||||
},
|
||||
visible(value) {
|
||||
if (value) {
|
||||
document.body.addEventListener('click', this.closeMenu)
|
||||
} else {
|
||||
document.body.removeEventListener('click', this.closeMenu)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initTags()
|
||||
this.addTags()
|
||||
},
|
||||
methods: {
|
||||
isActive(route) {
|
||||
return route.path === this.$route.path
|
||||
},
|
||||
activeStyle(tag) {
|
||||
if (!this.isActive(tag)) return {};
|
||||
return {
|
||||
"background-color": this.theme,
|
||||
"border-color": this.theme
|
||||
};
|
||||
},
|
||||
isAffix(tag) {
|
||||
return tag.meta && tag.meta.affix
|
||||
},
|
||||
isFirstView() {
|
||||
try {
|
||||
return this.selectedTag.fullPath === '/index' || this.selectedTag.fullPath === this.visitedViews[1].fullPath
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
},
|
||||
isLastView() {
|
||||
try {
|
||||
return this.selectedTag.fullPath === this.visitedViews[this.visitedViews.length - 1].fullPath
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
},
|
||||
filterAffixTags(routes, basePath = '/') {
|
||||
let tags = []
|
||||
routes.forEach(route => {
|
||||
if (route.meta && route.meta.affix) {
|
||||
const tagPath = path.resolve(basePath, route.path)
|
||||
tags.push({
|
||||
fullPath: tagPath,
|
||||
path: tagPath,
|
||||
name: route.name,
|
||||
meta: { ...route.meta }
|
||||
})
|
||||
}
|
||||
if (route.children) {
|
||||
const tempTags = this.filterAffixTags(route.children, route.path)
|
||||
if (tempTags.length >= 1) {
|
||||
tags = [...tags, ...tempTags]
|
||||
}
|
||||
}
|
||||
})
|
||||
return tags
|
||||
},
|
||||
initTags() {
|
||||
const affixTags = this.affixTags = this.filterAffixTags(this.routes)
|
||||
for (const tag of affixTags) {
|
||||
// Must have tag name
|
||||
if (tag.name) {
|
||||
this.$store.dispatch('tagsView/addVisitedView', tag)
|
||||
}
|
||||
}
|
||||
},
|
||||
addTags() {
|
||||
const { name } = this.$route
|
||||
if (name) {
|
||||
this.$store.dispatch('tagsView/addView', this.$route)
|
||||
}
|
||||
},
|
||||
moveToCurrentTag() {
|
||||
const tags = this.$refs.tag
|
||||
this.$nextTick(() => {
|
||||
for (const tag of tags) {
|
||||
if (tag.to.path === this.$route.path) {
|
||||
this.$refs.scrollPane.moveToTarget(tag)
|
||||
// when query is different then update
|
||||
if (tag.to.fullPath !== this.$route.fullPath) {
|
||||
this.$store.dispatch('tagsView/updateVisitedView', this.$route)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
refreshSelectedTag(view) {
|
||||
this.$tab.refreshPage(view);
|
||||
if (this.$route.meta.link) {
|
||||
this.$store.dispatch('tagsView/delIframeView', this.$route)
|
||||
}
|
||||
},
|
||||
closeSelectedTag(view) {
|
||||
this.$tab.closePage(view).then(({ visitedViews }) => {
|
||||
if (this.isActive(view)) {
|
||||
this.toLastView(visitedViews, view)
|
||||
}
|
||||
})
|
||||
},
|
||||
closeRightTags() {
|
||||
this.$tab.closeRightPage(this.selectedTag).then(visitedViews => {
|
||||
if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
|
||||
this.toLastView(visitedViews)
|
||||
}
|
||||
})
|
||||
},
|
||||
closeLeftTags() {
|
||||
this.$tab.closeLeftPage(this.selectedTag).then(visitedViews => {
|
||||
if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
|
||||
this.toLastView(visitedViews)
|
||||
}
|
||||
})
|
||||
},
|
||||
closeOthersTags() {
|
||||
this.$router.push(this.selectedTag.fullPath).catch(()=>{});
|
||||
this.$tab.closeOtherPage(this.selectedTag).then(() => {
|
||||
this.moveToCurrentTag()
|
||||
})
|
||||
},
|
||||
closeAllTags(view) {
|
||||
this.$tab.closeAllPage().then(({ visitedViews }) => {
|
||||
if (this.affixTags.some(tag => tag.path === this.$route.path)) {
|
||||
return
|
||||
}
|
||||
this.toLastView(visitedViews, view)
|
||||
})
|
||||
},
|
||||
toLastView(visitedViews, view) {
|
||||
const latestView = visitedViews.slice(-1)[0]
|
||||
if (latestView) {
|
||||
this.$router.push(latestView.fullPath)
|
||||
} else {
|
||||
// now the default is to redirect to the home page if there is no tags-view,
|
||||
// you can adjust it according to your needs.
|
||||
if (view.name === 'Dashboard') {
|
||||
// to reload home page
|
||||
this.$router.replace({ path: '/redirect' + view.fullPath })
|
||||
} else {
|
||||
this.$router.push('/')
|
||||
}
|
||||
}
|
||||
},
|
||||
openMenu(tag, e) {
|
||||
const menuMinWidth = 105
|
||||
const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
|
||||
const offsetWidth = this.$el.offsetWidth // container width
|
||||
const maxLeft = offsetWidth - menuMinWidth // left boundary
|
||||
const left = e.clientX - offsetLeft + 15 // 15: margin right
|
||||
|
||||
if (left > maxLeft) {
|
||||
this.left = maxLeft
|
||||
} else {
|
||||
this.left = left
|
||||
}
|
||||
|
||||
this.top = e.clientY
|
||||
this.visible = true
|
||||
this.selectedTag = tag
|
||||
},
|
||||
closeMenu() {
|
||||
this.visible = false
|
||||
},
|
||||
handleScroll() {
|
||||
this.closeMenu()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tags-view-container {
|
||||
height: 34px;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #d8dce5;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);
|
||||
.tags-view-wrapper {
|
||||
.tags-view-item {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
border: 1px solid #d8dce5;
|
||||
color: #495060;
|
||||
background: #fff;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
margin-left: 5px;
|
||||
margin-top: 4px;
|
||||
&:first-of-type {
|
||||
margin-left: 15px;
|
||||
}
|
||||
&:last-of-type {
|
||||
margin-right: 15px;
|
||||
}
|
||||
&.active {
|
||||
background-color: #42b983;
|
||||
color: #fff;
|
||||
border-color: #42b983;
|
||||
&::before {
|
||||
content: '';
|
||||
background: #fff;
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.contextmenu {
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
z-index: 3000;
|
||||
position: absolute;
|
||||
list-style-type: none;
|
||||
padding: 5px 0;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #333;
|
||||
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
|
||||
li {
|
||||
margin: 0;
|
||||
padding: 7px 16px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #eee;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
//reset element css of el-icon-close
|
||||
.tags-view-wrapper {
|
||||
.tags-view-item {
|
||||
.el-icon-close {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: 2px;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
transition: all .3s cubic-bezier(.645, .045, .355, 1);
|
||||
transform-origin: 100% 50%;
|
||||
&:before {
|
||||
transform: scale(.6);
|
||||
display: inline-block;
|
||||
vertical-align: -3px;
|
||||
}
|
||||
&:hover {
|
||||
background-color: #b4bccc;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div id="tags-view-container" class="tags-view-container">
|
||||
<scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll">
|
||||
<router-link
|
||||
v-for="tag in visitedViews"
|
||||
ref="tag"
|
||||
:key="tag.path"
|
||||
:class="isActive(tag)?'active':''"
|
||||
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
|
||||
tag="span"
|
||||
class="tags-view-item"
|
||||
:style="activeStyle(tag)"
|
||||
@click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
|
||||
@contextmenu.prevent.native="openMenu(tag,$event)"
|
||||
>
|
||||
{{ tag.title }}
|
||||
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
|
||||
</router-link>
|
||||
</scroll-pane>
|
||||
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
|
||||
<li @click="refreshSelectedTag(selectedTag)"><i class="el-icon-refresh-right"></i> 刷新页面</li>
|
||||
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"><i class="el-icon-close"></i> 关闭当前</li>
|
||||
<li @click="closeOthersTags"><i class="el-icon-circle-close"></i> 关闭其他</li>
|
||||
<li v-if="!isFirstView()" @click="closeLeftTags"><i class="el-icon-back"></i> 关闭左侧</li>
|
||||
<li v-if="!isLastView()" @click="closeRightTags"><i class="el-icon-right"></i> 关闭右侧</li>
|
||||
<li @click="closeAllTags(selectedTag)"><i class="el-icon-circle-close"></i> 全部关闭</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ScrollPane from './ScrollPane'
|
||||
import path from 'path'
|
||||
|
||||
export default {
|
||||
components: { ScrollPane },
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
top: 0,
|
||||
left: 0,
|
||||
selectedTag: {},
|
||||
affixTags: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visitedViews() {
|
||||
return this.$store.state.tagsView.visitedViews
|
||||
},
|
||||
routes() {
|
||||
return this.$store.state.permission.routes
|
||||
},
|
||||
theme() {
|
||||
return this.$store.state.settings.theme;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.addTags()
|
||||
this.moveToCurrentTag()
|
||||
},
|
||||
visible(value) {
|
||||
if (value) {
|
||||
document.body.addEventListener('click', this.closeMenu)
|
||||
} else {
|
||||
document.body.removeEventListener('click', this.closeMenu)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initTags()
|
||||
this.addTags()
|
||||
},
|
||||
methods: {
|
||||
isActive(route) {
|
||||
return route.path === this.$route.path
|
||||
},
|
||||
activeStyle(tag) {
|
||||
if (!this.isActive(tag)) return {};
|
||||
return {
|
||||
"background-color": "rgba(93, 173, 226, 0.16)",
|
||||
"border-color": "#85c1e9",
|
||||
"color": "#2f5d84"
|
||||
};
|
||||
},
|
||||
isAffix(tag) {
|
||||
return tag.meta && tag.meta.affix
|
||||
},
|
||||
isFirstView() {
|
||||
try {
|
||||
return this.selectedTag.fullPath === '/index' || this.selectedTag.fullPath === this.visitedViews[1].fullPath
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
},
|
||||
isLastView() {
|
||||
try {
|
||||
return this.selectedTag.fullPath === this.visitedViews[this.visitedViews.length - 1].fullPath
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
},
|
||||
filterAffixTags(routes, basePath = '/') {
|
||||
let tags = []
|
||||
routes.forEach(route => {
|
||||
if (route.meta && route.meta.affix) {
|
||||
const tagPath = path.resolve(basePath, route.path)
|
||||
tags.push({
|
||||
fullPath: tagPath,
|
||||
path: tagPath,
|
||||
name: route.name,
|
||||
meta: { ...route.meta }
|
||||
})
|
||||
}
|
||||
if (route.children) {
|
||||
const tempTags = this.filterAffixTags(route.children, route.path)
|
||||
if (tempTags.length >= 1) {
|
||||
tags = [...tags, ...tempTags]
|
||||
}
|
||||
}
|
||||
})
|
||||
return tags
|
||||
},
|
||||
initTags() {
|
||||
const affixTags = this.affixTags = this.filterAffixTags(this.routes)
|
||||
for (const tag of affixTags) {
|
||||
// Must have tag name
|
||||
if (tag.name) {
|
||||
this.$store.dispatch('tagsView/addVisitedView', tag)
|
||||
}
|
||||
}
|
||||
},
|
||||
addTags() {
|
||||
const { name } = this.$route
|
||||
if (name) {
|
||||
this.$store.dispatch('tagsView/addView', this.$route)
|
||||
}
|
||||
},
|
||||
moveToCurrentTag() {
|
||||
const tags = this.$refs.tag
|
||||
this.$nextTick(() => {
|
||||
for (const tag of tags) {
|
||||
if (tag.to.path === this.$route.path) {
|
||||
this.$refs.scrollPane.moveToTarget(tag)
|
||||
// when query is different then update
|
||||
if (tag.to.fullPath !== this.$route.fullPath) {
|
||||
this.$store.dispatch('tagsView/updateVisitedView', this.$route)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
refreshSelectedTag(view) {
|
||||
this.$tab.refreshPage(view);
|
||||
if (this.$route.meta.link) {
|
||||
this.$store.dispatch('tagsView/delIframeView', this.$route)
|
||||
}
|
||||
},
|
||||
closeSelectedTag(view) {
|
||||
this.$tab.closePage(view).then(({ visitedViews }) => {
|
||||
if (this.isActive(view)) {
|
||||
this.toLastView(visitedViews, view)
|
||||
}
|
||||
})
|
||||
},
|
||||
closeRightTags() {
|
||||
this.$tab.closeRightPage(this.selectedTag).then(visitedViews => {
|
||||
if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
|
||||
this.toLastView(visitedViews)
|
||||
}
|
||||
})
|
||||
},
|
||||
closeLeftTags() {
|
||||
this.$tab.closeLeftPage(this.selectedTag).then(visitedViews => {
|
||||
if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
|
||||
this.toLastView(visitedViews)
|
||||
}
|
||||
})
|
||||
},
|
||||
closeOthersTags() {
|
||||
this.$router.push(this.selectedTag.fullPath).catch(()=>{});
|
||||
this.$tab.closeOtherPage(this.selectedTag).then(() => {
|
||||
this.moveToCurrentTag()
|
||||
})
|
||||
},
|
||||
closeAllTags(view) {
|
||||
this.$tab.closeAllPage().then(({ visitedViews }) => {
|
||||
if (this.affixTags.some(tag => tag.path === this.$route.path)) {
|
||||
return
|
||||
}
|
||||
this.toLastView(visitedViews, view)
|
||||
})
|
||||
},
|
||||
toLastView(visitedViews, view) {
|
||||
const latestView = visitedViews.slice(-1)[0]
|
||||
if (latestView) {
|
||||
this.$router.push(latestView.fullPath)
|
||||
} else {
|
||||
// now the default is to redirect to the home page if there is no tags-view,
|
||||
// you can adjust it according to your needs.
|
||||
if (view.name === 'Dashboard') {
|
||||
// to reload home page
|
||||
this.$router.replace({ path: '/redirect' + view.fullPath })
|
||||
} else {
|
||||
this.$router.push('/')
|
||||
}
|
||||
}
|
||||
},
|
||||
openMenu(tag, e) {
|
||||
const menuMinWidth = 105
|
||||
const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
|
||||
const offsetWidth = this.$el.offsetWidth // container width
|
||||
const maxLeft = offsetWidth - menuMinWidth // left boundary
|
||||
const left = e.clientX - offsetLeft + 15 // 15: margin right
|
||||
|
||||
if (left > maxLeft) {
|
||||
this.left = maxLeft
|
||||
} else {
|
||||
this.left = left
|
||||
}
|
||||
|
||||
this.top = e.clientY
|
||||
this.visible = true
|
||||
this.selectedTag = tag
|
||||
},
|
||||
closeMenu() {
|
||||
this.visible = false
|
||||
},
|
||||
handleScroll() {
|
||||
this.closeMenu()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tags-view-container {
|
||||
height: 34px;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #d8dce5;
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);
|
||||
.tags-view-wrapper {
|
||||
.tags-view-item {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
border: 1px solid #d8dce5;
|
||||
color: #495060;
|
||||
background: #fff;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
margin-left: 5px;
|
||||
margin-top: 4px;
|
||||
&:first-of-type {
|
||||
margin-left: 15px;
|
||||
}
|
||||
&:last-of-type {
|
||||
margin-right: 15px;
|
||||
}
|
||||
&.active {
|
||||
background-color: rgba(93, 173, 226, 0.16);
|
||||
color: #2f5d84;
|
||||
border-color: #85c1e9;
|
||||
&::before {
|
||||
content: '';
|
||||
background: #85c1e9;
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.contextmenu {
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
z-index: 3000;
|
||||
position: absolute;
|
||||
list-style-type: none;
|
||||
padding: 5px 0;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #333;
|
||||
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
|
||||
li {
|
||||
margin: 0;
|
||||
padding: 7px 16px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #eee;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
//reset element css of el-icon-close
|
||||
.tags-view-wrapper {
|
||||
.tags-view-item {
|
||||
.el-icon-close {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: 2px;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
transition: all .3s cubic-bezier(.645, .045, .355, 1);
|
||||
transform-origin: 100% 50%;
|
||||
&:before {
|
||||
transform: scale(.6);
|
||||
display: inline-block;
|
||||
vertical-align: -3px;
|
||||
}
|
||||
&:hover {
|
||||
background-color: #b4bccc;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<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="80px">
|
||||
<el-form-item label="成本项目编码" prop="itemCode">
|
||||
<el-input
|
||||
v-model="queryParams.itemCode"
|
||||
|
||||
@@ -195,7 +195,7 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: #1c2b3a;
|
||||
background: #2b4358;
|
||||
color: #ecf0f1;
|
||||
padding: 0 16px;
|
||||
height: 36px;
|
||||
@@ -215,10 +215,10 @@ export default {
|
||||
}
|
||||
}
|
||||
.system-name { font-weight: 700; font-size: 13px; letter-spacing: .5px; }
|
||||
.divider { color: #4a6275; }
|
||||
.unit-tag { background: #1d4e89; padding: 1px 8px; border-radius: 2px; font-size: 11px; }
|
||||
.sys-status { font-size: 11px; &.online { color: #7fb3d3; } }
|
||||
.clock { font-family: 'Courier New', monospace; font-size: 12px; color: #aab7c4; }
|
||||
.divider { color: #89a0b4; }
|
||||
.unit-tag { background: rgba(133, 193, 233, 0.20); color: #eef7ff; padding: 1px 8px; border-radius: 2px; font-size: 11px; }
|
||||
.sys-status { font-size: 11px; &.online { color: #abd4ee; } }
|
||||
.clock { font-family: 'Courier New', monospace; font-size: 12px; color: #c4d3de; }
|
||||
|
||||
/* ── KPI 卡片 ── */
|
||||
.kpi-row { margin-bottom: 12px; }
|
||||
@@ -262,7 +262,7 @@ export default {
|
||||
overflow: hidden;
|
||||
|
||||
&__header {
|
||||
background: #1c2b3a;
|
||||
background: #2b4358;
|
||||
color: #ecf0f1;
|
||||
padding: 7px 12px;
|
||||
display: flex;
|
||||
@@ -294,7 +294,7 @@ export default {
|
||||
.stand-badge {
|
||||
font-size: 11px; padding: 2px 8px;
|
||||
border-radius: 2px; font-weight: 600;
|
||||
&.running { background: #1d4e89; color: #fff; }
|
||||
&.running { background: rgba(133, 193, 233, 0.20); color: #eef7ff; }
|
||||
&.stopped { background: #c0392b; color: #fff; }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
|
||||
<el-form-item label="钢卷号" prop="currentCoilNo">
|
||||
<el-input
|
||||
v-model="queryParams.currentCoilNo"
|
||||
placeholder="请输入钢卷号"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="挂接状态" prop="bindStatus">
|
||||
<el-select v-model="queryParams.bindStatus" placeholder="请选择挂接状态" clearable>
|
||||
<el-option label="已挂接" :value="1" />
|
||||
<el-option label="已撤回" :value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="操作人" prop="operateUser">
|
||||
<el-input
|
||||
v-model="queryParams.operateUser"
|
||||
placeholder="请输入操作人"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="yyyy-MM-dd"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="el-icon-download"
|
||||
size="mini"
|
||||
@click="handleExport"
|
||||
v-hasPermi="['mill:relation:export']"
|
||||
>导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="relationList">
|
||||
<el-table-column label="关系ID" align="center" prop="relationId" />
|
||||
<el-table-column label="钢卷号" align="center" prop="currentCoilNo" />
|
||||
<el-table-column label="二级异常ID" align="center" prop="secondAbnormalId" />
|
||||
<el-table-column label="三级钢卷ID" align="center" prop="thirdCoilId" />
|
||||
<el-table-column label="三级异常ID" align="center" prop="thirdAbnormalId" />
|
||||
<el-table-column label="挂接状态" align="center" prop="bindStatus">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.bindStatus === 1" type="success">已挂接</el-tag>
|
||||
<el-tag v-else-if="scope.row.bindStatus === 2" type="info">已撤回</el-tag>
|
||||
<el-tag v-else type="warning">未知</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="挂接时间" align="center" prop="bindTime" width="160">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.bindTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="撤回时间" align="center" prop="withdrawTime" width="160">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.withdrawTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作人" align="center" prop="operateUser" />
|
||||
<el-table-column label="操作备注" align="center" prop="operateRemark" show-overflow-tooltip />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="160">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listRelation } from "@/api/mill/coilAbnormalRelation";
|
||||
|
||||
export default {
|
||||
name: "RelationLog",
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
showSearch: true,
|
||||
total: 0,
|
||||
relationList: [],
|
||||
dateRange: [],
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
currentCoilNo: null,
|
||||
bindStatus: null,
|
||||
operateUser: null,
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.loading = true;
|
||||
const params = { ...this.queryParams };
|
||||
if (this.dateRange && this.dateRange.length === 2) {
|
||||
params.beginTime = this.dateRange[0];
|
||||
params.endTime = this.dateRange[1];
|
||||
}
|
||||
listRelation(params).then(response => {
|
||||
this.relationList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.dateRange = [];
|
||||
this.handleQuery();
|
||||
},
|
||||
handleExport() {
|
||||
const params = { ...this.queryParams };
|
||||
if (this.dateRange && this.dateRange.length === 2) {
|
||||
params.beginTime = this.dateRange[0];
|
||||
params.endTime = this.dateRange[1];
|
||||
}
|
||||
this.download('mill/relation/export', params, `relation_log_${new Date().getTime()}.xlsx`)
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -160,7 +160,6 @@
|
||||
<span style="font-size: 16px; font-weight: bold;">异常记录</span>
|
||||
<div style="float: right;">
|
||||
<el-button type="success" plain icon="el-icon-plus" size="mini" @click="handleAbnormalAdd">添加异常</el-button>
|
||||
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleAbnormalExport">导出</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<AbnormalTable
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="actualList" @selection-change="handleSelectionChange" @row-click="handleRowClick" highlight-current-row>
|
||||
<el-table ref="actualTable" v-loading="loading" :data="actualList" row-key="actualId" @selection-change="handleSelectionChange" @row-click="handleRowClick" highlight-current-row>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="成品卷号" align="center" prop="exitMatId" />
|
||||
<el-table-column label="来料卷号" align="center" prop="entryMatId" />
|
||||
@@ -108,9 +108,9 @@
|
||||
<el-table-column label="成品厚度" align="center" prop="exitThickness" />
|
||||
<el-table-column label="成品宽度" align="center" prop="exitWidth" />
|
||||
<el-table-column label="实际重量" align="center" prop="actualWeight" />
|
||||
<el-table-column label="上线时间" align="center" prop="onlineTime" width="120">
|
||||
<el-table-column label="上线时间" align="center" prop="onlineTime" width="170">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.onlineTime, '{y}-{m}-{d}') }}</span>
|
||||
<span>{{ parseTime(scope.row.onlineTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="状态" align="center" prop="status" /> -->
|
||||
@@ -476,6 +476,9 @@ export default {
|
||||
},
|
||||
form: {},
|
||||
rules: {
|
||||
exitMatId: [{ required: true, message: '请输入成品卷号', trigger: 'blur' }],
|
||||
entryMatId: [{ required: true, message: '请输入来料卷号', trigger: 'blur' }],
|
||||
planNo: [{ required: true, message: '请输入计划号', trigger: 'blur' }],
|
||||
}
|
||||
};
|
||||
},
|
||||
@@ -486,9 +489,17 @@ export default {
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listActual(this.queryParams).then(response => {
|
||||
this.actualList = response.rows;
|
||||
this.actualList = response.rows || [];
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
this.ids = [];
|
||||
this.single = true;
|
||||
this.multiple = true;
|
||||
if (this.$refs.actualTable) this.$refs.actualTable.clearSelection();
|
||||
if (this.currentRow && this.currentRow.actualId != null) {
|
||||
const updated = this.actualList.find(r => r.actualId === this.currentRow.actualId);
|
||||
this.currentRow = updated || null;
|
||||
}
|
||||
});
|
||||
},
|
||||
cancel() {
|
||||
@@ -549,6 +560,11 @@ export default {
|
||||
},
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.currentRow = null;
|
||||
this.ids = [];
|
||||
this.single = true;
|
||||
this.multiple = true;
|
||||
if (this.$refs.actualTable) this.$refs.actualTable.clearSelection();
|
||||
this.handleQuery();
|
||||
},
|
||||
handleSelectionChange(selection) {
|
||||
@@ -558,6 +574,10 @@ export default {
|
||||
},
|
||||
handleRowClick(row) {
|
||||
this.currentRow = row;
|
||||
if (this.$refs.actualTable) {
|
||||
this.$refs.actualTable.clearSelection();
|
||||
this.$refs.actualTable.toggleRowSelection(row, true);
|
||||
}
|
||||
},
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
@@ -600,6 +620,8 @@ export default {
|
||||
this.$modal.confirm('是否确认删除轧线生产实绩编号为"' + actualIds + '"的数据项?').then(function() {
|
||||
return delActual(actualIds);
|
||||
}).then(() => {
|
||||
const deleted = String(actualIds).split(',').map(v => Number(v));
|
||||
if (this.currentRow && deleted.includes(Number(this.currentRow.actualId))) this.currentRow = null;
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
|
||||
@@ -170,13 +170,17 @@
|
||||
|
||||
<div class="section-header" style="margin-top:8px"><span>队列操作</span></div>
|
||||
<div class="op-buttons">
|
||||
<el-button size="mini" type="primary" icon="el-icon-plus" @click="handleAdd">钢卷增加</el-button>
|
||||
<el-button size="mini" icon="el-icon-edit" :disabled="!selectedPlan" @click="handleEdit">修改</el-button>
|
||||
<!-- <el-button size="mini" icon="el-icon-edit" :disabled="!selectedPlan" @click="handleFinish"></el-button> -->
|
||||
<el-button size="mini" icon="el-icon-document" :disabled="!selectedPlan" @click="handleFinish">完成</el-button>
|
||||
<el-button size="mini" type="danger" icon="el-icon-delete" :disabled="!selectedPlan" @click="handleDelete">删除</el-button>
|
||||
<el-button size="mini" icon="el-icon-top" :disabled="!selectedPlan" @click="handleMoveUp">Up 上移</el-button>
|
||||
<el-button size="mini" icon="el-icon-bottom" :disabled="!selectedPlan" @click="handleMoveDown">Down 下移</el-button>
|
||||
<div class="op-btn-group">
|
||||
<el-button size="mini" type="primary" icon="el-icon-plus" @click="handleAdd">钢卷增加</el-button>
|
||||
<el-button size="mini" icon="el-icon-edit" :disabled="!selectedPlan" @click="handleEdit">修改</el-button>
|
||||
<el-button size="mini" icon="el-icon-document" :disabled="!selectedPlan || selectedPlan.prodStatus === 'Done'" @click="handleFinish">完成</el-button>
|
||||
<el-button size="mini" type="danger" icon="el-icon-delete" :disabled="!selectedPlan" @click="handleDelete">删除</el-button>
|
||||
</div>
|
||||
<div class="op-btn-sep"></div>
|
||||
<div class="op-btn-group">
|
||||
<el-button size="mini" icon="el-icon-top" :disabled="!selectedPlan" @click="handleMoveUp">上移</el-button>
|
||||
<el-button size="mini" icon="el-icon-bottom" :disabled="!selectedPlan" @click="handleMoveDown">下移</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -400,11 +404,24 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
refreshRecipeOptions() {
|
||||
listAllRecipe({}).then(res => { this.recipeOptions = res.data || [] })
|
||||
listAllRecipe({}).then(res => {
|
||||
const all = res.data || []
|
||||
const keepIds = new Set()
|
||||
if (this.selectedPlan && this.selectedPlan.recipeId) keepIds.add(this.selectedPlan.recipeId)
|
||||
if (this.form && this.form.recipeId) keepIds.add(this.form.recipeId)
|
||||
if (this.selectRecipeId) keepIds.add(this.selectRecipeId)
|
||||
|
||||
const visible = all.filter(r => !String(r.recipeNo || '').startsWith('__'))
|
||||
all.forEach(r => {
|
||||
if (keepIds.has(r.recipeId) && !visible.some(x => x.recipeId === r.recipeId)) visible.push(r)
|
||||
})
|
||||
this.recipeOptions = visible
|
||||
})
|
||||
},
|
||||
handleFinish() {
|
||||
const planId = this.selectedPlan.planId
|
||||
const planId = this.selectedPlan && this.selectedPlan.planId
|
||||
if (!planId) return this.$message.warning('请先选择钢卷')
|
||||
if (this.selectedPlan.prodStatus === 'Done') return this.$message.info('该计划已完成')
|
||||
finishPlan(planId).then(res => {
|
||||
if (res.code === 200) {
|
||||
this.$message.success('完成成功')
|
||||
@@ -415,12 +432,13 @@ export default {
|
||||
})
|
||||
},
|
||||
loadList() {
|
||||
const params = { inMatNo: this.query.inMatNo }
|
||||
if (this.query.hideFinished) params.Idle = 'Idle'
|
||||
const params = { inMatNo: this.query.inMatNo, params: {} }
|
||||
if (this.query.hideFinished) params.params.excludeDone = true
|
||||
if (this.query.dateRange && this.query.dateRange.length === 2) {
|
||||
params.beginTime = this.query.dateRange[0]
|
||||
params.endTime = this.query.dateRange[1]
|
||||
params.params.beginTime = this.query.dateRange[0]
|
||||
params.params.endTime = this.query.dateRange[1]
|
||||
}
|
||||
if (!Object.keys(params.params).length) delete params.params
|
||||
listPlan(params).then(res => { this.planList = res.data || [] })
|
||||
},
|
||||
resetQuery() {
|
||||
@@ -775,9 +793,33 @@ export default {
|
||||
padding: 8px 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
gap: 2px;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
.el-button { width: 100%; justify-content: flex-start; }
|
||||
|
||||
.op-btn-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.op-btn-sep {
|
||||
height: 1px;
|
||||
background: #e4e7ed;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.el-button {
|
||||
width: 100%;
|
||||
justify-content: flex-start;
|
||||
border-radius: 2px;
|
||||
padding-left: 10px;
|
||||
margin-left: 0 !important;
|
||||
i { margin-right: 4px; }
|
||||
&:not(.el-button--primary):not(.el-button--danger) {
|
||||
border-color: #dcdfe6;
|
||||
&:hover { color: #409eff; border-color: #c6e2ff; background: #ecf5ff; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 底部状态栏 */
|
||||
|
||||
@@ -175,7 +175,7 @@ const emptyPass = (no) => ({
|
||||
})
|
||||
|
||||
const emptyForm = () => ({
|
||||
id: null, recipeNo: '', alloyNo: '', passCount: 0,
|
||||
recipeId: null, recipeNo: '', alloyNo: '', passCount: 0,
|
||||
inThick: '', outThick: '', outWidth: '', status: '0', remark: ''
|
||||
})
|
||||
|
||||
@@ -200,16 +200,29 @@ export default {
|
||||
mounted() { this.loadList() },
|
||||
methods: {
|
||||
loadList() {
|
||||
listRecipe({ recipeNo: this.searchKey, alloyNo: this.searchKey }).then(res => {
|
||||
this.recipeList = res.rows || []
|
||||
return listRecipe({ recipeNo: this.searchKey, alloyNo: this.searchKey }).then(res => {
|
||||
const list = res.rows || []
|
||||
this.recipeList = list
|
||||
if (this.isNew) return
|
||||
if (this.selectedId != null && !list.some(item => item.recipeId === this.selectedId)) {
|
||||
this.clearSelection()
|
||||
}
|
||||
})
|
||||
},
|
||||
clearSelection() {
|
||||
this.selectedId = null
|
||||
this.isNew = false
|
||||
this.form = emptyForm()
|
||||
this.passList = []
|
||||
if (this.$refs.formRef) this.$refs.formRef.clearValidate()
|
||||
},
|
||||
handleSelect(r) {
|
||||
this.selectedId = r.recipeId
|
||||
this.isNew = false
|
||||
getRecipeDetail(r.recipeId).then(res => {
|
||||
this.form = { ...res.data }
|
||||
this.passList = res.data.passList || []
|
||||
if (this.$refs.formRef) this.$refs.formRef.clearValidate()
|
||||
})
|
||||
},
|
||||
handleAdd() {
|
||||
@@ -217,6 +230,7 @@ export default {
|
||||
this.selectedId = null
|
||||
this.form = emptyForm()
|
||||
this.passList = []
|
||||
if (this.$refs.formRef) this.$refs.formRef.clearValidate()
|
||||
},
|
||||
handleSave() {
|
||||
this.$refs.formRef.validate(valid => {
|
||||
@@ -224,23 +238,27 @@ export default {
|
||||
this.form.passList = this.passList
|
||||
this.form.passCount = this.passList.length
|
||||
const api = this.isNew ? addRecipe : updateRecipe
|
||||
api(this.form).then(() => {
|
||||
api(this.form).then((res) => {
|
||||
this.$message.success('保存成功')
|
||||
this.loadList()
|
||||
const targetId = this.isNew ? res.data : this.form.recipeId
|
||||
this.isNew = false
|
||||
this.loadList().then(() => {
|
||||
if (targetId != null) this.handleSelect({ recipeId: targetId })
|
||||
else this.clearSelection()
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
handleReset() {
|
||||
if (this.isNew) { this.form = emptyForm(); this.passList = [] }
|
||||
else this.handleSelect({ id: this.selectedId })
|
||||
else if (this.selectedId != null) this.handleSelect({ recipeId: this.selectedId })
|
||||
else this.clearSelection()
|
||||
},
|
||||
handleDelete() {
|
||||
this.$confirm('确定删除该方案?', '提示', { type: 'warning' }).then(() => {
|
||||
delRecipe([this.form.recipeId]).then(() => {
|
||||
this.$message.success('删除成功')
|
||||
this.form = emptyForm(); this.passList = []
|
||||
this.selectedId = null; this.isNew = false
|
||||
this.clearSelection()
|
||||
this.loadList()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
</el-card>
|
||||
|
||||
<!-- 工作绩效 -->
|
||||
<el-card shadow="never" class="roll-table-card aside-panel">
|
||||
<!-- <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>
|
||||
@@ -127,7 +127,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-card> -->
|
||||
|
||||
</div>
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<KLPTable v-loading="historyLoading" :data="historyList">
|
||||
<el-table v-loading="historyLoading" :data="historyList">
|
||||
<el-table-column label="换辊编号" align="center" prop="changeNo" width="130" />
|
||||
<el-table-column label="机架" align="center" prop="standNo" width="80" />
|
||||
<el-table-column label="换辊时间" align="center" prop="changeTime" width="160" />
|
||||
@@ -178,13 +178,13 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="工作长度(m)" align="center" prop="workLength" width="96">
|
||||
<!-- <el-table-column label="工作长度(m)" align="center" prop="workLength" width="96">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.workLength != null">{{ scope.row.workLength }}</span>
|
||||
<span v-else style="color:#c0c4cc">—</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="过卷数" align="center" prop="coilCount" width="72">
|
||||
</el-table-column> -->
|
||||
<!-- <el-table-column label="过卷数" align="center" prop="coilCount" width="72">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.coilCount != null">{{ scope.row.coilCount }}</span>
|
||||
<span v-else style="color:#c0c4cc">—</span>
|
||||
@@ -195,7 +195,7 @@
|
||||
<span v-if="scope.row.totalWeight != null">{{ scope.row.totalWeight }}</span>
|
||||
<span v-else style="color:#c0c4cc">—</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column> -->
|
||||
<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">
|
||||
@@ -204,7 +204,7 @@
|
||||
@click="handleDeleteHistory(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</KLPTable>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="historyTotal > 0"
|
||||
:total="historyTotal"
|
||||
@@ -378,7 +378,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCurrentRolls, listRollChange, addRollChange, updateRollChange, delRollChange, getRollPerformance } from '@/api/mill/rollChange'
|
||||
import { getCurrentRolls, listRollChange, addRollChange, updateRollChange, delRollChange } from '@/api/mill/rollChange'
|
||||
import { listRollStandby, addRollStandby, delRollStandby, clearRollStandby } from '@/api/mill/rollStandby'
|
||||
import { listRollOptions, listRollInfo } from '@/api/mill/rollInfo'
|
||||
import rollLineMixin from '../rollLineMixin'
|
||||
@@ -630,15 +630,15 @@ export default {
|
||||
})
|
||||
this.loadHistory()
|
||||
this.loadOfflineRolls()
|
||||
this.loadRollPerformance()
|
||||
// this.loadRollPerformance()
|
||||
},
|
||||
|
||||
loadRollPerformance() {
|
||||
this.perfLoading = true
|
||||
getRollPerformance(this.lineId).then(res => {
|
||||
this.perfData = res.data || {}
|
||||
}).finally(() => { this.perfLoading = false })
|
||||
},
|
||||
// loadRollPerformance() {
|
||||
// this.perfLoading = true
|
||||
// getRollPerformance(this.lineId).then(res => {
|
||||
// this.perfData = res.data || {}
|
||||
// }).finally(() => { this.perfLoading = false })
|
||||
// },
|
||||
|
||||
loadCurrent(standNo) {
|
||||
this.$set(this.loadingCurrent, standNo, true)
|
||||
@@ -732,7 +732,7 @@ export default {
|
||||
this.loadStandby(standNo)
|
||||
this.loadHistory()
|
||||
this.loadOfflineRolls()
|
||||
this.loadRollPerformance()
|
||||
// this.loadRollPerformance()
|
||||
})
|
||||
}).finally(() => {
|
||||
this.changeSubmitting = false
|
||||
|
||||
Reference in New Issue
Block a user