fix: merge
This commit is contained in:
commit
d488752e20
|
@ -8,9 +8,12 @@
|
||||||
:breadcrumb="{ routes: breadcrumb }"
|
:breadcrumb="{ routes: breadcrumb }"
|
||||||
>
|
>
|
||||||
<template #breadcrumbRender="slotProps">
|
<template #breadcrumbRender="slotProps">
|
||||||
<a v-if="slotProps.route.index !== 0">{{
|
<a
|
||||||
slotProps.route.breadcrumbName
|
v-if="slotProps.route.index !== 0 && !slotProps.route.isLast"
|
||||||
}}</a>
|
@click='() => jumpPage(slotProps.route.path)'
|
||||||
|
>
|
||||||
|
{{ slotProps.route.breadcrumbName }}
|
||||||
|
</a>
|
||||||
<span v-else >{{ slotProps.route.breadcrumbName }}</span>
|
<span v-else >{{ slotProps.route.breadcrumbName }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #rightContentRender>
|
<template #rightContentRender>
|
||||||
|
@ -32,6 +35,7 @@ import Notice from './components/Notice.vue';
|
||||||
import DefaultSetting from '../../../config/config';
|
import DefaultSetting from '../../../config/config';
|
||||||
import { useMenuStore } from '@/store/menu';
|
import { useMenuStore } from '@/store/menu';
|
||||||
import { clearMenuItem } from 'jetlinks-ui-components/es/ProLayout/util';
|
import { clearMenuItem } from 'jetlinks-ui-components/es/ProLayout/util';
|
||||||
|
import { AccountMenu } from '@/router/menu'
|
||||||
|
|
||||||
type StateType = {
|
type StateType = {
|
||||||
collapsed: boolean;
|
collapsed: boolean;
|
||||||
|
@ -50,7 +54,8 @@ const layoutConf = reactive({
|
||||||
siderWidth: DefaultSetting.layout.siderWidth,
|
siderWidth: DefaultSetting.layout.siderWidth,
|
||||||
logo: DefaultSetting.layout.logo,
|
logo: DefaultSetting.layout.logo,
|
||||||
title: DefaultSetting.layout.title,
|
title: DefaultSetting.layout.title,
|
||||||
menuData: clearMenuItem(menu.siderMenus),
|
menuData: [...clearMenuItem(menu.siderMenus), AccountMenu],
|
||||||
|
// menuData: menu.siderMenus,
|
||||||
splitMenus: true,
|
splitMenus: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -61,26 +66,49 @@ const state = reactive<StateType>({
|
||||||
selectedKeys: [],
|
selectedKeys: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const findRouteMeta = (code: string) => {
|
||||||
|
let meta = []
|
||||||
|
let menuItem: any = menu.menus[code]
|
||||||
|
while (menuItem) {
|
||||||
|
meta.unshift(menuItem)
|
||||||
|
if (menuItem.parentName) {
|
||||||
|
menuItem = menu.menus[menuItem.parentName]
|
||||||
|
} else {
|
||||||
|
menuItem = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return meta
|
||||||
|
}
|
||||||
|
|
||||||
|
const jumpPage = (path: string) => {
|
||||||
|
console.log(path)
|
||||||
|
router.push(path)
|
||||||
|
}
|
||||||
|
|
||||||
const breadcrumb = computed(() =>
|
const breadcrumb = computed(() =>
|
||||||
router.currentRoute.value.matched.concat().map((item, index) => {
|
{
|
||||||
|
const paths = router.currentRoute.value.name as string
|
||||||
|
const metas = findRouteMeta(paths)
|
||||||
|
return metas.map((item, index) => {
|
||||||
return {
|
return {
|
||||||
index,
|
index,
|
||||||
|
isLast: index === (metas.length - 1),
|
||||||
path: item.path,
|
path: item.path,
|
||||||
breadcrumbName: item.meta.title || '',
|
breadcrumbName: item.title || '',
|
||||||
};
|
};
|
||||||
}),
|
})
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
if (router.currentRoute) {
|
if (router.currentRoute) {
|
||||||
const matched = router.currentRoute.value.matched.concat();
|
const paths = router.currentRoute.value.name as string
|
||||||
state.selectedKeys = matched.map((r) => r.path);
|
if (paths) {
|
||||||
state.openKeys = matched
|
const _metas = findRouteMeta(paths)
|
||||||
.filter((r) => r.path !== router.currentRoute.value.path)
|
state.selectedKeys = _metas.map(item => item.path)
|
||||||
.map((r) => r.path);
|
state.openKeys = _metas.filter((r) => r !== router.currentRoute.value.path).map(item => item.path)
|
||||||
console.log(state.selectedKeys);
|
}
|
||||||
}
|
}
|
||||||
// TODO 获取当前路由中参数,用于控制pure
|
|
||||||
});
|
});
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
|
|
|
@ -5,6 +5,7 @@ export const AccountMenu = {
|
||||||
component: () => import('@/components/Layout/BasicLayoutPage.vue'),
|
component: () => import('@/components/Layout/BasicLayoutPage.vue'),
|
||||||
redirect: '/account/center',
|
redirect: '/account/center',
|
||||||
name: 'account',
|
name: 'account',
|
||||||
|
code: 'account',
|
||||||
meta: {
|
meta: {
|
||||||
title: '个人中心',
|
title: '个人中心',
|
||||||
icon: '',
|
icon: '',
|
||||||
|
@ -14,6 +15,7 @@ export const AccountMenu = {
|
||||||
{
|
{
|
||||||
path: '/account/center',
|
path: '/account/center',
|
||||||
name: 'account/center',
|
name: 'account/center',
|
||||||
|
code: 'account/center',
|
||||||
meta: {
|
meta: {
|
||||||
title: '基本设置',
|
title: '基本设置',
|
||||||
icon: '',
|
icon: '',
|
||||||
|
@ -24,6 +26,7 @@ export const AccountMenu = {
|
||||||
{
|
{
|
||||||
path: '/account/NotificationSubscription',
|
path: '/account/NotificationSubscription',
|
||||||
name: 'account/NotificationSubscription',
|
name: 'account/NotificationSubscription',
|
||||||
|
code: 'account/NotificationSubscription',
|
||||||
meta: {
|
meta: {
|
||||||
title: '通知订阅',
|
title: '通知订阅',
|
||||||
icon: '',
|
icon: '',
|
||||||
|
@ -34,6 +37,7 @@ export const AccountMenu = {
|
||||||
{
|
{
|
||||||
path: '/account/NotificationRecord',
|
path: '/account/NotificationRecord',
|
||||||
name: 'account/NotificationRecord',
|
name: 'account/NotificationRecord',
|
||||||
|
code: 'account/NotificationRecord',
|
||||||
meta: {
|
meta: {
|
||||||
title: '通知记录',
|
title: '通知记录',
|
||||||
icon: '',
|
icon: '',
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { queryOwnThree } from '@/api/system/menu'
|
import { queryOwnThree } from '@/api/system/menu'
|
||||||
import { filterAsnycRouter, MenuItem } from '@/utils/menu'
|
import { filterAsyncRouter, findCodeRoute, MenuItem } from '@/utils/menu'
|
||||||
import { isArray } from 'lodash-es'
|
import { isArray } from 'lodash-es'
|
||||||
import { usePermissionStore } from './permission'
|
import { usePermissionStore } from './permission'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
|
@ -33,6 +33,8 @@ type MenuStateType = {
|
||||||
menus: {
|
menus: {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
buttons?: string[]
|
buttons?: string[]
|
||||||
|
title: string
|
||||||
|
parentName: string
|
||||||
path: string
|
path: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,24 +100,15 @@ export const useMenuStore = defineStore({
|
||||||
if (resp.success) {
|
if (resp.success) {
|
||||||
const permission = usePermissionStore()
|
const permission = usePermissionStore()
|
||||||
permission.permissions = {}
|
permission.permissions = {}
|
||||||
const { menusData, silderMenus } = filterAsnycRouter(resp.result)
|
const { menusData, silderMenus } = filterAsyncRouter(resp.result)
|
||||||
this.menus = {}
|
this.menus = findCodeRoute([...resp.result, AccountMenu])
|
||||||
const handleMenuItem = (menu: any) => {
|
Object.keys(this.menus).forEach((item) => {
|
||||||
if (isArray(menu)) {
|
const _item = this.menus[item]
|
||||||
menu.forEach(menuItem => {
|
if (_item.buttons?.length) {
|
||||||
this.menus[menuItem.name] = {
|
permission.permissions[item] = _item.buttons
|
||||||
path: menuItem.path,
|
|
||||||
buttons: menuItem.meta.buttons
|
|
||||||
}
|
|
||||||
permission.permissions[menuItem.name] = menuItem.meta.buttons
|
|
||||||
if (menuItem.children && menuItem.children.length) {
|
|
||||||
handleMenuItem(menuItem.children)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleMenuItem(menusData)
|
|
||||||
menusData.push({
|
menusData.push({
|
||||||
path: '/',
|
path: '/',
|
||||||
redirect: menusData[0]?.path,
|
redirect: menusData[0]?.path,
|
||||||
|
@ -124,10 +117,7 @@ export const useMenuStore = defineStore({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
menusData.push(AccountMenu)
|
menusData.push(AccountMenu)
|
||||||
silderMenus.push(AccountMenu)
|
|
||||||
this.siderMenus = silderMenus
|
this.siderMenus = silderMenus
|
||||||
console.log('menusData', menusData)
|
|
||||||
console.log('silderMenus', silderMenus)
|
|
||||||
res(menusData)
|
res(menusData)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,11 +3,12 @@ import { defineStore } from "pinia";
|
||||||
export const usePermissionStore = defineStore({
|
export const usePermissionStore = defineStore({
|
||||||
id: 'permission',
|
id: 'permission',
|
||||||
state: () => ({
|
state: () => ({
|
||||||
permissions: {} as {[key: string]: string},
|
permissions: {} as {[key: string]: string[]},
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
check(state) {
|
check(state) {
|
||||||
return (permissionCode: string) => {
|
return (permissionCode: string) => {
|
||||||
|
|
||||||
if (!permissionCode) {
|
if (!permissionCode) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -16,6 +17,7 @@ export const usePermissionStore = defineStore({
|
||||||
}
|
}
|
||||||
const code = permissionCode.split(":")[0]
|
const code = permissionCode.split(":")[0]
|
||||||
const value = permissionCode.split(":")[1]
|
const value = permissionCode.split(":")[1]
|
||||||
|
|
||||||
const _buttonArray = state.permissions[code]
|
const _buttonArray = state.permissions[code]
|
||||||
if (!_buttonArray) {
|
if (!_buttonArray) {
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -151,7 +151,6 @@ const extraRouteObj = {
|
||||||
const resolveComponent = (name: any) => {
|
const resolveComponent = (name: any) => {
|
||||||
const importPage = pagesComponent[`../views/${name}/index.vue`];
|
const importPage = pagesComponent[`../views/${name}/index.vue`];
|
||||||
if (!importPage) {
|
if (!importPage) {
|
||||||
console.warn(`Unknown page ${name}. Is it located under Pages with a .vue extension?`)
|
|
||||||
return undefined
|
return undefined
|
||||||
} else {
|
} else {
|
||||||
const res = () => importPage()
|
const res = () => importPage()
|
||||||
|
@ -201,7 +200,52 @@ const findDetailRoutes = (routes: any[]): any[] => {
|
||||||
return newRoutes
|
return newRoutes
|
||||||
}
|
}
|
||||||
|
|
||||||
export function filterAsnycRouter(asyncRouterMap: any, parentCode = '', level = 1): { menusData: any, silderMenus: any } {
|
export const findCodeRoute = (asyncRouterMap: any[]) => {
|
||||||
|
const routeMeta = {}
|
||||||
|
|
||||||
|
function findChildren (data: any[], code: string = '') {
|
||||||
|
data.forEach(route => {
|
||||||
|
routeMeta[route.code] = {
|
||||||
|
path: route.url || route.path,
|
||||||
|
title: route.meta?.title || route.name,
|
||||||
|
parentName: code,
|
||||||
|
buttons: route.buttons?.map((b: any) => b.id) || []
|
||||||
|
}
|
||||||
|
const detail = findDetailRouteItem(route.code, route.url)
|
||||||
|
if (detail) {
|
||||||
|
routeMeta[(detail as MenuItem).code] = {
|
||||||
|
path: detail.url,
|
||||||
|
title: detail.name,
|
||||||
|
parentName: route.code,
|
||||||
|
buttons: detail.buttons?.map((b: any) => b.id) || []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const otherRoutes = extraRouteObj[route.code]
|
||||||
|
if (otherRoutes) {
|
||||||
|
otherRoutes.children.map((item: any) => {
|
||||||
|
const _code = `${route.code}/${item.code}`
|
||||||
|
routeMeta[_code] = {
|
||||||
|
path: `${route.url}/${item.code}`,
|
||||||
|
title: item.name,
|
||||||
|
parentName: route.code,
|
||||||
|
buttons: item.buttons?.map((b: any) => b.id) || []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.children) {
|
||||||
|
findChildren(route.children, route.code)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
findChildren(asyncRouterMap)
|
||||||
|
|
||||||
|
return routeMeta
|
||||||
|
}
|
||||||
|
|
||||||
|
export function filterAsyncRouter(asyncRouterMap: any, parentCode = '', level = 1): { menusData: any, silderMenus: any} {
|
||||||
const _asyncRouterMap = cloneDeep(asyncRouterMap)
|
const _asyncRouterMap = cloneDeep(asyncRouterMap)
|
||||||
const menusData: any[] = []
|
const menusData: any[] = []
|
||||||
const silderMenus: any[] = []
|
const silderMenus: any[] = []
|
||||||
|
@ -224,7 +268,7 @@ export function filterAsnycRouter(asyncRouterMap: any, parentCode = '', level =
|
||||||
route.children = findDetailRoutes(route.children)
|
route.children = findDetailRoutes(route.children)
|
||||||
if (route.children && route.children.length) {
|
if (route.children && route.children.length) {
|
||||||
// TODO 查看是否具有详情页
|
// TODO 查看是否具有详情页
|
||||||
const { menusData: _menusData, silderMenus: _silderMenus } = filterAsnycRouter(route.children, `${parentCode}/${route.code}`, level + 1)
|
const { menusData: _menusData, silderMenus: _silderMenus } = filterAsyncRouter(route.children, `${parentCode}/${route.code}`, level + 1)
|
||||||
_route.children = _menusData
|
_route.children = _menusData
|
||||||
silder.children = _silderMenus
|
silder.children = _silderMenus
|
||||||
const showChildren = _route.children.some((r: any) => !r.meta.hideInMenu)
|
const showChildren = _route.children.some((r: any) => !r.meta.hideInMenu)
|
||||||
|
@ -251,6 +295,6 @@ export function filterAsnycRouter(asyncRouterMap: any, parentCode = '', level =
|
||||||
})
|
})
|
||||||
return {
|
return {
|
||||||
menusData,
|
menusData,
|
||||||
silderMenus
|
silderMenus,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -95,6 +95,7 @@ import { queryFlow, list } from '@/api/iot-card/home';
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import { useMenuStore } from '@/store/menu';
|
import { useMenuStore } from '@/store/menu';
|
||||||
import { usePermissionStore } from '@/store/permission';
|
import { usePermissionStore } from '@/store/permission';
|
||||||
|
import { message } from 'jetlinks-ui-components'
|
||||||
|
|
||||||
const { proxy } = <any>getCurrentInstance();
|
const { proxy } = <any>getCurrentInstance();
|
||||||
|
|
||||||
|
@ -178,11 +179,10 @@ const pieChartData = ref<any[]>([
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const jumpPage = (data: GuideItemProps) => {
|
const jumpPage = (data: GuideItemProps) => {
|
||||||
// if (data.url && data.auth) {
|
if (!data.auth){
|
||||||
// router.push({ path: `${data.url}`, ...data.param });
|
message.warning('暂无权限,请联系管理员');
|
||||||
// } else {
|
return
|
||||||
// message.warning('暂无权限,请联系管理员');
|
}
|
||||||
// }
|
|
||||||
if (data.key === 'EQUIPMENT') {
|
if (data.key === 'EQUIPMENT') {
|
||||||
menuStory.jumpPage(data.url, { id: 'add' });
|
menuStory.jumpPage(data.url, { id: 'add' });
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -9,32 +9,50 @@
|
||||||
:confirmLoading="btnLoading"
|
:confirmLoading="btnLoading"
|
||||||
width="660px"
|
width="660px"
|
||||||
>
|
>
|
||||||
<j-form layout="vertical">
|
<j-form ref="formRef" :model="formData" layout="vertical">
|
||||||
<j-form-item label="产品名称" v-bind="validateInfos.name">
|
<j-form-item
|
||||||
|
label="产品名称"
|
||||||
|
name="name"
|
||||||
|
:rules="{ required: true, message: '请输入产品名称' }"
|
||||||
|
>
|
||||||
<j-input
|
<j-input
|
||||||
v-model:value="formData.name"
|
v-model:value="formData.name"
|
||||||
placeholder="请输入名称"
|
placeholder="请输入名称"
|
||||||
/>
|
/>
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
<template v-if="channel === 'gb28181-2016' && formData.accessId">
|
<template v-for="(item, index) in extendFormItem" :key="index">
|
||||||
<j-form-item
|
<j-form-item
|
||||||
label="接入密码"
|
:name="item.name"
|
||||||
v-bind="validateInfos['configuration.access_pwd']"
|
:label="item.label"
|
||||||
|
:rules="{
|
||||||
|
required: item.required,
|
||||||
|
message: item.message,
|
||||||
|
trigger: 'change',
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<j-input-password
|
|
||||||
v-model:value="formData.configuration.access_pwd"
|
|
||||||
placeholder="请输入接入密码"
|
|
||||||
/>
|
|
||||||
</j-form-item>
|
|
||||||
<j-form-item label="流传输模式">
|
|
||||||
<j-select
|
<j-select
|
||||||
v-model:value="formData.configuration.stream_mode"
|
v-if="item.type === 'enum'"
|
||||||
placeholder="请选择流传输模式"
|
v-model:value="formData[item.name[0]][item.name[1]]"
|
||||||
:options="streamMode"
|
:options="item.options"
|
||||||
|
:placeholder="item.message"
|
||||||
|
/>
|
||||||
|
<j-input-password
|
||||||
|
v-else-if="item.type === 'password'"
|
||||||
|
v-model:value="formData[item.name[0]][item.name[1]]"
|
||||||
|
:placeholder="item.message"
|
||||||
|
/>
|
||||||
|
<j-input
|
||||||
|
v-else
|
||||||
|
v-model:value="formData[item.name[0]][item.name[1]]"
|
||||||
|
:placeholder="item.message"
|
||||||
/>
|
/>
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
</template>
|
</template>
|
||||||
<j-form-item label="接入网关" v-bind="validateInfos.accessId">
|
<j-form-item
|
||||||
|
label="接入网关"
|
||||||
|
name="accessId"
|
||||||
|
:rules="{ required: true, message: '请选择接入网关' }"
|
||||||
|
>
|
||||||
<div class="gateway-box">
|
<div class="gateway-box">
|
||||||
<div v-if="!gatewayList.length">
|
<div v-if="!gatewayList.length">
|
||||||
暂无数据,请先
|
暂无数据,请先
|
||||||
|
@ -119,16 +137,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Form, message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import { PropType } from 'vue';
|
|
||||||
import { streamMode } from '@/views/media/Device/const';
|
|
||||||
import DeviceApi from '@/api/media/device';
|
import DeviceApi from '@/api/media/device';
|
||||||
import { getImage } from '@/utils/comm';
|
import { getImage } from '@/utils/comm';
|
||||||
import { gatewayType } from '@/views/media/Device/typings';
|
import { gatewayType } from '@/views/media/Device/typings';
|
||||||
import { providerType } from '../const';
|
import { providerType } from '../const';
|
||||||
|
|
||||||
const useForm = Form.useForm;
|
|
||||||
|
|
||||||
type Emits = {
|
type Emits = {
|
||||||
(e: 'update:visible', data: boolean): void;
|
(e: 'update:visible', data: boolean): void;
|
||||||
(e: 'update:productId', data: string): void;
|
(e: 'update:productId', data: string): void;
|
||||||
|
@ -168,6 +182,7 @@ const getGatewayList = async () => {
|
||||||
* @param e
|
* @param e
|
||||||
*/
|
*/
|
||||||
const _selectedRowKeys = ref<string[]>([]);
|
const _selectedRowKeys = ref<string[]>([]);
|
||||||
|
const extendFormItem = ref<any[]>();
|
||||||
const handleClick = async (e: any) => {
|
const handleClick = async (e: any) => {
|
||||||
_selectedRowKeys.value = [e.id];
|
_selectedRowKeys.value = [e.id];
|
||||||
formData.value.accessId = e.id;
|
formData.value.accessId = e.id;
|
||||||
|
@ -181,7 +196,22 @@ const handleClick = async (e: any) => {
|
||||||
e.protocol,
|
e.protocol,
|
||||||
e.transport,
|
e.transport,
|
||||||
);
|
);
|
||||||
console.log('result: ', result);
|
|
||||||
|
extendFormItem.value = result.properties.map((item: any) => ({
|
||||||
|
name: ['configuration', item.property],
|
||||||
|
label: item.name,
|
||||||
|
type: item.type?.type,
|
||||||
|
value: item.type.expands?.defaultValue,
|
||||||
|
options: item.type.elements?.map((e: any) => ({
|
||||||
|
label: e.text,
|
||||||
|
value: e.value,
|
||||||
|
})),
|
||||||
|
required: !!item.type.expands?.required,
|
||||||
|
message:
|
||||||
|
item.type?.type === 'enum'
|
||||||
|
? `请选择${item.name}`
|
||||||
|
: `请输入${item.name}`,
|
||||||
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
@ -189,10 +219,6 @@ watch(
|
||||||
(val) => {
|
(val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
getGatewayList();
|
getGatewayList();
|
||||||
|
|
||||||
formRules.value['configuration.access_pwd'][0].required =
|
|
||||||
props.channel === 'gb28181-2016';
|
|
||||||
validate();
|
|
||||||
} else {
|
} else {
|
||||||
emit('close');
|
emit('close');
|
||||||
}
|
}
|
||||||
|
@ -200,6 +226,7 @@ watch(
|
||||||
);
|
);
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
|
const formRef = ref();
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
accessId: '',
|
accessId: '',
|
||||||
accessName: '',
|
accessName: '',
|
||||||
|
@ -215,25 +242,13 @@ const formData = ref({
|
||||||
transportProtocol: '',
|
transportProtocol: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
// 验证规则
|
|
||||||
const formRules = ref({
|
|
||||||
name: [{ required: true, message: '请输入产品名称' }],
|
|
||||||
'configuration.access_pwd': [{ required: true, message: '请输入接入密码' }],
|
|
||||||
accessId: [{ required: true, message: '请选择接入网关' }],
|
|
||||||
});
|
|
||||||
|
|
||||||
const { resetFields, validate, validateInfos, clearValidate } = useForm(
|
|
||||||
formData.value,
|
|
||||||
formRules.value,
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提交
|
* 提交
|
||||||
*/
|
*/
|
||||||
const btnLoading = ref(false);
|
const btnLoading = ref(false);
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
// console.log('formData.value: ', formData.value);
|
formRef.value
|
||||||
validate()
|
?.validate()
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
btnLoading.value = true;
|
btnLoading.value = true;
|
||||||
const res = await DeviceApi.saveProduct(formData.value);
|
const res = await DeviceApi.saveProduct(formData.value);
|
||||||
|
@ -249,14 +264,14 @@ const handleOk = () => {
|
||||||
}
|
}
|
||||||
btnLoading.value = false;
|
btnLoading.value = false;
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err: any) => {
|
||||||
console.log('err: ', err);
|
console.log('err: ', err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
_vis.value = false;
|
_vis.value = false;
|
||||||
resetFields();
|
formRef.value.resetFields();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -50,10 +50,19 @@
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<j-form-item
|
<j-form-item
|
||||||
:name="['templateDetailTable', index, 'value']"
|
:name="['templateDetailTable', index, 'value']"
|
||||||
:rules="{
|
:rules="[
|
||||||
|
{
|
||||||
required: record.required,
|
required: record.required,
|
||||||
message: '该字段为必填字段',
|
message: '该字段为必填字段',
|
||||||
}"
|
},
|
||||||
|
...record.otherRules,
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<template
|
||||||
|
v-if="
|
||||||
|
data.type === 'dingTalk' ||
|
||||||
|
data.type === 'weixin'
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<ToUser
|
<ToUser
|
||||||
v-if="record.type === 'user'"
|
v-if="record.type === 'user'"
|
||||||
|
@ -78,6 +87,13 @@
|
||||||
v-model:modelValue="record.value"
|
v-model:modelValue="record.value"
|
||||||
:itemType="record.type"
|
:itemType="record.type"
|
||||||
/>
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<ValueItem
|
||||||
|
v-model:modelValue="record.value"
|
||||||
|
:itemType="record.type"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
@ -100,6 +116,8 @@ import { message } from 'ant-design-vue';
|
||||||
import ToUser from '../Detail/components/ToUser.vue';
|
import ToUser from '../Detail/components/ToUser.vue';
|
||||||
import ToOrg from '../Detail/components/ToOrg.vue';
|
import ToOrg from '../Detail/components/ToOrg.vue';
|
||||||
import ToTag from '../Detail/components/ToTag.vue';
|
import ToTag from '../Detail/components/ToTag.vue';
|
||||||
|
import type { Rule } from 'ant-design-vue/es/form';
|
||||||
|
import { phoneRegEx } from '@/utils/validate';
|
||||||
|
|
||||||
type Emits = {
|
type Emits = {
|
||||||
(e: 'update:visible', data: boolean): void;
|
(e: 'update:visible', data: boolean): void;
|
||||||
|
@ -156,6 +174,26 @@ const getTemplateDetail = async () => {
|
||||||
...m,
|
...m,
|
||||||
type: m.expands ? m.expands.businessType : m.type,
|
type: m.expands ? m.expands.businessType : m.type,
|
||||||
value: undefined,
|
value: undefined,
|
||||||
|
// 电话字段校验
|
||||||
|
otherRules:
|
||||||
|
m.id === 'calledNumber'
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
max: 64,
|
||||||
|
message: '最多可输入64个字符',
|
||||||
|
trigger: 'change',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
trigger: 'change',
|
||||||
|
validator(_rule: Rule, value: string) {
|
||||||
|
if (!value) return Promise.resolve();
|
||||||
|
if (!phoneRegEx(value))
|
||||||
|
return Promise.reject('请输入有效号码');
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: '',
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<span>
|
<span>
|
||||||
AgentID
|
AgentId
|
||||||
<j-tooltip title="应用唯一标识">
|
<j-tooltip title="应用唯一标识">
|
||||||
<AIcon
|
<AIcon
|
||||||
type="QuestionCircleOutlined"
|
type="QuestionCircleOutlined"
|
||||||
|
@ -98,7 +98,7 @@
|
||||||
v-model:value="
|
v-model:value="
|
||||||
formData.template.agentId
|
formData.template.agentId
|
||||||
"
|
"
|
||||||
placeholder="请输入AppSecret"
|
placeholder="请输入AgentId"
|
||||||
/>
|
/>
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
<j-row :gutter="10">
|
<j-row :gutter="10">
|
||||||
|
@ -271,7 +271,7 @@
|
||||||
</template>
|
</template>
|
||||||
<j-input
|
<j-input
|
||||||
v-model:value="formData.template.agentId"
|
v-model:value="formData.template.agentId"
|
||||||
placeholder="请输入agentId"
|
placeholder="请输入AgentId"
|
||||||
/>
|
/>
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
<j-row :gutter="10">
|
<j-row :gutter="10">
|
||||||
|
@ -664,7 +664,6 @@
|
||||||
<j-radio :value="false">自定义</j-radio>
|
<j-radio :value="false">自定义</j-radio>
|
||||||
</j-radio-group>
|
</j-radio-group>
|
||||||
<j-textarea
|
<j-textarea
|
||||||
v-model:value="formData.template.body"
|
|
||||||
placeholder="请求体中的数据来自于发送通知时指定的所有变量"
|
placeholder="请求体中的数据来自于发送通知时指定的所有变量"
|
||||||
v-if="formData.template.contextAsBody"
|
v-if="formData.template.contextAsBody"
|
||||||
disabled
|
disabled
|
||||||
|
@ -902,7 +901,10 @@ const formRules = ref({
|
||||||
provider: [{ required: true, message: '请选择类型' }],
|
provider: [{ required: true, message: '请选择类型' }],
|
||||||
configId: [{ required: true, message: '请选择绑定配置' }],
|
configId: [{ required: true, message: '请选择绑定配置' }],
|
||||||
// 钉钉
|
// 钉钉
|
||||||
'template.agentId': [{ required: true, message: '请输入agentId' }],
|
'template.agentId': [
|
||||||
|
{ required: true, message: '请输入AgentId' },
|
||||||
|
{ max: 64, message: '最多可输入64个字符', trigger: 'change' },
|
||||||
|
],
|
||||||
'template.messageType': [{ required: true, message: '请选择消息类型' }],
|
'template.messageType': [{ required: true, message: '请选择消息类型' }],
|
||||||
'template.markdown.title': [
|
'template.markdown.title': [
|
||||||
{ required: true, message: '请输入标题', trigger: 'change' },
|
{ required: true, message: '请输入标题', trigger: 'change' },
|
||||||
|
@ -914,7 +916,7 @@ const formRules = ref({
|
||||||
],
|
],
|
||||||
// 'template.url': [{ required: true, message: '请输入WebHook' }],
|
// 'template.url': [{ required: true, message: '请输入WebHook' }],
|
||||||
// 微信
|
// 微信
|
||||||
// 'template.agentId': [{ required: true, message: '请输入agentId' }],
|
// 'template.agentId': [{ required: true, message: '请输入AgentId' }],
|
||||||
// 邮件
|
// 邮件
|
||||||
'template.subject': [
|
'template.subject': [
|
||||||
{ required: true, message: '请输入标题' },
|
{ required: true, message: '请输入标题' },
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<a-form layout="vertical" :rules="rule" :model="form" ref="formRef">
|
<j-form layout="vertical" :rules="rule" :model="form" ref="formRef">
|
||||||
<a-row :gutter="24">
|
<j-row :gutter="24">
|
||||||
<a-col :span="12">
|
<j-col :span="12">
|
||||||
<a-form-item label="名称" name="name">
|
<j-form-item label="名称" name="name">
|
||||||
<a-input
|
<j-input
|
||||||
placeholder="请输入名称"
|
placeholder="请输入名称"
|
||||||
v-model:value="form.name"
|
v-model:value="form.name"
|
||||||
></a-input> </a-form-item
|
></j-input> </j-form-item
|
||||||
></a-col>
|
></j-col>
|
||||||
<a-col :span="12">
|
<j-col :span="12">
|
||||||
<a-form-item label="类型" name="targetType">
|
<j-form-item label="类型" name="targetType">
|
||||||
<a-select
|
<j-select
|
||||||
:options="options"
|
:options="options"
|
||||||
v-model:value="form.targetType"
|
v-model:value="form.targetType"
|
||||||
:disabled="selectDisable"
|
:disabled="selectDisable"
|
||||||
></a-select>
|
></j-select>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</a-col>
|
</j-col>
|
||||||
</a-row>
|
</j-row>
|
||||||
<a-form-item label="级别" name="level">
|
<j-form-item label="级别" name="level">
|
||||||
<a-radio-group v-model:value="form.level">
|
<j-radio-group v-model:value="form.level">
|
||||||
<a-radio-button
|
<j-radio-button
|
||||||
v-for="(item, index) in levelOption"
|
v-for="(item, index) in levelOption"
|
||||||
:key="index"
|
:key="index"
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
|
@ -40,14 +40,14 @@
|
||||||
alt=""
|
alt=""
|
||||||
/>{{ item.label }}
|
/>{{ item.label }}
|
||||||
</div>
|
</div>
|
||||||
</a-radio-button>
|
</j-radio-button>
|
||||||
</a-radio-group>
|
</j-radio-group>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="说明" name="description">
|
<j-form-item label="说明" name="description">
|
||||||
<a-textarea v-model:value="form.description"></a-textarea>
|
<j-textarea v-model:value="form.description"></j-textarea>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<PermissionButton type="primary" @click="handleSave" :hasPermission="['rule-engine/Alarm/Configuration:add','rule-engine/Alarm/Configuration:update']">保存</PermissionButton>
|
<PermissionButton type="primary" @click="handleSave" :hasPermission="['rule-engine/Alarm/Configuration:add','rule-engine/Alarm/Configuration:update']">保存</PermissionButton>
|
||||||
</a-form>
|
</j-form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ const handleSave = async () => {
|
||||||
const res = await save(form);
|
const res = await save(form);
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
message.success('操作成功');
|
message.success('操作成功,请配置关联的场景联动');
|
||||||
menuStory.jumpPage(
|
menuStory.jumpPage(
|
||||||
'rule-engine/Alarm/Configuration/Save',
|
'rule-engine/Alarm/Configuration/Save',
|
||||||
{},
|
{},
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<a-modal
|
<j-modal
|
||||||
visible
|
visible
|
||||||
title="新增"
|
title="新增"
|
||||||
okText="确定"
|
okText="确定"
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
@cancel="closeModal"
|
@cancel="closeModal"
|
||||||
@ok="saveCorrelation"
|
@ok="saveCorrelation"
|
||||||
>
|
>
|
||||||
<Search :columns="columns" @search="handleSearch"></Search>
|
<pro-search :columns="columns" @search="handleSearch"/>
|
||||||
<div style="height: 500px; overflow-y: auto">
|
<div style="height: 500px; overflow-y: auto">
|
||||||
<JProTable
|
<JProTable
|
||||||
model="CARD"
|
model="CARD"
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
</template>
|
</template>
|
||||||
</JProTable>
|
</JProTable>
|
||||||
</div>
|
</div>
|
||||||
</a-modal>
|
</j-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@ -213,7 +213,7 @@ const saveCorrelation = async () => {
|
||||||
const list = _selectedRowKeys.value.map((item: any) => {
|
const list = _selectedRowKeys.value.map((item: any) => {
|
||||||
return {
|
return {
|
||||||
alarmId: props.id,
|
alarmId: props.id,
|
||||||
releId: item,
|
ruleId: item,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
const res = await bindScene([...list]);
|
const res = await bindScene([...list]);
|
||||||
|
|
|
@ -10,12 +10,12 @@
|
||||||
ref="actionRef"
|
ref="actionRef"
|
||||||
>
|
>
|
||||||
<template #headerTitle>
|
<template #headerTitle>
|
||||||
<a-space>
|
<j-space>
|
||||||
<PermissionButton type="primary" @click="showModal" hasPermission="rule-engine/Alarm/Configuration:add">
|
<PermissionButton type="primary" @click="showModal" hasPermission="rule-engine/Alarm/Configuration:add">
|
||||||
<template #icon><AIcon type="PlusOutlined" /></template>
|
<template #icon><AIcon type="PlusOutlined" /></template>
|
||||||
新增
|
新增
|
||||||
</PermissionButton>
|
</PermissionButton>
|
||||||
</a-space>
|
</j-space>
|
||||||
</template>
|
</template>
|
||||||
<template #card="slotProps">
|
<template #card="slotProps">
|
||||||
<SceneCard
|
<SceneCard
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<Scene></Scene>
|
<Scene></Scene>
|
||||||
</j-tab-pane>
|
</j-tab-pane>
|
||||||
<j-tab-pane key="3" tab="告警记录">
|
<j-tab-pane key="3" tab="告警记录">
|
||||||
<Log/>
|
<Log v-if="activeKey === '3'" />
|
||||||
</j-tab-pane>
|
</j-tab-pane>
|
||||||
</j-tabs>
|
</j-tabs>
|
||||||
</j-card>
|
</j-card>
|
||||||
|
@ -29,7 +29,7 @@ const changeTabs = (e:any) =>{
|
||||||
} else {
|
} else {
|
||||||
message.error('请先保存基础配置');
|
message.error('请先保存基础配置');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
const activeKey = ref('1');
|
const activeKey = ref('1');
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -56,8 +56,8 @@
|
||||||
{{ slotProps.name }}
|
{{ slotProps.name }}
|
||||||
</span>
|
</span>
|
||||||
</Ellipsis>
|
</Ellipsis>
|
||||||
<a-row>
|
<j-row>
|
||||||
<a-col :span="12">
|
<j-col :span="12">
|
||||||
<div class="content-des-title">
|
<div class="content-des-title">
|
||||||
关联场景联动
|
关联场景联动
|
||||||
</div>
|
</div>
|
||||||
|
@ -66,8 +66,8 @@
|
||||||
{{ (slotProps?.scene || []).map((item: any) => item?.name).join(',') || '' }}
|
{{ (slotProps?.scene || []).map((item: any) => item?.name).join(',') || '' }}
|
||||||
</div></Ellipsis
|
</div></Ellipsis
|
||||||
>
|
>
|
||||||
</a-col>
|
</j-col>
|
||||||
<a-col :span="12">
|
<j-col :span="12">
|
||||||
<div class="content-des-title">
|
<div class="content-des-title">
|
||||||
告警级别
|
告警级别
|
||||||
</div>
|
</div>
|
||||||
|
@ -75,8 +75,8 @@
|
||||||
{{ (Store.get('default-level') || []).find((item: any) => item?.level === slotProps.level)?.title ||
|
{{ (Store.get('default-level') || []).find((item: any) => item?.level === slotProps.level)?.title ||
|
||||||
slotProps.level }}
|
slotProps.level }}
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</j-col>
|
||||||
</a-row>
|
</j-row>
|
||||||
</template>
|
</template>
|
||||||
<template #actions="item">
|
<template #actions="item">
|
||||||
<PermissionButton
|
<PermissionButton
|
||||||
|
@ -109,7 +109,7 @@
|
||||||
<span>{{ map[slotProps.targetType] }}</span>
|
<span>{{ map[slotProps.targetType] }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #level="slotProps">
|
<template #level="slotProps">
|
||||||
<a-tooltip
|
<j-tooltip
|
||||||
placement="topLeft"
|
placement="topLeft"
|
||||||
:title="(Store.get('default-level') || []).find((item: any) => item?.level === slotProps.level)?.title ||
|
:title="(Store.get('default-level') || []).find((item: any) => item?.level === slotProps.level)?.title ||
|
||||||
slotProps.level"
|
slotProps.level"
|
||||||
|
@ -118,7 +118,7 @@
|
||||||
{{ (Store.get('default-level') || []).find((item: any) => item?.level === slotProps.level)?.title ||
|
{{ (Store.get('default-level') || []).find((item: any) => item?.level === slotProps.level)?.title ||
|
||||||
slotProps.level }}
|
slotProps.level }}
|
||||||
</div>
|
</div>
|
||||||
</a-tooltip>
|
</j-tooltip>
|
||||||
</template>
|
</template>
|
||||||
<template #sceneId="slotProps">
|
<template #sceneId="slotProps">
|
||||||
<span
|
<span
|
||||||
|
@ -126,7 +126,7 @@
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #state="slotProps">
|
<template #state="slotProps">
|
||||||
<a-badge
|
<j-badge
|
||||||
:text="
|
:text="
|
||||||
slotProps.state?.value === 'enabled'
|
slotProps.state?.value === 'enabled'
|
||||||
? '正常'
|
? '正常'
|
||||||
|
@ -140,7 +140,7 @@
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #action="slotProps">
|
<template #action="slotProps">
|
||||||
<a-space :size="16">
|
<j-space :size="16">
|
||||||
<template
|
<template
|
||||||
v-for="i in getActions(slotProps, 'table')"
|
v-for="i in getActions(slotProps, 'table')"
|
||||||
:key="i.key"
|
:key="i.key"
|
||||||
|
@ -168,7 +168,7 @@
|
||||||
/></template>
|
/></template>
|
||||||
</PermissionButton>
|
</PermissionButton>
|
||||||
</template>
|
</template>
|
||||||
</a-space>
|
</j-space>
|
||||||
</template>
|
</template>
|
||||||
</JProTable>
|
</JProTable>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<page-container>
|
<page-container>
|
||||||
<Search
|
<pro-search
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
target="alarm-log-detail"
|
target="alarm-log-detail"
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
></Search>
|
/>
|
||||||
<JProTable
|
<JProTable
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
model="TABLE"
|
model="TABLE"
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
moment(slotProps.alarmTime).format('YYYY-MM-DD HH:mm:ss')
|
moment(slotProps.alarmTime).format('YYYY-MM-DD HH:mm:ss')
|
||||||
}}</template>
|
}}</template>
|
||||||
<template #action="slotProps">
|
<template #action="slotProps">
|
||||||
<a-space
|
<j-space
|
||||||
><template
|
><template
|
||||||
v-for="i in getActions(slotProps, 'table')"
|
v-for="i in getActions(slotProps, 'table')"
|
||||||
:key="i.key"
|
:key="i.key"
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
<template #icon><AIcon :type="i.icon"/></template>
|
<template #icon><AIcon :type="i.icon"/></template>
|
||||||
</PermissionButton>
|
</PermissionButton>
|
||||||
</template>
|
</template>
|
||||||
</a-space>
|
</j-space>
|
||||||
</template>
|
</template>
|
||||||
</JProTable>
|
</JProTable>
|
||||||
<Info v-if="visiable" :data="current" @close="close"/>
|
<Info v-if="visiable" :data="current" @close="close"/>
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<a-modal visible title="详情" okText="确定" cancelText="取消" :width="1000" @ok="closeModal" @cancel="closeModal">
|
<j-modal visible title="详情" okText="确定" cancelText="取消" :width="1000" @ok="closeModal" @cancel="closeModal">
|
||||||
<a-descriptions bordered :column="2">
|
<j-descriptions bordered :column="2">
|
||||||
<a-descriptions-item v-if="props.data.targetType==='device'" label="告警设备" :span="1">{{props.data?.targetName || ''}}</a-descriptions-item>
|
<j-descriptions-item v-if="props.data.targetType==='device'" label="告警设备" :span="1">{{props.data?.targetName || ''}}</j-descriptions-item>
|
||||||
<a-descriptions-item v-if="props.data.targetType==='device'" label="设备ID" :span="1">{{props.data?.targetId || ''}}</a-descriptions-item>
|
<j-descriptions-item v-if="props.data.targetType==='device'" label="设备ID" :span="1">{{props.data?.targetId || ''}}</j-descriptions-item>
|
||||||
<a-descriptions-item label="告警名称" :span="1">{{
|
<j-descriptions-item label="告警名称" :span="1">{{
|
||||||
props.data?.alarmConfigName
|
props.data?.alarmConfigName
|
||||||
}}</a-descriptions-item>
|
}}</j-descriptions-item>
|
||||||
<a-descriptions-item label="告警时间" :span="1">{{
|
<j-descriptions-item label="告警时间" :span="1">{{
|
||||||
moment(data?.alarmTime).format('YYYY-MM-DD HH:mm:ss')
|
moment(data?.alarmTime).format('YYYY-MM-DD HH:mm:ss')
|
||||||
}}</a-descriptions-item>
|
}}</j-descriptions-item>
|
||||||
<a-descriptions-item label="告警级别" :span="1">
|
<j-descriptions-item label="告警级别" :span="1">
|
||||||
<a-tooltip
|
<j-tooltip
|
||||||
placement="topLeft"
|
placement="topLeft"
|
||||||
:title="(Store.get('default-level') || []).find((item: any) => item?.level === data?.level)
|
:title="(Store.get('default-level') || []).find((item: any) => item?.level === data?.level)
|
||||||
?.title || props.data?.level"
|
?.title || props.data?.level"
|
||||||
|
@ -21,10 +21,10 @@
|
||||||
?.title || props.data?.level}}
|
?.title || props.data?.level}}
|
||||||
</span>
|
</span>
|
||||||
</Ellipsis>
|
</Ellipsis>
|
||||||
</a-tooltip>
|
</j-tooltip>
|
||||||
</a-descriptions-item>
|
</j-descriptions-item>
|
||||||
<a-descriptions-item label="告警说明" :span="1"
|
<j-descriptions-item label="告警说明" :span="1"
|
||||||
><a-tooltip
|
><j-tooltip
|
||||||
placement="topLeft"
|
placement="topLeft"
|
||||||
:title="data?.description || ''"
|
:title="data?.description || ''"
|
||||||
>
|
>
|
||||||
|
@ -33,14 +33,14 @@
|
||||||
{{ data?.description || '' }}
|
{{ data?.description || '' }}
|
||||||
</span> </Ellipsis
|
</span> </Ellipsis
|
||||||
>
|
>
|
||||||
</a-tooltip></a-descriptions-item
|
</j-tooltip></j-descriptions-item
|
||||||
>
|
>
|
||||||
<a-descriptions-item
|
<j-descriptions-item
|
||||||
label="告警流水"
|
label="告警流水"
|
||||||
:span="2"
|
:span="2"
|
||||||
><div style="max-height: 500px; overflow-y: auto;"><JsonViewer :value="JSON.parse(data?.alarmInfo || '{}')" :expand-depth="5"></JsonViewer></div></a-descriptions-item>
|
><div style="max-height: 500px; overflow-y: auto;"><JsonViewer :value="JSON.parse(data?.alarmInfo || '{}')" :expand-depth="5"></JsonViewer></div></j-descriptions-item>
|
||||||
</a-descriptions>
|
</j-descriptions>
|
||||||
</a-modal>
|
</j-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<a-modal
|
<j-modal
|
||||||
title="告警处理"
|
title="告警处理"
|
||||||
okText="确定"
|
okText="确定"
|
||||||
cancelText="取消"
|
cancelText="取消"
|
||||||
|
@ -9,18 +9,18 @@
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
:confirmLoading="loading"
|
:confirmLoading="loading"
|
||||||
>
|
>
|
||||||
<a-form :rules="rules" layout="vertical" ref="formRef" :model="form">
|
<j-form :rules="rules" layout="vertical" ref="formRef" :model="form">
|
||||||
<a-form-item label="处理结果" name="describe">
|
<j-form-item label="处理结果" name="describe">
|
||||||
<a-textarea
|
<j-textarea
|
||||||
:rows="8"
|
:rows="8"
|
||||||
:maxlength="200"
|
:maxlength="200"
|
||||||
showCount
|
showCount
|
||||||
placeholder="请输入处理结果"
|
placeholder="请输入处理结果"
|
||||||
v-model:value="form.describe"
|
v-model:value="form.describe"
|
||||||
></a-textarea>
|
></j-textarea>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</a-form>
|
</j-form>
|
||||||
</a-modal>
|
</j-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@ -64,6 +64,7 @@ const handleSave = () => {
|
||||||
});
|
});
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
onlyMessage('操作成功!');
|
onlyMessage('操作成功!');
|
||||||
|
emit('closeSolve');
|
||||||
} else {
|
} else {
|
||||||
onlyMessage('操作失败!', 'error');
|
onlyMessage('操作失败!', 'error');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<a-modal
|
<j-modal
|
||||||
visible
|
visible
|
||||||
title="处理记录"
|
title="处理记录"
|
||||||
:width="1200"
|
:width="1200"
|
||||||
|
@ -8,11 +8,11 @@
|
||||||
@ok="clsoeModal"
|
@ok="clsoeModal"
|
||||||
@cancel="clsoeModal"
|
@cancel="clsoeModal"
|
||||||
>
|
>
|
||||||
<Search
|
<pro-search
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
target="bind-channel"
|
target="bind-channel"
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
></Search>
|
/>
|
||||||
<JProTable
|
<JProTable
|
||||||
model="TABLE"
|
model="TABLE"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</JProTable>
|
</JProTable>
|
||||||
</a-modal>
|
</j-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="alarm-log-card">
|
<div class="alarm-log-card">
|
||||||
<Search
|
<pro-search
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
target="alarm-log"
|
target="alarm-log"
|
||||||
v-if="['all', 'detail'].includes(props.type)"
|
v-if="['all', 'detail'].includes(props.type)"
|
||||||
@search="search"
|
@search="search"
|
||||||
></Search>
|
/>
|
||||||
<Search
|
<pro-search
|
||||||
:columns="produtCol"
|
:columns="produtCol"
|
||||||
target="alarm-log"
|
target="alarm-log"
|
||||||
v-if="['product', 'other'].includes(props.type)"
|
v-if="['product', 'other'].includes(props.type)"
|
||||||
@search="search"
|
@search="search"
|
||||||
></Search>
|
/>
|
||||||
<Search
|
<pro-search
|
||||||
:columns="deviceCol"
|
:columns="deviceCol"
|
||||||
target="alarm-log"
|
target="alarm-log"
|
||||||
v-if="props.type === 'device'"
|
v-if="props.type === 'device'"
|
||||||
@search="search"
|
@search="search"
|
||||||
></Search>
|
/>
|
||||||
<Search
|
<pro-search
|
||||||
:columns="orgCol"
|
:columns="orgCol"
|
||||||
target="alarm-log"
|
target="alarm-log"
|
||||||
v-if="props.type === 'org'"
|
v-if="props.type === 'org'"
|
||||||
@search="search"
|
@search="search"
|
||||||
></Search>
|
/>
|
||||||
<JProTable
|
<JProTable
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:request="handleSearch"
|
:request="handleSearch"
|
||||||
|
@ -31,6 +31,7 @@
|
||||||
:gridColumns="[1, 1, 2]"
|
:gridColumns="[1, 1, 2]"
|
||||||
:gridColumn="2"
|
:gridColumn="2"
|
||||||
model="CARD"
|
model="CARD"
|
||||||
|
ref="tableRef"
|
||||||
>
|
>
|
||||||
<template #card="slotProps">
|
<template #card="slotProps">
|
||||||
<CardBox
|
<CardBox
|
||||||
|
@ -52,8 +53,8 @@
|
||||||
{{ slotProps.alarmName }}
|
{{ slotProps.alarmName }}
|
||||||
</span>
|
</span>
|
||||||
</Ellipsis>
|
</Ellipsis>
|
||||||
<a-row :gutter="24">
|
<j-row :gutter="24">
|
||||||
<a-col :span="8">
|
<j-col :span="8">
|
||||||
<div class="content-des-title">
|
<div class="content-des-title">
|
||||||
{{ titleMap.get(slotProps.targetType) }}
|
{{ titleMap.get(slotProps.targetType) }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -62,8 +63,8 @@
|
||||||
{{ slotProps?.targetName }}
|
{{ slotProps?.targetName }}
|
||||||
</div></Ellipsis
|
</div></Ellipsis
|
||||||
>
|
>
|
||||||
</a-col>
|
</j-col>
|
||||||
<a-col :span="8">
|
<j-col :span="8">
|
||||||
<div class="content-des-title">
|
<div class="content-des-title">
|
||||||
最近告警时间
|
最近告警时间
|
||||||
</div>
|
</div>
|
||||||
|
@ -76,17 +77,17 @@
|
||||||
}}
|
}}
|
||||||
</div></Ellipsis
|
</div></Ellipsis
|
||||||
>
|
>
|
||||||
</a-col>
|
</j-col>
|
||||||
<a-col :span="8">
|
<j-col :span="8">
|
||||||
<div class="content-des-title">状态</div>
|
<div class="content-des-title">状态</div>
|
||||||
<a-badge
|
<j-badge
|
||||||
:status="
|
:status="
|
||||||
slotProps.state.value === 'warning'
|
slotProps.state.value === 'warning'
|
||||||
? 'error'
|
? 'error'
|
||||||
: 'default'
|
: 'default'
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
</a-badge
|
</j-badge
|
||||||
><span
|
><span
|
||||||
:style="
|
:style="
|
||||||
slotProps.state.value === 'warning'
|
slotProps.state.value === 'warning'
|
||||||
|
@ -96,8 +97,8 @@
|
||||||
>
|
>
|
||||||
{{ slotProps.state.text }}
|
{{ slotProps.state.text }}
|
||||||
</span>
|
</span>
|
||||||
</a-col>
|
</j-col>
|
||||||
</a-row>
|
</j-row>
|
||||||
</template>
|
</template>
|
||||||
<template #actions="item">
|
<template #actions="item">
|
||||||
<PermissionButton
|
<PermissionButton
|
||||||
|
@ -105,7 +106,6 @@
|
||||||
item.key === 'solve' &&
|
item.key === 'solve' &&
|
||||||
slotProps.state.value === 'normal'
|
slotProps.state.value === 'normal'
|
||||||
"
|
"
|
||||||
:popConfirm="item.popConfirm"
|
|
||||||
:tooltip="{
|
:tooltip="{
|
||||||
...item.tooltip,
|
...item.tooltip,
|
||||||
}"
|
}"
|
||||||
|
@ -152,11 +152,11 @@ import { Store } from 'jetlinks-store';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import type { ActionsType } from '@/components/Table';
|
import type { ActionsType } from '@/components/Table';
|
||||||
import SolveComponent from '../SolveComponent/index.vue';
|
import SolveComponent from '../SolveComponent/index.vue';
|
||||||
import SolveLog from '../SolveLog/index.vue'
|
import SolveLog from '../SolveLog/index.vue';
|
||||||
import { useMenuStore } from '@/store/menu';
|
import { useMenuStore } from '@/store/menu';
|
||||||
import { usePermissionStore } from '@/store/permission';
|
import { usePermissionStore } from '@/store/permission';
|
||||||
const menuStory = useMenuStore();
|
const menuStory = useMenuStore();
|
||||||
|
const tableRef = ref();
|
||||||
const alarmStore = useAlarmStore();
|
const alarmStore = useAlarmStore();
|
||||||
const { data } = storeToRefs(alarmStore);
|
const { data } = storeToRefs(alarmStore);
|
||||||
const getDefaulitLevel = () => {
|
const getDefaulitLevel = () => {
|
||||||
|
@ -347,24 +347,20 @@ watchEffect(() => {
|
||||||
const search = (data: any) => {
|
const search = (data: any) => {
|
||||||
params.value.terms = [...data?.terms];
|
params.value.terms = [...data?.terms];
|
||||||
if (props.type !== 'all' && !props.id) {
|
if (props.type !== 'all' && !props.id) {
|
||||||
params.value.terms.push(
|
params.value.terms.push({
|
||||||
{
|
|
||||||
termType: 'eq',
|
termType: 'eq',
|
||||||
column: 'targetType',
|
column: 'targetType',
|
||||||
value: props.type,
|
value: props.type,
|
||||||
type: 'and',
|
type: 'and',
|
||||||
},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (props.id) {
|
if (props.id) {
|
||||||
params.value.terms.push (
|
params.value.terms.push({
|
||||||
{
|
|
||||||
termType: 'eq',
|
termType: 'eq',
|
||||||
column: 'alarmConfigId',
|
column: 'alarmConfigId',
|
||||||
value: props.id,
|
value: props.id,
|
||||||
type: 'and',
|
type: 'and',
|
||||||
},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -385,13 +381,15 @@ const getActions = (
|
||||||
data.value.current = currentData;
|
data.value.current = currentData;
|
||||||
data.value.solveVisible = true;
|
data.value.solveVisible = true;
|
||||||
},
|
},
|
||||||
popConfirm:{
|
// popConfirm: {
|
||||||
title: !usePermissionStore().hasPermission('rule-engine/Alarm/Log:action')
|
// title: !usePermissionStore().hasPermission(
|
||||||
? '暂无权限,请联系管理员'
|
// 'rule-engine/Alarm/Log:action',
|
||||||
: data.state?.value === 'normal'
|
// )
|
||||||
? '无告警'
|
// ? '暂无权限,请联系管理员'
|
||||||
: ''
|
// : data.state?.value === 'normal'
|
||||||
}
|
// ? '无告警'
|
||||||
|
// : '',
|
||||||
|
// },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'log',
|
key: 'log',
|
||||||
|
@ -401,8 +399,10 @@ const getActions = (
|
||||||
},
|
},
|
||||||
icon: 'FileOutlined',
|
icon: 'FileOutlined',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
menuStory.jumpPage(`rule-engine/Alarm/Log/Detail`,{id:currentData.id});
|
menuStory.jumpPage(`rule-engine/Alarm/Log/Detail`, {
|
||||||
}
|
id: currentData.id,
|
||||||
|
});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'detail',
|
key: 'detail',
|
||||||
|
@ -414,7 +414,7 @@ const getActions = (
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
data.value.current = currentData;
|
data.value.current = currentData;
|
||||||
data.value.logVisible = true;
|
data.value.logVisible = true;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
return actions;
|
return actions;
|
||||||
|
@ -424,13 +424,14 @@ const getActions = (
|
||||||
*/
|
*/
|
||||||
const closeSolve = () => {
|
const closeSolve = () => {
|
||||||
data.value.solveVisible = false;
|
data.value.solveVisible = false;
|
||||||
}
|
tableRef.value.reload(params.value);
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* 关闭处理记录
|
* 关闭处理记录
|
||||||
*/
|
*/
|
||||||
const closeLog = () => {
|
const closeLog = () => {
|
||||||
data.value.logVisible = false;
|
data.value.logVisible = false;
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<a-modal
|
<j-modal
|
||||||
:maskClosable="false"
|
:maskClosable="false"
|
||||||
width="650px"
|
width="650px"
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
|
@ -12,30 +12,30 @@
|
||||||
:confirmLoading="loading"
|
:confirmLoading="loading"
|
||||||
>
|
>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 10px">
|
||||||
<a-form
|
<j-form
|
||||||
:layout="'vertical'"
|
:layout="'vertical'"
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
:model="modelRef"
|
:model="modelRef"
|
||||||
>
|
>
|
||||||
<a-form-item label="名称" name="name">
|
<j-form-item label="名称" name="name">
|
||||||
<a-input
|
<j-input
|
||||||
v-model:value="modelRef.name"
|
v-model:value="modelRef.name"
|
||||||
placeholder="请输入名称"
|
placeholder="请输入名称"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item label="说明" name="describe">
|
<j-form-item label="说明" name="describe">
|
||||||
<a-textarea
|
<j-textarea
|
||||||
v-model:value="modelRef.description"
|
v-model:value="modelRef.description"
|
||||||
placeholder="请输入说明"
|
placeholder="请输入说明"
|
||||||
showCount
|
showCount
|
||||||
:maxlength="200"
|
:maxlength="200"
|
||||||
:rows="4"
|
:rows="4"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</a-form>
|
</j-form>
|
||||||
</div>
|
</div>
|
||||||
</a-modal>
|
</j-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<page-container>
|
<page-container>
|
||||||
<div>
|
<div>
|
||||||
<Search
|
<pro-search
|
||||||
:columns="query.columns"
|
:columns="query.columns"
|
||||||
target="device-instance"
|
target="device-instance"
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
></Search>
|
/>
|
||||||
<JProTable
|
<JProTable
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:request="queryList"
|
:request="queryList"
|
||||||
|
@ -53,15 +53,15 @@
|
||||||
{{ slotProps.name }}
|
{{ slotProps.name }}
|
||||||
</span>
|
</span>
|
||||||
</Ellipsis>
|
</Ellipsis>
|
||||||
<a-row>
|
<j-row>
|
||||||
<a-col :span="12">
|
<j-col :span="12">
|
||||||
<Ellipsis>
|
<Ellipsis>
|
||||||
<div>
|
<div>
|
||||||
{{ slotProps.description }}
|
{{ slotProps.description }}
|
||||||
</div>
|
</div>
|
||||||
</Ellipsis>
|
</Ellipsis>
|
||||||
</a-col>
|
</j-col>
|
||||||
</a-row>
|
</j-row>
|
||||||
</template>
|
</template>
|
||||||
<template #actions="item">
|
<template #actions="item">
|
||||||
<PermissionButton
|
<PermissionButton
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
</CardBox>
|
</CardBox>
|
||||||
</template>
|
</template>
|
||||||
<template #state="slotProps">
|
<template #state="slotProps">
|
||||||
<a-badge
|
<j-badge
|
||||||
:text="
|
:text="
|
||||||
slotProps.state?.value === 'started'
|
slotProps.state?.value === 'started'
|
||||||
? '正常'
|
? '正常'
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #action="slotProps">
|
<template #action="slotProps">
|
||||||
<a-space :size="16">
|
<j-space :size="16">
|
||||||
<template
|
<template
|
||||||
v-for="i in getActions(slotProps, 'table')"
|
v-for="i in getActions(slotProps, 'table')"
|
||||||
:key="i.key"
|
:key="i.key"
|
||||||
|
@ -123,7 +123,7 @@
|
||||||
/></template>
|
/></template>
|
||||||
</PermissionButton>
|
</PermissionButton>
|
||||||
</template>
|
</template>
|
||||||
</a-space>
|
</j-space>
|
||||||
</template>
|
</template>
|
||||||
</JProTable>
|
</JProTable>
|
||||||
<!-- 新增、编辑 -->
|
<!-- 新增、编辑 -->
|
||||||
|
|
Loading…
Reference in New Issue