生产监控前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

339 lines
10 KiB

2 years ago
<template>
<div class="headerInfo" v-show="tapsShow">
<div class="header">
<div class="headerItem" v-for="(item, index) in headerData" :key="index">
<div class="name">{{ item.name }}</div>
<div class="value">{{ item.value }}</div>
</div>
</div>
</div>
<!-- <div
class="mainTable"
:style="{ height: tapsShow ? 'calc(100vh - 5.7rem - 222px)' : 'calc(100vh - 5.7rem - 60px)' }"
> -->
<div class="mainTable" :style="{ height: `${sidebarHeight}px` }">
<n-spin :show="loadingShow">
<vxe-grid ref="tableRef" class="tableGrid" align="center" auto-resize :height="sidebarHeight - 4"
header-row-class-name="headerRowClass" header-cell-class-name="headerCellClass" row-class-name="tableRowClass"
cell-class-name="tableCellClass" :sort-config="{ multiple: true, trigger: 'cell' }" stripe border="outer"
2 years ago
:column-config="{ resizable: true, useKey: true }" :row-config="{ useKey: true }" :columns="tableColumn"
:data="tableData" @cell-dblclick="cellDBLClickEvent">
<template #deviceuuid_default="{ row }">
<div class="title">
<svg-icon icon-class="warning_lights" style="fill:currentColor;width: 15px;height: 15px;color: green;"
v-if="row.deviceuuid.deviceStatus === 0" />
<svg-icon icon-class="warning_lights" style="fill:currentColor;width: 15px;height: 15px;color: red;"
v-if="row.deviceuuid.deviceStatus === 2" />
<span class="name" @click.native="nameClick(row.deviceuuid)">{{ row.deviceuuid.title }}</span>
</div>
2 years ago
</template>
</vxe-grid>
<!-- <vxe-grid class="tableGrid" v-bind="gridOptions"> </vxe-grid> -->
</n-spin>
</div>
<vxe-modal :title="modalTitle" v-model="editModal">
<template #default>
<vxe-form title-colon ref="formRef" title-align="right" title-width="100" :data="formData" :rules="formRules"
:loading="formLoading" @submit="submitEvent" @reset="resetEvent">
<vxe-form-item field="value" span="24" :item-render="{}" title-overflow>
<template #default="params">
<vxe-input v-model="params.data.value" placeholder="请输入数值" clearable></vxe-input>
</template>
</vxe-form-item>
<vxe-form-item align="center" span="24">
<template #default>
<vxe-button type="submit" status="primary" content="确认"></vxe-button>
<vxe-button type="reset" content="重置"></vxe-button>
</template>
</vxe-form-item>
</vxe-form>
</template>
</vxe-modal>
</template>
<script lang="ts" setup>
import router from '@/router';
2 years ago
import {
VxeGridProps,
VxeGridInstance,
VxeTableEvents,
VxeColumnPropTypes,
VXETable,
VxeFormInstance,
VxeFormPropTypes,
VxeFormEvents,
} from 'vxe-table';
import { getTableHeader, getStationInfo, getTableData, editConfig } from '@/api/table/list';
import { TableVo } from '@/api/table/types';
import { tableStore } from '@/store/modules/table';
import mitt from '@/plugins/bus';
import socket from '@/utils/socket';
const tableStoreCounter = tableStore();
// import type { MenuOption } from 'naive-ui'
// import { useMessage } from 'naive-ui'
// const message = useMessage()
// const mainHeight = ref('calc(100vh - 161px)');
const loadingShow = ref(false);
const editModal = ref(false);
const modalTitle = ref('');
const menuKey = ref('');
const tableColumn = ref([]);
const tableData = ref<TableVo[]>();
const tableRef = ref<VxeGridInstance<TableVo>>();
interface FormDataVO {
url: string;
deviceName: string;
value: string;
}
const formRef = ref<VxeFormInstance>();
const formLoading = ref(false);
const formData = ref<FormDataVO>({
url: '',
deviceName: '',
value: '',
});
const formRules = ref<VxeFormPropTypes.Rules>({
value: [
{ required: true, message: '请输入数值' },
{ min: 1, max: 100, message: '长度在 1 到 100 个字符' },
{
validator({ itemValue }) {
// 自定义校验
const reg = /^-?\d+\.?\d{0,2}$/;
if (!reg.test(itemValue)) {
return new Error('请输入正确数值!');
}
},
},
],
});
const userStorageInfo = sessionStorage.getItem('userInfo')
const userInfo = JSON.parse(userStorageInfo === null ? '' : userStorageInfo);
2 years ago
// const loginIp = userInfo.loginIp.split('.').join('');
const baseApi = "http://10.10.10.56:9000"//websocket链接地址,与项目接口地址一致。
// const baseApi = import.meta.env.VITE_APP_BASE_API
const apiUrl = baseApi.replace(/https?:/, '');
2 years ago
const wsUrl = `ws:${apiUrl}/websocket/${userInfo.userName}`; //websocket地址
// const wsData = ref(socket.data);
const emit = defineEmits(['tableHeaderData']);
// const listData = ref([
// {
// name: 'area_default',
// value: 1,
// },
// ]);
defineProps({
tapsShow: {
type: Boolean,
default: true,
},
sidebarHeight: {
type: Number,
default: 0,
},
});
// watch(
// () => tableStoreCounter.tableDataStore,
// (newValue, oldValue) => {
// console.log('值发生了变更', newValue, oldValue);
// const $table = tableRef.value;
// $table.loadData(newValue);
// }
// );
// watchEffect(() => {
// const titleRef = props.tapsShow;
// console.log(tableStoreCounter.tableDataStore);
// tableData.value = tableStoreCounter.tableDataStore;
// $table.loadData(tableStoreCounter.tableDataStore);
// });
interface HeaderVo {
code: string;
name: string;
value: string;
}
const headerData = ref<HeaderVo[]>();
onMounted(() => {
// stationInfo();
tableHeader();
socket.initialize(wsUrl); //初始化websocket
});
mitt.on('menuKey', (res: any) => {
//监听左侧菜单点击
menuKey.value = res;
tableDatas();
});
mitt.on('treeData', (res: any) => {
//监听表格header点击
tableColumn.value = [];
nextTick(() => {
tableColumn.value = res;
});
const params = res;
editConfig(params).then((res: any) => {
if (res.code === 200) {
}
});
// tableColumn.value=res
// gridOptions.columns?.push(...res);
// console.log('列配置', gridOptions.columns);
});
mitt.on('tableMessage', (res: any) => {
//监听表格数据变化
console.log(res);
const $table = tableRef.value;
const index = tableData.value.findIndex((obj) => obj.id === res.id);
if (index !== -1) {
tableData.value.splice(index, 1, res);
}
// console.log("tableData:",tableData.value)
// tableStoreCounter.tableDataAction(res.data);
// tableData.value = oldData;
$table.loadData(tableData.value);
});
function stationInfo() {
//获取热源信息
getStationInfo().then((res: any) => {
if (res.code === 200) {
headerData.value = res.data;
}
});
}
function tableHeader() {
//获取表格header
getTableHeader().then((res: any) => {
console.log(res);
// 列配置
const tableCessText = [
{
id: 1,
title: '设备名称',
field: 'deviceuuid',
type: 'html',
formatter: formatRole,
},
];
console.log(tableCessText)
res.data.map((item: any) => {
2 years ago
if (item.formatter != undefined || item.children != undefined) {
item.formatter = eval(item.formatter);
if (item.children && item.children.length) {
item.children.map((res) => {
res.formatter = eval(res.formatter);
});
}
}
});
nextTick(() => {
tableColumn.value = res.data;
});
// tableColumn.value = res.data;
// const arr = [
// {
// id: 1,
// title: '设备名称',
// field: 'deviceuuid',
// colSort: 2,
// colType: '2',
// width: 150,
// show: true,
// disabled: true,
// fixed: 'left',
// type: 'html',
// formatter: "formatRole",
// },
// ];
// arr.map((item)=>{
// item.formatter=eval(item.formatter);
// })
// console.log(arr)
// tableColumn.value = arr;
// gridOptions.columns = res.data;
// console.log('列获取', gridOptions.value.columns);
emit('tableHeaderData', res.data);
// mitt.emit('tableHeaderData', res.data);
tableDatas();
});
}
function tableDatas() {
//获取表格数据
const params = menuKey.value;
loadingShow.value = true;
getTableData(params).then((res: any) => {
if (res.code === 200) {
// tableData.value=oldData
tableData.value = res.data;
tableStoreCounter.tableDataAction(res.data);
// gridOptions.data = res.data;
loadingShow.value = false;
}
});
}
const cellDBLClickEvent: VxeTableEvents.CellDblclick<TableVo> = ({ row, column }) => {
//双击单元格
console.log(row, column);
const cellFiled = row[column.field];
const data = row.data;
if (cellFiled.canBeControl === '1') {
modalTitle.value = column.title;
formData.value.url = data.url;
formData.value.deviceName = cellFiled.deviceName;
formData.value.value = cellFiled.val;
editModal.value = true;
}
console.log(row[column.field]);
};
const formatRole: VxeColumnPropTypes.Formatter<HeaderVo> = ({ cellValue }) => {
//表单参数为object时处理
// const iconFont=cellValue.changeProp===-1?'<i class="iconfont icon-decline" />':(cellValue.changeProp===1?'<i class="iconfont icon-rise" />':'<i/>')
// const cellData = `<span class="cellClass ${cellValue.alertProp===1?'warning':''}">${cellValue.val}</span>${iconFont}`;
const cellData = `<span class="cellClass ${cellValue.alertProp === 1 ? 'warning' : ''}">${cellValue.val}</span><i class="iconfont ${cellValue.changeProp === -1 ? 'icon-decline' : (cellValue.changeProp === 1 ? 'icon-rise' : '')}" />`;
return cellData;
};
const submitEvent: VxeFormEvents.Submit = () => {
//修改数据之后通过websocket传给后端
formLoading.value = true;
const submitData = {
code: 'W01',
data: {
url: formData.value.url,
deviceName: formData.value.deviceName,
value: formData.value.value,
},
};
console.log(submitData);
socket.send(submitData);
formLoading.value = false;
editModal.value = false;
// VXETable.modal.message({ content: '保存成功', status: 'success' });
};
function nameClick(row: any) {
//点击设备名称跳转设备管理
console.log(row)
router.push({ path: '/devicemanage', query: { id: row.id } });
}
2 years ago
const resetEvent: VxeFormEvents.Reset = () => {
console.log({ content: '重置', status: 'info' });
};
</script>
<style lang="scss" scoped>
@import '../index.scss';
</style>