GroupTree.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. <template>
  2. <div id="DeviceTree">
  3. <div v-if="showHeader" class="page-header" style="margin-bottom: 1rem;">
  4. <div class="page-title">业务分组</div>
  5. <div class="page-header-btn">
  6. <div style="display: inline;">
  7. <el-input @input="search" style="visibility:hidden; margin-right: 1rem; width: 12rem;" size="mini" placeholder="关键字"
  8. prefix-icon="el-icon-search" v-model="searchSrt" clearable></el-input>
  9. <el-checkbox v-model="showCode">显示编号</el-checkbox>
  10. </div>
  11. </div>
  12. </div>
  13. <div v-if="showHeader" style="height: 2rem; background-color: #FFFFFF" ></div>
  14. <div>
  15. <vue-easy-tree
  16. class="flow-tree"
  17. ref="veTree"
  18. node-key="deviceId"
  19. height="78vh"
  20. lazy
  21. style="padding: 0 0 2rem 0.5rem"
  22. :load="loadNode"
  23. :data="treeData"
  24. :props="props"
  25. :default-expanded-keys="['']"
  26. @node-contextmenu="contextmenuEventHandler"
  27. @node-click="nodeClickHandler"
  28. >
  29. <span class="custom-tree-node" slot-scope="{ node, data }">
  30. <span @click.stop v-if="edit">
  31. <el-radio v-if="node.data.type === 0 && node.level > 2" style="margin-right: 0" v-model="chooseId" @input="chooseIdChange(node.data.deviceId, node.data.businessGroup)" :label="node.data.deviceId">{{''}}</el-radio>
  32. </span>
  33. <span v-if="node.data.type === 0" style="color: #409EFF" class="iconfont icon-bianzubeifen3"></span>
  34. <span v-if="node.data.type === 1" style="color: #409EFF" class="iconfont icon-shexiangtou2"></span>
  35. <span style=" padding-left: 1px" v-if="node.data.deviceId !=='' && showCode" :title="node.data.deviceId">{{ node.label }}(编号:{{ node.data.deviceId }})</span>
  36. <span style=" padding-left: 1px" v-if="node.data.deviceId ==='' || !showCode" :title="node.data.deviceId">{{ node.label }}</span>
  37. </span>
  38. </vue-easy-tree>
  39. </div>
  40. <groupEdit ref="groupEdit"></groupEdit>
  41. <gbDeviceSelect ref="gbDeviceSelect"></gbDeviceSelect>
  42. </div>
  43. </template>
  44. <script>
  45. import VueEasyTree from "@wchbrad/vue-easy-tree";
  46. import groupEdit from './../dialog/groupEdit'
  47. import gbDeviceSelect from './../dialog/GbDeviceSelect'
  48. export default {
  49. name: 'DeviceTree',
  50. components: {
  51. VueEasyTree, groupEdit, gbDeviceSelect
  52. },
  53. data() {
  54. return {
  55. props: {
  56. label: "name",
  57. },
  58. showCode: false,
  59. searchSrt: "",
  60. chooseId: "",
  61. treeData: [],
  62. }
  63. },
  64. props: ['edit', 'clickEvent', 'chooseIdChange', 'onChannelChange', 'showHeader'],
  65. created() {
  66. },
  67. methods: {
  68. search() {
  69. },
  70. loadNode: function (node, resolve) {
  71. if (node.level === 0) {
  72. resolve([{
  73. deviceId: "",
  74. name: "根资源组",
  75. isLeaf: false,
  76. type: 0
  77. }]);
  78. } else {
  79. if (node.data.leaf) {
  80. resolve([]);
  81. return
  82. }
  83. this.$axios({
  84. method: 'get',
  85. url: `/api/group/tree/list`,
  86. params: {
  87. query: this.searchSrt,
  88. parent: node.data.id
  89. }
  90. }).then((res) => {
  91. if (res.data.code === 0) {
  92. resolve(res.data.data);
  93. }
  94. }).catch(function (error) {
  95. console.log(error);
  96. });
  97. }
  98. },
  99. reset: function () {
  100. this.$forceUpdate();
  101. },
  102. contextmenuEventHandler: function (event, data, node, element) {
  103. if (!this.edit) {
  104. return;
  105. }
  106. console.log(node.level)
  107. if (node.data.type === 1) {
  108. data.parentId = node.parent.data.id;
  109. this.$contextmenu({
  110. items: [
  111. {
  112. label: "移除通道",
  113. icon: "el-icon-delete",
  114. disabled: false,
  115. onClick: () => {
  116. console.log(data)
  117. this.$axios({
  118. method: "post",
  119. url: `/api/common/channel/group/delete`,
  120. data: {
  121. channelIds: [data.id]
  122. }
  123. }).then((res) => {
  124. console.log("移除成功")
  125. if (this.onChannelChange) {
  126. this.onChannelChange()
  127. }
  128. node.parent.loaded = false
  129. node.parent.expand();
  130. }).catch(function (error) {
  131. console.log(error);
  132. });
  133. }
  134. }
  135. ],
  136. event, // 鼠标事件信息
  137. customClass: "custom-class", // 自定义菜单 class
  138. zIndex: 3000, // 菜单样式 z-index
  139. });
  140. } else if (node.data.type === 0) {
  141. this.$contextmenu({
  142. items: [
  143. {
  144. label: "刷新节点",
  145. icon: "el-icon-refresh",
  146. disabled: false,
  147. onClick: () => {
  148. this.refreshNode(node);
  149. }
  150. },
  151. {
  152. label: "新建节点",
  153. icon: "el-icon-plus",
  154. disabled: false,
  155. onClick: () => {
  156. this.addGroup(data.id, node);
  157. }
  158. },
  159. {
  160. label: "编辑节点",
  161. icon: "el-icon-edit",
  162. disabled: node.level === 1,
  163. onClick: () => {
  164. this.editGroup(data, node);
  165. }
  166. },
  167. {
  168. label: "删除节点",
  169. icon: "el-icon-delete",
  170. disabled: node.level === 1,
  171. divided: true,
  172. onClick: () => {
  173. this.$confirm('确定删除?', '提示', {
  174. confirmButtonText: '确定',
  175. cancelButtonText: '取消',
  176. type: 'warning'
  177. }).then(() => {
  178. this.removeGroup(data.id, node)
  179. }).catch(() => {
  180. });
  181. }
  182. },
  183. {
  184. label: "添加设备",
  185. icon: "el-icon-plus",
  186. disabled: node.level <= 2,
  187. onClick: () => {
  188. this.addChannelFormDevice(data.id, node)
  189. }
  190. },
  191. {
  192. label: "移除设备",
  193. icon: "el-icon-delete",
  194. disabled: node.level <= 2,
  195. onClick: () => {
  196. this.removeChannelFormDevice(data.id, node)
  197. }
  198. },
  199. // {
  200. // label: "导出",
  201. // icon: "el-icon-download",
  202. // disabled: false,
  203. // children: [
  204. // {
  205. // label: "导出到文件",
  206. // onClick: () => {
  207. //
  208. // },
  209. // },
  210. // {
  211. // label: "导出到其他平台",
  212. // onClick: () => {
  213. //
  214. // },
  215. // }
  216. // ]
  217. // },
  218. ],
  219. event, // 鼠标事件信息
  220. customClass: "custom-class", // 自定义菜单 class
  221. zIndex: 3000, // 菜单样式 z-index
  222. });
  223. }
  224. return false;
  225. },
  226. removeGroup: function (id, node) {
  227. this.$axios({
  228. method: "delete",
  229. url: `/api/group/delete`,
  230. params: {
  231. id: node.data.id,
  232. }
  233. }).then((res) => {
  234. if (res.data.code === 0) {
  235. console.log("移除成功")
  236. node.parent.loaded = false
  237. node.parent.expand();
  238. if (this.onChannelChange) {
  239. this.onChannelChange()
  240. }
  241. }
  242. }).catch(function (error) {
  243. console.log(error);
  244. });
  245. },
  246. addChannelFormDevice: function (id, node) {
  247. this.$refs.gbDeviceSelect.openDialog((rows)=>{
  248. let deviceIds = []
  249. for (let i = 0; i < rows.length; i++) {
  250. deviceIds.push(rows[i].id)
  251. }
  252. this.$axios({
  253. method: 'post',
  254. url: `/api/common/channel/group/device/add`,
  255. data: {
  256. parentId: node.data.deviceId,
  257. businessGroup: node.data.businessGroup,
  258. deviceIds: deviceIds,
  259. }
  260. }).then((res)=> {
  261. if (res.data.code === 0) {
  262. this.$message.success({
  263. showClose: true,
  264. message: "保存成功"
  265. })
  266. if (this.onChannelChange) {
  267. this.onChannelChange()
  268. }
  269. node.loaded = false
  270. node.expand();
  271. }else {
  272. this.$message.error({
  273. showClose: true,
  274. message: res.data.msg
  275. })
  276. }
  277. this.loading = false
  278. }).catch((error)=> {
  279. this.$message.error({
  280. showClose: true,
  281. message: error
  282. })
  283. this.loading = false
  284. });
  285. })
  286. },
  287. removeChannelFormDevice: function (id, node) {
  288. this.$refs.gbDeviceSelect.openDialog((rows)=>{
  289. let deviceIds = []
  290. for (let i = 0; i < rows.length; i++) {
  291. deviceIds.push(rows[i].id)
  292. }
  293. this.$axios({
  294. method: 'post',
  295. url: `/api/common/channel/group/device/delete`,
  296. data: {
  297. deviceIds: deviceIds,
  298. }
  299. }).then((res)=> {
  300. if (res.data.code === 0) {
  301. this.$message.success({
  302. showClose: true,
  303. message: "保存成功"
  304. })
  305. if (this.onChannelChange) {
  306. this.onChannelChange()
  307. }
  308. node.loaded = false
  309. node.expand();
  310. }else {
  311. this.$message.error({
  312. showClose: true,
  313. message: res.data.msg
  314. })
  315. }
  316. this.loading = false
  317. }).catch((error)=> {
  318. this.$message.error({
  319. showClose: true,
  320. message: error
  321. })
  322. this.loading = false
  323. });
  324. })
  325. },
  326. refreshNode: function (node) {
  327. node.loaded = false
  328. node.expand();
  329. },
  330. refresh: function (id) {
  331. // 查询node
  332. let node = this.$refs.veTree.getNode(id)
  333. node.loaded = false
  334. node.expand();
  335. },
  336. addGroup: function (id, node) {
  337. this.$refs.groupEdit.openDialog({
  338. id: 0,
  339. name: "",
  340. deviceId: "",
  341. civilCode: "",
  342. parentDeviceId: node.level > 2 ? node.data.deviceId:"",
  343. parentId: node.data.id,
  344. businessGroup: node.level > 2 ? node.data.businessGroup: node.data.deviceId,
  345. },form => {
  346. node.loaded = false
  347. node.expand();
  348. }, id);
  349. },
  350. editGroup: function (id, node) {
  351. console.log(node)
  352. this.$refs.groupEdit.openDialog(node.data,form => {
  353. node.parent.loaded = false
  354. node.parent.expand();
  355. }, id);
  356. },
  357. nodeClickHandler: function (data, node, tree) {
  358. if (this.clickEvent) {
  359. this.clickEvent(data)
  360. }
  361. }
  362. },
  363. destroyed() {
  364. // if (this.jessibuca) {
  365. // this.jessibuca.destroy();
  366. // }
  367. // this.playing = false;
  368. // this.loaded = false;
  369. // this.performance = "";
  370. },
  371. }
  372. </script>
  373. <style>
  374. .device-tree-main-box {
  375. text-align: left;
  376. }
  377. .device-online {
  378. color: #252525;
  379. }
  380. .device-offline {
  381. color: #727272;
  382. }
  383. .custom-tree-node .el-radio__label {
  384. padding-left: 4px !important;
  385. }
  386. </style>