records);
38 |
39 | /**
40 | * 根据id查询指定的记录
41 | *
42 | * @param id 记录的id
43 | * @return 记录对象
44 | */
45 | T findById(Long id);
46 |
47 | /**
48 | * 分页查询,这里统一封装了分页请求和结果,避免直接引入具体框架的分页对象,
49 | *
50 | * 如MyBatis或JPA的分页对象从而避免因替换ORM框架导致服务层、控制层的分页接
51 | *
52 | * 口也需要变动的情况,替换ORM框架也不会影响服务层,所以这个分页接口起到了解耦的作用
53 | *
54 | * @param pageRequest 自己定义的统一分页查询请求
55 | * @return PageResult 自己定义的统一分页查询结果
56 | */
57 | PageResult findPage(PageRequest pageRequest);
58 | }
59 |
--------------------------------------------------------------------------------
/code/backend/core/src/main/java/com/huawei/l00379880/core/service/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Created By Liang Shan Guang at 2019/11/17 12:39
3 | * Description : 通用业务接口封装
4 | */
5 | package com.huawei.l00379880.core.service;
--------------------------------------------------------------------------------
/code/backend/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.huawei.l00379880
8 | backend
9 | 1.0-SNAPSHOT
10 | pom
11 |
12 |
13 | UTF-8
14 | UTF-8
15 | 1.8
16 |
17 |
18 |
19 | admin
20 | common
21 | core
22 |
23 |
24 |
25 | org.springframework.boot
26 | spring-boot-starter-parent
27 | 2.1.1.RELEASE
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | org.springframework.cloud
40 | spring-cloud-dependencies
41 | Finchley.RELEASE
42 | pom
43 | import
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | spring-milestones
52 | Spring Milestones
53 | https://repo.spring.io/libs-milestone
54 |
55 | false
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/code/frontend/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.{js,jsx,ts,tsx,vue}]
2 | indent_style = space
3 | indent_size = 2
4 | trim_trailing_whitespace = true
5 | insert_final_newline = true
6 |
--------------------------------------------------------------------------------
/code/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw?
22 |
--------------------------------------------------------------------------------
/code/frontend/README.md:
--------------------------------------------------------------------------------
1 | # frontend
2 |
3 | ## Project setup
4 | ```
5 | npm install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | npm run serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | npm run build
16 | ```
17 |
18 | ### Lints and fixes files
19 | ```
20 | npm run lint
21 | ```
22 |
23 | ### Customize configuration
24 | See [Configuration Reference](https://cli.vuejs.org/config/).
25 |
26 | ### 常见到的问题
27 |
28 | + node-sass安装失败
29 | > 单独用命令安装`npm i node-sass@^4.12.0 --dev --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/`
30 |
--------------------------------------------------------------------------------
/code/frontend/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/code/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "axios": "^0.19.0",
12 | "core-js": "^3.3.2",
13 | "element-ui": "^2.13.0",
14 | "font-awesome": "^4.7.0",
15 | "js-cookie": "^2.2.1",
16 | "vue": "^2.6.10",
17 | "vue-i18n": "^8.15.0",
18 | "vue-router": "^3.1.3",
19 | "vuex": "^3.0.1"
20 | },
21 | "devDependencies": {
22 | "@vue/cli-plugin-babel": "^4.0.0",
23 | "@vue/cli-plugin-eslint": "^4.0.0",
24 | "@vue/cli-plugin-router": "^4.0.0",
25 | "@vue/cli-plugin-vuex": "^4.0.0",
26 | "@vue/cli-service": "^4.0.0",
27 | "@vue/eslint-config-standard": "^4.0.0",
28 | "babel-eslint": "^10.0.3",
29 | "eslint": "^5.16.0",
30 | "eslint-plugin-vue": "^5.0.0",
31 | "fibers": "^3.1.0",
32 | "node-sass": "^4.13.0",
33 | "sass": "^1.23.7",
34 | "sass-loader": "^8.0.0",
35 | "vue-template-compiler": "^2.6.10"
36 | },
37 | "eslintConfig": {
38 | "root": true,
39 | "env": {
40 | "node": true
41 | },
42 | "extends": [
43 | "plugin:vue/essential",
44 | "@vue/standard"
45 | ],
46 | "rules": {},
47 | "parserOptions": {
48 | "parser": "babel-eslint"
49 | }
50 | },
51 | "postcss": {
52 | "plugins": {
53 | "autoprefixer": {}
54 | }
55 | },
56 | "browserslist": [
57 | "> 1%",
58 | "last 2 versions"
59 | ]
60 | }
61 |
--------------------------------------------------------------------------------
/code/frontend/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lsgwr/spring-cloud-vue-admin/e399bc238e486cef481ecbe789c57c433428715d/code/frontend/public/favicon.ico
--------------------------------------------------------------------------------
/code/frontend/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | frontend
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/code/frontend/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
29 |
--------------------------------------------------------------------------------
/code/frontend/src/assets/languages/en_us.json:
--------------------------------------------------------------------------------
1 | {
2 | "common": {
3 | "home": "Home",
4 | "login": "Login",
5 | "logout": "Logout",
6 | "doc": "Document",
7 | "blog": "Blog",
8 | "projectRepo": "Project",
9 | "myMsg": "Me Message",
10 | "config": "Config",
11 | "backup": "Backup",
12 | "restore": "Restore",
13 | "backupRestore": "Back Restore",
14 | "versionName": "Version",
15 | "exit": "Exit"
16 | },
17 | "action": {
18 | "operation": "Operation",
19 | "add": "Add",
20 | "edit": "Edit",
21 | "delete": "Delete",
22 | "batchDelete": "Batch Delete",
23 | "search": "Search",
24 | "loading": "loading",
25 | "submit": "Submit",
26 | "confirm": "Confirm",
27 | "cancel": "Cancel",
28 | "reset": "Reset"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/code/frontend/src/assets/languages/zh_cn.json:
--------------------------------------------------------------------------------
1 | {
2 | "common": {
3 | "home": "首页",
4 | "login": "登录",
5 | "logout": "退出登录",
6 | "doc": "文档",
7 | "blog": "博客",
8 | "projectRepo": "项目",
9 | "myMsg": "我的消息",
10 | "config": "系统配置",
11 | "backup": "备份",
12 | "restore": "还原",
13 | "backupRestore": "备份还原",
14 | "versionName": "版本名称",
15 | "exit": "退出"
16 | },
17 | "action": {
18 | "operation": "操作",
19 | "add": "新增",
20 | "edit": "编辑",
21 | "delete": "删除",
22 | "batchDelete": "批量删除",
23 | "search": "查询",
24 | "loading": "加载中",
25 | "submit": "提交",
26 | "confirm": "确定",
27 | "cancel": "取消",
28 | "reset": "重置"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/code/frontend/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lsgwr/spring-cloud-vue-admin/e399bc238e486cef481ecbe789c57c433428715d/code/frontend/src/assets/logo.png
--------------------------------------------------------------------------------
/code/frontend/src/assets/user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lsgwr/spring-cloud-vue-admin/e399bc238e486cef481ecbe789c57c433428715d/code/frontend/src/assets/user.png
--------------------------------------------------------------------------------
/code/frontend/src/components/Core/IFrame.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
51 |
52 |
66 |
--------------------------------------------------------------------------------
/code/frontend/src/components/Core/KtButton.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ label }}
4 |
5 |
6 |
7 |
57 |
58 |
61 |
--------------------------------------------------------------------------------
/code/frontend/src/components/Core/MessagePanel.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
![]()
8 |
9 |
10 | {{ item.sender }}
11 |
12 |
13 | {{ item.time }}
14 |
15 |
16 | {{ item.content }}
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
81 |
82 |
154 |
--------------------------------------------------------------------------------
/code/frontend/src/components/Core/NoticePanel.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | {{ item.content }}
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
60 |
61 |
112 |
--------------------------------------------------------------------------------
/code/frontend/src/components/Core/TableColumnFilterDialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 | {{ scope.row.prop }}
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
27 |
28 |
29 |
30 |
85 |
86 |
89 |
--------------------------------------------------------------------------------
/code/frontend/src/components/Core/TableTreeColumn.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ scope.row[prop] }}
7 |
8 |
9 |
10 |
11 |
12 |
85 |
--------------------------------------------------------------------------------
/code/frontend/src/components/FaIconTooltip/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
推荐使用 Font Aweson 图标
5 |
使用步骤:
6 |
1.进入 Font Aweson 页面
7 |
2.查找到需要的图标,点击查看。
8 |
3.复制图片样式到此处。
9 |
示例:fa fa-home fa-lg
10 |
11 |
12 |
13 |
14 |
25 |
26 |
31 |
--------------------------------------------------------------------------------
/code/frontend/src/components/Hamburger/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
16 |
17 |
37 |
38 |
53 |
--------------------------------------------------------------------------------
/code/frontend/src/components/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ msg }}
4 |
5 | For a guide and recipes on how to configure / customize this project,
6 | check out the
7 | vue-cli documentation.
8 |
9 |
Installed CLI Plugins
10 |
主要按钮
11 |
17 |
Essential Links
18 |
25 |
Ecosystem
26 |
33 |
34 |
35 |
36 |
44 |
45 |
46 |
62 |
--------------------------------------------------------------------------------
/code/frontend/src/components/MenuTree/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{menu.name}}
8 |
9 |
10 |
11 |
12 |
13 | {{menu.name}}
14 |
15 |
16 |
17 |
41 |
42 |
45 |
--------------------------------------------------------------------------------
/code/frontend/src/components/PopupTreeInput/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
58 |
59 |
62 |
--------------------------------------------------------------------------------
/code/frontend/src/components/Sys/Log.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
17 |
18 |
19 |
20 |
21 |
75 |
76 |
79 |
--------------------------------------------------------------------------------
/code/frontend/src/components/Sys/Loginlog.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
17 |
18 |
19 |
20 |
21 |
73 |
74 |
77 |
--------------------------------------------------------------------------------
/code/frontend/src/components/Sys/Online.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
17 |
18 |
19 |
20 |
21 |
73 |
74 |
77 |
--------------------------------------------------------------------------------
/code/frontend/src/http/api.js:
--------------------------------------------------------------------------------
1 | import * as config from './modules/config'
2 | import * as dept from './modules/dept'
3 | import * as dict from './modules/dict'
4 | import * as log from './modules/log'
5 | import * as login from './modules/login'
6 | import * as loginlog from './modules/loginlog'
7 | import * as menu from './modules/menu'
8 | import * as role from './modules/role'
9 | import * as user from './modules/user'
10 |
11 | // 默认全部导出
12 | export default {
13 | config, dept, dict, log, login, loginlog, menu, role, user
14 | }
15 |
--------------------------------------------------------------------------------
/code/frontend/src/http/axios.js:
--------------------------------------------------------------------------------
1 | /**
2 | * axios拦截器,可以进行请求拦截和相应拦截,在发送请求和相应请求时执行一些操作
3 | */
4 | import axios from 'axios'
5 | import config from './config'
6 | import Cookies from 'js-cookie'
7 | import router from '../router'
8 |
9 | export default function $axios (options) {
10 | // Promise是异步编程的一种解决方案, 有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数(例如ajax调用)
11 | return new Promise((resolve, reject) => {
12 | const instance = axios.create({
13 | baseURL: config.baseUrl,
14 | headers: config.headers,
15 | timeout: config.timeout,
16 | withCredentials: config.withCredentials
17 | })
18 |
19 | // request请求拦截器
20 | instance.interceptors.request.use(
21 | config => {
22 | let token = Cookies.get('token')
23 | if (token) { // 如果Cookie里有token就在发送请求的时候带上。
24 | config.headers.token = token
25 | } else { // Cookie中没有token,说明用户还没登录,跳转到登录页
26 | router.push('/login') // 实际可以用this.$router.push('router中的路径')来进行跳转,因为在main.js中已经全局注册了router
27 | }
28 | return config
29 | },
30 | error => {
31 | return Promise.reject(error)
32 | }
33 | )
34 |
35 | // response响应拦截器
36 | instance.interceptors.response.use(
37 | response => {
38 | return response.data
39 | },
40 | error => {
41 | return Promise.reject(error)
42 | }
43 | )
44 |
45 | // 请求处理
46 | instance(options).then(res => {
47 | resolve(res)
48 | return false
49 | }).catch(error => {
50 | reject(error)
51 | })
52 | })
53 | }
54 |
--------------------------------------------------------------------------------
/code/frontend/src/http/config.js:
--------------------------------------------------------------------------------
1 | import { baseUrl } from '../utils/global'
2 |
3 | export default {
4 | method: 'get',
5 | // 基础url前缀
6 | baseUrl: baseUrl,
7 | // 请求头信息
8 | headers: {
9 | 'Content-type': 'application/json;charset=UTF-8'
10 | },
11 | // 参数
12 | data: {},
13 | // 设置超时时间,单位毫秒
14 | timeout: 10000,
15 | // 携带凭证
16 | withCredentials: true,
17 | // 返回数据类型
18 | responseType: 'json'
19 | }
20 |
--------------------------------------------------------------------------------
/code/frontend/src/http/index.js:
--------------------------------------------------------------------------------
1 | import api from './api' // 导入所有接口
2 |
3 | const install = Vue => {
4 | if (install.installed) {
5 | return
6 | }
7 | install.installed = true
8 | Object.defineProperties(Vue.prototype, {
9 | // 注意,此处挂载在Vue原型的$api对象上
10 | $api: {
11 | get () {
12 | return api
13 | }
14 | }
15 | })
16 | }
17 | export default install
18 |
--------------------------------------------------------------------------------
/code/frontend/src/http/modules/config.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 | import REST_URLS from './index'
3 |
4 | export const save = (data) => {
5 | return axios({
6 | url: REST_URLS.ConfigSave,
7 | method: 'post',
8 | data
9 | })
10 | }
11 |
12 | export const batchDelete = (data) => {
13 | return axios({
14 | url: REST_URLS.ConfigDelete,
15 | method: 'post',
16 | data
17 | })
18 | }
19 |
20 | export const findPage = (data) => {
21 | return axios({
22 | url: REST_URLS.ConfigPage,
23 | method: 'post',
24 | data
25 | })
26 | }
27 |
--------------------------------------------------------------------------------
/code/frontend/src/http/modules/dept.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 | import REST_URLS from './index'
3 |
4 | export const save = (data) => {
5 | return axios({
6 | url: REST_URLS.DeptSave,
7 | method: 'post',
8 | data
9 | })
10 | }
11 |
12 | export const batchDelete = (data) => {
13 | return axios({
14 | url: REST_URLS.DeptDelete,
15 | method: 'post',
16 | data
17 | })
18 | }
19 |
20 | export const findDeptTree = () => {
21 | return axios({
22 | url: REST_URLS.DeptTree,
23 | method: 'get'
24 | })
25 | }
26 |
--------------------------------------------------------------------------------
/code/frontend/src/http/modules/dict.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 | import REST_URLS from './index'
3 |
4 | export const save = (data) => {
5 | return axios({
6 | url: REST_URLS.DictSave,
7 | method: 'post',
8 | data
9 | })
10 | }
11 |
12 | export const batchDelete = (data) => {
13 | return axios({
14 | url: REST_URLS.DictDelete,
15 | method: 'post',
16 | data
17 | })
18 | }
19 |
20 | export const findPage = (data) => {
21 | return axios({
22 | url: REST_URLS.DictPage,
23 | method: 'post',
24 | data
25 | })
26 | }
27 |
--------------------------------------------------------------------------------
/code/frontend/src/http/modules/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 所有接口的url
3 | */
4 | const modules = ['config', 'dept', 'dict', 'log', 'login', 'loginlog', 'menu', 'role', 'user']
5 | const REST_URLS = {
6 | // 1.系统配置接口
7 | ConfigSave: `/${modules[0]}/save`, // 保存
8 | ConfigDelete: `/${modules[0]}/delete`, // 删除
9 | ConfigPage: `/${modules[0]}/findPage`, // 分页查询
10 |
11 | // 2.机构管理模块
12 | DeptSave: `/${modules[1]}/save`, // 保存
13 | DeptDelete: `/${modules[1]}/delete`, // 删除
14 | DeptTree: `/${modules[1]}/findTree`, // 查询机构树
15 |
16 | // 3.字典管理模块
17 | DictSave: `/${modules[2]}/save`, // 保存
18 | DictDelete: `/${modules[2]}/delete`, // 删除
19 | DictPage: `/${modules[2]}/findPage`, // 分页查询
20 |
21 | // 4.操作日志模块
22 | LogDelete: `/${modules[3]}/delete`, // 删除
23 | LogPage: `/${modules[3]}/findPage`, // 分页查询
24 |
25 | // 5.系统登录模块
26 | Login: `login`, // 登录
27 | Logout: `logout`, // 登出
28 |
29 | // 6.登录日志模块
30 | LoginlogDelete: `/${modules[5]}/delete`,
31 | LoginlogPage: `/${modules[5]}/findPage`, // 分页查询
32 |
33 | // 7.菜单管理模块
34 | MenuSave: `/${modules[6]}/save`, // 保存
35 | MenuDelete: `/${modules[6]}/delete`, // 删除
36 | MenuNavTree: `/${modules[6]}/findNavTree`, // 获取导航树
37 | MenuTree: `/${modules[6]}/findMenuTree`, // 获取菜单树
38 |
39 | // 8.角色管理模块
40 | RoleSave: `/${modules[7]}/save`, // 保存
41 | RoleDelete: `/${modules[7]}/delete`, // 删除
42 | RolePage: `/${modules[7]}/findPage`, // 分页查询
43 | RoleAll: `/${modules[7]}/findAll`, // 获取所有角色
44 | RoleMenusGet: `/${modules[7]}/findRoleMenus`, // 获取指定角色可以访问的菜单集合
45 | RoleMenusSave: `/${modules[7]}/saveRoleMenus`, // 保存指定角色可以访问的菜单集合
46 |
47 | // 9.用户管理模块
48 | UserSave: `/${modules[8]}/save`, // 保存
49 | UserDelete: `/${modules[8]}/delete`, // 删除
50 | UserPage: `/${modules[8]}/findPage`, // 分页查询
51 | UserPermissions: `/${modules[8]}/findPermissions` // 获取指定用户的菜单权限集合
52 | }
53 | export default REST_URLS
54 |
--------------------------------------------------------------------------------
/code/frontend/src/http/modules/log.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 | import REST_URLS from './index'
3 |
4 | export const batchDelete = (data) => {
5 | return axios({
6 | url: REST_URLS.LogDelete,
7 | method: 'post',
8 | data
9 | })
10 | }
11 |
12 | export const findPage = (data) => {
13 | return axios({
14 | url: REST_URLS.LogPage,
15 | method: 'post',
16 | data
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/code/frontend/src/http/modules/login.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 | import REST_URLS from './index'
3 |
4 | export const login = (data) => {
5 | return axios({
6 | url: REST_URLS.Login,
7 | method: 'post',
8 | data
9 | })
10 | }
11 |
12 | export const logout = () => {
13 | return axios({
14 | url: REST_URLS.Logout,
15 | method: 'get'
16 | })
17 | }
18 |
--------------------------------------------------------------------------------
/code/frontend/src/http/modules/loginlog.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 | import REST_URLS from './index'
3 |
4 | export const batchDelete = (data) => {
5 | return axios({
6 | url: REST_URLS.LoginlogDelete,
7 | method: 'post',
8 | data
9 | })
10 | }
11 |
12 | export const findPage = (data) => {
13 | return axios({
14 | url: REST_URLS.LoginlogPage,
15 | method: 'post',
16 | data
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/code/frontend/src/http/modules/menu.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 | import REST_URLS from './index'
3 |
4 | export const save = (data) => {
5 | return axios({
6 | url: REST_URLS.MenuSave,
7 | method: 'post',
8 | data
9 | })
10 | }
11 |
12 | export const batchDelete = (data) => {
13 | return axios({
14 | url: REST_URLS.MenuDelete,
15 | method: 'post',
16 | data
17 | })
18 | }
19 |
20 | export const findNavTree = (params) => {
21 | return axios({
22 | url: REST_URLS.MenuNavTree,
23 | method: 'get',
24 | params
25 | })
26 | }
27 |
28 | export const findMenuTree = () => {
29 | return axios({
30 | url: REST_URLS.MenuTree,
31 | method: 'get'
32 | })
33 | }
34 |
--------------------------------------------------------------------------------
/code/frontend/src/http/modules/role.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 | import REST_URLS from './index'
3 |
4 | export const save = (data) => {
5 | return axios({
6 | url: REST_URLS.RoleSave,
7 | method: 'post',
8 | data
9 | })
10 | }
11 |
12 | export const batchDelete = (data) => {
13 | return axios({
14 | url: REST_URLS.RoleDelete,
15 | method: 'post',
16 | data
17 | })
18 | }
19 |
20 | export const findPage = (data) => {
21 | return axios({
22 | url: REST_URLS.RolePage,
23 | method: 'post',
24 | data
25 | })
26 | }
27 |
28 | export const findAll = () => {
29 | return axios({
30 | url: REST_URLS.RoleAll,
31 | method: 'get'
32 | })
33 | }
34 |
35 | export const findRoleMenus = (params) => {
36 | return axios({
37 | url: REST_URLS.RoleMenusGet,
38 | method: 'get',
39 | params
40 | })
41 | }
42 |
43 | export const saveRoleMenus = (data) => {
44 | return axios({
45 | url: REST_URLS.RoleMenusSave,
46 | method: 'post',
47 | data
48 | })
49 | }
50 |
--------------------------------------------------------------------------------
/code/frontend/src/http/modules/user.js:
--------------------------------------------------------------------------------
1 | import axios from '../axios'
2 | import REST_URLS from './index'
3 |
4 | export const save = (data) => {
5 | return axios({
6 | url: REST_URLS.UserSave,
7 | method: 'post',
8 | data
9 | })
10 | }
11 |
12 | export const batchDelete = (data) => {
13 | return axios({
14 | url: REST_URLS.UserDelete,
15 | method: 'post',
16 | data
17 | })
18 | }
19 |
20 | export const findPage = (data) => {
21 | return axios({
22 | url: REST_URLS.UserPage,
23 | method: 'post',
24 | data
25 | })
26 | }
27 |
28 | export const findPermissions = (params) => {
29 | return axios({
30 | url: REST_URLS.UserPermissions,
31 | method: 'get',
32 | params
33 | })
34 | }
35 |
--------------------------------------------------------------------------------
/code/frontend/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import api from './http'
5 | import i18n from './utils/i18n'
6 | import global from './utils/global'
7 | import store from './store'
8 | import ElementUI from 'element-ui'
9 | import 'element-ui/lib/theme-chalk/index.css'
10 | import 'font-awesome/css/font-awesome.min.css'
11 |
12 | import Router from 'vue-router'
13 |
14 | // 避免$route.push的时候没有接住Promise表达式而报错
15 | const originalPush = Router.prototype.push
16 | Router.prototype.push = function push (location) {
17 | return originalPush.call(this, location).catch(err => err)
18 | }
19 |
20 | Vue.config.productionTip = false
21 |
22 | Vue.use(api) // 注册使用API模块
23 |
24 | Vue.use(ElementUI) // 注册使用ElementUI模块
25 |
26 | Vue.prototype.global = global // 挂载全局配置模块
27 |
28 | new Vue({
29 | i18n,
30 | router,
31 | store,
32 | render: h => h(App)
33 | }).$mount('#app')
34 |
--------------------------------------------------------------------------------
/code/frontend/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | // 引入子模块
5 | import app from './modules/app'
6 | import user from './modules/user'
7 | import menu from './modules/menu'
8 | import tab from './modules/tab'
9 | import iframe from './modules/iframe'
10 |
11 | Vue.use(Vuex)
12 |
13 | const store = new Vuex.Store({
14 | state: {},
15 | mutations: {},
16 | actions: {},
17 | modules: {
18 | app: app, // 键值相同时应该可以缩写成单个的app,这里就不省略了
19 | iframe: iframe,
20 | user: user,
21 | tab: tab,
22 | menu: menu
23 | }
24 | })
25 | export default store
26 |
--------------------------------------------------------------------------------
/code/frontend/src/store/modules/app.js:
--------------------------------------------------------------------------------
1 | export default {
2 | state: {
3 | appName: 'Vue Admin', // 应用名称
4 | themeColor: '#14889A', // 主题颜色
5 | oldThemeColor: '#14889A', // 上一次主题颜色
6 | collapse: false, // 导航栏收缩状态
7 | menuRouteLoaded: false // 菜单和路由是否已经加载
8 | },
9 | getters: {
10 | collapse (state) {
11 | // 对应着上面的state
12 | return state.collapse
13 | }
14 | },
15 | mutations: {
16 | onCollapse (state) {
17 | // 改变收缩状态
18 | state.collapse = !state.collapse
19 | },
20 | setThemeColor (state, newThemeColor) {
21 | // 改变主题颜色
22 | state.oldThemeColor = state.themeColor
23 | state.themeColor = newThemeColor
24 | },
25 | menuRouteLoaded (state, menuRouteLoaded) {
26 | // 改变菜单加载状态
27 | state.menuRouteLoaded = menuRouteLoaded
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/code/frontend/src/store/modules/iframe.js:
--------------------------------------------------------------------------------
1 | /***********************************************************
2 | * @Description : 嵌套页面
3 | * @author : 梁山广(Liang Shan Guang)
4 | * @date : 2019/11/28 7:47
5 | * @email : liangshanguang2@gmail.com
6 | ***********************************************************/
7 | export default {
8 | state: {
9 | iframeUrl: [], // 当前嵌套页面路由路径
10 | iframeUrls: [] // 所有嵌套页面路由路径访问URL
11 | },
12 | getters: {},
13 | mutations: {
14 | setIFrameUrl (state, iframeUrl) { // 设置iframeUrl
15 | state.iframeUrl = iframeUrl
16 | },
17 | addIFrameUrl (state, iframeUrl) { // iframeUrls
18 | state.iframeUrls.push(iframeUrl)
19 | }
20 | },
21 | actions: {}
22 | }
23 |
--------------------------------------------------------------------------------
/code/frontend/src/store/modules/menu.js:
--------------------------------------------------------------------------------
1 | export default {
2 | state: {
3 | navTree: [] // 导航菜单树
4 | },
5 | getters: {},
6 | mutations: {
7 | // 设置导航菜单树
8 | setNavTree (state, navTree) {
9 | state.navTree = navTree
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/code/frontend/src/store/modules/tab.js:
--------------------------------------------------------------------------------
1 | /***********************************************************
2 | * @Description : 标签页管理功能
3 | * @author : 梁山广(Liang Shan Guang)
4 | * @date : 2019/11/26 23:59
5 | * @email : liangshanguang2@gmail.com
6 | ***********************************************************/
7 | export default {
8 | state: {
9 | // 主入口标签
10 | mainTabs: [],
11 | // 当前页标签
12 | mainTabsActiveName: ''
13 | },
14 | mutations: {
15 | updateMainTabs (state, tabs) {
16 | state.mainTabs = tabs
17 | },
18 | updateMainTabsActiveName (state, name) {
19 | state.mainTabsActiveName = name
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/code/frontend/src/store/modules/user.js:
--------------------------------------------------------------------------------
1 | export default {
2 | state: {
3 | perms: [] // 用户权限标识集合,记录可以访问哪些路由
4 | },
5 | getters: {},
6 | mutations: {
7 | setPerms (state, perms) {
8 | // 设置用户权限标识集合
9 | state.perms = perms
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/code/frontend/src/utils/datetime.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 时间日期相关操作
3 | */
4 |
5 | /**
6 | * 时间格式化
7 | * 将 2018-09-23T11:54:16.000+0000 格式化成 2018-09-23 11:54:16
8 | * @param datetime 国际化日期格式
9 | */
10 | export function format (datetime) {
11 | return formatWithSeparator(datetime, '-', ':')
12 | }
13 |
14 | /**
15 | * 时间格式化
16 | * 将 2018-09-23T11:54:16.000+0000 格式化成类似 2018/09/23 11:54:16
17 | * 可以指定日期和时间分隔符
18 | * @param datetime 国际化日期格式
19 | * @param dateSeparator 日期分隔符(年月日的分隔符)
20 | * @param timeSeparator 时间分隔符(时分秒的分隔符)
21 | */
22 | export function formatWithSeparator (datetime, dateSeparator, timeSeparator) {
23 | if (datetime != null) {
24 | const dateMat = new Date(datetime)
25 | const year = dateMat.getFullYear()
26 | const month = dateMat.getMonth() + 1
27 | const day = dateMat.getDate()
28 | const hh = dateMat.getHours()
29 | const mm = dateMat.getMinutes()
30 | const ss = dateMat.getSeconds()
31 | return year + dateSeparator + month + dateSeparator + day + ' ' + hh + timeSeparator + mm + timeSeparator + ss
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/code/frontend/src/utils/global.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 全局常量和方法封装模块
3 | * 通过原型prototype挂载到Vue属性
4 | * 通过this.Global调用
5 | */
6 |
7 | // 后台服务器的接口基地址
8 | export const baseUrl = '/api'
9 | // 图床的基地址
10 | export const picBaseUrl = 'https://i.loli.net'
11 |
12 | export default {
13 | baseUrl,
14 | picBaseUrl
15 | }
16 |
--------------------------------------------------------------------------------
/code/frontend/src/utils/i18n.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueI18n from 'vue-i18n'
3 |
4 | Vue.use(VueI18n)
5 |
6 | // 注册i18n实例并引入语言文件,文件格式等下解析
7 | const i18n = new VueI18n({
8 | locale: 'zh_cn',
9 | messages: {
10 | 'zh_cn': require('../assets/languages/zh_cn.json'),
11 | 'en_us': require('../assets/languages/en_us.json')
12 | }
13 | })
14 |
15 | export default i18n
16 |
--------------------------------------------------------------------------------
/code/frontend/src/utils/iframe.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 嵌套页面IFrame模块,主要用户URL替换和页面嵌入外部页面
3 | */
4 |
5 | import { baseUrl } from './global'
6 |
7 | /**
8 | * 嵌套页面URL地址
9 | * @param {*} url
10 | */
11 | export function getIFramePath (url) {
12 | let iframeUrl = ''
13 | if (/^iframe:.*/.test(url)) {
14 | iframeUrl = url.replace('iframe:', '')
15 | } else if (/^http[s]?:\/\/.*/.test(url)) {
16 | iframeUrl = url.replace('http://', '')
17 | if (iframeUrl.indexOf(':') !== -1) {
18 | iframeUrl = iframeUrl.substring(iframeUrl.lastIndexOf(':') + 1)
19 | }
20 | }
21 | return iframeUrl
22 | }
23 |
24 | /**
25 | * 嵌套页面路由路径
26 | * @param {*} url
27 | */
28 | export function getIFrameUrl (url) {
29 | let iframeUrl = ''
30 | if (/^iframe:.*/.test(url)) {
31 | iframeUrl = baseUrl + url.replace('iframe:', '')
32 | } else if (/^http[s]?:\/\/.*/.test(url)) {
33 | iframeUrl = url
34 | }
35 | return iframeUrl
36 | }
37 |
--------------------------------------------------------------------------------
/code/frontend/src/utils/permission.js:
--------------------------------------------------------------------------------
1 | import store from '../store'
2 |
3 | /**
4 | * 判断当前用户是否有操作权限。
5 | * 原理:根据传入的权限标识,查看总的权限列表perms中是否有指定的权限集合
6 | * @param perms 用户传入的权限集合
7 | * @returns {boolean} 用户是否有权限
8 | */
9 | export function hasPermission (perms) {
10 | let hasPermission = false
11 | let permissions = store.state.user.perms
12 | let len = permissions.length
13 | for (let i = 0; i < len; i++) {
14 | if (permissions[i] === perms) {
15 | hasPermission = true
16 | break
17 | }
18 | }
19 | return hasPermission
20 | }
21 |
--------------------------------------------------------------------------------
/code/frontend/src/utils/validate.js:
--------------------------------------------------------------------------------
1 | /***********************************************************
2 | * @Description : 正则匹配的工具类
3 | * @author : 梁山广(Liang Shan Guang)
4 | * @date : 2019/11/26 23:34
5 | * @email : liangshanguang2@gmail.com
6 | ***********************************************************/
7 |
8 | /**
9 | * 邮箱
10 | * @param {*} s
11 | */
12 | export function isEmail (s) {
13 | return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(s)
14 | }
15 |
16 | /**
17 | * 手机号码
18 | * @param {*} s
19 | */
20 | export function isMobile (s) {
21 | return /^1[0-9]{10}$/.test(s)
22 | }
23 |
24 | /**
25 | * 电话号码
26 | * @param {*} s
27 | */
28 | export function isPhone (s) {
29 | return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(s)
30 | }
31 |
32 | /**
33 | * URL地址
34 | * @param {*} s
35 | */
36 | export function isURL (s) {
37 | return /^http[s]?:\/\/.*/.test(s)
38 | }
39 |
--------------------------------------------------------------------------------
/code/frontend/src/views/404.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
404
6 |
抱歉!您访问的页面失联啦 ...
7 |
返回上一页
8 |
进入首页
9 |
10 |
11 |
12 |
13 |
14 |
19 |
20 |
69 |
--------------------------------------------------------------------------------
/code/frontend/src/views/About.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
This is an about page
4 |
5 |
6 |
--------------------------------------------------------------------------------
/code/frontend/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
28 |
29 |
38 |
--------------------------------------------------------------------------------
/code/frontend/src/views/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 系统登录
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | 重置
29 | 登录
30 |
31 |
32 |
33 |
34 |
35 |
97 |
98 |
118 |
--------------------------------------------------------------------------------
/code/frontend/src/views/NavBar.vue:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
86 |
87 |
136 |
--------------------------------------------------------------------------------
/code/frontend/vue.config.js:
--------------------------------------------------------------------------------
1 | // https://cli.vuejs.org/zh/config/#vue-config-js
2 | module.exports = {
3 | devServer: {
4 | port: 7777,
5 | proxy: 'http://localhost:9528'
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/images/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lsgwr/spring-cloud-vue-admin/e399bc238e486cef481ecbe789c57c433428715d/images/home.png
--------------------------------------------------------------------------------