index.vue 28 KB

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