Ver código fonte

fix: text错误

lvkun996 2 anos atrás
pai
commit
27954548f7
1 arquivos alterados com 857 adições e 857 exclusões
  1. 857 857
      src/pages/Iot/rule/forwardRule.vue

+ 857 - 857
src/pages/Iot/rule/forwardRule.vue

@@ -1,857 +1,857 @@
-<template>
-
-<StatisticsTemplate
-    title="规则统计"
-    :list="state.forwardCount"
-/>
-
-<a-card style="margin-top: 20px;" >
-  <table-pro
-    style="margin-top: 20px;"
-    :columns="columns"
-    :service="RuleController.pageForward"
-    :serviceParams="queryParams"
-    @add="openModal('add', {})"
-    ref="tableProDom"
-  >
-    <template #search >
-      <a-row style="width: 100%"  :gutter="[8,8]" >
-        <a-col :xs="20" :md="12" :xl="4">
-          <a-input  allowClear v-model:value="queryParams.ruleId" placeholder="请输入规则id"></a-input>
-        </a-col>
-        <a-col :xs="20" :md="12" :xl="4">
-          <a-input allowClear v-model:value="queryParams.ruleLabel" placeholder="请输入规则名称" ></a-input>
-        </a-col>
-        <a-col :xs="20" :md="12" :xl="4" >
-              <a-select allowClear style="width: 100% !important;" v-model:value="queryParams.subjectResource"    placeholder="选择数据来源">
-                <a-select-option
-                  v-for="item in subjectResourceList"
-                  :key="item.key"
-                  :value="item.value"
-                >
-                {{item.name}}
-                </a-select-option>
-              </a-select>
-        </a-col>
-        <a-col :xs="20" :md="12" :xl="4" >
-              <a-select allowClear style="width: 100% !important;" v-model:value="queryParams.subjectEvent"  placeholder="选择触发事件">
-                <a-select-option
-                  v-for="item in Array.from(RuleController.SubjectEventMap, ([key, value]) => ({ ...value, value: value.key }))"
-                  :key="item.key"
-                  :value="item.value"
-                >
-                {{item.name}}
-                </a-select-option>
-              </a-select>
-        </a-col>
-        <a-col :xs="20" :md="12" :xl="3" >
-              <a-select allowClear style="width: 100% !important;" v-model:value="queryParams.status" >
-                <a-select-option
-                  v-for="item in statusList"
-                  :key="item.key"
-                  :value="item.value"
-                >
-                {{item.name}}
-                </a-select-option>
-              </a-select>
-        </a-col>
-        <a-col :xs="20" :md="12" :xl="3" >
-          <a-button type="primary" @click="search">搜索</a-button>
-        </a-col>
-      </a-row>
-    </template>
-    <template #render="{column, record}"  >
-      <template v-if="column.key === 'id'" >
-          <a  @click="openDetailModal(record.id)">{{record.id}}</a>
-      </template>
-      <template v-if="column.key === 'subjectResource'" >
-        <a-tag >{{RuleController.SubjectResourceMap.get(record.subjectResource)?.name}}</a-tag>
-      </template>
-      <template v-if="column.key === 'subjectEvent'" >
-        <a-tag >{{RuleController.SubjectEventMap.get(record.subjectEvent)?.name}}</a-tag>
-      </template>
-      <template v-if="column.key === 'status'" >
-        <a-switch
-          v-model:checked="record.status"
-          checked-children="运行中"
-          un-checked-children="已停止"
-          @click="changeStatus(record)"
-        />
-      </template>
-      <template v-if="column.key === 'action'" >
-        <a-space>
-              <a @click="openModalDebug(record.id)">调试</a>
-              <a @click="openDetailModal(record.id)">详情</a>
-              <a @click="openModal('update', record)">编辑</a>
-              <a-popconfirm
-                  title="确实要删除吗?"
-                  ok-text="确定"
-                  cancel-text="取消"
-                  @confirm="delForwardRule(record.id)"
-                >
-                  <a>删除</a>
-              </a-popconfirm>
-        </a-space>
-      </template>
-    </template>
-  </table-pro>
-</a-card>
-
-<RealView
-  :open="state.visible"
-  title="创建规则"
-  @cancel="state.visible = false"
-  @ok="ok"
->
-  <a-card title="设置转发数据" >
-    <div style="margin-bottom: 20px;" >针对部分类型数据提供的快速配置,将引导您完成简单的业务设置。您也可以直接编辑过滤语句,实现更复杂的查询要求</div>
-    <a-form :label-col="{span: 4 }" :wrapper-col="{ span: 14 }" style="height: 300px; overflow-y: auto;">
-        <a-form-item  label="规则名称" v-bind="validateInfosStep1.ruleLabel" >
-          <a-input v-model:value="forwardRStateStep1.ruleLabel" ></a-input>
-        </a-form-item>
-        <a-form-item label="数据来源" v-bind="validateInfosStep1.subjectResource">
-            <a-select
-            allowClear
-            style="width: 100%;"
-            v-model:value="forwardRStateStep1.subjectResource"
-          >
-            <a-select-option
-              v-for="item in subjectResourceList"
-              :key="item.key"
-              :value="item.key"
-            >
-              {{item.name}}
-            </a-select-option>
-          </a-select>
-        </a-form-item>
-        <a-form-item label="数据来源" v-bind="validateInfosStep1.subjectEvent">
-            <a-select
-            allowClear
-            style="width: 100%;"
-            v-model:value="forwardRStateStep1.subjectEvent"
-          >
-            <a-select-option
-              v-for="item in subjectEventList"
-              :key="item.key"
-              :value="item.key"
-            >
-              {{item.name}}
-            </a-select-option>
-          </a-select>
-        </a-form-item>
-        <a-form-item label="规则描述" >
-          <a-textarea
-            v-model:value="forwardRStateStep1.ruleDescription"
-            placeholder="请输入规则描述"
-            :auto-size="{ minRows: 2, maxRows: 5 }"
-          />
-        </a-form-item>
-    </a-form>
-  </a-card>
-  <a-card title="设置转发目标" style="margin-top: 20px;" >
-    <template #extra > <a-button type="primary" @click="addForwardState">添加</a-button></template>
-    <div>您可以设置将数据转发至华为云其他服务或私有服务器。</div>
-      <a-table
-        style="margin-top: 20px;"
-        v-if="forwardRuleTargets.length"
-        :columns="forwardRuleTargetsColumns"
-        :data-source="forwardRuleTargets"
-        size="middle"
-      >
-        <template #bodyCell="{column, record, index}" >
-          <template v-if="column.key === 'action'" >
-            <a-space>
-              <a @click="updateForwardRuleTargets(record, index)">编辑</a>
-              <a @click="forwardRuleTargets.splice(index, 1)">删除</a>
-            </a-space>
-          </template>
-        </template>
-      </a-table>
-      <a-empty v-else :image="Empty.PRESENTED_IMAGE_SIMPLE" />
-  </a-card>
-</RealView>
-
-<modal-pro
-  style="width: 800px"
-  label="转发目标"
-  :open="state.targetVisible"
-  ok-text="确定"
-  @cancel="closeModal"
-  @ok="ok"
->
-    <a-form :label-col="{span: 4 }" :wrapper-col="{ span: 14 }" style="height: 400px; overflow-y: auto;">
-    <a-form-item label="转发目标">
-        <a-select
-        allowClear
-        style="width: 100%;"
-        v-model:value="forwardState.targetType"
-      >
-        <a-select-option
-          v-for="item in forwardTatget"
-          :key="item.key"
-          :value="item.key"
-        >
-          {{item.name}}
-        </a-select-option>
-      </a-select>
-    </a-form-item>
-      <span v-if="forwardState.targetType === 'HTTP'" >
-        <a-form-item label="地址" v-bind="validateInfos.endpointUrl">
-          <a-input allowClear v-model:value="forwardState.endpointUrl" placeholder="请填写http地址" />
-        </a-form-item>
-        <a-form-item label="方法" v-bind="validateInfos.requestMethod">
-          <a-select
-            allowClear
-            style="width: 100%;"
-            v-model:value="forwardState.requestMethod"
-          >
-            <a-select-option
-              v-for="item in HttpRequestMethods"
-              :key="item.key"
-              :value="item.key"
-            >
-              {{item.name}}
-            </a-select-option>
-          </a-select>
-        </a-form-item>
-        <a-form-item label="超时时间" v-bind="validateInfos.defaultTimeout">
-          <a-input-number id="inputNumber" v-model:value="forwardState.defaultTimeout" />
-        </a-form-item>
-        <a-form-item label="请求头" v-bind="validateInfos.requestHeaders">
-          <a-input-group style="margin-top: 10px;" size="large" v-for="(item, index) in forwardState.requestHeaders" :key="index">
-            <a-row :gutter="8">
-              <a-col :span="5">
-                <a-input allowClear style="height: 30px;" v-model:value="item.key" placeholder="key" />
-              </a-col>
-              <a-col :span="8">
-                <a-input allowClear style="height: 30px;"  v-model:value="item.value" placeholder="value" />
-              </a-col>
-              <a-col>
-                <a-button type="link" danger @click="forwardState.requestHeaders.splice(index, 1)" >删除</a-button>
-              </a-col>
-            </a-row>
-          </a-input-group>
-          <a-button style="margin-top: 20px;" @click="addRequestHeaders('requestHeaders')" type="primary" >添加参数</a-button>
-        </a-form-item>
-      </span>
-      <span v-if="forwardState.targetType === 'KAFKA'" >
-        <a-form-item label="主题" v-bind="validateInfos.topic" >
-          <a-input allowClear placeholder="请填写主题" v-model:value="forwardState.topic" ></a-input>
-        </a-form-item>
-        <a-form-item label="地址" v-bind="validateInfos.topic" >
-          <a-input allowClear placeholder="请填写地址" v-model:value="forwardState.bootstrapServers" ></a-input>
-        </a-form-item>
-        <a-form-item label="acks" v-bind="validateInfos.acks" >
-          <a-input allowClear placeholder="请填写acks" v-model:value="forwardState.acks"  disabled ></a-input>
-        </a-form-item>
-        <a-form-item label="重试次数" v-bind="validateInfos.retries" >
-          <a-input allowClear placeholder="请填写重试次数" v-model:value="forwardState.retries"></a-input>
-        </a-form-item>
-        <a-form-item label="batchSize" v-bind="validateInfos.batchSize" >
-          <a-input allowClear placeholder="请填写batchSize" v-model:value="forwardState.batchSize"></a-input>
-        </a-form-item>
-        <a-form-item label="linger" v-bind="validateInfos.linger" >
-          <a-input allowClear placeholder="请填写linger" v-model:value="forwardState.linger"></a-input>
-        </a-form-item>
-        <a-form-item label="bufferMemory" v-bind="validateInfos.bufferMemory" >
-          <a-input allowClear placeholder="请填写bufferMemory" v-model:value="forwardState.bufferMemory"></a-input>
-        </a-form-item>
-        <a-form-item label="keySerializer" v-bind="validateInfos.keySerializer" >
-          <a-input allowClear placeholder="请填写keySerializer" v-model:value="forwardState.keySerializer"></a-input>
-        </a-form-item>
-        <a-form-item label="valueSerializer" v-bind="validateInfos.valueSerializer" >
-          <a-input allowClear placeholder="请填写valueSerializer" v-model:value="forwardState.valueSerializer"></a-input>
-        </a-form-item>
-        <a-form-item label="其他参数">
-          <a-input-group style="margin-top: 10px;" size="large" v-for="(item, index) in forwardState.otherProperties" :key="index">
-            <a-row :gutter="8">
-              <a-col :span="5">
-                <a-input allowClear style="height: 30px;" v-model:value="item.key" placeholder="key" />
-              </a-col>
-              <a-col :span="8">
-                <a-input allowClear style="height: 30px;"  v-model:value="item.value" placeholder="value" />
-              </a-col>
-              <a-col>
-                <a-button type="link" danger @click="forwardState.otherProperties.splice(index, 1)" >删除</a-button>
-              </a-col>
-            </a-row>
-          </a-input-group>
-          <a-button style="margin-top: 20px;" @click="addRequestHeaders('otherProperties')" type="primary" >添加参数</a-button>
-        </a-form-item>
-      </span>
-      <span v-if="forwardState.targetType === 'MQTT'"  >
-        <a-form-item label="主题" v-bind="validateInfos.topic" >
-          <a-input allowClear placeholder="请填写主题" v-model:value="forwardState.topic" ></a-input>
-        </a-form-item>
-        <a-form-item label="broker服务器" v-bind="validateInfos.broker" >
-          <a-input allowClear placeholder="请填写broker服务器" v-model:value="forwardState.broker" ></a-input>
-        </a-form-item>
-        <a-form-item label="连接超时时间" v-bind="validateInfos.connectTimeout" >
-          <a-input-number placeholder="请填写连接超时时间" v-model:value="forwardState.connectTimeout" ></a-input-number>
-        </a-form-item>
-        <a-form-item label="客户端ID" v-bind="validateInfos.clientId" >
-          <a-input-number placeholder="请填写客户端ID" v-model:value="forwardState.clientId" ></a-input-number>
-        </a-form-item>
-        <a-form-item label="保留消息" >
-          <a-switch v-model:checked="forwardState.retainedMessage" checked-children="保留" un-checked-children="不保留" />
-        </a-form-item>
-        <a-form-item label="清除Session" >
-          <a-switch v-model:checked="forwardState.cleanSession" checked-children="清除" un-checked-children="不清除" />
-        </a-form-item>
-        <a-form-item label="qos" v-bind="validateInfos.qos" >
-          <a-input allowClear placeholder="请填写qos" v-model:value="forwardState.qos" ></a-input>
-        </a-form-item>
-        <a-form-item label="用户名" v-bind="validateInfos.userName">
-          <a-input allowClear placeholder="请填写用户名" v-model:value="forwardState.userName" ></a-input>
-        </a-form-item>
-        <a-form-item label="密码" v-bind="validateInfos.password" >
-          <a-input allowClear placeholder="请填写密码" v-model:value="forwardState.password" ></a-input>
-        </a-form-item>
-      </span>
-      <span v-if="forwardState.targetType === 'RABBIT'" >
-        <a-form-item label="exchangeName" v-bind="validateInfos.exchangeName">
-          <a-input allowClear v-model:value="forwardState.exchangeName" placeholder="请填写交换名" />
-        </a-form-item>
-        <a-form-item label="路由密钥" v-bind="validateInfos.routingKey">
-          <a-input allowClear v-model:value="forwardState.routingKey" placeholder="请填写路由密钥" />
-        </a-form-item>
-        <a-form-item label="消息属性" v-bind="validateInfos.messageProperties">
-          <a-input allowClear v-model:value="forwardState.messageProperties" placeholder="请填写消息属性" />
-        </a-form-item>
-        <a-form-item label="域名" v-bind="validateInfos.host">
-          <a-input allowClear v-model:value="forwardState.host" placeholder="请填写域名" />
-        </a-form-item>
-        <a-form-item label="端口" v-bind="validateInfos.port">
-          <a-input allowClear v-model:value="forwardState.port" placeholder="请填写端口" />
-        </a-form-item>
-        <a-form-item label="虚拟主机" v-bind="validateInfos.virtualHost">
-          <a-input allowClear v-model:value="forwardState.virtualHost" placeholder="请填写虚拟主机" />
-        </a-form-item>
-        <a-form-item label="自动恢复" >
-          <a-switch v-model:checked="forwardState.automaticRecoveryEnabled" checked-children="启用" un-checked-children="未启用" />
-        </a-form-item>
-        <a-form-item label="连接超时" >
-          <a-input allowClear  v-model:value="forwardState.connectionTimeout" placeholder="请填写连接超时时间" />
-        </a-form-item>
-        <a-form-item label="握手超时" >
-          <a-input allowClear v-model:value="forwardState.handshakeTimeout" placeholder="请填写握手超时" />
-        </a-form-item>
-        <a-form-item label="用户名" v-bind="validateInfos.userName">
-          <a-input allowClear placeholder="请填写用户名" v-model:value="forwardState.userName" ></a-input>
-        </a-form-item>
-        <a-form-item label="密码" v-bind="validateInfos.password" >
-          <a-input allowClear placeholder="请填写密码" v-model:value="forwardState.password" ></a-input>
-        </a-form-item>
-      </span>
-    </a-form>
-</modal-pro>
-
-<modal-pro
-  style="width: 1000px;"
-  label="详情"
-  :open="state.detailVisible"
-  @cancel="state.detailVisible = false"
-  @ok="state.detailVisible  = false"
->
-  <a-form  :label-col="{span: 2}" style="height: 400px;overflow: hidden;overflow-y: scroll;">
-    <a-form-item label="规则名称"> {{detailForwardRef.ruleLabel}} </a-form-item>
-    <a-form-item label="数据来源"> {{RuleController.SubjectResourceMap.get(detailForwardRef.subjectResource)?.name}} </a-form-item>
-    <a-form-item label="触发事件"> {{RuleController.SubjectEventMap.get(detailForwardRef.subjectEvent)?.name}} </a-form-item>
-    <a-form-item label="状态"> {{detailForwardRef.status ?  '运行中' : '已停止'}} </a-form-item>
-    <a-form-item label="HTTP" v-if="detailHTTPList.length">
-      <a-table
-        :columns="detailColumn['HTTP']"
-        :data-source="detailHTTPList"
-        :pagination="false"
-      />
-
-    </a-form-item>
-    <a-form-item label="Kafka"  v-if="detailKAFKAList.length">
-      <a-table
-        :columns="detailColumn['Kafka']"
-        :data-source="detailKAFKAList"
-        :pagination="false"
-      >
-
-      </a-table>
-    </a-form-item>
-    <a-form-item label="MQTT" v-if="detailMQTTList.length">
-      <a-table
-        :columns="detailColumn['MQTT']"
-        :data-source="detailMQTTList"
-        :pagination="false"
-      >
-      </a-table>
-    </a-form-item>
-    <a-form-item label="RabbitMQ" v-if="detailRABBITList.length">
-      <a-table
-        :columns="detailColumn['RabbitMQ']"
-        :data-source="detailRABBITList"
-        :pagination="false"
-      >
-      </a-table>
-    </a-form-item>
-  </a-form>
-</modal-pro>
-
-<modal-pro
-  label="调试"
-  :open="state.testVisble"
-  @cancel="state.testVisble = false"
-  @ok="dispatchDebug"
-  style="width: 640px;"
->
-  <TestDialog ref="testDialogRef"/>
-</modal-pro>
-
-</template>
-
-<script lang='ts' setup >
-import { onMounted, reactive, ref } from 'vue'
-import { RuleController } from '@/controller/index'
-import { Form, Empty, message } from 'ant-design-vue'
-import { computed } from '@vue/reactivity'
-import TestDialog from './components/testDialog.vue'
-import StatisticsTemplate from '@/components/StatisticsTemplate/index.vue'
-import { SubjectEventEnum, SubjectResourceEnum } from '@/enum/common'
-import { useId } from '@/hooks'
-import { RealView } from '@/components/RealView/index'
-
-const columns = [
-  {
-    title: '规则名称',
-    dataIndex: 'ruleLabel'
-  },
-  {
-    title: '规则ID',
-    dataIndex: 'id',
-    key: 'id'
-  },
-  {
-    title: '数据来源',
-    dataIndex: 'subjectResource',
-    key: 'subjectResource'
-  },
-  {
-    title: '触发事件',
-    dataIndex: 'subjectEvent',
-    key: 'subjectEvent'
-  },
-  {
-    title: '状态',
-    dataIndex: 'status',
-    key: 'status'
-  },
-  {
-    title: '操作',
-    dataIndex: 'action',
-    key: 'action'
-  }
-]
-
-const forwardRuleTargetsColumns = [
-  {
-    title: '转发目标',
-    dataIndex: 'targetType'
-  },
-  {
-    title: '操作',
-    dataIndex: 'action',
-    key: 'action'
-  }
-
-]
-
-const forwardTatget = [
-  { name: 'RabbitMQ', key: 'RABBIT' },
-  { name: 'Kafka', key: 'KAFKA' },
-  { name: 'HTTP编码', key: 'HTTP' },
-  { name: 'MQTT', key: 'MQTT' }
-]
-
-const HttpRequestMethods = [
-  { name: 'GET', key: 'GET' },
-  { name: 'POST', key: 'POST' },
-  { name: 'PUT', key: 'PUT' }
-]
-
-const subjectResourceList = Array.from(RuleController.SubjectResourceMap, ([key, value]) => ({ ...value, value: value.key }))
-
-const subjectEventListByResourceMap = new Map([
-  [SubjectResourceEnum.DEVICE, [SubjectEventEnum.DEVICE_CREATE, SubjectEventEnum.DEVICE_DELETE]],
-  [SubjectResourceEnum.DEVICE_STATUS, [SubjectEventEnum.DEVICE_STATUS_UPDATE]],
-  [SubjectResourceEnum.DEVICE_ATTRIBUTE, [SubjectEventEnum.DEVICE_ATTRIBUTE_REPORT]],
-  [SubjectResourceEnum.MODEL, [SubjectEventEnum.MODEL_CREATE, SubjectEventEnum.MODEL_DELETE]]
-])
-
-const subjectEventList = computed(() => {
-  const subjectevents = Array.from(RuleController.SubjectEventMap, ([key, value]) => ({ ...value, value: value.key }))
-  const keys = subjectEventListByResourceMap.get(forwardRStateStep1.subjectResource as SubjectResourceEnum)
-  return subjectevents.filter(subjectevent => keys?.includes(subjectevent.key))
-})
-
-const statusList = [
-  { name: '所有状态', key: '', value: '' },
-  { name: '运行中', key: 'status', value: true },
-  { name: '未启动', key: 'status', value: false }
-]
-
-const detailColumn = reactive({
-  HTTP: [
-    { title: 'http地址', dataIndex: 'endpointUrl' },
-    { title: 'requestMethod', dataIndex: '请求方法' },
-    { title: 'defaultTimeout', dataIndex: '超时时间' },
-    { title: 'requestHeaders', dataIndex: '请求头' }
-  ],
-  Kafka: [
-    { title: '主题', dataIndex: 'topic' },
-    { title: '地址', dataIndex: 'bootstrapServers' },
-    { title: 'acks', dataIndex: 'acks' },
-    { title: '重试', dataIndex: 'retries' },
-    { title: 'batchSize', dataIndex: 'batchSize' },
-    { title: 'linger', dataIndex: 'linger' },
-    { title: 'bufferMemory', dataIndex: 'bufferMemory' },
-    { title: 'keySerializer', dataIndex: 'keySerializer' },
-    { title: 'valueSerializer', dataIndex: 'valueSerializer' },
-    { title: '其他属性', dataIndex: 'otherProperties' }
-  ],
-  MQTT: [
-    { title: '主题', dataIndex: 'topic' },
-    { title: 'broker服务器', dataIndex: 'broker' },
-    { title: '连接超时时间', dataIndex: 'connectTimeout' },
-    { title: 'clientId', dataIndex: 'clientId' },
-    { title: 'retainedMessage', dataIndex: 'retainedMessage' },
-    { title: 'cleanSession', dataIndex: 'cleanSession' },
-    { title: 'qos', dataIndex: 'qos' },
-    { title: '用户名', dataIndex: 'userName' },
-    { title: '密码', dataIndex: 'password' }
-  ],
-  RabbitMQ: [
-    { title: '主题', dataIndex: 'exchangeName' },
-    { title: '路由密钥', dataIndex: 'routingKey' },
-    { title: '消息属性', dataIndex: 'messageProperties' },
-    { title: '域名', dataIndex: 'host' },
-    { title: '端口', dataIndex: 'port' },
-    { title: '虚拟主机', dataIndex: 'virtualHost' },
-    { title: '自动恢复', dataIndex: 'automaticRecoveryEnabled' },
-    { title: '连接超时', dataIndex: 'connectionTimeout' },
-    { title: '握手超时', dataIndex: 'handshakeTimeout' },
-    { title: '用户名', dataIndex: 'userName' },
-    { title: '密码', dataIndex: 'password' }
-  ]
-})
-
-const useForm = Form.useForm
-
-const tableProDom = ref('')
-
-const testDialogRef = ref('')
-
-let queryParams = reactive({
-  ruleId: '',
-  ruleLabel: '',
-  status: '',
-  subjectEvent: null,
-  subjectResource: null
-})
-
-const state = reactive({
-  loading: false,
-  dataSource: [],
-  visible: false,
-  targetVisible: false,
-  detailVisible: false,
-  stepCount: 0,
-  opraState: 'add',
-  forwardId: '',
-  testVisble: false,
-  forwardCount: [],
-  updateIndex: '' // 对规则的编辑时的下标
-})
-
-const requestHeader = { key: '', value: '' }
-
-const detailForwardRef = ref<Partial<IOT.API.RULE.ForwardRule>>({})
-
-const detailHTTPList = computed(() => detailForwardRef.value && detailForwardRef.value.forwardRuleTargets ? detailForwardRef.value.forwardRuleTargets!.filter(item => item.targetType === 'HTTP') : [])
-const detailRABBITList = computed(() => detailForwardRef.value && detailForwardRef.value.forwardRuleTargets ? detailForwardRef.value.forwardRuleTargets!.filter(item => item.targetType === 'RABBIT') : [])
-const detailKAFKAList = computed(() => detailForwardRef.value && detailForwardRef.value.forwardRuleTargets ? detailForwardRef.value.forwardRuleTargets!.filter(item => item.targetType === 'KAFKA') : [])
-const detailMQTTList = computed(() => detailForwardRef.value && detailForwardRef.value.forwardRuleTargets ? detailForwardRef.value.forwardRuleTargets!.filter(item => item.targetType === 'MQTT') : [])
-
-const initForwardState = {
-  targetType: '',
-  endpointUrl: '',
-  requestMethod: 'GET',
-  defaultTimeout: 6,
-  requestHeaders: [],
-  topic: '',
-  bootstrapServers: '',
-  acks: '-1',
-  retries: '0',
-  batchSize: '65535',
-  linger: '0',
-  bufferMemory: '33554432',
-  keySerializer: '',
-  valueSerializer: '',
-  otherProperties: [],
-  broker: '',
-  connectTimeout: '',
-  clientId: '',
-  retainedMessage: false,
-  cleanSession: false,
-  qos: '',
-  userName: '',
-  password: '',
-  exchangeName: '',
-  routingKey: '',
-  messageProperties: '',
-  host: '',
-  port: '',
-  virtualHost: '/',
-  automaticRecoveryEnabled: false,
-  connectionTimeout: 60000,
-  handshakeTimeout: 10000
-}
-
-const forwardState = reactive(JSON.parse(JSON.stringify(initForwardState)))
-
-const forwardRStateStep1 = reactive({
-  ruleLabel: '',
-  subjectResource: '',
-  subjectEvent: '',
-  ruleDescription: ''
-})
-
-const forwardRuleState = reactive({
-  HTTP: {
-    endpointUrl: [{ required: true, message: '请填写http地址' }],
-    requestMethod: [{ required: true, message: '请填写请求方法' }],
-    defaultTimeout: [{ required: true, message: '请填写超时时间' }],
-    requestHeaders: [{ required: true, message: '请填写请求头参数' }]
-  },
-  KAFKA: {
-    topic: [{ required: true, message: '请填写主题' }],
-    bootstrapServers: [{ required: true, message: '请填写地址' }],
-    acks: [{ required: true, message: '请填写acks' }],
-    retries: [{ required: true, message: '请填写retries' }],
-    batchSize: [{ required: true, message: '请填写batchSize' }],
-    linger: [{ required: true, message: '请填写linger' }],
-    bufferMemory: [{ required: true, message: '请填写bufferMemory' }],
-    keySerializer: [{ required: true, message: '请填写keySerializer' }],
-    valueSerializer: [{ required: true, message: '请填写valueSerializer' }]
-  },
-  RABBIT: {
-    exchangeName: [{ required: true, message: '请填写交换名' }],
-    routingKey: [{ required: true, message: '请填写路由密钥' }],
-    messageProperties: [{ required: true, message: '请填写消息属性' }],
-    host: [{ required: true, message: '请填写域名' }],
-    //  pattern: '^\d+$',
-    port: [{ required: true, message: '端口号必须由纯数字组成', pattern: /^\d+$/ }],
-    virtualHost: [{ required: true, message: 'virtualHost' }],
-    automaticRecoveryEnabled: [{ required: true, message: 'automaticRecoveryEnabled' }],
-    connectionTimeout: [{ required: true, message: 'connectionTimeout' }],
-    handshakeTimeout: [{ required: true, message: 'handshakeTimeout' }]
-  },
-  MQTT: {
-    topic: [{ required: true, message: '请填写主题' }],
-    broker: [{ required: true, message: '请填写broker服务器' }],
-    connectTimeout: [{ required: true, message: '请填写连接超时时间' }],
-    clientId: [{ required: true, message: '请填写客户端id' }],
-    qos: [{ required: true, message: '请填写qos' }],
-    userName: [{ required: true, message: '请填写用户名' }],
-    password: [{ required: true, message: '请填写密码' }]
-  }
-})
-
-let forwardRuleTargets = reactive([])
-
-const forwardRuleStateComputed = computed(() => forwardState.targetType === '' ? {} : forwardRuleState[forwardState.targetType])
-
-const { resetFields, validate, validateInfos } = useForm(forwardState, forwardRuleStateComputed)
-const { resetFields: resetFieldsStep1, validate: validateStep1, validateInfos: validateInfosStep1 } = useForm(forwardRStateStep1, reactive({
-  ruleLabel: [{ required: true, message: '请填写转发规则名称' }],
-  subjectResource: [{ required: true, message: '请填写转发规则名称' }],
-  subjectEvent: [{ required: true, message: '请填写转发规则名称' }]
-}))
-
-const updateForwardRuleTargets = (record, index) => {
-  state.targetVisible = true
-  state.updateIndex = index
-  resetFields({ ...record })
-}
-
-const openDetailModal = async (id: string) => {
-  state.detailVisible = true
-  const { data } = await RuleController.forwardById(id)
-  detailForwardRef.value = data
-  // const _forwardRuleTargets = data.forwardRuleTargets
-}
-
-const openModalDebug = (id: string) => {
-  state.testVisble = true
-  state.forwardId = id
-}
-
-const closeModal = () => {
-  state.stepCount = 1
-  state.targetVisible = false
-  resetFields(JSON.parse(JSON.stringify(initForwardState)))
-  resetFieldsStep1({
-    ruleLabel: '',
-    subjectResource: '',
-    subjectEvent: '',
-    ruleDescription: ''
-  })
-  forwardRuleTargets = []
-}
-
-const openModal = async (opraState: 'add' | 'update', record) => {
-  state.opraState = opraState
-
-  if (opraState === 'update' && record.status) {
-    message.error('规则运行中,停止后可编辑')
-    return
-  }
-
-  if (opraState === 'update') {
-    state.forwardId = record.id
-    state.stepCount = 1
-    const { data } = await RuleController.forwardById(record.id)
-    resetFieldsStep1(data)
-
-    const _forwardRuleTargets = data.forwardRuleTargets!.map(item => {
-      return {
-        ...item,
-        id: useId()
-      }
-    })
-
-    _forwardRuleTargets.forEach(item => {
-      const _requestHeaders = item.requestHeaders
-        ? Object.keys(item.requestHeaders).map(key => {
-          return {
-            key: key,
-            value: item!.requestHeaders[key]
-          }
-        })
-        : []
-      const _otherProperties = item.otherProperties
-        ? Object.keys(item.otherProperties).map(key => {
-          return {
-            key: key,
-            value: item!.otherProperties[key]
-          }
-        })
-        : []
-      item.requestHeaders = _requestHeaders
-      item.otherProperties = _otherProperties
-    })
-
-    forwardRuleTargets = reactive(JSON.parse(JSON.stringify(_forwardRuleTargets)))
-  }
-
-  if (opraState === 'add') {
-    state.stepCount = 0
-  }
-  state.visible = true
-}
-
-const addRequestHeaders = (key: 'requestHeaders' | 'otherProperties') => forwardState[key].push({ ...requestHeader })
-
-const search = (record) => {
-  queryParams = { ...queryParams, ...record }
-  tableProDom.value.reload()
-}
-
-const addForwardState = () => {
-  state.targetVisible = true
-  state.updateIndex = ''
-  resetFields(JSON.parse(JSON.stringify(initForwardState)))
-}
-
-const changeStatus = async (record) => RuleController.updateForwardStatus({ id: record.id, status: record.status })
-
-// 获取统计规则
-const getCount = async () => {
-  const { data } = await RuleController.forwardCount()
-  state.forwardCount = Object.keys(data).map(key => {
-    const item = RuleController.forwardStatisticMap.get(key)
-    return {
-      ...item,
-      value: data[key]
-    }
-  })
-}
-
-/** 提交转发规则 */
-const ok = async () => {
-  if (state.targetVisible) {
-    validate().then(() => {
-      if (typeof state.updateIndex === 'number') {
-        forwardRuleTargets.splice(state.updateIndex, 1, { ...forwardState })
-      } else {
-        forwardRuleTargets.push({ ...forwardState })
-        resetFields(JSON.parse(JSON.stringify(initForwardState)))
-      }
-      state.targetVisible = false
-    }).catch(e => e)
-  } else {
-    validateStep1().then(async (r) => {
-      const _otherProperties: Record<string, string> = {}
-
-      forwardRuleTargets.forEach(item => {
-        const _requestHeaders: Record<string, string> = {}
-        const _otherProperties: Record<string, string> = {}
-
-        item.requestHeaders.forEach(item => {
-          _requestHeaders[item.key] = item.value
-        })
-        item.requestHeaders = _requestHeaders
-
-        item.otherProperties.forEach(item => {
-          _otherProperties[item.key] = item.value
-        })
-        item.otherProperties = _otherProperties
-      })
-
-      forwardState.otherProperties.forEach(item => {
-        _otherProperties[item.key] = item.value
-      })
-      if (state.opraState === 'add') {
-        await RuleController.postForward({ ...forwardRStateStep1, forwardRuleTargets })
-      } else {
-        await RuleController.updateForward({ ...forwardRStateStep1, forwardRuleTargets, id: state.forwardId })
-      }
-
-      state.visible = false
-      closeModal()
-      tableProDom.value.reload()
-    }).catch((e) => {})
-  }
-}
-
-// 开始调试
-const dispatchDebug = async () => {
-  const value = await testDialogRef.value.getValue()
-  await RuleController.forwardDebug({
-    ...value,
-    ruleId: state.forwardId
-  })
-  state.testVisble = false
-}
-
-const delForwardRule = async (id: string) => {
-  await RuleController.delForwardRule(id)
-  tableProDom.value.reload()
-}
-
-onMounted(() => {
-  getCount()
-})
-</script>
-<style lang='less' scoped >
-
-::v-deep ant-form {
-  height: 200px!;
-}
-</style>
+<template>
+
+<StatisticsTemplate
+    title="规则统计"
+    :list="state.forwardCount"
+/>
+
+<a-card style="margin-top: 20px;" >
+  <table-pro
+    style="margin-top: 20px;"
+    :columns="columns"
+    :service="RuleController.pageForward"
+    :serviceParams="queryParams"
+    @add="openModal('add', {})"
+    ref="tableProDom"
+  >
+    <template #search >
+      <a-row style="width: 100%"  :gutter="[8,8]" >
+        <a-col :xs="20" :md="12" :xl="4">
+          <a-input  allowClear v-model:value="queryParams.ruleId" placeholder="请输入规则id"></a-input>
+        </a-col>
+        <a-col :xs="20" :md="12" :xl="4">
+          <a-input allowClear v-model:value="queryParams.ruleLabel" placeholder="请输入规则名称" ></a-input>
+        </a-col>
+        <a-col :xs="20" :md="12" :xl="4" >
+              <a-select allowClear style="width: 100% !important;" v-model:value="queryParams.subjectResource"    placeholder="选择数据来源">
+                <a-select-option
+                  v-for="item in subjectResourceList"
+                  :key="item.key"
+                  :value="item.value"
+                >
+                {{item.name}}
+                </a-select-option>
+              </a-select>
+        </a-col>
+        <a-col :xs="20" :md="12" :xl="4" >
+              <a-select allowClear style="width: 100% !important;" v-model:value="queryParams.subjectEvent"  placeholder="选择触发事件">
+                <a-select-option
+                  v-for="item in Array.from(RuleController.SubjectEventMap, ([key, value]) => ({ ...value, value: value.key }))"
+                  :key="item.key"
+                  :value="item.value"
+                >
+                {{item.name}}
+                </a-select-option>
+              </a-select>
+        </a-col>
+        <a-col :xs="20" :md="12" :xl="3" >
+              <a-select allowClear style="width: 100% !important;" v-model:value="queryParams.status" >
+                <a-select-option
+                  v-for="item in statusList"
+                  :key="item.key"
+                  :value="item.value"
+                >
+                {{item.name}}
+                </a-select-option>
+              </a-select>
+        </a-col>
+        <a-col :xs="20" :md="12" :xl="3" >
+          <a-button type="primary" @click="search">搜索</a-button>
+        </a-col>
+      </a-row>
+    </template>
+    <template #render="{column, record}"  >
+      <template v-if="column.key === 'id'" >
+          <a  @click="openDetailModal(record.id)">{{record.id}}</a>
+      </template>
+      <template v-if="column.key === 'subjectResource'" >
+        <a-tag >{{RuleController.SubjectResourceMap.get(record.subjectResource)?.name}}</a-tag>
+      </template>
+      <template v-if="column.key === 'subjectEvent'" >
+        <a-tag >{{RuleController.SubjectEventMap.get(record.subjectEvent)?.name}}</a-tag>
+      </template>
+      <template v-if="column.key === 'status'" >
+        <a-switch
+          v-model:checked="record.status"
+          checked-children="运行中"
+          un-checked-children="已停止"
+          @click="changeStatus(record)"
+        />
+      </template>
+      <template v-if="column.key === 'action'" >
+        <a-space>
+              <a @click="openModalDebug(record.id)">调试</a>
+              <a @click="openDetailModal(record.id)">详情</a>
+              <a @click="openModal('update', record)">编辑</a>
+              <a-popconfirm
+                  title="确实要删除吗?"
+                  ok-text="确定"
+                  cancel-text="取消"
+                  @confirm="delForwardRule(record.id)"
+                >
+                  <a>删除</a>
+              </a-popconfirm>
+        </a-space>
+      </template>
+    </template>
+  </table-pro>
+</a-card>
+
+<RealView
+  :open="state.visible"
+  title="创建规则"
+  @cancel="state.visible = false"
+  @ok="ok"
+>
+  <a-card title="设置转发数据" >
+    <div style="margin-bottom: 20px;" >针对部分类型数据提供的快速配置,将引导您完成简单的业务设置。您也可以直接编辑过滤语句,实现更复杂的查询要求</div>
+    <a-form :label-col="{span: 4 }" :wrapper-col="{ span: 14 }" style="height: 300px; overflow-y: auto;">
+        <a-form-item  label="规则名称" v-bind="validateInfosStep1.ruleLabel" >
+          <a-input v-model:value="forwardRStateStep1.ruleLabel" ></a-input>
+        </a-form-item>
+        <a-form-item label="数据来源" v-bind="validateInfosStep1.subjectResource">
+            <a-select
+            allowClear
+            style="width: 100%;"
+            v-model:value="forwardRStateStep1.subjectResource"
+          >
+            <a-select-option
+              v-for="item in subjectResourceList"
+              :key="item.key"
+              :value="item.key"
+            >
+              {{item.name}}
+            </a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item label="数据事件" v-bind="validateInfosStep1.subjectEvent">
+            <a-select
+            allowClear
+            style="width: 100%;"
+            v-model:value="forwardRStateStep1.subjectEvent"
+          >
+            <a-select-option
+              v-for="item in subjectEventList"
+              :key="item.key"
+              :value="item.key"
+            >
+              {{item.name}}
+            </a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item label="规则描述" >
+          <a-textarea
+            v-model:value="forwardRStateStep1.ruleDescription"
+            placeholder="请输入规则描述"
+            :auto-size="{ minRows: 2, maxRows: 5 }"
+          />
+        </a-form-item>
+    </a-form>
+  </a-card>
+  <a-card title="设置转发目标" style="margin-top: 20px;" >
+    <template #extra > <a-button type="primary" @click="addForwardState">添加</a-button></template>
+    <div>您可以设置将数据转发至华为云其他服务或私有服务器。</div>
+      <a-table
+        style="margin-top: 20px;"
+        v-if="forwardRuleTargets.length"
+        :columns="forwardRuleTargetsColumns"
+        :data-source="forwardRuleTargets"
+        size="middle"
+      >
+        <template #bodyCell="{column, record, index}" >
+          <template v-if="column.key === 'action'" >
+            <a-space>
+              <a @click="updateForwardRuleTargets(record, index)">编辑</a>
+              <a @click="forwardRuleTargets.splice(index, 1)">删除</a>
+            </a-space>
+          </template>
+        </template>
+      </a-table>
+      <a-empty v-else :image="Empty.PRESENTED_IMAGE_SIMPLE" />
+  </a-card>
+</RealView>
+
+<modal-pro
+  style="width: 800px"
+  label="转发目标"
+  :open="state.targetVisible"
+  ok-text="确定"
+  @cancel="closeModal"
+  @ok="ok"
+>
+    <a-form :label-col="{span: 4 }" :wrapper-col="{ span: 14 }" style="height: 400px; overflow-y: auto;">
+    <a-form-item label="转发目标">
+        <a-select
+        allowClear
+        style="width: 100%;"
+        v-model:value="forwardState.targetType"
+      >
+        <a-select-option
+          v-for="item in forwardTatget"
+          :key="item.key"
+          :value="item.key"
+        >
+          {{item.name}}
+        </a-select-option>
+      </a-select>
+    </a-form-item>
+      <span v-if="forwardState.targetType === 'HTTP'" >
+        <a-form-item label="地址" v-bind="validateInfos.endpointUrl">
+          <a-input allowClear v-model:value="forwardState.endpointUrl" placeholder="请填写http地址" />
+        </a-form-item>
+        <a-form-item label="方法" v-bind="validateInfos.requestMethod">
+          <a-select
+            allowClear
+            style="width: 100%;"
+            v-model:value="forwardState.requestMethod"
+          >
+            <a-select-option
+              v-for="item in HttpRequestMethods"
+              :key="item.key"
+              :value="item.key"
+            >
+              {{item.name}}
+            </a-select-option>
+          </a-select>
+        </a-form-item>
+        <a-form-item label="超时时间" v-bind="validateInfos.defaultTimeout">
+          <a-input-number id="inputNumber" v-model:value="forwardState.defaultTimeout" />
+        </a-form-item>
+        <a-form-item label="请求头" v-bind="validateInfos.requestHeaders">
+          <a-input-group style="margin-top: 10px;" size="large" v-for="(item, index) in forwardState.requestHeaders" :key="index">
+            <a-row :gutter="8">
+              <a-col :span="5">
+                <a-input allowClear style="height: 30px;" v-model:value="item.key" placeholder="key" />
+              </a-col>
+              <a-col :span="8">
+                <a-input allowClear style="height: 30px;"  v-model:value="item.value" placeholder="value" />
+              </a-col>
+              <a-col>
+                <a-button type="link" danger @click="forwardState.requestHeaders.splice(index, 1)" >删除</a-button>
+              </a-col>
+            </a-row>
+          </a-input-group>
+          <a-button style="margin-top: 20px;" @click="addRequestHeaders('requestHeaders')" type="primary" >添加参数</a-button>
+        </a-form-item>
+      </span>
+      <span v-if="forwardState.targetType === 'KAFKA'" >
+        <a-form-item label="主题" v-bind="validateInfos.topic" >
+          <a-input allowClear placeholder="请填写主题" v-model:value="forwardState.topic" ></a-input>
+        </a-form-item>
+        <a-form-item label="地址" v-bind="validateInfos.topic" >
+          <a-input allowClear placeholder="请填写地址" v-model:value="forwardState.bootstrapServers" ></a-input>
+        </a-form-item>
+        <a-form-item label="acks" v-bind="validateInfos.acks" >
+          <a-input allowClear placeholder="请填写acks" v-model:value="forwardState.acks"  disabled ></a-input>
+        </a-form-item>
+        <a-form-item label="重试次数" v-bind="validateInfos.retries" >
+          <a-input allowClear placeholder="请填写重试次数" v-model:value="forwardState.retries"></a-input>
+        </a-form-item>
+        <a-form-item label="batchSize" v-bind="validateInfos.batchSize" >
+          <a-input allowClear placeholder="请填写batchSize" v-model:value="forwardState.batchSize"></a-input>
+        </a-form-item>
+        <a-form-item label="linger" v-bind="validateInfos.linger" >
+          <a-input allowClear placeholder="请填写linger" v-model:value="forwardState.linger"></a-input>
+        </a-form-item>
+        <a-form-item label="bufferMemory" v-bind="validateInfos.bufferMemory" >
+          <a-input allowClear placeholder="请填写bufferMemory" v-model:value="forwardState.bufferMemory"></a-input>
+        </a-form-item>
+        <a-form-item label="keySerializer" v-bind="validateInfos.keySerializer" >
+          <a-input allowClear placeholder="请填写keySerializer" v-model:value="forwardState.keySerializer"></a-input>
+        </a-form-item>
+        <a-form-item label="valueSerializer" v-bind="validateInfos.valueSerializer" >
+          <a-input allowClear placeholder="请填写valueSerializer" v-model:value="forwardState.valueSerializer"></a-input>
+        </a-form-item>
+        <a-form-item label="其他参数">
+          <a-input-group style="margin-top: 10px;" size="large" v-for="(item, index) in forwardState.otherProperties" :key="index">
+            <a-row :gutter="8">
+              <a-col :span="5">
+                <a-input allowClear style="height: 30px;" v-model:value="item.key" placeholder="key" />
+              </a-col>
+              <a-col :span="8">
+                <a-input allowClear style="height: 30px;"  v-model:value="item.value" placeholder="value" />
+              </a-col>
+              <a-col>
+                <a-button type="link" danger @click="forwardState.otherProperties.splice(index, 1)" >删除</a-button>
+              </a-col>
+            </a-row>
+          </a-input-group>
+          <a-button style="margin-top: 20px;" @click="addRequestHeaders('otherProperties')" type="primary" >添加参数</a-button>
+        </a-form-item>
+      </span>
+      <span v-if="forwardState.targetType === 'MQTT'"  >
+        <a-form-item label="主题" v-bind="validateInfos.topic" >
+          <a-input allowClear placeholder="请填写主题" v-model:value="forwardState.topic" ></a-input>
+        </a-form-item>
+        <a-form-item label="broker服务器" v-bind="validateInfos.broker" >
+          <a-input allowClear placeholder="请填写broker服务器" v-model:value="forwardState.broker" ></a-input>
+        </a-form-item>
+        <a-form-item label="连接超时时间" v-bind="validateInfos.connectTimeout" >
+          <a-input-number placeholder="请填写连接超时时间" v-model:value="forwardState.connectTimeout" ></a-input-number>
+        </a-form-item>
+        <a-form-item label="客户端ID" v-bind="validateInfos.clientId" >
+          <a-input-number placeholder="请填写客户端ID" v-model:value="forwardState.clientId" ></a-input-number>
+        </a-form-item>
+        <a-form-item label="保留消息" >
+          <a-switch v-model:checked="forwardState.retainedMessage" checked-children="保留" un-checked-children="不保留" />
+        </a-form-item>
+        <a-form-item label="清除Session" >
+          <a-switch v-model:checked="forwardState.cleanSession" checked-children="清除" un-checked-children="不清除" />
+        </a-form-item>
+        <a-form-item label="qos" v-bind="validateInfos.qos" >
+          <a-input allowClear placeholder="请填写qos" v-model:value="forwardState.qos" ></a-input>
+        </a-form-item>
+        <a-form-item label="用户名" v-bind="validateInfos.userName">
+          <a-input allowClear placeholder="请填写用户名" v-model:value="forwardState.userName" ></a-input>
+        </a-form-item>
+        <a-form-item label="密码" v-bind="validateInfos.password" >
+          <a-input allowClear placeholder="请填写密码" v-model:value="forwardState.password" ></a-input>
+        </a-form-item>
+      </span>
+      <span v-if="forwardState.targetType === 'RABBIT'" >
+        <a-form-item label="exchangeName" v-bind="validateInfos.exchangeName">
+          <a-input allowClear v-model:value="forwardState.exchangeName" placeholder="请填写交换名" />
+        </a-form-item>
+        <a-form-item label="路由密钥" v-bind="validateInfos.routingKey">
+          <a-input allowClear v-model:value="forwardState.routingKey" placeholder="请填写路由密钥" />
+        </a-form-item>
+        <a-form-item label="消息属性" v-bind="validateInfos.messageProperties">
+          <a-input allowClear v-model:value="forwardState.messageProperties" placeholder="请填写消息属性" />
+        </a-form-item>
+        <a-form-item label="域名" v-bind="validateInfos.host">
+          <a-input allowClear v-model:value="forwardState.host" placeholder="请填写域名" />
+        </a-form-item>
+        <a-form-item label="端口" v-bind="validateInfos.port">
+          <a-input allowClear v-model:value="forwardState.port" placeholder="请填写端口" />
+        </a-form-item>
+        <a-form-item label="虚拟主机" v-bind="validateInfos.virtualHost">
+          <a-input allowClear v-model:value="forwardState.virtualHost" placeholder="请填写虚拟主机" />
+        </a-form-item>
+        <a-form-item label="自动恢复" >
+          <a-switch v-model:checked="forwardState.automaticRecoveryEnabled" checked-children="启用" un-checked-children="未启用" />
+        </a-form-item>
+        <a-form-item label="连接超时" >
+          <a-input allowClear  v-model:value="forwardState.connectionTimeout" placeholder="请填写连接超时时间" />
+        </a-form-item>
+        <a-form-item label="握手超时" >
+          <a-input allowClear v-model:value="forwardState.handshakeTimeout" placeholder="请填写握手超时" />
+        </a-form-item>
+        <a-form-item label="用户名" v-bind="validateInfos.userName">
+          <a-input allowClear placeholder="请填写用户名" v-model:value="forwardState.userName" ></a-input>
+        </a-form-item>
+        <a-form-item label="密码" v-bind="validateInfos.password" >
+          <a-input allowClear placeholder="请填写密码" v-model:value="forwardState.password" ></a-input>
+        </a-form-item>
+      </span>
+    </a-form>
+</modal-pro>
+
+<modal-pro
+  style="width: 1000px;"
+  label="详情"
+  :open="state.detailVisible"
+  @cancel="state.detailVisible = false"
+  @ok="state.detailVisible  = false"
+>
+  <a-form  :label-col="{span: 2}" style="height: 400px;overflow: hidden;overflow-y: scroll;">
+    <a-form-item label="规则名称"> {{detailForwardRef.ruleLabel}} </a-form-item>
+    <a-form-item label="数据来源"> {{RuleController.SubjectResourceMap.get(detailForwardRef.subjectResource)?.name}} </a-form-item>
+    <a-form-item label="触发事件"> {{RuleController.SubjectEventMap.get(detailForwardRef.subjectEvent)?.name}} </a-form-item>
+    <a-form-item label="状态"> {{detailForwardRef.status ?  '运行中' : '已停止'}} </a-form-item>
+    <a-form-item label="HTTP" v-if="detailHTTPList.length">
+      <a-table
+        :columns="detailColumn['HTTP']"
+        :data-source="detailHTTPList"
+        :pagination="false"
+      />
+
+    </a-form-item>
+    <a-form-item label="Kafka"  v-if="detailKAFKAList.length">
+      <a-table
+        :columns="detailColumn['Kafka']"
+        :data-source="detailKAFKAList"
+        :pagination="false"
+      >
+
+      </a-table>
+    </a-form-item>
+    <a-form-item label="MQTT" v-if="detailMQTTList.length">
+      <a-table
+        :columns="detailColumn['MQTT']"
+        :data-source="detailMQTTList"
+        :pagination="false"
+      >
+      </a-table>
+    </a-form-item>
+    <a-form-item label="RabbitMQ" v-if="detailRABBITList.length">
+      <a-table
+        :columns="detailColumn['RabbitMQ']"
+        :data-source="detailRABBITList"
+        :pagination="false"
+      >
+      </a-table>
+    </a-form-item>
+  </a-form>
+</modal-pro>
+
+<modal-pro
+  label="调试"
+  :open="state.testVisble"
+  @cancel="state.testVisble = false"
+  @ok="dispatchDebug"
+  style="width: 640px;"
+>
+  <TestDialog ref="testDialogRef"/>
+</modal-pro>
+
+</template>
+
+<script lang='ts' setup >
+import { onMounted, reactive, ref } from 'vue'
+import { RuleController } from '@/controller/index'
+import { Form, Empty, message } from 'ant-design-vue'
+import { computed } from '@vue/reactivity'
+import TestDialog from './components/testDialog.vue'
+import StatisticsTemplate from '@/components/StatisticsTemplate/index.vue'
+import { SubjectEventEnum, SubjectResourceEnum } from '@/enum/common'
+import { useId } from '@/hooks'
+import { RealView } from '@/components/RealView/index'
+
+const columns = [
+  {
+    title: '规则名称',
+    dataIndex: 'ruleLabel'
+  },
+  {
+    title: '规则ID',
+    dataIndex: 'id',
+    key: 'id'
+  },
+  {
+    title: '数据来源',
+    dataIndex: 'subjectResource',
+    key: 'subjectResource'
+  },
+  {
+    title: '触发事件',
+    dataIndex: 'subjectEvent',
+    key: 'subjectEvent'
+  },
+  {
+    title: '状态',
+    dataIndex: 'status',
+    key: 'status'
+  },
+  {
+    title: '操作',
+    dataIndex: 'action',
+    key: 'action'
+  }
+]
+
+const forwardRuleTargetsColumns = [
+  {
+    title: '转发目标',
+    dataIndex: 'targetType'
+  },
+  {
+    title: '操作',
+    dataIndex: 'action',
+    key: 'action'
+  }
+
+]
+
+const forwardTatget = [
+  { name: 'RabbitMQ', key: 'RABBIT' },
+  { name: 'Kafka', key: 'KAFKA' },
+  { name: 'HTTP编码', key: 'HTTP' },
+  { name: 'MQTT', key: 'MQTT' }
+]
+
+const HttpRequestMethods = [
+  { name: 'GET', key: 'GET' },
+  { name: 'POST', key: 'POST' },
+  { name: 'PUT', key: 'PUT' }
+]
+
+const subjectResourceList = Array.from(RuleController.SubjectResourceMap, ([key, value]) => ({ ...value, value: value.key }))
+
+const subjectEventListByResourceMap = new Map([
+  [SubjectResourceEnum.DEVICE, [SubjectEventEnum.DEVICE_CREATE, SubjectEventEnum.DEVICE_DELETE]],
+  [SubjectResourceEnum.DEVICE_STATUS, [SubjectEventEnum.DEVICE_STATUS_UPDATE]],
+  [SubjectResourceEnum.DEVICE_ATTRIBUTE, [SubjectEventEnum.DEVICE_ATTRIBUTE_REPORT]],
+  [SubjectResourceEnum.MODEL, [SubjectEventEnum.MODEL_CREATE, SubjectEventEnum.MODEL_DELETE]]
+])
+
+const subjectEventList = computed(() => {
+  const subjectevents = Array.from(RuleController.SubjectEventMap, ([key, value]) => ({ ...value, value: value.key }))
+  const keys = subjectEventListByResourceMap.get(forwardRStateStep1.subjectResource as SubjectResourceEnum)
+  return subjectevents.filter(subjectevent => keys?.includes(subjectevent.key))
+})
+
+const statusList = [
+  { name: '所有状态', key: '', value: '' },
+  { name: '运行中', key: 'status', value: true },
+  { name: '未启动', key: 'status', value: false }
+]
+
+const detailColumn = reactive({
+  HTTP: [
+    { title: 'http地址', dataIndex: 'endpointUrl' },
+    { title: 'requestMethod', dataIndex: '请求方法' },
+    { title: 'defaultTimeout', dataIndex: '超时时间' },
+    { title: 'requestHeaders', dataIndex: '请求头' }
+  ],
+  Kafka: [
+    { title: '主题', dataIndex: 'topic' },
+    { title: '地址', dataIndex: 'bootstrapServers' },
+    { title: 'acks', dataIndex: 'acks' },
+    { title: '重试', dataIndex: 'retries' },
+    { title: 'batchSize', dataIndex: 'batchSize' },
+    { title: 'linger', dataIndex: 'linger' },
+    { title: 'bufferMemory', dataIndex: 'bufferMemory' },
+    { title: 'keySerializer', dataIndex: 'keySerializer' },
+    { title: 'valueSerializer', dataIndex: 'valueSerializer' },
+    { title: '其他属性', dataIndex: 'otherProperties' }
+  ],
+  MQTT: [
+    { title: '主题', dataIndex: 'topic' },
+    { title: 'broker服务器', dataIndex: 'broker' },
+    { title: '连接超时时间', dataIndex: 'connectTimeout' },
+    { title: 'clientId', dataIndex: 'clientId' },
+    { title: 'retainedMessage', dataIndex: 'retainedMessage' },
+    { title: 'cleanSession', dataIndex: 'cleanSession' },
+    { title: 'qos', dataIndex: 'qos' },
+    { title: '用户名', dataIndex: 'userName' },
+    { title: '密码', dataIndex: 'password' }
+  ],
+  RabbitMQ: [
+    { title: '主题', dataIndex: 'exchangeName' },
+    { title: '路由密钥', dataIndex: 'routingKey' },
+    { title: '消息属性', dataIndex: 'messageProperties' },
+    { title: '域名', dataIndex: 'host' },
+    { title: '端口', dataIndex: 'port' },
+    { title: '虚拟主机', dataIndex: 'virtualHost' },
+    { title: '自动恢复', dataIndex: 'automaticRecoveryEnabled' },
+    { title: '连接超时', dataIndex: 'connectionTimeout' },
+    { title: '握手超时', dataIndex: 'handshakeTimeout' },
+    { title: '用户名', dataIndex: 'userName' },
+    { title: '密码', dataIndex: 'password' }
+  ]
+})
+
+const useForm = Form.useForm
+
+const tableProDom = ref('')
+
+const testDialogRef = ref('')
+
+let queryParams = reactive({
+  ruleId: '',
+  ruleLabel: '',
+  status: '',
+  subjectEvent: null,
+  subjectResource: null
+})
+
+const state = reactive({
+  loading: false,
+  dataSource: [],
+  visible: false,
+  targetVisible: false,
+  detailVisible: false,
+  stepCount: 0,
+  opraState: 'add',
+  forwardId: '',
+  testVisble: false,
+  forwardCount: [],
+  updateIndex: '' // 对规则的编辑时的下标
+})
+
+const requestHeader = { key: '', value: '' }
+
+const detailForwardRef = ref<Partial<IOT.API.RULE.ForwardRule>>({})
+
+const detailHTTPList = computed(() => detailForwardRef.value && detailForwardRef.value.forwardRuleTargets ? detailForwardRef.value.forwardRuleTargets!.filter(item => item.targetType === 'HTTP') : [])
+const detailRABBITList = computed(() => detailForwardRef.value && detailForwardRef.value.forwardRuleTargets ? detailForwardRef.value.forwardRuleTargets!.filter(item => item.targetType === 'RABBIT') : [])
+const detailKAFKAList = computed(() => detailForwardRef.value && detailForwardRef.value.forwardRuleTargets ? detailForwardRef.value.forwardRuleTargets!.filter(item => item.targetType === 'KAFKA') : [])
+const detailMQTTList = computed(() => detailForwardRef.value && detailForwardRef.value.forwardRuleTargets ? detailForwardRef.value.forwardRuleTargets!.filter(item => item.targetType === 'MQTT') : [])
+
+const initForwardState = {
+  targetType: '',
+  endpointUrl: '',
+  requestMethod: 'GET',
+  defaultTimeout: 6,
+  requestHeaders: [],
+  topic: '',
+  bootstrapServers: '',
+  acks: '-1',
+  retries: '0',
+  batchSize: '65535',
+  linger: '0',
+  bufferMemory: '33554432',
+  keySerializer: '',
+  valueSerializer: '',
+  otherProperties: [],
+  broker: '',
+  connectTimeout: '',
+  clientId: '',
+  retainedMessage: false,
+  cleanSession: false,
+  qos: '',
+  userName: '',
+  password: '',
+  exchangeName: '',
+  routingKey: '',
+  messageProperties: '',
+  host: '',
+  port: '',
+  virtualHost: '/',
+  automaticRecoveryEnabled: false,
+  connectionTimeout: 60000,
+  handshakeTimeout: 10000
+}
+
+const forwardState = reactive(JSON.parse(JSON.stringify(initForwardState)))
+
+const forwardRStateStep1 = reactive({
+  ruleLabel: '',
+  subjectResource: '',
+  subjectEvent: '',
+  ruleDescription: ''
+})
+
+const forwardRuleState = reactive({
+  HTTP: {
+    endpointUrl: [{ required: true, message: '请填写http地址' }],
+    requestMethod: [{ required: true, message: '请填写请求方法' }],
+    defaultTimeout: [{ required: true, message: '请填写超时时间' }],
+    requestHeaders: [{ required: true, message: '请填写请求头参数' }]
+  },
+  KAFKA: {
+    topic: [{ required: true, message: '请填写主题' }],
+    bootstrapServers: [{ required: true, message: '请填写地址' }],
+    acks: [{ required: true, message: '请填写acks' }],
+    retries: [{ required: true, message: '请填写retries' }],
+    batchSize: [{ required: true, message: '请填写batchSize' }],
+    linger: [{ required: true, message: '请填写linger' }],
+    bufferMemory: [{ required: true, message: '请填写bufferMemory' }],
+    keySerializer: [{ required: true, message: '请填写keySerializer' }],
+    valueSerializer: [{ required: true, message: '请填写valueSerializer' }]
+  },
+  RABBIT: {
+    exchangeName: [{ required: true, message: '请填写交换名' }],
+    routingKey: [{ required: true, message: '请填写路由密钥' }],
+    messageProperties: [{ required: true, message: '请填写消息属性' }],
+    host: [{ required: true, message: '请填写域名' }],
+    //  pattern: '^\d+$',
+    port: [{ required: true, message: '端口号必须由纯数字组成', pattern: /^\d+$/ }],
+    virtualHost: [{ required: true, message: 'virtualHost' }],
+    automaticRecoveryEnabled: [{ required: true, message: 'automaticRecoveryEnabled' }],
+    connectionTimeout: [{ required: true, message: 'connectionTimeout' }],
+    handshakeTimeout: [{ required: true, message: 'handshakeTimeout' }]
+  },
+  MQTT: {
+    topic: [{ required: true, message: '请填写主题' }],
+    broker: [{ required: true, message: '请填写broker服务器' }],
+    connectTimeout: [{ required: true, message: '请填写连接超时时间' }],
+    clientId: [{ required: true, message: '请填写客户端id' }],
+    qos: [{ required: true, message: '请填写qos' }],
+    userName: [{ required: true, message: '请填写用户名' }],
+    password: [{ required: true, message: '请填写密码' }]
+  }
+})
+
+let forwardRuleTargets = reactive([])
+
+const forwardRuleStateComputed = computed(() => forwardState.targetType === '' ? {} : forwardRuleState[forwardState.targetType])
+
+const { resetFields, validate, validateInfos } = useForm(forwardState, forwardRuleStateComputed)
+const { resetFields: resetFieldsStep1, validate: validateStep1, validateInfos: validateInfosStep1 } = useForm(forwardRStateStep1, reactive({
+  ruleLabel: [{ required: true, message: '请填写转发规则名称' }],
+  subjectResource: [{ required: true, message: '请选择数据来源' }],
+  subjectEvent: [{ required: true, message: '请填写转发规则名称' }]
+}))
+
+const updateForwardRuleTargets = (record, index) => {
+  state.targetVisible = true
+  state.updateIndex = index
+  resetFields({ ...record })
+}
+
+const openDetailModal = async (id: string) => {
+  state.detailVisible = true
+  const { data } = await RuleController.forwardById(id)
+  detailForwardRef.value = data
+  // const _forwardRuleTargets = data.forwardRuleTargets
+}
+
+const openModalDebug = (id: string) => {
+  state.testVisble = true
+  state.forwardId = id
+}
+
+const closeModal = () => {
+  state.stepCount = 1
+  state.targetVisible = false
+  resetFields(JSON.parse(JSON.stringify(initForwardState)))
+  resetFieldsStep1({
+    ruleLabel: '',
+    subjectResource: '',
+    subjectEvent: '',
+    ruleDescription: ''
+  })
+  forwardRuleTargets = []
+}
+
+const openModal = async (opraState: 'add' | 'update', record) => {
+  state.opraState = opraState
+
+  if (opraState === 'update' && record.status) {
+    message.error('规则运行中,停止后可编辑')
+    return
+  }
+
+  if (opraState === 'update') {
+    state.forwardId = record.id
+    state.stepCount = 1
+    const { data } = await RuleController.forwardById(record.id)
+    resetFieldsStep1(data)
+
+    const _forwardRuleTargets = data.forwardRuleTargets!.map(item => {
+      return {
+        ...item,
+        id: useId()
+      }
+    })
+
+    _forwardRuleTargets.forEach(item => {
+      const _requestHeaders = item.requestHeaders
+        ? Object.keys(item.requestHeaders).map(key => {
+          return {
+            key: key,
+            value: item!.requestHeaders[key]
+          }
+        })
+        : []
+      const _otherProperties = item.otherProperties
+        ? Object.keys(item.otherProperties).map(key => {
+          return {
+            key: key,
+            value: item!.otherProperties[key]
+          }
+        })
+        : []
+      item.requestHeaders = _requestHeaders
+      item.otherProperties = _otherProperties
+    })
+
+    forwardRuleTargets = reactive(JSON.parse(JSON.stringify(_forwardRuleTargets)))
+  }
+
+  if (opraState === 'add') {
+    state.stepCount = 0
+  }
+  state.visible = true
+}
+
+const addRequestHeaders = (key: 'requestHeaders' | 'otherProperties') => forwardState[key].push({ ...requestHeader })
+
+const search = (record) => {
+  queryParams = { ...queryParams, ...record }
+  tableProDom.value.reload()
+}
+
+const addForwardState = () => {
+  state.targetVisible = true
+  state.updateIndex = ''
+  resetFields(JSON.parse(JSON.stringify(initForwardState)))
+}
+
+const changeStatus = async (record) => RuleController.updateForwardStatus({ id: record.id, status: record.status })
+
+// 获取统计规则
+const getCount = async () => {
+  const { data } = await RuleController.forwardCount()
+  state.forwardCount = Object.keys(data).map(key => {
+    const item = RuleController.forwardStatisticMap.get(key)
+    return {
+      ...item,
+      value: data[key]
+    }
+  })
+}
+
+/** 提交转发规则 */
+const ok = async () => {
+  if (state.targetVisible) {
+    validate().then(() => {
+      if (typeof state.updateIndex === 'number') {
+        forwardRuleTargets.splice(state.updateIndex, 1, { ...forwardState })
+      } else {
+        forwardRuleTargets.push({ ...forwardState })
+        resetFields(JSON.parse(JSON.stringify(initForwardState)))
+      }
+      state.targetVisible = false
+    }).catch(e => e)
+  } else {
+    validateStep1().then(async (r) => {
+      const _otherProperties: Record<string, string> = {}
+
+      forwardRuleTargets.forEach(item => {
+        const _requestHeaders: Record<string, string> = {}
+        const _otherProperties: Record<string, string> = {}
+
+        item.requestHeaders.forEach(item => {
+          _requestHeaders[item.key] = item.value
+        })
+        item.requestHeaders = _requestHeaders
+
+        item.otherProperties.forEach(item => {
+          _otherProperties[item.key] = item.value
+        })
+        item.otherProperties = _otherProperties
+      })
+
+      forwardState.otherProperties.forEach(item => {
+        _otherProperties[item.key] = item.value
+      })
+      if (state.opraState === 'add') {
+        await RuleController.postForward({ ...forwardRStateStep1, forwardRuleTargets })
+      } else {
+        await RuleController.updateForward({ ...forwardRStateStep1, forwardRuleTargets, id: state.forwardId })
+      }
+
+      state.visible = false
+      closeModal()
+      tableProDom.value.reload()
+    }).catch((e) => {})
+  }
+}
+
+// 开始调试
+const dispatchDebug = async () => {
+  const value = await testDialogRef.value.getValue()
+  await RuleController.forwardDebug({
+    ...value,
+    ruleId: state.forwardId
+  })
+  state.testVisble = false
+}
+
+const delForwardRule = async (id: string) => {
+  await RuleController.delForwardRule(id)
+  tableProDom.value.reload()
+}
+
+onMounted(() => {
+  getCount()
+})
+</script>
+<style lang='less' scoped >
+
+::v-deep ant-form {
+  height: 200px!;
+}
+</style>