From 59569559a1d90d7a4340e5474346353fb823a0c1 Mon Sep 17 00:00:00 2001 From: dongyukun <1208714201@qq.com> Date: 星期五, 15 十一月 2024 17:01:00 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- src/views/data/video/nvr/index.vue | 187 ++-- src/api/data/plan/item/index.ts | 2 src/views/data/video/nvr/NvrCamera.vue | 174 ++-- types/env.d.ts | 1 src/views/bpm/model/index.vue | 17 src/api/data/video/image/index.ts | 50 + src/views/Home/Index.vue | 29 src/api/model/mcs/index.ts | 5 src/utils/is.ts | 3 src/views/model/pre/analysis/index.vue | 1099 ++++++++++++++++--------------- src/views/model/pre/item/MmPredictItemForm.vue | 24 /dev/null | 28 src/views/Login/components/LoginForm.vue | 32 src/views/data/video/camera/index.vue | 197 +++-- src/utils/hostMap.ts | 2 src/api/model/sche/model/index.ts | 21 src/views/data/video/camera/CameraImage.vue | 114 +++ 17 files changed, 1,113 insertions(+), 872 deletions(-) diff --git a/src/api/data/plan/item/index.ts b/src/api/data/plan/item/index.ts index e42e999..eec13e9 100644 --- a/src/api/data/plan/item/index.ts +++ b/src/api/data/plan/item/index.ts @@ -50,7 +50,7 @@ //获取下拉集合 export const getItemList = (params: PageParam) => { - return request.get({ url: '/data/plan-item/getList', params}) + return request.get({ url: '/data/plan-item/list', params}) } // 查询Plan图表 diff --git a/src/api/data/video/image/index.ts b/src/api/data/video/image/index.ts new file mode 100644 index 0000000..d2d5f7a --- /dev/null +++ b/src/api/data/video/image/index.ts @@ -0,0 +1,50 @@ +import request from '@/config/axios' + +export interface ImageVO { + id: undefined, + cameraId: string, + imagePath: string, + imageUrl: string, + createDate: undefined, +} + +// 查询列表 +export const getImagePage = (params: PageParam) => { + return request.get({url: '/data/video/image/page', params}) +} + +// 获得 +export const getImage = (id: number) => { + return request.get({url: '/data/video/image/get?id=' + id}) +} + +// 查询应用列表 +export const getImageList = () => { + return request.get({url: '/data/video/image/list'}) +} + +// 新增 +export const createImage = (data: ImageVO) => { + return request.post({url: '/data/video/image/create', data}) +} + +// 修改 +export const updateImage = (data: ImageVO) => { + return request.put({url: '/data/video/image/update', data}) +} + +// 删除 +export const deleteImage = (id: number) => { + return request.delete({url: '/data/video/image/delete?id=' + id}) +} + +// 导出 +export const exportImage = (params: ImageVO) => { + return request.download({url: '/data/video/image/export-excel', params}) +} + +//预览摄像头截图 +export const getPreviewUrl = (url: string) => { + const host = import.meta.env.VITE_VIDEO_CAMERA_DOMAIN ? import.meta.env.VITE_VIDEO_CAMERA_DOMAIN : window.location.host + return `http://${host}:8899` + url +} diff --git a/src/api/model/mcs/index.ts b/src/api/model/mcs/index.ts index 2cdaef3..4f55207 100644 --- a/src/api/model/mcs/index.ts +++ b/src/api/model/mcs/index.ts @@ -1,7 +1,7 @@ import request from '@/config/axios' export interface PreDataBarLineReqVO { - queryIds: string[], + outIds: string[], predictTime: string, startTime: string, endTime: string @@ -13,6 +13,9 @@ endTime: string } +export const getPredictItemTree = () => { + return request.get({ url: '/model/api/mcs/predict-item/tree'}) +} export const getPreDataCharts = (data: PreDataBarLineReqVO) => { return request.post({ url: '/model/api/mcs/predict-data/charts', data }) diff --git a/src/api/model/sche/model/index.ts b/src/api/model/sche/model/index.ts index 3c5b8bc..8863d31 100644 --- a/src/api/model/sche/model/index.ts +++ b/src/api/model/sche/model/index.ts @@ -1,7 +1,9 @@ import request from '@/config/axios' import * as DataPointApi from '@/api/data/da/point' import * as PredictItemApi from '@/api/model/pre/item' +import * as PlanItemApi from '@/api/data/plan/item' import {CommonEnabled} from "@/utils/constants"; +import {getItemList, ItemVO} from "@/api/data/plan/item"; export interface ScheduleModelVO { id: string @@ -100,8 +102,25 @@ ) }) } + + const planItemList = ref([] as PlanItemApi.ItemVO) + planItemList.value = await PlanItemApi.getItemList({ + }) + const planList = [] + if (planItemList.value) { + planItemList.value.forEach(item => { + planList.push( + { + id: item.id, + name: item.itemName + } + ) + }) + } + return { 'DATAPOINT':pointList, - 'PREDICTITEM': itemList + 'PREDICTITEM': itemList, + 'PLAN': planList, } } diff --git a/src/utils/hostMap.ts b/src/utils/hostMap.ts index 81df37d..c2904af 100644 --- a/src/utils/hostMap.ts +++ b/src/utils/hostMap.ts @@ -1,6 +1,6 @@ const map = { "//localhost:7200/": "//wujie-micro.github.io/demo-vue2/", - "//localhost:90/": "//localhost:90/", + "//localhost:9000/": "//localhost:9000/", "//localhost:8000/": "//wujie-micro.github.io/demo-main-vue/", }; diff --git a/src/utils/is.ts b/src/utils/is.ts index eec86a9..39812b6 100644 --- a/src/utils/is.ts +++ b/src/utils/is.ts @@ -98,8 +98,9 @@ export const isClient = !isServer export const isUrl = (path: string): boolean => { + // fix:修复hash路由无法跳转的问题 const reg = - /(((^https?:(?:\/\/)?)(?:[-:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&%@.\w_]*)#?(?:[\w]*))?)$/ + /(((^https?:(?:\/\/)?)(?:[-:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%#\/.\w-_]*)?\??(?:[-\+=&%@.\w_]*)#?(?:[\w]*))?)$/ return reg.test(path) } diff --git a/src/views/Home/Index.vue b/src/views/Home/Index.vue index aa64a85..822f800 100644 --- a/src/views/Home/Index.vue +++ b/src/views/Home/Index.vue @@ -5,9 +5,9 @@ <el-skeleton :loading="loading" animated> <div id="app" v-for="(item, index) in appList" :key="`dynamics-${index}`"> <div class="card" @click="gotoApp(item)"> - <img :src="item.icon" style="width: 100px; height: 100px" /> + <img :src="item.icon" style="width: 100px; height: 100px"/> <div> - {{item.appName}} + {{ item.appName }} </div> </div> </div> @@ -19,12 +19,11 @@ import * as AppApi from '@/api/system/app' import {Apps} from "@/views/Home/types"; import {CACHE_KEY, useCache} from "@/hooks/web/useCache"; -import * as authUtil from "@/utils/auth"; -defineOptions({ name: 'Home' }) +defineOptions({name: 'Home'}) -const { wsCache } = useCache() +const {wsCache} = useCache() const loading = ref(true) @@ -35,7 +34,7 @@ appList = Object.assign(appList, data) } -const getAppMenuList = async (id) => { +const getAppMenuList = async (id, appCode) => { const data = await AppApi.getAppMenuList(id) let userInfo = wsCache.get(CACHE_KEY.USER) userInfo.menus = data @@ -55,32 +54,38 @@ // 进入应用 const gotoApp = async (item) => { + let path = window.location.pathname + let appName = path.split("/")[0] + console.log(appName) let id = item.id let type = item.type - if(type === 0) { - getAppMenuList(id) + let appCode = item.appCode + if (type === 0) { + await getAppMenuList(id, appCode) } else { const data = await AppApi.getAppMenuList(id) let userInfo = wsCache.get(CACHE_KEY.USER) userInfo.menus = data wsCache.set(CACHE_KEY.USER, userInfo) wsCache.set(CACHE_KEY.ROLE_ROUTERS, data) - // await OAuth2Login(formData.value) - // window.open(item.appDomain + '/login?appid=' + item.id + "&username=" + authUtil.getLoginForm().username, '_blank') window.open(item.appDomain + '/index', '_blank') + // window.open('/plat/shasteel', '_blank') + // window.location.href = '/plat/shasteel' + // window.location.href = `/plat/shasteel?key=energy&url=http://localhost:9000&energy=/energy/demo` } } </script> <style lang="scss" scoped> -#app{ +#app { width: 300px; height: 200px; display: inline-block; background: transparent; } -.card{ + +.card { border: thin dashed gainsboro; width: 150px; height: 120px; diff --git a/src/views/Login/components/LoginForm.vue b/src/views/Login/components/LoginForm.vue index 22a80b2..bc3a32a 100644 --- a/src/views/Login/components/LoginForm.vue +++ b/src/views/Login/components/LoginForm.vue @@ -12,7 +12,7 @@ <el-row style="margin-right: -10px; margin-left: -10px"> <el-col :span="24" style="padding-right: 10px; padding-left: 10px"> <el-form-item> - <LoginFormTitle style="width: 100%" /> + <LoginFormTitle style="width: 100%"/> </el-form-item> </el-col> <el-col :span="24" style="padding-right: 10px; padding-left: 10px"> @@ -86,27 +86,27 @@ </el-form> </template> <script lang="ts" setup> -import { ElLoading } from 'element-plus' +import {ElLoading} from 'element-plus' import LoginFormTitle from './LoginFormTitle.vue' -import type { RouteLocationNormalizedLoaded } from 'vue-router' +import type {RouteLocationNormalizedLoaded} from 'vue-router' -import { useIcon } from '@/hooks/web/useIcon' +import {useIcon} from '@/hooks/web/useIcon' import * as authUtil from '@/utils/auth' -import { usePermissionStore } from '@/store/modules/permission' +import {usePermissionStore} from '@/store/modules/permission' import * as LoginApi from '@/api/login' -import { LoginStateEnum, useFormValid, useLoginState } from './useLogin' +import {LoginStateEnum, useFormValid, useLoginState} from './useLogin' -defineOptions({ name: 'LoginForm' }) +defineOptions({name: 'LoginForm'}) -const { t } = useI18n() -const iconHouse = useIcon({ icon: 'ep:house' }) -const iconAvatar = useIcon({ icon: 'ep:avatar' }) -const iconLock = useIcon({ icon: 'ep:lock' }) +const {t} = useI18n() +const iconHouse = useIcon({icon: 'ep:house'}) +const iconAvatar = useIcon({icon: 'ep:avatar'}) +const iconLock = useIcon({icon: 'ep:lock'}) const formLogin = ref() -const { validForm } = useFormValid(formLogin) -const { getLoginState } = useLoginState() -const { currentRoute, push } = useRouter() +const {validForm} = useFormValid(formLogin) +const {getLoginState} = useLoginState() +const {currentRoute, push} = useRouter() const permissionStore = usePermissionStore() const redirect = ref<string>('') const loginLoading = ref(false) @@ -199,14 +199,14 @@ authUtil.removeLoginForm() } authUtil.setToken(res) - if (!redirect.value) { + if (!redirect.value || redirect.value == "/") { redirect.value = '/index' } // 判断是否为SSO登录 if (redirect.value.indexOf('sso') !== -1) { window.location.href = window.location.href.replace('/login?redirect=', '') } else { - push({ path: redirect.value || permissionStore.addRouters[0].path }) + push({path: redirect.value || permissionStore.addRouters[0].path}) } } finally { loginLoading.value = false diff --git a/src/views/bpm/model/index.vue b/src/views/bpm/model/index.vue index f8b0b75..a20ea4e 100644 --- a/src/views/bpm/model/index.vue +++ b/src/views/bpm/model/index.vue @@ -163,14 +163,6 @@ <el-button link type="primary" - @click="handleSimpleDesign(scope.row.id)" - v-hasPermi="['bpm:model:update']" - > - 仿钉钉设计流程 - </el-button> - <el-button - link - type="primary" @click="handleDeploy(scope.row)" v-hasPermi="['bpm:model:deploy']" > @@ -328,15 +320,6 @@ const handleDesign = (row) => { push({ name: 'BpmModelEditor', - query: { - modelId: row.id - } - }) -} - -const handleSimpleDesign = (row) => { - push({ - name: 'SimpleWorkflowDesignEditor', query: { modelId: row.id } diff --git a/src/views/bpm/simpleWorkflow/index.vue b/src/views/bpm/simpleWorkflow/index.vue deleted file mode 100644 index 144615e..0000000 --- a/src/views/bpm/simpleWorkflow/index.vue +++ /dev/null @@ -1,28 +0,0 @@ -<template> - <div> - <section class="dingflow-design"> - <div class="box-scale"> - <nodeWrap v-model:nodeConfig="nodeConfig" /> - <div class="end-node"> - <div class="end-node-circle"></div> - <div class="end-node-text">流程结束</div> - </div> - </div> - </section> - </div> -</template> -<script lang="ts" setup> -import nodeWrap from '@/components/SimpleProcessDesigner/src/nodeWrap.vue' -defineOptions({ name: 'SimpleWorkflowDesignEditor' }) -let nodeConfig = ref({ - nodeName: '发起人', - type: 0, - id: 'root', - formPerms: {}, - nodeUserList: [], - childNode: {} -}) -</script> -<style> -@import url('@/components/SimpleProcessDesigner/theme/workflow.css'); -</style> \ No newline at end of file diff --git a/src/views/data/video/camera/CameraImage.vue b/src/views/data/video/camera/CameraImage.vue new file mode 100644 index 0000000..335983b --- /dev/null +++ b/src/views/data/video/camera/CameraImage.vue @@ -0,0 +1,114 @@ +<template> + <el-dialog v-model="dialogVisible" :title="dialogTitle" :close="handleClose" + style="width: 50%; margin-top: 20px; overflow: auto; z-index: 1"> + <!-- 列表 --> + <el-table v-loading="loading" :data="list"> + <el-table-column + label="截图时间" + align="center" + prop="createDate" + :formatter="dateFormatter" + width="200" + /> + <el-table-column label="图片路径" align="center" prop="imagePath" width="500" + :show-overflow-tooltip="true"/> + <el-table-column label="图片预览" align="center" prop="imageUrl"> + <template #default="scope"> + <el-image style="height: 50px; z-index: 1" + :src="getPreviewUrl(scope.row.imageUrl)" + :preview-src-list="getPreviewSrcList(scope.row.imageUrl)" fit="cover" + preview-teleported/> + </template> + </el-table-column> + <el-table-column label="操作" align="center" min-width="60" fixed="right"> + <template #default="scope"> + <el-button + link + type="danger" + style="z-index: 1" + @click="handleDelete(scope.row.id)" + v-hasPermi="['video:camera:delete']" + > + 删除 + </el-button> + </template> + </el-table-column> + </el-table> + <!-- 分页 --> + <Pagination + :total="total" + v-model:page="queryParams.pageNo" + v-model:limit="queryParams.pageSize" + @pagination="open" + /> + </el-dialog> +</template> +<script lang="ts" setup> +import * as ImageApi from '@/api/data/video/image' +import {getPreviewUrl} from "@/api/data/video/image"; +import {dateFormatter} from "@/utils/formatTime"; + +defineOptions({name: 'CameraImage'}) + +const message = useMessage() // 消息弹窗 +const {t} = useI18n() // 国际化 +const dialogTitle = ref('截图列表') +const loading = ref(true) // 列表的加载中 +const total = ref(0) // 列表的总页数 +const list = ref([]) // 列表的数据 +const queryParams = reactive({ + pageNo: 1, + pageSize: 10, + id: undefined, + brand: undefined, + code: undefined, + device: undefined, + cameraId: '', + imagePath: undefined, + imageUrl: undefined, + createDate: undefined, +}) +const cameraId = ref('') +const dialogVisible = ref(false) + +/** 查询列表 */ +const open = async (camera_id: string) => { + dialogVisible.value = true + cameraId.value = camera_id + queryParams.cameraId = camera_id + loading.value = true + try { + const data = await ImageApi.getImagePage(queryParams) + list.value = data.list + total.value = data.total + } finally { + loading.value = false + } +} + +defineExpose({open}) // 提供 open 方法,用于打开弹窗 + +const handleClose = async () => { + dialogVisible.value = false +} + +const getPreviewSrcList = (imageUrl: string) => { + let previewSrcList: string[] = [] + previewSrcList.push(getPreviewUrl(imageUrl)) + return previewSrcList +} + +/** 删除按钮操作 */ +const handleDelete = async (id: number) => { + try { + // 删除的二次确认 + await message.delConfirm() + // 发起删除 + await ImageApi.deleteImage(id) + message.success(t('common.delSuccess')) + // 刷新列表 + await open(cameraId.value) + } catch { + } +} +</script> diff --git a/src/views/data/video/camera/index.vue b/src/views/data/video/camera/index.vue index d0fbbe6..add49c5 100644 --- a/src/views/data/video/camera/index.vue +++ b/src/views/data/video/camera/index.vue @@ -61,11 +61,11 @@ </el-form-item> <el-form-item> <el-button @click="handleQuery"> - <Icon icon="ep:search" class="mr-5px" /> + <Icon icon="ep:search" class="mr-5px"/> 搜索 </el-button> <el-button @click="resetQuery"> - <Icon icon="ep:refresh" class="mr-5px" /> + <Icon icon="ep:refresh" class="mr-5px"/> 重置 </el-button> <el-button @@ -74,7 +74,7 @@ @click="openForm('create')" v-hasPermi="['video:camera:save']" > - <Icon icon="ep:plus" class="mr-5px" /> + <Icon icon="ep:plus" class="mr-5px"/> 新增 </el-button> <el-button @@ -84,7 +84,7 @@ :loading="exportLoading" v-hasPermi="['video:camera:export']" > - <Icon icon="ep:download" class="mr-5px" /> + <Icon icon="ep:download" class="mr-5px"/> 导出 </el-button> </el-form-item> @@ -96,20 +96,21 @@ <el-table v-loading="loading" :data="list"> <el-table-column label="品牌" align="center" prop="brand" width="80"> <template #default="scope"> - <dict-tag :type="DICT_TYPE.CAMERA_BRAND" :value="scope.row.brand" /> + <dict-tag :type="DICT_TYPE.CAMERA_BRAND" :value="scope.row.brand"/> </template> </el-table-column> <el-table-column label="设备类型" align="center" prop="device" width="200"/> <el-table-column label="编码" align="center" prop="code" width="200"/> - <el-table-column label="IP" align="center" prop="ip" /> - <el-table-column label="端口" align="center" prop="port" width="100"/> + <el-table-column label="IP" align="center" prop="ip"/> + <el-table-column label="端口" align="center" prop="port" width="80"/> + <el-table-column label="通道" align="center" prop="channel" width="80"/> <el-table-column label="用户名" align="center" prop="username" width="100"/> <el-table-column label="状态" prop="status" width="80"> <template #default="scope"> - <dict-tag :type="DICT_TYPE.NVR_ONLINE_STATUS" :value="scope.row.status" /> + <dict-tag :type="DICT_TYPE.NVR_ONLINE_STATUS" :value="scope.row.status"/> </template> </el-table-column> - <el-table-column label="位置" align="center" prop="location" /> + <el-table-column label="位置" align="center" prop="location"/> <el-table-column label="备注" align="center" prop="remark" width="150"/> <el-table-column label="操作" align="center" min-width="110" fixed="right"> <template #default="scope"> @@ -129,6 +130,14 @@ > 删除 </el-button> + <el-button + link + type="success" + @click="imageHandle(scope.row.id)" + v-hasPermi="['video:image:query']" + > + 查看截图 + </el-button> </template> </el-table-column> </el-table> @@ -142,99 +151,109 @@ </ContentWrap> <!-- 表单弹窗:添加/修改 --> - <CameraForm ref="formRef" @success="getList" /> + <CameraForm ref="formRef" @success="getList"/> + <CameraImage ref="imageFormRef"/> </template> <script lang="ts" setup> import {DICT_TYPE, getIntDictOptions} from '@/utils/dict' - import download from '@/utils/download' - import * as CameraApi from '@/api/data/video/camera' - import CameraForm from './CameraForm.vue' +import download from '@/utils/download' +import * as CameraApi from '@/api/data/video/camera' +import CameraForm from './CameraForm.vue' +import CameraImage from './CameraImage.vue' - defineOptions({name: 'Camera'}) - const message = useMessage() // 消息弹窗 - const {t} = useI18n() // 国际化 +defineOptions({name: 'Camera'}) - const loading = ref(true) // 列表的加载中 - const total = ref(0) // 列表的总页数 - const list = ref([]) // 列表的数据 - const queryParams = reactive({ - pageNo: 1, - pageSize: 10, - type: 1, - brand: undefined, - ip: undefined, - code: undefined, - device: undefined, - location: undefined, - status: undefined - }) - const queryFormRef = ref() // 搜索的表单 - const exportLoading = ref(false) // 导出的加载中 +const message = useMessage() // 消息弹窗 +const {t} = useI18n() // 国际化 - /** 查询列表 */ - const getList = async () => { - loading.value = true - try { - const data = await CameraApi.getCameraPage(queryParams) - list.value = data.list - total.value = data.total - } finally { - loading.value = false - } +const loading = ref(true) // 列表的加载中 +const total = ref(0) // 列表的总页数 +const list = ref([]) // 列表的数据 +const queryParams = reactive({ + pageNo: 1, + pageSize: 10, + type: 1, + brand: undefined, + ip: undefined, + code: undefined, + device: undefined, + location: undefined, + status: undefined +}) +const queryFormRef = ref() // 搜索的表单 +const exportLoading = ref(false) // 导出的加载中 + +/** 查询列表 */ +const getList = async () => { + loading.value = true + try { + const data = await CameraApi.getCameraPage(queryParams) + list.value = data.list + total.value = data.total + } finally { + loading.value = false } +} - /** 搜索按钮操作 */ - const handleQuery = () => { - queryParams.pageNo = 1 - getList() - } +/** 搜索按钮操作 */ +const handleQuery = () => { + queryParams.pageNo = 1 + getList() +} - /** 重置按钮操作 */ - const resetQuery = () => { - queryFormRef.value.resetFields() - handleQuery() - } +/** 重置按钮操作 */ +const resetQuery = () => { + queryFormRef.value.resetFields() + queryParams.brand = undefined + handleQuery() +} - /** 添加/修改操作 */ - const formRef = ref() - const openForm = (type: string, id?: number) => { - formRef.value.open(type, id) - } +/** 添加/修改操作 */ +const formRef = ref() +const openForm = (type: string, id?: number) => { + formRef.value.open(type, id) +} - /** 删除按钮操作 */ - const handleDelete = async (id: number) => { - try { - // 删除的二次确认 - await message.delConfirm() - // 发起删除 - await CameraApi.deleteCamera(id) - message.success(t('common.delSuccess')) - // 刷新列表 - await getList() - } catch { - } - } - - /** 导出按钮操作 */ - const handleExport = async () => { - try { - // 导出的二次确认 - await message.exportConfirm() - // 发起导出 - exportLoading.value = true - const data = await CameraApi.exportCamera(queryParams) - download.excel(data, '录像机列表.xls') - } catch { - } finally { - exportLoading.value = false - } - } - - /** 初始化 **/ - onMounted(async () => { +/** 删除按钮操作 */ +const handleDelete = async (id: number) => { + try { + // 删除的二次确认 + await message.delConfirm() + // 发起删除 + await CameraApi.deleteCamera(id) + message.success(t('common.delSuccess')) + // 刷新列表 await getList() - }) + } catch { + } +} + +/** 查看截图 */ +const imageFormRef = ref() +const imageHandle = (id: string) => { + imageFormRef.value.open(id) +} + +/** 导出按钮操作 */ +const handleExport = async () => { + try { + // 导出的二次确认 + await message.exportConfirm() + // 发起导出 + exportLoading.value = true + const data = await CameraApi.exportCamera(queryParams) + download.excel(data, '录像机列表.xls') + } catch { + } finally { + exportLoading.value = false + } +} + +/** 初始化 **/ +onMounted(async () => { + await getList() +}) </script> diff --git a/src/views/data/video/nvr/NvrCamera.vue b/src/views/data/video/nvr/NvrCamera.vue index 0ff49b3..212ff57 100644 --- a/src/views/data/video/nvr/NvrCamera.vue +++ b/src/views/data/video/nvr/NvrCamera.vue @@ -6,95 +6,104 @@ @close="handleClose" size="60%"> <div class="mod-dev__camera" style="padding: 10px;"> - <el-form - class="-mb-15px" - :model="queryParams" - ref="queryFormRef" - :inline="true" - label-width="68px" - > - <el-form-item label="监控区域" prop="code"> - <el-input - v-model="queryParams.location" - placeholder="请输入监控区域" - clearable - @keyup.enter="handleQuery" - class="!w-240px" - /> - </el-form-item> - <el-form-item> - <el-button @click="handleQuery"> - <Icon icon="ep:search" class="mr-5px" /> - 搜索 - </el-button> - <el-button @click="resetQuery"> - <Icon icon="ep:refresh" class="mr-5px" /> - 重置 - </el-button> - <el-button - type="primary" - plain - @click="openForm('create')" - > - <Icon icon="ep:plus" class="mr-5px" /> - 新增 - </el-button> - <el-button - type="success" - plain - @click="handleExport" - :loading="exportLoading" - v-hasPermi="['dev:camera:export']" - > - <Icon icon="ep:download" class="mr-5px" /> - 导出 - </el-button> - </el-form-item> - </el-form> - - <!-- 列表 --> - <el-table v-loading="loading" :data="list"> - <el-table-column label="编码" align="center" prop="code" width="80" /> - <el-table-column label="抓图方式" align="center" prop="captureType" width="80"> - <template #default="scope"> - <dict-tag :type="DICT_TYPE.CAPTURE_TYPE" :value="scope.row.captureType" /> - </template> - </el-table-column> - <el-table-column label="通道" align="center" prop="channel" width="80" /> - <el-table-column label="监控区域" align="center" prop="location" /> - <el-table-column label="备注" align="center" prop="remark" width="200" /> - <el-table-column label="操作" align="center" min-width="110" fixed="right"> - <template #default="scope"> + <el-form + class="-mb-15px" + :model="queryParams" + ref="queryFormRef" + :inline="true" + label-width="68px" + > + <el-form-item label="监控区域" prop="code"> + <el-input + v-model="queryParams.location" + placeholder="请输入监控区域" + clearable + @keyup.enter="handleQuery" + class="!w-240px" + /> + </el-form-item> + <el-form-item> + <el-button @click="handleQuery"> + <Icon icon="ep:search" class="mr-5px"/> + 搜索 + </el-button> + <el-button @click="resetQuery"> + <Icon icon="ep:refresh" class="mr-5px"/> + 重置 + </el-button> <el-button - link type="primary" - @click="openForm('update', scope.row.id)" + plain + @click="openForm('create')" > - 编辑 + <Icon icon="ep:plus" class="mr-5px"/> + 新增 </el-button> <el-button - link - type="danger" - @click="handleDelete(scope.row.id)" + type="success" + plain + @click="handleExport" + :loading="exportLoading" + v-hasPermi="['dev:camera:export']" > - 删除 + <Icon icon="ep:download" class="mr-5px"/> + 导出 </el-button> - </template> - </el-table-column> - </el-table> - <!-- 分页 --> - <Pagination - :total="total" - v-model:page="queryParams.pageNo" - v-model:limit="queryParams.pageSize" - @pagination="getList" - /> + </el-form-item> + </el-form> + + <!-- 列表 --> + <el-table v-loading="loading" :data="list"> + <el-table-column label="编码" align="center" prop="code" width="80"/> + <el-table-column label="抓图方式" align="center" prop="captureType" width="80"> + <template #default="scope"> + <dict-tag :type="DICT_TYPE.CAPTURE_TYPE" :value="scope.row.captureType"/> + </template> + </el-table-column> + <el-table-column label="通道" align="center" prop="channel" width="80"/> + <el-table-column label="监控区域" align="center" prop="location"/> + <el-table-column label="备注" align="center" prop="remark" width="200"/> + <el-table-column label="操作" align="center" min-width="110" fixed="right"> + <template #default="scope"> + <el-button + link + type="primary" + @click="openForm('update', scope.row.id)" + > + 编辑 + </el-button> + <el-button + link + type="danger" + @click="handleDelete(scope.row.id)" + > + 删除 + </el-button> + <el-button + link + type="success" + @click="imageHandle(scope.row.id)" + v-hasPermi="['video:image:query']" + > + 查看截图 + </el-button> + </template> + </el-table-column> + </el-table> + <!-- 分页 --> + <Pagination + :total="total" + v-model:page="queryParams.pageNo" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> </div> </el-drawer> <!-- 表单弹窗:添加/修改 --> - <NvrCameraForm ref="formRef" @success="getList" /> + <NvrCameraForm ref="formRef" @success="getList"/> + <CameraImage ref="imageFormRef"/> </template> <script lang="ts" setup> @@ -102,6 +111,7 @@ import * as CameraApi from '@/api/data/video/camera' import NvrCameraForm from './NvrCameraForm.vue' import {DICT_TYPE} from "@/utils/dict"; +import CameraImage from "../camera/CameraImage.vue"; defineOptions({name: 'NvrCamera'}) @@ -134,7 +144,7 @@ await getList() } -defineExpose({ open }) // 提供 open 方法,用于打开弹窗 +defineExpose({open}) // 提供 open 方法,用于打开弹窗 /** 查询列表 */ const getList = async () => { @@ -148,6 +158,12 @@ } } +/** 查看截图 */ +const imageFormRef = ref() +const imageHandle = (id: string) => { + imageFormRef.value.open(id) +} + /** 搜索按钮操作 */ const handleQuery = () => { queryParams.pageNo = 1 @@ -156,7 +172,7 @@ /** 重置按钮操作 */ const resetQuery = () => { - queryFormRef.value.resetFields() + queryParams.location = undefined handleQuery() } diff --git a/src/views/data/video/nvr/index.vue b/src/views/data/video/nvr/index.vue index 61d0163..b780a0e 100644 --- a/src/views/data/video/nvr/index.vue +++ b/src/views/data/video/nvr/index.vue @@ -52,11 +52,11 @@ </el-form-item> <el-form-item> <el-button @click="handleQuery"> - <Icon icon="ep:search" class="mr-5px" /> + <Icon icon="ep:search" class="mr-5px"/> 搜索 </el-button> <el-button @click="resetQuery"> - <Icon icon="ep:refresh" class="mr-5px" /> + <Icon icon="ep:refresh" class="mr-5px"/> 重置 </el-button> <el-button @@ -65,7 +65,7 @@ @click="openForm('create')" v-hasPermi="['video:nvr:save']" > - <Icon icon="ep:plus" class="mr-5px" /> + <Icon icon="ep:plus" class="mr-5px"/> 新增 </el-button> <el-button @@ -75,7 +75,7 @@ :loading="exportLoading" v-hasPermi="['video:nvr:export']" > - <Icon icon="ep:download" class="mr-5px" /> + <Icon icon="ep:download" class="mr-5px"/> 导出 </el-button> </el-form-item> @@ -87,20 +87,19 @@ <el-table v-loading="loading" :data="list"> <el-table-column label="品牌" align="center" prop="brand" width="80"> <template #default="scope"> - <dict-tag :type="DICT_TYPE.CAMERA_BRAND" :value="scope.row.brand" /> + <dict-tag :type="DICT_TYPE.CAMERA_BRAND" :value="scope.row.brand"/> </template> </el-table-column> <el-table-column label="编码" align="center" prop="code" width="100"/> <el-table-column label="名称" align="center" prop="name"/> - <el-table-column label="IP" align="center" prop="ip" /> + <el-table-column label="IP" align="center" prop="ip"/> <el-table-column label="端口" align="center" prop="port" width="100"/> <el-table-column label="用户名" align="center" prop="username" width="100"/> <el-table-column label="状态" prop="status" width="80"> <template #default="scope"> - <dict-tag :type="DICT_TYPE.NVR_ONLINE_STATUS" :value="scope.row.status" /> + <dict-tag :type="DICT_TYPE.NVR_ONLINE_STATUS" :value="scope.row.status"/> </template> </el-table-column> - <el-table-column label="位置" align="center" prop="position" /> <el-table-column label="备注" align="center" prop="remark" width="150"/> <el-table-column label="操作" align="center" min-width="110" fixed="right"> <template #default="scope"> @@ -120,7 +119,8 @@ > 删除 </el-button> - <el-button link type="success" size="small" @click="cameraHandle(scope.row.id)">摄像头</el-button> + <el-button link type="success" size="small" @click="cameraHandle(scope.row.id)">摄像头 + </el-button> </template> </el-table-column> </el-table> @@ -134,7 +134,7 @@ </ContentWrap> <!-- 表单弹窗:添加/修改 --> - <NvrForm ref="formRef" @success="getList" /> + <NvrForm ref="formRef" @success="getList"/> <!-- 弹窗, 摄像头 --> <NvrCamera ref="videoCameraRef"/> @@ -142,99 +142,100 @@ </template> <script lang="ts" setup> import {DICT_TYPE, getIntDictOptions} from '@/utils/dict' - import download from '@/utils/download' - import * as NvrApi from '@/api/data/video/nvr' - import NvrForm from './NvrForm.vue' - import NvrCamera from './NvrCamera.vue' +import download from '@/utils/download' +import * as NvrApi from '@/api/data/video/nvr' +import NvrForm from './NvrForm.vue' +import NvrCamera from './NvrCamera.vue' - defineOptions({name: 'Nvr'}) +defineOptions({name: 'Nvr'}) - const message = useMessage() // 消息弹窗 - const {t} = useI18n() // 国际化 +const message = useMessage() // 消息弹窗 +const {t} = useI18n() // 国际化 - const loading = ref(true) // 列表的加载中 - const total = ref(0) // 列表的总页数 - const list = ref([]) // 列表的数据 - const queryParams = reactive({ - pageNo: 1, - pageSize: 10, - brand: undefined, - ip: undefined, - code: undefined, - name: undefined, - status: undefined - }) - const queryFormRef = ref() // 搜索的表单 - const exportLoading = ref(false) // 导出的加载中 +const loading = ref(true) // 列表的加载中 +const total = ref(0) // 列表的总页数 +const list = ref([]) // 列表的数据 +const queryParams = reactive({ + pageNo: 1, + pageSize: 10, + brand: undefined, + ip: undefined, + code: undefined, + name: undefined, + status: undefined +}) +const queryFormRef = ref() // 搜索的表单 +const exportLoading = ref(false) // 导出的加载中 - const videoCameraRef = ref() +const videoCameraRef = ref() - /** 查询列表 */ - const getList = async () => { - loading.value = true - try { - const data = await NvrApi.getNvrPage(queryParams) - list.value = data.list - total.value = data.total - } finally { - loading.value = false - } +/** 查询列表 */ +const getList = async () => { + loading.value = true + try { + const data = await NvrApi.getNvrPage(queryParams) + list.value = data.list + total.value = data.total + } finally { + loading.value = false } +} - const cameraHandle = (id: string) => { - // devCameraVisible.value = true - videoCameraRef.value.open(id) - } +const cameraHandle = (id: string) => { + // devCameraVisible.value = true + videoCameraRef.value.open(id) +} - /** 搜索按钮操作 */ - const handleQuery = () => { - queryParams.pageNo = 1 - getList() - } +/** 搜索按钮操作 */ +const handleQuery = () => { + queryParams.pageNo = 1 + getList() +} - /** 重置按钮操作 */ - const resetQuery = () => { - queryFormRef.value.resetFields() - handleQuery() - } +/** 重置按钮操作 */ +const resetQuery = () => { + queryFormRef.value.resetFields() + queryParams.brand = undefined + handleQuery() +} - /** 添加/修改操作 */ - const formRef = ref() - const openForm = (type: string, id?: number) => { - formRef.value.open(type, id) - } +/** 添加/修改操作 */ +const formRef = ref() +const openForm = (type: string, id?: number) => { + formRef.value.open(type, id) +} - /** 删除按钮操作 */ - const handleDelete = async (id: number) => { - try { - // 删除的二次确认 - await message.delConfirm() - // 发起删除 - await NvrApi.deleteNvr(id) - message.success(t('common.delSuccess')) - // 刷新列表 - await getList() - } catch { - } - } - - /** 导出按钮操作 */ - const handleExport = async () => { - try { - // 导出的二次确认 - await message.exportConfirm() - // 发起导出 - exportLoading.value = true - const data = await NvrApi.exportNvr(queryParams) - download.excel(data, '录像机列表.xls') - } catch { - } finally { - exportLoading.value = false - } - } - - /** 初始化 **/ - onMounted(async () => { +/** 删除按钮操作 */ +const handleDelete = async (id: number) => { + try { + // 删除的二次确认 + await message.delConfirm() + // 发起删除 + await NvrApi.deleteNvr(id) + message.success(t('common.delSuccess')) + // 刷新列表 await getList() - }) + } catch { + } +} + +/** 导出按钮操作 */ +const handleExport = async () => { + try { + // 导出的二次确认 + await message.exportConfirm() + // 发起导出 + exportLoading.value = true + const data = await NvrApi.exportNvr(queryParams) + download.excel(data, '录像机列表.xls') + } catch { + } finally { + exportLoading.value = false + } +} + +/** 初始化 **/ +onMounted(async () => { + await getList() +}) </script> diff --git a/src/views/model/pre/analysis/index.vue b/src/views/model/pre/analysis/index.vue index b21627a..b0939c3 100644 --- a/src/views/model/pre/analysis/index.vue +++ b/src/views/model/pre/analysis/index.vue @@ -4,37 +4,42 @@ <el-form :inline="true" :model="formData" label-width="80px"> <el-form-item label="开始时间"> <el-date-picker - size="mini" - v-model="formData.startTime" - type="datetime" - placeholder="选择日期时间"/> + v-model="formData.startTime" + type="datetime" + format="YYYY-MM-DD HH:mm:00" + value-format="YYYY-MM-DD HH:mm:00" + placeholder="选择日期时间"/> </el-form-item> <el-form-item label="结束时间"> <el-date-picker - size="mini" - v-model="formData.endTime" - type="datetime" - placeholder="选择日期时间"/> + v-model="formData.endTime" + type="datetime" + format="YYYY-MM-DD HH:mm:00" + value-format="YYYY-MM-DD HH:mm:00" + placeholder="选择日期时间"/> </el-form-item> <el-form-item label="预测时间"> <el-date-picker - size="mini" - v-model="formData.predictTime" - type="datetime" - placeholder="选择日期时间"/> + v-model="formData.predictTime" + type="datetime" + format="YYYY-MM-DD HH:mm:00" + value-format="YYYY-MM-DD HH:mm:00" + placeholder="选择日期时间"/> </el-form-item> <el-form-item label="预测频率"> - <el-input-number size="mini" v-model="formData.predictFreq" controls-position="right" :min="1" + <el-input-number v-model="formData.predictFreq" controls-position="right" + :min="1" :max="10"/> </el-form-item> <el-form-item> <el-button-group> - <el-button size="mini" type="primary" plain :icon="ArrowLeft" - v-loading="loading1" @click="leftSearchDataByRange()"/> - <el-button size="mini" type="primary" plain :icon="Search" - v-loading="loading1" @click="getList()">查询</el-button> - <el-button size="mini" type="primary" plain :icon="ArrowRight" - v-loading="loading1" @click="rightSearchDataByRange()"/> + <el-button type="primary" plain :icon="ArrowLeft" + :loading="loading1" @click="leftSearchDataByRange()"/> + <el-button type="primary" plain :icon="Search" + :loading="loading1" @click="getList()">查询 + </el-button> + <el-button type="primary" plain :icon="ArrowRight" + :loading="loading1" @click="rightSearchDataByRange()"/> </el-button-group> </el-form-item> @@ -42,46 +47,52 @@ <div class="his-body-left"> <div class="his-body-tree"> <el-tree - :data="treeData" - show-checkbox - node-key="id" - ref="tree" - highlight-current - :props="defaultProps" - @check="onCheckTree"/> + :data="treeData" + show-checkbox + node-key="id" + ref="tree" + highlight-current + :props="defaultProps" + @check="onCheckTree"/> </div> </div> <div class="his-body-right"> <div class="his-body-chart"> - <el-form :inline="true" :model="calRateForm" :rules="formRules" ref="calRateForm" label-width="108px"> + <el-form :inline="true" :model="calRateForm" :rules="formRules" ref="calRateFormRef" + label-width="108px"> <el-row> - <el-col :span="6" > + <el-col :span="6"> <el-form-item label="预测项" prop="calItem" style="width: 90%"> - <el-select v-model="calRateForm.calItem" @change="calItemBaseVale" placeholder="请选择"> + <el-select size="small" v-model="calRateForm.calItem" + @change="calItemBaseVale" + placeholder="请选择"> <el-option - v-for="item in formData.checkedItemData" - :key="item.id" - :label="item.label" - :value="item.id"/> + v-for="itemOut in formData.checkedItemData" + :key="itemOut.id" + :label="itemOut.label" + :value="itemOut.id"/> </el-select> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="精准度偏差" prop="IN_DEVIATION"> - <el-input-number size="mini" v-model="calRateForm.IN_DEVIATION" controls-position="right" :min="1" + <el-input-number size="small" v-model="calRateForm.IN_DEVIATION" + controls-position="right" :min="1" :max="10"/> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="不可信率偏差" prop="OUT_DEVIATION"> - <el-input-number size="mini" v-model="calRateForm.OUT_DEVIATION" controls-position="right" + <el-input-number size="small" v-model="calRateForm.OUT_DEVIATION" + controls-position="right" :min="1" :max="20"/> </el-form-item> </el-col> <el-col :span="4"> <el-form-item> - <el-button size="mini" type="primary" plain :loading="loading2" @click="calAccuracyRate">计算精准度 + <el-button size="small" type="primary" plain :loading="loading2" + @click="calAccuracyRate">计算精准度 </el-button> </el-form-item> </el-col> @@ -89,54 +100,54 @@ <el-row> <el-col :span="4"> <el-form-item label="精准度:"> - {{calRateForm.IN_ACCURACY_RATE}}% + {{ calRateForm.IN_ACCURACY_RATE }}% </el-form-item> </el-col> <el-col :span="4"> <el-form-item label="预测平均值:"> - {{calRateForm.itemPreAvg}} + {{ calRateForm.itemPreAvg }} </el-form-item> </el-col> <el-col :span="4"> <el-form-item label="预测最大值:"> - {{calRateForm.itemPreMax}} + {{ calRateForm.itemPreMax }} </el-form-item> </el-col> <el-col :span="4"> <el-form-item label="预测最小值:"> - {{calRateForm.itemPreMin}} + {{ calRateForm.itemPreMin }} </el-form-item> </el-col> <el-col :span="4"> <el-form-item label="预测累积量:"> - {{calRateForm.preCumulant}} + {{ calRateForm.preCumulant }} </el-form-item> </el-col> </el-row> <el-row> <el-col :span="4"> <el-form-item label="不可信率:"> - {{calRateForm.OUT_ACCURACY_RATE}}% + {{ calRateForm.OUT_ACCURACY_RATE }}% </el-form-item> </el-col> <el-col :span="4"> <el-form-item label="真实平均值:"> - {{calRateForm.itemAvg}} + {{ calRateForm.itemAvg }} </el-form-item> </el-col> <el-col :span="4"> <el-form-item label="真实最大值:"> - {{calRateForm.itemMax}} + {{ calRateForm.itemMax }} </el-form-item> </el-col> <el-col :span="4"> <el-form-item label="真实最小值:"> - {{calRateForm.itemMin}} + {{ calRateForm.itemMin }} </el-form-item> </el-col> <el-col :span="4"> <el-form-item label="真实累积量:"> - {{calRateForm.realCumulant}} + {{ calRateForm.realCumulant }} </el-form-item> </el-col> </el-row> @@ -146,20 +157,25 @@ <el-col :span="12"> <el-form-item label="数据类型"> <el-checkbox-group v-model="formData.chartCheck" @change="changeChartCheck"> - <el-checkbox v-for="item in formData.chartOptions" :label="item" :key="item">{{item}} + <el-checkbox v-for="item in formData.chartOptions" :label="item" + :key="item">{{ item }} </el-checkbox> </el-checkbox-group> </el-form-item> </el-col> <el-col :span="6"> <el-form-item> - <el-radio v-model="formData.isMultipleY" :label="false" @input="onChangeMultipleY">单坐标轴</el-radio> - <el-radio v-model="formData.isMultipleY" :label="true" @input="onChangeMultipleY">多坐标轴</el-radio> + <el-radio v-model="formData.isMultipleY" :label="false" + @input="onChangeMultipleY">单坐标轴 + </el-radio> + <el-radio v-model="formData.isMultipleY" :label="true" + @input="onChangeMultipleY">多坐标轴 + </el-radio> </el-form-item> </el-col> </el-row> </el-form> - <div id="data-analysis" style="height: 500px;"></div> + <div ref="dataAnalysisChart" style="height: 500px;"></div> </div> </div> </div> @@ -168,31 +184,479 @@ </el-card> </template> <script lang="ts" setup> - import {getYMDHMS} from "@/utils/dateUtil" - import * as CategoryApi from "@/api/data/ind/category"; - import * as DmModule from '@/api/model/pre/dm' - import * as ItemApi from "@/api/data/ind/item/item"; - import * as MmPredictItem from '@/api/model/pre/item' - import * as echarts from "echarts"; - import { onMounted, ref } from 'vue'; - import { Search, ArrowLeft, ArrowRight,} from '@element-plus/icons-vue' +import {getYMDHMS} from "@/utils/dateUtil" +import * as McsApi from '@/api/model/mcs' +import * as echarts from "echarts"; +import {Search, ArrowLeft, ArrowRight,} from '@element-plus/icons-vue' - defineOptions({name: 'AnalysisformData'}) +defineOptions({name: 'AnalysisformData'}) - const message = useMessage() // 消息弹窗 - const { t } = useI18n() // 国际化 - const dataCategoryList = ref([] as CategoryApi.IndItemCategoryVO[]) - const loading1 = ref(false) // 列表的加载中 - const loading2 = ref(false) // 列表的加载中 - const total = ref(0) // 列表的总页数 - const list = ref([]) // 字典表格数据 - const queryParams = reactive({ - pageNo: 1, - pageSize: 10, - itemno: '', - itemname: '', +const message = useMessage() // 消息弹窗 +const {t} = useI18n() // 国际化 +const dataAnalysisChart = ref(null); +const loading1 = ref(false) // 列表的加载中 +const loading2 = ref(false) // 列表的加载中 +const total = ref(0) // 列表的总页数 +const list = ref([]) // 字典表格数据 +let formData = ref({ + rangeDate: '', + startTime: '', + endTime: '', + predictTime: '', + predictTimeStr: '', + startTimeStr: '', + endTimeStr: '', + predictTimeStamp: 0, + startTimeStamp: 0, + endTimeStamp: 0, + currentStamp: '', + currentStamp60: '', + predictStamp: '', + chartCheck: ['T+L', '真实值'], + chartOptions: ['T+N', 'T+L', '当时', '真实值', '调整值'], + checkedItemData: [], + backItem: '', + backValue: 0, + backCoe: 1, + preCumulant: 0, + realCumulant: 0, + queryStep: 2, + isMultipleYRadio: '单坐标轴', + isMultipleY: false, + predictFreq: 3, +}) +const calRateFormRef = ref() +const calRateForm = ref({ + calItem: undefined, + IN_DEVIATION: 0, + OUT_DEVIATION: 0, + IN_ACCURACY_RATE: 0, + OUT_ACCURACY_RATE: 0, + itemAvg: 0, + itemMax: 0, + itemMin: 0, + itemPreAvg: 0, + itemPreMax: 0, + itemPreMin: 0, + preCumulant: 0, + realCumulant: 0 +}) +let itemData = ref({ + currentTreeList: [], + chart: {}, + option: {} +}) +const treeData = ref([]) +const itemDataObject = ref() +const timer = ref() +let myChart = null; + +const formRules = reactive({ + calItem: [{required: true, message: '预测项不能为空', trigger: 'blur'}], + IN_DEVIATION: [{required: true, message: '精准度偏差不能为空', trigger: 'blur'}], + OUT_DEVIATION: [{required: true, message: '不可信率偏差不能为空', trigger: 'blur'}], +}) + +/** 查询列表 */ +const getList = async () => { + loading1.value = true + try { + if (!formData.value.chartCheck) { + formData.value.chartCheck = ['真实值'] + } + let chartCheckArray = formData.value.chartCheck; + if (!formData.value.checkedItemData || formData.value.checkedItemData.length == 0) { + itemData.value.option = {}; + return; + } + let outIds = formData.value.checkedItemData.map(item => { + return item.id + }) + const params = reactive({ + outIds: outIds, + predictTime: formData.value.predictTime, + startTime: formData.value.startTime, + endTime: formData.value.endTime + }) + const data = await McsApi.getPreDataCharts(params) + formData.value.predictTime = data.predictTime; + formData.value.startTime = data.startTime + formData.value.endTime = data.endTime + + let xAxisData = data.categories; + let yAxisData = []; + let offset = 0; + let yAxisIndex = 0; + let legendData = []; + let yMaxArr = []; + let seriesData = []; + seriesData.push({ + name: '', + data: [null], + type: 'line', + smooth: true, + color: 'green', + markLine: { + silent: true, + lineStyle: { + color: '#32a487', + width: 2 + }, + data: [{ + xAxis: formData.value.predictTime + }], + label: { + normal: { + formatter: formData.value.predictTime + } + }, + symbol: ['circle', 'none'], + }, + }); + itemDataObject.value = {} + for (let i = 0; i < data.dataViewList.length; i++) { + let dataView = data.dataViewList[i] + itemDataObject.value[dataView.outId] = dataView; + let maxValue = dataView.maxValue; + let minValue = dataView.minValue; + yAxisIndex = formData.value.isMultipleY ? i : 0; + let yMax = maxValue; + if (maxValue < 0) { + maxValue = 1; + } else if (maxValue < 10) { + yMax = (Math.ceil(maxValue * 11) / 10).toFixed(1); + } else if (maxValue < 100) { + yMax = (Math.ceil(maxValue * 1.1 / 5) * 5); + } else { + yMax = (Math.ceil(maxValue * 1.1 / 10) * 10); + } + yMaxArr.push(yMax); + let yMin = minValue; + if (minValue >= 0) { + yMin = 0; + } else if (minValue > -10) { + yMin = (Math.floor(minValue * 11) / 10).toFixed(1); + } else if (minValue > -100) { + yMin = (Math.floor(minValue * 1.1 / 5) * 5); + } else { + yMin = (Math.floor(minValue * 1.1 / 10) * 10); + } + yAxisData.push({ + type: 'value', + name: "", + min: yMin, + max: yMax, + position: 'left', + offset: offset, + splitLine: { + show: false + }, + axisLine: { + show: true, + lineStyle: {} + }, + axisLabel: { + formatter: '{value}' + } + }) + offset = offset + 40 + if (chartCheckArray.indexOf('真实值') !== -1) { + let legendName = dataView.resultstr + '(真实)'; + legendData.push(legendName); + seriesData.push({ + name: legendName, + data: dataView.realData || [], + type: 'line', + yAxisIndex: yAxisIndex, + showSymbol: false, + smooth: true, + lineStyle: { + width: 2 + } + }); + } + if (chartCheckArray.indexOf('T+N') !== -1) { + let legendName = dataView.resultstr + '(T+N)'; + seriesData.push({ + name: legendName, + data: dataView.preDataN || [], + type: 'line', + yAxisIndex: yAxisIndex, + showSymbol: false, + smooth: true, + lineStyle: { + width: 2 + } + }); + } + if (chartCheckArray.indexOf('T+L') !== -1) { + let legendName = dataView.resultstr + '(T+L)'; + legendData.push(legendName); + seriesData.push({ + name: legendName, + data: dataView.preDataL || [], + type: 'line', + showSymbol: false, + connectNulls: true, + yAxisIndex: yAxisIndex, + smooth: true, + lineStyle: { + width: 2 + } + }); + } + if (chartCheckArray.indexOf('当时') !== -1) { + let legendName = dataView.resultstr + '(当时)'; + legendData.push(legendName); + seriesData.push({ + name: legendName, + data: dataView.curData || [], + type: 'line', + yAxisIndex: yAxisIndex, + showSymbol: false, + smooth: true, + lineStyle: { + width: 2 + } + }); + } + if (chartCheckArray.indexOf('调整值') !== -1) { + let legendName = dataView.resultstr + '(调整值)'; + legendData.push(legendName); + seriesData.push({ + name: legendName, + data: dataView.adjData || [], + type: 'line', + yAxisIndex: yAxisIndex, + showSymbol: false, + connectNulls: true, + smooth: true, + lineStyle: { + width: 2, + type: 'dashed' + } + }); + } + } + //如果最大值相差不大,改成一致大小 + if (yMaxArr.length > 1) { + let max = Math.max.apply(null, yMaxArr); + let min = Math.min.apply(null, yMaxArr); + if (Math.abs((max - min) / max) <= 0.2) { + for (let i = 0; i < yAxisData.length; i++) { + yAxisData[i].max = max; + } + } + } + myChart = echarts.init(dataAnalysisChart.value); + let option = { + title: { + text: '' + }, + tooltip: { + trigger: 'axis' + }, + legend: { + show: true, + data: legendData, + top: 10 + }, + grid: { + top: '20%', + left: '3%', + right: '6%', + bottom: '3%', + containLabel: true + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: xAxisData + }, + yAxis: formData.value.isMultipleY ? yAxisData : { + type: 'value', + splitLine: {show: false}, + axisLine: {show: true} + }, + dataZoom: [ + { + type: 'inside', + start: 0, + end: 100 + }, + { + start: 0, + end: 10 + } + ], + series: seriesData + } + myChart.clear() + myChart.setOption(option) + } finally { + loading1.value = false + } +} + +onMounted(() => { + resetForm() + getPreItemTree() +}) + +async function getPreItemTree() { + treeData.value = await McsApi.getPredictItemTree() +} + +function leftSearchDataByRange() { + let mins = getRangeMins(); + let startTime = formData.value.startTime; + let endTime = formData.value.endTime; + let predictTime = formData.value.predictTime; + if (predictTime) { + predictTime = getYMDHMS(new Date(predictTime) - 1000 * 60 * mins); + formData.value.predictTime = predictTime; + } + if (startTime) { + startTime = getYMDHMS(new Date(startTime) - 1000 * 60 * mins); + formData.value.startTime = startTime; + } + if (endTime) { + endTime = getYMDHMS(new Date(endTime) - 1000 * 60 * mins); + formData.value.endTime = endTime; + } + getList(); +} + +function getRangeMins() { + let result: string | number = 0; + if (formData.value.startTime && formData.value.endTime) { + let startStamp = new Date(formData.value.startTime).getTime(); + let endStamp = new Date(formData.value.endTime).getTime(); + let queryStep = ((endStamp - startStamp) / (1000 * 60)).toFixed(0); + result = queryStep >= 0 ? queryStep : 0; + } + return result; +} + +function onCheckTree(data, checked, indeterminate) { + formData.value.checkedItemData = []; + if (checked.checkedNodes) { + formData.value.checkedItemData = [...checked.checkedNodes] + } + debounce(getList, 1000); +} + +function debounce(func, wait) { + let args = []; + if (timer.value) { + clearTimeout(timer.value); + } + timer.value = setTimeout(() => { + func.apply(this, args); + timer.value = null; + }, wait) +} + +function calItemBaseVale() { + if (!calRateForm.value.calItem) { + calRateForm.value.itemPreMax = 0; + calRateForm.value.itemPreMin = 0; + calRateForm.value.itemPreAvg = 0; + calRateForm.value.preCumulant = 0; + calRateForm.value.itemMax = 0; + calRateForm.value.itemMin = 0; + calRateForm.value.itemAvg = 0; + calRateForm.value.realCumulant = 0; + } else { + let dataView = itemDataObject.value[calRateForm.value.calItem] + calRateForm.value.itemPreMax = dataView.preMax; + calRateForm.value.itemPreMin = dataView.preMin; + calRateForm.value.itemPreAvg = dataView.preAvg; + calRateForm.value.preCumulant = dataView.preCumulant; + calRateForm.value.itemMax = dataView.hisMax; + calRateForm.value.itemMin = dataView.hisMin; + calRateForm.value.itemAvg = dataView.hisAvg; + calRateForm.value.realCumulant = dataView.hisCumulant; + } +} + +function calAccuracyRate() { + this.$refs['calRateForm'].validate((valid) => { + if (!valid) { + return false + } + let dataView = itemDataObject[calRateForm.value.calItem] + let seriesReaData = dataView.realData; + let seriesPreData = dataView.preDataL; + if (seriesReaData == null || seriesPreData == null || + seriesReaData.length === 0 || seriesPreData.length === 0) { + loading2.value = false; + return; + } + let predictValueMap = {}; + seriesPreData.forEach(function (item) { + predictValueMap[item[0]] = item[1]; + }) + let pointValueMap = {}; + seriesReaData.forEach(function (item) { + pointValueMap[item[0]] = item[1]; + }) + let inDeviation = Number(calRateForm.value.IN_DEVIATION); + let outDeviation = Number(calRateForm.value.OUT_DEVIATION); + if (inDeviation === 0 && outDeviation === 0) { + loading2.value = false; + return; + } + let inDeviationCount = 0; + let outDeviationCount = 0; + let totalCount = 0; + for (let key in predictValueMap) { + let predictValue = predictValueMap[key]; + let pointValue = pointValueMap[key]; + if (pointValue == null || "" === pointValue || predictValue == null || "" === predictValue) { + continue; + } + let deviationAbs = (predictValue - pointValue) >= 0 ? (predictValue - pointValue) : (predictValue - pointValue) * -1; + if (deviationAbs < inDeviation) { + inDeviationCount = inDeviationCount + 1; + } + if (deviationAbs > outDeviation) { + outDeviationCount = outDeviationCount + 1; + } + totalCount = totalCount + 1; + } + + let rateIn = (inDeviationCount / totalCount * 100).toFixed(2); + let rateOut = (outDeviationCount / totalCount * 100).toFixed(2); + calRateForm.value.IN_ACCURACY_RATE = Number(rateIn); + calRateForm.value.OUT_ACCURACY_RATE = Number(rateOut); + loading2.value = false; }) - let formData = ref({ +} + +function rightSearchDataByRange() { + let mins = getRangeMins(); + let startTime = formData.value.startTime; + let endTime = formData.value.endTime; + let predictTime = formData.value.predictTime; + if (predictTime) { + predictTime = getYMDHMS(new Date(predictTime) - 0 + 1000 * 60 * mins); + formData.value.predictTime = predictTime; + } + if (startTime) { + startTime = getYMDHMS(new Date(startTime) - 0 + 1000 * 60 * mins); + formData.value.startTime = startTime; + } + if (endTime) { + endTime = getYMDHMS(new Date(endTime) - 0 + 1000 * 60 * mins); + formData.value.endTime = endTime; + } + getList(); +} + +/** 重置表单 */ +const resetForm = () => { + formData.value = { rangeDate: '', startTime: '', endTime: '', @@ -218,9 +682,9 @@ isMultipleYRadio: '单坐标轴', isMultipleY: false, predictFreq: 3, - }) - let calRateForm = ref({ - calItem: '', + } + calRateForm.value = { + calItem: undefined, IN_DEVIATION: 0, OUT_DEVIATION: 0, IN_ACCURACY_RATE: 0, @@ -231,462 +695,47 @@ itemPreAvg: 0, itemPreMax: 0, itemPreMin: 0, - preCumulant:0, - realCumulant:0 - }) - let itemData = ref({ - currentTreeList: [], - chart: {}, - option: {} - }) - const chartContainer = ref(null); - const treeData = ref([]) - const itemDataObject = ref() - const timer = ref() - - const formRules = reactive({ - calItem: [{required: true, message: '预测项不能为空', trigger: 'blur'}], - IN_DEVIATION: [{required: true, message: '精准度偏差不能为空', trigger: 'blur'}], - OUT_DEVIATION: [{required: true, message: '不可信率偏差不能为空', trigger: 'blur'}], - }) - //const myChart = echarts.init(document.getElementById("data-analysis")); - /** 查询列表 */ - const getList = async () => { - loading1.value = true - try { - const data = formData.value - if (!formData.value.chartCheck) { - formData.value.chartCheck = ['真实值'] - } - let chartCheckArray = formData.value.chartCheck; - if (!formData.value.checkedItemData || formData.value.checkedItemData.length == 0) { - itemData.value.option = {}; - return; - } - let itemIdList = formData.value.checkedItemData.map(item => { - return item.id - }) - const params = ref({ - itemIds: itemIdList.join(','), - predictTime: formData.value.predictTime, - startTime: formData.value.startTime, - endTime: formData.value.endTime - }) - const res = await MmPredictItem.getViewCharts(params) - if (res.code !== 0) { - return message.error(res.msg) - } - formData.value.predictTime = res.data.predictTime; - formData.value.startTime = res.data.startTime - formData.value.endTime = res.data.endTime - - let xAxisData = res.data.categories; - let yAxisData = []; - let offset = 0; - let yAxisIndex = 0; - let legendData = []; - let yMaxArr = []; - let seriesData = []; - seriesData.push({ - name: '', - data: [null], - type: 'line', - smooth: true, - color: 'green', - markLine: { - silent: true, - lineStyle: { - color: '#32a487', - width: 2 - }, - data: [{ - xAxis: formData.value.predictTime - }], - label: { - normal: { - formatter: formData.value.predictTime - } - }, - symbol: ['circle', 'none'], - }, - }); - itemDataObject.value = {} - for (let i = 0; i < res.data.dataViewList.length; i++) { - let dataView = res.data.dataViewList[i] - itemDataObject.value.dataView.itemId = dataView; - let maxValue = dataView.maxValue; - let minValue = dataView.minValue; - yAxisIndex = formData.value.isMultipleY ? i : 0; - let yMax = maxValue; - if (maxValue < 0) { - maxValue = 1; - } else if (maxValue < 10) { - yMax = (Math.ceil(maxValue * 11) / 10).toFixed(1); - } else if (maxValue < 100) { - yMax = (Math.ceil(maxValue * 1.1 / 5) * 5); - } else { - yMax = (Math.ceil(maxValue * 1.1 / 10) * 10); - } - yMaxArr.push(yMax); - let yMin = minValue; - if (minValue >= 0) { - yMin = 0; - } else if (minValue > -10) { - yMin = (Math.floor(minValue * 11) / 10).toFixed(1); - } else if (minValue > -100) { - yMin = (Math.floor(minValue * 1.1 / 5) * 5); - } else { - yMin = (Math.floor(minValue * 1.1 / 10) * 10); - } - yAxisData.push({ - type: 'value', - name: "", - min: yMin, - max: yMax, - position: 'left', - offset: offset, - splitLine: { - show: false - }, - axisLine: { - show: true, - lineStyle: {} - }, - axisLabel: { - formatter: '{value}' - } - }) - offset = offset + 40 - if (chartCheckArray.indexOf('真实值') !== -1) { - let legendName = dataView.itemName + '(真实)'; - legendData.push(legendName); - seriesData.push({ - name: legendName, - data: dataView.realData || [], - type: 'line', - yAxisIndex: yAxisIndex, - showSymbol: false, - smooth: true, - lineStyle: { - width: 3 - } - }); - } - if (chartCheckArray.indexOf('T+N') !== -1) { - let legendName = dataView.itemName + '(T+N)'; - seriesData.push({ - name: legendName, - data: dataView.preDataN || [], - type: 'line', - yAxisIndex: yAxisIndex, - showSymbol: false, - smooth: true, - lineStyle: { - width: 3 - } - }); - } - if (chartCheckArray.indexOf('T+L') !== -1) { - let legendName = dataView.itemName + '(T+L)'; - legendData.push(legendName); - seriesData.push({ - name: legendName, - data: dataView.preDataL || [], - type: 'line', - showSymbol: false, - connectNulls: true, - yAxisIndex: yAxisIndex, - smooth: true, - lineStyle: { - width: 3 - } - }); - } - if (chartCheckArray.indexOf('当时') !== -1) { - let legendName = dataView.itemName + '(当时)'; - legendData.push(legendName); - seriesData.push({ - name: legendName, - data: dataView.curData || [], - type: 'line', - yAxisIndex: yAxisIndex, - showSymbol: false, - smooth: true, - lineStyle: { - width: 3 - } - }); - } - if (chartCheckArray.indexOf('调整值') !== -1) { - let legendName = dataView.itemName + '(调整值)'; - legendData.push(legendName); - seriesData.push({ - name: legendName, - data: dataView.adjData || [], - type: 'line', - yAxisIndex: yAxisIndex, - showSymbol: false, - connectNulls: true, - smooth: true, - lineStyle: { - width: 3, - type: 'dashed' - } - }); - } - } - //如果最大值相差不大,改成一致大小 - if (yMaxArr.length > 1) { - let max = Math.max.apply(null, yMaxArr); - let min = Math.min.apply(null, yMaxArr); - if (Math.abs((max - min) / max) <= 0.2) { - for (let i = 0; i < yAxisData.length; i++) { - yAxisData[i].max = max; - } - } - } - let option = { - title: { - text: '' - }, - tooltip: { - trigger: 'axis' - }, - legend: { - show: true, - data: legendData, - top: 10 - }, - grid: { - top: 50, - left: '3%', - right: '6%', - bottom: '3%', - containLabel: true - }, - xAxis: { - type: 'category', - boundaryGap: false, - data: xAxisData - }, - yAxis: formData.value.isMultipleY ? yAxisData : { - type: 'value', - splitLine: {show: false}, - axisLine: {show: true} - }, - dataZoom: [ - { - type: 'inside', - start: 0, - end: 100 - }, - { - start: 0, - end: 10 - } - ], - series: seriesData - } - //chart.setOption(option) - } finally { - loading1.value = false - } + preCumulant: 0, + realCumulant: 0 } - - onMounted(() => { - getPreItemTree() - getList() - }) - - async function getPreItemTree() { - treeData.value = await MmPredictItem.getMmPredictItemTree() - } - - function leftSearchDataByRange() { - let mins = getRangeMins(); - let startTime = formData.value.startTime; - let endTime = formData.value.endTime; - let predictTime = formData.value.predictTime; - if (predictTime) { - predictTime = getYMDHMS(new Date(predictTime) - 1000 * 60 * mins); - formData.value.predictTime = predictTime; - } - if (startTime) { - startTime = getYMDHMS(new Date(startTime) - 1000 * 60 * mins); - formData.value.startTime = startTime; - } - if (endTime) { - endTime = getYMDHMS(new Date(endTime) - 1000 * 60 * mins); - formData.value.endTime = endTime; - } - getList(); - } - - function getRangeMins () { - let result: string | number = 0; - if(formData.value.startTime && formData.value.endTime) { - let startStamp = new Date(formData.value.startTime).getTime(); - let endStamp = new Date(formData.value.endTime).getTime(); - let queryStep = ((endStamp - startStamp) / (1000 * 60)).toFixed(0); - result = queryStep >= 0 ? queryStep : 0; - } - return result; - } - - function onCheckTree(data, checked, indeterminate) { - formData.value.checkedItemData = []; - if (checked.checkedNodes) { - formData.value.checkedItemData = [...checked.checkedNodes] - } - //myChart.clear() - debounce(getList(), 1000); - } - - function debounce(func, wait) { - let args = []; - if (timer.value) { - clearTimeout(timer.value); - } - timer.value = setTimeout(() => { - func.apply(this, args); - timer.value = null; - }, wait) - } - - function calItemBaseVale() { - if (!calRateForm.value.calItem) { - calRateForm.value.itemPreMax = 0; - calRateForm.value.itemPreMin = 0; - calRateForm.value.itemPreAvg = 0; - calRateForm.value.preCumulant = 0; - calRateForm.value.itemMax = 0; - calRateForm.value.itemMin = 0; - calRateForm.value.itemAvg = 0; - calRateForm.value.realCumulant = 0; - return - } else { - let dataView = itemDataObject[calRateForm.value.calItem] - calRateForm.value.itemPreMax = dataView.preMax; - calRateForm.value.itemPreMin = dataView.preMin; - calRateForm.value.itemPreAvg = dataView.preAvg; - calRateForm.value.preCumulant = dataView.preCumulant; - calRateForm.value.itemMax = dataView.hisMax; - calRateForm.value.itemMin = dataView.hisMin; - calRateForm.value.itemAvg = dataView.hisAvg; - calRateForm.value.realCumulant = dataView.hisCumulant; - } - } - - function calAccuracyRate() { - this.$refs['calRateForm'].validate((valid) => { - if (!valid) { - return false - } - let dataView = itemDataObject[calRateForm.value.calItem] - let seriesReaData = dataView.realData; - let seriesPreData = dataView.preDataL; - if (seriesReaData == null || seriesPreData == null || - seriesReaData.length === 0 || seriesPreData.length === 0) { - loading2.value = false; - return; - } - let predictValueMap = {}; - seriesPreData.forEach(function (item) { - predictValueMap[item[0]] = item[1]; - }) - let pointValueMap = {}; - seriesReaData.forEach(function (item) { - pointValueMap[item[0]] = item[1]; - }) - let inDeviation = Number(calRateForm.value.IN_DEVIATION); - let outDeviation = Number(calRateForm.value.OUT_DEVIATION); - if (inDeviation === 0 && outDeviation === 0) { - loading2.value = false; - return; - } - let inDeviationCount = 0; - let outDeviationCount = 0; - let totalCount = 0; - for (let key in predictValueMap) { - let predictValue = predictValueMap[key]; - let pointValue = pointValueMap[key]; - if (pointValue == null || "" === pointValue || predictValue == null || "" === predictValue) { - continue; - } - let deviationAbs = (predictValue - pointValue) >= 0 ? (predictValue - pointValue) : (predictValue - pointValue) * -1; - if (deviationAbs < inDeviation) { - inDeviationCount = inDeviationCount + 1; - } - if (deviationAbs > outDeviation) { - outDeviationCount = outDeviationCount + 1; - } - totalCount = totalCount + 1; - } - - let rateIn = (inDeviationCount / totalCount * 100).toFixed(2); - let rateOut = (outDeviationCount / totalCount * 100).toFixed(2); - calRateForm.value.IN_ACCURACY_RATE = Number(rateIn); - calRateForm.value.OUT_ACCURACY_RATE = Number(rateOut); - loading2.value = false; - }) - } - - function rightSearchDataByRange() { - let mins = getRangeMins(); - let startTime = formData.value.startTime; - let endTime = formData.value.endTime; - let predictTime = formData.value.predictTime; - if (predictTime) { - predictTime = getYMDHMS(new Date(predictTime) - 0 + 1000 * 60 * mins); - formData.value.predictTime = predictTime; - } - if (startTime) { - startTime = getYMDHMS(new Date(startTime) - 0 + 1000 * 60 * mins); - formData.value.startTime = startTime; - } - if (endTime) { - endTime = getYMDHMS(new Date(endTime) - 0 + 1000 * 60 * mins); - formData.value.endTime = endTime; - } - getList(); - } - + calRateFormRef.value?.resetFields() +} </script> <style scoped> - .el-form-item { - margin-bottom: 0 !important; - } +.el-form-item { + margin-bottom: 0 !important; +} - .his-body-chart { - height: 100%; - border: 1px solid lightgray; - padding: 10px; - } +.his-body-chart { + height: 100%; + border: 1px solid lightgray; + padding: 10px; +} - .his-body-tree { - height: 100%; - border: 1px solid lightgray; - padding: 10px; - } +.his-body-tree { + height: 100%; + border: 1px solid lightgray; + padding: 10px; +} - .his-body-right { - width: 80%; - height: 100%; - padding-top: 10px; - } +.his-body-right { + width: 80%; + height: 100%; + padding-top: 10px; +} - .his-body-left { - width: 20%; - height: 100%; - padding: 10px 10px 0 0; - } +.his-body-left { + width: 20%; + height: 100%; + padding: 10px 10px 0 0; +} - .his-body { - width: 100%; - height: calc(calc(100vh - 68px - 38px - 160px)); - display: flex; - flex-direction: row; - justify-content: flex-start; - align-content: flex-start; - } +.his-body { + width: 100%; + height: calc(calc(100vh - 68px - 38px - 160px)); + display: flex; + flex-direction: row; + justify-content: flex-start; + align-content: flex-start; +} </style> diff --git a/src/views/model/pre/item/MmPredictItemForm.vue b/src/views/model/pre/item/MmPredictItemForm.vue index e10af7d..cb01f79 100644 --- a/src/views/model/pre/item/MmPredictItemForm.vue +++ b/src/views/model/pre/item/MmPredictItemForm.vue @@ -17,7 +17,8 @@ </el-col> <el-col :span="12"> <el-form-item label="编号" prop="mmPredictItem.itemno"> - <el-input v-model="dataForm.mmPredictItem.itemno" placeholder="编号" maxlength="50" readonly/> + <el-input v-model="dataForm.mmPredictItem.itemno" placeholder="编号" maxlength="50" + readonly/> </el-form-item> </el-col> </el-row> @@ -210,13 +211,13 @@ :data="dataForm.mmItemOutputList" border style="width: 100%; margin-top: 5px;"> - <el-table-column prop="outputorder" label="排序" align="center" width="80px" /> + <el-table-column prop="outputorder" label="排序" align="center" width="80px"/> <el-table-column label="结果" align="center" width="150px"> <template #default="scope"> <el-input v-model="scope.row.resultstr" placeholder="请输入"/> </template> </el-table-column> - <el-table-column label="结果数据类型" align="center" width="150px"> + <el-table-column label="结果数据类型" align="center" width="150px"> <template #default="scope"> <el-select v-model="scope.row.resultType" @@ -233,7 +234,9 @@ </el-table-column> <el-table-column label="索引" align="center" width="120px"> <template #default="scope"> - <el-input-number style="width:100%;hight:100%" :disabled="scope.row.resultType !== 2" v-model="scope.row.resultIndex" :min="0" step-strictly controls-position="right"/> + <el-input-number style="width:100%;hight:100%" :disabled="scope.row.resultType !== 2" + v-model="scope.row.resultIndex" :min="0" step-strictly + controls-position="right"/> </template> </el-table-column> <el-table-column label="数据点" align="center"> @@ -290,7 +293,9 @@ <el-table-column prop="modelparamorder" label="序号" width="60" align="center"/> <el-table-column prop="" label="类型" width="200" align="center"> <template #default="scope"> - <el-select v-model="scope.row.modelparamtype" placeholder="请选择"> + <el-select v-model="scope.row.modelparamtype" + @change="changeModelparamtype(scope.row)" + placeholder="请选择"> <el-option v-for="dict in getStrDictOptions(DICT_TYPE.MODEL_PARAM_TYPE)" :key="dict.value" @@ -761,11 +766,11 @@ dataForm.value.itemtypename = itemTypeMap[value] } -function changeModelparamtype(value, row) { +function changeModelparamtype(row) { row.modelparamid = '' } -function changeOutputPoint(value,row) { +function changeOutputPoint(value, row) { row.tagname = pointMap[value] } @@ -792,10 +797,12 @@ rows.splice(index, 0, row) orderRow(rows) } + function addItemOutput(list) { list.push({}) orderItemOutput(list) } + function deleteItemOutput(index: string, rows) { if (!rows || rows.length === 1) { message.error('不能全部删除!') @@ -804,6 +811,7 @@ rows.splice(index, 1) orderItemOutput(rows) } + function orderItemOutput(list) { list.sort((a, b) => a.outputorder - b.outputorder); let outputorder = 1 @@ -816,7 +824,7 @@ function resultTypeChange(value, row) { if (value === 1) { row.resultIndex = undefined - }else if (value === 2) { + } else if (value === 2) { row.resultIndex = 0 } } diff --git a/types/env.d.ts b/types/env.d.ts index 40ce343..82b4cd7 100644 --- a/types/env.d.ts +++ b/types/env.d.ts @@ -25,6 +25,7 @@ readonly VITE_UPLOAD_URL: string readonly VITE_API_URL: string readonly VITE_BASE_PATH: string + readonly VITE_VIDEO_CAMERA_DOMAIN: string readonly VITE_DROP_DEBUGGER: string readonly VITE_DROP_CONSOLE: string readonly VITE_SOURCEMAP: string -- Gitblit v1.9.3