|
|
@@ -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>
|