review:【IoT 物联网】场景联动的部分 review

This commit is contained in:
YunaiV
2025-07-18 23:55:51 +08:00
parent a72c297e86
commit bbd38e026b
23 changed files with 383 additions and 397 deletions

View File

@ -1,10 +1,11 @@
<!-- CRON 可视化构建器组件 -->
<!-- TODO @puhui999看看能不能复用全局的 cron 组件 -->
<template>
<div class="cron-builder">
<div class="builder-header">
<span class="header-title">可视化 CRON 编辑器</span>
</div>
<div class="builder-content">
<!-- 快捷选项 -->
<div class="quick-options">
@ -36,9 +37,9 @@
<el-option label="每分钟" value="*" />
<el-option
v-for="i in 60"
:key="i-1"
:label="`${i-1}分`"
:value="String(i-1)"
:key="i - 1"
:label="`${i - 1}分`"
:value="String(i - 1)"
/>
</el-select>
</el-form-item>
@ -49,9 +50,9 @@
<el-option label="每小时" value="*" />
<el-option
v-for="i in 24"
:key="i-1"
:label="`${i-1}时`"
:value="String(i-1)"
:key="i - 1"
:label="`${i - 1}时`"
:value="String(i - 1)"
/>
</el-select>
</el-form-item>
@ -60,12 +61,7 @@
<el-form-item label="日">
<el-select v-model="cronParts.day" @change="updateCronExpression">
<el-option label="每日" value="*" />
<el-option
v-for="i in 31"
:key="i"
:label="`${i}日`"
:value="String(i)"
/>
<el-option v-for="i in 31" :key="i" :label="`${i}日`" :value="String(i)" />
</el-select>
</el-form-item>
</el-col>
@ -132,7 +128,20 @@ const cronParts = reactive({
})
// 常量数据
const months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
const months = [
'1月',
'2月',
'3月',
'4月',
'5月',
'6月',
'7月',
'8月',
'9月',
'10月',
'11月',
'12月'
]
const weeks = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
// 快捷选项
@ -159,7 +168,7 @@ const applyQuickOption = (option: any) => {
const parseCronExpression = () => {
if (!localValue.value) return
const parts = localValue.value.split(' ')
if (parts.length >= 6) {
cronParts.second = parts[0] || '0'

View File

@ -1,4 +1,5 @@
<!-- CRON 表达式输入组件 -->
<!-- TODO @puhui999看看能不能复用全局的 cron 组件 -->
<template>
<div class="cron-input">
<el-input
@ -13,15 +14,10 @@
</el-tooltip>
</template>
</el-input>
<!-- 帮助信息 -->
<div v-if="showHelp" class="cron-help">
<el-alert
title="CRON 表达式格式:秒 分 时 日 月 周"
type="info"
:closable="false"
show-icon
>
<el-alert title="CRON 表达式格式:秒 分 时 日 月 周" type="info" :closable="false" show-icon>
<template #default>
<div class="help-content">
<p><strong>示例</strong></p>
@ -83,7 +79,7 @@ const validateExpression = () => {
emit('validate', { valid: false, message: '请输入CRON表达式' })
return
}
const isValid = validateCronExpression(localValue.value)
if (isValid) {
emit('validate', { valid: true, message: 'CRON表达式验证通过' })
@ -93,9 +89,12 @@ const validateExpression = () => {
}
// 监听值变化
watch(() => localValue.value, () => {
validateExpression()
})
watch(
() => localValue.value,
() => {
validateExpression()
}
)
// 初始化
onMounted(() => {

View File

@ -15,19 +15,10 @@
<!-- 描述模板 -->
<teleport to="body">
<div
v-if="showTemplates"
ref="templateDropdownRef"
class="templates"
:style="dropdownStyle"
>
<div v-if="showTemplates" ref="templateDropdownRef" class="templates" :style="dropdownStyle">
<div class="templates-header">
<span class="templates-title">描述模板</span>
<el-button
type="text"
size="small"
@click="showTemplates = false"
>
<el-button type="text" size="small" @click="showTemplates = false">
<Icon icon="ep:close" />
</el-button>
</div>
@ -45,13 +36,10 @@
</div>
</teleport>
<!-- TODO @puhui999不用模版哈简单点 -->
<!-- 模板按钮 -->
<div v-if="!localValue && !showTemplates" class="template-trigger">
<el-button
type="text"
size="small"
@click="toggleTemplates"
>
<el-button type="text" size="small" @click="toggleTemplates">
<Icon icon="ep:document" class="mr-1" />
使用模板
</el-button>
@ -163,8 +151,12 @@ const toggleTemplates = () => {
// 点击外部关闭下拉框
const handleClickOutside = (event: Event) => {
if (templateDropdownRef.value && !templateDropdownRef.value.contains(event.target as Node) &&
inputRef.value && !inputRef.value.$el.contains(event.target as Node)) {
if (
templateDropdownRef.value &&
!templateDropdownRef.value.contains(event.target as Node) &&
inputRef.value &&
!inputRef.value.$el.contains(event.target as Node)
) {
showTemplates.value = false
}
}

View File

@ -14,8 +14,9 @@
<Icon icon="ep:edit" class="input-icon" />
</template>
</el-input>
<!-- 智能提示 -->
<!-- TODO @puhui999暂时不用考虑智能推荐哈用途不大 -->
<div v-if="showSuggestions && suggestions.length > 0" class="suggestions">
<div class="suggestions-header">
<span class="suggestions-title">推荐名称</span>
@ -72,9 +73,12 @@ const nameTemplates = [
const handleInput = (value: string) => {
if (value.length > 0 && value.length < 10) {
// 根据输入内容过滤建议
suggestions.value = nameTemplates.filter(template =>
template.includes(value) || value.includes('温度') && template.includes('温度')
).slice(0, 5)
suggestions.value = nameTemplates
.filter(
(template) =>
template.includes(value) || (value.includes('温度') && template.includes('温度'))
)
.slice(0, 5)
showSuggestions.value = suggestions.value.length > 0
} else {
showSuggestions.value = false

View File

@ -1,4 +1,5 @@
<!-- 值输入组件 -->
<!-- TODO @yunai这个需要在看看 -->
<template>
<div class="value-input">
<!-- 布尔值选择 -->
@ -64,12 +65,7 @@
</el-input>
<div v-if="listPreview.length > 0" class="list-preview">
<span class="preview-label">解析结果</span>
<el-tag
v-for="(item, index) in listPreview"
:key="index"
size="small"
class="preview-tag"
>
<el-tag v-for="(item, index) in listPreview" :key="index" size="small" class="preview-tag">
{{ item }}
</el-tag>
</div>
@ -110,7 +106,11 @@
class="w-full"
>
<template #suffix>
<el-tooltip v-if="propertyConfig?.unit" :content="`单位:${propertyConfig.unit}`" placement="top">
<el-tooltip
v-if="propertyConfig?.unit"
:content="`单位:${propertyConfig.unit}`"
placement="top"
>
<span class="input-unit">{{ propertyConfig.unit }}</span>
</el-tooltip>
</template>
@ -172,7 +172,10 @@ const enumOptions = computed(() => {
const listPreview = computed(() => {
if (props.operator === 'in' && localValue.value) {
return localValue.value.split(',').map(item => item.trim()).filter(item => item)
return localValue.value
.split(',')
.map((item) => item.trim())
.filter((item) => item)
}
return []
})
@ -195,12 +198,12 @@ const getInputType = () => {
const getPlaceholder = () => {
const typeMap = {
'string': '请输入字符串',
'int': '请输入整数',
'float': '请输入浮点数',
'double': '请输入双精度数',
'struct': '请输入JSON格式数据',
'array': '请输入数组格式数据'
string: '请输入字符串',
int: '请输入整数',
float: '请输入浮点数',
double: '请输入双精度数',
struct: '请输入JSON格式数据',
array: '请输入数组格式数据'
}
return typeMap[props.propertyType || ''] || '请输入值'
}
@ -325,18 +328,24 @@ const validateValue = () => {
}
// 监听值变化
watch(() => localValue.value, () => {
validateValue()
})
watch(
() => localValue.value,
() => {
validateValue()
}
)
// 监听操作符变化
watch(() => props.operator, () => {
localValue.value = ''
rangeStart.value = ''
rangeEnd.value = ''
dateValue.value = ''
numberValue.value = undefined
})
watch(
() => props.operator,
() => {
localValue.value = ''
rangeStart.value = ''
rangeEnd.value = ''
dateValue.value = ''
numberValue.value = undefined
}
)
// 初始化
onMounted(() => {