index.vue 28 KB

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