21 changed files with 9611 additions and 7313 deletions
@ -0,0 +1,11 @@ |
|||||
|
{ |
||||
|
"name": "My Server", |
||||
|
"host": "120.26.116.243", |
||||
|
"protocol": "sftp", |
||||
|
"port": 22, |
||||
|
"username": "root", |
||||
|
"remotePath": "/", |
||||
|
"uploadOnSave": false, |
||||
|
"useTempFile": false, |
||||
|
"openSsh": false |
||||
|
} |
File diff suppressed because it is too large
@ -0,0 +1,75 @@ |
|||||
|
import { integer } from 'vue-types' |
||||
|
import { defHttp } from '@/utils/http/axios' |
||||
|
|
||||
|
export interface EXAPageReqVO extends PageParam { |
||||
|
condition?: string |
||||
|
|
||||
|
} |
||||
|
|
||||
|
export interface EXAHistoryReqVO { |
||||
|
itemName?: string |
||||
|
startTime?: Date |
||||
|
endTime?: Date |
||||
|
|
||||
|
} |
||||
|
|
||||
|
export interface EXANowReqVO { |
||||
|
itemName?: string |
||||
|
|
||||
|
} |
||||
|
|
||||
|
export interface EXAPoint { |
||||
|
AssetCode?: string |
||||
|
ItemName?: string |
||||
|
GroupName?: string |
||||
|
ItemType?: number |
||||
|
Descriptor?: string |
||||
|
EngUnits?: string |
||||
|
Source?: string |
||||
|
AutoSave?: number |
||||
|
UpperBound?: number |
||||
|
LowerBound?: number |
||||
|
UpperLimit?: number |
||||
|
LowerLimit?: number |
||||
|
UpperUpperLimit?: number |
||||
|
LowerLowerLimit?: number |
||||
|
Comment?: string |
||||
|
Note?: string |
||||
|
} |
||||
|
// 查询测点列表
|
||||
|
export function getEXAPage(params: EXAPageReqVO) { |
||||
|
return defHttp.get({ url: '/alert/exa/page', params }) |
||||
|
} |
||||
|
|
||||
|
// 查询实时值列表
|
||||
|
export function getExaNowList(itemName: string) { |
||||
|
return defHttp.get({ url: `/alert/exa/nowList?itemName=${itemName}` }) |
||||
|
} |
||||
|
|
||||
|
export function getExaNow(itemName: string) { |
||||
|
return defHttp.get({ url: `/alert/exa/now?itemName=${itemName}` }) |
||||
|
} |
||||
|
|
||||
|
// 查询历史值-单点
|
||||
|
export function getExaHistory(params: EXAHistoryReqVO) { |
||||
|
return defHttp.get({ url: '/alert/exa/history', params }) |
||||
|
} |
||||
|
|
||||
|
// 查询历史值-多点
|
||||
|
export function getExaHistorys(params: EXAHistoryReqVO) { |
||||
|
return defHttp.get({ url: '/alert/exa/historys', params }) |
||||
|
} |
||||
|
|
||||
|
// 新增点
|
||||
|
export function createEXAPoint(data: EXAPoint) { |
||||
|
return defHttp.post({ url: '/alert/exa/create', data }) |
||||
|
} |
||||
|
|
||||
|
// 获取全部组名
|
||||
|
export function getGroup() { |
||||
|
return defHttp.get({ url: '/alert/exa/group' }) |
||||
|
} |
||||
|
// 删除点
|
||||
|
export function deletePoint(ItemName: string) { |
||||
|
return defHttp.delete({ url: `/alert/exa/delete?ItemName=${ItemName}` }) |
||||
|
} |
@ -0,0 +1,2 @@ |
|||||
|
<template> |
||||
|
</template> |
@ -0,0 +1,114 @@ |
|||||
|
<script lang="ts" setup> |
||||
|
import type { Ref } from 'vue' |
||||
|
import { onMounted, ref, watch } from 'vue' |
||||
|
import type { YAXisOption } from 'echarts/types/dist/shared' |
||||
|
import { useECharts } from '@/hooks/web/useECharts' |
||||
|
import { propTypes } from '@/utils/propTypes' |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
height: { |
||||
|
type: String, |
||||
|
default: propTypes.string.def('500px'), |
||||
|
}, |
||||
|
name: { |
||||
|
type: Array<string>, |
||||
|
default: [], |
||||
|
}, |
||||
|
data: { |
||||
|
type: Array<Array<number>>, |
||||
|
default: () => [[]], |
||||
|
}, |
||||
|
width: propTypes.string.def('100%'), |
||||
|
// height: propTypes.string.def('70vh'), |
||||
|
}) |
||||
|
const chartRef = ref<HTMLDivElement | null>(null) |
||||
|
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>) |
||||
|
onMounted(() => { |
||||
|
|
||||
|
}) |
||||
|
|
||||
|
// const yAxis = reactive<yAxisForm>({ |
||||
|
// type: 'value', |
||||
|
// scale: true, // 开启自适应刻度 |
||||
|
|
||||
|
// }) |
||||
|
watch( |
||||
|
() => props.data, |
||||
|
() => { |
||||
|
console.log(props.data) |
||||
|
const yAxis = ref<YAXisOption[]>([]) |
||||
|
const series = ref<any[]>([]) |
||||
|
|
||||
|
for (let i = 0; i < props.data.length; i++) { |
||||
|
yAxis.value.push({ |
||||
|
type: 'value', |
||||
|
show: false, |
||||
|
scale: true, // 开启自适应刻度 |
||||
|
}) |
||||
|
series.value.push({ |
||||
|
name: props.name[i], |
||||
|
type: 'line', |
||||
|
smooth: true, |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
lineStyle: { |
||||
|
width: 3, // 0.1的线条是非常细的了 |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
showSymbol: false, |
||||
|
data: props.data[i], |
||||
|
yAxisIndex: i, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
setOptions({ |
||||
|
tooltip: { |
||||
|
trigger: 'axis', |
||||
|
position(pt) { |
||||
|
return [pt[0], '10%'] |
||||
|
}, |
||||
|
}, |
||||
|
title: { |
||||
|
left: 'center', |
||||
|
text: 'Large Ara Chart', |
||||
|
show: false, |
||||
|
}, |
||||
|
toolbox: { |
||||
|
feature: { |
||||
|
dataZoom: { |
||||
|
yAxisIndex: 'none', |
||||
|
}, |
||||
|
restore: {}, |
||||
|
saveAsImage: {}, |
||||
|
}, |
||||
|
}, |
||||
|
xAxis: { |
||||
|
type: 'time', |
||||
|
// boundaryGap: false, |
||||
|
}, |
||||
|
yAxis: yAxis.value, |
||||
|
legend: { |
||||
|
|
||||
|
}, |
||||
|
dataZoom: [ |
||||
|
{ |
||||
|
type: 'inside', |
||||
|
start: 0, |
||||
|
end: 100, |
||||
|
}, |
||||
|
{ |
||||
|
start: 0, |
||||
|
end: 100, |
||||
|
}, |
||||
|
], |
||||
|
series: series.value, |
||||
|
}) |
||||
|
}, |
||||
|
{ immediate: true }, |
||||
|
) |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<div ref="chartRef" :style="{ width, height }" /> |
||||
|
</template> |
@ -0,0 +1,60 @@ |
|||||
|
<script lang="ts" setup> |
||||
|
import { onBeforeMount, onMounted, ref, unref } from 'vue' |
||||
|
import { UploadDragger, message } from 'ant-design-vue' |
||||
|
import type { UploadChangeParam } from 'ant-design-vue' |
||||
|
import { InboxOutlined } from '@ant-design/icons-vue' |
||||
|
|
||||
|
import { useI18n } from '@/hooks/web/useI18n' |
||||
|
import { useMessage } from '@/hooks/web/useMessage' |
||||
|
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
|
import { createEXAPoint, getGroup } from '@/api/alert/exa' |
||||
|
|
||||
|
const emit = defineEmits(['success', 'register']) |
||||
|
const { t } = useI18n() |
||||
|
const { createMessage } = useMessage() |
||||
|
|
||||
|
const [registerCreateBatchModal, { setModalProps, closeModal }] = useModalInner(async () => { |
||||
|
|
||||
|
}) |
||||
|
const fileList = ref([]) |
||||
|
function handleChange(info: UploadChangeParam) { |
||||
|
const status = info.file.status |
||||
|
if (status !== 'uploading') |
||||
|
console.log(info.file, info.fileList) |
||||
|
|
||||
|
if (status === 'done') |
||||
|
message.success(`${info.file.name} file uploaded successfully.`) |
||||
|
else if (status === 'error') |
||||
|
message.error(`${info.file.name} file upload failed.`) |
||||
|
} |
||||
|
function handleDrop(e: DragEvent) { |
||||
|
console.log(e) |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<BasicModal |
||||
|
v-bind="$attrs" :min-height="200" :title="t('action.createBatch')" @register="registerCreateBatchModal" |
||||
|
@ok="handleSubmit" |
||||
|
> |
||||
|
<UploadDragger |
||||
|
v-model:fileList="fileList" |
||||
|
name="file" |
||||
|
:multiple="true" |
||||
|
action="/user/import/" |
||||
|
@change="handleChange" |
||||
|
@drop="handleDrop" |
||||
|
> |
||||
|
<p class="ant-upload-drag-icon"> |
||||
|
<inbox-outlined /> |
||||
|
</p> |
||||
|
<p class="ant-upload-text"> |
||||
|
Click or drag file to this area to upload |
||||
|
</p> |
||||
|
<p class="ant-upload-hint"> |
||||
|
Support for a single or bulk upload. Strictly prohibit from uploading company data or other |
||||
|
band files |
||||
|
</p> |
||||
|
</UploadDragger> |
||||
|
</BasicModal> |
||||
|
</template> |
@ -0,0 +1,95 @@ |
|||||
|
<script lang="ts" setup> |
||||
|
import { onBeforeMount, onMounted, ref, unref } from 'vue' |
||||
|
import { formSchema } from '../exa.data' |
||||
|
import { useI18n } from '@/hooks/web/useI18n' |
||||
|
import { useMessage } from '@/hooks/web/useMessage' |
||||
|
import { BasicForm, useForm } from '@/components/Form' |
||||
|
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
|
import { createEXAPoint, getGroup } from '@/api/alert/exa' |
||||
|
|
||||
|
const emit = defineEmits(['success', 'register']) |
||||
|
const { t } = useI18n() |
||||
|
const { createMessage } = useMessage() |
||||
|
|
||||
|
// 组名 |
||||
|
const groupList = ref() |
||||
|
|
||||
|
// onMounted(() => { |
||||
|
// getGroupListSelect() |
||||
|
// }) |
||||
|
const [registerForm, { resetFields, validate, updateSchema }] = useForm({ |
||||
|
labelWidth: 120, |
||||
|
baseColProps: { span: 24 }, |
||||
|
schemas: formSchema, |
||||
|
showActionButtonGroup: false, |
||||
|
actionColOptions: { span: 23 }, |
||||
|
|
||||
|
}) |
||||
|
|
||||
|
const [registerModal, { setModalProps, closeModal }] = useModalInner(async () => { |
||||
|
resetFields() |
||||
|
setModalProps({ confirmLoading: false }) |
||||
|
getGroupListSelect() |
||||
|
|
||||
|
// isUpdate.value = !!data?.isUpdate |
||||
|
// if (unref(isUpdate)) { |
||||
|
// const res = await getRole(data.record.id) |
||||
|
// setFieldsValue({ ...res }) |
||||
|
// } |
||||
|
}) |
||||
|
|
||||
|
async function getGroupListSelect() { |
||||
|
// 从后端接口获取值(后端返回数据必须是{label:'',value:''}形式) |
||||
|
const res = await getGroup() |
||||
|
const list = [] as any |
||||
|
// // 组名下拉框问题 |
||||
|
res.forEach((item) => { |
||||
|
list.push({ label: item.GroupName, value: item.GroupName }) |
||||
|
}) |
||||
|
|
||||
|
groupList.value = list |
||||
|
console.log(groupList.value) |
||||
|
// 将数据放入下拉框中 |
||||
|
updateSchema({ |
||||
|
field: 'GroupName', |
||||
|
componentProps: { |
||||
|
options: unref(groupList.value), |
||||
|
}, |
||||
|
}) |
||||
|
} |
||||
|
async function handleSubmit() { |
||||
|
try { |
||||
|
const values = await validate() |
||||
|
setModalProps({ confirmLoading: true }) |
||||
|
// const mergedObject = Object.assign({}, values, { AutoSave: 1 }) |
||||
|
const createResult = await createEXAPoint(values) |
||||
|
|
||||
|
closeModal() |
||||
|
if (createResult === '1') { |
||||
|
createMessage.success(t('common.successText')) |
||||
|
emit('success') |
||||
|
} |
||||
|
|
||||
|
else if (createResult === '-20') { |
||||
|
createMessage.info('点号已存在') |
||||
|
} |
||||
|
|
||||
|
else { |
||||
|
createMessage.error(t('common.errorText')) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
finally { |
||||
|
setModalProps({ confirmLoading: false }) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<BasicModal |
||||
|
v-bind="$attrs" :min-height="200" :title="t('action.create')" @register="registerModal" |
||||
|
@ok="handleSubmit" |
||||
|
> |
||||
|
<BasicForm @register="registerForm" /> |
||||
|
</BasicModal> |
||||
|
</template> |
@ -0,0 +1,77 @@ |
|||||
|
<script lang="ts" setup> |
||||
|
import { ref } from 'vue' |
||||
|
import moment from 'moment' |
||||
|
|
||||
|
import { Card } from 'ant-design-vue' |
||||
|
import { formHistory } from '../exa.data' |
||||
|
import EXAHistoryLine from '../EXAHistoryLine.vue' |
||||
|
|
||||
|
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
|
import { BasicForm, useForm } from '@/components/Form' |
||||
|
|
||||
|
import { getExaHistorys } from '@/api/alert/exa' |
||||
|
|
||||
|
const loading = ref(true) |
||||
|
|
||||
|
const itemName = ref('') |
||||
|
|
||||
|
const [registerForm, { getFieldsValue }] = useForm({ |
||||
|
labelWidth: 100, |
||||
|
// baseColProps: { span: 24 }, |
||||
|
schemas: formHistory, |
||||
|
showResetButton: false, |
||||
|
layout: 'horizontal', |
||||
|
model: { time: [moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')] }, |
||||
|
fieldMapToTime: [ |
||||
|
// data为时间组件在表单内的字段,startTime,endTime为转化后的开始时间于结束时间 |
||||
|
['time', ['startTime', 'endTime'], 'YYYY-MM-DD HH:mm:ss'], |
||||
|
], |
||||
|
actionColOptions: { span: 2 }, |
||||
|
}) |
||||
|
const historyData = ref() |
||||
|
const legendName = ref<any[]>([]) |
||||
|
|
||||
|
const [registerHistoryModal, { setModalProps }] = useModalInner(async (data) => { |
||||
|
console.log(543) |
||||
|
setModalProps({ confirmLoading: false, showCancelBtn: false, showOkBtn: false }) |
||||
|
itemName.value = data.record.itemName |
||||
|
legendName.value = [] |
||||
|
legendName.value.push(`${data.record.descriptor}-${data.record.itemName}`) |
||||
|
handleSubmitR() |
||||
|
// 利用点号去获取历史数据,从而生成曲线 |
||||
|
// setFieldsValue({ time: [moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')] }) |
||||
|
// console.log(startTime, endTime, itemName) |
||||
|
// const historyData = getExaHistory({ |
||||
|
// startTime, |
||||
|
// endTime, |
||||
|
// itemName: itemName.value, |
||||
|
// }) |
||||
|
// isUpdate.value = !!data?.isUpdate |
||||
|
// if (unref(isUpdate)) { |
||||
|
// const res = await getUser(data.record.id) |
||||
|
// setFieldsValue({ ...res }) |
||||
|
// } |
||||
|
}) |
||||
|
|
||||
|
async function handleSubmitR() { |
||||
|
const serachFormData = getFieldsValue() |
||||
|
loading.value = true |
||||
|
const exaHistoryReqVO = { |
||||
|
startTime: serachFormData.startTime, |
||||
|
endTime: serachFormData.endTime, |
||||
|
itemName: itemName.value, |
||||
|
} |
||||
|
historyData.value = await getExaHistorys(exaHistoryReqVO) |
||||
|
|
||||
|
loading.value = false |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<BasicModal v-bind="$attrs" title="历史曲线" width="80%" @register="registerHistoryModal"> |
||||
|
<BasicForm @register="registerForm" @submit="handleSubmitR" /> |
||||
|
<Card :loading="loading"> |
||||
|
<EXAHistoryLine :data="historyData" :name="legendName" height="500px" /> |
||||
|
</Card> |
||||
|
</BasicModal> |
||||
|
</template> |
@ -0,0 +1,154 @@ |
|||||
|
<script lang="ts" setup> |
||||
|
import { onMounted, onUnmounted } from 'vue' |
||||
|
import { columns, searchFormSchema } from '../exa.data' |
||||
|
import EXAModal from './EXAModal.vue' |
||||
|
import CreateBatchModal from './CreateBatchModal.vue' |
||||
|
|
||||
|
import HistoryModal from './HistoryModal.vue' |
||||
|
import { useI18n } from '@/hooks/web/useI18n' |
||||
|
import { useMessage } from '@/hooks/web/useMessage' |
||||
|
import { useModal } from '@/components/Modal' |
||||
|
import { IconEnum } from '@/enums/appEnum' |
||||
|
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
|
import type { RoleExportReqVO } from '@/api/system/role' |
||||
|
import { deletePoint, getEXAPage, getExaNow } from '@/api/alert/exa' |
||||
|
|
||||
|
defineOptions({ name: 'EXAConfig' }) |
||||
|
|
||||
|
const { t } = useI18n() |
||||
|
const { createConfirm, createMessage } = useMessage() |
||||
|
const [registerModal, { openModal }] = useModal() |
||||
|
const [registerCreateBatchModal, { openModal: openCreateBatchModal }] = useModal() |
||||
|
|
||||
|
const [registerHistoryModal, { openModal: openHistoryModal }] = useModal() |
||||
|
|
||||
|
const [registerTable, { getForm, reload, getDataSource, updateTableDataRecord }] = useTable({ |
||||
|
title: '测点列表', |
||||
|
api: getEXAPage, |
||||
|
rowKey: 'serialNumber', |
||||
|
immediate: false, |
||||
|
columns, |
||||
|
formConfig: { |
||||
|
labelWidth: 150, |
||||
|
schemas: searchFormSchema, |
||||
|
showResetButton: false, |
||||
|
actionColOptions: { |
||||
|
span: 2, |
||||
|
}, |
||||
|
}, |
||||
|
useSearchForm: true, |
||||
|
showTableSetting: true, |
||||
|
showIndexColumn: false, |
||||
|
actionColumn: { |
||||
|
width: 140, |
||||
|
title: t('common.action'), |
||||
|
dataIndex: 'action', |
||||
|
fixed: 'right', |
||||
|
}, |
||||
|
}) |
||||
|
// function handleQuery() { |
||||
|
// getForm().setFieldsValue({ condition: '锅炉' }) |
||||
|
// reload() |
||||
|
// } |
||||
|
|
||||
|
async function getNow() { |
||||
|
const params = getDataSource() |
||||
|
params.forEach((item: any) => { |
||||
|
// 对数组中的每个元素执行异步操作 |
||||
|
getExaNow(item.itemName).then((result) => { |
||||
|
updateTableDataRecord(item.serialNumber, Object.assign(item, { value: result })) |
||||
|
}) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
let timerId |
||||
|
onMounted(() => { |
||||
|
// 启动定时器,每5秒刷新一次 |
||||
|
timerId = setInterval(() => { |
||||
|
getNow() |
||||
|
}, 5000) // 每5秒执行一次[^1] |
||||
|
}) |
||||
|
|
||||
|
onUnmounted(() => { |
||||
|
// 组件销毁时清除定时器 |
||||
|
clearInterval(timerId) |
||||
|
}) |
||||
|
function handleCreate() { |
||||
|
openModal(true, {}) |
||||
|
} |
||||
|
function handleCreateBatch() { |
||||
|
openCreateBatchModal(true, {}) |
||||
|
} |
||||
|
function handleHistory(record: Recordable) { |
||||
|
openHistoryModal(true, { record }) |
||||
|
} |
||||
|
async function handleExport() { |
||||
|
createConfirm({ |
||||
|
title: t('common.exportTitle'), |
||||
|
iconType: 'warning', |
||||
|
content: t('common.exportMessage'), |
||||
|
async onOk() { |
||||
|
await exportRole(getForm().getFieldsValue() as RoleExportReqVO) |
||||
|
createMessage.success(t('common.exportSuccessText')) |
||||
|
}, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
async function handleDelete(record: Recordable) { |
||||
|
await deletePoint(record.itemName) |
||||
|
createMessage.success(t('common.delSuccessText')) |
||||
|
reload() |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<div> |
||||
|
<BasicTable @register="registerTable"> |
||||
|
<template #value="{ record }"> |
||||
|
<a class="click-status" @click="handleHistory(record)"> |
||||
|
{{ record.value }} |
||||
|
</a> |
||||
|
<!-- <SlidersOutlined class="click-status" /> --> |
||||
|
</template> |
||||
|
<template #toolbar> |
||||
|
<a-button v-auth="['system:role:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreate"> |
||||
|
{{ t('action.create') }} |
||||
|
</a-button> |
||||
|
<a-button v-auth="['system:role:create']" type="primary" :pre-icon="IconEnum.ADD" @click="handleCreateBatch"> |
||||
|
{{ t('action.createBatch') }} |
||||
|
</a-button> |
||||
|
<!-- <a-button v-auth="['system:role:create']" :pre-icon="IconEnum.EXPORT" @click="handleExport"> |
||||
|
{{ t('action.export') }} |
||||
|
</a-button> --> |
||||
|
</template> |
||||
|
<template #bodyCell="{ column, record }"> |
||||
|
<template v-if="column.key === 'action'"> |
||||
|
<TableAction |
||||
|
:actions="[{ |
||||
|
icon: IconEnum.DELETE, |
||||
|
danger: true, |
||||
|
label: t('action.delete'), |
||||
|
auth: 'alert:exa:delete', |
||||
|
popConfirm: { |
||||
|
title: t('common.delMessage'), |
||||
|
placement: 'left', |
||||
|
confirm: handleDelete.bind(null, record), |
||||
|
}, |
||||
|
}, |
||||
|
]" |
||||
|
/> |
||||
|
</template> |
||||
|
</template> |
||||
|
</BasicTable> |
||||
|
<EXAModal @register="registerModal" @success="reload" /> |
||||
|
<CreateBatchModal @register="registerCreateBatchModal" /> |
||||
|
<HistoryModal @register="registerHistoryModal" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<style lang="less" scoped> |
||||
|
:deep(.value) { |
||||
|
font-weight:bold; |
||||
|
color: #0B55A4 |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,128 @@ |
|||||
|
import moment from 'moment' |
||||
|
import type { BasicColumn, FormSchema } from '@/components/Table' |
||||
|
import { DICT_TYPE, getDictOptions } from '@/utils/dict' |
||||
|
|
||||
|
export const columns: BasicColumn[] = [ |
||||
|
{ |
||||
|
title: '编号', |
||||
|
dataIndex: 'serialNumber', |
||||
|
width: 80, |
||||
|
}, |
||||
|
{ |
||||
|
title: '测点编码', |
||||
|
dataIndex: 'itemName', |
||||
|
width: 150, |
||||
|
}, |
||||
|
{ |
||||
|
title: '测点名称', |
||||
|
dataIndex: 'descriptor', |
||||
|
width: 200, |
||||
|
}, |
||||
|
{ |
||||
|
title: '实时值', |
||||
|
dataIndex: 'value', |
||||
|
width: 90, |
||||
|
className: 'value', |
||||
|
slots: { customRender: 'value' }, |
||||
|
|
||||
|
}, |
||||
|
{ |
||||
|
title: '单位', |
||||
|
dataIndex: 'engUnits', |
||||
|
width: 30, |
||||
|
}, |
||||
|
{ |
||||
|
title: '组别', |
||||
|
dataIndex: 'groupName', |
||||
|
width: 50, |
||||
|
}, |
||||
|
|
||||
|
] |
||||
|
|
||||
|
export const searchFormSchema: FormSchema[] = [ |
||||
|
{ |
||||
|
label: '测点名称或测点描述', |
||||
|
field: 'condition', |
||||
|
component: 'Input', |
||||
|
defaultValue: '', |
||||
|
required: true, |
||||
|
colProps: { span: 8 }, |
||||
|
}, |
||||
|
] |
||||
|
|
||||
|
export const formSchema: FormSchema[] = [ |
||||
|
|
||||
|
{ |
||||
|
label: '测点编码', |
||||
|
field: 'ItemName', |
||||
|
required: true, |
||||
|
component: 'Input', |
||||
|
}, |
||||
|
{ |
||||
|
label: '测点描述', |
||||
|
field: 'Descriptor', |
||||
|
required: true, |
||||
|
component: 'Input', |
||||
|
}, |
||||
|
{ |
||||
|
label: '单位', |
||||
|
field: 'EngUnits', |
||||
|
required: true, |
||||
|
component: 'Input', |
||||
|
}, |
||||
|
{ |
||||
|
label: '组名', |
||||
|
field: 'GroupName', |
||||
|
component: 'Select', |
||||
|
componentProps: { |
||||
|
options: getDictOptions(DICT_TYPE.COMMON_STATUS), |
||||
|
}, |
||||
|
required: true, |
||||
|
|
||||
|
}, |
||||
|
{ |
||||
|
label: '类型', |
||||
|
field: 'ItemType', |
||||
|
component: 'Select', |
||||
|
componentProps: { |
||||
|
options: [{ value: 1, label: 1 }, { value: 2, label: 2 }, { value: 3, label: 3 }, { value: 4, label: 4 }, { value: 5, label: 5 }], |
||||
|
}, |
||||
|
required: true, |
||||
|
|
||||
|
}, |
||||
|
{ |
||||
|
label: '自动保存', |
||||
|
field: 'AutoSave', |
||||
|
component: 'Select', |
||||
|
componentProps: { |
||||
|
options: [{ value: 1, label: '是' }, { value: 2, label: '否' }], |
||||
|
}, |
||||
|
required: true, |
||||
|
|
||||
|
}, |
||||
|
{ |
||||
|
label: '数据来源', |
||||
|
field: 'Source', |
||||
|
component: 'Input', |
||||
|
}, |
||||
|
] |
||||
|
|
||||
|
export const formHistory: FormSchema[] = [ |
||||
|
{ |
||||
|
label: '时间', |
||||
|
field: 'time', |
||||
|
show: true, |
||||
|
component: 'RangePicker', |
||||
|
componentProps: { |
||||
|
placeholder: ['开始时间', '结束时间'], |
||||
|
defaultValue: [moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')], |
||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss', |
||||
|
showTime: { |
||||
|
defaultValue: [moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')], |
||||
|
}, |
||||
|
onChange: (e: any) => { |
||||
|
console.log(e) |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
] |
@ -0,0 +1,240 @@ |
|||||
|
<script lang="ts" setup> |
||||
|
import { computed, reactive, ref, watch } from 'vue' |
||||
|
import { columns, searchFormSchema } from '../exa.data' |
||||
|
import type { TableActionType } from '@/components/Table' |
||||
|
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
|
import { getEXAPage } from '@/api/alert/exa' |
||||
|
import { useI18n } from '@/hooks/web/useI18n' |
||||
|
import { IconEnum } from '@/enums/appEnum' |
||||
|
import { BasicModal, useModalInner } from '@/components/Modal' |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
selectedData: { type: Array<Recordable>, default: [] }, |
||||
|
selectedRowKeys: { type: Array<number>, default: [] }, |
||||
|
}) |
||||
|
const emit = defineEmits(['success', 'register']) |
||||
|
const [registerPointModal, { setModalProps, closeModal }] = useModalInner(async (data) => { |
||||
|
setModalProps({ confirmLoading: false }) |
||||
|
}) |
||||
|
const { t } = useI18n() |
||||
|
|
||||
|
const selectedData = ref<Recordable[]>(props.selectedData) |
||||
|
|
||||
|
interface RowKeys { |
||||
|
selectedRowKeys: number[] |
||||
|
} |
||||
|
const state = reactive<RowKeys>({ |
||||
|
selectedRowKeys: props.selectedRowKeys, |
||||
|
|
||||
|
}) |
||||
|
|
||||
|
const tableRef = ref<Nullable<TableActionType>>(null) |
||||
|
const tableRef1 = ref<Nullable<TableActionType>>(null) |
||||
|
|
||||
|
const [registerTable] = useTable({ |
||||
|
title: '测点列表', |
||||
|
api: getEXAPage, |
||||
|
immediate: false, |
||||
|
showTableSetting: false, |
||||
|
tableSetting: { |
||||
|
// 是否显示刷新按钮 |
||||
|
redo: false, |
||||
|
// 是否显示尺寸调整按钮 |
||||
|
size: false, |
||||
|
// 是否显示字段调整按钮 |
||||
|
setting: false, |
||||
|
// 是否显示全屏按 |
||||
|
fullScreen: false, |
||||
|
}, |
||||
|
columns, |
||||
|
formConfig: { |
||||
|
labelWidth: 150, |
||||
|
schemas: searchFormSchema, |
||||
|
showResetButton: false, |
||||
|
actionColOptions: { |
||||
|
span: 2, |
||||
|
}, |
||||
|
}, |
||||
|
rowKey: 'serialNumber', |
||||
|
useSearchForm: true, |
||||
|
showIndexColumn: false, |
||||
|
|
||||
|
}) |
||||
|
|
||||
|
// 这个必须写在computed计算属性里,心酸啊,弄一下午! |
||||
|
const rowSelection = computed(() => { |
||||
|
return { |
||||
|
preserveSelectedRowKeys: true, // 2.加这一行 |
||||
|
type: 'checkbox', |
||||
|
selectedRowKeys: state.selectedRowKeys, |
||||
|
onChange: onSelectChange, |
||||
|
|
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
// defaultChecked: record.serialNumber === 93, |
||||
|
watch( |
||||
|
() => props.selectedRowKeys, |
||||
|
() => { |
||||
|
state.selectedRowKeys = props.selectedRowKeys |
||||
|
selectedData.value = props.selectedData |
||||
|
}, |
||||
|
) |
||||
|
// onBeforeMount(() => { |
||||
|
// console.log(props.selectedRowKeys) |
||||
|
// console.log(props.selectedData) |
||||
|
// state.selectedRowKeys = props.selectedRowKeys |
||||
|
// selectedData.value = props.selectedData |
||||
|
// console.log(state.selectedRowKeys) |
||||
|
// console.log(selectedData.value) |
||||
|
|
||||
|
// emit('success') |
||||
|
// }) |
||||
|
|
||||
|
// const historyData = ref() |
||||
|
// const legendName = ref<any[]>([]) |
||||
|
|
||||
|
// async function getHistoryChart() { |
||||
|
// const pointCodeList = selectedData.value.map(item => (item.itemName)) |
||||
|
// loading.value = true |
||||
|
|
||||
|
// if (pointCodeList.length !== 0) { |
||||
|
// const pointCode = selectedData.value.map(item => (item.itemName)).join(',') |
||||
|
// const pointDesc: any[] = selectedData.value.map(item => (item.descriptor)) |
||||
|
|
||||
|
// const exaHistoryReqVO = { |
||||
|
// startTime: searchForm.publishTime[0], |
||||
|
// endTime: searchForm.publishTime[1], |
||||
|
// itemName: pointCode, |
||||
|
// } |
||||
|
// historyData.value = await getExaHistorys(exaHistoryReqVO) |
||||
|
// legendName.value = pointDesc |
||||
|
// } |
||||
|
// else { |
||||
|
// message.info('暂无测点') |
||||
|
// } |
||||
|
// loading.value = false |
||||
|
// } |
||||
|
|
||||
|
const [registerSelectedTable] = useTable({ |
||||
|
title: '已选中测点列表', |
||||
|
showTableSetting: false, |
||||
|
tableSetting: { |
||||
|
// 是否显示刷新按钮 |
||||
|
redo: false, |
||||
|
// 是否显示尺寸调整按钮 |
||||
|
size: false, |
||||
|
// 是否显示字段调整按钮 |
||||
|
setting: false, |
||||
|
// 是否显示全屏按 |
||||
|
fullScreen: false, |
||||
|
}, |
||||
|
columns, |
||||
|
formConfig: { |
||||
|
labelWidth: 150, |
||||
|
schemas: searchFormSchema, |
||||
|
showResetButton: false, |
||||
|
actionColOptions: { |
||||
|
span: 2, |
||||
|
}, |
||||
|
}, |
||||
|
rowKey: 'serialNumber', |
||||
|
useSearchForm: false, |
||||
|
showIndexColumn: false, |
||||
|
actionColumn: { |
||||
|
width: 140, |
||||
|
title: t('common.action'), |
||||
|
dataIndex: 'action', |
||||
|
fixed: 'right', |
||||
|
}, |
||||
|
}) |
||||
|
|
||||
|
function onSelectChange(selectedRowKeys, selectedRows) { |
||||
|
console.log(selectedRowKeys, selectedRows) |
||||
|
state.selectedRowKeys = selectedRowKeys |
||||
|
let selectionRows: any[] = [] |
||||
|
console.log('3', selectedData.value) |
||||
|
|
||||
|
selectionRows = selectedData.value.concat(selectedRows) |
||||
|
console.log('2', selectionRows) |
||||
|
|
||||
|
selectionRows = selectionRows.filter(item => selectedRowKeys.includes(item.serialNumber)) |
||||
|
console.log('1', selectionRows) |
||||
|
// 数组对象去重 |
||||
|
const map = new Map() |
||||
|
for (const item of selectionRows) { |
||||
|
if (!map.has(item.serialNumber)) |
||||
|
map.set(item.serialNumber, item) |
||||
|
}; |
||||
|
selectedData.value = [...map.values()] |
||||
|
} |
||||
|
|
||||
|
function handleOk() { |
||||
|
console.log('onOk:') |
||||
|
localStorage.setItem('pointInfo', JSON.stringify(state.selectedRowKeys)) |
||||
|
localStorage.setItem('pointInfoList', JSON.stringify(selectedData.value)) |
||||
|
closeModal() |
||||
|
|
||||
|
emit('success') |
||||
|
} |
||||
|
async function handleDelete(record: Recordable) { |
||||
|
const newArr = state.selectedRowKeys.filter((value) => { |
||||
|
return value !== record.serialNumber |
||||
|
}) |
||||
|
state.selectedRowKeys = newArr |
||||
|
localStorage.setItem('pointInfo', JSON.stringify(state.selectedRowKeys)) |
||||
|
|
||||
|
const newArrObj = selectedData.value.filter((value) => { |
||||
|
return value.serialNumber !== record.serialNumber |
||||
|
}) |
||||
|
selectedData.value = newArrObj |
||||
|
} |
||||
|
function handleClearAndClose() { |
||||
|
state.selectedRowKeys = [] |
||||
|
selectedData.value = [] |
||||
|
localStorage.setItem('pointInfo', JSON.stringify(state.selectedRowKeys)) |
||||
|
localStorage.setItem('pointInfoList', JSON.stringify(selectedData.value)) |
||||
|
closeModal() |
||||
|
emit('success') |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<BasicModal v-bind="$attrs" title="测点配置" width="1000px" @register="registerPointModal" @ok="handleOk"> |
||||
|
<BasicTable |
||||
|
ref="tableRef" :can-resize="false" title="RefTable示例" title-help-message="使用Ref调用表格内方法" |
||||
|
:row-selection="rowSelection" size="small" @register="registerTable" |
||||
|
/> |
||||
|
<BasicTable |
||||
|
ref="tableRef1" :pagination="false" size="small" :data-source="selectedData" :can-resize="false" |
||||
|
title="已选中测点" title-help-message="使用Ref调用表格内方法" @register="registerSelectedTable" |
||||
|
> |
||||
|
<template #bodyCell="{ column, record }"> |
||||
|
<template v-if="column.key === 'action'"> |
||||
|
<TableAction |
||||
|
:actions="[{ |
||||
|
icon: IconEnum.DELETE, |
||||
|
danger: true, |
||||
|
label: t('action.delete'), |
||||
|
auth: 'system:role:delete', |
||||
|
popConfirm: { |
||||
|
title: t('common.delMessage'), |
||||
|
placement: 'left', |
||||
|
confirm: handleDelete.bind(null, record), |
||||
|
}, |
||||
|
}, |
||||
|
]" |
||||
|
/> |
||||
|
</template> |
||||
|
</template> |
||||
|
<template #toolbar> |
||||
|
<a-button v-auth="['system:role:create']" type="primary" :pre-icon="IconEnum.DELETE" @click="handleClearAndClose"> |
||||
|
{{ t('action.clearAllandClose') }} |
||||
|
</a-button> |
||||
|
<!-- <a-button v-auth="['system:role:create']" :pre-icon="IconEnum.EXPORT" @click="handleExport"> |
||||
|
{{ t('action.export') }} |
||||
|
</a-button> --> |
||||
|
</template> |
||||
|
</BasicTable> |
||||
|
</BasicModal> |
||||
|
</template> |
@ -0,0 +1,260 @@ |
|||||
|
<script lang="ts" setup> |
||||
|
import { computed, onMounted, reactive, ref } from 'vue' |
||||
|
import type { Dayjs } from 'dayjs' |
||||
|
import moment from 'moment' |
||||
|
import { Button, Card, Form, FormItem, Modal, RangePicker, Space, message } from 'ant-design-vue' |
||||
|
import { columns, searchFormSchema } from '../exa.data' |
||||
|
import EXAHistoryLine from '../EXAHistoryLine.vue' |
||||
|
import type { TableActionType } from '@/components/Table' |
||||
|
import { BasicTable, TableAction, useTable } from '@/components/Table' |
||||
|
import { getEXAPage, getExaHistorys } from '@/api/alert/exa' |
||||
|
import { useI18n } from '@/hooks/web/useI18n' |
||||
|
import { IconEnum } from '@/enums/appEnum' |
||||
|
|
||||
|
const { t } = useI18n() |
||||
|
interface FormState { |
||||
|
publishTime: any[] |
||||
|
} |
||||
|
const searchForm = reactive<FormState>({ |
||||
|
publishTime: [], |
||||
|
}) |
||||
|
const loading = ref(true) |
||||
|
|
||||
|
function onRangeChange(value: [Dayjs, Dayjs], dateString: [string, string]) { |
||||
|
console.log('Selected Time: ', value) |
||||
|
console.log('Formatted Selected Time: ', dateString) |
||||
|
} |
||||
|
|
||||
|
function onRangeOk(value: [Dayjs, Dayjs]) { |
||||
|
console.log('onOk: ', value) |
||||
|
console.log(searchForm.publishTime) |
||||
|
searchForm.publishTime = value |
||||
|
} |
||||
|
|
||||
|
const open = ref<boolean>(false) |
||||
|
const selectedData = ref<Recordable[]>([]) |
||||
|
|
||||
|
interface RowKeys { |
||||
|
selectedRowKeys: number[] |
||||
|
} |
||||
|
const state = reactive<RowKeys>({ |
||||
|
selectedRowKeys: [], |
||||
|
|
||||
|
}) |
||||
|
|
||||
|
const tableRef = ref<Nullable<TableActionType>>(null) |
||||
|
const tableRef1 = ref<Nullable<TableActionType>>(null) |
||||
|
|
||||
|
const [registerTable] = useTable({ |
||||
|
title: '测点列表', |
||||
|
api: getEXAPage, |
||||
|
immediate: false, |
||||
|
showTableSetting: false, |
||||
|
tableSetting: { |
||||
|
// 是否显示刷新按钮 |
||||
|
redo: false, |
||||
|
// 是否显示尺寸调整按钮 |
||||
|
size: false, |
||||
|
// 是否显示字段调整按钮 |
||||
|
setting: false, |
||||
|
// 是否显示全屏按 |
||||
|
fullScreen: false, |
||||
|
}, |
||||
|
columns, |
||||
|
formConfig: { |
||||
|
labelWidth: 150, |
||||
|
schemas: searchFormSchema, |
||||
|
showResetButton: false, |
||||
|
actionColOptions: { |
||||
|
span: 2, |
||||
|
}, |
||||
|
}, |
||||
|
rowKey: 'serialNumber', |
||||
|
useSearchForm: true, |
||||
|
showIndexColumn: false, |
||||
|
|
||||
|
}) |
||||
|
|
||||
|
// 这个必须写在computed计算属性里,心酸啊,弄一下午! |
||||
|
const rowSelection = computed(() => { |
||||
|
return { |
||||
|
preserveSelectedRowKeys: true, // 2.加这一行 |
||||
|
type: 'checkbox', |
||||
|
selectedRowKeys: state.selectedRowKeys, |
||||
|
onChange: onSelectChange, |
||||
|
|
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
// defaultChecked: record.serialNumber === 93, |
||||
|
|
||||
|
onMounted(() => { |
||||
|
state.selectedRowKeys = localStorage.getItem('pointInfo') ? JSON.parse(localStorage.getItem('pointInfo') || '') : [] |
||||
|
selectedData.value = localStorage.getItem('pointInfoList') ? JSON.parse(localStorage.getItem('pointInfoList') || '') : [] |
||||
|
searchForm.publishTime = [moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')] |
||||
|
getHistoryChart() |
||||
|
}) |
||||
|
|
||||
|
const historyData = ref() |
||||
|
const legendName = ref<any[]>([]) |
||||
|
|
||||
|
async function getHistoryChart() { |
||||
|
const pointCodeList = selectedData.value.map(item => (item.itemName)) |
||||
|
loading.value = true |
||||
|
|
||||
|
if (pointCodeList.length !== 0) { |
||||
|
const pointCode = selectedData.value.map(item => (item.itemName)).join(',') |
||||
|
const pointDesc: any[] = selectedData.value.map(item => (item.descriptor)) |
||||
|
|
||||
|
const exaHistoryReqVO = { |
||||
|
startTime: searchForm.publishTime[0], |
||||
|
endTime: searchForm.publishTime[1], |
||||
|
itemName: pointCode, |
||||
|
} |
||||
|
historyData.value = await getExaHistorys(exaHistoryReqVO) |
||||
|
legendName.value = pointDesc |
||||
|
} |
||||
|
else { |
||||
|
message.info('暂无测点') |
||||
|
} |
||||
|
loading.value = false |
||||
|
} |
||||
|
|
||||
|
const [registerSelectedTable] = useTable({ |
||||
|
title: '已选中测点列表', |
||||
|
showTableSetting: false, |
||||
|
tableSetting: { |
||||
|
// 是否显示刷新按钮 |
||||
|
redo: false, |
||||
|
// 是否显示尺寸调整按钮 |
||||
|
size: false, |
||||
|
// 是否显示字段调整按钮 |
||||
|
setting: false, |
||||
|
// 是否显示全屏按 |
||||
|
fullScreen: false, |
||||
|
}, |
||||
|
columns, |
||||
|
formConfig: { |
||||
|
labelWidth: 150, |
||||
|
schemas: searchFormSchema, |
||||
|
showResetButton: false, |
||||
|
actionColOptions: { |
||||
|
span: 2, |
||||
|
}, |
||||
|
}, |
||||
|
rowKey: 'serialNumber', |
||||
|
useSearchForm: false, |
||||
|
showIndexColumn: false, |
||||
|
actionColumn: { |
||||
|
width: 140, |
||||
|
title: t('common.action'), |
||||
|
dataIndex: 'action', |
||||
|
fixed: 'right', |
||||
|
}, |
||||
|
}) |
||||
|
function openModal() { |
||||
|
open.value = true |
||||
|
console.log(24) |
||||
|
console.log(selectedData.value) |
||||
|
} |
||||
|
function onSelectChange(selectedRowKeys, selectedRows) { |
||||
|
console.log(selectedRowKeys, selectedRows) |
||||
|
state.selectedRowKeys = selectedRowKeys |
||||
|
let selectionRows: any[] = [] |
||||
|
console.log('3', selectedData.value) |
||||
|
|
||||
|
selectionRows = selectedData.value.concat(selectedRows) |
||||
|
console.log('2', selectionRows) |
||||
|
|
||||
|
selectionRows = selectionRows.filter(item => selectedRowKeys.includes(item.serialNumber)) |
||||
|
console.log('1', selectionRows) |
||||
|
// 数组对象去重 |
||||
|
const map = new Map() |
||||
|
for (const item of selectionRows) { |
||||
|
if (!map.has(item.serialNumber)) |
||||
|
map.set(item.serialNumber, item) |
||||
|
}; |
||||
|
selectedData.value = [...map.values()] |
||||
|
} |
||||
|
|
||||
|
function handleOk() { |
||||
|
console.log('onOk:') |
||||
|
localStorage.setItem('pointInfo', JSON.stringify(state.selectedRowKeys)) |
||||
|
localStorage.setItem('pointInfoList', JSON.stringify(selectedData.value)) |
||||
|
open.value = false |
||||
|
getHistoryChart() |
||||
|
} |
||||
|
async function handleDelete(record: Recordable) { |
||||
|
const newArr = state.selectedRowKeys.filter((value) => { |
||||
|
return value !== record.serialNumber |
||||
|
}) |
||||
|
state.selectedRowKeys = newArr |
||||
|
localStorage.setItem('pointInfo', JSON.stringify(state.selectedRowKeys)) |
||||
|
|
||||
|
const newArrObj = selectedData.value.filter((value) => { |
||||
|
return value.serialNumber !== record.serialNumber |
||||
|
}) |
||||
|
selectedData.value = newArrObj |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<div> |
||||
|
<Card> |
||||
|
<Form layout="inline" :model="searchForm"> |
||||
|
<FormItem label="时间范围"> |
||||
|
<RangePicker |
||||
|
:model="searchForm.publishTime" |
||||
|
:show-time="{ format: 'HH:mm:ss' }" |
||||
|
:placeholder="['开始时间', '结束时间']" :default-value="[moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')]" |
||||
|
value-format="YYYY-MM-DD HH:mm:ss" |
||||
|
@change="onRangeChange" |
||||
|
@ok="onRangeOk" |
||||
|
/> |
||||
|
</FormItem> |
||||
|
<FormItem> |
||||
|
<Space wrap> |
||||
|
<Button type="primary" @click="getHistoryChart"> |
||||
|
查看趋势 |
||||
|
</Button> |
||||
|
<Button @click="openModal()"> |
||||
|
测点配置 |
||||
|
</Button> |
||||
|
</Space> |
||||
|
</FormItem> |
||||
|
</Form> |
||||
|
</Card> |
||||
|
<Card style="margin:5px" :loading="loading"> |
||||
|
<EXAHistoryLine :data="historyData" :name="legendName" height="70vh" /> |
||||
|
</Card> |
||||
|
<Modal v-model:open="open" :destroy-on-close="false" width="1000px" title="测点配置" @ok="handleOk"> |
||||
|
<BasicTable |
||||
|
ref="tableRef" :can-resize="false" title="RefTable示例" title-help-message="使用Ref调用表格内方法" |
||||
|
:row-selection="rowSelection" size="small" @register="registerTable" |
||||
|
/> |
||||
|
<BasicTable |
||||
|
ref="tableRef1" :pagination="false" size="small" :data-source="selectedData" :can-resize="false" |
||||
|
title="已选中测点" title-help-message="使用Ref调用表格内方法" @register="registerSelectedTable" |
||||
|
> |
||||
|
<template #bodyCell="{ column, record }"> |
||||
|
<template v-if="column.key === 'action'"> |
||||
|
<TableAction |
||||
|
:actions="[{ |
||||
|
icon: IconEnum.DELETE, |
||||
|
danger: true, |
||||
|
label: t('action.delete'), |
||||
|
auth: 'system:role:delete', |
||||
|
popConfirm: { |
||||
|
title: t('common.delMessage'), |
||||
|
placement: 'left', |
||||
|
confirm: handleDelete.bind(null, record), |
||||
|
}, |
||||
|
}, |
||||
|
]" |
||||
|
/> |
||||
|
</template> |
||||
|
</template> |
||||
|
</BasicTable> |
||||
|
</Modal> |
||||
|
</div> |
||||
|
</template> |
@ -0,0 +1,105 @@ |
|||||
|
<script lang="ts" setup> |
||||
|
import { onMounted, reactive, ref } from 'vue' |
||||
|
import type { Dayjs } from 'dayjs' |
||||
|
import moment from 'moment' |
||||
|
import { Button, Card, Form, FormItem, RangePicker, Space, message } from 'ant-design-vue' |
||||
|
import EXAHistoryLine from '../EXAHistoryLine.vue' |
||||
|
import PointModal from './PointModal.vue' |
||||
|
import { getExaHistorys } from '@/api/alert/exa' |
||||
|
import { useModal } from '@/components/Modal' |
||||
|
|
||||
|
interface FormState { |
||||
|
publishTime: any[] |
||||
|
} |
||||
|
const searchForm = reactive<FormState>({ |
||||
|
publishTime: [], |
||||
|
}) |
||||
|
const loading = ref(true) |
||||
|
|
||||
|
function onRangeChange(value: [Dayjs, Dayjs], dateString: [string, string]) { |
||||
|
console.log('Selected Time: ', value) |
||||
|
console.log('Formatted Selected Time: ', dateString) |
||||
|
} |
||||
|
|
||||
|
function onRangeOk(value: [Dayjs, Dayjs]) { |
||||
|
console.log('onOk: ', value) |
||||
|
console.log(searchForm.publishTime) |
||||
|
searchForm.publishTime = value |
||||
|
} |
||||
|
|
||||
|
const selectedData = ref<Recordable[]>([]) |
||||
|
interface RowKeys { |
||||
|
selectedRowKeys: number[] |
||||
|
} |
||||
|
const state = reactive<RowKeys>({ |
||||
|
selectedRowKeys: [], |
||||
|
}) |
||||
|
onMounted(() => { |
||||
|
getHistoryChart() |
||||
|
}) |
||||
|
|
||||
|
const historyData = ref() |
||||
|
const legendName = ref<any[]>([]) |
||||
|
|
||||
|
async function getHistoryChart() { |
||||
|
state.selectedRowKeys = localStorage.getItem('pointInfo') ? JSON.parse(localStorage.getItem('pointInfo') || '') : [] |
||||
|
selectedData.value = localStorage.getItem('pointInfoList') ? JSON.parse(localStorage.getItem('pointInfoList') || '') : [] |
||||
|
searchForm.publishTime = [moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')] |
||||
|
|
||||
|
const pointCodeList = selectedData.value.map(item => (item.itemName)) |
||||
|
loading.value = true |
||||
|
|
||||
|
if (pointCodeList.length === 0) |
||||
|
message.info('暂无测点') |
||||
|
|
||||
|
const pointCode = selectedData.value.map(item => (item.itemName)).join(',') |
||||
|
const pointDesc: any[] = selectedData.value.map(item => (item.descriptor)) |
||||
|
|
||||
|
const exaHistoryReqVO = { |
||||
|
startTime: searchForm.publishTime[0], |
||||
|
endTime: searchForm.publishTime[1], |
||||
|
itemName: pointCode, |
||||
|
} |
||||
|
historyData.value = await getExaHistorys(exaHistoryReqVO) |
||||
|
legendName.value = pointDesc |
||||
|
loading.value = false |
||||
|
} |
||||
|
|
||||
|
const [registerPointModal, { openModal: openPointModal }] = useModal() |
||||
|
function handlePointModal() { |
||||
|
openPointModal(true) |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<div> |
||||
|
<Card> |
||||
|
<Form layout="inline" :model="searchForm"> |
||||
|
<FormItem label="时间范围"> |
||||
|
<RangePicker |
||||
|
:model="searchForm.publishTime" |
||||
|
:show-time="{ format: 'HH:mm:ss' }" |
||||
|
:placeholder="['开始时间', '结束时间']" :default-value="[moment().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), moment().format('YYYY-MM-DD HH:mm:ss')]" |
||||
|
value-format="YYYY-MM-DD HH:mm:ss" |
||||
|
@change="onRangeChange" |
||||
|
@ok="onRangeOk" |
||||
|
/> |
||||
|
</FormItem> |
||||
|
<FormItem> |
||||
|
<Space wrap> |
||||
|
<Button type="primary" @click="getHistoryChart"> |
||||
|
查看趋势 |
||||
|
</Button> |
||||
|
<Button @click="handlePointModal"> |
||||
|
测点配置 |
||||
|
</Button> |
||||
|
</Space> |
||||
|
</FormItem> |
||||
|
</Form> |
||||
|
</Card> |
||||
|
<Card style="margin:5px" :loading="loading"> |
||||
|
<EXAHistoryLine :data="historyData" :name="legendName" height="70vh" /> |
||||
|
</Card> |
||||
|
<PointModal :selected-row-keys="state.selectedRowKeys" :selected-data="selectedData" @register="registerPointModal" @success="getHistoryChart" /> |
||||
|
</div> |
||||
|
</template> |
Loading…
Reference in new issue