refactor: frontend 重命名为 backend-adminend,新增 shccd159/shjjy153 配置
- frontend 目录迁移至 backend-adminend(管理后台前端) - 新增 application-shccd159.yml、application-shjjy153.yml - 更新 deploy.conf、DEPLOY.md、application.yml Made-with: Cursor
This commit is contained in:
31
backend-adminend/src/store/getters.js
Normal file
31
backend-adminend/src/store/getters.js
Normal file
@@ -0,0 +1,31 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
const getters = {
|
||||
sidebar: (state) => state.app.sidebar,
|
||||
size: (state) => state.app.size,
|
||||
device: (state) => state.app.device,
|
||||
visitedViews: (state) => state.tagsView.visitedViews,
|
||||
cachedViews: (state) => state.tagsView.cachedViews,
|
||||
token: (state) => state.user.token,
|
||||
avatar: (state) => state.user.avatar,
|
||||
name: (state) => state.user.name,
|
||||
introduction: (state) => state.user.introduction,
|
||||
roles: (state) => state.user.roles,
|
||||
permission_routes: (state) => state.permission.routes,
|
||||
permissions: (state) => state.user.permissions,
|
||||
sidebarRouters: (state) => state.permission.sidebarRouters,
|
||||
errorLogs: (state) => state.errorLog.logs,
|
||||
isLogin: (state) => state.user.isLogin,
|
||||
adminProductClassify: (state) => state.product.adminProductClassify,
|
||||
frontDomain: (state) => state.settings.frontDomain,
|
||||
mediaDomain: (state) => state.settings.mediaDomain,
|
||||
};
|
||||
export default getters;
|
||||
34
backend-adminend/src/store/index.js
Normal file
34
backend-adminend/src/store/index.js
Normal file
@@ -0,0 +1,34 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
import Vue from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
import getters from './getters';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
// https://webpack.js.org/guides/dependency-management/#requirecontext
|
||||
const modulesFiles = require.context('./modules', true, /\.js$/);
|
||||
|
||||
// you do not need `import app from './modules/app'`
|
||||
// it will auto require all vuex module from modules file
|
||||
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
|
||||
// set './app.js' => 'app'
|
||||
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1');
|
||||
const value = modulesFiles(modulePath);
|
||||
modules[moduleName] = value.default;
|
||||
return modules;
|
||||
}, {});
|
||||
const store = new Vuex.Store({
|
||||
modules,
|
||||
getters,
|
||||
});
|
||||
|
||||
export default store;
|
||||
66
backend-adminend/src/store/modules/app.js
Normal file
66
backend-adminend/src/store/modules/app.js
Normal file
@@ -0,0 +1,66 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
const state = {
|
||||
sidebar: {
|
||||
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
|
||||
withoutAnimation: false,
|
||||
},
|
||||
device: 'desktop',
|
||||
size: Cookies.get('size') || 'mini',
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
TOGGLE_SIDEBAR: (state) => {
|
||||
state.sidebar.opened = !state.sidebar.opened;
|
||||
state.sidebar.withoutAnimation = false;
|
||||
if (state.sidebar.opened) {
|
||||
Cookies.set('sidebarStatus', 1);
|
||||
} else {
|
||||
Cookies.set('sidebarStatus', 0);
|
||||
}
|
||||
},
|
||||
CLOSE_SIDEBAR: (state, withoutAnimation) => {
|
||||
Cookies.set('sidebarStatus', 0);
|
||||
state.sidebar.opened = false;
|
||||
state.sidebar.withoutAnimation = withoutAnimation;
|
||||
},
|
||||
TOGGLE_DEVICE: (state, device) => {
|
||||
state.device = device;
|
||||
},
|
||||
SET_SIZE: (state, size) => {
|
||||
state.size = size;
|
||||
Cookies.set('size', size);
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
toggleSideBar({ commit }) {
|
||||
commit('TOGGLE_SIDEBAR');
|
||||
},
|
||||
closeSideBar({ commit }, { withoutAnimation }) {
|
||||
commit('CLOSE_SIDEBAR', withoutAnimation);
|
||||
},
|
||||
toggleDevice({ commit }, device) {
|
||||
commit('TOGGLE_DEVICE', device);
|
||||
},
|
||||
setSize({ commit }, size) {
|
||||
commit('SET_SIZE', size);
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions,
|
||||
};
|
||||
38
backend-adminend/src/store/modules/errorLog.js
Normal file
38
backend-adminend/src/store/modules/errorLog.js
Normal file
@@ -0,0 +1,38 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
const state = {
|
||||
logs: [],
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
ADD_ERROR_LOG: (state, log) => {
|
||||
state.logs.push(log);
|
||||
},
|
||||
CLEAR_ERROR_LOG: (state) => {
|
||||
state.logs.splice(0);
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
addErrorLog({ commit }, log) {
|
||||
commit('ADD_ERROR_LOG', log);
|
||||
},
|
||||
clearErrorLog({ commit }) {
|
||||
commit('CLEAR_ERROR_LOG');
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions,
|
||||
};
|
||||
266
backend-adminend/src/store/modules/mobildConfig.js
Normal file
266
backend-adminend/src/store/modules/mobildConfig.js
Normal file
@@ -0,0 +1,266 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
/**
|
||||
* diy自定义组件
|
||||
* */
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
configName: '',
|
||||
pageTitle: '',
|
||||
pageName: '' || '模板',
|
||||
pageShow: 1,
|
||||
pageColor: 1,
|
||||
pagePic: 0,
|
||||
pageColorPicker: '#f5f5f5',
|
||||
pageTabVal: '0',
|
||||
pagePicUrl: '',
|
||||
returnAddress: '',
|
||||
titleColor: '#000000',
|
||||
titleBgColor: '#fff',
|
||||
// 已知组件列表默认数据 数组
|
||||
defaultArray: {},
|
||||
},
|
||||
mutations: {
|
||||
FOOTER(state, data) {
|
||||
state.pageFooter.status.title = data.title;
|
||||
state.pageFooter.menuList[2] = data.name;
|
||||
},
|
||||
/**
|
||||
* 隐藏组件,更新数据显示值
|
||||
* @constructor
|
||||
*/
|
||||
UPDATESHOW(state, data) {
|
||||
state.defaultArray[data.num].isShow = !state.defaultArray[data.num].isShow;
|
||||
},
|
||||
/**
|
||||
* @description 默认配置push到数组里面
|
||||
* @param {Object} state vuex state
|
||||
* @param {Object} data
|
||||
* 把默认数据添加到默认数组里面,解耦重复组件公用一条配置的问题
|
||||
*/
|
||||
ADDARRAY(state, data) {
|
||||
data.val.id = 'id' + data.val.timestamp;
|
||||
state.defaultArray[data.num] = data.val;
|
||||
},
|
||||
/**
|
||||
* @description 删除列表第几个默认数据
|
||||
* @param {Object} state vuex state
|
||||
* @param {Object} data 数据
|
||||
*/
|
||||
DELETEARRAY(state, data) {
|
||||
let tempObj = delete state.defaultArray[data.num];
|
||||
},
|
||||
/**
|
||||
* @description 删除列表第几个默认数据
|
||||
* @param {Object} state vuex state
|
||||
* @param {Object} data 数据
|
||||
*/
|
||||
ARRAYREAST(state, data) {
|
||||
let tempObj = delete state.defaultArray[data];
|
||||
},
|
||||
/**
|
||||
* @description 数组排序
|
||||
* @param {Object} state vuex state
|
||||
* @param {Object} data 位置index记录
|
||||
*/
|
||||
defaultArraySort(state, data) {
|
||||
let newArr = objToArr(state.defaultArray);
|
||||
let sortArr = [];
|
||||
let newObj = {};
|
||||
function objToArr(data) {
|
||||
let obj = Object.keys(data);
|
||||
let m = obj.map((key) => data[key]);
|
||||
return m;
|
||||
}
|
||||
function swapArray(arr, index1, index2) {
|
||||
let oldObj = {};
|
||||
let newObj = {};
|
||||
let active = 0;
|
||||
arr.forEach((el, index) => {
|
||||
if (!el.id) {
|
||||
el.id = 'id' + el.timestamp;
|
||||
}
|
||||
data.list.forEach((item, j) => {
|
||||
if (el.id == item.id) {
|
||||
el.timestamp = item.num;
|
||||
}
|
||||
});
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
if (data.oldIndex != undefined) {
|
||||
sortArr = JSON.parse(JSON.stringify(swapArray(newArr, data.newIndex, data.oldIndex)));
|
||||
} else {
|
||||
newArr.splice(data.newIndex, 0, data.element.data().defaultConfig);
|
||||
sortArr = JSON.parse(JSON.stringify(swapArray(newArr, 0, 0)));
|
||||
}
|
||||
for (let i = 0; i < sortArr.length; i++) {
|
||||
newObj[sortArr[i].timestamp] = sortArr[i];
|
||||
}
|
||||
state.defaultArray = Object.assign({}, newObj);
|
||||
},
|
||||
/**
|
||||
* @description 更新数组某一组数据
|
||||
* @param {Object} state vuex state
|
||||
* @param {Object} data
|
||||
*/
|
||||
UPDATEARR(state, data) {
|
||||
for (var k in state.defaultArray) {
|
||||
if (state.defaultArray[k].id == data.val.id) {
|
||||
state.defaultArray[k] = data.val;
|
||||
}
|
||||
}
|
||||
let value = Object.assign({}, state.defaultArray);
|
||||
state.defaultArray = value;
|
||||
},
|
||||
/**
|
||||
* @description 保存组件名称
|
||||
* @param {Object} state vuex state
|
||||
* @param {string} data
|
||||
*/
|
||||
SETCONFIGNAME(state, name) {
|
||||
state.configName = name;
|
||||
},
|
||||
/**
|
||||
* @description 默认组件清空
|
||||
* @param {Object} state vuex state
|
||||
* @param {string} data
|
||||
*/
|
||||
SETEMPTY(state, name) {
|
||||
state.defaultArray = {};
|
||||
},
|
||||
UPTITLE(state, val) {
|
||||
state.pageTitle = val;
|
||||
},
|
||||
UPNAME(state, val) {
|
||||
state.pageName = val;
|
||||
},
|
||||
UPSHOW(state, val) {
|
||||
state.pageShow = val;
|
||||
},
|
||||
UPCOLOR(state, val) {
|
||||
state.pageColor = val;
|
||||
},
|
||||
UPPIC(state, val) {
|
||||
state.pagePic = val;
|
||||
},
|
||||
UPPICKER(state, val) {
|
||||
state.pageColorPicker = val;
|
||||
},
|
||||
UPRADIO(state, val) {
|
||||
state.pageTabVal = val;
|
||||
},
|
||||
UPPICURL(state, val) {
|
||||
state.pagePicUrl = val;
|
||||
},
|
||||
UPPReturnAddress(state, val) {
|
||||
state.returnAddress = val;
|
||||
},
|
||||
UPPTitleColor(state, val) {
|
||||
state.titleColor = val;
|
||||
},
|
||||
UPPTitleBgColor(state, val) {
|
||||
state.titleBgColor = val;
|
||||
},
|
||||
/**
|
||||
* @description 更新foot菜单配置
|
||||
* @param {Object} state vuex state
|
||||
* @param {string} data
|
||||
*/
|
||||
footUpdata(state, data) {
|
||||
state.pageFooter = [];
|
||||
state.pageFooter = data;
|
||||
},
|
||||
/**
|
||||
* @description 更新foot自定义开关
|
||||
* @param {Object} state vuex state
|
||||
* @param {string} data
|
||||
*/
|
||||
footStatus(state, data) {
|
||||
state.pageFooter.status.status = data;
|
||||
},
|
||||
/**
|
||||
* @description 更新foot配置
|
||||
* @param {Object} state vuex state
|
||||
* @param {string} data
|
||||
*/
|
||||
footPageUpdata(state, data) {
|
||||
state.pageFooter = data;
|
||||
},
|
||||
/**
|
||||
* @description 更新title配置
|
||||
* @param {Object} state vuex state
|
||||
* @param {string} data
|
||||
*/
|
||||
titleUpdata(state, data) {
|
||||
state.pageTitle = data;
|
||||
},
|
||||
/**
|
||||
* @description 更新name配置
|
||||
* @param {Object} state vuex state
|
||||
* @param {string} data
|
||||
*/
|
||||
nameUpdata(state, data) {
|
||||
state.pageName = data;
|
||||
},
|
||||
//
|
||||
showUpdata(state, data) {
|
||||
state.pageShow = data;
|
||||
},
|
||||
colorUpdata(state, data) {
|
||||
state.pageColor = data;
|
||||
},
|
||||
picUpdata(state, data) {
|
||||
state.pagePic = data;
|
||||
},
|
||||
/**
|
||||
* @description 更新页面背景色
|
||||
* @param {Object} state vuex state
|
||||
* @param {string} data
|
||||
*/
|
||||
pickerUpdata(state, data) {
|
||||
state.pageColorPicker = data;
|
||||
},
|
||||
radioUpdata(state, data) {
|
||||
state.pageTabVal = data;
|
||||
},
|
||||
picurlUpdata(state, data) {
|
||||
state.pagePicUrl = data;
|
||||
},
|
||||
/**
|
||||
* 更新页面设置中返回地址
|
||||
* @param state
|
||||
* @param data
|
||||
*/
|
||||
returnAddressUpdata(state, data) {
|
||||
state.returnAddress = data;
|
||||
},
|
||||
/**
|
||||
* 更新页面设置中顶部颜色
|
||||
* @param state
|
||||
* @param data
|
||||
*/
|
||||
titleBgColorUpdata(state, data) {
|
||||
state.titleBgColor = data;
|
||||
},
|
||||
/**
|
||||
* 更新页面设置中顶部颜色
|
||||
* @param state
|
||||
* @param data
|
||||
*/
|
||||
titleColorUpdata(state, data) {
|
||||
state.titleColor = data;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
getData({ commit }, data) {},
|
||||
},
|
||||
};
|
||||
109
backend-adminend/src/store/modules/permission.js
Normal file
109
backend-adminend/src/store/modules/permission.js
Normal file
@@ -0,0 +1,109 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
import { asyncRoutes, constantRoutes } from '@/router';
|
||||
import * as roleApi from '@/api/roleApi.js';
|
||||
import * as Auth from '@/libs/wechat';
|
||||
import { formatRoutes } from '@/utils/parsing';
|
||||
|
||||
/**
|
||||
* Filter asynchronous routing tables by recursion
|
||||
* @param routes asyncRoutes
|
||||
* @param roles
|
||||
*/
|
||||
export function filterAsyncRoutes(routes, roles) {
|
||||
const res = [];
|
||||
|
||||
routes.forEach((route) => {
|
||||
const tmp = { ...route };
|
||||
if (tmp.child) {
|
||||
tmp.child = filterAsyncRoutes(tmp.child, roles);
|
||||
}
|
||||
res.push(tmp);
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const state = {
|
||||
routes: [],
|
||||
addRoutes: [],
|
||||
topbarRouters: [],
|
||||
sidebarRouters: [],
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
SET_ROUTES: (state, routes) => {
|
||||
state.addRoutes = routes;
|
||||
// state.routes = constantRoutes.concat(routes)
|
||||
state.routes = routes;
|
||||
},
|
||||
SET_TOPBAR_ROUTES: (state, routes) => {
|
||||
state.topbarRouters = routes;
|
||||
},
|
||||
SET_SIDEBAR_ROUTERS: (state, routes) => {
|
||||
state.sidebarRouters = routes;
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
generateRoutes({ commit }, roleid) {
|
||||
return new Promise(async (resolve) => {
|
||||
let accessedRoutes = [];
|
||||
let menus = [];
|
||||
// const { rules } = await roleApi.getRoleById(roleid)
|
||||
let menusAll = await roleApi.menuListApi();
|
||||
menusAll = formatRoutes(menusAll);
|
||||
|
||||
!Auth.isPhone()
|
||||
? (menus = menusAll.filter((item) => item.url !== '/javaMobile'))
|
||||
: (menus = menusAll.filter((item) => item.url === '/javaMobile'));
|
||||
const _routerResult = comRouter(menus, asyncRoutes);
|
||||
accessedRoutes = filterAsyncRoutes(_routerResult);
|
||||
// todo 这里控制是否过滤路由,经测试有些菜单不能予以设置,比如系统设置等等
|
||||
this.state.settings.showSettings = false;
|
||||
commit('SET_ROUTES', menus);
|
||||
commit('SET_TOPBAR_ROUTES', menus);
|
||||
if (this.state.settings.topNav) {
|
||||
commit('SET_SIDEBAR_ROUTERS', state.sidebarRouters.length ? state.sidebarRouters : menus[0].child);
|
||||
} else {
|
||||
commit('SET_SIDEBAR_ROUTERS', menus);
|
||||
}
|
||||
// resolve(menus)
|
||||
// commit('SET_ROUTES', accessedRoutes)
|
||||
resolve(accessedRoutes);
|
||||
|
||||
// commit('SET_ROUTES', asyncRoutes)
|
||||
// resolve(asyncRoutes)
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
function comRouter(menus, asyncRouter, hasLeft) {
|
||||
const res = [];
|
||||
asyncRouter.forEach((router) => {
|
||||
const _leftUrl = hasLeft ? hasLeft + '/' + router.path : router.path;
|
||||
const _hasPromise = menus.filter((item) => item.url.startsWith(_leftUrl));
|
||||
if (_hasPromise.length > 0) {
|
||||
res.push(router);
|
||||
}
|
||||
if (router.children) {
|
||||
comRouter(menus, router.children, router.path);
|
||||
}
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions,
|
||||
};
|
||||
67
backend-adminend/src/store/modules/product.js
Normal file
67
backend-adminend/src/store/modules/product.js
Normal file
@@ -0,0 +1,67 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
import * as product from '@/api/store';
|
||||
|
||||
const state = {
|
||||
adminProductClassify: localStorage.getItem('adminProductClassify')
|
||||
? JSON.parse(localStorage.getItem('adminProductClassify'))
|
||||
: [] /** 平台商品分类 **/,
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
SET_AdminProductClassify: (state, adminProductClassify) => {
|
||||
state.adminProductClassify = adminProductClassify;
|
||||
localStorage.setItem('adminProductClassify', JSON.stringify(changeNodes(adminProductClassify)));
|
||||
if (!adminProductClassify.length) localStorage.removeItem('adminProductClassify');
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
/** 平台商品分类 **/
|
||||
getAdminProductClassify({ commit, dispatch }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
product
|
||||
.categoryApi({ status: -1, type: 1 })
|
||||
.then(async (res) => {
|
||||
commit('SET_AdminProductClassify', changeNodes(res));
|
||||
resolve(res);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
/** tree去除 childList=[] 的结构**/
|
||||
const changeNodes = function (data) {
|
||||
if (data.length > 0) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (data[i].isShow === false) {
|
||||
data[i].disabled = true;
|
||||
}
|
||||
if (!data[i].child || data[i].child.length < 1) {
|
||||
data[i].child = undefined;
|
||||
} else {
|
||||
changeNodes(data[i].child);
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions,
|
||||
changeNodes,
|
||||
};
|
||||
56
backend-adminend/src/store/modules/settings.js
Normal file
56
backend-adminend/src/store/modules/settings.js
Normal file
@@ -0,0 +1,56 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
import defaultSettings from '@/settings';
|
||||
import Cache from '@/plugins/cache';
|
||||
const { showSettings, tagsView, fixedHeader, sidebarLogo, topNav, sideTheme, navIcon } = defaultSettings;
|
||||
const storageSetting = Cache.local.has('layout-setting') ? Cache.local.getJSON('layout-setting') : '';
|
||||
const state = {
|
||||
theme: storageSetting.theme || '#409EFF',
|
||||
sideTheme: storageSetting.sideTheme || sideTheme,
|
||||
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
|
||||
showSettings: showSettings,
|
||||
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
|
||||
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
|
||||
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
|
||||
navIcon: storageSetting.navIcon === undefined ? navIcon : storageSetting.navIcon,
|
||||
frontDomain: localStorage.getItem('frontDomain') || '', //移动端域名
|
||||
mediaDomain: localStorage.getItem('mediaDomain') || '', //图片域名
|
||||
};
|
||||
const mutations = {
|
||||
CHANGE_SETTING: (state, { key, value }) => {
|
||||
if (state.hasOwnProperty(key)) {
|
||||
state[key] = value;
|
||||
}
|
||||
},
|
||||
SET_FrontDomain(state, frontDomain) {
|
||||
state.frontDomain = frontDomain;
|
||||
localStorage.setItem('frontDomain', frontDomain);
|
||||
if (!frontDomain) localStorage.removeItem('frontDomain');
|
||||
},
|
||||
SET_mediaDomain(state, mediaDomain) {
|
||||
state.mediaDomain = mediaDomain;
|
||||
localStorage.setItem('mediaDomain', mediaDomain);
|
||||
if (!mediaDomain) localStorage.removeItem('mediaDomain');
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
changeSetting({ commit }, data) {
|
||||
commit('CHANGE_SETTING', data);
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions,
|
||||
};
|
||||
183
backend-adminend/src/store/modules/tagsView.js
Normal file
183
backend-adminend/src/store/modules/tagsView.js
Normal file
@@ -0,0 +1,183 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
import Cache from '@/plugins/cache';
|
||||
const state = {
|
||||
visitedViews: Cache.local.getJSON('visitedViews') || [],
|
||||
cachedViews: [],
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
ADD_VISITED_VIEW: (state, view) => {
|
||||
if (state.visitedViews.some((v) => v.path === view.path)) return;
|
||||
state.visitedViews.push(
|
||||
Object.assign(
|
||||
{},
|
||||
{
|
||||
path: view.path,
|
||||
query: view.query,
|
||||
fullPath: view.fullPath,
|
||||
meta: view.meta,
|
||||
},
|
||||
{
|
||||
title: view.meta.title || 'no-name',
|
||||
},
|
||||
),
|
||||
);
|
||||
Cache.local.setJSON('visitedViews', [...state.visitedViews]);
|
||||
},
|
||||
ADD_CACHED_VIEW: (state, view) => {
|
||||
if (state.cachedViews.includes(view.name)) return;
|
||||
if (!view.meta.noCache) {
|
||||
state.cachedViews.push(view.name);
|
||||
}
|
||||
},
|
||||
|
||||
DEL_VISITED_VIEW: (state, view) => {
|
||||
for (const [i, v] of state.visitedViews.entries()) {
|
||||
if (v.path === view.path) {
|
||||
state.visitedViews.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Cache.local.setJSON('visitedViews', [...state.visitedViews]);
|
||||
},
|
||||
DEL_CACHED_VIEW: (state, view) => {
|
||||
const index = state.cachedViews.indexOf(view.name);
|
||||
index > -1 && state.cachedViews.splice(index, 1);
|
||||
},
|
||||
|
||||
DEL_OTHERS_VISITED_VIEWS: (state, view) => {
|
||||
state.visitedViews = state.visitedViews.filter((v) => {
|
||||
return v.meta.affix || v.path === view.path;
|
||||
});
|
||||
Cache.local.setJSON('visitedViews', [...state.visitedViews]);
|
||||
},
|
||||
DEL_OTHERS_CACHED_VIEWS: (state, view) => {
|
||||
const index = state.cachedViews.indexOf(view.name);
|
||||
if (index > -1) {
|
||||
state.cachedViews = state.cachedViews.slice(index, index + 1);
|
||||
} else {
|
||||
// if index = -1, there is no cached tags
|
||||
state.cachedViews = [];
|
||||
}
|
||||
},
|
||||
|
||||
DEL_ALL_VISITED_VIEWS: (state) => {
|
||||
// keep affix tags
|
||||
const affixTags = state.visitedViews.filter((tag) => tag.meta.affix);
|
||||
state.visitedViews = affixTags;
|
||||
Cache.local.setJSON('visitedViews', [...state.visitedViews]);
|
||||
},
|
||||
DEL_ALL_CACHED_VIEWS: (state) => {
|
||||
state.cachedViews = [];
|
||||
},
|
||||
|
||||
UPDATE_VISITED_VIEW: (state, view) => {
|
||||
for (let v of state.visitedViews) {
|
||||
if (v.path === view.path) {
|
||||
v = Object.assign(v, view);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
addView({ dispatch }, view) {
|
||||
dispatch('addVisitedView', view);
|
||||
dispatch('addCachedView', view);
|
||||
},
|
||||
addVisitedView({ commit }, view) {
|
||||
commit('ADD_VISITED_VIEW', view);
|
||||
},
|
||||
addCachedView({ commit }, view) {
|
||||
commit('ADD_CACHED_VIEW', view);
|
||||
},
|
||||
|
||||
delView({ dispatch, state }, view) {
|
||||
return new Promise((resolve) => {
|
||||
dispatch('delVisitedView', view);
|
||||
dispatch('delCachedView', view);
|
||||
resolve({
|
||||
visitedViews: [...state.visitedViews],
|
||||
cachedViews: [...state.cachedViews],
|
||||
});
|
||||
});
|
||||
},
|
||||
delVisitedView({ commit, state }, view) {
|
||||
return new Promise((resolve) => {
|
||||
commit('DEL_VISITED_VIEW', view);
|
||||
resolve([...state.visitedViews]);
|
||||
});
|
||||
},
|
||||
delCachedView({ commit, state }, view) {
|
||||
return new Promise((resolve) => {
|
||||
commit('DEL_CACHED_VIEW', view);
|
||||
resolve([...state.cachedViews]);
|
||||
});
|
||||
},
|
||||
|
||||
delOthersViews({ dispatch, state }, view) {
|
||||
return new Promise((resolve) => {
|
||||
dispatch('delOthersVisitedViews', view);
|
||||
dispatch('delOthersCachedViews', view);
|
||||
resolve({
|
||||
visitedViews: [...state.visitedViews],
|
||||
cachedViews: [...state.cachedViews],
|
||||
});
|
||||
});
|
||||
},
|
||||
delOthersVisitedViews({ commit, state }, view) {
|
||||
return new Promise((resolve) => {
|
||||
commit('DEL_OTHERS_VISITED_VIEWS', view);
|
||||
resolve([...state.visitedViews]);
|
||||
});
|
||||
},
|
||||
delOthersCachedViews({ commit, state }, view) {
|
||||
return new Promise((resolve) => {
|
||||
commit('DEL_OTHERS_CACHED_VIEWS', view);
|
||||
resolve([...state.cachedViews]);
|
||||
});
|
||||
},
|
||||
|
||||
delAllViews({ dispatch, state }, view) {
|
||||
return new Promise((resolve) => {
|
||||
dispatch('delAllVisitedViews', view);
|
||||
dispatch('delAllCachedViews', view);
|
||||
resolve({
|
||||
visitedViews: [...state.visitedViews],
|
||||
cachedViews: [...state.cachedViews],
|
||||
});
|
||||
});
|
||||
},
|
||||
delAllVisitedViews({ commit, state }) {
|
||||
return new Promise((resolve) => {
|
||||
commit('DEL_ALL_VISITED_VIEWS');
|
||||
resolve([...state.visitedViews]);
|
||||
});
|
||||
},
|
||||
delAllCachedViews({ commit, state }) {
|
||||
return new Promise((resolve) => {
|
||||
commit('DEL_ALL_CACHED_VIEWS');
|
||||
resolve([...state.cachedViews]);
|
||||
});
|
||||
},
|
||||
|
||||
updateVisitedView({ commit }, view) {
|
||||
commit('UPDATE_VISITED_VIEW', view);
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions,
|
||||
};
|
||||
201
backend-adminend/src/store/modules/user.js
Normal file
201
backend-adminend/src/store/modules/user.js
Normal file
@@ -0,0 +1,201 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
import { login, logout, getInfo } from '@/api/user';
|
||||
import { getToken, setToken, removeToken } from '@/utils/auth';
|
||||
import router, { resetRouter } from '@/router';
|
||||
import { isLoginApi } from '@/api/sms';
|
||||
import Cookies from 'js-cookie';
|
||||
import { oAuth, getQueryString } from '@/libs/wechat';
|
||||
|
||||
const state = {
|
||||
token: getToken(),
|
||||
name: '',
|
||||
avatar: '',
|
||||
introduction: '',
|
||||
roles: [],
|
||||
isLogin: Cookies.get('isLogin'),
|
||||
permissions: [],
|
||||
captcha: {
|
||||
captchaVerification: '',
|
||||
secretKey: '',
|
||||
token: '',
|
||||
}, //滑块验证token
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
SET_TOKEN: (state, token) => {
|
||||
state.token = token;
|
||||
},
|
||||
SET_ISLOGIN: (state, isLogin) => {
|
||||
state.isLogin = isLogin;
|
||||
Cookies.set(isLogin);
|
||||
},
|
||||
SET_INTRODUCTION: (state, introduction) => {
|
||||
state.introduction = introduction;
|
||||
},
|
||||
SET_NAME: (state, name) => {
|
||||
state.name = name;
|
||||
},
|
||||
SET_AVATAR: (state, avatar) => {
|
||||
state.avatar = avatar;
|
||||
},
|
||||
SET_ROLES: (state, roles) => {
|
||||
state.roles = roles;
|
||||
},
|
||||
SET_PERMISSIONS: (state, permissions) => {
|
||||
state.permissions = permissions;
|
||||
},
|
||||
SET_CAPTCHA: (state, captcha) => {
|
||||
state.captcha = captcha;
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
// user login
|
||||
login({ commit }, userInfo) {
|
||||
const { account, pwd, key, code, wxCode } = userInfo;
|
||||
return new Promise((resolve, reject) => {
|
||||
login(userInfo)
|
||||
.then((data) => {
|
||||
commit('SET_TOKEN', data.token);
|
||||
Cookies.set('JavaInfo', JSON.stringify(data));
|
||||
setToken(data.token);
|
||||
resolve();
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// 短信是否登录
|
||||
isLogin({ commit }, userInfo) {
|
||||
// const { username, password } = userInfo
|
||||
return new Promise((resolve, reject) => {
|
||||
isLoginApi()
|
||||
.then(async (res) => {
|
||||
commit('SET_ISLOGIN', res.status);
|
||||
resolve(res);
|
||||
})
|
||||
.catch((res) => {
|
||||
commit('SET_ISLOGIN', false);
|
||||
reject(res);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// get user info
|
||||
getInfo({ commit, state }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getInfo(state.token)
|
||||
.then((data) => {
|
||||
if (!data) {
|
||||
reject('Verification failed, please Login again.');
|
||||
}
|
||||
const { roles, account } = data;
|
||||
// roles must be a non-empty array
|
||||
if (!roles || roles.length <= 0) {
|
||||
reject('getInfo: roles must be a non-null array!');
|
||||
}
|
||||
|
||||
commit('SET_ROLES', roles);
|
||||
// commit('SET_ROLES', ['admin'])
|
||||
commit('SET_NAME', account);
|
||||
// commit('SET_AVATAR', avatar)
|
||||
commit('SET_AVATAR', 'http://kaifa.crmeb.net/system/images/admin_logo.png');
|
||||
|
||||
commit('SET_INTRODUCTION', 'CRMEB admin');
|
||||
commit('SET_PERMISSIONS', data.permissionsList); //权限标识
|
||||
resolve(data);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// user logout
|
||||
logout({ commit, state, dispatch }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
logout(state.token)
|
||||
.then(() => {
|
||||
commit('SET_TOKEN', '');
|
||||
commit('SET_ROLES', []);
|
||||
commit('SET_PERMISSIONS', []);
|
||||
removeToken();
|
||||
resetRouter();
|
||||
// localStorage.clear();
|
||||
Cookies.remove('storeStaffList');
|
||||
Cookies.remove('JavaInfo');
|
||||
sessionStorage.removeItem('token');
|
||||
// reset visited views and cached views
|
||||
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485
|
||||
dispatch('tagsView/delAllViews', null, { root: true });
|
||||
|
||||
resolve();
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// remove token
|
||||
resetToken({ commit }) {
|
||||
return new Promise((resolve) => {
|
||||
commit('SET_TOKEN', '');
|
||||
commit('SET_ROLES', []);
|
||||
removeToken();
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
// 设置token
|
||||
setToken({ commit }, state) {
|
||||
return new Promise((resolve) => {
|
||||
commit('SET_TOKEN', state.token);
|
||||
Cookies.set('JavaInfo', JSON.stringify(state));
|
||||
setToken(data.token);
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
|
||||
// dynamically modify permissions
|
||||
changeRoles({ commit, dispatch }, role) {
|
||||
return new Promise(async (resolve) => {
|
||||
const token = role + '-token';
|
||||
|
||||
commit('SET_TOKEN', token);
|
||||
setToken(token);
|
||||
|
||||
const { roles } = await dispatch('getInfo');
|
||||
|
||||
resetRouter();
|
||||
|
||||
// generate accessible routes map based on roles
|
||||
const accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true });
|
||||
|
||||
// dynamically add accessible routes
|
||||
router.addRoutes(accessRoutes);
|
||||
|
||||
// reset visited views and cached views
|
||||
dispatch('tagsView/delAllViews', null, { root: true });
|
||||
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions,
|
||||
};
|
||||
Reference in New Issue
Block a user