index.vue 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970
  1. <template>
  2. <div
  3. v-loading="pageLoading"
  4. loading-text="加载中..."
  5. class="page-manage-wrap"
  6. >
  7. <div class="page-manage-menu">
  8. <!-- 搜索部分 -->
  9. <div class="page-manage-menu-search">
  10. <el-input
  11. v-model="searchKey"
  12. placeholder="请输入名称"
  13. @keyup.enter.native="filterClick"
  14. />
  15. <!-- 新增页面按钮 -->
  16. <i
  17. class="page-icon el-icon-plus"
  18. @click="openPageMenuDialog"
  19. />
  20. </div>
  21. <!-- 页面列表 -->
  22. <div class="page-manage-menu-list">
  23. <template v-if="pageDesignListHasLength">
  24. <el-tree
  25. ref="tree"
  26. :key="treeKey"
  27. class="page-list-tree"
  28. node-key="code"
  29. :default-expanded-keys="defaultExpand"
  30. :current-node-key="currentNodeCode"
  31. :data="pageDesignList"
  32. :props="defaultProps"
  33. :filter-node-method="filterNode"
  34. @node-click="nodeClick"
  35. >
  36. <span
  37. slot-scope="{ node, data }"
  38. class="menu-span"
  39. >
  40. <icon-svg :name="pageIconName(data,node)" />
  41. <span
  42. style="padding-left:4px;font-size:14px"
  43. class="tree-node-name"
  44. >{{ data.name }}</span>
  45. <el-dropdown
  46. class="page-list-dropdown"
  47. placement="bottom-start"
  48. node-key="id"
  49. trigger="click"
  50. >
  51. <span class="el-dropdown-link menu-dropdown-link">
  52. <i class="el-icon-more" />
  53. </span>
  54. <el-dropdown-menu slot="dropdown">
  55. <el-dropdown-item @click.native="handleDropdownClick('edit',data,node)">编辑 </el-dropdown-item>
  56. <el-dropdown-item
  57. v-if="data.type!=='catalog'"
  58. @click.native="handleDropdownClick('copy',data,node)"
  59. >复制 </el-dropdown-item>
  60. <el-dropdown-item
  61. class="delete-item"
  62. @click.native="handleDropdownClick('delete',data,node)"
  63. >删除 </el-dropdown-item>
  64. </el-dropdown-menu>
  65. </el-dropdown>
  66. </span>
  67. </el-tree>
  68. </template>
  69. <el-empty
  70. v-else
  71. slot="empty"
  72. />
  73. </div>
  74. </div>
  75. <!-- 预览部分 -->
  76. <div class="page-manage-content">
  77. <div class="page-manage-content-top">
  78. <div class="page-manage-content-top-name">
  79. <icon-svg
  80. v-if="activePage.code"
  81. :name="pageIconImg(activePage)"
  82. class="active-page-icon"
  83. />
  84. {{ activePage.type !== 'catalog'? activePage.name:'' }}
  85. </div>
  86. <div>
  87. <el-button
  88. v-if="pageDesignList.length!==0 && activePage.code"
  89. class="top-button"
  90. icon="el-icon-share"
  91. @click="gopagePreview(activePage)"
  92. >
  93. 新窗口打开
  94. </el-button>
  95. <el-button
  96. v-if="pageDesignList.length!==0 && activePage.code"
  97. class="page-manage-content-top-page"
  98. type="primary"
  99. @click="gopageDesign(activePage)"
  100. >
  101. 设计
  102. </el-button>
  103. </div>
  104. </div>
  105. <div
  106. class="page-manage-content-body-box"
  107. :style="{ padding: activePage.type !== 'dashBoard' ? '16px' : '0' }"
  108. >
  109. <div class="page-manage-content-body">
  110. <el-empty
  111. v-if="!activePage.code"
  112. slot="empty"
  113. description="请在左侧选择页面修改或新增页面"
  114. class="empty-wrap"
  115. />
  116. <div
  117. v-else
  118. :class="{
  119. 'preview-wrap': true,
  120. 'inner-preview-wrap': true,
  121. 'padding': activePage.type === 'form'
  122. }"
  123. >
  124. <BigScreenRun
  125. v-if="activePage.type === 'bigScreen'"
  126. :key="activePage.code"
  127. :code="activePage.code"
  128. />
  129. </div>
  130. </div>
  131. </div>
  132. </div>
  133. <!-- 新增或编辑弹窗 -->
  134. <AddDialog
  135. ref="AddDialog"
  136. @refreshData="reSearch"
  137. />
  138. <!-- 新增目录弹窗 -->
  139. <el-dialog
  140. :title="catalogData.id ? '编辑目录':'新增目录'"
  141. :visible.sync="catalogVisible"
  142. width="30%"
  143. class="bs-dialog-wrap catalog-dialog bs-el-dialog"
  144. @close="handleClose"
  145. >
  146. <el-form
  147. ref="form"
  148. :model="catalogData"
  149. label-width="80px"
  150. :rules="formRules"
  151. class="bs-el-form"
  152. >
  153. <el-form-item
  154. label="上级目录"
  155. >
  156. <el-select
  157. ref="select"
  158. v-model="catalogData.parentCode"
  159. placeholder="请选择上级目录"
  160. clearable
  161. @change="parentCodeChange"
  162. >
  163. <el-option
  164. key="code"
  165. hidden
  166. :value="catalogData.parentCode"
  167. :label="selectName"
  168. />
  169. <el-tree
  170. :data="catalogList"
  171. :props="defaultProps"
  172. node-key="code"
  173. :check-on-click-node="true"
  174. :expand-on-click-node="false"
  175. @node-click="handleNodeClick"
  176. >
  177. <span
  178. slot-scope="{ data }"
  179. class="menu-span"
  180. >
  181. <span
  182. style="padding-left:4px;font-size:14px"
  183. class="tree-node-name"
  184. >{{ data.name }}</span>
  185. </span>
  186. </el-tree>
  187. </el-select>
  188. </el-form-item>
  189. <el-form-item
  190. label="目录名称"
  191. prop="name"
  192. >
  193. <el-input v-model="catalogData.name" />
  194. </el-form-item>
  195. <el-form-item
  196. label="排序"
  197. >
  198. <el-input-number
  199. v-model="catalogData.orderNum"
  200. :min="0"
  201. :max="30000"
  202. controls-position="right"
  203. />
  204. </el-form-item>
  205. </el-form>
  206. <span
  207. slot="footer"
  208. class="dialog-footer"
  209. >
  210. <el-button
  211. class="bs-el-button-default"
  212. @click="catalogVisible = false"
  213. >取消</el-button>
  214. <el-button
  215. type="primary"
  216. @click="addCatalog"
  217. >确定</el-button>
  218. </span>
  219. </el-dialog>
  220. <ChooseTemplateDialog
  221. ref="ChooseTemplateDialog"
  222. :loading="templateLoading"
  223. :has-create="true"
  224. @addNew="addNew"
  225. @useIt="useIt"
  226. />
  227. <pageMenuDialog
  228. ref="pageMenuDialog"
  229. @addPageDesign="addPageDesign"
  230. />
  231. </div>
  232. </template>
  233. <script>
  234. import AddDialog from './addDialog.vue'
  235. import ChooseTemplateDialog from './ChooseTemplateDialog.vue'
  236. import pageMenuDialog from './pageMenuDialog.vue'
  237. import BigScreenRun from 'data-room-ui/BigScreenRun/index.vue'
  238. import Icon from 'data-room-ui/assets/images/pageIcon/export'
  239. import { getPageType } from './utils'
  240. import _ from 'lodash'
  241. // import axios from 'axios'
  242. // import { post } from 'data-room-ui/js/utils/http'
  243. import IconSvg from 'data-room-ui/SvgIcon'
  244. let dashBoardPageCode = null
  245. export default {
  246. name: 'PageManage',
  247. components: {
  248. AddDialog,
  249. ChooseTemplateDialog,
  250. pageMenuDialog,
  251. BigScreenRun,
  252. IconSvg
  253. },
  254. // 路由钩子-进入后
  255. beforeRouteEnter (to, from, next) {
  256. next(vm => {
  257. dashBoardPageCode = from.query.code
  258. })
  259. },
  260. props: [],
  261. data () {
  262. return {
  263. isCatalog: false, // 用来判断当前点击的节点是否是目录
  264. parentNode: { code: '' }, // 用来保存当前的父节点
  265. currentTreeNode: {}, // 保存当前点击的节点信息
  266. selectName: '',
  267. catalogList: [],
  268. currentNodeCode: '',
  269. dashBoardConfig: {},
  270. defaultExpand: [], // 默认展开的节点
  271. currentNode: {}, // 默认选中的节点
  272. flag: true,
  273. pageIcon: Icon.getNameList(), // 获取所有的svg
  274. defaultProps: { // el-tree的配置
  275. children: 'children',
  276. label: 'name'
  277. },
  278. showPage: false, // 显示页面
  279. sort: false, // 排序
  280. searchKey: '', // 关键词
  281. parentCode: '', // 当前选中的子节点的父节点的编码
  282. zNodes: [],
  283. ztreeObj: '',
  284. nodeData: {}, // 当前鼠标悬浮时的树节点
  285. activePage: {
  286. code: null,
  287. type: null,
  288. name: null
  289. }, // 当前选中的的树节点
  290. rightClickForm: {
  291. visible: false,
  292. org: {}
  293. },
  294. catalogVisible: false, // 文件夹的弹窗
  295. isAdd: true, // 判断当前目录是新增还是编辑
  296. catalogData: {
  297. id: '',
  298. code: '',
  299. type: 'catalog',
  300. name: '',
  301. parentCode: '',
  302. orderNum: 0
  303. }, // 文件夹数据
  304. // formConf,
  305. formInitInfo: {}, // 初始的数据
  306. pageDesignList: [], // 页面列表
  307. menuList: [{}],
  308. showHover: false,
  309. pageLoading: false,
  310. treeKey: new Date().getTime(),
  311. formRules: {
  312. name: [
  313. { required: true, message: '目录名称不能为空', trigger: 'blur' }
  314. ]
  315. },
  316. catalogDataList: [], // 存储遍历后的所有目录列表
  317. templateLoading: false
  318. }
  319. },
  320. computed: {
  321. pageDesignListHasLength () {
  322. return this.pageDesignList?.length > 0
  323. }
  324. },
  325. watch: {
  326. catalogVisible: {
  327. handler (value) {
  328. if (value) {
  329. this.openCascader(this.currentTreeNode)
  330. }
  331. }
  332. }
  333. },
  334. mounted () {
  335. this.getDataList()
  336. this.chooseCatalog()
  337. },
  338. methods: {
  339. // 关闭新增页面菜单的弹窗
  340. closePageMenuDialog () {
  341. this.$refs.pageMenuDialog.dialogVisible = false
  342. },
  343. // 点击新增打开页面菜单弹窗
  344. openPageMenuDialog () {
  345. this.$refs.pageMenuDialog.dialogVisible = true
  346. },
  347. parentCodeChange (code) {
  348. this.catalogData.parentCode = code
  349. },
  350. // 初始化新增目录时选择上级目录
  351. chooseCatalog () {
  352. this.parentNode = this.activePage?.type === 'catalog' ? this.activePage : { code: '0', name: '根目录' }
  353. this.catalogData.parentCode = this.parentNode.code
  354. this.selectName = this.parentNode.name
  355. },
  356. // 点击下拉选项中的树节点选择上级目录树节点
  357. handleNodeClick (node) {
  358. this.$set(this.catalogData, 'parentCode', node.code)
  359. this.selectName = node.name
  360. this.$refs.select.blur() // 点击后关闭下拉框,因为点击树形控件后select不会自动折叠
  361. },
  362. // 获取所有的目录
  363. openCascader (node) {
  364. const excludeCategory = node.type === 'catalog' && !this.isAdd ? node.code : undefined
  365. this.$dataRoomAxios.post('/bigScreen/category/tree', { searchKey: '', typeList: ['catalog'], excludeCategory, sort: false }).then(data => {
  366. const list = [{ name: '根目录', code: '', children: data }]
  367. this.catalogList = list
  368. }).catch(() => {
  369. })
  370. },
  371. // 默认选择第一项
  372. chooseFirstNode () {
  373. this.defaultExpand = []
  374. // 如果存在activePage则将activePage设置为高亮
  375. if (this.activePage && this.activePage.code) {
  376. this.currentNodeCode = this.activePage.code
  377. this.$nextTick(() => {
  378. if (this.$refs.tree) {
  379. this.$refs.tree.setCurrentKey(this.currentNodeCode)
  380. }
  381. })
  382. this.defaultExpand.push(this.currentNodeCode)
  383. this.currentNode = { ...this.activePage }
  384. } else {
  385. // 如果不存在则默认选择第一项(或者是第一个目录的第一项)
  386. if (this.pageDesignList?.length > 0 && !(this.pageDesignList?.length === 1 && this.pageDesignList[0].type === 'catalog' && (!this.pageDesignList[0].children || this.pageDesignList[0].children?.length === 0))) {
  387. const code = this.getDefaultNode(this.pageDesignList)
  388. if (code) {
  389. this.currentNodeCode = code
  390. this.activePage = { ...this.currentNode }
  391. this.defaultExpand.push(code)
  392. this.$nextTick(() => {
  393. this.$refs.tree.setCurrentKey(code)
  394. })
  395. this.isCatalog = false
  396. }
  397. } else {
  398. this.activePage = { code: '', name: '', type: '' }
  399. }
  400. }
  401. },
  402. // 设置默认节点
  403. getDefaultNode (nodeList) {
  404. for (const node of nodeList) {
  405. if (this.flag) {
  406. if (node.children && node.children.length > 0 && node.type === 'catalog') {
  407. return this.getDefaultNode(node.children)
  408. } else if (!(node.children && node.children?.length > 0) && node?.type === 'catalog') {
  409. continue
  410. } else {
  411. this.flag = false
  412. this.currentNode = node
  413. return node.code
  414. }
  415. } else {
  416. return this.currentNode.code
  417. }
  418. }
  419. },
  420. // 左侧菜单图标
  421. pageIconName (data, node) {
  422. if (data.type === 'bigScreen') {
  423. return this.pageIcon[2]
  424. } else {
  425. return node.expanded ? this.pageIcon[1] : this.pageIcon[0]
  426. }
  427. },
  428. // 顶部图标
  429. pageIconImg () {
  430. return this.pageIcon[2]
  431. },
  432. // 树节点查询
  433. filterClick () {
  434. this.$refs.tree.filter(this.searchKey)
  435. },
  436. filterNode (value, data) {
  437. if (!value) return true
  438. return data.name.indexOf(value) !== -1
  439. },
  440. // 预览
  441. gopagePreview (nodeData) {
  442. if (nodeData.code && nodeData.type === 'bigScreen') {
  443. const { href } = this.$router.resolve({
  444. path: window.BS_CONFIG?.routers?.previewUrl || '/big-screen/preview', // 这里写的是要跳转的路由地址
  445. query: {
  446. code: nodeData.code
  447. }
  448. })
  449. window.open(href, '_blank')
  450. } else if (!nodeData.code) {
  451. this.$message.warning('请先选择表单或页面')
  452. }
  453. },
  454. // 点击节点
  455. nodeClick (treeNode, nodeObj, val) {
  456. this.currentTreeNode = treeNode
  457. // 点击的节点为目录,则当前父节点为目录
  458. if (treeNode.type === 'catalog') {
  459. this.parentNode = _.cloneDeep(treeNode)
  460. this.isCatalog = true
  461. } else {
  462. this.isCatalog = false
  463. this.activePage = treeNode
  464. // 点击的节点非目录,则为当前节点的父节点
  465. this.parentNode = (!treeNode.parentCode || treeNode.parentCode === '0') ? { code: '0', name: '根目录' } : _.cloneDeep(nodeObj.parent.data)
  466. }
  467. this.catalogData.parentCode = this.parentNode.code
  468. this.selectName = this.parentNode.name
  469. },
  470. handleClose () {
  471. this.catalogVisible = false
  472. this.$refs.form.clearValidate()
  473. },
  474. // 获取页面的列表(获取,搜索,排序)
  475. getDataList () {
  476. this.pageLoading = true
  477. this.$dataRoomAxios.post('/bigScreen/category/tree', { searchKey: this.searchKey, sort: this.sort }).then(data => {
  478. this.pageDesignList = data
  479. // 如果有addModel这个参数,说明是从页面直接新增过来的,直接进入页面或者表单的填写状态
  480. if (this.$route.query.add) {
  481. this.$refs.AddDialog.init(undefined, this.parentNode, 'form')
  482. }
  483. if (dashBoardPageCode) {
  484. this.$nextTick(() => {
  485. const currentNode = this.findItemBycode(dashBoardPageCode, data)
  486. if (currentNode && currentNode.code) {
  487. this.activePage = currentNode
  488. if (this.$refs.tree) {
  489. this.$refs.tree.setCurrentKey(currentNode)
  490. this.defaultExpand.push(currentNode.code)
  491. }
  492. } else {
  493. this.chooseFirstNode()
  494. }
  495. })
  496. } else {
  497. this.chooseFirstNode()
  498. }
  499. }).catch(() => {
  500. }).finally(() => {
  501. this.pageLoading = false
  502. })
  503. },
  504. // 遍历树节点匹配code
  505. findItemBycode (code, list) {
  506. let node = list.find(item => item.code === code)
  507. if (node) {
  508. return node
  509. } else {
  510. for (let i = 0; i < list?.length; i++) {
  511. if (list[i].children instanceof Array && list[i].children?.length > 0) {
  512. node = this.findItemBycode(code, list[i].children)
  513. if (node) {
  514. return node
  515. }
  516. }
  517. }
  518. return null
  519. }
  520. },
  521. // 对页面进行操作
  522. handleDropdownClick (command, nodeData, node) {
  523. switch (command) {
  524. case 'copy':
  525. this.copyPege(nodeData, node)
  526. break
  527. case 'edit':
  528. this.toEdit(nodeData, node)
  529. break
  530. case 'delete':
  531. this.deletePageDesign(nodeData, node)
  532. break
  533. // case 'code':
  534. // this.code(nodeData, node)
  535. // break
  536. }
  537. },
  538. // code (nodeData, node) {
  539. // axios({
  540. // method: 'get',
  541. // url: `${window.BS_CONFIG.baseUrl}/code/generation/adminPage/${nodeData.code}`,
  542. // headers: {
  543. // },
  544. // // 通过URL传参,后端通过 @RequestParam 注解获取参数
  545. // params: {},
  546. // // 通过body传参,后端通过 @RequestBody 注解获取参数
  547. // data: {},
  548. // withCredentials: false,
  549. // responseType: 'arraybuffer'
  550. // }).then(res => {
  551. // const fileUrl = window.URL.createObjectURL(new Blob([res.data]))
  552. // // 创建超链接
  553. // const fileLink = document.createElement('a')
  554. // fileLink.href = fileUrl
  555. // // 设置下载文件名
  556. // let responseFileName = res.headers.filename
  557. // // 解决中文乱码
  558. // responseFileName = window.decodeURI(responseFileName)
  559. // fileLink.setAttribute('download', responseFileName)
  560. // document.body.appendChild(fileLink)
  561. // // 模拟人工点击下载超链接
  562. // fileLink.click()
  563. // this.submitLoading = false
  564. // // 释放资源
  565. // document.body.removeChild(fileLink)
  566. // window.URL.revokeObjectURL(fileUrl)
  567. // this.step++
  568. // }).catch((error) => {
  569. // this.submitLoading = false
  570. // console.error(error)
  571. // })
  572. // },
  573. // 复制页面
  574. copyPege (nodeData, node) {
  575. this.$dataRoomAxios.post(`/${nodeData.type}/design/copy/${nodeData.code}`).then(() => {
  576. this.getDataList()
  577. })
  578. },
  579. // 新增大屏或新增页面,从空白新建
  580. addNew (parentNode, type) {
  581. this.$refs.AddDialog.init(undefined, this.parentNode, type)
  582. this.flag = true
  583. },
  584. // 大屏 dashboard从模版新建, 使用某个模版新建
  585. useIt (pageTemplateId, parentNode, type) {
  586. this.templateLoading = true
  587. const className = 'com.gccloud.dataroom.core.module.manage.dto.DataRoomPageDTO'
  588. this.$dataRoomAxios.post(`/bigScreen/${type}/design/add/template`, {
  589. pageTemplateId,
  590. parentCode: parentNode.code,
  591. type,
  592. className
  593. }).then((code) => {
  594. const path = window.BS_CONFIG?.routers?.designUrl || '/big-screen/design'
  595. const { href } = this.$router.resolve({
  596. path,
  597. query: {
  598. code: code
  599. }
  600. })
  601. window.open(href, '_self')
  602. }).finally(() => {
  603. this.templateLoading = true
  604. })
  605. },
  606. // 新增页面/表单/目录
  607. addPageDesign (page) {
  608. const type = page.type
  609. const categories = page.categories
  610. if (type !== 'catalog') {
  611. // 如果是大屏,弹出选择模版页面
  612. if (['bigScreen'].includes(type)) {
  613. this.$refs.ChooseTemplateDialog.init(this.parentNode, type)
  614. return
  615. }
  616. this.$refs.AddDialog.init(undefined, this.parentNode, type, categories)
  617. this.flag = true
  618. } else {
  619. // 新增时初始化目录配置
  620. this.catalogData = {
  621. id: '',
  622. code: '',
  623. type: 'catalog',
  624. name: '',
  625. parentCode: this.parentNode.code,
  626. orderNum: 0
  627. }
  628. this.isAdd = true
  629. this.catalogVisible = true
  630. }
  631. },
  632. // 刷新页面
  633. reSearch (treeNode, id) {
  634. this.getDataList()
  635. },
  636. // 编辑
  637. toEdit (nodeData, nodeObj) {
  638. // 编辑目录
  639. if (nodeData.type === 'catalog') {
  640. this.catalogVisible = true
  641. this.catalogData.name = nodeData.name
  642. this.isAdd = false
  643. this.catalogData.id = nodeData.id
  644. this.catalogData.code = nodeData.code
  645. this.catalogData.orderNum = nodeData.orderNum
  646. this.parentNode = (!nodeData.parentCode || nodeData.parentCode === '0') ? { code: '0', name: '根目录' } : _.cloneDeep(nodeObj.parent.data)
  647. this.catalogData.parentCode = this.parentNode.code
  648. this.selectName = this.parentNode.name
  649. } else {
  650. this.$refs.AddDialog.init(nodeData, this.parentNode)
  651. }
  652. },
  653. // 点击新增/编辑目录
  654. addCatalog () {
  655. this.$refs.form.validate(async (valid) => {
  656. if (!valid) {
  657. return
  658. }
  659. if (this.isAdd) {
  660. this.$dataRoomAxios.post('/bigScreen/category/add',
  661. {
  662. ...this.catalogData,
  663. id: '',
  664. code: ''
  665. }).then(data => {
  666. this.catalogVisible = false
  667. this.getDataList()
  668. this.flag = true
  669. // 关闭页面菜单的弹窗
  670. this.closePageMenuDialog()
  671. }).catch(() => {
  672. })
  673. } else {
  674. this.$dataRoomAxios.post('/bigScreen/category/update', { ...this.catalogData, excludeCategory: this.catalogData.code }).then(data => {
  675. this.catalogVisible = false
  676. this.getDataList()
  677. }).catch(() => {
  678. })
  679. }
  680. })
  681. },
  682. // 删除页面设计
  683. deletePageDesign (nodeData, node) {
  684. const type = getPageType(nodeData.type)// 由于类型与接口不统一需要转化一下
  685. const url = type === 'category' ? `/bigScreen/category/delete/${nodeData.code}` : `/bigScreen/${type}/design/delete/${nodeData.code}`// 接口地址
  686. this.$confirm('确定删除该页面设计?', '提示', {
  687. confirmButtonText: '确定',
  688. cancelButtonText: '取消',
  689. type: 'warning',
  690. customClass: 'bs-el-message-box'
  691. }).then(async () => {
  692. this.$dataRoomAxios.post(url).then(() => {
  693. this.$message({
  694. type: 'success',
  695. message: '删除成功'
  696. })
  697. this.flag = true
  698. this.activePage.code = ''
  699. this.chooseFirstNode()
  700. this.$refs.tree.remove(node)
  701. if (nodeData.type === 'catalog' && this.parentCode === nodeData.code) {
  702. this.parentCode = '0'
  703. }
  704. }).catch(() => {
  705. this.$message({
  706. type: 'error',
  707. message: '删除失败!'
  708. })
  709. })
  710. }).catch()
  711. },
  712. // 点击进入页面设计
  713. gopageDesign (nodeData) {
  714. const path = window.BS_CONFIG?.routers?.designUrl || '/big-screen/design'
  715. const openType = nodeData.type === 'report' ? '_blank' : '_self'
  716. const { href } = this.$router.resolve({
  717. path,
  718. query: {
  719. code: nodeData.code
  720. }
  721. })
  722. window.open(href, openType)
  723. }
  724. }
  725. }
  726. </script>
  727. <style lang="scss" scoped>
  728. .page-type-cover {
  729. position: absolute;
  730. top: 0;
  731. left: 16px;
  732. color: #fff;
  733. background: #00000020;
  734. padding: 4px;
  735. font-size: 12px;
  736. }
  737. .page-manage-wrap{
  738. display: flex;
  739. .page-manage-menu{
  740. width: 260px;
  741. border-right: 2px solid #F5F7FA;
  742. .page-manage-menu-search{
  743. display: flex;
  744. align-items: center;
  745. padding: 10px 15px;
  746. box-sizing: border-box;
  747. justify-content: space-around;
  748. .input-with-select{
  749. margin-bottom: 0px;
  750. }
  751. .page-icon{
  752. font-size: 20px;
  753. margin-left: 10px;
  754. color: var(--bs-el-color-primary);
  755. &:hover{
  756. cursor: pointer;
  757. }
  758. }
  759. }
  760. }
  761. .page-manage-menu-list{
  762. width: 100%;
  763. overflow: auto;
  764. height: calc(100vh - 40px - 50px);
  765. .tree-node-name{
  766. width: 170px;
  767. display: inline-block;
  768. overflow: hidden;
  769. white-space: nowrap;
  770. text-overflow: ellipsis;
  771. }
  772. .el-icon-document{
  773. font-size: 16px;
  774. padding: 5px 5px 0 0;
  775. color: #007afe;
  776. }
  777. .el-icon-notebook-1{
  778. font-size: 16px;
  779. padding: 5px 5px 0 0;
  780. color: #50D4FD;
  781. }
  782. .el-icon-folder{
  783. font-size: 16px;
  784. padding: 5px 5px 0 0;
  785. color: #6477FF;
  786. }
  787. .el-icon-folder-opened{
  788. font-size: 16px;
  789. padding: 5px 5px 0 0;
  790. color: #6477FF;
  791. }
  792. }
  793. .page-manage-content{
  794. width: calc(100vw - 260px);
  795. height: calc(100vh - 40px);
  796. .page-manage-content-top{
  797. height: 50px;
  798. width: 100%;
  799. display: flex;
  800. align-items: center;
  801. justify-content: space-between;
  802. padding: 0 20px;
  803. .page-name-icon{
  804. color: var(--bs-el-color-primary);
  805. padding-right: 10px;
  806. }
  807. }
  808. .page-manage-content-body-box{
  809. width: 100%;
  810. height: calc(100vh - 40px - 50px);
  811. background-color: #F5F7FA;
  812. .page-manage-content-body{
  813. height: 100%;
  814. background-color: #fff;
  815. position: relative;
  816. overflow: auto;
  817. overflow-x: hidden;
  818. ::v-deep.el-input__suffix-inner{
  819. /*pointer-events: none!important;*/
  820. }
  821. .preview-wrap{
  822. /*pointer-events: none;*/
  823. width: 100%;
  824. height: 100%;
  825. position: absolute;
  826. .admin-page-wrap {
  827. height: 100%;
  828. background: #F5F7FA;
  829. }
  830. }
  831. .empty-wrap{
  832. position: absolute;
  833. top:50%;
  834. left:50%;
  835. transform: translate(-50%,-50%);
  836. color: #AAAAAA;
  837. }
  838. }
  839. }
  840. }
  841. }
  842. .el-dropdown{
  843. cursor: pointer;
  844. }
  845. .catalog-dialog{
  846. ::v-deep .el-dialog__body{
  847. min-height: 80px;
  848. }
  849. }
  850. .el-icon-delete{
  851. color: #DF2A2A;
  852. }
  853. .el-dropdown-menu--mini .el-dropdown-menu__item i{
  854. padding-top: 6px;
  855. }
  856. .el-dropdown-menu--mini ::v-deep .el-dropdown-menu__item{
  857. display: flex;
  858. min-width: 100px!important;
  859. line-height: 36px;
  860. margin-bottom: 10px;
  861. .page-opt-list-icon{
  862. font-size: 16px;
  863. padding: 10px 5px 0 0;
  864. color: #007afe;
  865. }
  866. .page-dropdown-right{
  867. .page-name{
  868. font-size: 14px;
  869. }
  870. .page-desc{
  871. color: #878A8B;
  872. font-size: 12px;
  873. line-height: 20px;
  874. }
  875. }
  876. }
  877. .menu-span{
  878. width: 100%;
  879. display: flex;
  880. align-items: center;
  881. .el-dropdown{
  882. position: absolute;
  883. right: 10px;
  884. }
  885. }
  886. .disabled{
  887. pointer-events: auto!important;
  888. cursor: not-allowed!important;
  889. }
  890. .page-list-active{
  891. cursor: pointer;
  892. background-color: #F4F4F4;
  893. }
  894. .el-icon-rank{
  895. cursor: move;
  896. }
  897. .active-page-icon{
  898. margin-right: 5px;
  899. }
  900. .sort-icon {
  901. font-size: 20px;
  902. margin-left: 10px;
  903. color: var(--bs-el-color-primary);
  904. &:hover{
  905. cursor: pointer;
  906. }
  907. }
  908. /* 去除tree前面的小三角形*/
  909. .page-list-tree ::v-deep .el-tree-node__content > .el-tree-node__expand-icon{
  910. width: 20px;
  911. opacity: 0 !important;
  912. }
  913. /*选中树节点后*/
  914. .page-list-tree ::v-deep .ztree li a.curSelectedNode span{
  915. color: var(--bs-el-color-primary)!important;
  916. }
  917. #settingDropdown{
  918. display: inline-block;
  919. float: right;
  920. }
  921. ::v-deep .el-tree-node{
  922. line-height: 40px;
  923. .el-tree-node__content{
  924. line-height: 40px;
  925. height: 100%;
  926. }
  927. }
  928. /*当前tree节点激活样式*/
  929. .page-list-tree ::v-deep.is-current>.el-tree-node__content{
  930. background: #007aff10;
  931. color: var(--bs-el-color-primary);
  932. }
  933. .page-list-tree ::v-deep.is-current>.el-tree-node__content::before{
  934. position: absolute;
  935. left: 0;
  936. border-left: 4px solid var(--bs-el-color-primary);
  937. content: "";
  938. height: 40px;
  939. width: 4px;
  940. }
  941. ::v-deep .el-icon-more{
  942. transform: rotate(90deg);
  943. color: #999999;
  944. font-size: 10px;
  945. }
  946. /*滚动条样式*/
  947. ::v-deep ::-webkit-scrollbar {
  948. width: 6px;
  949. border-radius: 4px;
  950. /*height: 4px;*/
  951. }
  952. ::v-deep ::-webkit-scrollbar-thumb {
  953. background: #dddddd !important;
  954. border-radius: 10px;
  955. }
  956. .padding {
  957. padding: 20px;
  958. background: #fff;
  959. }
  960. .catalog-cascader{
  961. width: 100%!important;
  962. }
  963. .delete-item{
  964. color:#ea0b30!important;
  965. }
  966. </style>