|
|
@@ -18,27 +18,92 @@
|
|
|
<template v-if="form.stepType === 'ABILITY'">
|
|
|
<el-divider content-position="left">目标配置</el-divider>
|
|
|
|
|
|
- <el-form-item label="目标设备" prop="targetObjCode">
|
|
|
+ <!-- 新增:目标类型选择(设备/子系统) -->
|
|
|
+ <el-form-item label="目标类型">
|
|
|
+ <el-radio-group v-model="targetCategory" size="mini" @change="handleTargetCategoryChange">
|
|
|
+ <el-radio-button label="device">
|
|
|
+ <i class="el-icon-cpu"></i> 设备
|
|
|
+ </el-radio-button>
|
|
|
+ <el-radio-button label="subsystem">
|
|
|
+ <i class="el-icon-s-platform"></i> 子系统
|
|
|
+ </el-radio-button>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 设备选择 -->
|
|
|
+ <template v-if="targetCategory === 'device'">
|
|
|
+ <el-form-item label="目标设备" prop="targetObjCode">
|
|
|
+ <el-select
|
|
|
+ v-model="form.targetObjCode"
|
|
|
+ placeholder="请选择目标设备"
|
|
|
+ filterable
|
|
|
+ style="width: 100%"
|
|
|
+ @change="handleDeviceChange"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="device in deviceList"
|
|
|
+ :key="device.deviceCode"
|
|
|
+ :label="device.deviceName"
|
|
|
+ :value="device.deviceCode"
|
|
|
+ >
|
|
|
+ <span>{{ device.deviceName }}</span>
|
|
|
+ <span style="float: right; color: #909399; font-size: 12px">{{ device.deviceCode }}</span>
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 子系统选择 -->
|
|
|
+ <template v-if="targetCategory === 'subsystem'">
|
|
|
+ <el-form-item label="目标子系统" prop="targetObjCode">
|
|
|
+ <el-select
|
|
|
+ v-model="form.targetObjCode"
|
|
|
+ placeholder="请选择目标子系统"
|
|
|
+ filterable
|
|
|
+ style="width: 100%"
|
|
|
+ :loading="loadingSubsystem"
|
|
|
+ @change="handleSubsystemChange"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="subsystem in subsystemList"
|
|
|
+ :key="subsystem.systemCode"
|
|
|
+ :label="subsystem.systemName"
|
|
|
+ :value="subsystem.systemCode"
|
|
|
+ >
|
|
|
+ <span>{{ subsystem.systemName }}</span>
|
|
|
+ <span style="float: right; color: #909399; font-size: 12px">{{ subsystem.shortName }}</span>
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 设备/子系统能力选择 -->
|
|
|
+ <el-form-item label="设备能力" prop="abilityKey" v-if="targetCategory === 'device'">
|
|
|
<el-select
|
|
|
- v-model="form.targetObjCode"
|
|
|
- placeholder="请选择目标设备"
|
|
|
- filterable
|
|
|
+ v-model="form.abilityKey"
|
|
|
+ placeholder="请选择设备能力"
|
|
|
style="width: 100%"
|
|
|
- @change="handleDeviceChange"
|
|
|
+ :loading="loadingAbility"
|
|
|
+ @change="handleAbilityChange"
|
|
|
>
|
|
|
<el-option
|
|
|
- v-for="device in deviceList"
|
|
|
- :key="device.deviceCode"
|
|
|
- :label="device.deviceName"
|
|
|
- :value="device.deviceCode"
|
|
|
- />
|
|
|
+ v-for="ability in abilityList"
|
|
|
+ :key="ability.abilityKey"
|
|
|
+ :label="ability.abilityName"
|
|
|
+ :value="ability.abilityKey"
|
|
|
+ >
|
|
|
+ <span>{{ ability.abilityName }}</span>
|
|
|
+ <span style="float: right; color: #909399; font-size: 12px">{{ ability.abilityKey }}</span>
|
|
|
+ </el-option>
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="设备能力" prop="abilityKey">
|
|
|
+ <el-form-item label="系统能力" prop="abilityKey" v-if="targetCategory === 'subsystem'">
|
|
|
<el-select
|
|
|
v-model="form.abilityKey"
|
|
|
- placeholder="请选择设备能力"
|
|
|
+ placeholder="请选择系统能力"
|
|
|
style="width: 100%"
|
|
|
:loading="loadingAbility"
|
|
|
@change="handleAbilityChange"
|
|
|
@@ -48,7 +113,10 @@
|
|
|
:key="ability.abilityKey"
|
|
|
:label="ability.abilityName"
|
|
|
:value="ability.abilityKey"
|
|
|
- />
|
|
|
+ >
|
|
|
+ <span>{{ ability.abilityName }}</span>
|
|
|
+ <span style="float: right; color: #909399; font-size: 12px">{{ ability.abilityKey }}</span>
|
|
|
+ </el-option>
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
|
|
|
@@ -79,29 +147,79 @@
|
|
|
<el-input v-model="form.abilityParam" placeholder="请输入参数值" @input="emitChange" />
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
+
|
|
|
+ <el-form-item v-if="form.paramSource === 'CONTEXT'" label="上下文变量">
|
|
|
+ <el-select v-model="form.abilityParam" placeholder="请选择上下文变量" style="width: 100%" @change="emitChange">
|
|
|
+ <el-option
|
|
|
+ v-for="variable in contextVariables"
|
|
|
+ :key="variable.varKey"
|
|
|
+ :label="variable.varName"
|
|
|
+ :value="variable.varKey"
|
|
|
+ >
|
|
|
+ <span>{{ variable.varName }}</span>
|
|
|
+ <span style="float: right; color: #909399; font-size: 12px">{{ variable.varKey }}</span>
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
</template>
|
|
|
|
|
|
<!-- ==================== 属性查询配置 ==================== -->
|
|
|
<template v-if="form.stepType === 'ATTR_QUERY'">
|
|
|
<el-divider content-position="left">查询配置</el-divider>
|
|
|
|
|
|
- <el-form-item label="目标设备" prop="targetObjCode">
|
|
|
- <el-select
|
|
|
- v-model="form.targetObjCode"
|
|
|
- placeholder="请选择设备"
|
|
|
- filterable
|
|
|
- style="width: 100%"
|
|
|
- @change="handleQueryDeviceChange"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="device in deviceList"
|
|
|
- :key="device.deviceCode"
|
|
|
- :label="device.deviceName"
|
|
|
- :value="device.deviceCode"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
+ <!-- 新增:目标类型选择(设备/子系统) -->
|
|
|
+ <el-form-item label="目标类型">
|
|
|
+ <el-radio-group v-model="targetCategory" size="mini" @change="handleTargetCategoryChange">
|
|
|
+ <el-radio-button label="device">
|
|
|
+ <i class="el-icon-cpu"></i> 设备
|
|
|
+ </el-radio-button>
|
|
|
+ <el-radio-button label="subsystem">
|
|
|
+ <i class="el-icon-s-platform"></i> 子系统
|
|
|
+ </el-radio-button>
|
|
|
+ </el-radio-group>
|
|
|
</el-form-item>
|
|
|
|
|
|
+ <!-- 设备选择 -->
|
|
|
+ <template v-if="targetCategory === 'device'">
|
|
|
+ <el-form-item label="目标设备" prop="targetObjCode">
|
|
|
+ <el-select
|
|
|
+ v-model="form.targetObjCode"
|
|
|
+ placeholder="请选择设备"
|
|
|
+ filterable
|
|
|
+ style="width: 100%"
|
|
|
+ @change="handleQueryDeviceChange"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="device in deviceList"
|
|
|
+ :key="device.deviceCode"
|
|
|
+ :label="device.deviceName"
|
|
|
+ :value="device.deviceCode"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 子系统选择 -->
|
|
|
+ <template v-if="targetCategory === 'subsystem'">
|
|
|
+ <el-form-item label="目标子系统" prop="targetObjCode">
|
|
|
+ <el-select
|
|
|
+ v-model="form.targetObjCode"
|
|
|
+ placeholder="请选择子系统"
|
|
|
+ filterable
|
|
|
+ style="width: 100%"
|
|
|
+ :loading="loadingSubsystem"
|
|
|
+ @change="handleQuerySubsystemChange"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="subsystem in subsystemList"
|
|
|
+ :key="subsystem.systemCode"
|
|
|
+ :label="subsystem.systemName"
|
|
|
+ :value="subsystem.systemCode"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </template>
|
|
|
+
|
|
|
<el-form-item v-if="loadingQueryAttr">
|
|
|
<div style="color: #909399; font-size: 12px;">
|
|
|
<i class="el-icon-loading"></i> 正在加载属性列表...
|
|
|
@@ -268,6 +386,7 @@
|
|
|
|
|
|
<script>
|
|
|
import { getModelByCode } from '@/api/basecfg/objModel'
|
|
|
+import { listSubsystemAll } from '@/api/adapter/subsystem'
|
|
|
|
|
|
export default {
|
|
|
name: 'StepConfig',
|
|
|
@@ -284,7 +403,7 @@ export default {
|
|
|
stepName: '',
|
|
|
stepType: 'ABILITY',
|
|
|
targetObjCode: '',
|
|
|
- targetObjType: 2,
|
|
|
+ targetObjType: 2, // 2=设备, 1=子系统
|
|
|
targetModelCode: '',
|
|
|
abilityKey: '',
|
|
|
abilityParam: '',
|
|
|
@@ -300,6 +419,14 @@ export default {
|
|
|
stepName: [{ required: true, message: '请输入步骤名称', trigger: 'blur' }]
|
|
|
},
|
|
|
|
|
|
+ // 新增:目标类型选择
|
|
|
+ targetCategory: 'device', // 'device' 或 'subsystem'
|
|
|
+
|
|
|
+ // 子系统相关
|
|
|
+ subsystemList: [],
|
|
|
+ loadingSubsystem: false,
|
|
|
+ selectedSubsystem: null,
|
|
|
+
|
|
|
// 能力调用相关
|
|
|
abilityList: [],
|
|
|
currentAbility: null,
|
|
|
@@ -375,7 +502,13 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
|
|
|
+ created() {
|
|
|
+ // 预加载子系统列表
|
|
|
+ this.loadSubsystemList()
|
|
|
+ },
|
|
|
+
|
|
|
methods: {
|
|
|
+ // ========== 初始化 ==========
|
|
|
initFormFromStep(step) {
|
|
|
this.isUpdatingFromProp = true
|
|
|
|
|
|
@@ -393,13 +526,30 @@ export default {
|
|
|
this.continueOnFailSwitch = this.form.continueOnFail === 1
|
|
|
this.enableSwitch = this.form.enable === 1
|
|
|
|
|
|
+ // 根据 targetObjType 判断目标类型
|
|
|
+ // targetObjType: 1=子系统, 2=设备
|
|
|
+ if (step.targetObjType === 1) {
|
|
|
+ this.targetCategory = 'subsystem'
|
|
|
+ // 加载子系统并选中
|
|
|
+ this.loadSubsystemList().then(() => {
|
|
|
+ if (step.targetObjCode) {
|
|
|
+ this.selectedSubsystem = this.subsystemList.find(s => s.systemCode === step.targetObjCode)
|
|
|
+ if (this.selectedSubsystem && this.selectedSubsystem.modelCode) {
|
|
|
+ this.loadAbilities(this.selectedSubsystem.modelCode)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ this.targetCategory = 'device'
|
|
|
+ }
|
|
|
+
|
|
|
// 循环步骤解析跳出条件
|
|
|
if (step.stepType === 'LOOP' && step.loopCondition) {
|
|
|
this.parseLoopCondition(step.loopCondition)
|
|
|
}
|
|
|
|
|
|
// 能力调用加载能力列表
|
|
|
- if (step.stepType === 'ABILITY' && step.targetModelCode) {
|
|
|
+ if (step.stepType === 'ABILITY' && step.targetModelCode && this.targetCategory === 'device') {
|
|
|
this.loadAbilities(step.targetModelCode)
|
|
|
}
|
|
|
|
|
|
@@ -411,34 +561,47 @@ export default {
|
|
|
this.$nextTick(() => { this.isUpdatingFromProp = false })
|
|
|
},
|
|
|
|
|
|
- parseLoopCondition(loopCondition) {
|
|
|
+ // ========== 子系统相关 ==========
|
|
|
+ async loadSubsystemList() {
|
|
|
+ if (this.subsystemList.length > 0) return // 已加载则跳过
|
|
|
+
|
|
|
+ this.loadingSubsystem = true
|
|
|
try {
|
|
|
- const condition = JSON.parse(loopCondition)
|
|
|
- if (condition.breakType === 'ATTR' && condition.deviceCode) {
|
|
|
- this.loopBreakType = 'ATTR'
|
|
|
- this.breakConfig = {
|
|
|
- deviceCode: condition.deviceCode,
|
|
|
- modelCode: condition.modelCode || '',
|
|
|
- attrKey: condition.attrKey || '',
|
|
|
- operator: condition.operator || '==',
|
|
|
- value: condition.value || ''
|
|
|
- }
|
|
|
- if (condition.deviceCode) {
|
|
|
- const device = this.deviceList.find(d => d.deviceCode === condition.deviceCode)
|
|
|
- if (device) {
|
|
|
- const modelCode = device.deviceModel || device.modelCode
|
|
|
- if (modelCode) this.loadBreakAttrList(modelCode)
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- this.loopBreakType = 'EXPR'
|
|
|
- }
|
|
|
- } catch {
|
|
|
- this.loopBreakType = 'EXPR'
|
|
|
+ const res = await listSubsystemAll()
|
|
|
+ this.subsystemList = res.data || []
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载子系统列表失败:', error)
|
|
|
+ this.subsystemList = []
|
|
|
+ } finally {
|
|
|
+ this.loadingSubsystem = false
|
|
|
}
|
|
|
},
|
|
|
|
|
|
- // ========== 能力调用相关 ==========
|
|
|
+ // ========== 目标类型切换 ==========
|
|
|
+ handleTargetCategoryChange(category) {
|
|
|
+ // 清空之前的选择
|
|
|
+ this.form.targetObjCode = ''
|
|
|
+ this.form.targetModelCode = ''
|
|
|
+ this.form.abilityKey = ''
|
|
|
+ this.form.abilityParam = ''
|
|
|
+ this.abilityList = []
|
|
|
+ this.currentAbility = null
|
|
|
+ this.selectedSubsystem = null
|
|
|
+ this.queryAttrList = []
|
|
|
+ this.lastQueryModelCode = ''
|
|
|
+
|
|
|
+ // 更新 targetObjType
|
|
|
+ this.form.targetObjType = category === 'subsystem' ? 1 : 2
|
|
|
+
|
|
|
+ // 如果选择子系统,确保列表已加载
|
|
|
+ if (category === 'subsystem') {
|
|
|
+ this.loadSubsystemList()
|
|
|
+ }
|
|
|
+
|
|
|
+ this.emitChange()
|
|
|
+ },
|
|
|
+
|
|
|
+ // ========== 设备选择相关 ==========
|
|
|
handleDeviceChange(deviceCode) {
|
|
|
const device = this.deviceList.find(d => d.deviceCode === deviceCode)
|
|
|
if (device) {
|
|
|
@@ -452,6 +615,30 @@ export default {
|
|
|
this.emitChange()
|
|
|
},
|
|
|
|
|
|
+ // ========== 子系统选择相关 ==========
|
|
|
+ handleSubsystemChange(systemCode) {
|
|
|
+ const subsystem = this.subsystemList.find(s => s.systemCode === systemCode)
|
|
|
+ this.selectedSubsystem = subsystem
|
|
|
+
|
|
|
+ if (subsystem) {
|
|
|
+ this.form.targetModelCode = subsystem.modelCode || ''
|
|
|
+ this.form.targetObjType = 1 // 子系统类型
|
|
|
+
|
|
|
+ if (this.form.targetModelCode) {
|
|
|
+ this.loadAbilities(this.form.targetModelCode)
|
|
|
+ } else {
|
|
|
+ this.$message.warning('该子系统未配置物模型,无法获取能力列表')
|
|
|
+ this.abilityList = []
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.form.abilityKey = ''
|
|
|
+ this.form.abilityParam = ''
|
|
|
+ this.currentAbility = null
|
|
|
+ this.emitChange()
|
|
|
+ },
|
|
|
+
|
|
|
+ // ========== 能力加载 ==========
|
|
|
async loadAbilities(modelCode) {
|
|
|
if (!modelCode) return
|
|
|
this.loadingAbility = true
|
|
|
@@ -463,6 +650,7 @@ export default {
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error('加载能力失败:', error)
|
|
|
+ this.abilityList = []
|
|
|
} finally {
|
|
|
this.loadingAbility = false
|
|
|
}
|
|
|
@@ -479,13 +667,14 @@ export default {
|
|
|
this.emitChange()
|
|
|
},
|
|
|
|
|
|
- // ========== 属性查询相关 ==========
|
|
|
+ // ========== 属性查询相关(设备) ==========
|
|
|
async handleQueryDeviceChange(deviceCode) {
|
|
|
const device = this.deviceList.find(d => d.deviceCode === deviceCode)
|
|
|
if (!device) return
|
|
|
|
|
|
const modelCode = device.deviceModel || device.modelCode
|
|
|
this.form.targetModelCode = modelCode || ''
|
|
|
+ this.form.targetObjType = 2
|
|
|
this.form.abilityKey = ''
|
|
|
this.queryAttrList = []
|
|
|
this.lastQueryModelCode = ''
|
|
|
@@ -498,6 +687,28 @@ export default {
|
|
|
this.emitChange()
|
|
|
},
|
|
|
|
|
|
+ // ========== 属性查询相关(子系统) ==========
|
|
|
+ async handleQuerySubsystemChange(systemCode) {
|
|
|
+ const subsystem = this.subsystemList.find(s => s.systemCode === systemCode)
|
|
|
+ this.selectedSubsystem = subsystem
|
|
|
+
|
|
|
+ if (!subsystem) return
|
|
|
+
|
|
|
+ const modelCode = subsystem.modelCode || ''
|
|
|
+ this.form.targetModelCode = modelCode
|
|
|
+ this.form.targetObjType = 1
|
|
|
+ this.form.abilityKey = ''
|
|
|
+ this.queryAttrList = []
|
|
|
+ this.lastQueryModelCode = ''
|
|
|
+
|
|
|
+ if (modelCode) {
|
|
|
+ await this.loadQueryAttrList(modelCode)
|
|
|
+ } else {
|
|
|
+ this.$message.warning('该子系统未配置物模型')
|
|
|
+ }
|
|
|
+ this.emitChange()
|
|
|
+ },
|
|
|
+
|
|
|
async loadQueryAttrList(modelCode) {
|
|
|
if (!modelCode || modelCode === this.lastQueryModelCode) return
|
|
|
if (this.loadingQueryAttr) return
|
|
|
@@ -526,7 +737,34 @@ export default {
|
|
|
this.emitChange()
|
|
|
},
|
|
|
|
|
|
- // ========== 循环跳出条件相关 ==========
|
|
|
+ // ========== 循环跳出条件 ==========
|
|
|
+ parseLoopCondition(loopCondition) {
|
|
|
+ try {
|
|
|
+ const condition = JSON.parse(loopCondition)
|
|
|
+ if (condition.breakType === 'ATTR' && condition.deviceCode) {
|
|
|
+ this.loopBreakType = 'ATTR'
|
|
|
+ this.breakConfig = {
|
|
|
+ deviceCode: condition.deviceCode,
|
|
|
+ modelCode: condition.modelCode || '',
|
|
|
+ attrKey: condition.attrKey || '',
|
|
|
+ operator: condition.operator || '==',
|
|
|
+ value: condition.value || ''
|
|
|
+ }
|
|
|
+ if (condition.deviceCode) {
|
|
|
+ const device = this.deviceList.find(d => d.deviceCode === condition.deviceCode)
|
|
|
+ if (device) {
|
|
|
+ const modelCode = device.deviceModel || device.modelCode
|
|
|
+ if (modelCode) this.loadBreakAttrList(modelCode)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.loopBreakType = 'EXPR'
|
|
|
+ }
|
|
|
+ } catch {
|
|
|
+ this.loopBreakType = 'EXPR'
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
switchBreakType(type) {
|
|
|
this.loopBreakType = type
|
|
|
if (type === 'ATTR') {
|
|
|
@@ -688,6 +926,33 @@ export default {
|
|
|
margin: 16px 0 12px;
|
|
|
}
|
|
|
|
|
|
+ // 目标信息卡片
|
|
|
+ .target-info-card,
|
|
|
+ .ability-info-card {
|
|
|
+ background: #f5f7fa;
|
|
|
+ border-radius: 6px;
|
|
|
+ padding: 12px;
|
|
|
+ border-left: 3px solid #409eff;
|
|
|
+
|
|
|
+ .info-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ &:last-child { margin-bottom: 0; }
|
|
|
+
|
|
|
+ .info-label {
|
|
|
+ color: #909399;
|
|
|
+ font-size: 12px;
|
|
|
+ width: 70px;
|
|
|
+ flex-shrink: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .ability-info-card {
|
|
|
+ border-left-color: #67c23a;
|
|
|
+ }
|
|
|
+
|
|
|
.attr-info-card {
|
|
|
background: #f5f7fa;
|
|
|
border-radius: 6px;
|
|
|
@@ -747,5 +1012,18 @@ export default {
|
|
|
display: flex;
|
|
|
gap: 8px;
|
|
|
}
|
|
|
+
|
|
|
+ // 单选按钮组样式优化
|
|
|
+ :deep(.el-radio-group) {
|
|
|
+ .el-radio-button__inner {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 4px;
|
|
|
+
|
|
|
+ i {
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|