Merge remote-tracking branch 'origin/master'
# Conflicts:
# src/views/data/point/DaPointChart.vue
已修改32个文件
已删除5个文件
已重命名2个文件
已添加5个文件
| | |
| | | VITE_SOURCEMAP=true |
| | | |
| | | # 打包路径 |
| | | VITE_BASE_PATH=/ |
| | | VITE_BASE_PATH=/plat |
| | | |
| | | # 输出路径 |
| | | VITE_OUT_DIR=dist |
| | | |
| | | # 公共静态文件路径 |
| | | VITE_STATIC_DIR=/ |
| | | |
| | | # 商城H5会员端域名iai |
| | | VITE_MALL_H5_DOMAIN='http://' |
| | | |
| | | # 验证码的开关 |
| | | VITE_APP_CAPTCHA_ENABLE=true |
| | | VITE_APP_CAPTCHA_ENABLE=false |
| | | |
| | | # MDK模型上传路径 |
| | | MDK_UPLOAD_URL='http://localhost:48080/admin-api/model//pre/item/upload-model' |
| | |
| | | VITE_SOURCEMAP=false |
| | | |
| | | # 打包路径 |
| | | VITE_BASE_PATH=/ |
| | | VITE_BASE_PATH=/plat |
| | | |
| | | # 公共静态文件路径 |
| | | VITE_STATIC_DIR=/ |
| | | |
| | | # 商城H5会员端域名 |
| | | VITE_MALL_H5_DOMAIN='http://localhost:3000' |
| | |
| | | # 打包路径 |
| | | VITE_BASE_PATH=/plat |
| | | |
| | | # 数据采集服务所在服务器,映射截图图片用 |
| | | VITE_VIDEO_CAMERA_DOMAIN='172.16.59.105' |
| | | |
| | | # 输出路径 |
| | | VITE_OUT_DIR=dist |
| | | |
| | | # 公共静态文件路径 |
| | | VITE_STATIC_DIR=/plat/ |
| | | |
| | | # 商城H5会员端域名 |
| | | VITE_MALL_H5_DOMAIN='http://' |
| | | |
| | |
| | | |
| | | //获取下拉集合 |
| | | export const getItemList = (params: PageParam) => { |
| | | return request.get({ url: '/data/plan-item/getList', params}) |
| | | return request.get({ url: '/data/plan-item/list', params}) |
| | | } |
| | | |
| | | // 查询Plan图表 |
对比新文件 |
| | |
| | | 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 |
| | | } |
对比新文件 |
| | |
| | | import request from '@/config/axios' |
| | | |
| | | export interface PreDataBarLineReqVO { |
| | | outIds: string[], |
| | | predictTime: string, |
| | | startTime: string, |
| | | endTime: string |
| | | } |
| | | |
| | | export interface PreDataItemChartReqVO { |
| | | itemId: string, |
| | | startTime: string, |
| | | 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 }) |
| | | } |
| | | |
| | | export const getPreDataItemChart = (data: PreDataItemChartReqVO) => { |
| | | return request.post({ url: '/model/api/mcs/predict-data/item-chart', data }) |
| | | } |
| | | |
| | | export const exportPredictValue = (params) => { |
| | | return request.download({ url: '/model/api/mcs/predict-data/exportValue', params }) |
| | | } |
| | |
| | | import request from '@/config/axios' |
| | | |
| | | export interface DmModuleVO { |
| | | id: string |
| | | id: string, |
| | | modulename: string, |
| | | moduletype: string, |
| | | cycle: string |
| | |
| | | import request from '@/config/axios' |
| | | import {UploadRequestOptions} from "element-plus/es/components/upload/src/upload"; |
| | | |
| | | export interface MmItemTypeVO { |
| | | id: string |
| | | export interface MmPredictItemVO { |
| | | id: string, |
| | | itemtypename: string, |
| | | itemclasstype: string, |
| | | assemblyname: string |
| | | mmPredictItem: { |
| | | id: string, |
| | | itemno: string, |
| | | itemname: string, |
| | | caltypeid: string, |
| | | itemtypeid: string, |
| | | predictlength: string, |
| | | granularity: number, |
| | | status: string, |
| | | isfuse: number, |
| | | predictphase: string, |
| | | workchecked: number, |
| | | unittransfactor: string, |
| | | saveindex: string |
| | | }, |
| | | dmModuleItem: { |
| | | id: string, |
| | | moduleid: string, |
| | | itemid: string, |
| | | itemorder: number, |
| | | status: number, |
| | | categoryid: string |
| | | }, |
| | | mmItemOutput: { |
| | | id: string, |
| | | itemid: string, |
| | | pointid: string, |
| | | resulttableid: string, |
| | | tagname: string, |
| | | outputorder: number |
| | | }, |
| | | mmPredictModel: { |
| | | id: string, |
| | | modelno: string, |
| | | modelname: string, |
| | | itemid: string, |
| | | arithid: string, |
| | | trainsamplength: number, |
| | | predictsamplength: string, |
| | | isonlinetrain: string, |
| | | modelpath: string, |
| | | isnormal: string, |
| | | normalmax: string, |
| | | normalmin: string, |
| | | status: number, |
| | | classname: string, |
| | | methodname: string, |
| | | modelparamstructure: string, |
| | | resultstrid: string, |
| | | settingmap: string |
| | | }, |
| | | mmPredictMergeItem: { |
| | | id: string, |
| | | itemid: string, |
| | | expression: string, |
| | | num: string |
| | | }, |
| | | modelparamtypeList: [], |
| | | mmModelArithSettingsList: [], |
| | | mmModelParamList: [] |
| | | } |
| | | |
| | | export interface MmItemTypePageReqVO extends PageParam { |
| | | itemtypename?: string |
| | | export interface MmPredictItemPageReqVO extends PageParam { |
| | | itemno?: string, |
| | | itemname?: string, |
| | | } |
| | | |
| | | // 查询MmItemType列表 |
| | | export const getMmItemTypePage = (params: MmItemTypePageReqVO) => { |
| | | return request.get({ url: '/model/pre/item-type/page', params }) |
| | | // 查询MmPredictItem列表 |
| | | export const getMmPredictItemPage = (params: MmPredictItemPageReqVO) => { |
| | | return request.get({ url: '/model/pre/item/page', params }) |
| | | } |
| | | |
| | | // 查询MmItemType详情 |
| | | export const getMmItemType = (id: number) => { |
| | | return request.get({ url: `/model/pre/item-type/get/${id}`}) |
| | | // 查询MmPredictItem详情 |
| | | export const getMmPredictItem = (id: number) => { |
| | | return request.get({ url: `/model/pre/item/get/${id}`}) |
| | | } |
| | | |
| | | // 新增MmItemType |
| | | export const createMmItemType = (data: MmItemTypeVO) => { |
| | | return request.post({ url: '/model/pre/item-type/create', data }) |
| | | // 新增MmPredictItem |
| | | export const createMmPredictItem = (data: MmPredictItemVO) => { |
| | | return request.post({ url: '/model/pre/item/create', data }) |
| | | } |
| | | |
| | | // 修改MmItemType |
| | | export const updateMmItemType = (data: MmItemTypeVO) => { |
| | | return request.put({ url: '/model/pre/item-type/update', data }) |
| | | // 修改MmPredictItem |
| | | export const updateMmPredictItem = (data: MmPredictItemVO) => { |
| | | return request.put({ url: '/model/pre/item/update', data }) |
| | | } |
| | | |
| | | // 删除MmItemType |
| | | export const deleteMmItemType = (id: number) => { |
| | | return request.delete({ url: '/model/pre/item-type/delete?id=' + id }) |
| | | // 删除MmPredictItem |
| | | export const deleteMmPredictItem = (id: number) => { |
| | | return request.delete({ url: '/model/pre/item/delete?id=' + id }) |
| | | } |
| | | |
| | | // 查询MmPredictItem列表 |
| | | export const getMmPredictItemList = (params) => { |
| | | return request.get({ url: `/model/pre/item/list`, params}) |
| | | } |
| | | |
| | | // 查询getItemTypeList详情 |
| | | export const getItemTypeList = () => { |
| | | return request.get({ url: `/model/pre/item-type/list`}) |
| | | export const updateModel = (data: any) => { |
| | | return request.upload({ url: '/model/pre/item/upload-model', data }) |
| | | } |
| | | |
| | | export const useUpload = () => { |
| | | const uploadUrl = import.meta.env.VITE_BASE_URL + '/admin-api/model/pre/item/upload-model' |
| | | |
| | | const httpRequest = async (options: UploadRequestOptions) => { |
| | | return new Promise((resolve, reject) => { |
| | | updateModel({ file: options.file }) |
| | | .then((res) => { |
| | | if (res.code === 0) { |
| | | resolve(res) |
| | | } else { |
| | | reject(res) |
| | | } |
| | | }) |
| | | .catch((res) => { |
| | | reject(res) |
| | | }) |
| | | }) |
| | | |
| | | } |
| | | |
| | | return { |
| | | uploadUrl, |
| | | httpRequest |
| | | } |
| | | } |
| | | |
| | | export const getMmPredictItemTree = () => { |
| | | return request.get({ url: `/model/pre/item/tree`}) |
| | | } |
| | | |
| | | export const getViewCharts = (params) => { |
| | | return request.get({ url: `/model/pre/item/view-charts`,params}) |
| | | } |
对比新文件 |
| | |
| | | import request from '@/config/axios' |
| | | |
| | | export interface MmItemTypeVO { |
| | | id: string |
| | | itemtypename: string, |
| | | itemclasstype: string, |
| | | assemblyname: string |
| | | } |
| | | |
| | | export interface MmItemTypePageReqVO extends PageParam { |
| | | itemtypename?: string |
| | | } |
| | | |
| | | // 查询MmItemType列表 |
| | | export const getMmItemTypePage = (params: MmItemTypePageReqVO) => { |
| | | return request.get({ url: '/model/pre/item-type/page', params }) |
| | | } |
| | | |
| | | // 查询MmItemType详情 |
| | | export const getMmItemType = (id: number) => { |
| | | return request.get({ url: `/model/pre/item-type/get/${id}`}) |
| | | } |
| | | |
| | | // 新增MmItemType |
| | | export const createMmItemType = (data: MmItemTypeVO) => { |
| | | return request.post({ url: '/model/pre/item-type/create', data }) |
| | | } |
| | | |
| | | // 修改MmItemType |
| | | export const updateMmItemType = (data: MmItemTypeVO) => { |
| | | return request.put({ url: '/model/pre/item-type/update', data }) |
| | | } |
| | | |
| | | // 删除MmItemType |
| | | export const deleteMmItemType = (id: number) => { |
| | | return request.delete({ url: '/model/pre/item-type/delete?id=' + id }) |
| | | } |
| | | |
| | | |
| | | // 查询getItemTypeList详情 |
| | | export const getItemTypeList = () => { |
| | | return request.get({ url: `/model/pre/item-type/list`}) |
| | | } |
| | |
| | | import request from '@/config/axios' |
| | | import * as DataPointApi from '@/api/data/da/point' |
| | | import * as PredictItemApi from '@/api/model/pre/predict' |
| | | 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 |
| | |
| | | ) |
| | | }) |
| | | } |
| | | |
| | | 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, |
| | | } |
| | | } |
| | |
| | | noTagsView: true |
| | | } |
| | | }, |
| | | // { |
| | | // path: '/shasteel', |
| | | // component: () => import('@/views/micro/index.vue'), |
| | | // name: 'shasteel', |
| | | // meta: { |
| | | // hidden: true, |
| | | // noTagsView: true |
| | | // }, |
| | | // }, |
| | | { |
| | | path: '/home2', |
| | | component: () => import('@/views/Home/Index2.vue'), |
| | |
| | | hidden: true, |
| | | canTo: true, |
| | | title: '设计流程', |
| | | activeMenu: '/bpm/manager/model' |
| | | } |
| | | }, |
| | | { |
| | | path: 'manager/simple/workflow/model/edit', |
| | | component: () => import('@/views/bpm/simpleWorkflow/index.vue'), |
| | | name: 'SimpleWorkflowDesignEditor', |
| | | meta: { |
| | | noCache: true, |
| | | hidden: true, |
| | | canTo: true, |
| | | title: '仿钉钉设计流程', |
| | | activeMenu: '/bpm/manager/model' |
| | | } |
| | | }, |
| | |
| | | MODEL_TYPE = 'model_type', |
| | | MODEL_METHOD_SETTING_TYPE = 'model_method_setting_type', |
| | | MODEL_METHOD_SETTING_VALUE_TYPE = 'model_method_setting_value_type', |
| | | PRED_GRANULARITY = 'pred_granularity', |
| | | ITEM_RUN_STATUS = 'item_run_status', |
| | | |
| | | // ========== DATA - 数据平台模块 ========== |
| | | DATA_FIELD_TYPE = 'data_field_type', |
| | |
| | | NVR_ONLINE_STATUS = 'nvr_online_status', |
| | | CAMERA_BRAND = 'camera_brand', |
| | | CAPTURE_TYPE = 'capture_type', |
| | | MODEL_RESULT_TYPE = 'model_result_type', |
| | | } |
| | |
| | | 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/", |
| | | }; |
| | | |
| | |
| | | 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) |
| | | } |
| | | |
| | |
| | | <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> |
| | |
| | | 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) |
| | | |
| | |
| | | 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 |
| | |
| | | |
| | | // 进入应用 |
| | | 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; |
| | |
| | | <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"> |
| | |
| | | </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) |
| | |
| | | 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 |
| | |
| | | <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']" |
| | | > |
| | |
| | | const handleDesign = (row) => { |
| | | push({ |
| | | name: 'BpmModelEditor', |
| | | query: { |
| | | modelId: row.id |
| | | } |
| | | }) |
| | | } |
| | | |
| | | const handleSimpleDesign = (row) => { |
| | | push({ |
| | | name: 'SimpleWorkflowDesignEditor', |
| | | query: { |
| | | modelId: row.id |
| | | } |
| | |
| | | <template> |
| | | <el-drawer |
| | | v-model="drawer" |
| | | size="50%" |
| | | size="60%" |
| | | title="Http Tag" |
| | | :direction="direction" |
| | | :before-close="handleClose" |
| | |
| | | label="数据值" |
| | | header-align="center" |
| | | align="center" |
| | | min-width="100" |
| | | :formatter="(row) => {if (row.dataValue === -2.0) {return '--';}return row.dataValue;}" |
| | | /> |
| | | <el-table-column |
| | | prop="quality" |
| | | prop="dataTime" |
| | | label="数据时间" |
| | | header-align="center" |
| | | align="center" |
| | | min-width="150" |
| | | /> |
| | | <el-table-column |
| | | prop="dataQuality" |
| | | label="数据质量" |
| | | header-align="center" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | <el-tag v-if="scope.row.dataValue === Number(-2.0)" type="danger" size="small">bad |
| | | </el-tag> |
| | | <el-tag v-else size="small">good</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | /> |
| | | <el-table-column label="操作" align="center" min-width="110" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button |
| | |
| | | <template> |
| | | <el-drawer |
| | | v-model="drawer" |
| | | size="50%" |
| | | size="60%" |
| | | title="Kio Tag" |
| | | :direction="direction" |
| | | :before-close="handleClose" |
| | |
| | | label="数据值" |
| | | header-align="center" |
| | | align="center" |
| | | min-width="100" |
| | | :formatter="(row) => {if (row.dataValue === -2.0) {return '--';}return row.dataValue;}" |
| | | /> |
| | | <el-table-column |
| | | prop="quality" |
| | | prop="dataTime" |
| | | label="数据时间" |
| | | header-align="center" |
| | | align="center" |
| | | min-width="150" |
| | | /> |
| | | <el-table-column |
| | | prop="dataQuality" |
| | | label="数据质量" |
| | | header-align="center" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | <el-tag v-if="scope.row.dataValue === Number(-2.0)" type="danger" size="small">bad</el-tag> |
| | | <el-tag v-else size="small">good</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | /> |
| | | <el-table-column label="操作" align="center" min-width="110" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button |
| | |
| | | <template> |
| | | <el-drawer |
| | | v-model="drawer" |
| | | size="50%" |
| | | size="60%" |
| | | title="ModBus Tag" |
| | | :direction="direction" |
| | | :before-close="handleClose" |
| | |
| | | label="数据值" |
| | | header-align="center" |
| | | align="center" |
| | | min-width="100" |
| | | :formatter="(row) => {if (row.dataValue === -2.0) {return '--';}return row.dataValue;}" |
| | | /> |
| | | <el-table-column |
| | | prop="quality" |
| | | prop="dataTime" |
| | | label="数据时间" |
| | | header-align="center" |
| | | align="center" |
| | | min-width="150" |
| | | /> |
| | | <el-table-column |
| | | prop="dataQuality" |
| | | label="数据质量" |
| | | header-align="center" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | <el-tag v-if="scope.row.dataValue === Number(-2.0)" type="danger" size="small">bad</el-tag> |
| | | <el-tag v-else size="small">good</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | /> |
| | | <el-table-column label="操作" align="center" min-width="110" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button |
| | |
| | | <template> |
| | | <el-drawer |
| | | v-model="drawer" |
| | | size="50%" |
| | | size="60%" |
| | | title="OpcDA Tag" |
| | | :direction="direction" |
| | | :before-close="handleClose" |
| | |
| | | label="数据值" |
| | | header-align="center" |
| | | align="center" |
| | | min-width="100" |
| | | :formatter="(row) => {if (row.dataValue === -2.0) {return '--';}return row.dataValue;}" |
| | | /> |
| | | <el-table-column |
| | | prop="quality" |
| | | prop="dataTime" |
| | | label="数据时间" |
| | | header-align="center" |
| | | align="center" |
| | | min-width="150" |
| | | /> |
| | | <el-table-column |
| | | prop="dataQuality" |
| | | label="数据质量" |
| | | header-align="center" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | <el-tag v-if="scope.row.dataValue === Number(-2.0)" type="danger" size="small">bad</el-tag> |
| | | <el-tag v-else size="small">good</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | /> |
| | | <el-table-column label="操作" align="center" min-width="110" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button |
| | |
| | | <template> |
| | | <el-drawer |
| | | v-model="drawer" |
| | | size="50%" |
| | | size="60%" |
| | | title="Opcua Tag" |
| | | :direction="direction" |
| | | :before-close="handleClose" |
| | |
| | | <Icon icon="ep:download" />导出 |
| | | </el-button> |
| | | </el-form-item> |
| | | <el-form-item label="更新当前值" label-width="100px"> |
| | | <el-switch |
| | | v-model="queryParams.currentValue" |
| | | active-color="#13ce66" |
| | | inactive-color="#ff4949"/> |
| | | </el-form-item> |
| | | </el-form> |
| | | </ContentWrap> |
| | | <!-- 列表 --> |
| | |
| | | label="数据值" |
| | | header-align="center" |
| | | align="center" |
| | | min-width="100" |
| | | :formatter="(row) => {if (row.dataValue === -2.0) {return '--';}return row.dataValue;}" |
| | | /> |
| | | <el-table-column |
| | | prop="quality" |
| | | prop="dataTime" |
| | | label="数据时间" |
| | | header-align="center" |
| | | align="center" |
| | | min-width="150" |
| | | /> |
| | | <el-table-column |
| | | prop="dataQuality" |
| | | label="数据质量" |
| | | header-align="center" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | <el-tag v-if="scope.row.dataValue === Number(-2.0)" type="danger" size="small">bad</el-tag> |
| | | <el-tag v-else size="small">good</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | /> |
| | | <el-table-column label="操作" align="center" min-width="110" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button |
| | |
| | | :loading="exportLoading" |
| | | v-hasPermi="['data:point:export']" |
| | | > |
| | | <Icon icon="ep:download" />导出 |
| | | <Icon icon="ep:download"/> |
| | | 导出 |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import {ref} from 'vue'; |
| | | import * as echarts from 'echarts'; |
| | | import * as DaPoint from '@/api/data/da/point/daPointChart' |
| | | import {getYMDHM0} from "@/utils/dateUtil" |
| | | import download from "@/utils/download"; |
| | | const message = useMessage() // 消息弹窗 |
| | | const visible = ref(false); |
| | | const chartDom = ref(null); |
| | | let myChart = null; |
| | | const chartParams = reactive({ |
| | | codes:[], |
| | | startDate : undefined, |
| | | endDate: undefined, |
| | | }) |
| | | const dataForm = ref({ |
| | | id: "", |
| | | pointNo: "", |
| | | pointName: "", |
| | | pointTypeName: "", |
| | | startTime: getYMDHM0(new Date() - 60 * 60 * 1000), |
| | | endTime: "", |
| | | }); |
| | | const loading = ref(true) // 列表的加载中 |
| | | /** 打开弹窗 */ |
| | | const open = async (row: object) => { |
| | | visible.value = true |
| | | dataForm.value.id = row.id; |
| | | dataForm.value.pointNo = row.pointNo; |
| | | dataForm.value.pointName = row.pointName; |
| | | getDataList(); |
| | | } |
| | | import {ref} from 'vue'; |
| | | import * as echarts from 'echarts'; |
| | | import * as DaPoint from '@/api/data/da/point/daPointChart' |
| | | import {getYMDHM0} from "@/utils/dateUtil" |
| | | import download from "@/utils/download"; |
| | | |
| | | defineExpose({open}) // 提供 open 方法,用于打开弹窗 |
| | | const message = useMessage() // 消息弹窗 |
| | | const visible = ref(false); |
| | | const chartDom = ref(null); |
| | | let myChart = null; |
| | | const chartParams = reactive({ |
| | | codes: [], |
| | | pointNo: undefined, |
| | | startDate: undefined, |
| | | endDate: undefined, |
| | | }) |
| | | const dataForm = ref({ |
| | | id: "", |
| | | pointNo: "", |
| | | pointName: "", |
| | | pointTypeName: "", |
| | | startTime: getYMDHM0(new Date() - 60 * 60 * 1000), |
| | | endTime: "", |
| | | }); |
| | | |
| | | /** 打开弹窗 */ |
| | | const open = async (row: object) => { |
| | | visible.value = true |
| | | dataForm.value.id = row.id; |
| | | dataForm.value.pointNo = row.pointNo; |
| | | dataForm.value.pointName = row.pointName; |
| | | getDataList(); |
| | | } |
| | | |
| | | defineExpose({open}) // 提供 open 方法,用于打开弹窗 |
| | | |
| | | async function getDataList() { |
| | | visible.value = true; |
| | |
| | | }); |
| | | }) |
| | | |
| | | myChart = echarts.init(chartDom.value); |
| | | const option = { |
| | | title: { |
| | | text: dataForm.value.pointName, |
| | | top: 0, |
| | | left: "1%", |
| | | textStyle: { |
| | | fontSize: 14, |
| | | myChart = echarts.init(chartDom.value); |
| | | const option = { |
| | | title: { |
| | | text: dataForm.value.pointName, |
| | | top: 0, |
| | | left: "1%", |
| | | textStyle: { |
| | | fontSize: 14, |
| | | }, |
| | | }, |
| | | tooltip: { |
| | | trigger: "axis", |
| | | axisPointer: { |
| | | type: "line", |
| | | lineStyle: { |
| | | color: "#cccccc", |
| | | width: "1", |
| | | type: "dashed", |
| | | }, |
| | | }, |
| | | tooltip: { |
| | | trigger: "axis", |
| | | axisPointer: { |
| | | type: "line", |
| | | lineStyle: { |
| | | color: "#cccccc", |
| | | width: "1", |
| | | type: "dashed", |
| | | }, |
| | | }, |
| | | }, |
| | | legend: { |
| | | show: false, |
| | | top: 10, |
| | | }, |
| | | grid: { |
| | | top: 30, |
| | | left: "3%", |
| | | right: "5%", |
| | | bottom: 10, |
| | | containLabel: true, |
| | | }, |
| | | xAxis: { |
| | | type: "category", |
| | | boundaryGap: false, |
| | | data: data.categories, |
| | | }, |
| | | yAxis: { |
| | | type: "value", |
| | | }, |
| | | dataZoom: [ |
| | | { |
| | | type: "inside", |
| | | }, |
| | | legend: { |
| | | show: false, |
| | | top: 10, |
| | | }, |
| | | grid: { |
| | | top: 30, |
| | | left: "3%", |
| | | right: "5%", |
| | | bottom: 10, |
| | | containLabel: true, |
| | | }, |
| | | xAxis: { |
| | | type: "category", |
| | | boundaryGap: false, |
| | | data: data.categories, |
| | | }, |
| | | yAxis: { |
| | | type: "value", |
| | | }, |
| | | dataZoom: [ |
| | | { |
| | | type: "inside", |
| | | }, |
| | | ], |
| | | series: seriesData, |
| | | }; |
| | | myChart.setOption(option); |
| | | } catch (error) { |
| | | console.error(error) |
| | | } |
| | | ], |
| | | series: seriesData, |
| | | }; |
| | | myChart.setOption(option); |
| | | } catch (error) { |
| | | console.error(error) |
| | | } |
| | | } |
| | | /** 导出按钮操作 */ |
| | | const exportLoading = ref(false) |
| | | const handleExport = async () => { |
| | | chartParams.codes=[dataForm.value.pointNo]; |
| | | chartParams.startDate = dataForm.value.startTime; |
| | | chartParams.endDate = dataForm.value.endTime; |
| | | try { |
| | | // 导出的二次确认 |
| | | await message.exportConfirm() |
| | | // 发起导出 |
| | | exportLoading.value = true |
| | | const data = await DaPoint.exportDaPointValue(chartParams) |
| | | download.excel(data, dataForm.value.pointName +'.xls') |
| | | } catch { |
| | | } finally { |
| | | exportLoading.value = false |
| | | } |
| | | } |
| | | |
| | | /** 导出按钮操作 */ |
| | | const exportLoading = ref(false) |
| | | const handleExport = async () => { |
| | | try { |
| | | // 导出的二次确认 |
| | | await message.exportConfirm() |
| | | // 发起导出 |
| | | exportLoading.value = true |
| | | const data = await DaPoint.exportDaPointValue({ |
| | | pointNo: dataForm.value.pointNo, |
| | | start: dataForm.value.startTime, |
| | | end: dataForm.value.endTime |
| | | }) |
| | | download.excel(data, dataForm.value.pointName + '.xls') |
| | | } catch { |
| | | } finally { |
| | | exportLoading.value = false |
| | | } |
| | | } |
| | | </script> |
| | | <style> |
| | | .el-select { |
| | | width: 100%; |
| | | } |
| | | .el-select { |
| | | width: 100%; |
| | | } |
| | | |
| | | .result-chart { |
| | | height: 500px; |
| | | } |
| | | .result-chart { |
| | | height: 500px; |
| | | } |
| | | </style> |
对比新文件 |
| | |
| | | <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> |
| | |
| | | </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 |
| | |
| | | @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 |
| | |
| | | :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> |
| | |
| | | <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"> |
| | |
| | | > |
| | | 删除 |
| | | </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> |
| | |
| | | </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> |
| | |
| | | @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> |
| | |
| | | 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'}) |
| | | |
| | |
| | | await getList() |
| | | } |
| | | |
| | | defineExpose({ open }) // 提供 open 方法,用于打开弹窗 |
| | | defineExpose({open}) // 提供 open 方法,用于打开弹窗 |
| | | |
| | | /** 查询列表 */ |
| | | const getList = async () => { |
| | |
| | | } |
| | | } |
| | | |
| | | /** 查看截图 */ |
| | | const imageFormRef = ref() |
| | | const imageHandle = (id: string) => { |
| | | imageFormRef.value.open(id) |
| | | } |
| | | |
| | | /** 搜索按钮操作 */ |
| | | const handleQuery = () => { |
| | | queryParams.pageNo = 1 |
| | |
| | | |
| | | /** 重置按钮操作 */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields() |
| | | queryParams.location = undefined |
| | | handleQuery() |
| | | } |
| | | |
| | |
| | | </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 |
| | |
| | | @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 |
| | |
| | | :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> |
| | |
| | | <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"> |
| | |
| | | > |
| | | 删除 |
| | | </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> |
| | |
| | | </ContentWrap> |
| | | |
| | | <!-- 表单弹窗:添加/修改 --> |
| | | <NvrForm ref="formRef" @success="getList" /> |
| | | <NvrForm ref="formRef" @success="getList"/> |
| | | |
| | | <!-- 弹窗, 摄像头 --> |
| | | <NvrCamera ref="videoCameraRef"/> |
| | |
| | | </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> |
文件名从 src/views/data/swagger/index.vue 修改 |
| | |
| | | <script lang="ts" setup> |
| | | import * as ConfigApi from '@/api/infra/config' |
| | | |
| | | defineOptions({ name: 'DataSwagger' }) |
| | | defineOptions({ name: 'DataWiki' }) |
| | | |
| | | const loading = ref(true) // 是否加载中 |
| | | const src = ref(import.meta.env.VITE_BASE_URL + '/doc.html') |
| | |
| | | /** 初始化 */ |
| | | onMounted(async () => { |
| | | try { |
| | | const data = await ConfigApi.getConfigKey('data.swagger') |
| | | const data = await ConfigApi.getConfigKey('data.wiki') |
| | | if (data && data.length > 0) { |
| | | src.value = data |
| | | } |
| | |
| | | float: right; |
| | | color: var(--el-text-color-secondary); |
| | | font-size: 13px;"> |
| | | <img :src="'/SimtreeUnitImage/' + item.iconName" style="height: 24px;" :alt=" item.iconDesc" /> |
| | | <img :src="staticDir + 'SimtreeUnitImage/' + item.iconName" style="height: 24px;" :alt=" item.iconDesc" /> |
| | | </span> |
| | | </el-option> |
| | | </el-select> |
| | |
| | | const route = useRoute() // 路由 |
| | | const router = useRouter(); |
| | | |
| | | const staticDir = ref(import.meta.env.VITE_STATIC_DIR) |
| | | |
| | | const treeData = ref([]) |
| | | const iconList = ref([] as MpkIconApi.MpkIconVO) |
| | | const pkgNameList = ref([] as MpkPackApi.MpkPackVO) |
| | |
| | | <el-divider content-position="left">模型参数信息</el-divider> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="2" style="margin-bottom: 10px;margin-left: 20px"> |
| | | <el-button tag="a" href="/template/模型参数导入模板.xlsx" download="模型参数导入模板.xlsx" style="text-decoration: none;" type="primary" size="small" link>模板下载</el-button> |
| | | <el-button tag="a" :href="staticDir + '/template/模型参数导入模板.xlsx'" download="模型参数导入模板.xlsx" style="text-decoration: none;" type="primary" size="small" link>模板下载</el-button> |
| | | </el-col> |
| | | <el-col :span="2" style="margin-bottom: 10px;"> |
| | | <el-upload |
| | |
| | | import * as MpkApi from '@/api/model/mpk/mpk' |
| | | import {FormRules} from "element-plus"; |
| | | import {getAccessToken, getTenantId} from "@/utils/auth"; |
| | | const staticDir = ref(import.meta.env.VITE_STATIC_DIR) |
| | | |
| | | const { t } = useI18n() // 国际化 |
| | | const message = useMessage() // 消息弹窗 |
| | |
| | | <el-table-column prop="iconDesc" label="描述"/> |
| | | <el-table-column align="center" label="图标" prop="icon" width="100"> |
| | | <template #default="scope"> |
| | | <img :src="'/SimtreeUnitImage/' + scope.row.iconName" class="mpk-icon-list" :alt=" scope.row.iconDesc" /> |
| | | <img :src="staticDir + 'SimtreeUnitImage/' + scope.row.iconName" class="mpk-icon-list" :alt=" scope.row.iconDesc" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="sort" label="排序"/> |
| | |
| | | |
| | | defineOptions({name: 'MpkIcon'}) |
| | | |
| | | const staticDir = ref(import.meta.env.VITE_STATIC_DIR) |
| | | |
| | | const message = useMessage() // 消息弹窗 |
| | | const {t} = useI18n() // 国际化 |
| | | |
| | |
| | | <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> |
| | | |
| | |
| | | <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> |
| | |
| | | <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> |
| | |
| | | <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> |
| | | </el-form> |
| | | |
| | | </div> |
| | | </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/predict' |
| | | 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: '', |
| | |
| | | isMultipleYRadio: '单坐标轴', |
| | | isMultipleY: false, |
| | | predictFreq: 3, |
| | | }) |
| | | let calRateForm = ref({ |
| | | calItem: '', |
| | | } |
| | | calRateForm.value = { |
| | | calItem: undefined, |
| | | IN_DEVIATION: 0, |
| | | OUT_DEVIATION: 0, |
| | | IN_ACCURACY_RATE: 0, |
| | |
| | | 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 - 48px - 38px - 130px)); |
| | | 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> |
对比新文件 |
| | |
| | | <template> |
| | | <el-dialog |
| | | title="预测数据" |
| | | :close-on-click-modal="false" |
| | | width="50%" |
| | | v-model="visible" |
| | | > |
| | | <el-form |
| | | :inline="true" |
| | | :model="dataForm" |
| | | @keydown.enter="getDataList()" |
| | | > |
| | | <el-form-item label="开始时间"> |
| | | <el-date-picker |
| | | size="mini" |
| | | v-model="dataForm.startTime" |
| | | format="YYYY-MM-DD HH:mm:00" |
| | | value-format="YYYY-MM-DD HH:mm:00" |
| | | type="datetime" |
| | | :clearable="false" |
| | | placeholder="选择日期时间"/> |
| | | </el-form-item> |
| | | <el-form-item label="结束时间"> |
| | | <el-date-picker |
| | | size="mini" |
| | | v-model="dataForm.endTime" |
| | | format="YYYY-MM-DD HH:mm:00" |
| | | value-format="YYYY-MM-DD HH:mm:00" |
| | | type="datetime" |
| | | :clearable="false" |
| | | placeholder="选择日期时间"/> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button @click="getDataList()">查询</el-button> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | @click="handleExport" |
| | | :loading="exportLoading" |
| | | > |
| | | <Icon icon="ep:download"/> |
| | | 导出 |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div ref="chartDomPre" class="result-chart"></div> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import {ref} from 'vue'; |
| | | import * as echarts from 'echarts'; |
| | | import * as McsApi from '@/api/model/mcs' |
| | | import {getYMDHM0} from "@/utils/dateUtil" |
| | | import download from "@/utils/download"; |
| | | |
| | | const message = useMessage() // 消息弹窗 |
| | | const visible = ref(false); |
| | | const chartDomPre = ref(null); |
| | | let myChart = null; |
| | | const chartParams = reactive({ |
| | | itemId: undefined, |
| | | startTime: undefined, |
| | | endTime: undefined, |
| | | }) |
| | | const dataForm = ref({ |
| | | id: "", |
| | | itemName: "", |
| | | startTime: getYMDHM0(new Date() - 60 * 60 * 1000), |
| | | endTime: getYMDHM0(new Date() + 60 * 60 * 1000), |
| | | }); |
| | | |
| | | /** 打开弹窗 */ |
| | | const open = async (row: object) => { |
| | | visible.value = true |
| | | resetForm() |
| | | dataForm.value.id = row.id; |
| | | dataForm.value.itemName = row.itemname; |
| | | if (row.id) { |
| | | getDataList(); |
| | | } |
| | | } |
| | | |
| | | defineExpose({open}) // 提供 open 方法,用于打开弹窗 |
| | | |
| | | async function getDataList() { |
| | | visible.value = true; |
| | | if (dataForm.value.id) { |
| | | try { |
| | | chartParams.itemId = dataForm.value.id; |
| | | chartParams.startTime = dataForm.value.startTime; |
| | | chartParams.endTime = dataForm.value.endTime; |
| | | const data = await McsApi.getPreDataItemChart(chartParams) |
| | | let legendData = [] |
| | | if (data.legend && data.legend.length > 0) { |
| | | data.legend.forEach(item => { |
| | | legendData.push(item + ":" + '真实值') |
| | | legendData.push(item + ":" + '预测值') |
| | | }) |
| | | } |
| | | |
| | | let seriesData = [] |
| | | if (data.predictTime) { |
| | | seriesData.push({ |
| | | name: '', |
| | | data: [null], |
| | | type: 'line', |
| | | smooth: true, |
| | | color: 'green', |
| | | markLine: { |
| | | silent: true, |
| | | lineStyle: { |
| | | color: '#32a487', |
| | | width: 2 |
| | | }, |
| | | data: [{ |
| | | xAxis: data.predictTime |
| | | }], |
| | | label: { |
| | | normal: { |
| | | formatter: data.predictTime |
| | | } |
| | | }, |
| | | symbol: ['circle', 'none'], |
| | | }, |
| | | }); |
| | | } |
| | | |
| | | if (data.viewMap) { |
| | | Object.keys(data.viewMap).forEach(key => { |
| | | let viewData = data.viewMap[key] |
| | | seriesData.push({ |
| | | name: key + ":" + '真实值', |
| | | type: "line", |
| | | data: viewData.realData, |
| | | showSymbol: false, |
| | | smooth: false, |
| | | lineStyle: { |
| | | normal: { |
| | | width: 1, |
| | | }, |
| | | }, |
| | | }) |
| | | seriesData.push({ |
| | | name: key + ":" + '预测值', |
| | | type: "line", |
| | | data: viewData.preDataN, |
| | | showSymbol: false, |
| | | smooth: false, |
| | | lineStyle: { |
| | | normal: { |
| | | width: 1, |
| | | }, |
| | | }, |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | myChart = echarts.init(chartDomPre.value); |
| | | const option = { |
| | | title: { |
| | | text: dataForm.value.itemName, |
| | | top: 0, |
| | | left: "1%", |
| | | textStyle: { |
| | | fontSize: 14, |
| | | }, |
| | | }, |
| | | tooltip: { |
| | | trigger: "axis", |
| | | axisPointer: { |
| | | type: "line", |
| | | lineStyle: { |
| | | color: "#cccccc", |
| | | width: "1", |
| | | type: "dashed", |
| | | }, |
| | | }, |
| | | }, |
| | | legend: { |
| | | show: true, |
| | | top: 20, |
| | | data: legendData |
| | | }, |
| | | grid: { |
| | | top: "20%", |
| | | left: "3%", |
| | | right: "5%", |
| | | bottom: 10, |
| | | containLabel: true, |
| | | }, |
| | | xAxis: { |
| | | type: "category", |
| | | boundaryGap: false, |
| | | data: data.categories, |
| | | }, |
| | | yAxis: { |
| | | type: "value", |
| | | }, |
| | | dataZoom: [ |
| | | { |
| | | type: "inside", |
| | | }, |
| | | ], |
| | | series: seriesData, |
| | | }; |
| | | myChart.setOption(option); |
| | | } catch (error) { |
| | | console.error(error) |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** 导出按钮操作 */ |
| | | const exportLoading = ref(false) |
| | | const handleExport = async () => { |
| | | chartParams.itemId = dataForm.value.id; |
| | | chartParams.startTime = dataForm.value.startTime?dataForm.value.startTime:""; |
| | | chartParams.endTime = dataForm.value.endTime?dataForm.value.endTime:""; |
| | | try { |
| | | // 导出的二次确认 |
| | | await message.exportConfirm() |
| | | // 发起导出 |
| | | exportLoading.value = true |
| | | const data = await McsApi.exportPredictValue(chartParams) |
| | | download.excel(data, dataForm.value.itemName + '.xls') |
| | | } catch { |
| | | } finally { |
| | | exportLoading.value = false |
| | | } |
| | | } |
| | | |
| | | /** 重置表单 */ |
| | | const resetForm = () => { |
| | | dataForm.value = { |
| | | id: undefined, |
| | | itemName: undefined, |
| | | startTime: undefined, |
| | | endTime: undefined |
| | | } |
| | | } |
| | | </script> |
| | | <style> |
| | | .el-select { |
| | | width: 100%; |
| | | } |
| | | |
| | | .result-chart { |
| | | height: 500px; |
| | | } |
| | | </style> |
| | |
| | | </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> |
| | |
| | | <el-form-item label="粒度" prop="mmPredictItem.granularity"> |
| | | <el-select v-model="dataForm.mmPredictItem.granularity" placeholder="请选择"> |
| | | <el-option |
| | | v-for="dict in getIntDictOptions(DICT_TYPE.TIME_GRANULARITY)" |
| | | v-for="dict in getIntDictOptions(DICT_TYPE.PRED_GRANULARITY)" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | |
| | | controls-position="right"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="数据点" prop="mmItemOutput.pointid"> |
| | | <el-select |
| | | v-model="dataForm.mmItemOutput.pointid" |
| | | filterable |
| | | @change="changeOutputPoint" |
| | | placeholder="请选择"> |
| | | <el-option |
| | | v-for="item in pointList" |
| | | :key="item.id" |
| | | :label="item.pointName" |
| | | :value="item.id"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row v-if="dataForm.itemtypename === 'MergeItem'"> |
| | | <el-col :span="12"> |
| | |
| | | :on-success="uploadModelSuccess" |
| | | :on-error="uploadModelError" |
| | | :action="uploadUrl" |
| | | :show-file-list="false" |
| | | :http-request="httpRequest"> |
| | | <el-button type="primary" @click="setReplaceModelOnly(false)"> |
| | | <Icon icon="ep:upload"/> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | <el-row v-if="dataForm.itemtypename === 'NormalItem'"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="结果"> |
| | | <el-select v-model="dataForm.mmPredictModel.resultstrid" placeholder="请选择"> |
| | | <el-option |
| | | v-for="item in resultstridList" |
| | | :key="item.id" |
| | | :label="item.resultstr" |
| | | :value="item.id"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="关联项目"> |
| | | <el-select v-model="dataForm.mmPredictModel.mpkprojectid" placeholder="请选择"> |
| | | <el-option |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="编号"> |
| | | <el-input |
| | | v-model="dataForm.mmPredictModel.modelno" placeholder="编号" maxlength="30" readonly |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-divider content-position="left" v-if="dataForm.itemtypename === 'NormalItem'">模型输出 |
| | | </el-divider> |
| | | <el-button |
| | | @click="addItemOutput(dataForm.mmItemOutputList)" |
| | | type="primary" |
| | | size="small"> |
| | | 添加 |
| | | </el-button> |
| | | <el-table |
| | | v-if="dataForm.itemtypename === 'NormalItem'" |
| | | :data="dataForm.mmItemOutputList" |
| | | border |
| | | style="width: 100%; margin-top: 5px;"> |
| | | <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"> |
| | | <template #default="scope"> |
| | | <el-select |
| | | v-model="scope.row.resultType" |
| | | @change="(value) => resultTypeChange(value,scope.row)" |
| | | filterable |
| | | placeholder="请选择"> |
| | | <el-option |
| | | v-for="dict in getIntDictOptions(DICT_TYPE.MODEL_RESULT_TYPE)" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value"/> |
| | | </el-select> |
| | | </template> |
| | | </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"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="数据点" align="center"> |
| | | <template #default="scope"> |
| | | <el-select |
| | | v-model="scope.row.pointid" |
| | | filterable |
| | | @change="(value) => changeOutputPoint(value,scope.row)" |
| | | placeholder="请选择"> |
| | | <el-option |
| | | v-for="item in pointList" |
| | | :key="item.id" |
| | | :label="item.pointName" |
| | | :value="item.id"/> |
| | | </el-select> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="" label="操作" width="80" align="center"> |
| | | <template #default="scope"> |
| | | <el-button |
| | | @click="deleteItemOutput(scope.$index, dataForm.mmItemOutputList)" |
| | | type="text" |
| | | size="small"> |
| | | 删除 |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <el-divider content-position="left" v-if="dataForm.itemtypename === 'NormalItem'">模型设置参数 |
| | | </el-divider> |
| | | <el-table |
| | | v-if="dataForm.itemtypename === 'NormalItem'" |
| | | :data="dataForm.mmModelArithSettingsList" |
| | | border |
| | | style="width: 100%; margin-top: 5px;"> |
| | | <el-table-column prop="key" label="键" align="center"/> |
| | | <el-table-column prop="name" label="名称" align="center"/> |
| | | <el-table-column prop="valuetype" label="类型" align="center"/> |
| | | <el-table-column prop="key" label="键" align="center" min-width="150"/> |
| | | <el-table-column prop="name" label="名称" align="center" min-width="150"/> |
| | | <el-table-column prop="valuetype" label="类型" align="center" min-width="150"/> |
| | | <el-table-column prop="" label="值" align="center" min-width="150"> |
| | | <template #default="scope"> |
| | | <el-input size="mini" v-model="scope.row.value" maxlength="256" |
| | |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <el-divider content-position="left" v-if="dataForm.itemtypename === 'NormalItem'">输入参数 |
| | | <el-divider content-position="left" v-if="dataForm.itemtypename === 'NormalItem'">模型输入参数 |
| | | </el-divider> |
| | | <el-table |
| | | v-if="dataForm.itemtypename === 'NormalItem'" |
| | |
| | | <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" |
| | |
| | | style="width:100%;hight:100%"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="" label="操作" width="140" align="center"> |
| | | <el-table-column prop="" label="操作" width="120" align="center"> |
| | | <template #default="scope"> |
| | | <el-button |
| | | @click="addRow(scope.$index, dataForm.mmModelParamList)" |
| | | type="text" |
| | | size="small"> |
| | | size="mini"> |
| | | 添加 |
| | | </el-button> |
| | | <el-button |
| | | @click="deleteRow(scope.$index, dataForm.mmModelParamList)" |
| | | type="text" |
| | | size="small"> |
| | | size="mini"> |
| | | 删除 |
| | | </el-button> |
| | | </template> |
| | |
| | | <el-option |
| | | v-for="(item, index) in predictItemList" |
| | | :key="index" |
| | | :label="item.name" |
| | | :value="item.code"/> |
| | | :label="item.itemname" |
| | | :value="item.itemno"/> |
| | | </el-select> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | label="运算符" |
| | | align="center"> |
| | | <template #default="scope"> |
| | | <el-select v-model="scope.row.operator" placeholder="请选择"> |
| | | <el-select v-model="scope.row.operator" placeholder="请选择" clearable> |
| | | <el-option |
| | | v-for="item in operatorList" |
| | | :key="item" |
| | |
| | | </template> |
| | | <script lang="ts" setup> |
| | | import {DICT_TYPE, getIntDictOptions, getStrDictOptions} from '@/utils/dict' |
| | | import * as MmPredictItem from '@/api/model/pre/predict' |
| | | import * as MmItemType from '@/api/model/pre/item' |
| | | import * as MmPredictItem from '@/api/model/pre/item' |
| | | import * as MmItemType from '@/api/model/pre/type' |
| | | import * as DmModule from '@/api/model/pre/dm' |
| | | import * as MmResultTable from '@/api/model/pre/result' |
| | | import * as ProjectApi from '@/api/model/mpk/project' |
| | | import * as DaPoint from '@/api/data/da/point' |
| | | import {useUpload} from '@/api/model/pre/predict' |
| | | import {useUpload} from '@/api/model/pre/item' |
| | | import * as ScheduleModelApi from '@/api/model/sche/model' |
| | | |
| | | const {uploadUrl, httpRequest} = useUpload() |
| | |
| | | const itemTypeList = ref([]) |
| | | const itemTypeMap = ref({}) |
| | | const moduleList = ref([]) |
| | | const resultstridList = ref([]) |
| | | const mpkProjectList = ref([]) |
| | | const pointNoList = ref([]) |
| | | const pointList = ref([]) |
| | |
| | | status: undefined, |
| | | categoryid: undefined |
| | | }, |
| | | mmItemOutput: { |
| | | id: undefined, |
| | | itemid: undefined, |
| | | pointid: undefined, |
| | | resulttableid: undefined, |
| | | tagname: undefined, |
| | | outputorder: undefined |
| | | }, |
| | | mmItemOutputList: [], |
| | | mmPredictModel: { |
| | | id: undefined, |
| | | modelno: undefined, |
| | |
| | | 'mmPredictItem.status': [{required: true, message: '是否启用不能为空', trigger: 'blur'}], |
| | | 'dmModuleItem.moduleid': [{required: true, message: '管网不能为空', trigger: 'blur'}], |
| | | 'dmModuleItem.itemorder': [{required: true, message: '排序不能为空', trigger: 'blur'}], |
| | | 'mmItemOutput.pointid': [{required: true, message: '数据点不能为空', trigger: 'blur'}], |
| | | |
| | | }) |
| | | const formRef = ref() // 表单 Ref |
| | |
| | | resetForm() |
| | | resetFields(dataForm.value) |
| | | setDefaultFields() |
| | | // 修改时,设置数据 |
| | | if (id) { |
| | | formLoading.value = true |
| | | try { |
| | | getInfo(id) |
| | | } finally { |
| | | /*formLoading.value = false*/ |
| | | } |
| | | } |
| | | |
| | | // 加载参数列表 |
| | | modelparamListMap.value = await ScheduleModelApi.getModelParamList() |
| | |
| | | if (!dataForm.value.id) { |
| | | dataForm.value.mmPredictItem.itemtypeid = itemTypeList.value[0].id |
| | | } |
| | | dataForm.value.itemtypename = itemTypeMap[dataForm.value.mmPredictItem.itemtypeid] |
| | | |
| | | // 获取管网列表 |
| | | moduleList.value = await DmModule.getModuleList() |
| | | |
| | | // 获取结果字符串列表 |
| | | resultstridList.value = await MmResultTable.getResultstridList() |
| | | |
| | | // 获取mpk项目列表 |
| | | mpkProjectList.value = await ProjectApi.list() |
| | | |
| | | // 获取normal列表 |
| | | predictItemList.value = await MmPredictItem.getMmPredictItemList({ |
| | | itemtypename: 'NormalItem' |
| | | }) |
| | | |
| | | // 获取数据点列表 |
| | | pointNoList.value = await DaPoint.getPointList(queryParams) |
| | | if (pointNoList.value.length > 0) { |
| | | pointList.value = [] |
| | | pointNoList.value.forEach(function (value) { |
| | | pointList.value.push(value) |
| | | pointMap[value.id] = value.pointname |
| | | pointMap[value.id] = value.pointName |
| | | }) |
| | | } |
| | | |
| | | // 修改时,设置数据 |
| | | if (id) { |
| | | formLoading.value = true |
| | | try { |
| | | getInfo(id) |
| | | } finally { |
| | | formLoading.value = false |
| | | } |
| | | } |
| | | formLoading.value = false |
| | | } |
| | | defineExpose({open}) // 提供 open 方法,用于打开弹窗 |
| | |
| | | if (!formRef) return |
| | | const valid = await formRef.value.validate() |
| | | if (!valid) return |
| | | |
| | | //校验模型输出 |
| | | if (dataForm.value.mmItemOutputList == undefined || dataForm.value.mmItemOutputList.length <= 0) { |
| | | message.error("模型输出不为空") |
| | | return |
| | | } |
| | | |
| | | let flag = false |
| | | dataForm.value.mmItemOutputList.forEach(e => { |
| | | if (e.resultstr == undefined || e.resultstr === '' || e.resultType == undefined || e.resultType === '' || e.pointid == undefined || e.pointid === '' || (e.resultType === 2 && (e.resultIndex == undefined || e.resultIndex === ''))) { |
| | | message.error("模型输出数据异常") |
| | | flag = true |
| | | } |
| | | }) |
| | | if (flag) return |
| | | |
| | | // 提交请求 |
| | | formLoading.value = true |
| | | try { |
| | |
| | | |
| | | const getInfo = async (id) => { |
| | | dataForm.value = await MmPredictItem.getMmPredictItem(id) |
| | | dataForm.value.itemtypename = itemTypeMap[dataForm.value.mmPredictItem.itemtypeid] |
| | | expressionList.value = [] |
| | | if (dataForm.value.mmPredictMergeItem && dataForm.value.mmPredictMergeItem.expression) { |
| | | let expression = dataForm.value.mmPredictMergeItem.expression |
| | |
| | | dataForm.value.itemtypename = itemTypeMap[value] |
| | | } |
| | | |
| | | function changeModelparamtype(value, row) { |
| | | function changeModelparamtype(row) { |
| | | row.modelparamid = '' |
| | | } |
| | | |
| | | function changeOutputPoint(value) { |
| | | dataForm.value.mmItemOutput.tagname = pointMap[value] |
| | | function changeOutputPoint(value, row) { |
| | | row.tagname = pointMap[value] |
| | | } |
| | | |
| | | function deleteExpressionRow(index, rows) { |
| | |
| | | orderRow(rows) |
| | | } |
| | | |
| | | function addItemOutput(list) { |
| | | list.push({}) |
| | | orderItemOutput(list) |
| | | } |
| | | |
| | | function deleteItemOutput(index: string, rows) { |
| | | if (!rows || rows.length === 1) { |
| | | message.error('不能全部删除!') |
| | | return |
| | | } |
| | | rows.splice(index, 1) |
| | | orderItemOutput(rows) |
| | | } |
| | | |
| | | function orderItemOutput(list) { |
| | | list.sort((a, b) => a.outputorder - b.outputorder); |
| | | let outputorder = 1 |
| | | list.forEach(function (value) { |
| | | value.outputorder = outputorder |
| | | outputorder++ |
| | | }) |
| | | } |
| | | |
| | | function resultTypeChange(value, row) { |
| | | if (value === 1) { |
| | | row.resultIndex = undefined |
| | | } else if (value === 2) { |
| | | row.resultIndex = 0 |
| | | } |
| | | } |
| | | |
| | | function orderRow(rows) { |
| | | let modelparamorder = 0 |
| | | let modelparamportorder = 0 |
| | |
| | | dataForm.value.mmPredictModel.trainsamplength = 60 |
| | | dataForm.value.mmPredictModel.isonlinetrain = 0 |
| | | dataForm.value.mmPredictModel.status = 1 |
| | | dataForm.value.mmItemOutput.outputorder = 1 |
| | | dataForm.value.mmItemOutput.resulttableid = '3cc2b483-3a01-40f7-a419-0c260210d8eb' |
| | | dataForm.value.mmItemOutputList = [] |
| | | expressionList.value = [{ |
| | | point: '', |
| | | operator: '' |
| | |
| | | status: 1, |
| | | categoryid: '' |
| | | }, |
| | | mmItemOutput: { |
| | | id: '', |
| | | itemid: '', |
| | | pointid: '', |
| | | resulttableid: '3cc2b483-3a01-40f7-a419-0c260210d8eb', |
| | | tagname: '', |
| | | outputorder: 1 |
| | | }, |
| | | mmItemOutputList: [], |
| | | mmPredictModel: { |
| | | id: '', |
| | | modelno: '', |
| | |
| | | <!-- 列表 --> |
| | | <ContentWrap> |
| | | <el-table v-loading="loading" :data="list"> |
| | | <el-table-column label="编号" align="center" prop="itemno"/> |
| | | <el-table-column label="编号" align="center" min-width="150" prop="itemno"/> |
| | | <el-table-column label="预测项名" header-align="center" align="left" min-width="200" prop="itemname"/> |
| | | <el-table-column label="类型名称" align="center" prop="itemtypename"> |
| | | <el-table-column label="类型名称" align="center" min-width="120" prop="itemtypename"> |
| | | <template #default="scope"> |
| | | <el-tag v-if="scope.row.itemtypename === 'NormalItem'" size="small" type="success">{{scope.row.itemtypename}}</el-tag> |
| | | <el-tag v-else size="small" type="primary">{{scope.row.itemtypename}}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="预测长度" align="center" prop="predictlength"/> |
| | | <el-table-column label="预测长度(min)" align="center" prop="predictlength"/> |
| | | <el-table-column label="粒度" align="center" prop="granularity"> |
| | | <template #default="scope"> |
| | | <dict-tag :type="DICT_TYPE.TIME_GRANULARITY" :value="scope.row.granularity" /> |
| | | <dict-tag :type="DICT_TYPE.PRED_GRANULARITY" :value="scope.row.granularity" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="是否融合" align="center" prop="isfuse"> |
| | |
| | | <dict-tag :type="DICT_TYPE.COM_IS_INT" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="数据点名称" align="center" prop="tagname"/> |
| | | <el-table-column label="存放表" align="center" prop="tablename"/> |
| | | <el-table-column label="操作" align="center" min-width="110" fixed="right"> |
| | | <el-table-column label="运行时间" min-width="150" align="center" prop="lastTime"/> |
| | | <el-table-column label="运行状态" align="center" prop="runStatus"> |
| | | <template #default="scope"> |
| | | <dict-tag :type="DICT_TYPE.ITEM_RUN_STATUS" :value="scope.row.runStatus" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="运行耗时(s)" align="center" prop="duration"/> |
| | | <el-table-column label="操作" align="center" min-width="120" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | size="mini" |
| | | @click="openForm('update', scope.row.id, scope.row.itemtypename)" |
| | | v-hasPermi="['model:pre-item:update']" |
| | | > |
| | | 编辑 |
| | | </el-button> |
| | | <el-button link size="mini" type="primary" @click="chartHandle(scope.row)">数据</el-button> |
| | | <el-button |
| | | link |
| | | type="danger" |
| | | size="mini" |
| | | @click="handleDelete(scope.row.id)" |
| | | v-hasPermi="['model:pre-item:delete']" |
| | | > |
| | |
| | | <!-- 表单弹窗:添加/修改 --> |
| | | <MmPredictItemForm ref="formRef" @success="getList"/> |
| | | |
| | | <!-- 表单弹窗:数据 --> |
| | | <MmPredictItemChart ref="chartView" @success="getList"/> |
| | | |
| | | </template> |
| | | <script lang="ts" setup> |
| | | import MmPredictItemForm from './MmPredictItemForm.vue' |
| | | import * as MmPredictItem from '@/api/model/pre/predict' |
| | | import MmPredictItemChart from './MmPredictItemChart.vue' |
| | | import * as MmPredictItem from '@/api/model/pre/item' |
| | | import {DICT_TYPE} from "@/utils/dict"; |
| | | |
| | | defineOptions({name: 'DataMmPredictItem'}) |
| | |
| | | handleQuery() |
| | | } |
| | | |
| | | /** 查看数据操作 */ |
| | | const chartView = ref() |
| | | const chartHandle = (raw: object) => { |
| | | chartView.value.open(raw) |
| | | } |
| | | |
| | | /** 添加/修改操作 */ |
| | | const formRef = ref() |
| | | const openForm = (type: string, id?: number, itemtypename?: string) => { |
| | |
| | | </Dialog> |
| | | </template> |
| | | <script lang="ts" setup> |
| | | import * as MmItemType from '@/api/model/pre/item' |
| | | import * as MmItemType from '@/api/model/pre/type' |
| | | |
| | | defineOptions({name: 'DataMmItemTypeForm'}) |
| | | |
| | |
| | | </template> |
| | | <script lang="ts" setup> |
| | | import MmItemTypeForm from './ItemTypeForm.vue' |
| | | import * as MmItemType from '@/api/model/pre/item' |
| | | import * as MmItemType from '@/api/model/pre/type' |
| | | |
| | | defineOptions({name: 'DataMmItemType'}) |
| | | |
文件名从 src/views/model/swagger/index.vue 修改 |
| | |
| | | <script lang="ts" setup> |
| | | import * as ConfigApi from '@/api/infra/config' |
| | | |
| | | defineOptions({ name: 'ModelSwagger' }) |
| | | defineOptions({ name: 'ModelWiki' }) |
| | | |
| | | const loading = ref(true) // 是否加载中 |
| | | const src = ref(import.meta.env.VITE_BASE_URL + '/doc.html') |
| | |
| | | /** 初始化 */ |
| | | onMounted(async () => { |
| | | try { |
| | | const data = await ConfigApi.getConfigKey('model.swagger') |
| | | const data = await ConfigApi.getConfigKey('model.wiki') |
| | | if (data && data.length > 0) { |
| | | src.value = data |
| | | } |
| | |
| | | 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 |
| | | readonly VITE_OUT_DIR: string |
| | | readonly VITE_STATIC_DIR: string |
| | | } |
| | | |
| | | declare global { |