├── .env.production
├── .env.development
├── public
├── favicon.ico
└── index.html
├── src
├── assets
│ ├── logo.png
│ ├── image
│ │ ├── app.jpg
│ │ ├── uni.png
│ │ ├── vue.png
│ │ ├── login.jpg
│ │ └── react.jpg
│ ├── font
│ │ ├── webfont.eot
│ │ ├── webfont.ttf
│ │ ├── webfont.woff
│ │ ├── webfont.woff2
│ │ └── wenfont.css
│ └── icon
│ │ ├── circle.svg
│ │ ├── count.svg
│ │ ├── visitors.svg
│ │ ├── vue.svg
│ │ ├── zhuye.svg
│ │ ├── money.svg
│ │ ├── refuse.svg
│ │ ├── sales.svg
│ │ ├── refund.svg
│ │ ├── favorite.svg
│ │ ├── dynamic.svg
│ │ ├── ship.svg
│ │ ├── flag.svg
│ │ ├── feedback.svg
│ │ ├── u.svg
│ │ ├── crying.svg
│ │ ├── herd.svg
│ │ ├── screen.svg
│ │ ├── views.svg
│ │ ├── clear.svg
│ │ ├── email.svg
│ │ ├── app.svg
│ │ ├── news.svg
│ │ ├── analysis.svg
│ │ ├── horn.svg
│ │ ├── deal.svg
│ │ ├── finance.svg
│ │ ├── shelves.svg
│ │ ├── laugh.svg
│ │ ├── github2.svg
│ │ ├── reduction.svg
│ │ ├── approval.svg
│ │ ├── operating.svg
│ │ ├── group.svg
│ │ ├── order.svg
│ │ ├── nodejs.svg
│ │ ├── sort.svg
│ │ ├── registration.svg
│ │ ├── github.svg
│ │ ├── daiban.svg
│ │ ├── react.svg
│ │ └── friend.svg
├── views
│ ├── home
│ │ ├── Index.vue
│ │ └── Informationall.vue
│ ├── marketing
│ │ ├── Produce.vue
│ │ ├── Choice.vue
│ │ └── Spike.vue
│ ├── Home.vue
│ ├── communication
│ │ ├── WeChat.vue
│ │ └── Index.vue
│ ├── analyze
│ │ └── Index.vue
│ ├── control
│ │ ├── KeyCode.vue
│ │ └── Placard.vue
│ ├── goods
│ │ ├── FromGood.vue
│ │ ├── OnIndex.vue
│ │ └── OffIndex.vue
│ ├── coupon
│ │ └── AddCoupon.vue
│ └── login
│ │ └── Login.vue
├── utils
│ ├── auth.js
│ └── theme.js
├── App.vue
├── store
│ ├── index.js
│ └── modules
│ │ ├── user.js
│ │ ├── permission.js
│ │ └── tagsView.js
├── components
│ ├── Sidebar
│ │ ├── Item.vue
│ │ ├── index.vue
│ │ └── SidebarItem.vue
│ ├── Dropdown
│ │ ├── empy.vue
│ │ ├── newsBox.vue
│ │ ├── matter.vue
│ │ ├── drop.vue
│ │ └── index.vue
│ ├── analyze
│ │ ├── pay.vue
│ │ ├── client.vue
│ │ ├── cards.vue
│ │ ├── monitorcar.vue
│ │ ├── product.vue
│ │ └── maps.vue
│ ├── TageView
│ │ └── ScrollPane.vue
│ ├── Breadcrumb
│ │ ├── Breadcrumb2.vue
│ │ └── Breadcrumb.vue
│ ├── Home
│ │ └── InformationList.vue
│ └── Index
│ │ ├── fast.vue
│ │ ├── colleague.vue
│ │ ├── dynamicBox.vue
│ │ └── project.vue
├── directive
│ └── permission.js
├── main.js
├── http
│ └── index.js
└── router
│ └── permission.js
├── babel.config.js
├── .gitignore
├── vue.config.js
├── README.md
└── package.json
/.env.production:
--------------------------------------------------------------------------------
1 | # 上线环境
2 | VUE_APP_BASE_API = '/api'
--------------------------------------------------------------------------------
/.env.development:
--------------------------------------------------------------------------------
1 | ## base API 测试环境
2 | VUE_APP_BASE_API = '/api'
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cgq001/admin-menu/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cgq001/admin-menu/HEAD/src/assets/logo.png
--------------------------------------------------------------------------------
/src/assets/image/app.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cgq001/admin-menu/HEAD/src/assets/image/app.jpg
--------------------------------------------------------------------------------
/src/assets/image/uni.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cgq001/admin-menu/HEAD/src/assets/image/uni.png
--------------------------------------------------------------------------------
/src/assets/image/vue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cgq001/admin-menu/HEAD/src/assets/image/vue.png
--------------------------------------------------------------------------------
/src/assets/font/webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cgq001/admin-menu/HEAD/src/assets/font/webfont.eot
--------------------------------------------------------------------------------
/src/assets/font/webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cgq001/admin-menu/HEAD/src/assets/font/webfont.ttf
--------------------------------------------------------------------------------
/src/assets/image/login.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cgq001/admin-menu/HEAD/src/assets/image/login.jpg
--------------------------------------------------------------------------------
/src/assets/image/react.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cgq001/admin-menu/HEAD/src/assets/image/react.jpg
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/src/assets/font/webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cgq001/admin-menu/HEAD/src/assets/font/webfont.woff
--------------------------------------------------------------------------------
/src/assets/font/webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cgq001/admin-menu/HEAD/src/assets/font/webfont.woff2
--------------------------------------------------------------------------------
/src/views/home/Index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 个人中心
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/views/marketing/Produce.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/assets/icon/circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
5 |
6 |
7 |
8 |
19 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/src/utils/auth.js:
--------------------------------------------------------------------------------
1 | import Cookie from 'js-cookie';
2 |
3 | const Token = 'token';
4 |
5 | export function getToken(){
6 | return Cookie.get(Token);
7 | }
8 |
9 | export function setToken(token){
10 | return Cookie.set(Token,token)
11 | }
12 |
13 | export function removeToken(){
14 | return Cookie.remove(Token)
15 | }
--------------------------------------------------------------------------------
/src/assets/icon/count.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/visitors.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | publicPath: "/admin-vue/",
3 | // 关闭线上源码
4 | productionSourceMap: false,
5 | chainWebpack: (config) => {
6 | const svgRule = config.module.rule('svg');
7 |
8 | svgRule.uses.clear();
9 |
10 | svgRule
11 | .use('babel-loader')
12 | .loader('babel-loader')
13 | .end()
14 | .use('vue-svg-loader')
15 | .loader('vue-svg-loader');
16 | }
17 | }
--------------------------------------------------------------------------------
/src/utils/theme.js:
--------------------------------------------------------------------------------
1 | import Cookie from 'js-cookie';
2 |
3 | const Theme = 'theme';
4 |
5 | export function getTheme(){
6 | return window.localStorage.getItem(Theme)
7 | // return Cookie.get(Theme);
8 | }
9 |
10 | export function setTheme(token){
11 | // return Cookie.set(Theme,token)
12 | return window.localStorage.setItem(Theme,token)
13 | }
14 |
15 | export function removeTheme(){
16 | return window.localStorage.removeItem(Theme)
17 | // return Cookie.remove(Theme)
18 | }
--------------------------------------------------------------------------------
/src/assets/icon/vue.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/views/communication/WeChat.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
15 |
16 |
29 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import permission from './modules/permission'
4 | import user from './modules/user'
5 | import tagsView from './modules/tagsView'
6 | Vue.use(Vuex)
7 |
8 | export default new Vuex.Store({
9 | state: {
10 | },
11 | mutations: {
12 | },
13 | actions: {
14 | },
15 | modules: {
16 | permission,
17 | user,
18 | tagsView
19 | },
20 | // 定义全局getters 方便访问user 模块的roles
21 | getters:{
22 | roles: state => state.user.roles,
23 | permission_routes: state => state.permission.routes
24 | }
25 | })
26 |
--------------------------------------------------------------------------------
/src/assets/font/wenfont.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'webfont';
3 | font-display: swap;
4 | src: url('webfont.eot'); /* IE9 */
5 | src: url('webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
6 | url('webfont.woff2') format('woff2'),
7 | url('webfont.woff') format('woff'), /* chrome��firefox */
8 | url('webfont.ttf') format('truetype'), /* chrome��firefox��opera��Safari, Android, iOS 4.2+*/
9 | url('webfont.svg#webfont') format('svg'); /* iOS 4.1- */
10 | }
11 |
12 | html,body,#app{
13 | font-family: "webfont" !important;
14 | font-size: 16px;
15 | font-style: normal;
16 | }
--------------------------------------------------------------------------------
/src/assets/icon/zhuye.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/money.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/refuse.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/sales.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/refund.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/favorite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/Sidebar/Item.vue:
--------------------------------------------------------------------------------
1 |
32 |
--------------------------------------------------------------------------------
/src/assets/icon/dynamic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/ship.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # power
3 | vue后台管理系统模板
4 | 见文章: https://juejin.im/post/5e670edde51d4527110a9b40
5 |
6 | # 说明
7 | >默认(主)版本为基础框架版
8 |
9 | 丰富组件 请访问 2.0版本: https://github.com/cgq001/admin-menu/tree/2.0
10 |
11 |
12 | ## 初始化
13 | ```
14 | yarn install
15 | ```
16 | ### 运行
17 | ```
18 | yarn run serve
19 | ```
20 | ### 打包
21 | ```
22 | yarn run build
23 | ```
24 | ##
25 | ## 后台管理通用框架2.0效果图(正在更新中...)
26 | ### 1.登陆
27 | 
28 | ### 2.工作台
29 | 
30 | ### 3.通知
31 | 
32 | ### 4.主题
33 | 
34 | ### 5.发邮件
35 | 
36 | ### 6.通知详情
37 | 
38 | 目前可实现Excel表格下载,请见MarkDown文档,下一步规划图标功能
39 |
40 |
--------------------------------------------------------------------------------
/src/assets/icon/flag.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/feedback.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/u.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/crying.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/herd.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/screen.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "power",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build"
8 | },
9 | "dependencies": {
10 | "@jiaminghi/data-view": "^2.10.0",
11 | "axios": "^0.19.2",
12 | "core-js": "^3.6.4",
13 | "echarts": "^4.8.0",
14 | "element-ui": "^2.13.0",
15 | "js-cookie": "^2.2.1",
16 | "nprogress": "^0.2.0",
17 | "screenfull": "^5.0.2",
18 | "v-charts": "^1.19.0",
19 | "vue": "^2.6.11",
20 | "vue-count-to": "^1.0.13",
21 | "vue-grid-layout": "^2.3.7",
22 | "vue-particles": "^1.0.9",
23 | "vue-router": "^3.1.5",
24 | "vue-seamless-scroll": "^1.1.17",
25 | "vue-svg-loader": "^0.16.0",
26 | "vue-template-compiler": "^2.6.11",
27 | "vuex": "^3.1.2",
28 | "wangeditor": "^3.1.1",
29 | "xlsx": "^0.15.6"
30 | },
31 | "devDependencies": {
32 | "@vue/cli-plugin-babel": "^4.2.0",
33 | "@vue/cli-service": "^4.2.0",
34 | "sass": "^1.25.0",
35 | "sass-loader": "^8.0.2",
36 | "vue-happy-scroll": "^2.1.1"
37 | },
38 | "browserslist": [
39 | "> 1%",
40 | "last 2 versions"
41 | ]
42 | }
43 |
--------------------------------------------------------------------------------
/src/assets/icon/views.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/clear.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/email.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/app.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/news.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/directive/permission.js:
--------------------------------------------------------------------------------
1 | // 封装一个指令v-permission,从而实现按钮级别权限控制
2 | import store from '@/store'
3 | /**
4 | * 指令的使用
5 | * v-permission="['admin','editor']"
6 | *
7 | */
8 | const permission = {
9 | inserted(el, binding){
10 | /**
11 | * el 当前指令的元素
12 | * binding {name,expression,vale}等
13 | * */
14 | // 获取指令的值: 按钮要求的角色数组
15 | const { value: pRoles } = binding;
16 | // 获取用户角色
17 | const roles = store.getters && store.getters.roles
18 |
19 | if(pRoles && pRoles instanceof Array && pRoles.length >0 ){
20 | // 判断用户角色中是否有按钮要求的角色
21 | const hasPermission = roles.some(role => {
22 | return pRoles.includes(role);
23 | })
24 | // console.log(hasPermission)
25 | // 如果没有权限则删除当前DOM
26 | if(!hasPermission){
27 | el.parentNode && el.parentNode.removeChild(el);
28 | }
29 | }else{
30 | throw new Error(`需要指定按钮要求角色数组,如v-permission="['admin','editor']"`)
31 | }
32 | }
33 | }
34 |
35 | export default permission;
36 |
37 |
38 | /**
39 | * 全局注册指令
40 | * import vPermission from './directive/permission'
41 | * Vue.directive('permission',vPermission)
42 | *
43 | * 使用
44 | *
45 | * */
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import store from './store'
5 |
6 | import ElementUI from 'element-ui';
7 | import 'element-ui/lib/theme-chalk/index.css';
8 |
9 | // 引入进度条样式
10 | import 'nprogress/nprogress.css'
11 |
12 | //引入自定义滚动条
13 | import HappyScroll from 'vue-happy-scroll'
14 | import 'vue-happy-scroll/docs/happy-scroll.css'
15 |
16 | //自动滚动插件
17 | import scroll from 'vue-seamless-scroll'
18 |
19 | // 炫酷的粒子动效
20 | import VueParticles from 'vue-particles'
21 |
22 | // 引入图表
23 | import VCharts from 'v-charts'
24 |
25 | Vue.use(VCharts)
26 |
27 | // 制作地图
28 | import echarts from 'echarts'
29 | Vue.prototype.$echarts = echarts
30 | import china from 'echarts/map/json/china.json'
31 | echarts.registerMap('china', china)
32 |
33 | // 炫酷图标
34 | import dataV from '@jiaminghi/data-view'
35 |
36 | Vue.use(dataV)
37 |
38 |
39 | Vue.config.productionTip = false
40 |
41 | Vue.use(HappyScroll)
42 |
43 | Vue.use(scroll)
44 |
45 | Vue.use(VueParticles)
46 |
47 | Vue.use(ElementUI);
48 |
49 | // 全局路由守卫
50 | import './router/permission'
51 |
52 | // 全局注册指令
53 | import vPermission from './directive/permission'
54 | Vue.directive('permission',vPermission)
55 |
56 | new Vue({
57 | router,
58 | store,
59 | render: h => h(App)
60 | }).$mount('#app')
61 |
--------------------------------------------------------------------------------
/src/assets/icon/analysis.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/horn.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/deal.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/finance.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/shelves.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/laugh.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/Dropdown/empy.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
{{text}}
9 |
10 |
11 |
12 |
41 |
42 |
--------------------------------------------------------------------------------
/src/assets/icon/github2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/reduction.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/store/modules/user.js:
--------------------------------------------------------------------------------
1 | import { getToken, setToken, removeToken } from '@/utils/auth'
2 |
3 | // 村赤用户令牌和角色信息
4 | const state ={
5 | token: getToken(),
6 | roles: [] //角色
7 | }
8 |
9 | const mutations ={
10 | SET_TOKEN: (state,token) => {
11 | state.token = token;
12 | },
13 | SET_ROLES: (state,roles) => {
14 | state.roles = roles;
15 | }
16 | };
17 |
18 | const actions = {
19 | // 用户登录
20 | login({ commit }, userInfo) {
21 | const { username } = userInfo;
22 | return new Promise((resolve,reject) => {
23 | setTimeout(() => {
24 | if(username === 'admin' || username === 'jerry'){
25 | // 保存状态
26 | commit('SET_TOKEN',username);
27 | // 写入cookie
28 | setToken(username)
29 | resolve()
30 | }else{
31 | reject('用户名或密码错误')
32 | }
33 | },1000)
34 | })
35 | },
36 | // 获取用户角色信息
37 | getInfo({ commit, state }){
38 | return new Promise((resolve) => {
39 | setTimeout(() => {
40 | const roles = state.token === 'admin' ? ['admin'] : ['jerry']
41 | commit('SET_ROLES',roles)
42 | resolve({roles})
43 | },1000)
44 | })
45 | },
46 | // 重置令牌
47 | resetToken({ commit }){
48 | return new Promise(resolve => {
49 | commit('SET_TOKEN','')
50 | commit('SET_ROLES',[])
51 | removeToken();
52 | resolve()
53 | })
54 | }
55 | }
56 |
57 | export default {
58 | namespaced: true,
59 | state,
60 | mutations,
61 | actions
62 | }
--------------------------------------------------------------------------------
/src/assets/icon/approval.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/operating.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/group.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/views/home/Informationall.vue:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
25 |
43 |
44 |
--------------------------------------------------------------------------------
/src/assets/icon/order.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/http/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import { MessageBox, Message } from 'element-ui'
3 | import store from '../store/index'
4 | import { getToken } from '@/utils/auth';
5 |
6 | // 创建axios实例
7 | const service = axios.create({
8 | baseURL: process.env.VUE_APP_BASE_API, //URL地址 环境变量文件 .env.development
9 | timeout: 5000 ,//超时
10 | withCredentials: true, //跨域时若要发生cookie,需要设置该选项
11 | })
12 |
13 | // 请求拦截器
14 | service.interceptors.request.use(
15 | config => {
16 | if(store.getters.token){
17 | // 设置令牌请求头
18 | config.headers['Authorization'] = getToken()
19 | }
20 | },
21 | error => {
22 | return Promise.reject(error)
23 | }
24 | )
25 |
26 | // 相应拦截
27 | service.interceptors.response.use(
28 | // 通过自定义code 判定响应状态 也可以通过HTTP状态码判断
29 | response =>{
30 | const res = response.data
31 |
32 | // code 不为0 则判断为一个错误
33 | if(res.code !== 0){
34 | Message({
35 | message: res.msg || "Error",
36 | type: 'error',
37 | duration: 5*1000
38 | })
39 |
40 |
41 | // 假设 10008 非法令牌 10012 其他客户端已经登陆
42 | if(res.code === 10008 || res.code === 10012){
43 | // 重新登陆
44 | MessageBox.confirm(
45 | '登陆状态异常,请重新登陆',
46 | "确认登陆信息",
47 | {
48 | confirmButtonText: '重新登陆',
49 | cancelButtonText: '取消',
50 | type: 'warning'
51 | }
52 | ).then(()=>{
53 | store.dispatch('user/resetToken')
54 | .then(()=>{
55 | location.reload()
56 | })
57 | })
58 | }
59 |
60 | return Promise.reject(new Error(res.message || 'Error'));
61 |
62 | }else{
63 | return res;
64 | }
65 | },
66 | error =>{
67 | Message({
68 | message: error.message,
69 | type: 'error',
70 | duration: 5*1000
71 | })
72 | }
73 | )
74 |
75 | export default service;
--------------------------------------------------------------------------------
/src/components/analyze/pay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
支付方式
5 |
6 |
7 | 近七天
8 | 本月
9 | 本年
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
35 |
--------------------------------------------------------------------------------
/src/router/permission.js:
--------------------------------------------------------------------------------
1 | // 路由的全局守卫
2 |
3 | // 权限控制逻辑
4 | import router from './index'
5 | import store from '../store/index'
6 |
7 | //引入nprogress 进度条插件
8 | import NProgress from 'nprogress'
9 |
10 | import { Message } from 'element-ui'
11 | import { getToken } from '@/utils/auth' // 从cookie获取令牌
12 |
13 | // 简单配置 进度条
14 | NProgress.inc(0.2)
15 | NProgress.configure({ easing: 'ease', speed: 500, showSpinner: false })
16 |
17 |
18 | const whiteList = ['/login'] //排除的路径
19 |
20 | router.beforeEach(async (to,from,next) => {
21 | NProgress.start()
22 | // 获取令牌判断用户是否登陆
23 | const hasToken = getToken()
24 | // 有令牌 表示已经登陆
25 | if(hasToken){
26 |
27 | if(to.path === '/login'){
28 |
29 | // 已登录重定向到首页
30 | next({path: '/'})
31 | }else{
32 |
33 | //若用户角色已附加则说明动态路由已经添加
34 | const hasRoles = store.getters.roles && store.getters.roles.length > 0
35 |
36 | if(hasRoles){
37 | //角色存在
38 | next() //继续即可
39 | } else {
40 | try {
41 | //先请求获取用户角色
42 | const { roles } = await store.dispatch('user/getInfo')
43 |
44 | // 根据当前用户角色动态生成路由
45 | const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
46 |
47 | // 添加这些路由至路由器
48 | router.addRoutes(accessRoutes)
49 |
50 | // 继续路由切换,确保addRoutes完成
51 | next({...to,replace: true})
52 | } catch(error){
53 | // 出错需要重置令牌并重新登陆(令牌过期,网络错误等原因)
54 | await store.dispatch('user/resetToken')
55 | Message.error(error || "网络错误")
56 | next(`/login?redirect=${to.path}`)
57 | }
58 | }
59 |
60 | }
61 | }else{
62 | // 用户无令牌
63 | if(whiteList.indexOf(to.path) !== -1){
64 | //白名单路由放过
65 | next()
66 | } else {
67 | // 重定向至登录页
68 | next(`/login?redirect=${to.path}`)
69 | }
70 | }
71 | })
72 |
73 | router.afterEach(() => {
74 | NProgress.done()
75 | })
--------------------------------------------------------------------------------
/src/assets/icon/nodejs.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 后台管理系统
10 |
65 |
74 |
75 |
76 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/src/components/TageView/ScrollPane.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
61 |
62 |
73 |
--------------------------------------------------------------------------------
/src/store/modules/permission.js:
--------------------------------------------------------------------------------
1 | // 权限管理模块
2 | import { asyncRoutes, constRouter } from '@/router'
3 |
4 | /**
5 | * 根据路由meta.role 确定是否当前用户拥有访问权限
6 | * @roles 用户拥有角色
7 | * @route 待判定路由
8 | *
9 | *
10 | *
11 | */
12 | function hasPermission (roles,route){
13 |
14 | // 如果当前路由有roles 字段则需要判断用户访问权限
15 | if(route.meta && route.meta.roles){
16 | // 若用户拥有的角色中有被包含在待定路由角色表中的则拥有访问权限
17 | return roles.some(role => route.meta.roles.includes(role))
18 | } else{
19 | // 没有设置roles 则无需判定即可访问
20 | return true;
21 | }
22 | }
23 |
24 | /**
25 | * 递归过滤AsyncRoutes路由表
26 | * @routes 待过滤路由表,首次传入的就是AsyncRoutes
27 | * @roles 用户拥有角色
28 | *
29 | */
30 | export function filterAsyncRoutes(routes,roles){
31 | const res = []
32 |
33 | routes.forEach(route => {
34 | // 复制一份
35 | const tmp = { ...route}
36 |
37 | // 如果用户有访问权限则加入结果路由表
38 | if(hasPermission(roles,tmp)){
39 | // 如果存在子路由则递归过滤之
40 | if(tmp.children){
41 | tmp.children = filterAsyncRoutes(tmp.children,roles)
42 | }
43 | res.push(tmp)
44 | }
45 | })
46 |
47 | return res;
48 | }
49 |
50 | const state = {
51 | routes: [], //完整路由表
52 | addRoutes: [] //用户可访问路由表
53 | }
54 |
55 | const mutations = {
56 | SET_ROUTES: (state, routes) => {
57 | // routes 用户可以访问的权限
58 | state.addRoutes = routes
59 | // 完整的路由表
60 |
61 | state.routes = constRouter.concat(routes)
62 |
63 | }
64 | }
65 |
66 | const actions = {
67 | generateRoutes({ commit }, roles) {
68 | return new Promise(resolve => {
69 |
70 | let accessedRoutes;
71 | // 用户是管理员则拥有完整访问权限
72 | if(roles.includes('admin')){
73 | accessedRoutes = asyncRoutes || []
74 | }else{
75 | // console.log(roles)
76 | // 否则需要根据用户角色做过滤处理 jerry
77 | accessedRoutes = filterAsyncRoutes(asyncRoutes,roles)
78 | }
79 |
80 | commit('SET_ROUTES',accessedRoutes)
81 |
82 | resolve(accessedRoutes)
83 | })
84 | }
85 | }
86 |
87 | export default {
88 | namespaced: true,
89 | state,
90 | mutations,
91 | actions
92 | }
--------------------------------------------------------------------------------
/src/components/analyze/client.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
购买来源
5 |
6 |
7 | 近七天
8 | 本月
9 | 本年
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
37 |
--------------------------------------------------------------------------------
/src/components/Sidebar/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
25 |
26 |
27 |
58 |
59 |
--------------------------------------------------------------------------------
/src/assets/icon/sort.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/store/modules/tagsView.js:
--------------------------------------------------------------------------------
1 | const tagsView = {
2 | state: {
3 | visitedViews: [],
4 | cachedViews: []
5 | },
6 | mutations: {
7 | ADD_VISITED_VIEWS: (state, view) => {
8 | if (state.visitedViews.some(v => v.path === view.path)) return
9 | state.visitedViews.push({
10 | name: view.name,
11 | path: view.path,
12 | title: view.meta.title || 'no-name'
13 | })
14 | if (!view.meta.noCache) {
15 | state.cachedViews.push(view.name)
16 | }
17 | },
18 | DEL_VISITED_VIEWS: (state, view) => {
19 | for (const [i, v] of state.visitedViews.entries()) {
20 | if (v.path === view.path) {
21 | state.visitedViews.splice(i, 1)
22 | break
23 | }
24 | }
25 | for (const i of state.cachedViews) {
26 | if (i === view.name) {
27 | const index = state.cachedViews.indexOf(i)
28 | state.cachedViews.splice(index, 1)
29 | break
30 | }
31 | }
32 | },
33 | DEL_OTHERS_VIEWS: (state, view) => {
34 | for (const [i, v] of state.visitedViews.entries()) {
35 | if (v.path === view.path) {
36 | state.visitedViews = state.visitedViews.slice(i, i + 1)
37 | break
38 | }
39 | }
40 | for (const i of state.cachedViews) {
41 | if (i === view.name) {
42 | const index = state.cachedViews.indexOf(i)
43 | state.cachedViews = state.cachedViews.slice(index, i + 1)
44 | break
45 | }
46 | }
47 | },
48 | DEL_ALL_VIEWS: (state) => {
49 | state.visitedViews = []
50 | state.cachedViews = []
51 | }
52 | },
53 | actions: {
54 | addVisitedViews({ commit }, view) {
55 | commit('ADD_VISITED_VIEWS', view)
56 | },
57 | delVisitedViews({ commit, state }, view) {
58 | return new Promise((resolve) => {
59 | commit('DEL_VISITED_VIEWS', view)
60 | resolve([...state.visitedViews])
61 | })
62 | },
63 | delOthersViews({ commit, state }, view) {
64 | return new Promise((resolve) => {
65 | commit('DEL_OTHERS_VIEWS', view)
66 | resolve([...state.visitedViews])
67 | })
68 | },
69 | delAllViews({ commit, state }) {
70 | return new Promise((resolve) => {
71 | commit('DEL_ALL_VIEWS')
72 | resolve([...state.visitedViews])
73 | })
74 | }
75 | }
76 | }
77 |
78 | export default tagsView
79 |
--------------------------------------------------------------------------------
/src/components/analyze/cards.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{name}}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
33 |
34 |
--------------------------------------------------------------------------------
/src/components/Breadcrumb/Breadcrumb2.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{item.meta.title}}
7 | {{item.meta.title}}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
45 |
46 |
81 |
--------------------------------------------------------------------------------
/src/assets/icon/registration.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/github.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icon/daiban.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/Breadcrumb/Breadcrumb.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 | {{item.meta.title}}
11 |
12 | {{item.meta.title}}
13 |
14 |
15 |
16 |
17 |
18 |
79 |
80 |
--------------------------------------------------------------------------------
/src/components/analyze/monitorcar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{name}}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
39 |
40 |
--------------------------------------------------------------------------------
/src/components/Dropdown/newsBox.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
6 |
7 |
{{text}}
8 |
{{time}}
9 |
10 |
11 |
12 |
13 |
40 |
41 |
--------------------------------------------------------------------------------
/src/assets/icon/react.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/Home/InformationList.vue:
--------------------------------------------------------------------------------
1 |
2 |
36 |
37 |
38 |
90 |
91 |
--------------------------------------------------------------------------------
/src/views/analyze/Index.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 |
36 |
37 |
53 |
54 |
--------------------------------------------------------------------------------
/src/components/analyze/product.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
热销产品Top 10
5 |
6 |
7 | 近七天
8 | 本月
9 | 本年
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
70 |
--------------------------------------------------------------------------------
/src/components/Index/fast.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 |
36 |
37 |
38 |
39 |
40 | 财务
41 |
42 |
43 |
44 |
47 |
48 | 数据分析
49 |
50 |
51 |
52 |
53 |
54 |
72 |
--------------------------------------------------------------------------------
/src/components/Sidebar/SidebarItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
25 |
26 |
27 |
88 |
89 |
--------------------------------------------------------------------------------
/src/assets/icon/friend.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/Dropdown/matter.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{text}}
5 |
{{time}}
6 |
7 |
8 | 进行中
9 | 完成
10 | 即将到期
11 | 未完成
12 | 未开始
13 |
14 |
15 |
16 |
17 |
40 |
41 |
--------------------------------------------------------------------------------
/src/views/marketing/Choice.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 添加
7 |
8 |
9 |
10 |
11 |
12 |
16 |
20 |
21 |
25 |
26 |
30 |
31 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
51 |
52 |
53 |
54 |
55 |
93 |
94 |
--------------------------------------------------------------------------------
/src/components/Index/colleague.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |

6 |
7 |
8 |
{{item.name}}
9 |
{{item.position}}
10 |
11 |
12 | 在线
13 | ;离线
14 |
15 |
16 |
17 |
18 |
19 |
64 |
65 |
--------------------------------------------------------------------------------
/src/views/communication/Index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | 本邮件发送需要配置邮箱的IMAP/SMTP服务
17 |
20 |
21 |
22 | 保存草稿
23 | 立即发送
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
91 |
92 |
--------------------------------------------------------------------------------
/src/components/Index/dynamicBox.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |

7 |
8 |
9 |
10 | {{item.name}}
11 | {{item.type}}
12 | {{item.msg}}
13 |
14 |
15 | {{item.time}}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
94 |
95 |
--------------------------------------------------------------------------------
/src/views/control/KeyCode.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 添加
7 |
8 |
9 |
10 |
11 |
12 |
16 |
20 |
21 |
25 |
26 |
30 |
31 |
35 |
36 |
40 |
41 |
45 |
46 |
50 |
51 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
71 |
72 |
73 |
74 |
75 |
109 |
110 |
--------------------------------------------------------------------------------
/src/views/goods/FromGood.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 |
36 |
37 |
38 |
39 |
40 |
41 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | 立即添加
66 |
67 |
68 |
69 |
70 |
71 |
100 |
101 |
--------------------------------------------------------------------------------
/src/components/Index/project.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | star
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | star
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | star
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | star
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | star
55 |
56 |
57 |
58 |
59 |
60 |
63 |
64 |
65 | star
66 |
67 |
68 |
69 |
70 |
71 |
72 |
96 |
97 |
--------------------------------------------------------------------------------
/src/views/coupon/AddCoupon.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 添加优惠券类型
7 |
8 |
9 |
10 |
11 |
12 |
16 |
20 |
21 |
25 |
26 |
30 |
31 |
35 |
36 |
40 |
41 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
64 |
65 |
66 |
67 |
68 |
111 |
112 |
--------------------------------------------------------------------------------
/src/components/Dropdown/drop.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
{{text}}
13 |
{{time}}
14 |
15 |
16 |
17 |
18 |
87 |
88 |
--------------------------------------------------------------------------------
/src/views/marketing/Spike.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 添加
7 |
8 |
9 |
10 |
11 |
12 |
16 |
20 |
21 |
25 |
26 |
30 |
31 |
35 |
36 |
40 |
41 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
63 |
64 |
65 |
66 |
74 |
75 |
76 |
77 |
80 |
81 |
82 |
83 |
84 |
125 |
126 |
--------------------------------------------------------------------------------
/src/views/login/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
22 |
23 |
24 |
25 | 后台管理系统
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | 立即登陆
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
114 |
115 |
--------------------------------------------------------------------------------
/src/views/goods/OnIndex.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
17 |
18 |
19 |
20 |
21 | 搜索
22 |
23 |
24 | 添加
25 |
26 |
27 |
28 |
29 |
30 |
35 |
39 |
40 |
44 |
45 |
49 |
50 |
54 |
55 |
59 |
60 |
64 |
65 |
69 |
70 |
74 |
75 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
136 |
137 |
--------------------------------------------------------------------------------
/src/views/goods/OffIndex.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
17 |
18 |
19 |
20 |
21 | 搜索
22 |
23 |
24 |
25 |
26 |
27 |
32 |
36 |
37 |
41 |
42 |
46 |
47 |
51 |
52 |
56 |
57 |
61 |
62 |
66 |
67 |
71 |
72 |
76 |
77 |
81 |
82 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
140 |
141 |
--------------------------------------------------------------------------------
/src/components/Dropdown/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | 加载更多
16 |
17 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
43 |
44 |
45 |
46 |
47 |
48 |
82 |
83 |
--------------------------------------------------------------------------------
/src/views/control/Placard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 添加
7 |
8 |
9 |
10 |
11 |
12 |
16 |
20 |
21 |
25 |
26 |
30 |
31 |
35 |
36 |
40 |
41 |
45 |
46 |
50 |
51 |
55 |
56 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
79 |
80 |
81 |
82 |
83 |
135 |
136 |
--------------------------------------------------------------------------------
/src/components/analyze/maps.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
118 |
119 |
--------------------------------------------------------------------------------