Merge branch 'dev' into dev-hub
This commit is contained in:
commit
62592b6e83
|
@ -5180,7 +5180,7 @@
|
|||
"node_modules/jetlinks-ui-components": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "http://47.108.170.157:9013/jetlinks-ui-components/-/jetlinks-ui-components-1.0.5.tgz",
|
||||
"integrity": "sha512-u1jqTyBWHB+b/NOKimucxNMYxet6g9Hi/I30T1VNWGq+x/Gf2zjz8dJoxjUcLW+9t/yjG6opWUE8Z8NWQRp3Eg==",
|
||||
"integrity": "sha512-zrMe/4PjtWNCQtlP6kNLA7hVyQ7ftPSgivQZp8TGcpbUMOU/IYyCLQ0+VoWcqEopTSt1zEzEazodR4EjEzv7pQ==",
|
||||
"dependencies": {
|
||||
"@vueuse/core": "^9.12.0",
|
||||
"ant-design-vue": "^3.2.15",
|
||||
|
@ -8343,6 +8343,8 @@
|
|||
},
|
||||
"node_modules/npm/node_modules/debug/node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"inBundle": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
|
@ -9913,6 +9915,8 @@
|
|||
},
|
||||
"node_modules/npm/node_modules/request/node_modules/form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.jetlinks.cn/form-data/-/form-data-2.3.3.tgz",
|
||||
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
@ -9926,6 +9930,8 @@
|
|||
},
|
||||
"node_modules/npm/node_modules/request/node_modules/tough-cookie": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.jetlinks.cn/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
||||
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
|
||||
"inBundle": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
|
@ -10156,6 +10162,8 @@
|
|||
},
|
||||
"node_modules/npm/node_modules/string-width/node_modules/strip-ansi": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-4.0.0.tgz",
|
||||
"integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
@ -17272,7 +17280,7 @@
|
|||
"jetlinks-ui-components": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "http://47.108.170.157:9013/jetlinks-ui-components/-/jetlinks-ui-components-1.0.5.tgz",
|
||||
"integrity": "sha512-u1jqTyBWHB+b/NOKimucxNMYxet6g9Hi/I30T1VNWGq+x/Gf2zjz8dJoxjUcLW+9t/yjG6opWUE8Z8NWQRp3Eg==",
|
||||
"integrity": "sha512-zrMe/4PjtWNCQtlP6kNLA7hVyQ7ftPSgivQZp8TGcpbUMOU/IYyCLQ0+VoWcqEopTSt1zEzEazodR4EjEzv7pQ==",
|
||||
"requires": {
|
||||
"@vueuse/core": "^9.12.0",
|
||||
"ant-design-vue": "^3.2.15",
|
||||
|
@ -19672,6 +19680,8 @@
|
|||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"bundled": true
|
||||
}
|
||||
}
|
||||
|
@ -20833,6 +20843,8 @@
|
|||
"dependencies": {
|
||||
"form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.jetlinks.cn/form-data/-/form-data-2.3.3.tgz",
|
||||
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
|
@ -20842,6 +20854,8 @@
|
|||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.jetlinks.cn/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
||||
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"psl": "^1.1.28",
|
||||
|
@ -20994,6 +21008,8 @@
|
|||
},
|
||||
"strip-ansi": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-4.0.0.tgz",
|
||||
"integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^3.0.0"
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import server from '@/utils/request'
|
||||
|
||||
// 获取记录列表
|
||||
export const getList_api = (data:object): any =>server.post(`/notifications/_query`,data)
|
||||
export const getList_api = (data:object): any =>server.get(`/notifications/_query`,encodeParams(data))
|
||||
// 获取未读记录列表
|
||||
export const getListByUnRead_api = (data:object): any =>server.post(`/notifications/_query`,data)
|
||||
// 修改记录状态
|
||||
export const changeStatus_api = (type:'_read'|'_unread',data:string[]): any =>server.post(`/notifications/${type}`,data)
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ export default {
|
|||
// 不分页-列表
|
||||
queryListNoPaging: (data: any) => post(`/notifier/config/_query/no-paging?paging=false`, data),
|
||||
//
|
||||
queryDingTalkUsers: (id: string) => get<any>(`/notifier/dingtalk/corp/${id}/users?sorts[0].name='name'&sorts[0].order=asc`),
|
||||
queryDingTalkUsers: (id: string) => get<any>(`/notifier/dingtalk/corp/${id}/users?sorts[0].name="name"&sorts[0].order=asc`),
|
||||
//
|
||||
queryWechatUsers: (id: string) => get<any>(`/notifier/wechat/corp/${id}/users?sorts[0].name='name'&sorts[0].order=asc`),
|
||||
queryWechatUsers: (id: string) => get<any>(`/notifier/wechat/corp/${id}/users?sorts[0].name="name"&sorts[0].order=asc`),
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="tsx">
|
||||
import { getList_api } from '@/api/account/notificationRecord';
|
||||
import { getListByUnRead_api } from '@/api/account/notificationRecord';
|
||||
import NoticeInfo from './NoticeInfo.vue';
|
||||
import { getWebSocket } from '@/utils/websocket';
|
||||
import { notification, Button } from 'ant-design-vue';
|
||||
|
@ -93,7 +93,7 @@ const getList = () => {
|
|||
},
|
||||
],
|
||||
};
|
||||
getList_api(params)
|
||||
getListByUnRead_api(params)
|
||||
.then((resp: any) => {
|
||||
list.value = resp.result.data;
|
||||
total.value = resp.result.total;
|
||||
|
|
|
@ -53,9 +53,10 @@
|
|||
v-model:value="myValue"
|
||||
placeholder="请输入图片链接"
|
||||
allowClear
|
||||
@change='inputChange'
|
||||
>
|
||||
<template #addonAfter>
|
||||
<a-upload
|
||||
<j-upload
|
||||
name="file"
|
||||
:action="FILE_UPLOAD"
|
||||
:headers="headers"
|
||||
|
@ -63,7 +64,7 @@
|
|||
@change="handleFileChange"
|
||||
>
|
||||
<AIcon type="UploadOutlined" />
|
||||
</a-upload>
|
||||
</j-upload>
|
||||
</template>
|
||||
</j-input>
|
||||
<j-input
|
||||
|
@ -182,6 +183,7 @@ const handleFileChange = (info: UploadChangeParam<UploadFile<any>>) => {
|
|||
const url = info.file.response?.result;
|
||||
myValue.value = url;
|
||||
emit('update:modelValue', url);
|
||||
emit('change', url);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -149,8 +149,8 @@ const columns = [
|
|||
},
|
||||
{
|
||||
title: '说明',
|
||||
dataIndex: 'describe',
|
||||
key: 'describe',
|
||||
dataIndex: 'description',
|
||||
key: 'description',
|
||||
search: {
|
||||
type: 'string',
|
||||
},
|
||||
|
|
|
@ -191,8 +191,8 @@ const columns = [
|
|||
},
|
||||
{
|
||||
title: '说明',
|
||||
dataIndex: 'describe',
|
||||
key: 'describe',
|
||||
dataIndex: 'description',
|
||||
key: 'description',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
margin-top: 20px;
|
||||
"
|
||||
>
|
||||
<a-upload
|
||||
<j-upload
|
||||
v-model:file-list="upload.fileList"
|
||||
accept=".jpg,.png,.jfif,.pjp,.pjpeg,.jpeg"
|
||||
:maxCount="1"
|
||||
|
@ -40,7 +40,7 @@
|
|||
<AIcon type="UploadOutlined" />
|
||||
更换头像
|
||||
</j-button>
|
||||
</a-upload>
|
||||
</j-upload>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
|
|
@ -22,12 +22,8 @@
|
|||
><TopCard
|
||||
title="当前在线"
|
||||
:footer="onlineFooter"
|
||||
:value="onlineToday"
|
||||
:value="deviceOnline"
|
||||
>
|
||||
<!-- <BarChart
|
||||
:chartXData="barChartXData"
|
||||
:chartYData="barChartYData"
|
||||
></BarChart> -->
|
||||
<Charts :options="onlineOptions"></Charts> </TopCard
|
||||
></j-col>
|
||||
<j-col :span="6"
|
||||
|
@ -140,6 +136,9 @@ const quickBtnList = [
|
|||
{ label: '近一月', value: 'month' },
|
||||
{ label: '近一年', value: 'year' },
|
||||
];
|
||||
/**
|
||||
* 获取产品数量
|
||||
*/
|
||||
const getProductData = () => {
|
||||
if (menuStore.hasMenu('device/Product')) {
|
||||
productCount().then((res) => {
|
||||
|
@ -174,6 +173,9 @@ const getProductData = () => {
|
|||
}
|
||||
};
|
||||
getProductData();
|
||||
/**
|
||||
* 获取设备数量
|
||||
*/
|
||||
const getDeviceData = () => {
|
||||
if (menuStore.hasMenu('device/Instance')) {
|
||||
deviceCount().then((res) => {
|
||||
|
@ -197,6 +199,9 @@ const getDeviceData = () => {
|
|||
}
|
||||
};
|
||||
getDeviceData();
|
||||
/**
|
||||
* 获取在线数量
|
||||
*/
|
||||
const getOnline = () => {
|
||||
dashboard([
|
||||
{
|
||||
|
@ -222,7 +227,8 @@ const getOnline = () => {
|
|||
const onlineYdata = y;
|
||||
onlineYdata.reverse();
|
||||
setOnlineChartOpition(x, onlineYdata);
|
||||
deviceFooter.value[0].value = y?.[1];
|
||||
onlineFooter.value[0].value = y?.[1];
|
||||
console.log(res.result);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!-- 绑定设备 -->
|
||||
<template>
|
||||
<a-modal
|
||||
<j-modal
|
||||
:maskClosable="false"
|
||||
width="1000px"
|
||||
:visible="true"
|
||||
|
@ -12,7 +12,7 @@
|
|||
:confirmLoading="btnLoading"
|
||||
>
|
||||
<div style="margin-top: 10px">
|
||||
<Search
|
||||
<pro-search
|
||||
:columns="columns"
|
||||
target="child-device-bind"
|
||||
@search="handleSearch"
|
||||
|
@ -73,14 +73,14 @@
|
|||
}}
|
||||
</template>
|
||||
<template #state="slotProps">
|
||||
<a-badge
|
||||
<j-badge
|
||||
:text="slotProps.state.text"
|
||||
:status="statusMap.get(slotProps.state.value)"
|
||||
/>
|
||||
</template>
|
||||
</JProTable>
|
||||
</div>
|
||||
</a-modal>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<template>
|
||||
<a-select allowClear v-model:value="_value" @change="onChange" placeholder="请选择" style="width: 100%">
|
||||
<a-select-option
|
||||
<j-select allowClear v-model:value="_value" @change="onChange" placeholder="请选择" style="width: 100%">
|
||||
<j-select-option
|
||||
v-for="item in list"
|
||||
:key="item.id"
|
||||
:value="item.id"
|
||||
:label="item.name"
|
||||
:filter-option="filterOption"
|
||||
>{{ item.name }}</a-select-option
|
||||
>{{ item.name }}</j-select-option
|
||||
>
|
||||
</a-select>
|
||||
</j-select>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<a-modal
|
||||
<j-modal
|
||||
width="900px"
|
||||
title="批量映射"
|
||||
visible
|
||||
|
@ -10,49 +10,49 @@
|
|||
<div class="map-tree-top">
|
||||
采集器的点位名称与属性名称一致时将自动映射绑定;有多个采集器点位名称与属性名称一致时以第1个采集器的点位数据进行绑定
|
||||
</div>
|
||||
<a-spin :spinning="loading">
|
||||
<j-spin :spinning="loading">
|
||||
<div class="map-tree-content">
|
||||
<a-card class="map-tree-content-card" title="源数据">
|
||||
<a-tree
|
||||
<j-card class="map-tree-content-card" title="源数据">
|
||||
<j-tree
|
||||
checkable
|
||||
:height="300"
|
||||
:tree-data="dataSource"
|
||||
:checkedKeys="checkedKeys"
|
||||
@check="onCheck"
|
||||
/>
|
||||
</a-card>
|
||||
</j-card>
|
||||
<div style="width: 100px">
|
||||
<a-button
|
||||
<j-button
|
||||
:disabled="rightList.length >= leftList.length"
|
||||
@click="onRight"
|
||||
>加入右侧</a-button
|
||||
>加入右侧</j-button
|
||||
>
|
||||
</div>
|
||||
<a-card class="map-tree-content-card" title="采集器">
|
||||
<a-list
|
||||
<j-card class="map-tree-content-card" title="采集器">
|
||||
<j-list
|
||||
size="small"
|
||||
:data-source="rightList"
|
||||
class="map-tree-content-card-list"
|
||||
>
|
||||
<template #renderItem="{ item }">
|
||||
<a-list-item>
|
||||
<j-list-item>
|
||||
{{ item.title }}
|
||||
<template #actions>
|
||||
<a-popconfirm
|
||||
<j-popconfirm
|
||||
title="确定删除?"
|
||||
@confirm="_delete(item.key)"
|
||||
>
|
||||
<AIcon type="DeleteOutlined" />
|
||||
</a-popconfirm>
|
||||
</j-popconfirm>
|
||||
</template>
|
||||
</a-list-item>
|
||||
</j-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
</a-card>
|
||||
</j-list>
|
||||
</j-card>
|
||||
</div>
|
||||
</a-spin>
|
||||
</j-spin>
|
||||
</div>
|
||||
</a-modal>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@ -119,6 +119,7 @@ const onCheck = (keys: string[], e: any) => {
|
|||
};
|
||||
|
||||
const onRight = () => {
|
||||
console.log(rightList.value,leftList.value);
|
||||
rightList.value = leftList.value;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,49 +1,51 @@
|
|||
<template>
|
||||
<a-spin :spinning="loading" v-if="_metadata.length">
|
||||
<a-card :bordered="false">
|
||||
<j-spin :spinning="loading" v-if="_metadata.length">
|
||||
<j-card :bordered="false">
|
||||
<template #title>
|
||||
<TitleComponent data="点位映射"></TitleComponent>
|
||||
</template>
|
||||
<template #extra>
|
||||
<a-space>
|
||||
<a-button @click="showModal">批量映射</a-button>
|
||||
<a-button type="primary" @click="onSave">保存并应用</a-button>
|
||||
</a-space>
|
||||
<j-space>
|
||||
<j-button @click="showModal">批量映射</j-button>
|
||||
<j-button type="primary" @click="onSave"
|
||||
>保存并应用</j-button
|
||||
>
|
||||
</j-space>
|
||||
</template>
|
||||
<a-form ref="formRef" :model="modelRef">
|
||||
<a-table :dataSource="modelRef.dataSource" :columns="columns">
|
||||
<j-form ref="formRef" :model="modelRef">
|
||||
<j-table :dataSource="modelRef.dataSource" :columns="columns">
|
||||
<template #headerCell="{ column }">
|
||||
<template v-if="column.key === 'collectorId'">
|
||||
采集器
|
||||
<a-tooltip title="边缘网关代理的真实物理设备">
|
||||
<j-tooltip title="边缘网关代理的真实物理设备">
|
||||
<AIcon type="QuestionCircleOutlined" />
|
||||
</a-tooltip>
|
||||
</j-tooltip>
|
||||
</template>
|
||||
</template>
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.dataIndex === 'channelId'">
|
||||
<a-form-item
|
||||
<j-form-item
|
||||
:name="['dataSource', index, 'channelId']"
|
||||
>
|
||||
<a-select
|
||||
<j-select
|
||||
style="width: 100%"
|
||||
v-model:value="record[column.dataIndex]"
|
||||
placeholder="请选择"
|
||||
allowClear
|
||||
:filter-option="filterOption"
|
||||
>
|
||||
<a-select-option
|
||||
<j-select-option
|
||||
v-for="item in channelList"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
>{{ item.label }}</a-select-option
|
||||
>{{ item.label }}</j-select-option
|
||||
>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</j-select>
|
||||
</j-form-item>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'collectorId'">
|
||||
<a-form-item
|
||||
<j-form-item
|
||||
:name="['dataSource', index, 'collectorId']"
|
||||
:rules="[
|
||||
{
|
||||
|
@ -58,10 +60,10 @@
|
|||
type="COLLECTOR"
|
||||
:edgeId="instanceStore.current.id"
|
||||
/>
|
||||
</a-form-item>
|
||||
</j-form-item>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'pointId'">
|
||||
<a-form-item
|
||||
<j-form-item
|
||||
:name="['dataSource', index, 'pointId']"
|
||||
:rules="[
|
||||
{
|
||||
|
@ -76,33 +78,33 @@
|
|||
type="POINT"
|
||||
:edgeId="instanceStore.current.id"
|
||||
/>
|
||||
</a-form-item>
|
||||
</j-form-item>
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'id'">
|
||||
<a-badge
|
||||
<j-badge
|
||||
v-if="record[column.dataIndex]"
|
||||
status="success"
|
||||
text="已绑定"
|
||||
/>
|
||||
<a-badge v-else status="error" text="未绑定" />
|
||||
<j-badge v-else status="error" text="未绑定" />
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-tooltip title="解绑">
|
||||
<a-popconfirm
|
||||
<j-tooltip title="解绑">
|
||||
<j-popconfirm
|
||||
title="确认解绑"
|
||||
:disabled="!record.id"
|
||||
@confirm="unbind(record.id)"
|
||||
>
|
||||
<a-button type="link" :disabled="!record.id"
|
||||
<j-button type="link" :disabled="!record.id"
|
||||
><AIcon type="icon-jiebang"
|
||||
/></a-button>
|
||||
</a-popconfirm>
|
||||
</a-tooltip>
|
||||
/></j-button>
|
||||
</j-popconfirm>
|
||||
</j-tooltip>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-form>
|
||||
</a-card>
|
||||
</j-table>
|
||||
</j-form>
|
||||
</j-card>
|
||||
<PatchMapping
|
||||
:deviceId="instanceStore.current.parentId"
|
||||
v-if="visible"
|
||||
|
@ -112,10 +114,10 @@
|
|||
:edgeId="instanceStore.current.id"
|
||||
:deviceData="deviceData"
|
||||
/>
|
||||
</a-spin>
|
||||
<a-card v-else>
|
||||
</j-spin>
|
||||
<j-card v-else>
|
||||
<JEmpty description="暂无数据,请配置物模型" style="margin: 10% 0" />
|
||||
</a-card>
|
||||
</j-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@ -175,7 +177,7 @@ const filterOption = (input: string, option: any) => {
|
|||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||
};
|
||||
const props = defineProps(['productList']);
|
||||
const _emit = defineEmits(['close']);
|
||||
const _emit = defineEmits(['close','getEdgeMap']);
|
||||
const instanceStore = useInstanceStore();
|
||||
let _metadata = ref();
|
||||
const loading = ref<boolean>(false);
|
||||
|
@ -187,7 +189,7 @@ const modelRef = reactive({
|
|||
const deviceData = ref();
|
||||
const formRef = ref();
|
||||
const visible = ref<boolean>(false);
|
||||
|
||||
/**获取通道列表 */
|
||||
const getChannel = async () => {
|
||||
if (instanceStore.current?.id) {
|
||||
const resp: any = await edgeChannel(instanceStore.current.id);
|
||||
|
@ -200,51 +202,31 @@ const getChannel = async () => {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
const handleSearch = async () => {
|
||||
loading.value = true;
|
||||
getChannel();
|
||||
modelRef.dataSource = _metadata.value;
|
||||
console.log(modelRef.dataSource);
|
||||
// if (_metadata.value && _metadata.value.length) {
|
||||
// console.log(1234);
|
||||
// const resp: any = await getEdgeMap(instanceStore.current?.orgId || '', {
|
||||
// deviceId: instanceStore.current.id,
|
||||
// query: {},
|
||||
// }).catch(() => {
|
||||
// modelRef.dataSource = _metadata;
|
||||
// loading.value = false;
|
||||
// });
|
||||
// if (resp.status === 200) {
|
||||
// const array = resp.result?.[0].reduce((x: any, y: any) => {
|
||||
// const metadataId = _metadata.find(
|
||||
// (item: any) => item.metadataId === y.metadataId,
|
||||
// );
|
||||
// if (metadataId) {
|
||||
// Object.assign(metadataId, y);
|
||||
// } else {
|
||||
// x.push(y);
|
||||
// }
|
||||
// return x;
|
||||
// }, _metadata);
|
||||
// modelRef.dataSource = array;
|
||||
// }
|
||||
// }
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* 解绑映射
|
||||
* @param id 选择解绑id
|
||||
*/
|
||||
const unbind = async (id: string) => {
|
||||
if (id) {
|
||||
const resp = await removeEdgeMap(
|
||||
instanceStore.current?.parentId || '',
|
||||
instanceStore.current?.id || '',
|
||||
{
|
||||
deviceId: instanceStore.current.id,
|
||||
deviceId: instanceStore.current.parentId,
|
||||
idList: [id],
|
||||
},
|
||||
);
|
||||
if (resp.status === 200) {
|
||||
message.success('操作成功!');
|
||||
handleSearch();
|
||||
_emit('getEdgeMap');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -280,8 +262,8 @@ const onSave = async () => {
|
|||
productName: props.productList.find(
|
||||
(item: any) => item.id === form.value?.productId,
|
||||
).name,
|
||||
parentId: instanceStore.current.id,
|
||||
id: instanceStore.current.parentId
|
||||
parentId: instanceStore.current.id, // 网关设备id
|
||||
id: instanceStore.current.parentId // 设备id
|
||||
? instanceStore.current.parentId
|
||||
: undefined,
|
||||
};
|
||||
|
@ -329,7 +311,4 @@ const showModal = async () => {
|
|||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.ant-form-item) {
|
||||
margin: 0 !important;
|
||||
}
|
||||
</style>
|
|
@ -2,7 +2,7 @@
|
|||
<div>
|
||||
<TitleComponent data="基本信息">
|
||||
<template #extra>
|
||||
<j-button @click="comeBack">返回</j-button>
|
||||
<j-button @click="comeBack" style="margin-left: 10px;">返回</j-button>
|
||||
</template>
|
||||
</TitleComponent>
|
||||
<j-form layout="vertical" :model="form" ref="formRef">
|
||||
|
@ -39,7 +39,10 @@
|
|||
</j-row>
|
||||
<j-row :gutter="24" v-if="visible">
|
||||
<j-col :span="24"
|
||||
><EdgeMap :productList="productList" @close="comeBack"
|
||||
><EdgeMap
|
||||
:productList="productList"
|
||||
@close="comeBack"
|
||||
@getEdgeMap="getEdgeMapData"
|
||||
/></j-col>
|
||||
</j-row>
|
||||
</j-form>
|
||||
|
@ -64,12 +67,22 @@ const formRef = ref();
|
|||
const emit = defineEmits(['closeChildSave']);
|
||||
const productList = ref();
|
||||
const visible = ref(false);
|
||||
/**
|
||||
* 获取产品列表
|
||||
*/
|
||||
const getProductList = async () => {
|
||||
const res = await getProductListNoPage({
|
||||
terms: [{ column: 'accessProvider', value: 'edge-child-device' }],
|
||||
});
|
||||
if (res.status === 200) {
|
||||
productList.value = res.result;
|
||||
getEdgeMapData();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 获取映射数据
|
||||
*/
|
||||
const getEdgeMapData = () => {
|
||||
if (props.childData?.id) {
|
||||
current.value.parentId = props.childData.id;
|
||||
form.name = props.childData?.name;
|
||||
|
@ -123,8 +136,11 @@ const getProductList = async () => {
|
|||
} else {
|
||||
current.value.parentId = '';
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 根据产品id获取对应映射列表
|
||||
* @param e 产品id
|
||||
*/
|
||||
const selectChange = (e: any) => {
|
||||
if (e) {
|
||||
visible.value = true;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<template>
|
||||
<a-card>
|
||||
<j-card>
|
||||
<SaveChild
|
||||
v-if="childVisible"
|
||||
@close-child-save="closeChildSave"
|
||||
:childData="_current"
|
||||
/>
|
||||
<div v-else>
|
||||
<Search
|
||||
<pro-search
|
||||
:columns="columns"
|
||||
target="child-device"
|
||||
@search="handleSearch"
|
||||
|
@ -76,7 +76,7 @@
|
|||
}}
|
||||
</template>
|
||||
<template #state="slotProps">
|
||||
<a-badge
|
||||
<j-badge
|
||||
:text="slotProps.state.text"
|
||||
:status="statusMap.get(slotProps.state.value)"
|
||||
/>
|
||||
|
@ -108,7 +108,7 @@
|
|||
</JProTable>
|
||||
<BindChildDevice v-if="visible" @change="closeBindDevice" />
|
||||
</div>
|
||||
</a-card>
|
||||
</j-card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<j-row type="flex">
|
||||
<j-col flex="180px">
|
||||
<j-form-item name="photoUrl">
|
||||
<JUpload v-model="form.photoUrl" />
|
||||
<Upload v-model="form.photoUrl" />
|
||||
</j-form-item>
|
||||
<!-- <j-form-item>
|
||||
<div class="upload-image-warp-logo">
|
||||
|
|
|
@ -144,7 +144,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { queryNoPagingPost } from '@/api/device/product';
|
||||
import { queryGatewayList, queryNoPagingPost } from '@/api/device/product';
|
||||
import { queryTree } from '@/api/device/category';
|
||||
import { message } from 'jetlinks-ui-components';
|
||||
import { ActionsType } from '@/views/device/Instance/typings';
|
||||
|
@ -260,6 +260,26 @@ const columns = [
|
|||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'productId$product-info',
|
||||
dataIndex: 'productId$product-info',
|
||||
title: '接入方式',
|
||||
hideInTable: true,
|
||||
search: {
|
||||
type: 'select',
|
||||
options: () =>
|
||||
new Promise((resolve) => {
|
||||
queryGatewayList({}).then((resp: any) => {
|
||||
resolve(
|
||||
resp.result.map((item: any) => ({
|
||||
label: item.name,
|
||||
value: `accessId is ${item.id}`,
|
||||
})),
|
||||
);
|
||||
});
|
||||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
dataIndex: 'deviceType',
|
||||
title: '设备类型',
|
||||
|
|
|
@ -10,12 +10,7 @@
|
|||
@cancel="_vis = false"
|
||||
:confirmLoading="loading"
|
||||
>
|
||||
<pro-search
|
||||
type="simple"
|
||||
:columns="columns"
|
||||
target="media"
|
||||
@search="handleSearch"
|
||||
/>
|
||||
<pro-search :columns="columns" target="media" @search="handleSearch" />
|
||||
|
||||
<JProTable
|
||||
ref="listRef"
|
||||
|
@ -23,6 +18,7 @@
|
|||
:columns="columns"
|
||||
:request="CascadeApi.queryChannelList"
|
||||
:defaultParams="{
|
||||
pageSize: 10,
|
||||
sorts: [{ name: 'name', order: 'desc' }],
|
||||
terms: [
|
||||
{
|
||||
|
@ -46,6 +42,10 @@
|
|||
onSelectAll: onSelectAllChange,
|
||||
}"
|
||||
@cancelSelect="_selectedRowKeys = []"
|
||||
:pagination="{
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ['10', '20', '50', '100'],
|
||||
}"
|
||||
>
|
||||
<template #headerTitle>
|
||||
<h3>通道列表</h3>
|
||||
|
@ -96,6 +96,7 @@ watch(
|
|||
() => _vis.value,
|
||||
(val) => {
|
||||
if (val) handleSearch({ terms: [] });
|
||||
else _selectedRowKeys.value = [];
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -114,6 +115,7 @@ const columns = [
|
|||
key: 'name',
|
||||
search: {
|
||||
type: 'string',
|
||||
first: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -158,7 +160,6 @@ const params = ref<Record<string, any>>({});
|
|||
*/
|
||||
const handleSearch = (e: any) => {
|
||||
params.value = e;
|
||||
console.log('params.value: ', params.value);
|
||||
};
|
||||
|
||||
const listRef = ref();
|
||||
|
@ -193,7 +194,10 @@ const getSetRowKey = (selectedRows: any[]) =>
|
|||
|
||||
const loading = ref(false);
|
||||
const handleSave = async () => {
|
||||
if (!_selectedRowKeys.value.length) message.error('请勾选数据');
|
||||
if (!_selectedRowKeys.value.length) {
|
||||
message.error('请勾选数据');
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
const resp = await CascadeApi.bindChannel(
|
||||
route.query.id as string,
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
<!-- 国标级联-通道列表 -->
|
||||
<template>
|
||||
<page-container>
|
||||
<pro-search
|
||||
type="simple"
|
||||
:columns="columns"
|
||||
target="media"
|
||||
@search="handleSearch"
|
||||
/>
|
||||
<pro-search :columns="columns" target="media" @search="handleSearch" />
|
||||
|
||||
<JProTable
|
||||
ref="listRef"
|
||||
|
@ -14,6 +9,7 @@
|
|||
:columns="columns"
|
||||
:request="(e:any) => CascadeApi.queryBindChannel(route?.query.id as string, e)"
|
||||
:defaultParams="{
|
||||
pageSize: 10,
|
||||
sorts: [{ name: 'name', order: 'desc' }],
|
||||
}"
|
||||
:params="params"
|
||||
|
@ -23,6 +19,10 @@
|
|||
onSelectAll: onSelectAllChange,
|
||||
}"
|
||||
@cancelSelect="_selectedRowKeys = []"
|
||||
:pagination="{
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ['10', '20', '50', '100'],
|
||||
}"
|
||||
>
|
||||
<template #headerTitle>
|
||||
<h3>通道列表</h3>
|
||||
|
@ -50,9 +50,9 @@
|
|||
</j-space>
|
||||
</j-tooltip>
|
||||
</template>
|
||||
<template #gbChannelId="slotProps">
|
||||
<template #channelId="slotProps">
|
||||
<j-space>
|
||||
<Ellipsis>
|
||||
<Ellipsis style="width: 150px">
|
||||
{{ slotProps.gbChannelId }}
|
||||
</Ellipsis>
|
||||
<j-popover
|
||||
|
@ -73,6 +73,7 @@
|
|||
<j-input
|
||||
v-model:value="gbID"
|
||||
@change="validField(slotProps)"
|
||||
placeholder="请输入国标ID"
|
||||
/>
|
||||
<div
|
||||
class="error"
|
||||
|
@ -152,7 +153,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import CascadeApi from '@/api/media/cascade';
|
||||
import type { ActionsType } from '@/components/Table/index.vue';
|
||||
import type { ActionsType } from '@/views/device/Instance/typings';
|
||||
import { message } from 'ant-design-vue';
|
||||
import BindChannel from './BindChannel/index.vue';
|
||||
|
||||
|
@ -175,12 +176,13 @@ const columns = [
|
|||
key: 'name',
|
||||
search: {
|
||||
type: 'string',
|
||||
first: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '国标ID',
|
||||
dataIndex: 'gbChannelId',
|
||||
key: 'gbChannelId',
|
||||
dataIndex: 'channelId',
|
||||
key: 'channelId',
|
||||
scopedSlots: true,
|
||||
headerCell: 'gbChannelIdHeader', // 表头单元格插槽
|
||||
search: {
|
||||
|
@ -204,7 +206,7 @@ const columns = [
|
|||
},
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
title: '在线状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
scopedSlots: true,
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
message: '请输入名称',
|
||||
},
|
||||
{
|
||||
max: 84,
|
||||
message: '最多可输入84个字符',
|
||||
max: 64,
|
||||
message: '最多可输入64个字符',
|
||||
},
|
||||
]"
|
||||
>
|
||||
|
@ -238,6 +238,7 @@
|
|||
v-model:value="formData.host"
|
||||
placeholder="请选择IP地址"
|
||||
:options="allList"
|
||||
@change="setPorts"
|
||||
/>
|
||||
</j-col>
|
||||
<j-col :span="10">
|
||||
|
@ -301,7 +302,7 @@
|
|||
<j-radio-group
|
||||
button-style="solid"
|
||||
v-model:value="formData.transport"
|
||||
@change="setPorts"
|
||||
@change="handleTransportChange"
|
||||
>
|
||||
<j-radio-button value="UDP">
|
||||
UDP
|
||||
|
@ -566,31 +567,31 @@ const route = useRoute();
|
|||
// 表单数据
|
||||
const formData = ref({
|
||||
id: route.query.id || undefined,
|
||||
// name: '',
|
||||
cascadeName: '',
|
||||
// name: undefined,
|
||||
cascadeName: undefined,
|
||||
proxyStream: false,
|
||||
// 以下字段, 提交时需提取到sipConfigs[{}]字段当中
|
||||
clusterNodeId: '',
|
||||
name: '',
|
||||
sipId: '',
|
||||
domain: '',
|
||||
remoteAddress: '',
|
||||
clusterNodeId: undefined,
|
||||
name: undefined,
|
||||
sipId: undefined,
|
||||
domain: undefined,
|
||||
remoteAddress: undefined,
|
||||
remotePort: undefined,
|
||||
localSipId: '',
|
||||
host: '',
|
||||
localSipId: undefined,
|
||||
host: undefined,
|
||||
port: undefined,
|
||||
// remotePublic: {
|
||||
// host: '',
|
||||
// host: undefined,
|
||||
// port: undefined,
|
||||
// },
|
||||
publicHost: '',
|
||||
publicHost: undefined,
|
||||
publicPort: undefined,
|
||||
transport: 'UDP',
|
||||
user: '',
|
||||
password: '',
|
||||
manufacturer: '',
|
||||
model: '',
|
||||
firmware: '',
|
||||
user: undefined,
|
||||
password: undefined,
|
||||
manufacturer: undefined,
|
||||
model: undefined,
|
||||
firmware: undefined,
|
||||
keepaliveInterval: '60',
|
||||
registerInterval: '3600',
|
||||
});
|
||||
|
@ -616,19 +617,29 @@ const getAllList = async () => {
|
|||
allList.value = result.map((m: any) => ({
|
||||
label: m.host,
|
||||
value: m.host,
|
||||
...m,
|
||||
}));
|
||||
setPorts();
|
||||
};
|
||||
getAllList();
|
||||
|
||||
const handleTransportChange = () => {
|
||||
formData.value.host = undefined;
|
||||
formData.value.port = undefined;
|
||||
setPorts();
|
||||
};
|
||||
/**
|
||||
* 传输协议改变, 获取对应的端口
|
||||
* 获取端口
|
||||
*/
|
||||
const allListPorts = ref([]);
|
||||
const setPorts = () => {
|
||||
allListPorts.value = allList.value.find(
|
||||
(f: any) => f.host === formData.value.host,
|
||||
)?.ports[formData.value.transport || ''];
|
||||
if (!formData.value.host) return;
|
||||
allListPorts.value = allList.value
|
||||
.find((f: any) => f.host === formData.value.host)
|
||||
?.ports[formData.value.transport || '']?.map((m: string) => ({
|
||||
label: m,
|
||||
value: m,
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -141,7 +141,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import CascadeApi from '@/api/media/cascade';
|
||||
import type { ActionsType } from '@/components/Table/index.vue';
|
||||
import type { ActionsType } from '@/views/device/Instance/typings';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { getImage } from '@/utils/comm';
|
||||
import Publish from './Publish/index.vue';
|
||||
|
@ -180,12 +180,14 @@ const columns = [
|
|||
title: '通道数量',
|
||||
dataIndex: 'count',
|
||||
key: 'count',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
scopedSlots: true,
|
||||
width: 100,
|
||||
search: {
|
||||
type: 'select',
|
||||
options: [
|
||||
|
@ -202,6 +204,7 @@ const columns = [
|
|||
dataIndex: 'onlineStatus',
|
||||
key: 'onlineStatus',
|
||||
scopedSlots: true,
|
||||
width: 100,
|
||||
search: {
|
||||
type: 'select',
|
||||
options: [
|
||||
|
@ -237,20 +240,12 @@ const handleSearch = (e: any) => {
|
|||
const lastValueFrom = async (params: any) => {
|
||||
const res = await CascadeApi.list(params);
|
||||
res.result.data.forEach(async (item: any) => {
|
||||
const resp = await queryChannelCount(item.id);
|
||||
const resp = await CascadeApi.queryBindChannel(item.id, {});
|
||||
item.count = resp.result.total;
|
||||
});
|
||||
return res;
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询通道数量
|
||||
* @param id
|
||||
*/
|
||||
const queryChannelCount = async (id: string) => {
|
||||
return await CascadeApi.queryBindChannel(id, {});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*/
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<div class="top-card-content">
|
||||
<div class="content-left">
|
||||
<div class="content-left-title">
|
||||
<j-space>
|
||||
<span>{{ title }}</span>
|
||||
<j-tooltip placement="top" v-if="tooltip">
|
||||
<template #title>
|
||||
|
@ -10,6 +11,7 @@
|
|||
</template>
|
||||
<AIcon type="QuestionCircleOutlined" />
|
||||
</j-tooltip>
|
||||
</j-space>
|
||||
</div>
|
||||
<div class="content-left-value">{{ value }}</div>
|
||||
</div>
|
||||
|
|
|
@ -28,13 +28,18 @@
|
|||
|
||||
<JProTable
|
||||
ref="listRef"
|
||||
model="table"
|
||||
:columns="columns"
|
||||
:request="(e:any) => ChannelApi.list(e, route?.query.id as string)"
|
||||
:defaultParams="{
|
||||
pageSize: 10,
|
||||
sorts: [{ name: 'notifyTime', order: 'desc' }],
|
||||
}"
|
||||
:params="params"
|
||||
model="table"
|
||||
:pagination="{
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ['10', '20', '50', '100'],
|
||||
}"
|
||||
>
|
||||
<template #headerTitle>
|
||||
<j-tooltip
|
||||
|
@ -109,7 +114,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import ChannelApi from '@/api/media/channel';
|
||||
import type { ActionsType } from '@/components/Table/index.vue';
|
||||
import type { ActionsType } from '@/views/device/Instance/typings';
|
||||
import { useMenuStore } from 'store/menu';
|
||||
import { message } from 'ant-design-vue';
|
||||
import Save from './Save.vue';
|
||||
|
@ -136,6 +141,7 @@ const columns = [
|
|||
key: 'name',
|
||||
search: {
|
||||
type: 'string',
|
||||
first: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
sorts: [{ name: 'createTime', order: 'desc' }],
|
||||
}"
|
||||
:params="params"
|
||||
:gridColumn="3"
|
||||
>
|
||||
<template #headerTitle>
|
||||
<PermissionButton
|
||||
|
@ -119,7 +120,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import DeviceApi from '@/api/media/device';
|
||||
import type { ActionsType } from '@/components/Table/index.vue';
|
||||
import type { ActionsType } from '@/views/device/Instance/typings';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { getImage } from '@/utils/comm';
|
||||
import { PROVIDER_OPTIONS } from '@/views/media/Device/const';
|
||||
|
@ -147,6 +148,7 @@ const columns = [
|
|||
key: 'name',
|
||||
search: {
|
||||
type: 'string',
|
||||
first: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
:columns="columns"
|
||||
:request="deviceApi.list"
|
||||
:defaultParams="{
|
||||
pageSize: 10,
|
||||
sorts: [{ name: 'createTime', order: 'desc' }],
|
||||
}"
|
||||
:params="params"
|
||||
|
@ -56,7 +57,14 @@
|
|||
deviceItem = record;
|
||||
}
|
||||
}"
|
||||
:pagination="{
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ['10', '20', '50', '100'],
|
||||
}"
|
||||
>
|
||||
<template #channelNumber="slotProps">
|
||||
<span>{{ slotProps.channelNumber || 0 }}</span>
|
||||
</template>
|
||||
<template #state="slotProps">
|
||||
<a-space>
|
||||
<a-badge
|
||||
|
@ -160,12 +168,14 @@ const columns = [
|
|||
key: 'name',
|
||||
search: {
|
||||
type: 'string',
|
||||
first: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '通道数量',
|
||||
dataIndex: 'channelNumber',
|
||||
key: 'channelNumber',
|
||||
scopedSlots: true,
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<!-- 调试 -->
|
||||
<template>
|
||||
<j-modal
|
||||
v-model:visible="_vis"
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
<!-- 通知记录 -->
|
||||
<template>
|
||||
<j-modal v-model:visible="_vis" title="通知记录" :footer="null" width="70%">
|
||||
<pro-search
|
||||
type="simple"
|
||||
:columns="columns"
|
||||
@search="handleSearch"
|
||||
/>
|
||||
<pro-search type="simple" :columns="columns" @search="handleSearch" />
|
||||
|
||||
<JProTable
|
||||
ref="instanceRef"
|
||||
ref="logRef"
|
||||
model="table"
|
||||
:columns="columns"
|
||||
:request="(e:any) => configApi.getHistory(e, data.id)"
|
||||
:defaultParams="{
|
||||
pageSize: 5,
|
||||
sorts: [{ name: 'notifyTime', order: 'desc' }],
|
||||
terms: [{ column: 'notifyType$IN', value: data.type }],
|
||||
}"
|
||||
:params="params"
|
||||
model="table"
|
||||
:pagination="{
|
||||
pageSizeOptions: ['5', '10', '20', '50', '100'],
|
||||
}"
|
||||
>
|
||||
<template #notifyTime="slotProps">
|
||||
{{ moment(slotProps.notifyTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
|
@ -127,9 +128,7 @@ const params = ref<Record<string, any>>({});
|
|||
* @param params
|
||||
*/
|
||||
const handleSearch = (e: any) => {
|
||||
// console.log('handleSearch e:', e);
|
||||
params.value = e;
|
||||
// console.log('params.value: ', params.value);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -169,5 +168,3 @@ const handleDetail = (e: any) => {
|
|||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<!-- 同步用户 -->
|
||||
<template>
|
||||
<div>
|
||||
<j-modal
|
||||
|
@ -46,8 +47,9 @@
|
|||
total: dataSource.length,
|
||||
current: current,
|
||||
pageSize: pageSize,
|
||||
pageSizeOptions: ['12', '24', '48', '96'],
|
||||
pageSizeOptions: ['5', '10', '20', '50', '100'],
|
||||
showSizeChanger: true,
|
||||
hideOnSinglePage: true,
|
||||
showTotal: (total: number, range: number) => `第 ${range[0]} - ${range[1]} 条/总共 ${total} 条`,
|
||||
}"
|
||||
@change="handleTableChange"
|
||||
|
@ -133,9 +135,8 @@
|
|||
<script setup lang="ts" name="SyncUser">
|
||||
import configApi from '@/api/notice/config';
|
||||
import { PropType } from 'vue';
|
||||
import moment from 'moment';
|
||||
import { Modal, message } from 'ant-design-vue';
|
||||
import type { ActionsType } from '@/components/Table/index.vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import type { ActionsType } from '@/views/device/Instance/typings';
|
||||
import { Form } from 'ant-design-vue';
|
||||
|
||||
const useForm = Form.useForm;
|
||||
|
@ -384,7 +385,7 @@ const getTableData = () => {
|
|||
* 前端分页
|
||||
*/
|
||||
const current = ref(1);
|
||||
const pageSize = ref(12);
|
||||
const pageSize = ref(5);
|
||||
const handleTableChange = (pagination: any) => {
|
||||
current.value = pagination.current;
|
||||
pageSize.value = pagination.pageSize;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<!-- 通知配置 -->
|
||||
<template>
|
||||
<page-container>
|
||||
<pro-search
|
||||
|
@ -24,7 +25,7 @@
|
|||
>
|
||||
新增
|
||||
</PermissionButton>
|
||||
<a-upload
|
||||
<j-upload
|
||||
name="file"
|
||||
accept=".json"
|
||||
:showUploadList="false"
|
||||
|
@ -33,7 +34,7 @@
|
|||
<PermissionButton hasPermission="notice/Config:import">
|
||||
导入
|
||||
</PermissionButton>
|
||||
</a-upload>
|
||||
</j-upload>
|
||||
<j-popconfirm
|
||||
title="确认导出?"
|
||||
ok-text="确定"
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<!-- 调试 -->
|
||||
<template>
|
||||
<j-modal
|
||||
v-model:visible="_vis"
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
>
|
||||
<j-input v-model:value="item.name" @change="emitEvents">
|
||||
<template #addonAfter>
|
||||
<a-upload
|
||||
<j-upload
|
||||
name="file"
|
||||
:action="FILE_UPLOAD"
|
||||
:headers="{
|
||||
|
@ -18,7 +18,7 @@
|
|||
@change="(e) => handleChange(e, item.id)"
|
||||
>
|
||||
<upload-outlined />
|
||||
</a-upload>
|
||||
</j-upload>
|
||||
</template>
|
||||
</j-input>
|
||||
<delete-outlined
|
||||
|
|
|
@ -13,19 +13,22 @@
|
|||
import templateApi from '@/api/notice/template';
|
||||
|
||||
type Emits = {
|
||||
(e: 'update:toParty', data: string): void;
|
||||
(e: 'update:toParty', data: string | undefined): void;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
toParty: string | undefined;
|
||||
type: string | undefined;
|
||||
configId: string | undefined;
|
||||
}
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const props = defineProps({
|
||||
toParty: { type: String, default: '' },
|
||||
type: { type: String, default: '' },
|
||||
configId: { type: String, default: '' },
|
||||
});
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const _value = computed({
|
||||
get: () => props.toParty,
|
||||
set: (val: string) => emit('update:toParty', val),
|
||||
set: (val: string | undefined) => emit('update:toParty', val),
|
||||
});
|
||||
const typeObj = {
|
||||
weixin: 'wechat',
|
||||
|
|
|
@ -13,19 +13,21 @@
|
|||
import templateApi from '@/api/notice/template';
|
||||
|
||||
type Emits = {
|
||||
(e: 'update:toTag', data: string): void;
|
||||
(e: 'update:toTag', data: string | undefined): void;
|
||||
};
|
||||
type Props = {
|
||||
toTag: string | undefined;
|
||||
type: string | undefined;
|
||||
configId: string | undefined;
|
||||
}
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const props = defineProps({
|
||||
toTag: { type: String, default: '' },
|
||||
type: { type: String, default: '' },
|
||||
configId: { type: String, default: '' },
|
||||
});
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const _value = computed({
|
||||
get: () => props.toTag,
|
||||
set: (val: string) => emit('update:toTag', val),
|
||||
set: (val: string | undefined) => emit('update:toTag', val),
|
||||
});
|
||||
|
||||
const options = ref([]);
|
||||
|
|
|
@ -13,19 +13,21 @@
|
|||
import templateApi from '@/api/notice/template';
|
||||
|
||||
type Emits = {
|
||||
(e: 'update:toUser', data: string): void;
|
||||
(e: 'update:toUser', data: string | undefined): void;
|
||||
};
|
||||
type Props = {
|
||||
toUser: string | undefined;
|
||||
type: string | undefined;
|
||||
configId: string | undefined;
|
||||
}
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const props = defineProps({
|
||||
toUser: { type: String, default: '' },
|
||||
type: { type: String, default: '' },
|
||||
configId: { type: String, default: '' },
|
||||
});
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const _value = computed({
|
||||
get: () => props.toUser,
|
||||
set: (val: string) => emit('update:toUser', val),
|
||||
set: (val: string | undefined) => emit('update:toUser', val),
|
||||
});
|
||||
|
||||
const typeObj = {
|
||||
|
|
|
@ -820,49 +820,49 @@ const resetPublicFiles = () => {
|
|||
formData.value.template = {};
|
||||
switch (formData.value.provider) {
|
||||
case 'dingTalkMessage':
|
||||
formData.value.template.agentId = '';
|
||||
formData.value.template.message = '';
|
||||
formData.value.template.departmentIdList = '';
|
||||
formData.value.template.userIdList = '';
|
||||
formData.value.template.agentId = undefined;
|
||||
formData.value.template.message = undefined;
|
||||
formData.value.template.departmentIdList = undefined;
|
||||
formData.value.template.userIdList = undefined;
|
||||
break;
|
||||
case 'dingTalkRobotWebHook':
|
||||
formData.value.template.message = '';
|
||||
formData.value.template.message = undefined;
|
||||
formData.value.template.messageType = 'markdown';
|
||||
formData.value.template.markdown = { text: '', title: '' };
|
||||
formData.value.template.markdown = { text: undefined, title: undefined };
|
||||
break;
|
||||
case 'corpMessage':
|
||||
formData.value.template.agentId = '';
|
||||
formData.value.template.message = '';
|
||||
formData.value.template.toParty = '';
|
||||
formData.value.template.toUser = '';
|
||||
formData.value.template.toTag = '';
|
||||
formData.value.template.agentId = undefined;
|
||||
formData.value.template.message = undefined;
|
||||
formData.value.template.toParty = undefined;
|
||||
formData.value.template.toUser = undefined;
|
||||
formData.value.template.toTag = undefined;
|
||||
break;
|
||||
case 'embedded':
|
||||
formData.value.template.subject = '';
|
||||
formData.value.template.message = '';
|
||||
formData.value.template.text = '';
|
||||
formData.value.template.subject = undefined;
|
||||
formData.value.template.message = undefined;
|
||||
formData.value.template.text = undefined;
|
||||
formData.value.template.sendTo = [];
|
||||
formData.value.template.attachments = [];
|
||||
break;
|
||||
case 'aliyun':
|
||||
formData.value.template.templateType = 'tts';
|
||||
formData.value.template.templateCode = '';
|
||||
formData.value.template.ttsCode = '';
|
||||
// formData.value.template.message = '';
|
||||
formData.value.template.ttsmessage = '';
|
||||
formData.value.template.templateCode = undefined;
|
||||
formData.value.template.ttsCode = undefined;
|
||||
// formData.value.template.message = undefined;
|
||||
formData.value.template.ttsmessage = undefined;
|
||||
formData.value.template.playTimes = 1;
|
||||
formData.value.template.calledShowNumbers = '';
|
||||
formData.value.template.calledNumber = '';
|
||||
formData.value.template.calledShowNumbers = undefined;
|
||||
formData.value.template.calledNumber = undefined;
|
||||
break;
|
||||
case 'aliyunSms':
|
||||
formData.value.template.code = '';
|
||||
formData.value.template.message = '';
|
||||
formData.value.template.phoneNumber = '';
|
||||
formData.value.template.signName = '';
|
||||
formData.value.template.code = undefined;
|
||||
formData.value.template.message = undefined;
|
||||
formData.value.template.phoneNumber = undefined;
|
||||
formData.value.template.signName = undefined;
|
||||
break;
|
||||
case 'http':
|
||||
formData.value.template.contextAsBody = true;
|
||||
formData.value.template.body = '';
|
||||
formData.value.template.body = undefined;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1012,7 +1012,10 @@ const { resetFields, validate, validateInfos, clearValidate } = useForm(
|
|||
watch(
|
||||
() => formData.value.template.markdown?.title,
|
||||
(val) => {
|
||||
if (!val) return;
|
||||
if (!val) {
|
||||
formData.value.variableDefinitions = [];
|
||||
return;
|
||||
}
|
||||
variableReg();
|
||||
},
|
||||
{ deep: true },
|
||||
|
@ -1021,7 +1024,10 @@ watch(
|
|||
watch(
|
||||
() => formData.value.template.link?.title,
|
||||
(val) => {
|
||||
if (!val) return;
|
||||
if (!val) {
|
||||
formData.value.variableDefinitions = [];
|
||||
return;
|
||||
}
|
||||
variableReg();
|
||||
},
|
||||
{ deep: true },
|
||||
|
@ -1030,7 +1036,10 @@ watch(
|
|||
watch(
|
||||
() => formData.value.template.subject,
|
||||
(val) => {
|
||||
if (!val) return;
|
||||
if (!val) {
|
||||
formData.value.variableDefinitions = [];
|
||||
return;
|
||||
}
|
||||
variableReg();
|
||||
},
|
||||
{ deep: true },
|
||||
|
@ -1040,7 +1049,10 @@ watch(
|
|||
watch(
|
||||
() => formData.value.template.message,
|
||||
(val) => {
|
||||
if (!val) return;
|
||||
if (!val) {
|
||||
formData.value.variableDefinitions = [];
|
||||
return;
|
||||
}
|
||||
variableReg();
|
||||
},
|
||||
{ deep: true },
|
||||
|
@ -1049,7 +1061,10 @@ watch(
|
|||
watch(
|
||||
() => formData.value.template.ttsmessage,
|
||||
(val) => {
|
||||
if (!val) return;
|
||||
if (!val) {
|
||||
formData.value.variableDefinitions = [];
|
||||
return;
|
||||
}
|
||||
variableReg();
|
||||
},
|
||||
{ deep: true },
|
||||
|
@ -1058,7 +1073,10 @@ watch(
|
|||
watch(
|
||||
() => formData.value.template.body,
|
||||
(val) => {
|
||||
if (!val) return;
|
||||
if (!val) {
|
||||
formData.value.variableDefinitions = [];
|
||||
return;
|
||||
}
|
||||
variableReg();
|
||||
},
|
||||
{ deep: true },
|
||||
|
@ -1162,7 +1180,10 @@ const getConfigList = async () => {
|
|||
{ column: 'type$IN', value: formData.value.type },
|
||||
{ column: 'provider', value: formData.value.provider },
|
||||
];
|
||||
const { result } = await templateApi.getConfig({ terms });
|
||||
const { result } = await templateApi.getConfig({
|
||||
terms,
|
||||
sorts: [{ name: 'createTime', order: 'desc' }],
|
||||
});
|
||||
configList.value = result;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
<!-- 通知记录 -->
|
||||
<template>
|
||||
<j-modal v-model:visible="_vis" title="通知记录" :footer="null" width="70%">
|
||||
<pro-search
|
||||
type="simple"
|
||||
:columns="columns"
|
||||
@search="handleSearch"
|
||||
/>
|
||||
<pro-search type="simple" :columns="columns" @search="handleSearch" />
|
||||
|
||||
<JProTable
|
||||
ref="instanceRef"
|
||||
ref="logRef"
|
||||
model="table"
|
||||
:columns="columns"
|
||||
:request="(e:any) => templateApi.getHistory(e, data.id)"
|
||||
:defaultParams="{
|
||||
pageSize: 5,
|
||||
sorts: [{ name: 'notifyTime', order: 'desc' }],
|
||||
terms: [{ column: 'notifyType$IN', value: data.type }],
|
||||
}"
|
||||
:params="params"
|
||||
model="table"
|
||||
:pagination="{
|
||||
pageSizeOptions: ['5', '10', '20', '50', '100'],
|
||||
}"
|
||||
>
|
||||
<template #notifyTime="slotProps">
|
||||
{{ moment(slotProps.notifyTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
|
@ -127,9 +128,7 @@ const params = ref<Record<string, any>>({});
|
|||
* @param params
|
||||
*/
|
||||
const handleSearch = (e: any) => {
|
||||
// console.log('handleSearch e:', e);
|
||||
params.value = e;
|
||||
// console.log('params.value: ', params.value);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -169,5 +168,3 @@ const handleDetail = (e: any) => {
|
|||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<!-- 通知模板 -->
|
||||
<template>
|
||||
<page-container>
|
||||
<pro-search
|
||||
|
@ -24,7 +25,7 @@
|
|||
>
|
||||
新增
|
||||
</PermissionButton>
|
||||
<a-upload
|
||||
<j-upload
|
||||
name="file"
|
||||
accept=".json"
|
||||
:showUploadList="false"
|
||||
|
@ -35,7 +36,7 @@
|
|||
>
|
||||
导入
|
||||
</PermissionButton>
|
||||
</a-upload>
|
||||
</j-upload>
|
||||
<j-popconfirm
|
||||
title="确认导出?"
|
||||
ok-text="确定"
|
||||
|
@ -154,7 +155,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import TemplateApi from '@/api/notice/template';
|
||||
import type { ActionsType } from '@/components/Table/index.vue';
|
||||
import type { ActionsType } from '@/views/device/Instance/typings';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { NOTICE_METHOD, MSG_TYPE } from '@/views/notice/const';
|
||||
import Debug from './Debug/index.vue';
|
||||
|
|
|
@ -94,42 +94,42 @@ export const MSG_TYPE = {
|
|||
export const CONFIG_FIELD_MAP = {
|
||||
dingTalk: {
|
||||
dingTalkMessage: {
|
||||
appKey: '',
|
||||
appSecret: '',
|
||||
appKey: undefined,
|
||||
appSecret: undefined,
|
||||
},
|
||||
dingTalkRobotWebHook: {
|
||||
url: '',
|
||||
url: undefined,
|
||||
}
|
||||
},
|
||||
weixin: {
|
||||
corpMessage: {
|
||||
corpId: '',
|
||||
corpSecret: '',
|
||||
corpId: undefined,
|
||||
corpSecret: undefined,
|
||||
},
|
||||
// officialMessage: {},
|
||||
},
|
||||
email: {
|
||||
embedded: {
|
||||
host: '',
|
||||
host: undefined,
|
||||
port: 25,
|
||||
ssl: false,
|
||||
sender: '',
|
||||
username: '',
|
||||
password: '',
|
||||
sender: undefined,
|
||||
username: undefined,
|
||||
password: undefined,
|
||||
}
|
||||
},
|
||||
voice: {
|
||||
aliyun: {
|
||||
regionId: '',
|
||||
accessKeyId: '',
|
||||
secret: '',
|
||||
regionId: undefined,
|
||||
accessKeyId: undefined,
|
||||
secret: undefined,
|
||||
}
|
||||
},
|
||||
sms: {
|
||||
aliyunSms: {
|
||||
regionId: '',
|
||||
accessKeyId: '',
|
||||
secret: '',
|
||||
regionId: undefined,
|
||||
accessKeyId: undefined,
|
||||
secret: undefined,
|
||||
}
|
||||
},
|
||||
webhook: {
|
||||
|
@ -145,69 +145,69 @@ export const CONFIG_FIELD_MAP = {
|
|||
export const TEMPLATE_FIELD_MAP = {
|
||||
dingTalk: {
|
||||
dingTalkMessage: {
|
||||
agentId: '',
|
||||
message: '',
|
||||
departmentIdList: '',
|
||||
userIdList: ''
|
||||
agentId: undefined,
|
||||
message: undefined,
|
||||
departmentIdList: undefined,
|
||||
userIdList: undefined
|
||||
},
|
||||
dingTalkRobotWebHook: {
|
||||
message: '',
|
||||
message: undefined,
|
||||
messageType: 'markdown',
|
||||
markdown: {
|
||||
text: '',
|
||||
title: '',
|
||||
text: undefined,
|
||||
title: undefined,
|
||||
},
|
||||
link: {
|
||||
title: '',
|
||||
picUrl: '',
|
||||
messageUrl: '',
|
||||
text: '',
|
||||
title: undefined,
|
||||
picUrl: undefined,
|
||||
messageUrl: undefined,
|
||||
text: undefined,
|
||||
},
|
||||
}
|
||||
},
|
||||
weixin: {
|
||||
corpMessage: {
|
||||
agentId: '',
|
||||
message: '',
|
||||
toParty: '',
|
||||
toUser: '',
|
||||
toTag: '',
|
||||
agentId: undefined,
|
||||
message: undefined,
|
||||
toParty: undefined,
|
||||
toUser: undefined,
|
||||
toTag: undefined,
|
||||
},
|
||||
officialMessage: {},
|
||||
},
|
||||
email: {
|
||||
embedded: {
|
||||
subject: '',
|
||||
subject: undefined,
|
||||
sendTo: [],
|
||||
attachments: [],
|
||||
message: '',
|
||||
text: '',
|
||||
message: undefined,
|
||||
text: undefined,
|
||||
}
|
||||
},
|
||||
voice: {
|
||||
aliyun: {
|
||||
templateType: 'tts',
|
||||
templateCode: '',
|
||||
ttsCode: '',
|
||||
// message: '',
|
||||
ttsmessage: '',
|
||||
templateCode: undefined,
|
||||
ttsCode: undefined,
|
||||
// message: undefined,
|
||||
ttsmessage: undefined,
|
||||
playTimes: 1,
|
||||
calledShowNumbers: '',
|
||||
calledNumber: '',
|
||||
calledShowNumbers: undefined,
|
||||
calledNumber: undefined,
|
||||
}
|
||||
},
|
||||
sms: {
|
||||
aliyunSms: {
|
||||
code: '',
|
||||
message: '',
|
||||
phoneNumber: '',
|
||||
signName: '',
|
||||
code: undefined,
|
||||
message: undefined,
|
||||
phoneNumber: undefined,
|
||||
signName: undefined,
|
||||
}
|
||||
},
|
||||
webhook: {
|
||||
http: {
|
||||
contextAsBody: true,
|
||||
body: ''
|
||||
body: undefined
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -53,9 +53,8 @@ const props = defineProps({
|
|||
const productList = ref<Record<string, any>[]>([]);
|
||||
const loading = ref<boolean>(false);
|
||||
const formRef = ref();
|
||||
let id = ref<string>();
|
||||
const modelRef = ref();
|
||||
modelRef.value = props.data
|
||||
modelRef.value = {...props.data};
|
||||
const rules = {
|
||||
name: [
|
||||
{
|
||||
|
|
|
@ -245,6 +245,9 @@ const getActions = (
|
|||
title: '查看',
|
||||
},
|
||||
icon: 'EyeOutlined',
|
||||
onClick: () => {
|
||||
openRuleEditor(data);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'action',
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
</AddButton>
|
||||
</a-form-item>
|
||||
<Terms />
|
||||
<Action />
|
||||
<AddModel v-if='visible' @cancel='visible = false' @save='save' :value='data.trigger.device' :options='data.options.trigger' />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -13,20 +13,28 @@
|
|||
import { useSceneStore } from '@/store/scene';
|
||||
import Action from '../action/index.vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { ActionsType } from '@/views/rule-engine/Scene/typings';
|
||||
|
||||
const sceneStore = useSceneStore();
|
||||
const { data } = storeToRefs(sceneStore);
|
||||
|
||||
const onActionAdd = (_data: any) => {
|
||||
if (data.value?.branches && _data) {
|
||||
data?.value.branches?.[0].then.push(_data)
|
||||
console.log(data?.value.branches?.[0].then)
|
||||
const newThen = [...data.value.branches[0].then, _data];
|
||||
data.value.branches![0].then = newThen
|
||||
}
|
||||
};
|
||||
|
||||
const onActionUpdate = (_data: ActionsType, type: boolean) => {
|
||||
console.log(_data, type)
|
||||
const onActionUpdate = (_data: any, type: boolean) => {
|
||||
const indexOf = data.value.branches![0].then.findIndex(
|
||||
(item) => item.parallel === type,
|
||||
);
|
||||
if (indexOf !== -1) {
|
||||
if (_data?.actions?.length) {
|
||||
data.value.branches![0].then[indexOf] = _data;
|
||||
} else {
|
||||
data.value.branches![0].then[indexOf].actions = [];
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
@ok="onOk"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<a-input-number
|
||||
<j-input-number
|
||||
style="max-width: 220px"
|
||||
placeholder="请输入时间"
|
||||
v-model:value="_value"
|
||||
|
@ -16,7 +16,7 @@
|
|||
:max="6535"
|
||||
>
|
||||
<template #addonAfter>
|
||||
<a-select
|
||||
<j-select
|
||||
:options="[
|
||||
{ label: '秒', value: 'seconds' },
|
||||
{ label: '分', value: 'minutes' },
|
||||
|
@ -25,7 +25,7 @@
|
|||
v-model:value="unit"
|
||||
/>
|
||||
</template>
|
||||
</a-input-number>
|
||||
</j-input-number>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<template>
|
||||
<j-advanced-search
|
||||
<pro-search
|
||||
:columns="columns"
|
||||
type="simple"
|
||||
@search="handleSearch"
|
||||
class="search"
|
||||
target="scene-trigger-device-product"
|
||||
/>
|
||||
<a-divider style="margin: 0" />
|
||||
<j-divider style="margin: 0" />
|
||||
<j-pro-table
|
||||
ref="actionRef"
|
||||
model="CARD"
|
||||
|
@ -48,16 +48,16 @@
|
|||
</span>
|
||||
</Ellipsis>
|
||||
</div>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<j-row>
|
||||
<j-col :span="12">
|
||||
<div class="card-item-content-text">设备类型</div>
|
||||
<Ellipsis>{{ slotProps.deviceType?.text }}</Ellipsis>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
</j-col>
|
||||
<j-col :span="12">
|
||||
<div class="card-item-content-text">接入方式</div>
|
||||
<Ellipsis>{{ slotProps?.accessName || '未接入' }}</Ellipsis>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</j-col>
|
||||
</j-row>
|
||||
</template>
|
||||
</CardBox>
|
||||
</template>
|
||||
|
|
|
@ -15,13 +15,16 @@
|
|||
</template>
|
||||
<template v-else>
|
||||
<ParamsDropdown
|
||||
icon="icon-canshu"
|
||||
placeholder="请选择"
|
||||
:options="[]"
|
||||
:tabsOptions="tabOptions"
|
||||
:metricOption="upperOptions(record.valueType)"
|
||||
v-model:value="record.value"
|
||||
/>
|
||||
>
|
||||
<template v-slot="{label}">
|
||||
<j-input :value="label" />
|
||||
</template>
|
||||
</ParamsDropdown>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-form :layout="'vertical'" ref="formRef" :model="modelRef">
|
||||
<j-form :layout="'vertical'" ref="formRef" :model="modelRef">
|
||||
<j-row>
|
||||
<j-col :span="11">
|
||||
<j-form-item
|
||||
|
@ -40,7 +40,7 @@
|
|||
</j-form-item>
|
||||
</j-col>
|
||||
</j-row>
|
||||
</a-form>
|
||||
</j-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-form :layout="'vertical'" ref="formRef" :model="modelRef">
|
||||
<j-form :layout="'vertical'" ref="formRef" :model="modelRef">
|
||||
<j-form-item
|
||||
:name="['message', 'messageType']"
|
||||
label="动作类型"
|
||||
|
@ -67,7 +67,7 @@
|
|||
:builtInList="builtInList"
|
||||
/>
|
||||
</template>
|
||||
</a-form>
|
||||
</j-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -211,6 +211,7 @@ watch(
|
|||
watch(
|
||||
() => props.values?.message,
|
||||
(newVal) => {
|
||||
console.log(newVal)
|
||||
if (newVal?.messageType) {
|
||||
modelRef.message = newVal;
|
||||
if (newVal.messageType === 'INVOKE_FUNCTION' && newVal.functionId) {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<template>
|
||||
<j-advanced-search
|
||||
<pro-search
|
||||
:columns="columns"
|
||||
type="simple"
|
||||
@search="handleSearch"
|
||||
class="search"
|
||||
target="scene-trigger-device-device"
|
||||
/>
|
||||
<a-divider style="margin: 0" />
|
||||
<j-divider style="margin: 0" />
|
||||
<j-pro-table
|
||||
ref="actionRef"
|
||||
model="CARD"
|
||||
|
@ -153,7 +153,7 @@ const deviceQuery = (p: any) => {
|
|||
if (props.value) {
|
||||
sorts.push({
|
||||
name: 'id',
|
||||
value: props.value,
|
||||
value: props.value[0]?.value,
|
||||
});
|
||||
}
|
||||
sorts.push({ name: 'createTime', order: 'desc' });
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-form :layout="'vertical'" ref="formRef" :model="modelRef">
|
||||
<j-form :layout="'vertical'" ref="formRef" :model="modelRef">
|
||||
<j-form-item
|
||||
name="selector"
|
||||
label="选择方式"
|
||||
|
@ -64,16 +64,16 @@
|
|||
:fieldNames="{ label: 'name', value: 'id' }"
|
||||
>
|
||||
<template #title="{ name, description }">
|
||||
<a-space>
|
||||
<j-space>
|
||||
{{ name }}
|
||||
<span style="color: grey; margin-left: 5px">{{
|
||||
description
|
||||
}}</span>
|
||||
</a-space>
|
||||
</j-space>
|
||||
</template>
|
||||
</j-tree-select>
|
||||
</j-form-item>
|
||||
</a-form>
|
||||
</j-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -0,0 +1,254 @@
|
|||
<template>
|
||||
<div class='terms-params-item'>
|
||||
<div v-if='!isFirst' class='term-type-warp'>
|
||||
<DropdownButton
|
||||
:options='[
|
||||
{ label: "并且", value: "and" },
|
||||
{ label: "或者", value: "or" },
|
||||
]'
|
||||
type='type'
|
||||
v-model:value='paramsValue.type'
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class='params-item_button'
|
||||
@mouseover='mouseover'
|
||||
@mouseout='mouseout'
|
||||
>
|
||||
<DropdownButton
|
||||
:options='columnOptions'
|
||||
icon='icon-zhihangdongzuoxie-1'
|
||||
type='column'
|
||||
value-name='column'
|
||||
label-name='fullName'
|
||||
placeholder='请选择参数'
|
||||
v-model:value='paramsValue.column'
|
||||
component='treeSelect'
|
||||
@select='columnSelect'
|
||||
/>
|
||||
<DropdownButton
|
||||
:options='termTypeOptions'
|
||||
type="termType"
|
||||
value-name='id'
|
||||
label-name='name'
|
||||
placeholder="操作符"
|
||||
v-model:value='paramsValue.termType'
|
||||
@select='termsTypeSelect'
|
||||
/>
|
||||
<DoubleParamsDropdown
|
||||
v-if='showDouble'
|
||||
icon='icon-canshu'
|
||||
placeholder='参数值'
|
||||
:options='valueOptions'
|
||||
:metricOptions='metricOption'
|
||||
:tabsOptions='tabsOptions'
|
||||
v-model:value='paramsValue.value.value'
|
||||
v-model:source='paramsValue.value.source'
|
||||
/>
|
||||
<ParamsDropdown
|
||||
v-else
|
||||
icon='icon-canshu'
|
||||
placeholder='参数值'
|
||||
:options='valueOptions'
|
||||
:metricOptions='metricOption'
|
||||
:tabsOptions='tabsOptions'
|
||||
v-model:value='paramsValue.value.value'
|
||||
v-model:source='paramsValue.value.source'
|
||||
/>
|
||||
<j-popconfirm title='确认删除?' @confirm='onDelete'>
|
||||
<div v-show='showDelete' class='button-delete'> <AIcon type='CloseOutlined' /></div>
|
||||
</j-popconfirm>
|
||||
</div>
|
||||
<div class='term-add' @click.stop='termAdd' v-if='isLast'>
|
||||
<div class='terms-content'>
|
||||
<AIcon type='PlusOutlined' style='font-size: 12px' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang='ts' name='FilterCondition'>
|
||||
import type { PropType } from 'vue'
|
||||
import type { TermsType } from '@/views/rule-engine/Scene/typings'
|
||||
import DropdownButton from '../../components/DropdownButton'
|
||||
import { getOption } from '../../components/DropdownButton/util'
|
||||
import ParamsDropdown, { DoubleParamsDropdown } from '../../components/ParamsDropdown'
|
||||
import { inject } from 'vue'
|
||||
import { ContextKey } from '../../components/Terms/util'
|
||||
import { useSceneStore } from 'store/scene'
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
const sceneStore = useSceneStore()
|
||||
const { data: formModel } = storeToRefs(sceneStore)
|
||||
|
||||
type Emit = {
|
||||
(e: 'update:value', data: TermsType): void
|
||||
}
|
||||
|
||||
type TabsOption = {
|
||||
label: string;
|
||||
key: string;
|
||||
component: string
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
isFirst: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
isLast: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showDeleteBtn: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
name: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
termsName: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
branchName: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
thenName: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
value: {
|
||||
type: Object as PropType<TermsType>,
|
||||
default: () => ({
|
||||
column: '',
|
||||
type: '',
|
||||
termType: 'eq',
|
||||
value: {
|
||||
source: 'fixed',
|
||||
value: undefined
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits<Emit>()
|
||||
|
||||
const paramsValue = reactive<TermsType>({
|
||||
column: props.value.column,
|
||||
type: props.value.type,
|
||||
termType: props.value.termType,
|
||||
value: props.value.value
|
||||
})
|
||||
|
||||
const showDelete = ref(false)
|
||||
const columnOptions: any = inject(ContextKey) //
|
||||
const termTypeOptions = ref<Array<{ id: string, name: string}>>([]) // 条件值
|
||||
const valueOptions = ref<any[]>([]) // 默认手动输入下拉
|
||||
const metricOption = ref<any[]>([]) //
|
||||
const tabsOptions = ref<Array<TabsOption>>([{ label: '内置参数', key: 'upper', component: 'tree' }])
|
||||
// { label: '手动输入', key: 'fixed', component: 'string' },
|
||||
|
||||
|
||||
const handOptionByColumn = (option: any) => {
|
||||
if (option) {
|
||||
termTypeOptions.value = option.termTypes || []
|
||||
metricOption.value = option.metrics || []
|
||||
tabsOptions.value.length = 1
|
||||
tabsOptions.value[0].component = option.dataType
|
||||
|
||||
if (option.metrics && option.metrics.length) {
|
||||
tabsOptions.value.push(
|
||||
{ label: '指标值', key: 'metric', component: 'select' }
|
||||
)
|
||||
}
|
||||
|
||||
if (option.dataType === 'boolean') {
|
||||
valueOptions.value = [
|
||||
{ label: '是', value: true },
|
||||
{ label: '否', value: false },
|
||||
]
|
||||
} else if(option.dataType === 'enum') {
|
||||
valueOptions.value = option.options?.map((item: any) => ({ ...item, label: item.name, value: item.id})) || []
|
||||
} else{
|
||||
valueOptions.value = option.options || []
|
||||
}
|
||||
} else {
|
||||
termTypeOptions.value = []
|
||||
metricOption.value = []
|
||||
valueOptions.value = []
|
||||
}
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
const option = getOption(columnOptions.value, paramsValue.column, 'column')
|
||||
handOptionByColumn(option)
|
||||
})
|
||||
|
||||
const showDouble = computed(() => {
|
||||
const isRange = paramsValue.termType ? ['nbtw', 'btw', 'in', 'nin'].includes(paramsValue.termType) : false
|
||||
if (metricOption.value.length) {
|
||||
metricOption.value = metricOption.value.filter(item => isRange ? item.range : !item.range)
|
||||
} else {
|
||||
metricOption.value = []
|
||||
}
|
||||
return isRange
|
||||
})
|
||||
|
||||
const mouseover = () => {
|
||||
if (props.showDeleteBtn){
|
||||
showDelete.value = true
|
||||
}
|
||||
}
|
||||
|
||||
const mouseout = () => {
|
||||
if (props.showDeleteBtn){
|
||||
showDelete.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const columnSelect = () => {
|
||||
paramsValue.termType = 'eq'
|
||||
paramsValue.value = {
|
||||
source: tabsOptions.value[0].key,
|
||||
value: undefined
|
||||
}
|
||||
emit('update:value', { ...paramsValue })
|
||||
}
|
||||
|
||||
const termsTypeSelect = () => {
|
||||
paramsValue.value = {
|
||||
source: tabsOptions.value[0].key,
|
||||
value: undefined
|
||||
}
|
||||
emit('update:value', { ...paramsValue })
|
||||
}
|
||||
|
||||
const termAdd = () => {
|
||||
const terms = {
|
||||
column: undefined,
|
||||
value: {
|
||||
source: 'fixed',
|
||||
value: undefined
|
||||
},
|
||||
termType: undefined,
|
||||
type: 'and',
|
||||
key: `params_${new Date().getTime()}`
|
||||
}
|
||||
formModel.value.branches?.[props.branchName]?.then?.[props.thenName]?.actions?.[props.name].terms?.push(terms)
|
||||
}
|
||||
|
||||
const onDelete = () => {
|
||||
formModel.value.branches?.[props.branchName]?.then?.[props.thenName]?.actions?.[props.name].terms?.splice(props.name, 1)
|
||||
}
|
||||
|
||||
nextTick(() => {
|
||||
Object.assign(paramsValue, props.value)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,13 @@
|
|||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang='ts' name='FilterGroup'>
|
||||
export default {
|
||||
name: 'FilterGroup'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -19,17 +19,17 @@
|
|||
v-if="data?.executor === 'alarm'"
|
||||
>
|
||||
<template v-if="data?.alarm?.mode === 'trigger'">
|
||||
满足条件后将触发<a-button
|
||||
满足条件后将触发<j-button style="padding: 0;"
|
||||
type="link"
|
||||
@click.stop="triggerVisible = true"
|
||||
>关联此场景的告警</a-button
|
||||
>关联此场景的告警</j-button
|
||||
>
|
||||
</template>
|
||||
<template v-else>
|
||||
满足条件后将解除<a-button
|
||||
满足条件后将解除<j-button style="padding: 0;"
|
||||
type="link"
|
||||
@click.stop="triggerVisible = true"
|
||||
>关联此场景的告警</a-button
|
||||
>关联此场景的告警</j-button
|
||||
>
|
||||
</template>
|
||||
</div>
|
||||
|
@ -308,26 +308,36 @@
|
|||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<a-button v-else @click="onAdd">点击配置执行动作</a-button>
|
||||
<j-button v-else @click="onAdd">点击配置执行动作</j-button>
|
||||
</div>
|
||||
<div class="item-number">{{ name + 1 }}</div>
|
||||
<a-popconfirm title="确认删除?" @confirm="onDelete">
|
||||
<j-popconfirm title="确认删除?" @confirm="onDelete">
|
||||
<div class="item-delete">
|
||||
<AIcon type="DeleteOutlined" />
|
||||
</div>
|
||||
</a-popconfirm>
|
||||
</j-popconfirm>
|
||||
</div>
|
||||
<template v-if="!isLast && type === 'serial'">
|
||||
<div class="actions-item-filter-warp">
|
||||
<!-- filter-border -->
|
||||
<div :class='["actions-item-filter-warp", termsOptions.length ? "filter-border" : ""]'>
|
||||
<template v-if='termsOptions.length'>
|
||||
<div class='actions-item-filter-warp-tip'>
|
||||
满足此条件后执行后续动作
|
||||
</div>
|
||||
<div class='actions-item-filter-overflow'>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<div v-else class='filter-add-button'>
|
||||
<AIcon type='PlusOutlined' style='padding-right: 4px;' />
|
||||
<span>添加过滤条件</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 编辑 -->
|
||||
<template v-if="visible">
|
||||
<Modal
|
||||
:name="name"
|
||||
:branchGroup="branchGroup"
|
||||
:branchGroup="thenName"
|
||||
:branchesName="branchesName"
|
||||
:data="data"
|
||||
@cancel="onClose"
|
||||
|
@ -352,7 +362,6 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { getImage } from '@/utils/comm';
|
||||
import { isBoolean } from 'lodash-es';
|
||||
import { PropType } from 'vue';
|
||||
import { ActionsType, ParallelType } from '../../../typings';
|
||||
|
@ -361,6 +370,7 @@ import ActionTypeComponent from '../Modal/ActionTypeComponent.vue';
|
|||
import TriggerAlarm from '../TriggerAlarm/index.vue';
|
||||
import { useSceneStore } from '@/store/scene';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { iconMap, itemNotifyIconMap, typeIconMap } from './util'
|
||||
|
||||
const sceneStore = useSceneStore();
|
||||
const { data: _data } = storeToRefs(sceneStore);
|
||||
|
@ -370,7 +380,7 @@ const props = defineProps({
|
|||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
branchGroup: {
|
||||
thenName: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
|
@ -397,37 +407,17 @@ const props = defineProps({
|
|||
|
||||
const emit = defineEmits(['delete', 'update']);
|
||||
|
||||
const iconMap = new Map();
|
||||
iconMap.set('trigger', getImage('/scene/action-bind-icon.png'));
|
||||
iconMap.set('notify', getImage('/scene/action-notify-icon.png'));
|
||||
iconMap.set('device', getImage('/scene/action-device-icon.png'));
|
||||
iconMap.set('relieve', getImage('/scene/action-unbind-icon.png'));
|
||||
iconMap.set('delay', getImage('/scene/action-delay-icon.png'));
|
||||
|
||||
const itemNotifyIconMap = new Map();
|
||||
itemNotifyIconMap.set(
|
||||
'dingTalk',
|
||||
getImage('/scene/notify-item-img/dingtalk.png'),
|
||||
);
|
||||
itemNotifyIconMap.set('weixin', getImage('/scene/notify-item-img/weixin.png'));
|
||||
itemNotifyIconMap.set('email', getImage('/scene/notify-item-img/email.png'));
|
||||
itemNotifyIconMap.set('voice', getImage('/scene/notify-item-img/voice.png'));
|
||||
itemNotifyIconMap.set('sms', getImage('/scene/notify-item-img/sms.png'));
|
||||
itemNotifyIconMap.set(
|
||||
'webhook',
|
||||
getImage('/scene/notify-item-img/webhook.png'),
|
||||
);
|
||||
|
||||
const typeIconMap = {
|
||||
READ_PROPERTY: 'icon-zhihangdongzuodu',
|
||||
INVOKE_FUNCTION: 'icon-zhihangdongzuoxie-1',
|
||||
WRITE_PROPERTY: 'icon-zhihangdongzuoxie',
|
||||
};
|
||||
|
||||
const visible = ref<boolean>(false);
|
||||
const triggerVisible = ref<boolean>(false);
|
||||
const actionType = ref('');
|
||||
|
||||
const termsOptions = computed(() => {
|
||||
if (!props.parallel) { // 串行
|
||||
return _data.value.branches![props.branchesName].then?.[props.thenName].actions?.[props.name].terms || []
|
||||
}
|
||||
return []
|
||||
})
|
||||
|
||||
const onDelete = () => {
|
||||
emit('delete');
|
||||
};
|
||||
|
@ -463,6 +453,7 @@ const onPropsOk = (data: ActionsType, options?: any) => {
|
|||
const onPropsCancel = () => {
|
||||
actionType.value = '';
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
@ -582,6 +573,19 @@ const onPropsCancel = () => {
|
|||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.actions-item-filter-warp-tip {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 16px;
|
||||
z-index: 2;
|
||||
color: rgba(0, 0, 0, 0.55);
|
||||
font-weight: 800;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
background-color: #fff;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.actions-item-filter-overflow {
|
||||
display: flex;
|
||||
padding-top: 4px;
|
||||
|
@ -590,6 +594,13 @@ const onPropsCancel = () => {
|
|||
row-gap: 16px;
|
||||
}
|
||||
|
||||
.filter-add-button{
|
||||
width: 100%;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.terms-params {
|
||||
// display: inline-block;
|
||||
display: flex;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
:parallel="parallel"
|
||||
:data="item"
|
||||
:branchesName="branchesName"
|
||||
:branchGroup="parallel ? 1 : 0"
|
||||
:thenName="thenName"
|
||||
:name="index"
|
||||
:type="type"
|
||||
:isLast="index === actions.length - 1"
|
||||
|
@ -25,7 +25,7 @@
|
|||
@cancel="onCancel"
|
||||
:parallel="parallel"
|
||||
:name="actions.length"
|
||||
:branchGroup="parallel ? 1 : 0"
|
||||
:branchGroup="thenName"
|
||||
@save="onSave"
|
||||
:branchesName="branchesName"
|
||||
/>
|
||||
|
@ -38,6 +38,11 @@ import { ActionsType, ParallelType } from '../../../typings';
|
|||
import Modal from '../Modal/index.vue';
|
||||
import Item from './Item.vue';
|
||||
import { pick } from 'lodash';
|
||||
import { useSceneStore } from '@/store/scene';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
const sceneStore = useSceneStore();
|
||||
const { data: _data } = storeToRefs(sceneStore);
|
||||
|
||||
interface ListProps {
|
||||
branchesName: number;
|
||||
|
@ -47,7 +52,10 @@ interface ListProps {
|
|||
}
|
||||
|
||||
const props = defineProps({
|
||||
branchesName: Number,
|
||||
branchesName: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
type: {
|
||||
type: String as PropType<ListProps['type']>,
|
||||
default: 'serial',
|
||||
|
@ -63,6 +71,10 @@ const emit = defineEmits(['delete', 'add']);
|
|||
|
||||
const visible = ref<boolean>(false);
|
||||
|
||||
const thenName = computed(() => {
|
||||
return _data.value.branches![props.branchesName].then.findIndex(item => item.parallel === props.parallel)
|
||||
})
|
||||
|
||||
const onAdd = () => {
|
||||
visible.value = true;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
import { getImage } from '@/utils/comm'
|
||||
|
||||
export const iconMap = new Map();
|
||||
iconMap.set('trigger', getImage('/scene/action-bind-icon.png'));
|
||||
iconMap.set('notify', getImage('/scene/action-notify-icon.png'));
|
||||
iconMap.set('device', getImage('/scene/action-device-icon.png'));
|
||||
iconMap.set('relieve', getImage('/scene/action-unbind-icon.png'));
|
||||
iconMap.set('delay', getImage('/scene/action-delay-icon.png'));
|
||||
|
||||
export const itemNotifyIconMap = new Map();
|
||||
itemNotifyIconMap.set(
|
||||
'dingTalk',
|
||||
getImage('/scene/notify-item-img/dingtalk.png'),
|
||||
);
|
||||
itemNotifyIconMap.set('weixin', getImage('/scene/notify-item-img/weixin.png'));
|
||||
itemNotifyIconMap.set('email', getImage('/scene/notify-item-img/email.png'));
|
||||
itemNotifyIconMap.set('voice', getImage('/scene/notify-item-img/voice.png'));
|
||||
itemNotifyIconMap.set('sms', getImage('/scene/notify-item-img/sms.png'));
|
||||
itemNotifyIconMap.set(
|
||||
'webhook',
|
||||
getImage('/scene/notify-item-img/webhook.png'),
|
||||
);
|
||||
|
||||
export const typeIconMap = {
|
||||
READ_PROPERTY: 'icon-zhihangdongzuodu',
|
||||
INVOKE_FUNCTION: 'icon-zhihangdongzuoxie-1',
|
||||
WRITE_PROPERTY: 'icon-zhihangdongzuoxie',
|
||||
};
|
|
@ -4,7 +4,7 @@
|
|||
<Device v-bind="props" :value="data?.device" @cancel="onCancel" @save="onPropsOk" :thenName="branchesName" />
|
||||
</template>
|
||||
<template v-else-if="actionType === 'notify'">
|
||||
<Notify v-bind="props" :value="data?.notify" @cancel="onCancel" @save="onPropsOk" />
|
||||
<Notify :options="data?.options" :value="data?.notify" @cancel="onCancel" @save="onPropsOk" />
|
||||
</template>
|
||||
<template v-else-if="actionType === 'delay'">
|
||||
<Delay :value="data?.delay" @cancel="onCancel" @save="onPropsOk" />
|
||||
|
@ -55,7 +55,7 @@ const onPropsOk = (data: any, options: any) => {
|
|||
type: props.actionType,
|
||||
executor: props.actionType,
|
||||
key: props?.data?.key || `${props.actionType}_${new Date().getTime()}`,
|
||||
device: {
|
||||
[props.actionType]: {
|
||||
...data,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
@ok="onOk"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<a-form ref="actionForm" :model="formModel" layout="vertical">
|
||||
<a-form-item
|
||||
<j-form ref="actionForm" :model="formModel" layout="vertical">
|
||||
<j-form-item
|
||||
label="类型"
|
||||
name="type"
|
||||
:rules="[
|
||||
|
@ -19,7 +19,7 @@
|
|||
]"
|
||||
>
|
||||
<CardSelect v-model:value="formModel.type" :options="options"/>
|
||||
</a-form-item>
|
||||
</j-form-item>
|
||||
<ActionTypeComponent
|
||||
v-bind="props"
|
||||
v-if="!!actionType"
|
||||
|
@ -27,7 +27,7 @@
|
|||
@save="onPropsOk"
|
||||
@cancel="onPropsCancel"
|
||||
/>
|
||||
</a-form>
|
||||
</j-form>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<j-advanced-search
|
||||
<pro-search
|
||||
:columns="columns"
|
||||
type="simple"
|
||||
target="action-notice-config"
|
||||
|
@ -9,22 +9,7 @@
|
|||
<div style="height: 400px; overflow-y: auto">
|
||||
<JProTable
|
||||
:columns="columns"
|
||||
:request="(e) => ConfigApi.list({
|
||||
...e,
|
||||
terms: [
|
||||
...e?.terms,
|
||||
{
|
||||
terms: [
|
||||
{
|
||||
termType: 'eq',
|
||||
column: 'type',
|
||||
value: props.notifyType,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
sorts: [{ name: 'id', value: props.value }, { name: 'createTime', order: 'desc' }],
|
||||
})"
|
||||
:request="query"
|
||||
model="CARD"
|
||||
:bodyStyle="{
|
||||
paddingRight: 0,
|
||||
|
@ -34,8 +19,8 @@
|
|||
:gridColumn="2"
|
||||
:rowSelection="{
|
||||
selectedRowKeys: _selectedRowKeys,
|
||||
onChange: onSelectChange,
|
||||
}"
|
||||
@cancelSelect="cancelSelect"
|
||||
>
|
||||
<template #card="slotProps">
|
||||
<CardBox
|
||||
|
@ -63,22 +48,22 @@
|
|||
{{ slotProps.name }}
|
||||
</span>
|
||||
</Ellipsis>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<j-row>
|
||||
<j-col :span="12">
|
||||
<div class="card-item-content-text">
|
||||
通知方式
|
||||
</div>
|
||||
<div>
|
||||
{{ getMethodTxt(slotProps.type) }}
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
</j-col>
|
||||
<j-col :span="12">
|
||||
<div class="card-item-content-text">说明</div>
|
||||
<Ellipsis>
|
||||
{{ slotProps.description }}
|
||||
</Ellipsis>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</j-col>
|
||||
</j-row>
|
||||
</template>
|
||||
</CardBox>
|
||||
</template>
|
||||
|
@ -100,7 +85,7 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:value']);
|
||||
const emit = defineEmits(['update:value', 'change']);
|
||||
|
||||
const getLogo = (type: string, provider: string) => {
|
||||
return MSG_TYPE[type].find((f: any) => f.value === provider)?.logo;
|
||||
|
@ -140,17 +125,39 @@ const columns = [
|
|||
},
|
||||
];
|
||||
|
||||
const query = (e: Record<string, any>) =>
|
||||
ConfigApi.list({
|
||||
...e,
|
||||
terms: [
|
||||
...e?.terms,
|
||||
{
|
||||
terms: [
|
||||
{
|
||||
termType: 'eq',
|
||||
column: 'type',
|
||||
value: props.notifyType,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
sorts: [
|
||||
{ name: 'id', value: props.value },
|
||||
{ name: 'createTime', order: 'desc' },
|
||||
],
|
||||
});
|
||||
|
||||
const handleSearch = (_params: any) => {
|
||||
params.value = _params;
|
||||
};
|
||||
|
||||
const cancelSelect = () => {
|
||||
_selectedRowKeys.value = [];
|
||||
const onSelectChange = (keys: string[]) => {
|
||||
_selectedRowKeys.value = [...keys];
|
||||
};
|
||||
|
||||
const handleClick = (dt: any) => {
|
||||
_selectedRowKeys.value = [dt.id];
|
||||
emit('update:value', dt.id);
|
||||
emit('change', { provider: dt?.provider });
|
||||
};
|
||||
|
||||
watch(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<j-advanced-search
|
||||
<pro-search
|
||||
:columns="columns"
|
||||
type="simple"
|
||||
target="action-notice-template"
|
||||
|
@ -19,8 +19,8 @@
|
|||
:gridColumn="2"
|
||||
:rowSelection="{
|
||||
selectedRowKeys: _selectedRowKeys,
|
||||
onChange: onSelectChange,
|
||||
}"
|
||||
@cancelSelect="cancelSelect"
|
||||
>
|
||||
<template #card="slotProps">
|
||||
<CardBox
|
||||
|
@ -48,22 +48,22 @@
|
|||
{{ slotProps.name }}
|
||||
</span>
|
||||
</Ellipsis>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<j-row>
|
||||
<j-col :span="12">
|
||||
<div class="card-item-content-text">
|
||||
通知方式
|
||||
</div>
|
||||
<div>
|
||||
{{ getMethodTxt(slotProps.type) }}
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
</j-col>
|
||||
<j-col :span="12">
|
||||
<div class="card-item-content-text">说明</div>
|
||||
<Ellipsis>
|
||||
{{ slotProps.description }}
|
||||
</Ellipsis>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</j-col>
|
||||
</j-row>
|
||||
</template>
|
||||
</CardBox>
|
||||
</template>
|
||||
|
@ -85,7 +85,7 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:value']);
|
||||
const emit = defineEmits(['update:value', 'change']);
|
||||
|
||||
const getLogo = (type: string, provider: string) => {
|
||||
return MSG_TYPE[type].find((f: any) => f.value === provider)?.logo;
|
||||
|
@ -129,13 +129,14 @@ const handleSearch = (_params: any) => {
|
|||
params.value = _params;
|
||||
};
|
||||
|
||||
const cancelSelect = () => {
|
||||
_selectedRowKeys.value = [];
|
||||
};
|
||||
|
||||
const handleClick = (dt: any) => {
|
||||
_selectedRowKeys.value = [dt.id];
|
||||
emit('update:value', dt.id);
|
||||
emit('change', { templateName: dt?.name });
|
||||
};
|
||||
|
||||
const onSelectChange = (keys: string[]) => {
|
||||
_selectedRowKeys.value = [...keys];
|
||||
};
|
||||
|
||||
const handleData = async (e: any) => {
|
||||
|
@ -178,8 +179,7 @@ watch(
|
|||
<style lang="less" scoped>
|
||||
.search {
|
||||
margin-bottom: 0;
|
||||
padding-right: 0px;
|
||||
padding-left: 0px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<a-spin :spinning="loading">
|
||||
<j-spin :spinning="loading">
|
||||
<div class="notify-type-warp" :class="{ disabled: disabled }">
|
||||
<div
|
||||
:key="item.id"
|
||||
|
@ -14,7 +14,7 @@
|
|||
<div class="notify-type-item-title">{{item.label}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
</j-spin>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@ -40,7 +40,7 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:value']);
|
||||
const emit = defineEmits(['update:value', 'change']);
|
||||
|
||||
const loading = ref<boolean>(false);
|
||||
const notifyType = ref('');
|
||||
|
@ -57,6 +57,7 @@ watch(
|
|||
const onSelect = (val: string) => {
|
||||
if (!props.disabled) {
|
||||
emit('update:value', val);
|
||||
emit('change', val);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<a-form
|
||||
<j-form
|
||||
v-if="variableDefinitions.length"
|
||||
:layout="'vertical'"
|
||||
ref="formRef"
|
||||
:model="modelRef"
|
||||
>
|
||||
<a-form-item
|
||||
<j-form-item
|
||||
:name="`${item?.id}`"
|
||||
:label="item?.name"
|
||||
v-for="item in variableDefinitions"
|
||||
|
@ -14,7 +14,7 @@
|
|||
:rules="[
|
||||
{
|
||||
validator: (_rule, value) => checkValue(_rule, value, item),
|
||||
trigger: 'change',
|
||||
trigger: ['change', 'blur']
|
||||
},
|
||||
]"
|
||||
>
|
||||
|
@ -27,23 +27,25 @@
|
|||
:notify="notify"
|
||||
v-else-if="getType(item) === 'org'"
|
||||
v-model:value="modelRef[item.id]"
|
||||
@change="(val) => onChange(val, 'org')"
|
||||
/>
|
||||
<Tag
|
||||
:notify="notify"
|
||||
v-else-if="getType(item) === 'tag'"
|
||||
v-model:value="modelRef[item.id]"
|
||||
@change="(val) => onChange(val, 'tag')"
|
||||
/>
|
||||
<InputFile
|
||||
v-else-if="getType(item) === 'file'"
|
||||
v-model:value="modelRef[item.id]"
|
||||
/>
|
||||
<a-input
|
||||
<j-input
|
||||
v-else-if="getType(item) === 'link'"
|
||||
v-model:value="modelRef[item.id]"
|
||||
/>
|
||||
<BuildIn v-else :item="item" v-model:value="modelRef[item.id]" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</j-form-item>
|
||||
</j-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@ -69,6 +71,8 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:value', 'change']);
|
||||
|
||||
const formRef = ref();
|
||||
|
||||
const modelRef = reactive({});
|
||||
|
@ -111,14 +115,14 @@ const checkValue = (_rule: any, value: any, item: any) => {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (value.source === 'fixed' && !value.value) {
|
||||
} else if (value?.source === 'fixed' && !value.value) {
|
||||
return Promise.reject(new Error('请输入' + item.name));
|
||||
} else if (value.source === 'relation' && !value.value && !value.relation) {
|
||||
} else if (value?.source === 'relation' && !value.value && !value.relation) {
|
||||
return Promise.reject(new Error('请选择' + item.name));
|
||||
} else if (value.source === 'upper' && !value.upperKey) {
|
||||
} else if (value?.source === 'upper' && !value.upperKey) {
|
||||
return Promise.reject(new Error('请选择' + item.name));
|
||||
} else if (type === 'user') {
|
||||
if (props.notify.notifyType === 'email') {
|
||||
if (props.notify.notifyType === 'email' && value?.source !== 'relation') {
|
||||
if (Array.isArray(value.value)) {
|
||||
if (!value.value.length) {
|
||||
return Promise.reject(new Error('请输入收件人'));
|
||||
|
@ -139,7 +143,7 @@ const checkValue = (_rule: any, value: any, item: any) => {
|
|||
}
|
||||
if (
|
||||
props.notify.notifyType &&
|
||||
['sms', 'voice'].includes(props?.notify?.notifyType)
|
||||
['sms', 'voice'].includes(props?.notify?.notifyType) && value?.source !== 'relation'
|
||||
) {
|
||||
const reg = /^[1][3-9]\d{9}$/;
|
||||
if (!reg.test(value.value)) {
|
||||
|
@ -151,4 +155,21 @@ const checkValue = (_rule: any, value: any, item: any) => {
|
|||
}
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
const onChange = (val: any, type: any) => {
|
||||
if (type === 'org') {
|
||||
emit('change', { orgName: val.join(',') });
|
||||
} else if (type === 'tag') {
|
||||
emit('change', { tagName: val });
|
||||
}
|
||||
};
|
||||
|
||||
const onSave = () =>
|
||||
new Promise((resolve) => {
|
||||
formRef.value.validate().then(async (_data: any) => {
|
||||
resolve(_data);
|
||||
});
|
||||
});
|
||||
|
||||
defineExpose({ onSave });
|
||||
</script>
|
|
@ -8,17 +8,17 @@
|
|||
:maskClosable="false"
|
||||
>
|
||||
<div class="steps-steps">
|
||||
<a-steps :current="current" size="small" @change="onChange">
|
||||
<a-step title="通知方式" key="way" />
|
||||
<a-step title="通知配置" key="config" />
|
||||
<a-step title="通知模板" key="template" />
|
||||
<a-step title="模板变量" key="variable" />
|
||||
</a-steps>
|
||||
<j-steps :current="current" size="small" @change="onChange">
|
||||
<j-step title="通知方式" key="way" />
|
||||
<j-step title="通知配置" key="config" />
|
||||
<j-step title="通知模板" key="template" />
|
||||
<j-step title="模板变量" key="variable" />
|
||||
</j-steps>
|
||||
</div>
|
||||
<div class="steps-content">
|
||||
<a-form ref="actionForm" :model="formModel" layout="vertical">
|
||||
<j-form ref="actionForm" :model="formModel" layout="vertical">
|
||||
<template v-if="current === 0">
|
||||
<a-form-item
|
||||
<j-form-item
|
||||
label="应用"
|
||||
name="notifyType"
|
||||
:rules="[
|
||||
|
@ -28,38 +28,45 @@
|
|||
},
|
||||
]"
|
||||
>
|
||||
<NotifyWay v-model:value="formModel.notifyType" />
|
||||
</a-form-item>
|
||||
<NotifyWay
|
||||
v-model:value="formModel.notifyType"
|
||||
@change="(val) => onValChange(val, 'notifyType')"
|
||||
/>
|
||||
</j-form-item>
|
||||
</template>
|
||||
<template v-if="current === 1">
|
||||
<a-form-item name="notifierId">
|
||||
<j-form-item name="notifierId">
|
||||
<NotifyConfig
|
||||
v-model:value="formModel.notifierId"
|
||||
:notifyType="formModel.notifyType"
|
||||
@change="(val) => onValChange(val, 'notifierId')"
|
||||
/>
|
||||
</a-form-item>
|
||||
</j-form-item>
|
||||
</template>
|
||||
<template v-if="current === 2">
|
||||
<a-form-item name="templateId">
|
||||
<j-form-item name="templateId">
|
||||
<NotifyTemplate
|
||||
v-model:value="formModel.templateId"
|
||||
:notifierId="formModel.notifierId"
|
||||
@change="(val) => onValChange(val, 'templateId')"
|
||||
/>
|
||||
</a-form-item>
|
||||
</j-form-item>
|
||||
</template>
|
||||
<template v-if="current === 3">
|
||||
<a-form-item name="variables">
|
||||
<j-form-item name="variables">
|
||||
<VariableDefinitions
|
||||
:variableDefinitions="variable"
|
||||
v-model:value="formModel.variables"
|
||||
:value="formModel.variables"
|
||||
:notify="formModel"
|
||||
@change="(val) => onValChange(val, 'variables')"
|
||||
ref="variableRef"
|
||||
/>
|
||||
</a-form-item>
|
||||
</j-form-item>
|
||||
</template>
|
||||
</a-form>
|
||||
</j-form>
|
||||
</div>
|
||||
<template #footer>
|
||||
<a-space>
|
||||
<j-space>
|
||||
<j-button v-if="current === 0" @click="onCancel">取消</j-button>
|
||||
<j-button v-if="current > 0" @click="prev">上一步</j-button>
|
||||
<j-button v-if="current < 3" type="primary" @click="next"
|
||||
|
@ -68,7 +75,7 @@
|
|||
<j-button v-if="current === 3" type="primary" @click="onOk"
|
||||
>确定</j-button
|
||||
>
|
||||
</a-space>
|
||||
</j-space>
|
||||
</template>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
@ -90,6 +97,7 @@ const props = defineProps({
|
|||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
name: {
|
||||
type: Number,
|
||||
|
@ -106,9 +114,11 @@ const formModel = reactive({
|
|||
notifierId: '',
|
||||
templateId: '',
|
||||
variables: {},
|
||||
options: {},
|
||||
});
|
||||
|
||||
const variable = ref([]);
|
||||
const variableRef = ref();
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
|
@ -118,6 +128,27 @@ watch(
|
|||
{ deep: true, immediate: true },
|
||||
);
|
||||
|
||||
watchEffect(() => {
|
||||
formModel.options = props.options || {};
|
||||
});
|
||||
|
||||
const onValChange = (val: any, type: string) => {
|
||||
if (type === 'notifyType') {
|
||||
formModel.templateId = '';
|
||||
formModel.variables = [];
|
||||
formModel.notifierId = '';
|
||||
} else if (type === 'notifierId') {
|
||||
formModel.templateId = '';
|
||||
formModel.variables = [];
|
||||
} else if (type === 'templateId') {
|
||||
formModel.variables = [];
|
||||
}
|
||||
formModel.options = {
|
||||
...unref(formModel.options),
|
||||
...val,
|
||||
};
|
||||
};
|
||||
|
||||
const jumpStep = async (val: number) => {
|
||||
if (val === 0) {
|
||||
current.value = val;
|
||||
|
@ -134,7 +165,6 @@ const jumpStep = async (val: number) => {
|
|||
onlyMessage('请选择通知配置', 'error');
|
||||
}
|
||||
} else if (val === 3) {
|
||||
formModel.templateId = '1628943618904956928';
|
||||
if (formModel.templateId) {
|
||||
const resp = await Template.getTemplateDetail(formModel.templateId);
|
||||
if (resp.status === 200) {
|
||||
|
@ -162,8 +192,11 @@ const next = async () => {
|
|||
const onCancel = () => {
|
||||
emit('cancel');
|
||||
};
|
||||
const onOk = () => {
|
||||
emit('save');
|
||||
const onOk = async () => {
|
||||
const _data = await variableRef.value.onSave();
|
||||
formModel.variables = _data;
|
||||
const { options, ...extra } = formModel;
|
||||
emit('save', { ...extra }, { ...options });
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<a-input-group compact>
|
||||
<a-select
|
||||
<j-input-group compact>
|
||||
<j-select
|
||||
:options="[
|
||||
{ label: '手动输入', value: 'fixed' },
|
||||
{ label: '内置参数', value: 'upper' },
|
||||
|
@ -10,22 +10,22 @@
|
|||
@change="sourceChange"
|
||||
/>
|
||||
<template v-if="source === 'upper'">
|
||||
<a-tree-select
|
||||
<j-tree-select
|
||||
v-model:value="upperKey"
|
||||
:treeData="builtInList"
|
||||
placeholder="请选择参数"
|
||||
style="width: calc(100% - 120px)"
|
||||
>
|
||||
<template #title="{ name, description }">
|
||||
<a-space>
|
||||
<j-space>
|
||||
{{ name }}
|
||||
<span style="color: grey; margin-left: 5px">{{ description }}</span>
|
||||
</a-space>
|
||||
</j-space>
|
||||
</template>
|
||||
</a-tree-select>
|
||||
</j-tree-select>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-date-picker
|
||||
<j-date-picker
|
||||
:value="value.value"
|
||||
allowClear
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
|
@ -33,7 +33,7 @@
|
|||
v-if="item.type === 'date'"
|
||||
@change="(_, dateString) => itemOnChange(dateString)"
|
||||
/>
|
||||
<a-input-number
|
||||
<j-input-number
|
||||
:value="value.value"
|
||||
allowClear
|
||||
style="width: calc(100% - 120px)"
|
||||
|
@ -41,7 +41,7 @@
|
|||
:placeholder="`请输入${item.name}`"
|
||||
@change="itemOnChange"
|
||||
/>
|
||||
<a-input
|
||||
<j-input
|
||||
:value="value.value"
|
||||
allowClear
|
||||
style="width: calc(100% - 120px)"
|
||||
|
@ -50,7 +50,7 @@
|
|||
@change="(e) => itemOnChange(e.target.value)"
|
||||
/>
|
||||
</template>
|
||||
</a-input-group>
|
||||
</j-input-group>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<template>
|
||||
<a-input
|
||||
<j-input
|
||||
allowClear
|
||||
placeholder="请上传文件"
|
||||
v-model:value="url"
|
||||
@change="onChange"
|
||||
>
|
||||
<template #addonAfter>
|
||||
<a-upload
|
||||
<j-upload
|
||||
name="file"
|
||||
:showUploadList="false"
|
||||
:accept="'image/jpeg,image/png'"
|
||||
|
@ -23,9 +23,9 @@
|
|||
<AIcon type="PlusOutlined" v-else />
|
||||
上传附件
|
||||
</j-button>
|
||||
</a-upload>
|
||||
</j-upload>
|
||||
</template>
|
||||
</a-input>
|
||||
</j-input>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
|
|
@ -26,7 +26,7 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:value']);
|
||||
const emit = defineEmits(['update:value', 'change']);
|
||||
|
||||
const departmentTree = ref<any[]>([]);
|
||||
const keys = ref<any[]>([]);
|
||||
|
@ -68,6 +68,7 @@ const onChange = (key: string[], label: string[]) => {
|
|||
source: 'fixed',
|
||||
value: key,
|
||||
});
|
||||
emit('change', label)
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -22,10 +22,10 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:value']);
|
||||
const emit = defineEmits(['update:value', 'change']);
|
||||
|
||||
const tagsList = ref<any[]>([]);
|
||||
const keys = ref<string>('');
|
||||
const keys = ref<string | undefined>(undefined);
|
||||
|
||||
const getDepartment = async (id: string) => {
|
||||
const resp = await TemplateApi.getTags(id);
|
||||
|
@ -37,9 +37,9 @@ const getDepartment = async (id: string) => {
|
|||
watch(
|
||||
() => props.value,
|
||||
(newVal) => {
|
||||
keys.value = newVal || ''
|
||||
keys.value = newVal || undefined
|
||||
},
|
||||
{ deep: true, immediate: true },
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
|
@ -52,12 +52,12 @@ watch(
|
|||
{ deep: true, immediate: true },
|
||||
);
|
||||
|
||||
const onChange = (key: string, label: string[]) => {
|
||||
// TODO 回显label的问题
|
||||
const onChange = (key: string, option: any) => {
|
||||
emit('update:value', {
|
||||
source: 'fixed',
|
||||
value: key,
|
||||
});
|
||||
emit('change', option ? option?.label : '')
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,83 +1,87 @@
|
|||
<template>
|
||||
<a-input-group compact>
|
||||
<a-select
|
||||
<j-input-group compact>
|
||||
<j-select
|
||||
style="width: 120px"
|
||||
v-model:value="mySource"
|
||||
@change="sourceChange"
|
||||
>
|
||||
<a-select-option key="5" value="relation">
|
||||
<j-select-option key="5" value="relation">
|
||||
平台用户
|
||||
</a-select-option>
|
||||
<a-select-option
|
||||
</j-select-option>
|
||||
<j-select-option
|
||||
v-if="notifyType === 'dingTalk'"
|
||||
key="1"
|
||||
value="fixed"
|
||||
>
|
||||
钉钉用户
|
||||
</a-select-option>
|
||||
<a-select-option
|
||||
</j-select-option>
|
||||
<j-select-option
|
||||
v-else-if="notifyType === 'weixin'"
|
||||
key="2"
|
||||
value="fixed"
|
||||
>
|
||||
微信用户
|
||||
</a-select-option>
|
||||
<a-select-option
|
||||
</j-select-option>
|
||||
<j-select-option
|
||||
v-else-if="notifyType === 'email'"
|
||||
key="3"
|
||||
value="fixed"
|
||||
>
|
||||
固定邮箱
|
||||
</a-select-option>
|
||||
<a-select-option v-else key="4" value="fixed">
|
||||
</j-select-option>
|
||||
<j-select-option v-else key="4" value="fixed">
|
||||
固定号码
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-tree-select
|
||||
</j-select-option>
|
||||
</j-select>
|
||||
<j-tree-select
|
||||
v-if="source === 'relation'"
|
||||
style="width: calc(100% - 120px)"
|
||||
placeholder="请选择收信人"
|
||||
@select="treeSelect"
|
||||
@select="(key, node) => onChange(source, key, false, node?.relation, node.name)"
|
||||
:tree-data="treeData"
|
||||
:multiple="['email'].includes(notifyType)"
|
||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
:value="relationData"
|
||||
/>
|
||||
<a-select
|
||||
>
|
||||
<template #title="{ key, username, title }">
|
||||
<div style="display: flex; justify-content: space-between; margin-right: 10px;" v-if="key !== 'p1' && key !== 'p2'">{{ title }} <span style="color: #cfcfcf;">{{ username }}</span></div>
|
||||
<span v-else>{{ title }}</span>
|
||||
</template>
|
||||
</j-tree-select>
|
||||
<template v-else>
|
||||
<j-select
|
||||
style="width: calc(100% - 120px)"
|
||||
v-else-if="['dingTalk', 'weixin'].includes(notifyType)"
|
||||
v-if="['dingTalk', 'weixin'].includes(notifyType)"
|
||||
placeholder="请选择收信人"
|
||||
:value="value?.value"
|
||||
@change="(val) => onChange(val)"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="item in relationList"
|
||||
:key="item.id"
|
||||
:value="item.id"
|
||||
>{{ item.name }}</a-select-option
|
||||
>
|
||||
</a-select>
|
||||
<a-input
|
||||
showSearch
|
||||
@change="(val, option) => onChange(source, val, false, option?.label || option?.name)"
|
||||
:options="relationList"
|
||||
/>
|
||||
<j-select
|
||||
style="width: calc(100% - 120px)"
|
||||
v-else-if="['email'].includes(notifyType)"
|
||||
placeholder="请输入固定邮箱"
|
||||
placeholder="请输入收件人邮箱,多个收件人用换行分隔"
|
||||
:value="value?.value"
|
||||
:multiple="true"
|
||||
@change="(e) => onChange(e.target.value)"
|
||||
></a-input>
|
||||
<a-input
|
||||
mode="tags"
|
||||
@change="(val) => onChange(source, val, false, Array.isArray(val) ? val.join(',') : val)"
|
||||
/>
|
||||
<j-input
|
||||
style="width: calc(100% - 120px)"
|
||||
v-else-if="['sms', 'voice'].includes(notifyType)"
|
||||
placeholder="请输入固定号码"
|
||||
:value="value?.value"
|
||||
@change="(e) => onChange(e.target.value)"
|
||||
></a-input>
|
||||
</a-input-group>
|
||||
@change="(e) => onChange(source, e.target.value, false, e.target.value)"
|
||||
></j-input>
|
||||
</template>
|
||||
</j-input-group>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useSceneStore } from '@/store/scene';
|
||||
import NoticeApi from '@/api/notice/config';
|
||||
import { unionBy } from 'lodash-es';
|
||||
|
||||
const sceneStore = useSceneStore();
|
||||
const { data } = storeToRefs(sceneStore);
|
||||
|
@ -93,7 +97,7 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:value']);
|
||||
const emit = defineEmits(['update:value', 'change']);
|
||||
|
||||
const notifyType = computed(() => {
|
||||
return props.notify?.notifyType;
|
||||
|
@ -142,6 +146,7 @@ const treeData = ref<any[]>([
|
|||
},
|
||||
]);
|
||||
const mySource = ref<string>('relation');
|
||||
const labelMap = new Map();
|
||||
|
||||
const getRelationUsers = async (notifyType: string, notifierId: string) => {
|
||||
let resp = undefined;
|
||||
|
@ -151,7 +156,12 @@ const getRelationUsers = async (notifyType: string, notifierId: string) => {
|
|||
resp = await NoticeApi.queryWechatUsers(notifierId);
|
||||
}
|
||||
if (resp && resp.status === 200) {
|
||||
relationList.value = resp.result;
|
||||
relationList.value = unionBy(resp.result, 'id').map((item: any) => {
|
||||
return {
|
||||
value: item.id,
|
||||
label: item.name,
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -206,43 +216,72 @@ const getUser = async (_source: string, triggerType: string) => {
|
|||
treeData.value = newTree;
|
||||
};
|
||||
|
||||
const treeSelect = (val: string, _data: any) => {
|
||||
const obj = {
|
||||
source: source.value,
|
||||
relation: {}
|
||||
};
|
||||
if (_data?.isRelation) {
|
||||
obj.relation = {
|
||||
objectType: 'device',
|
||||
objectSource: {
|
||||
source: 'upper',
|
||||
upperKey: 'scene.deviceId',
|
||||
},
|
||||
related: {
|
||||
objectType: 'user',
|
||||
relation: val,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
obj.relation = {
|
||||
objectType: 'user',
|
||||
objectId: val,
|
||||
};
|
||||
}
|
||||
emit('update:value', obj);
|
||||
};
|
||||
|
||||
const sourceChange = (v: any) => {
|
||||
emit('update:value', {
|
||||
source: v,
|
||||
});
|
||||
};
|
||||
|
||||
const onChange = (val: any) => {
|
||||
emit('update:value', {
|
||||
source: source.value,
|
||||
value: val,
|
||||
const getObj = (
|
||||
_source: string = 'fixed',
|
||||
_value?: string | string[],
|
||||
isRelation?: boolean,
|
||||
) => {
|
||||
const obj: any = {
|
||||
source: _source,
|
||||
};
|
||||
if (_source === 'relation') {
|
||||
if (isRelation) {
|
||||
obj.relation = {
|
||||
objectType: 'device',
|
||||
objectSource: {
|
||||
source: 'upper',
|
||||
upperKey: 'deviceId',
|
||||
},
|
||||
related: {
|
||||
objectType: 'user',
|
||||
relation: _value,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
obj.relation = {
|
||||
objectType: 'user',
|
||||
objectId: _value,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
obj.value = _value;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
const onChange = (
|
||||
_source: string = 'fixed',
|
||||
_value?: string | string[],
|
||||
isRelation?: boolean,
|
||||
_name?: string,
|
||||
) => {
|
||||
let _values: any = undefined;
|
||||
const _names: string[] = [_name || ''];
|
||||
if (Array.isArray(_value)) {
|
||||
if (props?.notify?.notifyType === 'email') {
|
||||
if (isRelation) {
|
||||
const arr = _value.map((item) => {
|
||||
const _item = labelMap.get(item);
|
||||
_names.push(_item?.name || '');
|
||||
return getObj('relation', item, _item?.relation);
|
||||
});
|
||||
_values = arr;
|
||||
} else {
|
||||
_values = getObj(_source, _value, false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_values = getObj(_source, _value, isRelation);
|
||||
}
|
||||
console.log(_values, '_values')
|
||||
emit('update:value', _values);
|
||||
emit('change', { sendTo: _names.filter((item) => !!item).join(',') });
|
||||
};
|
||||
|
||||
watch(
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
<span>执行</span>
|
||||
<ShakeLimit
|
||||
v-if="props.openShakeLimit"
|
||||
v-model:value="shakeLimit"
|
||||
v-model:value="FormModel.branches[name].shakeLimit"
|
||||
/>
|
||||
</div>
|
||||
<div class="actions-warp">
|
||||
<a-collapse v-model:activeKey="activeKeys">
|
||||
<a-collapse-panel key="1">
|
||||
<j-collapse v-model:activeKey="activeKeys">
|
||||
<j-collapse-panel key="1">
|
||||
<template #header>
|
||||
<span>
|
||||
串行
|
||||
|
@ -21,17 +21,17 @@
|
|||
<div class="actions-list">
|
||||
<List
|
||||
type="serial"
|
||||
:branchesName="props.name"
|
||||
:branchesName="name"
|
||||
:parallel="false"
|
||||
:actions="
|
||||
serialArray.length ? serialArray[0].actions : []
|
||||
"
|
||||
@add="(_item) => onAdd(_item, false)"
|
||||
@delete="onDelete"
|
||||
@delete="(_key) => onDelete(_key, false)"
|
||||
/>
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel key="2">
|
||||
</j-collapse-panel>
|
||||
<j-collapse-panel key="2">
|
||||
<template #header>
|
||||
<span>
|
||||
并行
|
||||
|
@ -43,7 +43,7 @@
|
|||
<div class="actions-list">
|
||||
<List
|
||||
type="parallel"
|
||||
:branchesName="props.name"
|
||||
:branchesName="name"
|
||||
:parallel="true"
|
||||
:actions="
|
||||
parallelArray.length
|
||||
|
@ -51,11 +51,11 @@
|
|||
: []
|
||||
"
|
||||
@add="(_item) => onAdd(_item, true)"
|
||||
@delete="onDelete"
|
||||
@delete="(_key) => onDelete(_key, true)"
|
||||
/>
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
</a-collapse>
|
||||
</j-collapse-panel>
|
||||
</j-collapse>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -63,30 +63,32 @@
|
|||
<script lang="ts" setup>
|
||||
import ShakeLimit from '../components/ShakeLimit/index.vue';
|
||||
import { List } from './ListItem';
|
||||
import { BranchesThen } from '../../typings';
|
||||
import { BranchesThen } from '../../typings'
|
||||
import { PropType } from 'vue';
|
||||
import { randomString } from '@/utils/utils';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useSceneStore } from 'store/scene'
|
||||
|
||||
interface ActionsProps {
|
||||
name: number;
|
||||
openShakeLimit?: boolean;
|
||||
thenOptions: BranchesThen[];
|
||||
}
|
||||
const sceneStore = useSceneStore()
|
||||
const { data: FormModel } = storeToRefs(sceneStore)
|
||||
|
||||
const props = defineProps({
|
||||
name: Number,
|
||||
name: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
thenOptions: {
|
||||
type: Array as PropType<ActionsProps['thenOptions']>,
|
||||
type: Array as PropType<BranchesThen[]>,
|
||||
default: () => [],
|
||||
},
|
||||
openShakeLimit: Boolean,
|
||||
openShakeLimit: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update', 'add']);
|
||||
|
||||
const shakeLimit = ref({
|
||||
enabled: false,
|
||||
});
|
||||
const activeKeys = ref<string[]>(['1']);
|
||||
const parallelArray = ref<BranchesThen[]>([]);
|
||||
const serialArray = ref<BranchesThen[]>([]);
|
||||
|
@ -98,8 +100,6 @@ watch(
|
|||
parallelArray.value = newVal.filter((item) => item.parallel);
|
||||
serialArray.value = newVal.filter((item) => !item.parallel);
|
||||
|
||||
console.log(parallelArray.value, serialArray.value, '123')
|
||||
|
||||
const isSerialActions = serialArray.value.some((item) => {
|
||||
return !!item.actions.length;
|
||||
});
|
||||
|
@ -112,8 +112,6 @@ watch(
|
|||
activeKeys.value = ['2'];
|
||||
lock.value = true;
|
||||
}
|
||||
|
||||
//TODO 回传数据
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
|
@ -121,35 +119,31 @@ watch(
|
|||
},
|
||||
);
|
||||
|
||||
const onDelete = (_key: string) => {
|
||||
const aIndex = unref(serialArray)[0].actions?.findIndex(
|
||||
(aItem) => aItem.key === _key,
|
||||
);
|
||||
if (aIndex !== -1) {
|
||||
serialArray.value[0].actions?.splice(aIndex, 1);
|
||||
emit('update', serialArray[0], false);
|
||||
const onDelete = (_key: string, _parallel: boolean) => {
|
||||
const thenName = props.thenOptions.findIndex(item => item.parallel === _parallel)
|
||||
const actionIndex = FormModel.value.branches?.[props.name].then?.[thenName].actions.findIndex(item => item.key === _key)
|
||||
if (actionIndex !== -1) {
|
||||
FormModel.value.branches?.[props.name].then?.[thenName].actions.splice(actionIndex!, 1)
|
||||
}
|
||||
};
|
||||
|
||||
const onAdd = (actionItem: any, _parallel: boolean) => {
|
||||
const newParallelArray = [...parallelArray.value];
|
||||
if (newParallelArray.length) {
|
||||
const indexOf = newParallelArray[0].actions?.findIndex(
|
||||
(aItem) => aItem.key === actionItem.key,
|
||||
);
|
||||
const thenName = props.thenOptions.findIndex(item => item.parallel === _parallel)
|
||||
if (thenName !== -1) { // 编辑
|
||||
const cacheAction = props.thenOptions[thenName].actions
|
||||
const indexOf = cacheAction?.findIndex(item => item.key === actionItem.key) || -1
|
||||
if (indexOf !== -1) {
|
||||
newParallelArray[0].actions.splice(indexOf, 1, actionItem);
|
||||
FormModel.value.branches?.[props.name].then?.[thenName].actions.splice(indexOf, 1, actionItem)
|
||||
} else {
|
||||
newParallelArray[0].actions.push(actionItem);
|
||||
FormModel.value.branches?.[props.name].then?.[thenName].actions.push(actionItem)
|
||||
}
|
||||
parallelArray.value = [...newParallelArray];
|
||||
emit('update', newParallelArray[0], _parallel);
|
||||
} else {
|
||||
actionItem.key = randomString();
|
||||
emit('add', {
|
||||
} else { // 新增
|
||||
const newThenItem = {
|
||||
parallel: _parallel,
|
||||
key: randomString(),
|
||||
actions: [actionItem],
|
||||
});
|
||||
actions: [actionItem]
|
||||
}
|
||||
FormModel.value.branches?.[props.name].then.push(newThenItem)
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -15,18 +15,18 @@
|
|||
</div>
|
||||
<template #overlay>
|
||||
<div class='scene-select-content'>
|
||||
<template v-if='options.length'>
|
||||
<DropdownTimePicker
|
||||
v-if='["date","time"].includes(component)'
|
||||
:type='component'
|
||||
@change='timeSelect'
|
||||
/>
|
||||
<template v-else-if='options.length'>
|
||||
<drop-menus
|
||||
v-if='component === "select"'
|
||||
:value='selectValue'
|
||||
:options='options'
|
||||
@click='menuSelect'
|
||||
/>
|
||||
<DropdownTimePicker
|
||||
v-else-if='["date","time"].includes(component)'
|
||||
:type='component'
|
||||
@change='timeSelect'
|
||||
/>
|
||||
<div style='min-width: 400px' v-else>
|
||||
<j-tree
|
||||
:selectedKeys='selectValue ? [selectValue] : []'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class='dropdown-time-picker'>
|
||||
<j-time-picker
|
||||
v-if='!_type'
|
||||
v-if='type === "time"'
|
||||
open
|
||||
v-model:value='myValue'
|
||||
class='manual-time-picker'
|
||||
|
@ -59,9 +59,6 @@ const change = (e: Dayjs) => {
|
|||
emit('change', e.format(myFormat))
|
||||
}
|
||||
|
||||
const _type = computed(() => {
|
||||
return props.value?.includes('-')
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang='less'>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
:icon='icon'
|
||||
:placeholder='placeholder'
|
||||
:tabs-options='tabsOptions'
|
||||
:metricOptions='metricOptions'
|
||||
@select='onSelect'
|
||||
/>
|
||||
<ParamsDropdown
|
||||
|
@ -14,6 +15,7 @@
|
|||
:icon='icon'
|
||||
:placeholder='placeholder'
|
||||
:tabs-options='tabsOptions'
|
||||
:metricOptions='metricOptions'
|
||||
:options='options'
|
||||
@select='onSelect'
|
||||
/>
|
||||
|
|
|
@ -23,22 +23,27 @@
|
|||
<div class='select-box-content'>
|
||||
<DropdownTimePicker
|
||||
v-if='["time","date"].includes(item.component)'
|
||||
:type='item.component'
|
||||
type='time'
|
||||
v-model:value='myValue'
|
||||
@change='timeChange'
|
||||
/>
|
||||
<DropdownMenus
|
||||
<template
|
||||
v-else-if='["select","enum", "boolean"].includes(item.component)'
|
||||
:options='["metric", "upper"].includes(item.key) ? metricOption : options'
|
||||
>
|
||||
<DropdownMenus
|
||||
v-if='(["metric", "upper"].includes(item.key) ? metricOptions : options).length'
|
||||
:options='["metric", "upper"].includes(item.key) ? metricOptions : options'
|
||||
@click='onSelect'
|
||||
/>
|
||||
<div
|
||||
v-else-if='item.component === "tree"'
|
||||
style='min-width: 400px'
|
||||
>
|
||||
<div class='scene-select-empty' v-else>
|
||||
<j-empty />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if='item.component === "tree"'>
|
||||
<div style='min-width: 400px' v-if='(item.key === "upper" ? metricOptions : options).length'>
|
||||
<j-tree
|
||||
:selectedKeys='myValue ? [myValue] : []'
|
||||
:treeData='item.key === "upper" ? metricOption : options'
|
||||
:treeData='item.key === "upper" ? metricOptions : options'
|
||||
@select='treeSelect'
|
||||
:height='450'
|
||||
:virtual='true'
|
||||
|
@ -51,11 +56,16 @@
|
|||
</template>
|
||||
</j-tree>
|
||||
</div>
|
||||
<div class='scene-select-empty' v-else>
|
||||
<j-empty />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<ValueItem
|
||||
v-else
|
||||
v-model:modelValue='myValue'
|
||||
:itemType='item.component'
|
||||
:options='item.key === "upper" ? metricOption : options'
|
||||
:options='item.key === "upper" ? metricOptions : options'
|
||||
@change='valueItemChange'
|
||||
/>
|
||||
</div>
|
||||
|
@ -73,8 +83,6 @@ import { defaultSetting } from './typings'
|
|||
import { DropdownMenus, DropdownTimePicker} from '../DropdownButton'
|
||||
import { getComponent, getOption } from '../DropdownButton/util'
|
||||
|
||||
const valueItemKey = ['int', 'int','long','float','double','string', 'password']
|
||||
|
||||
type Emit = {
|
||||
(e: 'update:value', data: ValueType): void
|
||||
(e: 'update:source', data: string): void
|
||||
|
|
|
@ -46,10 +46,6 @@ export const defaultSetting = {
|
|||
type: Array as PropType<Array<DropdownButtonOptions>>,
|
||||
default: () => []
|
||||
},
|
||||
metricOption: {
|
||||
type: Array as PropType<Array<DropdownButtonOptions>>,
|
||||
default: () => []
|
||||
},
|
||||
metricOptions: { // 指标值
|
||||
type: Array as PropType<Array<DropdownButtonOptions>>,
|
||||
default: () => []
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
<template>
|
||||
<div class="shakeLimit">
|
||||
<a-switch
|
||||
<j-switch
|
||||
checkedChildren="开启防抖"
|
||||
unCheckedChildren="关闭防抖"
|
||||
v-model:checked="shakeLimit.enabled"
|
||||
style="margin-right: 12px"
|
||||
/>
|
||||
<template v-if="shakeLimit.enabled">
|
||||
<a-input-number :min="1" :max="100" :precision="0" size="small" v-model:value="shakeLimit.time" style="width: 32px" />
|
||||
<j-input-number :min="1" :max="100" :precision="0" size="small" v-model:value="shakeLimit.time" style="width: 38px" />
|
||||
<span>秒内发送</span>
|
||||
<a-input-number :min="1" :max="100" :precision="0" size="small" v-model:value="shakeLimit.threshold" style="width: 32px" />
|
||||
<j-input-number :min="1" :max="100" :precision="0" size="small" v-model:value="shakeLimit.threshold" style="width: 38px" />
|
||||
<span>次及以上时,处理</span>
|
||||
<a-radio-group :options="alarmFirstOptions" optionType="button" v-model:value="shakeLimit.alarmFirst" size="small" />
|
||||
<j-radio-group :options="alarmFirstOptions" optionType="button" v-model:value="shakeLimit.alarmFirst" size="small" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -55,8 +55,7 @@ const shakeLimit = reactive<ShakeLimitType>({
|
|||
Object.assign(shakeLimit, props.value)
|
||||
|
||||
watch(() => shakeLimit, () => {
|
||||
const cloneValue = cloneDeep(shakeLimit)
|
||||
emit('update:value', cloneValue)
|
||||
emit('update:value', {...shakeLimit})
|
||||
}, {
|
||||
deep: true
|
||||
})
|
||||
|
|
|
@ -19,19 +19,23 @@
|
|||
>
|
||||
<j-popconfirm
|
||||
title='该操作将清空其它所有否则条件,确认删除?'
|
||||
placement='topRight'
|
||||
placement="topRight"
|
||||
@confirm='onDeleteAll'
|
||||
>
|
||||
<AIcon type='CloseOutlined' v-show='showDelete' />
|
||||
<div class='terms-params-delete' v-show='showDelete'>
|
||||
<AIcon type='CloseOutlined' />
|
||||
</div>
|
||||
</j-popconfirm>
|
||||
|
||||
<div class='actions-terms-list-content'>
|
||||
<template v-if='showWhen'>
|
||||
<TermsItem
|
||||
v-for='(item, index) in data.when'
|
||||
v-for='(item, index) in whenData'
|
||||
:key='item.key'
|
||||
:name='index'
|
||||
:showDeleteBtn='whenData.length !== 1'
|
||||
:isFirst='index === 0'
|
||||
:isLast='index === data.when.length -1'
|
||||
:isLast='index === whenData.length -1'
|
||||
:branchName='name'
|
||||
:whenName='index'
|
||||
:data='item'
|
||||
|
@ -45,9 +49,17 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class='actions-branches'>
|
||||
<j-form-item></j-form-item>
|
||||
<j-form-item
|
||||
:name='["branches", name, "then"]'
|
||||
:rules='rules'
|
||||
>
|
||||
<Action
|
||||
:name='name'
|
||||
:openShakeLimit="true"
|
||||
:thenOptions='FormModel.branches[name].then'
|
||||
/>
|
||||
</j-form-item>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -58,6 +70,7 @@ import type { ActionBranchesProps } from '@/views/rule-engine/Scene/typings'
|
|||
import TermsItem from './TermsItem.vue'
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useSceneStore } from 'store/scene'
|
||||
import Action from '../../action/index.vue'
|
||||
|
||||
const sceneStore = useSceneStore()
|
||||
const { data: FormModel } = storeToRefs(sceneStore)
|
||||
|
@ -92,6 +105,10 @@ const showWhen = computed(() => {
|
|||
return props.data.when.length
|
||||
})
|
||||
|
||||
const whenData = computed(() => {
|
||||
return props.data.when
|
||||
})
|
||||
|
||||
const onDelete = () => {
|
||||
|
||||
}
|
||||
|
@ -101,19 +118,36 @@ const onDeleteAll = () => {
|
|||
}
|
||||
|
||||
const mouseover = () => {
|
||||
if (props.isFirst && props.data.when.length){
|
||||
if (!props.isFirst){
|
||||
showDelete.value = true
|
||||
}
|
||||
}
|
||||
|
||||
const mouseout = () => {
|
||||
if (props.isFirst && props.data.when.length){
|
||||
if (!props.isFirst){
|
||||
showDelete.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const addWhen = () => {
|
||||
|
||||
const whenItem = {
|
||||
key: `when_${new Date().getTime()}`,
|
||||
type: 'and',
|
||||
terms: [
|
||||
{
|
||||
column: undefined,
|
||||
value: {
|
||||
source: 'fixed',
|
||||
value: undefined
|
||||
},
|
||||
termType: undefined,
|
||||
key: 'params_1',
|
||||
type: 'and',
|
||||
}
|
||||
]
|
||||
}
|
||||
FormModel.value.branches?.[props.name].when.push(whenItem)
|
||||
FormModel.value.branches?.push(null)
|
||||
}
|
||||
|
||||
const optionsClass = computed(() => {
|
||||
|
@ -124,6 +158,18 @@ const optionsClass = computed(() => {
|
|||
}
|
||||
})
|
||||
|
||||
const rules = [{
|
||||
validator(_: string, value: any) {
|
||||
if (!value || (value && !value.length)) {
|
||||
return Promise.reject('至少配置一个执行动作')
|
||||
} else {
|
||||
const isActions = value.some((item: any) => item.actions && item.actions.length)
|
||||
return isActions ? Promise.resolve() : Promise.reject('至少配置一个执行动作');
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
}]
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang='less'>
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
icon='icon-canshu'
|
||||
placeholder='参数值'
|
||||
:options='valueOptions'
|
||||
:metricOption='metricOption'
|
||||
:metricOptions='metricOption'
|
||||
:tabsOptions='tabsOptions'
|
||||
v-model:value='paramsValue.value.value'
|
||||
v-model:source='paramsValue.value.source'
|
||||
|
@ -50,7 +50,7 @@
|
|||
icon='icon-canshu'
|
||||
placeholder='参数值'
|
||||
:options='valueOptions'
|
||||
:metricOption='metricOption'
|
||||
:metricOptions='metricOption'
|
||||
:tabsOptions='tabsOptions'
|
||||
v-model:value='paramsValue.value.value'
|
||||
v-model:source='paramsValue.value.source'
|
||||
|
@ -75,6 +75,11 @@ import { getOption } from '../DropdownButton/util'
|
|||
import ParamsDropdown, { DoubleParamsDropdown } from '../ParamsDropdown'
|
||||
import { inject } from 'vue'
|
||||
import { ContextKey } from './util'
|
||||
import { useSceneStore } from 'store/scene'
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
const sceneStore = useSceneStore()
|
||||
const { data: formModel } = storeToRefs(sceneStore)
|
||||
|
||||
type Emit = {
|
||||
(e: 'update:value', data: TermsType): void
|
||||
|
@ -95,10 +100,26 @@ const props = defineProps({
|
|||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showDeleteBtn: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
name: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
termsName: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
branchName: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
whenName: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
value: {
|
||||
type: Object as PropType<TermsType>,
|
||||
default: () => ({
|
||||
|
@ -176,13 +197,13 @@ const showDouble = computed(() => {
|
|||
})
|
||||
|
||||
const mouseover = () => {
|
||||
if (props.name !== 0){
|
||||
if (props.showDeleteBtn){
|
||||
showDelete.value = true
|
||||
}
|
||||
}
|
||||
|
||||
const mouseout = () => {
|
||||
if (props.name !== 0){
|
||||
if (props.showDeleteBtn){
|
||||
showDelete.value = false
|
||||
}
|
||||
}
|
||||
|
@ -205,11 +226,21 @@ const termsTypeSelect = () => {
|
|||
}
|
||||
|
||||
const termAdd = () => {
|
||||
|
||||
const terms = {
|
||||
column: undefined,
|
||||
value: {
|
||||
source: 'fixed',
|
||||
value: undefined
|
||||
},
|
||||
termType: undefined,
|
||||
type: 'and',
|
||||
key: `params_${new Date().getTime()}`
|
||||
}
|
||||
formModel.value.branches?.[props.branchName]?.when?.[props.whenName]?.terms?.push(terms)
|
||||
}
|
||||
|
||||
const onDelete = () => {
|
||||
|
||||
formModel.value.branches?.[props.branchName]?.when?.[props.whenName]?.terms?.splice(props.name, 1)
|
||||
}
|
||||
|
||||
nextTick(() => {
|
||||
|
|
|
@ -32,13 +32,13 @@
|
|||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<j-form-item
|
||||
v-else
|
||||
:name='["branches", 0, "then"]'
|
||||
:rules='rules'
|
||||
>
|
||||
|
||||
</j-form-item>
|
||||
<!-- <j-form-item-->
|
||||
<!-- v-else-->
|
||||
<!-- :name='["branches", 0, "then"]'-->
|
||||
<!-- :rules='rules'-->
|
||||
<!-- >-->
|
||||
<!-- -->
|
||||
<!-- </j-form-item>-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -65,18 +65,6 @@ const change = (e: boolean) => {
|
|||
open.value = e
|
||||
}
|
||||
|
||||
const rules = [{
|
||||
validator(_: string, value: any) {
|
||||
if (!value || (value && !value.length)) {
|
||||
return Promise.reject('至少配置一个执行动作')
|
||||
} else {
|
||||
const isActions = value.some((item: any) => item.actions && item.actions.length)
|
||||
return isActions ? Promise.resolve() : Promise.reject('至少配置一个执行动作');
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
}]
|
||||
|
||||
const handleParamsData = (data: any[]): any[] => {
|
||||
return data?.map(item => {
|
||||
return {
|
||||
|
@ -97,7 +85,19 @@ const queryColumn = (dataModel: FormModelType) => {
|
|||
}
|
||||
|
||||
const addBranches = () => {
|
||||
|
||||
const branchesItem = {
|
||||
when: [],
|
||||
key: `branches_${new Date().getTime()}`,
|
||||
shakeLimit: {
|
||||
enabled: false,
|
||||
time: 1,
|
||||
threshold: 1,
|
||||
alarmFirst: false,
|
||||
},
|
||||
then: [],
|
||||
}
|
||||
const lastIndex = data.value.branches!.length - 1 || 0
|
||||
data.value.branches?.splice(lastIndex, 1, branchesItem)
|
||||
}
|
||||
|
||||
const branchesDelete = (index: number) => {
|
||||
|
|
|
@ -26,21 +26,29 @@
|
|||
</j-popconfirm>
|
||||
|
||||
<j-form-item
|
||||
v-for='(item, index) in data.terms'
|
||||
v-for='(item, index) in termsData'
|
||||
:key='item.key'
|
||||
:name='["branches", branchName, "when", whenName, "terms", index]'
|
||||
>
|
||||
<ParamsItem
|
||||
v-model:value='formModel.branches[branchName].when[whenName].terms[index]'
|
||||
:isFirst='index === 0'
|
||||
:isLast='index === data.terms.length - 1'
|
||||
:isLast='index === termsData.length - 1'
|
||||
:showDeleteBtn='termsData.length !== 1'
|
||||
:name='index'
|
||||
:termsName='name'
|
||||
:whenName='whenName'
|
||||
:branchName='branchName'
|
||||
@change='paramsChange'
|
||||
@delete='paramsDelete'
|
||||
@add='paramsAdd'
|
||||
/>
|
||||
</j-form-item>
|
||||
</div>
|
||||
<div class='terms-group-add' @click='addTerms' v-if='isLast'>
|
||||
<div class='terms-content'>
|
||||
<AIcon type='PlusOutlined' />
|
||||
<span>分组</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -61,6 +69,14 @@ const props = defineProps({
|
|||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
isLast: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showDeleteBtn: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
data: {
|
||||
type: Object as PropType<TermsType>,
|
||||
default: () => ({
|
||||
|
@ -73,6 +89,10 @@ const props = defineProps({
|
|||
type: String,
|
||||
default: ''
|
||||
},
|
||||
name: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
branchName: {
|
||||
type: Number,
|
||||
default: 0
|
||||
|
@ -85,36 +105,48 @@ const props = defineProps({
|
|||
|
||||
const showDelete = ref(false)
|
||||
|
||||
const termsData = computed(() => {
|
||||
return props.data.terms
|
||||
})
|
||||
|
||||
const mouseover = () => {
|
||||
if (props.whenName !== 0){
|
||||
if (props.showDeleteBtn){
|
||||
showDelete.value = true
|
||||
}
|
||||
}
|
||||
|
||||
const mouseout = () => {
|
||||
if (props.whenName !== 0){
|
||||
if (props.showDeleteBtn){
|
||||
showDelete.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const onDelete = () => {
|
||||
|
||||
}
|
||||
|
||||
const onDeleteAll = () => {
|
||||
|
||||
formModel.value.branches?.[props.branchName]?.when?.splice(props.name, 1)
|
||||
}
|
||||
|
||||
const paramsChange = () => {
|
||||
|
||||
}
|
||||
|
||||
const paramsDelete = () => {
|
||||
|
||||
const addTerms = () => {
|
||||
const terms = {
|
||||
type: 'and',
|
||||
terms: [
|
||||
{
|
||||
column: undefined,
|
||||
value: {
|
||||
source: 'fixed',
|
||||
value: undefined
|
||||
},
|
||||
termType: undefined,
|
||||
key: 'params_1',
|
||||
type: 'and',
|
||||
}
|
||||
|
||||
const paramsAdd = () => {
|
||||
|
||||
],
|
||||
key: `terms_${new Date().getTime()}`
|
||||
}
|
||||
formModel.value.branches?.[props.branchName]?.when?.push(terms)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
position: absolute;
|
||||
top: -10px;
|
||||
right: -10px;
|
||||
display: none;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
color: #999;
|
||||
|
@ -37,7 +36,7 @@
|
|||
.actions-terms {
|
||||
.actions-terms-warp {
|
||||
display: flex;
|
||||
width: 66.66%;
|
||||
//width: 66.66%;
|
||||
margin-bottom: 24px;
|
||||
|
||||
&.first-children {
|
||||
|
|
|
@ -714,7 +714,7 @@
|
|||
placeholder="请选中角色"
|
||||
></j-select>
|
||||
<PermissionButton
|
||||
:uhasPermission="`${rolePermission}:update`"
|
||||
:hasPermission="`${rolePermission}:update`"
|
||||
type="link"
|
||||
@click="
|
||||
clickAddItem(
|
||||
|
@ -755,7 +755,7 @@
|
|||
</template>
|
||||
</j-tree-select>
|
||||
<PermissionButton
|
||||
:uhasPermission="`${deptPermission}:update`"
|
||||
:hasPermission="`${deptPermission}:update`"
|
||||
type="link"
|
||||
@click="
|
||||
clickAddItem(
|
||||
|
@ -1000,7 +1000,7 @@
|
|||
/>
|
||||
</j-form-item>
|
||||
<j-form-item label="logo">
|
||||
<a-upload
|
||||
<j-upload
|
||||
v-model:file-list="form.fileList"
|
||||
accept=".jpg,.png,.jfif,.pjp,.pjpeg,.jpeg"
|
||||
:maxCount="1"
|
||||
|
@ -1036,7 +1036,7 @@
|
|||
点击上传图片
|
||||
</div>
|
||||
</div>
|
||||
</a-upload>
|
||||
</j-upload>
|
||||
</j-form-item>
|
||||
|
||||
<j-form-item
|
||||
|
@ -1297,7 +1297,7 @@
|
|||
placeholder="请选中角色"
|
||||
></j-select>
|
||||
<PermissionButton
|
||||
:uhasPermission="`${rolePermission}:update`"
|
||||
:hasPermission="`${rolePermission}:update`"
|
||||
type="link"
|
||||
@click="
|
||||
clickAddItem(
|
||||
|
@ -1332,7 +1332,7 @@
|
|||
</template>
|
||||
</j-tree-select>
|
||||
<PermissionButton
|
||||
:uhasPermission="`${deptPermission}:update`"
|
||||
:hasPermission="`${deptPermission}:update`"
|
||||
type="link"
|
||||
@click="
|
||||
clickAddItem(
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<template #headerTitle>
|
||||
<div style="display: flex; align-items: center">
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:add`"
|
||||
:hasPermission="`${permission}:add`"
|
||||
type="primary"
|
||||
@click="() => table.toSave()"
|
||||
>
|
||||
|
@ -110,7 +110,7 @@
|
|||
</j-dropdown>
|
||||
<PermissionButton
|
||||
v-else
|
||||
:uhasPermission="item.permission"
|
||||
:hasPermission="item.permission"
|
||||
:tooltip="item.tooltip"
|
||||
:pop-confirm="item.popConfirm"
|
||||
@click="item.onClick"
|
||||
|
@ -151,7 +151,7 @@
|
|||
<j-space :size="16">
|
||||
<PermissionButton
|
||||
v-for="i in table.getActions(slotProps, 'table')"
|
||||
:uhasPermission="i.permission"
|
||||
:hasPermission="i.permission"
|
||||
type="link"
|
||||
:tooltip="i.tooltip"
|
||||
:pop-confirm="i.popConfirm"
|
||||
|
@ -190,7 +190,7 @@ import { useMenuStore } from '@/store/menu';
|
|||
import { message } from 'ant-design-vue';
|
||||
|
||||
const menuStory = useMenuStore();
|
||||
const permission = 'system/User';
|
||||
const permission = 'system/Apply';
|
||||
const typeOptions = [
|
||||
{
|
||||
label: '内部独立应用',
|
||||
|
@ -312,7 +312,7 @@ const table = {
|
|||
|
||||
const result = [
|
||||
{
|
||||
permission: true,
|
||||
permission: `${permission}:update`,
|
||||
key: 'edit',
|
||||
text: '编辑',
|
||||
tooltip: {
|
||||
|
@ -322,7 +322,7 @@ const table = {
|
|||
onClick: () => table.toSave(data.id),
|
||||
},
|
||||
{
|
||||
permission: true,
|
||||
permission: `${permission}:update`,
|
||||
key: 'action',
|
||||
text: disabled ? '禁用' : '启用',
|
||||
tooltip: {
|
||||
|
@ -335,7 +335,7 @@ const table = {
|
|||
icon: disabled ? 'StopOutlined' : 'PlayCircleOutlined',
|
||||
},
|
||||
{
|
||||
permission: true,
|
||||
permission: `${permission}:delete`,
|
||||
key: 'delete',
|
||||
text: '删除',
|
||||
tooltip: {
|
||||
|
@ -348,7 +348,7 @@ const table = {
|
|||
disabled,
|
||||
icon: 'DeleteOutlined',
|
||||
},
|
||||
] as ActionsType[];
|
||||
] as any[];
|
||||
const otherServers = data.integrationModes.map(
|
||||
(item: any) => item.value as string,
|
||||
);
|
||||
|
@ -356,12 +356,12 @@ const table = {
|
|||
key: 'others',
|
||||
text: '其他',
|
||||
icon: 'EllipsisOutlined',
|
||||
children: [] as ActionsType[],
|
||||
children: [] as any[],
|
||||
};
|
||||
// 有集成菜单权限
|
||||
if (otherServers.includes('page'))
|
||||
others.children?.push({
|
||||
permission: true,
|
||||
permission: [`${permission}:add`,`${permission}:update`],
|
||||
key: 'page',
|
||||
text: '集成菜单',
|
||||
tooltip: {
|
||||
|
@ -378,7 +378,7 @@ const table = {
|
|||
if (otherServers.includes('apiServer'))
|
||||
others.children?.push(
|
||||
{
|
||||
permission: true,
|
||||
permission: [`${permission}:add`,`${permission}:update`],
|
||||
key: 'empowerment',
|
||||
text: '赋权',
|
||||
tooltip: {
|
||||
|
@ -394,7 +394,7 @@ const table = {
|
|||
},
|
||||
},
|
||||
{
|
||||
permission: true,
|
||||
permission: [`${permission}:add`,`${permission}:update`],
|
||||
key: 'viewApi',
|
||||
text: '查看API',
|
||||
tooltip: {
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
<j-form-item label="系统logo">
|
||||
<div class="upload-image-warp-logo">
|
||||
<div class="upload-image-border-logo">
|
||||
<a-upload
|
||||
<j-upload
|
||||
name="file"
|
||||
:action="action"
|
||||
:headers="headers"
|
||||
|
@ -114,7 +114,7 @@
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
</a-upload>
|
||||
</j-upload>
|
||||
<div v-if="form.logoLoading">
|
||||
<div
|
||||
class="upload-loading-mask"
|
||||
|
@ -152,7 +152,7 @@
|
|||
</template>
|
||||
<div class="upload-image-warp-logo">
|
||||
<div class="upload-image-border-logo">
|
||||
<a-upload
|
||||
<j-upload
|
||||
name="file"
|
||||
:action="action"
|
||||
:headers="headers"
|
||||
|
@ -201,7 +201,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-upload>
|
||||
</j-upload>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -215,7 +215,7 @@
|
|||
<j-form-item label="登录背景图">
|
||||
<div class="upload-image-warp-back">
|
||||
<div class="upload-image-border-back">
|
||||
<a-upload
|
||||
<j-upload
|
||||
name="file"
|
||||
:action="action"
|
||||
:headers="headers"
|
||||
|
@ -256,7 +256,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-upload>
|
||||
</j-upload>
|
||||
</div>
|
||||
</div>
|
||||
<div class="upload-tips">
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
</template>
|
||||
<template #action="slotProps">
|
||||
<PermissionButton
|
||||
:uhasPermission="`{permission}:delete`"
|
||||
:hasPermission="`{permission}:delete`"
|
||||
type="link"
|
||||
:tooltip="{ title: '删除' }"
|
||||
:popConfirm="{
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<template #headerTitle>
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
:uhasPermission="`${permission}:add`"
|
||||
:hasPermission="`${permission}:add`"
|
||||
@click="table.openDialog({})"
|
||||
>
|
||||
<AIcon type="PlusOutlined" />新增
|
||||
|
@ -47,7 +47,7 @@
|
|||
<template #action="slotProps">
|
||||
<j-space :size="16">
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:update`"
|
||||
:hasPermission="`${permission}:update`"
|
||||
type="link"
|
||||
:tooltip="{
|
||||
title: '编辑',
|
||||
|
@ -57,7 +57,7 @@
|
|||
<AIcon type="EditOutlined" />
|
||||
</PermissionButton>
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:manage`"
|
||||
:hasPermission="`${permission}:manage`"
|
||||
type="link"
|
||||
:tooltip="{
|
||||
title:
|
||||
|
@ -81,7 +81,7 @@
|
|||
<AIcon type="icon-ziyuankuguanli" />
|
||||
</PermissionButton>
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:action`"
|
||||
:hasPermission="`${permission}:action`"
|
||||
type="link"
|
||||
:popConfirm="{
|
||||
title: `确定要${
|
||||
|
@ -109,7 +109,7 @@
|
|||
</PermissionButton>
|
||||
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:delete`"
|
||||
:hasPermission="`${permission}:delete`"
|
||||
type="link"
|
||||
:tooltip="{
|
||||
title: table.getRowStatus(slotProps)
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<template #headerTitle>
|
||||
<j-space>
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:assert`"
|
||||
:hasPermission="`${permission}:assert`"
|
||||
type="primary"
|
||||
@click="table.clickAdd"
|
||||
>
|
||||
|
@ -32,7 +32,7 @@
|
|||
<j-menu>
|
||||
<j-menu-item>
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:bind`"
|
||||
:hasPermission="`${permission}:bind`"
|
||||
:popConfirm="{
|
||||
title: `是否批量解除绑定`,
|
||||
onConfirm: () =>
|
||||
|
@ -46,7 +46,7 @@
|
|||
</j-menu-item>
|
||||
<j-menu-item>
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:assert`"
|
||||
:hasPermission="`${permission}:assert`"
|
||||
@click="table.clickEdit()"
|
||||
>
|
||||
<AIcon type="EditOutlined" />批量编辑
|
||||
|
@ -117,14 +117,14 @@
|
|||
</template>
|
||||
<template #actions>
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:assert`"
|
||||
:hasPermission="`${permission}:assert`"
|
||||
@click="table.clickEdit(slotProps)"
|
||||
>
|
||||
<AIcon type="EditOutlined" />
|
||||
</PermissionButton>
|
||||
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:bind`"
|
||||
:hasPermission="`${permission}:bind`"
|
||||
:popConfirm="{
|
||||
title: `是否解除绑定`,
|
||||
onConfirm: () => table.clickUnBind(slotProps),
|
||||
|
@ -157,7 +157,7 @@
|
|||
<j-space :size="16">
|
||||
<PermissionButton
|
||||
v-for="i in table.getActions(slotProps, 'table')"
|
||||
:uhasPermission="i.permission"
|
||||
:hasPermission="i.permission"
|
||||
type="link"
|
||||
:tooltip="i?.tooltip"
|
||||
:pop-confirm="i.popConfirm"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<template #headerTitle>
|
||||
<j-space>
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:assert`"
|
||||
:hasPermission="`${permission}:assert`"
|
||||
type="primary"
|
||||
@click="dialogs.addShow = true"
|
||||
>
|
||||
|
@ -32,7 +32,7 @@
|
|||
<j-menu>
|
||||
<j-menu-item>
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:bind`"
|
||||
:hasPermission="`${permission}:bind`"
|
||||
:popConfirm="{
|
||||
title: `是否批量解除绑定`,
|
||||
onConfirm: () =>
|
||||
|
@ -46,7 +46,7 @@
|
|||
</j-menu-item>
|
||||
<j-menu-item>
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:assert`"
|
||||
:hasPermission="`${permission}:assert`"
|
||||
@click="() => table.clickEdit()"
|
||||
>
|
||||
<AIcon type="EditOutlined" />批量编辑
|
||||
|
|
|
@ -203,7 +203,7 @@
|
|||
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
:uhasPermission="`${permission}:update`"
|
||||
:hasPermission="`${permission}:update`"
|
||||
@click="form.clickSave"
|
||||
>
|
||||
保存
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<template #headerTitle>
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
:uhasPermission="`${permission}:update`"
|
||||
:hasPermission="`${permission}:update`"
|
||||
@click="openDialog('新增', {})"
|
||||
>
|
||||
<AIcon type="PlusOutlined" />新增
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<template #headerTitle>
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
:uhasPermission="`${permission}:add`"
|
||||
:hasPermission="`${permission}:add`"
|
||||
@click="table.toDetails({})"
|
||||
>
|
||||
<AIcon type="PlusOutlined" />新增
|
||||
|
@ -51,7 +51,7 @@
|
|||
|
||||
<PermissionButton
|
||||
type="link"
|
||||
:uhasPermission="`${permission}:add`"
|
||||
:hasPermission="`${permission}:add`"
|
||||
:tooltip="{ title: '新增子菜单' }"
|
||||
@click="table.addChildren(slotProps)"
|
||||
>
|
||||
|
@ -59,7 +59,7 @@
|
|||
</PermissionButton>
|
||||
<PermissionButton
|
||||
type="link"
|
||||
:uhasPermission="`${permission}:delete`"
|
||||
:hasPermission="`${permission}:delete`"
|
||||
:tooltip="{ title: '删除' }"
|
||||
:popConfirm="{
|
||||
title: `是否删除该菜单`,
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<template #overlay>
|
||||
<j-menu>
|
||||
<j-menu-item>
|
||||
<a-upload
|
||||
<j-upload
|
||||
name="file"
|
||||
action="#"
|
||||
accept=".json"
|
||||
|
@ -45,7 +45,7 @@
|
|||
>
|
||||
导入
|
||||
</PermissionButton>
|
||||
</a-upload>
|
||||
</j-upload>
|
||||
</j-menu-item>
|
||||
<j-menu-item>
|
||||
<PermissionButton
|
||||
|
@ -76,7 +76,7 @@
|
|||
<template #action="slotProps">
|
||||
<j-space :size="16">
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:update`"
|
||||
:hasPermission="`${permission}:update`"
|
||||
type="link"
|
||||
:tooltip="{
|
||||
title: '编辑',
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
<template v-else-if="column.key === 'action'">
|
||||
<PermissionButton
|
||||
type="link"
|
||||
:uhasPermission="`{permission}:delete`"
|
||||
:hasPermission="`{permission}:delete`"
|
||||
:popConfirm="{
|
||||
title: `确定删除`,
|
||||
onConfirm: () =>
|
||||
|
|
|
@ -64,7 +64,7 @@ const confirm = () => {
|
|||
// @ts-ignore
|
||||
window?.onSaveSuccess(resp.result.id);
|
||||
window.close();
|
||||
} else jumpPage(`system/Role/detail`, { id: resp.result.id });
|
||||
} else jumpPage(`system/Role/Detail`, { id: resp.result.id });
|
||||
}
|
||||
})
|
||||
.finally(() => (loading.value = false));
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<template #headerTitle>
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
:uhasPermission="`${permission}:add`"
|
||||
:hasPermission="`${permission}:add`"
|
||||
@click="dialogVisible = true"
|
||||
>
|
||||
<AIcon type="PlusOutlined" />新增
|
||||
|
@ -33,7 +33,7 @@
|
|||
<template #action="slotProps">
|
||||
<j-space :size="16">
|
||||
<PermissionButton
|
||||
:uhasPermission="`${permission}:update`"
|
||||
:hasPermission="`${permission}:update`"
|
||||
type="link"
|
||||
:tooltip="{
|
||||
title: '编辑',
|
||||
|
@ -44,7 +44,7 @@
|
|||
</PermissionButton>
|
||||
<PermissionButton
|
||||
type="link"
|
||||
:uhasPermission="`${permission}:delete`"
|
||||
:hasPermission="`${permission}:delete`"
|
||||
:tooltip="{ title: '删除' }"
|
||||
:popConfirm="{
|
||||
title: `确定要删除吗`,
|
||||
|
|
Loading…
Reference in New Issue