Merge branch 'dev' of github.com:jetlinks/jetlinks-ui-vue into dev
This commit is contained in:
commit
ff52a91888
|
@ -1,7 +1,7 @@
|
||||||
import server from '@/utils/request'
|
import server from '@/utils/request'
|
||||||
|
|
||||||
// 获取记录列表
|
// 获取记录列表
|
||||||
export const getList_api = (data:object): any =>server.get(`/notifications/_query`,encodeParams(data))
|
export const getList_api = (data:object): any =>server.post(`/notifications/_query`,data)
|
||||||
// 修改记录状态
|
// 修改记录状态
|
||||||
export const changeStatus_api = (type:'_read'|'_unread',data:string[]): any =>server.post(`/notifications/${type}`,data)
|
export const changeStatus_api = (type:'_read'|'_unread',data:string[]): any =>server.post(`/notifications/${type}`,data)
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,9 @@ export default {
|
||||||
// 删除
|
// 删除
|
||||||
del: (id: string) => server.remove(`/media/channel/${id}`),
|
del: (id: string) => server.remove(`/media/channel/${id}`),
|
||||||
|
|
||||||
|
// 查询树形数据
|
||||||
|
queryTree: (id: string, data?: any) => server.post(`/media/device/${id}/catalog/_query/tree`, data),
|
||||||
|
|
||||||
// ========== 视频播放 ==========
|
// ========== 视频播放 ==========
|
||||||
// 开始直播
|
// 开始直播
|
||||||
ptzStart: (deviceId: string, channelId: string, type: string) =>
|
ptzStart: (deviceId: string, channelId: string, type: string) =>
|
||||||
|
|
|
@ -77,6 +77,7 @@ const iconKeys = [
|
||||||
'CloudDownloadOutlined',
|
'CloudDownloadOutlined',
|
||||||
'PauseCircleOutlined',,
|
'PauseCircleOutlined',,
|
||||||
'FormOutlined',
|
'FormOutlined',
|
||||||
|
'EyeInvisibleOutlined',
|
||||||
]
|
]
|
||||||
|
|
||||||
const Icon = (props: {type: string}) => {
|
const Icon = (props: {type: string}) => {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<a-table :columns="columns" :data-source="property" :pagination="false" bordered size="small">
|
<a-table :columns="columns" :data-source="property" :pagination="false" bordered size="small">
|
||||||
<template #bodyCell="{ column, record, index }">
|
<template #bodyCell="{ column, record, index }">
|
||||||
<template v-if="column.key === 'id'">
|
<template v-if="column.key === 'id'">
|
||||||
<a-input v-model:value="record.id" size="small"></a-input>
|
<j-auto-complete :options="options" v-model:value="record.id" size="small" width="130px"/>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.key === 'current'">
|
<template v-if="column.key === 'current'">
|
||||||
<a-input v-model:value="record.current" size="small"></a-input>
|
<a-input v-model:value="record.current" size="small"></a-input>
|
||||||
|
@ -58,8 +58,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="log">
|
<div class="log">
|
||||||
<a-descriptions>
|
<a-descriptions>
|
||||||
<a-descriptions-item v-for="item in ruleEditorStore.state.log" :label="moment(item.time).format('HH:mm:ss')" :key="item.time"
|
<a-descriptions-item v-for="item in ruleEditorStore.state.log" :label="moment(item.time).format('HH:mm:ss')"
|
||||||
:span="3">
|
:key="item.time" :span="3">
|
||||||
<a-tooltip placement="top" :title="item.content">
|
<a-tooltip placement="top" :title="item.content">
|
||||||
{{ item.content }}
|
{{ item.content }}
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
|
@ -78,6 +78,7 @@ import { message } from 'ant-design-vue';
|
||||||
import { useRuleEditorStore } from '@/store/ruleEditor';
|
import { useRuleEditorStore } from '@/store/ruleEditor';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { getWebSocket } from '@/utils/websocket';
|
import { getWebSocket } from '@/utils/websocket';
|
||||||
|
import { PropertyMetadata } from '@/views/device/Product/typings';
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
@ -135,25 +136,25 @@ const runScript = () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (ws.value) {
|
if (ws.value) {
|
||||||
ws.value.unsubscribe();
|
ws.value.unsubscribe?.();
|
||||||
}
|
}
|
||||||
if (!props.virtualRule?.script) {
|
if (!props.virtualRule?.script) {
|
||||||
isBeginning.value = true;
|
isBeginning.value = true;
|
||||||
message.warning('请编辑规则');
|
message.warning('请编辑规则');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ws.value = getWebSocket(`virtual-property-debug-${ruleEditorStore.state.property}-${new Date().getTime()}`,
|
ws.value = getWebSocket(`virtual-property-debug-${props.id}-${new Date().getTime()}`,
|
||||||
'/virtual-property-debug',
|
'/virtual-property-debug',
|
||||||
{
|
{
|
||||||
virtualId: `${virtualIdRef.value}-virtual-id`,
|
virtualId: `${virtualIdRef.value}-virtual-id`,
|
||||||
property: ruleEditorStore.state.property,
|
property: props.id,
|
||||||
virtualRule: {
|
virtualRule: {
|
||||||
...props.virtualRule,
|
...props.virtualRule,
|
||||||
},
|
},
|
||||||
properties: _properties || [],
|
properties: _properties || [],
|
||||||
})
|
})
|
||||||
ws.value.subscribe((data: any) => {
|
ws.value.subscribe((data: any) => {
|
||||||
ruleEditorStore.state.log.push({ time: new Date().getTime(), content: JSON.stringify(data.payload) });
|
ruleEditorStore.state.log.push({ time: new Date().getTime(), content: JSON.stringify(data.payload) });
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const beginAction = () => {
|
const beginAction = () => {
|
||||||
|
@ -163,7 +164,7 @@ const beginAction = () => {
|
||||||
const stopAction = () => {
|
const stopAction = () => {
|
||||||
isBeginning.value = true;
|
isBeginning.value = true;
|
||||||
if (ws.value) {
|
if (ws.value) {
|
||||||
ws.value.unsubscribe();
|
ws.value.unsubscribe?.();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const clearAction = () => {
|
const clearAction = () => {
|
||||||
|
@ -172,9 +173,21 @@ const clearAction = () => {
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
if (ws.value) {
|
if (ws.value) {
|
||||||
ws.value.unsubscribe();
|
ws.value.unsubscribe?.();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const options = ref<{ label: string, value: string }[]>()
|
||||||
|
const getProperty = () => {
|
||||||
|
const metadata = productStore.current.metadata || '{}';
|
||||||
|
const _p: PropertyMetadata[] = JSON.parse(metadata).properties || [];
|
||||||
|
options.value = _p.filter((p) => p.id !== props.id).map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
console.log(options.value)
|
||||||
|
}
|
||||||
|
getProperty()
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.debug-container {
|
.debug-container {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<Editor key="simple" @change="change" v-model:value="_value" :id="id" />
|
<Editor key="simple" @change="change" v-model:value="_value" :id="id" />
|
||||||
{{ _value }}
|
|
||||||
<Advance v-if="ruleEditorStore.state.model === 'advance'" v-model:value="_value" :model="ruleEditorStore.state.model"
|
<Advance v-if="ruleEditorStore.state.model === 'advance'" v-model:value="_value" :model="ruleEditorStore.state.model"
|
||||||
:virtualRule="virtualRule" :id="id" @change="change" />
|
:virtualRule="virtualRule" :id="id" @change="change" />
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -26,7 +26,7 @@ import { notification } from 'ant-design-vue';
|
||||||
import { changeStatus_api } from '@/api/account/notificationRecord';
|
import { changeStatus_api } from '@/api/account/notificationRecord';
|
||||||
import { useUserInfo } from '@/store/userInfo';
|
import { useUserInfo } from '@/store/userInfo';
|
||||||
|
|
||||||
const updateCount = computed(()=>useUserInfo().$state.alarmUpdateCount);
|
const updateCount = computed(() => useUserInfo().$state.alarmUpdateCount);
|
||||||
|
|
||||||
const total = ref(0);
|
const total = ref(0);
|
||||||
const list = ref<any[]>([]);
|
const list = ref<any[]>([]);
|
||||||
|
@ -50,10 +50,20 @@ const subscribeNotice = () => {
|
||||||
const getList = () => {
|
const getList = () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const params = {
|
const params = {
|
||||||
'terms[0].column': 'state',
|
|
||||||
'terms[0].value': 'unread',
|
|
||||||
'sorts[0].name': 'notifyTime',
|
'sorts[0].name': 'notifyTime',
|
||||||
'sorts[0].order': 'desc',
|
'sorts[0].order': 'desc',
|
||||||
|
terms: [
|
||||||
|
{
|
||||||
|
terms: [
|
||||||
|
{
|
||||||
|
type: 'or',
|
||||||
|
value: 'unread',
|
||||||
|
termType: 'eq',
|
||||||
|
column: 'state',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
getList_api(params)
|
getList_api(params)
|
||||||
.then((resp: any) => {
|
.then((resp: any) => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<j-form-item :name="name.concat(['script'])">
|
<j-form-item :name="name.concat(['script'])">
|
||||||
<f-rule-editor v-model:value="value.script" :id="id"></f-rule-editor>
|
<f-rule-editor v-model:value="value.script" :id="id" :virtualRule="value"></f-rule-editor>
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
<template v-if="showWindow">
|
<template v-if="showWindow">
|
||||||
<j-form-item label="规则配置" :name="name.concat(['isVirtualRule'])">
|
<j-form-item label="规则配置" :name="name.concat(['isVirtualRule'])">
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
@ok="handleOk"
|
@ok="handleOk"
|
||||||
width="770px"
|
width="770px"
|
||||||
@cancel="emits('update:visible', false)"
|
@cancel="emits('update:visible', false)"
|
||||||
|
:confirmLoading="loading"
|
||||||
>
|
>
|
||||||
<j-form :model="form" layout="vertical" ref="formRef">
|
<j-form :model="form" layout="vertical" ref="formRef">
|
||||||
<j-row :gutter="24">
|
<j-row :gutter="24">
|
||||||
|
@ -12,7 +13,10 @@
|
||||||
<j-form-item
|
<j-form-item
|
||||||
label="姓名"
|
label="姓名"
|
||||||
name="name"
|
name="name"
|
||||||
:rules="[{ required: true, message: '姓名必填' }]"
|
:rules="[
|
||||||
|
{ required: true, message: '姓名必填' },
|
||||||
|
{ max: 64, message: '最多可输入64个字符' },
|
||||||
|
]"
|
||||||
>
|
>
|
||||||
<j-input
|
<j-input
|
||||||
v-model:value="form.name"
|
v-model:value="form.name"
|
||||||
|
@ -56,7 +60,16 @@
|
||||||
</j-row>
|
</j-row>
|
||||||
<j-row :gutter="24">
|
<j-row :gutter="24">
|
||||||
<j-col :span="12">
|
<j-col :span="12">
|
||||||
<j-form-item label="手机号">
|
<j-form-item
|
||||||
|
label="手机号"
|
||||||
|
name="telephone"
|
||||||
|
:rules="[
|
||||||
|
{
|
||||||
|
pattern: /^1[3456789]\d{9}$/,
|
||||||
|
message: '请输入正确手机号',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
<j-input
|
<j-input
|
||||||
v-model:value="form.telephone"
|
v-model:value="form.telephone"
|
||||||
placeholder="请输入手机号"
|
placeholder="请输入手机号"
|
||||||
|
@ -64,7 +77,11 @@
|
||||||
</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="邮箱"
|
||||||
|
name="email"
|
||||||
|
:rules="[{ type: 'email',message:'邮箱不是一个有效的email' }]"
|
||||||
|
>
|
||||||
<j-input
|
<j-input
|
||||||
v-model:value="form.email"
|
v-model:value="form.email"
|
||||||
placeholder="请输入邮箱"
|
placeholder="请输入邮箱"
|
||||||
|
@ -87,17 +104,19 @@ const props = defineProps<{
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
data: userInfoType;
|
data: userInfoType;
|
||||||
}>();
|
}>();
|
||||||
|
const loading = ref(false)
|
||||||
const form = ref(props.data);
|
const form = ref(props.data);
|
||||||
const formRef = ref<FormInstance>();
|
const formRef = ref<FormInstance>();
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
formRef.value?.validate().then(() => {
|
formRef.value?.validate().then(() => {
|
||||||
|
loading.value = true
|
||||||
updateMeInfo_api(form.value).then((resp) => {
|
updateMeInfo_api(form.value).then((resp) => {
|
||||||
if (resp.status === 200) {
|
if (resp.status === 200) {
|
||||||
message.success('保存成功');
|
message.success('保存成功');
|
||||||
emits('ok');
|
emits('ok');
|
||||||
emits('update:visible', false);
|
emits('update:visible', false);
|
||||||
}
|
}
|
||||||
});
|
}).finally(()=>loading.value = false)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
title="重置密码"
|
title="重置密码"
|
||||||
@ok="handleOk"
|
@ok="handleOk"
|
||||||
width="520px"
|
width="520px"
|
||||||
|
:confirmLoading="loading"
|
||||||
@cancel="emits('update:visible', false)"
|
@cancel="emits('update:visible', false)"
|
||||||
>
|
>
|
||||||
<j-form :model="form" layout="vertical" ref="formRef">
|
<j-form :model="form" layout="vertical" ref="formRef">
|
||||||
|
@ -11,7 +12,7 @@
|
||||||
label="旧密码"
|
label="旧密码"
|
||||||
name="oldPassword"
|
name="oldPassword"
|
||||||
:rules="[
|
:rules="[
|
||||||
{ required: true },
|
{ required: true, message: '请输入密码' },
|
||||||
{ validator: checkMothods.old, trigger: 'blur' },
|
{ validator: checkMothods.old, trigger: 'blur' },
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
|
@ -24,7 +25,7 @@
|
||||||
label="密码"
|
label="密码"
|
||||||
name="newPassword"
|
name="newPassword"
|
||||||
:rules="[
|
:rules="[
|
||||||
{ required: true },
|
{ required: true,message:'请输入密码' },
|
||||||
{ validator: checkMothods.new, trigger: 'blur' },
|
{ validator: checkMothods.new, trigger: 'blur' },
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
|
@ -37,7 +38,7 @@
|
||||||
label="确认密码"
|
label="确认密码"
|
||||||
name="confirmPassword"
|
name="confirmPassword"
|
||||||
:rules="[
|
:rules="[
|
||||||
{ required: true },
|
{ required: true, message: '请输入确认密码' },
|
||||||
{ validator: checkMothods.confirm, trigger: 'blur' },
|
{ validator: checkMothods.confirm, trigger: 'blur' },
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
|
@ -63,6 +64,7 @@ const emits = defineEmits(['ok', 'update:visible']);
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
const loading = ref(false)
|
||||||
const formRef = ref<FormInstance>();
|
const formRef = ref<FormInstance>();
|
||||||
const form = ref<formType>({
|
const form = ref<formType>({
|
||||||
oldPassword: '',
|
oldPassword: '',
|
||||||
|
@ -72,7 +74,7 @@ const form = ref<formType>({
|
||||||
|
|
||||||
const checkMothods = {
|
const checkMothods = {
|
||||||
old: async (_rule: Rule, value: string) => {
|
old: async (_rule: Rule, value: string) => {
|
||||||
if (!value) return Promise.reject('请输入密码');
|
if (!value) return Promise.reject();
|
||||||
try {
|
try {
|
||||||
const resp: any = await checkOldPassword_api(value);
|
const resp: any = await checkOldPassword_api(value);
|
||||||
if (resp.status === 200 && !resp.result.passed)
|
if (resp.status === 200 && !resp.result.passed)
|
||||||
|
@ -83,7 +85,7 @@ const checkMothods = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new: async (_rule: Rule, value: string) => {
|
new: async (_rule: Rule, value: string) => {
|
||||||
if (!value) return Promise.reject('请输入密码');
|
if (!value) return Promise.reject();
|
||||||
else if (
|
else if (
|
||||||
form.value.confirmPassword &&
|
form.value.confirmPassword &&
|
||||||
value !== form.value.confirmPassword
|
value !== form.value.confirmPassword
|
||||||
|
@ -99,7 +101,7 @@ const checkMothods = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
confirm: async (_rule: Rule, value: string) => {
|
confirm: async (_rule: Rule, value: string) => {
|
||||||
if (!value) return Promise.reject('请输入确认密码');
|
if (!value) return Promise.reject();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resp: any = await validateField_api('password', value);
|
const resp: any = await validateField_api('password', value);
|
||||||
|
@ -114,6 +116,7 @@ const checkMothods = {
|
||||||
|
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
formRef.value?.validate().then(() => {
|
formRef.value?.validate().then(() => {
|
||||||
|
loading.value = true
|
||||||
const params = {
|
const params = {
|
||||||
oldPassword: form.value.oldPassword,
|
oldPassword: form.value.oldPassword,
|
||||||
newPassword: form.value.newPassword,
|
newPassword: form.value.newPassword,
|
||||||
|
@ -124,7 +127,7 @@ const handleOk = () => {
|
||||||
emits('ok');
|
emits('ok');
|
||||||
emits('update:visible', false);
|
emits('update:visible', false);
|
||||||
}
|
}
|
||||||
});
|
}).finally(()=>loading.value = false)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
console.clear();
|
console.clear();
|
||||||
|
|
|
@ -8,10 +8,15 @@
|
||||||
style="width: 350px; justify-content: center"
|
style="width: 350px; justify-content: center"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
|
v-if="userInfo.avatar"
|
||||||
:src="userInfo.avatar"
|
:src="userInfo.avatar"
|
||||||
style="width: 140px; border-radius: 70px"
|
style="width: 140px; border-radius: 70px"
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
|
<div class="default-avatar" v-else>
|
||||||
|
<AIcon type="UserOutlined" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
style="
|
style="
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -29,6 +34,7 @@
|
||||||
}"
|
}"
|
||||||
:action="`${BASE_API_PATH}/file/static`"
|
:action="`${BASE_API_PATH}/file/static`"
|
||||||
@change="upload.changeBackUpload"
|
@change="upload.changeBackUpload"
|
||||||
|
:beforeUpload="upload.beforeUpload"
|
||||||
>
|
>
|
||||||
<j-button>
|
<j-button>
|
||||||
<AIcon type="UploadOutlined" />
|
<AIcon type="UploadOutlined" />
|
||||||
|
@ -51,11 +57,17 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="info-card">
|
<div class="info-card">
|
||||||
<p>注册时间</p>
|
<p>注册时间</p>
|
||||||
<p>{{ moment(userInfo.createTime).format('YYYY-MM-DD HH:mm:ss') }}</p>
|
<p>
|
||||||
|
{{
|
||||||
|
moment(userInfo.createTime).format(
|
||||||
|
'YYYY-MM-DD HH:mm:ss',
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-card">
|
<div class="info-card">
|
||||||
<p>电话</p>
|
<p>电话</p>
|
||||||
<p>{{ userInfo.telephone }}</p>
|
<p>{{ userInfo.telephone || '-' }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-card">
|
<div class="info-card">
|
||||||
<p>姓名</p>
|
<p>姓名</p>
|
||||||
|
@ -117,7 +129,7 @@
|
||||||
type="link"
|
type="link"
|
||||||
@click="editPasswordVisible = true"
|
@click="editPasswordVisible = true"
|
||||||
>
|
>
|
||||||
<AIcon type="EditOutlined" style="color: #1d39c4;" />
|
<AIcon type="EditOutlined" style="color: #1d39c4" />
|
||||||
</PermissionButton>
|
</PermissionButton>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -205,7 +217,7 @@
|
||||||
<EditInfoDialog
|
<EditInfoDialog
|
||||||
v-if="editInfoVisible"
|
v-if="editInfoVisible"
|
||||||
v-model:visible="editInfoVisible"
|
v-model:visible="editInfoVisible"
|
||||||
:data="{...userInfo}"
|
:data="{ ...userInfo }"
|
||||||
@ok="getUserInfo"
|
@ok="getUserInfo"
|
||||||
/>
|
/>
|
||||||
<EditPasswordDialog
|
<EditPasswordDialog
|
||||||
|
@ -277,6 +289,15 @@ const upload = reactive({
|
||||||
message.error('logo上传失败,请稍后再试');
|
message.error('logo上传失败,请稍后再试');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
beforeUpload: ({ size, type }: File) => {
|
||||||
|
const imageTypes = ['jpg', 'png', 'jfif', 'pjp', 'pjpeg', 'jpeg'];
|
||||||
|
const typeBool =
|
||||||
|
imageTypes.filter((typeStr) => type.includes(typeStr)).length > 0;
|
||||||
|
const sizeBool = size < 4 * 1024 * 1024;
|
||||||
|
|
||||||
|
(typeBool && sizeBool) || message.error('请上传正确格式的图片');
|
||||||
|
return typeBool && sizeBool;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
// 首页视图
|
// 首页视图
|
||||||
const isApiUser = ref<boolean>();
|
const isApiUser = ref<boolean>();
|
||||||
|
@ -346,7 +367,7 @@ function getViews() {
|
||||||
background-color: #f0f2f5;
|
background-color: #f0f2f5;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
.card {
|
.card {
|
||||||
margin: 24px;
|
margin: 16px 0;
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -370,6 +391,18 @@ function getViews() {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
.content-item {
|
.content-item {
|
||||||
margin-right: 24px;
|
margin-right: 24px;
|
||||||
|
|
||||||
|
.default-avatar {
|
||||||
|
background-color: #ccc;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
font-size: 70px;
|
||||||
|
width: 140px;
|
||||||
|
height: 140px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
.info-card {
|
.info-card {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<page-container>
|
<page-container>
|
||||||
<div class="notification-record-container">
|
<div class="notification-record-container">
|
||||||
<Search :columns="columns" @search="query.search" />
|
<j-advanced-search
|
||||||
|
:columns="columns"
|
||||||
|
@search="(params:any)=>queryParams = {...params}"
|
||||||
|
/>
|
||||||
|
|
||||||
<j-pro-table
|
<j-pro-table
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:request="getList_api"
|
:request="getList_api"
|
||||||
model="TABLE"
|
model="TABLE"
|
||||||
:params="query.params.value"
|
:params="queryParams"
|
||||||
:defaultParams="{
|
:defaultParams="{
|
||||||
'sorts[0].name': 'notifyTime',
|
'sorts[0].name': 'notifyTime',
|
||||||
'sorts[0].order': 'desc',
|
'sorts[0].order': 'desc',
|
||||||
|
@ -52,8 +55,8 @@
|
||||||
? '标为未读'
|
? '标为未读'
|
||||||
: '标为已读',
|
: '标为已读',
|
||||||
}"
|
}"
|
||||||
>1
|
>
|
||||||
<AIcon type="ReadIconOutlined" />
|
<AIcon type="icon-a-PIZHU1" />
|
||||||
</PermissionButton>
|
</PermissionButton>
|
||||||
<PermissionButton
|
<PermissionButton
|
||||||
type="link"
|
type="link"
|
||||||
|
@ -158,15 +161,10 @@ const columns = [
|
||||||
key: 'action',
|
key: 'action',
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
scopedSlots: true,
|
scopedSlots: true,
|
||||||
width:'200px'
|
width: '200px',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const query = {
|
const queryParams = ref({});
|
||||||
params: ref({}),
|
|
||||||
search: (params: object) => {
|
|
||||||
query.params.value = { ...params };
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
const table = {
|
const table = {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
visible
|
visible
|
||||||
:title="props.data.id ? '编辑' : '新增'"
|
:title="props.data.id ? '编辑' : '新增'"
|
||||||
width="865px"
|
width="865px"
|
||||||
|
:confirmLoading="loading"
|
||||||
@ok="confirm"
|
@ok="confirm"
|
||||||
@cancel="emits('update:visible', false)"
|
@cancel="emits('update:visible', false)"
|
||||||
>
|
>
|
||||||
|
@ -92,6 +93,7 @@ const props = defineProps<{
|
||||||
data: rowType;
|
data: rowType;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const loading = ref(false);
|
||||||
const initForm = {
|
const initForm = {
|
||||||
subscribeName: '',
|
subscribeName: '',
|
||||||
topicConfig: {},
|
topicConfig: {},
|
||||||
|
@ -106,13 +108,16 @@ const form = ref({
|
||||||
const confirm = () => {
|
const confirm = () => {
|
||||||
formRef.value &&
|
formRef.value &&
|
||||||
formRef.value.validate().then(() => {
|
formRef.value.validate().then(() => {
|
||||||
save_api(form.value).then((resp) => {
|
loading.value = true;
|
||||||
if (resp.status === 200) {
|
save_api(form.value)
|
||||||
message.success('操作成功');
|
.then((resp) => {
|
||||||
emits('ok')
|
if (resp.status === 200) {
|
||||||
emits('update:visible', false);
|
message.success('操作成功');
|
||||||
}
|
emits('ok');
|
||||||
});
|
emits('update:visible', false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => (loading.value = false));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<page-container>
|
<page-container>
|
||||||
<div class="notification-subscription-container">
|
<div class="notification-subscription-container">
|
||||||
<Search :columns="columns" @search="query.search" />
|
<j-advanced-search
|
||||||
|
:columns="columns"
|
||||||
|
@search="(params:any)=>queryParams = {...params}"
|
||||||
|
/>
|
||||||
<j-pro-table
|
<j-pro-table
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:request="getNoticeList_api"
|
:request="getNoticeList_api"
|
||||||
model="TABLE"
|
model="TABLE"
|
||||||
:params="query.params.value"
|
:params="queryParams"
|
||||||
:defaultParams="{
|
:defaultParams="{
|
||||||
sorts: [{ name: 'notifyTime', order: 'desc' }],
|
sorts: [{ name: 'notifyTime', order: 'desc' }],
|
||||||
}"
|
}"
|
||||||
|
@ -105,7 +108,7 @@ import EditDialog from './components/EditDialog.vue';
|
||||||
import {
|
import {
|
||||||
getNoticeList_api,
|
getNoticeList_api,
|
||||||
changeStatus_api,
|
changeStatus_api,
|
||||||
remove_api
|
remove_api,
|
||||||
} from '@/api/account/notificationSubscription';
|
} from '@/api/account/notificationSubscription';
|
||||||
import { rowType } from './typing';
|
import { rowType } from './typing';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
|
@ -147,19 +150,14 @@ const columns = [
|
||||||
key: 'action',
|
key: 'action',
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
scopedSlots: true,
|
scopedSlots: true,
|
||||||
width: '200px'
|
width: '200px',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const query = {
|
const queryParams = ref({});
|
||||||
params: ref({}),
|
|
||||||
search: (params: object) => {
|
|
||||||
query.params.value = {...params};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const dialogVisible = ref<boolean>(false);
|
const dialogVisible = ref<boolean>(false);
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
const table = {
|
const table = {
|
||||||
seletctRow: ref<rowType>(),
|
seletctRow: ref<any>({}),
|
||||||
edit: (row?: rowType) => {
|
edit: (row?: rowType) => {
|
||||||
table.seletctRow = {
|
table.seletctRow = {
|
||||||
...(row || ({} as any)),
|
...(row || ({} as any)),
|
||||||
|
@ -176,12 +174,12 @@ const table = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
delete: (row: rowType) => {
|
delete: (row: rowType) => {
|
||||||
remove_api(row.id as string).then(resp=>{
|
remove_api(row.id as string).then((resp) => {
|
||||||
if(resp.status === 200) {
|
if (resp.status === 200) {
|
||||||
message.success('操作成功!')
|
message.success('操作成功!');
|
||||||
table.refresh()
|
table.refresh();
|
||||||
}else message.warning('操作失败!')
|
} else message.warning('操作失败!');
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
refresh: () => {
|
refresh: () => {
|
||||||
tableRef.value && tableRef.value.reload();
|
tableRef.value && tableRef.value.reload();
|
||||||
|
|
|
@ -86,7 +86,7 @@ const metadataStore = useMetadataStore()
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (props.type === 'product' || !props.value?.source) {
|
if (props.type === 'product' || !props.value?.source) {
|
||||||
emit('update:value', { ...props.value, source: 'device' })
|
emit('update:value', { source: 'device', ...props.value })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<j-pro-table :loading="loading" :data-source="data" size="small" :columns="columns" row-key="id" model="TABLE">
|
<div class="table-header">
|
||||||
<template #headerTitle>
|
<div>
|
||||||
<j-input-search v-model:value="searchValue" placeholder="请输入名称" @search="handleSearch"></j-input-search>
|
<j-input-search v-model:value="searchValue" placeholder="请输入名称" @search="handleSearch"></j-input-search>
|
||||||
</template>
|
</div>
|
||||||
<template #rightExtraRender>
|
<div>
|
||||||
<PermissionButton type="primary" :uhas-permission="`${permission}:update`" key="add" @click="handleAddClick"
|
<PermissionButton type="primary" :uhas-permission="`${permission}:update`" key="add" @click="handleAddClick"
|
||||||
:disabled="operateLimits('add', type)" :tooltip="{
|
:disabled="operateLimits('add', type)" :tooltip="{
|
||||||
title: operateLimits('add', type) ? '当前的存储方式不支持新增' : '新增',
|
title: operateLimits('add', type) ? '当前的存储方式不支持新增' : '新增',
|
||||||
|
@ -14,45 +14,52 @@
|
||||||
新增
|
新增
|
||||||
</PermissionButton>
|
</PermissionButton>
|
||||||
<Edit v-if="metadataStore.model.edit" :type="target" :tabs="type" @refresh="refreshMetadata"></Edit>
|
<Edit v-if="metadataStore.model.edit" :type="target" :tabs="type" @refresh="refreshMetadata"></Edit>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a-table :loading="loading" :data-source="data" :columns="columns" row-key="id" model="TABLE" size="small"
|
||||||
|
:pagination="pagination">
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.dataIndex === 'level'">
|
||||||
|
{{ levelMap[record.expands?.level] || '-' }}
|
||||||
|
</template>
|
||||||
|
<template v-if="column.dataIndex === 'async'">
|
||||||
|
{{ record.async ? '是' : '否' }}
|
||||||
|
</template>
|
||||||
|
<template v-if="column.dataIndex === 'valueType'">
|
||||||
|
{{ record.valueType?.type }}
|
||||||
|
</template>
|
||||||
|
<template v-if="column.dataIndex === 'source'">
|
||||||
|
{{ sourceMap[record.expands?.source] }}
|
||||||
|
</template>
|
||||||
|
<template v-if="column.dataIndex === 'type'">
|
||||||
|
<j-tag v-for="item in (record.expands?.type || [])" :key="item">
|
||||||
|
{{ expandsType[item] }}
|
||||||
|
</j-tag>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.dataIndex === 'action'">
|
||||||
|
<j-space>
|
||||||
|
<PermissionButton :uhas-permission="`${permission}:update`" type="link" key="edit" style="padding: 0"
|
||||||
|
:udisabled="operateLimits('updata', type)" @click="handleEditClick(record)" :tooltip="{
|
||||||
|
title: operateLimits('updata', type) ? '当前的存储方式不支持编辑' : '编辑',
|
||||||
|
}">
|
||||||
|
<AIcon type="EditOutlined" />
|
||||||
|
</PermissionButton>
|
||||||
|
<PermissionButton :uhas-permission="`${permission}:delete`" type="link" key="delete" style="padding: 0"
|
||||||
|
:pop-confirm="{
|
||||||
|
title: '确认删除?', onConfirm: async () => {
|
||||||
|
await removeItem(record);
|
||||||
|
},
|
||||||
|
}"
|
||||||
|
:tooltip="{
|
||||||
|
title: '删除',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<AIcon type="DeleteOutlined" />
|
||||||
|
</PermissionButton>
|
||||||
|
</j-space>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<template #level="slotProps">
|
</a-table>
|
||||||
{{ levelMap[slotProps.expands?.level] || '-' }}
|
|
||||||
</template>
|
|
||||||
<template #async="slotProps">
|
|
||||||
{{ slotProps.async ? '是' : '否' }}
|
|
||||||
</template>
|
|
||||||
<template #valueType="slotProps">
|
|
||||||
{{ slotProps.valueType?.type }}
|
|
||||||
</template>
|
|
||||||
<template #source="slotProps">
|
|
||||||
{{ sourceMap[slotProps.expands?.source] }}
|
|
||||||
</template>
|
|
||||||
<template #type="slotProps">
|
|
||||||
<j-tag v-for="item in (slotProps.expands?.type || [])" :key="item">
|
|
||||||
{{ expandsType[item] }}
|
|
||||||
</j-tag>
|
|
||||||
</template>
|
|
||||||
<template #action="slotProps">
|
|
||||||
<j-space>
|
|
||||||
<PermissionButton :uhas-permission="`${permission}:update`" type="link" key="edit" style="padding: 0"
|
|
||||||
:udisabled="operateLimits('updata', type)" @click="handleEditClick(slotProps)" :tooltip="{
|
|
||||||
title: operateLimits('updata', type) ? '当前的存储方式不支持编辑' : '编辑',
|
|
||||||
}">
|
|
||||||
<AIcon type="EditOutlined" />
|
|
||||||
</PermissionButton>
|
|
||||||
<PermissionButton :uhas-permission="`${permission}:delete`" type="link" key="delete" style="padding: 0"
|
|
||||||
:pop-confirm="{
|
|
||||||
title: '确认删除?', onConfirm: async () => {
|
|
||||||
await removeItem(slotProps);
|
|
||||||
},
|
|
||||||
}" :tooltip="{
|
|
||||||
title: '删除',
|
|
||||||
}">
|
|
||||||
<Aicon type="DeleteOutlined" />
|
|
||||||
</PermissionButton>
|
|
||||||
</j-space>
|
|
||||||
</template>
|
|
||||||
</j-pro-table>
|
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts" name="BaseMetadata">
|
<script setup lang="ts" name="BaseMetadata">
|
||||||
import type { MetadataItem, MetadataType } from '@/views/device/Product/typings'
|
import type { MetadataItem, MetadataType } from '@/views/device/Product/typings'
|
||||||
|
@ -61,7 +68,7 @@ import { useInstanceStore } from '@/store/instance'
|
||||||
import { useProductStore } from '@/store/product'
|
import { useProductStore } from '@/store/product'
|
||||||
import { useMetadataStore } from '@/store/metadata'
|
import { useMetadataStore } from '@/store/metadata'
|
||||||
import PermissionButton from '@/components/PermissionButton/index.vue'
|
import PermissionButton from '@/components/PermissionButton/index.vue'
|
||||||
import { message } from 'ant-design-vue/es'
|
import { TablePaginationConfig, message } from 'ant-design-vue/es'
|
||||||
import { SystemConst } from '@/utils/consts'
|
import { SystemConst } from '@/utils/consts'
|
||||||
import { Store } from 'jetlinks-store'
|
import { Store } from 'jetlinks-store'
|
||||||
import { asyncUpdateMetadata, removeMetadata } from '../metadata'
|
import { asyncUpdateMetadata, removeMetadata } from '../metadata'
|
||||||
|
@ -106,6 +113,15 @@ const actions = [
|
||||||
scopedSlots: true,
|
scopedSlots: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
const pagination = {
|
||||||
|
showTotal: (num: number, range: number[]) => {
|
||||||
|
return `第 ${range[0]} - ${range[1]} 条/总共 ${num} 条`;
|
||||||
|
},
|
||||||
|
showSizeChanger: true,
|
||||||
|
showQuickJumper: false,
|
||||||
|
defaultPageSize: 10,
|
||||||
|
size: 'small',
|
||||||
|
} as TablePaginationConfig
|
||||||
const columns = computed(() => MetadataMapping.get(type)!.concat(actions))
|
const columns = computed(() => MetadataMapping.get(type)!.concat(actions))
|
||||||
const items = computed(() => JSON.parse((target === 'product' ? productStore.current?.metadata : instanceStore.current.metadata) || '{}') as MetadataItem[])
|
const items = computed(() => JSON.parse((target === 'product' ? productStore.current?.metadata : instanceStore.current.metadata) || '{}') as MetadataItem[])
|
||||||
const searchValue = ref<string>()
|
const searchValue = ref<string>()
|
||||||
|
@ -196,4 +212,10 @@ const removeItem = async (record: MetadataItem) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="less"></style>
|
<style scoped lang="less">
|
||||||
|
.table-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 16px 0;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -28,34 +28,19 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import { bootConfig } from "../typing";
|
import { bootConfig } from '../typing';
|
||||||
|
import { useMenuStore } from '@/store/menu';
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
cardData: Array<bootConfig>,
|
cardData: Array<bootConfig>,
|
||||||
cardTitle: String,
|
cardTitle: String,
|
||||||
});
|
});
|
||||||
const { cardData, cardTitle } = toRefs(props);
|
const { cardData, cardTitle } = toRefs(props);
|
||||||
|
const { jumpPage: _jumpPage } = useMenuStore();
|
||||||
|
|
||||||
const jumpPage = (row: bootConfig): void => {
|
const jumpPage = (item: bootConfig) => {
|
||||||
if (row.auth && row.link) {
|
if (item.auth === undefined || item.auth) _jumpPage(item.link, item.params);
|
||||||
router.push(`${row.link}${objToParams(row.params || {})}`);
|
else message.warning('暂无权限,请联系管理员');
|
||||||
} else {
|
|
||||||
message.warning('暂无权限,请联系管理员');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const objToParams = (source: object): string => {
|
|
||||||
if (Object.prototype.toString.call(source) === '[object Object]') {
|
|
||||||
const paramsArr = <any>[];
|
|
||||||
// 直接使用for in遍历对象ts会报错
|
|
||||||
Object.entries(source).forEach(([prop, value]) => {
|
|
||||||
if (typeof value === 'object') value = JSON.stringify(value);
|
|
||||||
paramsArr.push(`${prop}=${value}`);
|
|
||||||
});
|
|
||||||
if (paramsArr.length > 0) return '?' + paramsArr.join('&');
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
<ProductChooseDialog
|
<ProductChooseDialog
|
||||||
v-if="productDialogVisible"
|
v-if="productDialogVisible"
|
||||||
v-model:visible="productDialogVisible"
|
v-model:visible="productDialogVisible"
|
||||||
@confirm="(id:string)=>jumpPage('device/Product/Detail', { id })"
|
@confirm="(id:string)=>jumpPage('device/Product/Detail', { id, tab: 'Device'})"
|
||||||
/>
|
/>
|
||||||
<DeviceChooseDialog
|
<DeviceChooseDialog
|
||||||
v-if="deviceDialogVisible"
|
v-if="deviceDialogVisible"
|
||||||
|
@ -80,7 +80,7 @@ const deviceBootConfig: bootConfig[] = [
|
||||||
auth: productPermission('add'),
|
auth: productPermission('add'),
|
||||||
image: '/images/home/guide-home1.png',
|
image: '/images/home/guide-home1.png',
|
||||||
params: {
|
params: {
|
||||||
type: 'add',
|
save: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -100,7 +100,7 @@ const deviceBootConfig: bootConfig[] = [
|
||||||
auth: rulePermission('add'),
|
auth: rulePermission('add'),
|
||||||
image: '/images/home/guide-home3.png',
|
image: '/images/home/guide-home3.png',
|
||||||
params: {
|
params: {
|
||||||
type: 'add',
|
save: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -115,7 +115,7 @@ const deviceStepDetails: recommendList[] = [
|
||||||
linkUrl: 'device/Product',
|
linkUrl: 'device/Product',
|
||||||
auth: productPermission('add'),
|
auth: productPermission('add'),
|
||||||
params: {
|
params: {
|
||||||
type: 'add',
|
save: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -182,10 +182,7 @@ const opsBootConfig: bootConfig[] = [
|
||||||
{
|
{
|
||||||
english: 'STEP3',
|
english: 'STEP3',
|
||||||
label: '实时监控',
|
label: '实时监控',
|
||||||
link: 'link/Dashboard',
|
link: 'link/DashBoard',
|
||||||
params: {
|
|
||||||
save: true,
|
|
||||||
},
|
|
||||||
image: '/images/home/guide-home6.png',
|
image: '/images/home/guide-home6.png',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -230,4 +227,17 @@ const opsStepDetails: recommendList[] = [
|
||||||
|
|
||||||
const productDialogVisible = ref(false);
|
const productDialogVisible = ref(false);
|
||||||
const deviceDialogVisible = ref(false);
|
const deviceDialogVisible = ref(false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 设备管理-产品---新增弹窗 {save:true}
|
||||||
|
// 设备管理-产品-产品详情---设备接入标签页 {id: 'xxxx', tab:'xxx'}
|
||||||
|
// 规则引擎-规则编排---新增弹窗 {save: true}
|
||||||
|
|
||||||
|
|
||||||
|
// 设备管理-设备---新增弹窗
|
||||||
|
// 设备管理-设备---导入弹窗
|
||||||
|
// 设备管理-设备-设备详情---设备诊断标签页
|
||||||
|
|
||||||
|
// 运维管理-日志管理---系统日志标签页
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -32,12 +32,12 @@ const opsBootConfig: bootConfig[] = [
|
||||||
{
|
{
|
||||||
english: 'STEP1',
|
english: 'STEP1',
|
||||||
label: '设备接入配置',
|
label: '设备接入配置',
|
||||||
link: 'link/accessConfig',
|
link: 'link/AccessConfig',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
english: 'STEP2',
|
english: 'STEP2',
|
||||||
label: '日志排查',
|
label: '日志排查',
|
||||||
link: 'link/Log',
|
link: 'Log',
|
||||||
params: {
|
params: {
|
||||||
key: 'system',
|
key: 'system',
|
||||||
},
|
},
|
||||||
|
@ -45,7 +45,7 @@ const opsBootConfig: bootConfig[] = [
|
||||||
{
|
{
|
||||||
english: 'STEP3',
|
english: 'STEP3',
|
||||||
label: '实时监控',
|
label: '实时监控',
|
||||||
link: 'link/dashboard',
|
link: 'link/DashBoard',
|
||||||
params: {
|
params: {
|
||||||
type: 'add',
|
type: 'add',
|
||||||
},
|
},
|
||||||
|
|
|
@ -26,13 +26,19 @@ const { jumpPage } = useMenuStore();
|
||||||
const projectNum = ref(0);
|
const projectNum = ref(0);
|
||||||
const deviceNum = ref(0);
|
const deviceNum = ref(0);
|
||||||
|
|
||||||
|
const menuPermission = useMenuStore().hasPermission;
|
||||||
const getData = () => {
|
const getData = () => {
|
||||||
getDeviceCount_api().then((resp: any) => {
|
// 有产品菜单权限则获取数据
|
||||||
deviceNum.value = resp.result;
|
menuPermission('device/Product') &&
|
||||||
});
|
getDeviceCount_api().then((resp: any) => {
|
||||||
getProductCount_api({}).then((resp: any) => {
|
deviceNum.value = resp.result;
|
||||||
projectNum.value = resp.result;
|
});
|
||||||
});
|
|
||||||
|
// 有设备菜单权限则获取数据
|
||||||
|
menuPermission('device/Instance') &&
|
||||||
|
getProductCount_api({}).then((resp: any) => {
|
||||||
|
projectNum.value = resp.result;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
getData();
|
getData();
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<ProductChooseDialog
|
<ProductChooseDialog
|
||||||
v-if="productDialogVisible"
|
v-if="productDialogVisible"
|
||||||
v-model:visible="productDialogVisible"
|
v-model:visible="productDialogVisible"
|
||||||
@confirm="(id:string)=>jumpPage('device/Product/Detail', { id })"
|
@confirm="(id:string)=>jumpPage('device/Product/Detail', { id, tab: 'Device'})"
|
||||||
/>
|
/>
|
||||||
<DeviceChooseDialog
|
<DeviceChooseDialog
|
||||||
v-if="deviceDialogVisible"
|
v-if="deviceDialogVisible"
|
||||||
|
@ -67,7 +67,7 @@ const deviceBootConfig: bootConfig[] = [
|
||||||
link: 'device/Product',
|
link: 'device/Product',
|
||||||
auth: productPermission('add'),
|
auth: productPermission('add'),
|
||||||
params: {
|
params: {
|
||||||
type: 'add',
|
save: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -85,7 +85,7 @@ const deviceBootConfig: bootConfig[] = [
|
||||||
link: 'rule-engine/Instance',
|
link: 'rule-engine/Instance',
|
||||||
auth: rulePermission('add'),
|
auth: rulePermission('add'),
|
||||||
params: {
|
params: {
|
||||||
type: 'add',
|
save: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -98,7 +98,7 @@ const deviceStepDetails: recommendList[] = [
|
||||||
linkUrl: 'device/Product',
|
linkUrl: 'device/Product',
|
||||||
auth: productPermission('add'),
|
auth: productPermission('add'),
|
||||||
params: {
|
params: {
|
||||||
type: 'add',
|
save: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,12 +17,22 @@
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h3 style="margin: 0 0 24px 0">基本信息</h3>
|
<h3 style="margin: 0 0 24px 0">基本信息</h3>
|
||||||
<p>
|
<p>
|
||||||
<span style="font-weight: bold">clientId: </span>
|
<span class="label">clientId: </span>
|
||||||
<span>{{ clientId }}</span>
|
<span class="value">{{ clientId }}</span>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<span style="font-weight: bold">secureKey:</span>
|
<span class="label">secureKey:</span>
|
||||||
<span>{{ secureKey }}</span>
|
<span class="value">
|
||||||
|
{{ showKey ? secureKey : '****************' }}
|
||||||
|
</span>
|
||||||
|
<AIcon
|
||||||
|
:type="
|
||||||
|
showKey
|
||||||
|
? 'EyeOutlined'
|
||||||
|
: 'EyeInvisibleOutlined'
|
||||||
|
"
|
||||||
|
@click="showKey = !showKey"
|
||||||
|
/>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -47,14 +57,15 @@ const currentView = ref<string>('');
|
||||||
const loading = ref<boolean>(true);
|
const loading = ref<boolean>(true);
|
||||||
const clientId = useUserInfo().$state.userInfos.id;
|
const clientId = useUserInfo().$state.userInfos.id;
|
||||||
const secureKey = ref<string>('');
|
const secureKey = ref<string>('');
|
||||||
|
const showKey = ref(false);
|
||||||
// 获取选择的视图
|
// 获取选择的视图
|
||||||
const setCurrentView = () => {
|
const setCurrentView = () => {
|
||||||
getView_api().then((resp: any) => {
|
getView_api().then((resp: any) => {
|
||||||
if (resp.status === 200) {
|
if (resp.status === 200) {
|
||||||
if (resp.result) currentView.value = resp.result?.content;
|
if (resp.result) {
|
||||||
else if (resp.result.username === 'admin') {
|
if (resp.result.username === 'admin')
|
||||||
currentView.value = 'comprehensive';
|
currentView.value = 'comprehensive';
|
||||||
|
else currentView.value = resp.result?.content;
|
||||||
} else currentView.value = 'init';
|
} else currentView.value = 'init';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -90,6 +101,15 @@ if (isNoCommunity) {
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 3px;
|
||||||
|
}
|
||||||
|
.value {
|
||||||
|
margin-right: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
<template>
|
||||||
|
<div class="channel-tree">
|
||||||
|
<div class="channel-tree-query">
|
||||||
|
<j-input @change="queryTree" placeholder="请输入目录名称">
|
||||||
|
<template #suffix>
|
||||||
|
<AIcon type="SearchOutlined" />
|
||||||
|
</template>
|
||||||
|
</j-input>
|
||||||
|
</div>
|
||||||
|
<div class="channel-tree-content">
|
||||||
|
<j-tree
|
||||||
|
:height="500"
|
||||||
|
:selectedKeys="selectedKeys"
|
||||||
|
:treeData="treeData"
|
||||||
|
:onSelect="(keys:any) => {
|
||||||
|
if (keys.length) {
|
||||||
|
selectedKeys = keys
|
||||||
|
if (props.onSelect) {
|
||||||
|
props.onSelect(keys[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
:fieldNames="{ key: 'id', title: 'name' }"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { debounce } from 'lodash';
|
||||||
|
import ChannelApi from '@/api/media/channel';
|
||||||
|
import DeviceApi from '@/api/media/device';
|
||||||
|
|
||||||
|
interface TreeProps {
|
||||||
|
deviceId: string;
|
||||||
|
onSelect: (id: string) => void;
|
||||||
|
onTreeLoad: (type: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<TreeProps>();
|
||||||
|
|
||||||
|
const treeData = ref<any[]>([]);
|
||||||
|
const selectedKeys = ref<string[]>([]);
|
||||||
|
|
||||||
|
const getTreeData = async (id: string, data?: any) => {
|
||||||
|
const { result } = await ChannelApi.queryTree(id, data);
|
||||||
|
treeData.value[0].children = result || [];
|
||||||
|
props.onTreeLoad(treeData.value[0].children.length > 10);
|
||||||
|
treeData.value = treeData.value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取设备详情
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
const getDeviceDetail = async (id: string) => {
|
||||||
|
const deviceResp = await DeviceApi.detail(id);
|
||||||
|
if (deviceResp.status === 200) {
|
||||||
|
treeData.value = [
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
name: deviceResp.result.name,
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
selectedKeys.value = [id];
|
||||||
|
getTreeData(props.deviceId, {});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const queryTree = debounce((e: any) => {
|
||||||
|
getTreeData(props.deviceId, {
|
||||||
|
terms: [
|
||||||
|
{ column: 'name', termType: 'like', value: `%${e.target.value}%` },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
getDeviceDetail(props.deviceId);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.channel-tree {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.channel-tree-query {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.channel-tree-content {
|
||||||
|
min-height: calc(100% - 50px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,48 @@
|
||||||
|
.device-channel-warp {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.left-warp {
|
||||||
|
position: relative;
|
||||||
|
margin-right: 16px;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
.left-content {
|
||||||
|
width: 0;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
width: 260px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-warp--btn {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 0;
|
||||||
|
padding: 20px 4px;
|
||||||
|
color: rgba(#000, 0.3);
|
||||||
|
background-color: rgba(#f0f0f0, 6);
|
||||||
|
border-radius: ~'100% 0 0 100% / 50% 0 0 50%';
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: rgba(#000, 0.5);
|
||||||
|
background-color: rgba(#f0f0f0, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
right: 50%;
|
||||||
|
background-color: transparent;
|
||||||
|
border-radius: 0;
|
||||||
|
transform: translateX(50%) rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,82 +1,102 @@
|
||||||
<!-- 视频设备-通道列表 -->
|
<!-- 视频设备-通道列表 -->
|
||||||
<template>
|
<template>
|
||||||
<page-container>
|
<page-container>
|
||||||
<j-advanced-search
|
<div class="device-channel-warp">
|
||||||
type="simple"
|
<div class="left-warp" v-if="route.query.type === 'gb28181-2016'">
|
||||||
:columns="columns"
|
<div class="left-content" :class="{ active: show }">
|
||||||
target="product"
|
<Tree
|
||||||
@search="handleSearch"
|
:deviceId="deviceId"
|
||||||
/>
|
:on-tree-load="(e) => (show = e)"
|
||||||
|
:on-select="handleSelect"
|
||||||
<JProTable
|
/>
|
||||||
ref="listRef"
|
</div>
|
||||||
:columns="columns"
|
<div
|
||||||
:request="(e:any) => ChannelApi.list(e, route?.query.id as string)"
|
class="left-warp--btn"
|
||||||
:defaultParams="{
|
:class="{ active: !show }"
|
||||||
sorts: [{ name: 'notifyTime', order: 'desc' }],
|
@click="show = !show"
|
||||||
}"
|
|
||||||
:params="params"
|
|
||||||
model="table"
|
|
||||||
>
|
|
||||||
<template #headerTitle>
|
|
||||||
<j-tooltip
|
|
||||||
v-if="route?.query.type === 'gb28181-2016'"
|
|
||||||
title="接入方式为GB/T28281时,不支持新增"
|
|
||||||
>
|
>
|
||||||
<j-button type="primary" disabled> 新增 </j-button>
|
<AIcon type="LeftOutlined" />
|
||||||
</j-tooltip>
|
</div>
|
||||||
<j-button type="primary" @click="handleAdd" v-else>
|
</div>
|
||||||
新增
|
<div class="right">
|
||||||
</j-button>
|
<j-advanced-search
|
||||||
</template>
|
type="simple"
|
||||||
<template #status="slotProps">
|
:columns="columns"
|
||||||
<j-space>
|
target="product"
|
||||||
<j-badge
|
@search="handleSearch"
|
||||||
:status="
|
/>
|
||||||
slotProps.status.value === 'online'
|
|
||||||
? 'success'
|
<JProTable
|
||||||
: 'error'
|
ref="listRef"
|
||||||
"
|
:columns="columns"
|
||||||
:text="slotProps.status.text"
|
:request="(e:any) => ChannelApi.list(e, route?.query.id as string)"
|
||||||
></j-badge>
|
:defaultParams="{
|
||||||
</j-space>
|
sorts: [{ name: 'notifyTime', order: 'desc' }],
|
||||||
</template>
|
}"
|
||||||
<template #action="slotProps">
|
:params="params"
|
||||||
<j-space :size="16">
|
model="table"
|
||||||
<j-tooltip
|
>
|
||||||
v-for="i in getActions(slotProps, 'table')"
|
<template #headerTitle>
|
||||||
:key="i.key"
|
<j-tooltip
|
||||||
v-bind="i.tooltip"
|
v-if="route?.query.type === 'gb28181-2016'"
|
||||||
>
|
title="接入方式为GB/T28281时,不支持新增"
|
||||||
<j-popconfirm
|
|
||||||
v-if="i.popConfirm"
|
|
||||||
v-bind="i.popConfirm"
|
|
||||||
:disabled="i.disabled"
|
|
||||||
>
|
>
|
||||||
<j-button
|
<j-button type="primary" disabled> 新增 </j-button>
|
||||||
:disabled="i.disabled"
|
</j-tooltip>
|
||||||
style="padding: 0"
|
<j-button type="primary" @click="handleAdd" v-else>
|
||||||
type="link"
|
新增
|
||||||
><AIcon :type="i.icon"
|
|
||||||
/></j-button>
|
|
||||||
</j-popconfirm>
|
|
||||||
<j-button
|
|
||||||
style="padding: 0"
|
|
||||||
type="link"
|
|
||||||
v-else
|
|
||||||
@click="i.onClick && i.onClick(slotProps)"
|
|
||||||
>
|
|
||||||
<j-button
|
|
||||||
:disabled="i.disabled"
|
|
||||||
style="padding: 0"
|
|
||||||
type="link"
|
|
||||||
><AIcon :type="i.icon"
|
|
||||||
/></j-button>
|
|
||||||
</j-button>
|
</j-button>
|
||||||
</j-tooltip>
|
</template>
|
||||||
</j-space>
|
<template #status="slotProps">
|
||||||
</template>
|
<j-space>
|
||||||
</JProTable>
|
<j-badge
|
||||||
|
:status="
|
||||||
|
slotProps.status.value === 'online'
|
||||||
|
? 'success'
|
||||||
|
: 'error'
|
||||||
|
"
|
||||||
|
:text="slotProps.status.text"
|
||||||
|
></j-badge>
|
||||||
|
</j-space>
|
||||||
|
</template>
|
||||||
|
<template #action="slotProps">
|
||||||
|
<j-space :size="16">
|
||||||
|
<j-tooltip
|
||||||
|
v-for="i in getActions(slotProps, 'table')"
|
||||||
|
:key="i.key"
|
||||||
|
v-bind="i.tooltip"
|
||||||
|
>
|
||||||
|
<j-popconfirm
|
||||||
|
v-if="i.popConfirm"
|
||||||
|
v-bind="i.popConfirm"
|
||||||
|
:disabled="i.disabled"
|
||||||
|
>
|
||||||
|
<j-button
|
||||||
|
:disabled="i.disabled"
|
||||||
|
style="padding: 0"
|
||||||
|
type="link"
|
||||||
|
><AIcon :type="i.icon"
|
||||||
|
/></j-button>
|
||||||
|
</j-popconfirm>
|
||||||
|
<j-button
|
||||||
|
style="padding: 0"
|
||||||
|
type="link"
|
||||||
|
v-else
|
||||||
|
@click="i.onClick && i.onClick(slotProps)"
|
||||||
|
>
|
||||||
|
<j-button
|
||||||
|
:disabled="i.disabled"
|
||||||
|
style="padding: 0"
|
||||||
|
type="link"
|
||||||
|
><AIcon :type="i.icon"
|
||||||
|
/></j-button>
|
||||||
|
</j-button>
|
||||||
|
</j-tooltip>
|
||||||
|
</j-space>
|
||||||
|
</template>
|
||||||
|
</JProTable>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Save
|
<Save
|
||||||
v-model:visible="saveVis"
|
v-model:visible="saveVis"
|
||||||
|
@ -94,7 +114,9 @@ import { useMenuStore } from 'store/menu';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import Save from './Save.vue';
|
import Save from './Save.vue';
|
||||||
import Live from './Live/index.vue';
|
import Live from './Live/index.vue';
|
||||||
|
import Tree from './Tree/index.vue';
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
|
import { useElementSize } from '@vueuse/core';
|
||||||
|
|
||||||
const menuStory = useMenuStore();
|
const menuStory = useMenuStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
@ -253,4 +275,25 @@ const getActions = (
|
||||||
? actions.filter((f) => f.key !== 'delete')
|
? actions.filter((f) => f.key !== 'delete')
|
||||||
: actions;
|
: actions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 左侧树
|
||||||
|
const show = ref(false);
|
||||||
|
const deviceId = computed(() => route.query.id as string);
|
||||||
|
const handleSelect = (key: string) => {
|
||||||
|
if (key === deviceId.value && listRef.value?.reload) {
|
||||||
|
listRef.value?.reload();
|
||||||
|
} else {
|
||||||
|
params.value = {
|
||||||
|
terms: [
|
||||||
|
{
|
||||||
|
column: 'parentId',
|
||||||
|
value: key,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
@import './index.less';
|
||||||
|
</style>
|
||||||
|
|
|
@ -84,14 +84,16 @@
|
||||||
?.addresses"
|
?.addresses"
|
||||||
:key="`${i.address}_address${idx}`"
|
:key="`${i.address}_address${idx}`"
|
||||||
>
|
>
|
||||||
<j-badge
|
<Ellipsis>
|
||||||
:text="i.address"
|
<j-badge
|
||||||
:color="
|
:text="i.address"
|
||||||
i.health === -1
|
:color="
|
||||||
? 'red'
|
i.health === -1
|
||||||
: 'green'
|
? 'red'
|
||||||
"
|
: 'green'
|
||||||
/>
|
"
|
||||||
|
/>
|
||||||
|
</Ellipsis>
|
||||||
</p>
|
</p>
|
||||||
</j-col>
|
</j-col>
|
||||||
</j-row>
|
</j-row>
|
||||||
|
@ -263,6 +265,7 @@ const handleCancel = () => {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
.gateway-item {
|
.gateway-item {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
|
text-align: left;
|
||||||
.card-item-content-title,
|
.card-item-content-title,
|
||||||
.desc,
|
.desc,
|
||||||
.subtitle {
|
.subtitle {
|
||||||
|
|
|
@ -257,9 +257,7 @@ const columns = [
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
const handleSearch = (e: any) => {
|
const handleSearch = (e: any) => {
|
||||||
console.log('handleSearch:', e);
|
|
||||||
params.value = e;
|
params.value = e;
|
||||||
console.log('params.value: ', params.value);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,18 +1,35 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<Action :thenOptions="data.branches ? data?.branches[0].then : []" :name="0" />
|
<Action
|
||||||
|
:thenOptions="data.branches ? data?.branches[0].then : []"
|
||||||
|
:name="0"
|
||||||
|
@add="onActionAdd"
|
||||||
|
@update="onActionUpdate"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useSceneStore } from '@/store/scene'
|
import { useSceneStore } from '@/store/scene';
|
||||||
import Action from '../action/index.vue'
|
import Action from '../action/index.vue';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { ActionsType } from '@/components/Table';
|
||||||
|
|
||||||
const sceneStore = useSceneStore()
|
const sceneStore = useSceneStore();
|
||||||
const { data } = storeToRefs(sceneStore)
|
const { data } = storeToRefs(sceneStore);
|
||||||
|
|
||||||
|
const onActionAdd = (_data: ActionsType) => {
|
||||||
|
console.log(_data)
|
||||||
|
// if (data?.branches && _data) {
|
||||||
|
// const newThen = [...data?.branches?.[0].then, data];
|
||||||
|
// data.branches[0].then = newThen;
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
const onActionUpdate = (_data: ActionsType, type: boolean) => {
|
||||||
|
console.log(_data, type)
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
||||||
</style>
|
</style>
|
|
@ -8,12 +8,20 @@
|
||||||
>
|
>
|
||||||
<template #bodyCell="{ column, text, record }">
|
<template #bodyCell="{ column, text, record }">
|
||||||
<div>
|
<div>
|
||||||
<template v-if="['valueType', 'name'].includes(column.dataIndex)">
|
<template
|
||||||
|
v-if="['valueType', 'name'].includes(column.dataIndex)"
|
||||||
|
>
|
||||||
<span>{{ text }}</span>
|
<span>{{ text }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<j-input />
|
<ParamsDropdown
|
||||||
<!-- TODO -->
|
icon="icon-canshu"
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="[]"
|
||||||
|
:tabsOptions="tabOptions"
|
||||||
|
:metricOption="upperOptions(record.valueType)"
|
||||||
|
v-model:value="record.value"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -21,7 +29,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { PropType } from "vue";
|
import { PropType } from 'vue';
|
||||||
|
import ParamsDropdown from '../../../components/ParamsDropdown';
|
||||||
|
|
||||||
type Emits = {
|
type Emits = {
|
||||||
(e: 'update:modelValue', data: Record<string, any>[]): void;
|
(e: 'update:modelValue', data: Record<string, any>[]): void;
|
||||||
|
@ -31,9 +40,27 @@ const _emit = defineEmits<Emits>();
|
||||||
const _props = defineProps({
|
const _props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Array as PropType<Record<string, any>[]>,
|
type: Array as PropType<Record<string, any>[]>,
|
||||||
default: '',
|
default: () => undefined,
|
||||||
}
|
},
|
||||||
|
builtInList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const tabOptions = [
|
||||||
|
{
|
||||||
|
label: '手动输入',
|
||||||
|
component: 'string',
|
||||||
|
key: 'fixed',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '内置参数',
|
||||||
|
component: 'tree',
|
||||||
|
key: 'upper',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '参数名称',
|
title: '参数名称',
|
||||||
|
@ -54,11 +81,31 @@ const columns = [
|
||||||
|
|
||||||
const dataSource = computed({
|
const dataSource = computed({
|
||||||
get: () => {
|
get: () => {
|
||||||
return _props.modelValue || []
|
return _props.modelValue || [];
|
||||||
},
|
},
|
||||||
set: (val: any) => {
|
set: (val: any) => {
|
||||||
_emit('update:modelValue', val);
|
_emit('update:modelValue', val);
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
|
const filterParamsData = (type?: string, data?: any[]): any[] => {
|
||||||
|
if (type && data) {
|
||||||
|
return data.filter((item) => {
|
||||||
|
if (item.children) {
|
||||||
|
const _children = filterParamsData(type, item.children);
|
||||||
|
item.children = _children;
|
||||||
|
return _children.length ? true : false;
|
||||||
|
} else if (item.type === type) {
|
||||||
|
// optionMap.current.set(item.id, item);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return data || [];
|
||||||
|
};
|
||||||
|
|
||||||
|
const upperOptions = (_type: string) => {
|
||||||
|
return filterParamsData(_type, _props?.builtInList) || [];
|
||||||
|
};
|
||||||
</script>
|
</script>
|
|
@ -0,0 +1,140 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-form :layout="'vertical'" ref="formRef" :model="modelRef">
|
||||||
|
<j-row>
|
||||||
|
<j-col :span="11">
|
||||||
|
<j-form-item
|
||||||
|
:name="['message', 'properties']"
|
||||||
|
label="读取属性"
|
||||||
|
:rules="[{ required: true, message: '请选择读取属性' }]"
|
||||||
|
>
|
||||||
|
<j-select
|
||||||
|
showSearch
|
||||||
|
placeholder="请选择属性"
|
||||||
|
v-model:value="modelRef.properties"
|
||||||
|
>
|
||||||
|
<j-select-option
|
||||||
|
v-for="item in metadata?.properties || []"
|
||||||
|
:value="item?.id"
|
||||||
|
:key="item?.id"
|
||||||
|
>{{ item?.name }}</j-select-option
|
||||||
|
>
|
||||||
|
</j-select>
|
||||||
|
</j-form-item>
|
||||||
|
</j-col>
|
||||||
|
<j-col :span="2"></j-col>
|
||||||
|
<j-col :span="11">
|
||||||
|
<j-form-item
|
||||||
|
:name="['message', 'propertiesValue']"
|
||||||
|
label="属性值"
|
||||||
|
:rules="[{ required: true, message: '请选择' }]"
|
||||||
|
>
|
||||||
|
<ParamsDropdown
|
||||||
|
icon="icon-canshu"
|
||||||
|
placeholder="请选择"
|
||||||
|
:options="[]"
|
||||||
|
:tabsOptions="tabOptions"
|
||||||
|
:metricOption="upperOptions(getType)"
|
||||||
|
v-model:value="modelRef.propertiesValue"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</j-col>
|
||||||
|
</j-row>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
const props = defineProps({
|
||||||
|
value: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
properties: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
builtInList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
|
||||||
|
const modelRef = reactive({
|
||||||
|
properties: '',
|
||||||
|
propertiesValue: '',
|
||||||
|
source: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const tabOptions = [
|
||||||
|
{
|
||||||
|
label: '手动输入',
|
||||||
|
component: 'string',
|
||||||
|
key: 'fixed',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '内置参数',
|
||||||
|
component: 'tree',
|
||||||
|
key: 'upper',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const getType = computed(() => {
|
||||||
|
return props.metadata.properties.find((item: any) => item.id === modelRef.properties)?.valueType?.type
|
||||||
|
})
|
||||||
|
|
||||||
|
const filterParamsData = (type?: string, data?: any[]): any[] => {
|
||||||
|
if (type && data) {
|
||||||
|
return data.filter((item) => {
|
||||||
|
if (item.children) {
|
||||||
|
const _children = filterParamsData(type, item.children);
|
||||||
|
item.children = _children;
|
||||||
|
return _children.length ? true : false;
|
||||||
|
} else if (item.type === type) {
|
||||||
|
// optionMap.current.set(item.id, item);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return data || [];
|
||||||
|
};
|
||||||
|
|
||||||
|
const upperOptions = (type: string) => {
|
||||||
|
return filterParamsData(type, props?.builtInList) || []
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.value,
|
||||||
|
(newVal) => {
|
||||||
|
const _keys = Object.keys(newVal)?.[0];
|
||||||
|
if (_keys) {
|
||||||
|
(modelRef.properties = _keys),
|
||||||
|
(modelRef.propertiesValue = newVal[_keys]?.value);
|
||||||
|
modelRef.source = newVal[_keys]?.source;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
const onFormSave = () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
formRef.value
|
||||||
|
.validate()
|
||||||
|
.then(async (_data: any) => {
|
||||||
|
// 处理回传数据
|
||||||
|
resolve(_data);
|
||||||
|
})
|
||||||
|
.catch((err: any) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({ onFormSave });
|
||||||
|
</script>
|
|
@ -9,6 +9,7 @@
|
||||||
<TopCard
|
<TopCard
|
||||||
:typeList="TypeList"
|
:typeList="TypeList"
|
||||||
v-model:value="modelRef.message.messageType"
|
v-model:value="modelRef.message.messageType"
|
||||||
|
@change="onMessageTypeChange"
|
||||||
/>
|
/>
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
<template v-if="deviceMessageType === 'INVOKE_FUNCTION'">
|
<template v-if="deviceMessageType === 'INVOKE_FUNCTION'">
|
||||||
|
@ -21,7 +22,7 @@
|
||||||
showSearch
|
showSearch
|
||||||
placeholder="请选择功能"
|
placeholder="请选择功能"
|
||||||
v-model:value="modelRef.message.functionId"
|
v-model:value="modelRef.message.functionId"
|
||||||
@change="onFunctionChange"
|
@change="(val) => onFunctionChange(val, [])"
|
||||||
>
|
>
|
||||||
<j-select-option
|
<j-select-option
|
||||||
v-for="item in metadata?.functions || []"
|
v-for="item in metadata?.functions || []"
|
||||||
|
@ -36,7 +37,7 @@
|
||||||
:name="['message', 'inputs']"
|
:name="['message', 'inputs']"
|
||||||
:rules="[{ required: true, message: '请输入功能值' }]"
|
:rules="[{ required: true, message: '请输入功能值' }]"
|
||||||
>
|
>
|
||||||
<EditTable v-model="modelRef.message.inputs" />
|
<EditTable v-model:modelValue="modelRef.message.inputs" :builtInList="builtInList" />
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="deviceMessageType === 'READ_PROPERTY'">
|
<template v-else-if="deviceMessageType === 'READ_PROPERTY'">
|
||||||
|
@ -60,44 +61,11 @@
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="deviceMessageType === 'WRITE_PROPERTY'">
|
<template v-else-if="deviceMessageType === 'WRITE_PROPERTY'">
|
||||||
<j-row>
|
<WriteProperty
|
||||||
<j-col :span="11">
|
v-model:value="modelRef.message.properties"
|
||||||
<j-form-item
|
:metadata="metadata"
|
||||||
:name="['message', 'properties']"
|
:builtInList="builtInList"
|
||||||
label="读取属性"
|
/>
|
||||||
:rules="[
|
|
||||||
{ required: true, message: '请选择读取属性' },
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<j-select
|
|
||||||
showSearch
|
|
||||||
placeholder="请选择属性"
|
|
||||||
v-model:value="modelRef.message.properties"
|
|
||||||
>
|
|
||||||
<j-select-option
|
|
||||||
v-for="item in metadata?.properties || []"
|
|
||||||
:value="item?.id"
|
|
||||||
:key="item?.id"
|
|
||||||
>{{ item?.name }}</j-select-option
|
|
||||||
>
|
|
||||||
</j-select>
|
|
||||||
</j-form-item>
|
|
||||||
</j-col>
|
|
||||||
<j-col :span="2"></j-col>
|
|
||||||
<j-col :span="11">
|
|
||||||
<j-form-item
|
|
||||||
:name="['message', 'properties']"
|
|
||||||
label="读取属性"
|
|
||||||
:rules="[
|
|
||||||
{ required: true, message: '请选择读取属性' },
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<j-select placeholder="请选择">
|
|
||||||
<!-- TODO -->
|
|
||||||
</j-select>
|
|
||||||
</j-form-item>
|
|
||||||
</j-col>
|
|
||||||
</j-row>
|
|
||||||
</template>
|
</template>
|
||||||
</a-form>
|
</a-form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -108,6 +76,13 @@ import { getImage } from '@/utils/comm';
|
||||||
import TopCard from '../device/TopCard.vue';
|
import TopCard from '../device/TopCard.vue';
|
||||||
import { detail } from '@/api/device/instance';
|
import { detail } from '@/api/device/instance';
|
||||||
import EditTable from './EditTable.vue';
|
import EditTable from './EditTable.vue';
|
||||||
|
import WriteProperty from './WriteProperty.vue';
|
||||||
|
import { queryBuiltInParams } from '@/api/rule-engine/scene';
|
||||||
|
import { useSceneStore } from '@/store/scene';
|
||||||
|
import { storeToRefs } from 'pinia'
|
||||||
|
|
||||||
|
const sceneStore = useSceneStore();
|
||||||
|
const { data } = storeToRefs(sceneStore);
|
||||||
|
|
||||||
const TypeList = [
|
const TypeList = [
|
||||||
{
|
{
|
||||||
|
@ -172,44 +147,93 @@ const deviceMessageType = computed(() => {
|
||||||
return modelRef.message.messageType;
|
return modelRef.message.messageType;
|
||||||
});
|
});
|
||||||
|
|
||||||
const onFunctionChange = (val: string) => {
|
const builtInList = ref<any[]>([]);
|
||||||
|
|
||||||
|
const onFunctionChange = (val: string, values?: any[]) => {
|
||||||
const _item = (metadata.value?.functions || []).find((item: any) => {
|
const _item = (metadata.value?.functions || []).find((item: any) => {
|
||||||
return val === item.id;
|
return val === item.id;
|
||||||
});
|
});
|
||||||
const list = (_item?.inputs || []).map((item: any) => {
|
const list = (_item?.inputs || []).map((item: any) => {
|
||||||
|
const _a = values?.find((i) => i.name === item.id);
|
||||||
return {
|
return {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
name: item.name,
|
value: _a?.value,
|
||||||
value: undefined,
|
|
||||||
valueType: item?.valueType?.type,
|
valueType: item?.valueType?.type,
|
||||||
|
..._a,
|
||||||
|
name: item.name,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
modelRef.message.inputs = list;
|
modelRef.message.inputs = list;
|
||||||
};
|
};
|
||||||
|
|
||||||
watchEffect(() => {
|
const onMessageTypeChange = (val: string) => {
|
||||||
// console.log(props.values)
|
if (['WRITE_PROPERTY', 'INVOKE_FUNCTION'].includes(val)) {
|
||||||
// console.log(metadata.value)
|
const _params = {
|
||||||
// Object.assign()
|
branch: props.thenName,
|
||||||
});
|
branchGroup: props.branchGroup,
|
||||||
|
action: props.name - 1,
|
||||||
|
};
|
||||||
|
queryBuiltInParams(unref(data), _params).then((res: any) => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
builtInList.value = res.result
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => [props.values?.productDetail, props.values.deviceDetail],
|
() => [
|
||||||
([newVal1, newVal2]) => {
|
props.values?.productDetail,
|
||||||
if (newVal1) {
|
props.values.selectorValues,
|
||||||
if (props.values?.selector === 'fixed') {
|
props.values?.selector,
|
||||||
detail(newVal2.id).then((resp) => {
|
],
|
||||||
if (resp.status === 200) {
|
([newVal1, newVal2, newVal3]) => {
|
||||||
metadata.value = JSON.parse(
|
if (newVal1?.id) {
|
||||||
resp.result?.metadata || '{}',
|
if (newVal3?.selector === 'fixed') {
|
||||||
);
|
const id = newVal2?.[0]?.value;
|
||||||
}
|
if (id) {
|
||||||
});
|
detail(id).then((resp) => {
|
||||||
|
if (resp.status === 200) {
|
||||||
|
metadata.value = JSON.parse(
|
||||||
|
resp.result?.metadata || '{}',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
metadata.value = JSON.parse(newVal1?.metadata || '{}');
|
metadata.value = JSON.parse(newVal1?.metadata || '{}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{ immediate: true, deep: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.values?.message,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal?.messageType) {
|
||||||
|
modelRef.message = newVal;
|
||||||
|
if (newVal.messageType === 'INVOKE_FUNCTION' && newVal.functionId) {
|
||||||
|
onFunctionChange(newVal.functionId, newVal?.inputs);
|
||||||
|
}
|
||||||
|
onMessageTypeChange(newVal.messageType)
|
||||||
|
}
|
||||||
|
},
|
||||||
{ deep: true, immediate: true },
|
{ deep: true, immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const onFormSave = () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
formRef.value
|
||||||
|
.validate()
|
||||||
|
.then(async (_data: any) => {
|
||||||
|
resolve(_data);
|
||||||
|
})
|
||||||
|
.catch((err: any) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({ onFormSave });
|
||||||
</script>
|
</script>
|
|
@ -1,11 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- <j-advanced-search
|
<j-advanced-search
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
type="simple"
|
type="simple"
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
class="search"
|
class="search"
|
||||||
target="scene-trigger-device-device"
|
target="scene-trigger-device-device"
|
||||||
/> -->
|
/>
|
||||||
<a-divider style="margin: 0" />
|
<a-divider style="margin: 0" />
|
||||||
<j-pro-table
|
<j-pro-table
|
||||||
ref="actionRef"
|
ref="actionRef"
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
v-model:value="modelRef.selectorValues"
|
v-model:value="modelRef.selectorValues"
|
||||||
placeholder="请选择参数"
|
placeholder="请选择参数"
|
||||||
@select="onVariableChange"
|
@select="onVariableChange"
|
||||||
|
:fieldNames="{ label: 'name', value: 'id' }"
|
||||||
>
|
>
|
||||||
<template #title="{ name, description }">
|
<template #title="{ name, description }">
|
||||||
<a-space>
|
<a-space>
|
||||||
|
@ -108,6 +109,7 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// save保存deviceDetail
|
||||||
const emits = defineEmits(['save', 'cancel']);
|
const emits = defineEmits(['save', 'cancel']);
|
||||||
|
|
||||||
const sceneStore = useSceneStore();
|
const sceneStore = useSceneStore();
|
||||||
|
@ -122,6 +124,7 @@ const modelRef = reactive({
|
||||||
source: '',
|
source: '',
|
||||||
relationName: '',
|
relationName: '',
|
||||||
upperKey: '',
|
upperKey: '',
|
||||||
|
message: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
const list = ref<any[]>([]);
|
const list = ref<any[]>([]);
|
||||||
|
@ -160,7 +163,7 @@ const filterTree = (nodes: any[]) => {
|
||||||
if (!nodes?.length) {
|
if (!nodes?.length) {
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
return nodes.filter((it) => {
|
const arr = nodes.filter((it) => {
|
||||||
if (
|
if (
|
||||||
it.children.find(
|
it.children.find(
|
||||||
(item: any) =>
|
(item: any) =>
|
||||||
|
@ -173,43 +176,16 @@ const filterTree = (nodes: any[]) => {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
};
|
return arr.map((item) => {
|
||||||
|
if (item.children) {
|
||||||
const treeDataFilter = (arr: any[]) => {
|
}
|
||||||
if (Array.isArray(arr) && arr.length) {
|
return {
|
||||||
const list: any[] = [];
|
...item,
|
||||||
arr.map((item: any) => {
|
title: item.name,
|
||||||
if (item.children) {
|
value: item.id,
|
||||||
const children = treeDataFilter(item.children);
|
disabled: !!item.children,
|
||||||
if (children.length) {
|
};
|
||||||
list.push({
|
});
|
||||||
...item,
|
|
||||||
title: item.name,
|
|
||||||
value: item.id,
|
|
||||||
disabled: true,
|
|
||||||
children,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (
|
|
||||||
item.children.find(
|
|
||||||
(item: any) =>
|
|
||||||
item.id.indexOf(
|
|
||||||
'deviceId' || 'device_id' || 'device_Id',
|
|
||||||
) > -1,
|
|
||||||
) &&
|
|
||||||
!item.children.find(
|
|
||||||
(item: any) => item.id.indexOf('bolaen') > -1,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
list.push(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return list;
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const sourceChangeEvent = async () => {
|
const sourceChangeEvent = async () => {
|
||||||
|
@ -220,11 +196,9 @@ const sourceChangeEvent = async () => {
|
||||||
};
|
};
|
||||||
const resp = await queryBuiltInParams(unref(data), _params);
|
const resp = await queryBuiltInParams(unref(data), _params);
|
||||||
if (resp.status === 200) {
|
if (resp.status === 200) {
|
||||||
// const array = filterTree(resp.result as any[]);
|
const array = filterTree(resp.result as any[]);
|
||||||
//判断相同产品才有按变量
|
//判断相同产品才有按变量
|
||||||
// if (props.formProductId === DeviceModel.productId)// TODO
|
// if (props.formProductId === DeviceModel.productId)// TODO
|
||||||
console.log(array);
|
|
||||||
const arr = treeDataFilter(resp.result as any[]);
|
|
||||||
builtInList.value = array;
|
builtInList.value = array;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -293,6 +267,7 @@ const filterType = async () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSelectorChange = (val: string) => {
|
const onSelectorChange = (val: string) => {
|
||||||
|
modelRef.selectorValues = undefined;
|
||||||
if (val === 'relation') {
|
if (val === 'relation') {
|
||||||
queryRelationList();
|
queryRelationList();
|
||||||
}
|
}
|
||||||
|
@ -300,7 +275,17 @@ const onSelectorChange = (val: string) => {
|
||||||
|
|
||||||
const onDeviceChange = (_detail: any) => {
|
const onDeviceChange = (_detail: any) => {
|
||||||
if (_detail) {
|
if (_detail) {
|
||||||
emits('save', modelRef, _detail);
|
if (_detail.id) {
|
||||||
|
modelRef.deviceId = _detail.id;
|
||||||
|
modelRef.selectorValues = [
|
||||||
|
{ value: _detail.id, name: _detail.name },
|
||||||
|
] as any;
|
||||||
|
modelRef.message = {} as any;
|
||||||
|
} else {
|
||||||
|
modelRef.deviceId = '';
|
||||||
|
modelRef.selectorValues = [] as any;
|
||||||
|
}
|
||||||
|
emits('save', unref(modelRef), _detail);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -310,7 +295,7 @@ const onRelationChange = (val: any, options: any) => {
|
||||||
modelRef.selectorValues = val;
|
modelRef.selectorValues = val;
|
||||||
modelRef.upperKey = 'scene.deviceId';
|
modelRef.upperKey = 'scene.deviceId';
|
||||||
modelRef.relationName = options.label;
|
modelRef.relationName = options.label;
|
||||||
emits('save', modelRef, {});
|
emits('save', unref(modelRef), {});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onTagChange = (val: any[], arr: any[]) => {
|
const onTagChange = (val: any[], arr: any[]) => {
|
||||||
|
@ -321,11 +306,12 @@ const onTagChange = (val: any[], arr: any[]) => {
|
||||||
if (arr) {
|
if (arr) {
|
||||||
tagList.value = arr;
|
tagList.value = arr;
|
||||||
}
|
}
|
||||||
|
emits('save', unref(modelRef), {});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onVariableChange = (val: any, node: any) => {
|
const onVariableChange = (val: any, node: any) => {
|
||||||
modelRef.deviceId = val;
|
modelRef.deviceId = val;
|
||||||
// modelRef.deviceDetail = node;
|
emits('save', unref(modelRef), node);
|
||||||
modelRef.selectorValues = [{ value: val, name: node.description }] as any;
|
modelRef.selectorValues = [{ value: val, name: node.description }] as any;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -348,6 +334,21 @@ watch(
|
||||||
deep: true,
|
deep: true,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const onFormSave = () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
formRef.value
|
||||||
|
.validate()
|
||||||
|
.then(async (_data: any) => {
|
||||||
|
resolve(_data);
|
||||||
|
})
|
||||||
|
.catch((err: any) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({ onFormSave });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang='less'>
|
<style scoped lang='less'>
|
||||||
|
|
|
@ -33,13 +33,16 @@
|
||||||
:thenName="thenName"
|
:thenName="thenName"
|
||||||
:values="DeviceModel"
|
:values="DeviceModel"
|
||||||
@save="onDeviceSave"
|
@save="onDeviceSave"
|
||||||
|
ref="deviceRef"
|
||||||
/>
|
/>
|
||||||
<Action v-else-if="current === 2"
|
<Action
|
||||||
|
v-else-if="current === 2"
|
||||||
:name="name"
|
:name="name"
|
||||||
:branchGroup="branchGroup"
|
:branchGroup="branchGroup"
|
||||||
:thenName="thenName"
|
:thenName="thenName"
|
||||||
:values="DeviceModel"
|
:values="DeviceModel"
|
||||||
/>
|
ref="actionRef"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="steps-action">
|
<div class="steps-action">
|
||||||
|
@ -62,7 +65,13 @@ import Product from './Product.vue';
|
||||||
import Device from './device/index.vue';
|
import Device from './device/index.vue';
|
||||||
import Action from './actions/index.vue';
|
import Action from './actions/index.vue';
|
||||||
import { onlyMessage } from '@/utils/comm';
|
import { onlyMessage } from '@/utils/comm';
|
||||||
import { detail } from '@/api/device/product'
|
import { detail } from '@/api/device/product';
|
||||||
|
|
||||||
|
import { useSceneStore } from '@/store/scene';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
|
||||||
|
const sceneStore = useSceneStore();
|
||||||
|
const { data } = storeToRefs(sceneStore);
|
||||||
|
|
||||||
type Emit = {
|
type Emit = {
|
||||||
(e: 'cancel'): void;
|
(e: 'cancel'): void;
|
||||||
|
@ -92,6 +101,8 @@ const props = defineProps({
|
||||||
});
|
});
|
||||||
|
|
||||||
const current = ref<number>(0);
|
const current = ref<number>(0);
|
||||||
|
const deviceRef = ref<any>();
|
||||||
|
const actionRef = ref<any>();
|
||||||
|
|
||||||
const DeviceModel = reactive<DeviceModelType>({
|
const DeviceModel = reactive<DeviceModelType>({
|
||||||
productId: '',
|
productId: '',
|
||||||
|
@ -119,6 +130,71 @@ const onCancel = () => {
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onSave = (_data: any) => {
|
||||||
|
const item: any = {
|
||||||
|
selector: DeviceModel.selector,
|
||||||
|
source: DeviceModel.source,
|
||||||
|
selectorValues: DeviceModel.selectorValues,
|
||||||
|
productId: DeviceModel.productId,
|
||||||
|
message: _data.message,
|
||||||
|
};
|
||||||
|
//处理按变量
|
||||||
|
if (DeviceModel.selector === 'variable') {
|
||||||
|
item.selector = 'fixed';
|
||||||
|
}
|
||||||
|
if (DeviceModel.selector === 'relation') {
|
||||||
|
item.upperKey = 'scene.deviceId';
|
||||||
|
}
|
||||||
|
const _options: any = {
|
||||||
|
name: '-', //设备名称
|
||||||
|
type: '', //类型
|
||||||
|
properties: '', //属性功能
|
||||||
|
propertiesValue: '', //设置功能
|
||||||
|
selector: DeviceModel.selector, //选择器标识
|
||||||
|
productName: DeviceModel.productDetail.name,
|
||||||
|
relationName: DeviceModel.relationName,
|
||||||
|
triggerName: data.value.options?.trigger?.name || '触发设备',
|
||||||
|
taglist: [],
|
||||||
|
columns: [],
|
||||||
|
otherColumns: [],
|
||||||
|
};
|
||||||
|
_options.name = DeviceModel.deviceDetail?.name;
|
||||||
|
const _type = _data.message.messageType;
|
||||||
|
if (_type === 'INVOKE_FUNCTION') {
|
||||||
|
_options.type = '执行';
|
||||||
|
_options.properties = DeviceModel.propertiesName;
|
||||||
|
}
|
||||||
|
if (_type === 'READ_PROPERTY') {
|
||||||
|
_options.type = '读取';
|
||||||
|
_options.properties = DeviceModel.propertiesName;
|
||||||
|
}
|
||||||
|
if (_type === 'WRITE_PROPERTY') {
|
||||||
|
_options.type = '设置';
|
||||||
|
_options.properties = DeviceModel.propertiesName;
|
||||||
|
_options.propertiesValue =
|
||||||
|
typeof DeviceModel.propertiesValue === 'object'
|
||||||
|
? JSON.stringify(DeviceModel.propertiesValue)
|
||||||
|
: `${DeviceModel.propertiesValue}`;
|
||||||
|
_options.columns = DeviceModel.columns;
|
||||||
|
_options.otherColumns = DeviceModel.columns;
|
||||||
|
const cur: any = Object.values(_data.message.properties)?.[0];
|
||||||
|
if (cur?.source === 'upper') {
|
||||||
|
_options.propertiesValue = DeviceModel.actionName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_options.selector === 'tag') {
|
||||||
|
_options.taglist = DeviceModel.tagList.map((it) => ({
|
||||||
|
name: it.column || it.name,
|
||||||
|
type: it.type ? (it.type === 'and' ? '并且' : '或者') : '',
|
||||||
|
value: it.value,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
if (_options.selector === 'variable') {
|
||||||
|
_options.name = DeviceModel.selectorValues?.[0]?.name;
|
||||||
|
}
|
||||||
|
emit('save', item, _options);
|
||||||
|
};
|
||||||
|
|
||||||
const save = async (step?: number) => {
|
const save = async (step?: number) => {
|
||||||
let _step = step !== undefined ? step : current.value;
|
let _step = step !== undefined ? step : current.value;
|
||||||
if (_step === 0) {
|
if (_step === 0) {
|
||||||
|
@ -126,10 +202,15 @@ const save = async (step?: number) => {
|
||||||
? (current.value = 1)
|
? (current.value = 1)
|
||||||
: onlyMessage('请选择产品', 'error');
|
: onlyMessage('请选择产品', 'error');
|
||||||
} else if (_step === 1) {
|
} else if (_step === 1) {
|
||||||
DeviceModel.deviceId
|
if (deviceRef.value) {
|
||||||
? (current.value = 2)
|
await deviceRef.value?.onFormSave();
|
||||||
: onlyMessage('请选择设备', 'error');
|
current.value = 2;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (actionRef.value) {
|
||||||
|
const _data = await actionRef.value?.onFormSave();
|
||||||
|
onSave(_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -148,24 +229,23 @@ const prev = () => {
|
||||||
const saveClick = () => save();
|
const saveClick = () => save();
|
||||||
|
|
||||||
const onDeviceSave = (_data: any, _detail: any) => {
|
const onDeviceSave = (_data: any, _detail: any) => {
|
||||||
Object.assign(DeviceModel, _data)
|
Object.assign(DeviceModel, _data);
|
||||||
DeviceModel.deviceId = _detail.id
|
DeviceModel.deviceDetail = _detail;
|
||||||
DeviceModel.deviceDetail = _detail
|
};
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.value,
|
() => props.value,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
Object.assign(DeviceModel, newValue);
|
Object.assign(DeviceModel, newValue);
|
||||||
if(newValue?.productId){
|
if (newValue?.productId) {
|
||||||
detail(newValue.productId).then(resp => {
|
detail(newValue.productId).then((resp) => {
|
||||||
if(resp.status === 200){
|
if (resp.status === 200) {
|
||||||
DeviceModel.productDetail = resp.result
|
DeviceModel.productDetail = resp.result;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true, deep: true },
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,13 @@
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<j-card-select
|
<!-- <j-card-select
|
||||||
v-model:value="formModel.type"
|
v-model:value="formModel.type"
|
||||||
:options="options"
|
:options="options"
|
||||||
type="horizontal"
|
type="horizontal"
|
||||||
float="right"
|
float="right"
|
||||||
/>
|
/> -->
|
||||||
|
<a-radio-group v-model:value="formModel.type" :options="options" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<ActionTypeComponent
|
<ActionTypeComponent
|
||||||
v-bind="props"
|
v-bind="props"
|
||||||
|
@ -43,10 +44,9 @@ import Notify from '../Notify/index.vue';
|
||||||
import Device from '../Device/index.vue';
|
import Device from '../Device/index.vue';
|
||||||
import { PropType } from 'vue';
|
import { PropType } from 'vue';
|
||||||
import { ActionsType } from '../../../typings';
|
import { ActionsType } from '../../../typings';
|
||||||
import ActionTypeComponent from './ActionTypeComponent.vue'
|
import ActionTypeComponent from './ActionTypeComponent.vue';
|
||||||
import { randomString } from '@/utils/utils';
|
import { randomString } from '@/utils/utils';
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
branchesName: {
|
branchesName: {
|
||||||
type: Number,
|
type: Number,
|
||||||
|
@ -63,8 +63,8 @@ const props = defineProps({
|
||||||
data: {
|
data: {
|
||||||
type: Object as PropType<ActionsType>,
|
type: Object as PropType<ActionsType>,
|
||||||
default: () => ({
|
default: () => ({
|
||||||
key: randomString()
|
key: randomString(),
|
||||||
})
|
}),
|
||||||
},
|
},
|
||||||
parallel: {
|
parallel: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@ -117,7 +117,11 @@ watch(
|
||||||
() => props.data,
|
() => props.data,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
if (newVal?.executor) {
|
if (newVal?.executor) {
|
||||||
formModel.type = (newVal?.executor === 'alarm' ? newVal?.alarm?.mode : newVal?.executor) as string
|
formModel.type = (
|
||||||
|
newVal?.executor === 'alarm'
|
||||||
|
? newVal?.alarm?.mode
|
||||||
|
: newVal?.executor
|
||||||
|
) as string;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -129,7 +133,15 @@ const onOk = () => {
|
||||||
actionForm.value.validate().then((values: any) => {
|
actionForm.value.validate().then((values: any) => {
|
||||||
actionType.value = values?.type;
|
actionType.value = values?.type;
|
||||||
if (values?.type === 'relieve' || values?.type === 'trigger') {
|
if (values?.type === 'relieve' || values?.type === 'trigger') {
|
||||||
emit('save', { ...props.data, executor: 'alarm', alarm: { mode: values.type } }, {});
|
emit(
|
||||||
|
'save',
|
||||||
|
{
|
||||||
|
...props.data,
|
||||||
|
executor: 'alarm',
|
||||||
|
alarm: { mode: values.type },
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -140,10 +152,10 @@ const onCancel = () => {
|
||||||
|
|
||||||
const onPropsOk = (data: any, options?: any) => {
|
const onPropsOk = (data: any, options?: any) => {
|
||||||
emit('save', { ...data, executor: data.type }, options);
|
emit('save', { ...data, executor: data.type }, options);
|
||||||
actionType.value = ''
|
actionType.value = '';
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPropsCancel = () => {
|
const onPropsCancel = () => {
|
||||||
actionType.value = ''
|
actionType.value = '';
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<Search
|
<j-advanced-search
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
type="simple"
|
type="simple"
|
||||||
target="action-notice-config"
|
target="action-notice-config"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<Search
|
<j-advanced-search
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
type="simple"
|
type="simple"
|
||||||
target="action-notice-template"
|
target="action-notice-template"
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<a-spin :spinning="loading">
|
<a-spin :spinning="loading">
|
||||||
<j-card-select
|
<!-- <j-card-select
|
||||||
v-model:value="notifyType"
|
v-model:value="notifyType"
|
||||||
:options="options"
|
:options="options"
|
||||||
:icon-size="106"
|
:icon-size="106"
|
||||||
/>
|
/> -->
|
||||||
|
<a-radio-group v-model:value="notifyType" :options="options" @change="onRadioChange" />
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -34,13 +35,17 @@ const notifyType = ref('');
|
||||||
const options = ref<any[]>([]);
|
const options = ref<any[]>([]);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => notifyType,
|
() => props.value,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
emit('update:value', newVal)
|
notifyType.value = newVal
|
||||||
},
|
},
|
||||||
{ deep: true, immediate: true },
|
{ deep: true, immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const onRadioChange = (e: any) => {
|
||||||
|
emit('update:value', e.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
notice.queryMessageType().then((resp) => {
|
notice.queryMessageType().then((resp) => {
|
||||||
|
|
|
@ -122,7 +122,6 @@ const jumpStep = async (val: number) => {
|
||||||
if (val === 0) {
|
if (val === 0) {
|
||||||
current.value = val;
|
current.value = val;
|
||||||
} else if (val === 1) {
|
} else if (val === 1) {
|
||||||
console.log(formModel)
|
|
||||||
if (formModel.notifyType) {
|
if (formModel.notifyType) {
|
||||||
current.value = val;
|
current.value = val;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -23,7 +23,11 @@
|
||||||
type="serial"
|
type="serial"
|
||||||
:branchesName="props.name"
|
:branchesName="props.name"
|
||||||
:parallel="false"
|
:parallel="false"
|
||||||
:actions="serialArray.length ? serialArray[0].actions : []"
|
:actions="
|
||||||
|
serialArray.length ? serialArray[0].actions : []
|
||||||
|
"
|
||||||
|
@add="onAdd"
|
||||||
|
@delete="onDelete"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</a-collapse-panel>
|
</a-collapse-panel>
|
||||||
|
@ -41,7 +45,11 @@
|
||||||
type="parallel"
|
type="parallel"
|
||||||
:branchesName="props.name"
|
:branchesName="props.name"
|
||||||
:parallel="true"
|
:parallel="true"
|
||||||
:actions="parallelArray.length ? parallelArray[0].actions : []"
|
:actions="
|
||||||
|
parallelArray.length
|
||||||
|
? parallelArray[0].actions
|
||||||
|
: []
|
||||||
|
"
|
||||||
@add="onAdd"
|
@add="onAdd"
|
||||||
@delete="onDelete"
|
@delete="onDelete"
|
||||||
/>
|
/>
|
||||||
|
@ -57,6 +65,7 @@ import ShakeLimit from '../components/ShakeLimit/index.vue';
|
||||||
import { List } from './ListItem';
|
import { List } from './ListItem';
|
||||||
import { BranchesThen } from '../../typings';
|
import { BranchesThen } from '../../typings';
|
||||||
import { PropType } from 'vue';
|
import { PropType } from 'vue';
|
||||||
|
import { randomString } from '@/utils/utils';
|
||||||
|
|
||||||
interface ActionsProps {
|
interface ActionsProps {
|
||||||
name: number;
|
name: number;
|
||||||
|
@ -73,13 +82,15 @@ const props = defineProps({
|
||||||
openShakeLimit: Boolean,
|
openShakeLimit: Boolean,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['update', 'add']);
|
||||||
|
|
||||||
const shakeLimit = ref({
|
const shakeLimit = ref({
|
||||||
enabled: false
|
enabled: false,
|
||||||
});
|
});
|
||||||
const activeKeys = ref<string[]>(['1']);
|
const activeKeys = ref<string[]>(['1']);
|
||||||
const parallelArray = ref<BranchesThen[]>([]);
|
const parallelArray = ref<BranchesThen[]>([]);
|
||||||
const serialArray = ref<BranchesThen[]>([]);
|
const serialArray = ref<BranchesThen[]>([]);
|
||||||
const lock = ref<boolean>(false)
|
const lock = ref<boolean>(false);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.thenOptions,
|
() => props.thenOptions,
|
||||||
|
@ -96,8 +107,8 @@ watch(
|
||||||
parallelArray.value.length &&
|
parallelArray.value.length &&
|
||||||
(!serialArray.value.length || !isSerialActions)
|
(!serialArray.value.length || !isSerialActions)
|
||||||
) {
|
) {
|
||||||
activeKeys.value = ['2']
|
activeKeys.value = ['2'];
|
||||||
lock.value = true
|
lock.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO 回传数据
|
//TODO 回传数据
|
||||||
|
@ -109,11 +120,37 @@ watch(
|
||||||
);
|
);
|
||||||
|
|
||||||
const onDelete = (_key: string) => {
|
const onDelete = (_key: string) => {
|
||||||
console.log(_key)
|
const aIndex = unref(serialArray)[0].actions?.findIndex(
|
||||||
}
|
(aItem) => aItem.key === _key,
|
||||||
const onAdd = (data: any) => {
|
);
|
||||||
console.log(data)
|
if (aIndex !== -1) {
|
||||||
}
|
serialArray.value[0].actions?.splice(aIndex, 1);
|
||||||
|
emit('update', serialArray[0], false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const onAdd = (actionItem: any) => {
|
||||||
|
const newParallelArray = [...parallelArray.value];
|
||||||
|
if (newParallelArray.length) {
|
||||||
|
const indexOf = newParallelArray[0].actions?.findIndex(
|
||||||
|
(aItem) => aItem.key === actionItem.key,
|
||||||
|
);
|
||||||
|
if (indexOf !== -1) {
|
||||||
|
newParallelArray[0].actions.splice(indexOf, 1, actionItem);
|
||||||
|
} else {
|
||||||
|
newParallelArray[0].actions.push(actionItem);
|
||||||
|
}
|
||||||
|
parallelArray.value = [...newParallelArray];
|
||||||
|
console.log(parallelArray.value);
|
||||||
|
emit('update', newParallelArray[0], true);
|
||||||
|
} else {
|
||||||
|
actionItem.key = randomString();
|
||||||
|
emit('add', {
|
||||||
|
parallel: true,
|
||||||
|
key: randomString(),
|
||||||
|
actions: [actionItem],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
@ -1,8 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<j-dropdown class='scene-select' trigger='click'>
|
<j-dropdown
|
||||||
<div :class='dropdownButtonClass'>
|
class='scene-select'
|
||||||
<AIcon v-if='!!icon' :type='icon' />
|
trigger='click'
|
||||||
{{ label }}
|
v-model:visible='visible'
|
||||||
|
@visibleChange='visibleChange'
|
||||||
|
>
|
||||||
|
<div @click.prevent='visible = true'>
|
||||||
|
<slot :label='label'>
|
||||||
|
<div :class='dropdownButtonClass' >
|
||||||
|
<AIcon v-if='!!icon' :type='icon' />
|
||||||
|
{{ label }}
|
||||||
|
</div>
|
||||||
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
<div class='scene-select-content'>
|
<div class='scene-select-content'>
|
||||||
|
@ -18,7 +27,7 @@
|
||||||
:type='component'
|
:type='component'
|
||||||
@change='timeSelect'
|
@change='timeSelect'
|
||||||
/>
|
/>
|
||||||
<div v-else>
|
<div style='min-width: 400px' v-else>
|
||||||
<j-tree
|
<j-tree
|
||||||
:selectedKeys='selectValue ? [selectValue] : []'
|
:selectedKeys='selectValue ? [selectValue] : []'
|
||||||
:treeData='options'
|
:treeData='options'
|
||||||
|
@ -89,20 +98,18 @@ const props = defineProps({
|
||||||
component: {
|
component: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'select' // 'select' | 'treeSelect'
|
default: 'select' // 'select' | 'treeSelect'
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits<Emit>()
|
const emit = defineEmits<Emit>()
|
||||||
|
|
||||||
const label = ref<LabelType>(props.placeholder)
|
const label = ref<LabelType>(props.placeholder)
|
||||||
const selectValue = ref(props.value)
|
const selectValue = ref(props.value)
|
||||||
const flatMapTree = new Map()
|
const visible = ref(false)
|
||||||
|
|
||||||
const LabelStyle = computed(() => {
|
const visibleChange = (v: boolean) => {
|
||||||
return {
|
visible.value = v
|
||||||
color: selectValue.value ? '#' : '#'
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const dropdownButtonClass = computed(() => ({
|
const dropdownButtonClass = computed(() => ({
|
||||||
'dropdown-button': true,
|
'dropdown-button': true,
|
||||||
|
@ -112,24 +119,33 @@ const dropdownButtonClass = computed(() => ({
|
||||||
'type': props.type === 'type',
|
'type': props.type === 'type',
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const treeSelect = (v: any) => {
|
const treeSelect = (v: any, option: any) => {
|
||||||
|
const node = option.node
|
||||||
|
visible.value = false
|
||||||
|
label.value = node.fullname || node.name
|
||||||
|
selectValue.value = v[0]
|
||||||
|
emit('update:value', node[props.valueName])
|
||||||
|
emit('select', node)
|
||||||
}
|
}
|
||||||
|
|
||||||
const timeSelect = (v: string) => {
|
const timeSelect = (v: string) => {
|
||||||
|
selectValue.value = v
|
||||||
|
visible.value = false
|
||||||
emit('update:value', v)
|
emit('update:value', v)
|
||||||
emit('select', v)
|
emit('select', v)
|
||||||
}
|
}
|
||||||
|
|
||||||
const menuSelect = (v: any) => {
|
const menuSelect = (v: string, option: any) => {
|
||||||
const option = getOption(props.options, props.value, props.valueName)
|
selectValue.value = v
|
||||||
emit('update:value', v.key)
|
visible.value = false
|
||||||
|
emit('update:value', v)
|
||||||
emit('select', option)
|
emit('select', option)
|
||||||
}
|
}
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
const option = getOption(props.options, props.value, props.valueName)
|
const option = getOption(props.options, props.value, props.valueName)
|
||||||
if (option && Object.keys(option).length) {
|
selectValue.value = props.value
|
||||||
|
if (option) {
|
||||||
label.value = option[props.labelName] || option.name
|
label.value = option[props.labelName] || option.name
|
||||||
} else {
|
} else {
|
||||||
label.value = props.value || props.placeholder
|
label.value = props.value || props.placeholder
|
||||||
|
|
|
@ -7,13 +7,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang='ts' setup name='DropdownMenus'>
|
<script lang='ts' setup name='DropdownMenus'>
|
||||||
import { isBoolean } from 'lodash-es'
|
import { isBoolean, isUndefined } from 'lodash-es'
|
||||||
import { getOption } from '../DropdownButton/util'
|
import { getOption } from '../DropdownButton/util'
|
||||||
|
|
||||||
type ValueType = string| number | boolean
|
type ValueType = string| number | boolean
|
||||||
type Emits = {
|
type Emits = {
|
||||||
(e: 'update:value', value: ValueType): void
|
(e: 'update:value', value: ValueType): void
|
||||||
(e: 'click', data: any): void
|
(e: 'click', value: string, data: any): void
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
@ -32,29 +32,39 @@ const emit = defineEmits<Emits>()
|
||||||
const myOptions = computed(() => {
|
const myOptions = computed(() => {
|
||||||
return props.options.map((item: any) => {
|
return props.options.map((item: any) => {
|
||||||
let _label = item.label || item.name
|
let _label = item.label || item.name
|
||||||
if (isBoolean(item.value)) {
|
let _value = isUndefined(item.value) ? item.id : item.value
|
||||||
_label = item.value === true ? '是' : '否'
|
if (isBoolean(_value)) {
|
||||||
|
_label = _value === true ? '是' : '否'
|
||||||
|
_value = String(_value)
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
label: _label,
|
label: _label,
|
||||||
value: item.value || item.id,
|
value: _value
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const myValue = ref(props.value)
|
const myValue = ref(props.value)
|
||||||
|
|
||||||
|
const handleBoolean = (key: string) => {
|
||||||
|
return key === 'false' ? false : true
|
||||||
|
}
|
||||||
|
|
||||||
const click = (e: any) => {
|
const click = (e: any) => {
|
||||||
const option = getOption(myOptions.value, e.key)
|
const _key = ['true', 'false'].includes(e.key) ? handleBoolean(e.key) : e.key
|
||||||
myValue.value = e.key
|
const option = getOption(myOptions.value, _key)
|
||||||
emit('update:value', e.key)
|
myValue.value = _key
|
||||||
emit('click', {
|
emit('update:value', _key)
|
||||||
key: e.key,
|
emit('click', _key, {
|
||||||
|
key: _key,
|
||||||
...option
|
...option
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(() => props.value, () => {
|
||||||
|
myValue.value = props.value
|
||||||
|
}, { immediate: true})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang='less'>
|
<style scoped lang='less'>
|
||||||
|
|
|
@ -62,7 +62,7 @@ const change = (e: string) => {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang='less'>
|
<style lang='less' scoped>
|
||||||
.dropdown-time-picker {
|
.dropdown-time-picker {
|
||||||
>div{
|
>div{
|
||||||
position: relative !important;
|
position: relative !important;
|
||||||
|
@ -86,4 +86,8 @@ const change = (e: string) => {
|
||||||
box-shadow: unset;
|
box-shadow: unset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wrapper{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
|
@ -26,8 +26,8 @@ export const getComponent = (type: string): string => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getOption = (data: any[], value?: string | number | boolean, key: string = 'name'): DropdownButtonOptions | any => {
|
export const getOption = (data: any[], value?: string | number | boolean, key: string = 'name'): DropdownButtonOptions | any => {
|
||||||
let option = {}
|
let option
|
||||||
if (!value) return option
|
if (value === undefined && value === null) return option
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
const item = data[i]
|
const item = data[i]
|
||||||
if (item[key] === value) {
|
if (item[key] === value) {
|
||||||
|
@ -35,7 +35,9 @@ export const getOption = (data: any[], value?: string | number | boolean, key: s
|
||||||
break
|
break
|
||||||
} else if (item.children && item.children.length){
|
} else if (item.children && item.children.length){
|
||||||
option = getOption(item.children, value, key)
|
option = getOption(item.children, value, key)
|
||||||
if (option) break
|
if (option) {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return option
|
return option
|
||||||
|
|
|
@ -5,9 +5,13 @@
|
||||||
v-model:visible='visible'
|
v-model:visible='visible'
|
||||||
@visibleChange='visibleChange'
|
@visibleChange='visibleChange'
|
||||||
>
|
>
|
||||||
<div class='dropdown-button value' @click.prevent='visible = true'>
|
<div @click.prevent='visible = true'>
|
||||||
<AIcon v-if='!!icon' :type='icon' />
|
<slot :label='label'>
|
||||||
{{ label }}
|
<div class='dropdown-button value'>
|
||||||
|
<AIcon v-if='!!icon' :type='icon' />
|
||||||
|
{{ label }}
|
||||||
|
</div>
|
||||||
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
<div class='scene-select-content'>
|
<div class='scene-select-content'>
|
||||||
|
@ -24,32 +28,36 @@
|
||||||
@change='timeChange'
|
@change='timeChange'
|
||||||
/>
|
/>
|
||||||
<DropdownMenus
|
<DropdownMenus
|
||||||
v-if='["metric","enum", "boolean"].includes(item.component)'
|
v-if='["select","enum", "boolean"].includes(item.component)'
|
||||||
:options='options'
|
:options='["metric", "upper"].includes(item.key) ? metricOption : options'
|
||||||
@change='onSelect'
|
@click='onSelect'
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
|
v-else-if='item.component === "tree"'
|
||||||
|
style='min-width: 400px'
|
||||||
|
>
|
||||||
|
<j-tree
|
||||||
|
:selectedKeys='myValue ? [myValue] : []'
|
||||||
|
:treeData='item.key === "upper" ? metricOption : options'
|
||||||
|
@select='treeSelect'
|
||||||
|
:height='450'
|
||||||
|
:virtual='true'
|
||||||
|
>
|
||||||
|
<template #title="{ name, description }">
|
||||||
|
<j-space>
|
||||||
|
{{ name }}
|
||||||
|
<span v-if='description' class='tree-title-description'>{{ description }}</span>
|
||||||
|
</j-space>
|
||||||
|
</template>
|
||||||
|
</j-tree>
|
||||||
|
</div>
|
||||||
<ValueItem
|
<ValueItem
|
||||||
v-else-if='valueItemKey.includes(item.component)'
|
v-else
|
||||||
v-model:modelValue='myValue'
|
v-model:modelValue='myValue'
|
||||||
:itemType='getComponent(item.component)'
|
:itemType='getComponent(item.component)'
|
||||||
:options='options'
|
:options='item.key === "upper" ? metricOption : options'
|
||||||
@change='valueItemChange'
|
@change='valueItemChange'
|
||||||
/>
|
/>
|
||||||
<j-tree
|
|
||||||
v-else
|
|
||||||
:selectedKeys='myValue ? [myValue] : []'
|
|
||||||
:treeData='options'
|
|
||||||
@select='treeSelect'
|
|
||||||
:height='450'
|
|
||||||
:virtual='true'
|
|
||||||
>
|
|
||||||
<template #title="{ name, description }">
|
|
||||||
<j-space>
|
|
||||||
{{ name }}
|
|
||||||
<span v-if='description' class='tree-title-description'>{{ description }}</span>
|
|
||||||
</j-space>
|
|
||||||
</template>
|
|
||||||
</j-tree>
|
|
||||||
</div>
|
</div>
|
||||||
</j-tab-pane>
|
</j-tab-pane>
|
||||||
</j-tabs>
|
</j-tabs>
|
||||||
|
@ -101,10 +109,9 @@ const updateValue = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const treeSelect = (e: any) => {
|
const treeSelect = (e: any) => {
|
||||||
console.log('treeSelect', e)
|
|
||||||
visible.value = false
|
visible.value = false
|
||||||
label.value = e.fullname || e.name
|
label.value = e.fullname || e.name
|
||||||
emit('update:value', e.id)
|
emit('update:value', e[props.valueName])
|
||||||
emit('select', e)
|
emit('select', e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +122,8 @@ const valueItemChange = (e: string) => {
|
||||||
emit('select', e)
|
emit('select', e)
|
||||||
}
|
}
|
||||||
|
|
||||||
const sonSelect = (e: string, option: any) => {
|
const onSelect = (e: string, option: any) => {
|
||||||
|
console.log(e, option)
|
||||||
visible.value = false
|
visible.value = false
|
||||||
label.value = option.label
|
label.value = option.label
|
||||||
emit('update:value', e)
|
emit('update:value', e)
|
||||||
|
@ -133,14 +141,16 @@ const visibleChange = (v: boolean) => {
|
||||||
visible.value = v
|
visible.value = v
|
||||||
}
|
}
|
||||||
|
|
||||||
watch([props.options, props.value], () => {
|
watchEffect(() => {
|
||||||
const option = getOption(props.options, props.value as string, props.valueName) // 回显label值
|
const option = getOption(props.options, props.value as string, props.valueName) // 回显label值
|
||||||
if (option && Object.keys(option).length) {
|
myValue.value = props.value
|
||||||
|
mySource.value = props.source
|
||||||
|
if (option) {
|
||||||
label.value = option[props.labelName] || option.name
|
label.value = option[props.labelName] || option.name
|
||||||
} else {
|
} else {
|
||||||
label.value = props.value || props.placeholder
|
label.value = props.value || props.placeholder
|
||||||
}
|
}
|
||||||
}, { immediate: true })
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,7 @@ export type DropdownButtonOptions = {
|
||||||
export type TabsOption = {
|
export type TabsOption = {
|
||||||
label: string;
|
label: string;
|
||||||
key: string;
|
key: string;
|
||||||
component: string,
|
component: string
|
||||||
options: DropdownButtonOptions[]
|
|
||||||
}
|
}
|
||||||
type ValueArrayType = [string, number]
|
type ValueArrayType = [string, number]
|
||||||
export type ValueType = string | number | undefined | ValueArrayType
|
export type ValueType = string | number | undefined | ValueArrayType
|
||||||
|
@ -47,6 +46,10 @@ export const defaultSetting = {
|
||||||
type: Array as PropType<Array<DropdownButtonOptions>>,
|
type: Array as PropType<Array<DropdownButtonOptions>>,
|
||||||
default: () => []
|
default: () => []
|
||||||
},
|
},
|
||||||
|
metricOption: {
|
||||||
|
type: Array as PropType<Array<DropdownButtonOptions>>,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
metricOptions: { // 指标值
|
metricOptions: { // 指标值
|
||||||
type: Array as PropType<Array<DropdownButtonOptions>>,
|
type: Array as PropType<Array<DropdownButtonOptions>>,
|
||||||
default: () => []
|
default: () => []
|
||||||
|
|
|
@ -40,10 +40,8 @@
|
||||||
icon='icon-canshu'
|
icon='icon-canshu'
|
||||||
placeholder='参数值'
|
placeholder='参数值'
|
||||||
:options='valueOptions'
|
:options='valueOptions'
|
||||||
:tabsOptions='[
|
:metricOption='metricOption'
|
||||||
{ label: "手动输入", component: "input", key: "fixed" },
|
:tabsOptions='tabsOptions'
|
||||||
{ label: "指标值", component: "time", key: "manual" }
|
|
||||||
]'
|
|
||||||
v-model:value='paramsValue.value.value'
|
v-model:value='paramsValue.value.value'
|
||||||
v-model:source='paramsValue.value.source'
|
v-model:source='paramsValue.value.source'
|
||||||
/>
|
/>
|
||||||
|
@ -52,10 +50,8 @@
|
||||||
icon='icon-canshu'
|
icon='icon-canshu'
|
||||||
placeholder='参数值'
|
placeholder='参数值'
|
||||||
:options='valueOptions'
|
:options='valueOptions'
|
||||||
:tabsOptions='[
|
:metricOption='metricOption'
|
||||||
{ label: "手动输入", component: "time", key: "fixed" },
|
:tabsOptions='tabsOptions'
|
||||||
{ label: "指标值", component: "input", key: "manual" },
|
|
||||||
]'
|
|
||||||
v-model:value='paramsValue.value.value'
|
v-model:value='paramsValue.value.value'
|
||||||
v-model:source='paramsValue.value.source'
|
v-model:source='paramsValue.value.source'
|
||||||
/>
|
/>
|
||||||
|
@ -80,6 +76,16 @@ import ParamsDropdown, { DoubleParamsDropdown } from '../ParamsDropdown'
|
||||||
import { inject } from 'vue'
|
import { inject } from 'vue'
|
||||||
import { ContextKey } from './util'
|
import { ContextKey } from './util'
|
||||||
|
|
||||||
|
type Emit = {
|
||||||
|
(e: 'update:value', data: TermsType): void
|
||||||
|
}
|
||||||
|
|
||||||
|
type TabsOption = {
|
||||||
|
label: string;
|
||||||
|
key: string;
|
||||||
|
component: string
|
||||||
|
}
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
isFirst: {
|
isFirst: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@ -98,7 +104,7 @@ const props = defineProps({
|
||||||
default: () => ({
|
default: () => ({
|
||||||
column: '',
|
column: '',
|
||||||
type: '',
|
type: '',
|
||||||
termType: undefined,
|
termType: 'eq',
|
||||||
value: {
|
value: {
|
||||||
source: 'fixed',
|
source: 'fixed',
|
||||||
value: undefined
|
value: undefined
|
||||||
|
@ -107,6 +113,8 @@ const props = defineProps({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits<Emit>()
|
||||||
|
|
||||||
const paramsValue = reactive<TermsType>({
|
const paramsValue = reactive<TermsType>({
|
||||||
column: props.value.column,
|
column: props.value.column,
|
||||||
type: props.value.type,
|
type: props.value.type,
|
||||||
|
@ -115,21 +123,56 @@ const paramsValue = reactive<TermsType>({
|
||||||
})
|
})
|
||||||
|
|
||||||
const showDelete = ref(false)
|
const showDelete = ref(false)
|
||||||
const columnOptions: any = inject(ContextKey)
|
const columnOptions: any = inject(ContextKey) //
|
||||||
const options = ref<any>([])
|
const termTypeOptions = ref<Array<{ id: string, name: string}>>([]) // 条件值
|
||||||
|
const valueOptions = ref<any[]>([]) // 默认手动输入下拉
|
||||||
|
const metricOption = ref<any[]>([]) // 根据termType获取对应指标值
|
||||||
|
const tabsOptions = ref<Array<TabsOption>>([{ label: '手动输入', key: 'manual', component: 'string' }])
|
||||||
|
let metricsCacheOption: any[] = [] // 缓存指标值
|
||||||
|
|
||||||
const termTypeOptions = computed(() => {
|
const handOptionByColumn = (option: any) => {
|
||||||
|
if (option) {
|
||||||
|
termTypeOptions.value = option.termTypes || []
|
||||||
|
metricsCacheOption = option.metrics || []
|
||||||
|
tabsOptions.value.length = 1
|
||||||
|
tabsOptions.value[0].component = option.dataType
|
||||||
|
|
||||||
|
if (option.metrics && option.metrics.length) {
|
||||||
|
tabsOptions.value.push(
|
||||||
|
{ label: '指标值', key: 'metric', component: 'select' }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option.dataType === 'boolean') {
|
||||||
|
valueOptions.value = [
|
||||||
|
{ label: '是', value: true },
|
||||||
|
{ label: '否', value: false },
|
||||||
|
]
|
||||||
|
} else if(option.dataType === 'enum') {
|
||||||
|
valueOptions.value = option.options?.map((item: any) => ({ ...item, label: item.name, value: item.id})) || []
|
||||||
|
} else{
|
||||||
|
valueOptions.value = option.options || []
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
termTypeOptions.value = []
|
||||||
|
metricsCacheOption = []
|
||||||
|
valueOptions.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
const option = getOption(columnOptions.value, paramsValue.column, 'column')
|
const option = getOption(columnOptions.value, paramsValue.column, 'column')
|
||||||
return option && Object.keys(option).length ? option.termTypes : []
|
handOptionByColumn(option)
|
||||||
})
|
|
||||||
|
|
||||||
const tabsOptions = computed(() => {
|
|
||||||
// 获取当前value对应的option
|
|
||||||
return []
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const showDouble = computed(() => {
|
const showDouble = computed(() => {
|
||||||
return paramsValue.termType ? ['nbtw', 'btw', 'in', 'nin'].includes(paramsValue.termType) : false
|
const isRange = paramsValue.termType ? ['nbtw', 'btw', 'in', 'nin'].includes(paramsValue.termType) : false
|
||||||
|
if (metricsCacheOption.length) {
|
||||||
|
metricOption.value = metricsCacheOption.filter(item => isRange ? item.range : !item.range)
|
||||||
|
} else {
|
||||||
|
metricOption.value = []
|
||||||
|
}
|
||||||
|
return isRange
|
||||||
})
|
})
|
||||||
|
|
||||||
const mouseover = () => {
|
const mouseover = () => {
|
||||||
|
@ -145,11 +188,20 @@ const mouseout = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const columnSelect = () => {
|
const columnSelect = () => {
|
||||||
|
paramsValue.termType = 'eq'
|
||||||
|
paramsValue.value = {
|
||||||
|
source: tabsOptions.value[0].key,
|
||||||
|
value: undefined
|
||||||
|
}
|
||||||
|
emit('update:value', { ...paramsValue })
|
||||||
}
|
}
|
||||||
|
|
||||||
const termsTypeSelect = () => {
|
const termsTypeSelect = () => {
|
||||||
|
paramsValue.value = {
|
||||||
|
source: tabsOptions.value[0].key,
|
||||||
|
value: undefined
|
||||||
|
}
|
||||||
|
emit('update:value', { ...paramsValue })
|
||||||
}
|
}
|
||||||
|
|
||||||
const termAdd = () => {
|
const termAdd = () => {
|
||||||
|
@ -160,10 +212,6 @@ const onDelete = () => {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const valueOptions = computed(() => {
|
|
||||||
return []
|
|
||||||
})
|
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
Object.assign(paramsValue, props.value)
|
Object.assign(paramsValue, props.value)
|
||||||
})
|
})
|
||||||
|
|
|
@ -77,11 +77,22 @@ const rules = [{
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
const handleParamsData = (data: any[]): any[] => {
|
||||||
|
return data?.map(item => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
key: item.column,
|
||||||
|
disabled: !!item.children,
|
||||||
|
children: handleParamsData(item.children)
|
||||||
|
}
|
||||||
|
}) || []
|
||||||
|
}
|
||||||
|
|
||||||
const queryColumn = (dataModel: FormModelType) => {
|
const queryColumn = (dataModel: FormModelType) => {
|
||||||
const cloneDevice = cloneDeep(dataModel)
|
const cloneDevice = cloneDeep(dataModel)
|
||||||
cloneDevice.branches = cloneDevice.branches?.filter(item => !!item)
|
cloneDevice.branches = cloneDevice.branches?.filter(item => !!item)
|
||||||
getParseTerm(cloneDevice).then(res => {
|
getParseTerm(cloneDevice).then(res => {
|
||||||
columnOptions.value = res.result
|
columnOptions.value = handleParamsData(res.result as any[])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@
|
||||||
</page-container>
|
</page-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang='ts'>
|
<script setup lang='ts' name='Scene'>
|
||||||
import SaveModal from './Save/save.vue';
|
import SaveModal from './Save/save.vue';
|
||||||
import type { SceneItem } from './typings';
|
import type { SceneItem } from './typings';
|
||||||
import { useMenuStore } from 'store/menu';
|
import { useMenuStore } from 'store/menu';
|
||||||
|
|
|
@ -187,7 +187,7 @@ export type TriggerType = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface TermsVale {
|
export interface TermsVale {
|
||||||
source: keyof typeof Source;
|
source: string;
|
||||||
/** 手动输入值,source为 manual 时不能为空 */
|
/** 手动输入值,source为 manual 时不能为空 */
|
||||||
value?: Record<string, any> | any[];
|
value?: Record<string, any> | any[];
|
||||||
/** 指标值,source为 metric 时不能为空 */
|
/** 指标值,source为 metric 时不能为空 */
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<slot name="top" />
|
<slot name="top" />
|
||||||
</div>
|
</div>
|
||||||
<j-row :gutter="24">
|
<j-row :gutter="24" class="content">
|
||||||
<j-col
|
<j-col
|
||||||
:span="24"
|
:span="24"
|
||||||
v-if="props.showTitle"
|
v-if="props.showTitle"
|
||||||
|
@ -151,11 +151,16 @@ function init() {
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.api-page-container {
|
.api-page-container {
|
||||||
.tree-content {
|
.content {
|
||||||
padding-bottom: 30px;
|
background-color: #fff;
|
||||||
height: calc(100vh - 230px);
|
padding: 24px;
|
||||||
overflow-y: auto;
|
margin: 0 !important;
|
||||||
border-right: 1px solid #e9e9e9;
|
.tree-content {
|
||||||
|
padding-bottom: 30px;
|
||||||
|
height: calc(100vh - 230px);
|
||||||
|
overflow-y: auto;
|
||||||
|
border-right: 1px solid #e9e9e9;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -3695,8 +3695,8 @@ jetlinks-store@^0.0.3:
|
||||||
|
|
||||||
jetlinks-ui-components@^1.0.4:
|
jetlinks-ui-components@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.jetlinks.cn/jetlinks-ui-components/-/jetlinks-ui-components-1.0.4.tgz#34b70f75dcc4ea679f0da6674a3f372dfc4acab4"
|
resolved "https://registry.jetlinks.cn/jetlinks-ui-components/-/jetlinks-ui-components-1.0.4.tgz#41d52892f0f4d38adc6df02a87290a3042eb5645"
|
||||||
integrity sha512-ffDi9NyD51hPzu6iRBhibxlI36In5igUciMugm+Lui2LxnYdGbXGvB0i4y6xKaGg4jRDJ/lDX+b6AvuIrlb1lg==
|
integrity sha512-aX+XiGigzxZnrG52xqipxd+WuFwBeZ6+dvLkcvOfLLBqSu8sgfvr/8NJ5hFgv5Eo2QFnUJq3Qf4HXLw9Ogv/yw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vueuse/core" "^9.12.0"
|
"@vueuse/core" "^9.12.0"
|
||||||
ant-design-vue "^3.2.15"
|
ant-design-vue "^3.2.15"
|
||||||
|
|
Loading…
Reference in New Issue