linkRules.vue 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082
  1. <template>
  2. <a-card>
  3. <a-row justify="space-between" >
  4. <a-col :span="12" >
  5. <a-space>
  6. <a-input placeholder="请填写规则名称" v-model:value="queryParamsState.ruleLabel" ></a-input>
  7. <a-button type="primary" @click="getLinkPage()" >搜索</a-button>
  8. </a-space>
  9. </a-col>
  10. <a-col>
  11. <a-space>
  12. <a-button type="primary" @click="openModal('add', {})" >创建规则</a-button>
  13. </a-space>
  14. </a-col>
  15. </a-row>
  16. <a-table
  17. style="margin-top: 20px;"
  18. :columns="columns"
  19. :data-source="state.dataSource"
  20. :loading="state.loading"
  21. :pagination="queryParamsState"
  22. @change="changePage"
  23. >
  24. <template #bodyCell="{column, record}" >
  25. <template v-if="column.key === 'status'" >
  26. <a-switch
  27. v-model:checked="record.status"
  28. checked-children="运行中"
  29. un-checked-children="已停止"
  30. @click="changeStatus(record)"
  31. />
  32. </template>
  33. <template v-if="column.key === 'action'" >
  34. <a-space>
  35. <a @click="openModal('update', record)" >编辑</a>
  36. <a-popconfirm
  37. title="确实要删除吗?"
  38. ok-text="确定"
  39. cancel-text="取消"
  40. @confirm="delLinkRule(record.id)"
  41. >
  42. <a>删除</a>
  43. </a-popconfirm>
  44. </a-space>
  45. </template>
  46. </template>
  47. </a-table>
  48. </a-card>
  49. <modal-pro
  50. style="width: 1400px;"
  51. label="创建转发规则"
  52. :visible="state.visible"
  53. @cancel="state.visible = false"
  54. @ok="ok"
  55. >
  56. <div style="height: 750px;overflow: hidden;overflow-y: auto;">
  57. <a-card
  58. title="基本信息"
  59. :bordered="false"
  60. >
  61. <a-form :labelCol="{span: 2}" :wapperCol="{span: 12}" >
  62. <a-form-item label="规则名称" v-bind="validateInfos.ruleLabel">
  63. <a-input v-model:value="bodyParamsState.ruleLabel" ></a-input>
  64. </a-form-item >
  65. <a-form-item label='规则描述'>
  66. <a-textarea
  67. v-model:value="bodyParamsState.ruleDescription"
  68. placeholder="请输入规则描述"
  69. :auto-size="{ minRows: 2, maxRows: 5 }"
  70. />
  71. </a-form-item>
  72. </a-form>
  73. <!-- <form-pro
  74. :labelCol="{span: 2}"
  75. :formProps="formProps"
  76. ref="formProRef"
  77. /> -->
  78. </a-card>
  79. <a-card
  80. title="触发条件"
  81. :bordered="false"
  82. >
  83. <a-row class="condition" >
  84. <a-col span="12" >
  85. 需满足
  86. <a-dropdown >
  87. <a class="ant-dropdown-link" @click.prevent>
  88. {{bodyParamsState.conditionLogic === 'AND' ? '全部' : '任意一个'}}
  89. <DownOutlined />
  90. </a>
  91. <template #overlay>
  92. <a-menu>
  93. <a-menu-item @click="changeConditionLogic('AND')" >
  94. <a >全部</a>
  95. </a-menu-item>
  96. <a-menu-item @click="changeConditionLogic('ALL')">
  97. <a >任意一个</a>
  98. </a-menu-item>
  99. </a-menu>
  100. </template>
  101. </a-dropdown>
  102. 以下条件:
  103. </a-col>
  104. <a-col class="df" span="12" >
  105. <a-button type="primary" @click="openFormVisible('conditions')">添加条件</a-button>
  106. </a-col>
  107. <a-col :span="24" v-if="deviceDataSource.length" >
  108. <a-table
  109. style="width: 100%;margin-top: 10px;"
  110. :columns="conditionColumns.DEVICE_DATA"
  111. :data-source="deviceDataSource"
  112. size="small"
  113. :pagination="false"
  114. >
  115. <template #bodyCell="{column, record}" >
  116. <template v-if="column.key === 'action'" >
  117. <a @click="delCondiTionsAndActions(record.id, 'conditions')" >
  118. 删除
  119. </a>
  120. </template>
  121. </template>
  122. </a-table>
  123. </a-col>
  124. <a-col :span="24" v-if="deviceSessionSource.length" >
  125. <a-table
  126. style="width: 100%;margin-top: 10px;"
  127. :columns="conditionColumns.DEVICE_SESSION"
  128. :data-source="deviceSessionSource"
  129. size="small"
  130. :pagination="false"
  131. >
  132. <template #bodyCell="{column, record}" >
  133. <template v-if="column.key === 'sessionEventType'" >
  134. {{record.sessionEventType === 'CONNECT' ? '连接' : '断开连接' }}
  135. </template>
  136. <template v-if="column.key === 'action'" >
  137. <a @click="delCondiTionsAndActions(record.id, 'conditions')" >
  138. 删除
  139. </a>
  140. </template>
  141. </template>
  142. </a-table>
  143. </a-col>
  144. <a-col :span="24" v-if="dailyTimerSource.length" >
  145. <a-table
  146. style="width: 100%;margin-top: 10px;"
  147. :columns="conditionColumns.DAILY_TIMER"
  148. :data-source="dailyTimerSource"
  149. size="small"
  150. :pagination="false"
  151. >
  152. <template #bodyCell="{column, record}" >
  153. <template v-if="column.key === 'dayOfWeek'" >
  154. {{record.dayOfWeek.map(item => '周' + item).join(',') }}
  155. </template>
  156. <template v-if="column.key === 'time'" >
  157. {{record.time}}
  158. </template>
  159. <template v-if="column.key === 'action'" >
  160. <a @click="delCondiTionsAndActions(record.id, 'conditions')" >
  161. 删除
  162. </a>
  163. </template>
  164. </template>
  165. </a-table>
  166. </a-col>
  167. <a-col v-if="bodyParamsState.conditions.length === 0" class="content" >尚未设置条件</a-col>
  168. </a-row>
  169. </a-card>
  170. <a-card
  171. title="执行动作"
  172. :bordered="false"
  173. >
  174. <a-row style="width: 100%;" >
  175. <a-col :span="24" class="df" ><a-button type="primary" @click="openFormVisible('actions')" >添加动作</a-button></a-col>
  176. <a-row style="width: 100%;" v-if="bodyParamsState.actions.length">
  177. <a-col :span="24" v-if="deviceCmdsource.length" >
  178. <a-table
  179. style="width: 100%;margin-top: 10px;"
  180. :columns="actionsColumns.DEVICE_CMD"
  181. :data-source="deviceCmdsource"
  182. size="small"
  183. :pagination="false"
  184. >
  185. <template #bodyCell="{column, record}" >
  186. <template v-if="column.key === 'action'" >
  187. <a @click="delCondiTionsAndActions(record.id, 'actions')" >
  188. 删除
  189. </a>
  190. </template>
  191. </template>
  192. </a-table>
  193. </a-col>
  194. <a-col :span="24" v-if="reportWarnSource.length" >
  195. <a-table
  196. style="width: 100%;margin-top: 10px;"
  197. :columns="actionsColumns.REPORT_WARN"
  198. :data-source="reportWarnSource"
  199. size="small"
  200. :pagination="false"
  201. >
  202. <template #bodyCell="{column, record}" >
  203. <template v-if="column.key === 'action'" >
  204. <a @click="delCondiTionsAndActions(record.id, 'actions')" >
  205. 删除
  206. </a>
  207. </template>
  208. </template>
  209. </a-table>
  210. </a-col>
  211. <a-col :span="24" v-if="resumeWarnSource.length" >
  212. <a-table
  213. style="width: 100%;margin-top: 10px;"
  214. :columns="actionsColumns.RESUME_WARN"
  215. :data-source="resumeWarnSource"
  216. size="small"
  217. :pagination="false"
  218. >
  219. <template #bodyCell="{column, record}" >
  220. <template v-if="column.key === 'action'" >
  221. <a @click="delCondiTionsAndActions(record.id, 'actions')" >
  222. 删除
  223. </a>
  224. </template>
  225. </template>
  226. </a-table>
  227. </a-col>
  228. <a-col :span="24" v-if="noticeSource.length" >
  229. <a-table
  230. style="width: 100%;margin-top: 10px;"
  231. :columns="actionsColumns.NOTICE"
  232. :data-source="noticeSource"
  233. size="small"
  234. :pagination="false"
  235. >
  236. <template #bodyCell="{column, record}" >
  237. <template v-if="column.key === 'action'" >
  238. <a @click="delCondiTionsAndActions(record.id, 'actions')" >
  239. 删除
  240. </a>
  241. </template>
  242. </template>
  243. </a-table>
  244. </a-col>
  245. </a-row>
  246. <a-col class="content" v-if="bodyParamsState.actions.length === 0" >尚未设置动作</a-col>
  247. </a-row>
  248. </a-card>
  249. </div>
  250. </modal-pro>
  251. <modal-pro
  252. label="选择"
  253. :visible="state.formVisible"
  254. @cancel="state.formVisible = false"
  255. @ok="selectConditionAndAction"
  256. style="width: 700px;"
  257. >
  258. <div style="width: 100%;" v-if="state.opraModel === 'conditions'" >
  259. <a-row :gutter="[8, 8]" style="width: 100%;" >
  260. <a-form
  261. style="width: 100%;"
  262. :label-col="{ span: 3 }"
  263. :wrapper-col="{ span: 16 }"
  264. >
  265. <a-col>
  266. <a-form-item label="触发条件" >
  267. <a-select
  268. style="width: 170px"
  269. v-model:value="initConditionsData.conditionType"
  270. >
  271. <a-select-option
  272. v-for="itemType in conditionTypeList"
  273. :key="itemType.key"
  274. :value="itemType.key"
  275. >
  276. {{itemType.name}}
  277. </a-select-option>
  278. </a-select>
  279. </a-form-item>
  280. <span v-if="initConditionsData.conditionType === 'DEVICE_DATA'" >
  281. <a-form-item label="产品" >
  282. <a-select
  283. style="width: 170px"
  284. placeholder="请选择产品"
  285. v-model:value="initConditionsData.modelId"
  286. >
  287. <a-select-option
  288. v-for="model in state.modelList"
  289. :key="model.id"
  290. :value="model.id"
  291. >
  292. {{model.modelLabel}}
  293. </a-select-option>
  294. </a-select>
  295. </a-form-item>
  296. <a-form-item label="设备类型" >
  297. <a-space>
  298. <a-select
  299. style="width: 170px"
  300. placeholder="请选择设备"
  301. v-model:value="initConditionsData.deviceType"
  302. >
  303. <a-select-option
  304. v-for="deviceItem in selectDeviceList"
  305. :key="deviceItem.key"
  306. :value="deviceItem.key"
  307. >
  308. {{deviceItem.name}}
  309. </a-select-option>
  310. </a-select>
  311. <a-tag color="blue" v-if="initConditionsData.deviceLabel" >{{initConditionsData.deviceLabel}}</a-tag>
  312. <a-button
  313. type="primary"
  314. v-if="initConditionsData.deviceType === 'target'"
  315. @click="openDeviceModal('conditions')"
  316. >
  317. {{initConditionsData.deviceId ? '重新选择' : '请选择设备'}}
  318. </a-button>
  319. </a-space>
  320. </a-form-item>
  321. <a-form-item label="属性key" >
  322. <a-select
  323. style="width: 170px"
  324. placeholder="请选择属性key"
  325. v-model:value="initConditionsData.attributeKey"
  326. >
  327. <a-select-option
  328. v-for="attrItem in state.attrList"
  329. :key="attrItem.attributeKey"
  330. :value="attrItem.attributeKey"
  331. >
  332. {{attrItem.attributeKey}}
  333. </a-select-option>
  334. </a-select>
  335. </a-form-item>
  336. <a-form-item label="操作符" >
  337. <a-select
  338. style="width: 170px"
  339. placeholder="请选择操作符"
  340. v-model:value="initConditionsData.operator"
  341. >
  342. <a-select-option
  343. v-for="operaItem in operatorList"
  344. :key="operaItem"
  345. :value="operaItem"
  346. >
  347. {{operaItem}}
  348. </a-select-option>
  349. </a-select>
  350. </a-form-item>
  351. <a-form-item label="触发值" >
  352. <a-input
  353. v-if="initConditionsData.operator !== 'BETWEEN'"
  354. style="width: 170px;"
  355. placeholder="请选择触发值"
  356. v-model:value="initConditionsData.value"
  357. ></a-input>
  358. <a-input-group compact v-else >
  359. <a-input placeholder="值1" v-model:value="initConditionsData.v1" style="width: 20%" />
  360. <a-input placeholder="值2" v-model:value="initConditionsData.v2" style="width: 30%" />
  361. </a-input-group>
  362. </a-form-item>
  363. </span>
  364. <span v-else-if="initConditionsData.conditionType === 'DEVICE_SESSION'" >
  365. <a-form-item label="产品">
  366. <a-select
  367. style="width: 170px"
  368. placeholder="请选择产品"
  369. v-model:value="initConditionsData.modelId"
  370. >
  371. <a-select-option
  372. v-for="model in state.modelList"
  373. :key="model.id"
  374. :value="model.id"
  375. >
  376. {{model.modelLabel}}
  377. </a-select-option>
  378. </a-select>
  379. </a-form-item>
  380. <a-form-item label="设备类型" >
  381. <a-space>
  382. <a-select
  383. style="width: 170px"
  384. placeholder="请选择设备"
  385. v-model:value="initConditionsData.deviceType"
  386. >
  387. <a-select-option
  388. v-for="deviceItem in selectDeviceList"
  389. :key="deviceItem.key"
  390. :value="deviceItem.key"
  391. >
  392. {{deviceItem.name}}
  393. </a-select-option>
  394. </a-select>
  395. <a-tag color="blue" v-if="initConditionsData.deviceLabel" >{{initConditionsData.deviceLabel}}</a-tag>
  396. <a-button
  397. type="primary"
  398. v-if="initConditionsData.deviceType === 'target'"
  399. @click="openDeviceModal('conditions')"
  400. >
  401. {{initConditionsData.deviceId ? '重新选择' : '请选择设备'}}
  402. </a-button>
  403. </a-space>
  404. </a-form-item>
  405. <a-form-item label="是否连接" >
  406. <a-select
  407. style="width: 170px"
  408. placeholder="请选择session"
  409. v-model:value="initConditionsData.sessionEventType"
  410. >
  411. <a-select-option
  412. v-for="essionEventTypeItem in sessionEventTypeList"
  413. :key="essionEventTypeItem.key"
  414. :value="essionEventTypeItem.key"
  415. >
  416. {{essionEventTypeItem.name}}
  417. </a-select-option>
  418. </a-select>
  419. </a-form-item>
  420. </span>
  421. <span v-else-if="initConditionsData.conditionType === 'DAILY_TIMER'" >
  422. <a-form-item label="时间" >
  423. <a-checkbox-group v-model:value="initConditionsData.dayOfWeek" :options="dayOptions" />
  424. </a-form-item>
  425. <a-form-item label="日期" >
  426. <a-time-picker v-model:value="initConditionsData.time" value-format="HH:mm:ss" />
  427. </a-form-item>
  428. </span>
  429. </a-col>
  430. </a-form>
  431. </a-row>
  432. </div>
  433. <div v-else style="width: 100%;" >
  434. <a-row :gutter="[8, 8]" style="width: 100%;" >
  435. <a-form
  436. style="width: 100%;"
  437. :label-col="{ span: 3 }"
  438. :wrapper-col="{ span: 16 }"
  439. >
  440. <a-col>
  441. <a-form-item label="触发动作" >
  442. <a-select
  443. style="width: 170px"
  444. v-model:value="initActionsData.actionType"
  445. >
  446. <a-select-option
  447. v-for="actionItem in actionTypeList"
  448. :key="actionItem.key"
  449. :value="actionItem.key"
  450. >
  451. {{actionItem.name}}
  452. </a-select-option>
  453. </a-select>
  454. </a-form-item>
  455. </a-col>
  456. <span v-if="initActionsData.actionType === 'DEVICE_CMD'" >
  457. <a-col>
  458. <a-form-item label="选择产品" >
  459. <a-select
  460. style="width: 170px"
  461. placeholder="请选择产品"
  462. v-model:value="initActionsData.modelId"
  463. >
  464. <a-select-option
  465. v-for="model in state.modelList"
  466. :key="model.id"
  467. :value="model.id"
  468. >
  469. {{model.modelLabel}}
  470. </a-select-option>
  471. </a-select>
  472. </a-form-item>
  473. <a-form-item label="设备类型" >
  474. <a-space>
  475. <a-select
  476. style="width: 170px"
  477. placeholder="请选择设备"
  478. v-model:value="initActionsData.deviceType"
  479. >
  480. <a-select-option
  481. v-for="deviceItem in selectDeviceList"
  482. :key="deviceItem.key"
  483. :value="deviceItem.key"
  484. >
  485. {{deviceItem.name}}
  486. </a-select-option>
  487. </a-select>
  488. <a-tag color="blue" v-if="initActionsData.deviceLabel" >{{initActionsData.deviceLabel}}</a-tag>
  489. <a-button
  490. type="primary"
  491. v-if="initActionsData.deviceType === 'target'"
  492. @click="openDeviceModal('actions')"
  493. >
  494. {{initActionsData.deviceId ? '重新选择' : '请选择设备'}}
  495. </a-button>
  496. </a-space>
  497. </a-form-item>
  498. <a-form-item label="选择命令" >
  499. <a-select
  500. style="width: 170px;"
  501. v-model:value="initActionsData.cmdId"
  502. >
  503. <a-select-option
  504. v-for="cmdItem in state.cmdList"
  505. :key="cmdItem.id"
  506. :value="cmdItem.id"
  507. >
  508. {{cmdItem.cmdLabel}}
  509. </a-select-option>
  510. </a-select>
  511. </a-form-item>
  512. <a-form-item label="命令参数" >
  513. <div
  514. v-for="(item, index) in initActionsData.cmdParameters"
  515. :key="index"
  516. style="margin-bottom: 10px;"
  517. >
  518. <a-input-group compact >
  519. <a-input placeholder="key" disabled v-model:value="item.paramLabel" style="width: 50%" />
  520. <a-input placeholder="value" v-model:value="item.dataUnit" style="width: 50%" />
  521. </a-input-group>
  522. </div>
  523. </a-form-item>
  524. </a-col>
  525. </span>
  526. <span v-else-if="initActionsData.actionType === 'REPORT_WARN'">
  527. <a-form-item label="设备类型" >
  528. <a-space>
  529. <a-select
  530. style="width: 170px"
  531. placeholder="请选择设备"
  532. v-model:value="initActionsData.deviceType"
  533. >
  534. <a-select-option
  535. v-for="deviceItem in selectDeviceList"
  536. :key="deviceItem.key"
  537. :value="deviceItem.key"
  538. >
  539. {{deviceItem.name}}
  540. </a-select-option>
  541. </a-select>
  542. <a-tag color="blue" v-if="initActionsData.deviceLabel" >{{initActionsData.deviceLabel}}</a-tag>
  543. <a-button
  544. type="primary"
  545. v-if="initActionsData.deviceType === 'target'"
  546. @click="openDeviceModal('actions')"
  547. >
  548. {{initActionsData.deviceId ? '重新选择' : '请选择设备'}}
  549. </a-button>
  550. </a-space>
  551. </a-form-item>
  552. <a-form-item label="告警名称" >
  553. <a-input v-model:value="initActionsData.warnLabel" ></a-input>
  554. </a-form-item>
  555. <a-form-item label="告警描述" >
  556. <a-input v-model:value="initActionsData.warnDescription" ></a-input>
  557. </a-form-item>
  558. <a-form-item label="告警级别" >
  559. <a-select v-model:value="initActionsData.warnSeverity" >
  560. <a-select-option
  561. v-for='warnItem in warnSeverityList'
  562. :key="warnItem.key"
  563. :value="warnItem.key"
  564. >
  565. {{warnItem.name}}
  566. </a-select-option>
  567. </a-select>
  568. </a-form-item>
  569. </span>
  570. <span v-else-if="initActionsData.actionType === 'RESUME_WARN'">
  571. <a-form-item label="设备类型" >
  572. <a-space>
  573. <a-select
  574. style="width: 170px"
  575. placeholder="请选择设备"
  576. v-model:value="initActionsData.deviceType"
  577. >
  578. <a-select-option
  579. v-for="deviceItem in selectDeviceList"
  580. :key="deviceItem.key"
  581. :value="deviceItem.key"
  582. >
  583. {{deviceItem.name}}
  584. </a-select-option>
  585. </a-select>
  586. <a-tag color="blue" v-if="initActionsData.deviceLabel" >{{initActionsData.deviceLabel}}</a-tag>
  587. <a-button
  588. type="primary"
  589. v-if="initActionsData.deviceType === 'target'"
  590. @click="openDeviceModal('actions')"
  591. >
  592. {{initActionsData.deviceId ? '重新选择' : '请选择设备'}}
  593. </a-button>
  594. </a-space>
  595. </a-form-item>
  596. <a-form-item label="告警名称" >
  597. <a-input v-model:value="initActionsData.warnLabel" ></a-input>
  598. </a-form-item>
  599. <a-form-item label="告警级别" >
  600. <a-select v-model:value="initActionsData.warnSeverity" >
  601. <a-select-option
  602. v-for='warnItem in warnSeverityList'
  603. :key="warnItem.key"
  604. :value="warnItem.key"
  605. >
  606. {{warnItem.name}}
  607. </a-select-option>
  608. </a-select>
  609. </a-form-item>
  610. </span>
  611. <span v-else-if="initActionsData.actionType === 'NOTICE'">
  612. <a-form-item label="提示名称" >
  613. <a-input v-model:value="initActionsData.noticeLabel" ></a-input>
  614. </a-form-item>
  615. <a-form-item label="提示描述" >
  616. <a-input v-model:value="initActionsData.noticeDescription" ></a-input>
  617. </a-form-item>
  618. <a-form-item label="提示用户" >
  619. <a-input v-model:value="initActionsData.userId" ></a-input>
  620. </a-form-item>
  621. </span>
  622. </a-form>
  623. </a-row>
  624. </div>
  625. </modal-pro>
  626. <modal-pro
  627. style="width: 700px"
  628. label="选择设备"
  629. :visible="state.deviceModalVisible"
  630. @cancel="state.deviceModalVisible = false"
  631. @ok="selectDevice"
  632. >
  633. <SelectDevice
  634. ref="selectDeviceRef"
  635. />
  636. </modal-pro>
  637. </template>
  638. <script lang='ts' setup >
  639. import { FormItemProps } from '@/components/FormPro/index.vue'
  640. import { ModelAttrController, ModelCmdController, ModelController, RuleController } from '@/controller'
  641. import { computed, nextTick, onMounted, reactive, ref, watch, getCurrentInstance } from 'vue'
  642. import { DownOutlined, FacebookFilled } from '@ant-design/icons-vue'
  643. import SelectDevice from './components/selectDevice.vue'
  644. import { useId } from '@/hooks'
  645. import { Form } from 'ant-design-vue'
  646. const {
  647. proxy: { $forceUpdate }
  648. }: any = getCurrentInstance()
  649. const useForm = Form.useForm
  650. const columns = [
  651. {
  652. title: '状态',
  653. dataIndex: 'status',
  654. key: 'status'
  655. },
  656. {
  657. title: '规则ID',
  658. dataIndex: 'id',
  659. key: 'id'
  660. },
  661. {
  662. title: '规则名称',
  663. dataIndex: 'ruleLabel',
  664. key: 'ruleLabel'
  665. },
  666. {
  667. title: '规则描述',
  668. dataIndex: 'ruleDescription',
  669. key: 'ruleDescription'
  670. },
  671. {
  672. title: '操作',
  673. dataIndex: 'action',
  674. key: 'action'
  675. }
  676. ]
  677. const formProps: FormItemProps[] = reactive([
  678. {
  679. label: '规则名称',
  680. key: 'ruleLabel',
  681. value: '',
  682. type: 'input',
  683. rules: true
  684. },
  685. {
  686. label: '规则描述',
  687. key: 'ruleDescription',
  688. value: '',
  689. type: 'textarea',
  690. rules: false
  691. }
  692. ])
  693. const conditionTypeList = [
  694. { key: 'DEVICE_DATA', name: '设备数据触发' },
  695. { key: 'DEVICE_SESSION', name: '设备状态触发' },
  696. { key: 'DAILY_TIMER', name: '周期时间条件' }
  697. ]
  698. const selectDeviceList = [
  699. { key: 'all', name: '全部设备' },
  700. { key: 'target', name: '指定设备' }
  701. ]
  702. const conditionColumns = reactive({
  703. DEVICE_DATA: [
  704. { title: '触发条件', dataIndex: 'conditionType' }, { title: '产品ID', dataIndex: 'modelId' },
  705. { title: '属性key', dataIndex: 'attributeKey' }, { title: '操作符', dataIndex: 'operator' },
  706. { title: '触发值', dataIndex: 'value' }, { title: '操作符', dataIndex: 'operator' }, { title: '操作', key: 'action' }
  707. ],
  708. DEVICE_SESSION: [
  709. { title: '触发条件', dataIndex: 'conditionType' }, { title: '产品ID', dataIndex: 'modelId' },
  710. { title: '设备类型', dataIndex: 'deviceType' }, { title: '设备名称', dataIndex: 'deviceLabel' },
  711. { title: 'sessionEventType', dataIndex: 'attributeKey', key: 'sessionEventType' }, { title: '操作', key: 'action' }
  712. ],
  713. DAILY_TIMER: [
  714. { title: '触发条件', dataIndex: 'conditionType' }, { title: '时间', dataIndex: 'time', key: 'time' },
  715. { title: '日期', dataIndex: 'dayOfWeek', key: 'dayOfWeek' }, { title: '操作', key: 'action' }
  716. ]
  717. })
  718. const actionsColumns = reactive({
  719. DEVICE_CMD: [
  720. { title: '触发动作', dataIndex: 'actionType' }, { title: '产品ID', dataIndex: 'modelId' },
  721. { title: '设备id', dataIndex: 'deviceId' }, { title: '命令名称', dataIndex: 'cmdLabel' },
  722. { title: '命令参数', dataIndex: 'cmdParameters' }, { title: '操作', dataIndex: 'action', key: 'action' }
  723. ],
  724. REPORT_WARN: [
  725. { title: '触发动作', dataIndex: 'actionType' }, { title: '设备id', dataIndex: 'deviceId' },
  726. { title: '告警名称', dataIndex: 'warnLabel' }, { title: '告警描述', dataIndex: 'warnDescription' },
  727. { title: '告警级别', dataIndex: 'warnSeverity' }, { title: '操作', dataIndex: 'action', key: 'action' }
  728. ],
  729. RESUME_WARN: [
  730. { title: '触发动作', dataIndex: 'actionType' }, { title: '告警名称', dataIndex: 'warnLabel' },
  731. { title: '告警级别', dataIndex: 'warnSeverity' }, { title: '操作', dataIndex: 'action', key: 'action' }
  732. ],
  733. NOTICE: [
  734. { title: '触发动作', dataIndex: 'actionType' }, { title: '提示名称', dataIndex: 'noticeLabel' },
  735. { title: '提示描述', dataIndex: 'noticeDescription' }, { title: '提示用户', dataIndex: 'userId' },
  736. { title: '操作', dataIndex: 'action', key: 'action' }
  737. ]
  738. })
  739. const sessionEventTypeList = [
  740. { key: 'CONNECT', name: '连接' },
  741. { key: 'DISCONNECT', name: '断开连接' }
  742. ]
  743. const dayOptions = [
  744. { value: 1, label: '周一' },
  745. { value: 2, label: '周二' },
  746. { value: 3, label: '周三' },
  747. { value: 4, label: '周四' },
  748. { value: 5, label: '周五' },
  749. { value: 6, label: '周六' },
  750. { value: 7, label: '周日' }
  751. ]
  752. const actionTypeList = [
  753. { key: 'DEVICE_CMD', name: '设备命令' },
  754. { key: 'REPORT_WARN', name: '上报告警' },
  755. { key: 'RESUME_WARN', name: '恢复告警' },
  756. { key: 'NOTICE', name: '通知' }
  757. ]
  758. const warnSeverityList = [
  759. { key: 'NOTICE', name: '提示' },
  760. { key: 'MINOR', name: '次要' },
  761. { key: 'MJAJOP', name: '重要' },
  762. { key: 'EMERGENCY', name: '紧急' }
  763. ]
  764. const operatorList = [
  765. 'EQ', 'NE', 'GT', 'GE', 'LT', 'LE', 'BETWEEN'
  766. ]
  767. const selectDeviceRef = ref('')
  768. const formProRef = ref('')
  769. const queryParamsState = reactive({
  770. page: 1,
  771. pageSize: 10,
  772. total: 0,
  773. ruleLabel: ''
  774. })
  775. const _initConditionsData = {
  776. conditionType: '',
  777. modelId: '',
  778. deviceType: '',
  779. deviceLabel: '',
  780. deviceId: '',
  781. sessionEventType: 'CONNECT',
  782. dayOfWeek: [],
  783. time: '',
  784. noticeLabel: '',
  785. noticeDescription: '',
  786. userId: '',
  787. attributeKey: '',
  788. operator: 'EQ',
  789. value: '',
  790. v1: '',
  791. v2: ''
  792. }
  793. const initConditionsData = reactive({ ..._initConditionsData })
  794. const _initActionsData = {
  795. actionType: '',
  796. modelId: '',
  797. deviceId: '',
  798. deviceLabel: '',
  799. deviceType: '',
  800. cmdId: '',
  801. cmdLabel: '',
  802. cmdParameters: [],
  803. warnLabel: '',
  804. warnDescription: '',
  805. warnSeverity: '',
  806. noticeLabel: '',
  807. noticeDescription: '',
  808. userId: ''
  809. }
  810. const initActionsData = reactive({ ..._initActionsData })
  811. const bodyParamsState = reactive<{
  812. id: string
  813. conditions: [],
  814. actions: [],
  815. conditionLogic: string
  816. ruleLabel: string
  817. ruleDescription: string
  818. }>({
  819. id: '',
  820. ruleLabel: '',
  821. ruleDescription: '',
  822. conditionLogic: 'AND',
  823. conditions: [],
  824. actions: []
  825. })
  826. const state = reactive({
  827. loading: false,
  828. dataSource: [],
  829. visible: false,
  830. formVisible: false,
  831. deviceModalVisible: false,
  832. opraState: 'add',
  833. modelList: [],
  834. cmdList: [],
  835. attrList: [],
  836. opraModel: '',
  837. opraIndex: 0, // 点击 条件 与 动作 时的下标
  838. opraKey: ''
  839. })
  840. watch(
  841. () => initConditionsData.conditionType,
  842. () => {
  843. Object.keys(initConditionsData).forEach(key => {
  844. if (key !== 'conditionType') {
  845. initConditionsData[key] = _initConditionsData[key]
  846. }
  847. })
  848. }
  849. )
  850. watch(
  851. () => initActionsData.actionType,
  852. () => {
  853. Object.keys(initActionsData).forEach(key => {
  854. if (key !== 'actionType') {
  855. initActionsData[key] = _initActionsData[key]
  856. }
  857. })
  858. }
  859. )
  860. watch(
  861. () => initConditionsData.modelId,
  862. () => {
  863. console.log('我触发吗')
  864. getAttrList()
  865. },
  866. {
  867. deep: true
  868. }
  869. )
  870. watch(
  871. () => initActionsData.modelId,
  872. () => {
  873. initActionsData.cmdParameters = []
  874. initActionsData.cmdLabel = ''
  875. initActionsData.cmdId = ''
  876. getCmdList()
  877. }
  878. )
  879. watch(
  880. () => initActionsData.cmdId,
  881. () => {
  882. const cmdDetail = state.cmdList.find(item => item.id === initActionsData.cmdId)!
  883. console.log('cmdDetail:', cmdDetail)
  884. initActionsData.cmdParameters = cmdDetail.cmdParams
  885. console.log(' initActionsData.cmdParameters:', initActionsData.cmdParameters, initActionsData.cmdId)
  886. initActionsData.cmdLabel = cmdDetail.cmdLabel
  887. }
  888. )
  889. const deviceSessionSource = computed(() => bodyParamsState.conditions.filter(item => item.conditionType === 'DEVICE_SESSION'))
  890. const deviceDataSource = computed(() => bodyParamsState.conditions.filter(item => item.conditionType === 'DEVICE_DATA'))
  891. const dailyTimerSource = computed(() => bodyParamsState.conditions.filter(item => item.conditionType === 'DAILY_TIMER'))
  892. const deviceCmdsource = computed(() => bodyParamsState.actions.filter(item => item.actionType === 'DEVICE_CMD'))
  893. const reportWarnSource = computed(() => bodyParamsState.actions.filter(item => item.actionType === 'REPORT_WARN'))
  894. const resumeWarnSource = computed(() => bodyParamsState.actions.filter(item => item.actionType === 'RESUME_WARN'))
  895. const noticeSource = computed(() => bodyParamsState.actions.filter(item => item.actionType === 'NOTICE'))
  896. const { resetFields, validate, validateInfos } = useForm(bodyParamsState, {
  897. ruleLabel: [{ required: true, message: '请填写联动规则名称' }]
  898. })
  899. const openModal = (_opraState: 'add' | 'update', record: any) => {
  900. state.visible = true
  901. state.opraState = _opraState
  902. getLinkPageById(record.id)
  903. }
  904. const ok = async () => {
  905. validate().then(async () => {
  906. bodyParamsState.conditions.forEach(item => {
  907. if (item.operator === 'BETWEEN') {
  908. item.value = `{${item.v1}, ${item.v2}}`
  909. }
  910. })
  911. bodyParamsState.actions.forEach(item => {
  912. if (item.cmdParameters && item.cmdParameters.length) {
  913. const obj = {}
  914. item.cmdParameters.forEach(item => {
  915. obj[item.paramLabel] = item.dataUnit
  916. })
  917. item.cmdParameters = obj
  918. }
  919. })
  920. state.opraState === 'add' ? await RuleController.addLink({ ...bodyParamsState }) : await RuleController.updateLink({ ...bodyParamsState })
  921. state.visible = false
  922. getLinkPage()
  923. })
  924. }
  925. // 选择设备
  926. const selectDevice = () => {
  927. const _device = selectDeviceRef.value.getSelectDevice()
  928. state.deviceModalVisible = false
  929. if (state.opraKey === 'conditions') {
  930. initConditionsData.deviceLabel = _device.deviceLabelß
  931. initConditionsData.deviceId = _device.id
  932. } else {
  933. initActionsData.deviceLabel = _device.deviceLabel
  934. initActionsData.deviceId = _device.id
  935. }
  936. }
  937. const changePage = ({ current }) => {
  938. queryParamsState.page = current
  939. getLinkPage()
  940. }
  941. // 打开选择设备弹窗
  942. const openDeviceModal = (key: 'conditions' | 'actions') => {
  943. state.deviceModalVisible = true
  944. state.opraKey = key
  945. }
  946. const openFormVisible = (model: 'conditions' | 'actions') => {
  947. state.formVisible = true
  948. state.opraModel = model
  949. }
  950. // 删除条件或则动作
  951. const delCondiTionsAndActions = (id: string, key: 'conditions' | 'actions') => {
  952. const index = bodyParamsState[key].findIndex(item => item.id === id)
  953. bodyParamsState[key].splice(index, 1)
  954. }
  955. const selectConditionAndAction = () => {
  956. if (state.opraModel === 'conditions') {
  957. bodyParamsState.conditions.push({ ...initConditionsData, id: useId() })
  958. } else {
  959. bodyParamsState.actions.push({ ...initActionsData, id: useId() })
  960. }
  961. state.formVisible = false
  962. }
  963. // 获取命令
  964. const getCmdList = async () => {
  965. const { data } = await ModelCmdController.list({ modelId: initActionsData.modelId })
  966. state.cmdList = data
  967. }
  968. // 获取属性
  969. const getAttrList = async () => {
  970. const { data } = await ModelAttrController.list({ modelId: initConditionsData.modelId })
  971. state.attrList = data
  972. }
  973. // 获取模型
  974. const getModelList = async () => {
  975. const { data } = await ModelController.list()
  976. state.modelList = data
  977. }
  978. const getLinkPageById = async (id: string) => {
  979. const { data } = await RuleController.getLinkById(id)
  980. console.log(data)
  981. resetFields({
  982. ruleLabel: data.ruleLabel,
  983. ruleDescription: data.ruleDescription
  984. })
  985. bodyParamsState.conditionLogic = data.conditionLogic
  986. bodyParamsState.actions = data.actions.map(item => {
  987. return {
  988. ...item,
  989. id: useId()
  990. }
  991. })
  992. bodyParamsState.conditions = data.conditions.map(item => {
  993. return {
  994. ...item,
  995. id: useId()
  996. }
  997. })
  998. $forceUpdate()
  999. bodyParamsState.id = data.id
  1000. }
  1001. const getLinkPage = async () => {
  1002. state.loading = true
  1003. const { data, sum } = await RuleController.pageLink(queryParamsState)
  1004. state.dataSource = data
  1005. queryParamsState.total = sum
  1006. state.loading = false
  1007. }
  1008. onMounted(() => {
  1009. getLinkPage()
  1010. getModelList()
  1011. })
  1012. </script>
  1013. <style lang='less' scoped >
  1014. .content {
  1015. width: 100%;
  1016. height: 45px;
  1017. background-color: #F2F5FC;
  1018. display: flex;
  1019. justify-content: center;
  1020. align-items: center;
  1021. margin: 20px 0;
  1022. }
  1023. .df {
  1024. display: flex;
  1025. justify-content: end;
  1026. }
  1027. </style>