Merge branch 'dev' of github.com:jetlinks/jetlinks-ui-vue into dev
This commit is contained in:
commit
2607f9aace
File diff suppressed because it is too large
Load Diff
|
@ -4,6 +4,7 @@
|
|||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"dev": "vite --mode develop",
|
||||
"dev:force": "vite --force --mode develop",
|
||||
"build": "node --max_old_space_size=1024000 ./node_modules/vite/bin/vite.js build",
|
||||
"preview": "vite preview",
|
||||
"eslint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src",
|
||||
|
@ -23,7 +24,7 @@
|
|||
"event-source-polyfill": "^1.0.31",
|
||||
"global": "^4.4.0",
|
||||
"jetlinks-store": "^0.0.3",
|
||||
"jetlinks-ui-components": "^1.0.0",
|
||||
"jetlinks-ui-components": "^1.0.1",
|
||||
"js-cookie": "^3.0.1",
|
||||
"less": "^4.1.3",
|
||||
"less-loader": "^11.1.0",
|
||||
|
|
|
@ -33,4 +33,9 @@ export const detail = (id:string) => server.get(`/alarm/record/${id}`);
|
|||
/**
|
||||
* 告警历史记录
|
||||
*/
|
||||
export const queryHistoryList = (data:any) => server.post('/alarm/history/_query',data)
|
||||
export const queryHistoryList = (data:any) => server.post('/alarm/history/_query',data);
|
||||
|
||||
/**
|
||||
* 获取告警处理结果
|
||||
*/
|
||||
export const queryHandleHistory = (data:any) => server.post('/alarm/record/handle-history/_query',data);
|
|
@ -10,6 +10,7 @@
|
|||
:columns="columns"
|
||||
:request="queryList"
|
||||
:gridColumn="3"
|
||||
:gridColumns="[1,2,3]"
|
||||
ref="tableRef"
|
||||
:defaultParams="{
|
||||
sorts: [{ name: 'createTime', order: 'desc' }],
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
<template>
|
||||
<a-modal
|
||||
title="告警处理"
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
visible
|
||||
@cancel="handleCancel"
|
||||
@ok="handleSave"
|
||||
destroyOnClose
|
||||
:confirmLoading="loading"
|
||||
>
|
||||
<a-form :rules="rules" layout="vertical" ref="formRef" :model="form">
|
||||
<a-form-item label="处理结果" name="describe">
|
||||
<a-textarea
|
||||
:rows="8"
|
||||
:maxlength="200"
|
||||
showCount
|
||||
placeholder="请输入处理结果"
|
||||
v-model:value="form.describe"
|
||||
></a-textarea>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { handleLog } from '@/api/rule-engine/log';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
},
|
||||
});
|
||||
const loading = ref<boolean>(false);
|
||||
const formRef = ref();
|
||||
const rules = {
|
||||
describe: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入处理结果',
|
||||
},
|
||||
],
|
||||
};
|
||||
const form = reactive({
|
||||
describe: '',
|
||||
});
|
||||
let visible = ref(true);
|
||||
const emit = defineEmits(['closeSolve'])
|
||||
const handleCancel = () => {
|
||||
emit('closeSolve');
|
||||
};
|
||||
const handleSave = () => {
|
||||
loading.value = true;
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(async () => {
|
||||
const res = await handleLog({
|
||||
describe: form.describe,
|
||||
type: 'user',
|
||||
state: 'normal',
|
||||
alarmRecordId: props.data?.current?.id || '',
|
||||
alarmConfigId: props.data?.current?.alarmConfigId || '',
|
||||
alarmTime: props?.data?.current?.alarmTime || '',
|
||||
});
|
||||
if (res.status === 200) {
|
||||
onlyMessage('操作成功!');
|
||||
} else {
|
||||
onlyMessage('操作失败!', 'error');
|
||||
}
|
||||
loading.value = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
</style>
|
|
@ -1,78 +1,130 @@
|
|||
<template>
|
||||
<a-modal
|
||||
title="告警处理"
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
visible
|
||||
@cancel="handleCancel"
|
||||
@ok="handleSave"
|
||||
destroyOnClose
|
||||
:confirmLoading="loading"
|
||||
title="处理记录"
|
||||
:width="1200"
|
||||
cancelText="取消"
|
||||
okText="确定"
|
||||
@ok="clsoeModal"
|
||||
@cancel="clsoeModal"
|
||||
>
|
||||
<a-form :rules="rules" layout="vertical" ref="formRef" :model="form">
|
||||
<a-form-item label="处理结果" name="describe">
|
||||
<a-textarea
|
||||
:rows="8"
|
||||
:maxlength="200"
|
||||
showCount
|
||||
placeholder="请输入处理结果"
|
||||
v-model:value="form.describe"
|
||||
></a-textarea>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<Search
|
||||
:columns="columns"
|
||||
target="bind-channel"
|
||||
@search="handleSearch"
|
||||
></Search>
|
||||
<JTable
|
||||
model="TABLE"
|
||||
:columns="columns"
|
||||
:defaultParams="{
|
||||
sorts: [{ name: 'createTime', order: 'desc' }],
|
||||
terms,
|
||||
}"
|
||||
:request="queryHandleHistory"
|
||||
:params="params"
|
||||
>
|
||||
<template #headerTitle>
|
||||
<h3>记录列表</h3>
|
||||
</template>
|
||||
<template #handleTime="slotsProps">
|
||||
<span>
|
||||
{{
|
||||
moment(slotsProps.handleTime).format(
|
||||
'YYYY-MM-DD HH:mm:ss'
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
</template>
|
||||
<template #handleType="slotProps">
|
||||
<span>{{ slotProps.handleType.text }}</span>
|
||||
</template>
|
||||
<template #alarmTime="slotProps">
|
||||
<span>
|
||||
{{
|
||||
moment(slotProps.alarmTime).format(
|
||||
'YYYY-MM-DD HH:mm:ss',
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
</template>
|
||||
</JTable>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { handleLog } from '@/api/rule-engine/log';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
import { queryHandleHistory } from '@/api/rule-engine/log';
|
||||
import moment from 'moment';
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
},
|
||||
});
|
||||
const loading = ref<boolean>(false);
|
||||
const formRef = ref();
|
||||
const rules = {
|
||||
describe: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入处理结果',
|
||||
const terms = [
|
||||
{
|
||||
column: 'alarmRecordId',
|
||||
termType: 'eq',
|
||||
value: props.data.id,
|
||||
type: 'and',
|
||||
},
|
||||
];
|
||||
const columns = [
|
||||
{
|
||||
title: '处理时间',
|
||||
dataIndex: 'handleTime',
|
||||
key: 'handleTime',
|
||||
scopedSlots: true,
|
||||
search: {
|
||||
type: 'date',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
dataIndex: 'handleType',
|
||||
title: '处理类型',
|
||||
key: 'handleType',
|
||||
scopedSlots: true,
|
||||
search: {
|
||||
type: 'select',
|
||||
options: [
|
||||
{
|
||||
label: '系统',
|
||||
value: 'system',
|
||||
},
|
||||
{
|
||||
label: '人工',
|
||||
value: 'user',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '告警时间',
|
||||
dataIndex: 'alarmTime',
|
||||
key: 'alarmTime',
|
||||
scopedSlots: true,
|
||||
search: {
|
||||
type: 'date',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '告警处理',
|
||||
dataIndex: 'description',
|
||||
key: 'description',
|
||||
search: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
];
|
||||
const params = ref();
|
||||
const emit = defineEmits(['closeLog']);
|
||||
/**
|
||||
* 关闭弹窗
|
||||
*/
|
||||
const clsoeModal = () => {
|
||||
emit('closeLog');
|
||||
};
|
||||
const form = reactive({
|
||||
describe: '',
|
||||
});
|
||||
let visible = ref(true);
|
||||
const emit = defineEmits(['closeSolve'])
|
||||
const handleCancel = () => {
|
||||
emit('closeSolve');
|
||||
};
|
||||
const handleSave = () => {
|
||||
loading.value = true;
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(async () => {
|
||||
const res = await handleLog({
|
||||
describe: form.describe,
|
||||
type: 'user',
|
||||
state: 'normal',
|
||||
alarmRecordId: props.data?.current?.id || '',
|
||||
alarmConfigId: props.data?.current?.alarmConfigId || '',
|
||||
alarmTime: props?.data?.current?.alarmTime || '',
|
||||
});
|
||||
if (res.status === 200) {
|
||||
onlyMessage('操作成功!');
|
||||
} else {
|
||||
onlyMessage('操作失败!', 'error');
|
||||
}
|
||||
loading.value = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
loading.value = false;
|
||||
});
|
||||
|
||||
const handleSearch = (e: any) => {
|
||||
params.value = e;
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
:columns="columns"
|
||||
:request="handleSearch"
|
||||
:params="params"
|
||||
:gridColumns="[1,1,2]"
|
||||
:gridColumn="2"
|
||||
model="CARD"
|
||||
>
|
||||
|
@ -115,7 +116,8 @@
|
|||
</CardBox>
|
||||
</template>
|
||||
</JTable>
|
||||
<SolveLog :data="data" v-if="data.solveVisible" @closeSolve="closeSolve"/>
|
||||
<SolveComponent :data="data" v-if="data.solveVisible" @closeSolve="closeSolve"/>
|
||||
<SolveLog :data="data.current" v-if="data.logVisible" @closeLog="closeLog"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -134,6 +136,7 @@ import { storeToRefs } from 'pinia';
|
|||
import { Store } from 'jetlinks-store';
|
||||
import moment from 'moment';
|
||||
import type { ActionsType } from '@/components/Table';
|
||||
import SolveComponent from '../SolveComponent/index.vue';
|
||||
import SolveLog from '../SolveLog/index.vue'
|
||||
import { useMenuStore } from '@/store/menu';
|
||||
const menuStory = useMenuStore();
|
||||
|
@ -390,12 +393,25 @@ const getActions = (
|
|||
title: '处理记录',
|
||||
},
|
||||
icon: 'FileTextOutlined',
|
||||
onClick:() =>{
|
||||
data.value.current = currentData;
|
||||
data.value.logVisible = true;
|
||||
}
|
||||
},
|
||||
];
|
||||
return actions;
|
||||
};
|
||||
/**
|
||||
* 关闭告警日志
|
||||
*/
|
||||
const closeSolve = () =>{
|
||||
data.value.solveVisible = false
|
||||
data.value.solveVisible = false;
|
||||
}
|
||||
/**
|
||||
* 关闭处理记录
|
||||
*/
|
||||
const closeLog = () =>{
|
||||
data.value.logVisible = false;
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
v-model:selectorValues='addModel.selectorValues'
|
||||
/>
|
||||
<Type
|
||||
ref='typeRef'
|
||||
v-else-if='addModel.stepNumber === 2'
|
||||
:metadata='addModel.metadata'
|
||||
/>
|
||||
|
@ -46,7 +47,7 @@
|
|||
|
||||
<script setup lang='ts' name='AddModel'>
|
||||
import type { PropType } from 'vue'
|
||||
import type { metadataType, TriggerDevice } from '@/views/rule-engine/Scene/typings'
|
||||
import type { metadataType, TriggerDevice, TriggerDeviceOptions } from '@/views/rule-engine/Scene/typings'
|
||||
import { onlyMessage } from '@/utils/comm'
|
||||
import { detail as deviceDetail } from '@/api/device/instance'
|
||||
import Product from './Product.vue'
|
||||
|
@ -69,6 +70,7 @@ interface AddModelType extends Omit<TriggerDevice, 'selectorValues'> {
|
|||
}
|
||||
|
||||
const emit = defineEmits<Emit>()
|
||||
const typeRef = ref()
|
||||
|
||||
const props = defineProps({
|
||||
value: {
|
||||
|
@ -81,9 +83,7 @@ const props = defineProps({
|
|||
},
|
||||
options: {
|
||||
type: Object as PropType<any>,
|
||||
default: () => ({
|
||||
|
||||
})
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -100,7 +100,7 @@ const addModel = reactive<AddModelType>({
|
|||
|
||||
Object.assign(addModel, props.value)
|
||||
|
||||
const handleOptions = () => {
|
||||
const handleOptions = (data: TriggerDeviceOptions) => {
|
||||
|
||||
}
|
||||
|
||||
|
@ -138,10 +138,12 @@ const save = async (step?: number) => {
|
|||
}
|
||||
addModel.stepNumber = 2
|
||||
} else {
|
||||
|
||||
const typeData = await typeRef.value.vail()
|
||||
console.log(typeData)
|
||||
if (typeData) {
|
||||
const _options = handleOptions(typeData);
|
||||
}
|
||||
}
|
||||
// handleOptions()
|
||||
// emit('update:value', {})
|
||||
}
|
||||
|
||||
const saveClick = () => save()
|
||||
|
|
|
@ -1,52 +1,57 @@
|
|||
<template>
|
||||
<a-row :gutter='24'>
|
||||
<a-col :span='10'>
|
||||
<a-form-item
|
||||
name='functionId'
|
||||
:rules="[{ required: true, message: '请选择功能' }]"
|
||||
>
|
||||
<a-select
|
||||
showSearch
|
||||
allowClear
|
||||
v-model='functionId'
|
||||
style='width: 100%'
|
||||
placeholder='请选择功能'
|
||||
:filterOption='filterSelectNode'
|
||||
@select='onSelect'
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span='14'>
|
||||
<a-form-item>定时调用所选功能</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span='24'>
|
||||
<a-form-item
|
||||
style='margin-top: 24px'
|
||||
name='functionParameters'
|
||||
>
|
||||
<a-form ref='invokeForm' :model='formModel' layout='vertical' :colon='false'>
|
||||
<a-row :gutter='24'>
|
||||
<a-col :span='10'>
|
||||
<a-form-item
|
||||
name='functionId'
|
||||
:rules="[{ required: true, message: '请选择功能' }]"
|
||||
>
|
||||
<a-select
|
||||
showSearch
|
||||
allowClear
|
||||
v-model:value='formModel.functionId'
|
||||
style='width: 100%'
|
||||
placeholder='请选择功能'
|
||||
:options='functions'
|
||||
:filterOption='filterSelectNode'
|
||||
@select='onSelect'
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span='14'>
|
||||
<a-form-item>定时调用所选功能</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span='24'>
|
||||
<FunctionCall
|
||||
v-model:value='_value'
|
||||
:data='callDataOptions'
|
||||
:value='_value'
|
||||
:data='functionData'
|
||||
@change='callDataChange'
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script setup lang='ts' name='InvokeFunction'>
|
||||
import { filterSelectNode } from '@/utils/comm'
|
||||
import { FunctionCall } from '../components'
|
||||
import type { PropType } from 'vue'
|
||||
import { defineExpose } from 'vue'
|
||||
|
||||
type Emit = {
|
||||
(e: 'update:value', data: Record<string, any>): void
|
||||
(e: 'update:functionParameters', data: Array<Record<string, any>>): void
|
||||
(e: 'update:functionId', data: string): void
|
||||
(e: 'update:action', data: string): void
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
functionId: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
functionParameters: {
|
||||
type: Array as PropType<Record<string, any>[]>,
|
||||
default: () => []
|
||||
},
|
||||
action: {
|
||||
type: String,
|
||||
|
@ -59,46 +64,53 @@ const props = defineProps({
|
|||
})
|
||||
|
||||
const emit = defineEmits<Emit>()
|
||||
const invokeForm = ref()
|
||||
const formModel = reactive({
|
||||
functionId: props.functionId
|
||||
})
|
||||
const _value = ref<any[]>(props.functionParameters)
|
||||
|
||||
const functionId = ref()
|
||||
const _value = ref([])
|
||||
/**
|
||||
* 获取当前选择功能属性
|
||||
*/
|
||||
const functionData = computed(() => {
|
||||
const functionItem: any = props.functions.find((f: any) => f.id === formModel.functionId)
|
||||
const arrCache = []
|
||||
|
||||
const callDataOptions = computed(() => {
|
||||
const _valueKeys = Object.keys(props.value)
|
||||
if (_valueKeys.length) {
|
||||
return _valueKeys.map(key => {
|
||||
const item: any = props.functions.find((p: any) => p.id === key)
|
||||
if (item) {
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
type: item.valueType ? item.valueType.type : '-',
|
||||
format: item.valueType ? item.valueType.format : undefined,
|
||||
options: item.valueType ? item.valueType.element : undefined,
|
||||
value: props.value[key]
|
||||
}
|
||||
}
|
||||
return {
|
||||
id: key,
|
||||
name: key,
|
||||
type: '',
|
||||
format: undefined,
|
||||
options: undefined,
|
||||
value: props.value[key]
|
||||
}
|
||||
})
|
||||
if (functionItem) {
|
||||
const properties = functionItem.valueType ? functionItem.valueType.properties : functionItem.inputs;
|
||||
for (const datum of properties) {
|
||||
arrCache.push({
|
||||
id: datum.id,
|
||||
name: datum.name,
|
||||
type: datum.valueType ? datum.valueType.type : '-',
|
||||
format: datum.valueType ? datum.valueType.format : undefined,
|
||||
options: datum.valueType ? datum.valueType.elements : undefined,
|
||||
value: undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
return []
|
||||
|
||||
return arrCache
|
||||
})
|
||||
|
||||
const onSelect = (v: string, item: any) => {
|
||||
emit('update:action', `执行${item.name}`)
|
||||
emit('update:functionId', v)
|
||||
}
|
||||
|
||||
const callDataChange = () => {
|
||||
|
||||
const callDataChange = (v: any[]) => {
|
||||
_value.value = v
|
||||
emit('update:functionParameters', v)
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
validateFields: () => new Promise(async (resolve) => {
|
||||
const data = await invokeForm.value?.validateFields()
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
:params='params'
|
||||
:request='productQuery'
|
||||
:gridColumn='2'
|
||||
:gridColumns='[2,2,2]'
|
||||
:bodyStyle='{
|
||||
paddingRight: 0,
|
||||
paddingLeft: 0
|
||||
|
|
|
@ -11,15 +11,22 @@
|
|||
v-model:value='formModel.operator'
|
||||
/>
|
||||
</a-form-item>
|
||||
<Timer v-if='showTimer' v-model:value='formModel.timer' />
|
||||
<ReadProperties v-if='showReadProperty' v-model:value='formModel.readProperties' v-model:action='optionCache.action' :properties='readProperties' />
|
||||
<a-form-item
|
||||
<template v-if='showTimer'>
|
||||
<Timer ref='timerRef' v-model:value='formModel.timer' />
|
||||
</template>
|
||||
<ReadProperties
|
||||
v-if='showReadProperty'
|
||||
v-model:value='formModel.readProperties'
|
||||
v-model:action='optionCache.action'
|
||||
:properties='readProperties'
|
||||
/>
|
||||
<WriteProperty
|
||||
ref='writeRef'
|
||||
v-if='showWriteProperty'
|
||||
name='writeProperties'
|
||||
:rules="[{ required: true, message: '请输入修改值' }]"
|
||||
>
|
||||
<WriteProperty v-model:value='formModel.writeProperties' v-model:action='optionCache.action' :properties='writeProperties' />
|
||||
</a-form-item>
|
||||
v-model:value='formModel.writeProperties'
|
||||
v-model:action='optionCache.action'
|
||||
:properties='writeProperties'
|
||||
/>
|
||||
<a-form-item
|
||||
v-if='showReportEvent'
|
||||
name='eventId'
|
||||
|
@ -34,6 +41,14 @@
|
|||
@select='eventSelect'
|
||||
/>
|
||||
</a-form-item>
|
||||
<template v-if='showInvokeFunction'>
|
||||
<InvokeFunction
|
||||
ref='invokeRef'
|
||||
v-model:type='formModel.functionId'
|
||||
v-model:functionParameters='formModel.functionParameters'
|
||||
:functions='functionOptions'
|
||||
/>
|
||||
</template>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -47,6 +62,9 @@ import type { PropType } from 'vue'
|
|||
import { TypeEnum } from '@/views/rule-engine/Scene/Save/Device/util'
|
||||
import ReadProperties from './ReadProperties.vue'
|
||||
import WriteProperty from './WriteProperty.vue'
|
||||
import InvokeFunction from './InvokeFunction.vue'
|
||||
import { defineExpose } from 'vue'
|
||||
import { cloneDeep, omit } from 'lodash-es'
|
||||
|
||||
const props = defineProps({
|
||||
metadata: {
|
||||
|
@ -72,19 +90,25 @@ const optionCache = reactive({
|
|||
const readProperties = ref<any[]>([])
|
||||
const writeProperties = ref<any[]>([])
|
||||
const eventOptions = ref<any[]>([])
|
||||
const functionOptions = ref<any[]>([])
|
||||
|
||||
const typeForm = ref()
|
||||
const timerRef = ref()
|
||||
const writeRef = ref()
|
||||
const invokeRef = ref()
|
||||
|
||||
const topOptions = computed(() => {
|
||||
const baseOptions = [
|
||||
{
|
||||
label: '设备上线',
|
||||
value: 'online',
|
||||
img: getImage('/scene/online.png'),
|
||||
img: getImage('/scene/online.png')
|
||||
},
|
||||
{
|
||||
label: '设备离线',
|
||||
value: 'offline',
|
||||
img: getImage('/scene/offline.png'),
|
||||
},
|
||||
img: getImage('/scene/offline.png')
|
||||
}
|
||||
]
|
||||
|
||||
if (props.metadata.events?.length) {
|
||||
|
@ -94,9 +118,21 @@ const topOptions = computed(() => {
|
|||
|
||||
if (props.metadata.properties?.length) {
|
||||
const _properties = props.metadata.properties
|
||||
readProperties.value = _properties.filter((item: any) => item.expands.type?.includes('read')).map(item => ({...item, label: item.name, value: item.id }))
|
||||
writeProperties.value = _properties.filter((item: any) => item.expands.type?.includes('write')).map(item => ({...item, label: item.name, value: item.id }))
|
||||
const reportProperties = _properties.filter((item: any) => item.expands.type?.includes('report')).map(item => ({...item, label: item.name, value: item.id }))
|
||||
readProperties.value = _properties.filter((item: any) => item.expands.type?.includes('read')).map(item => ({
|
||||
...item,
|
||||
label: item.name,
|
||||
value: item.id
|
||||
}))
|
||||
writeProperties.value = _properties.filter((item: any) => item.expands.type?.includes('write')).map(item => ({
|
||||
...item,
|
||||
label: item.name,
|
||||
value: item.id
|
||||
}))
|
||||
const reportProperties = _properties.filter((item: any) => item.expands.type?.includes('report')).map(item => ({
|
||||
...item,
|
||||
label: item.name,
|
||||
value: item.id
|
||||
}))
|
||||
|
||||
if (readProperties.value.length) {
|
||||
baseOptions.push(TypeEnum.readProperty)
|
||||
|
@ -109,11 +145,11 @@ const topOptions = computed(() => {
|
|||
if (reportProperties.length) {
|
||||
baseOptions.push(TypeEnum.reportProperty)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (props.metadata.functions?.length) {
|
||||
baseOptions.push(TypeEnum.invokeFunction)
|
||||
functionOptions.value = props.metadata.functions.map(item => ({ ...item, label: item.name, value: item.id }))
|
||||
}
|
||||
|
||||
return baseOptions
|
||||
|
@ -147,6 +183,50 @@ const eventSelect = (_: string, eventItem: any) => {
|
|||
optionCache.action = `${eventItem.name}上报`
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
vail: () => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
|
||||
const cloneModel = cloneDeep(formModel)
|
||||
const filterKey: string[] = []
|
||||
const typeData = await typeForm.value?.validateFields()
|
||||
|
||||
if (!typeData) return resolve(false)
|
||||
|
||||
if (!showReadProperty.value) {
|
||||
filterKey.push('readProperties')
|
||||
}
|
||||
|
||||
if (showInvokeFunction.value) {
|
||||
const invokeData = await invokeRef.value?.validateFields()
|
||||
if (!invokeData) return resolve(false)
|
||||
} else {
|
||||
filterKey.push('functionId')
|
||||
filterKey.push('functionParameters')
|
||||
}
|
||||
|
||||
if (showTimer.value) {
|
||||
const timerData = await timerRef.value?.validateFields()
|
||||
if (!timerData) return resolve(false)
|
||||
} else {
|
||||
filterKey.push('timer')
|
||||
}
|
||||
|
||||
if (!showReportEvent.value) {
|
||||
filterKey.push('eventId')
|
||||
}
|
||||
if (showWriteProperty.value) {
|
||||
const writeData = await writeRef.value?.validateFields()
|
||||
if (!writeData) return resolve(false)
|
||||
} else {
|
||||
filterKey.push('writeProperties')
|
||||
}
|
||||
|
||||
resolve(omit(cloneModel, filterKey))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang='less'>
|
||||
|
|
|
@ -1,37 +1,43 @@
|
|||
<template>
|
||||
<a-row :futter='[24, 24]'>
|
||||
<a-col :span='10'>
|
||||
<a-select
|
||||
showSearch
|
||||
style='width: 100%'
|
||||
placeholder='请选择属性'
|
||||
v-model:value='reportKey'
|
||||
:options='properties'
|
||||
:filter-option='filterSelectNode'
|
||||
@change='change'
|
||||
/>
|
||||
</a-col>
|
||||
<a-col :span='14'>
|
||||
<span style='line-height: 32px;padding-left: 24px'>
|
||||
定时调用所选属性
|
||||
</span>
|
||||
</a-col>
|
||||
<a-col :span='24' v-if='showTable'>
|
||||
<div style='margin-top: 24px'>
|
||||
<a-form ref='writeForm' :model='formModel' layout='vertical' :colon='false'>
|
||||
<a-row :futter='[24, 24]'>
|
||||
<a-col :span='10'>
|
||||
<a-form-item
|
||||
name='reportKey'
|
||||
:rules="[{ required: true, message: '请输入修改值' }]"
|
||||
>
|
||||
<a-select
|
||||
showSearch
|
||||
style='width: 100%'
|
||||
placeholder='请选择属性'
|
||||
v-model:value='formModel.reportKey'
|
||||
:options='properties'
|
||||
:filter-option='filterSelectNode'
|
||||
@change='change'
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span='14'>
|
||||
<span style='line-height: 32px;padding-left: 24px'>
|
||||
定时调用所选属性
|
||||
</span>
|
||||
</a-col>
|
||||
<a-col :span='24' v-if='showTable'>
|
||||
<FunctionCall
|
||||
:value='_value'
|
||||
:data='callDataOptions'
|
||||
@change='callDataChange'
|
||||
/>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script setup lang='ts' name='WriteProperties'>
|
||||
import { filterSelectNode } from '@/utils/comm'
|
||||
import { FunctionCall } from '../components'
|
||||
import type { PropType } from 'vue'
|
||||
import { defineExpose } from 'vue'
|
||||
|
||||
type Emit = {
|
||||
(e: 'update:value', data: Record<string, any>): void
|
||||
|
@ -55,8 +61,12 @@ const props = defineProps({
|
|||
|
||||
const emit = defineEmits<Emit>()
|
||||
|
||||
const reportKey = ref<string>()
|
||||
const formModel = reactive<{ reportKey: string | undefined }>({
|
||||
reportKey: undefined
|
||||
})
|
||||
|
||||
const callData = ref<Array<{ id: string, value: string | undefined }>>()
|
||||
const writeForm = ref()
|
||||
const _value = ref([])
|
||||
|
||||
const callDataOptions = computed(() => {
|
||||
|
@ -88,11 +98,10 @@ const callDataOptions = computed(() => {
|
|||
})
|
||||
|
||||
const showTable = computed(() => {
|
||||
return !!reportKey.value
|
||||
return !!formModel.reportKey
|
||||
})
|
||||
|
||||
const change = (v: string, option: any) => {
|
||||
console.log(v, option)
|
||||
const _data = {
|
||||
[v]: undefined
|
||||
}
|
||||
|
@ -103,17 +112,24 @@ const change = (v: string, option: any) => {
|
|||
|
||||
const callDataChange = (v: any[]) => {
|
||||
emit('update:value', {
|
||||
[reportKey.value!]: v[0]?.value
|
||||
[formModel.reportKey!]: v[0]?.value
|
||||
})
|
||||
}
|
||||
|
||||
const initRowKey = () => {
|
||||
if (props.value.length) {
|
||||
const keys = Object.keys(props.value)
|
||||
reportKey.value = keys[0]
|
||||
formModel.reportKey = keys[0]
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
validateFields: () => new Promise(async (resolve) => {
|
||||
const data = await writeForm.value?.validateFields()
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
<template>
|
||||
<a-table
|
||||
<j-table
|
||||
model='TABLE'
|
||||
:noPagination='true'
|
||||
:data-source='dataSource.value'
|
||||
:columns='columns'
|
||||
:bodyStyle='{ padding: 0}'
|
||||
>
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if='column.dataIndex === "name"'>
|
||||
|
@ -33,7 +36,7 @@
|
|||
/>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</j-table>
|
||||
</template>
|
||||
|
||||
<script setup lang='ts' name='FunctionCall'>
|
||||
|
@ -61,13 +64,6 @@ const dataSource = reactive<{value: any[]}>({
|
|||
value: []
|
||||
})
|
||||
|
||||
watch(() => props.data, () => {
|
||||
dataSource.value = props.data.map((item: any) => {
|
||||
const oldValue = props.value.find((oldItem: any) => oldItem.name === item.id)
|
||||
return oldValue ? { ...item, value: oldValue.value } : item
|
||||
})
|
||||
}, { immediate: true })
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '参数名称',
|
||||
|
@ -99,6 +95,13 @@ const handleOptions = (record: any) => {
|
|||
}
|
||||
}
|
||||
|
||||
watch(() => props.data, () => {
|
||||
dataSource.value = props.data.map((item: any) => {
|
||||
const oldValue = props.value.find((oldItem: any) => oldItem.name === item.id)
|
||||
return oldValue ? { ...item, value: oldValue.value } : item
|
||||
})
|
||||
}, { immediate: true })
|
||||
|
||||
watch(() => dataSource.value, () => {
|
||||
const _value = dataSource.value.map(item => ({
|
||||
name: item.id, value: item.value
|
||||
|
|
|
@ -108,6 +108,7 @@ import WhenOption from './WhenOption.vue'
|
|||
import { cloneDeep } from 'lodash-es'
|
||||
import type { OperationTimer } from '../../../typings'
|
||||
import { isCron } from '@/utils/regular'
|
||||
import { defineExpose } from 'vue'
|
||||
|
||||
type NameType = string[] | string
|
||||
|
||||
|
@ -143,6 +144,7 @@ const formModel = reactive<OperationTimer>({
|
|||
unit: 'seconds'
|
||||
}
|
||||
})
|
||||
const timerForm = ref()
|
||||
|
||||
Object.assign(formModel, props.value)
|
||||
|
||||
|
@ -174,6 +176,13 @@ watch(() => formModel, () => {
|
|||
emit('update:value', cloneValue)
|
||||
}, { deep: true })
|
||||
|
||||
defineExpose({
|
||||
validateFields: () => new Promise(async (resolve) => {
|
||||
const data = await timerForm.value?.validateFields()
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang='less'>
|
||||
|
|
Loading…
Reference in New Issue