houzhongjian
2024-11-08 c4b4ee6c0a1352ec887ebe54170e1ac7a9a8514b
提交文档管理平台代码
已添加31个文件
27061 ■■■■■ 文件已修改
iailab-doc-ui/console-ui/.editorconfig 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/.env.development 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/.env.production 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/.gitignore 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/README.md 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/babel.config.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/package-lock.json 16191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/package.json 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/public/favicon-console.png 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/public/index.html 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/App.vue 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/assets/img/dubbo.png 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/common/api/console.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/common/api/request.js 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/common/api/system.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/components/layouts/PageTableView.vue 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/main.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/routes.js 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/store/index.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/store/modules/global.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/views/common/AboutDialog.vue 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/views/common/NoAuth.vue 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/views/console/AuthList.vue 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/views/console/RoleList.vue 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/views/console/UserGroupList.vue 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/views/console/UserList.vue 247 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/views/home/Home.vue 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/views/user/Login.vue 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/src/views/user/MyInfo.vue 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/vue.config.js 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/yarn.lock 9149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-doc-ui/console-ui/.editorconfig
对比新文件
@@ -0,0 +1,13 @@
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = tab
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false
iailab-doc-ui/console-ui/.env.development
对比新文件
@@ -0,0 +1,12 @@
# 开发环境
ENV = 'development'
# base api
VUE_APP_BASE_API = 'http://localhost:8083/zyplayer-doc'
# VUE_APP_BASE_API = 'http://zyplayer.com'
VUE_CLI_BABEL_TRANSPILE_MODULES = true
iailab-doc-ui/console-ui/.env.production
对比新文件
@@ -0,0 +1,7 @@
# 线上环境
ENV = 'production'
# base api
#VUE_APP_BASE_API = '/'
# base api
VUE_APP_BASE_API = 'http://localhost:8083/zyplayer-doc'
iailab-doc-ui/console-ui/.gitignore
对比新文件
@@ -0,0 +1,21 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
iailab-doc-ui/console-ui/README.md
对比新文件
@@ -0,0 +1,42 @@
# zyplayer-doc-manage项目的UI
## 常见问题
1、命令行要进入这个文件夹才能执行命令:
zyplayer-doc/zyplayer-doc-ui/console-ui
2、修改host,否则run不起来:
在文件 C:\Windows\System32\drivers\etc\hosts 末尾增加:
127.0.0.1 local.zyplayer.com
## 配置文件
配置开发环境和线上环境的请求域名地址:
开发环境:.env.development
线上环境:.env.production
## 环境要求
`Node >= 6`
## 开始
执行下面的命令安装项目依赖
``` bash
npm install
```
## 开发环境
执行下面的命令启动前端工程
``` bash
npm run dev
```
## 打包
执行下面的命令编译打包前端页面
``` bash
npm run build
```
打包会自动将打包的文件放到项目的resource文件夹下
iailab-doc-ui/console-ui/babel.config.js
对比新文件
@@ -0,0 +1,5 @@
module.exports = {
    presets: [
        '@vue/cli-plugin-babel/preset'
    ]
};
iailab-doc-ui/console-ui/package-lock.json
对比新文件
文件太大
iailab-doc-ui/console-ui/package.json
对比新文件
@@ -0,0 +1,42 @@
{
    "name": "zyplayer-console-ui",
    "version": "0.1.0",
    "private": true,
    "scripts": {
        "dev": "vue-cli-service serve --mode development",
        "build": "vue-cli-service build --mode production"
    },
    "dependencies": {
        "@icon-park/vue": "^1.2.6",
        "axios": "^0.19.0",
        "connect-history-api-fallback": "^2.0.0",
        "core-js": "^3.3.2",
        "echarts": "^4.5.0",
        "element-ui": "^2.15.0",
        "js-cookie": "^2.2.1",
        "pouchdb": "^7.1.1",
        "sql-formatter": "^2.3.3",
        "vue": "^2.6.10",
        "vue-axios": "^2.1.5",
        "vue-hljs": "^1.1.2",
        "vue-router": "^3.1.3",
        "vuex": "^3.1.2",
        "wangeditor": "^3.1.1"
    },
    "devDependencies": {
        "@vue/cli-plugin-babel": "^4.0.0",
        "@vue/cli-service": "^4.0.0",
        "less": "^3.10.3",
        "less-loader": "^5.0.0",
        "vue-template-compiler": "^2.6.10"
    },
    "postcss": {
        "plugins": {
            "autoprefixer": {}
        }
    },
    "browserslist": [
        "> 1%",
        "last 2 versions"
    ]
}
iailab-doc-ui/console-ui/public/favicon-console.png
iailab-doc-ui/console-ui/public/index.html
对比新文件
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon-console.png">
    <title>文档管理系统</title>
</head>
<body>
<noscript>
    <strong>We're sorry but zyplayer-console-ui doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
iailab-doc-ui/console-ui/src/App.vue
对比新文件
@@ -0,0 +1,138 @@
<template>
    <div id="app">
        <template v-if="fullscreen">
            <router-view @loginSuccess="getSelfUserInfo"></router-view>
        </template>
        <el-container v-else>
            <el-aside>
                <div class="menu-box">
                    <el-menu default-active="1-4-1" :router="true" class="el-menu-vertical" @open="handleOpen" @close="handleClose" :collapse="isCollapse">
                        <el-menu-item index="/"><i class="el-icon-s-home"></i>控制台</el-menu-item>
                        <el-submenu index="1" v-if="userAuth.userManage">
                            <template slot="title">
                                <i class="el-icon-s-platform"></i>
                                <span slot="title">系统管理</span>
                            </template>
                            <el-menu-item index="/console/userList">
                                <people theme="filled" size="16" fill="#909399"></people>
                                <span>用户管理</span>
                            </el-menu-item>
                            <el-menu-item index="/console/userGroupList">
                                <peoples theme="filled" size="16" fill="#909399"></peoples>
                                <span>分组管理</span>
                            </el-menu-item>
                        </el-submenu>
                    </el-menu>
                </div>
            </el-aside>
            <el-container>
                <el-header>
                    <span class="header-right-user-name">{{userSelfInfo.userName}}</span>
                    <el-dropdown @command="userSettingDropdown" trigger="click">
                        <i class="el-icon-setting" style="margin-right: 15px; font-size: 16px;cursor: pointer;color: #fff;"> </i>
                        <el-dropdown-menu slot="dropdown">
                            <el-dropdown-item command="console">控制台</el-dropdown-item>
                            <el-dropdown-item command="aboutDoc" divided>关于</el-dropdown-item>
                            <el-dropdown-item command="myInfo">我的资料</el-dropdown-item>
                            <el-dropdown-item command="userSignOut">退出登录</el-dropdown-item>
                        </el-dropdown-menu>
                    </el-dropdown>
                </el-header>
                <el-main style="padding: 0;">
                    <router-view></router-view>
                </el-main>
            </el-container>
        </el-container>
        <about-dialog ref="aboutDialog"></about-dialog>
    </div>
</template>
<script>
    import consoleApi from './common/api/console'
    import {Peoples, People} from '@icon-park/vue';
    import aboutDialog from './views/common/AboutDialog'
    export default {
        data() {
            return {
                isCollapse: false,
                userSelfInfo: {},
                userAuth: {
                    userManage: false
                },
            }
        },
        components: {
            "peoples": Peoples,
            "people": People,
            'about-dialog': aboutDialog
        },
        computed: {
            fullscreen () {
                return this.$store.state.global.fullscreen;
            }
        },
        mounted() {
            this.getSelfUserInfo();
        },
        methods: {
            handleOpen(key, keyPath) {
                console.log(key, keyPath);
            },
            handleClose(key, keyPath) {
                console.log(key, keyPath);
            },
            userSettingDropdown(command) {
                console.log("command:" + command);
                if (command == 'userSignOut') {
                    this.userSignOut();
                } else if (command == 'aboutDoc') {
                    this.$refs.aboutDialog.show();
                } else if (command == 'myInfo') {
                    this.$router.push({path: '/user/myInfo'});
                } else if (command == 'console') {
                    window.open(process.env.VUE_APP_BASE_API, '_blank');
                } else {
                    this.$message.warn("功能暂未开放");
                }
            },
            userSignOut() {
                consoleApi.userLogout().then(() => {
                    location.reload();
                }).catch(e => {
                    console.log("退出登录失败", e);
                });
            },
            getSelfUserInfo() {
                consoleApi.selfInfoWithAuth().then(json => {
                    let infoVo = json.data || {};
                    this.userSelfInfo = infoVo.userInfo || {};
                    this.userAuth = infoVo.userAuth || {};
                }).catch(e => {
                    console.log("获取用户信息失败", e);
                });
            },
        }
    }
</script>
<style>
    html, body {
        margin: 0;
        padding: 0;
        height: 100%;
    }
    #app, .el-container, .el-menu {
        height: 100%;
    }
    .el-header {
        background-color: #1D4E89 !important;
    }
    .header-right-user-name{color: #fff;padding-right: 5px;}
    .el-menu-vertical{border-right: 0;background: #fafafa;}
    .el-menu-vertical .el-menu{background: #fafafa;}
    .el-header {background-color: #409EFF; color: #333; line-height: 40px; text-align: right;height: 40px !important;}
    .menu-box{padding: 10px;height: 100%;box-sizing: border-box;background: #fafafa;}
    .menu-box .i-icon{line-height: 1;margin-right: 5px;}
</style>
iailab-doc-ui/console-ui/src/assets/img/dubbo.png
iailab-doc-ui/console-ui/src/common/api/console.js
对比新文件
@@ -0,0 +1,59 @@
import Qs from 'qs'
import request from './request'
export default {
    userLogin: data => {
        return request({url: '/login', method: 'post', data: Qs.stringify(data)});
    },
    userLogout: data => {
        return request({url: '/logout', method: 'post', data: Qs.stringify(data)});
    },
    getSelfUserInfo: data => {
        return request({url: '/user/info/selfInfo', method: 'post', data: Qs.stringify(data)});
    },
    updateSelfPwd: data => {
        return request({url: '/user/info/updateSelfPwd', method: 'post', data: Qs.stringify(data)});
    },
    selfInfoWithAuth: data => {
        return request({url: '/user/info/selfInfoWithAuth', method: 'post', data: Qs.stringify(data)});
    },
    getUserInfoList: data => {
        return request({url: '/user/info/list', method: 'post', data: Qs.stringify(data)});
    },
    searchUserInfoList: data => {
        return request({url: '/user/info/search', method: 'post', data: Qs.stringify(data)});
    },
    updateUserInfo: data => {
        return request({url: '/user/info/update', method: 'post', data: Qs.stringify(data)});
    },
    deleteUserInfo: data => {
        return request({url: '/user/info/delete', method: 'post', data: Qs.stringify(data)});
    },
    userAuthList: data => {
        return request({url: '/user/info/auth/list', method: 'post', data: Qs.stringify(data)});
    },
    updateUserAuth: data => {
        return request({url: '/user/info/auth/update', method: 'post', data: Qs.stringify(data)});
    },
    resetPassword: data => {
        return request({url: '/user/info/resetPassword', method: 'post', data: Qs.stringify(data)});
    },
    userGroupList: data => {
        return request({url: '/user/group/list', method: 'post', data: Qs.stringify(data)});
    },
    updateUserGroup: data => {
        return request({url: '/user/group/update', method: 'post', data: Qs.stringify(data)});
    },
    deleteUserGroup: data => {
        return request({url: '/user/group/delete', method: 'post', data: Qs.stringify(data)});
    },
    updateUserGroupRelation: data => {
        return request({url: '/user/group/relation/update', method: 'post', data: Qs.stringify(data)});
    },
    removeUserGroupRelation: data => {
        return request({url: '/user/group/relation/remove', method: 'post', data: Qs.stringify(data)});
    },
    userGroupRelationList: data => {
        return request({url: '/user/group/relation/list', method: 'post', data: Qs.stringify(data)});
    },
};
iailab-doc-ui/console-ui/src/common/api/request.js
对比新文件
@@ -0,0 +1,70 @@
import axios from 'axios'
import vue from '../../main'
const service = axios.create({
    baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url process.env.APP_BASE_API
    timeout: 10000,
    headers: {'Content-type': 'application/x-www-form-urlencoded'},
    withCredentials: true
});
// 增加不需要验证结果的标记
const noValidate = {
    "/zyplayer-doc-db/executor/execute": true,
    "/zyplayer-doc-db/datasource/test": true,
};
let lastToastLoginTime = 0;
service.interceptors.request.use(
    config => {
        config.needValidateResult = true;
        // 增加不需要验证结果的标记
        if (noValidate[config.url]) {
            config.needValidateResult = false;
        }
        return config
    },
    error => {
        console.log(error);
        return Promise.reject(error);
    }
);
service.interceptors.response.use(
    response => {
        if (!!response.message) {
            vue.$message.error('请求错误:' + response.message);
        }else {
            if (!response.config.needValidateResult || response.data.errCode == 200) {
                return response.data;
            } else if (response.data.errCode == 400) {
                // 一秒钟只提示一次
                if (new Date().getTime() - lastToastLoginTime > 1000) {
                    vue.$message.error('请先登录');
                    lastToastLoginTime = new Date().getTime();
                }
                let redirectUrl = '';
                let locationHref = window.location.href;
                if (locationHref.indexOf("?") >= 0) {
                    let reg = new RegExp("(^|&)redirect=([^&]*)(&|$)", "i");
                    let r = locationHref.substring(locationHref.indexOf("?") + 1).match(reg);
                    if (r != null) {
                        redirectUrl = unescape(r[2]);
                    }
                }
                redirectUrl = redirectUrl || encodeURIComponent(window.location.href);
                vue.$router.push({path: '/user/login', query: {redirect: redirectUrl}});
            } else if (response.data.errCode == 402) {
                vue.$router.push("/common/noAuth");
            } else if (response.data.errCode !== 200) {
                vue.$message.error(response.data.errMsg || "未知错误");
            }
        }
        return Promise.reject('请求错误');
    },
    error => {
        console.log('err' + error);
        vue.$message.info('请求错误:' + error.message);
        return Promise.reject(error)
    }
);
export default service;
iailab-doc-ui/console-ui/src/common/api/system.js
对比新文件
@@ -0,0 +1,11 @@
import Qs from 'qs'
import request from './request'
export default {
    systemUpgradeInfo: data => {
        return request({url: '/system/info/upgrade', method: 'post', data: Qs.stringify(data)});
    },
    fetchMoudleData: data => {
        return request({url: '/system/info/module', method: 'get', data: Qs.stringify(data)});
    }
};
iailab-doc-ui/console-ui/src/components/layouts/PageTableView.vue
对比新文件
@@ -0,0 +1,76 @@
<template>
    <div>
        <el-tabs v-model="activePage" type="card" closable @tab-click="changePage" @tab-remove="removePageTab" style="padding: 5px 10px 0;">
            <el-tab-pane :label="pageTabNameMap[item.fullPath]||item.name" :name="item.fullPath" v-for="item in pageList"/>
        </el-tabs>
        <keep-alive>
            <router-view :key="$route.fullPath" @initLoadDataList="initLoadDataList" @loadDatasourceList="loadDatasourceList"/>
        </keep-alive>
    </div>
</template>
<script>
    export default {
        name: 'PageTableView',
        components: {},
        data() {
            return {
                pageList: [],
                linkList: [],
                activePage: '',
                multiPage: true,
            }
        },
        computed: {
            pageTabNameMap () {
                return this.$store.state.global.pageTabNameMap;
            }
        },
        created() {
            this.pageList.push(this.$route);
            this.linkList.push(this.$route.fullPath);
            this.activePage = this.$route.fullPath;
        },
        watch: {
            '$route': function (newRoute, oldRoute) {
                this.activePage = newRoute.fullPath;
                if (this.linkList.indexOf(newRoute.fullPath) < 0) {
                    this.linkList.push(newRoute.fullPath);
                    this.pageList.push(newRoute);
                }
            },
            'activePage': function (key) {
                this.$router.push(key)
            },
        },
        methods: {
            initLoadDataList(param) {
                this.$emit('initLoadDataList', param);
            },
            loadDatasourceList() {
                this.$emit('loadDatasourceList');
            },
            changePage(key) {
                this.activePage = key.name;
            },
            editPage(key, action) {
                this[action](key);
            },
            removePageTab(key) {
                if (this.pageList.length === 1) {
                    this.$message.warning('这是最后一页,不能再关闭了啦');
                    return
                }
                this.pageList = this.pageList.filter(item => item.fullPath !== key);
                let index = this.linkList.indexOf(key);
                this.linkList = this.linkList.filter(item => item !== key);
                index = index >= this.linkList.length ? this.linkList.length - 1 : index;
                this.activePage = this.linkList[index];
            },
        }
    }
</script>
<style scoped>
</style>
iailab-doc-ui/console-ui/src/main.js
对比新文件
@@ -0,0 +1,46 @@
import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import App from './App.vue'
import VueRouter from 'vue-router'
import routes from './routes'
import store from './store/index'
import axios from 'axios'
import VueAxios from 'vue-axios'
import vueHljs from "vue-hljs";
import "vue-hljs/dist/vue-hljs.min.css";
Vue.use(ElementUI);
Vue.use(VueRouter);
Vue.use(VueAxios, axios);
Vue.use(vueHljs);
// 公用方法
Vue.prototype.$store = store;
const router = new VueRouter({
    mode: 'hash',
    routes,
});
// 路由跳转时判断处理
router.beforeEach((to, from, next) => {
    if (to.meta.title) {
        document.title = to.meta.title;
    }
    store.commit('global/setFullscreen', !!to.meta.fullscreen);
    next();
});
let vue = new Vue({
    el: '#app',
    router,
    render(h) {
        return h(App);
    }
});
export default vue;
iailab-doc-ui/console-ui/src/routes.js
对比新文件
@@ -0,0 +1,55 @@
import PageTableView from './components/layouts/PageTableView.vue'
import Home from './views/home/Home.vue'
import MyInfo from './views/user/MyInfo.vue'
import Login from './views/user/Login.vue'
import UserList from './views/console/UserList.vue'
import AuthList from './views/console/AuthList.vue'
import RoleList from './views/console/RoleList.vue'
import UserGroupList from './views/console/UserGroupList.vue'
import NoAuth from './views/common/NoAuth.vue'
let routes = [
    {path: '/', redirect: '/home'},
    {
        path: '/user/login',
        name: '系统登录',
        component: Login,
        meta: {fullscreen: true}
    }, {
        path: '/',
        name: '页面管理',
        component: PageTableView,
        children: [
            {path: '/home', name: '控制台', component: Home},
        ]
    }, {
        path: '/user',
        name: '用户管理',
        component: PageTableView,
        children: [
            {path: 'myInfo', name: '我的信息', component: MyInfo},
        ]
    }, {
        path: '/console',
        name: '系统管理',
        component: PageTableView,
        children: [
            {path: 'userList', name: '用户管理', component: UserList},
            {path: 'roleList', name: '权限管理', component: AuthList},
            {path: 'authList', name: '角色列表', component: RoleList},
            {path: 'userGroupList', name: '分组管理', component: UserGroupList},
        ]
    }, {
        path: '/common',
        name: '',
        component: PageTableView,
        children: [
            {path: 'noAuth', name: '没有权限', component: NoAuth},
        ]
    },
];
export default routes;
iailab-doc-ui/console-ui/src/store/index.js
对比新文件
@@ -0,0 +1,11 @@
import Vue from 'vue'
import Vuex from 'vuex'
import global from './modules/global'
Vue.use(Vuex);
export default new Vuex.Store({
    modules: {
        global,
    }
});
iailab-doc-ui/console-ui/src/store/modules/global.js
对比新文件
@@ -0,0 +1,22 @@
export default {
    namespaced: true,
    state: {
        pageTabNameMap: {},
        fullscreen: false,
    },
    getters: {
        getPageTabNameMap(state) {
            return state.pageTabNameMap;
        },
    },
    mutations: {
        addTableName(state, item) {
            let sameObj = Object.assign({}, state.pageTabNameMap);
            sameObj[item.key] = item.val;
            state.pageTabNameMap = sameObj;
        },
        setFullscreen(state, val) {
            state.fullscreen = val;
        },
    }
}
iailab-doc-ui/console-ui/src/views/common/AboutDialog.vue
对比新文件
@@ -0,0 +1,55 @@
<template>
    <!--关于弹窗-->
    <el-dialog title="关于" :visible.sync="aboutDialogVisible" width="600px" custom-class="about-zyplayer-doc">
        <div style="">
            <div style="font-weight: bold;font-size: 25px;">zyplayer-doc</div>
            <div style="line-height: 30px;padding: 10px 0;">
                <div style="margin-bottom: 30px;">专注于私有化部署的在线知识库管理平台</div>
                <div>当前版本 {{upgradeInfo.nowVersion || '1.0.0'}}</div>
                <div>版权所有 © 2018-2023 <a target="_blank" href="https://doc.zyplayer.com">doc.zyplayer.com</a></div>
            </div>
        </div>
    </el-dialog>
</template>
<script>
    import systemApi from "../../common/api/system";
    export default {
        data() {
            return {
                aboutDialogVisible: false,
                upgradeInfo: {},
            };
        },
        mounted() {
            this.checkSystemUpgrade();
        },
        methods: {
            show() {
                this.aboutDialogVisible = true;
            },
            checkSystemUpgrade() {
                systemApi.systemUpgradeInfo({}).then(json => {
                    if (!!json.data) {
                        this.upgradeInfo = json.data;
                        if (!!this.upgradeInfo.upgradeContent) {
                            this.upgradeInfo.upgradeContent = this.upgradeInfo.upgradeContent.replaceAll(';', '\n');
                        }
                        console.log("zyplayer-doc发现新版本:"
                                + "\n升级地址:" + json.data.upgradeUrl
                                + "\n当前版本:" + json.data.nowVersion
                                + "\n最新版本:" + json.data.lastVersion
                                + "\n升级内容:" + json.data.upgradeContent
                        );
                    }
                });
            },
        }
    }
</script>
<style>
    .about-zyplayer-doc{text-align: left; line-height: normal;}
    .about-zyplayer-doc .el-dialog__body{padding: 20px;}
</style>
iailab-doc-ui/console-ui/src/views/common/NoAuth.vue
对比新文件
@@ -0,0 +1,18 @@
<template>
    <div>没有权限访问该模块</div>
</template>
<script>
    export default {
        data() {
            return {};
        },
        mounted: function () {
        },
        methods: {}
    }
</script>
<style>
</style>
iailab-doc-ui/console-ui/src/views/console/AuthList.vue
对比新文件
@@ -0,0 +1,71 @@
<template>
    <div>
        <div style="border-bottom: 1px solid #eee;padding: 10px;margin-bottom: 10px;">权限列表</div>
        <div style="padding: 10px;">
            <el-table :data="searchResultList" border style="width: 100%; margin-bottom: 5px;" max-height="500">
                <el-table-column prop="id" label="编号" width="60"></el-table-column>
                <el-table-column prop="name" label="权限名"></el-table-column>
                <el-table-column prop="spaceExplain" label="权限说明"></el-table-column>
                <el-table-column prop="createTime" label="创建时间"></el-table-column>
            </el-table>
        </div>
        <div class="page-info-box">
            <el-pagination
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                    :page-sizes="[20, 50, 100]"
                    :page-size="20"
                    :current-page="searchParam.pageNum"
                    layout="prev, pager, next, jumper, sizes, total"
                    :total="totalCount"
            >
            </el-pagination>
        </div>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                editUserDialogVisible: false,
                totalCount: 0,
                searchParam: {
                    type: 1,
                    keyword: '',
                    pageSize: 20,
                    pageNum: 1,
                },
                searchResultList: [
                    {name: '张三'}
                ],
                roleOptions: [
                    {value: '管理员'}
                ],
                editUserForm: {},
            };
        },
        mounted: function () {
        },
        methods: {
            handleSizeChange(val) {
                this.searchParam.pageSize = val;
            },
            handleCurrentChange(val) {
                this.searchParam.pageNum = val;
            },
            editUserInfo() {
                this.editUserDialogVisible = true;
            },
            resetPassword() {
            },
        }
    }
</script>
<style>
    .search-form-box{padding: 10px;}
    .page-info-box{text-align: right;margin: 20px 0 50px 0;}
</style>
iailab-doc-ui/console-ui/src/views/console/RoleList.vue
对比新文件
@@ -0,0 +1,123 @@
<template>
    <div>
        <div style="border-bottom: 1px solid #eee;padding: 10px;margin-bottom: 10px;">角色管理</div>
        <el-form :inline="true" :model="searchParam" class="search-form-box">
            <el-form-item label="搜索类型">
                <el-select v-model="searchParam.type" placeholder="请选择">
                    <el-option label="角色名" :value="1"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item label="关键字">
                <el-input v-model="searchParam.keyword" placeholder="输入关键字"></el-input>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="">查询</el-button>
            </el-form-item>
        </el-form>
        <div style="padding: 10px;">
            <el-table :data="searchResultList" border style="width: 100%; margin-bottom: 5px;" max-height="500">
                <el-table-column prop="id" label="编号" width="60"></el-table-column>
                <el-table-column prop="name" label="角色名"></el-table-column>
                <el-table-column prop="spaceExplain" label="CODE"></el-table-column>
                <el-table-column prop="createTime" label="创建时间"></el-table-column>
                <el-table-column label="操作">
                    <template slot-scope="scope">
                        <el-button size="small" plain type="primary" v-on:click="editUserInfo(scope.row)">修改</el-button>
                        <el-button size="small" plain type="primary" v-on:click="resetPassword(scope.row)">权限管理</el-button>
                        <el-button size="small" plain type="warning" v-on:click="editUserInfo(scope.row)">删除</el-button>
                    </template>
                </el-table-column>
            </el-table>
        </div>
        <div class="page-info-box">
            <el-pagination
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                    :page-sizes="[20, 50, 100]"
                    :page-size="20"
                    :current-page="searchParam.pageNum"
                    layout="prev, pager, next, jumper, sizes, total"
                    :total="totalCount"
            >
            </el-pagination>
        </div>
        <!--修改用户弹窗-->
        <el-dialog title="修改用户" :visible.sync="editUserDialogVisible" width="600px">
            <el-form ref="form" :model="editUserForm" label-width="80px">
                <el-form-item label="账号">
                    <el-input v-model="editUserForm.name"></el-input>
                </el-form-item>
                <el-form-item label="用户名">
                    <el-input v-model="editUserForm.name"></el-input>
                </el-form-item>
                <el-form-item label="手机号">
                    <el-input v-model="editUserForm.name"></el-input>
                </el-form-item>
                <el-form-item label="邮箱">
                    <el-input v-model="editUserForm.name"></el-input>
                </el-form-item>
                <el-form-item label="性别">
                    <el-radio-group v-model="editUserForm.resource">
                        <el-radio label="男"></el-radio>
                        <el-radio label="女"></el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="角色">
                    <el-select v-model="editUserForm.xx" multiple filterable placeholder="请选择">
                        <el-option v-for="item in roleOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="">确定</el-button>
                    <el-button>取消</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                editUserDialogVisible: false,
                totalCount: 0,
                searchParam: {
                    type: 1,
                    keyword: '',
                    pageSize: 20,
                    pageNum: 1,
                },
                searchResultList: [
                    {name: '张三'}
                ],
                roleOptions: [
                    {value: '管理员'}
                ],
                editUserForm: {},
            };
        },
        mounted: function () {
        },
        methods: {
            handleSizeChange(val) {
                this.searchParam.pageSize = val;
            },
            handleCurrentChange(val) {
                this.searchParam.pageNum = val;
            },
            editUserInfo() {
                this.editUserDialogVisible = true;
            },
            resetPassword() {
            },
        }
    }
</script>
<style>
    .search-form-box{padding: 10px;}
    .page-info-box{text-align: right;margin: 20px 0 50px 0;}
</style>
iailab-doc-ui/console-ui/src/views/console/UserGroupList.vue
对比新文件
@@ -0,0 +1,217 @@
<template>
    <div class="user-group-vue">
        <el-breadcrumb separator-class="el-icon-arrow-right" style="padding: 20px 10px;">
            <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>系统管理</el-breadcrumb-item>
            <el-breadcrumb-item>分组管理</el-breadcrumb-item>
        </el-breadcrumb>
        <el-row>
            <el-col :span="6">
                <div class="group-box page-scroll-box">
                    <el-popover placement="bottom" width="300" trigger="click" v-model="createUserGroupVisible">
                        <el-tag slot="reference" class="group-item" @click="">
                            <div style="text-align: center;"><i class="el-icon-plus"></i> 创建分组</div>
                        </el-tag>
                        <div>
                            <el-input v-model="editGroupName" placeholder="请输入新的分组名称" style="width: 220px;margin-right: 10px;"></el-input>
                            <el-button plain type="primary" v-on:click="createUserGroup">创建</el-button>
                        </div>
                    </el-popover>
                    <el-tag :type="item.id==checkedUserGroupId?'warning':'info'" class="group-item" @click="loadUserGroupRelation(item.id)" @dblclick.native="item.edit = true" v-for="item in userGroupList">
                        <el-input v-if="item.edit" size="mini" v-model="item.editName" @keyup.enter.native="updateUserGroup(item)" @blur="updateUserGroup(item)" class="group-name-input">{{item.name}}</el-input>
                        <span v-else>{{item.name}}</span>
                        <el-popconfirm title="确定要删除此分组吗?" @confirm="removeUserGroup(item.id)">
                            <i slot="reference" class="el-tag__close el-icon-close"></i>
                        </el-popconfirm>
                    </el-tag>
                </div>
            </el-col>
            <el-col :span="18">
                <div v-if="checkedUserGroupId > 0" class="page-scroll-box" v-loading="searchLoading">
                    <div style="margin-bottom: 10px;">
                        <el-button size="mini" plain type="primary" @click="showChoiceUserDialog" icon="el-icon-plus">添加用户</el-button>
                    </div>
                    <el-table :data="userGroupRelationList" border style="width: 100%; margin-bottom: 5px;" :max-height="tableHeight">
                        <el-table-column prop="id" label="编号" width="60"></el-table-column>
                        <el-table-column prop="userNo" label="账号"></el-table-column>
                        <el-table-column prop="email" label="邮箱"></el-table-column>
                        <el-table-column prop="userName" label="用户名"></el-table-column>
                        <el-table-column prop="phone" label="手机号"></el-table-column>
                        <el-table-column label="性别">
                            <template slot-scope="scope">{{scope.row.sex==0?'女':'男'}}</template>
                        </el-table-column>
                        <el-table-column label="操作" width="300">
                            <template slot-scope="scope">
                                <el-button size="mini" plain type="danger" v-on:click="removeUserRelationFromList(scope.row.id)">移除</el-button>
                            </template>
                        </el-table-column>
                    </el-table>
                </div>
            </el-col>
        </el-row>
        <!--添加用户到分组弹窗-->
        <el-dialog title="添加用户到分组" :visible.sync="choiceUserVisible" width="600px" @close="closeChoiceUserDialog">
            <el-row>
                <el-select v-model="searchAddNewUser" filterable remote reserve-keyword autoComplete="new-password"
                           placeholder="请输入名字、邮箱、账号搜索用户" :remote-method="getSearchUserList"
                           :loading="searchUserLoading" style="width: 450px;margin-right: 10px;">
                    <el-option v-for="item in searchUserList" :key="item.id" :label="item.userName" :value="item.id"></el-option>
                </el-select>
                <el-button v-on:click="addSearchChoiceUser">添加</el-button>
            </el-row>
            <div style="margin: 10px 0;">
                <el-tag v-for="item in searchAddUserList" :key="item.userId" closable type="info" style="margin-right: 10px;" @close="removeUserRelationFromSearch(item.userId)">
                    {{item.userName}}
                </el-tag>
            </div>
        </el-dialog>
    </div>
</template>
<script>
    import consoleApi from '../../common/api/console'
    export default {
        data() {
            return {
                searchLoading: false,
                editUserDialogVisible: false,
                editUserAuthDialogVisible: false,
                totalCount: 0,
                searchParam: {
                    type: 1,
                    keyword: '',
                },
                searchResultList: [],
                roleOptions: [
                    {value: '管理员'}
                ],
                editUserForm: {},
                allUserAuth: [],
                editUserAuth: [],
                userGroupRelationList: [],
                userGroupList: [],
                editGroupName: '',
                checkedUserGroupId: '',
                createUserGroupVisible: false,
                choiceUserVisible: false,
                // 添加用户
                searchAddUserList: [],
                searchUserList: [],
                searchAddNewUser: "",
                searchUserLoading: false,
                tableHeight: (document.body.clientHeight - 250),
            };
        },
        mounted() {
            this.getUserGroupList();
        },
        methods: {
            getUserGroupList() {
                this.userGroupList = [];
                consoleApi.userGroupList().then(json => {
                    let userGroupList = json.data || [];
                    userGroupList.forEach(item => {
                        item.edit = false;
                        item.checked = false;
                        item.editName = item.name;
                    });
                    this.userGroupList = userGroupList;
                });
            },
            loadUserGroupRelation(groupId, force) {
                if (!force && groupId == this.checkedUserGroupId) return;
                this.checkedUserGroupId = groupId;
                this.searchLoading = true;
                consoleApi.userGroupRelationList({groupId: groupId}).then(json => {
                    this.searchLoading = false;
                    this.userGroupRelationList = json.data || [];
                });
            },
            updateUserGroup(item) {
                if (item.name == item.editName) {
                    item.edit = false;
                    return;
                }
                let param = {id: item.id, name: item.editName};
                consoleApi.updateUserGroup(param).then(json => {
                    item.edit = false;
                    item.name = item.editName;
                });
            },
            createUserGroup() {
                let param = {name: this.editGroupName};
                consoleApi.updateUserGroup(param).then(json => {
                    this.editGroupName = '';
                    this.createUserGroupVisible = false;
                    this.getUserGroupList();
                });
            },
            removeUserGroup(id) {
                consoleApi.deleteUserGroup({id: id}).then(json => {
                    this.checkedUserGroupId = '';
                    this.getUserGroupList();
                });
            },
            closeChoiceUserDialog() {
                this.loadUserGroupRelation(this.checkedUserGroupId, true);
            },
            showChoiceUserDialog() {
                this.choiceUserVisible = true;
                this.searchAddUserList = [];
                this.userGroupRelationList.forEach(item => {
                    this.searchAddUserList.push({userName: item.userName, userId: item.id});
                });
            },
            getSearchUserList(query) {
                if (!query) return;
                this.searchUserLoading = true;
                consoleApi.searchUserInfoList({search: query}).then(json => {
                    this.searchUserList = json.data || [];
                    this.searchUserLoading = false;
                });
            },
            removeUserRelationFromSearch(userId) {
                let param = {groupId: this.checkedUserGroupId, userId: userId};
                consoleApi.removeUserGroupRelation(param).then(json => {
                    this.searchAddUserList = this.searchAddUserList.filter(item => item.userId != userId);
                });
            },
            removeUserRelationFromList(userId) {
                let param = {groupId: this.checkedUserGroupId, userId: userId};
                consoleApi.removeUserGroupRelation(param).then(json => {
                    this.loadUserGroupRelation(this.checkedUserGroupId, true);
                });
            },
            addSearchChoiceUser() {
                if (this.searchAddNewUser.length <= 0) {
                    this.$message.warning("请先选择用户");
                    return;
                }
                if (!!this.searchAddUserList.find(item => item.userId == this.searchAddNewUser)) {
                    this.searchAddNewUser = "";
                    return;
                }
                let userName = this.searchUserList.find(item => item.id == this.searchAddNewUser).userName;
                let param = {groupId: this.checkedUserGroupId, userId: this.searchAddNewUser};
                consoleApi.updateUserGroupRelation(param).then(json => {
                    this.searchAddUserList.push({userName: userName, userId: this.searchAddNewUser});
                });
                this.searchAddNewUser = "";
            },
        }
    }
</script>
<style>
    .user-group-vue .search-form-box{padding: 10px;}
    .user-group-vue .page-info-box{text-align: right;margin: 20px 0 50px 0;}
    .user-group-vue .el-button+.el-button{margin-left: 5px;}
    .user-group-vue .page-scroll-box{padding: 10px;height: calc(100vh - 200px);overflow: auto;}
    .user-group-vue .group-box .group-item{width: 100%;margin-bottom: 10px;cursor: pointer;}
    .user-group-vue .group-box .group-item .el-icon-close{float: right; top: 6px;}
    .user-group-vue .group-box .group-item .group-name-input{width: calc(100% - 30px);}
    .user-group-vue .group-box .group-item .group-name-input input{border: 0;padding-left: 5px;}
</style>
iailab-doc-ui/console-ui/src/views/console/UserList.vue
对比新文件
@@ -0,0 +1,247 @@
<template>
    <div class="user-list-vue">
        <el-breadcrumb separator-class="el-icon-arrow-right" style="padding: 20px 10px;">
            <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>系统管理</el-breadcrumb-item>
            <el-breadcrumb-item>用户列表</el-breadcrumb-item>
        </el-breadcrumb>
        <el-form :inline="true" :model="searchParam" class="search-form-box">
            <el-form-item label="搜索类型">
                <el-select v-model="searchParam.type" placeholder="请选择">
                    <el-option label="ID" :value="1"></el-option>
                    <el-option label="账号" :value="2"></el-option>
                    <el-option label="用户名" :value="3"></el-option>
                    <el-option label="手机" :value="4"></el-option>
                    <el-option label="邮箱" :value="5"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item label="关键字">
                <el-input v-model="searchParam.keyword" placeholder="输入关键字"></el-input>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="getUserList">查询</el-button>
            </el-form-item>
            <el-form-item>
                <el-button type="success" @click="addUserInfo"><i class="el-icon-plus"></i> 添加</el-button>
            </el-form-item>
        </el-form>
        <div style="padding: 10px;" v-loading="searchLoading">
            <el-table :data="searchResultList" border style="width: 100%; margin-bottom: 5px;" max-height="500">
                <el-table-column prop="id" label="编号" width="60"></el-table-column>
                <el-table-column prop="userNo" label="账号"></el-table-column>
                <el-table-column prop="email" label="邮箱"></el-table-column>
                <el-table-column prop="userName" label="用户名"></el-table-column>
                <el-table-column prop="phone" label="手机号"></el-table-column>
                <el-table-column label="性别">
                    <template slot-scope="scope">{{scope.row.sex==0?'女':'男'}}</template>
                </el-table-column>
                <el-table-column prop="creationTime" label="创建时间"></el-table-column>
                <el-table-column label="状态">
                    <template slot-scope="scope">{{scope.row.delFlag==0?'正常':'停用'}}</template>
                </el-table-column>
                <el-table-column label="操作" width="300">
                    <template slot-scope="scope">
                        <el-button size="mini" plain type="primary" v-on:click="editUserInfo(scope.row)">修改</el-button>
                        <el-button size="mini" plain type="success" v-on:click="editUserAuthFun(scope.row)">权限</el-button>
                        <el-button size="mini" plain type="warning" v-on:click="resetPassword(scope.row)">重置密码</el-button>
                        <el-button size="mini" plain type="danger" v-on:click="deleteUser(scope.row)">删除</el-button>
                    </template>
                </el-table-column>
            </el-table>
        </div>
        <div class="page-info-box">
            <el-pagination
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                    :page-sizes="[20, 50, 100]"
                    :page-size="20"
                    :current-page="searchParam.pageNum"
                    layout="prev, pager, next, jumper, sizes, total"
                    :total="totalCount"
            >
            </el-pagination>
        </div>
        <!--修改用户权限弹窗-->
        <el-dialog title="权限编辑" :visible.sync="editUserAuthDialogVisible" width="600px" :close-on-click-modal="false">
            <el-form ref="form" label-width="80px">
                <el-form-item label="账号">
                    <el-input v-model="editUserForm.userNo" disabled></el-input>
                </el-form-item>
                <el-form-item label="用户名">
                    <el-input v-model="editUserForm.userName" disabled></el-input>
                </el-form-item>
                <el-form-item label="权限">
                    <el-select v-model="editUserAuth" multiple filterable placeholder="请选择" style="width: 100%;">
                        <el-option v-for="item in allUserAuth" :key="item.id" :label="item.authDesc" :value="item.id"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="editUserAuthSave">确定</el-button>
                    <el-button @click="editUserAuthDialogVisible = false">取消</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
        <!--修改用户弹窗-->
        <el-dialog :title="editUserForm.id > 0 ? '修改用户':'创建用户'" :visible.sync="editUserDialogVisible" width="600px" :close-on-click-modal="false">
            <el-form ref="form" :model="editUserForm" label-width="80px">
                <el-form-item label="账号">
                    <el-input v-model="editUserForm.userNo"></el-input>
                </el-form-item>
                <el-form-item label="用户名">
                    <el-input v-model="editUserForm.userName"></el-input>
                </el-form-item>
                <el-form-item label="手机号">
                    <el-input v-model="editUserForm.phone"></el-input>
                </el-form-item>
                <el-form-item label="邮箱">
                    <el-input v-model="editUserForm.email"></el-input>
                </el-form-item>
                <el-form-item label="新密码">
                    <el-input v-model="editUserForm.password" placeholder="为空代表不修改密码"></el-input>
                </el-form-item>
                <el-form-item label="状态">
                    <el-switch v-model="editUserForm.delFlag" :active-value="0" active-text="正常" :inactive-value="2" inactive-text="停用"></el-switch>
                </el-form-item>
                <el-form-item label="性别">
                    <el-radio-group v-model="editUserForm.sex">
                        <el-radio :label="1">男</el-radio>
                        <el-radio :label="0">女</el-radio>
                    </el-radio-group>
                </el-form-item>
<!--                先不做角色,想清楚了再做-->
<!--                <el-form-item label="角色">-->
<!--                    <el-select v-model="editUserForm.role" multiple filterable placeholder="请选择">-->
<!--                        <el-option v-for="item in roleOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>-->
<!--                    </el-select>-->
<!--                </el-form-item>-->
                <el-form-item>
                    <el-button type="primary" @click="updateEditUser">确定</el-button>
                    <el-button @click="editUserDialogVisible = false">取消</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
    </div>
</template>
<script>
    import consoleApi from '../../common/api/console'
    export default {
        data() {
            return {
                searchLoading: false,
                editUserDialogVisible: false,
                editUserAuthDialogVisible: false,
                totalCount: 0,
                searchParam: {
                    type: 1,
                    keyword: '',
                    pageSize: 20,
                    pageNum: 1,
                },
                searchResultList: [],
                roleOptions: [
                    {value: '管理员'}
                ],
                editUserForm: {},
                allUserAuth: [],
                editUserAuth: [],
            };
        },
        mounted: function () {
            this.getUserList();
        },
        methods: {
            handleSizeChange(val) {
                this.searchParam.pageSize = val;
                this.getUserList();
            },
            handleCurrentChange(val) {
                this.searchParam.pageNum = val;
                this.getUserList();
            },
            editUserAuthFun(row) {
                this.allUserAuth = [];
                this.editUserAuth = [];
                var param = {userIds: row.id};
                consoleApi.userAuthList(param).then(json => {
                    this.editUserAuth = [];
                    this.allUserAuth = json.data;
                    this.editUserAuthDialogVisible = true;
                    this.editUserForm = JSON.parse(JSON.stringify(row));
                    for (var i = 0; i < this.allUserAuth.length; i++) {
                        if (this.allUserAuth[i].checked == 1) {
                            this.editUserAuth.push(this.allUserAuth[i].id);
                        }
                    }
                });
            },
            editUserAuthSave() {
                var param = {
                    userIds: this.editUserForm.id,
                    authIds: this.editUserAuth.join(","),
                };
                consoleApi.updateUserAuth(param).then(json => {
                    this.$message.success("保存成功!");
                    this.editUserAuthDialogVisible = false;
                });
            },
            editUserInfo(row) {
                this.editUserDialogVisible = true;
                this.editUserForm = JSON.parse(JSON.stringify(row));
            },
            addUserInfo() {
                this.editUserDialogVisible = true;
                this.editUserForm = {};
            },
            resetPassword(row) {
                this.$confirm('确定要重置此用户密码吗?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.editUserForm = JSON.parse(JSON.stringify(row));
                    consoleApi.resetPassword(this.editUserForm).then(json => {
                        this.$confirm("重置成功!新的密码为:" + json.data).then(()=> {
                        }).catch(()=> {});
                    });
                }).catch(()=>{});
            },
            deleteUser(row) {
                this.$confirm('确定要删除此用户吗?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.editUserForm = JSON.parse(JSON.stringify(row));
                    consoleApi.deleteUserInfo(this.editUserForm).then(json => {
                        this.$message.success("删除成功!");
                        this.getUserList();
                    });
                }).catch(()=>{});
            },
            updateEditUser() {
                consoleApi.updateUserInfo(this.editUserForm).then(json => {
                    this.$message.success("保存成功!");
                    this.editUserDialogVisible = false;
                    this.getUserList();
                });
            },
            getUserList() {
                this.searchLoading = true;
                consoleApi.getUserInfoList(this.searchParam).then(json => {
                    // 让加载动画停留一会
                    setTimeout(()=>{this.searchLoading = false;}, 500);
                    this.totalCount = json.total;
                    this.searchResultList = json.data;
                });
            },
        }
    }
</script>
<style>
    .user-list-vue .search-form-box{padding: 10px;}
    .user-list-vue .page-info-box{text-align: right;margin: 20px 0 50px 0;}
    .user-list-vue .el-button+.el-button{margin-left: 5px;}
</style>
iailab-doc-ui/console-ui/src/views/home/Home.vue
对比新文件
@@ -0,0 +1,87 @@
<template>
    <div style="padding: 10px;">
        <div style="max-width: 800px;margin: 20px auto;">
            <div style="padding: 20px;">
                <el-card class="box-card">
<!--                    <div slot="header" class="clearfix">-->
<!--                        <span>所有产品</span>-->
<!--                    </div>-->
                    <div class="product-list">
                        <div class="item" v-on:click="jumpToDocPage('doc-api')" v-if="this.moudleInfo.enableApi">
                            <div class="logo-text text1">API</div>
                            <div>API接口文档</div>
                        </div>
<!--                        <div class="item" v-on:click="jumpToDocPage('doc-db')" v-if="this.moudleInfo.enableDb">-->
<!--                            <div class="logo-text text2">DB</div>-->
<!--                            <div>数据库文档</div>-->
<!--                        </div>-->
<!--                        <div class="item" v-on:click="jumpToDocPage('doc-wiki')" v-if="this.moudleInfo.enableWiki">-->
<!--                            <div class="logo-text text3">WIKI</div>-->
<!--                            <div>WIKI文档</div>-->
<!--                        </div>-->
                    </div>
                </el-card>
            </div>
        </div>
    </div>
</template>
<script>
    import systemApi from "../../common/api/system";
    export default {
        data() {
            return {
                moudleInfo:{
                    enableWiki:true,
                    enableDb:true,
                    enableApi:true,
                }
            };
        },
        mounted: function () {
        },
        created(){
            this.fetchMoudle()
        },
        methods: {
            fetchMoudle(){
                systemApi.fetchMoudleData().then(json => {
                    if(!!json.data){
                        this.moudleInfo = json.data;
                        console.log(
                                "wiki模块启动状态" +this.moudleInfo.enableWiki+
                                "db模块启动状态" +this.moudleInfo.enableDb+
                                "api模块启动状态" +this.moudleInfo.enableApi
                        )
                    }
                })
            },
            jumpToDocPage(val) {
                window.open(val);
            },
        }
    }
</script>
<style>
    .product-list{text-align: left;}
    .product-list .item{
        text-align: center;display: inline-block;padding: 10px;border-radius: 5px;cursor: pointer;
        width: 110px; height: 100px;color: #666;
    }
    .product-list .item:hover{background: #ddd;}
    .product-list .item.disabled{background: #fff;cursor: auto;}
    .product-list .item.disabled .logo-text{background: #909399;}
    .product-list .item .logo-text{
        width: 80px; height: 80px;line-height: 80px;text-align: center; color: #fff;
        margin: 0 auto;background: #67C23A; border-radius: 50%;overflow: hidden;
        font-weight: bold;
    }
    .product-list .item .logo-text.text1{background: #67C23A;}
    .product-list .item .logo-text.text2{background: #E6A23C;}
    .product-list .item .logo-text.text3{background: #F56C6C;}
    .product-list .item .logo-text.text4{background: #387BCD;}
    .product-list .item .logo-text.text5{background: #298b8e;}
    .product-list .item .logo-img{width: 80px; height: 80px;margin: 0 auto;}
    .product-list .item .logo-img img{width: 65px; height: 65px; margin: 7px;}
</style>
iailab-doc-ui/console-ui/src/views/user/Login.vue
对比新文件
@@ -0,0 +1,97 @@
<template>
    <div :class="'login-background linear-gradient-'+bgImgRandom">
        <div class="login-box">
            <el-form :model="loginParam" :rules="loginRules" ref="loginParam" label-position="left" label-width="0px" class="demo-ruleForm login-container">
                <h3 class="title">文档管理-系统登录</h3>
                <el-form-item prop="username">
                    <el-input type="text" v-model="loginParam.username" auto-complete="off" placeholder="账号" @keyup.enter.native="loginSubmit"></el-input>
                </el-form-item>
                <el-form-item prop="password">
                    <el-input type="password" v-model="loginParam.password" auto-complete="off" placeholder="密码" @keyup.enter.native="loginSubmit"></el-input>
                </el-form-item>
                <el-form-item style="width:100%;">
                    <el-button type="primary" style="width:100%;" @click.native.prevent="loginSubmit" :loading="loginLoading">登录</el-button>
                </el-form-item>
            </el-form>
        </div>
        <div class="power-by">Powered By <a target="_blank" href="https://gitee.com/zyplayer/zyplayer-doc">zyplayer-doc</a></div>
    </div>
</template>
<script>
    import consoleApi from '../../common/api/console'
    export default {
        data() {
            return {
                loginLoading: false,
                redirect: '',
                loginParam: {
                    username: '',
                    password: ''
                },
                loginRules: {
                    username: [
                        {required: true, message: '请输入账号', trigger: 'blur'},
                    ],
                    password: [
                        {required: true, message: '请输入密码', trigger: 'blur'},
                    ]
                },
                bgImgRandom: Math.ceil(Math.random() * 5),
            };
        },
        mounted: function () {
            this.redirect = this.$route.query.redirect;
        },
        methods: {
            loginSubmit() {
                this.$refs.loginParam.validate((valid) => {
                    if (!valid) return;
                    this.loginLoading = true;
                    consoleApi.userLogin(this.loginParam).then(() => {
                        this.$emit('loginSuccess');
                        this.loginLoading = false;
                        if (!!this.redirect) {
                            location.href = decodeURIComponent(this.redirect);
                        } else {
                            this.$router.back();
                        }
                    }).catch(e => {
                        console.log("登录失败", e);
                        this.loginLoading = false;
                    });
                });
            }
        }
    }
</script>
<style>
    .login-container {
        -webkit-border-radius: 5px;
        border-radius: 5px;
        -moz-border-radius: 5px;
        background-clip: padding-box;
        margin: 0 auto;
        width: 350px;
        padding: 35px 35px 15px 35px;
        background: #fff;
        border: 1px solid #eaeaea;
        box-shadow: 0 0 25px #cac6c6;
    }
    .title {margin: 0px auto 40px auto;text-align: center;color: #505458;}
    .remember {margin: 0px 0px 35px 0px;}
    .login-background{height: 100%;}
    .linear-gradient-0{background: linear-gradient(to top, #a8edea 0%, #fed6e3 100%);}
    .linear-gradient-1{background: linear-gradient(to top, #9795f0 0%, #fbc8d4 100%);}
    .linear-gradient-2{background: linear-gradient(to top, #fad0c4 0%, #ffd1ff 100%);}
    .linear-gradient-3{background: linear-gradient(to top, #fbc2eb 0%, #a6c1ee 100%);}
    .linear-gradient-4{background: linear-gradient(120deg, #a6c0fe 0%, #f68084 100%);}
    .linear-gradient-5{background: linear-gradient(120deg, #e0c3fc 0%, #8ec5fc 100%);}
    .login-box{padding-top: 50px;}
    .power-by{position: absolute; bottom: 0; text-align: center; color: #888; padding: 10px 0;width: 100%;}
    .power-by a{color: #888;padding: 10px 0; width: 100%;}
</style>
iailab-doc-ui/console-ui/src/views/user/MyInfo.vue
对比新文件
@@ -0,0 +1,126 @@
<template>
    <div class="my-info-vue">
        <div style="margin: 0 auto;max-width: 1000px;">
            <el-card class="box-card">
                <div slot="header" class="clearfix">
                    <el-row>
                        <el-col :span="12" style="line-height: 40px;">我的信息</el-col>
                        <el-col :span="12" style="text-align: right;">
                            <el-button type="primary" @click="showUpdatePasswordDialog"><i class="el-icon-edit"></i> 修改密码</el-button>
                        </el-col>
                    </el-row>
                </div>
                <el-form class="search-form-box" label-width="100px">
                    <el-form-item label="账号:">{{userInfo.userNo}}</el-form-item>
                    <el-form-item label="用户名:">{{userInfo.userName}}</el-form-item>
                    <el-form-item label="手机号:">{{userInfo.phone}}</el-form-item>
                    <el-form-item label="邮箱:">{{userInfo.email}}</el-form-item>
                    <el-form-item label="状态:">{{userInfo.delFlag==0?'正常':'停用'}}</el-form-item>
                    <el-form-item label="性别:">{{userInfo.sex==0?'女':'男'}}</el-form-item>
                </el-form>
            </el-card>
        </div>
        <el-dialog title="修改密码" :visible.sync="updatePasswordDialogVisible" width="500px">
            <el-form label-width="120px" :model="updatePassword" status-icon :rules="updatePasswordRules" ref="passwordForm">
                <el-form-item label="当前密码" prop="currentPwd">
                    <el-input type="password" v-model="updatePassword.currentPwd" placeholder="请输入当前密码"></el-input>
                </el-form-item>
                <el-form-item label="新密码" prop="newPwd">
                    <el-input type="password" v-model="updatePassword.newPwd" placeholder="请输入新密码"></el-input>
                </el-form-item>
                <el-form-item label="确认新密码" prop="repeatPwd">
                    <el-input type="password" v-model="updatePassword.repeatPwd" placeholder="请再次输入新密码"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="submitUpdatePasswordForm">修改密码</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
    </div>
</template>
<script>
    import consoleApi from '../../common/api/console'
    export default {
        data() {
            return {
                userInfo: {},
                updatePasswordDialogVisible: false,
                updatePassword: {
                    currentPwd: '',
                    newPwd: '',
                    repeatPwd: '',
                },
                updatePasswordRules: {
                    currentPwd: [{validator: this.validateCurrentPwd, trigger: 'blur'}],
                    newPwd: [{validator: this.validateNewPwd, trigger: 'blur'}],
                    repeatPwd: [{validator: this.validateRepeatPwd, trigger: 'blur'}],
                },
            };
        },
        mounted: function () {
            this.getUserInfo();
        },
        methods: {
            getUserInfo() {
                consoleApi.getSelfUserInfo().then(json => {
                    this.userInfo = json.data;
                });
            },
            showUpdatePasswordDialog() {
                this.updatePasswordDialogVisible = true;
            },
            submitUpdatePasswordForm() {
                this.$refs.passwordForm.validate((valid) => {
                    if (!valid) {
                        return false;
                    }
                    consoleApi.updateSelfPwd(this.updatePassword).then(json => {
                        this.$message.success("修改成功!请重新登录");
                        setTimeout(() => {
                            consoleApi.userLogout().then(() => {
                                location.reload();
                            }).catch(e => {
                                console.log("退出登录失败", e);
                            });
                        }, 500);
                    });
                });
            },
            validateCurrentPwd(rule, value, callback) {
                if (value === '') {
                    callback(new Error('请输入密码'));
                } else {
                    callback();
                }
            },
            validateNewPwd(rule, value, callback) {
                if (value === '') {
                    callback(new Error('请输入新密码'));
                } else {
                    if (this.updatePassword.newPwd !== '') {
                        this.$refs.passwordForm.validateField('repeatPwd');
                    }
                    callback();
                }
            },
            validateRepeatPwd(rule, value, callback) {
                if (value === '') {
                    callback(new Error('请再次输入新密码'));
                } else {
                    if (this.updatePassword.repeatPwd !== this.updatePassword.newPwd) {
                        callback(new Error('两次输入的密码不一致'));
                    } else {
                        callback();
                    }
                }
            },
        }
    }
</script>
<style>
    .my-info-vue{}
    .my-info-vue .box-card{margin: 10px;}
</style>
iailab-doc-ui/console-ui/vue.config.js
对比新文件
@@ -0,0 +1,33 @@
// 官方配置文档:https://webpack.js.org/configuration/dev-server/
module.exports = {
    devServer: {
        host: '0.0.0.0',
        port: 8002,
        open: true,
        proxy: {
            ['/']: {
                target: 'http://localhost:8083/zyplayer-doc',
                changeOrigin: true,
                pathRewrite: {
                    '^/zyplayer-doc': ''
                }
            }
        },
        historyApiFallback: {
            index: '/index.html',
        },
        disableHostCheck: true
    },
    publicPath: '/',
    outputDir: '../../iailab-doc-manage/src/main/resources/dist',
    productionSourceMap: false,
    pages: {
        index: {
            entry: 'src/main.js',
            template: 'public/index.html',
            filename: process.env.NODE_ENV === 'production'?'doc-console.html':'index.html',
        },
    }
};
iailab-doc-ui/console-ui/yarn.lock
对比新文件
文件太大