Merge remote-tracking branch 'origin/main'

This commit is contained in:
houwei 2024-11-05 18:01:20 +08:00
commit 7e17b04d71
15 changed files with 496 additions and 144 deletions

View File

@ -6,7 +6,6 @@ import lombok.Data;
@Data @Data
public class DeviceEventInfo { public class DeviceEventInfo {
@JsonSerialize(using = ToStringSerializer.class)
private Long eventTime; private Long eventTime;
@JsonSerialize(using = ToStringSerializer.class) @JsonSerialize(using = ToStringSerializer.class)
@ -22,7 +21,6 @@ public class DeviceEventInfo {
private String confirmAccount; private String confirmAccount;
@JsonSerialize(using = ToStringSerializer.class)
private Long confirmTime; private Long confirmTime;
private String deviceId; private String deviceId;

View File

@ -2,6 +2,7 @@ package com.das.modules.data.service;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.das.common.utils.PageDataInfo;
import com.das.modules.data.domain.DeviceEventInfo; import com.das.modules.data.domain.DeviceEventInfo;
import com.das.modules.data.service.impl.DataServiceImpl; import com.das.modules.data.service.impl.DataServiceImpl;
import com.das.modules.equipment.domain.vo.IotModelFieldVo; import com.das.modules.equipment.domain.vo.IotModelFieldVo;
@ -609,9 +610,10 @@ public class TDEngineService {
return result; return result;
} }
public List<DeviceEventInfo> queryEvent(Integer eventLevel, Long startTime, Long endTime, List<String> deviceCodeList) { public PageDataInfo<DeviceEventInfo> queryEvent(Integer eventLevel, Long startTime, Long endTime, List<String> deviceCodeList, Integer limit, Integer offset) {
List<DeviceEventInfo> result = new ArrayList<>(); List<DeviceEventInfo> result = new ArrayList<>();
StringBuffer sb = new StringBuffer(2048); StringBuffer sb = new StringBuffer(2048);
Integer total = 0;
sb.append("select t.* from event_info t where "); sb.append("select t.* from event_info t where ");
sb.append(String.format(" t.event_time >= %d and t.event_time < %d", startTime, endTime)); sb.append(String.format(" t.event_time >= %d and t.event_time < %d", startTime, endTime));
if (eventLevel != null) { if (eventLevel != null) {
@ -628,7 +630,13 @@ public class TDEngineService {
} }
} }
sb.append(" order by t.event_time"); sb.append(" order by t.event_time");
if (limit != null){
sb.append(" limit ").append(offset).append(",").append(limit);
total = getEventCount(eventLevel,startTime,endTime,deviceCodeList);
}
log.debug(sb.toString()); log.debug(sb.toString());
try (Connection conn = hikariDataSource.getConnection(); try (Connection conn = hikariDataSource.getConnection();
Statement smt = conn.createStatement(); Statement smt = conn.createStatement();
ResultSet rs = smt.executeQuery(sb.toString())) { ResultSet rs = smt.executeQuery(sb.toString())) {
@ -648,9 +656,42 @@ public class TDEngineService {
} }
} catch (Exception e) { } catch (Exception e) {
log.error("获取数据异常", e); log.error("获取数据异常", e);
return result; return PageDataInfo.build(result, total);
} }
return result; return PageDataInfo.build(result, total);
}
private Integer getEventCount(Integer eventLevel, Long startTime, Long endTime, List<String> deviceCodeList){
List<DeviceEventInfo> result = new ArrayList<>();
StringBuffer sb = new StringBuffer(2048);
sb.append("select count(t.*) as total from event_info t where ");
sb.append(String.format(" t.event_time >= %d and t.event_time < %d", startTime, endTime));
if (eventLevel != null) {
sb.append(String.format(" and t.event_level = %d", eventLevel));
}
if (!CollectionUtils.isEmpty(deviceCodeList)) {
sb.append(" and t.device_code in (");
for (int i = 0; i < deviceCodeList.size(); i++) {
if (i == deviceCodeList.size() - 1) {
sb.append("'").append(deviceCodeList.get(i)).append("')");
} else {
sb.append("'").append(deviceCodeList.get(i)).append("',");
}
}
}
log.debug(sb.toString());
Integer total = null;
try (Connection conn = hikariDataSource.getConnection();
Statement smt = conn.createStatement();
ResultSet rs = smt.executeQuery(sb.toString())) {
while (rs.next()) {
total = rs.getInt("total");
}
} catch (Exception e) {
log.error("获取数据异常", e);
}
return total;
} }
public void confirmEvent(DeviceEventInfo deviceEventInfo) { public void confirmEvent(DeviceEventInfo deviceEventInfo) {

View File

@ -2,6 +2,7 @@ package com.das.modules.event.controller;
import com.das.common.result.R; import com.das.common.result.R;
import com.das.common.utils.JsonUtils; import com.das.common.utils.JsonUtils;
import com.das.common.utils.PageDataInfo;
import com.das.modules.data.domain.DeviceEventInfo; import com.das.modules.data.domain.DeviceEventInfo;
import com.das.modules.event.domain.EventQueryParam; import com.das.modules.event.domain.EventQueryParam;
import com.das.modules.event.service.EventService; import com.das.modules.event.service.EventService;
@ -33,17 +34,17 @@ public class EventController {
* @return TD数据库数据 * @return TD数据库数据
*/ */
@PostMapping("/query") @PostMapping("/query")
public R<List<DeviceEventInfo>> queryEvent(@RequestBody @Valid EventQueryParam param) { public PageDataInfo<DeviceEventInfo> queryEvent(@RequestBody @Valid EventQueryParam param) {
if (log.isDebugEnabled()){ if (log.isDebugEnabled()){
log.debug("/api/event/query is calling"); log.debug("/api/event/query is calling");
log.debug(JsonUtils.toJsonString(param)); log.debug(JsonUtils.toJsonString(param));
} }
return R.success(eventService.queryEvent(param)); return eventService.queryEvent(param);
} }
/** /**
* 确认告警信息 * 确认告警信息
* @param deviceEventInfo 确认信息 * @param deviceEventInfoList 确认信息
*/ */
@PostMapping("/confirm") @PostMapping("/confirm")
public R<Void> confirmEvent(@RequestBody List<DeviceEventInfo> deviceEventInfoList){ public R<Void> confirmEvent(@RequestBody List<DeviceEventInfo> deviceEventInfoList){

View File

@ -14,12 +14,12 @@ public class EventQueryParam
/** /**
* 开始时间 * 开始时间
*/ */
private String startTime; private Long startTime;
/** /**
* 结束时间 * 结束时间
*/ */
private String endTime; private Long endTime;
/** /**
* 事件等级 * 事件等级
@ -30,4 +30,14 @@ public class EventQueryParam
* 设备编码列表 * 设备编码列表
*/ */
private List<String> deviceCode; private List<String> deviceCode;
/**
* pageNum;
*/
private Integer pageNum;
/**
* pageSize
*/
private Integer pageSize;
} }

View File

@ -1,5 +1,6 @@
package com.das.modules.event.service; package com.das.modules.event.service;
import com.das.common.utils.PageDataInfo;
import com.das.modules.data.domain.DeviceEventInfo; import com.das.modules.data.domain.DeviceEventInfo;
import com.das.modules.event.domain.EventQueryParam; import com.das.modules.event.domain.EventQueryParam;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@ -7,7 +8,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import java.util.List; import java.util.List;
public interface EventService { public interface EventService {
List<DeviceEventInfo> queryEvent(EventQueryParam param); PageDataInfo<DeviceEventInfo> queryEvent(EventQueryParam param);
void confirmEvent(List<DeviceEventInfo> deviceEventInfoList); void confirmEvent(List<DeviceEventInfo> deviceEventInfoList);
} }

View File

@ -3,6 +3,7 @@ package com.das.modules.event.service.impl;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import com.das.common.config.SessionUtil; import com.das.common.config.SessionUtil;
import com.das.common.exceptions.ServiceException; import com.das.common.exceptions.ServiceException;
import com.das.common.utils.PageDataInfo;
import com.das.modules.auth.domain.vo.SysUserVo; import com.das.modules.auth.domain.vo.SysUserVo;
import com.das.modules.data.domain.DeviceEventInfo; import com.das.modules.data.domain.DeviceEventInfo;
import com.das.modules.data.service.TDEngineService; import com.das.modules.data.service.TDEngineService;
@ -22,11 +23,15 @@ public class EventServiceImpl implements EventService {
private TDEngineService tdEngineService; private TDEngineService tdEngineService;
@Override @Override
public List<DeviceEventInfo> queryEvent(EventQueryParam param) { public PageDataInfo<DeviceEventInfo> queryEvent(EventQueryParam param) {
if (param.getStartTime() == null || param.getEndTime() ==null){ if (param.getStartTime() == null || param.getEndTime() == null) {
throw new ServiceException("查询时间不能为空"); throw new ServiceException("查询时间不能为空");
} }
List<DeviceEventInfo> deviceEventInfos = tdEngineService.queryEvent(param.getEventLevel(), Long.valueOf(param.getStartTime()), Long.valueOf(param.getEndTime()), param.getDeviceCode()); Integer offset = null;
if (param.getPageNum() != null) {
offset = (param.getPageNum() - 1) * param.getPageSize();
}
PageDataInfo<DeviceEventInfo> deviceEventInfos = tdEngineService.queryEvent(param.getEventLevel(), param.getStartTime(), param.getEndTime(), param.getDeviceCode(), param.getPageSize(), offset);
return deviceEventInfos; return deviceEventInfos;
} }

View File

@ -7,6 +7,7 @@
- [数据字段接口](api/enumPage.md) - [数据字段接口](api/enumPage.md)
- [人工操作接口](api/operation.md) - [人工操作接口](api/operation.md)
- [页面访问接口](api/pages/) - [页面访问接口](api/pages/)
- [告警事件接口](api/event.md)
- [首页接口](api/pages/home.md) - [首页接口](api/pages/home.md)
- [数据采集](datacollect/) - [数据采集](datacollect/)
- [系统部署](deploy/) - [系统部署](deploy/)

118
docs/api/event.md Normal file
View File

@ -0,0 +1,118 @@
# 告警相关模块
## API接口一览表
| 接口分类 | 接口描述 | API接口 | 权限 |
|---------|-----------------| ------------------------------------- | --------------------------- |
| 1.1告警相关操作 | 1.1.1查询设备告警信息列表 | /api/event/query | |
| | 1.2.1确认告警信息 | /api/event/confirm | |
| | | | |
### 1.1 告警相关操作接口
#### 1.1.1查询设备告警信息列表
POST 请求接口
> /api/event/query
请求参数
```json
{
"startTime":1730778600161,
"endTime":1730779105676,
"eventLevel": 0,
"deviceCode":["A-001"],
"pageNum": 1,
"pageSize": 10
}
```
入参描述
| 参数名 | 参数类型 | 必填 | 描述 |
| ------------ |---------|-----|--------|
| startTime | Long | True | 开始时间 |
| endTime | Long | True | 结束时间 |
| eventLevel | int | False | 事件等级0告警1故障 |
| deviceCode | List | True | 设备编码数组 |
| pageNum | Integer | NO | 当前页 |
| pageSize | Integer | NO | 每页显示大小 |
返回报文
```json
{
"total": 10501,
"rows": [
{
"eventTime": 1730778601000,
"eventId": "1853647068678127617",
"eventType": 0,
"eventLevel": 0,
"eventText": "风机由于变桨系统安全链断开导致机组急停 动作",
"confirmed": 1,
"confirmAccount": "null",
"confirmTime": 1730789465314,
"deviceId": "1846101273013739522",
"deviceCode": "A-001"
},
{
"eventTime": 1730778601000,
"eventId": "1853647068678127618",
"eventType": 0,
"eventLevel": 0,
"eventText": "风机轮毂温度>60℃ 复归",
"confirmed": 0,
"confirmTime": 0,
"deviceId": "1846101273013739522",
"deviceCode": "A-001"
}
],
"code": 200,
"msg": "查询成功"
}
```
#### 1.1.2 确认告警信息
POST 请求接口
> /api/event/confirm
请求参数
```json
[
{
"eventTime": 1730778601000,
"eventId": "1853647068678127617",
"confirmed": 1,
"deviceId": "1846101273013739522"
}
]
```
入参描述
| 参数名 | 参数类型 | 必填 | 描述 |
| ------------ |---------|-----|------|
| eventTime | Long | true | 事件时间 |
| eventId | String | true | 事件id |
| confirmed | int | true | 是否确认0不确认1确认 |
| deviceId | String | true | 设备id |
返回报文
```json
{
"code": 200,
"success": true,
"msg": "操作成功"
}
```

View File

@ -4,7 +4,15 @@ import { RequestReturnRowType, GetAlarmsTableParam, AlarmsTableType } from '/@/v
// 告警列表 // 告警列表
export const getAlarmListReq = (data: GetAlarmsTableParam) => { export const getAlarmListReq = (data: GetAlarmsTableParam) => {
return createAxios<never, RequestReturnRowType<AlarmsTableType[]>>({ return createAxios<never, RequestReturnRowType<AlarmsTableType[]>>({
url: '/api/alarm/list', url: 'api/event/query',
method: 'post',
data: data,
})
}
export const eventComfirm = (data: any) => {
return createAxios<never, RequestReturnRowType<any>>({
url: '/api/event/confirm',
method: 'post', method: 'post',
data: data, data: data,
}) })

View File

@ -7,12 +7,12 @@
<el-date-picker <el-date-picker
style="height: 40px" style="height: 40px"
v-model="timeRange" v-model="timeRange"
type="daterange" type="datetimerange"
format="YYYY-MM-DD" format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD"
range-separator="-" range-separator="-"
:start-placeholder="t('alarm.selectDate')" :start-placeholder="t('alarm.selectDate')"
:end-placeholder="t('alarm.selectDate')" :end-placeholder="t('alarm.selectDate')"
:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]"
:shortcuts="shortcuts" :shortcuts="shortcuts"
/> />
<div style="width: 20px"></div> <div style="width: 20px"></div>
@ -32,16 +32,21 @@
<el-main class="mainMain"> <el-main class="mainMain">
<div class="tabsPart"> <div class="tabsPart">
<el-table :data="alarmsTableData" class="tablePart" highlight-current-row> <el-table :data="alarmsTableData" class="tablePart" highlight-current-row>
<el-table-column prop="alarmTime" :label="AlarmsFieldsEnums['alarmTime']" align="center"> </el-table-column> <el-table-column prop="eventTimeFormate" :label="AlarmsFieldsEnums['alarmTime']" align="center"> </el-table-column>
<el-table-column prop="airBlowerNumber" :label="AlarmsFieldsEnums['airBlowerNumber']" align="center"> </el-table-column> <el-table-column prop="deviceCode" :label="AlarmsFieldsEnums['airBlowerNumber']" align="center"> </el-table-column>
<el-table-column prop="faultDescription" :label="AlarmsFieldsEnums['faultDescription']" align="center"> </el-table-column> <el-table-column prop="eventText" :label="AlarmsFieldsEnums['faultDescription']" align="center"> </el-table-column>
<el-table-column prop="alarmGrade" :label="AlarmsFieldsEnums['alarmGrade']" align="center"> </el-table-column> <el-table-column prop="eventType" :label="AlarmsFieldsEnums['alarmType']" align="center">
<el-table-column prop="alarmType" :label="AlarmsFieldsEnums['alarmType']" align="center"> </el-table-column> <template #default="scope">
<div class="fault" v-if="scope.row.eventType">故障</div>
<div class="alarm" v-else>告警</div>
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center"> <el-table-column label="操作" width="200" align="center">
<template #default="scope"> <template #default="scope">
<div class="tableOperate"> <div class="tableOperate comfirmed" v-if="scope.row.confirmed">已确认</div>
<a @click="okSubmit(scope.row)">确认</a> <div class="tableOperate" v-else>
<a @click="open(scope.row)">确认</a>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@ -65,13 +70,12 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref, nextTick, onMounted } from 'vue' import { reactive, ref, onMounted } from 'vue'
import { ElMessage, TableInstance, TreeInstance } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { Search } from '@element-plus/icons-vue' import { Search } from '@element-plus/icons-vue'
import { AlarmsFieldsEnums, AlarmsTableType, GetAlarmsTableParam } from './type' import { AlarmsFieldsEnums, AlarmsTableType, GetAlarmsTableParam } from './type'
import { getAlarmListReq } from '/@/api/backend/alarms/request' import { getAlarmListReq, eventComfirm } from '/@/api/backend/alarms/request'
import { equipList } from '/@/api/backend/realData/request.ts' import { equipList } from '/@/api/backend/realData/request'
import { debounce, cloneDeep } from 'lodash'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
const { t } = useI18n() const { t } = useI18n()
import { useAdminInfo } from '/@/stores/adminInfo' import { useAdminInfo } from '/@/stores/adminInfo'
@ -79,32 +83,29 @@ const adminInfo = useAdminInfo()
// //
const timeRange = ref([]) const timeRange = ref([new Date().setHours(0, 0, 0, 0), new Date()])
const shortcuts = [ const shortcuts = [
{ {
text: '今天', text: '今天',
value: () => { value: () => {
const start = getFormattedDate(0) + ' 00:00:00'
const end = new Date() const end = new Date()
const start = new Date()
return [start, end] return [start, end]
}, },
}, },
{ {
text: '昨天', text: '昨天',
value: () => { value: () => {
const end = new Date() const start = getFormattedDate(-1) + ' 00:00:00'
end.setDate(end.getDate() - 1) const end = getFormattedDate(-1) + ' 23:59:59'
const start = new Date()
start.setDate(start.getDate() - 1)
return [start, end] return [start, end]
}, },
}, },
{ {
text: '前3天', text: '前3天',
value: () => { value: () => {
const end = new Date() const start = getFormattedDate(-3) + ' 00:00:00'
const start = new Date() const end = getFormattedDate(-1) + ' 23:59:59'
start.setDate(start.getDate() - 2)
return [start, end] return [start, end]
}, },
}, },
@ -121,6 +122,15 @@ const shortcuts = [
}, },
}, },
] ]
const getFormattedDate = (offset: number) => {
const date = new Date()
date.setDate(date.getDate() + offset)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
}
// //
const airBlowerNumberValue = ref('') const airBlowerNumberValue = ref('')
@ -128,18 +138,26 @@ const airBlowerList = ref([{ label: '', value: '' }])
// //
const alarmTypeValue = ref('') const alarmTypeValue = ref('')
const alarmTypes = ref([ const alarmTypes = ref([
{ label: '告警', value: 0 },
{ label: '故障', value: 1 }, { label: '故障', value: 1 },
{ label: '告警', value: 2 },
]) ])
const searchalarms = (): GetAlarmsTableParam => { const searchalarms = (): GetAlarmsTableParam => {
const start = timeRange.value[0] const start = timeRange.value[0]
const end = timeRange.value[1] const end = timeRange.value[1]
const deviceCode: any = []
if (airBlowerNumberValue.value.length) {
deviceCode.push(airBlowerNumberValue.value)
} else {
airBlowerList.value.forEach((item: any) => {
deviceCode.push(item.value)
})
}
return { return {
startTime: start || '', startTime: new Date(start).getTime() || new Date().setHours(0, 0, 0, 0).valueOf(),
endTime: end || '', endTime: new Date(end).getTime() || new Date().valueOf(),
airBlowerNumber: airBlowerNumberValue.value, eventLevel: alarmTypeValue.value || null,
alarmType: alarmTypeValue.value, deviceCode: deviceCode,
pageNum: paginationOptions.current, pageNum: paginationOptions.current,
pageSize: paginationOptions.pageSize, pageSize: paginationOptions.pageSize,
} }
@ -160,49 +178,74 @@ const getcurrentPage = () => {
const getalarmsList = () => { const getalarmsList = () => {
const transparams = searchalarms() const transparams = searchalarms()
console.log('🚀 ~ getalarmsList ~ transparams:', transparams) getAlarmListReq(transparams)
setTimeout(() => { .then((res: any) => {
alarmsTableData.value = [ if (res.code == 200) {
{ paginationOptions.total = res.total
alarmTime: '2024-09-30 14:08:00', alarmsTableData.value = res.rows.map((item: any) => {
airBlowerNumber: 'sc-001', return {
faultDescription: '变桨轴1处于紧急模式', ...item,
alarmGrade: '一级', eventTimeFormate: timestampToTime(item.eventTime),
alarmType: '故障', }
}, })
{ } else {
alarmTime: '2024-09-30 14:08:00', ElMessage.error(res.msg ?? '查询失败')
airBlowerNumber: 'sc-001', }
faultDescription: '变桨轴1处于紧急模式', })
alarmGrade: '一级', .catch((err) => {
alarmType: '故障', ElMessage.error(err?.response?.data?.msg ?? '查询失败')
}, })
{ }
alarmTime: '2024-09-30 14:08:00', const timestampToTime = (timestamp: any) => {
airBlowerNumber: 'sc-001', timestamp = timestamp ? timestamp : null
faultDescription: '变桨轴1处于紧急模式', let date = new Date(timestamp)
alarmGrade: '一级', let Y = date.getFullYear() + '-'
alarmType: '故障', let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'
}, let D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' '
] let h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':'
paginationOptions.total = 3 let m = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
return Y + M + D + h + m
}
const open = (val: any) => {
ElMessageBox.confirm('是否确认?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}) })
// getAlarmListReq(transparams) .then(() => {
// .then((res) => { okSubmit(val)
// if (res.rows) { })
// paginationOptions.total = res.total .catch(() => {
// } else { ElMessage({
// ElMessage.error(res.msg ?? '') type: 'info',
// } message: '取消确认',
// }) })
// .catch((err) => { })
// ElMessage.error(err?.response?.data?.msg ?? '')
// })
} }
const okSubmit = (val: any) => { const okSubmit = (val: any) => {
console.log(val) const reqData: any = [
getalarmsList() {
eventTime: val.eventTime,
eventId: val.eventId,
confirmed: 1,
deviceId: val.deviceId,
},
]
eventComfirm(reqData)
.then((res: any) => {
if (res.code == 200) {
ElMessage.success(res.msg ?? '确认成功')
getalarmsList()
} else {
ElMessage.error(res.msg ?? '查询失败')
}
})
.catch((err) => {
ElMessage.error(err?.response?.data?.msg ?? '查询失败')
})
} }
const getDateRange = (type: 'week' | 'month') => { const getDateRange = (type: 'week' | 'month') => {
const today = new Date() const today = new Date()
@ -233,13 +276,13 @@ onMounted(() => {
if (res.code == 200) { if (res.code == 200) {
airBlowerList.value = res.data.map((item: any) => { airBlowerList.value = res.data.map((item: any) => {
return { return {
label: item.code, label: item.name,
value: item.id, value: item.code,
} }
}) })
getalarmsList()
} }
}) })
getalarmsList()
}) })
</script> </script>
@ -294,6 +337,22 @@ $paginationHeight: 32px;
} }
.tablePart { .tablePart {
height: 100%; height: 100%;
.alarm {
border: 1px solid rgb(228, 161, 18);
width: fit-content;
margin: 0 auto;
padding: 5px;
border-radius: 6px;
color: rgb(228, 161, 18);
}
.fault {
border: 1px solid #a03b1d;
width: fit-content;
margin: 0 auto;
padding: 5px;
border-radius: 6px;
color: #a03b1d;
}
} }
.tableOperate { .tableOperate {
display: flex; display: flex;
@ -307,6 +366,10 @@ $paginationHeight: 32px;
cursor: pointer; cursor: pointer;
} }
} }
&.comfirmed {
font-weight: 600;
color: rgb(5, 174, 163);
}
} }
} }
.mainFooter { .mainFooter {

View File

@ -20,12 +20,12 @@ export type AlarmsTableType = {
alarmType: string alarmType: string
} }
export type GetAlarmsTableParam = { export type GetAlarmsTableParam = {
startTime: string startTime: string | number
endTime: string endTime: string | number
airBlowerNumber: string deviceCode: any
alarmType: string eventLevel: string | null
pageNum: number pageNum: Number
pageSize: number pageSize: Number
} }
export enum AlarmsFieldsEnums { export enum AlarmsFieldsEnums {

View File

@ -40,10 +40,26 @@
</div> </div>
</div> </div>
<div class="headerRight"> <div class="headerRight">
<el-button type="primary" @click="airBlowerOperate('setTurbineFastStart')">{{ t('airBlower.start') }}</el-button> <el-popconfirm title="确认启动么?" @confirm="airBlowerOperate('setTurbineFastStart')">
<el-button style="color: #0064aa" @click="airBlowerOperate('setTurbineStop')">{{ t('airBlower.stop') }}</el-button> <template #reference>
<el-button style="color: #0064aa" @click="airBlowerOperate('setTurbineResetStatusCode')">{{ t('airBlower.reset') }}</el-button> <el-button type="primary">{{ t('airBlower.start') }}</el-button>
<el-button style="color: #0064aa">{{ t('airBlower.verify') }}</el-button> </template>
</el-popconfirm>
<el-popconfirm title="确认停机么?" @confirm="airBlowerOperate('setTurbineStop')">
<template #reference>
<el-button style="color: #0064aa">{{ t('airBlower.stop') }}</el-button>
</template>
</el-popconfirm>
<el-popconfirm title="确认复位么?" @confirm="airBlowerOperate('setTurbineResetStatusCode')">
<template #reference>
<el-button style="color: #0064aa">{{ t('airBlower.reset') }}</el-button>
</template>
</el-popconfirm>
<el-popconfirm title="确认风机对时么?">
<template #reference>
<el-button style="color: #0064aa">{{ t('airBlower.verify') }}</el-button>
</template>
</el-popconfirm>
</div> </div>
</el-header> </el-header>
<el-main class="mainPart"> <el-main class="mainPart">
@ -120,6 +136,29 @@
</el-main> </el-main>
</el-container> </el-container>
</div> </div>
<el-dialog v-model="multiTaskVisible" :title="mutiTaskTitle" width="400" :close-on-click-modal="false">
<el-row v-for="item in mutiTaskList" :key="item.sendData.deviceId">
<el-col :span="18">
<div class="mutiTaskName">
{{ item.deviceName }}
</div>
</el-col>
<el-col :span="6">
<div class="mutiTaskStatus">
<el-icon style="color: #f56c6c" size="30" v-if="item.loading === 3">
<CircleClose />
</el-icon>
<el-icon style="color: #06b429" size="30" v-if="item.loading === 2">
<CircleCheck />
</el-icon>
<el-icon style="color: #4fa5ff" size="30" class="mutiTaskLoading" v-if="item.loading === 1">
<Loading />
</el-icon>
<div v-if="item.loading === 0">等待发送</div>
</div>
</el-col>
</el-row>
</el-dialog>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -127,9 +166,13 @@ import { SelectTypeObjType, SelectTypeKeyUnionType, TableDataObjType, TableColum
import { onUnmounted, reactive, ref, watch, nextTick } from 'vue' import { onUnmounted, reactive, ref, watch, nextTick } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { getAirBlowerListReq, getBelongLineListReq, runAirBlowerReq } from '/@/api/backend/airBlower/request' import { getAirBlowerListReq, getBelongLineListReq, runAirBlowerReq } from '/@/api/backend/airBlower/request'
import { ElMessage, TableInstance } from 'element-plus' import { CircleCheck, CircleClose, Loading } from '@element-plus/icons-vue'
import { ElMessage, TableInstance, ElPopconfirm } from 'element-plus'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import { getRealTimeState } from './utils' import { getRealTimeState } from './utils'
import { sendCommandReq } from '/@/api/backend/control/request'
import { fa } from 'element-plus/es/locales.mjs'
const router = useRouter() const router = useRouter()
const { t } = useI18n() const { t } = useI18n()
@ -240,27 +283,38 @@ const airBlowerOperate = (type: 'setTurbineFastStart' | 'setTurbineStop' | 'setT
setTurbineStop: '风机停机指令', setTurbineStop: '风机停机指令',
setTurbineResetStatusCode: '风机复位故障代码指令', setTurbineResetStatusCode: '风机复位故障代码指令',
} }
if (!selectList.value.length) {
ElMessage.warning('请先选择风机')
return
}
const data = selectList.value.map((item) => { const data = selectList.value.map((item) => {
return { return {
deviceId: item, sendData: {
serviceName: sendTypeEnum[type], deviceId: item,
serviceCode: type, serviceName: sendTypeEnum[type],
optDesc: sendTypeEnum[type] +',设定值为:'+ 1, serviceCode: type,
opValue: 1 as const, optDesc: sendTypeEnum[type] + ',设定值为:' + 1,
measType: 147 as const, opValue: 1 as const,
},
deviceName: tableData.value.find((listItem) => listItem.irn === item)!.name,
loading: 0 as const,
} }
}) })
console.log(data) mutiTaskList.value = data
mutiTaskTitle.value = sendTypeEnum[type]
runAirBlowerReq(data).then((res) => { multiTaskVisible.value = true
console.log(res); mutiTaskList.value.forEach((item) => {
if(res.success){ item.loading = 1
ElMessage.success('指令发送成功') sendCommandReq(item.sendData)
} .then((res) => {
// ElMessage.success('') console.log(res)
}).catch(()=>{ if (res.success) {
ElMessage.error('操作失败') item.loading = 2
}
})
.catch(() => {
item.loading = 3
})
}) })
} }
@ -481,6 +535,22 @@ const openWindTurbine = (row: TableDataObjType) => {
}) })
} }
const multiTaskVisible = ref(false)
const mutiTaskTitle = ref('')
const mutiTaskList = ref<
{
loading: 0 | 1 | 2 | 3
deviceName: string
sendData: {
deviceId: string
serviceName: string
serviceCode: string
optDesc: string
opValue: 1
}
}[]
>([])
onUnmounted(() => { onUnmounted(() => {
autoUpdateInterval.value && clearInterval(autoUpdateInterval.value) autoUpdateInterval.value && clearInterval(autoUpdateInterval.value)
autoUpdateInterval.value = null autoUpdateInterval.value = null
@ -538,4 +608,29 @@ getBlongLineList()
} }
} }
} }
.mutiTaskName {
width: 100%;
height: 40px;
line-height: 40px;
font-size: 16px;
}
.mutiTaskStatus {
display: flex;
align-items: center;
justify-content: right;
width: 100%;
height: 40px;
}
.mutiTaskLoading {
animation: rotate 1s linear infinite;
}
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style> </style>

View File

@ -74,8 +74,8 @@
<div class="correctionTreeItem"> <div class="correctionTreeItem">
<span>{{ correctionDevice.findIndex((item) => item === data) + 1 + '、' + data.name }}</span> <span>{{ correctionDevice.findIndex((item) => item === data) + 1 + '、' + data.name }}</span>
<div class="rightItem"> <div class="rightItem">
<el-input v-if="data.isEdit" v-model="data.iotAddr" @keyup.enter="okEdit(data)" @blur="okEdit(data)" ></el-input> <el-input v-if="data.isEdit" v-model="data.iotAddr" @keyup.enter="okEdit(data)" @blur="okEdit(data)"></el-input>
<el-tag v-else type="info" @click="editAttr(data)">{{ data.iotAddr??'请输入地址' }}</el-tag> <el-tag v-else type="info" @click="editAttr(data)">{{ data.iotAddr ?? '请输入地址' }}</el-tag>
<el-popconfirm @confirm="delCorrectionDevice(node)" title="确认删除么?"> <el-popconfirm @confirm="delCorrectionDevice(node)" title="确认删除么?">
<template #reference> <template #reference>
<el-icon><Delete /></el-icon> <el-icon><Delete /></el-icon>
@ -111,13 +111,13 @@ import {
uploadMappingListReq, uploadMappingListReq,
} from '/@/api/backend/node/request' } from '/@/api/backend/node/request'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { onBeforeUnmount, onMounted, ref, reactive } from 'vue' import { onBeforeUnmount, onMounted, ref, reactive, nextTick } from 'vue'
import '@univerjs/design/lib/index.css' import '@univerjs/design/lib/index.css'
import '@univerjs/ui/lib/index.css' import '@univerjs/ui/lib/index.css'
import '@univerjs/docs-ui/lib/index.css' import '@univerjs/docs-ui/lib/index.css'
import '@univerjs/sheets-ui/lib/index.css' import '@univerjs/sheets-ui/lib/index.css'
import '@univerjs/sheets-formula/lib/index.css' // import '@univerjs/sheets-formula-ui/lib/index.css'
import { Univer, UniverInstanceType, Tools, Workbook, LocaleType, IWorkbookData } from '@univerjs/core' import { Univer, UniverInstanceType, Tools, Workbook, LocaleType, IWorkbookData } from '@univerjs/core'
import { defaultTheme } from '@univerjs/design' import { defaultTheme } from '@univerjs/design'
@ -132,6 +132,7 @@ import { UniverDocsUIPlugin } from '@univerjs/docs-ui'
import { UniverSheetsPlugin } from '@univerjs/sheets' import { UniverSheetsPlugin } from '@univerjs/sheets'
import { UniverSheetsFormulaPlugin } from '@univerjs/sheets-formula' import { UniverSheetsFormulaPlugin } from '@univerjs/sheets-formula'
// import { UniverSheetsFormulaUIPlugin } from '@univerjs/sheets-formula-ui'
import { UniverSheetsUIPlugin } from '@univerjs/sheets-ui' import { UniverSheetsUIPlugin } from '@univerjs/sheets-ui'
import DesignZhCN from '@univerjs/design/locale/zh-CN' import DesignZhCN from '@univerjs/design/locale/zh-CN'
@ -139,6 +140,7 @@ import UIZhCN from '@univerjs/ui/locale/zh-CN'
import DocsUIZhCN from '@univerjs/docs-ui/locale/zh-CN' import DocsUIZhCN from '@univerjs/docs-ui/locale/zh-CN'
import SheetsZhCN from '@univerjs/sheets/locale/zh-CN' import SheetsZhCN from '@univerjs/sheets/locale/zh-CN'
import SheetsUIZhCN from '@univerjs/sheets-ui/locale/zh-CN' import SheetsUIZhCN from '@univerjs/sheets-ui/locale/zh-CN'
// import SheetsFormulaUIZhCN from '@univerjs/sheets-formula-ui/locale/zh-CN'
import { FUniver } from '@univerjs/facade' import { FUniver } from '@univerjs/facade'
import { excelDefaultConfig, createWookbookData, createUpLoadExcelData, createSheetData, setExcelNameToLinkId } from './utils' import { excelDefaultConfig, createWookbookData, createUpLoadExcelData, createSheetData, setExcelNameToLinkId } from './utils'
@ -192,6 +194,7 @@ const initExcel = (data = {}) => {
theme: defaultTheme, theme: defaultTheme,
locale: LocaleType.ZH_CN, locale: LocaleType.ZH_CN,
locales: { locales: {
// [LocaleType.ZH_CN]: Tools.deepMerge(SheetsZhCN, DocsUIZhCN, SheetsUIZhCN,SheetsFormulaUIZhCN, UIZhCN, DesignZhCN),
[LocaleType.ZH_CN]: Tools.deepMerge(SheetsZhCN, DocsUIZhCN, SheetsUIZhCN, UIZhCN, DesignZhCN), [LocaleType.ZH_CN]: Tools.deepMerge(SheetsZhCN, DocsUIZhCN, SheetsUIZhCN, UIZhCN, DesignZhCN),
}, },
}) })
@ -214,6 +217,7 @@ const initExcel = (data = {}) => {
univer.registerPlugin(UniverSheetsPlugin) univer.registerPlugin(UniverSheetsPlugin)
univer.registerPlugin(UniverSheetsUIPlugin) univer.registerPlugin(UniverSheetsUIPlugin)
univer.registerPlugin(UniverSheetsFormulaPlugin) univer.registerPlugin(UniverSheetsFormulaPlugin)
// univer.registerPlugin(UniverSheetsFormulaUIPlugin)
// create workbook instance // create workbook instance
workbook.value = univer.createUnit<IWorkbookData, Workbook>(UniverInstanceType.UNIVER_SHEET, data) workbook.value = univer.createUnit<IWorkbookData, Workbook>(UniverInstanceType.UNIVER_SHEET, data)
@ -239,6 +243,14 @@ const initExcel = (data = {}) => {
} }
}) })
hasLoading.value = false hasLoading.value = false
// const wb = univerAPI.getActiveWorkbook()
// const worksheet = wb.getActiveSheet()
// console.log(worksheet)
// worksheet.setFrozenRows(1)
// const freezeState = worksheet.getFreeze()
// console.log('', freezeState)
} }
/** /**
@ -552,12 +564,11 @@ onBeforeUnmount(() => {
} }
} }
} }
.treeMain{ .treeMain {
height: 600px; height: 600px;
.el-tree{ .el-tree {
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
} }
} }
</style> </style>

View File

@ -46,14 +46,14 @@ export const excelDefaultConfig: any = {
code: 'limit1Enable', code: 'limit1Enable',
default: 0 default: 0
}, },
{
label: '限值1下限',
code: 'limit1Low'
},
{ {
label: '限值1上限', label: '限值1上限',
code: 'limit1High' code: 'limit1High'
}, },
{
label: '限值1下限',
code: 'limit1Low'
},
{ {
label: '限值2', label: '限值2',
code: 'limit2Enable', code: 'limit2Enable',
@ -255,14 +255,14 @@ export const excelDefaultConfig: any = {
label: '限值1', label: '限值1',
code: 'limit1Enable' code: 'limit1Enable'
}, },
{
label: '限值1下限',
code: 'limit1Low'
},
{ {
label: '限值1上限', label: '限值1上限',
code: 'limit1High' code: 'limit1High'
}, },
{
label: '限值1下限',
code: 'limit1Low'
},
{ {
label: '限值2', label: '限值2',
code: 'limit2Enable' code: 'limit2Enable'
@ -451,14 +451,14 @@ export const excelDefaultConfig: any = {
label: '限值1', label: '限值1',
code: 'limit1Enable' code: 'limit1Enable'
}, },
{
label: '限值1下限',
code: 'limit1Low'
},
{ {
label: '限值1上限', label: '限值1上限',
code: 'limit1High' code: 'limit1High'
}, },
{
label: '限值1下限',
code: 'limit1Low'
},
{ {
label: '限值2', label: '限值2',
code: 'limit2Enable' code: 'limit2Enable'
@ -544,14 +544,14 @@ export const excelDefaultConfig: any = {
label: '限值1', label: '限值1',
code: 'limit1Enable' code: 'limit1Enable'
}, },
{
label: '限值1下限',
code: 'limit1Low'
},
{ {
label: '限值1上限', label: '限值1上限',
code: 'limit1High' code: 'limit1High'
}, },
{
label: '限值1下限',
code: 'limit1Low'
},
{ {
label: '限值2', label: '限值2',
code: 'limit2Enable' code: 'limit2Enable'
@ -669,12 +669,12 @@ const createHeaderData = (protocol: string | number) => {
2: { 2: {
v: '属性名称', v: '属性名称',
s: '1', s: '1',
custom: 'name', custom: 'measPointName',
}, },
3: { 3: {
v: '属性编码', v: '属性编码',
s: '1', s: '1',
custom: 'code', custom: 'measPointCode',
}, },
...dynamicData, ...dynamicData,
}, },
@ -772,7 +772,7 @@ export const createUpLoadExcelData = (workbookData: any) => {
const sheetkeyMap: any = {} const sheetkeyMap: any = {}
const sheetKeys = Object.keys(sheets[item].cellData) const sheetKeys = Object.keys(sheets[item].cellData)
sheetKeys.forEach((key) => { sheetKeys.forEach((key) => {
const sheetData: any = {} let sheetData: any = {}
const fieldKeys = Object.keys(sheets[item].cellData[key]) const fieldKeys = Object.keys(sheets[item].cellData[key])
if (key === '0') { if (key === '0') {
fieldKeys.forEach((fieldKey) => { fieldKeys.forEach((fieldKey) => {
@ -784,11 +784,10 @@ export const createUpLoadExcelData = (workbookData: any) => {
const sheetKeyMapKeys = Object.keys(sheetkeyMap) const sheetKeyMapKeys = Object.keys(sheetkeyMap)
for (let fieldKey of sheetKeyMapKeys) { for (let fieldKey of sheetKeyMapKeys) {
if (fieldKey === '0') { if (fieldKey === '0') {
sheetData.equipmentId = sheets[item].cellData[key][fieldKey].custom.equipmentId sheetData = { ...sheets[item].cellData[key][fieldKey].custom.otherData }
sheetData.linkId = workbookData.name sheetData.linkId = workbookData.name
sheetData[sheetkeyMap[fieldKey]] = sheets[item].cellData[key][fieldKey]?.v ?? '' sheetData[sheetkeyMap[fieldKey]] = sheets[item].cellData[key][fieldKey]?.v ?? ''
sheetData.type = sheets[item].cellData[key][fieldKey].custom.type sheetData.type = sheets[item].cellData[key][fieldKey].custom.type
sheetData.id = sheets[item].cellData[key][fieldKey].custom.id
continue continue
} }
if (fieldKey === '1') { if (fieldKey === '1') {
@ -822,14 +821,14 @@ export const createSheetData = (data: any, protocol: string | number) => {
const row = index + 1 const row = index + 1
result[row] = {} result[row] = {}
Object.keys(obj).forEach((field) => { Object.keys(obj).forEach((field) => {
const col = excelCellDataMap[field] const col = excelCellDataMap[field]
if (col) { if (col) {
let custom: any let custom: any
if (col === '0') { if (col === '0') {
custom = {} custom = {}
custom.equipmentId = obj.equipmentId
custom.type = item custom.type = item
custom.id = obj.id custom.otherData = obj
} }
result[row][col] = { v: obj[field], s: '1', custom } result[row][col] = { v: obj[field], s: '1', custom }
} }

View File

@ -582,6 +582,7 @@ const timestampToTime = (timestamp: any) => {
let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds() let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
return Y + M + D + h + m + s return Y + M + D + h + m + s
} }
getReportTemplateList()
onMounted(() => { onMounted(() => {
queryWindBlower() queryWindBlower()
}) })