808b3a2b 张雷

feat(equipment): 添加设备健康度定时更新功能

- 新增设备健康度和健康状态字段
- 实现设备列表查询和屏幕列表查询接口
- 添加设备健康度定时更新任务
- 优化设备信息查询 SQL
1 个父辈 3f99ad9c
......@@ -332,6 +332,8 @@ public class EquipmentController {
}
queryWrapper.eq(flag, "EquipmentInfo_isSpecial", isSpecial)
.groupBy("EquipmentInfo_equipmentStatus");//EquipmentInfo_isSpecial
sql = sql.replace("EquipmentInfo.maintenance_cost as EquipmentInfo_maintenanceCost,", "")
.replace("EquipmentInfo.gz_count as EquipmentInfo_gzCount,", "");
List<Map<String, Object>> countMapList = iCommonSqlService.queryWrapperForList(sql, queryWrapper);
for (Map<String, Object> item : countMapList) {
String key = "" + item.get("EquipmentInfo_equipmentStatus");
......
package com.skua.modules.equipment.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
......@@ -276,11 +277,22 @@ public class EquipmentInfo {
@ApiModelProperty(value = "性能分数")
private String performanceScore;
@ApiModelProperty(value = "设备健康度")
private String equipmentHealthLevel;
@ApiModelProperty(value = "设备健康状态")
@Dict(dicCode = "equipment_health_status")
private String equipmentHealthStatus;
//维护费用
@TableField(exist = false)
private String maintenanceCost;
//维修次数
@TableField(exist = false)
private String gzCount;
//检测机构
@ApiModelProperty(value = "检测机构")
private String testingDepart;
......
package com.skua.modules.equipment.mapper;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.skua.modules.equipment.entity.EquipmentInfo;
import com.skua.modules.equipment.vo.EquipmentInfoForMonitorVO;
import io.lettuce.core.dynamic.annotation.Param;
/**
* 设备信息
......@@ -24,4 +26,9 @@ public interface EquipmentInfoMapper extends BaseMapper<EquipmentInfo> {
List<EquipmentInfoForMonitorVO> queryCustomPageList(Page<EquipmentInfoForMonitorVO> pageList, EquipmentInfoForMonitorVO equipmentInfoForMonitorVO);
void clearDigitaltwins();
List<EquipmentInfo> getEquipmentList();
List<Map<String, Object>> getScreenList(@Param("screenType") String screenType);
}
......
......@@ -28,4 +28,24 @@
<update id="clearDigitaltwins">
update equipment_info set digital_twins_struct_code = ''
</update>
<select id="getEquipmentList" resultType="com.skua.modules.equipment.entity.EquipmentInfo">
SELECT
ifnull( t.maintenance_cost, 0 ) maintenance_cost,
ifnull( r.id_count, 0 ) gz_count,
e.*
FROM
equipment_info e
LEFT JOIN ( SELECT SUM( maintenance_cost ) AS maintenance_cost, equipment_id FROM equipment_maintain_task GROUP BY equipment_id ) t ON e.id = t.equipment_id
LEFT JOIN ( SELECT count( id ) id_count, info_id FROM equipment_repair GROUP BY info_id ) r ON e.id = r.info_id
</select>
<select id="getScreenList" resultType="java.util.HashMap">
SELECT
context_code AS code,
context_title AS value,
context_name AS name
FROM
screen_user_context
WHERE
screen_type = #{screenType}
</select>
</mapper>
......
package com.skua.modules.equipment.quartz;
import com.skua.core.util.ConvertUtils;
import com.skua.core.util.DateUtils;
import com.skua.core.util.DoubleOperaUtils;
import com.skua.modules.equipment.entity.EquipmentInfo;
import com.skua.modules.equipment.service.IEquipmentInfoService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @program: skboot
* @description: 设备健康度定时任务
* @author: zhanglei
* @create: 2025/03/08 16:05:05
*/
@Slf4j
@Component
public class EquipHealthLevelJob implements Job {
@Autowired
private IEquipmentInfoService equipmentInfoService;
private static final String qz_screen_type = "71";//权重标识
private static final String status_screen_type = "70";//状态标识
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
log.info("设备健康度更新任务开始");
//获取当前时间 yyyy-MM-dd
String today = DateUtils.formatDate(new Date(), "yyyy-MM-dd");
Map<String,Double> qzMap = initQzMap();
Map<String,String> statusValueMap = initStatusMap();
//workingLife 使用年限、originalValue 购置价格、installDate 安装日期
List<EquipmentInfo> list = equipmentInfoService.getEquipmentList();
for (EquipmentInfo equipmentInfo : list){
double performanceScore = 100.00;//性能得分
double faultScore = 100.00;//故障得分
double maintainScore = 100.00;//维护得分
double useYearScore = 100.00;//使用年限得分
//性能分数
if(ConvertUtils.isNotEmpty(equipmentInfo.getPerformanceScore())){
performanceScore = Double.valueOf(equipmentInfo.getPerformanceScore());
}
performanceScore = DoubleOperaUtils.bigDecimalRound(qzMap.get("xnzb")/100.00 * performanceScore,2);
//故障分数
faultScore = getFaultScore(equipmentInfo.getGzCount(),qzMap.get("gzl")/100.00);
//维护分数
maintainScore = getMaintainScore(equipmentInfo.getMaintenanceCost(), equipmentInfo.getOriginalValue(),qzMap.get("whcb")/100.00);
//使用年限分数
useYearScore = getUseYearScore(equipmentInfo.getWorkingLife(),equipmentInfo.getInstallDate(),today,qzMap.get("synx")/100.00);
//计算总分
double score = performanceScore + faultScore + maintainScore + useYearScore;
equipmentInfo.setEquipmentHealthLevel(String.valueOf(score));
//判断score在statusValueMap的key值的哪个区间,返回对应的value
String statusValue = getEquipmentHealthStatus(score,statusValueMap);
equipmentInfo.setEquipmentHealthStatus(statusValue);
equipmentInfoService.updateById(equipmentInfo);
}
}
private String getEquipmentHealthStatus(double score,Map<String,String> statusValueMap) {
String statusValue = "";
for (Map.Entry<String, String> entry : statusValueMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (score >= Double.valueOf(key.split("-")[0]) && score <= Double.valueOf(key.split("-")[1])) {
statusValue = value.split("-")[0];
break;
}
}
return statusValue;
}
//初始化权重
private Map<String,Double> initQzMap() {
Map<String,Double> qzMap = new HashMap<>();
qzMap.put("xnzb",40.00);//性能指标
qzMap.put("gzl",20.00);//故障率
qzMap.put("whcb",20.00);//维护成本
qzMap.put("synx",20.00);//使用年限
//获取权重及分值信息
List<Map<String,Object>> weightList = equipmentInfoService.getScreenList(qz_screen_type);
for (Map<String,Object> map : weightList){
if("xnzb".equals(map.get("code"))){
qzMap.put("xnzb",Double.valueOf(map.get("value").toString()));
}
if("gzl".equals(map.get("code"))){
qzMap.put("gzl",Double.valueOf(map.get("value").toString()));
}
if("whcb".equals(map.get("code"))){
qzMap.put("whcb",Double.valueOf(map.get("value").toString()));
}
if("synx".equals(map.get("code"))){
qzMap.put("synx",Double.valueOf(map.get("value").toString()));
}
}
return qzMap;
}
//初始化状态字典
private Map<String,String> initStatusMap() {
Map<String,String> statusValueMap = new HashMap<>();
statusValueMap.put("90-100","wdyx-稳定运行");//稳定运行
statusValueMap.put("60-90","qwth-轻微退化");//轻微退化
statusValueMap.put("40-60","mxxj-明显下降");//明显下降
statusValueMap.put("0-40","jjbf-接近报废");//接近报废
List<Map<String,Object>> statusList = equipmentInfoService.getScreenList(status_screen_type);
for (Map<String,Object> map : statusList){
if("wdyx".equals(map.get("code"))){
statusValueMap.put(map.get("value").toString(),"wdyx-"+map.get("name").toString());//稳定运行
}
if("qwth".equals(map.get("code"))){
statusValueMap.put(map.get("value").toString(),"qwth-"+map.get("name").toString());//轻微退化
}
if("mxxj".equals(map.get("code"))){
statusValueMap.put(map.get("value").toString(),"mxxj-"+map.get("name").toString());//明显下降
}
if("jjbf".equals(map.get("code"))){
statusValueMap.put(map.get("value").toString(),"jjbf-"+map.get("name").toString());//接近报废
}
}
return statusValueMap;
}
/**
* 计算故障评分
* @param gzCount 设备信息
* @param qz 权重因子
* @return 返回计算得到的故障评分
*/
private double getFaultScore(String gzCount, double qz) {
double score = 100.00;
if(Double.valueOf(gzCount) >= 4){
score = 0.00;
}else{
score = 100 - 100*Double.valueOf(gzCount)/4;
}
return DoubleOperaUtils.bigDecimalRound(qz * score,2);
}
/**
* 计算维护得分
* @param maintenanceCost 设备维护费用
* @param originalValue 购置金额
* @param qz 权重
* @return 返回计算得到的维护得分
*/
private double getMaintainScore(String maintenanceCost, String originalValue, double qz) {
double score = 100.00;
if(ConvertUtils.isNotEmpty(originalValue)){
double gzfy = Double.valueOf(originalValue);
double whfy = Double.valueOf(maintenanceCost);
score = 100*(gzfy-whfy)/gzfy;
}
return DoubleOperaUtils.bigDecimalRound(qz * score,2);
}
/**
* 计算使用寿命得分
* @param workingLife 使用年限
* @param installDate 安装日期
* @param today 当前日期
* @param qz 权重因子
* @return 返回使用寿命得分,固定为100分的20%
*/
private double getUseYearScore(String workingLife, String installDate, String today, double qz) {
double score = 100.00;
if(ConvertUtils.isNotEmpty(installDate)){
if(ConvertUtils.isNotEmpty(workingLife)){
double sjsy = Double.valueOf(DateUtils.dayDiff(installDate,today));
double sm = 365*Double.valueOf(workingLife);
score = 100 * (sm-sjsy)/sm;
}
}
return DoubleOperaUtils.bigDecimalRound(qz * score,2);
}
}
......@@ -87,4 +87,9 @@ public interface IEquipmentInfoService extends IService<EquipmentInfo> {
String reCreateQrCode(String id);
void batchConfigDigitaltwins(JSONObject jsonObject);
List<EquipmentInfo> getEquipmentList();
List<Map<String, Object>> getScreenList(String screenType);
}
......
......@@ -3,11 +3,7 @@ package com.skua.modules.equipment.service.impl;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
......@@ -79,7 +75,6 @@ public class EquipmentInfoServiceImpl extends ServiceImpl<EquipmentInfoMapper, E
@Autowired
private IEquipmentAssetService equipmentAssetService;
@Override
public void addData(Result<EquipmentVO> result, EquipmentDTO equipmentDTO) throws Exception {
......@@ -360,4 +355,14 @@ public class EquipmentInfoServiceImpl extends ServiceImpl<EquipmentInfoMapper, E
}
}
@Override
public List<EquipmentInfo> getEquipmentList() {
return equipmentInfoMapper.getEquipmentList();
}
@Override
public List<Map<String, Object>> getScreenList(String screenType) {
return equipmentInfoMapper.getScreenList(screenType);
}
}
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!