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
parent
83bf576daf
commit
66843f2392
|
|
@ -65,5 +65,6 @@ const useVbenForm = useForm<ComponentType, ComponentPropsMap>;
|
|||
|
||||
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 VbenFormProps = FormProps<ComponentType, ComponentPropsMap>;
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ const maxValue = computed(() => {
|
|||
if (!canShowChart.value || list.value.length === 0) return '-';
|
||||
const values = list.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) : '-';
|
||||
});
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ const minValue = computed(() => {
|
|||
if (!canShowChart.value || list.value.length === 0) return '-';
|
||||
const values = list.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) : '-';
|
||||
});
|
||||
|
||||
|
|
@ -103,9 +103,9 @@ const avgValue = computed(() => {
|
|||
if (!canShowChart.value || list.value.length === 0) return '-';
|
||||
const values = list.value
|
||||
.map((item) => Number(item.value))
|
||||
.filter((v) => !Number.isNaN(v));
|
||||
.filter((value) => !Number.isNaN(value));
|
||||
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);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -434,7 +434,10 @@ onMounted(async () => {
|
|||
class="cursor-pointer text-primary"
|
||||
@click="openProductDetail(row.productId)"
|
||||
>
|
||||
{{ products.find((p) => p.id === row.productId)?.name || '-' }}
|
||||
{{
|
||||
products.find((product) => product.id === row.productId)?.name ||
|
||||
'-'
|
||||
}}
|
||||
</a>
|
||||
</template>
|
||||
<template #groups="{ row }">
|
||||
|
|
@ -445,7 +448,7 @@ onMounted(async () => {
|
|||
size="small"
|
||||
class="mr-1"
|
||||
>
|
||||
{{ deviceGroups.find((g) => g.id === groupId)?.name }}
|
||||
{{ deviceGroups.find((group) => group.id === groupId)?.name }}
|
||||
</Tag>
|
||||
</template>
|
||||
<span v-else>-</span>
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ const [Form, formApi] = useVbenForm({
|
|||
return;
|
||||
}
|
||||
// 从产品列表中查找产品
|
||||
const product = products.value.find((p) => p.id === productId);
|
||||
const product = products.value.find((item) => item.id === productId);
|
||||
if (product?.deviceType !== undefined) {
|
||||
await formApi.setFieldValue('deviceType', product.deviceType);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ export function getProductName(productId?: number): string {
|
|||
if (!productId) {
|
||||
return '-';
|
||||
}
|
||||
return productList.find((p) => p.id === productId)?.name || '-';
|
||||
return (
|
||||
productList.find((product) => product.id === productId)?.name || '-'
|
||||
);
|
||||
}
|
||||
|
||||
/** 固件详情的描述字段 */
|
||||
|
|
|
|||
|
|
@ -47,7 +47,12 @@ onMounted(() => {
|
|||
<template>
|
||||
<Select
|
||||
:value="modelValue"
|
||||
:options="productList.map((p) => ({ label: p.name, value: p.id }))"
|
||||
:options="
|
||||
productList.map((product) => ({
|
||||
label: product.name,
|
||||
value: product.id,
|
||||
}))
|
||||
"
|
||||
:loading="loading"
|
||||
placeholder="请选择产品"
|
||||
allow-clear
|
||||
|
|
|
|||
|
|
@ -108,7 +108,9 @@ function handleDeviceChange(deviceId?: number) {
|
|||
function handleServiceChange(serviceIdentifier?: any) {
|
||||
// 根据服务标识符找到对应的服务对象
|
||||
const service =
|
||||
serviceList.value.find((s) => s.identifier === serviceIdentifier) || null;
|
||||
serviceList.value.find(
|
||||
(item) => item.identifier === serviceIdentifier,
|
||||
) || null;
|
||||
selectedService.value = service;
|
||||
|
||||
// 当服务变化时,清空参数配置
|
||||
|
|
|
|||
|
|
@ -91,12 +91,16 @@ const propertyGroups = computed(() => {
|
|||
|
||||
/** 当前选中的属性 */
|
||||
const selectedProperty = computed(() =>
|
||||
propertyList.value.find((p) => p.identifier === localValue.value),
|
||||
propertyList.value.find(
|
||||
(property) => property.identifier === localValue.value,
|
||||
),
|
||||
);
|
||||
|
||||
/** 处理选择变化事件 */
|
||||
function handleChange(value: any) {
|
||||
const property = propertyList.value.find((p) => p.identifier === value);
|
||||
const property = propertyList.value.find(
|
||||
(item) => item.identifier === value,
|
||||
);
|
||||
if (property) {
|
||||
emit('change', { type: property.dataType, config: property });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,5 +57,6 @@ const useVbenForm = useForm<ComponentType, ComponentPropsMap>;
|
|||
|
||||
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 VbenFormProps = FormProps<ComponentType, ComponentPropsMap>;
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ const maxValue = computed(() => {
|
|||
if (!canShowChart.value || list.value.length === 0) return '-';
|
||||
const values = list.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) : '-';
|
||||
});
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ const minValue = computed(() => {
|
|||
if (!canShowChart.value || list.value.length === 0) return '-';
|
||||
const values = list.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) : '-';
|
||||
});
|
||||
|
||||
|
|
@ -103,9 +103,9 @@ const avgValue = computed(() => {
|
|||
if (!canShowChart.value || list.value.length === 0) return '-';
|
||||
const values = list.value
|
||||
.map((item) => Number(item.value))
|
||||
.filter((v) => !Number.isNaN(v));
|
||||
.filter((value) => !Number.isNaN(value));
|
||||
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);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ onBeforeUnmount(() => {
|
|||
<!-- 标题区域 -->
|
||||
<div class="mb-3 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 class="flex-1 text-base font-bold">{{ item.name }}</div>
|
||||
<!-- 标识符 -->
|
||||
|
|
@ -357,7 +357,7 @@ onBeforeUnmount(() => {
|
|||
"
|
||||
>
|
||||
<IconifyIcon
|
||||
class="text-lg text-primary"
|
||||
class="text-lg text-[var(--el-color-primary)]"
|
||||
icon="ep:data-line"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -425,10 +425,13 @@ onMounted(async () => {
|
|||
<Grid table-title="设备列表" v-show="viewMode === 'list'">
|
||||
<template #product="{ row }">
|
||||
<a
|
||||
class="cursor-pointer text-primary"
|
||||
class="cursor-pointer text-[var(--el-color-primary)]"
|
||||
@click="openProductDetail(row.productId)"
|
||||
>
|
||||
{{ products.find((p) => p.id === row.productId)?.name || '-' }}
|
||||
{{
|
||||
products.find((product) => product.id === row.productId)?.name ||
|
||||
'-'
|
||||
}}
|
||||
</a>
|
||||
</template>
|
||||
<template #groups="{ row }">
|
||||
|
|
@ -439,7 +442,7 @@ onMounted(async () => {
|
|||
size="small"
|
||||
class="mr-1"
|
||||
>
|
||||
{{ deviceGroups.find((g) => g.id === groupId)?.name }}
|
||||
{{ deviceGroups.find((group) => group.id === groupId)?.name }}
|
||||
</ElTag>
|
||||
</template>
|
||||
<span v-else>-</span>
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ onMounted(() => {
|
|||
所属产品
|
||||
</span>
|
||||
<a
|
||||
class="cursor-pointer truncate font-medium text-primary"
|
||||
class="cursor-pointer truncate font-medium text-[var(--el-color-primary)]"
|
||||
@click="
|
||||
(e) => {
|
||||
e.stopPropagation();
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ const [Form, formApi] = useVbenForm({
|
|||
return;
|
||||
}
|
||||
// 从产品列表中查找产品
|
||||
const product = products.value.find((p) => p.id === productId);
|
||||
const product = products.value.find((item) => item.id === productId);
|
||||
if (product?.deviceType !== undefined) {
|
||||
await formApi.setFieldValue('deviceType', product.deviceType);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ export function getProductName(productId?: number): string {
|
|||
if (!productId) {
|
||||
return '-';
|
||||
}
|
||||
return productList.find((p) => p.id === productId)?.name || '-';
|
||||
return (
|
||||
productList.find((product) => product.id === productId)?.name || '-'
|
||||
);
|
||||
}
|
||||
|
||||
/** 固件详情的描述字段 */
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||
<template #productName="{ row }">
|
||||
<a
|
||||
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)"
|
||||
>
|
||||
{{ getProductName(row.productId) }}
|
||||
|
|
@ -129,13 +129,13 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||
>
|
||||
<IconifyIcon
|
||||
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
|
||||
:href="row.fileUrl"
|
||||
target="_blank"
|
||||
download
|
||||
class="cursor-pointer align-middle text-primary hover:underline"
|
||||
class="cursor-pointer align-middle text-[var(--el-color-primary)] hover:underline"
|
||||
>
|
||||
下载固件
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -78,9 +78,7 @@ export function useFormSchema(): VbenFormSchema[] {
|
|||
componentProps: {
|
||||
multiple: true,
|
||||
placeholder: '请选择设备',
|
||||
showSearch: true,
|
||||
filterOption: true,
|
||||
optionFilterProp: 'label',
|
||||
filterable: true,
|
||||
},
|
||||
defaultValue: [],
|
||||
dependencies: {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
|
|||
component: 'Input',
|
||||
componentProps: {
|
||||
placeholder: '请输入规则名称',
|
||||
allowClear: true,
|
||||
clearable: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -25,7 +25,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
|
|||
componentProps: {
|
||||
options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'),
|
||||
placeholder: '请选择状态',
|
||||
allowClear: true,
|
||||
clearable: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -34,7 +34,7 @@ export function useGridFormSchema(): VbenFormSchema[] {
|
|||
component: 'RangePicker',
|
||||
componentProps: {
|
||||
...getRangePickerDefaultProps(),
|
||||
allowClear: true,
|
||||
clearable: true,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -87,9 +87,9 @@ const needsTimeInput = computed(() => {
|
|||
return timeOnlyOperators.includes(condition.value.operator as any);
|
||||
});
|
||||
|
||||
// 计算属性:是否需要日期输入
|
||||
/** 是否需要日期输入 ;当前仅支持时间 */
|
||||
const needsDateInput = computed(() => {
|
||||
return false; // 暂时不支持日期输入,只支持时间
|
||||
return false;
|
||||
});
|
||||
|
||||
// 计算属性:是否需要第二个时间输入
|
||||
|
|
@ -225,7 +225,7 @@ watch(
|
|||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
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>
|
||||
</ElCol>
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,9 @@ function handleDeviceChange(deviceId?: number) {
|
|||
function handleServiceChange(serviceIdentifier?: any) {
|
||||
// 根据服务标识符找到对应的服务对象
|
||||
const service =
|
||||
serviceList.value.find((s) => s.identifier === serviceIdentifier) || null;
|
||||
serviceList.value.find(
|
||||
(item) => item.identifier === serviceIdentifier,
|
||||
) || null;
|
||||
selectedService.value = service;
|
||||
|
||||
// 当服务变化时,清空参数配置
|
||||
|
|
|
|||
|
|
@ -365,10 +365,10 @@ function handlePropertyChange(propertyInfo: any) {
|
|||
|
||||
<!-- 其他触发类型的提示 -->
|
||||
<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) }}
|
||||
</p>
|
||||
<p class="text-xs text-secondary">此触发类型暂不需要配置额外条件</p>
|
||||
<p class="text-xs text-[var(--el-text-color-secondary)]">此触发类型暂不需要配置额外条件</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -89,8 +89,8 @@ function updateCondition(
|
|||
<!-- 空状态 -->
|
||||
<div v-if="!subGroup || subGroup.length === 0" class="py-6 text-center">
|
||||
<div class="flex flex-col items-center gap-3">
|
||||
<IconifyIcon icon="lucide:plus" class="text-8 text-secondary" />
|
||||
<div class="text-secondary">
|
||||
<IconifyIcon icon="lucide:plus" class="text-8 text-[var(--el-text-color-secondary)]" />
|
||||
<div class="text-[var(--el-text-color-secondary)]">
|
||||
<p class="mb-1 text-base font-bold">暂无条件</p>
|
||||
<p class="text-xs">点击下方按钮添加第一个条件</p>
|
||||
</div>
|
||||
|
|
@ -121,7 +121,7 @@ function updateCondition(
|
|||
>
|
||||
{{ conditionIndex + 1 }}
|
||||
</div>
|
||||
<span class="text-base font-bold text-primary">
|
||||
<span class="text-base font-bold text-[var(--el-text-color-primary)]">
|
||||
条件 {{ conditionIndex + 1 }}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -161,7 +161,7 @@ function updateCondition(
|
|||
<IconifyIcon icon="lucide:plus" />
|
||||
继续添加条件
|
||||
</ElButton>
|
||||
<span class="mt-2 block text-xs text-secondary">
|
||||
<span class="mt-2 block text-xs text-[var(--el-text-color-secondary)]">
|
||||
最多可添加 {{ maxConditions }} 个条件
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -450,8 +450,11 @@ watch(
|
|||
<!-- 弹出层内容 -->
|
||||
<div class="json-params-detail-content">
|
||||
<div class="mb-4 flex items-center gap-2">
|
||||
<IconifyIcon :icon="titleIcon" class="text-lg text-primary" />
|
||||
<span class="text-base font-bold text-primary">
|
||||
<IconifyIcon
|
||||
:icon="titleIcon"
|
||||
class="text-lg text-[var(--el-color-primary)]"
|
||||
/>
|
||||
<span class="text-base font-bold text-[var(--el-text-color-primary)]">
|
||||
{{ title }}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -462,9 +465,9 @@ watch(
|
|||
<div class="mb-2 flex items-center gap-2">
|
||||
<IconifyIcon
|
||||
: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 }}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -475,7 +478,7 @@ watch(
|
|||
class="flex items-center justify-between rounded-lg bg-card p-2"
|
||||
>
|
||||
<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 }}
|
||||
<ElTag
|
||||
v-if="param.required"
|
||||
|
|
@ -486,7 +489,7 @@ watch(
|
|||
{{ JSON_PARAMS_INPUT_CONSTANTS.REQUIRED_TAG }}
|
||||
</ElTag>
|
||||
</div>
|
||||
<div class="text-xs text-secondary">
|
||||
<div class="text-xs text-[var(--el-text-color-secondary)]">
|
||||
{{ param.identifier }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -494,7 +497,7 @@ watch(
|
|||
<ElTag :type="getParamTypeTag(param.dataType)" size="small">
|
||||
{{ getParamTypeName(param.dataType) }}
|
||||
</ElTag>
|
||||
<span class="text-xs text-secondary">
|
||||
<span class="text-xs text-[var(--el-text-color-secondary)]">
|
||||
{{ getExampleValue(param) }}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -502,11 +505,11 @@ watch(
|
|||
</div>
|
||||
|
||||
<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 }}
|
||||
</div>
|
||||
<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>
|
||||
</pre>
|
||||
|
|
@ -516,7 +519,7 @@ watch(
|
|||
<!-- 无参数提示 -->
|
||||
<div v-else>
|
||||
<div class="py-4 text-center">
|
||||
<p class="text-sm text-secondary">
|
||||
<p class="text-sm text-[var(--el-text-color-secondary)]">
|
||||
{{ emptyMessage }}
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -550,7 +553,7 @@ watch(
|
|||
|
||||
<!-- 快速填充按钮 -->
|
||||
<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 }}
|
||||
</span>
|
||||
<ElButton size="small" type="primary" plain @click="fillExampleJson">
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ watch(
|
|||
class="min-w-0 flex-1"
|
||||
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
|
||||
v-model="rangeEnd"
|
||||
:type="getInputType()"
|
||||
|
|
@ -240,7 +240,7 @@ watch(
|
|||
v-if="listPreview.length > 0"
|
||||
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
|
||||
v-for="(item, index) in listPreview"
|
||||
:key="index"
|
||||
|
|
@ -292,7 +292,7 @@ watch(
|
|||
:content="`单位:${propertyConfig.unit}`"
|
||||
placement="top"
|
||||
>
|
||||
<span class="px-1 text-xs text-secondary">
|
||||
<span class="px-1 text-xs text-[var(--el-text-color-secondary)]">
|
||||
{{ propertyConfig.unit }}
|
||||
</span>
|
||||
</ElTooltip>
|
||||
|
|
|
|||
|
|
@ -156,12 +156,20 @@ function onActionTypeChange(action: RuleSceneApi.Action, type: number) {
|
|||
</script>
|
||||
|
||||
<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>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="gap-8px flex items-center">
|
||||
<IconifyIcon icon="ep:setting" class="text-18px text-primary" />
|
||||
<span class="text-16px font-600 text-primary"> 执行器配置 </span>
|
||||
<IconifyIcon
|
||||
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">
|
||||
{{ actions.length }} 个执行器
|
||||
</ElTag>
|
||||
|
|
@ -271,14 +279,19 @@ function onActionTypeChange(action: RuleSceneApi.Action, type: number) {
|
|||
<!-- 触发告警提示 - 触发告警时显示 -->
|
||||
<div
|
||||
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">
|
||||
<IconifyIcon icon="ep:warning" class="text-base text-warning" />
|
||||
<span class="font-600 text-sm text-primary">触发告警</span>
|
||||
<IconifyIcon
|
||||
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>
|
||||
</div>
|
||||
<div class="text-xs leading-relaxed text-secondary">
|
||||
<div class="text-xs leading-relaxed text-[var(--el-text-color-secondary)]">
|
||||
当触发条件满足时,系统将自动发送告警通知,可在菜单 [告警中心 ->
|
||||
告警配置] 管理。
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ defineOptions({ name: 'BasicInfoSection' });
|
|||
|
||||
const props = defineProps<{
|
||||
modelValue: RuleSceneApi.SceneRule;
|
||||
rules?: any;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
|
@ -35,12 +34,20 @@ const formData = useVModel(props, 'modelValue', emit); // 表单数据
|
|||
</script>
|
||||
|
||||
<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>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="gap-8px flex items-center">
|
||||
<IconifyIcon icon="ep:info-filled" class="text-18px text-primary" />
|
||||
<span class="text-16px font-600 text-primary">基础信息</span>
|
||||
<IconifyIcon
|
||||
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 class="gap-8px flex items-center">
|
||||
<DictTag :type="DICT_TYPE.COMMON_STATUS" :value="formData.status" />
|
||||
|
|
|
|||
|
|
@ -134,12 +134,20 @@ onMounted(() => {
|
|||
</script>
|
||||
|
||||
<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>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="gap-8px flex items-center">
|
||||
<IconifyIcon icon="ep:lightning" class="text-18px text-primary" />
|
||||
<span class="text-16px font-600 text-primary">触发器配置</span>
|
||||
<IconifyIcon
|
||||
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">
|
||||
{{ triggers.length }} 个触发器
|
||||
</ElTag>
|
||||
|
|
@ -216,20 +224,22 @@ onMounted(() => {
|
|||
class="gap-16px flex flex-col"
|
||||
>
|
||||
<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
|
||||
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>
|
||||
</div>
|
||||
|
||||
<!-- CRON 表达式配置 -->
|
||||
<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>
|
||||
<CronTab
|
||||
|
|
@ -258,9 +268,9 @@ onMounted(() => {
|
|||
<ElEmpty description="暂无触发器">
|
||||
<template #description>
|
||||
<div class="space-y-8px">
|
||||
<p class="text-secondary">暂无触发器配置</p>
|
||||
<p class="text-12px text-primary">
|
||||
请使用上方的"添加触发器"按钮来设置触发规则
|
||||
<p class="text-[var(--el-text-color-secondary)]">暂无触发器配置</p>
|
||||
<p class="text-12px text-[var(--el-text-color-placeholder)]">
|
||||
请使用上方的「添加触发器」按钮来设置触发规则
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -95,10 +95,12 @@ watch(
|
|||
>
|
||||
<div class="py-4px flex w-full items-center justify-between">
|
||||
<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 }}
|
||||
</div>
|
||||
<div class="text-12px text-primary">
|
||||
<div class="text-12px text-[var(--el-text-color-secondary)]">
|
||||
{{ device.deviceKey }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -252,16 +252,16 @@ watch(
|
|||
>
|
||||
<div class="py-4px flex w-full items-center justify-between">
|
||||
<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 }}
|
||||
</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 }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-12px text-secondary">
|
||||
<div class="text-12px text-[var(--el-text-color-secondary)]">
|
||||
{{ operator.description }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -71,10 +71,12 @@ onMounted(() => {
|
|||
>
|
||||
<div class="py-4px flex w-full items-center justify-between">
|
||||
<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 }}
|
||||
</div>
|
||||
<div class="text-12px text-secondary">
|
||||
<div class="text-12px text-[var(--el-text-color-secondary)]">
|
||||
{{ product.productKey }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -105,7 +105,9 @@ const propertyGroups = 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 选中的属性标识符
|
||||
*/
|
||||
function handleChange(value: any) {
|
||||
const property = propertyList.value.find((p) => p.identifier === value);
|
||||
const property = propertyList.value.find(
|
||||
(item) => item.identifier === value,
|
||||
);
|
||||
if (property) {
|
||||
emit('change', {
|
||||
type: property.dataType,
|
||||
|
|
@ -298,7 +302,7 @@ watch(
|
|||
:value="property.identifier"
|
||||
>
|
||||
<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 }}
|
||||
</span>
|
||||
<ElTag size="small" class="ml-8px flex-shrink-0">
|
||||
|
|
@ -335,8 +339,8 @@ watch(
|
|||
<!-- 弹出层内容 -->
|
||||
<div class="property-detail-content">
|
||||
<div class="gap-8px mb-12px flex items-center">
|
||||
<IconifyIcon icon="ep:info-filled" class="text-16px text-info" />
|
||||
<span class="text-14px font-500 text-primary">
|
||||
<IconifyIcon icon="ep:info-filled" class="text-16px text-[var(--el-color-info)]" />
|
||||
<span class="text-14px font-500 text-[var(--el-text-color-primary)]">
|
||||
{{ selectedProperty.name }}
|
||||
</span>
|
||||
<ElTag size="small">
|
||||
|
|
@ -346,10 +350,10 @@ watch(
|
|||
|
||||
<div class="space-y-8px ml-24px">
|
||||
<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 class="text-12px flex-1 text-primary">
|
||||
<span class="text-12px flex-1 text-[var(--el-text-color-primary)]">
|
||||
{{ selectedProperty.identifier }}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -358,28 +362,28 @@ watch(
|
|||
v-if="selectedProperty.description"
|
||||
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 class="text-12px flex-1 text-primary">
|
||||
<span class="text-12px flex-1 text-[var(--el-text-color-primary)]">
|
||||
{{ selectedProperty.description }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<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 class="text-12px flex-1 text-primary">
|
||||
<span class="text-12px flex-1 text-[var(--el-text-color-primary)]">
|
||||
{{ selectedProperty.unit }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<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 class="text-12px flex-1 text-primary">
|
||||
<span class="text-12px flex-1 text-[var(--el-text-color-primary)]">
|
||||
{{ selectedProperty.range }}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -392,10 +396,10 @@ watch(
|
|||
"
|
||||
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 class="text-12px flex-1 text-primary">
|
||||
<span class="text-12px flex-1 text-[var(--el-text-color-primary)]">
|
||||
{{ getAccessModeLabel(selectedProperty.accessMode) }}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -407,10 +411,10 @@ watch(
|
|||
"
|
||||
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 class="text-12px flex-1 text-primary">
|
||||
<span class="text-12px flex-1 text-[var(--el-text-color-primary)]">
|
||||
{{ getEventTypeLabel(selectedProperty.eventType) }}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -422,10 +426,10 @@ watch(
|
|||
"
|
||||
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 class="text-12px flex-1 text-primary">
|
||||
<span class="text-12px flex-1 text-[var(--el-text-color-primary)]">
|
||||
{{
|
||||
getThingModelServiceCallTypeLabel(selectedProperty.callType)
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -679,7 +679,7 @@ export const getByteOrderOptions = (rawDataType: string) => {
|
|||
return ModbusByteOrder32Options;
|
||||
}
|
||||
if (rawDataType === 'DOUBLE') {
|
||||
// 64 位暂时复用 32 位字节序
|
||||
// 64 位复用 32 位字节序
|
||||
return ModbusByteOrder32Options;
|
||||
}
|
||||
return ModbusByteOrder16Options;
|
||||
|
|
|
|||
Loading…
Reference in New Issue