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:
apple
2026-03-16 09:33:54 +08:00
parent 0cd7ebe202
commit 4b0afb3951
738 changed files with 292 additions and 89 deletions

View 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;

View 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;

View 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,
};

View 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,
};

View 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) {},
},
};

View 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,
};

View 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,
};

View 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,
};

View 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,
};

View 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,
};