IoTDataBridgeForm.vue 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <template>
  2. <Dialog v-model="dialogVisible" :title="dialogTitle">
  3. <el-form
  4. ref="formRef"
  5. v-loading="formLoading"
  6. :model="formData"
  7. :rules="formRules"
  8. label-width="120px"
  9. >
  10. <el-form-item label="桥梁名称" prop="name">
  11. <el-input v-model="formData.name" placeholder="请输入桥梁名称" />
  12. </el-form-item>
  13. <el-form-item label="桥梁方向" prop="direction">
  14. <el-radio-group v-model="formData.direction">
  15. <el-radio
  16. v-for="dict in getIntDictOptions(DICT_TYPE.IOT_DATA_BRIDGE_DIRECTION_ENUM)"
  17. :key="dict.value"
  18. :label="dict.value"
  19. >
  20. {{ dict.label }}
  21. </el-radio>
  22. </el-radio-group>
  23. </el-form-item>
  24. <el-form-item label="桥梁类型" prop="type">
  25. <el-radio-group v-model="formData.type">
  26. <el-radio
  27. v-for="dict in getIntDictOptions(DICT_TYPE.IOT_DATA_BRIDGE_TYPE_ENUM)"
  28. :key="dict.value"
  29. :label="dict.value"
  30. >
  31. {{ dict.label }}
  32. </el-radio>
  33. </el-radio-group>
  34. </el-form-item>
  35. <HttpConfigForm v-if="showConfig(IoTDataBridgeConfigType.HTTP)" v-model="formData.config" />
  36. <MqttConfigForm v-if="showConfig(IoTDataBridgeConfigType.MQTT)" v-model="formData.config" />
  37. <RocketMQConfigForm
  38. v-if="showConfig(IoTDataBridgeConfigType.ROCKETMQ)"
  39. v-model="formData.config"
  40. />
  41. <KafkaMQConfigForm
  42. v-if="showConfig(IoTDataBridgeConfigType.KAFKA)"
  43. v-model="formData.config!"
  44. />
  45. <RabbitMQConfigForm
  46. v-if="showConfig(IoTDataBridgeConfigType.RABBITMQ)"
  47. v-model="formData.config!"
  48. />
  49. <RedisStreamMQConfigForm
  50. v-if="showConfig(IoTDataBridgeConfigType.REDIS_STREAM)"
  51. v-model="formData.config!"
  52. />
  53. <el-form-item label="桥梁状态" prop="status">
  54. <el-radio-group v-model="formData.status">
  55. <el-radio
  56. v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
  57. :key="dict.value"
  58. :label="dict.value"
  59. >
  60. {{ dict.label }}
  61. </el-radio>
  62. </el-radio-group>
  63. </el-form-item>
  64. <el-form-item label="桥梁描述" prop="description">
  65. <el-input v-model="formData.description" height="150px" type="textarea" />
  66. </el-form-item>
  67. </el-form>
  68. <template #footer>
  69. <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
  70. <el-button @click="dialogVisible = false">取 消</el-button>
  71. </template>
  72. </Dialog>
  73. </template>
  74. <script lang="ts" setup>
  75. import { DICT_TYPE, getDictLabel, getIntDictOptions } from '@/utils/dict'
  76. import { DataBridgeApi, DataBridgeVO, IoTDataBridgeConfigType } from '@/api/iot/rule/databridge'
  77. import {
  78. HttpConfigForm,
  79. KafkaMQConfigForm,
  80. MqttConfigForm,
  81. RabbitMQConfigForm,
  82. RedisStreamMQConfigForm,
  83. RocketMQConfigForm
  84. } from './config'
  85. /** IoT 数据桥梁 表单 */
  86. defineOptions({ name: 'IoTDataBridgeForm' })
  87. const { t } = useI18n() // 国际化
  88. const message = useMessage() // 消息弹窗
  89. const dialogVisible = ref(false) // 弹窗的是否展示
  90. const dialogTitle = ref('') // 弹窗的标题
  91. const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
  92. const formType = ref('') // 表单的类型:create - 新增;update - 修改
  93. const formData = ref<DataBridgeVO>({
  94. status: 0,
  95. direction: 1,
  96. type: 1,
  97. config: {} as any
  98. })
  99. const formRules = reactive({
  100. // 通用字段
  101. name: [{ required: true, message: '桥梁名称不能为空', trigger: 'blur' }],
  102. status: [{ required: true, message: '桥梁状态不能为空', trigger: 'blur' }],
  103. direction: [{ required: true, message: '桥梁方向不能为空', trigger: 'blur' }],
  104. type: [{ required: true, message: '桥梁类型不能为空', trigger: 'change' }],
  105. // HTTP 配置
  106. 'config.url': [{ required: true, message: '请求地址不能为空', trigger: 'blur' }],
  107. 'config.method': [{ required: true, message: '请求方法不能为空', trigger: 'blur' }],
  108. // MQTT 配置
  109. 'config.username': [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
  110. 'config.password': [{ required: true, message: '密码不能为空', trigger: 'blur' }],
  111. 'config.clientId': [{ required: true, message: '客户端ID不能为空', trigger: 'blur' }],
  112. 'config.topic': [{ required: true, message: '主题不能为空', trigger: 'blur' }],
  113. // RocketMQ 配置
  114. 'config.nameServer': [{ required: true, message: 'NameServer 地址不能为空', trigger: 'blur' }],
  115. 'config.accessKey': [{ required: true, message: 'AccessKey 不能为空', trigger: 'blur' }],
  116. 'config.secretKey': [{ required: true, message: 'SecretKey 不能为空', trigger: 'blur' }],
  117. 'config.group': [{ required: true, message: '消费组不能为空', trigger: 'blur' }],
  118. // Kafka 配置
  119. 'config.bootstrapServers': [{ required: true, message: '服务地址不能为空', trigger: 'blur' }],
  120. 'config.ssl': [{ required: true, message: 'SSL 配置不能为空', trigger: 'change' }],
  121. // RabbitMQ 配置
  122. 'config.host': [{ required: true, message: '主机地址不能为空', trigger: 'blur' }],
  123. 'config.port': [
  124. { required: true, message: '端口不能为空', trigger: 'blur' },
  125. { type: 'number', min: 1, max: 65535, message: '端口号范围 1-65535', trigger: 'blur' }
  126. ],
  127. 'config.virtualHost': [{ required: true, message: '虚拟主机不能为空', trigger: 'blur' }],
  128. 'config.exchange': [{ required: true, message: '交换机不能为空', trigger: 'blur' }],
  129. 'config.routingKey': [{ required: true, message: '路由键不能为空', trigger: 'blur' }],
  130. 'config.queue': [{ required: true, message: '队列不能为空', trigger: 'blur' }],
  131. // Redis Stream 配置
  132. 'config.database': [
  133. { required: true, message: '数据库索引不能为空', trigger: 'blur' },
  134. { type: 'number', min: 0, message: '数据库索引必须是非负整数', trigger: 'blur' }
  135. ]
  136. })
  137. const formRef = ref() // 表单 Ref
  138. const showConfig = computed(() => (val: string) => {
  139. const label = getDictLabel(DICT_TYPE.IOT_DATA_BRIDGE_TYPE_ENUM, formData.value.type)
  140. return label && label === val
  141. }) // 显示对应的 Config 配置项
  142. /** 打开弹窗 */
  143. const open = async (type: string, id?: number) => {
  144. dialogVisible.value = true
  145. dialogTitle.value = t('action.' + type)
  146. formType.value = type
  147. resetForm()
  148. // 修改时,设置数据
  149. if (id) {
  150. formLoading.value = true
  151. try {
  152. formData.value = await DataBridgeApi.getDataBridge(id)
  153. } finally {
  154. formLoading.value = false
  155. }
  156. }
  157. }
  158. defineExpose({ open }) // 提供 open 方法,用于打开弹窗
  159. /** 提交表单 */
  160. const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
  161. const submitForm = async () => {
  162. // 校验表单
  163. await formRef.value.validate()
  164. // 提交请求
  165. formLoading.value = true
  166. try {
  167. const data = formData.value as unknown as DataBridgeVO
  168. if (formType.value === 'create') {
  169. await DataBridgeApi.createDataBridge(data)
  170. message.success(t('common.createSuccess'))
  171. } else {
  172. await DataBridgeApi.updateDataBridge(data)
  173. message.success(t('common.updateSuccess'))
  174. }
  175. dialogVisible.value = false
  176. // 发送操作成功的事件
  177. emit('success')
  178. } finally {
  179. formLoading.value = false
  180. }
  181. }
  182. /** 重置表单 */
  183. const resetForm = () => {
  184. formData.value = {
  185. status: 0,
  186. direction: 1,
  187. type: 1,
  188. config: {} as any
  189. }
  190. formRef.value?.resetFields()
  191. }
  192. </script>