index.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <template>
  2. <div>
  3. <yt-crud
  4. v-bind="options"
  5. ref="crudRef"
  6. :data="data"
  7. :column="column"
  8. :loading="state.loading"
  9. :total="state.total"
  10. :addBtn = "hasPermission('iot:rule:eidt')"
  11. v-model:page="state.page"
  12. v-model:query="state.query"
  13. @on-load="getData"
  14. @saveFun="onSave"
  15. @del-fun="handleDelete"
  16. >
  17. <template #state="scope">
  18. <el-switch
  19. v-model="scope.row.state"
  20. active-value="running"
  21. inactive-value="stopped"
  22. disabled
  23. style="--el-switch-on-color: #029D40; --el-switch-off-color: #DFDFDF"
  24. />
  25. <!-- <div v-if="scope.row.state === 'stopped'" style="color: red;">已停止</div>
  26. <div v-if="scope.row.state === 'running'" style="color: green;">运行中</div> -->
  27. </template>
  28. <template #log="scope">
  29. <el-button size="small" type="primary" @click="handleViewLog(scope.row.id)">查看</el-button>
  30. </template>
  31. <template #menuSlot="scope">
  32. <el-tooltip class="box-item" effect="dark" content="停止" placement="top">
  33. <el-button v-if="scope.row.state === 'running'" link type="danger" icon="SwitchButton" @click="handlePause(scope.row)" />
  34. </el-tooltip>
  35. <el-tooltip class="box-item" effect="dark" content="开启" placement="top">
  36. <el-button v-if="scope.row.state === 'stopped'" link type="success" icon="Open" @click="handleOpen(scope.row)" />
  37. </el-tooltip>
  38. </template>
  39. <template #customFormItem="{row}">
  40. <el-tabs v-model="activeName" type="border-card">
  41. <el-tab-pane label="监听器" :name="1">
  42. <listener v-if="activeName === 1" v-model:listeners="row.listeners" />
  43. </el-tab-pane>
  44. <el-tab-pane label="过滤器" :name="2">
  45. <filtera v-if="activeName === 2" v-model:filters="row.filters" />
  46. </el-tab-pane>
  47. <el-tab-pane label="输出" :name="3">
  48. <Output v-if="activeName === 3" v-model:list="row.actions" type="rule" actions="device,http,mqtt,kafka,tcp,alert" />
  49. </el-tab-pane>
  50. </el-tabs>
  51. </template>
  52. </yt-crud>
  53. <log-dialog ref="logDialogRef" title="场景执行日志" />
  54. </div>
  55. </template>
  56. <script lang="ts" setup>
  57. import { IColumn } from '@/components/common/types/tableCommon'
  58. import { getRuleList, saveRule, deleteRule, pauseRule, resumeRule } from '../api/rule.api'
  59. import Listener from './modules/listener.vue'
  60. import Filtera from './modules/filtera.vue'
  61. import Output from './modules/output.vue'
  62. import LogDialog from '../modules/logDialog.vue'
  63. import YtCrud from '@/components/common/yt-crud.vue'
  64. import { hasPermission } from '@/utils/auth'
  65. // 查看日志
  66. const logDialogRef = ref()
  67. const handleViewLog = (id: string) => {
  68. logDialogRef.value.openDialog(id)
  69. }
  70. const activeName = ref(1)
  71. const column: IColumn[] = [{
  72. label: '规则名称',
  73. key: 'name',
  74. rules: [{ required: true, message: '规则名称不能为空' }],
  75. }, {
  76. label: '状态',
  77. key: 'state',
  78. slot: true,
  79. formHide: true,
  80. },
  81. {
  82. label: '规则类型',
  83. key: 'type',
  84. type: 'select',
  85. search: false,
  86. componentProps: {
  87. defaultValue: 'scene',
  88. clearable: false,
  89. options: [{
  90. label: '场景联动',
  91. value: 'scene',
  92. }
  93. // , {
  94. // label: '数据流转',
  95. // value: 'flow'
  96. // }
  97. ]
  98. }
  99. },
  100. {
  101. label: '执行日志',
  102. key: 'log',
  103. slot: true,
  104. formHide: true,
  105. }, {
  106. label: '场景描述',
  107. key: 'desc',
  108. hide: true,
  109. componentProps: {
  110. type: 'textarea',
  111. row: 3,
  112. }
  113. }, {
  114. label: '自定义表单项',
  115. key: 'custom',
  116. hide: true,
  117. formItemSlot: true,
  118. }, {
  119. label: '创建时间',
  120. key: 'createAt',
  121. type: 'date',
  122. formHide: true,
  123. }]
  124. const state = reactive({
  125. page: {
  126. pageSize: 10,
  127. pageNum: 1,
  128. },
  129. total: 0,
  130. loading: false,
  131. query: {
  132. type: 'scene',
  133. },
  134. })
  135. const data = ref([])
  136. // 保存数据
  137. const onSave = ({type, data, cancel}: any) => {
  138. state.loading = true
  139. const obj = toRaw(data)
  140. obj.listeners = (obj.listeners || [])?.map(m => {
  141. const mObj = {
  142. type: m.type,
  143. pk: m.pk,
  144. dn: m.dn,
  145. // deviceDn: m.deviceDn,
  146. // device: m.device,
  147. conditions: m.conditions.map(m2 => ({
  148. ...m2,
  149. device: m.device,
  150. })),
  151. }
  152. return {
  153. ...mObj,
  154. config: JSON.stringify(mObj)
  155. }
  156. })
  157. obj.filters = (obj.filters || [])?.map(m => {
  158. const mObj = {
  159. type: 'device',
  160. pk: m.pk,
  161. dn: m.dn,
  162. // deviceDn: m.deviceDn,
  163. // device: m.device,
  164. conditions: m.conditions.map(m2 => ({
  165. ...m2,
  166. device: m.device,
  167. })),
  168. deviceRadio: m.deviceRadio,
  169. }
  170. return {
  171. ...mObj,
  172. config: JSON.stringify(mObj)
  173. }
  174. })
  175. obj.actions = (obj.actions || [])?.map(m => {
  176. m.saved = true
  177. if (m.config) {
  178. return m
  179. }
  180. return {
  181. ...m,
  182. config: JSON.stringify(m),
  183. }
  184. })
  185. saveRule(obj).then(res => {
  186. ElMessage.success(type === 'add' ? '添加成功' : '编辑成功')
  187. cancel()
  188. getData()
  189. }).finally(() => {
  190. state.loading = false
  191. })
  192. }
  193. const getData = () => {
  194. state.loading = true
  195. getRuleList({
  196. ...state.page,
  197. ...state.query,
  198. }).then((res) => {
  199. data.value = res.data.rows
  200. state.total = res.data.total
  201. })
  202. state.loading = false
  203. }
  204. const handleDelete = (row) => {
  205. state.loading = true
  206. deleteRule(row.id).then(res => {
  207. ElMessage.success('删除成功!')
  208. getData()
  209. }).finally(() => {
  210. state.loading = false
  211. })
  212. }
  213. const handleOpen = (row) => {
  214. state.loading = true
  215. resumeRule(row.id).then(res => {
  216. ElMessage.success('开启成功!')
  217. getData()
  218. }).finally(() => {
  219. state.loading = false
  220. })
  221. }
  222. const handlePause = (row) => {
  223. state.loading = true
  224. pauseRule(row.id).then(res => {
  225. ElMessage.success('停止成功!')
  226. getData()
  227. }).finally(() => {
  228. state.loading = false
  229. })
  230. }
  231. const options = reactive({
  232. formProps: {
  233. width: 1000,
  234. },
  235. tableProps: {
  236. selection: false,
  237. viewBtn: false,
  238. menuSlot: true,
  239. menuWidth: 300,
  240. },
  241. searchProps: {},
  242. })
  243. </script>
  244. <!-- <style lang="scss" scoped>
  245. </style> -->