Merge branch 'dev' of github.com:jetlinks/jetlinks-ui-vue into dev

This commit is contained in:
JiangQiming 2023-02-28 13:41:22 +08:00
commit 32f3039153
6 changed files with 447 additions and 11 deletions

View File

@ -0,0 +1,21 @@
import server from '@/utils/request';
/**
*
*/
export const getProductList = (parmas?:any) => server.get('/device/product/_query/no-paging?paging=false',parmas);
/**
*
*/
export const getDeviceList = (parmas?:any) => server.get('/device-instance/_query/no-paging?paging=false',parmas);
/**
*
*/
export const getOrgList = (parmas?:any) => server.get('/organization/_query/no-paging?paging=false',parmas);
/**
*
*/
export const query = (data:any) => server.post('/alarm/record/_query/',data);

37
src/store/alarm.ts Normal file
View File

@ -0,0 +1,37 @@
import { defineStore } from "pinia";
export const useAlarmStore = defineStore('alarm',()=>{
const data = reactive({
tab: 'all',
current: {},
solveVisible: false,
logVisible: false,
defaultLevel: [],
columns: [
{
dataIndex: 'alarmConfigName',
title: '告警名称',
// hideInSearch: true,
},
{
dataIndex: 'alarmTime',
title: '告警时间',
valueType: 'dateTime',
},
{
dataIndex: 'description',
title: '说明',
// hideInSearch: true,
},
{
dataIndex: 'action',
title: '操作',
hideInSearch: true,
valueType: 'option',
},
],
})
return {
data
}
})

View File

@ -35,7 +35,6 @@
<template #card="slotProps">
<CardBox
:value="slotProps"
@click="handleClick"
:actions="getActions(slotProps, 'card')"
v-bind="slotProps"
:active="_selectedRowKeys.includes(slotProps.id)"
@ -272,14 +271,14 @@ const cancelSelect = () => {
_selectedRowKeys.value = [];
};
const handleClick = (dt: any) => {
if (_selectedRowKeys.value.includes(dt.id)) {
const _index = _selectedRowKeys.value.findIndex((i) => i === dt.id);
_selectedRowKeys.value.splice(_index, 1);
} else {
_selectedRowKeys.value = [..._selectedRowKeys.value, dt.id];
}
};
// const handleClick = (dt: any) => {
// if (_selectedRowKeys.value.includes(dt.id)) {
// const _index = _selectedRowKeys.value.findIndex((i) => i === dt.id);
// _selectedRowKeys.value.splice(_index, 1);
// } else {
// _selectedRowKeys.value = [..._selectedRowKeys.value, dt.id];
// }
// };
const getActions = (
data: Partial<Record<string, any>>,

View File

@ -278,6 +278,7 @@ import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface';
import { message } from 'ant-design-vue';
import { LocalStore } from '@/utils/comm';
import { TOKEN_KEY } from '@/utils/variable';
import { SystemConst } from '@/utils/consts'
const formRef = ref();
const menuRef = ref();
const formBasicRef = ref();
@ -352,6 +353,7 @@ const saveBasicInfo = () =>{
const res = await save(item);
if (res.status === 200) {
resolve(true);
localStorage.setItem(SystemConst.AMAP_KEY,form.value.apikey);
const ico: any = document.querySelector('link[rel="icon"]');
if (ico !== null) {
ico.href = form.value.ico;

View File

@ -0,0 +1,316 @@
<template>
<div class="alarm-log-card">
<Search
:columns="columns"
target="alarm-log"
v-if="['all', 'detail'].includes(props.type)"
@search="search"
></Search>
<Search
:columns="produtCol"
target="alarm-log"
v-if="['product', 'other'].includes(props.type)"
@search="search"
></Search>
<Search
:columns="deviceCol"
target="alarm-log"
v-if="props.type === 'device'"
@search="search"
></Search>
<Search
:columns="orgCol"
target="alarm-log"
v-if="props.type === 'org'"
@search="search"
></Search>
<JTable :columns="columns" :request="handleSearch" :params="params">
<template #card="slotProps">
<CardBox
:value="slotProps"
v-bind="slotProps"
:statusText="
data.defaultLevel.find(
(i) => i.level === slotProps.level,
)?.title || slotProps.level
"
>
<template #img>
<img :src="imgMap.get(slotProps.targetType)" alt="" />
</template>
<template #content>
<Ellipsis>
<span style="font-weight: 500">
{{ slotProps.alarmName }}
</span>
</Ellipsis>
<a-row :gutter="24">
<a-col :span="8">
<div class="content-des-title">
{{ titleMap.get(slotProps.targetType) }}
</div>
<Ellipsis
><div>
{{ slotProps?.targetName }}
</div></Ellipsis
>
</a-col>
<a-col :span="8">
<div class="content-des-title">
最近告警时间
</div>
<Ellipsis
><div>
{{
moment(slotProps?.alarmTime).format(
'YYYY-MM-DD HH:mm:ss',
)
}}
</div></Ellipsis
>
</a-col>
<a-col :span="8">
<div class="content-des-title">状态</div>
<a-badge
:status="
slotProps.state.value === 'warning'
? 'error'
: 'default'
"
>
</a-badge
><span
:style="
slotProps.state.value === 'warning'
? 'color: #E50012'
: 'color:black'
"
>
{{ slotProps.state.text }}
</span>
</a-col>
</a-row>
</template>
</CardBox>
</template>
</JTable>
</div>
</template>
<script lang="ts" setup>
import { getImage } from '@/utils/comm';
import {
getProductList,
getDeviceList,
getOrgList,
query,
} from '@/api/rule-engine/log';
import { queryLevel } from '@/api/rule-engine/config';
import Search from '@/components/Search';
import { useAlarmStore } from '@/store/alarm';
import { storeToRefs } from 'pinia';
import { Store } from 'jetlinks-store';
import moment from 'moment';
const alarmStore = useAlarmStore();
const { data } = storeToRefs(alarmStore);
const getDefaulitLevel = () => {
queryLevel().then((res) => {
if (res.status === 200) {
Store.set('default-level', res.result?.levels || []);
data.value.defaultLevel = res.result?.levels || [];
}
});
};
getDefaulitLevel();
const props = defineProps<{
type: string;
id?: string;
}>();
const imgMap = new Map();
imgMap.set('product', getImage('/alarm/product.png'));
imgMap.set('device', getImage('/alarm/device.png'));
imgMap.set('other', getImage('/alarm/other.png'));
imgMap.set('org', getImage('/alarm/org.png'));
const titleMap = new Map();
titleMap.set('product', '产品');
titleMap.set('device', '设备');
titleMap.set('other', '其他');
titleMap.set('org', '组织');
const colorMap = new Map();
colorMap.set(1, '#E50012');
colorMap.set(2, '#FF9457');
colorMap.set(3, '#FABD47');
colorMap.set(4, '#999999');
colorMap.set(5, '#C4C4C4');
const columns = [
{
title: '名称',
dataIndex: 'alarmName',
key: 'alarmName',
search: {
type: 'string',
},
},
{
title: '最近告警事件',
dataIndex: 'alarmTime',
key: 'alarmTime',
search: {
type: 'dateTime',
},
},
{
title: '状态',
dataIndex: 'state',
key: 'state',
search: {
type: 'select',
options: [
{
label: '告警中',
value: 'warning',
},
{
label: '无告警',
value: 'normal',
},
],
},
},
];
const produtCol = [
...columns,
{
title: '产品名称',
dataIndex: 'targetName',
key: 'targetName',
search: {
type: 'select',
options: async () => {
const resq = await getProductList();
if (resq.status === 200) {
return resq.result.map((item: any) => ({
label: item.name,
value: item.name,
}));
}
return [];
},
},
},
];
const deviceCol = [
...columns,
{
title: '设备名称',
dataIndex: 'targetName',
key: 'targetName',
search: {
type: 'select',
opstions: async () => {
const res = await getDeviceList();
if (res.status === 200) {
return res.result.map((item: any) => ({
label: item.name,
value: item.name,
}));
}
return [];
},
},
},
];
const orgCol = [
...columns,
{
title: '组织名称',
dataIndex: 'targetName',
key: 'targetName',
search: {
type: 'select',
options: async () => {
const res = await getOrgList();
if (res.status === 200) {
return res.result.map((item: any) => ({
label: item.name,
value: item.name,
}));
}
return [];
},
},
},
];
let params = ref({
sorts: [{ name: 'alarmTime', order: 'desc' }],
terms: [],
});
let param = reactive({
pageSize: 10,
terms: [],
});
// let dataSource = reactive({
// data: [],
// pageSize: 10,
// pageIndex: 0,
// total: 0,
// });
const handleSearch = async (params: any) => {
const resp = await query(params);
if (resp.status === 200) {
const res = await getOrgList();
if (res.status === 200) {
resp.result.data.map((item: any) => {
if (item.targetType === 'org') {
res.result.forEach((item2: any) => {
if (item2.id === item.targetId) {
item.targetName = item2.name;
}
//targetName
if (item.targetId === item.targetName) {
item.targetName = '无';
}
});
}
});
return resp;
}
}
};
watchEffect(() => {
if (props.type !== 'all' && !props.id) {
params.value.terms.push({
termType: 'eq',
column: 'targetType',
value: props.type,
type: 'and',
});
}
if (props.id) {
params.value.terms.push({
termType: 'eq',
column: 'alarmConfigId',
value: props.id,
type: 'and',
});
}
});
const search = (data: any) => {
const dt = {
pageSize: 10,
terms: [...data?.terms],
};
};
const log = () => {
console.log(data.value.defaultLevel);
};
log();
</script>
<style lang="less" scoped>
</style>

View File

@ -1,9 +1,70 @@
<template>
<div></div>
<page-container :tabList="isNoCommunity ? list : noList" :tabActiveKey="data.tab" @tabChange="onTabChange">
<TableComponents :type="data.tab"></TableComponents>
</page-container>
</template>
<script lang="ts" setup>
import { isNoCommunity } from '@/utils/utils';
import { useAlarmStore } from '@/store/alarm';
import { storeToRefs } from 'pinia';
import { queryLevel } from '@/api/rule-engine/config';
import { Store } from 'jetlinks-store';
import TableComponents from './TabComponent/indev.vue';
const list = [
{
key: 'all',
tab: '全部',
},
{
key: 'product',
tab: '产品',
},
{
key: 'device',
tab: '设备',
},
{
key: 'org',
tab: '组织',
},
{
key: 'other',
tab: '其他',
},
];
const noList = [
{
key: 'all',
tab: '全部',
},
{
key: 'product',
tab: '产品',
},
{
key: 'device',
tab: '设备',
},
{
key: 'other',
tab: '其他',
},
];
const alarmStore = useAlarmStore();
const { data } = storeToRefs(alarmStore);
const getDefaulitLevel = () => {
queryLevel().then((res)=>{
if(res.status === 200 ){
Store.set('default-level', res.result?.levels || []);
data.value.defaultLevel = res.result?.levels || [];
}
})
}
getDefaulitLevel();
const onTabChange = (key:string) =>{
data.value.tab = key;
}
</script>
<style lang="less" scoped>
</style>