Merge branch 'master' of https://gitee.com/y_project/RuoYi-Vue into dev
Conflicts:
ruoyi-admin/src/main/resources/application-prod.yml
ruoyi-generator/src/main/resources/vm/java/controller.java.vm
ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm
ruoyi-ui/src/assets/styles/ruoyi.scss
ruoyi-ui/src/assets/styles/sidebar.scss
ruoyi-ui/src/layout/components/Navbar.vue
ruoyi-ui/src/layout/components/Settings/index.vue
ruoyi-ui/src/layout/components/TagsView/index.vue
ruoyi-ui/src/settings.js
ruoyi-ui/src/store/getters.js
ruoyi-ui/src/store/modules/permission.js
ruoyi-ui/src/store/modules/settings.js
ruoyi-ui/src/store/modules/tagsView.js
ruoyi-ui/src/views/monitor/druid/index.vue
| | |
| | | allow: |
| | | url-pattern: /druid/* |
| | | # æ§å¶å°ç®¡çç¨æ·ååå¯ç |
| | | login-username: admin |
| | | login-username: ruoyi |
| | | login-password: 123456 |
| | | filter: |
| | | stat: |
| | |
| | | public AjaxResult<${ClassName}Vo> export(${ClassName}QueryBo bo) { |
| | | List<${ClassName}Vo> list = i${ClassName}Service.queryList(bo); |
| | | ExcelUtil<${ClassName}Vo> util = new ExcelUtil<${ClassName}Vo>(${ClassName}Vo.class); |
| | | return util.exportExcel(list, "${businessName}" ); |
| | | return util.exportExcel(list, "${businessName}æ°æ®" ); |
| | | } |
| | | |
| | | /** |
| | |
| | | color: #FFFFFF; |
| | | } |
| | | |
| | | /* submenu item */ |
| | | .el-menu--horizontal > .el-submenu .el-submenu__title { |
| | | height: 50px !important; |
| | | line-height: 50px !important; |
| | | } |
| | | |
| | | /* text color */ |
| | | .text-navy { |
| | | color: #1ab394; |
| | |
| | | margin-left: 20px; |
| | | } |
| | | |
| | | .el-submenu__icon-arrow { |
| | | display: none; |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | <template> |
| | | <div> |
| | | <el-upload |
| | | :action="uploadUrl" |
| | | :on-success="handleUploadSuccess" |
| | | :on-error="handleUploadError" |
| | | name="file" |
| | | :show-file-list="false" |
| | | :headers="headers" |
| | | style="display: none" |
| | | ref="upload" |
| | | v-if="this.uploadUrl" |
| | | > |
| | | </el-upload> |
| | | <div class="editor" ref="editor" :style="styles"></div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | |
| | | import "quill/dist/quill.core.css"; |
| | | import "quill/dist/quill.snow.css"; |
| | | import "quill/dist/quill.bubble.css"; |
| | | import { getToken } from "@/utils/auth"; |
| | | |
| | | export default { |
| | | name: "Editor", |
| | |
| | | readOnly: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | /* ä¸ä¼ å°å */ |
| | | uploadUrl: { |
| | | type: String, |
| | | default: "", |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | headers: { |
| | | Authorization: "Bearer " + getToken() |
| | | }, |
| | | Quill: null, |
| | | currentValue: "", |
| | | options: { |
| | |
| | | [{ color: [] }, { background: [] }], // åä½é¢è²ãåä½èæ¯é¢è² |
| | | [{ align: [] }], // 坹齿¹å¼ |
| | | ["clean"], // æ¸
é¤ææ¬æ ¼å¼ |
| | | ["link", "image", "video"] // 龿¥ãå¾çãè§é¢ |
| | | ["link", "image"] // 龿¥ãå¾ç |
| | | ], |
| | | }, |
| | | placeholder: "请è¾å
¥å
容", |
| | |
| | | init() { |
| | | const editor = this.$refs.editor; |
| | | this.Quill = new Quill(editor, this.options); |
| | | // å¦æè®¾ç½®äºä¸ä¼ å°ååèªå®ä¹å¾çä¸ä¼ äºä»¶ |
| | | if (this.uploadUrl) { |
| | | let toolbar = this.Quill.getModule("toolbar"); |
| | | toolbar.addHandler("image", (value) => { |
| | | this.uploadType = "image"; |
| | | if (value) { |
| | | this.$refs.upload.$children[0].$refs.input.click(); |
| | | } else { |
| | | this.quill.format("image", false); |
| | | } |
| | | }); |
| | | toolbar.addHandler("video", (value) => { |
| | | this.uploadType = "video"; |
| | | if (value) { |
| | | this.$refs.upload.$children[0].$refs.input.click(); |
| | | } else { |
| | | this.quill.format("video", false); |
| | | } |
| | | }); |
| | | } |
| | | this.Quill.pasteHTML(this.currentValue); |
| | | this.Quill.on("text-change", (delta, oldDelta, source) => { |
| | | const html = this.$refs.editor.children[0].innerHTML; |
| | |
| | | this.$emit("on-editor-change", eventName, ...args); |
| | | }); |
| | | }, |
| | | handleUploadSuccess(res, file) { |
| | | // è·å坿æ¬ç»ä»¶å®ä¾ |
| | | let quill = this.Quill; |
| | | // 妿ä¸ä¼ æå |
| | | if (res.code == 200) { |
| | | // è·åå
æ æå¨ä½ç½® |
| | | let length = quill.getSelection().index; |
| | | // æå
¥å¾ç res.url为æå¡å¨è¿åçå¾çå°å |
| | | quill.insertEmbed(length, "image", res.url); |
| | | // è°æ´å
æ å°æå |
| | | quill.setSelection(length + 1); |
| | | } else { |
| | | this.$message.error("å¾çæå
¥å¤±è´¥"); |
| | | } |
| | | }, |
| | | handleUploadError() { |
| | | this.$message.error("å¾çæå
¥å¤±è´¥"); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style> |
| | | .editor, .ql-toolbar { |
| | | white-space: pre-wrap!important; |
| | | white-space: pre-wrap !important; |
| | | line-height: normal !important; |
| | | } |
| | | .quill-img { |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-menu |
| | | :default-active="activeMenu" |
| | | mode="horizontal" |
| | | @select="handleSelect" |
| | | > |
| | | <template v-for="(item, index) in topMenus"> |
| | | <el-menu-item :index="item.path" :key="index" v-if="index < visibleNumber" |
| | | ><svg-icon :icon-class="item.meta.icon" /> |
| | | {{ item.meta.title }}</el-menu-item |
| | | > |
| | | </template> |
| | | |
| | | <!-- é¡¶é¨èåè¶
åºæ°éæå --> |
| | | <el-submenu index="more" v-if="topMenus.length > visibleNumber"> |
| | | <template slot="title">æ´å¤èå</template> |
| | | <template v-for="(item, index) in topMenus"> |
| | | <el-menu-item |
| | | :index="item.path" |
| | | :key="index" |
| | | v-if="index >= visibleNumber" |
| | | ><svg-icon :icon-class="item.meta.icon" /> |
| | | {{ item.meta.title }}</el-menu-item |
| | | > |
| | | </template> |
| | | </el-submenu> |
| | | </el-menu> |
| | | </template> |
| | | |
| | | <script> |
| | | import { constantRoutes } from "@/router"; |
| | | |
| | | // ä¸éè¦æ¿æ´»çè·¯ç± |
| | | const noactiveList = ["/user/profile", "/dict/type", "/gen/edit", "/job/log"]; |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | // 顶鍿 åå§æ° |
| | | visibleNumber: 5, |
| | | // æ¯å¦ä¸ºé¦æ¬¡å è½½ |
| | | isFrist: false, |
| | | }; |
| | | }, |
| | | computed: { |
| | | // 顶鍿¾ç¤ºèå |
| | | topMenus() { |
| | | let topMenus = []; |
| | | this.routers.map((menu) => { |
| | | if (menu.hidden !== true) { |
| | | topMenus.push(menu); |
| | | } |
| | | }); |
| | | return topMenus; |
| | | }, |
| | | // ææçè·¯ç±ä¿¡æ¯ |
| | | routers() { |
| | | return this.$store.state.permission.topbarRouters; |
| | | }, |
| | | // 设置åè·¯ç± |
| | | childrenMenus() { |
| | | var childrenMenus = []; |
| | | this.routers.map((router) => { |
| | | for (var item in router.children) { |
| | | if (router.children[item].parentPath === undefined) { |
| | | router.children[item].path = router.path + "/" + router.children[item].path; |
| | | router.children[item].parentPath = router.path; |
| | | } |
| | | childrenMenus.push(router.children[item]); |
| | | } |
| | | }); |
| | | return constantRoutes.concat(childrenMenus); |
| | | }, |
| | | // é»è®¤æ¿æ´»çèå |
| | | activeMenu() { |
| | | const path = this.$route.path; |
| | | let activePath = this.routers[0].path; |
| | | var noactive = noactiveList.some(function (item) { |
| | | return path.indexOf(item) !== -1; |
| | | }); |
| | | if (noactive) { |
| | | return; |
| | | } |
| | | if (path.lastIndexOf("/") > 0) { |
| | | const tmpPath = path.substring(1, path.length); |
| | | activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/")); |
| | | } else if ("/index" == path || "" == path) { |
| | | if (!this.isFrist) { |
| | | this.isFrist = true; |
| | | } else { |
| | | activePath = "index"; |
| | | } |
| | | } |
| | | this.activeRoutes(activePath); |
| | | return activePath; |
| | | }, |
| | | }, |
| | | beforeMount() { |
| | | window.addEventListener('resize', this.setVisibleNumber) |
| | | }, |
| | | beforeDestroy() { |
| | | window.removeEventListener('resize', this.setVisibleNumber) |
| | | }, |
| | | mounted() { |
| | | this.setVisibleNumber(); |
| | | }, |
| | | methods: { |
| | | // æ ¹æ®å®½åº¦è®¡ç®è®¾ç½®æ¾ç¤ºæ æ° |
| | | setVisibleNumber() { |
| | | const width = document.body.getBoundingClientRect().width / 3; |
| | | this.visibleNumber = parseInt(width / 85); |
| | | }, |
| | | // èåéæ©äºä»¶ |
| | | handleSelect(key, keyPath) { |
| | | if (key.indexOf("http://") !== -1 || key.indexOf("https://") !== -1) { |
| | | // http(s):// è·¯å¾æ°çªå£æå¼ |
| | | window.open(key, "_blank"); |
| | | } else { |
| | | this.activeRoutes(key); |
| | | } |
| | | }, |
| | | // å½åæ¿æ´»çè·¯ç± |
| | | activeRoutes(key) { |
| | | var routes = []; |
| | | if (this.childrenMenus && this.childrenMenus.length > 0) { |
| | | this.childrenMenus.map((item) => { |
| | | if (key == item.parentPath || (key == "index" && "" == item.path)) { |
| | | routes.push(item); |
| | | } |
| | | }); |
| | | } |
| | | this.$store.commit("SET_SIDEBAR_ROUTERS", routes); |
| | | } |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .el-menu--horizontal > .el-menu-item { |
| | | float: left; |
| | | height: 50px; |
| | | line-height: 50px; |
| | | margin: 0; |
| | | border-bottom: 3px solid transparent; |
| | | color: #999093; |
| | | padding: 0 5px; |
| | | margin: 0 10px; |
| | | } |
| | | |
| | | .el-menu--horizontal > .el-menu-item.is-active { |
| | | border-bottom: 3px solid #409eff; |
| | | color: #303133; |
| | | } |
| | | </style> |
| | |
| | | <div class="navbar"> |
| | | <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> |
| | | |
| | | <breadcrumb id="breadcrumb-container" class="breadcrumb-container" /> |
| | | <breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav"/> |
| | | <top-nav id="topmenu-container" class="topmenu-container" v-if="topNav"/> |
| | | |
| | | <div class="right-menu"> |
| | | <template v-if="device!=='mobile'"> |
| | |
| | | <script> |
| | | import { mapGetters } from 'vuex' |
| | | import Breadcrumb from '@/components/Breadcrumb' |
| | | import TopNav from '@/components/TopNav' |
| | | import Hamburger from '@/components/Hamburger' |
| | | import Screenfull from '@/components/Screenfull' |
| | | import SizeSelect from '@/components/SizeSelect' |
| | |
| | | export default { |
| | | components: { |
| | | Breadcrumb, |
| | | TopNav, |
| | | Hamburger, |
| | | Screenfull, |
| | | SizeSelect, |
| | |
| | | key: 'showSettings', |
| | | value: val |
| | | }) |
| | | } |
| | | }, |
| | | topNav: { |
| | | get() { |
| | | return this.$store.state.settings.topNav |
| | | } |
| | | } |
| | | }, |
| | |
| | | float: left; |
| | | } |
| | | |
| | | .topmenu-container { |
| | | position: absolute; |
| | | left: 50px; |
| | | } |
| | | |
| | | .errLog-container { |
| | | display: inline-block; |
| | | vertical-align: top; |
| | |
| | | <el-divider/> |
| | | |
| | | <h3 class="drawer-title">ç³»ç»å¸å±é
ç½®</h3> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>å¼å¯ TopNav</span> |
| | | <el-switch v-model="topNav" class="drawer-switch" /> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>å¼å¯ Tags-Views</span> |
| | |
| | | <el-switch v-model="sidebarLogo" class="drawer-switch" /> |
| | | </div> |
| | | |
| | | <el-divider/> |
| | | |
| | | <el-button size="small" type="primary" plain icon="el-icon-document-add" @click="saveSetting">ä¿åé
ç½®</el-button> |
| | | <el-button size="small" plain icon="el-icon-refresh" @click="resetSetting">éç½®é
ç½®</el-button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | export default { |
| | | components: { ThemePicker }, |
| | | data() { |
| | | return {} |
| | | return { |
| | | sideTheme: this.$store.state.settings.sideTheme |
| | | }; |
| | | }, |
| | | computed: { |
| | | theme() { |
| | | return this.$store.state.settings.theme |
| | | }, |
| | | sideTheme() { |
| | | return this.$store.state.settings.sideTheme |
| | | }, |
| | | fixedHeader: { |
| | | get() { |
| | |
| | | key: 'fixedHeader', |
| | | value: val |
| | | }) |
| | | } |
| | | }, |
| | | topNav: { |
| | | get() { |
| | | return this.$store.state.settings.topNav |
| | | }, |
| | | set(val) { |
| | | this.$store.dispatch('settings/changeSetting', { |
| | | key: 'topNav', |
| | | value: val |
| | | }) |
| | | if (!val) { |
| | | this.$store.commit("SET_SIDEBAR_ROUTERS", this.$store.state.permission.defaultRoutes); |
| | | } |
| | | } |
| | | }, |
| | | tagsView: { |
| | |
| | | key: 'sideTheme', |
| | | value: val |
| | | }) |
| | | this.sideTheme = val; |
| | | }, |
| | | saveSetting() { |
| | | const loading = this.$loading({ |
| | | lock: true, |
| | | fullscreen: false, |
| | | text: "æ£å¨ä¿åå°æ¬å°ï¼è¯·ç¨å...", |
| | | spinner: "el-icon-loading", |
| | | background: "rgba(0, 0, 0, 0.7)" |
| | | }); |
| | | localStorage.setItem( |
| | | "layout-setting", |
| | | `{ |
| | | "topNav":${this.topNav}, |
| | | "tagsView":${this.tagsView}, |
| | | "fixedHeader":${this.fixedHeader}, |
| | | "sidebarLogo":${this.sidebarLogo}, |
| | | "sideTheme":"${this.sideTheme}" |
| | | }` |
| | | ); |
| | | setTimeout(loading.close(), 1000) |
| | | }, |
| | | resetSetting() { |
| | | this.$loading({ |
| | | lock: true, |
| | | fullscreen: false, |
| | | text: "æ£å¨æ¸
é¤è®¾ç½®ç¼åå¹¶å·æ°ï¼è¯·ç¨å...", |
| | | spinner: "el-icon-loading", |
| | | background: "rgba(0, 0, 0, 0.7)" |
| | | }); |
| | | localStorage.removeItem("layout-setting") |
| | | setTimeout("window.location.reload()", 1000) |
| | | } |
| | | } |
| | | } |
| | |
| | | <li @click="refreshSelectedTag(selectedTag)">å·æ°é¡µé¢</li> |
| | | <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">å
³éå½å</li> |
| | | <li @click="closeOthersTags">å
³éå
¶ä»</li> |
| | | <li v-if="!isLastView()" @click="closeRightTags">å
³éå³ä¾§</li> |
| | | <li @click="closeAllTags(selectedTag)">å
³éææ</li> |
| | | </ul> |
| | | </div> |
| | |
| | | }, |
| | | isAffix(tag) { |
| | | return tag.meta && tag.meta.affix |
| | | }, |
| | | isLastView() { |
| | | try { |
| | | return this.selectedTag.fullPath === this.visitedViews[this.visitedViews.length - 1].fullPath |
| | | } catch (err) { |
| | | return false |
| | | } |
| | | }, |
| | | filterAffixTags(routes, basePath = '/') { |
| | | let tags = [] |
| | |
| | | } |
| | | }) |
| | | }, |
| | | closeRightTags() { |
| | | this.$store.dispatch('tagsView/delRightTags', this.selectedTag).then(visitedViews => { |
| | | if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) { |
| | | this.toLastView(visitedViews) |
| | | } |
| | | }) |
| | | }, |
| | | closeOthersTags() { |
| | | this.$router.push(this.selectedTag).catch(()=>{}); |
| | | this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => { |
| | |
| | | showSettings: false, |
| | | |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºé¡¶é¨å¯¼èª |
| | | */ |
| | | topNav: false, |
| | | |
| | | /** |
| | | * æ¯å¦æ¾ç¤º tagsView |
| | | */ |
| | | tagsView: true, |
| | |
| | | roles: state => state.user.roles, |
| | | permissions: state => state.user.permissions, |
| | | permission_routes: state => state.permission.routes, |
| | | topbarRouters:state => state.permission.topbarRouters, |
| | | defaultRoutes:state => state.permission.defaultRoutes, |
| | | sidebarRouters:state => state.permission.sidebarRouters, |
| | | } |
| | | export default getters |
| | |
| | | state: { |
| | | routes: [], |
| | | addRoutes: [], |
| | | defaultRoutes: [], |
| | | topbarRouters: [], |
| | | sidebarRouters: [] |
| | | }, |
| | | mutations: { |
| | |
| | | state.addRoutes = routes |
| | | state.routes = constantRoutes.concat(routes) |
| | | }, |
| | | SET_SIDEBAR_ROUTERS: (state, routers) => { |
| | | state.sidebarRouters = constantRoutes.concat(routers) |
| | | SET_DEFAULT_ROUTES: (state, routes) => { |
| | | state.defaultRoutes = constantRoutes.concat(routes) |
| | | }, |
| | | SET_TOPBAR_ROUTES: (state, routes) => { |
| | | // é¡¶é¨å¯¼èªèåé»è®¤æ·»å ç»è®¡æ¥è¡¨æ æåé¦é¡µ |
| | | const index = [{ |
| | | path: 'index', |
| | | meta: { title: 'ç»è®¡æ¥è¡¨', icon: 'dashboard'} |
| | | }] |
| | | state.topbarRouters = routes.concat(index); |
| | | }, |
| | | SET_SIDEBAR_ROUTERS: (state, routes) => { |
| | | state.sidebarRouters = routes |
| | | }, |
| | | }, |
| | | actions: { |
| | |
| | | const rewriteRoutes = filterAsyncRouter(rdata, false, true) |
| | | rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true }) |
| | | commit('SET_ROUTES', rewriteRoutes) |
| | | commit('SET_SIDEBAR_ROUTERS', sidebarRoutes) |
| | | commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes)) |
| | | commit('SET_DEFAULT_ROUTES', sidebarRoutes) |
| | | commit('SET_TOPBAR_ROUTES', sidebarRoutes) |
| | | resolve(rewriteRoutes) |
| | | }) |
| | | }) |
| | |
| | | import variables from '@/assets/styles/element-variables.scss' |
| | | import defaultSettings from '@/settings' |
| | | |
| | | const { sideTheme, showSettings, tagsView, fixedHeader, sidebarLogo } = defaultSettings |
| | | const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo } = defaultSettings |
| | | |
| | | const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || '' |
| | | const state = { |
| | | theme: variables.theme, |
| | | sideTheme: sideTheme, |
| | | sideTheme: storageSetting.sideTheme || sideTheme, |
| | | showSettings: showSettings, |
| | | tagsView: tagsView, |
| | | fixedHeader: fixedHeader, |
| | | sidebarLogo: sidebarLogo |
| | | topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav, |
| | | tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView, |
| | | fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader, |
| | | sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo |
| | | } |
| | | |
| | | const mutations = { |
| | | CHANGE_SETTING: (state, { key, value }) => { |
| | | if (state.hasOwnProperty(key)) { |
| | |
| | | break |
| | | } |
| | | } |
| | | }, |
| | | |
| | | DEL_RIGHT_VIEWS: (state, view) => { |
| | | const index = state.visitedViews.findIndex(v => v.path === view.path) |
| | | if (index === -1) { |
| | | return |
| | | } |
| | | state.visitedViews = state.visitedViews.filter((item, idx) => { |
| | | if (idx <= index || (item.meta && item.meta.affix)) { |
| | | return true |
| | | } |
| | | const i = state.cachedViews.indexOf(item.name) |
| | | if (i > -1) { |
| | | state.cachedViews.splice(i, 1) |
| | | } |
| | | return false |
| | | }) |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | updateVisitedView({ commit }, view) { |
| | | commit('UPDATE_VISITED_VIEW', view) |
| | | }, |
| | | |
| | | delRightTags({ commit }, view) { |
| | | return new Promise(resolve => { |
| | | commit('DEL_RIGHT_VIEWS', view) |
| | | resolve([...state.visitedViews]) |
| | | }) |
| | | } |
| | | } |
| | | |
| | |
| | | var search = params; |
| | | search.params = {}; |
| | | if (null != dateRange && '' != dateRange) { |
| | | if (typeof(propName) === "undefined") { |
| | | if (typeof (propName) === "undefined") { |
| | | search.params["beginTime"] = dateRange[0]; |
| | | search.params["endTime"] = dateRange[1]; |
| | | } else { |
| | |
| | | * @param {*} id idåæ®µ é»è®¤ 'id' |
| | | * @param {*} parentId ç¶èç¹å段 é»è®¤ 'parentId' |
| | | * @param {*} children å©åèç¹å段 é»è®¤ 'children' |
| | | * @param {*} rootId æ ¹Id é»è®¤ 0 |
| | | */ |
| | | export function handleTree(data, id, parentId, children, rootId) { |
| | | id = id || 'id' |
| | | parentId = parentId || 'parentId' |
| | | children = children || 'children' |
| | | rootId = rootId || Math.min.apply(Math, data.map(item => { return item[parentId] })) || 0 |
| | | //å¯¹æºæ°æ®æ·±åº¦å
é |
| | | const cloneData = JSON.parse(JSON.stringify(data)) |
| | | //å¾ªç¯ææé¡¹ |
| | | const treeData = cloneData.filter(father => { |
| | | let branchArr = cloneData.filter(child => { |
| | | //è¿åæ¯ä¸é¡¹çå级æ°ç» |
| | | return father[id] === child[parentId] |
| | | }); |
| | | branchArr.length > 0 ? father.children = branchArr : ''; |
| | | //è¿å第ä¸å± |
| | | return father[parentId] === rootId; |
| | | }); |
| | | return treeData != '' ? treeData : data; |
| | | export function handleTree(data, id, parentId, children) { |
| | | let config = { |
| | | id: id || 'id', |
| | | parentId: parentId || 'parentId', |
| | | childrenList: children || 'children' |
| | | }; |
| | | |
| | | var childrenListMap = {}; |
| | | var nodeIds = {}; |
| | | var tree = []; |
| | | |
| | | for (let d of data) { |
| | | let parentId = d[config.parentId]; |
| | | if (childrenListMap[parentId] == null) { |
| | | childrenListMap[parentId] = []; |
| | | } |
| | | nodeIds[d[config.id]] = d; |
| | | childrenListMap[parentId].push(d); |
| | | } |
| | | |
| | | for (let d of data) { |
| | | let parentId = d[config.parentId]; |
| | | if (nodeIds[parentId] == null) { |
| | | tree.push(d); |
| | | } |
| | | } |
| | | |
| | | for (let t of tree) { |
| | | adaptToChildrenList(t); |
| | | } |
| | | |
| | | function adaptToChildrenList(o) { |
| | | if (childrenListMap[o[config.id]] !== null) { |
| | | o[config.childrenList] = childrenListMap[o[config.id]]; |
| | | } |
| | | if (o[config.childrenList]) { |
| | | for (let c of o[config.childrenList]) { |
| | | adaptToChildrenList(c); |
| | | } |
| | | } |
| | | } |
| | | return tree; |
| | | } |
| | |
| | | name: "Druid", |
| | | data() { |
| | | return { |
| | | src: process.env.VUE_APP_BASE_API + "/druid/index.html", |
| | | src: process.env.VUE_APP_BASE_API + "/druid/login.html", |
| | | height: document.documentElement.clientHeight - 94.5 + "px;", |
| | | loading: true |
| | | }; |