【代码评审】IoT:场景联动的 review
This commit is contained in:
@ -1,7 +1,7 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
import { IotRuleSceneTriggerConfig } from '@/api/iot/rule/scene/scene.types'
|
import { IotRuleSceneTriggerConfig } from '@/api/iot/rule/scene/scene.types'
|
||||||
|
|
||||||
// IoT 规则场景(场景联动) VO
|
// IoT 场景联动 VO
|
||||||
export interface RuleSceneVO {
|
export interface RuleSceneVO {
|
||||||
id?: number // 场景编号
|
id?: number // 场景编号
|
||||||
name: string // 场景名称
|
name: string // 场景名称
|
||||||
@ -11,29 +11,29 @@ export interface RuleSceneVO {
|
|||||||
actions?: any[] // 执行器数组
|
actions?: any[] // 执行器数组
|
||||||
}
|
}
|
||||||
|
|
||||||
// IoT 规则场景(场景联动) API
|
// IoT 场景联动 API
|
||||||
export const RuleSceneApi = {
|
export const RuleSceneApi = {
|
||||||
// 查询规则场景(场景联动)分页
|
// 查询场景联动分页
|
||||||
getRuleScenePage: async (params: any) => {
|
getRuleScenePage: async (params: any) => {
|
||||||
return await request.get({ url: `/iot/rule-scene/page`, params })
|
return await request.get({ url: `/iot/rule-scene/page`, params })
|
||||||
},
|
},
|
||||||
|
|
||||||
// 查询规则场景(场景联动)详情
|
// 查询场景联动详情
|
||||||
getRuleScene: async (id: number) => {
|
getRuleScene: async (id: number) => {
|
||||||
return await request.get({ url: `/iot/rule-scene/get?id=` + id })
|
return await request.get({ url: `/iot/rule-scene/get?id=` + id })
|
||||||
},
|
},
|
||||||
|
|
||||||
// 新增规则场景(场景联动)
|
// 新增场景联动
|
||||||
createRuleScene: async (data: RuleSceneVO) => {
|
createRuleScene: async (data: RuleSceneVO) => {
|
||||||
return await request.post({ url: `/iot/rule-scene/create`, data })
|
return await request.post({ url: `/iot/rule-scene/create`, data })
|
||||||
},
|
},
|
||||||
|
|
||||||
// 修改规则场景(场景联动)
|
// 修改场景联动
|
||||||
updateRuleScene: async (data: RuleSceneVO) => {
|
updateRuleScene: async (data: RuleSceneVO) => {
|
||||||
return await request.put({ url: `/iot/rule-scene/update`, data })
|
return await request.put({ url: `/iot/rule-scene/update`, data })
|
||||||
},
|
},
|
||||||
|
|
||||||
// 删除规则场景(场景联动)
|
// 删除场景联动
|
||||||
deleteRuleScene: async (id: number) => {
|
deleteRuleScene: async (id: number) => {
|
||||||
return await request.delete({ url: `/iot/rule-scene/delete?id=` + id })
|
return await request.delete({ url: `/iot/rule-scene/delete?id=` + id })
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,7 +61,7 @@ export const useAppStore = defineStore('app', {
|
|||||||
tagsView: true, // 标签页
|
tagsView: true, // 标签页
|
||||||
tagsViewImmerse: false, // 标签页沉浸
|
tagsViewImmerse: false, // 标签页沉浸
|
||||||
tagsViewIcon: true, // 是否显示标签图标
|
tagsViewIcon: true, // 是否显示标签图标
|
||||||
logo: false, // logo
|
logo: true, // logo
|
||||||
fixedHeader: true, // 固定toolheader
|
fixedHeader: true, // 固定toolheader
|
||||||
footer: true, // 显示页脚
|
footer: true, // 显示页脚
|
||||||
greyMode: false, // 是否开始灰色模式,用于特殊悼念日
|
greyMode: false, // 是否开始灰色模式,用于特殊悼念日
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
<!-- TODO @puhui999:IoT 前缀去掉哈,文件名 -->
|
||||||
|
<!-- IoT 设备选择,使用弹窗展示 -->
|
||||||
<template>
|
<template>
|
||||||
<Dialog :title="dialogTitle" v-model="dialogVisible" :appendToBody="true" width="60%">
|
<Dialog :title="dialogTitle" v-model="dialogVisible" :appendToBody="true" width="60%">
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
@ -99,6 +101,8 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table
|
<el-table
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
<!-- TODO @puhui999:IoT 前缀去掉哈,文件名 -->
|
||||||
|
<!-- IoT 产品选择,使用弹窗展示 -->
|
||||||
<template>
|
<template>
|
||||||
<Dialog :title="dialogTitle" v-model="dialogVisible" :appendToBody="true" width="60%">
|
<Dialog :title="dialogTitle" v-model="dialogVisible" :appendToBody="true" width="60%">
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
@ -39,6 +41,8 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table
|
<el-table
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
|
|||||||
@ -48,6 +48,7 @@
|
|||||||
@click="removeTrigger(index)"
|
@click="removeTrigger(index)"
|
||||||
/>
|
/>
|
||||||
</device-listener>
|
</device-listener>
|
||||||
|
<!-- TODO @puhui999:可以使用 el-button,然后选个合适的样式哇 -->
|
||||||
<el-text class="ml-10px!" type="primary" @click="addTrigger">添加触发器</el-text>
|
<el-text class="ml-10px!" type="primary" @click="addTrigger">添加触发器</el-text>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
@ -68,6 +69,7 @@
|
|||||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
import { RuleSceneApi, RuleSceneVO } from '@/api/iot/rule/scene'
|
import { RuleSceneApi, RuleSceneVO } from '@/api/iot/rule/scene'
|
||||||
import DeviceListener from './components/DeviceListener.vue'
|
import DeviceListener from './components/DeviceListener.vue'
|
||||||
|
// TODO @puhui999:尽量用 icon 组件哈,项目里的
|
||||||
import { Delete } from '@element-plus/icons-vue'
|
import { Delete } from '@element-plus/icons-vue'
|
||||||
import { IotRuleSceneTriggerConfig } from '@/api/iot/rule/scene/scene.types'
|
import { IotRuleSceneTriggerConfig } from '@/api/iot/rule/scene/scene.types'
|
||||||
|
|
||||||
@ -82,7 +84,7 @@ const dialogTitle = ref('') // 弹窗的标题
|
|||||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
const formData = ref<RuleSceneVO>({
|
const formData = ref<RuleSceneVO>({
|
||||||
status: 0,
|
status: 0, // TODO @puhui999:使用枚举值
|
||||||
triggers: [] as IotRuleSceneTriggerConfig[]
|
triggers: [] as IotRuleSceneTriggerConfig[]
|
||||||
} as RuleSceneVO)
|
} as RuleSceneVO)
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
@ -96,7 +98,7 @@ const formRef = ref() // 表单 Ref
|
|||||||
/** 添加触发器 */
|
/** 添加触发器 */
|
||||||
const addTrigger = () => {
|
const addTrigger = () => {
|
||||||
formData.value.triggers.push({
|
formData.value.triggers.push({
|
||||||
type: 1,
|
type: 1, // TODO @puhui999:使用枚举值
|
||||||
productKey: '',
|
productKey: '',
|
||||||
deviceNames: [],
|
deviceNames: [],
|
||||||
conditions: [
|
conditions: [
|
||||||
@ -113,6 +115,7 @@ const removeTrigger = (index: number) => {
|
|||||||
newTriggers.splice(index, 1)
|
newTriggers.splice(index, 1)
|
||||||
formData.value.triggers = newTriggers
|
formData.value.triggers = newTriggers
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 打开弹窗 */
|
/** 打开弹窗 */
|
||||||
const open = async (type: string, id?: number) => {
|
const open = async (type: string, id?: number) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
@ -158,7 +161,7 @@ const submitForm = async () => {
|
|||||||
/** 重置表单 */
|
/** 重置表单 */
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
status: 0,
|
status: 0, // TODO @puhui999:使用枚举值
|
||||||
triggers: [] as IotRuleSceneTriggerConfig[]
|
triggers: [] as IotRuleSceneTriggerConfig[]
|
||||||
} as RuleSceneVO
|
} as RuleSceneVO
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
>
|
>
|
||||||
<!-- TODO puhui999: 考虑根据属性类型不同展示不同的可选条件 -->
|
<!-- TODO puhui999: 考虑根据属性类型不同展示不同的可选条件 -->
|
||||||
|
<!-- TODO @puhui999:可以在 scene.types.ts IotRuleSceneTriggerConditionParameterOperatorEnum 枚举下 -->
|
||||||
<el-option label="等于" value="=" />
|
<el-option label="等于" value="=" />
|
||||||
<el-option label="不等于" value="!=" />
|
<el-option label="不等于" value="!=" />
|
||||||
<el-option label="大于" value=">" />
|
<el-option label="大于" value=">" />
|
||||||
@ -45,6 +46,7 @@ const selectedOperator = computed({
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<!-- TODO @puhui999:尽量用 unocss -->
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.condition-selector {
|
.condition-selector {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@ -19,13 +19,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex items-center mr-60px">
|
<div class="flex items-center mr-60px">
|
||||||
<span class="mr-10px">产品</span>
|
<span class="mr-10px">产品</span>
|
||||||
<el-button type="primary" @click="productTableSelectRef?.open()">
|
<el-button type="primary" @click="productTableSelectRef?.open()" size="small" plain>
|
||||||
|
<!-- TODO @puhui999:最终最好是,product ? product.name : '选择产品',减少取反 -->
|
||||||
{{ !product ? '选择产品' : product.name }}
|
{{ !product ? '选择产品' : product.name }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center mr-60px">
|
<div class="flex items-center mr-60px">
|
||||||
<span class="mr-10px">设备</span>
|
<span class="mr-10px">设备</span>
|
||||||
<el-button type="primary" @click="openDeviceSelect">
|
<el-button type="primary" @click="openDeviceSelect" size="small" plain>
|
||||||
{{ isEmpty(deviceList) ? '选择设备' : triggerConfig.deviceNames.join(',') }}
|
{{ isEmpty(deviceList) ? '选择设备' : triggerConfig.deviceNames.join(',') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@ -106,6 +107,7 @@
|
|||||||
<el-text class="ml-10px!" type="primary" @click="addCondition">添加触发条件</el-text>
|
<el-text class="ml-10px!" type="primary" @click="addCondition">添加触发条件</el-text>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 产品、设备的选择 -->
|
||||||
<IoTProductTableSelect ref="productTableSelectRef" @success="handleProductSelect" />
|
<IoTProductTableSelect ref="productTableSelectRef" @success="handleProductSelect" />
|
||||||
<IoTDeviceTableSelect
|
<IoTDeviceTableSelect
|
||||||
ref="deviceTableSelectRef"
|
ref="deviceTableSelectRef"
|
||||||
@ -152,6 +154,7 @@ const addCondition = () => {
|
|||||||
const removeCondition = (index: number) => {
|
const removeCondition = (index: number) => {
|
||||||
triggerConfig.value.conditions.splice(index, 1)
|
triggerConfig.value.conditions.splice(index, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 添加参数 */
|
/** 添加参数 */
|
||||||
const addConditionParameter = (conditionParameters: IotRuleSceneTriggerConditionParameter[]) => {
|
const addConditionParameter = (conditionParameters: IotRuleSceneTriggerConditionParameter[]) => {
|
||||||
if (!product.value) {
|
if (!product.value) {
|
||||||
@ -196,6 +199,7 @@ const openDeviceSelect = () => {
|
|||||||
/** 获取产品物模型 */
|
/** 获取产品物模型 */
|
||||||
const thingModelTSL = ref<any>()
|
const thingModelTSL = ref<any>()
|
||||||
const thingModels = computed(() => (condition: IotRuleSceneTriggerCondition) => {
|
const thingModels = computed(() => (condition: IotRuleSceneTriggerCondition) => {
|
||||||
|
// TODO @puhui999:这里最好也用枚举
|
||||||
switch (condition.type) {
|
switch (condition.type) {
|
||||||
case 'property':
|
case 'property':
|
||||||
return thingModelTSL.value.properties
|
return thingModelTSL.value.properties
|
||||||
@ -215,6 +219,7 @@ const getThingModelTSL = async () => {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<!-- TODO @puhui999:建议使用 unocss 哈 -->
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.device-listener {
|
.device-listener {
|
||||||
.device-listener-header {
|
.device-listener-header {
|
||||||
|
|||||||
@ -69,6 +69,7 @@
|
|||||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<!-- TODO @puhui999:触发器数组 => 触发器,然后展示 x 个? ps:执行器数组也类似哈。-->
|
||||||
<el-table-column label="触发器数组" align="center" prop="triggers" />
|
<el-table-column label="触发器数组" align="center" prop="triggers" />
|
||||||
<el-table-column label="执行器数组" align="center" prop="actions" />
|
<el-table-column label="执行器数组" align="center" prop="actions" />
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
|||||||
Reference in New Issue
Block a user