merge: merge dev
* fix: 优化设备接入配置 * fix: 兼容2.1版本创建的菜单数据 * fix: 菜单配置兼容2.1菜单 * fix: bug#28524 【产品】产品选择设备接入网关,有多个配置时,只展示了一个 * fix: bug#28520【设备】当配置未开启时,前端应不展示配置按钮 * fix: bug#28533仪表盘本年流量消耗界面展示需优化 * fix: bug#28520、28534【设备】设备详情-物模型-其他配置 在点击配置时界面提示错误、【设备】当配置未开启时,前端应不展示配置按钮 * fix: bug#28531【设备】详情中查看预处理数据时提示错误 * fix: bug#28545【菜单管理】新增菜单,权限控制处无法正常加载出权限 * fix: 菜单配置->菜单权限同步功能 * fix: bug#28520【设备】当配置未开启时,前端应不展示配置按钮 * fix(media): bug#28595屏蔽固定地址通道列表的厂商字段 * fix(NoticeRule): 文字组织替换部门 * fix(Alarm): bug#28571手动触发展示说明 * fix(media): bug#28553界面展示异常 * fix(iotCard): bug#28567 * fix(media): bug#28595屏蔽固定地址通道列表的厂商字段 * fix: bug#28560【通知配置】微信-企业消息的同步用户页面,列表字段展示错误,【钉钉用户名】需改为【企业微信用户名】 * fix: bug#28544【通知配置】用户自己创建的数据,没有权限调试,报错:暂无权限,请联系管理员! * fix: bug#28549【采集器】在点位进行批量操作时,开启推送控制,进行保存异常 * fix: bug#28540【组织管理】设备资产分配页,设备列表形式展示,资产权限显示不完整 * fix: bug#28537【产品】新增的网关设备,接入方式选择"边缘网关接入"时,物模型中功能定义界面展示异常 * fix: bug#28550【远程升级】升级任务中的任务详情列表中文案修改 * fix: bug#28551【通知模版】和【通知配置】两者保存的查询条件共用了 * fix: bug#28560【通知配置】微信-企业消息的同步用户页面,列表字段展示错误,【钉钉用户名】需改为【企业微信用户名】 * fix(media): bug#28602屏蔽onvif相关配置 * fix: 物联卡管理样式优化及运营商状态取值 * fix(AliCloud): bug#28581新增阿里云网桥产品下拉值清空 * fix(media): bug#28602屏蔽onvif相关配置 * fix: bug#28578、28597【产品】物模型-属性定义-其他配置 在只进行选择了数据类型时,界面展示异常 、【产品】在进行更换接入网关时,会增加“预处理数据” * fix: bug#28578、28597【产品】物模型-属性定义-其他配置 在只进行选择了数据类型时,界面展示异常 、【产品】在进行更换接入网关时,会增加“预处理数据” * fix: bug#28538 【角色管理】【97】进入页面提示权限不足 * fix: bug#28605 【产品】产品物模型点击其它配置时,有时候界面会不出现蒙层 * fix: 【告警配置】兼容2.1绑定与取消绑定场景联动 * fix(region): 地区新增屏蔽重复校验及同步下级区域处理 * fix(system): 数据字典新增选中异常修复 * fix: bug#28611.28613 * fix(media): 仪表盘快捷时间没有取消选中效果 * fix(region): 地区新增屏蔽重复校验及同步下级区域处理 * fix: bug#28616【设备】【日志管理页】列表字段过长时,鼠标悬停【内容】展示数据不友好,和别处不一致 * fix: bug#28560【通知配置】微信-企业消息的同步用户页面,列表字段展示错误,【钉钉用户名】需改为【企业微信用户名】 * fix: bug#28559【通知管理】微信同步用户页面,查询无匹配部门时,后端不需要报错 * fix: bug#28563【通知模版】新增/编辑数据页,【绑定配置】的数据后端校验有错误时,也能正常新增保存,后端校验失败时,应不能新增保存,需要前端把后端的报错处理到校验规则内。 * fix: bug#28568【产品】通过导入的属性,其他配置中的存在方式为正确的展示 * fix: bug#28616【设备】【日志管理页】列表字段过长时,鼠标悬停【内容】展示数据不友好,和别处不一致 * fix: 修改预处理数据页面接口 * fix: 配置枚举项必填按钮放在右方 * fix: 【物模型】修复功能定义名称校验异常 * fix: 【运维管理】仪表盘修复jvm中Echarts无法显示服务名称 * fix: 【物模型】修复功能定义名称校验异常 * fix: 【场景联动】校验接口社区版兼容处理 * fix: bug#28615 【产品】【物模型-属性定义-编辑规则页】在屏幕分辦率【1380* 920】的情况下,属性名称下拉框无法正常获取到值 * fix: bug#28559 【通知管理】微信同步用户页面,查询无匹配部门时,后端不需要报错 * fix: bug#28563【通知模版】新增/编辑数据页,【绑定配置】的数据后端校验有错误时,也能正常新增保存,后端校验失败时,应不能新增保存,需要前端把后端的报错处理到校验规则内。 * fix: bug#28604 【产品】产品指标保存后查看,未回显已填入内容(设备运行状态界面查看是有指标的,但是产品配置查看未回显) * fix: bug#28634【产品】【物模型-事件定义-输出参数】当数据类型选择枚举值,不配置必填项【枚举项】,直接点击保存,可成功保存,理应提示必填 * fix: bug#28615 【产品】【物模型-属性定义-编辑规则页】在屏幕分辦率【1380* 920】的情况下,属性名称下拉框无法正常获取到值 * fix: 修改预处理数据查询处理结果接口 * fix: bug#28633新增字典后选中新增项 * fix: bug#28628编辑区域报错 * fix: bug#28526 【场景联动】场景联动文案描述错误,并且关闭执行动作后,应该同步隐藏防抖 * fix: 优化过滤条件开关逻辑条件 * fix: bug#【产品】产品(设备、告警记录),告警源不展示设备ID,展示设备名称 * fix: bug#28652【通知配置】通知配置钉钉(微信)进行用户绑定时,展示需优化 * fix: bug#28575 流媒体服务>>>服务商新增可选项内置流媒体 * fix: bug#28618.28619日历维护相关优化 * fix: bug#28648地区管理新增区域后下级消失 * fix: bug#28575 流媒体服务>>>服务商新增可选项内置流媒体 * fix: bug#28672产品物模型>>>功能定义>>>输入参数,选择类型为Object时,无法选择参数(事件也存在) * fix: bug#28654、28664、28663产品(设备)无效数据修改“告警源”>>>“数据源”,并且设备ID,修改为设备名称、通知模板>>>企业微信和钉钉消息调试时,名称应和模板内变量名称一致 * fix: bug#28663、28659通知模板>>>企业微信进行调试时,需判断收信人、收信人部门,收信人标签三个内容任意填写一个、钉钉消息调试时,需判断收信人或收信人部门任意填写其中一个 * fix: bug#28659【场景联动】场景联动>>>执行动作>>>>消息通知.>>>模板变量需判断收信人或者收信部门任意填写一个 * fix: bug#28661企业微信进行调试时,需判断收信人、收信人部门,收信人标签三个内容任意填写一个 * fix: bug#28672产品物模型>>>功能定义>>>输入参数,选择类型为Object时,无法选择参数(事件也存在) * fix: 修复钉钉调试选择了收信人过不了校验问题 * fix: 阈值处理方式取值修改 * fix: 场景联动执行动作微信显示部门标签 * fix: 修改场景联通通知图标 * fix: bug#28575内嵌流媒体样式优化 * fix: bug28679.28678 * fix: 修改流媒体详情字段 * fix: 场景联动执行动作微信显示部门标签 * fix: 修改场景联通通知图标 * fix: 无效数据数据源跳转功能 * fix: 流媒体详情修改文字 * fix: 修改流媒体详情字段 * fix: bug#28687 【场景联动】场景联动>>>执行动作>>>消息通知>>>清除了收信信息后(有其余可校验内容)但是无法通过校验(企微、钉钉都存在) * fix: bug#28688场景联动>>>执行动作>>>消息发送,当钉钉(企业)选择收信人后,切换收信人类型,然后点击保存,未清空切换前的内容 * fix: api配置调试请求体判断条件修改
This commit is contained in:
parent
2b3e3280ac
commit
827b824451
Binary file not shown.
Before Width: | Height: | Size: 457 B After Width: | Height: | Size: 3.6 KiB |
|
@ -31,7 +31,7 @@ export const saveMetadata = (id: string, data: DeviceMetadata) => server.put(`/d
|
||||||
* @param id 设备ID
|
* @param id 设备ID
|
||||||
* @returns 设备详情
|
* @returns 设备详情
|
||||||
*/
|
*/
|
||||||
export const detail = (id: string) => server.get<DeviceInstance>(`/device-instance/${id}/detail`)
|
export const detail = (id: string, _hideError?: any) => server.get<DeviceInstance>(`/device-instance/${id}/detail`, {}, {} , _hideError)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询数据
|
* 查询数据
|
||||||
|
@ -666,20 +666,20 @@ export const queryProductThreshold = (productId: string, propertyId: string,hidd
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 阈值限制-删除产品物模型的阈值
|
* 阈值限制-删除产品物模型的阈值
|
||||||
* @param productId
|
* @param productId
|
||||||
* @param propertyId
|
* @param propertyId
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const deleteProductThreshold = (productId:string,propertyId:string,data:any) => server.remove(`/message/preprocessor/product/${productId}/property/${propertyId}`,data)
|
export const deleteProductThreshold = (productId:string,propertyId:string,data:any) => server.remove(`/message/preprocessor/product/${productId}/property/${propertyId}`,data)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 阈值限制-删除产品物模型的阈值
|
* 阈值限制-删除产品物模型的阈值
|
||||||
* @param productId
|
* @param productId
|
||||||
* @param propertyId
|
* @param propertyId
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const deleteDeviceThreshold = (productId:string,deviceId:string,propertyId:string,data:any) => server.remove(`/message/preprocessor/device/${productId}/${deviceId}/property/${propertyId}`,data)
|
export const deleteDeviceThreshold = (productId:string,deviceId:string,propertyId:string,data:any) => server.remove(`/message/preprocessor/device/${productId}/${deviceId}/property/${propertyId}`,data)
|
||||||
|
|
||||||
export const getTemplate = (id: string, format: string) => `${BASE_API_PATH}/device/instance/${id}/property-metadata/template.${format}`
|
export const getTemplate = (id: string, format: string) => `${BASE_API_PATH}/device/instance/${id}/property-metadata/template.${format}`
|
||||||
|
|
||||||
export const uploadAnalyzeMetadata = (data: any) => server.post('/device/instance/property-metadata/file/analyze', data)
|
export const uploadAnalyzeMetadata = (productId:string,data: any) => server.post(`/device/instance/${productId}/property-metadata/file/analyze`, data)
|
||||||
|
|
|
@ -37,6 +37,12 @@ export const queryByDevice = (data:any) => server.post(`/alarm/record/device/_qu
|
||||||
*/
|
*/
|
||||||
export const handleLog = (data:any) => server.post('/alarm/record/_handle',data);
|
export const handleLog = (data:any) => server.post('/alarm/record/_handle',data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 预处理告警处理
|
||||||
|
*/
|
||||||
|
export const handlePreconditioning = (data:any) => server.post(`/alarm/record/device/_handle`,data)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 告警记录
|
* 告警记录
|
||||||
*/
|
*/
|
||||||
|
@ -58,11 +64,21 @@ export const queryHistoryList = (data:any) => server.post('/alarm/history/_query
|
||||||
*/
|
*/
|
||||||
export const queryHandleHistory = (data:any) => server.post('/alarm/record/handle-history/_query',data);
|
export const queryHandleHistory = (data:any) => server.post('/alarm/record/handle-history/_query',data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取预处理数据告警处理结果
|
||||||
|
*/
|
||||||
|
export const queryPreHandleHistory = (recordId:any,data:any) => server.post(`/alarm/record/handle-history/device/${recordId}/_query`,data)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取告警日志(新)
|
* 获取告警日志(新)
|
||||||
*/
|
*/
|
||||||
export const queryLogList = (alarmConfigId:any,data:any) => server.post(`/alarm/history/${alarmConfigId}/_query`,data)
|
export const queryLogList = (alarmConfigId:any,data:any) => server.post(`/alarm/history/${alarmConfigId}/_query`,data)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取预处理数据告警日志
|
||||||
|
*/
|
||||||
|
export const queryPreconditioningLogList = (alarmConfigId:any,data:any) => server.post(`/alarm/history/device/${alarmConfigId}/_query`,data)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询无效数据
|
* 查询无效数据
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
showSearch
|
showSearch
|
||||||
:options="options"
|
:options="options"
|
||||||
v-model:value="record.id"
|
v-model:value="record.id"
|
||||||
:getPopupContainer="(node) => tableWrapperRef || node"
|
:getPopupContainer="getPopupContainer"
|
||||||
size="small"
|
size="small"
|
||||||
style="width: 100%;"
|
style="width: 100%;"
|
||||||
:virtual="true"
|
:virtual="true"
|
||||||
|
@ -105,7 +105,7 @@
|
||||||
size="small"
|
size="small"
|
||||||
style="width: 100%;"
|
style="width: 100%;"
|
||||||
:virtual="true"
|
:virtual="true"
|
||||||
:getPopupContainer="(node) => tableWrapperRef || node"
|
:getPopupContainer="getPopupContainer"
|
||||||
:dropdownStyle="{
|
:dropdownStyle="{
|
||||||
zIndex: 1072
|
zIndex: 1072
|
||||||
}"
|
}"
|
||||||
|
@ -202,6 +202,7 @@ import { getWebSocket } from '@/utils/websocket';
|
||||||
import {useTableWrapper} from "@/components/Metadata/Table/context";
|
import {useTableWrapper} from "@/components/Metadata/Table/context";
|
||||||
import { onlyMessage } from '@/utils/comm';
|
import { onlyMessage } from '@/utils/comm';
|
||||||
import {message} from "ant-design-vue";
|
import {message} from "ant-design-vue";
|
||||||
|
import { useTableFullScreen} from "@/components/Metadata/Table/context";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
virtualRule: Object as PropType<Record<any, any>>,
|
virtualRule: Object as PropType<Record<any, any>>,
|
||||||
|
@ -222,7 +223,7 @@ type propertyType = {
|
||||||
const property = ref<propertyType[]>([]);
|
const property = ref<propertyType[]>([]);
|
||||||
const tag = ref<Array<any>>([]);
|
const tag = ref<Array<any>>([]);
|
||||||
const tableWrapperRef = useTableWrapper()
|
const tableWrapperRef = useTableWrapper()
|
||||||
|
const fullScreen = useTableFullScreen()
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '属性名称',
|
title: '属性名称',
|
||||||
|
@ -287,6 +288,14 @@ const ruleEditorStore = useRuleEditorStore();
|
||||||
const time = ref<number>(0);
|
const time = ref<number>(0);
|
||||||
const timer = ref<any>(null);
|
const timer = ref<any>(null);
|
||||||
|
|
||||||
|
//是否全屏监听
|
||||||
|
const getPopupContainer = (node: any) => {
|
||||||
|
if (fullScreen.value) {
|
||||||
|
return tableWrapperRef.value || node
|
||||||
|
}
|
||||||
|
|
||||||
|
return document.body
|
||||||
|
}
|
||||||
const runScript = () => {
|
const runScript = () => {
|
||||||
const propertiesList = medataSource?.value || []
|
const propertiesList = medataSource?.value || []
|
||||||
const _properties = property.value.map((item: any) => {
|
const _properties = property.value.map((item: any) => {
|
||||||
|
|
|
@ -105,7 +105,10 @@ const validateRules = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const promise = context.validateItem({ [filedName.value]: get(context.dataSource.value, props.name) }, index)
|
const promise = context.validateItem({ [filedName.value]: get(context.dataSource.value, props.name) }, index)
|
||||||
promise.catch(res => {
|
promise.then(() => {
|
||||||
|
hideErrorTip()
|
||||||
|
context.removeFieldError(eventKey.value)
|
||||||
|
}).catch(res => {
|
||||||
const error = res?.filter(item => item.field === filedName.value) || []
|
const error = res?.filter(item => item.field === filedName.value) || []
|
||||||
if (error.length === 0) {
|
if (error.length === 0) {
|
||||||
hideErrorTip()
|
hideErrorTip()
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<a-form-item :name="name" :rules="rules" :validate-first="true">
|
<a-form-item :name="name" :rules="rules" :validate-first="true">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span style="color: #ff4d4f; padding-right: 4px; padding-top: 2px">*</span>
|
|
||||||
枚举项
|
枚举项
|
||||||
|
<span style="color: #ff4d4f; padding-right: 4px; padding-top: 2px">*</span>
|
||||||
</template>
|
</template>
|
||||||
<Content ref="tableRef" v-model:value="dataSource" @change="change" />
|
<Content ref="tableRef" v-model:value="dataSource" @change="change" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
|
@ -1,232 +1,347 @@
|
||||||
<template>
|
<template>
|
||||||
<PopoverModal
|
<PopoverModal
|
||||||
v-model:visible="visible"
|
v-model:visible="visible"
|
||||||
:placement="placement"
|
:placement="placement"
|
||||||
@ok="onOk"
|
@ok="onOk"
|
||||||
@cancel="onCancel"
|
@cancel="onCancel"
|
||||||
>
|
>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div style="width: 750px">
|
<div style="width: 750px">
|
||||||
<EditTable
|
<EditTable
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:columns="myColumns"
|
:columns="myColumns"
|
||||||
:dataSource="dataSource"
|
:dataSource="dataSource"
|
||||||
:pagination="false"
|
:pagination="false"
|
||||||
:height="200"
|
:height="200"
|
||||||
>
|
>
|
||||||
<!-- <template v-for="(_, key) in slots" :key="key" #[key]="slotData">-->
|
<!-- <template v-for="(_, key) in slots" :key="key" #[key]="slotData">-->
|
||||||
<!-- <slot :name="key" v-bind="slotData"/>-->
|
<!-- <slot :name="key" v-bind="slotData"/>-->
|
||||||
<!-- </template>-->
|
<!-- </template>-->
|
||||||
<template #id="{ record, index }">
|
<template #id="{ record, index }">
|
||||||
<EditTableFormItem :name="[index, 'id']">
|
<EditTableFormItem :name="[index, 'id']">
|
||||||
<a-input v-model:value="record.id" placeholder="请输入标识"/>
|
<a-input
|
||||||
</EditTableFormItem>
|
v-model:value="record.id"
|
||||||
</template>
|
placeholder="请输入标识"
|
||||||
<template #name="{ record, index }">
|
/>
|
||||||
<EditTableFormItem :name="[index, 'name']">
|
</EditTableFormItem>
|
||||||
<a-input v-model:value="record.name" placeholder="请输入名称"/>
|
</template>
|
||||||
</EditTableFormItem>
|
<template #name="{ record, index }">
|
||||||
</template>
|
<EditTableFormItem :name="[index, 'name']">
|
||||||
<template #expands="{ record }">
|
<a-input
|
||||||
<BooleanSelect v-model:value="record.expands.required"/>
|
v-model:value="record.name"
|
||||||
</template>
|
placeholder="请输入名称"
|
||||||
<template #valueType="{ record, index }">
|
/>
|
||||||
<EditTableFormItem :name="[index, 'valueType']">
|
</EditTableFormItem>
|
||||||
<div style="display: flex; gap: 12px; align-items: center">
|
</template>
|
||||||
<TypeSelect v-model:value="record.valueType.type" style="flex: 1 1 0;min-width: 0" />
|
<template #expands="{ record }">
|
||||||
<DoubleParams v-if="['float', 'double'].includes(record.valueType.type)" v-model:value="record.valueType" placement="topRight"/>
|
<BooleanSelect
|
||||||
<StringParams v-else-if="record.valueType.type === 'string'" v-model:value="record.valueType" placement="topRight"/>
|
v-model:value="record.expands.required"
|
||||||
<DateParams v-else-if="record.valueType.type === 'date'" v-model:value="record.valueType.format" placement="topRight"/>
|
/>
|
||||||
<FileParams v-else-if="record.valueType.type === 'file'" v-model:value="record.valueType.bodyType" placement="topRight"/>
|
</template>
|
||||||
<EnumParams v-else-if="record.valueType.type === 'enum'" v-model:value="record.valueType.elements" placement="topRight"/>
|
<template #valueType="{ record, index }">
|
||||||
<BooleanParams
|
<EditTableFormItem :name="[index, 'valueType']">
|
||||||
v-else-if="record.valueType.type === 'boolean'"
|
<div
|
||||||
v-model:falseText="record.valueType.falseText"
|
style="
|
||||||
v-model:falseValue="record.valueType.falseValue"
|
display: flex;
|
||||||
v-model:trueText="record.valueType.trueText"
|
gap: 12px;
|
||||||
v-model:trueValue="record.valueType.trueValue"
|
align-items: center;
|
||||||
placement="topRight"
|
"
|
||||||
/>
|
>
|
||||||
<ArrayParams v-else-if="record.valueType.type === 'array'" v-model:value="record.valueType.elementType" placement="topRight"/>
|
<TypeSelect
|
||||||
</div>
|
v-model:value="record.valueType.type"
|
||||||
</EditTableFormItem>
|
style="flex: 1 1 0; min-width: 0"
|
||||||
</template>
|
/>
|
||||||
<template #action="{ index }">
|
<DoubleParams
|
||||||
<a-button danger type="link" style="padding: 0 5px" @click="() => deleteItem(index)">
|
v-if="
|
||||||
<template #icon>
|
['float', 'double'].includes(
|
||||||
<AIcon type="DeleteOutlined" />
|
record.valueType.type,
|
||||||
</template>
|
)
|
||||||
</a-button>
|
"
|
||||||
</template>
|
v-model:value="record.valueType"
|
||||||
</EditTable>
|
placement="topRight"
|
||||||
<a-button style="width: 100%;margin-top: 4px" @click="addItem">
|
/>
|
||||||
<template #icon><AIcon type="PlusOutlined" /></template>
|
<StringParams
|
||||||
新增
|
v-else-if="
|
||||||
</a-button>
|
record.valueType.type === 'string'
|
||||||
</div>
|
"
|
||||||
</template>
|
v-model:value="record.valueType"
|
||||||
<slot>
|
placement="topRight"
|
||||||
<a-button type="link" :disabled="disabled" style="padding: 0">
|
/>
|
||||||
<template #icon>
|
<DateParams
|
||||||
<AIcon type="EditOutlined" :class="{'table-form-required-aicon': !value.length}"/>
|
v-else-if="record.valueType.type === 'date'"
|
||||||
|
v-model:value="record.valueType.format"
|
||||||
|
placement="topRight"
|
||||||
|
/>
|
||||||
|
<FileParams
|
||||||
|
v-else-if="record.valueType.type === 'file'"
|
||||||
|
v-model:value="record.valueType.bodyType"
|
||||||
|
placement="topRight"
|
||||||
|
/>
|
||||||
|
<EnumParams
|
||||||
|
v-else-if="record.valueType.type === 'enum'"
|
||||||
|
v-model:value="record.valueType.elements"
|
||||||
|
placement="topRight"
|
||||||
|
/>
|
||||||
|
<BooleanParams
|
||||||
|
v-else-if="
|
||||||
|
record.valueType.type === 'boolean'
|
||||||
|
"
|
||||||
|
v-model:falseText="
|
||||||
|
record.valueType.falseText
|
||||||
|
"
|
||||||
|
v-model:falseValue="
|
||||||
|
record.valueType.falseValue
|
||||||
|
"
|
||||||
|
v-model:trueText="record.valueType.trueText"
|
||||||
|
v-model:trueValue="
|
||||||
|
record.valueType.trueValue
|
||||||
|
"
|
||||||
|
placement="topRight"
|
||||||
|
/>
|
||||||
|
<ArrayParams
|
||||||
|
v-else-if="
|
||||||
|
record.valueType.type === 'array'
|
||||||
|
"
|
||||||
|
v-model:value="record.valueType.elementType"
|
||||||
|
placement="topRight"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</EditTableFormItem>
|
||||||
|
</template>
|
||||||
|
<template #action="{ index }">
|
||||||
|
<a-button
|
||||||
|
danger
|
||||||
|
type="link"
|
||||||
|
style="padding: 0 5px"
|
||||||
|
@click="() => deleteItem(index)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<AIcon type="DeleteOutlined" />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
</EditTable>
|
||||||
|
<a-button style="width: 100%; margin-top: 4px" @click="addItem">
|
||||||
|
<template #icon><AIcon type="PlusOutlined" /></template>
|
||||||
|
新增
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</a-button>
|
<slot>
|
||||||
</slot>
|
<a-button type="link" :disabled="disabled" style="padding: 0">
|
||||||
</PopoverModal>
|
<template #icon>
|
||||||
|
<AIcon
|
||||||
|
type="EditOutlined"
|
||||||
|
:class="{ 'table-form-required-aicon': !value.length }"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</slot>
|
||||||
|
</PopoverModal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="MetadataObject">
|
<script setup name="MetadataObject">
|
||||||
import { PopoverModal } from '../index'
|
import { PopoverModal } from '../index';
|
||||||
import BooleanSelect from "../BooleanSelect/index.vue";
|
import BooleanSelect from '../BooleanSelect/index.vue';
|
||||||
import { EditTable, TypeSelect, EditTableFormItem, StringParams, DateParams, FileParams, EnumParams, BooleanParams, ObjectParams, ArrayParams, DoubleParams } from '@/components/Metadata/Table'
|
import {
|
||||||
import {Form} from "ant-design-vue";
|
EditTable,
|
||||||
|
TypeSelect,
|
||||||
|
EditTableFormItem,
|
||||||
|
StringParams,
|
||||||
|
DateParams,
|
||||||
|
FileParams,
|
||||||
|
EnumParams,
|
||||||
|
BooleanParams,
|
||||||
|
ObjectParams,
|
||||||
|
ArrayParams,
|
||||||
|
DoubleParams,
|
||||||
|
} from '@/components/Metadata/Table';
|
||||||
|
import { Form } from 'ant-design-vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
value: {
|
value: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
placement: {
|
placement: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'top',
|
default: 'top',
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'properties'
|
default: 'properties',
|
||||||
},
|
},
|
||||||
disabled: {
|
disabled: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default:false
|
default: false,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const validatorConfig = (value, _isObject = false) => {
|
||||||
|
if (!value) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.type === 'enum' && !value.elements?.length) {
|
||||||
|
return Promise.reject('请添加枚举项');
|
||||||
|
}
|
||||||
|
if (value.type === 'array' && !value.elementType?.type) {
|
||||||
|
return Promise.reject('请选择元素类型');
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (_isObject && value.type === 'object' && !value.properties?.length) {
|
||||||
|
// return Promise.reject('请添加参数');
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (value.type === 'date' && !value.format) {
|
||||||
|
return Promise.reject('请选择时间格式');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
value.type === 'file' &&
|
||||||
|
(!value.bodyType ||
|
||||||
|
(isObject(value.bodyType) && !Object.keys(value.bodyType).length))
|
||||||
|
) {
|
||||||
|
return Promise.reject('请选择文件类型');
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
|
};
|
||||||
|
|
||||||
const emit = defineEmits(['update:value', 'confirm', 'cancel']);
|
const emit = defineEmits(['update:value', 'confirm', 'cancel']);
|
||||||
const formItemContext = Form.useInjectFormItemContext();
|
const formItemContext = Form.useInjectFormItemContext();
|
||||||
|
|
||||||
const slots = useSlots()
|
const slots = useSlots();
|
||||||
|
|
||||||
const tableRef = ref()
|
const tableRef = ref();
|
||||||
const dataSource = ref([])
|
const dataSource = ref([]);
|
||||||
const visible = ref(false)
|
const visible = ref(false);
|
||||||
|
|
||||||
const defaultColumns = [
|
const defaultColumns = [
|
||||||
{
|
{
|
||||||
title: '参数标识',
|
title: '参数标识',
|
||||||
dataIndex: 'id',
|
dataIndex: 'id',
|
||||||
form: {
|
form: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
asyncValidator(_, value, ...setting) {
|
asyncValidator(_, value, ...setting) {
|
||||||
if (value) {
|
if (value) {
|
||||||
const option = setting[2]
|
const option = setting[2];
|
||||||
|
|
||||||
const isSome = dataSource.value.some((item) => {
|
const isSome = dataSource.value.some((item) => {
|
||||||
return item.__dataIndex !== option.index && item.id === value
|
return (
|
||||||
})
|
item.__dataIndex !== option.index &&
|
||||||
|
item.id === value
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
if (isSome) {
|
if (isSome) {
|
||||||
return Promise.reject('该标识已存在')
|
return Promise.reject('该标识已存在');
|
||||||
}
|
}
|
||||||
return Promise.resolve()
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
return Promise.reject('请输入标识')
|
return Promise.reject('请输入标识');
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
{
|
||||||
|
pattern: /^[a-zA-Z0-9_]+$/,
|
||||||
|
message: '标识只能由数字、字母、下划线组成',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{ max: 64, message: '最多可输入64个字符' },
|
|
||||||
{
|
|
||||||
pattern: /^[a-zA-Z0-9_]+$/,
|
|
||||||
message: '标识只能由数字、字母、下划线组成',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '参数名称',
|
|
||||||
dataIndex: 'name',
|
|
||||||
form: {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入名称'
|
|
||||||
},
|
|
||||||
{ max: 64, message: '最多可输入64个字符' },
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
props.type === 'functions' ? {
|
|
||||||
title: '填写约束',
|
|
||||||
dataIndex: 'expands',
|
|
||||||
width: 120,
|
|
||||||
} : null,
|
|
||||||
{
|
|
||||||
title: '数据类型',
|
|
||||||
dataIndex: 'valueType',
|
|
||||||
width: 240,
|
|
||||||
form: {
|
|
||||||
required: true,
|
|
||||||
rules: [{
|
|
||||||
validator(_, value) {
|
|
||||||
if (!value?.type) {
|
|
||||||
return Promise.reject('请选择数据类型')
|
|
||||||
}
|
|
||||||
return Promise.resolve()
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
},
|
},
|
||||||
}
|
{
|
||||||
]
|
title: '参数名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
form: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入名称',
|
||||||
|
},
|
||||||
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props.type === 'functions'
|
||||||
|
? {
|
||||||
|
title: '填写约束',
|
||||||
|
dataIndex: 'expands',
|
||||||
|
width: 120,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
{
|
||||||
|
title: '数据类型',
|
||||||
|
dataIndex: 'valueType',
|
||||||
|
width: 240,
|
||||||
|
form: {
|
||||||
|
required: true,
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
validator(_, value) {
|
||||||
|
if (!value?.type) {
|
||||||
|
return Promise.reject('请选择数据类型');
|
||||||
|
}
|
||||||
|
return validatorConfig(value, true);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const myColumns = computed(() => {
|
const myColumns = computed(() => {
|
||||||
|
return [
|
||||||
return [
|
...defaultColumns.filter((item) => !!item),
|
||||||
...defaultColumns.filter(item => !!item),
|
{
|
||||||
{
|
dataIndex: 'action',
|
||||||
dataIndex: 'action',
|
title: '操作',
|
||||||
title: '操作',
|
width: 60,
|
||||||
width: 60,
|
},
|
||||||
}
|
];
|
||||||
]
|
});
|
||||||
})
|
|
||||||
|
|
||||||
const onOk = async () => {
|
const onOk = async () => {
|
||||||
const data = await tableRef.value.validate()
|
const data = await tableRef.value.validate();
|
||||||
if (data) {
|
if (data) {
|
||||||
visible.value = false
|
visible.value = false;
|
||||||
emit('update:value', data)
|
emit('update:value', data);
|
||||||
emit('confirm', data)
|
emit('confirm', data);
|
||||||
formItemContext.onFieldChange()
|
formItemContext.onFieldChange();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteItem = (index) => {
|
const deleteItem = (index) => {
|
||||||
dataSource.value.splice(index, 1)
|
dataSource.value.splice(index, 1);
|
||||||
}
|
};
|
||||||
|
|
||||||
const addItem = () => {
|
const addItem = () => {
|
||||||
dataSource.value.push({
|
dataSource.value.push({
|
||||||
id: undefined,
|
id: undefined,
|
||||||
name: undefined,
|
name: undefined,
|
||||||
expands: {
|
expands: {
|
||||||
required: false
|
required: false,
|
||||||
|
},
|
||||||
|
valueType: {
|
||||||
|
expands: {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => [JSON.stringify(props.value), visible.value],
|
||||||
|
(val) => {
|
||||||
|
if (visible.value) {
|
||||||
|
dataSource.value = JSON.parse(val[0] || '[]');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
valueType: {
|
{ immediate: true },
|
||||||
expands: {}
|
);
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(() => [JSON.stringify(props.value), visible.value], (val) => {
|
|
||||||
if (visible.value) {
|
|
||||||
dataSource.value = JSON.parse(val[0] || '[]')
|
|
||||||
}
|
|
||||||
}, { immediate: true })
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -29,14 +29,14 @@ const bodyHidden = () => {
|
||||||
|
|
||||||
const getMaskNode = (id: string, warpClassNames: string) => {
|
const getMaskNode = (id: string, warpClassNames: string) => {
|
||||||
let maskNode = document.querySelector(`#${id}`) as HTMLElement
|
let maskNode = document.querySelector(`#${id}`) as HTMLElement
|
||||||
|
|
||||||
if (maskNode) {
|
if (maskNode) {
|
||||||
return maskNode
|
return maskNode
|
||||||
}
|
}
|
||||||
|
|
||||||
maskNode = document.createElement('div')
|
maskNode = document.createElement('div')
|
||||||
maskNode.id = id
|
maskNode.id = id
|
||||||
|
|
||||||
updateStyle(maskNode, {
|
updateStyle(maskNode, {
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
top: 0,
|
top: 0,
|
||||||
|
@ -48,7 +48,6 @@ const getMaskNode = (id: string, warpClassNames: string) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const warpNode = document.querySelector(`.${warpClassNames}`) as HTMLDivElement
|
const warpNode = document.querySelector(`.${warpClassNames}`) as HTMLDivElement
|
||||||
|
|
||||||
if (!warpNode) return undefined
|
if (!warpNode) return undefined
|
||||||
|
|
||||||
warpNode.insertAdjacentElement('beforebegin', maskNode)
|
warpNode.insertAdjacentElement('beforebegin', maskNode)
|
||||||
|
@ -64,10 +63,11 @@ export const useMask = (propVisible: boolean, options: { visibleChange: (visible
|
||||||
showMask: Function,
|
showMask: Function,
|
||||||
visibleChange: (visible: boolean) => void
|
visibleChange: (visible: boolean) => void
|
||||||
} => {
|
} => {
|
||||||
|
const key = randomString(6)
|
||||||
const visible = ref(propVisible)
|
const visible = ref(propVisible)
|
||||||
const maskDomId = `${maskNodeClassName}-${randomString(6)}`
|
const maskDomId = `${maskNodeClassName}-${key}`
|
||||||
|
|
||||||
const warpClassNames = `${maskNodeClassName}-warp-${randomString(4)}`
|
const warpClassNames = `${maskNodeClassName}-warp-${key}`
|
||||||
const createMask = () => {
|
const createMask = () => {
|
||||||
if (!maskIds.includes(maskDomId)) {
|
if (!maskIds.includes(maskDomId)) {
|
||||||
maskIds.push(maskDomId)
|
maskIds.push(maskDomId)
|
||||||
|
@ -78,16 +78,15 @@ export const useMask = (propVisible: boolean, options: { visibleChange: (visible
|
||||||
|
|
||||||
const getLastMask = (): HTMLElement | undefined => {
|
const getLastMask = (): HTMLElement | undefined => {
|
||||||
const index = maskIds.findIndex(key => key === maskDomId) // 当前遮罩层下标
|
const index = maskIds.findIndex(key => key === maskDomId) // 当前遮罩层下标
|
||||||
|
|
||||||
let dom = undefined
|
let dom = undefined
|
||||||
let lastIndex = 0
|
let lastIndex = 0
|
||||||
|
|
||||||
if (maskIds.length > 0) {
|
if (maskIds.length > 0) {
|
||||||
|
|
||||||
lastIndex = index < 0 ? 0 : index - 1
|
lastIndex = index <= 0 ? 0 : index - 1
|
||||||
|
|
||||||
const lastMaskId = maskIds[lastIndex]
|
const lastMaskId = maskIds[lastIndex]
|
||||||
|
|
||||||
dom = document.querySelector(`#${lastMaskId}`) as HTMLElement
|
dom = document.querySelector(`#${lastMaskId}`) as HTMLElement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +115,7 @@ export const useMask = (propVisible: boolean, options: { visibleChange: (visible
|
||||||
updateStyle(maskNode, {
|
updateStyle(maskNode, {
|
||||||
display: 'block'
|
display: 'block'
|
||||||
})
|
})
|
||||||
}, 10)
|
}, 150)
|
||||||
}
|
}
|
||||||
|
|
||||||
const hideMask = () => {
|
const hideMask = () => {
|
||||||
|
|
|
@ -45,7 +45,7 @@ export const defaultBranches = [
|
||||||
key: 'terms_1',
|
key: 'terms_1',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
key: 'branches_1',
|
key: defaultBranchId,
|
||||||
shakeLimit: {
|
shakeLimit: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
time: 1,
|
time: 1,
|
||||||
|
@ -69,7 +69,7 @@ const defaultOptions = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
branchName:'条件',
|
branchName:'条件',
|
||||||
key: 'branches_1',
|
key:defaultBranchId,
|
||||||
executeAnyway: true,
|
executeAnyway: true,
|
||||||
groupIndex: 1
|
groupIndex: 1
|
||||||
},
|
},
|
||||||
|
|
|
@ -537,7 +537,10 @@ const getProduct = async () => {
|
||||||
|
|
||||||
const getAliyunProduct = async (data: any) => {
|
const getAliyunProduct = async (data: any) => {
|
||||||
if (data.regionId && data.accessKeyId && data.accessSecret) {
|
if (data.regionId && data.accessKeyId && data.accessSecret) {
|
||||||
const resp: any = await getAliyunProductsList(data);
|
const resp: any = await getAliyunProductsList(data).catch(()=>{
|
||||||
|
aliyunProductList.value = [];
|
||||||
|
modelRef.bridgeProductKey = undefined;
|
||||||
|
});
|
||||||
if (resp.status === 200) {
|
if (resp.status === 200) {
|
||||||
aliyunProductList.value = resp?.result?.data as Record<
|
aliyunProductList.value = resp?.result?.data as Record<
|
||||||
string,
|
string,
|
||||||
|
@ -720,6 +723,7 @@ watch(
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
modelRef.description = undefined;
|
modelRef.description = undefined;
|
||||||
|
aliyunProductList.value = [];
|
||||||
} else if (props.data?.type === 'noData') {
|
} else if (props.data?.type === 'noData') {
|
||||||
noData.value = true;
|
noData.value = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,12 +33,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Log :currentId="AlarmData.id" :configId="AlarmData.alarmConfigId" />
|
<Log :currentId="AlarmData.id" :configId="AlarmData.alarmConfigId" :goal="goal"/>
|
||||||
</a-drawer>
|
</a-drawer>
|
||||||
<SolveComponent
|
<SolveComponent
|
||||||
v-if="solveVisible"
|
v-if="solveVisible"
|
||||||
@closeSolve="closeSolve"
|
@closeSolve="closeSolve"
|
||||||
@refresh="refresh"
|
@refresh="refresh"
|
||||||
|
:goal="goal"
|
||||||
:data="AlarmData"
|
:data="AlarmData"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
@ -53,6 +54,10 @@ const props = defineProps({
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: {},
|
||||||
},
|
},
|
||||||
|
goal:{
|
||||||
|
type:String,
|
||||||
|
default:''
|
||||||
|
}
|
||||||
});
|
});
|
||||||
const emit = defineEmits(['closeDrawer', 'refreshTable']);
|
const emit = defineEmits(['closeDrawer', 'refreshTable']);
|
||||||
const { levelMap } = useAlarmLevel();
|
const { levelMap } = useAlarmLevel();
|
||||||
|
|
|
@ -26,10 +26,10 @@
|
||||||
: '--'
|
: '--'
|
||||||
}}
|
}}
|
||||||
</template>
|
</template>
|
||||||
<template #sourceId="slotProps">
|
<template #sourceName="slotProps">
|
||||||
<Ellipsis>
|
<Ellipsis>
|
||||||
设备ID:
|
设备名称:
|
||||||
<span class="deviceId" @click="() => gotoDevice(slotProps.sourceId)">{{ slotProps.sourceId }}</span></Ellipsis
|
<span class="deviceId" @click="() => gotoDevice(slotProps.sourceId)">{{ slotProps.sourceName }}</span></Ellipsis
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #handleType="slotProps">
|
<template #handleType="slotProps">
|
||||||
|
@ -65,6 +65,7 @@
|
||||||
v-if="solveVisible"
|
v-if="solveVisible"
|
||||||
:data="currentAlarm"
|
:data="currentAlarm"
|
||||||
:solveType="solveType"
|
:solveType="solveType"
|
||||||
|
:goal="goal"
|
||||||
:handleDes="handleDescription"
|
:handleDes="handleDescription"
|
||||||
@closeSolve="closeSolve"
|
@closeSolve="closeSolve"
|
||||||
@refresh="solveRefresh"
|
@refresh="solveRefresh"
|
||||||
|
@ -72,6 +73,7 @@
|
||||||
<AlarmLog
|
<AlarmLog
|
||||||
v-if="visibleDrawer"
|
v-if="visibleDrawer"
|
||||||
:data="currentAlarm"
|
:data="currentAlarm"
|
||||||
|
:goal="goal"
|
||||||
@closeDrawer="visibleDrawer = false"
|
@closeDrawer="visibleDrawer = false"
|
||||||
@refreshTable="refresh"
|
@refreshTable="refresh"
|
||||||
/>
|
/>
|
||||||
|
@ -80,7 +82,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import {
|
||||||
queryByDevice as queryAlarmRecord,
|
queryByDevice as queryAlarmRecord,
|
||||||
queryHandleHistory,
|
queryPreHandleHistory,
|
||||||
} from '@/api/rule-engine/log';
|
} from '@/api/rule-engine/log';
|
||||||
import { useInstanceStore } from '@/store/instance';
|
import { useInstanceStore } from '@/store/instance';
|
||||||
import { useProductStore } from '@/store/product';
|
import { useProductStore } from '@/store/product';
|
||||||
|
@ -204,8 +206,8 @@ const columns =
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '告警源',
|
title: '告警源',
|
||||||
dataIndex: 'sourceId',
|
dataIndex: 'sourceName',
|
||||||
key: 'sourceId',
|
key: 'sourceName',
|
||||||
scopedSlots: true,
|
scopedSlots: true,
|
||||||
search: {
|
search: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
@ -329,16 +331,8 @@ const handleSearch = (e) => {
|
||||||
params.value = e;
|
params.value = e;
|
||||||
};
|
};
|
||||||
const queryHandle = async (id) => {
|
const queryHandle = async (id) => {
|
||||||
const res = await queryHandleHistory({
|
const res = await queryPreHandleHistory(id,{
|
||||||
sorts: [{ name: 'createTime', order: 'desc' }],
|
sorts: [{ name: 'handleTime', order: 'desc' }],
|
||||||
terms: [
|
|
||||||
{
|
|
||||||
column: 'alarmRecordId',
|
|
||||||
termType: 'eq',
|
|
||||||
value: id,
|
|
||||||
type: 'and',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
if (res.status === 200 && res.result?.data.length) {
|
if (res.status === 200 && res.result?.data.length) {
|
||||||
handleDescription.value = res.result.data?.[0]?.description;
|
handleDescription.value = res.result.data?.[0]?.description;
|
||||||
|
|
|
@ -31,12 +31,13 @@
|
||||||
><template #createTime="slotProps">
|
><template #createTime="slotProps">
|
||||||
{{ dayjs(slotProps.createTime).format('YYYY-MM-DD HH:mm:ss') }}
|
{{ dayjs(slotProps.createTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||||
</template>
|
</template>
|
||||||
<template #thingId="slotProps">
|
<template #thingName="slotProps">
|
||||||
<Ellipsis>
|
<Ellipsis>
|
||||||
设备ID:
|
设备名称:
|
||||||
<span
|
<span
|
||||||
class="deviceId"
|
class="deviceId"
|
||||||
>{{ slotProps.thingId }}</span
|
@click="() => gotoDevice(slotProps.thingId)"
|
||||||
|
>{{ slotProps.thingName }}</span
|
||||||
></Ellipsis
|
></Ellipsis
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
|
@ -48,12 +49,14 @@ import { queryInvalidData } from '@/api/rule-engine/log';
|
||||||
import { useInstanceStore } from '@/store/instance';
|
import { useInstanceStore } from '@/store/instance';
|
||||||
import { useProductStore } from '@/store/product';
|
import { useProductStore } from '@/store/product';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { useMenuStore } from 'store/menu';
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
goal: {
|
goal: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'device',
|
default: 'device',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const menuStory = useMenuStore();
|
||||||
const { current } =
|
const { current } =
|
||||||
props.goal === 'device' ? useInstanceStore() : useProductStore();
|
props.goal === 'device' ? useInstanceStore() : useProductStore();
|
||||||
const columns = props.goal === 'device' ? [
|
const columns = props.goal === 'device' ? [
|
||||||
|
@ -92,9 +95,9 @@ const columns = props.goal === 'device' ? [
|
||||||
scopedSlots: true,
|
scopedSlots: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '告警源',
|
title: '数据源',
|
||||||
dataIndex: 'thingId',
|
dataIndex: 'thingName',
|
||||||
key: 'thingId',
|
key: 'thingName',
|
||||||
scopedSlots: true,
|
scopedSlots: true,
|
||||||
search: {
|
search: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
@ -114,6 +117,10 @@ const columns = props.goal === 'device' ? [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const gotoDevice = (id) => {
|
||||||
|
menuStory.jumpPage('device/Instance/Detail', { id, tab: 'Running' });
|
||||||
|
};
|
||||||
const handleSearch = (e) => {
|
const handleSearch = (e) => {
|
||||||
params.value = e;
|
params.value = e;
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
<template #type="slotProps">
|
<template #type="slotProps">
|
||||||
{{ slotProps?.type?.text }}
|
{{ slotProps?.type?.text }}
|
||||||
</template>
|
</template>
|
||||||
|
<template #content="slotProps">
|
||||||
|
<Ellipsis style="width:calc(100% - 20px)">{{ slotProps?.content }}</Ellipsis>
|
||||||
|
</template>
|
||||||
<template #timestamp="slotProps">
|
<template #timestamp="slotProps">
|
||||||
{{
|
{{
|
||||||
slotProps.timestamp
|
slotProps.timestamp
|
||||||
|
@ -87,7 +90,6 @@ const columns = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '内容',
|
title: '内容',
|
||||||
ellipsis: true,
|
|
||||||
dataIndex: 'content',
|
dataIndex: 'content',
|
||||||
key: 'content',
|
key: 'content',
|
||||||
scopedSlots: true,
|
scopedSlots: true,
|
||||||
|
|
|
@ -163,7 +163,7 @@ import { usePermissionStore } from '@/store/permission';
|
||||||
import { isNoCommunity } from '@/utils/utils';
|
import { isNoCommunity } from '@/utils/utils';
|
||||||
import { useSystem } from '@/store/system';
|
import { useSystem } from '@/store/system';
|
||||||
|
|
||||||
const { showThreshold } = useSystem()
|
const { showThreshold } = useSystem();
|
||||||
const permissionStore = usePermissionStore();
|
const permissionStore = usePermissionStore();
|
||||||
const menuStory = useMenuStore();
|
const menuStory = useMenuStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
@ -272,6 +272,21 @@ const handleUndeploy = () => {
|
||||||
* 是否显示数据解析模块
|
* 是否显示数据解析模块
|
||||||
*/
|
*/
|
||||||
const getProtocol = async () => {
|
const getProtocol = async () => {
|
||||||
|
list.value = [
|
||||||
|
{
|
||||||
|
key: 'Info',
|
||||||
|
tab: '配置信息',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Metadata',
|
||||||
|
tab: '物模型',
|
||||||
|
class: 'objectModel',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Device',
|
||||||
|
tab: '设备接入',
|
||||||
|
},
|
||||||
|
];
|
||||||
if (productStore.current?.messageProtocol) {
|
if (productStore.current?.messageProtocol) {
|
||||||
const res: any = await getProtocolDetail(
|
const res: any = await getProtocolDetail(
|
||||||
productStore.current?.messageProtocol,
|
productStore.current?.messageProtocol,
|
||||||
|
@ -294,7 +309,8 @@ const getProtocol = async () => {
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
supportFirmware &&
|
supportFirmware &&
|
||||||
permissionStore.hasPermission('device/Firmware:view') && isNoCommunity
|
permissionStore.hasPermission('device/Firmware:view') &&
|
||||||
|
isNoCommunity
|
||||||
) {
|
) {
|
||||||
list.value.push({
|
list.value.push({
|
||||||
key: 'Firmware',
|
key: 'Firmware',
|
||||||
|
@ -316,7 +332,9 @@ const getProtocol = async () => {
|
||||||
if (
|
if (
|
||||||
permissionStore.hasPermission(
|
permissionStore.hasPermission(
|
||||||
'rule-engine/Alarm/Configuration:view',
|
'rule-engine/Alarm/Configuration:view',
|
||||||
) && isNoCommunity && showThreshold
|
) &&
|
||||||
|
isNoCommunity &&
|
||||||
|
showThreshold
|
||||||
) {
|
) {
|
||||||
list.value.push({
|
list.value.push({
|
||||||
key: 'AlarmRecord',
|
key: 'AlarmRecord',
|
||||||
|
|
|
@ -260,7 +260,7 @@ export const useColumns = (dataSource: Ref<MetadataItem[]>, type?: MetadataType,
|
||||||
{
|
{
|
||||||
asyncValidator: async (rule: any, value: any) => {
|
asyncValidator: async (rule: any, value: any) => {
|
||||||
|
|
||||||
const source = value.source
|
const source = value?.source
|
||||||
if (source) {
|
if (source) {
|
||||||
if (source === 'device' && !value.type?.length) {
|
if (source === 'device' && !value.type?.length) {
|
||||||
return Promise.reject('请选择读写类型');
|
return Promise.reject('请选择读写类型');
|
||||||
|
|
|
@ -69,6 +69,7 @@ import { getTemplate, uploadAnalyzeMetadata} from '@/api/device/instance'
|
||||||
import {getTemplate as getProductTemplate} from '@/api/device/product'
|
import {getTemplate as getProductTemplate} from '@/api/device/product'
|
||||||
import {downloadFileByUrl} from "@/utils/utils";
|
import {downloadFileByUrl} from "@/utils/utils";
|
||||||
import {useGroupActive, useTableWrapper} from "@/components/Metadata/Table/context";
|
import {useGroupActive, useTableWrapper} from "@/components/Metadata/Table/context";
|
||||||
|
import { useProductStore } from '@/store/product';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
target: {
|
target: {
|
||||||
|
@ -82,7 +83,7 @@ const props = defineProps({
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['ok'])
|
const emit = defineEmits(['ok'])
|
||||||
|
const { current } = useProductStore()
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const successCount = ref(0);
|
const successCount = ref(0);
|
||||||
const errorCount = ref(0);
|
const errorCount = ref(0);
|
||||||
|
@ -117,7 +118,6 @@ const onCancel = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const submitData = async (metadataStr) => {
|
const submitData = async (metadataStr) => {
|
||||||
console.log(metadataStr)
|
|
||||||
if (metadataStr) {
|
if (metadataStr) {
|
||||||
const _metadataObject = JSON.parse(metadataStr || "{}")
|
const _metadataObject = JSON.parse(metadataStr || "{}")
|
||||||
const properties = _metadataObject.properties
|
const properties = _metadataObject.properties
|
||||||
|
@ -176,7 +176,7 @@ const beforeUpload = (file) => {
|
||||||
formData.append('file', file)
|
formData.append('file', file)
|
||||||
|
|
||||||
step.value = 2
|
step.value = 2
|
||||||
uploadAnalyzeMetadata(formData).then(res => {
|
uploadAnalyzeMetadata(current.id , formData).then(res => {
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
submitData(res.result)
|
submitData(res.result)
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,6 @@ const beforeUpload = (file) => {
|
||||||
|
|
||||||
|
|
||||||
const uploadChange = async (info) => {
|
const uploadChange = async (info) => {
|
||||||
console.log(info)
|
|
||||||
if (info.file.status === 'uploading') {
|
if (info.file.status === 'uploading') {
|
||||||
step.value = 2
|
step.value = 2
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,9 +75,9 @@ const formData = reactive<{
|
||||||
value: ValueType;
|
value: ValueType;
|
||||||
rangeValue: ValueType;
|
rangeValue: ValueType;
|
||||||
}>({
|
}>({
|
||||||
value: props.value?.range === false ? props.value?.value : undefined,
|
value: props.range === false ? props.value : undefined,
|
||||||
rangeValue: props.value?.range === true
|
rangeValue: props.range === true
|
||||||
? cloneDeep(props.value?.value) || [undefined, undefined]
|
? cloneDeep(props.value) || [undefined, undefined]
|
||||||
: [undefined, undefined],
|
: [undefined, undefined],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -87,10 +87,10 @@ const showText = computed(() => {
|
||||||
if (props.range === false) {
|
if (props.range === false) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'date':
|
case 'date':
|
||||||
return props.value?.value;
|
return props.value;
|
||||||
case 'boolean':
|
case 'boolean':
|
||||||
const _value = props.value?.value
|
const _value = props.value
|
||||||
const item = props.options.find(item => item.value === props.value?.value)
|
const item = props.options.find(item => item.value === props.value)
|
||||||
if (item) {
|
if (item) {
|
||||||
return item.label
|
return item.label
|
||||||
}else if (_value) {
|
}else if (_value) {
|
||||||
|
@ -99,10 +99,10 @@ const showText = computed(() => {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return props.value?.value
|
return props.value
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return props.value?.value?.[0] ? props.value.value.join('-') : ''
|
return props.value?.[0] ? props.value.join('-') : ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ const confirm = () => {
|
||||||
|
|
||||||
watch(() => props.range, (value, oldValue) => {
|
watch(() => props.range, (value, oldValue) => {
|
||||||
if (value !== oldValue ) {
|
if (value !== oldValue ) {
|
||||||
formData.rangeValue = value ? [undefined, undefined] : undefined
|
formData.rangeValue = value ? cloneDeep(props.value) || [undefined, undefined] : undefined
|
||||||
}
|
}
|
||||||
}, { immediate: true})
|
}, { immediate: true})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -210,7 +210,10 @@
|
||||||
v-model:value="extraForm.mode"
|
v-model:value="extraForm.mode"
|
||||||
:options="[
|
:options="[
|
||||||
{ label: '忽略', value: 'ignore' },
|
{ label: '忽略', value: 'ignore' },
|
||||||
{ label: '记录', value: 'record' },
|
{
|
||||||
|
label: '记录',
|
||||||
|
value: 'device-record',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: '告警',
|
label: '告警',
|
||||||
value: 'device-alarm',
|
value: 'device-alarm',
|
||||||
|
@ -310,7 +313,7 @@ const props = defineProps({
|
||||||
|
|
||||||
const type = inject('_metadataType');
|
const type = inject('_metadataType');
|
||||||
|
|
||||||
const { showThreshold } = useSystem()
|
const { showThreshold } = useSystem();
|
||||||
const productStore = useProductStore();
|
const productStore = useProductStore();
|
||||||
const deviceStore = useInstanceStore();
|
const deviceStore = useInstanceStore();
|
||||||
const tableWrapperRef = useTableWrapper();
|
const tableWrapperRef = useTableWrapper();
|
||||||
|
@ -354,7 +357,7 @@ const typeMap = {
|
||||||
const handleTip = computed(() => {
|
const handleTip = computed(() => {
|
||||||
if (extraForm.mode === 'ignore') {
|
if (extraForm.mode === 'ignore') {
|
||||||
return '平台将忽略超出阈值的数据,无法查看上报记录';
|
return '平台将忽略超出阈值的数据,无法查看上报记录';
|
||||||
} else if (extraForm.mode === 'record') {
|
} else if (extraForm.mode === 'device-record') {
|
||||||
return '您可以在预处理数据-无效数据页面查看超出阈值的数据上报记录';
|
return '您可以在预处理数据-无效数据页面查看超出阈值的数据上报记录';
|
||||||
}
|
}
|
||||||
return '您可以在预处理数据-告警数据页面查看告警情况';
|
return '您可以在预处理数据-告警数据页面查看告警情况';
|
||||||
|
@ -366,7 +369,7 @@ const showContent = computed(() => {
|
||||||
return showExtra.value;
|
return showExtra.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return showMetrics.value || config.value.length > 0;
|
return (showMetrics.value || config.value.length > 0) && props.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
const showMetrics = computed(() => {
|
const showMetrics = computed(() => {
|
||||||
|
@ -384,7 +387,8 @@ const showMetrics = computed(() => {
|
||||||
const showExtra = computed(() => {
|
const showExtra = computed(() => {
|
||||||
return (
|
return (
|
||||||
['int', 'long', 'float', 'double'].includes(props.type as any) &&
|
['int', 'long', 'float', 'double'].includes(props.type as any) &&
|
||||||
props.metadataType === 'properties' && showThreshold
|
props.metadataType === 'properties' &&
|
||||||
|
showThreshold
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -485,8 +489,8 @@ const getConfig = async () => {
|
||||||
} else if (showMetrics.value) {
|
} else if (showMetrics.value) {
|
||||||
activeKey.value = ['metrics'];
|
activeKey.value = ['metrics'];
|
||||||
}
|
}
|
||||||
if(showExtra.value){
|
if (showExtra.value) {
|
||||||
activeKey.value = ['extra']
|
activeKey.value = ['extra'];
|
||||||
}
|
}
|
||||||
if (resp.result.length && !configValue.value) {
|
if (resp.result.length && !configValue.value) {
|
||||||
resp.result.forEach((a) => {
|
resp.result.forEach((a) => {
|
||||||
|
|
|
@ -3844,6 +3844,10 @@ export default [
|
||||||
permission: 'role',
|
permission: 'role',
|
||||||
actions: ['query'],
|
actions: ['query'],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
permission: "role-group",
|
||||||
|
actions: ["query"]
|
||||||
|
}
|
||||||
],
|
],
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
|
@ -3912,7 +3916,7 @@ export default [
|
||||||
permissions: [
|
permissions: [
|
||||||
{
|
{
|
||||||
permission: 'role-group',
|
permission: 'role-group',
|
||||||
actions: ['query','save']
|
actions: ['save']
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -3922,7 +3926,7 @@ export default [
|
||||||
permissions: [
|
permissions: [
|
||||||
{
|
{
|
||||||
permission: 'role-group',
|
permission: 'role-group',
|
||||||
actions: ['query','delete']
|
actions: ['delete']
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -217,7 +217,8 @@
|
||||||
</template>
|
</template>
|
||||||
<template #cardState="slotProps">
|
<template #cardState="slotProps">
|
||||||
<BadgeStatus
|
<BadgeStatus
|
||||||
:status="slotProps.cardState?.value"
|
v-if="slotProps.cardState?.state"
|
||||||
|
:status="slotProps.cardState?.state"
|
||||||
:text="slotProps.cardState?.text"
|
:text="slotProps.cardState?.text"
|
||||||
:statusNames="{
|
:statusNames="{
|
||||||
using: 'processing',
|
using: 'processing',
|
||||||
|
@ -508,7 +509,8 @@ const columns = [
|
||||||
title: '运营商状态',
|
title: '运营商状态',
|
||||||
dataIndex: 'operatorState',
|
dataIndex: 'operatorState',
|
||||||
key: 'operatorState',
|
key: 'operatorState',
|
||||||
hidden: true,
|
// hidden: true,
|
||||||
|
hideInTable: true,
|
||||||
search: {
|
search: {
|
||||||
type: 'select',
|
type: 'select',
|
||||||
options: [
|
options: [
|
||||||
|
|
|
@ -101,7 +101,8 @@ const pickerTimeChange = () => {
|
||||||
const echartsOptions = computed(() => {
|
const echartsOptions = computed(() => {
|
||||||
const series = serverActive.value.length
|
const series = serverActive.value.length
|
||||||
? serverActive.value.map((key) => setOptions(serverData.data, key))
|
? serverActive.value.map((key) => setOptions(serverData.data, key))
|
||||||
: typeDataLine
|
: typeDataLine;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
|
|
|
@ -140,7 +140,7 @@ const getJVMEcharts = async (val: any) => {
|
||||||
|
|
||||||
const setOptions = (optionsData: any, key: string) => ({
|
const setOptions = (optionsData: any, key: string) => ({
|
||||||
data: arrayReverse(optionsData[key]),
|
data: arrayReverse(optionsData[key]),
|
||||||
// name: key!= 'undefined' ? key : '',
|
name: key !== 'undefined' ? key : '',
|
||||||
type: 'line',
|
type: 'line',
|
||||||
smooth: true,
|
smooth: true,
|
||||||
symbol: 'none',
|
symbol: 'none',
|
||||||
|
@ -158,6 +158,7 @@ const echartsOptions = computed(() => {
|
||||||
const series = serverActive.value.length
|
const series = serverActive.value.length
|
||||||
? serverActive.value.map((key) => setOptions(serverData.data, key))
|
? serverActive.value.map((key) => setOptions(serverData.data, key))
|
||||||
: typeDataLine
|
: typeDataLine
|
||||||
|
|
||||||
return {
|
return {
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
|
|
|
@ -76,4 +76,4 @@ watch(() => JSON.stringify(props.value), () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
valueFormat="x"
|
valueFormat="x"
|
||||||
v-model:value="dateRange"
|
v-model:value="dateRange"
|
||||||
|
@change="onChange"
|
||||||
/>
|
/>
|
||||||
</j-space>
|
</j-space>
|
||||||
</div>
|
</div>
|
||||||
|
@ -144,6 +145,10 @@ const createChart = () => {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onChange = ()=>{
|
||||||
|
dimension.value = 'other'
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.chartData,
|
() => props.chartData,
|
||||||
(val) => {
|
(val) => {
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
<div>开始录像</div>
|
<div>开始录像</div>
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
<j-menu @click="recordStart">
|
<j-menu @click="recordStart">
|
||||||
<j-menu-item key="true" v-if="_type">
|
<j-menu-item key="true" v-if="_type && route.query.type !== 'onvif'">
|
||||||
<span style="padding-right: 12px"
|
<span style="padding-right: 12px"
|
||||||
>本地存储</span
|
>本地存储</span
|
||||||
>
|
>
|
||||||
|
@ -129,7 +129,7 @@
|
||||||
</MediaTool>
|
</MediaTool>
|
||||||
</div>
|
</div>
|
||||||
<Preset
|
<Preset
|
||||||
v-if="data.ptzType.value === 0 || data.ptzType.value === 1"
|
v-if="(data.ptzType.value === 0 || data.ptzType.value === 1) && route.query.type !== 'onvif'"
|
||||||
:data="data"
|
:data="data"
|
||||||
@refresh="onRefresh"
|
@refresh="onRefresh"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
</j-tooltip>
|
</j-tooltip>
|
||||||
<RadioCard
|
<RadioCard
|
||||||
layout="horizontal"
|
layout="horizontal"
|
||||||
:options="[
|
:options="deviceType !== 'onvif' ?[
|
||||||
{
|
{
|
||||||
label: '云端',
|
label: '云端',
|
||||||
value: 'cloud',
|
value: 'cloud',
|
||||||
|
@ -70,7 +70,12 @@
|
||||||
logo: getImage('/local.png'),
|
logo: getImage('/local.png'),
|
||||||
disabled: deviceType === 'fixed-media',
|
disabled: deviceType === 'fixed-media',
|
||||||
},
|
},
|
||||||
]"
|
]:
|
||||||
|
[{
|
||||||
|
label: '云端',
|
||||||
|
value: 'cloud',
|
||||||
|
logo: getImage('/media/cloud.png'),
|
||||||
|
}]"
|
||||||
:checkStyle="true"
|
:checkStyle="true"
|
||||||
v-model="type"
|
v-model="type"
|
||||||
/>
|
/>
|
||||||
|
@ -319,7 +324,7 @@ onMounted(() => {
|
||||||
deviceType.value = _type;
|
deviceType.value = _type;
|
||||||
const _timeStr = dayjs(new Date());
|
const _timeStr = dayjs(new Date());
|
||||||
time.value = _timeStr;
|
time.value = _timeStr;
|
||||||
if (_type === 'fixed-media') {
|
if (_type === 'fixed-media' || _type === 'onvif') {
|
||||||
type.value = 'cloud';
|
type.value = 'cloud';
|
||||||
queryServiceRecords(_timeStr);
|
queryServiceRecords(_timeStr);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -128,140 +128,404 @@
|
||||||
/>
|
/>
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
</j-col>
|
</j-col>
|
||||||
<j-col :span="8" class="form-item">
|
|
||||||
<j-form-item
|
|
||||||
:name="['configuration', 'rtpIp']"
|
|
||||||
:rules="[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入RTP IP',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
validator: validateAddress,
|
|
||||||
message: '请输入正确的IP地址或者域名',
|
|
||||||
},
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<template #label>
|
|
||||||
RTP IP
|
|
||||||
<j-tooltip
|
|
||||||
title="视频设备将流推送到该IP地址下,部分设备仅支持IP地址,建议全是用IP地址"
|
|
||||||
>
|
|
||||||
<AIcon
|
|
||||||
type="QuestionCircleOutlined"
|
|
||||||
style="margin-left: 2px"
|
|
||||||
/>
|
|
||||||
</j-tooltip>
|
|
||||||
</template>
|
|
||||||
<j-input
|
|
||||||
placeholder="请输入RTP IP"
|
|
||||||
v-model:value="formData.configuration.rtpIp"
|
|
||||||
/>
|
|
||||||
</j-form-item>
|
|
||||||
</j-col>
|
|
||||||
<j-col :span="4" v-if="!checked">
|
|
||||||
<j-form-item
|
|
||||||
class="form-item"
|
|
||||||
:name="['configuration', 'rtpPort']"
|
|
||||||
:rules="[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入端口',
|
|
||||||
},
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<div class="form-label"></div>
|
|
||||||
|
|
||||||
<j-input-number
|
<template
|
||||||
style="width: 100%"
|
v-if="formData.provider === 'embedded-zlmedia'"
|
||||||
:min="1"
|
>
|
||||||
:max="65535"
|
<j-col :span="24">
|
||||||
:precision="0"
|
<j-form-item
|
||||||
placeholder="请输入端口"
|
:name="['configuration', 'rtpIp']"
|
||||||
v-model:value="
|
:rules="[
|
||||||
formData.configuration.rtpPort
|
{
|
||||||
"
|
required: true,
|
||||||
/>
|
message: '请输入IP',
|
||||||
</j-form-item>
|
},
|
||||||
</j-col>
|
{
|
||||||
<j-col :span="4" v-if="checked">
|
validator: validateAddress,
|
||||||
<j-form-item
|
message:
|
||||||
class="form-item"
|
'请输入正确的IP地址或者域名',
|
||||||
:name="[
|
},
|
||||||
'configuration',
|
]"
|
||||||
'dynamicRtpPortRange0',
|
|
||||||
]"
|
|
||||||
:rules="[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入起始端口',
|
|
||||||
},
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<div class="form-label"></div>
|
|
||||||
<j-input-number
|
|
||||||
style="width: 100%"
|
|
||||||
:min="1"
|
|
||||||
:max="
|
|
||||||
formData.configuration
|
|
||||||
.dynamicRtpPortRange1 || 65535
|
|
||||||
"
|
|
||||||
:precision="0"
|
|
||||||
placeholder="起始端口"
|
|
||||||
v-model:value="
|
|
||||||
formData.configuration
|
|
||||||
.dynamicRtpPortRange0
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</j-form-item>
|
|
||||||
</j-col>
|
|
||||||
<div class="form-item-checked" v-if="checked">至</div>
|
|
||||||
<j-col :span="4" v-if="checked">
|
|
||||||
<j-form-item
|
|
||||||
class="form-item"
|
|
||||||
:name="[
|
|
||||||
'configuration',
|
|
||||||
'dynamicRtpPortRange1',
|
|
||||||
]"
|
|
||||||
:rules="[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入终止端口',
|
|
||||||
},
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<div class="form-label"></div>
|
|
||||||
<j-input-number
|
|
||||||
style="width: 100%"
|
|
||||||
:min="
|
|
||||||
formData.configuration
|
|
||||||
.dynamicRtpPortRange0 || 1
|
|
||||||
"
|
|
||||||
:max="65535"
|
|
||||||
:precision="0"
|
|
||||||
placeholder="终止端口"
|
|
||||||
v-model:value="
|
|
||||||
formData.configuration
|
|
||||||
.dynamicRtpPortRange1
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</j-form-item>
|
|
||||||
</j-col>
|
|
||||||
<j-col :span="4">
|
|
||||||
<j-form-item
|
|
||||||
class="form-item-checked2"
|
|
||||||
:name="['configuration', 'dynamicRtpPort']"
|
|
||||||
>
|
|
||||||
<div class="form-label"></div>
|
|
||||||
<j-checkbox
|
|
||||||
v-model:checked="
|
|
||||||
formData.configuration.dynamicRtpPort
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
动态端口
|
<template #label>
|
||||||
</j-checkbox>
|
IP
|
||||||
</j-form-item>
|
<j-tooltip
|
||||||
</j-col>
|
title="视频设备将流推送到该IP地址下,部分设备仅支持IP地址,建议全是用IP地址"
|
||||||
|
>
|
||||||
|
<AIcon
|
||||||
|
type="QuestionCircleOutlined"
|
||||||
|
style="margin-left: 2px"
|
||||||
|
/>
|
||||||
|
</j-tooltip>
|
||||||
|
</template>
|
||||||
|
<j-input
|
||||||
|
placeholder="请输入IP"
|
||||||
|
style="width: 50%"
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.rtpIp
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</j-col>
|
||||||
|
<j-col :span="12" class="item">
|
||||||
|
<j-row :gutter="[16, 0]">
|
||||||
|
<j-col :span="20" v-if="!checked">
|
||||||
|
<j-form-item
|
||||||
|
class="form-item"
|
||||||
|
:name="['configuration', 'rtpPort']"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入RTP端口',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
RTP 端口
|
||||||
|
<j-tooltip
|
||||||
|
title="视频设备将流推送到该IP地址对应的RTP端口下,部分设备仅支持IP地址,建议全是用IP地址"
|
||||||
|
>
|
||||||
|
<AIcon
|
||||||
|
type="QuestionCircleOutlined"
|
||||||
|
style="margin-left: 2px"
|
||||||
|
/>
|
||||||
|
</j-tooltip>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<j-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
:min="1"
|
||||||
|
:max="65535"
|
||||||
|
:precision="0"
|
||||||
|
placeholder="请输入RTP端口"
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration
|
||||||
|
.rtpPort
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</j-col>
|
||||||
|
<j-col :span="8" v-if="checked">
|
||||||
|
<j-form-item
|
||||||
|
class="form-item"
|
||||||
|
:name="[
|
||||||
|
'configuration',
|
||||||
|
'dynamicRtpPortRange0',
|
||||||
|
]"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入起始端口',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
RTP 端口
|
||||||
|
<j-tooltip
|
||||||
|
title="视频设备将流推送到该IP地址对应的RTP端口下,部分设备仅支持IP地址,建议全是用IP地址"
|
||||||
|
>
|
||||||
|
<AIcon
|
||||||
|
type="QuestionCircleOutlined"
|
||||||
|
style="margin-left: 2px"
|
||||||
|
/>
|
||||||
|
</j-tooltip>
|
||||||
|
</template>
|
||||||
|
<j-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
:min="1"
|
||||||
|
:max="
|
||||||
|
formData.configuration
|
||||||
|
.dynamicRtpPortRange1 ||
|
||||||
|
65535
|
||||||
|
"
|
||||||
|
:precision="0"
|
||||||
|
placeholder="起始端口"
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration
|
||||||
|
.dynamicRtpPortRange0
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</j-col>
|
||||||
|
<div
|
||||||
|
class="form-item-checked"
|
||||||
|
v-if="checked"
|
||||||
|
>
|
||||||
|
至
|
||||||
|
</div>
|
||||||
|
<j-col :span="8" v-if="checked">
|
||||||
|
<j-form-item
|
||||||
|
class="form-item"
|
||||||
|
:name="[
|
||||||
|
'configuration',
|
||||||
|
'dynamicRtpPortRange1',
|
||||||
|
]"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入终止端口',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div class="form-label"></div>
|
||||||
|
<j-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
:min="
|
||||||
|
formData.configuration
|
||||||
|
.dynamicRtpPortRange0 ||
|
||||||
|
1
|
||||||
|
"
|
||||||
|
:max="65535"
|
||||||
|
:precision="0"
|
||||||
|
placeholder="终止端口"
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration
|
||||||
|
.dynamicRtpPortRange1
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</j-col>
|
||||||
|
<j-col :span="4">
|
||||||
|
<j-form-item
|
||||||
|
class="form-item-checked2"
|
||||||
|
:name="[
|
||||||
|
'configuration',
|
||||||
|
'dynamicRtpPort',
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div class="form-label"></div>
|
||||||
|
<j-checkbox
|
||||||
|
v-model:checked="
|
||||||
|
formData.configuration
|
||||||
|
.dynamicRtpPort
|
||||||
|
"
|
||||||
|
>
|
||||||
|
动态端口
|
||||||
|
</j-checkbox>
|
||||||
|
</j-form-item>
|
||||||
|
</j-col>
|
||||||
|
|
||||||
|
<j-col :span="24">
|
||||||
|
<j-form-item
|
||||||
|
class="form-item"
|
||||||
|
:name="[
|
||||||
|
'configuration',
|
||||||
|
'rtmpPort',
|
||||||
|
]"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入RTMP端口',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
RTMP 端口
|
||||||
|
<j-tooltip
|
||||||
|
title="对外分享的RTMP视频流地址对应端口"
|
||||||
|
>
|
||||||
|
<AIcon
|
||||||
|
type="QuestionCircleOutlined"
|
||||||
|
style="margin-left: 2px"
|
||||||
|
/>
|
||||||
|
</j-tooltip>
|
||||||
|
</template>
|
||||||
|
<j-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
:min="1"
|
||||||
|
:max="65535"
|
||||||
|
:precision="0"
|
||||||
|
placeholder="RTMP 端口"
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration
|
||||||
|
.rtmpPort
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</j-col>
|
||||||
|
<j-col :span="24">
|
||||||
|
<j-form-item
|
||||||
|
:name="[
|
||||||
|
'configuration',
|
||||||
|
'rtspPort',
|
||||||
|
]"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入RTSP端口',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
RTSP 端口
|
||||||
|
<j-tooltip
|
||||||
|
title="对外分享的RTSP视频流地址对应端口"
|
||||||
|
>
|
||||||
|
<AIcon
|
||||||
|
type="QuestionCircleOutlined"
|
||||||
|
style="margin-left: 2px"
|
||||||
|
/>
|
||||||
|
</j-tooltip>
|
||||||
|
</template>
|
||||||
|
<j-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
:min="1"
|
||||||
|
:max="65535"
|
||||||
|
:precision="0"
|
||||||
|
placeholder="RTSP 端口"
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration
|
||||||
|
.rtspPort
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</j-col>
|
||||||
|
</j-row>
|
||||||
|
</j-col>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div v-else style="width: 100%; display: flex">
|
||||||
|
<j-col :span="8" class="form-item">
|
||||||
|
<j-form-item
|
||||||
|
:name="['configuration', 'rtpIp']"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入RTP IP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
validator: validateAddress,
|
||||||
|
message:
|
||||||
|
'请输入正确的IP地址或者域名',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
RTP IP
|
||||||
|
<j-tooltip
|
||||||
|
title="视频设备将流推送到该IP地址下,部分设备仅支持IP地址,建议全是用IP地址"
|
||||||
|
>
|
||||||
|
<AIcon
|
||||||
|
type="QuestionCircleOutlined"
|
||||||
|
style="margin-left: 2px"
|
||||||
|
/>
|
||||||
|
</j-tooltip>
|
||||||
|
</template>
|
||||||
|
<j-input
|
||||||
|
placeholder="请输入RTP IP"
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.rtpIp
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</j-col>
|
||||||
|
<j-col :span="4" v-if="!checked">
|
||||||
|
<j-form-item
|
||||||
|
class="form-item"
|
||||||
|
:name="['configuration', 'rtpPort']"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入端口',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div class="form-label"></div>
|
||||||
|
|
||||||
|
<j-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
:min="1"
|
||||||
|
:max="65535"
|
||||||
|
:precision="0"
|
||||||
|
placeholder="请输入端口"
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration.rtpPort
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</j-col>
|
||||||
|
<j-col :span="4" v-if="checked">
|
||||||
|
<j-form-item
|
||||||
|
class="form-item"
|
||||||
|
:name="[
|
||||||
|
'configuration',
|
||||||
|
'dynamicRtpPortRange0',
|
||||||
|
]"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入起始端口',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div class="form-label"></div>
|
||||||
|
<j-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
:min="1"
|
||||||
|
:max="
|
||||||
|
formData.configuration
|
||||||
|
.dynamicRtpPortRange1 || 65535
|
||||||
|
"
|
||||||
|
:precision="0"
|
||||||
|
placeholder="起始端口"
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration
|
||||||
|
.dynamicRtpPortRange0
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</j-col>
|
||||||
|
<div class="form-item-checked" v-if="checked">
|
||||||
|
至
|
||||||
|
</div>
|
||||||
|
<j-col :span="4" v-if="checked">
|
||||||
|
<j-form-item
|
||||||
|
class="form-item"
|
||||||
|
:name="[
|
||||||
|
'configuration',
|
||||||
|
'dynamicRtpPortRange1',
|
||||||
|
]"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入终止端口',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<div class="form-label"></div>
|
||||||
|
<j-input-number
|
||||||
|
style="width: 100%"
|
||||||
|
:min="
|
||||||
|
formData.configuration
|
||||||
|
.dynamicRtpPortRange0 || 1
|
||||||
|
"
|
||||||
|
:max="65535"
|
||||||
|
:precision="0"
|
||||||
|
placeholder="终止端口"
|
||||||
|
v-model:value="
|
||||||
|
formData.configuration
|
||||||
|
.dynamicRtpPortRange1
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</j-col>
|
||||||
|
<j-col :span="4">
|
||||||
|
<j-form-item
|
||||||
|
class="form-item-checked2"
|
||||||
|
:name="['configuration', 'dynamicRtpPort']"
|
||||||
|
>
|
||||||
|
<div class="form-label"></div>
|
||||||
|
<j-checkbox
|
||||||
|
v-model:checked="
|
||||||
|
formData.configuration
|
||||||
|
.dynamicRtpPort
|
||||||
|
"
|
||||||
|
>
|
||||||
|
动态端口
|
||||||
|
</j-checkbox>
|
||||||
|
</j-form-item>
|
||||||
|
</j-col>
|
||||||
|
</div>
|
||||||
|
|
||||||
<j-col :span="24">
|
<j-col :span="24">
|
||||||
<j-form-item>
|
<j-form-item>
|
||||||
|
@ -309,10 +573,7 @@ const Validator = {
|
||||||
|
|
||||||
const validateAddress = (_rule: any, value: string): Promise<any> =>
|
const validateAddress = (_rule: any, value: string): Promise<any> =>
|
||||||
new Promise(async (resolve, reject) => {
|
new Promise(async (resolve, reject) => {
|
||||||
if (
|
if (testIpv4_6(value) || Validator.regDomain.test(value)) {
|
||||||
testIpv4_6(value) ||
|
|
||||||
Validator.regDomain.test(value)
|
|
||||||
) {
|
|
||||||
return resolve('');
|
return resolve('');
|
||||||
} else {
|
} else {
|
||||||
return value ? reject('请输入正确的IP地址或者域名') : resolve('');
|
return value ? reject('请输入正确的IP地址或者域名') : resolve('');
|
||||||
|
@ -328,6 +589,8 @@ const formData = ref<FormDataType>({
|
||||||
apiPort: '',
|
apiPort: '',
|
||||||
rtpIp: '',
|
rtpIp: '',
|
||||||
rtpPort: '',
|
rtpPort: '',
|
||||||
|
rtspPort: '',
|
||||||
|
rtmpPort: '',
|
||||||
dynamicRtpPort: false,
|
dynamicRtpPort: false,
|
||||||
// dynamicRtpPortRange: [],
|
// dynamicRtpPortRange: [],
|
||||||
dynamicRtpPortRange0: '',
|
dynamicRtpPortRange0: '',
|
||||||
|
@ -413,5 +676,12 @@ watch(
|
||||||
height: 30px;
|
height: 30px;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
.item{
|
||||||
|
padding-top: 6px;
|
||||||
|
border: 1px solid #d1d1d1;
|
||||||
|
background-color: #e0e0e007;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -4,6 +4,8 @@ export interface Configuration {
|
||||||
apiPort: number | string;
|
apiPort: number | string;
|
||||||
rtpIp: string | string;
|
rtpIp: string | string;
|
||||||
rtpPort: number | string;
|
rtpPort: number | string;
|
||||||
|
rtspPort: number | string;
|
||||||
|
rtmpPort: number | string;
|
||||||
dynamicRtpPort: boolean;
|
dynamicRtpPort: boolean;
|
||||||
dynamicRtpPortRange?: array<any>;
|
dynamicRtpPortRange?: array<any>;
|
||||||
dynamicRtpPortRange0?: number | string | undefined;
|
dynamicRtpPortRange0?: number | string | undefined;
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<j-modal
|
<j-modal
|
||||||
v-model:visible="_vis"
|
visible
|
||||||
title="同步用户"
|
title="同步用户"
|
||||||
:footer="null"
|
:footer="null"
|
||||||
@cancel="_vis = false"
|
@cancel="$emit('cancel')"
|
||||||
width="80%"
|
width="80%"
|
||||||
>
|
>
|
||||||
<j-row :gutter="10" class="model-body">
|
<j-row :gutter="10" class="model-body">
|
||||||
|
@ -131,34 +131,17 @@ import { onlyMessage } from '@/utils/comm';
|
||||||
const useForm = Form.useForm;
|
const useForm = Form.useForm;
|
||||||
|
|
||||||
type Emits = {
|
type Emits = {
|
||||||
(e: 'update:visible', data: boolean): void;
|
(e: 'cancel'): void;
|
||||||
};
|
};
|
||||||
const emit = defineEmits<Emits>();
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
visible: { type: Boolean, default: false },
|
|
||||||
data: {
|
data: {
|
||||||
type: Object as PropType<Partial<Record<string, any>>>,
|
type: Object as PropType<Partial<Record<string, any>>>,
|
||||||
default: () => ({}),
|
default: () => ({}),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const _vis = computed({
|
|
||||||
get: () => props.visible,
|
|
||||||
set: (val) => emit('update:visible', val),
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => _vis.value,
|
|
||||||
(val) => {
|
|
||||||
if (val) {
|
|
||||||
getDepartment();
|
|
||||||
} else {
|
|
||||||
dataSource.value = [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// 左侧部门
|
// 左侧部门
|
||||||
const deptTreeData = ref([]);
|
const deptTreeData = ref([]);
|
||||||
const deptName = ref('');
|
const deptName = ref('');
|
||||||
|
@ -182,16 +165,11 @@ const getDepartment = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
deptTreeData.value = _result;
|
deptTreeData.value = _result;
|
||||||
deptId.value = _result[0]?.id;
|
if(_result.length){
|
||||||
|
deptId.value = _result[0]?.id;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
|
||||||
() => deptName.value,
|
|
||||||
(val: any) => {
|
|
||||||
if (!val) getDepartment();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门点击
|
* 部门点击
|
||||||
*/
|
*/
|
||||||
|
@ -253,7 +231,7 @@ const getActions = (
|
||||||
icon: 'DisconnectOutlined',
|
icon: 'DisconnectOutlined',
|
||||||
popConfirm: {
|
popConfirm: {
|
||||||
title: '确认解绑?',
|
title: '确认解绑?',
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
const response = configApi.unBindUser(
|
const response = configApi.unBindUser(
|
||||||
{ bindingId: data.bindId },
|
{ bindingId: data.bindId },
|
||||||
data.bindId,
|
data.bindId,
|
||||||
|
@ -336,7 +314,7 @@ const getAllUsers = async (terms?: any) => {
|
||||||
};
|
};
|
||||||
const { result } = await configApi.getPlatformUsers(params);
|
const { result } = await configApi.getPlatformUsers(params);
|
||||||
allUserList.value = result.map((m: any) => ({
|
allUserList.value = result.map((m: any) => ({
|
||||||
label: m.name,
|
label: m.name + ` (${m.username})`,
|
||||||
value: m.id,
|
value: m.id,
|
||||||
...m,
|
...m,
|
||||||
}));
|
}));
|
||||||
|
@ -357,7 +335,7 @@ const getTableData = (terms?: any) => {
|
||||||
(deptUsers || []).forEach((deptUser: any) => {
|
(deptUsers || []).forEach((deptUser: any) => {
|
||||||
// 未绑定的用户
|
// 未绑定的用户
|
||||||
let unBindUser = unBindUsers.find(
|
let unBindUser = unBindUsers.find(
|
||||||
(f: any) => f.name === deptUser?.name,
|
(f: any) => f.id === deptUser?.id,
|
||||||
);
|
);
|
||||||
// 绑定的用户
|
// 绑定的用户
|
||||||
const bindUser = bindUsers.find(
|
const bindUser = bindUsers.find(
|
||||||
|
@ -399,14 +377,6 @@ const handleTableChange = (pagination: any) => {
|
||||||
pageSize.value = pagination.pageSize;
|
pageSize.value = pagination.pageSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
|
||||||
() => deptId.value,
|
|
||||||
() => {
|
|
||||||
getTableData();
|
|
||||||
},
|
|
||||||
{ immediate: true },
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定用户
|
* 绑定用户
|
||||||
*/
|
*/
|
||||||
|
@ -487,6 +457,23 @@ const handleCancel = () => {
|
||||||
bindVis.value = false;
|
bindVis.value = false;
|
||||||
resetFields();
|
resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => deptId.value,
|
||||||
|
() => {
|
||||||
|
getTableData();
|
||||||
|
},
|
||||||
|
// { immediate: true },
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
() => deptName.value,
|
||||||
|
(val: any) => {
|
||||||
|
if (!val) getDepartment();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
onMounted(() => {
|
||||||
|
getDepartment();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -194,7 +194,7 @@
|
||||||
|
|
||||||
<Debug v-model:visible="debugVis" :data="currentConfig" />
|
<Debug v-model:visible="debugVis" :data="currentConfig" />
|
||||||
<Log v-if="logVis" :data="currentConfig" @cancel="logVis = false" />
|
<Log v-if="logVis" :data="currentConfig" @cancel="logVis = false" />
|
||||||
<SyncUser v-model:visible="syncVis" :data="currentConfig" />
|
<SyncUser v-if="syncVis" :data="currentConfig" @cancel="syncVis = false"/>
|
||||||
</page-container>
|
</page-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -142,62 +142,6 @@ const _vis = computed({
|
||||||
* 获取通知模板
|
* 获取通知模板
|
||||||
*/
|
*/
|
||||||
const configList = ref<BindConfig[]>([]);
|
const configList = ref<BindConfig[]>([]);
|
||||||
const getConfigList = async () => {
|
|
||||||
const params = {
|
|
||||||
terms: [
|
|
||||||
{ column: 'type', value: props.data.type },
|
|
||||||
{ column: 'provider', value: props.data.provider },
|
|
||||||
],
|
|
||||||
};
|
|
||||||
const { result } = await TemplateApi.getConfig(params);
|
|
||||||
configList.value = result;
|
|
||||||
// 设置默认配置
|
|
||||||
if (configList.value.length) formData.value.configId = props.data.configId;
|
|
||||||
};
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => _vis.value,
|
|
||||||
(val) => {
|
|
||||||
if (val) {
|
|
||||||
getConfigList();
|
|
||||||
getTemplateDetail();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取模板详情
|
|
||||||
*/
|
|
||||||
const getTemplateDetail = async () => {
|
|
||||||
const { result } = await TemplateApi.getTemplateDetail(props.data.id);
|
|
||||||
formData.value.templateDetailTable = result.variableDefinitions.map(
|
|
||||||
(m: any) => ({
|
|
||||||
...m,
|
|
||||||
type: m.expands?.businessType ? m.expands.businessType : m.type,
|
|
||||||
value: undefined,
|
|
||||||
// 电话字段校验
|
|
||||||
otherRules:
|
|
||||||
m.id === 'calledNumber' || m.id === 'phoneNumber'
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
max: 64,
|
|
||||||
message: '最多可输入64个字符',
|
|
||||||
trigger: 'change',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
trigger: 'change',
|
|
||||||
validator(_rule: Rule, value: string) {
|
|
||||||
if (!value) return Promise.resolve();
|
|
||||||
if (!phoneRegEx(value))
|
|
||||||
return Promise.reject('请输入有效号码');
|
|
||||||
return Promise.resolve();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: [],
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
|
@ -236,7 +180,74 @@ const formData = ref<{
|
||||||
*/
|
*/
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
const btnLoading = ref(false);
|
const btnLoading = ref(false);
|
||||||
|
|
||||||
|
const getConfigList = async () => {
|
||||||
|
const params = {
|
||||||
|
terms: [
|
||||||
|
{ column: 'type', value: props.data.type },
|
||||||
|
{ column: 'provider', value: props.data.provider },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const { result } = await TemplateApi.getConfig(params);
|
||||||
|
configList.value = result;
|
||||||
|
// 设置默认配置
|
||||||
|
if (configList.value.length) formData.value.configId = props.data.configId;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模板详情
|
||||||
|
*/
|
||||||
|
const getTemplateDetail = async () => {
|
||||||
|
const { result } = await TemplateApi.getTemplateDetail(props.data.id);
|
||||||
|
formData.value.templateDetailTable = result.variableDefinitions.map(
|
||||||
|
(m: any) => ({
|
||||||
|
...m,
|
||||||
|
type: m.expands?.businessType ? m.expands.businessType : m.type,
|
||||||
|
value: undefined,
|
||||||
|
// 电话字段校验
|
||||||
|
otherRules:
|
||||||
|
m.id === 'calledNumber' || m.id === 'phoneNumber'
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
max: 64,
|
||||||
|
message: '最多可输入64个字符',
|
||||||
|
trigger: 'change',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
trigger: 'change',
|
||||||
|
validator(_rule: Rule, value: string) {
|
||||||
|
if (!value) return Promise.resolve();
|
||||||
|
if (!phoneRegEx(value))
|
||||||
|
return Promise.reject('请输入有效号码');
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
|
console.log(formData.value.templateDetailTable)
|
||||||
|
const filterData = formData.value.templateDetailTable.filter((item: any) =>
|
||||||
|
['user', 'org', 'tag', 'userIdList', 'departmentIdList'].includes(
|
||||||
|
item.id,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const pass = filterData.length
|
||||||
|
? filterData.some((i: any) => {
|
||||||
|
return i.value;
|
||||||
|
})
|
||||||
|
: true;
|
||||||
|
if (!pass && props.data.type === 'dingTalk') {
|
||||||
|
onlyMessage('收信人,收信人部门至少填写一个', 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!pass && props.data.type === 'weixin') {
|
||||||
|
onlyMessage('收信人,收信人部门,收信人标签至少填写一个', 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
formRef.value
|
formRef.value
|
||||||
.validate()
|
.validate()
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
|
@ -267,6 +278,16 @@ const handleCancel = () => {
|
||||||
formRef.value.resetFields();
|
formRef.value.resetFields();
|
||||||
formData.value.templateDetailTable = [];
|
formData.value.templateDetailTable = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => _vis.value,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
getConfigList();
|
||||||
|
getTemplateDetail();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -14,12 +14,13 @@ import templateApi from '@/api/notice/template';
|
||||||
|
|
||||||
type Emits = {
|
type Emits = {
|
||||||
(e: 'update:toUser', data: string | undefined): void;
|
(e: 'update:toUser', data: string | undefined): void;
|
||||||
|
(e: 'update:canSave', data: boolean): void;
|
||||||
};
|
};
|
||||||
type Props = {
|
type Props = {
|
||||||
toUser: string | undefined;
|
toUser: string | undefined;
|
||||||
type: string | undefined;
|
type: string | undefined;
|
||||||
configId: string | undefined;
|
configId: string | undefined;
|
||||||
}
|
};
|
||||||
|
|
||||||
const emit = defineEmits<Emits>();
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
|
@ -37,14 +38,19 @@ const typeObj = {
|
||||||
const options = ref([]);
|
const options = ref([]);
|
||||||
const queryData = async () => {
|
const queryData = async () => {
|
||||||
if (!props.configId) return;
|
if (!props.configId) return;
|
||||||
const { result } = await templateApi.getUser(
|
const res: any = await templateApi
|
||||||
typeObj[props.type],
|
.getUser(typeObj[props.type], props.configId)
|
||||||
props.configId,
|
.catch(() => {
|
||||||
);
|
emit('update:canSave', false);
|
||||||
options.value = result.map((item: any) => ({
|
});
|
||||||
label: item.name,
|
|
||||||
value: item.id,
|
if (res.status === 200) {
|
||||||
}));
|
options.value = res?.result.map((item: any) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
emit('update:canSave', true);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
queryData();
|
queryData();
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,10 @@ const AliyunVoice = () => {
|
||||||
<div> 阿里云语音对每一条语音验证码/语音通知分配的唯一ID标识</div>
|
<div> 阿里云语音对每一条语音验证码/语音通知分配的唯一ID标识</div>
|
||||||
<h2> 4、被叫号码</h2>
|
<h2> 4、被叫号码</h2>
|
||||||
<div> 当前仅支持国内手机号,此处若不填,则在模板调试和配置告警通知时手动填写。</div>
|
<div> 当前仅支持国内手机号,此处若不填,则在模板调试和配置告警通知时手动填写。</div>
|
||||||
<div>若您使用的语音通知文件为公共模式外呼,则该参数值不填。</div>
|
|
||||||
<div>若您使用的语音通知文件为专属模式外呼,则必须传入已购买的号码,仅支持一个号码。</div>
|
|
||||||
<h2> 5、被叫显号</h2>
|
<h2> 5、被叫显号</h2>
|
||||||
<div> 用户呼叫号码显示,必须是在阿里云购买的号码。</div>
|
<div> 用户呼叫号码显示,必须是在阿里云购买的号码。</div>
|
||||||
|
<div>若您使用的语音通知文件为公共模式外呼,则该参数值不填。</div>
|
||||||
|
<div>若您使用的语音通知文件为专属模式外呼,则必须传入已购买的号码,仅支持一个号码。</div>
|
||||||
<h2> 6、播放次数</h2>
|
<h2> 6、播放次数</h2>
|
||||||
<div> 最多可播放3次</div>
|
<div> 最多可播放3次</div>
|
||||||
<h2> 7、模板内容</h2>
|
<h2> 7、模板内容</h2>
|
||||||
|
|
|
@ -105,7 +105,7 @@
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
<j-row :gutter="10">
|
<j-row :gutter="10">
|
||||||
<j-col :span="12">
|
<j-col :span="12">
|
||||||
<j-form-item label="收信部门">
|
<j-form-item label="收信人部门">
|
||||||
<ToOrg
|
<ToOrg
|
||||||
v-model:toParty="
|
v-model:toParty="
|
||||||
formData.template
|
formData.template
|
||||||
|
@ -137,6 +137,7 @@
|
||||||
v-model:toUser="
|
v-model:toUser="
|
||||||
formData.template.userIdList
|
formData.template.userIdList
|
||||||
"
|
"
|
||||||
|
v-model:canSave="canSave"
|
||||||
:type="formData.type"
|
:type="formData.type"
|
||||||
:config-id="formData.configId"
|
:config-id="formData.configId"
|
||||||
/>
|
/>
|
||||||
|
@ -294,7 +295,7 @@
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
</j-col>
|
</j-col>
|
||||||
<j-col :span="12">
|
<j-col :span="12">
|
||||||
<j-form-item label="收信部门">
|
<j-form-item label="收信人部门">
|
||||||
<ToOrg
|
<ToOrg
|
||||||
v-model:toParty="
|
v-model:toParty="
|
||||||
formData.template.toParty
|
formData.template.toParty
|
||||||
|
@ -308,7 +309,7 @@
|
||||||
<j-form-item>
|
<j-form-item>
|
||||||
<template #label>
|
<template #label>
|
||||||
<span>
|
<span>
|
||||||
标签推送
|
收信人标签
|
||||||
<j-tooltip
|
<j-tooltip
|
||||||
title="本企业微信的标签ID列表,最多支持100个,如果不填写该字段,将在使用此模板发送通知时进行指定"
|
title="本企业微信的标签ID列表,最多支持100个,如果不填写该字段,将在使用此模板发送通知时进行指定"
|
||||||
>
|
>
|
||||||
|
@ -722,6 +723,7 @@
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
<j-form-item>
|
<j-form-item>
|
||||||
<j-button
|
<j-button
|
||||||
|
:disabled="!canSave"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleSubmit"
|
@click="handleSubmit"
|
||||||
:loading="btnLoading"
|
:loading="btnLoading"
|
||||||
|
@ -771,7 +773,7 @@ const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const useForm = Form.useForm;
|
const useForm = Form.useForm;
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
|
const canSave = ref(true)
|
||||||
const flag = ref<boolean>(false)
|
const flag = ref<boolean>(false)
|
||||||
// 消息类型
|
// 消息类型
|
||||||
const msgType = ref([
|
const msgType = ref([
|
||||||
|
@ -1184,8 +1186,13 @@ const templateList = ref();
|
||||||
const getTemplateList = async () => {
|
const getTemplateList = async () => {
|
||||||
if (!formData.value.configId) return
|
if (!formData.value.configId) return
|
||||||
const id = formData.value.configId || undefined;
|
const id = formData.value.configId || undefined;
|
||||||
const { result } = await templateApi.getAliTemplate(id);
|
const res:any = await templateApi.getAliTemplate(id).catch(()=>{
|
||||||
templateList.value = result;
|
canSave.value = false
|
||||||
|
})
|
||||||
|
if(res.status === 200){
|
||||||
|
canSave.value = true
|
||||||
|
templateList.value = res.result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
</template>
|
</template>
|
||||||
{{ selectedKeys.some(selectKey => selectKey === item.actionId) ? '已关联' : '关联' }}
|
{{ selectedKeys.some(selectKey => selectKey === item.actionId) ? '已关联' : '关联' }}
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button v-else-if="activeKeys.some(active => active === item.actionId)" type="link" @click.stop="onSelect(item)">
|
<a-button v-else-if="activeKeys.some(active => active === item.actionId || active === -1)" type="link" @click.stop="onSelect(item)">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<AIcon type="icon-jiebang"/>
|
<AIcon type="icon-jiebang"/>
|
||||||
</template>
|
</template>
|
||||||
|
@ -254,8 +254,8 @@ const onBind = (record) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSelect = (record) => {
|
const onSelect = (record) => {
|
||||||
const selected = props.activeKeys.some(item => item === record.actionId)
|
const id = props.activeKeys.find(active => active === record.actionId || active === -1)
|
||||||
emit('select', record.actionId, !selected)
|
emit('select', id, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -188,6 +188,10 @@ const props = defineProps({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
|
showHistory: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
maskStyle: {
|
maskStyle: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: undefined
|
default: undefined
|
||||||
|
@ -221,7 +225,7 @@ const branchesGroup = computed(() => {
|
||||||
const activeBranches = computed(() => {
|
const activeBranches = computed(() => {
|
||||||
const { data, invalid } = handleActiveBranches(branchesGroup.value, props.activeKeys)
|
const { data, invalid } = handleActiveBranches(branchesGroup.value, props.activeKeys)
|
||||||
|
|
||||||
isInvalid.value = invalid
|
isInvalid.value = invalid && props.showHistory
|
||||||
return data
|
return data
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
|
|
||||||
<script setup name="SceneDrawer">
|
<script setup name="SceneDrawer">
|
||||||
import {useRequest} from "@/hook";
|
import {useRequest} from "@/hook";
|
||||||
import {queryBindScene} from "@/api/rule-engine/configuration";
|
import {queryBindScene, unbindScene} from "@/api/rule-engine/configuration";
|
||||||
import {handleGroupAndFilter, typeMap} from "./Save/utils";
|
import {handleGroupAndFilter, typeMap} from "./Save/utils";
|
||||||
import BranchesTabs from './Save/BranchesTabs.vue'
|
import BranchesTabs from './Save/BranchesTabs.vue'
|
||||||
import { unBindAlarm, bindScene } from "@/api/rule-engine/configuration";
|
import { unBindAlarm, bindScene } from "@/api/rule-engine/configuration";
|
||||||
|
@ -97,11 +97,13 @@ const handleBind = (id, selected) => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
unBindAlarm(props.detail.id, props.id, [id]).then(res => {
|
const request = id === -1 ? unbindScene(props.id, [props.detail.id]) : unBindAlarm(props.detail.id, props.id, [id])
|
||||||
|
request.then(res => {
|
||||||
activeKeys.value = activeKeys.value.filter(key => key !== id)
|
activeKeys.value = activeKeys.value.filter(key => key !== id)
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
:showBranches="false"
|
:showBranches="false"
|
||||||
:showBindTags="true"
|
:showBindTags="true"
|
||||||
:showRule="false"
|
:showRule="false"
|
||||||
|
:showHistory="false"
|
||||||
@click="handleView(slotProps)"
|
@click="handleView(slotProps)"
|
||||||
>
|
>
|
||||||
<div class="scene-view">
|
<div class="scene-view">
|
||||||
|
@ -116,32 +117,32 @@ const {data: activeKeys, reload} = useRequest(queryBindScene, {
|
||||||
defaultValue: {}
|
defaultValue: {}
|
||||||
})
|
})
|
||||||
|
|
||||||
const getActions = (
|
// const getActions = (
|
||||||
data: Partial<Record<string, any>>,
|
// data: Partial<Record<string, any>>,
|
||||||
type: 'card' | 'table',
|
// type: 'card' | 'table',
|
||||||
): ActionsType[] => {
|
// ): ActionsType[] => {
|
||||||
if (!data) return [];
|
// if (!data) return [];
|
||||||
const actions: ActionsType[] = [
|
// const actions: ActionsType[] = [
|
||||||
{
|
// {
|
||||||
key: 'action',
|
// key: 'action',
|
||||||
text: '解绑',
|
// text: '解绑',
|
||||||
icon: 'DisconnectOutlined',
|
// icon: 'DisconnectOutlined',
|
||||||
popConfirm: {
|
// popConfirm: {
|
||||||
title: '确认解绑?',
|
// title: '确认解绑?',
|
||||||
onConfirm: async () => {
|
// onConfirm: async () => {
|
||||||
// const res = await unbindScene(id, [data.id], data.branchIndex);
|
// // const res = await unbindScene(id, [data.id], data.branchIndex);
|
||||||
const res = await unbindScene(id, [data.id]);
|
// const res = await unbindScene(id, [data.id]);
|
||||||
if (res.status === 200) {
|
// if (res.status === 200) {
|
||||||
onlyMessage('操作成功');
|
// onlyMessage('操作成功');
|
||||||
actionRef.value.reload();
|
// actionRef.value.reload();
|
||||||
}
|
// }
|
||||||
return
|
// return
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
];
|
// ];
|
||||||
return actions;
|
// return actions;
|
||||||
};
|
// };
|
||||||
|
|
||||||
const queryTable = (_terms: any) => {
|
const queryTable = (_terms: any) => {
|
||||||
return query(_terms, id)
|
return query(_terms, id)
|
||||||
|
|
|
@ -20,11 +20,11 @@
|
||||||
<template #alarmTime="slotProps">{{
|
<template #alarmTime="slotProps">{{
|
||||||
dayjs(slotProps.alarmTime).format('YYYY-MM-DD HH:mm:ss')
|
dayjs(slotProps.alarmTime).format('YYYY-MM-DD HH:mm:ss')
|
||||||
}}</template>
|
}}</template>
|
||||||
<template #sourceId="slotProps"
|
<template #sourceName="slotProps"
|
||||||
>设备ID:<a-button
|
>设备名称:<a-button
|
||||||
type="link"
|
type="link"
|
||||||
@click="() => gotoDevice(slotProps.sourceId)"
|
@click="() => gotoDevice(slotProps.sourceId)"
|
||||||
>{{ slotProps.sourceId }}</a-button
|
>{{ slotProps.sourceName }}</a-button
|
||||||
></template
|
></template
|
||||||
>
|
>
|
||||||
<template #action="slotProps">
|
<template #action="slotProps">
|
||||||
|
@ -213,8 +213,8 @@ watch(
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '告警源',
|
title: '告警源',
|
||||||
dataIndex: 'sourceId',
|
dataIndex: 'sourceName',
|
||||||
key: 'sourceId',
|
key: 'sourceName',
|
||||||
scopedSlots: true,
|
scopedSlots: true,
|
||||||
search: {
|
search: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { handleLog } from '@/api/rule-engine/log';
|
import { handleLog, handlePreconditioning } from '@/api/rule-engine/log';
|
||||||
import { onlyMessage } from '@/utils/comm';
|
import { onlyMessage } from '@/utils/comm';
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: {
|
data: {
|
||||||
|
@ -39,6 +39,10 @@ const props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
goal: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const loading = ref<boolean>(false);
|
const loading = ref<boolean>(false);
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
|
@ -66,14 +70,17 @@ const handleSave = () => {
|
||||||
formRef.value
|
formRef.value
|
||||||
.validate()
|
.validate()
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
const res = await handleLog({
|
const params = {
|
||||||
describe: form.describe,
|
describe: form.describe,
|
||||||
type: 'user',
|
type: 'user',
|
||||||
state: 'normal',
|
state: 'normal',
|
||||||
alarmRecordId: props.data?.id || '',
|
alarmRecordId: props.data?.id || '',
|
||||||
alarmConfigId: props.data?.alarmConfigId || '',
|
alarmConfigId: props.data?.alarmConfigId || '',
|
||||||
alarmTime: props?.data?.alarmTime || '',
|
alarmTime: props?.data?.alarmTime || '',
|
||||||
});
|
};
|
||||||
|
const res = props.goal
|
||||||
|
? await handlePreconditioning(params)
|
||||||
|
: await handleLog(params);
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
onlyMessage('操作成功!');
|
onlyMessage('操作成功!');
|
||||||
emit('refresh');
|
emit('refresh');
|
||||||
|
@ -82,13 +89,13 @@ const handleSave = () => {
|
||||||
}
|
}
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error:any) => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
props.solveType === 'view' ? form.describe = props.handleDes : '';
|
props.solveType === 'view' ? (form.describe = props.handleDes) : '';
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped></style>
|
<style lang="less" scoped></style>
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
>{{ dayjs(text).format('YYYY-MM-DD HH:mm:ss')
|
>{{ dayjs(text).format('YYYY-MM-DD HH:mm:ss')
|
||||||
}}</span
|
}}</span
|
||||||
></template>
|
></template>
|
||||||
<template v-if="column.dataIndex === 'sourceId'">
|
<template v-if="column.dataIndex === 'sourceName'">
|
||||||
<Ellipsis>
|
<Ellipsis>
|
||||||
设备ID:
|
设备名称:
|
||||||
<span class="deviceId" @click="() => gotoDevice(text)">{{
|
<span class="deviceId" @click="() => gotoDevice(text)">{{
|
||||||
text
|
text
|
||||||
}}</span></Ellipsis
|
}}</span></Ellipsis
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { queryLogList } from '@/api/rule-engine/log';
|
import { queryLogList ,queryPreconditioningLogList } from '@/api/rule-engine/log';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { useMenuStore } from 'store/menu';
|
import { useMenuStore } from 'store/menu';
|
||||||
import LogDetail from './LogDetail.vue';
|
import LogDetail from './LogDetail.vue';
|
||||||
|
@ -62,6 +62,10 @@ const props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
goal:{
|
||||||
|
type:String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
});
|
});
|
||||||
const menuStory = useMenuStore();
|
const menuStory = useMenuStore();
|
||||||
const exceed = ref();
|
const exceed = ref();
|
||||||
|
@ -81,8 +85,8 @@ const columns = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '告警源',
|
title: '告警源',
|
||||||
dataIndex: 'sourceId',
|
dataIndex: 'sourceName',
|
||||||
key: 'sourceId',
|
key: 'sourceName',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '告警原因',
|
title: '告警原因',
|
||||||
|
@ -97,7 +101,7 @@ const columns = [
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
const queryData = async () => {
|
const queryData = async () => {
|
||||||
const res = await queryLogList(props.configId, {
|
const params = {
|
||||||
pageIndex: 0,
|
pageIndex: 0,
|
||||||
pageSize: 51,
|
pageSize: 51,
|
||||||
terms: [
|
terms: [
|
||||||
|
@ -114,7 +118,8 @@ const queryData = async () => {
|
||||||
order: 'desc',
|
order: 'desc',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
}
|
||||||
|
const res = props.goal ? await queryPreconditioningLogList(props.configId,params) : await queryLogList(props.configId, params);
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
if (res.result.data?.length > 50) {
|
if (res.result.data?.length > 50) {
|
||||||
exceed.value = true;
|
exceed.value = true;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { storeToRefs } from 'pinia';
|
||||||
import { useSceneStore } from '@/store/scene'
|
import { useSceneStore } from '@/store/scene'
|
||||||
import { Form } from 'jetlinks-ui-components'
|
import { Form } from 'jetlinks-ui-components'
|
||||||
import { queryProductList } from '@/api/device/product'
|
import { queryProductList } from '@/api/device/product'
|
||||||
import {query as deviceQuery, detail as deviceDetailQuery} from '@/api/device/instance'
|
import {query as deviceQuery, detail as deviceDetailQuery, queryNoPagingPost} from '@/api/device/instance'
|
||||||
import { getTreeData_api } from '@/api/system/department'
|
import { getTreeData_api } from '@/api/system/department'
|
||||||
import {queryDetailListNoPaging} from "@/api/device/firmware";
|
import {queryDetailListNoPaging} from "@/api/device/firmware";
|
||||||
|
|
||||||
|
@ -36,24 +36,29 @@ const check = async (): Promise<boolean> => {
|
||||||
|
|
||||||
// 判断设备是否删除
|
// 判断设备是否删除
|
||||||
if (deviceTrigger.selector === 'fixed') { // 设备
|
if (deviceTrigger.selector === 'fixed') { // 设备
|
||||||
const deviceResp = await queryDetailListNoPaging({
|
// const deviceResp = await queryDetailListNoPaging({
|
||||||
terms: [{ column: 'id', termType: 'in', value: selectorValues?.toString() }],
|
// terms: [{ column: 'id', termType: 'in', value: selectorValues?.toString() }],
|
||||||
context: {
|
// context: {
|
||||||
"includeTags": false,
|
// "includeTags": false,
|
||||||
"includeBind": false,
|
// "includeBind": false,
|
||||||
"includeRelations": false,
|
// "includeRelations": false,
|
||||||
"includeFirmwareInfos": false
|
// "includeFirmwareInfos": false
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
|
const deviceResp = await queryNoPagingPost(
|
||||||
|
{
|
||||||
|
terms: [{ terms: [{ column: 'id', termType: 'in', value: selectorValues?.toString() }]}],
|
||||||
|
})
|
||||||
|
|
||||||
if (deviceResp.success && deviceResp.result.length !== (selectorValues!.length)) {
|
if (deviceResp.success && deviceResp.result.length !== (selectorValues!.length)) {
|
||||||
data.value.trigger!.device!.selectorValues = undefined
|
data.value.trigger!.device!.selectorValues = undefined
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectorValues!.length === 1) {
|
if (selectorValues!.length === 1) {
|
||||||
// const deviceDetailResp = await deviceDetailQuery(selectorValues![0])
|
const deviceDetailResp = await deviceDetailQuery(selectorValues![0])
|
||||||
// const deviceDetail = deviceDetailResp?.result
|
const deviceDetail = deviceDetailResp?.result
|
||||||
const deviceDetail = deviceResp.result[0]
|
// const deviceDetail = deviceResp.result[0]
|
||||||
metadata = JSON.parse(deviceDetail?.metadata || '{}') // 只选中一个设备,以设备物模型为准
|
metadata = JSON.parse(deviceDetail?.metadata || '{}') // 只选中一个设备,以设备物模型为准
|
||||||
}
|
}
|
||||||
} else if (deviceTrigger.selector === 'org') { // 组织
|
} else if (deviceTrigger.selector === 'org') { // 组织
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { EventEmitter, EventSubscribeKeys, getParams } from '@/views/rule-engine
|
||||||
import { getOption } from '@/views/rule-engine/Scene/Save/components/DropdownButton/util'
|
import { getOption } from '@/views/rule-engine/Scene/Save/components/DropdownButton/util'
|
||||||
import { getBuildInData, getNotifyVariablesUser } from './util'
|
import { getBuildInData, getNotifyVariablesUser } from './util'
|
||||||
import { defineExpose } from 'vue'
|
import { defineExpose } from 'vue'
|
||||||
import {queryDetailListNoPaging} from "@/api/device/firmware";
|
import {detail as getDeviceDetail, queryNoPagingPost} from "@/api/device/instance";
|
||||||
|
|
||||||
|
|
||||||
const sceneStore = useSceneStore();
|
const sceneStore = useSceneStore();
|
||||||
|
@ -62,22 +62,17 @@ const checkDeviceDelete = async () => {
|
||||||
let hasDevice = false
|
let hasDevice = false
|
||||||
if (item!.selectorValues) {
|
if (item!.selectorValues) {
|
||||||
const deviceList = item!.selectorValues?.map(item => item.value) || []
|
const deviceList = item!.selectorValues?.map(item => item.value) || []
|
||||||
const deviceResp = await queryDetailListNoPaging(
|
const deviceResp = await queryNoPagingPost(
|
||||||
{
|
{
|
||||||
terms: [{ terms: [{ column: 'id', termType: 'in', value: deviceList.toString() }]}],
|
terms: [{ terms: [{ column: 'id', termType: 'in', value: deviceList.toString() }]}],
|
||||||
context: {
|
|
||||||
"includeTags": false,
|
|
||||||
"includeBind": false,
|
|
||||||
"includeRelations": false,
|
|
||||||
"includeFirmwareInfos": false
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
hasDevice = deviceResp.success && deviceResp.result.length === (item!.selectorValues?.length || 0)
|
hasDevice = deviceResp.success && deviceResp.result.length === (item!.selectorValues?.length || 0)
|
||||||
|
|
||||||
if (item!.selectorValues!.length === 1 && hasDevice) {
|
if (item!.selectorValues!.length === 1 && hasDevice) {
|
||||||
const deviceDetail = deviceResp.result?.[0]
|
const deviceDetailResp = await getDeviceDetail(deviceList[0])
|
||||||
// const deviceDetailResp = await getDeviceDetail(deviceList[0])
|
// const deviceDetail = deviceResp.result?.[0]
|
||||||
|
const deviceDetail = deviceDetailResp.result
|
||||||
metadata = JSON.parse(deviceDetail?.metadata || productDetail?.metadata || '{}') // 只选中一个设备,以设备物模型为准
|
metadata = JSON.parse(deviceDetail?.metadata || productDetail?.metadata || '{}') // 只选中一个设备,以设备物模型为准
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,6 +167,18 @@ const queryOrgList = async (id: string) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const queryTagList = async (id:string) =>{
|
||||||
|
if (! props.notifierId) return '';
|
||||||
|
const resp = await TemplateApi.getTags(
|
||||||
|
props.notifierId,
|
||||||
|
);
|
||||||
|
if (resp.status === 200) {
|
||||||
|
return resp.result?.find((item: any) => item.id === id)?.name;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const getOptions = async (dt: any) => {
|
const getOptions = async (dt: any) => {
|
||||||
const obj = {};
|
const obj = {};
|
||||||
// 钉钉,微信
|
// 钉钉,微信
|
||||||
|
@ -177,6 +189,9 @@ const getOptions = async (dt: any) => {
|
||||||
if (dt?.template?.toUser) {
|
if (dt?.template?.toUser) {
|
||||||
obj['sendTo'] = await queryUserList(dt?.template?.toUser);
|
obj['sendTo'] = await queryUserList(dt?.template?.toUser);
|
||||||
}
|
}
|
||||||
|
if (dt?.template?.toTag) {
|
||||||
|
obj['tagName'] = await queryTagList(dt?.template?.toTag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (props.notifyType === 'dingTalk') {
|
if (props.notifyType === 'dingTalk') {
|
||||||
if (dt?.template?.departmentIdList) {
|
if (dt?.template?.departmentIdList) {
|
||||||
|
@ -190,10 +205,11 @@ const getOptions = async (dt: any) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClick = async (dt: any) => {
|
const handleClick = async (dt: any) => {
|
||||||
|
console.log(dt,'dt')
|
||||||
if (_selectedRowKeys.value.includes(dt.id)) {
|
if (_selectedRowKeys.value.includes(dt.id)) {
|
||||||
_selectedRowKeys.value = [];
|
_selectedRowKeys.value = [];
|
||||||
emit('update:value', undefined);
|
emit('update:value', undefined);
|
||||||
emit('change', { templateName: undefined, orgName: undefined, sendTo: undefined });
|
emit('change', { templateName: undefined, orgName: undefined, sendTo: undefined ,tagName: undefined });
|
||||||
emit('update:detail', undefined);
|
emit('update:detail', undefined);
|
||||||
} else {
|
} else {
|
||||||
const obj = await getOptions(dt)
|
const obj = await getOptions(dt)
|
||||||
|
|
|
@ -23,7 +23,7 @@ import notice from '@/api/notice/config';
|
||||||
|
|
||||||
const iconMap = new Map();
|
const iconMap = new Map();
|
||||||
iconMap.set('dingTalk', getImage('/notice/dingtalk.png'));
|
iconMap.set('dingTalk', getImage('/notice/dingtalk.png'));
|
||||||
iconMap.set('weixin', getImage('/notice/wechat.png'));
|
iconMap.set('weixin', getImage('/notice/weixin-corp.png'));
|
||||||
iconMap.set('email', getImage('/notice/email.png'));
|
iconMap.set('email', getImage('/notice/email.png'));
|
||||||
iconMap.set('voice', getImage('/notice/voice.png'));
|
iconMap.set('voice', getImage('/notice/voice.png'));
|
||||||
iconMap.set('sms', getImage('/notice/sms.png'));
|
iconMap.set('sms', getImage('/notice/sms.png'));
|
||||||
|
|
|
@ -10,7 +10,12 @@
|
||||||
:label="item?.name"
|
:label="item?.name"
|
||||||
v-for="(item, index) in variableDefinitions"
|
v-for="(item, index) in variableDefinitions"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:required="!['file', 'user', 'org', 'tag'].includes(getType(item)) ? true : false"
|
:required="
|
||||||
|
!['file', 'user', 'org', 'tag'].includes(getType(item)) ||
|
||||||
|
item.id === 'calledNumber'
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
"
|
||||||
:rules="[
|
:rules="[
|
||||||
{
|
{
|
||||||
validator: (_rule, value) => checkValue(_rule, value, item),
|
validator: (_rule, value) => checkValue(_rule, value, item),
|
||||||
|
@ -48,7 +53,10 @@
|
||||||
v-else
|
v-else
|
||||||
:item="item"
|
:item="item"
|
||||||
v-model:value="modelRef[item.id]"
|
v-model:value="modelRef[item.id]"
|
||||||
@change="(val, _options) => onChange(val, 'build-in', index, _options)"
|
@change="
|
||||||
|
(val, _options) =>
|
||||||
|
onChange(val, 'build-in', index, _options)
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
</j-form>
|
</j-form>
|
||||||
|
@ -82,9 +90,9 @@ const props = defineProps({
|
||||||
default: () => ({}),
|
default: () => ({}),
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({}),
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['update:value', 'change']);
|
const emit = defineEmits(['update:value', 'change']);
|
||||||
|
@ -92,15 +100,23 @@ const emit = defineEmits(['update:value', 'change']);
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
|
|
||||||
const modelRef = reactive({});
|
const modelRef = reactive({});
|
||||||
const otherColumns = ref<(string | undefined)[]>(props.options?.otherColumns || [])
|
const otherColumns = ref<(string | undefined)[]>(
|
||||||
|
props.options?.otherColumns || [],
|
||||||
|
);
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
Object.assign(modelRef, props?.value);
|
Object.assign(modelRef, props?.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
if(props?.template?.template?.sendTo && Array.isArray(props?.template?.template?.sendTo) && props?.template?.template?.sendTo?.length) {
|
if (
|
||||||
emit('change', { sendTo: props?.template?.template?.sendTo?.join(' ') });
|
props?.template?.template?.sendTo &&
|
||||||
|
Array.isArray(props?.template?.template?.sendTo) &&
|
||||||
|
props?.template?.template?.sendTo?.length
|
||||||
|
) {
|
||||||
|
emit('change', {
|
||||||
|
sendTo: props?.template?.template?.sendTo?.join(' '),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -109,10 +125,15 @@ const getType = (item: any) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkValue = (_rule: any, value: any, item: any) => {
|
const checkValue = (_rule: any, value: any, item: any) => {
|
||||||
if(!value){
|
if (!value) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
const type = item.expands?.businessType || item?.type;
|
const type = item.expands?.businessType || item?.type;
|
||||||
|
if (
|
||||||
|
['user', 'org', 'tag', 'userIdList', 'departmentIdList'].includes(type)
|
||||||
|
) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
if (type === 'file') {
|
if (type === 'file') {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} else if (type === 'link') {
|
} else if (type === 'link') {
|
||||||
|
@ -142,10 +163,10 @@ const checkValue = (_rule: any, value: any, item: any) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (value?.source === 'fixed' && !value?.value) {
|
} else if (value?.source === 'fixed' && !value?.value) {
|
||||||
let tip = '请输入' + item.name
|
let tip = '请输入' + item.name;
|
||||||
if (props.notify.notifyType === 'email') {
|
if (props.notify.notifyType === 'email') {
|
||||||
tip = '请输入收件人'
|
tip = '请输入收件人';
|
||||||
}
|
}
|
||||||
return Promise.reject(new Error(tip));
|
return Promise.reject(new Error(tip));
|
||||||
} else if (
|
} else if (
|
||||||
value?.source === 'relation' &&
|
value?.source === 'relation' &&
|
||||||
|
@ -181,7 +202,8 @@ const checkValue = (_rule: any, value: any, item: any) => {
|
||||||
if (
|
if (
|
||||||
props.notify.notifyType &&
|
props.notify.notifyType &&
|
||||||
['sms', 'voice'].includes(props?.notify?.notifyType) &&
|
['sms', 'voice'].includes(props?.notify?.notifyType) &&
|
||||||
value?.source !== 'relation' && value?.value
|
value?.source !== 'relation' &&
|
||||||
|
value?.value
|
||||||
) {
|
) {
|
||||||
const reg = /^[1][3-9]\d{9}$/;
|
const reg = /^[1][3-9]\d{9}$/;
|
||||||
if (!reg.test(value?.value)) {
|
if (!reg.test(value?.value)) {
|
||||||
|
@ -196,9 +218,9 @@ const checkValue = (_rule: any, value: any, item: any) => {
|
||||||
|
|
||||||
const onChange = (val: any, type: any, index: number, options?: string) => {
|
const onChange = (val: any, type: any, index: number, options?: string) => {
|
||||||
if (type === 'build-in') {
|
if (type === 'build-in') {
|
||||||
otherColumns.value[index] = options
|
otherColumns.value[index] = options;
|
||||||
} else {
|
} else {
|
||||||
otherColumns.value[index] = undefined
|
otherColumns.value[index] = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'org') {
|
if (type === 'org') {
|
||||||
|
@ -208,24 +230,58 @@ const onChange = (val: any, type: any, index: number, options?: string) => {
|
||||||
} else if (type === 'user') {
|
} else if (type === 'user') {
|
||||||
emit('change', { sendTo: val, otherColumns: [] });
|
emit('change', { sendTo: val, otherColumns: [] });
|
||||||
} else {
|
} else {
|
||||||
emit('change', { otherColumns: otherColumns.value });
|
emit('change', { otherColumns: otherColumns.value });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSave = () =>
|
const onSave = () =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
const pass = props.variableDefinitions.filter(item => ['user', 'org', 'tag'].includes(getType(item))).some(item => {
|
const filterData = props.variableDefinitions.filter((item) =>
|
||||||
return modelRef[item.id]
|
['user', 'org', 'tag', 'userIdList', 'departmentIdList'].includes(
|
||||||
})
|
getType(item),
|
||||||
if(!pass && props.notify.notifyType === 'weixin') {
|
),
|
||||||
onlyMessage('收信人,收信人部门,收信人标签至少填写一个', 'warning')
|
);
|
||||||
return reject(false)
|
const pass = filterData.length
|
||||||
|
? filterData.some((item) => {
|
||||||
|
|
||||||
|
if (
|
||||||
|
item.id === 'toUser' &&
|
||||||
|
modelRef[item.id]?.source === 'relation'
|
||||||
|
) {
|
||||||
|
|
||||||
|
return (
|
||||||
|
modelRef[item.id].relation?.objectId ||
|
||||||
|
modelRef[item.id].relation?.related
|
||||||
|
);
|
||||||
|
} else if (item.id === 'userIdList') {
|
||||||
|
return (
|
||||||
|
modelRef[item.id]?.value ||
|
||||||
|
modelRef[item.id]?.relation?.objectId
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return modelRef[item.id]?.value;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
: true;
|
||||||
|
if (!pass && props.notify.notifyType === 'weixin') {
|
||||||
|
onlyMessage(
|
||||||
|
'收信人,收信人部门,收信人标签至少填写一个',
|
||||||
|
'warning',
|
||||||
|
);
|
||||||
|
return reject(false);
|
||||||
}
|
}
|
||||||
formRef.value?.validate().then((_data: any) => {
|
if (!pass && props.notify.notifyType === 'dingTalk') {
|
||||||
resolve(_data);
|
onlyMessage('收信人,收信人部门至少填写一个', 'warning');
|
||||||
}).catch(() => {
|
return reject(false);
|
||||||
reject(false)
|
}
|
||||||
})
|
formRef.value
|
||||||
|
?.validate()
|
||||||
|
.then((_data: any) => {
|
||||||
|
resolve(_data);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
reject(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
defineExpose({ onSave });
|
defineExpose({ onSave });
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
placeholder="请选择组织"
|
placeholder="请选择组织"
|
||||||
:tree-data="departmentTree"
|
:tree-data="departmentTree"
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
|
allowClear
|
||||||
:fieldNames="{
|
:fieldNames="{
|
||||||
label: 'name',
|
label: 'name',
|
||||||
value: 'id',
|
value: 'id',
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
v-model:value="keys"
|
v-model:value="keys"
|
||||||
placeholder="请选择标签"
|
placeholder="请选择标签"
|
||||||
:options="tagsList"
|
:options="tagsList"
|
||||||
|
allowClear
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||||
:value="relationData"
|
:value="relationData"
|
||||||
showSearch
|
showSearch
|
||||||
|
allowClear
|
||||||
treeNodeFilterProp="title"
|
treeNodeFilterProp="title"
|
||||||
>
|
>
|
||||||
<template #title="{ key, username, title }">
|
<template #title="{ key, username, title }">
|
||||||
|
@ -72,6 +73,7 @@
|
||||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||||
:value="relationData"
|
:value="relationData"
|
||||||
showSearch
|
showSearch
|
||||||
|
allowClear
|
||||||
treeNodeFilterProp="title"
|
treeNodeFilterProp="title"
|
||||||
>
|
>
|
||||||
<template #title="{ key, username, title }">
|
<template #title="{ key, username, title }">
|
||||||
|
@ -97,6 +99,7 @@
|
||||||
placeholder="请选择收信人"
|
placeholder="请选择收信人"
|
||||||
:value="value?.value"
|
:value="value?.value"
|
||||||
showSearch
|
showSearch
|
||||||
|
allowClear
|
||||||
@change="
|
@change="
|
||||||
(val, option) =>
|
(val, option) =>
|
||||||
onChange(
|
onChange(
|
||||||
|
@ -219,6 +222,7 @@ const treeData = ref<any[]>([
|
||||||
const mySource = ref<string>('relation');
|
const mySource = ref<string>('relation');
|
||||||
const treeDataMap = new Map()
|
const treeDataMap = new Map()
|
||||||
|
|
||||||
|
|
||||||
const getRelationUsers = async (notifyType: string, notifierId: string) => {
|
const getRelationUsers = async (notifyType: string, notifierId: string) => {
|
||||||
let resp = undefined;
|
let resp = undefined;
|
||||||
if (notifyType === 'dingTalk') {
|
if (notifyType === 'dingTalk') {
|
||||||
|
@ -294,6 +298,7 @@ const sourceChange = (v: any) => {
|
||||||
emit('update:value', {
|
emit('update:value', {
|
||||||
source: v,
|
source: v,
|
||||||
});
|
});
|
||||||
|
emit('change',undefined)
|
||||||
};
|
};
|
||||||
|
|
||||||
const getObj = (
|
const getObj = (
|
||||||
|
@ -375,7 +380,6 @@ const onChange = (
|
||||||
const _isRelation = item?.isRelation
|
const _isRelation = item?.isRelation
|
||||||
_values = getObj(_source, _value, _isRelation);
|
_values = getObj(_source, _value, _isRelation);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit('update:value', _values);
|
emit('update:value', _values);
|
||||||
emit('change', _names.filter((item) => !!item).join(','));
|
emit('change', _names.filter((item) => !!item).join(','));
|
||||||
};
|
};
|
||||||
|
|
|
@ -100,10 +100,10 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { queryAlarmPage } from '@/api/rule-engine/scene';
|
import { queryAlarmPage } from '@/api/rule-engine/scene';
|
||||||
import AlarmModal from "./AlarmModal.vue";
|
import AlarmModal from "./AlarmModal.vue";
|
||||||
import {unBindAlarm} from "@/api/rule-engine/configuration";
|
import {queryBindScene, unBindAlarm, unbindScene} from "@/api/rule-engine/configuration";
|
||||||
import {onlyMessage} from "@/utils/comm";
|
import {onlyMessage} from "@/utils/comm";
|
||||||
import { EventEmitter } from '@/views/rule-engine/Scene/Save/util'
|
import { EventEmitter } from '@/views/rule-engine/Scene/Save/util'
|
||||||
import {useAlarmLevel} from "@/hook";
|
import {useAlarmLevel, useRequest} from "@/hook";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -131,6 +131,18 @@ const visible = ref(false)
|
||||||
const tableRef = ref()
|
const tableRef = ref()
|
||||||
const { levelMap } = useAlarmLevel();
|
const { levelMap } = useAlarmLevel();
|
||||||
|
|
||||||
|
const { data: activeKeys } = useRequest<any, Record<string, any>>(queryBindScene, {
|
||||||
|
defaultParams: { terms: [{ column: 'ruleId', value: props.id}]},
|
||||||
|
onSuccess(res) {
|
||||||
|
const _result = res.result.data || []
|
||||||
|
return _result.reduce((prev: Record<string, any>, next: { branchIndex: string, ruleId: string }) => {
|
||||||
|
prev[next.ruleId] = next.branchIndex
|
||||||
|
return prev
|
||||||
|
}, {})
|
||||||
|
},
|
||||||
|
defaultValue: []
|
||||||
|
})
|
||||||
|
|
||||||
const map = {
|
const map = {
|
||||||
product: '产品',
|
product: '产品',
|
||||||
device: '设备',
|
device: '设备',
|
||||||
|
@ -193,7 +205,8 @@ const showAlarm = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const unBind = async (record: any) => {
|
const unBind = async (record: any) => {
|
||||||
const res = await unBindAlarm(props.id, record.id, [props.actionId])
|
const branchId = activeKeys.value![props.id]
|
||||||
|
const res = branchId === -1 ? await unbindScene(record.id, [props.id]) : await unBindAlarm(props.id, record.id, [props.actionId || props.branchId])
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
tableRef.value.reload()
|
tableRef.value.reload()
|
||||||
onlyMessage('操作成功!')
|
onlyMessage('操作成功!')
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class='actions-terms'>
|
<div class='actions-terms'>
|
||||||
<TitleComponent data='执行动作' style='font-size: 14px;' >
|
<TitleComponent data='执行动作' style='font-size: 14px;' >
|
||||||
<template #extra>
|
|
||||||
<j-switch
|
|
||||||
v-model:checked='open'
|
|
||||||
@change='change'
|
|
||||||
checkedChildren='开'
|
|
||||||
unCheckedChildren='关'
|
|
||||||
style='margin-left: 4px;'
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</TitleComponent>
|
</TitleComponent>
|
||||||
<!-- <template v-if='open'>-->
|
<!-- <template v-if='open'>-->
|
||||||
<div>
|
<div>
|
||||||
|
@ -25,6 +16,16 @@
|
||||||
{{ b.branchName || `条件${i+1}` }}
|
{{ b.branchName || `条件${i+1}` }}
|
||||||
</TermsTabPane>
|
</TermsTabPane>
|
||||||
</template>
|
</template>
|
||||||
|
<div class="filterConditionSwitch">
|
||||||
|
<span>执行</span>
|
||||||
|
<j-switch
|
||||||
|
v-model:checked='b.openFilter'
|
||||||
|
@change='(e)=>change(e,b,i)'
|
||||||
|
checkedChildren='开'
|
||||||
|
unCheckedChildren='关'
|
||||||
|
style='margin-left: 4px;'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<template v-for='(item, index) in data.branches'>
|
<template v-for='(item, index) in data.branches'>
|
||||||
<template v-if="index >= b.start && index < (b.start + b.len)">
|
<template v-if="index >= b.start && index < (b.start + b.len)">
|
||||||
<Branches
|
<Branches
|
||||||
|
@ -94,7 +95,6 @@ import {queryBindScene, unBindAlarmMultiple} from "@/api/rule-engine/configurati
|
||||||
|
|
||||||
const sceneStore = useSceneStore()
|
const sceneStore = useSceneStore()
|
||||||
const { data } = storeToRefs(sceneStore)
|
const { data } = storeToRefs(sceneStore)
|
||||||
const open = ref<boolean>(false)
|
|
||||||
const columnOptions = ref<any>([])
|
const columnOptions = ref<any>([])
|
||||||
const group = ref<Array<{ id: string, len: number}>>([])
|
const group = ref<Array<{ id: string, len: number}>>([])
|
||||||
const activeKey = ref('')
|
const activeKey = ref('')
|
||||||
|
@ -103,15 +103,42 @@ const conditionName = ref<any>()
|
||||||
|
|
||||||
provide(ContextKey, columnOptions)
|
provide(ContextKey, columnOptions)
|
||||||
|
|
||||||
const change = (e: boolean) => {
|
const change = (e: boolean,groupItem:any,index:number) => {
|
||||||
group.value = []
|
// group.value = []
|
||||||
activeKey.value = ''
|
// activeKey.value = ''
|
||||||
if (!e) {
|
// if (!e) {
|
||||||
data.value.branches!.length = 1
|
// data.value.branches!.length = 1
|
||||||
data.value.branches![0].when = []
|
// data.value.branches![0].when = []
|
||||||
} else {
|
// } else {
|
||||||
data.value.branches!.push(null as any)
|
// data.value.branches!.push(null as any)
|
||||||
data.value.branches![0].when = [
|
// data.value.branches![0].when = [
|
||||||
|
// {
|
||||||
|
// terms: [
|
||||||
|
// {
|
||||||
|
// column: undefined,
|
||||||
|
// value: {
|
||||||
|
// source: 'fixed',
|
||||||
|
// value: undefined
|
||||||
|
// },
|
||||||
|
// termType: undefined,
|
||||||
|
// key: `params_${randomString()}`,
|
||||||
|
// type: 'and',
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// type: 'and',
|
||||||
|
// key: `terms_${randomString()}`,
|
||||||
|
// },
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
const start = groupItem.start
|
||||||
|
const len = groupItem.len
|
||||||
|
if(!e){
|
||||||
|
data.value.branches?.splice(start + 1 , len - 1)
|
||||||
|
data.value.branches![start].when = []
|
||||||
|
data.value.options!.when.splice(start,len - 1)
|
||||||
|
}else{
|
||||||
|
data.value.branches!.splice(start + 1,0,null)
|
||||||
|
data.value.branches![start].when = [
|
||||||
{
|
{
|
||||||
terms: [
|
terms: [
|
||||||
{
|
{
|
||||||
|
@ -141,9 +168,10 @@ const queryColumn = (dataModel: FormModelType) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const addBranches = (len: number) => {
|
const addBranches = (len: number) => {
|
||||||
|
const key = randomNumber()
|
||||||
const branchesItem = {
|
const branchesItem = {
|
||||||
when: [],
|
when: [],
|
||||||
key: randomNumber(),
|
key: key,
|
||||||
shakeLimit: {
|
shakeLimit: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
time: 1,
|
time: 1,
|
||||||
|
@ -151,12 +179,13 @@ const addBranches = (len: number) => {
|
||||||
alarmFirst: false,
|
alarmFirst: false,
|
||||||
},
|
},
|
||||||
then: [],
|
then: [],
|
||||||
branchId: randomNumber()
|
branchId: key
|
||||||
}
|
}
|
||||||
// const lastIndex = data.value.branches!.length - 1 || 0
|
// const lastIndex = data.value.branches!.length - 1 || 0
|
||||||
data.value.branches?.splice(len - 1, 1, branchesItem)
|
data.value.branches?.splice(len - 1, 1, branchesItem)
|
||||||
data.value.options!.when.splice(len - 1, 1, {
|
data.value.options!.when.splice(len - 1, 1, {
|
||||||
terms: []
|
terms: [],
|
||||||
|
key
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,12 +407,6 @@ watchEffect(() => {
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
const branches = data.value.branches
|
const branches = data.value.branches
|
||||||
if (data.value.branches?.filter(item => item).length) {
|
|
||||||
open.value = !!data.value.branches[0].when.length
|
|
||||||
} else {
|
|
||||||
open.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
let _group = []
|
let _group = []
|
||||||
let _branchesIndex = 0
|
let _branchesIndex = 0
|
||||||
if (branches) {
|
if (branches) {
|
||||||
|
@ -407,8 +430,10 @@ watchEffect(() => {
|
||||||
branchId: item.branchId,
|
branchId: item.branchId,
|
||||||
// branchName: item.branchName || whenItem?.branchName || `条件 ${_branchesIndex + 1}`,
|
// branchName: item.branchName || whenItem?.branchName || `条件 ${_branchesIndex + 1}`,
|
||||||
branchName: item.branchName || whenItem?.branchName || `条件`,
|
branchName: item.branchName || whenItem?.branchName || `条件`,
|
||||||
groupIndex: _branchesIndex
|
groupIndex: _branchesIndex,
|
||||||
|
openFilter: !!item.when.length
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_group[lastIndex].len += 1
|
_group[lastIndex].len += 1
|
||||||
}
|
}
|
||||||
|
@ -444,4 +469,13 @@ defineExpose({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.filterConditionSwitch{
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
font-weight: 800;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
type="color"
|
type="color"
|
||||||
:hex="tagInfo.color"
|
:hex="tagInfo.color"
|
||||||
:rgba="tagInfo.color"
|
:rgba="tagInfo.color"
|
||||||
:themeColor="themeColor"
|
:themeColor="themeColor"
|
||||||
|
:show-opacity="false"
|
||||||
@change="changeColor"
|
@change="changeColor"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
@ -84,8 +85,8 @@ const themeColor = [
|
||||||
'#FF85C0'
|
'#FF85C0'
|
||||||
]
|
]
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
loading.value = true
|
|
||||||
form.value.validate().then(async () => {
|
form.value.validate().then(async () => {
|
||||||
|
loading.value = true
|
||||||
let id;
|
let id;
|
||||||
if (props.editType === 'add') {
|
if (props.editType === 'add') {
|
||||||
id = randomString();
|
id = randomString();
|
||||||
|
@ -96,7 +97,9 @@ const submit = () => {
|
||||||
id,
|
id,
|
||||||
name: tagInfo.name,
|
name: tagInfo.name,
|
||||||
};
|
};
|
||||||
const res = await saveTag(submitData);
|
const res = await saveTag(submitData).finally(()=>{
|
||||||
|
loading.value = false
|
||||||
|
});
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
colorData.value[id] = tagInfo.color;
|
colorData.value[id] = tagInfo.color;
|
||||||
const saveRes = await saveTagsColor(colorData.value).catch(()=>{
|
const saveRes = await saveTagsColor(colorData.value).catch(()=>{
|
||||||
|
|
|
@ -83,6 +83,11 @@ const addTag = () => {
|
||||||
editType.value = 'add';
|
editType.value = 'add';
|
||||||
};
|
};
|
||||||
const buildInTag = ['weekend', 'holiday', 'workday'];
|
const buildInTag = ['weekend', 'holiday', 'workday'];
|
||||||
|
const defaultColor = new Map()
|
||||||
|
defaultColor.set('weekend', 'rgb(149, 222, 100)')
|
||||||
|
defaultColor.set('holiday', 'rgb(161, 180, 204)')
|
||||||
|
defaultColor.set('workday', 'rgba(105,177,255,1')
|
||||||
|
|
||||||
const createDrag = () => {
|
const createDrag = () => {
|
||||||
new Draggable(tags.value, {
|
new Draggable(tags.value, {
|
||||||
itemSelector: '.tagName',
|
itemSelector: '.tagName',
|
||||||
|
@ -111,6 +116,7 @@ const queryTagsData = async () => {
|
||||||
}
|
}
|
||||||
if (buildInTag.includes(i.id)) {
|
if (buildInTag.includes(i.id)) {
|
||||||
disabled = true;
|
disabled = true;
|
||||||
|
color = defaultColor.get(i.id);
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...i,
|
...i,
|
||||||
|
|
|
@ -201,9 +201,10 @@ const queryData = (first?: Boolean, searchName?: any) => {
|
||||||
listData.value = res.result;
|
listData.value = res.result;
|
||||||
if (first && res.result.length) {
|
if (first && res.result.length) {
|
||||||
selectDic(res.result[0]);
|
selectDic(res.result[0]);
|
||||||
}else if(selectedKeys.value){
|
}else if(selectedKeys.value){
|
||||||
|
console.log(selectedKeys.value)
|
||||||
selectDic(res.result.find(i=>{
|
selectDic(res.result.find(i=>{
|
||||||
return i.id = selectedKeys.value[0]
|
return i.id === selectedKeys.value[0]
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,10 +229,10 @@ const showEdit = (data: any) => {
|
||||||
const reload = () => {
|
const reload = () => {
|
||||||
queryData();
|
queryData();
|
||||||
};
|
};
|
||||||
const saveSuccess = () => {
|
const saveSuccess = (id?: string) => {
|
||||||
saveShow.value = false;
|
saveShow.value = false;
|
||||||
|
selectedKeys.value = [id] ;
|
||||||
reload();
|
reload();
|
||||||
|
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -270,7 +271,7 @@ const updateDic = (data: any) => {
|
||||||
* 切换选中字典
|
* 切换选中字典
|
||||||
*/
|
*/
|
||||||
const selectDic = (selectKeys: any) => {
|
const selectDic = (selectKeys: any) => {
|
||||||
selectedKeys.value = [selectKeys.id];
|
selectedKeys.value = [selectKeys.id]
|
||||||
emit('selectData', selectKeys);
|
emit('selectData', selectKeys);
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -109,7 +109,7 @@ const submitData = () =>{
|
||||||
const res = await addDictionary(form)
|
const res = await addDictionary(form)
|
||||||
if(res.status === 200){
|
if(res.status === 200){
|
||||||
onlyMessage('保存成功!')
|
onlyMessage('保存成功!')
|
||||||
emit('success')
|
emit('success',form.id)
|
||||||
}else{
|
}else{
|
||||||
onlyMessage('操作失败!','error')
|
onlyMessage('操作失败!','error')
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,11 +215,13 @@ const handleOk = async () => {
|
||||||
_dataSorts.push(USER_CENTER_MENU_DATA);
|
_dataSorts.push(USER_CENTER_MENU_DATA);
|
||||||
const res = await updateMenus(_dataSorts).catch(() => {});
|
const res = await updateMenus(_dataSorts).catch(() => {});
|
||||||
if (res?.status === 200) {
|
if (res?.status === 200) {
|
||||||
|
loading.value = false;
|
||||||
|
visible.value = false;
|
||||||
onlyMessage('操作成功', 'success');
|
onlyMessage('操作成功', 'success');
|
||||||
location.reload();
|
setTimeout(() => {
|
||||||
|
location.reload();
|
||||||
|
}, 100);
|
||||||
}
|
}
|
||||||
loading.value = false;
|
|
||||||
visible.value = false;
|
|
||||||
};
|
};
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<h5>接口描述</h5>
|
<h5>接口描述</h5>
|
||||||
<div>{{ props.selectApi.description }}</div>
|
<div>{{ props.selectApi.description }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="api-card" v-if="requestCard.codeText">
|
<div class="api-card" v-if="requestCard.codeText !== undefined">
|
||||||
<h5>请求示例</h5>
|
<h5>请求示例</h5>
|
||||||
<JsonViewer :value="requestCard.codeText" copyable />
|
<JsonViewer :value="requestCard.codeText" copyable />
|
||||||
</div>
|
</div>
|
||||||
|
@ -154,7 +154,9 @@ const requestCard = reactive<cardType>({
|
||||||
// schema不是Java中的类的话则不进行解析,直接结束
|
// schema不是Java中的类的话则不进行解析,直接结束
|
||||||
if (!_ref) {
|
if (!_ref) {
|
||||||
const type = schema.type || '';
|
const type = schema.type || '';
|
||||||
|
console.log(type,'type')
|
||||||
requestCard.codeText = dealNoRef(type, schema);
|
requestCard.codeText = dealNoRef(type, schema);
|
||||||
|
console.log(requestCard.codeText)
|
||||||
} else {
|
} else {
|
||||||
const schemaName = _ref?.split('/').pop();
|
const schemaName = _ref?.split('/').pop();
|
||||||
const type = schema.type || '';
|
const type = schema.type || '';
|
||||||
|
|
|
@ -66,10 +66,10 @@
|
||||||
max: 64,
|
max: 64,
|
||||||
message: '最多输入64个字符',
|
message: '最多输入64个字符',
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
validator: vailName,
|
// validator: vailName,
|
||||||
trigger: 'blur',
|
// trigger: 'blur',
|
||||||
},
|
// },
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<j-input
|
<j-input
|
||||||
|
@ -86,10 +86,10 @@
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入区划代码',
|
message: '请输入区划代码',
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
validator: vailCode,
|
// validator: vailCode,
|
||||||
trigger: 'blur',
|
// trigger: 'blur',
|
||||||
},
|
// },
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<j-input-number
|
<j-input-number
|
||||||
|
@ -156,7 +156,7 @@ import type {PropType} from 'vue';
|
||||||
import {reactive, ref, watch} from 'vue';
|
import {reactive, ref, watch} from 'vue';
|
||||||
import BuildIn from './BuildIn.vue';
|
import BuildIn from './BuildIn.vue';
|
||||||
import {updateRegion, validateName, validateCode} from '@/api/system/region';
|
import {updateRegion, validateName, validateCode} from '@/api/system/region';
|
||||||
import {omit} from "lodash-es";
|
import {cloneDeep, omit} from "lodash-es";
|
||||||
import {onlyMessage} from "@/utils/comm";
|
import {onlyMessage} from "@/utils/comm";
|
||||||
import RadioButton from '@/components/CardSelect/RadioButton.vue'
|
import RadioButton from '@/components/CardSelect/RadioButton.vue'
|
||||||
import GeoJsonModal from './GeoJsonModal.vue'
|
import GeoJsonModal from './GeoJsonModal.vue'
|
||||||
|
@ -293,8 +293,8 @@ const handleSave = () => {
|
||||||
newData.parentId = newData.parentId || ''
|
newData.parentId = newData.parentId || ''
|
||||||
|
|
||||||
if (newData.properties.sync) {
|
if (newData.properties.sync) {
|
||||||
const _syncChildren = syncChildren(newData.code, props.areaTree)
|
const arr = cloneDeep(props.areaTree)
|
||||||
|
const _syncChildren = syncChildren(newData.code, arr)
|
||||||
const different = _syncChildren.filter(item => {
|
const different = _syncChildren.filter(item => {
|
||||||
if (newData.children && newData.children.some(oldItem => oldItem.code === item.code)) {
|
if (newData.children && newData.children.some(oldItem => oldItem.code === item.code)) {
|
||||||
return false
|
return false
|
||||||
|
@ -310,7 +310,10 @@ const handleSave = () => {
|
||||||
newData.children = [
|
newData.children = [
|
||||||
...(newData.children || []),
|
...(newData.children || []),
|
||||||
...different
|
...different
|
||||||
]
|
].map(item=>{
|
||||||
|
const {id,...extra} =item
|
||||||
|
return extra
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|
|
@ -95,8 +95,8 @@ function openEdit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function layerSetData(geoJson: Record<string, any>, edit = true) {
|
function layerSetData(geoJson: Record<string, any>, edit = true) {
|
||||||
regionState.type = geoJson.features[0].properties.type
|
regionState.type = geoJson?.features?.[0]?.properties?.type
|
||||||
mapRef.value?.showGeoJson(geoJson.features[0].geometry.coordinates)
|
mapRef.value?.showGeoJson(geoJson?.features?.[0]?.geometry?.coordinates)
|
||||||
if (edit) {
|
if (edit) {
|
||||||
mapRef.value?.openEdit()
|
mapRef.value?.openEdit()
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,9 @@
|
||||||
}}</Ellipsis>
|
}}</Ellipsis>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
||||||
@click="(e) => e.stopPropagation()"
|
@click="(e) => e.stopPropagation()"
|
||||||
v-if="item.id !== 'default_group'"
|
v-if="item.id !== 'default_group' && admin"
|
||||||
>
|
>
|
||||||
<PermissionButton
|
<PermissionButton
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -94,6 +95,7 @@ import {
|
||||||
import { randomString } from '@/utils/utils';
|
import { randomString } from '@/utils/utils';
|
||||||
import { useUserInfo } from '@/store/userInfo';
|
import { useUserInfo } from '@/store/userInfo';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
|
|
||||||
const emit = defineEmits(['selectData']);
|
const emit = defineEmits(['selectData']);
|
||||||
const userInfoStore = useUserInfo();
|
const userInfoStore = useUserInfo();
|
||||||
const { userInfos } = storeToRefs(userInfoStore);
|
const { userInfos } = storeToRefs(userInfoStore);
|
||||||
|
|
Loading…
Reference in New Issue