chore(iot): 数组回调缩写参数展开为完整业务命名

- products.find((p)) → ((product)),propertyList.find((p)) → ((property))
  等:把 .find / .filter / .map / .reduce 的单字母回调参数 (p / d / s / g / v
  / acc / val) 全部展开为 product / device / service / group / value /
  total 等完整命名
- 涉及 web-antd 与 web-ele 两侧 :device 列表 / 卡片 / 物模型属性历史 /
  ota 固件 / 场景执行器服务选择 / 属性选择器 / 产品选择组件
- 外层已绑定同名变量的场景,回调形参用 item 避免命名重复
pull/345/head
YunaiV 2026-05-21 18:46:59 +08:00
parent 83bf576daf
commit 66843f2392
32 changed files with 169 additions and 105 deletions

View File

@ -65,5 +65,6 @@ const useVbenForm = useForm<ComponentType, ComponentPropsMap>;
export { initSetupVbenForm, useVbenForm, z }; export { initSetupVbenForm, useVbenForm, z };
export type VbenFormApi = ReturnType<typeof useVbenForm>[1]; // add by 芋艿:用于 data.ts 表单 schema 内调用 setFieldValue
export type VbenFormSchema = FormSchema<ComponentType, ComponentPropsMap>; export type VbenFormSchema = FormSchema<ComponentType, ComponentPropsMap>;
export type VbenFormProps = FormProps<ComponentType, ComponentPropsMap>; export type VbenFormProps = FormProps<ComponentType, ComponentPropsMap>;

View File

@ -85,7 +85,7 @@ const maxValue = computed(() => {
if (!canShowChart.value || list.value.length === 0) return '-'; if (!canShowChart.value || list.value.length === 0) return '-';
const values = list.value const values = list.value
.map((item) => Number(item.value)) .map((item) => Number(item.value))
.filter((v) => !Number.isNaN(v)); .filter((value) => !Number.isNaN(value));
return values.length > 0 ? Math.max(...values).toFixed(2) : '-'; return values.length > 0 ? Math.max(...values).toFixed(2) : '-';
}); });
@ -94,7 +94,7 @@ const minValue = computed(() => {
if (!canShowChart.value || list.value.length === 0) return '-'; if (!canShowChart.value || list.value.length === 0) return '-';
const values = list.value const values = list.value
.map((item) => Number(item.value)) .map((item) => Number(item.value))
.filter((v) => !Number.isNaN(v)); .filter((value) => !Number.isNaN(value));
return values.length > 0 ? Math.min(...values).toFixed(2) : '-'; return values.length > 0 ? Math.min(...values).toFixed(2) : '-';
}); });
@ -103,9 +103,9 @@ const avgValue = computed(() => {
if (!canShowChart.value || list.value.length === 0) return '-'; if (!canShowChart.value || list.value.length === 0) return '-';
const values = list.value const values = list.value
.map((item) => Number(item.value)) .map((item) => Number(item.value))
.filter((v) => !Number.isNaN(v)); .filter((value) => !Number.isNaN(value));
if (values.length === 0) return '-'; if (values.length === 0) return '-';
const sum = values.reduce((acc, val) => acc + val, 0); const sum = values.reduce((total, value) => total + value, 0);
return (sum / values.length).toFixed(2); return (sum / values.length).toFixed(2);
}); });

View File

@ -434,7 +434,10 @@ onMounted(async () => {
class="cursor-pointer text-primary" class="cursor-pointer text-primary"
@click="openProductDetail(row.productId)" @click="openProductDetail(row.productId)"
> >
{{ products.find((p) => p.id === row.productId)?.name || '-' }} {{
products.find((product) => product.id === row.productId)?.name ||
'-'
}}
</a> </a>
</template> </template>
<template #groups="{ row }"> <template #groups="{ row }">
@ -445,7 +448,7 @@ onMounted(async () => {
size="small" size="small"
class="mr-1" class="mr-1"
> >
{{ deviceGroups.find((g) => g.id === groupId)?.name }} {{ deviceGroups.find((group) => group.id === groupId)?.name }}
</Tag> </Tag>
</template> </template>
<span v-else>-</span> <span v-else>-</span>

View File

@ -48,7 +48,7 @@ const [Form, formApi] = useVbenForm({
return; return;
} }
// //
const product = products.value.find((p) => p.id === productId); const product = products.value.find((item) => item.id === productId);
if (product?.deviceType !== undefined) { if (product?.deviceType !== undefined) {
await formApi.setFieldValue('deviceType', product.deviceType); await formApi.setFieldValue('deviceType', product.deviceType);
} }

View File

@ -17,7 +17,9 @@ export function getProductName(productId?: number): string {
if (!productId) { if (!productId) {
return '-'; return '-';
} }
return productList.find((p) => p.id === productId)?.name || '-'; return (
productList.find((product) => product.id === productId)?.name || '-'
);
} }
/** 固件详情的描述字段 */ /** 固件详情的描述字段 */

View File

@ -47,7 +47,12 @@ onMounted(() => {
<template> <template>
<Select <Select
:value="modelValue" :value="modelValue"
:options="productList.map((p) => ({ label: p.name, value: p.id }))" :options="
productList.map((product) => ({
label: product.name,
value: product.id,
}))
"
:loading="loading" :loading="loading"
placeholder="请选择产品" placeholder="请选择产品"
allow-clear allow-clear

View File

@ -108,7 +108,9 @@ function handleDeviceChange(deviceId?: number) {
function handleServiceChange(serviceIdentifier?: any) { function handleServiceChange(serviceIdentifier?: any) {
// //
const service = const service =
serviceList.value.find((s) => s.identifier === serviceIdentifier) || null; serviceList.value.find(
(item) => item.identifier === serviceIdentifier,
) || null;
selectedService.value = service; selectedService.value = service;
// //

View File

@ -91,12 +91,16 @@ const propertyGroups = computed(() => {
/** 当前选中的属性 */ /** 当前选中的属性 */
const selectedProperty = computed(() => const selectedProperty = computed(() =>
propertyList.value.find((p) => p.identifier === localValue.value), propertyList.value.find(
(property) => property.identifier === localValue.value,
),
); );
/** 处理选择变化事件 */ /** 处理选择变化事件 */
function handleChange(value: any) { function handleChange(value: any) {
const property = propertyList.value.find((p) => p.identifier === value); const property = propertyList.value.find(
(item) => item.identifier === value,
);
if (property) { if (property) {
emit('change', { type: property.dataType, config: property }); emit('change', { type: property.dataType, config: property });
} }

View File

@ -57,5 +57,6 @@ const useVbenForm = useForm<ComponentType, ComponentPropsMap>;
export { initSetupVbenForm, useVbenForm, z }; export { initSetupVbenForm, useVbenForm, z };
export type VbenFormApi = ReturnType<typeof useVbenForm>[1]; // add by 芋艿:用于 data.ts 表单 schema 内调用 setFieldValue
export type VbenFormSchema = FormSchema<ComponentType, ComponentPropsMap>; export type VbenFormSchema = FormSchema<ComponentType, ComponentPropsMap>;
export type VbenFormProps = FormProps<ComponentType, ComponentPropsMap>; export type VbenFormProps = FormProps<ComponentType, ComponentPropsMap>;

View File

@ -85,7 +85,7 @@ const maxValue = computed(() => {
if (!canShowChart.value || list.value.length === 0) return '-'; if (!canShowChart.value || list.value.length === 0) return '-';
const values = list.value const values = list.value
.map((item) => Number(item.value)) .map((item) => Number(item.value))
.filter((v) => !Number.isNaN(v)); .filter((value) => !Number.isNaN(value));
return values.length > 0 ? Math.max(...values).toFixed(2) : '-'; return values.length > 0 ? Math.max(...values).toFixed(2) : '-';
}); });
@ -94,7 +94,7 @@ const minValue = computed(() => {
if (!canShowChart.value || list.value.length === 0) return '-'; if (!canShowChart.value || list.value.length === 0) return '-';
const values = list.value const values = list.value
.map((item) => Number(item.value)) .map((item) => Number(item.value))
.filter((v) => !Number.isNaN(v)); .filter((value) => !Number.isNaN(value));
return values.length > 0 ? Math.min(...values).toFixed(2) : '-'; return values.length > 0 ? Math.min(...values).toFixed(2) : '-';
}); });
@ -103,9 +103,9 @@ const avgValue = computed(() => {
if (!canShowChart.value || list.value.length === 0) return '-'; if (!canShowChart.value || list.value.length === 0) return '-';
const values = list.value const values = list.value
.map((item) => Number(item.value)) .map((item) => Number(item.value))
.filter((v) => !Number.isNaN(v)); .filter((value) => !Number.isNaN(value));
if (values.length === 0) return '-'; if (values.length === 0) return '-';
const sum = values.reduce((acc, val) => acc + val, 0); const sum = values.reduce((total, value) => total + value, 0);
return (sum / values.length).toFixed(2); return (sum / values.length).toFixed(2);
}); });

View File

@ -334,7 +334,7 @@ onBeforeUnmount(() => {
<!-- 标题区域 --> <!-- 标题区域 -->
<div class="mb-3 flex items-center"> <div class="mb-3 flex items-center">
<div class="mr-2.5 flex items-center"> <div class="mr-2.5 flex items-center">
<IconifyIcon class="text-lg text-primary" icon="ep:cpu" /> <IconifyIcon class="text-lg text-[var(--el-color-primary)]" icon="ep:cpu" />
</div> </div>
<div class="flex-1 text-base font-bold">{{ item.name }}</div> <div class="flex-1 text-base font-bold">{{ item.name }}</div>
<!-- 标识符 --> <!-- 标识符 -->
@ -357,7 +357,7 @@ onBeforeUnmount(() => {
" "
> >
<IconifyIcon <IconifyIcon
class="text-lg text-primary" class="text-lg text-[var(--el-color-primary)]"
icon="ep:data-line" icon="ep:data-line"
/> />
</div> </div>

View File

@ -425,10 +425,13 @@ onMounted(async () => {
<Grid table-title="" v-show="viewMode === 'list'"> <Grid table-title="" v-show="viewMode === 'list'">
<template #product="{ row }"> <template #product="{ row }">
<a <a
class="cursor-pointer text-primary" class="cursor-pointer text-[var(--el-color-primary)]"
@click="openProductDetail(row.productId)" @click="openProductDetail(row.productId)"
> >
{{ products.find((p) => p.id === row.productId)?.name || '-' }} {{
products.find((product) => product.id === row.productId)?.name ||
'-'
}}
</a> </a>
</template> </template>
<template #groups="{ row }"> <template #groups="{ row }">
@ -439,7 +442,7 @@ onMounted(async () => {
size="small" size="small"
class="mr-1" class="mr-1"
> >
{{ deviceGroups.find((g) => g.id === groupId)?.name }} {{ deviceGroups.find((group) => group.id === groupId)?.name }}
</ElTag> </ElTag>
</template> </template>
<span v-else>-</span> <span v-else>-</span>

View File

@ -150,7 +150,7 @@ onMounted(() => {
所属产品 所属产品
</span> </span>
<a <a
class="cursor-pointer truncate font-medium text-primary" class="cursor-pointer truncate font-medium text-[var(--el-color-primary)]"
@click=" @click="
(e) => { (e) => {
e.stopPropagation(); e.stopPropagation();

View File

@ -53,7 +53,7 @@ const [Form, formApi] = useVbenForm({
return; return;
} }
// //
const product = products.value.find((p) => p.id === productId); const product = products.value.find((item) => item.id === productId);
if (product?.deviceType !== undefined) { if (product?.deviceType !== undefined) {
await formApi.setFieldValue('deviceType', product.deviceType); await formApi.setFieldValue('deviceType', product.deviceType);
} }

View File

@ -17,7 +17,9 @@ export function getProductName(productId?: number): string {
if (!productId) { if (!productId) {
return '-'; return '-';
} }
return productList.find((p) => p.id === productId)?.name || '-'; return (
productList.find((product) => product.id === productId)?.name || '-'
);
} }
/** 固件详情的描述字段 */ /** 固件详情的描述字段 */

View File

@ -114,7 +114,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
<template #productName="{ row }"> <template #productName="{ row }">
<a <a
v-if="row.productId" v-if="row.productId"
class="cursor-pointer text-primary hover:underline" class="cursor-pointer text-[var(--el-color-primary)] hover:underline"
@click="handleOpenProductDetail(row.productId)" @click="handleOpenProductDetail(row.productId)"
> >
{{ getProductName(row.productId) }} {{ getProductName(row.productId) }}
@ -129,13 +129,13 @@ const [Grid, gridApi] = useVbenVxeGrid({
> >
<IconifyIcon <IconifyIcon
icon="ant-design:download-outlined" icon="ant-design:download-outlined"
class="shrink-0 align-middle text-base text-primary" class="shrink-0 align-middle text-base text-[var(--el-color-primary)]"
/> />
<a <a
:href="row.fileUrl" :href="row.fileUrl"
target="_blank" target="_blank"
download download
class="cursor-pointer align-middle text-primary hover:underline" class="cursor-pointer align-middle text-[var(--el-color-primary)] hover:underline"
> >
下载固件 下载固件
</a> </a>

View File

@ -78,9 +78,7 @@ export function useFormSchema(): VbenFormSchema[] {
componentProps: { componentProps: {
multiple: true, multiple: true,
placeholder: '请选择设备', placeholder: '请选择设备',
showSearch: true, filterable: true,
filterOption: true,
optionFilterProp: 'label',
}, },
defaultValue: [], defaultValue: [],
dependencies: { dependencies: {

View File

@ -15,7 +15,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'Input', component: 'Input',
componentProps: { componentProps: {
placeholder: '请输入规则名称', placeholder: '请输入规则名称',
allowClear: true, clearable: true,
}, },
}, },
{ {
@ -25,7 +25,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
componentProps: { componentProps: {
options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'),
placeholder: '请选择状态', placeholder: '请选择状态',
allowClear: true, clearable: true,
}, },
}, },
{ {
@ -34,7 +34,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
component: 'RangePicker', component: 'RangePicker',
componentProps: { componentProps: {
...getRangePickerDefaultProps(), ...getRangePickerDefaultProps(),
allowClear: true, clearable: true,
}, },
}, },
]; ];

View File

@ -87,9 +87,9 @@ const needsTimeInput = computed(() => {
return timeOnlyOperators.includes(condition.value.operator as any); return timeOnlyOperators.includes(condition.value.operator as any);
}); });
// /** 是否需要日期输入 ;当前仅支持时间 */
const needsDateInput = computed(() => { const needsDateInput = computed(() => {
return false; // return false;
}); });
// //
@ -225,7 +225,7 @@ watch(
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
class="w-full" class="w-full"
/> />
<div v-else class="text-sm text-secondary">无需设置时间值</div> <div v-else class="text-sm text-[var(--el-text-color-secondary)]">无需设置时间值</div>
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>

View File

@ -115,7 +115,9 @@ function handleDeviceChange(deviceId?: number) {
function handleServiceChange(serviceIdentifier?: any) { function handleServiceChange(serviceIdentifier?: any) {
// //
const service = const service =
serviceList.value.find((s) => s.identifier === serviceIdentifier) || null; serviceList.value.find(
(item) => item.identifier === serviceIdentifier,
) || null;
selectedService.value = service; selectedService.value = service;
// //

View File

@ -365,10 +365,10 @@ function handlePropertyChange(propertyInfo: any) {
<!-- 其他触发类型的提示 --> <!-- 其他触发类型的提示 -->
<div v-else class="py-5 text-center"> <div v-else class="py-5 text-center">
<p class="mb-1 text-sm text-secondary"> <p class="mb-1 text-sm text-[var(--el-text-color-secondary)]">
当前触发事件类型{{ getTriggerTypeLabel(triggerType) }} 当前触发事件类型{{ getTriggerTypeLabel(triggerType) }}
</p> </p>
<p class="text-xs text-secondary">此触发类型暂不需要配置额外条件</p> <p class="text-xs text-[var(--el-text-color-secondary)]">此触发类型暂不需要配置额外条件</p>
</div> </div>
</div> </div>
</template> </template>

View File

@ -89,8 +89,8 @@ function updateCondition(
<!-- 空状态 --> <!-- 空状态 -->
<div v-if="!subGroup || subGroup.length === 0" class="py-6 text-center"> <div v-if="!subGroup || subGroup.length === 0" class="py-6 text-center">
<div class="flex flex-col items-center gap-3"> <div class="flex flex-col items-center gap-3">
<IconifyIcon icon="lucide:plus" class="text-8 text-secondary" /> <IconifyIcon icon="lucide:plus" class="text-8 text-[var(--el-text-color-secondary)]" />
<div class="text-secondary"> <div class="text-[var(--el-text-color-secondary)]">
<p class="mb-1 text-base font-bold">暂无条件</p> <p class="mb-1 text-base font-bold">暂无条件</p>
<p class="text-xs">点击下方按钮添加第一个条件</p> <p class="text-xs">点击下方按钮添加第一个条件</p>
</div> </div>
@ -121,7 +121,7 @@ function updateCondition(
> >
{{ conditionIndex + 1 }} {{ conditionIndex + 1 }}
</div> </div>
<span class="text-base font-bold text-primary"> <span class="text-base font-bold text-[var(--el-text-color-primary)]">
条件 {{ conditionIndex + 1 }} 条件 {{ conditionIndex + 1 }}
</span> </span>
</div> </div>
@ -161,7 +161,7 @@ function updateCondition(
<IconifyIcon icon="lucide:plus" /> <IconifyIcon icon="lucide:plus" />
继续添加条件 继续添加条件
</ElButton> </ElButton>
<span class="mt-2 block text-xs text-secondary"> <span class="mt-2 block text-xs text-[var(--el-text-color-secondary)]">
最多可添加 {{ maxConditions }} 个条件 最多可添加 {{ maxConditions }} 个条件
</span> </span>
</div> </div>

View File

@ -450,8 +450,11 @@ watch(
<!-- 弹出层内容 --> <!-- 弹出层内容 -->
<div class="json-params-detail-content"> <div class="json-params-detail-content">
<div class="mb-4 flex items-center gap-2"> <div class="mb-4 flex items-center gap-2">
<IconifyIcon :icon="titleIcon" class="text-lg text-primary" /> <IconifyIcon
<span class="text-base font-bold text-primary"> :icon="titleIcon"
class="text-lg text-[var(--el-color-primary)]"
/>
<span class="text-base font-bold text-[var(--el-text-color-primary)]">
{{ title }} {{ title }}
</span> </span>
</div> </div>
@ -462,9 +465,9 @@ watch(
<div class="mb-2 flex items-center gap-2"> <div class="mb-2 flex items-center gap-2">
<IconifyIcon <IconifyIcon
:icon="paramsIcon" :icon="paramsIcon"
class="text-base text-primary" class="text-base text-[var(--el-color-primary)]"
/> />
<span class="text-base font-bold text-primary"> <span class="text-base font-bold text-[var(--el-text-color-primary)]">
{{ paramsLabel }} {{ paramsLabel }}
</span> </span>
</div> </div>
@ -475,7 +478,7 @@ watch(
class="flex items-center justify-between rounded-lg bg-card p-2" class="flex items-center justify-between rounded-lg bg-card p-2"
> >
<div class="flex-1"> <div class="flex-1">
<div class="text-base font-bold text-primary"> <div class="text-base font-bold text-[var(--el-text-color-primary)]">
{{ param.name }} {{ param.name }}
<ElTag <ElTag
v-if="param.required" v-if="param.required"
@ -486,7 +489,7 @@ watch(
{{ JSON_PARAMS_INPUT_CONSTANTS.REQUIRED_TAG }} {{ JSON_PARAMS_INPUT_CONSTANTS.REQUIRED_TAG }}
</ElTag> </ElTag>
</div> </div>
<div class="text-xs text-secondary"> <div class="text-xs text-[var(--el-text-color-secondary)]">
{{ param.identifier }} {{ param.identifier }}
</div> </div>
</div> </div>
@ -494,7 +497,7 @@ watch(
<ElTag :type="getParamTypeTag(param.dataType)" size="small"> <ElTag :type="getParamTypeTag(param.dataType)" size="small">
{{ getParamTypeName(param.dataType) }} {{ getParamTypeName(param.dataType) }}
</ElTag> </ElTag>
<span class="text-xs text-secondary"> <span class="text-xs text-[var(--el-text-color-secondary)]">
{{ getExampleValue(param) }} {{ getExampleValue(param) }}
</span> </span>
</div> </div>
@ -502,11 +505,11 @@ watch(
</div> </div>
<div class="ml-6 mt-3"> <div class="ml-6 mt-3">
<div class="mb-1 text-xs text-secondary"> <div class="mb-1 text-xs text-[var(--el-text-color-secondary)]">
{{ JSON_PARAMS_INPUT_CONSTANTS.COMPLETE_JSON_FORMAT }} {{ JSON_PARAMS_INPUT_CONSTANTS.COMPLETE_JSON_FORMAT }}
</div> </div>
<pre <pre
class="border-l-3px overflow-x-auto rounded-lg border-primary bg-card p-3 text-sm text-primary" class="border-l-3px overflow-x-auto rounded-lg border-[var(--el-color-primary)] bg-[var(--el-fill-color-light)] p-3 text-sm text-[var(--el-text-color-primary)]"
> >
<code>{{ generateExampleJson() }}</code> <code>{{ generateExampleJson() }}</code>
</pre> </pre>
@ -516,7 +519,7 @@ watch(
<!-- 无参数提示 --> <!-- 无参数提示 -->
<div v-else> <div v-else>
<div class="py-4 text-center"> <div class="py-4 text-center">
<p class="text-sm text-secondary"> <p class="text-sm text-[var(--el-text-color-secondary)]">
{{ emptyMessage }} {{ emptyMessage }}
</p> </p>
</div> </div>
@ -550,7 +553,7 @@ watch(
<!-- 快速填充按钮 --> <!-- 快速填充按钮 -->
<div v-if="paramsList.length > 0" class="flex items-center gap-2"> <div v-if="paramsList.length > 0" class="flex items-center gap-2">
<span class="text-xs text-secondary"> <span class="text-xs text-[var(--el-text-color-secondary)]">
{{ JSON_PARAMS_INPUT_CONSTANTS.QUICK_FILL_LABEL }} {{ JSON_PARAMS_INPUT_CONSTANTS.QUICK_FILL_LABEL }}
</span> </span>
<ElButton size="small" type="primary" plain @click="fillExampleJson"> <ElButton size="small" type="primary" plain @click="fillExampleJson">

View File

@ -205,7 +205,7 @@ watch(
class="min-w-0 flex-1" class="min-w-0 flex-1"
style="width: auto !important" style="width: auto !important"
/> />
<span class="whitespace-nowrap text-xs text-secondary"> </span> <span class="whitespace-nowrap text-xs text-[var(--el-text-color-secondary)]"> </span>
<ElInput <ElInput
v-model="rangeEnd" v-model="rangeEnd"
:type="getInputType()" :type="getInputType()"
@ -240,7 +240,7 @@ watch(
v-if="listPreview.length > 0" v-if="listPreview.length > 0"
class="mt-2 flex flex-wrap items-center gap-1" class="mt-2 flex flex-wrap items-center gap-1"
> >
<span class="text-xs text-secondary"> 解析结果 </span> <span class="text-xs text-[var(--el-text-color-secondary)]"> 解析结果 </span>
<ElTag <ElTag
v-for="(item, index) in listPreview" v-for="(item, index) in listPreview"
:key="index" :key="index"
@ -292,7 +292,7 @@ watch(
:content="`单位:${propertyConfig.unit}`" :content="`单位:${propertyConfig.unit}`"
placement="top" placement="top"
> >
<span class="px-1 text-xs text-secondary"> <span class="px-1 text-xs text-[var(--el-text-color-secondary)]">
{{ propertyConfig.unit }} {{ propertyConfig.unit }}
</span> </span>
</ElTooltip> </ElTooltip>

View File

@ -156,12 +156,20 @@ function onActionTypeChange(action: RuleSceneApi.Action, type: number) {
</script> </script>
<template> <template>
<ElCard class="rounded-lg border border-primary" shadow="never"> <ElCard
class="rounded-8px border border-[var(--el-border-color-light)]"
shadow="never"
>
<template #header> <template #header>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div class="gap-8px flex items-center"> <div class="gap-8px flex items-center">
<IconifyIcon icon="ep:setting" class="text-18px text-primary" /> <IconifyIcon
<span class="text-16px font-600 text-primary"> 执行器配置 </span> icon="ep:setting"
class="text-18px text-[var(--el-color-primary)]"
/>
<span class="text-16px font-600 text-[var(--el-text-color-primary)]">
执行器配置
</span>
<ElTag size="small" type="info"> <ElTag size="small" type="info">
{{ actions.length }} 个执行器 {{ actions.length }} 个执行器
</ElTag> </ElTag>
@ -271,14 +279,19 @@ function onActionTypeChange(action: RuleSceneApi.Action, type: number) {
<!-- 触发告警提示 - 触发告警时显示 --> <!-- 触发告警提示 - 触发告警时显示 -->
<div <div
v-if="action.type === IotRuleSceneActionTypeEnum.ALERT_TRIGGER" v-if="action.type === IotRuleSceneActionTypeEnum.ALERT_TRIGGER"
class="bg-fill-color-blank rounded-lg border border-border p-4" class="rounded-6px border border-[var(--el-border-color-light)] bg-[var(--el-fill-color-blank)] p-4"
> >
<div class="mb-2 flex items-center gap-2"> <div class="mb-2 flex items-center gap-2">
<IconifyIcon icon="ep:warning" class="text-base text-warning" /> <IconifyIcon
<span class="font-600 text-sm text-primary">触发告警</span> icon="ep:warning"
class="text-base text-[var(--el-color-warning)]"
/>
<span class="font-600 text-sm text-[var(--el-text-color-primary)]">
触发告警
</span>
<ElTag size="small" type="warning">自动执行</ElTag> <ElTag size="small" type="warning">自动执行</ElTag>
</div> </div>
<div class="text-xs leading-relaxed text-secondary"> <div class="text-xs leading-relaxed text-[var(--el-text-color-secondary)]">
当触发条件满足时系统将自动发送告警通知可在菜单 [告警中心 -> 当触发条件满足时系统将自动发送告警通知可在菜单 [告警中心 ->
告警配置] 管理 告警配置] 管理
</div> </div>

View File

@ -24,7 +24,6 @@ defineOptions({ name: 'BasicInfoSection' });
const props = defineProps<{ const props = defineProps<{
modelValue: RuleSceneApi.SceneRule; modelValue: RuleSceneApi.SceneRule;
rules?: any;
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
@ -35,12 +34,20 @@ const formData = useVModel(props, 'modelValue', emit); // 表单数据
</script> </script>
<template> <template>
<ElCard class="rounded-8px mb-10px border border-primary" shadow="never"> <ElCard
class="rounded-8px mb-10px border border-[var(--el-border-color-light)]"
shadow="never"
>
<template #header> <template #header>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div class="gap-8px flex items-center"> <div class="gap-8px flex items-center">
<IconifyIcon icon="ep:info-filled" class="text-18px text-primary" /> <IconifyIcon
<span class="text-16px font-600 text-primary">基础信息</span> icon="ep:info-filled"
class="text-18px text-[var(--el-color-primary)]"
/>
<span class="text-16px font-600 text-[var(--el-text-color-primary)]">
基础信息
</span>
</div> </div>
<div class="gap-8px flex items-center"> <div class="gap-8px flex items-center">
<DictTag :type="DICT_TYPE.COMMON_STATUS" :value="formData.status" /> <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="formData.status" />

View File

@ -134,12 +134,20 @@ onMounted(() => {
</script> </script>
<template> <template>
<ElCard class="rounded-8px mb-10px border border-primary" shadow="never"> <ElCard
class="rounded-8px mb-10px border border-[var(--el-border-color-light)]"
shadow="never"
>
<template #header> <template #header>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div class="gap-8px flex items-center"> <div class="gap-8px flex items-center">
<IconifyIcon icon="ep:lightning" class="text-18px text-primary" /> <IconifyIcon
<span class="text-16px font-600 text-primary">触发器配置</span> icon="ep:lightning"
class="text-18px text-[var(--el-color-primary)]"
/>
<span class="text-16px font-600 text-[var(--el-text-color-primary)]">
触发器配置
</span>
<ElTag size="small" type="info"> <ElTag size="small" type="info">
{{ triggers.length }} 个触发器 {{ triggers.length }} 个触发器
</ElTag> </ElTag>
@ -216,20 +224,22 @@ onMounted(() => {
class="gap-16px flex flex-col" class="gap-16px flex flex-col"
> >
<div <div
class="gap-8px p-12px px-16px rounded-6px flex items-center border border-primary bg-background" class="gap-8px p-12px px-16px rounded-6px flex items-center border border-[var(--el-border-color-lighter)] bg-[var(--el-fill-color-light)]"
> >
<IconifyIcon <IconifyIcon
icon="lucide:timer" icon="lucide:timer"
class="text-18px text-danger" class="text-18px text-[var(--el-color-danger)]"
/> />
<span class="text-14px font-500 text-primary"> <span
class="text-14px font-500 text-[var(--el-text-color-primary)]"
>
定时触发配置 定时触发配置
</span> </span>
</div> </div>
<!-- CRON 表达式配置 --> <!-- CRON 表达式配置 -->
<div <div
class="p-16px rounded-6px border border-primary bg-background" class="p-16px rounded-6px border border-[var(--el-border-color-lighter)] bg-[var(--el-fill-color-blank)]"
> >
<ElFormItem label="CRON 表达式" required> <ElFormItem label="CRON 表达式" required>
<CronTab <CronTab
@ -258,9 +268,9 @@ onMounted(() => {
<ElEmpty description="暂无触发器"> <ElEmpty description="暂无触发器">
<template #description> <template #description>
<div class="space-y-8px"> <div class="space-y-8px">
<p class="text-secondary">暂无触发器配置</p> <p class="text-[var(--el-text-color-secondary)]">暂无触发器配置</p>
<p class="text-12px text-primary"> <p class="text-12px text-[var(--el-text-color-placeholder)]">
请使用上方的"添加触发器"按钮来设置触发规则 请使用上方的添加触发器按钮来设置触发规则
</p> </p>
</div> </div>
</template> </template>

View File

@ -95,10 +95,12 @@ watch(
> >
<div class="py-4px flex w-full items-center justify-between"> <div class="py-4px flex w-full items-center justify-between">
<div class="flex-1"> <div class="flex-1">
<div class="text-14px font-500 mb-2px text-primary"> <div
class="text-14px font-500 mb-2px text-[var(--el-text-color-primary)]"
>
{{ device.deviceName }} {{ device.deviceName }}
</div> </div>
<div class="text-12px text-primary"> <div class="text-12px text-[var(--el-text-color-secondary)]">
{{ device.deviceKey }} {{ device.deviceKey }}
</div> </div>
</div> </div>

View File

@ -252,16 +252,16 @@ watch(
> >
<div class="py-4px flex w-full items-center justify-between"> <div class="py-4px flex w-full items-center justify-between">
<div class="gap-8px flex items-center"> <div class="gap-8px flex items-center">
<div class="text-14px font-500 text-primary"> <div class="text-14px font-500 text-[var(--el-text-color-primary)]">
{{ operator.label }} {{ operator.label }}
</div> </div>
<div <div
class="text-12px px-6px py-2px rounded-4px bg-primary-light-9 font-mono text-primary" class="text-12px px-6px py-2px rounded-4px bg-[var(--el-color-primary-light-9)] font-mono text-[var(--el-color-primary)]"
> >
{{ operator.symbol }} {{ operator.symbol }}
</div> </div>
</div> </div>
<div class="text-12px text-secondary"> <div class="text-12px text-[var(--el-text-color-secondary)]">
{{ operator.description }} {{ operator.description }}
</div> </div>
</div> </div>

View File

@ -71,10 +71,12 @@ onMounted(() => {
> >
<div class="py-4px flex w-full items-center justify-between"> <div class="py-4px flex w-full items-center justify-between">
<div class="flex-1"> <div class="flex-1">
<div class="text-14px font-500 mb-2px text-primary"> <div
class="text-14px font-500 mb-2px text-[var(--el-text-color-primary)]"
>
{{ product.name }} {{ product.name }}
</div> </div>
<div class="text-12px text-secondary"> <div class="text-12px text-[var(--el-text-color-secondary)]">
{{ product.productKey }} {{ product.productKey }}
</div> </div>
</div> </div>

View File

@ -105,7 +105,9 @@ const propertyGroups = computed(() => {
// //
const selectedProperty = computed(() => { const selectedProperty = computed(() => {
return propertyList.value.find((p) => p.identifier === localValue.value); return propertyList.value.find(
(property) => property.identifier === localValue.value,
);
}); });
/** /**
@ -113,7 +115,9 @@ const selectedProperty = computed(() => {
* @param value 选中的属性标识符 * @param value 选中的属性标识符
*/ */
function handleChange(value: any) { function handleChange(value: any) {
const property = propertyList.value.find((p) => p.identifier === value); const property = propertyList.value.find(
(item) => item.identifier === value,
);
if (property) { if (property) {
emit('change', { emit('change', {
type: property.dataType, type: property.dataType,
@ -298,7 +302,7 @@ watch(
:value="property.identifier" :value="property.identifier"
> >
<div class="py-2px flex w-full items-center justify-between"> <div class="py-2px flex w-full items-center justify-between">
<span class="text-14px font-500 flex-1 truncate text-primary"> <span class="text-14px font-500 flex-1 truncate text-[var(--el-text-color-primary)]">
{{ property.name }} {{ property.name }}
</span> </span>
<ElTag size="small" class="ml-8px flex-shrink-0"> <ElTag size="small" class="ml-8px flex-shrink-0">
@ -335,8 +339,8 @@ watch(
<!-- 弹出层内容 --> <!-- 弹出层内容 -->
<div class="property-detail-content"> <div class="property-detail-content">
<div class="gap-8px mb-12px flex items-center"> <div class="gap-8px mb-12px flex items-center">
<IconifyIcon icon="ep:info-filled" class="text-16px text-info" /> <IconifyIcon icon="ep:info-filled" class="text-16px text-[var(--el-color-info)]" />
<span class="text-14px font-500 text-primary"> <span class="text-14px font-500 text-[var(--el-text-color-primary)]">
{{ selectedProperty.name }} {{ selectedProperty.name }}
</span> </span>
<ElTag size="small"> <ElTag size="small">
@ -346,10 +350,10 @@ watch(
<div class="space-y-8px ml-24px"> <div class="space-y-8px ml-24px">
<div class="gap-8px flex items-start"> <div class="gap-8px flex items-start">
<span class="text-12px min-w-60px flex-shrink-0 text-secondary"> <span class="text-12px min-w-60px flex-shrink-0 text-[var(--el-text-color-secondary)]">
标识符 标识符
</span> </span>
<span class="text-12px flex-1 text-primary"> <span class="text-12px flex-1 text-[var(--el-text-color-primary)]">
{{ selectedProperty.identifier }} {{ selectedProperty.identifier }}
</span> </span>
</div> </div>
@ -358,28 +362,28 @@ watch(
v-if="selectedProperty.description" v-if="selectedProperty.description"
class="gap-8px flex items-start" class="gap-8px flex items-start"
> >
<span class="text-12px min-w-60px flex-shrink-0 text-secondary"> <span class="text-12px min-w-60px flex-shrink-0 text-[var(--el-text-color-secondary)]">
描述 描述
</span> </span>
<span class="text-12px flex-1 text-primary"> <span class="text-12px flex-1 text-[var(--el-text-color-primary)]">
{{ selectedProperty.description }} {{ selectedProperty.description }}
</span> </span>
</div> </div>
<div v-if="selectedProperty.unit" class="gap-8px flex items-start"> <div v-if="selectedProperty.unit" class="gap-8px flex items-start">
<span class="text-12px min-w-60px flex-shrink-0 text-secondary"> <span class="text-12px min-w-60px flex-shrink-0 text-[var(--el-text-color-secondary)]">
单位 单位
</span> </span>
<span class="text-12px flex-1 text-primary"> <span class="text-12px flex-1 text-[var(--el-text-color-primary)]">
{{ selectedProperty.unit }} {{ selectedProperty.unit }}
</span> </span>
</div> </div>
<div v-if="selectedProperty.range" class="gap-8px flex items-start"> <div v-if="selectedProperty.range" class="gap-8px flex items-start">
<span class="text-12px min-w-60px flex-shrink-0 text-secondary"> <span class="text-12px min-w-60px flex-shrink-0 text-[var(--el-text-color-secondary)]">
取值范围 取值范围
</span> </span>
<span class="text-12px flex-1 text-primary"> <span class="text-12px flex-1 text-[var(--el-text-color-primary)]">
{{ selectedProperty.range }} {{ selectedProperty.range }}
</span> </span>
</div> </div>
@ -392,10 +396,10 @@ watch(
" "
class="gap-8px flex items-start" class="gap-8px flex items-start"
> >
<span class="text-12px min-w-60px flex-shrink-0 text-secondary"> <span class="text-12px min-w-60px flex-shrink-0 text-[var(--el-text-color-secondary)]">
访问模式 访问模式
</span> </span>
<span class="text-12px flex-1 text-primary"> <span class="text-12px flex-1 text-[var(--el-text-color-primary)]">
{{ getAccessModeLabel(selectedProperty.accessMode) }} {{ getAccessModeLabel(selectedProperty.accessMode) }}
</span> </span>
</div> </div>
@ -407,10 +411,10 @@ watch(
" "
class="gap-8px flex items-start" class="gap-8px flex items-start"
> >
<span class="text-12px min-w-60px flex-shrink-0 text-secondary"> <span class="text-12px min-w-60px flex-shrink-0 text-[var(--el-text-color-secondary)]">
事件类型 事件类型
</span> </span>
<span class="text-12px flex-1 text-primary"> <span class="text-12px flex-1 text-[var(--el-text-color-primary)]">
{{ getEventTypeLabel(selectedProperty.eventType) }} {{ getEventTypeLabel(selectedProperty.eventType) }}
</span> </span>
</div> </div>
@ -422,10 +426,10 @@ watch(
" "
class="gap-8px flex items-start" class="gap-8px flex items-start"
> >
<span class="text-12px min-w-60px flex-shrink-0 text-secondary"> <span class="text-12px min-w-60px flex-shrink-0 text-[var(--el-text-color-secondary)]">
调用类型 调用类型
</span> </span>
<span class="text-12px flex-1 text-primary"> <span class="text-12px flex-1 text-[var(--el-text-color-primary)]">
{{ {{
getThingModelServiceCallTypeLabel(selectedProperty.callType) getThingModelServiceCallTypeLabel(selectedProperty.callType)
}} }}

View File

@ -679,7 +679,7 @@ export const getByteOrderOptions = (rawDataType: string) => {
return ModbusByteOrder32Options; return ModbusByteOrder32Options;
} }
if (rawDataType === 'DOUBLE') { if (rawDataType === 'DOUBLE') {
// 64 位暂时复用 32 位字节序 // 64 位复用 32 位字节序
return ModbusByteOrder32Options; return ModbusByteOrder32Options;
} }
return ModbusByteOrder16Options; return ModbusByteOrder16Options;