This commit is contained in:
geting 2024-12-23 13:58:35 +08:00
commit 58210dbbeb
22 changed files with 595 additions and 438 deletions

View File

@ -1,33 +0,0 @@
package com.das.common.log;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import java.util.concurrent.Executor;
/**
* @author chenhaojie
*
*/
@Slf4j
public class MdcExecutor implements Executor {
private final Executor executor;
public MdcExecutor(Executor executor) {
this.executor = executor;
}
@Override
public void execute(Runnable command) {
final String requestId = MDC.get("REQUEST_ID");
executor.execute(() -> {
MDC.put("REQUEST_ID", requestId);
try {
command.run();
} finally {
MDC.remove("REQUEST_ID");
}
});
}
}

View File

@ -1,32 +0,0 @@
package com.das.common.log;
import java.util.UUID;
/**
* @author chenhaojie
*
*/
public class RequestIdUtils {
private static final ThreadLocal<UUID> requestIdHolder = new ThreadLocal<>();
private RequestIdUtils() {
}
public static void generateRequestId() {
requestIdHolder.set(UUID.randomUUID());
}
public static void generateRequestId(UUID uuid) {
requestIdHolder.set(uuid);
}
public static UUID getRequestId() {
return requestIdHolder.get();
}
public static void removeRequestId() {
requestIdHolder.remove();
}
}

View File

@ -1,74 +0,0 @@
package com.das.common.log;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import java.util.UUID;
/**
* @author chenhaojie
*
*/
@Slf4j
public class RequestLogInterceptor implements HandlerInterceptor {
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
String servletPath = request.getServletPath();
log.info("preHandle 后置处理----------");
log.info("servletPath:{}", servletPath);
RequestIdUtils.removeRequestId();
MDC.clear();
}
/**
* 获取RequestId
* 优先从header头获取如果没有则自己生成
* @return RequestId
*/
private String getRequestId(){
// 因为如果有网关则一般会从网关传递过来所以优先从header头获取
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(attributes != null && StringUtils.hasText(attributes.getRequest().getHeader("x-request-id"))) {
HttpServletRequest request = attributes.getRequest();
String requestId = request.getHeader("x-request-id");
UUID uuid = UUID.fromString(requestId);
RequestIdUtils.generateRequestId(uuid);
return requestId;
}
UUID existUUID = RequestIdUtils.getRequestId();
if(existUUID != null){
return existUUID.toString();
}
RequestIdUtils.generateRequestId();
return RequestIdUtils.getRequestId().toString();
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String servletPath = request.getServletPath();
// 生成RequestId
String requestId = this.getRequestId();
// 配置日志文件打印 REQUEST_ID
MDC.put("REQUEST_ID", requestId);
log.info("servletPath:{}", servletPath);
log.info("preHandle 前置处理----------");
return true;
}
}

View File

@ -45,7 +45,8 @@ public class IotModelCacheImpl implements IotModelCache {
@PreDestroy @PreDestroy
public void destroy(){ public void destroy(){
iotFieldsMap.clear();
iotModelInfoIdMap.clear();
} }
@Override @Override

View File

@ -26,7 +26,7 @@ public class CalcModule {
private Date updateTime; private Date updateTime;
private String cron; private String cron;
public static final CalcModule of(String content){ public final CalcModule of(String content){
CalcModule calcModule = new CalcModule(); CalcModule calcModule = new CalcModule();
calcModule.setScript(content); calcModule.setScript(content);
try(BufferedReader reader = new BufferedReader(new StringReader(content))){ try(BufferedReader reader = new BufferedReader(new StringReader(content))){

View File

@ -23,12 +23,10 @@ import java.util.Map;
@Slf4j @Slf4j
public class FunctionWindSpeedFactor extends AbstractFunction { public class FunctionWindSpeedFactor extends AbstractFunction {
private DataService dataService = null;
private CacheService cacheService = null; private CacheService cacheService = null;
public FunctionWindSpeedFactor(DataService dataService, CacheService cacheService) { public FunctionWindSpeedFactor(CacheService cacheService) {
this.dataService = dataService;
this.cacheService = cacheService; this.cacheService = cacheService;
} }

View File

@ -136,7 +136,7 @@ public class CalcService {
FunctionOffsetDate offsetDate = new FunctionOffsetDate(); FunctionOffsetDate offsetDate = new FunctionOffsetDate();
aviator.addFunction(offsetDate); aviator.addFunction(offsetDate);
FunctionWindSpeedFactor windSpeedFactor = new FunctionWindSpeedFactor(dataService,cacheService); FunctionWindSpeedFactor windSpeedFactor = new FunctionWindSpeedFactor(cacheService);
aviator.addFunction(windSpeedFactor); aviator.addFunction(windSpeedFactor);
FunctionIsOnline isOnline = new FunctionIsOnline(adminRedisTemplate, cacheService); FunctionIsOnline isOnline = new FunctionIsOnline(adminRedisTemplate, cacheService);

View File

@ -38,6 +38,7 @@ public class DataController {
public R<Map<String,Map<String,Object>>> querySnapshotValues(@RequestBody @Valid List<SnapshotValueQueryParam> param) { public R<Map<String,Map<String,Object>>> querySnapshotValues(@RequestBody @Valid List<SnapshotValueQueryParam> param) {
if (log.isDebugEnabled()){ if (log.isDebugEnabled()){
log.debug("/api/rtdbsvr/snapshot is calling"); log.debug("/api/rtdbsvr/snapshot is calling");
log.debug("request params: {}", param);
} }
return R.success(dataService.querySnapshotValues(param)); return R.success(dataService.querySnapshotValues(param));
} }
@ -50,7 +51,8 @@ public class DataController {
@PostMapping("/history") @PostMapping("/history")
public R<Map<String, Map<String, Map<String, Object>>>> queryTimeSeriesValues(@RequestBody @Valid TSValueQueryParam param) { public R<Map<String, Map<String, Map<String, Object>>>> queryTimeSeriesValues(@RequestBody @Valid TSValueQueryParam param) {
if (log.isDebugEnabled()){ if (log.isDebugEnabled()){
log.debug("/api/rtdbsvr/timeseries is calling"); log.debug("/api/rtdbsvr/history is calling");
log.debug("request params: {}", param);
} }
return R.success(dataService.queryTimeSeriesValues(param)); return R.success(dataService.queryTimeSeriesValues(param));
} }
@ -63,7 +65,8 @@ public class DataController {
@PostMapping("/windows") @PostMapping("/windows")
public R<Map<String, Map<String, Map<String, Object>>>> queryWindowsValues(@RequestBody @Valid WindowValueQueryParam param) { public R<Map<String, Map<String, Map<String, Object>>>> queryWindowsValues(@RequestBody @Valid WindowValueQueryParam param) {
if (log.isDebugEnabled()){ if (log.isDebugEnabled()){
log.debug("/api/rtdbsvr/timeseries is calling"); log.debug("/api/rtdbsvr/windows is calling");
log.debug("request params: {}", param);
} }
return R.success(dataService.queryWindowsValues(param)); return R.success(dataService.queryWindowsValues(param));
} }

View File

@ -92,7 +92,7 @@ public class TDEngineService {
log.info(sb.toString()); log.info(sb.toString());
pstmt.executeUpdate(sb.toString()); pstmt.executeUpdate(sb.toString());
} catch (Exception e) { } catch (Exception e) {
log.error("创建超级表失败,失败原因{}", e); log.error("创建超级表失败", e);
} }
} }
} catch (Exception ignored) { } catch (Exception ignored) {
@ -114,7 +114,7 @@ public class TDEngineService {
log.info(sb.toString()); log.info(sb.toString());
pstmt.executeUpdate(sb.toString()); pstmt.executeUpdate(sb.toString());
} catch (Exception e) { } catch (Exception e) {
log.error("创建超级表失败,失败原因{}", e); log.error("创建[计算量]超级表失败", e);
} }
} catch (Exception ignored) { } catch (Exception ignored) {
@ -141,7 +141,7 @@ public class TDEngineService {
try { try {
pstmt.executeUpdate(sb.toString()); pstmt.executeUpdate(sb.toString());
} catch (Exception e) { } catch (Exception e) {
log.error("新增超级表列失败:{},失败原因{}", sb, e); log.error(String.format("新增超级表列失败:%s", sb.toString()), e);
} }
} }
@ -167,7 +167,7 @@ public class TDEngineService {
try { try {
pstmt.executeUpdate(sb.toString()); pstmt.executeUpdate(sb.toString());
} catch (Exception e) { } catch (Exception e) {
log.error("删除超级表列失败:{},失败原因{}", sb, e); log.error(String.format("删除超级表列失败:%s", sb.toString()), e);
} }
} catch (Exception ignored) { } catch (Exception ignored) {
@ -189,7 +189,7 @@ public class TDEngineService {
try { try {
pstmt.executeUpdate(sb.toString()); pstmt.executeUpdate(sb.toString());
} catch (Exception e) { } catch (Exception e) {
log.error("删除超级表失败:{},失败原因{}", sb, e); log.error(String.format("删除超级表失败:%s", sb.toString()), e);
} }
} catch (Exception ignored) { } catch (Exception ignored) {
@ -963,7 +963,7 @@ public class TDEngineService {
Statement pstmt = conn.createStatement()) { Statement pstmt = conn.createStatement()) {
pstmt.executeUpdate(sb.toString()); pstmt.executeUpdate(sb.toString());
} catch (Exception e) { } catch (Exception e) {
log.error("新增超级表列失败:{},失败原因{}", sb, e); log.error(String.format("新增超级表列失败:%s", sb.toString()), e);
} }
} }

View File

@ -123,7 +123,7 @@ public class DataServiceImpl implements DataService {
} }
}); });
long end = System.currentTimeMillis(); long end = System.currentTimeMillis();
log.debug("读取快照{}个,耗时: {}秒", paramList.size(), (end - start) / 1000.0); log.debug("querySnapshotValues {}个,耗时: {}秒", paramList.size(), (end - start) / 1000.0);
return result; return result;
} }
@ -149,7 +149,7 @@ public class DataServiceImpl implements DataService {
result.putAll(values); result.putAll(values);
} }
Long end = System.currentTimeMillis(); Long end = System.currentTimeMillis();
log.debug("读取快照{}个,耗时: {}秒", param.getDevices().size(), (end-start)/ 1000.0); log.debug("queryTimeSeriesValues {}个,耗时: {}秒", param.getDevices().size(), (end-start)/ 1000.0);
return result; return result;
} }
@ -178,7 +178,7 @@ public class DataServiceImpl implements DataService {
result.putAll(values); result.putAll(values);
} }
Long end = System.currentTimeMillis(); Long end = System.currentTimeMillis();
log.debug("读取快照{}个,耗时: {}秒", param.getDevices().size(), (end-start)/ 1000.0); log.debug("queryTimeSeriesValues {}个,耗时: {}秒", param.getDevices().size(), (end-start)/ 1000.0);
return result; return result;
} }

View File

@ -123,7 +123,7 @@ public class MinioViewsServcie {
.stream(inputStream, inputStream.available(), -1) .stream(inputStream, inputStream.available(), -1)
.build()); .build());
}catch (Exception e){ }catch (Exception e){
log.error("minio文件上传失败{}", e); log.error("minio文件上传失败", e);
} }
} }

View File

@ -128,6 +128,9 @@ public class FaultRecorderServiceImpl implements FaultRecorderService {
queryWrapper.eq("madeinfactory",madeinfactory); queryWrapper.eq("madeinfactory",madeinfactory);
queryWrapper.eq("MODEL",model); queryWrapper.eq("MODEL",model);
TheoreticalPowerCurveEntity theoreticalPowerCurveEntity = theoreticalPowerCurveMapper.selectOne(queryWrapper); TheoreticalPowerCurveEntity theoreticalPowerCurveEntity = theoreticalPowerCurveMapper.selectOne(queryWrapper);
if (theoreticalPowerCurveEntity == null) {
return Collections.emptyList();
}
QueryWrapper<SysFaultCodeDict> sysFaultCodeDictQueryWrapper = new QueryWrapper<>(); QueryWrapper<SysFaultCodeDict> sysFaultCodeDictQueryWrapper = new QueryWrapper<>();
sysFaultCodeDictQueryWrapper.eq("parent",theoreticalPowerCurveEntity.getId()); sysFaultCodeDictQueryWrapper.eq("parent",theoreticalPowerCurveEntity.getId());
sysFaultCodeDictQueryWrapper.orderByAsc("code"); sysFaultCodeDictQueryWrapper.orderByAsc("code");
@ -191,7 +194,7 @@ public class FaultRecorderServiceImpl implements FaultRecorderService {
resultMap = parseFile(fileStream, fdrFormatVo.getTimeFormat(), fdrFormatVo.getDelimiter(), fdrFormatVo.getValidStartLine()); resultMap = parseFile(fileStream, fdrFormatVo.getTimeFormat(), fdrFormatVo.getDelimiter(), fdrFormatVo.getValidStartLine());
} catch (Exception e) { } catch (Exception e) {
log.error("文件解析异常{}",e); log.error("文件解析异常",e);
throw new ServiceException("文件解析异常,请检查配置"); throw new ServiceException("文件解析异常,请检查配置");
} }
return resultMap; return resultMap;
@ -235,7 +238,7 @@ public class FaultRecorderServiceImpl implements FaultRecorderService {
} }
stringListMap = parseDataCurve(result, timeFormat); stringListMap = parseDataCurve(result, timeFormat);
} catch (Exception e) { } catch (Exception e) {
log.error("文件解析失败{}", e); log.error("文件解析失败", e);
throw new ServiceException("文件解析失败"); throw new ServiceException("文件解析失败");
} }
return stringListMap; return stringListMap;

View File

@ -407,7 +407,7 @@ public class NodeMessageServiceImpl extends TextWebSocketHandler implements Node
try { try {
tdEngineService.updateDeviceEventValues(valueList); tdEngineService.updateDeviceEventValues(valueList);
} catch (Exception e) { } catch (Exception e) {
log.error("事件信息存入Td失败,失败原因{}", e); log.error("事件信息存入Td失败,失败原因", e);
} }
} }

View File

@ -551,7 +551,7 @@ public class SysNodeServiceImpl implements SysNodeService {
}) })
.anyMatch(order -> !orderSet.add(order)); .anyMatch(order -> !orderSet.add(order));
}catch (Exception e){ }catch (Exception e){
log.error("校验order不重复失败:{}",e); log.error("校验order不重复失败",e);
} }
return orderRepeated; return orderRepeated;
} }

View File

@ -86,7 +86,7 @@ public class PlcLogsServiceImpl implements PlcLogService {
resultMap = parseFile(fileStream, fdrFormatVo.getTimeFormat(), fdrFormatVo.getDelimiter(), fdrFormatVo.getValidStartLine()); resultMap = parseFile(fileStream, fdrFormatVo.getTimeFormat(), fdrFormatVo.getDelimiter(), fdrFormatVo.getValidStartLine());
} catch (Exception e) { } catch (Exception e) {
log.error("文件解析异常{}",e); log.error("文件解析异常",e);
throw new ServiceException("文件解析异常,请检查配置"); throw new ServiceException("文件解析异常,请检查配置");
} }
return resultMap; return resultMap;
@ -162,7 +162,7 @@ public class PlcLogsServiceImpl implements PlcLogService {
} }
stringListMap = parseDataCurve(result, timeFormat); stringListMap = parseDataCurve(result, timeFormat);
} catch (Exception e) { } catch (Exception e) {
log.error("文件解析失败{}", e); log.error("文件解析失败", e);
throw new ServiceException("文件解析失败"); throw new ServiceException("文件解析失败");
} }
return stringListMap; return stringListMap;

View File

@ -0,0 +1,18 @@
import { defineStore } from 'pinia'
import type { Faults } from '/@/stores/interface'
export const useFaultsStore = defineStore('faults', {
state: (): Faults => ({
data: {},
keys: []
}),
actions: {
setData(data: Faults['data']) {
this.data = data
},
setKeys(keys: string[]) {
this.keys = keys
}
},
persist: true
})

View File

@ -135,3 +135,9 @@ export interface Enums {
} }
keys: string[] keys: string[]
} }
export interface Faults {
data: {
[key: string]: { [k: string]: string }
}
keys: string[]
}

View File

@ -59,11 +59,16 @@
</div> </div>
</div> </div>
<!--功率趋势--> <!--温度-->
<div class="power"> <div class="temperatureList">
<div class="cardLabel">功率趋势</div> <div class="chartPart-item" @click="openTemperature">
<div class="chartBox"> <div class="chartParm" ref="temperatureChartRef1"></div>
<div class="power-chart" ref="powerChartRef"></div> </div>
<div class="chartPart-item" @click="openTemperature">
<div class="chartParm" ref="temperatureChartRef2"></div>
</div>
<div class="chartPart-item" @click="openTemperature">
<div class="chartParm" ref="temperatureChartRef3"></div>
</div> </div>
</div> </div>
</div> </div>
@ -137,16 +142,12 @@
<div @click="openSubSystem(11)" class="dot index-12"></div> <div @click="openSubSystem(11)" class="dot index-12"></div>
</el-tooltip> </el-tooltip>
</div> </div>
<!-- 温度 --> <!-- 功率趋势 -->
<div class="chartPart"> <div class="chartPart">
<div class="chartPart-item" @click="openTemperature"> <div class="power">
<div class="chartParm" ref="temperatureChartRef1"></div> <div class="chartBox">
<div class="power-chart" ref="powerChartRef"></div>
</div> </div>
<div class="chartPart-item" @click="openTemperature">
<div class="chartParm" ref="temperatureChartRef2"></div>
</div>
<div class="chartPart-item" @click="openTemperature">
<div class="chartParm" ref="temperatureChartRef3"></div>
</div> </div>
<div class="chartPart-item item_bar"> <div class="chartPart-item item_bar">
<div class="frequencyChart" ref="frequencyChartRef"></div> <div class="frequencyChart" ref="frequencyChartRef"></div>
@ -382,8 +383,18 @@ const initpowerChart = () => {
const powerChart = state.charts.powerChart ?? echarts.init(powerChartRef.value as unknown as HTMLElement) const powerChart = state.charts.powerChart ?? echarts.init(powerChartRef.value as unknown as HTMLElement)
const option = { const option = {
title: {
show: true,
text: '功率趋势',
textStyle: {
color: '#4E5969',
fontSize: 14,
fontFamily: 'PingFangSC-Semibold',
},
padding: 10,
},
grid: { grid: {
top: 50, top: 70,
right: 23, right: 23,
bottom: 10, bottom: 10,
left: 18, left: 18,
@ -485,6 +496,7 @@ const initpowerChart = () => {
textStyle: { textStyle: {
color: '#73767a', color: '#73767a',
}, },
top: 20,
}, },
series: [ series: [
{ {
@ -715,17 +727,21 @@ const initTemperatureChart = () => {
const option = { const option = {
grid: { grid: {
top: 30, top: 30,
//right: 100, right: 5,
bottom: 0, bottom: 0,
left: -100, left: -100,
containLabel: true, containLabel: true,
}, },
xAxis: { xAxis: {
type: 'category', // type: 'category',
type: 'value',
show: false, show: false,
}, },
yAxis: { yAxis: {
type: 'value', // type: 'value',
type: 'category',
show: false, show: false,
}, },
series: [ series: [
@ -735,8 +751,9 @@ const initTemperatureChart = () => {
type: 'bar', type: 'bar',
label: { label: {
show: true, show: true,
align: 'center', align: 'left',
formatter: `{a|{c}}\n{b|{a}}`, // verticalAlign:'top',
formatter: `{b|{a}} {a|{c}}`,
rich: { rich: {
a: { a: {
color: '#333333', color: '#333333',
@ -747,12 +764,14 @@ const initTemperatureChart = () => {
fontSize: 14, fontSize: 14,
}, },
}, },
position: 'insideBottom', width: 100,
offset: [62, 0], height: 22,
position: 'insideLeft',
offset: [85, -22],
}, },
itemStyle: { itemStyle: {
color: '#048bd2', color: '#048bd2',
borderRadius: [0, 0, 4, 4], borderRadius: [0, 4, 4, 0],
}, },
barWidth: 20, barWidth: 20,
}, },
@ -835,7 +854,7 @@ const initFrequencyChart = () => {
fontSize: 14, fontSize: 14,
fontFamily: 'PingFangSC-Semibold', fontFamily: 'PingFangSC-Semibold',
}, },
padding: 15, padding: 10,
}, },
], ],
polar: { polar: {
@ -1241,8 +1260,9 @@ const getThisDayChartDataForMinute = () => {
const getAllChartData = (type: ('power' | 'trend' | 'frequency')[] = ['power', 'trend', 'frequency']) => { const getAllChartData = (type: ('power' | 'trend' | 'frequency')[] = ['power', 'trend', 'frequency']) => {
if (type.includes('power')) { if (type.includes('power')) {
getThisDayChartData().then(() => { getThisDayChartData().then(() => {
nextTick(() => {
initpowerChart() initpowerChart()
// initTemperatureChart() })
}) })
} }
// if (type.includes('trend')) { // if (type.includes('trend')) {
@ -1254,8 +1274,10 @@ const getAllChartData = (type: ('power' | 'trend' | 'frequency')[] = ['power', '
// } // }
if (type.includes('frequency')) { if (type.includes('frequency')) {
getThisDayChartDataForMinute().then((res) => { getThisDayChartDataForMinute().then((res) => {
nextTick(() => {
initFrequencyChart() initFrequencyChart()
}) })
})
} }
} }
@ -1609,23 +1631,50 @@ $labelHeight: 24px;
} }
} }
} }
.power { .temperatureList {
@include cardDefaultStyle; @include cardDefaultStyle;
@include cardlabel; @include cardlabel;
display: flex;
flex-direction: column;
justify-content: space-around;
margin: 10px 0; margin: 10px 0;
width: 100%; width: 100%;
height: calc(40% - 20px); height: calc(40% - 20px);
// min-height: 285px; .chartPart-item {
// height: v-bind('computedHeight.powerHeight'); // margin: 5px 0;
.chartBox {
width: 100%; width: 100%;
height: calc(100% - $labelHeight); height: calc(33.3% - 10px);
.power-chart { background: #f0f6ff;
border-radius: 8px;
// text-align: center;
color: #4e5969;
.chartParm {
width: 100%;
height: 100%;
}
.frequencyChart {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
} }
// .power {
// @include cardDefaultStyle;
// @include cardlabel;
// margin: 10px 0;
// width: 100%;
// height: calc(40% - 20px);
// // min-height: 285px;
// // height: v-bind('computedHeight.powerHeight');
// .chartBox {
// width: 100%;
// height: calc(100% - $labelHeight);
// .power-chart {
// width: 100%;
// height: 100%;
// }
// }
// }
} }
.cardContentCenter { .cardContentCenter {
@include cardDefaultStyle; @include cardDefaultStyle;
@ -1846,18 +1895,29 @@ $labelHeight: 24px;
&:hover { &:hover {
cursor: pointer; cursor: pointer;
} }
.chartPart-item { .power {
margin: 5px; margin-bottom: 5px;
width: 25%; width: 60%;
height: 100%; height: 100%;
background: #f0f6ff; background-color: #f0f6ff;
border-radius: 8px; border-radius: 8px;
// text-align: center; .chartBox {
color: #4e5969; width: 100%;
.chartParm { height: 100%;
.power-chart {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
}
}
.chartPart-item {
margin: 0 0 5px 5px;
// width: 25%;
height: 100%;
background: #f0f6ff;
border-radius: 8px;
color: #4e5969;
.frequencyChart { .frequencyChart {
width: 100%; width: 100%;
height: 100%; height: 100%;

View File

@ -23,14 +23,14 @@
<div class="small-base">实时无功:<span>{{ realData.attributeMap.windfarmreactivepower}}kVar</span></div> <div class="small-base">实时无功:<span>{{ realData.attributeMap.windfarmreactivepower}}kVar</span></div>
<div class="small-base">日发电量:<span>{{ realData.attributeMap.windfarmdayprodenergy}}万kWh</span></div> <div class="small-base">日发电量:<span>{{ realData.attributeMap.windfarmdayprodenergy}}万kWh</span></div>
<div class="small-base">月发电量:<span>{{ realData.attributeMap.windfarmmonthprodenergy}}万kWh</span></div> <div class="small-base">月发电量:<span>{{ realData.attributeMap.windfarmmonthprodenergy}}万kWh</span></div>
<div class="small-base">年发电量:<span>{{ realData.attributeMap.windfarmyearprodenergy}}万kWh</span></div> <div style="padding: 0;" class="small-base">年发电量:<span>{{ realData.attributeMap.windfarmyearprodenergy}}万kWh</span></div>
</div> </div>
<div class="overviewItem" style="border: none;"> <div class="overviewItem" style="border: none;">
<div class="small-base">并网:<span>{{ realData.attributeMap.turbinecountpowerprod}}</span></div> <div class="small-base"><i class="powerprod"></i>并网:<span>{{ realData.attributeMap.turbinecountpowerprod}}</span></div>
<div class="small-base">停机/待机:<span>{{ realData.attributeMap.turbinecountidle}}</span></div> <div class="small-base"><i class="idle"></i>停机/待机:<span>{{ realData.attributeMap.turbinecountidle}}</span></div>
<div class="small-base">故障:<span>{{ realData.attributeMap.turbinecountfaulted}}</span></div> <div class="small-base"><i class="faulted"></i>故障:<span>{{ realData.attributeMap.turbinecountfaulted}}</span></div>
<div class="small-base">维护:<span>{{ realData.attributeMap.turbinecountservice}}</span></div> <div class="small-base"><i class="service"></i>维护:<span>{{ realData.attributeMap.turbinecountservice}}</span></div>
<div style="padding: 0;" class="small-base">无通讯:<span>{{ realData.attributeMap.turbinecountdisconnected}}</span></div> <div style="padding: 0;" class="small-base"><i class="disconnected"></i>无通讯:<span>{{ realData.attributeMap.turbinecountdisconnected}}</span></div>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -58,16 +58,18 @@ import { useRoute } from 'vue-router'
import { getParamList } from '/@/api/backend/SystemParam/request' import { getParamList } from '/@/api/backend/SystemParam/request'
import { queryfaultCodeDict } from '/@/api/backend/theoreticalpowerCurve/request' import { queryfaultCodeDict } from '/@/api/backend/theoreticalpowerCurve/request'
import { useEnumStore } from '/@/stores/enums' import { useEnumStore } from '/@/stores/enums'
import { useFaultsStore } from '/@/stores/faults'
import {equipList} from "/@/api/backend/realData/request"; import {equipList} from "/@/api/backend/realData/request";
const route = useRoute() const route = useRoute()
const enumStore = useEnumStore() const enumStore = useEnumStore()
const faultCodeDict = useFaultsStore()
const d = new Date() const d = new Date()
const { t } = useI18n() const { t } = useI18n()
let timer: any = null let timer: any = null
let myTable = ref<TableInstance>() let myTable = ref<TableInstance>()
const windList=ref([])
const overviewSlotData= ref('') const overviewSlotData= ref('')
@ -235,13 +237,17 @@ const StatusListData = () => {
let color:any='' let color:any=''
const state = getRealTimeState(item.attributeMap) const state = getRealTimeState(item.attributeMap)
let firsttriggeredcode=item.attributeMap.firsttriggeredcode let firsttriggeredcode=item.attributeMap.firsttriggeredcode
const key = `${item.madeinFactory}-${item.model}`;
if (enumStore.keys.includes('FirstTriggeredCode')) { if (enumStore.keys.includes('FirstTriggeredCode')) {
firsttriggeredcode = enumStore.data['FirstTriggeredCode'][firsttriggeredcode] firsttriggeredcode = enumStore.data['FirstTriggeredCode'][firsttriggeredcode]
} }
/*if (malFunctionKeys.includes('FirstTriggeredCode')) { if (faultCodeDict.keys.includes(key)) {
firsttriggeredcode = malFunctionEnums?.[firsttriggeredcode] ?? firsttriggeredcode if (firsttriggeredcode == 0) {
firsttriggeredcode = '';
} else {
firsttriggeredcode = faultCodeDict.data[key][firsttriggeredcode] ?? '';
}
} }
*/
paramColorData.value.forEach((item, index) => { paramColorData.value.forEach((item, index) => {
if (item.state == state) { if (item.state == state) {
color = item.color color = item.color
@ -345,7 +351,6 @@ const StatusListData = () => {
locked: item.attributeMap.locked, locked: item.attributeMap.locked,
irotorspeed: item.attributeMap.irotorspeed, irotorspeed: item.attributeMap.irotorspeed,
firsttriggeredcode:firsttriggeredcode, firsttriggeredcode:firsttriggeredcode,
//firsttriggeredcode:item.attributeMap.firsttriggeredcode,
}, },
} }
}) })
@ -358,53 +363,34 @@ const StatusListData = () => {
} }
}) })
} }
let malFunctionEnums: any = {} //
/*const getMalfunctionEnums = () => { /*const malFunctionEnums = ref<{ [key: string]: { [code: string]: string } }>({});
windList.value.forEach((item)=> {
console.log({madeinfactory: item.madeinfactory, model: item.model })
queryfaultCodeDict({madeinfactory: item.madeinfactory, model: item.model }).then((res) => {
if (res.code == 200) {
const data: any = {}
res.data.forEach((item: any) => {
data[item.code] = item.description
})
malFunctionEnums = data
} else {
console.warn('查询故障代码字典失败:', res.message);
}
})
})
}*/ const requestedParams = new Set<string>();
const failedRequests = new Set<string>();
/*const requestedParams = new Set<string>();
const fetchData = async (item: any) => { const fetchData = async (item: any) => {
//
const key = `${item.madeinFactory}-${item.model}`; const key = `${item.madeinFactory}-${item.model}`;
// Set
if (requestedParams.has(key)) { if (requestedParams.has(key)) {
console.log('Duplicate request detected, skipping...');
return; return;
} }
// Set
requestedParams.add(key); requestedParams.add(key);
try { try {
console.log({ madeinfactory: item.madeinFactory, model: item.model })
const response = await queryfaultCodeDict({ madeinfactory: item.madeinFactory, model: item.model }); const response = await queryfaultCodeDict({ madeinfactory: item.madeinFactory, model: item.model });
if (response.code === 200) { if (response.code === 200) {
const data: any = {}; const data: any = {};
response.data.forEach((item: any) => { response.data.forEach((item: any) => {
data[item.code] = item.description; data[item.code] = item.description;
}); });
malFunctionEnums = data; malFunctionEnums.value[key] = data;
} else { } else {
console.warn('查询故障代码字典失败:', response.message); console.warn('查询故障代码字典失败:', response.message);
failedRequests.add(key);
} }
} catch (error) { } catch (error) {
console.error('请求出错:', error); failedRequests.add(key);
} }
};*/ };*/
@ -445,14 +431,6 @@ onMounted(() => {
res.data.map((item: any) => { res.data.map((item: any) => {
deviceCode.value.push(item.code) deviceCode.value.push(item.code)
}) })
windList.value=res.data.map((item: any) => {
//fetchData(item)
return {
madeinfactory:item.madeinFactory,
model: item.model ?? '-',
}
})
//getMalfunctionEnums()
}) })
overviewList() overviewList()
@ -535,40 +513,69 @@ $labelHeight: 30px;
height: v-bind('computedHeight.centerHeight'); height: v-bind('computedHeight.centerHeight');
margin-bottom: 0; margin-bottom: 0;
.el-scrollbar { .el-scrollbar {
height: calc(100% - 20px); height: calc(100% - 50px);
} }
.homeHeader{ .homeHeader{
display: flex; display: flex;
justify-content: space-between; justify-content: flex-start;
/*justify-content: space-between;*/
.cardLabel{ .cardLabel{
margin-right: 10px; margin-right: 10px;
white-space: nowrap; white-space: nowrap;
display: flex;
justify-content: center;
align-items: center;
vertical-align: middle
} }
.cardBtn{ .cardBtn{
white-space: nowrap; white-space: nowrap;
:deep(.el-radio-group){ :deep(.el-radio-group){
flex-wrap: nowrap; flex-wrap: nowrap;
} }
:deep(.el-radio){ :deep(.el-radio){
margin-right: 12px; margin-right: 10px;
} }
} }
.headerRight{ .headerRight{
width: 100%; /*width: 100%;*/
margin-left: auto;
text-align: right;
display: flex; display: flex;
background: #F0F6FF; background: #F0F6FF;
border-radius: 8px; border-radius: 8px;
line-height: 30px; line-height: 30px;
padding: 0 10px; padding: 0 10px;
.overviewItem{ .overviewItem{
display: inline-block;
.small-base{ .small-base{
display: inline-block; display: inline-block;
padding-right: 8px; padding-right: 15px;
color: #4E5969; color: #4E5969;
i{
width: 10px;
height: 10px;
aspect-ratio: 1 / 1;
border-radius: 50%;
display: inline-block;
margin-right: 5px;
}
.powerprod{
background-color: #0277B3;
}
.idle{
background-color: #FFB600;
}
.faulted{
background-color: #FE3731;
}
.service{
background-color: #00A096;
}
.disconnected{
background-color: #999999;
}
span{ span{
color: #000000; color: #000000;
font-weight: 600;
} }
} }
} }

View File

@ -1,8 +1,9 @@
<template> <template>
<div class="FanList-content"> <div class="FanList-content">
<el-row :gutter="10"> <!-- <el-row :gutter="10">
<el-col :xs="12" :sm="8" :md="8" :lg="4" :xl="3" v-for="item in props.parentData" style="margin-bottom: 5px"> <el-col :xs="12" :sm="8" :md="8" :lg="4" :xl="3" v-for="item in props.parentData" style="margin-bottom: 5px">-->
<div class="grid-content ep-bg-purple" <div class="overviewPart" v-for="item in props.parentData">
<div class="grid-content"
@click="handleClick(item)" @click="handleClick(item)"
@contextmenu.prevent="windContextMenu($event,item)" @contextmenu.prevent="windContextMenu($event,item)"
> >
@ -37,9 +38,40 @@
>通讯中断</el-tag> >通讯中断</el-tag>
</div> </div>
<div class="fanlist-main"> <div class="fanlist-main">
<WindContentleft :item="item" v-if="item.layout==='风格1'"></WindContentleft> <el-row>
<WindContentright :item="item" v-else-if="item.layout==='风格2'"></WindContentright> <el-col :span="24">
<WindContentcenter :item="item" v-else-if="item.layout==='风格3'"></WindContentcenter> <div class="fanlist-pic">
<div class="mask">
<div class="heart"><img :src="getSafeImagePath(item, 'heart')" alt="" /></div>
<div class="leafs" :style="getAnimationStyle(item)">
<div class="leaf_1"><img :src="getSafeImagePath(item, 'leaf')" alt="" /></div>
<div class="leaf_2"><img :src="getSafeImagePath(item, 'leaf')" alt="" /></div>
<div class="leaf_3"><img :src="getSafeImagePath(item, 'leaf')" alt="" /></div>
</div>
</div>
</div>
<div class="fanlist-pic">
<img :src="getSafeImagePath(item, 'fan')" alt="" />
</div>
<!-- <div class="fanlist-pic" style="margin: 0;">
<img src="~assets/dashboard/fannew/base.png" alt="" />
</div>-->
</el-col>
</el-row>
<el-row class="fanlist-data">
<div class="fanlist-text">
<span class="content-number">{{ item.attributeMap.iwindspeed }}</span>
<span>m/s</span>
</div>
<div class="fanlist-text">
<span class="content-number">{{ item.attributeMap.igenpower }}</span>
<span>kW</span>
</div>
<div class="fanlist-text">
<span class="content-number">{{ item.attributeMap.ikwhthisday }}</span>
<span>kWh</span>
</div>
</el-row>
</div> </div>
<div class="fanlist-bottom"> <div class="fanlist-bottom">
<!-- <el-tag class="tag-panel is-danger">已锁定</el-tag>--> <!-- <el-tag class="tag-panel is-danger">已锁定</el-tag>-->
@ -48,8 +80,9 @@
</div> </div>
</div> </div>
</el-col> </div>
</el-row> <!-- </el-col>
</el-row>-->
<ContextMenu :pos="contextMenuPos" v-model:visible="OperateVisible"> <ContextMenu :pos="contextMenuPos" v-model:visible="OperateVisible">
<template #default> <template #default>
@ -105,6 +138,31 @@ const props = defineProps({
default: () => [], default: () => [],
}, },
}) })
const getAnimationStyle = (item) => {
const irotorspeed = item.attributeMap?.irotorspeed ?? 0
let animationDuration;
animationDuration = 60 / irotorspeed / 3
const processedoperationmode = item.attributeMap?.processedoperationmode ?? 0
if(processedoperationmode==33){
return {
'animation-duration': `0s`,
'animation-timing-function': 'linear',
'animation-iteration-count': 'infinite',
'animation-direction': 'normaL',
}
}else{
return {
'animation-duration': `${animationDuration}s`,
'animation-timing-function': 'linear',
'animation-iteration-count': 'infinite',
'animation-direction': 'normaL',
}
}
}
const handleClick = (row) => { const handleClick = (row) => {
if (!router.hasRoute('windTurbine')) { if (!router.hasRoute('windTurbine')) {
router.addRoute('admin', { router.addRoute('admin', {
@ -264,6 +322,92 @@ const hexToRgba = (hex, alpha) => {
} }
return `rgba(${r}, ${g}, ${b}, ${alpha})`; return `rgba(${r}, ${g}, ${b}, ${alpha})`;
} }
const imagePathMap = {
'#9C27B0': {
heart: 'heart1.png',
leaf: 'leaf1.png',
fan: 'fan1.png',
},
'#673AB7': {
heart: 'heart2.png',
leaf: 'leaf2.png',
fan: 'fan2.png',
},
'#3F51B5': {
heart: 'heart3.png',
leaf: 'leaf3.png',
fan: 'fan3.png',
},
'#3059EC': {
heart: 'heart4.png',
leaf: 'leaf4.png',
fan: 'fan4.png',
},
'#0277B3': {
heart: 'heart5.png',
leaf: 'leaf5.png',
fan: 'fan5.png',
},
'#00A096': {
heart: 'heart6.png',
leaf: 'leaf6.png',
fan: 'fan6.png',
},
'#06B429': {
heart: 'heart7.png',
leaf: 'leaf7.png',
fan: 'fan7.png',
},
'#64DD17': {
heart: 'heart8.png',
leaf: 'leaf8.png',
fan: 'fan8.png',
},
'#EEFF41': {
heart: 'heart9.png',
leaf: 'leaf9.png',
fan: 'fan9.png',
},
'#FFB600': {
heart: 'heart10.png',
leaf: 'leaf10.png',
fan: 'fan10.png',
},
'#FF7E00': {
heart: 'heart11.png',
leaf: 'leaf11.png',
fan: 'fan11.png',
},
'#FE3731': {
heart: 'heart12.png',
leaf: 'leaf12.png',
fan: 'fan12.png',
},
'#999999': {
heart: 'heart13.png',
leaf: 'leaf13.png',
fan: 'fan13.png',
}
};
const getImagePath = (item, type) => {
const color = item.attributeMap.color;
return imagePathMap[color]?.[type];
};
const getSafeImagePath = (item, type) => {
const path = getImagePath(item, type);
if (!getSafeImagePath.cache) {
getSafeImagePath.cache = {};
}
if (getSafeImagePath.cache[path]) {
return getSafeImagePath.cache[path];
}
const imagePath = new URL(`/src/assets/dashboard/fan/${path}`, import.meta.url).href;
getSafeImagePath.cache[path] = imagePath;
return imagePath;
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@ -312,6 +456,16 @@ const hexToRgba = (hex, alpha) => {
} }
.FanList-content { .FanList-content {
overflow-x: hidden; overflow-x: hidden;
display: grid;
justify-content: space-between;
grid-template-columns: repeat(auto-fill, 170px);
.overviewPart{
display: flex;
box-sizing: border-box;
width: 170px;
height: 140px;
margin-top: 8px;
margin-bottom: 8px;
.FanList-panel { .FanList-panel {
border-radius: 8px; border-radius: 8px;
cursor: pointer; cursor: pointer;
@ -455,6 +609,7 @@ const hexToRgba = (hex, alpha) => {
} }
} }
} }
}
.modelOperate{ .modelOperate{
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -11,7 +11,6 @@
'': item.standard==0, '': item.standard==0,
'wind-offline': item.attributeMap.processedoperationmode == 33 'wind-offline': item.attributeMap.processedoperationmode == 33
}"> }">
<div class="fanlist-top"> <div class="fanlist-top">
<span :class="item.standard == 1 ? 'wind-mark-icon' : 'fanlist-icon'"> <span :class="item.standard == 1 ? 'wind-mark-icon' : 'fanlist-icon'">
<img :class="item.standard == 1 ? '' : 'wind-picture'" src="~assets/dashboard/biaogan.png" alt="" /> <img :class="item.standard == 1 ? '' : 'wind-picture'" src="~assets/dashboard/biaogan.png" alt="" />
@ -69,12 +68,12 @@
</el-row> </el-row>
</div> </div>
<div class="fanlist-bottom"> <div class="fanlist-bottom">
<!-- <span :style="item.attributeMap.locked == 1 ? 'max-width:120px;' : 'max-width:150px;'">
{{ item.attributeMap.firsttriggeredcode }}
</span>-->
<span :style="item.attributeMap.locked == 1 ? 'max-width:120px;' : 'max-width:150px;'"> <span :style="item.attributeMap.locked == 1 ? 'max-width:120px;' : 'max-width:150px;'">
{{ getFaultDescription(item) }} {{ item.attributeMap.firsttriggeredcode }}
</span> </span>
<!-- <span :style="item.attributeMap.locked == 1 ? 'max-width:120px;' : 'max-width:150px;'">
{{ getFaultDescription(item) }}
</span>-->
<!-- <el-tag class="tag-panel is-danger">已锁定</el-tag>--> <!-- <el-tag class="tag-panel is-danger">已锁定</el-tag>-->
<el-tag v-if="item.attributeMap.locked === 1" class="tag-panel is-danger">已锁定</el-tag> <el-tag v-if="item.attributeMap.locked === 1" class="tag-panel is-danger">已锁定</el-tag>
</div> </div>
@ -411,59 +410,58 @@ const getSafeImagePath = (item, type) => {
return imagePath; return imagePath;
}; };
const getFaultDescription=(item)=>{
//getMalfunctionEnums(item) /*const getFaultDescription=(item)=>{
fetchData(item) const key = `${item.madeinFactory}-${item.model}`;
let firsttriggeredcode=item.attributeMap.firsttriggeredcode if (failedRequests.has(key)) {
if (malFunctionKeys.includes('FirstTriggeredCode')) { return '';
firsttriggeredcode = malFunctionEnums?.[firsttriggeredcode] ?? firsttriggeredcode
} }
return firsttriggeredcode
if (!malFunctionEnums[key]) {
fetchData(item); //
// return item.attributeMap.firsttriggeredcode;
}
let firsttriggeredcode = item.attributeMap.firsttriggeredcode;
if (malFunctionKeys.includes('FirstTriggeredCode') && malFunctionEnums[key]) {
if(firsttriggeredcode==0){
return ''
}else{
firsttriggeredcode = malFunctionEnums[key][firsttriggeredcode] ?? '';
}
}
return firsttriggeredcode;
} }
let malFunctionEnums: any = {} let malFunctionEnums: { [key: string]: { [code: string]: string } } = {};
/*const getMalfunctionEnums = (item) => {
/!*queryfaultCodeDict({ madeinfactory: item!.madeinFactory, model: item!.model }).then((res) => {*!/
queryfaultCodeDict({ madeinfactory: '广东明阳风电', model: 'MY1.5/89' }).then((res) => {
if (res.code == 200) {
const data: any = {}
res.data.forEach((item: any) => {
data[item.code] = item.description
})
malFunctionEnums = data
} else {
console.warn('查询故障代码字典失败:', res.message);
}
})
}*/
const requestedParams = new Set<string>(); const requestedParams = new Set<string>();
const failedRequests = new Set<string>();
const fetchData = async (item: any) => { const fetchData = async (item: any) => {
const key = `${item.madeinFactory}-${item.model}`; const key = `${item.madeinFactory}-${item.model}`;
if (requestedParams.has(key)) { if (requestedParams.has(key)) {
console.log('Duplicate request detected, skipping...');
return; return;
} }
requestedParams.add(key); requestedParams.add(key);
try { try {
malFunctionEnums={}
const response = await queryfaultCodeDict({ madeinfactory: item.madeinFactory, model: item.model }); const response = await queryfaultCodeDict({ madeinfactory: item.madeinFactory, model: item.model });
if (response.code === 200) { if (response.code === 200) {
const data: any = {}; const data: any = {};
response.data.forEach((item: any) => { response.data.forEach((item: any) => {
data[item.code] = item.description; data[item.code] = item.description;
}); });
malFunctionEnums = data; malFunctionEnums[key] = data;
} else { } else {
console.warn('查询故障代码字典失败:', response.message); console.warn('查询故障代码字典失败:', response.message);
failedRequests.add(key);
} }
} catch (error) { } catch (error) {
console.error('请求出错:', error); failedRequests.add(key);
} }
}; };*/
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@ -92,6 +92,7 @@ import { editDefaultLang } from '/@/lang/index'
import { useConfig } from '/@/stores/config' import { useConfig } from '/@/stores/config'
import { useAdminInfo } from '/@/stores/adminInfo' import { useAdminInfo } from '/@/stores/adminInfo'
import { useEnumStore } from '/@/stores/enums' import { useEnumStore } from '/@/stores/enums'
import {useFaultsStore} from "/@/stores/faults"
import { login } from '/@/api/backend' import { login } from '/@/api/backend'
import { buildValidatorData } from '/@/utils/validate' import { buildValidatorData } from '/@/utils/validate'
import router from '/@/router' import router from '/@/router'
@ -100,11 +101,15 @@ import toggleDark from '/@/utils/useDark'
import { fullUrl } from '/@/utils/common' import { fullUrl } from '/@/utils/common'
import { adminBaseRoutePath } from '/@/router/static/adminBase' import { adminBaseRoutePath } from '/@/router/static/adminBase'
import { getAllEnumData } from '/@/api/backend/Enumeration/request' import { getAllEnumData } from '/@/api/backend/Enumeration/request'
import {equipList} from "/@/api/backend/realData/request";
import { queryfaultCodeDict } from '/@/api/backend/theoreticalpowerCurve/request'
let timer: number let timer: number
const config = useConfig() const config = useConfig()
const adminInfo = useAdminInfo() const adminInfo = useAdminInfo()
const enumsStore = useEnumStore() const enumsStore = useEnumStore()
const FaultsStore = useFaultsStore()
const isSmall = ref(window.screen.width < 620 ? true : false) const isSmall = ref(window.screen.width < 620 ? true : false)
@ -192,7 +197,6 @@ const load = () => {
state.captcha = 'data:image\/png;base64,' + res.data.img state.captcha = 'data:image\/png;base64,' + res.data.img
}) })
} }
const getEnumsData = () => { const getEnumsData = () => {
getAllEnumData().then((res) => { getAllEnumData().then((res) => {
if (res.success) { if (res.success) {
@ -213,6 +217,49 @@ const getEnumsData = () => {
} }
}) })
} }
equipList({ objectType: 10002 }).then((res) => {
res.data.map((item: any) => {
fetchData(item)
return {
madeinfactory:item.madeinFactory,
model: item.model ?? '-',
}
})
})
const malFunctionEnums = ref<{ [key: string]: { [code: string]: string } }>({});
const requestedParams = new Set<string>();
const failedRequests = new Set<string>();
const fetchData = async (item: any) => {
const key = `${item.madeinFactory}-${item.model}`;
if (requestedParams.has(key)) {
return;
}
requestedParams.add(key);
const keys = requestedParams;
const response = await queryfaultCodeDict({ madeinfactory: item.madeinFactory, model: item.model });
if (response.code === 200) {
const data: any = {};
response.data.forEach((item: any) => {
data[item.code] = item.description;
});
malFunctionEnums.value[key] = data;
const datas=malFunctionEnums.value
sessionStorage.setItem(
'faultCodeDict',
JSON.stringify({
datas,
keys:Array.from(requestedParams),
})
)
FaultsStore.setKeys(Array.from(requestedParams))
FaultsStore.setData(datas)
} else {
console.warn('查询故障代码字典失败:', response.message);
failedRequests.add(key);
}
};
const onSubmit = () => { const onSubmit = () => {
state.submitLoading = true state.submitLoading = true