初次提交

This commit is contained in:
2025-06-30 10:17:15 +08:00
commit 5446088524
989 changed files with 365987 additions and 0 deletions

34
src/store/getters.js Normal file
View File

@ -0,0 +1,34 @@
const getters = {
sidebar: state => state.app.sidebar,
language: state => state.app.language,
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,
permissions: state => state.user.permissions,
menuList: state => state.user.menuList,
mainMenus: state => state.user.mainMenus,
userinfo: state => state.user.userinfo,
roles: state => state.user.roles,
permission_routes: state => state.permission.routes,
errorLogs: state => state.errorLog.logs,
dicts: state => state.user.dicts,
publicKey: state => state.user.publicKey,
stations: state => state.user.stations,
currentStation: state => state.user.currentStation,
selectId: state => state.user.selectId,
isHasHomePage: state => state.user.isHasHomePage,
isHasAlarmPage: state => state.user.isHasAlarmPage,
isHasTaskPage: state => state.user.isHasTaskPage,
alarmNum: state => state.user.alarmNum,
activeMenuName: state => state.user.activeMenuName || localStorage.getItem('activeMenuName'),
userDeptId: state => state.user.userDeptId,
password: state => state.user.password || localStorage.getItem('password'),
isBell: state => state.user.isBell || localStorage.getItem('isBell'),
searchHeight: state => state.user.searchHeight,
logoUrl: state => state.user.logoUrl,
msgChange: state => state.user.msgChange,
config: state => state.user.config
}
export default getters

25
src/store/index.js Normal file
View File

@ -0,0 +1,25 @@
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

64
src/store/modules/app.js Normal file
View File

@ -0,0 +1,64 @@
import Cookies from 'js-cookie'
import { getLanguage } from '@/lang/index'
const state = {
sidebar: {
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
withoutAnimation: false
},
device: 'desktop',
language: getLanguage(),
size: Cookies.get('size') || 'small'
}
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_LANGUAGE: (state, language) => {
state.language = language
sessionStorage.setItem('language', language)
},
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)
},
setLanguage({ commit }, language) {
commit('SET_LANGUAGE', language)
},
setSize({ commit }, size) {
commit('SET_SIZE', size)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@ -0,0 +1,28 @@
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,69 @@
import { asyncRoutes, constantRoutes } from '@/router'
/**
* Use meta.role to determine if the current user has permission
* @param roles
* @param route
*/
function hasPermission(roles, route) {
if (route.meta && route.meta.roles) {
return roles.some(role => route.meta.roles.includes(role))
} else {
return true
}
}
/**
* 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 (hasPermission(roles, tmp)) {
if (tmp.children) {
tmp.children = filterAsyncRoutes(tmp.children, roles)
}
res.push(tmp)
}
})
return res
}
const state = {
routes: [],
addRoutes: []
}
const mutations = {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
}
}
const actions = {
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
let accessedRoutes
if (roles.includes('admin')) {
accessedRoutes = asyncRoutes || []
} else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@ -0,0 +1,36 @@
import variables from '@/styles/element-variables.scss'
import defaultSettings from '@/settings'
const { showSettings, tagsView, fixedHeader, sidebarLogo, supportPinyinSearch } = defaultSettings
const state = {
theme: variables.theme,
showSettings,
tagsView,
fixedHeader,
sidebarLogo,
supportPinyinSearch
}
const mutations = {
CHANGE_SETTING: (state, { key, value }) => {
// eslint-disable-next-line no-prototype-builtins
if (state.hasOwnProperty(key)) {
state[key] = value
}
}
}
const actions = {
changeSetting({ commit }, data) {
commit('CHANGE_SETTING', data)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@ -0,0 +1,160 @@
const state = {
visitedViews: [],
cachedViews: []
}
const mutations = {
ADD_VISITED_VIEW: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return
state.visitedViews.push(
Object.assign({}, view, {
title: view.meta.title || 'no-name'
})
)
},
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
}
}
},
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
})
},
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
},
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
}

922
src/store/modules/user.js Normal file
View File

@ -0,0 +1,922 @@
import { Login, Logout, GetInfo, GetAllDict, GetThemeConfig, GetStationByUser, LoginByBigScreen, checkPlatToken, GetCommonScreenToken, GetApplyLargeScreenToken, getEventNum } from '@/api/user'
import {
getProvinceStation
} from '@/api/station/maintain'
import { getToken, setToken, removeToken, setIV, setAseKey, setScreenToken } from '@/utils/auth'
import router, { resetRouter } from '@/router'
import { encryptPsd, JSEncryptData, JSEncryptDataByBigScreen } from '@/utils'
import { searchTree, validURL } from '@/utils/validate'
import { GetExclusiveMenu } from '@/api/user'
import store from '@/store'
const whiteList = ['/task/all-task-detail'] // no redirect whitelist
// import bcrypt from 'bcryptjs'
const state = {
token: getToken(),
userinfo: {},
permissions: [],
mainMenus: [],
menuList: [],
roles: [],
dicts: {},
stations: [],
currentStation: {},
selectId: undefined, // 当前电站的id
publicKey: 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCuG6ZABNgLQCI9iVPDuJEb7xb5zR9UGKyKXshLuJFZxyNtaEzfpjSMqsshUYA1QpwUvkmZE0lcRE4F4QtZO9rDnH2PoW1FWRbjgg0+MKWOmZr9hSPKM/BIE+knTtTaj4/0TK7QwDd9q/QAIduC1hIyxIIkxfWx0gFuTnxui0waCwIDAQAB',
activeMenuName: '',
isHasHomePage: 0, // -1 没有 其他 有
isHasAlarmPage: 0, // -1 没有 其他 有
isHasTaskPage: 0, // -1 没有 其他 有
userDeptId: -1,
alarmNum: 0,
password: '',
isScreenEnter: false,
isBell: '', // 是否是从右上角进入 查看实时数据 2.右上角 1.正常
searchHeight: null, // table的筛选高度
logoUrl: null,
screenToken: null,
msgChange: 0,
config: {}
}
const mutations = {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_PERMISSIONS: (state, permissions) => {
state.permissions = permissions
},
SET_MENU_LIST: (state, menuList) => {
state.menuList = menuList
},
SET_MAIN_MENU: (state, mainMenus) => {
state.mainMenus = mainMenus
},
SET_USER_INFO: (state, userinfo) => {
state.userinfo = userinfo
},
SET_IS_HAS_TASK: (state, isHasTaskPage) => {
state.isHasTaskPage = isHasTaskPage
},
SET_ROLES: (state, roles) => {
state.roles = roles
},
SET_DICTS: (state, dicts) => {
state.dicts = dicts
},
SET_STATION: (state, stations) => {
state.stations = stations
},
SET_CURRENT_STATION: (state, currentStation) => {
state.currentStation = currentStation
},
SET_ACTIVE_MENU: (state, activeMenuName) => {
state.activeMenuName = activeMenuName
},
SET_ISHAS_HOMEPAGE: (state, isHasHomePage) => {
state.isHasHomePage = isHasHomePage
},
SET_SELECT_ID: (state, selectId) => {
state.selectId = selectId
localStorage.setItem('currentStationId', selectId)
},
SET_IS_HAS_ALARM: (state, isHasAlarmPage) => {
state.isHasAlarmPage = isHasAlarmPage
},
SET_ALARM_NUM: (state, alarmNum) => {
state.alarmNum = alarmNum
},
SET_USER_DEPT_ID: (state, userDeptId) => {
state.userDeptId = userDeptId
},
SET_BELL_VALUE: (state, isBell) => {
localStorage.setItem('isBell', isBell)
state.isBell = isBell
},
SET_PASSWORD: (state, password) => {
state.password = password
},
SET_SCREEN_ENTER: (state, isScreenEnter) => {
state.isScreenEnter = isScreenEnter
},
SET_SEARCH_HEIGHT: (state, searchHeight) => {
state.searchHeight = searchHeight
},
SET_LOGOURL: (state, logoUrl) => {
state.logoUrl = logoUrl
},
SET_SCREEN_TOKEN: (state, screenToken) => {
state.screenToken = screenToken
},
SET_MSG_CHANGE: (state, msgChange) => {
state.msgChange = msgChange
},
SET_THEME_CONFIG: (state, config) => {
localStorage.setItem('themeConfig', JSON.stringify(config))
state.config = config
}
}
const actions = {
getNewMenu({ commit, state }, { id, path }) {
const params = {
stationId: id
}
return new Promise((resolve, reject) => {
GetExclusiveMenu(params).then(response => {
const { data } = response
const menuList = data
let subMenu = []
if (window.location.href !== process.env.VUE_APP_VISUALE_API + '/#' + '/screen' && window.location.href !== process.env.VUE_APP_VISUALE_API + '/#' + '/new-screen' && window.location.href !== process.env.VUE_APP_VISUALE_API + '/#' + '/common-screen' && window.location.href !== process.env.VUE_APP_VISUALE_API + '/#' + '/new-screen-zz') {
if (menuList) { // 有菜单
const menu = searchTree('/surveillance/site-homepage', menuList, 'url')// 查询站首页
const hasAlarmPage = searchTree('/alarm/realtime', menuList, 'url')// 查询站首页
if (hasAlarmPage.length > 0) {
commit('SET_IS_HAS_ALARM', hasAlarmPage[0])
} else {
commit('SET_IS_HAS_ALARM', -1)
}
menuList.forEach(menu => { // 暂时没有activeName
menu.isActive = false
})
let seq // 站首页父节点的index
if (menu.length > 0) { // 如果有一级菜单包含站首页则此一级菜单设置成active
const menuSeq = menuList.findIndex(item => item.id === menu[0].id) !== -1 ? menuList.findIndex(item => item.id === menu[0].id) : 0
commit('SET_ISHAS_HOMEPAGE', menuSeq !== -1 ? menuSeq : -1) // 是否有站首页 -1 没有 其他 有
seq = menuSeq !== -1 ? menuSeq : 0
} else { // 没有站首页就返回第一个
seq = 0
commit('SET_ISHAS_HOMEPAGE', -1)
}
if (localStorage.getItem('activeMenuName')) { // 缓存中的activeName
const index = menuList.findIndex(item => {
return item.name === localStorage.getItem('activeMenuName')
})
if (index !== -1) { // 一级菜单没有被禁用
menuList[index].isActive = true
subMenu = menuList[index].children
if (whiteList.indexOf(path) !== -1) { // 找到了
path = '/task/all-task'
}
const urlIndex = subMenu.findIndex(item => item.url === path)// 突然当前路径 被禁用
if (subMenu.length > 0 && !subMenu[0].children.length && urlIndex === -1) { // 有subMenu的菜单
router.push(subMenu[0].url)
} else if (subMenu.length > 0 && subMenu[0].children.length > 0 && urlIndex === -1) { // subMenu 子菜单为空
router.push(subMenu[0].children[0].url)
} else if (subMenu.length === 0) { // subMenu 子菜单为空
store.dispatch('app/toggleDevice', 'desktop')
store.dispatch('app/closeSideBar', { withoutAnimation: true })
}
} else { // 一级菜单突然被禁用
// // 在菜单中找一个一级菜单不是外部链接的
const canSetIndex = menuList.findIndex(item => item.children.length > 0)
if (canSetIndex !== -1) { // 找到一个有children 的一级菜单
menuList[canSetIndex].isActive = true// 设置active
subMenu = menuList[canSetIndex].children // 设置submenu
const canSetUrlIndex = subMenu.findIndex(item => !validURL(item.url)) // submenu 里面含有 本地路径
if (canSetUrlIndex !== -1) { // 如果有
router.push(subMenu[canSetUrlIndex].url)
} else { // 没有的话就直接跳转成站首页
router.push('/surveillance/site-homepage')
}
} else { // 找不到含有children的一级菜单,直接跳转站首页
router.push('/surveillance/site-homepage')
}
}
} else { // 缓存中没有activeName
if (menuList.length === 1 && menuList[0].children.length === 0) {
router.push(menuList[0].url)
} else {
menuList[seq].isActive = true // 直接设置有站首页的一级菜单为active
router.push(menuList[seq].children[0].url)
localStorage.setItem('activeMenuName', menuList[seq].name)
}
if (menuList[seq].children.length === 0) {
subMenu = []
store.dispatch('app/toggleDevice', 'desktop')
store.dispatch('app/closeSideBar', { withoutAnimation: true })
} else {
subMenu = menuList[seq].children
}
}
}
}
commit('SET_MAIN_MENU', menuList)
commit('SET_MENU_LIST', subMenu)
resolve(data)
}).catch(error => {
reject(error)
})
})
},
// user login
login({ commit }, userInfo) {
// const salt = bcrypt.genSaltSync(10) // 定义密码加密的计算强度,默认10
// const hash = bcrypt.hashSync(userInfo.password, salt) // 变量hash就是加密后的密码
const { username, password } = userInfo
commit('SET_PASSWORD', password)
localStorage.setItem('password', password)
const encryptData = encryptPsd(password)
const publicData = JSEncryptData(state.publicKey, encryptData.iv, encryptData.key)
const params = {
username: username.trim(),
password: encryptData.password,
type: 'pc',
aesKey: publicData.keyData,
iv: publicData.ivData
}
setIV(encryptData.iv)
setAseKey(encryptData.key)
return new Promise((resolve, reject) => {
Login(params).then(response => {
const { data } = response
commit('SET_TOKEN', data.accessToken)
setToken(data.accessToken)
resolve()
}).catch(error => {
reject(error)
})
})
},
loginByBigscreen({ commit }, bigToken) {
// const salt = bcrypt.genSaltSync(10) // 定义密码加密的计算强度,默认10
// const hash = bcrypt.hashSync(userInfo.password, salt) // 变量hash就是加密后的密码
const publicData = JSEncryptDataByBigScreen(state.publicKey)
const params = {
bigToken: bigToken,
type: 'pc',
aesKey: publicData.keyData,
iv: publicData.ivData
}
setIV(publicData.iv)
setAseKey(publicData.key)
return new Promise((resolve, reject) => {
LoginByBigScreen(params).then(response => {
const { data } = response
commit('SET_TOKEN', data.accessToken)
setToken(data.accessToken)
resolve()
}).catch(error => {
reject(error)
})
})
},
// get user info
getInfo({ commit, state }, path) {
return new Promise((resolve, reject) => {
GetInfo().then(response => {
const { data } = response
commit('SET_USER_DEPT_ID', data.deptId)
GetThemeConfig(data.userId).then((res, rej) => {
commit('SET_THEME_CONFIG', res.data)
})
if (!data) {
reject('Verification failed, please Login again.')
}
const { roles, powerList } = data
// 判断是否事进入大屏
commit('SET_ROLES', roles)
commit('SET_PERMISSIONS', powerList)
commit('SET_USER_INFO', data)
resolve(data)
}).catch(error => {
reject(error)
})
})
},
// user logout
logout({ commit, state, dispatch }) {
return new Promise((resolve, reject) => {
Logout(state.token).then(() => {
localStorage.removeItem('activeMenuName')
localStorage.removeItem('currentStationId')
localStorage.removeItem('stationAddress')
localStorage.removeItem('password')
localStorage.removeItem('userpassword')
localStorage.removeItem('stationIdAndDeviceList')
state.mainMenus.forEach(item => {
localStorage.removeItem(item.name)
})
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
commit('SET_LOGOURL', undefined)
commit('SET_SELECT_ID', undefined)
commit('SET_STATION', [])
removeToken()
resetRouter()
// reset visited views and cached views
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485
dispatch('tagsView/delAllViews', null, { root: true })
// router.push(`${localStorage.getItem('loginPage')}?redirect=${this.$route.fullPath}`)
resolve()
}).catch(error => {
reject(error)
})
})
},
getScreenToken({ commit, state, dispatch }) {
return new Promise((resolve, reject) => {
GetCommonScreenToken().then((res) => {
commit('SET_SCREEN_TOKEN', res.data.token)
console.log('setScreenToken', new Date())
setScreenToken(res.data.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
// get alarmNum
getAlarmNum({ commit, state, dispatch }) {
return new Promise((resolve, reject) => {
const params = {
stationId: state.currentStation.id
}
getEventNum(params).then((res) => {
commit('SET_ALARM_NUM', res.data)
resolve()
}).catch(error => {
reject(error)
})
})
},
// user getAllDict
getAllDict({ commit, state, dispatch }) {
return new Promise((resolve, reject) => {
GetAllDict().then((response) => {
const { data } = response
const dicts = {}
data.forEach(element => {
dicts[element.type] = element.list
})
commit('SET_DICTS', dicts)
resolve()
}).catch(error => {
reject(error)
})
})
},
getAdminMain({ commit, state }, { path }) {
const menuList = [
{
'id': 28,
'code': null,
'name': '系统管理',
'perms': '',
'url': '/system',
'urlApp': null,
'icon': 'icon-xitongguanli',
'iconApp': 'icon-xitongguanli',
'method': '',
'pid': 0,
'pidName': null,
'orderNum': 18,
'type': 2,
'show': 'pc',
'color': null,
'status': 1,
'createTime': '2019-09-28T15:16:14.000+0800',
'updateTime': '2024-10-14T11:19:37.000+0800',
'deleted': 1,
'children': [
{
'id': 10,
'code': null,
'name': '菜单管理',
'perms': '',
'url': '/system/menu',
'urlApp': null,
'icon': 'icon-caidanguanli',
'iconApp': null,
'method': 'GET',
'pid': 28,
'pidName': null,
'orderNum': 3,
'type': 2,
'show': 'all',
'color': null,
'status': 1,
'createTime': '2019-09-22T15:18:12.000+0800',
'updateTime': '2023-08-08T08:57:30.000+0800',
'deleted': 1,
'children': [],
'scope': null,
'isConfig': null,
'component': null,
'menuName': null,
'stationList': null
},
{
'id': 3,
'code': '',
'name': '用户管理',
'perms': '',
'url': '/system/user',
'urlApp': null,
'icon': 'icon-yonghuguanli',
'iconApp': null,
'method': 'GET',
'pid': 28,
'pidName': null,
'orderNum': 4,
'type': 2,
'show': 'all',
'color': null,
'status': 1,
'createTime': '2020-01-01T19:30:30.000+0800',
'updateTime': '2023-08-08T08:57:30.000+0800',
'deleted': 1,
'children': [],
'scope': null,
'isConfig': null,
'component': null,
'menuName': null,
'stationList': null
},
{
'id': 11,
'code': null,
'name': '角色管理',
'perms': null,
'url': '/system/role',
'urlApp': null,
'icon': 'icon-navicon-jsgl',
'iconApp': null,
'method': null,
'pid': 28,
'pidName': null,
'orderNum': 5,
'type': 2,
'show': 'all',
'color': null,
'status': 1,
'createTime': '2023-01-06T09:26:20.000+0800',
'updateTime': '2023-08-08T08:57:30.000+0800',
'deleted': 1,
'children': [],
'scope': null,
'isConfig': null,
'component': null,
'menuName': null,
'stationList': null
},
{
'id': 4,
'code': '',
'name': '组织机构管理',
'perms': '',
'url': '/system/org',
'urlApp': null,
'icon': 'icon-zuzhijigouguanli',
'iconApp': null,
'method': 'GET',
'pid': 28,
'pidName': null,
'orderNum': 6,
'type': 2,
'show': 'all',
'color': null,
'status': 1,
'createTime': '2019-11-07T22:37:20.000+0800',
'updateTime': '2023-08-08T08:57:30.000+0800',
'deleted': 1,
'children': [],
'scope': null,
'isConfig': null,
'component': null,
'menuName': null,
'stationList': null
},
{
'id': 5,
'code': null,
'name': '日志管理',
'perms': null,
'url': '/system/log',
'urlApp': null,
'icon': 'icon-rizhiguanli',
'iconApp': null,
'method': null,
'pid': 28,
'pidName': null,
'orderNum': 7,
'type': 2,
'show': 'all',
'color': null,
'status': 1,
'createTime': '2022-08-23T09:50:51.000+0800',
'updateTime': '2024-01-22T17:13:56.000+0800',
'deleted': 1,
'children': [],
'scope': null,
'isConfig': null,
'component': null,
'menuName': null,
'stationList': null
},
{
'id': 6,
'code': null,
'name': '字典管理',
'perms': null,
'url': '/system/dictionary',
'urlApp': null,
'icon': 'icon-tubiaozhizuomoban-27',
'iconApp': null,
'method': null,
'pid': 28,
'pidName': null,
'orderNum': 9,
'type': 2,
'show': 'all',
'color': null,
'status': 1,
'createTime': '2022-08-23T13:36:04.000+0800',
'updateTime': '2023-08-08T08:57:30.000+0800',
'deleted': 1,
'children': [],
'scope': null,
'isConfig': null,
'component': null,
'menuName': null,
'stationList': null
},
{
'id': 8,
'code': null,
'name': '站点管理',
'perms': null,
'url': '/system/department',
'urlApp': null,
'icon': 'icon-zhandianguanli',
'iconApp': null,
'method': null,
'pid': 28,
'pidName': null,
'orderNum': 11,
'type': 2,
'show': 'pc',
'color': null,
'status': 1,
'createTime': '2022-12-30T11:10:42.000+0800',
'updateTime': '2023-08-18T14:52:04.000+0800',
'deleted': 1,
'children': [],
'scope': null,
'isConfig': null,
'component': null,
'menuName': null,
'stationList': null
},
{
'id': 1161,
'code': null,
'name': '费率模板管理',
'perms': null,
'url': '/system/rate',
'urlApp': null,
'icon': 'icon-yemianpeizhi',
'iconApp': null,
'method': null,
'pid': 28,
'pidName': null,
'orderNum': 14,
'type': 2,
'show': 'all',
'color': null,
'status': 1,
'createTime': '2024-08-02T09:47:57.000+0800',
'updateTime': '2024-08-02T09:48:12.000+0800',
'deleted': 1,
'children': [],
'scope': null,
'isConfig': 0,
'component': null,
'menuName': null,
'stationList': null
},
{
'id': 7,
'code': null,
'name': '岗位管理',
'perms': null,
'url': '/system/post',
'urlApp': null,
'icon': 'icon-gangwei',
'iconApp': null,
'method': null,
'pid': 28,
'pidName': null,
'orderNum': 16,
'type': 2,
'show': 'pc',
'color': null,
'status': 1,
'createTime': '2022-12-19T09:29:35.000+0800',
'updateTime': '2024-07-26T17:04:40.000+0800',
'deleted': 1,
'children': [],
'scope': null,
'isConfig': null,
'component': null,
'menuName': null,
'stationList': null
},
{
'id': 891,
'code': null,
'name': '电站角色管理',
'perms': null,
'url': '/system/station-role',
'urlApp': null,
'icon': 'icon-yemianpeizhi',
'iconApp': null,
'method': null,
'pid': 28,
'pidName': null,
'orderNum': 18,
'type': 2,
'show': 'all',
'color': null,
'status': 1,
'createTime': '2023-06-20T17:07:15.000+0800',
'updateTime': '2024-07-26T17:04:40.000+0800',
'deleted': 1,
'children': [],
'scope': null,
'isConfig': null,
'component': null,
'menuName': null,
'stationList': null
}
]
}
]
let subMenu = []
if (window.location.href !== process.env.VUE_APP_VISUALE_API + '/#' + '/screen' && window.location.href !== process.env.VUE_APP_VISUALE_API + '/#' + '/new-screen' && window.location.href !== process.env.VUE_APP_VISUALE_API + '/#' + '/common-screen' && window.location.href !== process.env.VUE_APP_VISUALE_API + '/#' + '/new-screen-zz') {
if (menuList) { // 有菜单
const menu = searchTree('/surveillance/site-homepage', menuList, 'url')// 查询站首页
const hasAlarmPage = searchTree('/alarm/realtime', menuList, 'url')// 查询站首页
if (hasAlarmPage.length > 0) {
commit('SET_IS_HAS_ALARM', hasAlarmPage[0])
} else {
commit('SET_IS_HAS_ALARM', -1)
}
menuList.forEach(menu => { // 暂时没有activeName
menu.isActive = false
})
let seq // 站首页父节点的index
if (menu.length > 0) { // 如果有一级菜单包含站首页则此一级菜单设置成active
const menuSeq = menuList.findIndex(item => item.id === menu[0].id) !== -1 ? menuList.findIndex(item => item.id === menu[0].id) : 0
commit('SET_ISHAS_HOMEPAGE', menuSeq !== -1 ? menuSeq : -1) // 是否有站首页 -1 没有 其他 有
seq = menuSeq !== -1 ? menuSeq : 0
} else { // 没有站首页就返回第一个
seq = 0
commit('SET_ISHAS_HOMEPAGE', -1)
}
if (localStorage.getItem('activeMenuName')) { // 缓存中的activeName
const index = menuList.findIndex(item => {
return item.name === localStorage.getItem('activeMenuName')
})
if (index !== -1) { // 一级菜单没有被禁用
menuList[index].isActive = true
subMenu = menuList[index].children
if (whiteList.indexOf(path) !== -1) { // 找到了
path = '/task/all-task'
}
const urlIndex = subMenu.findIndex(item => item.url === path)// 突然当前路径 被禁用
if (subMenu.length > 0 && !subMenu[0].children.length && urlIndex === -1) { // 有subMenu的菜单
router.push(subMenu[0].url)
} else if (subMenu.length > 0 && subMenu[0].children.length > 0 && urlIndex === -1) { // subMenu 子菜单为空
router.push(subMenu[0].children[0].url)
} else if (subMenu.length === 0) { // subMenu 子菜单为空
store.dispatch('app/toggleDevice', 'desktop')
store.dispatch('app/closeSideBar', { withoutAnimation: true })
}
} else { // 一级菜单突然被禁用
// // 在菜单中找一个一级菜单不是外部链接的
const canSetIndex = menuList.findIndex(item => item.children.length > 0)
if (canSetIndex !== -1) { // 找到一个有children 的一级菜单
menuList[canSetIndex].isActive = true// 设置active
subMenu = menuList[canSetIndex].children // 设置submenu
const canSetUrlIndex = subMenu.findIndex(item => !validURL(item.url)) // submenu 里面含有 本地路径
if (canSetUrlIndex !== -1) { // 如果有
router.push(subMenu[canSetUrlIndex].url)
} else { // 没有的话就直接跳转成站首页
router.push('/surveillance/site-homepage')
}
} else { // 找不到含有children的一级菜单,直接跳转站首页
router.push('/surveillance/site-homepage')
}
}
} else { // 缓存中没有activeName
if (menuList.length === 1 && menuList[0].children.length === 0) {
router.push(menuList[0].url)
} else {
menuList[seq].isActive = true // 直接设置有站首页的一级菜单为active
router.push(menuList[seq].children[0].url)
localStorage.setItem('activeMenuName', menuList[seq].name)
}
if (menuList[seq].children.length === 0) {
subMenu = []
store.dispatch('app/toggleDevice', 'desktop')
store.dispatch('app/closeSideBar', { withoutAnimation: true })
} else {
subMenu = menuList[seq].children
}
}
}
}
commit('SET_MAIN_MENU', menuList)
commit('SET_MENU_LIST', subMenu)
},
// user getAllDict
getStationByUser({ commit, state, dispatch }) {
return new Promise((resolve, reject) => {
GetStationByUser().then((response) => {
console.log(state.userinfo)
const { data } = response
commit('SET_STATION', data)
getProvinceStation().then((res) => {
if (res.data.list.length) {
store.dispatch('user/getNewMenu', {
id: localStorage.getItem('currentStationId') ? localStorage.getItem('currentStationId') : res.data.list[0].list[0].list[0].id,
path: ''
})
} else if (state.userinfo.username === 'admin' && !res.data.list.length) {
store.dispatch('user/getAdminMain', {
path: ''
})
}
})
resolve()
}).catch(error => {
reject(error)
})
})
},
// remove token
resetToken({ commit }) {
return new Promise(resolve => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
commit('SET_SELECT_ID', undefined)
commit('SET_STATION', [])
localStorage.removeItem('activeMenuName')
state.mainMenus.forEach(item => {
localStorage.removeItem(item.name)
})
localStorage.removeItem('currentStationId')
localStorage.removeItem('stationAddress')
removeToken()
resolve()
})
},
// mainMenu click
mainMenuChange({ commit }, index) {
return new Promise(resolve => {
const menuList = state.mainMenus
const subMenu = menuList[index].children
if (subMenu.length > 0) {
menuList.forEach((menu, num) => {
if (index === num) {
menu.isActive = true
} else {
menu.isActive = false
}
})
commit('SET_ACTIVE_MENU', menuList[index].name)
localStorage.setItem('activeMenuName', menuList[index].name)
const url = subMenu[0].children && subMenu[0].children.length > 0 ? subMenu[0].children[0].url : subMenu[0].url
if (validURL(url)) {
if (localStorage.getItem(menuList[index].name) !== null) { // 上次点击的路径
router.push(localStorage.getItem(menuList[index].name) !== null ? localStorage.getItem(menuList[index].name) : url)
} else {
checkPlatToken().then(res => {
if (res.data) {
GetApplyLargeScreenToken().then(response => {
const href = url + '?token=' + response.data.accessToken
window.open(href, '_blank')
})
} else {
store.dispatch('user/logout')
router.push(`${localStorage.getItem('loginPage')}`)
}
})
}
} else {
store.dispatch('app/toggleDevice', 'desktop')
if (!store.getters.sidebar.opened) {
store.dispatch('app/toggleSideBar')
}
const urlIndex = subMenu.findIndex(menu => menu.url === localStorage.getItem(menuList[index].name))// 判断缓存的路径是否在submenu中
if (localStorage.getItem(menuList[index].name) && urlIndex !== -1) { // 不为空 并且在
router.push(localStorage.getItem(menuList[index].name))
} else { // 为空 或者 不在
router.push(url)
}
}
commit('SET_MENU_LIST', subMenu)
} else {
const url = menuList[index].url
if (validURL(url)) {
checkPlatToken().then(res => {
if (res.data) {
GetApplyLargeScreenToken().then(response => {
const href = url + '?token=' + response.data.accessToken
window.open(href, '_blank')
})
} else {
store.dispatch('user/logout')
router.push(`/login`)
}
})
} else {
if (url === '/screen' || url === '/new-screen' || url === '/common-screen') {
if (url === '/common-screen') {
store.dispatch('user/getScreenToken')
}
const href = process.env.VUE_APP_VISUALE_API + '/#' + url
window.open(href, '_blank')
} else {
store.dispatch('app/toggleDevice', 'desktop')
store.dispatch('app/closeSideBar', { withoutAnimation: true })
router.push(url)
commit('SET_MENU_LIST', subMenu)
}
}
}
commit('SET_MAIN_MENU', menuList)
resolve()
})
},
// dynamically modify permissions
async changeRoles({ commit, dispatch }, role) {
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 })
},
menuChange({ commit, dispatch }, params) {
const url = params.url
const urlName = params.urlName
const menuList = state.mainMenus
// 1.查询url在哪个mainList里面
const menu = searchTree(url, menuList, 'url')// 查询站首页
// 2.设置所有菜单为未选中
menuList.forEach(menu => { // 暂时没有activeName
menu.isActive = false
})
// 3. 查询url在mainMenus里面的index
const menuSeq = menuList.findIndex(item => item.id === menu[0].id) !== -1 ? menuList.findIndex(item => item.id === menu[0].id) : 0
// 4.直接设置有的一级菜单为active
menuList[menuSeq].isActive = true
commit('SET_ACTIVE_MENU', menuList[menuSeq].name)
localStorage.setItem('activeMenuName', menuList[menuSeq].name)
localStorage.getItem(menuList[menuSeq].name, url)
// 5.跳转
router.push({ name: urlName, params: params.data })
// 6.设置 右侧menuList
commit('SET_MENU_LIST', menuList[menuSeq].children)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}