فهرست منبع

feat:【IoT 物联网】初步实现“数据流转”功能

YunaiV 9 ماه پیش
والد
کامیت
8479d557a2

+ 39 - 0
src/api/iot/rule/data/rule/index.ts

@@ -0,0 +1,39 @@
+import request from '@/config/axios'
+
+/** IoT 数据流转规则信息 */
+export interface DataRule {
+  id: number // 场景编号
+  name?: string // 场景名称
+  description: string // 场景描述
+  status?: number // 场景状态
+  sourceConfigs?: string // 数据源配置数组
+  sinkIds?: string // 数据目的编号数组
+}
+
+// IoT 数据流转规则 API
+export const DataRuleApi = {
+  // 查询数据流转规则分页
+  getDataRulePage: async (params: any) => {
+    return await request.get({ url: `/iot/data-rule/page`, params })
+  },
+
+  // 查询数据流转规则详情
+  getDataRule: async (id: number) => {
+    return await request.get({ url: `/iot/data-rule/get?id=` + id })
+  },
+
+  // 新增数据流转规则
+  createDataRule: async (data: DataRule) => {
+    return await request.post({ url: `/iot/data-rule/create`, data })
+  },
+
+  // 修改数据流转规则
+  updateDataRule: async (data: DataRule) => {
+    return await request.put({ url: `/iot/data-rule/update`, data })
+  },
+
+  // 删除数据流转规则
+  deleteDataRule: async (id: number) => {
+    return await request.delete({ url: `/iot/data-rule/delete?id=` + id })
+  }
+}

+ 24 - 30
src/api/iot/rule/databridge/index.ts → src/api/iot/rule/data/sink/index.ts

@@ -1,7 +1,7 @@
 import request from '@/config/axios'
 
-// IoT 数据桥梁 VO
-export interface DataBridgeVO {
+// IoT 数据流转目的 VO
+export interface DataSinkVO {
   id?: number // 桥梁编号
   name?: string // 桥梁名称
   description?: string // 桥梁描述
@@ -79,8 +79,8 @@ export interface RedisStreamMQConfig extends Config {
   topic: string
 }
 
-/** 数据桥梁类型 */
-export const IoTDataBridgeConfigType = {
+/** 数据流转目的类型 */
+export const IotDataSinkTypeEnum = {
   HTTP: 1,
   TCP: 2,
   WEBSOCKET: 3,
@@ -92,41 +92,35 @@ export const IoTDataBridgeConfigType = {
   KAFKA: 32
 } as const
 
-export const IotDataBridgeDirectionEnum = {
-  INPUT: 1, // 输入
-  OUTPUT: 2 // 输出
-} as const
-
-// 数据桥梁 API
-export const DataBridgeApi = {
-  // 查询数据桥梁分页
-  getDataBridgePage: async (params: any) => {
-    return await request.get({ url: `/iot/data-bridge/page`, params })
+// 数据流转目的 API
+export const DataSinkApi = {
+  // 查询数据流转目的分页
+  getDataSinkPage: async (params: any) => {
+    return await request.get({ url: `/iot/data-sink/page`, params })
   },
 
-  // 查询数据桥梁详情
-  getDataBridge: async (id: number) => {
-    return await request.get({ url: `/iot/data-bridge/get?id=` + id })
+  // 查询数据流转目的详情
+  getDataSink: async (id: number) => {
+    return await request.get({ url: `/iot/data-sink/get?id=` + id })
   },
 
-  // 新增数据桥梁
-  createDataBridge: async (data: DataBridgeVO) => {
-    return await request.post({ url: `/iot/data-bridge/create`, data })
+  // 新增数据流转目的
+  createDataSink: async (data: DataSinkVO) => {
+    return await request.post({ url: `/iot/data-sink/create`, data })
   },
 
-  // 修改数据桥梁
-  updateDataBridge: async (data: DataBridgeVO) => {
-    return await request.put({ url: `/iot/data-bridge/update`, data })
+  // 修改数据流转目的
+  updateDataSink: async (data: DataSinkVO) => {
+    return await request.put({ url: `/iot/data-sink/update`, data })
   },
 
-  // 删除数据桥梁
-  deleteDataBridge: async (id: number) => {
-    return await request.delete({ url: `/iot/data-bridge/delete?id=` + id })
+  // 删除数据流转目的
+  deleteDataSink: async (id: number) => {
+    return await request.delete({ url: `/iot/data-sink/delete?id=` + id })
   },
 
-  // 查询数据桥梁(精简)列表
-  // TODO @puhui999:getDataBridgeSimpleList 哈。项目的风格统一~ 之前有几个,我写错了。。。
-  getSimpleDataBridgeList() {
-    return request.get({ url: '/iot/data-bridge/simple-list' })
+  // 查询数据流转目的(精简)列表
+  getDataSinkSimpleList() {
+    return request.get({ url: '/iot/data-sink/simple-list' })
   }
 }

+ 1 - 1
src/api/iot/rule/scene/scene.types.ts

@@ -104,7 +104,7 @@ interface ActionConfig {
   type: number // 执行类型
   deviceControl?: ActionDeviceControl // 设备控制
   alert?: ActionAlert // 告警执行
-  dataBridgeId?: number // 数据桥接编号
+  dataBridgeId?: number // 数据流转目的编号
 }
 
 // 主接口

+ 1 - 2
src/utils/dict.ts

@@ -237,8 +237,7 @@ export enum DICT_TYPE {
   IOT_THING_MODEL_TYPE = 'iot_thing_model_type', // IOT 产品功能类型
   IOT_THING_MODEL_UNIT = 'iot_thing_model_unit', // IOT 物模型单位
   IOT_RW_TYPE = 'iot_rw_type', // IOT 读写类型
-  IOT_DATA_BRIDGE_DIRECTION_ENUM = 'iot_data_bridge_direction_enum', // 桥梁方向
-  IOT_DATA_BRIDGE_TYPE_ENUM = 'iot_data_bridge_type_enum', // 桥梁类型
+  IOT_DATA_SINK_TYPE_ENUM = 'iot_data_sink_type_enum', // IoT 数据流转目的类型
   IOT_RULE_SCENE_TRIGGER_TYPE_ENUM = 'iot_rule_scene_trigger_type_enum', // IoT 场景流转的触发类型枚举
   IOT_RULE_SCENE_ACTION_TYPE_ENUM = 'iot_rule_scene_action_type_enum' // IoT 规则场景的触发类型枚举
 }

+ 20 - 0
src/views/iot/rule/data/index.vue

@@ -0,0 +1,20 @@
+<template>
+  <el-tabs v-model="activeTab" type="border-card">
+    <el-tab-pane label="规则" name="rule">
+      <RuleIndex />
+    </el-tab-pane>
+    <el-tab-pane label="目的" name="sink" lazy>
+      <SinkIndex />
+    </el-tab-pane>
+  </el-tabs>
+</template>
+
+<script setup lang="ts">
+import RuleIndex from './rule/index.vue'
+import SinkIndex from './sink/index.vue'
+
+/** IoT 数据流转 */
+defineOptions({ name: 'IotData' })
+
+const activeTab = ref('rule')
+</script>

+ 124 - 0
src/views/iot/rule/data/rule/DataRuleForm.vue

@@ -0,0 +1,124 @@
+<template>
+  <Dialog :title="dialogTitle" v-model="dialogVisible">
+    <el-form
+      ref="formRef"
+      :model="formData"
+      :rules="formRules"
+      label-width="100px"
+      v-loading="formLoading"
+    >
+      <el-form-item label="场景名称" prop="name">
+        <el-input v-model="formData.name" placeholder="请输入场景名称" />
+      </el-form-item>
+      <el-form-item label="场景描述" prop="description">
+        <Editor v-model="formData.description" height="150px" />
+      </el-form-item>
+      <el-form-item label="场景状态" prop="status">
+        <el-radio-group v-model="formData.status">
+          <el-radio
+            v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
+            :key="dict.value"
+            :label="dict.value"
+          >
+            {{ dict.label }}
+          </el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="数据源配置数组" prop="sourceConfigs">
+        <el-input v-model="formData.sourceConfigs" placeholder="请输入数据源配置数组" />
+      </el-form-item>
+      <el-form-item label="数据目的编号数组" prop="sinkIds">
+        <el-input v-model="formData.sinkIds" placeholder="请输入数据目的编号数组" />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+<script setup lang="ts">
+import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
+import { DataRuleApi, DataRule } from '@/api/iot/rule/data/rule'
+
+/** IoT 数据流转规则 表单 */
+defineOptions({ name: 'DataRuleForm' })
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+
+const dialogVisible = ref(false) // 弹窗的是否展示
+const dialogTitle = ref('') // 弹窗的标题
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formType = ref('') // 表单的类型:create - 新增;update - 修改
+const formData = ref({
+  id: undefined,
+  name: undefined,
+  description: undefined,
+  status: undefined,
+  sourceConfigs: undefined,
+  sinkIds: undefined
+})
+const formRules = reactive({
+  name: [{ required: true, message: '场景名称不能为空', trigger: 'blur' }],
+  status: [{ required: true, message: '场景状态不能为空', trigger: 'blur' }],
+  sourceConfigs: [{ required: true, message: '数据源配置数组不能为空', trigger: 'blur' }],
+  sinkIds: [{ required: true, message: '数据目的编号数组不能为空', trigger: 'blur' }]
+})
+const formRef = ref() // 表单 Ref
+
+/** 打开弹窗 */
+const open = async (type: string, id?: number) => {
+  dialogVisible.value = true
+  dialogTitle.value = t('action.' + type)
+  formType.value = type
+  resetForm()
+  // 修改时,设置数据
+  if (id) {
+    formLoading.value = true
+    try {
+      formData.value = await DataRuleApi.getDataRule(id)
+    } finally {
+      formLoading.value = false
+    }
+  }
+}
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  // 校验表单
+  await formRef.value.validate()
+  // 提交请求
+  formLoading.value = true
+  try {
+    const data = formData.value as unknown as DataRule
+    if (formType.value === 'create') {
+      await DataRuleApi.createDataRule(data)
+      message.success(t('common.createSuccess'))
+    } else {
+      await DataRuleApi.updateDataRule(data)
+      message.success(t('common.updateSuccess'))
+    }
+    dialogVisible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+  }
+}
+
+/** 重置表单 */
+const resetForm = () => {
+  formData.value = {
+    id: undefined,
+    name: undefined,
+    description: undefined,
+    status: undefined,
+    sourceConfigs: undefined,
+    sinkIds: undefined
+  }
+  formRef.value?.resetFields()
+}
+</script>

+ 194 - 0
src/views/iot/rule/data/rule/index.vue

@@ -0,0 +1,194 @@
+<template>
+  <ContentWrap>
+    <!-- 搜索工作栏 -->
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="68px"
+    >
+      <el-form-item label="场景名称" prop="name">
+        <el-input
+          v-model="queryParams.name"
+          placeholder="请输入场景名称"
+          clearable
+          @keyup.enter="handleQuery"
+          class="!w-240px"
+        />
+      </el-form-item>
+      <el-form-item label="场景状态" prop="status">
+        <el-select
+          v-model="queryParams.status"
+          placeholder="请选择场景状态"
+          clearable
+          class="!w-240px"
+        >
+          <el-option
+            v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="创建时间" prop="createTime">
+        <el-date-picker
+          v-model="queryParams.createTime"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          type="daterange"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
+          class="!w-220px"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+        <el-button
+          type="primary"
+          plain
+          @click="openForm('create')"
+          v-hasPermi="['iot:data-rule:create']"
+        >
+          <Icon icon="ep:plus" class="mr-5px" /> 新增
+        </el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <el-table
+      row-key="id"
+      v-loading="loading"
+      :data="list"
+      :stripe="true"
+      :show-overflow-tooltip="true"
+    >
+      <el-table-column type="selection" width="55" />
+      <el-table-column label="场景编号" align="center" prop="id" />
+      <el-table-column label="场景名称" align="center" prop="name" />
+      <el-table-column label="场景描述" align="center" prop="description" />
+      <el-table-column label="场景状态" align="center" prop="status">
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
+        </template>
+      </el-table-column>
+      <el-table-column label="数据源配置数组" align="center" prop="sourceConfigs" />
+      <el-table-column label="数据目的编号数组" align="center" prop="sinkIds" />
+      <el-table-column
+        label="创建时间"
+        align="center"
+        prop="createTime"
+        :formatter="dateFormatter"
+        width="180px"
+      />
+      <el-table-column label="操作" align="center" min-width="120px">
+        <template #default="scope">
+          <el-button
+            link
+            type="primary"
+            @click="openForm('update', scope.row.id)"
+            v-hasPermi="['iot:data-rule:update']"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="danger"
+            @click="handleDelete(scope.row.id)"
+            v-hasPermi="['iot:data-rule:delete']"
+          >
+            删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </ContentWrap>
+
+  <!-- 表单弹窗:添加/修改 -->
+  <DataRuleForm ref="formRef" @success="getList" />
+</template>
+
+<script setup lang="ts">
+import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
+import { dateFormatter } from '@/utils/formatTime'
+import { DataRuleApi, DataRule } from '@/api/iot/rule/data/rule'
+import DataRuleForm from './DataRuleForm.vue'
+
+/** IoT 数据流转规则列表 */
+defineOptions({ name: 'IotDataRule' })
+
+const message = useMessage() // 消息弹窗
+const { t } = useI18n() // 国际化
+
+const loading = ref(true) // 列表的加载中
+const list = ref<DataRule[]>([]) // 列表的数据
+const total = ref(0) // 列表的总页数
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  name: undefined,
+  status: undefined,
+  createTime: []
+})
+const queryFormRef = ref() // 搜索的表单
+const exportLoading = ref(false) // 导出的加载中
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await DataRuleApi.getDataRulePage(queryParams)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.pageNo = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+/** 添加/修改操作 */
+const formRef = ref()
+const openForm = (type: string, id?: number) => {
+  formRef.value.open(type, id)
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (id: number) => {
+  try {
+    // 删除的二次确认
+    await message.delConfirm()
+    // 发起删除
+    await DataRuleApi.deleteDataRule(id)
+    message.success(t('common.delSuccess'))
+    // 刷新列表
+    await getList()
+  } catch {}
+}
+
+/** 初始化 **/
+onMounted(() => {
+  getList()
+})
+</script>

+ 34 - 54
src/views/iot/rule/databridge/IoTDataBridgeForm.vue → src/views/iot/rule/data/sink/DataSinkForm.vue

@@ -7,50 +7,38 @@
       :rules="formRules"
       label-width="120px"
     >
-      <el-form-item label="桥梁名称" prop="name">
-        <el-input v-model="formData.name" placeholder="请输入桥梁名称" />
+      <el-form-item label="目的名称" prop="name">
+        <el-input v-model="formData.name" placeholder="请输入目的名称" />
       </el-form-item>
-      <el-form-item label="桥梁方向" prop="direction">
-        <el-radio-group v-model="formData.direction">
-          <el-radio
-            v-for="dict in getIntDictOptions(DICT_TYPE.IOT_DATA_BRIDGE_DIRECTION_ENUM)"
-            :key="dict.value"
-            :label="dict.value"
-          >
-            {{ dict.label }}
-          </el-radio>
-        </el-radio-group>
-      </el-form-item>
-      <el-form-item label="桥梁类型" prop="type">
-        <el-radio-group :model-value="formData.type" @change="handleTypeChange">
-          <el-radio
-            v-for="dict in getIntDictOptions(DICT_TYPE.IOT_DATA_BRIDGE_TYPE_ENUM)"
-            :key="dict.value"
-            :label="dict.value"
-          >
-            {{ dict.label }}
-          </el-radio>
-        </el-radio-group>
+      <el-form-item label="目的类型" prop="type">
+        <el-select v-model="formData.type">
+          <el-option
+            v-for="item in getIntDictOptions(DICT_TYPE.IOT_DATA_SINK_TYPE_ENUM)"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          />
+        </el-select>
       </el-form-item>
-      <HttpConfigForm v-if="showConfig(IoTDataBridgeConfigType.HTTP)" v-model="formData.config" />
-      <MqttConfigForm v-if="showConfig(IoTDataBridgeConfigType.MQTT)" v-model="formData.config" />
+      <HttpConfigForm v-if="IotDataSinkTypeEnum.HTTP === formData.type" v-model="formData.config" />
+      <MqttConfigForm v-if="IotDataSinkTypeEnum.MQTT === formData.type" v-model="formData.config" />
       <RocketMQConfigForm
-        v-if="showConfig(IoTDataBridgeConfigType.ROCKETMQ)"
+        v-if="IotDataSinkTypeEnum.ROCKETMQ === formData.type"
         v-model="formData.config"
       />
       <KafkaMQConfigForm
-        v-if="showConfig(IoTDataBridgeConfigType.KAFKA)"
+        v-if="IotDataSinkTypeEnum.KAFKA === formData.type"
         v-model="formData.config"
       />
       <RabbitMQConfigForm
-        v-if="showConfig(IoTDataBridgeConfigType.RABBITMQ)"
+        v-if="IotDataSinkTypeEnum.RABBITMQ === formData.type"
         v-model="formData.config"
       />
       <RedisStreamConfigForm
-        v-if="showConfig(IoTDataBridgeConfigType.REDIS_STREAM)"
+        v-if="IotDataSinkTypeEnum.REDIS_STREAM === formData.type"
         v-model="formData.config"
       />
-      <el-form-item label="桥梁状态" prop="status">
+      <el-form-item label="目的状态" prop="status">
         <el-radio-group v-model="formData.status">
           <el-radio
             v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
@@ -61,7 +49,7 @@
           </el-radio>
         </el-radio-group>
       </el-form-item>
-      <el-form-item label="桥梁描述" prop="description">
+      <el-form-item label="目的描述" prop="description">
         <el-input v-model="formData.description" height="150px" type="textarea" />
       </el-form-item>
     </el-form>
@@ -74,12 +62,7 @@
 <script lang="ts" setup>
 import { DICT_TYPE, getDictObj, getIntDictOptions } from '@/utils/dict'
 import { CommonStatusEnum } from '@/utils/constants'
-import {
-  DataBridgeApi,
-  DataBridgeVO,
-  IoTDataBridgeConfigType,
-  IotDataBridgeDirectionEnum
-} from '@/api/iot/rule/databridge'
+import { DataSinkApi, DataSinkVO, IotDataSinkTypeEnum } from '@/api/iot/rule/data/sink'
 import {
   HttpConfigForm,
   KafkaMQConfigForm,
@@ -89,8 +72,8 @@ import {
   RocketMQConfigForm
 } from './config'
 
-/** IoT 数据桥梁的表单 */
-defineOptions({ name: 'IoTDataBridgeForm' })
+/** IoT 数据流转目的的表单 */
+defineOptions({ name: 'IoTDataSinkForm' })
 
 const { t } = useI18n() // 国际化
 const message = useMessage() // 消息弹窗
@@ -99,25 +82,23 @@ const dialogVisible = ref(false) // 弹窗的是否展示
 const dialogTitle = ref('') // 弹窗的标题
 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
 const formType = ref('') // 表单的类型:create - 新增;update - 修改
-const formData = ref<DataBridgeVO>({
+const formData = ref<DataSinkVO>({
   status: CommonStatusEnum.ENABLE,
-  direction: IotDataBridgeDirectionEnum.INPUT,
-  type: IoTDataBridgeConfigType.HTTP,
+  type: IotDataSinkTypeEnum.HTTP,
   config: {} as any
 })
 const formRules = reactive({
   // 通用字段
-  name: [{ required: true, message: '桥梁名称不能为空', trigger: 'blur' }],
-  status: [{ required: true, message: '桥梁状态不能为空', trigger: 'blur' }],
-  direction: [{ required: true, message: '桥梁方向不能为空', trigger: 'blur' }],
-  type: [{ required: true, message: '桥梁类型不能为空', trigger: 'change' }],
+  name: [{ required: true, message: '目的名称不能为空', trigger: 'blur' }],
+  status: [{ required: true, message: '目的状态不能为空', trigger: 'blur' }],
+  type: [{ required: true, message: '目的类型不能为空', trigger: 'change' }],
   // HTTP 配置
   'config.url': [{ required: true, message: '请求地址不能为空', trigger: 'blur' }],
   'config.method': [{ required: true, message: '请求方法不能为空', trigger: 'blur' }],
   // MQTT 配置
   'config.username': [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
   'config.password': [{ required: true, message: '密码不能为空', trigger: 'blur' }],
-  'config.clientId': [{ required: true, message: '客户端ID不能为空', trigger: 'blur' }],
+  'config.clientId': [{ required: true, message: '客户端 ID 不能为空', trigger: 'blur' }],
   'config.topic': [{ required: true, message: '主题不能为空', trigger: 'blur' }],
   // RocketMQ 配置
   'config.nameServer': [{ required: true, message: 'NameServer 地址不能为空', trigger: 'blur' }],
@@ -146,7 +127,7 @@ const formRules = reactive({
 
 const formRef = ref() // 表单 Ref
 const showConfig = computed(() => (val: number) => {
-  const dict = getDictObj(DICT_TYPE.IOT_DATA_BRIDGE_TYPE_ENUM, formData.value.type)
+  const dict = getDictObj(DICT_TYPE.IOT_DATA_SINK_TYPE_ENUM, formData.value.type)
   return dict && dict.value + '' === val + ''
 }) // 显示对应的 Config 配置项
 
@@ -160,7 +141,7 @@ const open = async (type: string, id?: number) => {
   if (id) {
     formLoading.value = true
     try {
-      formData.value = await DataBridgeApi.getDataBridge(id)
+      formData.value = await DataSinkApi.getDataSink(id)
     } finally {
       formLoading.value = false
     }
@@ -176,12 +157,12 @@ const submitForm = async () => {
   // 提交请求
   formLoading.value = true
   try {
-    const data = formData.value as unknown as DataBridgeVO
+    const data = formData.value as unknown as DataSinkVO
     if (formType.value === 'create') {
-      await DataBridgeApi.createDataBridge(data)
+      await DataSinkApi.createDataSink(data)
       message.success(t('common.createSuccess'))
     } else {
-      await DataBridgeApi.updateDataBridge(data)
+      await DataSinkApi.updateDataSink(data)
       message.success(t('common.updateSuccess'))
     }
     dialogVisible.value = false
@@ -203,8 +184,7 @@ const handleTypeChange = (val: number) => {
 const resetForm = () => {
   formData.value = {
     status: CommonStatusEnum.ENABLE,
-    direction: IotDataBridgeDirectionEnum.INPUT,
-    type: IoTDataBridgeConfigType.HTTP,
+    type: IotDataSinkTypeEnum.HTTP,
     config: {} as any
   }
   formRef.value?.resetFields()

+ 2 - 2
src/views/iot/rule/databridge/config/HttpConfigForm.vue → src/views/iot/rule/data/sink/config/HttpConfigForm.vue

@@ -29,7 +29,7 @@
 </template>
 
 <script lang="ts" setup>
-import { HttpConfig, IoTDataBridgeConfigType } from '@/api/iot/rule/databridge'
+import { HttpConfig, IotDataSinkTypeEnum } from '@/api/iot/rule/data/sink'
 import { useVModel } from '@vueuse/core'
 import { isEmpty } from '@/utils/is'
 import KeyValueEditor from './components/KeyValueEditor.vue'
@@ -73,7 +73,7 @@ onMounted(() => {
   }
 
   config.value = {
-    type: IoTDataBridgeConfigType.HTTP + '', // 序列化成对应类型时使用
+    type: IotDataSinkTypeEnum.HTTP + '', // 序列化成对应类型时使用
     url: '',
     method: 'POST',
     headers: {},

+ 2 - 2
src/views/iot/rule/databridge/config/KafkaMQConfigForm.vue → src/views/iot/rule/data/sink/config/KafkaMQConfigForm.vue

@@ -16,7 +16,7 @@
   </el-form-item>
 </template>
 <script lang="ts" setup>
-import { IoTDataBridgeConfigType, KafkaMQConfig } from '@/api/iot/rule/databridge'
+import { IotDataSinkTypeEnum, KafkaMQConfig } from '@/api/iot/rule/data/sink'
 import { useVModel } from '@vueuse/core'
 import { isEmpty } from '@/utils/is'
 
@@ -34,7 +34,7 @@ onMounted(() => {
     return
   }
   config.value = {
-    type: IoTDataBridgeConfigType.KAFKA + '', // 序列化成对应类型时使用
+    type: IotDataSinkTypeEnum.KAFKA + '', // 序列化成对应类型时使用
     bootstrapServers: '',
     username: '',
     password: '',

+ 2 - 2
src/views/iot/rule/databridge/config/MqttConfigForm.vue → src/views/iot/rule/data/sink/config/MqttConfigForm.vue

@@ -16,7 +16,7 @@
   </el-form-item>
 </template>
 <script lang="ts" setup>
-import { IoTDataBridgeConfigType, MqttConfig } from '@/api/iot/rule/databridge'
+import { IotDataSinkTypeEnum, MqttConfig } from '@/api/iot/rule/data/sink'
 import { useVModel } from '@vueuse/core'
 import { isEmpty } from '@/utils/is'
 
@@ -34,7 +34,7 @@ onMounted(() => {
     return
   }
   config.value = {
-    type: IoTDataBridgeConfigType.MQTT + '', // 序列化成对应类型时使用
+    type: IotDataSinkTypeEnum.MQTT + '', // 序列化成对应类型时使用
     url: '',
     username: '',
     password: '',

+ 2 - 2
src/views/iot/rule/databridge/config/RabbitMQConfigForm.vue → src/views/iot/rule/data/sink/config/RabbitMQConfigForm.vue

@@ -31,7 +31,7 @@
   </el-form-item>
 </template>
 <script lang="ts" setup>
-import { IoTDataBridgeConfigType, RabbitMQConfig } from '@/api/iot/rule/databridge'
+import { IotDataSinkTypeEnum, RabbitMQConfig } from '@/api/iot/rule/data/sink'
 import { useVModel } from '@vueuse/core'
 import { isEmpty } from '@/utils/is'
 
@@ -49,7 +49,7 @@ onMounted(() => {
     return
   }
   config.value = {
-    type: IoTDataBridgeConfigType.RABBITMQ + '', // 序列化成对应类型时使用
+    type: IotDataSinkTypeEnum.RABBITMQ + '', // 序列化成对应类型时使用
     host: '',
     port: 5672,
     virtualHost: '/',

+ 2 - 2
src/views/iot/rule/databridge/config/RedisStreamConfigForm.vue → src/views/iot/rule/data/sink/config/RedisStreamConfigForm.vue

@@ -28,7 +28,7 @@
   </el-form-item>
 </template>
 <script lang="ts" setup>
-import { IoTDataBridgeConfigType, RedisStreamMQConfig } from '@/api/iot/rule/databridge'
+import { IotDataSinkTypeEnum, RedisStreamMQConfig } from '@/api/iot/rule/data/sink'
 import { useVModel } from '@vueuse/core'
 import { isEmpty } from '@/utils/is'
 
@@ -46,7 +46,7 @@ onMounted(() => {
     return
   }
   config.value = {
-    type: IoTDataBridgeConfigType.REDIS_STREAM + '', // 序列化成对应类型时使用
+    type: IotDataSinkTypeEnum.REDIS_STREAM + '', // 序列化成对应类型时使用
     host: '',
     port: 6379,
     password: '',

+ 2 - 2
src/views/iot/rule/databridge/config/RocketMQConfigForm.vue → src/views/iot/rule/data/sink/config/RocketMQConfigForm.vue

@@ -27,7 +27,7 @@
   </el-form-item>
 </template>
 <script lang="ts" setup>
-import { IoTDataBridgeConfigType, RocketMQConfig } from '@/api/iot/rule/databridge'
+import { IotDataSinkTypeEnum, RocketMQConfig } from '@/api/iot/rule/data/sink'
 import { useVModel } from '@vueuse/core'
 import { isEmpty } from '@/utils/is'
 
@@ -45,7 +45,7 @@ onMounted(() => {
     return
   }
   config.value = {
-    type: IoTDataBridgeConfigType.ROCKETMQ + '', // 序列化成对应类型时使用
+    type: IotDataSinkTypeEnum.ROCKETMQ + '', // 序列化成对应类型时使用
     nameServer: '',
     accessKey: '',
     secretKey: '',

+ 0 - 0
src/views/iot/rule/databridge/config/components/KeyValueEditor.vue → src/views/iot/rule/data/sink/config/components/KeyValueEditor.vue


+ 0 - 0
src/views/iot/rule/databridge/config/index.ts → src/views/iot/rule/data/sink/config/index.ts


+ 24 - 46
src/views/iot/rule/databridge/index.vue → src/views/iot/rule/data/sink/index.vue

@@ -8,21 +8,21 @@
       class="-mb-15px"
       label-width="68px"
     >
-      <el-form-item label="桥梁名称" prop="name">
+      <el-form-item label="目的名称" prop="name">
         <el-input
           v-model="queryParams.name"
           class="!w-240px"
           clearable
-          placeholder="请输入桥梁名称"
+          placeholder="请输入目的名称"
           @keyup.enter="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="桥梁状态" prop="status">
+      <el-form-item label="目的状态" prop="status">
         <el-select
           v-model="queryParams.status"
           class="!w-240px"
           clearable
-          placeholder="请选择桥梁状态"
+          placeholder="请选择目的状态"
         >
           <el-option
             v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
@@ -32,30 +32,15 @@
           />
         </el-select>
       </el-form-item>
-      <el-form-item label="桥梁方向" prop="direction">
-        <el-select
-          v-model="queryParams.direction"
-          class="!w-240px"
-          clearable
-          placeholder="请选择桥梁方向"
-        >
-          <el-option
-            v-for="dict in getIntDictOptions(DICT_TYPE.IOT_DATA_BRIDGE_DIRECTION_ENUM)"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="桥梁类型" prop="type">
+      <el-form-item label="目的类型" prop="type">
         <el-select
           v-model="queryParams.type"
           class="!w-240px"
           clearable
-          placeholder="请选择桥梁类型"
+          placeholder="请选择目的类型"
         >
           <el-option
-            v-for="dict in getIntDictOptions(DICT_TYPE.IOT_DATA_BRIDGE_TYPE_ENUM)"
+            v-for="dict in getIntDictOptions(DICT_TYPE.IOT_DATA_SINK_TYPE_ENUM)"
             :key="dict.value"
             :label="dict.label"
             :value="dict.value"
@@ -83,7 +68,7 @@
           重置
         </el-button>
         <el-button
-          v-hasPermi="['iot:data-bridge:create']"
+          v-hasPermi="['iot:data-sink:create']"
           plain
           type="primary"
           @click="openForm('create')"
@@ -98,22 +83,17 @@
   <!-- 列表 -->
   <ContentWrap>
     <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
-      <el-table-column align="center" label="桥梁编号" prop="id" />
-      <el-table-column align="center" label="桥梁名称" prop="name" />
-      <el-table-column align="center" label="桥梁描述" prop="description" />
-      <el-table-column align="center" label="桥梁状态" prop="status">
+      <el-table-column align="center" label="目的编号" prop="id" />
+      <el-table-column align="center" label="目的名称" prop="name" />
+      <el-table-column align="center" label="目的描述" prop="description" />
+      <el-table-column align="center" label="目的状态" prop="status">
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
         </template>
       </el-table-column>
-      <el-table-column align="center" label="桥梁方向" prop="direction">
-        <template #default="scope">
-          <dict-tag :type="DICT_TYPE.IOT_DATA_BRIDGE_DIRECTION_ENUM" :value="scope.row.direction" />
-        </template>
-      </el-table-column>
-      <el-table-column align="center" label="桥梁类型" prop="type">
+      <el-table-column align="center" label="目的类型" prop="type">
         <template #default="scope">
-          <dict-tag :type="DICT_TYPE.IOT_DATA_BRIDGE_TYPE_ENUM" :value="scope.row.type" />
+          <dict-tag :type="DICT_TYPE.IOT_DATA_SINK_TYPE_ENUM" :value="scope.row.type" />
         </template>
       </el-table-column>
       <el-table-column
@@ -126,7 +106,7 @@
       <el-table-column align="center" fixed="right" label="操作" width="120px">
         <template #default="scope">
           <el-button
-            v-hasPermi="['iot:data-bridge:update']"
+            v-hasPermi="['iot:data-sink:update']"
             link
             type="primary"
             @click="openForm('update', scope.row.id)"
@@ -134,7 +114,7 @@
             编辑
           </el-button>
           <el-button
-            v-hasPermi="['iot:data-bridge:delete']"
+            v-hasPermi="['iot:data-sink:delete']"
             link
             type="danger"
             @click="handleDelete(scope.row.id)"
@@ -154,31 +134,29 @@
   </ContentWrap>
 
   <!-- 表单弹窗:添加/修改 -->
-  <DataBridgeForm ref="formRef" @success="getList" />
+  <DataSinkForm ref="formRef" @success="getList" />
 </template>
 
 <script lang="ts" setup>
 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
 import { dateFormatter } from '@/utils/formatTime'
-import { DataBridgeApi, DataBridgeVO } from '@/api/iot/rule/databridge'
-import DataBridgeForm from './IoTDataBridgeForm.vue'
+import { DataSinkApi, DataSinkVO } from '@/api/iot/rule/data/sink'
+import DataSinkForm from './DataSinkForm.vue'
 
-/** IoT 数据桥梁 列表 */
-defineOptions({ name: 'IotDataBridge' })
+/** IoT 数据流转目的 列表 */
+defineOptions({ name: 'IotDataSink' })
 
 const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
 
 const loading = ref(true) // 列表的加载中
-const list = ref<DataBridgeVO[]>([]) // 列表的数据
+const list = ref<DataSinkVO[]>([]) // 列表的数据
 const total = ref(0) // 列表的总页数
 const queryParams = reactive({
   pageNo: 1,
   pageSize: 10,
   name: undefined,
-  description: undefined,
   status: undefined,
-  direction: undefined,
   type: undefined,
   createTime: []
 })
@@ -188,7 +166,7 @@ const queryFormRef = ref() // 搜索的表单
 const getList = async () => {
   loading.value = true
   try {
-    const data = await DataBridgeApi.getDataBridgePage(queryParams)
+    const data = await DataSinkApi.getDataSinkPage(queryParams)
     list.value = data.list
     total.value = data.total
   } finally {
@@ -220,7 +198,7 @@ const handleDelete = async (id: number) => {
     // 删除的二次确认
     await message.delConfirm()
     // 发起删除
-    await DataBridgeApi.deleteDataBridge(id)
+    await DataSinkApi.deleteDataBridge(id)
     message.success(t('common.delSuccess'))
     // 刷新列表
     await getList()

+ 2 - 2
src/views/iot/rule/scene/components/action/ActionExecutor.vue

@@ -61,7 +61,7 @@
         @update:model-value="(val) => (actionConfig.alert = val)"
       />
 
-      <!-- 数据桥接执行器 -->
+      <!-- 数据流转目的执行器 -->
       <DataBridgeAction
         v-else-if="actionConfig.type === IotRuleSceneActionTypeEnum.DATA_BRIDGE"
         :model-value="actionConfig.dataBridgeId"
@@ -134,7 +134,7 @@ const initActionConfig = () => {
     actionConfig.value.alert = {} as ActionAlert
   }
 
-  // 数据桥接执行器初始化
+  // 数据流转目的执行器初始化
   if (
     actionConfig.value.type === IotRuleSceneActionTypeEnum.DATA_BRIDGE &&
     !actionConfig.value.dataBridgeId

+ 7 - 7
src/views/iot/rule/scene/components/action/DataBridgeAction.vue

@@ -1,8 +1,8 @@
 <template>
   <div class="bg-[#dbe5f6] p-10px">
     <div class="flex items-center">
-      <span class="mr-10px w-80px">数据桥梁</span>
-      <el-select v-model="dataBridgeId" class="!w-240px" clearable placeholder="选择数据桥接">
+      <span class="mr-10px w-80px">数据流转目的</span>
+      <el-select v-model="dataBridgeId" class="!w-240px" clearable placeholder="选择数据流转目的">
         <el-option
           v-for="bridge in dataBridgeList"
           :key="bridge.id"
@@ -16,20 +16,20 @@
 
 <script setup lang="ts">
 import { useVModel } from '@vueuse/core'
-import { DataBridgeApi } from '@/api/iot/rule/databridge'
+import { DataSinkApi } from '@/api/iot/rule/data/sink'
 
-/** 数据桥接执行器组件 */
+/** 数据流转目的执行器组件 */
 defineOptions({ name: 'DataBridgeAction' })
 
 const props = defineProps<{ modelValue: any }>()
 const emits = defineEmits(['update:modelValue'])
 const dataBridgeId = useVModel(props, 'modelValue', emits)
 
-const dataBridgeList = ref<any[]>([]) // 数据桥接列表
+const dataBridgeList = ref<any[]>([]) // 数据流转目的列表
 
-/** 获取数据桥接列表 */
+/** 获取数据流转目的列表 */
 const getDataBridgeList = async () => {
-  dataBridgeList.value = await DataBridgeApi.getSimpleDataBridgeList()
+  dataBridgeList.value = await DataSinkApi.getDataSinkSimpleList()
 }
 
 onMounted(() => {