|
|
@@ -2,58 +2,126 @@
|
|
|
<div class="company-home">
|
|
|
<div class="border">
|
|
|
<customHeader>矿井全域皮带巷三级防灭火系统</customHeader>
|
|
|
- <!-- Tab 切换 -->
|
|
|
- <div class="tab-box">
|
|
|
- <div class="tab-item" :class="{ active: activeTab === 'device' }" @click="switchTab('device')"> 设备历史数据 </div>
|
|
|
- <div class="tab-item" :class="{ active: activeTab === 'operate' }" @click="switchTab('operate')"> 操作历史 </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="box-container">
|
|
|
- <!-- 设备历史 -->
|
|
|
- <div v-if="activeTab === 'device'" key="device">
|
|
|
- <BasicTable ref="historyTable" @register="registerTable" :data-source="dataSource" :scroll="{ x: 1000, y: 500 }" />
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 操作历史 -->
|
|
|
- <div v-if="activeTab === 'operate'" key="operate">
|
|
|
- <BasicTable ref="operateTable" @register="registerOperateTable" :data-source="ctrlSource" :scroll="{ x: 1000, y: 500 }" />
|
|
|
- </div>
|
|
|
+ <div :style="`padding: 5px; height: ${scroll.y + 100}px`">
|
|
|
+ <a-tabs class="tabs-box" v-model:activeKey="activeKey" @change="tabChange" id="tabsBox">
|
|
|
+ <a-tab-pane key="1" tab="历史数据">
|
|
|
+ <div class="tab-item">
|
|
|
+ <BasicTable ref="historyTable" @register="registerTable" :scroll="{ x: 1000, y: 350 }">
|
|
|
+ <template #bodyCell="{ column, record }">
|
|
|
+ <a-tag v-if="column.dataIndex === 'warnFlag'" :color="record.warnFlag == '0' ? 'green' : 'red'">
|
|
|
+ {{ record.warnFlag == '0' ? '正常' : '报警' }}
|
|
|
+ </a-tag>
|
|
|
+ <a-tag v-if="column.dataIndex === 'netStatus'" :color="record.netStatus == '0' ? '#f00' : 'green'">
|
|
|
+ {{ record.netStatus == '0' ? '断开' : '连接' }}
|
|
|
+ </a-tag>
|
|
|
+ </template>
|
|
|
+ </BasicTable>
|
|
|
+ </div>
|
|
|
+ </a-tab-pane>
|
|
|
+ <a-tab-pane key="2" tab="操作历史">
|
|
|
+ <div class="tab-item">
|
|
|
+ <BasicTable ref="operateTable" @register="registerOperateTable" :scroll="{ x: 1000, y: 350 }" />
|
|
|
+ </div>
|
|
|
+ </a-tab-pane>
|
|
|
+ <a-tab-pane key="3" tab="预警历史">
|
|
|
+ <div class="tab-item">
|
|
|
+ <BasicTable ref="alarmTable" @register="registerAlarmTable" :scroll="{ x: 1000, y: 350 }" />
|
|
|
+ </div>
|
|
|
+ </a-tab-pane>
|
|
|
+ </a-tabs>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-import { ref, onMounted, nextTick } from 'vue';
|
|
|
+import { ref, onMounted, reactive, nextTick, watch, computed } from 'vue';
|
|
|
import { BasicTable } from '/@/components/Table';
|
|
|
import { useListPage } from '/@/hooks/system/useListPage';
|
|
|
+import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
|
|
|
import dayjs from 'dayjs';
|
|
|
import customHeader from './components/customHeader-belt.vue';
|
|
|
-import { getLeatherInfo, getTableList, getDeviceHistoryApi, getDeviceData } from './configurable.api';
|
|
|
+import { getLeatherInfo, getDeviceHistoryApi, getDevicesetLog, systemList, getAlarmList } from './configurable.api';
|
|
|
+
|
|
|
+type DeviceType = { deviceType: string; deviceName: string; datalist: any[] };
|
|
|
+
|
|
|
+const operateColumns = ref([]);
|
|
|
+const alarmColumns = ref([]);
|
|
|
|
|
|
-const activeTab = ref('device');
|
|
|
-// 设备下拉选项
|
|
|
const deviceOptions = ref<any>([]);
|
|
|
-const deviceDataOptions = ref<any>([]);
|
|
|
-const dataSource = ref([]);
|
|
|
-const ctrlSource = ref([]);
|
|
|
-// 工具方法
|
|
|
-function resetFormParam() {
|
|
|
+const deviceList = ref<DeviceType[]>([]);
|
|
|
+// 设备名称选项:用 ref 保证响应式
|
|
|
+const deviceNameOptions = ref<any>([]);
|
|
|
+
|
|
|
+const strtype = ref('');
|
|
|
+const historyType = ref('');
|
|
|
+const columns = ref([]);
|
|
|
+const scroll = reactive({ y: 180 });
|
|
|
+const activeKey = ref('1');
|
|
|
+const deviceActive = ref('');
|
|
|
+
|
|
|
+// 设备类型下拉(计算属性)
|
|
|
+const deviceTypeSelectOptions = computed(() => {
|
|
|
+ return deviceList.value.map((item) => ({
|
|
|
+ label: item.deviceName,
|
|
|
+ value: item.deviceType,
|
|
|
+ }));
|
|
|
+});
|
|
|
+
|
|
|
+function tabChange(activeKeyVal) {
|
|
|
+ activeKey.value = activeKeyVal;
|
|
|
+ activeKey.value === '1' ? reload() : reloadOperate();
|
|
|
+}
|
|
|
+
|
|
|
+async function fetchDeviceHistory() {
|
|
|
const formData = getForm().getFieldsValue();
|
|
|
const pagination = getPaginationRef();
|
|
|
+
|
|
|
+ const p = {
|
|
|
+ pageNum: pagination.current,
|
|
|
+ pageSize: pagination.pageSize,
|
|
|
+ ttime_begin: formData.ttime_begin,
|
|
|
+ ttime_end: formData.ttime_end,
|
|
|
+ gdeviceids: formData.gdeviceids,
|
|
|
+ strtype: strtype.value,
|
|
|
+ };
|
|
|
+ const res = await getDeviceHistoryApi(p);
|
|
|
return {
|
|
|
+ total: res?.datalist?.total || 0,
|
|
|
+ records: res?.datalist?.records?.map((item) => ({ ...item, ...item.readData })) || [],
|
|
|
+ };
|
|
|
+}
|
|
|
+// 获取操作历史
|
|
|
+async function fetchOperateHistory() {
|
|
|
+ const formData = getForm().getFieldsValue();
|
|
|
+ const pagination = getPaginationRef();
|
|
|
+ const p = {
|
|
|
pageNum: pagination.current,
|
|
|
pageSize: pagination.pageSize,
|
|
|
- column: 'createTime',
|
|
|
- startTime: formData.startTime,
|
|
|
- endTime: formData.endTime,
|
|
|
- deviceId: formData.gdeviceids,
|
|
|
- strtype: 'sys_Leather',
|
|
|
- sysId: formData.id,
|
|
|
+ createTime_begin: formData.ttime_begin,
|
|
|
+ createTime_end: formData.ttime_end,
|
|
|
+ devicetype: strtype.value ? strtype.value + '*' : '',
|
|
|
};
|
|
|
+ const res = await getDevicesetLog(p);
|
|
|
+ return { total: res?.total || 0, records: res?.records || [] };
|
|
|
+}
|
|
|
+// 获取预警历史
|
|
|
+
|
|
|
+async function fetchAlarmHistory() {
|
|
|
+ const formData = getForm().getFieldsValue();
|
|
|
+ const pagination = getPaginationRef();
|
|
|
+ const p = {
|
|
|
+ pageNum: pagination.current,
|
|
|
+ pageSize: pagination.pageSize,
|
|
|
+ createTime_begin: formData.ttime_begin,
|
|
|
+ createTime_end: formData.ttime_end,
|
|
|
+ devicetype: strtype.value ? strtype.value + '*' : '',
|
|
|
+ gdeviceids: formData.gdeviceids,
|
|
|
+ };
|
|
|
+ const res = await getAlarmList(p);
|
|
|
+ return { total: res?.total || 0, records: res?.records || [] };
|
|
|
}
|
|
|
|
|
|
-// 获取皮带巷列表
|
|
|
async function getDeviceList() {
|
|
|
const res = await getLeatherInfo({
|
|
|
strtype: 'sys_Leather',
|
|
|
@@ -61,57 +129,95 @@ async function getDeviceList() {
|
|
|
pageNo: 1,
|
|
|
pageSize: 999,
|
|
|
});
|
|
|
- deviceOptions.value = res.records.map((item) => ({
|
|
|
- label: item.systemname,
|
|
|
- value: item.id,
|
|
|
- }));
|
|
|
-}
|
|
|
-// 获取皮带巷下设备信息
|
|
|
-async function getDevice(id) {
|
|
|
- const res = await getDeviceData({ sysId: id });
|
|
|
- deviceDataOptions.value = res.map((item) => ({
|
|
|
- label: item.deviceName,
|
|
|
- value: item.deviceId,
|
|
|
- }));
|
|
|
+ deviceOptions.value = res.records.map((item) => ({ label: item.systemname, value: item.id }));
|
|
|
+
|
|
|
+ if (deviceOptions.value.length > 0) {
|
|
|
+ const firstSysId = deviceOptions.value[0].value;
|
|
|
+ getForm().setFieldsValue({ sysId: firstSysId });
|
|
|
+ await getDeviceTypeList(firstSysId);
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+// 查询表单
|
|
|
const getSchemas = () => [
|
|
|
{
|
|
|
- field: 'startTime',
|
|
|
+ field: 'ttime_begin',
|
|
|
label: '开始时间',
|
|
|
component: 'DatePicker',
|
|
|
defaultValue: dayjs().subtract(1, 'day').startOf('day'),
|
|
|
- componentProps: {
|
|
|
- showTime: true,
|
|
|
- valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
|
|
- },
|
|
|
+ componentProps: { showTime: true, valueFormat: 'YYYY-MM-DD HH:mm:ss' },
|
|
|
colProps: { span: 4 },
|
|
|
},
|
|
|
{
|
|
|
- field: 'endTime',
|
|
|
+ field: 'ttime_end',
|
|
|
label: '结束时间',
|
|
|
component: 'DatePicker',
|
|
|
defaultValue: dayjs(),
|
|
|
- componentProps: {
|
|
|
- showTime: true,
|
|
|
- valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
|
|
- },
|
|
|
+ componentProps: { showTime: true, valueFormat: 'YYYY-MM-DD HH:mm:ss' },
|
|
|
colProps: { span: 4 },
|
|
|
},
|
|
|
{
|
|
|
- field: 'id',
|
|
|
+ field: 'sysId',
|
|
|
label: '皮带巷',
|
|
|
component: 'Select',
|
|
|
componentProps: {
|
|
|
placeholder: '请选择皮带巷',
|
|
|
showSearch: true,
|
|
|
options: deviceOptions,
|
|
|
- onChange: (e, option) => {
|
|
|
- getDevice(option.value);
|
|
|
+ onChange: async (value) => {
|
|
|
+ if (value) {
|
|
|
+ getForm().setFieldsValue({ sysId: value, deviceType: undefined, gdeviceids: undefined });
|
|
|
+ strtype.value = '';
|
|
|
+ await getDeviceTypeList(value);
|
|
|
+ }
|
|
|
},
|
|
|
},
|
|
|
required: true,
|
|
|
colProps: { span: 4 },
|
|
|
},
|
|
|
+ {
|
|
|
+ field: 'deviceType',
|
|
|
+ label: '设备类型',
|
|
|
+ component: 'Select',
|
|
|
+ componentProps: {
|
|
|
+ placeholder: '请选择设备类型',
|
|
|
+ showSearch: true,
|
|
|
+ options: deviceTypeSelectOptions,
|
|
|
+ onChange: async (value) => {
|
|
|
+ const selectedType = deviceList.value.find((item) => item.deviceType === value);
|
|
|
+ if (selectedType) {
|
|
|
+ // 1. 先更新设备名称选项
|
|
|
+ deviceNameOptions.value = selectedType.datalist.map((item) => ({
|
|
|
+ label: item.strname,
|
|
|
+ value: item.deviceID,
|
|
|
+ deviceKind: item.deviceType,
|
|
|
+ }));
|
|
|
+ deviceNameOptions.value = [...deviceNameOptions.value];
|
|
|
+ console.log(deviceNameOptions.value, '=============');
|
|
|
+ await nextTick();
|
|
|
+ // 4. 设置表单值
|
|
|
+ if (deviceNameOptions.value.length) {
|
|
|
+ getForm().setFieldsValue({
|
|
|
+ gdeviceids: deviceNameOptions.value[0].value,
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ getForm().setFieldsValue({ gdeviceids: undefined });
|
|
|
+ }
|
|
|
+
|
|
|
+ strtype.value = selectedType.deviceType;
|
|
|
+ historyType.value = selectedType.deviceType;
|
|
|
+
|
|
|
+ if (activeKey.value === '2') {
|
|
|
+ await loadOperateColumns();
|
|
|
+ } else if (activeKey.value === '3') {
|
|
|
+ await loadAlarmColumns();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: true,
|
|
|
+ colProps: { span: 5 },
|
|
|
+ },
|
|
|
{
|
|
|
field: 'gdeviceids',
|
|
|
label: '设备名称',
|
|
|
@@ -119,41 +225,54 @@ const getSchemas = () => [
|
|
|
componentProps: {
|
|
|
placeholder: '请选择设备',
|
|
|
showSearch: true,
|
|
|
- options: deviceDataOptions,
|
|
|
- onChange: (e, option) => {
|
|
|
- getHistoryData();
|
|
|
+ options: computed(() => deviceNameOptions.value),
|
|
|
+ onChange: (_, option) => {
|
|
|
+ historyType.value = option.deviceKind;
|
|
|
+ strtype.value = option.deviceKind;
|
|
|
+ if (activeKey.value === '2') {
|
|
|
+ loadOperateColumns();
|
|
|
+ } else if (activeKey.value === '3') {
|
|
|
+ loadAlarmColumns();
|
|
|
+ }
|
|
|
},
|
|
|
},
|
|
|
required: true,
|
|
|
+ colProps: { span: 5 },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '间隔时间',
|
|
|
+ field: 'skip',
|
|
|
+ component: 'Select',
|
|
|
+ defaultValue: '8',
|
|
|
+ componentProps: {
|
|
|
+ options: [
|
|
|
+ { label: '1秒', value: '1' },
|
|
|
+ { label: '5秒', value: '2' },
|
|
|
+ { label: '10秒', value: '3' },
|
|
|
+ { label: '30秒', value: '4' },
|
|
|
+ { label: '1分钟', value: '5' },
|
|
|
+ { label: '10分钟', value: '6' },
|
|
|
+ { label: '30分钟', value: '7' },
|
|
|
+ { label: '1小时', value: '8' },
|
|
|
+ ],
|
|
|
+ },
|
|
|
colProps: { span: 4 },
|
|
|
},
|
|
|
];
|
|
|
|
|
|
-//设备历史
|
|
|
-const deviceColumns = ref([
|
|
|
- { title: '设备名称', dataIndex: 'gdevicename', width: 180 },
|
|
|
- { title: '设备位置', dataIndex: 'devicePos', width: 180 },
|
|
|
- { title: '监测值', dataIndex: 'monitorValue', width: 120 },
|
|
|
- { title: '采集时间', dataIndex: 'gcreatetime', width: 200 },
|
|
|
-]);
|
|
|
-
|
|
|
-async function getHistoryData() {
|
|
|
- const params = resetFormParam();
|
|
|
- const res = await getDeviceHistoryApi(params);
|
|
|
- dataSource.value = res.records;
|
|
|
+function loadOperateColumns() {
|
|
|
+ const cols = getTableHeaderColumns('operator_history');
|
|
|
+ operateColumns.value = cols;
|
|
|
+ setOperateColumns(cols);
|
|
|
}
|
|
|
|
|
|
-const { tableContext: deviceTableContext } = useListPage({
|
|
|
+// 历史数据表格
|
|
|
+const { tableContext } = useListPage({
|
|
|
tableProps: {
|
|
|
- api: async (params) => {
|
|
|
- const res = await getDeviceHistoryApi(params);
|
|
|
- return {
|
|
|
- total: res.total || 0,
|
|
|
- items: res.records || [],
|
|
|
- };
|
|
|
- },
|
|
|
- columns: deviceColumns.value,
|
|
|
+ api: fetchDeviceHistory,
|
|
|
+ columns: columns,
|
|
|
showIndexColumn: true,
|
|
|
+ showActionColumn: false,
|
|
|
bordered: true,
|
|
|
size: 'small',
|
|
|
formConfig: {
|
|
|
@@ -166,21 +285,15 @@ const { tableContext: deviceTableContext } = useListPage({
|
|
|
pagination: { pageSize: 20 },
|
|
|
},
|
|
|
});
|
|
|
-const [registerTable, { getForm, getPaginationRef }] = deviceTableContext;
|
|
|
-
|
|
|
-//操作历史
|
|
|
-const operateColumns = ref([
|
|
|
- { title: '操作人', dataIndex: 'operateUser', width: 160 },
|
|
|
- { title: '操作内容', dataIndex: 'operateContent', width: 300 },
|
|
|
- { title: '操作时间', dataIndex: 'operateTime', width: 200 },
|
|
|
- { title: '设备/位置', dataIndex: 'deviceName', width: 180 },
|
|
|
-]);
|
|
|
+const [registerTable, { getForm, setColumns, getPaginationRef, reload }] = tableContext;
|
|
|
|
|
|
+// 操作历史表格
|
|
|
const { tableContext: operateTableContext } = useListPage({
|
|
|
tableProps: {
|
|
|
- api: getTableList,
|
|
|
- columns: operateColumns.value,
|
|
|
+ api: fetchOperateHistory,
|
|
|
+ columns: operateColumns,
|
|
|
showIndexColumn: true,
|
|
|
+ showActionColumn: false,
|
|
|
bordered: true,
|
|
|
size: 'small',
|
|
|
formConfig: {
|
|
|
@@ -193,16 +306,87 @@ const { tableContext: operateTableContext } = useListPage({
|
|
|
pagination: { pageSize: 20 },
|
|
|
},
|
|
|
});
|
|
|
-const [registerOperateTable] = operateTableContext;
|
|
|
+const [registerOperateTable, { setColumns: setOperateColumns, reload: reloadOperate }] = operateTableContext;
|
|
|
|
|
|
-//Tab 切换
|
|
|
-function switchTab(tab) {
|
|
|
- activeTab.value = tab;
|
|
|
+// 获取设备类型列表
|
|
|
+async function getDeviceTypeList(value) {
|
|
|
+ const res = await systemList({ devicetype: 'sys', systemID: value });
|
|
|
+ const result = res.msgTxt;
|
|
|
+ const deviceArr: DeviceType[] = [];
|
|
|
+
|
|
|
+ result.forEach((item) => {
|
|
|
+ if (item.type !== 'sys' && item.datalist?.length) {
|
|
|
+ deviceArr.push({
|
|
|
+ deviceType: item.type,
|
|
|
+ deviceName: item.typeName || item.datalist[0]?.typeName || '',
|
|
|
+ datalist: item.datalist,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ deviceList.value = deviceArr;
|
|
|
+
|
|
|
+ if (deviceList.value.length) {
|
|
|
+ const firstType = deviceList.value[0];
|
|
|
+ deviceNameOptions.value = firstType.datalist.map((i) => ({
|
|
|
+ label: i.strname || i.deviceName,
|
|
|
+ value: i.deviceID || i.deviceId,
|
|
|
+ deviceKind: i.deviceType || i.deviceKind || firstType.deviceType,
|
|
|
+ }));
|
|
|
+ getForm().setFieldsValue({ deviceType: firstType.deviceType });
|
|
|
+ await nextTick();
|
|
|
+ if (deviceNameOptions.value.length) {
|
|
|
+ getForm().setFieldsValue({
|
|
|
+ gdeviceids: deviceNameOptions.value[0].value,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ strtype.value = firstType.deviceType;
|
|
|
+ historyType.value = firstType.deviceType;
|
|
|
+ await nextTick();
|
|
|
+ const columnKey = `${firstType.deviceType.split('_')[0]}_history`;
|
|
|
+ columns.value = getTableHeaderColumns(columnKey);
|
|
|
+ if (columns.value && columns.value.length) {
|
|
|
+ setColumns(columns.value);
|
|
|
+ reload();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
+function loadAlarmColumns() {
|
|
|
+ const cols = getTableHeaderColumns('alarm_history');
|
|
|
+ alarmColumns.value = cols;
|
|
|
+ setAlarmColumns(cols);
|
|
|
+}
|
|
|
+// 预警历史表格
|
|
|
+const { tableContext: AlarmTableContext } = useListPage({
|
|
|
+ tableProps: {
|
|
|
+ api: fetchAlarmHistory,
|
|
|
+ columns: alarmColumns,
|
|
|
+ showIndexColumn: true,
|
|
|
+ showActionColumn: false,
|
|
|
+ bordered: true,
|
|
|
+ size: 'small',
|
|
|
+ formConfig: {
|
|
|
+ labelWidth: 80,
|
|
|
+ schemas: getSchemas(),
|
|
|
+ showAdvancedButton: false,
|
|
|
+ autoAdvancedCol: 99,
|
|
|
+ alwaysShowLines: 99,
|
|
|
+ },
|
|
|
+ pagination: { pageSize: 20 },
|
|
|
+ },
|
|
|
+});
|
|
|
+const [registerAlarmTable, { setColumns: setAlarmColumns, reload: reloadAlarm }] = AlarmTableContext;
|
|
|
+
|
|
|
+watch(historyType, async (type) => {
|
|
|
+ if (!type) return;
|
|
|
+ await nextTick();
|
|
|
+ columns.value = getTableHeaderColumns(`${type.split('_')[0]}_history`);
|
|
|
+ setColumns(columns.value);
|
|
|
+ reload();
|
|
|
+});
|
|
|
|
|
|
-//初始化
|
|
|
-onMounted(() => {
|
|
|
- getDeviceList();
|
|
|
+onMounted(async () => {
|
|
|
+ await getDeviceList();
|
|
|
});
|
|
|
</script>
|
|
|
|
|
|
@@ -213,7 +397,6 @@ onMounted(() => {
|
|
|
color: #fff;
|
|
|
background: url('/@/assets/images/beltFire/baseMap.png') no-repeat center;
|
|
|
background-size: cover;
|
|
|
-
|
|
|
.border {
|
|
|
width: 100%;
|
|
|
height: 94%;
|
|
|
@@ -223,23 +406,5 @@ onMounted(() => {
|
|
|
box-sizing: border-box;
|
|
|
margin-top: 50px;
|
|
|
}
|
|
|
-
|
|
|
- .tab-box {
|
|
|
- display: flex;
|
|
|
- gap: 4px;
|
|
|
- margin-bottom: 16px;
|
|
|
-
|
|
|
- .tab-item {
|
|
|
- padding: 8px 20px;
|
|
|
- cursor: pointer;
|
|
|
- border-radius: 6px;
|
|
|
-
|
|
|
- &.active {
|
|
|
- background: #1890ff;
|
|
|
- color: #fff;
|
|
|
- font-weight: bold;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
</style>
|