fix: 修改设备列表为protable
This commit is contained in:
parent
dcf0b05bc7
commit
f7fac41743
|
@ -34,5 +34,9 @@ export default {
|
|||
// 微信绑定用户
|
||||
weChatBindUser: (data: any, id: string) => patch(`/user/third-party/weixin_corpMessage/${id}`, data),
|
||||
// 解绑
|
||||
unBindUser: (data: any, id: string) => post(`/user/third-party/${id}/_unbind`, data)
|
||||
unBindUser: (data: any, id: string) => post(`/user/third-party/${id}/_unbind`, data),
|
||||
//通知类型
|
||||
queryMessageType: () => get(`/notifier/config/types`),
|
||||
// 不分页-列表
|
||||
queryListNoPaging: (data: any) => post(`/notifier/config/_query/no-paging?paging=false`, data)
|
||||
}
|
|
@ -23,5 +23,6 @@ export default {
|
|||
// 语音/短信获取阿里云模板
|
||||
getAliTemplate: (id: any) => get(`/notifier/sms/aliyun/${id}/templates`),
|
||||
// 短信获取签名
|
||||
getSigns: (id: any) => get(`/notifier/sms/aliyun/${id}/signs`)
|
||||
getSigns: (id: any) => get(`/notifier/sms/aliyun/${id}/signs`),
|
||||
getListByConfigId: (id: string, data: any): any => post(`/notifier/template/${id}/_query`, data),
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<a-badge
|
||||
<j-badge
|
||||
:status="statusNames ? statusNames[status] : 'default'"
|
||||
:text="text"
|
||||
></a-badge>
|
||||
></j-badge>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<!-- 勾选 -->
|
||||
<div v-if="active" class="checked-icon">
|
||||
<div>
|
||||
<CheckOutlined />
|
||||
<AIcon type="CheckOutlined" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -62,24 +62,6 @@
|
|||
}"
|
||||
>
|
||||
<slot name="actions" v-bind="item"></slot>
|
||||
<!-- <a-popconfirm v-if="item.popConfirm" v-bind="item.popConfirm">
|
||||
<a-button :disabled="item.disabled">
|
||||
<DeleteOutlined v-if="item.key === 'delete'" />
|
||||
<template v-else>
|
||||
<AIcon :type="item.icon" />
|
||||
<span>{{ item.text }}</span>
|
||||
</template>
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
<template v-else>
|
||||
<a-button :disabled="item.disabled">
|
||||
<DeleteOutlined v-if="item.key === 'delete'" />
|
||||
<template v-else>
|
||||
<AIcon :type="item.icon" />
|
||||
<span>{{ item.text }}</span>
|
||||
</template>
|
||||
</a-button>
|
||||
</template> -->
|
||||
</div>
|
||||
</div>
|
||||
</slot>
|
||||
|
@ -87,13 +69,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
SearchOutlined,
|
||||
CheckOutlined,
|
||||
DeleteOutlined,
|
||||
} from '@ant-design/icons-vue';
|
||||
import BadgeStatus from '@/components/BadgeStatus/index.vue';
|
||||
import { StatusColorEnum } from '@/utils/consts.ts';
|
||||
import type { ActionsType } from '@/components/Table/index.vue';
|
||||
import { PropType } from 'vue';
|
||||
|
||||
|
|
|
@ -1,54 +1,54 @@
|
|||
<template>
|
||||
<template v-if="isPermission">
|
||||
<template v-if="popConfirm">
|
||||
<a-popconfirm v-bind="popConfirm" :disabled="!isPermission || props.disabled">
|
||||
<a-tooltip v-if="tooltip" v-bind="tooltip">
|
||||
<j-popconfirm v-bind="popConfirm" :disabled="!isPermission || props.disabled">
|
||||
<j-tooltip v-if="tooltip" v-bind="tooltip">
|
||||
<slot v-if="noButton"></slot>
|
||||
<a-button v-else v-bind="props" :disabled="_isPermission" :style="props.style">
|
||||
<j-button v-else v-bind="props" :disabled="_isPermission" :style="props.style">
|
||||
<slot></slot>
|
||||
<template #icon>
|
||||
<slot name="icon"></slot>
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-button v-else v-bind="props" :disabled="_isPermission" >
|
||||
</j-button>
|
||||
</j-tooltip>
|
||||
<j-button v-else v-bind="props" :disabled="_isPermission" >
|
||||
<slot></slot>
|
||||
<template #icon>
|
||||
<slot name="icon"></slot>
|
||||
</template>
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
</j-button>
|
||||
</j-popconfirm>
|
||||
</template>
|
||||
<template v-else-if="tooltip">
|
||||
<a-tooltip v-bind="tooltip">
|
||||
<j-tooltip v-bind="tooltip">
|
||||
<slot v-if="noButton"></slot>
|
||||
<a-button v-else v-bind="props" :disabled="_isPermission" :style="props.style">
|
||||
<j-button v-else v-bind="props" :disabled="_isPermission" :style="props.style">
|
||||
<slot></slot>
|
||||
<template #icon>
|
||||
<slot name="icon"></slot>
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</j-button>
|
||||
</j-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<slot v-if="noButton"></slot>
|
||||
<a-button v-else v-bind="props" :disabled="_isPermission" :style="props.style">
|
||||
<j-button v-else v-bind="props" :disabled="_isPermission" :style="props.style">
|
||||
<slot></slot>
|
||||
<template #icon>
|
||||
<slot name="icon"></slot>
|
||||
</template>
|
||||
</a-button>
|
||||
</j-button>
|
||||
</template>
|
||||
</template>
|
||||
<a-tooltip v-else title="没有权限">
|
||||
<j-tooltip v-else title="没有权限">
|
||||
<slot v-if="noButton"></slot>
|
||||
<a-button v-else v-bind="props" :disabled="_isPermission" :style="props.style">
|
||||
<j-button v-else v-bind="props" :disabled="_isPermission" :style="props.style">
|
||||
<slot></slot>
|
||||
<template #icon>
|
||||
<slot name="icon"></slot>
|
||||
</template>
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</j-button>
|
||||
</j-tooltip>
|
||||
</template>
|
||||
<script setup lang="ts" name="PermissionButton">
|
||||
import { CSSProperties, PropType } from 'vue'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<a-drawer placement="right" :closable="false" :visible="true">
|
||||
<j-drawer placement="right" :closable="false" :visible="true">
|
||||
<template #title>
|
||||
<div
|
||||
style="
|
||||
|
@ -15,21 +15,21 @@
|
|||
@click="onClose"
|
||||
/>编辑配置</span
|
||||
>
|
||||
<a-button type="primary" @click="saveBtn">保存</a-button>
|
||||
<j-button type="primary" @click="saveBtn">保存</j-button>
|
||||
</div>
|
||||
</template>
|
||||
<a-form layout="vertical" ref="formRef" :model="modelRef">
|
||||
<j-form layout="vertical" ref="formRef" :model="modelRef">
|
||||
<template v-for="(item, index) in props.config" :key="index">
|
||||
<a-form-item
|
||||
<j-form-item
|
||||
:name="item.property"
|
||||
v-for="i in item.properties"
|
||||
:key="i.property"
|
||||
>
|
||||
<template #label>
|
||||
<span style="margin-right: 5px">{{ i.name }}</span>
|
||||
<a-tooltip v-if="i.description" :title="i.description"
|
||||
<j-tooltip v-if="i.description" :title="i.description"
|
||||
><AIcon type="QuestionCircleOutlined"
|
||||
/></a-tooltip>
|
||||
/></j-tooltip>
|
||||
</template>
|
||||
<ValueItem
|
||||
v-model:modelValue="modelRef[i.property]"
|
||||
|
@ -45,10 +45,10 @@
|
|||
: undefined
|
||||
"
|
||||
/>
|
||||
</a-form-item>
|
||||
</j-form-item>
|
||||
</template>
|
||||
</a-form>
|
||||
</a-drawer>
|
||||
</j-form>
|
||||
</j-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div style="margin-top: 20px" v-if="config.length">
|
||||
<div style="display: flex; margin-bottom: 20px; align-items: center">
|
||||
<div style="font-size: 16px; font-weight: 700">配置</div>
|
||||
<a-space>
|
||||
<j-space>
|
||||
<PermissionButton
|
||||
type="link"
|
||||
@click="visible = true"
|
||||
|
@ -20,10 +20,10 @@
|
|||
}"
|
||||
hasPermission="device/Instance:update"
|
||||
>
|
||||
<AIcon type="CheckOutlined" />应用配置<a-tooltip
|
||||
<AIcon type="CheckOutlined" />应用配置<j-tooltip
|
||||
title="修改配置后需重新应用后才能生效。"
|
||||
><AIcon type="QuestionCircleOutlined"
|
||||
/></a-tooltip>
|
||||
/></j-tooltip>
|
||||
</PermissionButton>
|
||||
<PermissionButton
|
||||
type="link"
|
||||
|
@ -34,26 +34,26 @@
|
|||
}"
|
||||
hasPermission="device/Instance:update"
|
||||
>
|
||||
<AIcon type="SyncOutlined" />恢复默认<a-tooltip
|
||||
<AIcon type="SyncOutlined" />恢复默认<j-tooltip
|
||||
title="该设备单独编辑过配置信息,点击此将恢复成默认的配置信息,请谨慎操作。"
|
||||
><AIcon type="QuestionCircleOutlined"
|
||||
/></a-tooltip>
|
||||
/></j-tooltip>
|
||||
</PermissionButton>
|
||||
</a-space>
|
||||
</j-space>
|
||||
</div>
|
||||
<a-descriptions bordered size="small" v-for="i in config" :key="i.name">
|
||||
<j-descriptions bordered size="small" v-for="i in config" :key="i.name">
|
||||
<template #title
|
||||
><h4 style="font-size: 15px">{{ i.name }}</h4></template
|
||||
>
|
||||
<a-descriptions-item
|
||||
<j-descriptions-item
|
||||
v-for="item in i.properties"
|
||||
:key="item.property"
|
||||
>
|
||||
<template #label>
|
||||
<span style="margin-right: 5px">{{ item.name }}</span>
|
||||
<a-tooltip v-if="item.description" :title="item.description"
|
||||
<j-tooltip v-if="item.description" :title="item.description"
|
||||
><AIcon type="QuestionCircleOutlined"
|
||||
/></a-tooltip>
|
||||
/></j-tooltip>
|
||||
</template>
|
||||
<span
|
||||
v-if="
|
||||
|
@ -68,7 +68,7 @@
|
|||
instanceStore.current?.configuration?.[item.property] ||
|
||||
''
|
||||
}}</span>
|
||||
<a-tooltip
|
||||
<j-tooltip
|
||||
v-if="isExit(item.property)"
|
||||
:title="`有效值:${
|
||||
instanceStore.current?.configuration?.[
|
||||
|
@ -76,10 +76,10 @@
|
|||
]
|
||||
}`"
|
||||
><AIcon type="QuestionCircleOutlined"
|
||||
/></a-tooltip>
|
||||
/></j-tooltip>
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</j-descriptions-item>
|
||||
</j-descriptions>
|
||||
<Save
|
||||
v-if="visible"
|
||||
@save="saveBtn"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<a-drawer placement="right" :closable="false" :visible="true">
|
||||
<j-drawer placement="right" :closable="false" :visible="true">
|
||||
<template #title>
|
||||
<div
|
||||
style="
|
||||
|
@ -15,32 +15,32 @@
|
|||
@click="onClose"
|
||||
/>编辑</span
|
||||
>
|
||||
<a-button type="primary" @click="saveBtn">保存</a-button>
|
||||
<j-button type="primary" @click="saveBtn">保存</j-button>
|
||||
</div>
|
||||
</template>
|
||||
<a-form layout="vertical" ref="formRef" :model="modelRef">
|
||||
<a-form-item
|
||||
<j-form layout="vertical" ref="formRef" :model="modelRef">
|
||||
<j-form-item
|
||||
:name="item.relation"
|
||||
:label="item.relationName"
|
||||
v-for="(item, index) in dataSource"
|
||||
:key="index"
|
||||
>
|
||||
<a-select
|
||||
<j-select
|
||||
showSearch
|
||||
mode="multiple"
|
||||
v-model:value="modelRef[item.relation]"
|
||||
:placeholder="`请选择${item.relationName}`"
|
||||
>
|
||||
<a-select-option
|
||||
<j-select-option
|
||||
:value="item.value"
|
||||
v-for="item in userList"
|
||||
:key="item.id"
|
||||
>{{ item.name }}</a-select-option
|
||||
>{{ item.name }}</j-select-option
|
||||
>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-drawer>
|
||||
</j-select>
|
||||
</j-form-item>
|
||||
</j-form>
|
||||
</j-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div style="margin-top: 20px">
|
||||
<a-descriptions bordered>
|
||||
<j-descriptions bordered>
|
||||
<template #title>
|
||||
关系信息
|
||||
<PermissionButton
|
||||
|
@ -8,13 +8,13 @@
|
|||
@click="visible = true"
|
||||
hasPermission="device/Instance:update"
|
||||
>
|
||||
<AIcon type="EditOutlined" />编辑<a-tooltip
|
||||
<AIcon type="EditOutlined" />编辑<j-tooltip
|
||||
title="管理设备与其他业务的关联关系,关系来源于关系配置"
|
||||
><AIcon type="QuestionCircleOutlined"
|
||||
/></a-tooltip>
|
||||
/></j-tooltip>
|
||||
</PermissionButton>
|
||||
</template>
|
||||
<a-descriptions-item
|
||||
<j-descriptions-item
|
||||
:span="1"
|
||||
v-for="item in dataSource"
|
||||
:key="item.objectId"
|
||||
|
@ -23,9 +23,9 @@
|
|||
item?.related
|
||||
? (item?.related || []).map((i) => i.name).join(',')
|
||||
: ''
|
||||
}}</a-descriptions-item
|
||||
}}</j-descriptions-item
|
||||
>
|
||||
</a-descriptions>
|
||||
</j-descriptions>
|
||||
<Save v-if="visible" @save="saveBtn" @close="visible = false" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<template>
|
||||
<a-modal
|
||||
<j-modal
|
||||
:width="1000"
|
||||
:visible="true"
|
||||
title="编辑标签"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-table
|
||||
<j-table
|
||||
rowKey="id"
|
||||
:columns="columns"
|
||||
:data-source="dataSource"
|
||||
:datj-source="dataSource"
|
||||
bordered
|
||||
:pagination="false"
|
||||
>
|
||||
|
@ -43,8 +43,8 @@
|
|||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-modal>
|
||||
</j-table>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div style="margin-top: 20px">
|
||||
<a-descriptions bordered>
|
||||
<j-descriptions bordered>
|
||||
<template #title>
|
||||
标签
|
||||
<PermissionButton
|
||||
|
@ -11,14 +11,14 @@
|
|||
<AIcon type="EditOutlined" />编辑
|
||||
</PermissionButton>
|
||||
</template>
|
||||
<a-descriptions-item
|
||||
<j-descriptions-item
|
||||
:span="1"
|
||||
v-for="item in dataSource"
|
||||
:key="item.key"
|
||||
:label="`${item.name}(${item.key})`"
|
||||
>{{ item?.value }}</a-descriptions-item
|
||||
>{{ item?.value }}</j-descriptions-item
|
||||
>
|
||||
</a-descriptions>
|
||||
</j-descriptions>
|
||||
<Save v-if="visible" @close="visible = false" @save="saveBtn" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<a-card>
|
||||
<a-descriptions bordered>
|
||||
<j-card>
|
||||
<j-descriptions bordered>
|
||||
<template #title>
|
||||
设备信息
|
||||
<PermissionButton
|
||||
|
@ -12,59 +12,59 @@
|
|||
编辑
|
||||
</PermissionButton>
|
||||
</template>
|
||||
<a-descriptions-item label="设备ID">{{
|
||||
<j-descriptions-item label="设备ID">{{
|
||||
instanceStore.current.id
|
||||
}}</a-descriptions-item>
|
||||
<a-descriptions-item label="产品名称">{{
|
||||
}}</j-descriptions-item>
|
||||
<j-descriptions-item label="产品名称">{{
|
||||
instanceStore.current.productName
|
||||
}}</a-descriptions-item>
|
||||
<a-descriptions-item label="产品分类">{{
|
||||
}}</j-descriptions-item>
|
||||
<j-descriptions-item label="产品分类">{{
|
||||
instanceStore.current.classifiedName
|
||||
}}</a-descriptions-item>
|
||||
<a-descriptions-item label="设备类型">{{
|
||||
}}</j-descriptions-item>
|
||||
<j-descriptions-item label="设备类型">{{
|
||||
instanceStore.current.deviceType?.text
|
||||
}}</a-descriptions-item>
|
||||
<a-descriptions-item label="固件版本">{{
|
||||
}}</j-descriptions-item>
|
||||
<j-descriptions-item label="固件版本">{{
|
||||
instanceStore.current.firmwareInfo?.version
|
||||
}}</a-descriptions-item>
|
||||
<a-descriptions-item label="连接协议">{{
|
||||
}}</j-descriptions-item>
|
||||
<j-descriptions-item label="连接协议">{{
|
||||
instanceStore.current?.protocolName
|
||||
}}</a-descriptions-item>
|
||||
<a-descriptions-item label="消息协议">{{
|
||||
}}</j-descriptions-item>
|
||||
<j-descriptions-item label="消息协议">{{
|
||||
instanceStore.current.transport
|
||||
}}</a-descriptions-item>
|
||||
<a-descriptions-item label="创建时间">{{
|
||||
}}</j-descriptions-item>
|
||||
<j-descriptions-item label="创建时间">{{
|
||||
instanceStore.current.createTime
|
||||
? moment(instanceStore.current.createTime).format(
|
||||
'YYYY-MM-DD HH:mm:ss',
|
||||
)
|
||||
: ''
|
||||
}}</a-descriptions-item>
|
||||
<a-descriptions-item label="注册时间">{{
|
||||
}}</j-descriptions-item>
|
||||
<j-descriptions-item label="注册时间">{{
|
||||
instanceStore.current.registerTime
|
||||
? moment(instanceStore.current.registerTime).format(
|
||||
'YYYY-MM-DD HH:mm:ss',
|
||||
)
|
||||
: ''
|
||||
}}</a-descriptions-item>
|
||||
<a-descriptions-item label="最后上线时间">{{
|
||||
}}</j-descriptions-item>
|
||||
<j-descriptions-item label="最后上线时间">{{
|
||||
instanceStore.current.onlineTime
|
||||
? moment(instanceStore.current.onlineTime).format(
|
||||
'YYYY-MM-DD HH:mm:ss',
|
||||
)
|
||||
: ''
|
||||
}}</a-descriptions-item>
|
||||
<a-descriptions-item
|
||||
}}</j-descriptions-item>
|
||||
<j-descriptions-item
|
||||
label="父设备"
|
||||
v-if="
|
||||
instanceStore.current.deviceType?.value === 'childrenDevice'
|
||||
"
|
||||
>{{ instanceStore.current.parentId }}</a-descriptions-item
|
||||
>{{ instanceStore.current.parentId }}</j-descriptions-item
|
||||
>
|
||||
<a-descriptions-item label="说明">{{
|
||||
<j-descriptions-item label="说明">{{
|
||||
instanceStore.current.description
|
||||
}}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
}}</j-descriptions-item>
|
||||
</j-descriptions>
|
||||
<Config />
|
||||
<Tags
|
||||
v-if="
|
||||
|
@ -84,7 +84,7 @@
|
|||
@close="visible = false"
|
||||
@save="saveBtn"
|
||||
/>
|
||||
</a-card>
|
||||
</j-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<a-card>
|
||||
<j-card>
|
||||
<Search
|
||||
:columns="columns"
|
||||
target="device-instance-log"
|
||||
@search="handleSearch"
|
||||
/>
|
||||
<JTable
|
||||
<JProTable
|
||||
ref="instanceRefLog"
|
||||
:columns="columns"
|
||||
:request="(e: Record<string, any>) => queryLog(instanceStore.current.id, e)"
|
||||
|
@ -26,23 +26,23 @@
|
|||
}}
|
||||
</template>
|
||||
<template #action="slotProps">
|
||||
<a-space>
|
||||
<j-space>
|
||||
<template
|
||||
v-for="i in getActions(slotProps, 'table')"
|
||||
:key="i.key"
|
||||
>
|
||||
<a-button
|
||||
<j-button
|
||||
@click="i.onClick"
|
||||
type="link"
|
||||
style="padding: 0px"
|
||||
>
|
||||
<template #icon><AIcon :type="i.icon" /></template>
|
||||
</a-button>
|
||||
</j-button>
|
||||
</template>
|
||||
</a-space>
|
||||
</j-space>
|
||||
</template>
|
||||
</JTable>
|
||||
</a-card>
|
||||
</JProTable>
|
||||
</j-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<template>
|
||||
<a-spin :spinning="loading">
|
||||
<JTable
|
||||
<j-spin :spinning="loading">
|
||||
<JProTable
|
||||
:columns="columns"
|
||||
:dataSource="dataSource"
|
||||
:bodyStyle="{ padding: '0 0 0 20px' }"
|
||||
>
|
||||
<template #headerTitle>
|
||||
<a-input-search
|
||||
<j-input-search
|
||||
placeholder="请输入名称"
|
||||
style="width: 300px; margin-bottom: 10px"
|
||||
@search="onSearch"
|
||||
|
@ -31,18 +31,18 @@
|
|||
{{ propertyValue[slotProps?.id]?.timeString || '--' }}
|
||||
</template>
|
||||
<template #action="slotProps">
|
||||
<a-space :size="16">
|
||||
<j-space :size="16">
|
||||
<template v-for="i in getActions(slotProps)" :key="i.key">
|
||||
<a-tooltip v-bind="i.tooltip" v-if="i.key !== 'edit'">
|
||||
<a-button
|
||||
<j-tooltip v-bind="i.tooltip" v-if="i.key !== 'edit'">
|
||||
<j-button
|
||||
style="padding: 0"
|
||||
type="link"
|
||||
:disabled="i.disabled"
|
||||
@click="i.onClick && i.onClick(slotProps)"
|
||||
>
|
||||
<AIcon :type="i.icon" />
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</j-button>
|
||||
</j-tooltip>
|
||||
<PermissionButton
|
||||
:disabled="i.disabled"
|
||||
v-else
|
||||
|
@ -56,10 +56,10 @@
|
|||
<template #icon><AIcon :type="i.icon" /></template>
|
||||
</PermissionButton>
|
||||
</template>
|
||||
</a-space>
|
||||
</j-space>
|
||||
</template>
|
||||
<template #paginationRender>
|
||||
<a-pagination
|
||||
<j-pagination
|
||||
size="small"
|
||||
:total="total"
|
||||
:showQuickJumper="false"
|
||||
|
@ -78,8 +78,8 @@
|
|||
@change="pageChange"
|
||||
/>
|
||||
</template>
|
||||
</JTable>
|
||||
</a-spin>
|
||||
</JProTable>
|
||||
</j-spin>
|
||||
<Save v-if="editVisible" @close="editVisible = false" :data="currentInfo" />
|
||||
<Indicators
|
||||
v-if="indicatorVisible"
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<template>
|
||||
<a-card>
|
||||
<j-card>
|
||||
<div class="property-box">
|
||||
<div class="property-box-left">
|
||||
<a-input-search
|
||||
<j-input-search
|
||||
v-model:value="value"
|
||||
placeholder="请输入事件名称"
|
||||
style="width: 200px; margin-bottom: 10px"
|
||||
@search="onSearch"
|
||||
:allowClear="true"
|
||||
/>
|
||||
<a-tabs
|
||||
<j-tabs
|
||||
tab-position="left"
|
||||
style="height: 600px"
|
||||
v-if="tabList.length"
|
||||
|
@ -17,12 +17,12 @@
|
|||
:tabBarStyle="{ width: '200px' }"
|
||||
@change="tabChange"
|
||||
>
|
||||
<a-tab-pane
|
||||
<j-tab-pane
|
||||
v-for="i in tabList"
|
||||
:key="i.key"
|
||||
:tab="i.tab"
|
||||
/>
|
||||
</a-tabs>
|
||||
</j-tabs>
|
||||
<JEmpty v-else style="margin: 250px 0" />
|
||||
</div>
|
||||
<div class="property-box-right">
|
||||
|
@ -30,7 +30,7 @@
|
|||
<Property v-else :data="properties" />
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
</j-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
|
|
@ -1,88 +1,88 @@
|
|||
<template>
|
||||
<a-modal
|
||||
<j-modal
|
||||
:maskClosable="false"
|
||||
width="650px"
|
||||
:visible="true"
|
||||
:title="!!props.data.id ? '编辑' : '新增'"
|
||||
:title="!!data?.id ? '编辑' : '新增'"
|
||||
@ok="handleSave"
|
||||
@cancel="handleCancel"
|
||||
:confirmLoading="loading"
|
||||
>
|
||||
<div style="margin-top: 10px">
|
||||
<a-form
|
||||
<j-form
|
||||
:layout="'vertical'"
|
||||
ref="formRef"
|
||||
:rules="rules"
|
||||
:model="modelRef"
|
||||
>
|
||||
<a-row type="flex">
|
||||
<a-col flex="180px">
|
||||
<a-form-item name="photoUrl">
|
||||
<j-row type="flex">
|
||||
<j-col flex="180px">
|
||||
<j-form-item name="photoUrl">
|
||||
<JUpload v-model="modelRef.photoUrl" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col flex="auto">
|
||||
<a-form-item name="id">
|
||||
</j-form-item>
|
||||
</j-col>
|
||||
<j-col flex="auto">
|
||||
<j-form-item name="id">
|
||||
<template #label>
|
||||
<span>
|
||||
ID
|
||||
<a-tooltip title="若不填写,系统将自动生成唯一ID">
|
||||
<j-tooltip title="若不填写,系统将自动生成唯一ID">
|
||||
<AIcon
|
||||
type="QuestionCircleOutlined"
|
||||
style="margin-left: 2px;" />
|
||||
</a-tooltip>
|
||||
</j-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<a-input
|
||||
<j-input
|
||||
v-model:value="modelRef.id"
|
||||
placeholder="请输入ID"
|
||||
:disabled="!!props.data.id"
|
||||
:disabled="!!data?.id"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="名称" name="name">
|
||||
<a-input
|
||||
</j-form-item>
|
||||
<j-form-item label="名称" name="name">
|
||||
<j-input
|
||||
v-model:value="modelRef.name"
|
||||
placeholder="请输入名称"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-form-item name="productId">
|
||||
</j-form-item>
|
||||
</j-col>
|
||||
</j-row>
|
||||
<j-form-item name="productId">
|
||||
<template #label>
|
||||
<span>所属产品
|
||||
<a-tooltip title="只能选择“正常”状态的产品">
|
||||
<j-tooltip title="只能选择“正常”状态的产品">
|
||||
<AIcon
|
||||
type="QuestionCircleOutlined"
|
||||
style="margin-left: 2px" />
|
||||
</a-tooltip>
|
||||
</j-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<a-select
|
||||
<j-select
|
||||
showSearch
|
||||
v-model:value="modelRef.productId"
|
||||
placeholder="请选择所属产品"
|
||||
:filter-option="filterOption"
|
||||
>
|
||||
<a-select-option
|
||||
<j-select-option
|
||||
:value="item.id"
|
||||
v-for="item in productList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:disabled="!!props.data.id"
|
||||
>{{item.name}}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="说明" name="describe">
|
||||
<a-textarea
|
||||
:disabled="!!data?.id"
|
||||
>{{item.name}}</j-select-option>
|
||||
</j-select>
|
||||
</j-form-item>
|
||||
<j-form-item label="说明" name="describe">
|
||||
<j-textarea
|
||||
v-model:value="modelRef.describe"
|
||||
placeholder="请输入说明"
|
||||
showCount
|
||||
:maxlength="200"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</j-form-item>
|
||||
</j-form>
|
||||
</div>
|
||||
</a-modal>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
@ -157,7 +157,7 @@ const rules = {
|
|||
message: '最多输入64个字符',
|
||||
},
|
||||
{
|
||||
pattern: /^[a-zA-Z0-9_\-]+$/,
|
||||
pattern: /^[j-zA-Z0-9_\-]+$/,
|
||||
message: '请输入英文或者数字或者-或者_',
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<page-container>
|
||||
<Search
|
||||
<JSearch
|
||||
:columns="columns"
|
||||
target="device-instance"
|
||||
@search="handleSearch"
|
||||
/>
|
||||
<JTable
|
||||
<JProTable
|
||||
ref="instanceRef"
|
||||
:columns="columns"
|
||||
:request="query"
|
||||
|
@ -18,7 +18,7 @@
|
|||
:params="params"
|
||||
>
|
||||
<template #headerTitle>
|
||||
<a-space>
|
||||
<j-space>
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
@click="handleAdd"
|
||||
|
@ -27,13 +27,13 @@
|
|||
<template #icon><AIcon type="PlusOutlined" /></template>
|
||||
新增
|
||||
</PermissionButton>
|
||||
<a-dropdown>
|
||||
<a-button
|
||||
<j-dropdown>
|
||||
<j-button
|
||||
>批量操作 <AIcon type="DownOutlined"
|
||||
/></a-button>
|
||||
/></j-button>
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item>
|
||||
<j-menu>
|
||||
<j-menu-item>
|
||||
<PermissionButton
|
||||
@click="exportVisible = true"
|
||||
hasPermission="device/Instance:export"
|
||||
|
@ -43,8 +43,8 @@
|
|||
/></template>
|
||||
批量导出设备
|
||||
</PermissionButton>
|
||||
</a-menu-item>
|
||||
<a-menu-item>
|
||||
</j-menu-item>
|
||||
<j-menu-item>
|
||||
<PermissionButton
|
||||
@click="importVisible = true"
|
||||
hasPermission="device/Instance:import"
|
||||
|
@ -54,8 +54,8 @@
|
|||
/></template>
|
||||
批量导入设备
|
||||
</PermissionButton>
|
||||
</a-menu-item>
|
||||
<a-menu-item>
|
||||
</j-menu-item>
|
||||
<j-menu-item>
|
||||
<PermissionButton
|
||||
ghost
|
||||
type="primary"
|
||||
|
@ -70,8 +70,8 @@
|
|||
/></template>
|
||||
激活全部设备
|
||||
</PermissionButton>
|
||||
</a-menu-item>
|
||||
<a-menu-item>
|
||||
</j-menu-item>
|
||||
<j-menu-item>
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
@click="syncDeviceStatus"
|
||||
|
@ -82,8 +82,8 @@
|
|||
/></template>
|
||||
同步设备状态
|
||||
</PermissionButton>
|
||||
</a-menu-item>
|
||||
<a-menu-item v-if="_selectedRowKeys.length">
|
||||
</j-menu-item>
|
||||
<j-menu-item v-if="_selectedRowKeys.length">
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
danger
|
||||
|
@ -98,8 +98,8 @@
|
|||
/></template>
|
||||
删除选中设备
|
||||
</PermissionButton>
|
||||
</a-menu-item>
|
||||
<a-menu-item v-if="_selectedRowKeys.length">
|
||||
</j-menu-item>
|
||||
<j-menu-item v-if="_selectedRowKeys.length">
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
:popConfirm="{
|
||||
|
@ -113,8 +113,8 @@
|
|||
/></template>
|
||||
激活选中设备
|
||||
</PermissionButton>
|
||||
</a-menu-item>
|
||||
<a-menu-item v-if="_selectedRowKeys.length">
|
||||
</j-menu-item>
|
||||
<j-menu-item v-if="_selectedRowKeys.length">
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
danger
|
||||
|
@ -129,11 +129,11 @@
|
|||
/></template>
|
||||
禁用选中设备
|
||||
</PermissionButton>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</j-menu-item>
|
||||
</j-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-space>
|
||||
</j-dropdown>
|
||||
</j-space>
|
||||
</template>
|
||||
<template #card="slotProps">
|
||||
<CardBox
|
||||
|
@ -160,22 +160,22 @@
|
|||
{{ slotProps.name }}
|
||||
</span>
|
||||
</Ellipsis>
|
||||
<a-row style="margin-top: 20px">
|
||||
<a-col :span="12">
|
||||
<j-row style="margin-top: 20px">
|
||||
<j-col :span="12">
|
||||
<div class="card-item-content-text">
|
||||
设备类型
|
||||
</div>
|
||||
<div>{{ slotProps.deviceType?.text }}</div>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
</j-col>
|
||||
<j-col :span="12">
|
||||
<div class="card-item-content-text">
|
||||
产品名称
|
||||
</div>
|
||||
<Ellipsis style="width: 100%">
|
||||
{{ slotProps.productName }}
|
||||
</Ellipsis>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</j-col>
|
||||
</j-row>
|
||||
</template>
|
||||
<template #actions="item">
|
||||
<PermissionButton
|
||||
|
@ -200,13 +200,13 @@
|
|||
</CardBox>
|
||||
</template>
|
||||
<template #state="slotProps">
|
||||
<a-badge
|
||||
<j-badge
|
||||
:text="slotProps.state?.text"
|
||||
:status="statusMap.get(slotProps.state?.value)"
|
||||
/>
|
||||
</template>
|
||||
<template #action="slotProps">
|
||||
<a-space>
|
||||
<j-space>
|
||||
<template
|
||||
v-for="i in getActions(slotProps, 'table')"
|
||||
:key="i.key"
|
||||
|
@ -225,9 +225,9 @@
|
|||
<template #icon><AIcon :type="i.icon" /></template>
|
||||
</PermissionButton>
|
||||
</template>
|
||||
</a-space>
|
||||
</j-space>
|
||||
</template>
|
||||
</JTable>
|
||||
</JProTable>
|
||||
</page-container>
|
||||
<Import v-if="importVisible" @close="importVisible = false" />
|
||||
<Export
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
<Title :options='data.options.trigger' />
|
||||
</AddButton>
|
||||
</a-form-item>
|
||||
<Action />
|
||||
<AddModel v-if='visible' @cancel='visible = false' v-model='data.device' v-model:options='data.options.trigger' />
|
||||
</div>
|
||||
</template>
|
||||
|
@ -24,6 +25,7 @@ import { useSceneStore } from '@/store/scene'
|
|||
import AddModel from './AddModal.vue'
|
||||
import AddButton from '../components/AddButton.vue'
|
||||
import Title from '../components/Title.vue'
|
||||
import Action from '../action/index.vue'
|
||||
|
||||
const sceneStore = useSceneStore()
|
||||
const { data } = storeToRefs<any>(sceneStore)
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<template>
|
||||
<j-modal
|
||||
title="延迟执行"
|
||||
visible
|
||||
:width="400"
|
||||
@cancel="onCancel"
|
||||
@ok="onOk"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<a-input-number
|
||||
style="max-width: 220px"
|
||||
placeholder="请输入时间"
|
||||
v-model:value="value"
|
||||
:precision="3"
|
||||
:min="0"
|
||||
:max="6535"
|
||||
>
|
||||
<template #addonAfter>
|
||||
<a-select
|
||||
:options="[
|
||||
{ label: '秒', value: 'seconds' },
|
||||
{ label: '分', value: 'minutes' },
|
||||
{ label: '小时', value: 'hours' },
|
||||
]"
|
||||
v-model:value="unit"
|
||||
/>
|
||||
</template>
|
||||
</a-input-number>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
|
||||
const timeUnitEnum = {
|
||||
seconds: '秒',
|
||||
minutes: '分',
|
||||
hours: '小时',
|
||||
};
|
||||
|
||||
const emit = defineEmits(['cancel', 'save']);
|
||||
|
||||
const value = ref<number>(0);
|
||||
const unit = ref<'seconds' | 'minutes' | 'hours'>('seconds');
|
||||
|
||||
const onCancel = () => {
|
||||
emit('cancel');
|
||||
};
|
||||
const onOk = () => {
|
||||
if (unref(value) || unref(value) === 0) {
|
||||
} else {
|
||||
onlyMessage('请输入时间', 'error');
|
||||
}
|
||||
emit(
|
||||
'save',
|
||||
{
|
||||
time: value.value,
|
||||
unit: unit.value,
|
||||
},
|
||||
{ name: `${value.value} ${timeUnitEnum[unit.value]}后,执行后续动作` },
|
||||
);
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,22 @@
|
|||
<template>
|
||||
<j-modal
|
||||
title="执行动作"
|
||||
visible
|
||||
:width="860"
|
||||
@cancel="onCancel"
|
||||
@ok="onOk"
|
||||
:maskClosable="false"
|
||||
>
|
||||
device
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const emit = defineEmits(['cancel', 'save']);
|
||||
const onCancel = () => {
|
||||
emit('cancel');
|
||||
};
|
||||
const onOk = () => {
|
||||
emit('save');
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
<div>ITEM</div>
|
||||
</template>
|
|
@ -0,0 +1,74 @@
|
|||
<template>
|
||||
<div class="action-list-content">
|
||||
<div class="actions-add-list" :class="{'border': props.actions.length}">
|
||||
<j-button type="primary" ghost style="width: 100%" @click="onAdd">
|
||||
<template #icon><AIcon type="PlusOutlined" /></template>
|
||||
添加执行动作
|
||||
</j-button>
|
||||
</div>
|
||||
<Modal v-if="visible" @cancel="visible = false" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { PropType } from 'vue';
|
||||
import { ActionsType, ParallelType } from '../../../typings';
|
||||
import Modal from '../Modal/index.vue'
|
||||
|
||||
interface ListProps {
|
||||
branchesName: number;
|
||||
type: ParallelType;
|
||||
actions: ActionsType[];
|
||||
parallel: boolean;
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
branchesName: Number,
|
||||
type: {
|
||||
type: String as PropType<ListProps['type']>,
|
||||
default: 'serial',
|
||||
},
|
||||
actions: {
|
||||
type: Array as PropType<ListProps['actions']>,
|
||||
default: () => [],
|
||||
},
|
||||
parallel: Boolean,
|
||||
});
|
||||
|
||||
const visible = ref<boolean>(false)
|
||||
|
||||
const onAdd = () => {
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.action-list-content {
|
||||
padding: 8px;
|
||||
|
||||
.actions-list_form {
|
||||
.action-list-add {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-add-button {
|
||||
width: 100%;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.actions-add-list {
|
||||
&.border {
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,2 @@
|
|||
export { default as List } from './List.vue';
|
||||
export { default as Item } from './Item.vue';
|
|
@ -0,0 +1,105 @@
|
|||
<template>
|
||||
<j-modal
|
||||
title="类型"
|
||||
visible
|
||||
:width="860"
|
||||
@cancel="onCancel"
|
||||
@ok="onOk"
|
||||
:maskClosable="false"
|
||||
>
|
||||
<a-form ref="actionForm" :model="formModel" layout="vertical">
|
||||
<a-form-item
|
||||
label="类型"
|
||||
name="type"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请选择类型',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<j-card-select
|
||||
v-model:value="formModel.type"
|
||||
:options="options"
|
||||
type="horizontal"
|
||||
float="right"
|
||||
/>
|
||||
</a-form-item>
|
||||
<template v-if="actionType === 'device'">
|
||||
<Device @cancel="onCancel" @save="onPropsOk" />
|
||||
</template>
|
||||
<template v-else-if="actionType === 'notify'">
|
||||
<Notify @cancel="onCancel" @save="onPropsOk" />
|
||||
</template>
|
||||
<template v-else-if="actionType === 'delay'">
|
||||
<Delay @cancel="onCancel" @save="onPropsOk" />
|
||||
</template>
|
||||
</a-form>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { getImage } from '@/utils/comm';
|
||||
import Delay from '../Delay/index.vue'
|
||||
import Notify from '../Notify/index.vue'
|
||||
import Device from '../Device/index.vue'
|
||||
|
||||
const emit = defineEmits(['cancel', 'save']);
|
||||
|
||||
const options = [
|
||||
{
|
||||
label: '设备输出',
|
||||
value: 'device',
|
||||
iconUrl: getImage('/scene/device-type.png'),
|
||||
subLabel: '配置设备调用功能、读取属性、设置属性规则',
|
||||
},
|
||||
{
|
||||
label: '消息通知',
|
||||
value: 'notify',
|
||||
iconUrl: getImage('/scene/message-type.png'),
|
||||
subLabel: '配置向指定用户发邮件、钉钉、微信、短信等通知',
|
||||
},
|
||||
{
|
||||
label: '延迟执行',
|
||||
value: 'delay',
|
||||
iconUrl: getImage('/scene/delay-type.png'),
|
||||
subLabel: '等待一段时间后,再执行后续动作',
|
||||
},
|
||||
{
|
||||
label: '触发告警',
|
||||
value: 'trigger',
|
||||
iconUrl: getImage('/scene/trigger-type.png'),
|
||||
subLabel: '配置触发告警规则,需配合“告警配置”使用',
|
||||
},
|
||||
{
|
||||
label: '解除告警',
|
||||
value: 'relieve',
|
||||
iconUrl: getImage('/scene/cancel-type.png'),
|
||||
subLabel: '配置解除告警规则,需配合“告警配置”使用',
|
||||
},
|
||||
];
|
||||
|
||||
const actionForm = ref();
|
||||
const formModel = reactive({
|
||||
type: '',
|
||||
});
|
||||
|
||||
const actionType = ref<string>('')
|
||||
|
||||
const onCancel = () => {
|
||||
emit('cancel');
|
||||
};
|
||||
const onOk = () => {
|
||||
actionForm.value.validate().then((values: any) => {
|
||||
actionType.value = values?.type
|
||||
if (values?.type === 'relieve' || values?.type === 'trigger') {
|
||||
// emit('save');
|
||||
// props.save({ ...props.data, executor: 'alarm', alarm: { mode: values.type } }, {});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const onPropsOk = (data: any, option: any) => {
|
||||
console.log(data, option)
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,178 @@
|
|||
<template>
|
||||
<Search
|
||||
:columns="columns"
|
||||
type="simple"
|
||||
target="action-notice-config"
|
||||
@search="handleSearch"
|
||||
class="search"
|
||||
/>
|
||||
<div style="height: 400px; overflow-y: auto">
|
||||
<JTable
|
||||
:columns="columns"
|
||||
:request="ConfigApi.list"
|
||||
model="CARD"
|
||||
:bodyStyle="{
|
||||
paddingRight: 0,
|
||||
paddingLeft: 0,
|
||||
}"
|
||||
:defaultParams="{
|
||||
terms: [
|
||||
{
|
||||
terms: [
|
||||
{
|
||||
termType: 'eq',
|
||||
column: 'type',
|
||||
value: props.notifyType,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
sorts: [{ name: 'createTime', order: 'desc' }],
|
||||
}"
|
||||
:params="params"
|
||||
:gridColumn="2"
|
||||
:gridColumns="[2, 2, 2]"
|
||||
:rowSelection="{
|
||||
selectedRowKeys: _selectedRowKeys,
|
||||
}"
|
||||
@cancelSelect="cancelSelect"
|
||||
>
|
||||
<template #card="slotProps">
|
||||
<CardBox
|
||||
:showStatus="false"
|
||||
:value="slotProps"
|
||||
:showTool="false"
|
||||
:actions="[]"
|
||||
v-bind="slotProps"
|
||||
@click="handleClick"
|
||||
:active="_selectedRowKeys.includes(slotProps.id)"
|
||||
>
|
||||
<template #img>
|
||||
<slot name="img">
|
||||
<img
|
||||
:src="
|
||||
getLogo(slotProps.type, slotProps.provider)
|
||||
"
|
||||
class="logo"
|
||||
/>
|
||||
</slot>
|
||||
</template>
|
||||
<template #content>
|
||||
<Ellipsis style="width: calc(100% - 100px)">
|
||||
<span style="font-size: 16px; font-weight: 600">
|
||||
{{ slotProps.name }}
|
||||
</span>
|
||||
</Ellipsis>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<div class="card-item-content-text">
|
||||
通知方式
|
||||
</div>
|
||||
<div>
|
||||
{{ getMethodTxt(slotProps.type) }}
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<div class="card-item-content-text">说明</div>
|
||||
<Ellipsis>
|
||||
{{ slotProps.description }}
|
||||
</Ellipsis>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
</CardBox>
|
||||
</template>
|
||||
</JTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ConfigApi from '@/api/notice/config';
|
||||
import { MSG_TYPE, NOTICE_METHOD } from '@/views/notice/const';
|
||||
const props = defineProps({
|
||||
notifyType: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:value']);
|
||||
|
||||
const getLogo = (type: string, provider: string) => {
|
||||
return MSG_TYPE[type].find((f: any) => f.value === provider)?.logo;
|
||||
};
|
||||
|
||||
const getMethodTxt = (type: string) => {
|
||||
return NOTICE_METHOD.find((f) => f.value === type)?.label;
|
||||
};
|
||||
|
||||
const params = ref<Record<string, any>>({});
|
||||
const _selectedRowKeys = ref<string[]>([]);
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
search: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
search: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '说明',
|
||||
dataIndex: 'description',
|
||||
key: 'description',
|
||||
search: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const handleSearch = (_params: any) => {
|
||||
params.value = _params;
|
||||
};
|
||||
|
||||
const cancelSelect = () => {
|
||||
_selectedRowKeys.value = [];
|
||||
};
|
||||
|
||||
const handleClick = (dt: any) => {
|
||||
_selectedRowKeys.value = [dt.id];
|
||||
emit('update:value', dt.id);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
(newValue) => {
|
||||
if (newValue) {
|
||||
_selectedRowKeys.value = [newValue];
|
||||
} else {
|
||||
_selectedRowKeys.value = [];
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.search {
|
||||
margin-bottom: 0;
|
||||
padding-right: 0px;
|
||||
padding-left: 0px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,167 @@
|
|||
<template>
|
||||
<Search
|
||||
:columns="columns"
|
||||
type="simple"
|
||||
target="action-notice-template"
|
||||
@search="handleSearch"
|
||||
class="search"
|
||||
/>
|
||||
<div style="height: 400px; overflow-y: auto">
|
||||
<JTable
|
||||
:columns="columns"
|
||||
:request="(e) => TemplateApi.getListByConfigId(props.notifierId, e)"
|
||||
model="CARD"
|
||||
:bodyStyle="{
|
||||
paddingRight: 0,
|
||||
paddingLeft: 0,
|
||||
}"
|
||||
:defaultParams="{
|
||||
sorts: [{ name: 'createTime', order: 'desc' }],
|
||||
}"
|
||||
:params="params"
|
||||
:gridColumn="2"
|
||||
:gridColumns="[2, 2, 2]"
|
||||
:rowSelection="{
|
||||
selectedRowKeys: _selectedRowKeys,
|
||||
}"
|
||||
@cancelSelect="cancelSelect"
|
||||
>
|
||||
<template #card="slotProps">
|
||||
<CardBox
|
||||
:showStatus="false"
|
||||
:value="slotProps"
|
||||
:showTool="false"
|
||||
:actions="[]"
|
||||
v-bind="slotProps"
|
||||
@click="handleClick"
|
||||
:active="_selectedRowKeys.includes(slotProps.id)"
|
||||
>
|
||||
<template #img>
|
||||
<slot name="img">
|
||||
<img
|
||||
:src="
|
||||
getLogo(slotProps.type, slotProps.provider)
|
||||
"
|
||||
class="logo"
|
||||
/>
|
||||
</slot>
|
||||
</template>
|
||||
<template #content>
|
||||
<Ellipsis style="width: calc(100% - 100px)">
|
||||
<span style="font-size: 16px; font-weight: 600">
|
||||
{{ slotProps.name }}
|
||||
</span>
|
||||
</Ellipsis>
|
||||
<a-row>
|
||||
<a-col :span="12">
|
||||
<div class="card-item-content-text">
|
||||
通知方式
|
||||
</div>
|
||||
<div>
|
||||
{{ getMethodTxt(slotProps.type) }}
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<div class="card-item-content-text">说明</div>
|
||||
<Ellipsis>
|
||||
{{ slotProps.description }}
|
||||
</Ellipsis>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
</CardBox>
|
||||
</template>
|
||||
</JTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import TemplateApi from '@/api/notice/template';
|
||||
import { MSG_TYPE, NOTICE_METHOD } from '@/views/notice/const';
|
||||
const props = defineProps({
|
||||
notifierId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:value']);
|
||||
|
||||
const getLogo = (type: string, provider: string) => {
|
||||
return MSG_TYPE[type].find((f: any) => f.value === provider)?.logo;
|
||||
};
|
||||
|
||||
const getMethodTxt = (type: string) => {
|
||||
return NOTICE_METHOD.find((f) => f.value === type)?.label;
|
||||
};
|
||||
|
||||
const params = ref<Record<string, any>>({});
|
||||
const _selectedRowKeys = ref<string[]>([]);
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
search: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
search: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '说明',
|
||||
dataIndex: 'description',
|
||||
key: 'description',
|
||||
search: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const handleSearch = (_params: any) => {
|
||||
params.value = _params;
|
||||
};
|
||||
|
||||
const cancelSelect = () => {
|
||||
_selectedRowKeys.value = [];
|
||||
};
|
||||
|
||||
const handleClick = (dt: any) => {
|
||||
_selectedRowKeys.value = [dt.id];
|
||||
emit('update:value', dt.id);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
(newValue) => {
|
||||
if (newValue) {
|
||||
_selectedRowKeys.value = [newValue];
|
||||
} else {
|
||||
_selectedRowKeys.value = [];
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.search {
|
||||
margin-bottom: 0;
|
||||
padding-right: 0px;
|
||||
padding-left: 0px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,61 @@
|
|||
<template>
|
||||
<a-spin :spinning="loading">
|
||||
<j-card-select
|
||||
v-model:value="notifyType"
|
||||
:options="options"
|
||||
:icon-size="106"
|
||||
/>
|
||||
</a-spin>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { getImage } from '@/utils/comm';
|
||||
import notice from '@/api/notice/config';
|
||||
|
||||
const iconMap = new Map();
|
||||
iconMap.set('dingTalk', getImage('/notice/dingtalk.png'));
|
||||
iconMap.set('weixin', getImage('/notice/wechat.png'));
|
||||
iconMap.set('email', getImage('/notice/email.png'));
|
||||
iconMap.set('voice', getImage('/notice/voice.png'));
|
||||
iconMap.set('sms', getImage('/notice/sms.png'));
|
||||
iconMap.set('webhook', getImage('/notice/webhook.png'));
|
||||
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:value'])
|
||||
|
||||
const loading = ref<boolean>(false);
|
||||
const notifyType = ref('');
|
||||
const options = ref<any[]>([]);
|
||||
|
||||
watch(
|
||||
() => notifyType,
|
||||
(newVal) => {
|
||||
emit('update:value', newVal)
|
||||
},
|
||||
{ deep: true, immediate: true },
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
notice.queryMessageType().then((resp) => {
|
||||
if (resp.status === 200) {
|
||||
options.value = (resp.result as any[]).map((item) => {
|
||||
return {
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
iconUrl: iconMap.get(item.id),
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
notifyType.value = props.value
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
</style>
|
|
@ -0,0 +1,70 @@
|
|||
<template>
|
||||
<a-form
|
||||
v-if="variableDefinitions.length"
|
||||
:layout="'vertical'"
|
||||
ref="formRef"
|
||||
:model="modelRef"
|
||||
>
|
||||
<template v-for="item in variableDefinitions" :key="item.id">
|
||||
<a-form-item
|
||||
:name="item.id"
|
||||
:label="item.name"
|
||||
:rules="[{ required: true, message: `请输入${item.name}` }]"
|
||||
>
|
||||
<User
|
||||
v-if="getType(item) === 'user'"
|
||||
v-model="modelRef[`${item.id}`]"
|
||||
/>
|
||||
<Org
|
||||
v-else-if="getType(item) === 'org'"
|
||||
v-model="modelRef[`${item.id}`]"
|
||||
/>
|
||||
<Tag
|
||||
v-else-if="getType(item) === 'tag'"
|
||||
v-model="modelRef[`${item.id}`]"
|
||||
/>
|
||||
<InputFile
|
||||
v-else-if="getType(item) === 'file'"
|
||||
v-model="modelRef[`${item.id}`]"
|
||||
/>
|
||||
<a-input
|
||||
v-else-if="getType(item) === 'link'"
|
||||
v-model="modelRef[`${item.id}`]"
|
||||
/>
|
||||
<BuildIn
|
||||
v-else
|
||||
v-model="modelRef[`${item.id}`]"
|
||||
/>
|
||||
</a-form-item>
|
||||
</template>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import BuildIn from './variableItem/BuildIn.vue';
|
||||
import Org from './variableItem/Org.vue';
|
||||
import Tag from './variableItem/Tag.vue';
|
||||
import InputFile from './variableItem/InputFile.vue';
|
||||
import User from './variableItem/User.vue';
|
||||
|
||||
const props = defineProps({
|
||||
variableDefinitions: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const formRef = ref();
|
||||
|
||||
const modelRef = reactive({});
|
||||
|
||||
Object.assign(formRef, props.value);
|
||||
|
||||
const getType = (item: any) => {
|
||||
return item.expands?.businessType || item.type;
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,146 @@
|
|||
<template>
|
||||
<j-modal
|
||||
title="执行动作"
|
||||
visible
|
||||
:width="860"
|
||||
@cancel="onCancel"
|
||||
@ok="onOk"
|
||||
: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>
|
||||
</div>
|
||||
<div class="steps-content">
|
||||
<a-form ref="actionForm" :model="formModel" layout="vertical">
|
||||
<template v-if="current === 0">
|
||||
<a-form-item
|
||||
label="应用"
|
||||
name="notifyType"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请选择通知方式',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<NotifyWay v-model:value="formModel.notifyType" />
|
||||
</a-form-item>
|
||||
</template>
|
||||
<template v-if="current === 1">
|
||||
<a-form-item name="notifierId">
|
||||
<NotifyConfig v-model:value="formModel.notifierId" :notifyType="formModel.notifyType" />
|
||||
</a-form-item>
|
||||
</template>
|
||||
<template v-if="current === 2">
|
||||
<a-form-item name="templateId">
|
||||
<NotifyTemplate v-model:value="formModel.templateId" :notifierId="formModel.notifierId" />
|
||||
</a-form-item>
|
||||
</template>
|
||||
<template v-if="current === 3">
|
||||
<a-form-item name="variables">
|
||||
<VariableDefinitions
|
||||
:variableDefinitions="variable"
|
||||
v-model:value="formModel.variables"
|
||||
/>
|
||||
</a-form-item>
|
||||
</template>
|
||||
</a-form>
|
||||
</div>
|
||||
<template #footer>
|
||||
<a-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">下一步</j-button>
|
||||
<j-button v-if="current === 3" type="primary" @click="onOk">确定</j-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import NotifyWay from './NotifyWay.vue';
|
||||
import NotifyConfig from './NotifyConfig.vue';
|
||||
import NotifyTemplate from './NotifyTemplate.vue';
|
||||
import VariableDefinitions from './VariableDefinitions.vue';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
import Template from '@/api/notice/template';
|
||||
|
||||
const emit = defineEmits(['cancel', 'save']);
|
||||
|
||||
const current = ref(0);
|
||||
|
||||
const formModel = reactive({
|
||||
notifyType: '',
|
||||
notifierId: '',
|
||||
templateId: '',
|
||||
variables: [],
|
||||
});
|
||||
|
||||
const variable = ref([]);
|
||||
|
||||
const jumpStep = async (val: number) => {
|
||||
if (val === 0) {
|
||||
current.value = val;
|
||||
} else if (val === 1) {
|
||||
if (formModel.notifyType) {
|
||||
current.value = val
|
||||
} else {
|
||||
onlyMessage('请选择通知方式', 'error');
|
||||
}
|
||||
} else if (val === 2) {
|
||||
if (formModel.notifierId) {
|
||||
current.value = val
|
||||
} else {
|
||||
onlyMessage('请选择通知配置', 'error');
|
||||
}
|
||||
} else if (val === 3) {
|
||||
formModel.templateId = '1628943618904956928'
|
||||
if (formModel.templateId) {
|
||||
const resp = await Template.getTemplateDetail(formModel.templateId);
|
||||
if (resp.status === 200) {
|
||||
variable.value = resp.result?.variableDefinitions || [];
|
||||
current.value = val
|
||||
}
|
||||
} else {
|
||||
onlyMessage('请选择通知模板', 'error');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onChange = (cur: number) => {
|
||||
jumpStep(cur)
|
||||
};
|
||||
|
||||
const prev = () => {
|
||||
current.value -= 1;
|
||||
};
|
||||
|
||||
const next = async () => {
|
||||
jumpStep(current.value + 1)
|
||||
};
|
||||
|
||||
const onCancel = () => {
|
||||
emit('cancel');
|
||||
};
|
||||
const onOk = () => {
|
||||
emit('save');
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.steps-steps {
|
||||
width: 100%;
|
||||
margin-bottom: 17px;
|
||||
padding-bottom: 17px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.steps-content {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
build-in
|
||||
</template>
|
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
input-file
|
||||
</template>
|
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
org
|
||||
</template>
|
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
tag
|
||||
</template>
|
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
user
|
||||
</template>
|
|
@ -0,0 +1,133 @@
|
|||
<template>
|
||||
<div class="actions">
|
||||
<div class="actions-title">
|
||||
<span>执行</span>
|
||||
<ShakeLimit
|
||||
v-if="props.openShakeLimit"
|
||||
v-model:value="shakeLimit"
|
||||
/>
|
||||
</div>
|
||||
<div class="actions-warp">
|
||||
<a-collapse v-model:activeKey="activeKeys">
|
||||
<a-collapse-panel key="1">
|
||||
<template #header>
|
||||
<span>
|
||||
串行
|
||||
<span class="panel-tip">
|
||||
按顺序依次执行动作,适用于基于动作输出参数,判断是否执行后续动作的场景
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
<div class="actions-list">
|
||||
<List
|
||||
type="serial"
|
||||
:branchesName="props.name"
|
||||
:parallel="false"
|
||||
:actions="serialArray.length ? serialArray[0].actions : []"
|
||||
/>
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
<a-collapse-panel key="2">
|
||||
<template #header>
|
||||
<span>
|
||||
并行
|
||||
<span class="panel-tip">
|
||||
同时执行所有动作,适用于不需要关注执行动作先后顺序和结果的场景
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
<div class="actions-list">
|
||||
<List
|
||||
type="parallel"
|
||||
:branchesName="props.name"
|
||||
:parallel="true"
|
||||
:actions="parallelArray.length ? parallelArray[0].actions : []"
|
||||
/>
|
||||
</div>
|
||||
</a-collapse-panel>
|
||||
</a-collapse>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ShakeLimit from '../components/ShakeLimit/index.vue';
|
||||
import { List } from './ListItem';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useSceneStore } from '@/store/scene';
|
||||
import { BranchesThen } from '../../typings';
|
||||
import { PropType } from 'vue';
|
||||
|
||||
interface ActionsProps {
|
||||
name: number;
|
||||
openShakeLimit?: boolean;
|
||||
thenOptions: BranchesThen[];
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
name: Number,
|
||||
thenOptions: {
|
||||
type: Array as PropType<ActionsProps['thenOptions']>,
|
||||
default: () => [],
|
||||
},
|
||||
openShakeLimit: Boolean,
|
||||
});
|
||||
|
||||
const shakeLimit = ref({});
|
||||
const activeKeys = ref<string[]>(['1']);
|
||||
const parallelArray = ref<BranchesThen[]>([]);
|
||||
const serialArray = ref<BranchesThen[]>([]);
|
||||
const lock = ref<boolean>(false)
|
||||
|
||||
watch(
|
||||
() => props.thenOptions,
|
||||
(newVal) => {
|
||||
parallelArray.value = newVal.filter((item) => item.parallel);
|
||||
serialArray.value = newVal.filter((item) => !item.parallel);
|
||||
|
||||
const isSerialActions = serialArray.value.some((item) => {
|
||||
return !!item.actions.length;
|
||||
});
|
||||
|
||||
if (
|
||||
!lock.value &&
|
||||
parallelArray.value.length &&
|
||||
(!serialArray.value.length || !isSerialActions)
|
||||
) {
|
||||
activeKeys.value = ['2']
|
||||
lock.value = true
|
||||
}
|
||||
|
||||
//TODO 回传数据
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.actions {
|
||||
.actions-title {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
font-weight: 800;
|
||||
font-size: 14px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.actions-warp {
|
||||
.actions-list {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-tip {
|
||||
padding-left: 8px;
|
||||
color: rgba(#000, 0.45);
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,85 @@
|
|||
<template>
|
||||
<div class="shakeLimit">
|
||||
<a-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" />
|
||||
<span>秒内发送</span>
|
||||
<a-input-number :min="1" :max="100" :precision="0" size="small" v-model:value="shakeLimit.threshold" style="width: 32px" />
|
||||
<span>次及以上时,处理</span>
|
||||
<a-radio-group :options="alarmFirstOptions" optionType="button" v-model:value="shakeLimit.alarmFirst" size="small" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { cloneDeep } from "lodash-es";
|
||||
import { PropType } from "vue";
|
||||
|
||||
type ShakeLimitType = {
|
||||
enabled: boolean | undefined,
|
||||
time?: number | undefined | null,
|
||||
threshold?: number | undefined | null,
|
||||
alarmFirst?: boolean | undefined
|
||||
}
|
||||
|
||||
type Emit = {
|
||||
(e: 'update:value', data: ShakeLimitType): void
|
||||
}
|
||||
|
||||
const alarmFirstOptions = [
|
||||
{ label: '第一次', value: true },
|
||||
{ label: '最后一次', value: false },
|
||||
];
|
||||
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: Object as PropType<ShakeLimitType>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits<Emit>()
|
||||
|
||||
const shakeLimit = reactive<ShakeLimitType>({
|
||||
enabled: undefined,
|
||||
time: 1,
|
||||
threshold: 1,
|
||||
alarmFirst: undefined
|
||||
})
|
||||
|
||||
Object.assign(shakeLimit, props.value)
|
||||
|
||||
watch(() => shakeLimit, () => {
|
||||
const cloneValue = cloneDeep(shakeLimit)
|
||||
emit('update:value', cloneValue)
|
||||
}, {
|
||||
deep: true
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.shakeLimit {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
:deep(.ant-input-number-handler-wrap) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
:deep(.ant-radio-button-wrapper) {
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 0 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<page-container>
|
||||
<Search :columns="columns" target="scene" @search="handleSearch" />
|
||||
<JTable
|
||||
<JProTable
|
||||
ref="sceneRef"
|
||||
:columns="columns"
|
||||
:request="query"
|
||||
|
@ -9,7 +9,7 @@
|
|||
:params="params"
|
||||
>
|
||||
<template #headerTitle>
|
||||
<a-space>
|
||||
<j-space>
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
@click="handleAdd"
|
||||
|
@ -18,7 +18,7 @@
|
|||
<template #icon><AIcon type="PlusOutlined" /></template>
|
||||
新增
|
||||
</PermissionButton>
|
||||
</a-space>
|
||||
</j-space>
|
||||
</template>
|
||||
<template #card="slotProps">
|
||||
<SceneCard
|
||||
|
@ -90,13 +90,13 @@
|
|||
{{ typeMap.get(slotProps.triggerType)?.text }}
|
||||
</template>
|
||||
<template #state="slotProps">
|
||||
<a-badge
|
||||
<j-badge
|
||||
:text="slotProps.state?.text"
|
||||
:status="statusMap.get(slotProps.state?.value)"
|
||||
/>
|
||||
</template>
|
||||
<template #action="slotProps">
|
||||
<a-space>
|
||||
<j-space>
|
||||
<template
|
||||
v-for="i in getActions(slotProps, 'table')"
|
||||
:key="i.key"
|
||||
|
@ -115,9 +115,9 @@
|
|||
<template #icon><AIcon :type="i.icon" /></template>
|
||||
</PermissionButton>
|
||||
</template>
|
||||
</a-space>
|
||||
</j-space>
|
||||
</template>
|
||||
</JTable>
|
||||
</JProTable>
|
||||
<SaveModal v-if="visible" @close="visible = false" :data="current" />
|
||||
</page-container>
|
||||
</template>
|
||||
|
|
Loading…
Reference in New Issue