375 lines
12 KiB
JavaScript
375 lines
12 KiB
JavaScript
|
|
import * as appService from "../services/login";
|
|||
|
|
import { routerRedux } from "dva/router";
|
|||
|
|
import { initFilter } from "../utils/common";
|
|||
|
|
import storage from "../utils/storage";
|
|||
|
|
import { history as globalHistory } from "../utils/history";
|
|||
|
|
import { cloneDeep } from "lodash";
|
|||
|
|
import ReactDOM from "react-dom";
|
|||
|
|
import { Spin } from "antd";
|
|||
|
|
import config from "../config";
|
|||
|
|
|
|||
|
|
function recurseMenu(menus, parentMenu = {}, flatMenus = []) {
|
|||
|
|
menus.forEach((menu) => {
|
|||
|
|
const { Node: Menu, Children: ChildMenus } = menu;
|
|||
|
|
menu.Menu = Menu;
|
|||
|
|
menu.ChildMenus = ChildMenus;
|
|||
|
|
Menu.idLevels = (parentMenu.idLevels || []).concat(Menu.ID);
|
|||
|
|
Menu.nameLevels = (parentMenu.nameLevels || []).concat(Menu.NAME);
|
|||
|
|
Menu.menuLevels = (parentMenu.menuLevels || []).concat(Menu.MENU_LEVEL);
|
|||
|
|
Menu.childMenuLevels = (parentMenu.childMenuLevels || []).concat([
|
|||
|
|
ChildMenus,
|
|||
|
|
]);
|
|||
|
|
flatMenus.push(Menu);
|
|||
|
|
ChildMenus && ChildMenus.length && recurseMenu(ChildMenus, Menu, flatMenus);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 当前正在请求的数量
|
|||
|
|
let requestCount = 0;
|
|||
|
|
|
|||
|
|
// 显示loading
|
|||
|
|
function showLoading() {
|
|||
|
|
const spinStyle = {
|
|||
|
|
position: "fixed",
|
|||
|
|
width: "100vw",
|
|||
|
|
height: "100vh",
|
|||
|
|
justifyContent: "center",
|
|||
|
|
alignItems: "center",
|
|||
|
|
display: "flex",
|
|||
|
|
top: 0,
|
|||
|
|
left: 0,
|
|||
|
|
background: "rgba(229, 229, 229, 0.5)",
|
|||
|
|
zIndex: 1000,
|
|||
|
|
};
|
|||
|
|
if (requestCount === 0) {
|
|||
|
|
var dom = document.createElement("div");
|
|||
|
|
dom.setAttribute("id", "loading");
|
|||
|
|
document.body.appendChild(dom);
|
|||
|
|
ReactDOM.render(
|
|||
|
|
<div style={spinStyle}>
|
|||
|
|
<Spin tip="加载中..." size="large" />
|
|||
|
|
</div>,
|
|||
|
|
dom
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
requestCount++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 隐藏loading
|
|||
|
|
function hideLoading() {
|
|||
|
|
requestCount--;
|
|||
|
|
if (requestCount === 0) {
|
|||
|
|
document.body.removeChild(document.getElementById("loading"));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default {
|
|||
|
|
namespace: "login",
|
|||
|
|
state: {
|
|||
|
|
loginInfo: {},
|
|||
|
|
OrgId: "",
|
|||
|
|
baseConfig: {},
|
|||
|
|
userId: "",
|
|||
|
|
user: {},
|
|||
|
|
Tenant: storage("lacal").getItem("Tenant").val,
|
|||
|
|
Notifications: [],
|
|||
|
|
screenLocked: false, // 是否锁屏
|
|||
|
|
flatMenus: [],
|
|||
|
|
currActivatedTab: null, // 用于面包屑导航,同步于 model app
|
|||
|
|
currActivatedMenu: null, // 当前选中的菜单项,同步于 model app
|
|||
|
|
},
|
|||
|
|
subscriptions: {
|
|||
|
|
setup({ dispatch, history }) {
|
|||
|
|
history.listen((params) => {
|
|||
|
|
const toLogin = function () {
|
|||
|
|
let tm;
|
|||
|
|
showLoading();
|
|||
|
|
tm = setTimeout(() => {
|
|||
|
|
localStorage.removeItem("accessToken");
|
|||
|
|
dispatch(routerRedux.push("/login"));
|
|||
|
|
hideLoading();
|
|||
|
|
}, 10000);
|
|||
|
|
const { username, password } =
|
|||
|
|
storage("lacal").getItem("loginUserVerify").val;
|
|||
|
|
const webOrgId = storage("lacal").getItem("webOrgId").val;
|
|||
|
|
dispatch({
|
|||
|
|
type: "toLogin",
|
|||
|
|
payload: {
|
|||
|
|
Parameter1: username,
|
|||
|
|
Parameter2: password,
|
|||
|
|
Parameter4: webOrgId,
|
|||
|
|
Parameter5: storage("lacal").getItem("formConfigVersion").val,
|
|||
|
|
Parameter7: true,
|
|||
|
|
},
|
|||
|
|
}).then((validRes) => {
|
|||
|
|
if (validRes) {
|
|||
|
|
dispatch({
|
|||
|
|
type: "getOrg",
|
|||
|
|
payload: {
|
|||
|
|
Sort: "CODE",
|
|||
|
|
Order: 0,
|
|||
|
|
Parameter10: window.location.host,
|
|||
|
|
Parameter11: "0",
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
dispatch({
|
|||
|
|
type: "refreshToken",
|
|||
|
|
});
|
|||
|
|
dispatch({
|
|||
|
|
type: "app/getCurrVer",
|
|||
|
|
});
|
|||
|
|
dispatch({
|
|||
|
|
type: "app/getAllEnum",
|
|||
|
|
}).then((e) => {
|
|||
|
|
clearTimeout(tm);
|
|||
|
|
hideLoading();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const { pathname } = params;
|
|||
|
|
if (pathname !== "/login") {
|
|||
|
|
/**
|
|||
|
|
* 当前页不在登录页,并且 local 不存在 token
|
|||
|
|
* 那么直接跳转登录页
|
|||
|
|
*/
|
|||
|
|
if (!storage("lacal").getItem("accessToken").val) {
|
|||
|
|
dispatch(routerRedux.push("/login"));
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* 当前页不在登录页,并且 local 存在 token
|
|||
|
|
* 如果不存在 OrgId,则说明还未登录,此时调用登录接口
|
|||
|
|
*/
|
|||
|
|
dispatch({
|
|||
|
|
type: "checkLoginStatus",
|
|||
|
|
onFail: () => toLogin(),
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
/**
|
|||
|
|
* 当前页在登录页,并且 local 存在 token
|
|||
|
|
* 则直接跳转到首页,首页调用的接口会验证此 token 是否过期
|
|||
|
|
* 如果 local token 真的过期,那么还是会自动跳转到登录页
|
|||
|
|
* 如果 local token 没过期,则正常停留在主页
|
|||
|
|
*/
|
|||
|
|
if (storage("lacal").getItem("accessToken").val) {
|
|||
|
|
if (window.navigator.userAgent.indexOf("Windows") < 1) {
|
|||
|
|
window.location.replace(config.guideH5Host);
|
|||
|
|
// dispatch(routerRedux.push("/HomeMobileNew"));
|
|||
|
|
} else {
|
|||
|
|
dispatch(routerRedux.push("/home"));
|
|||
|
|
}
|
|||
|
|
// 新开 tab 页面,直接从 login 路径进来,则需要重新检查一下是否登录,未登录则执行登录获取到菜单以及必要数据
|
|||
|
|
dispatch({
|
|||
|
|
type: "checkLoginStatus",
|
|||
|
|
onFail: () => toLogin(),
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
effects: {
|
|||
|
|
// 获取组织列表
|
|||
|
|
*getOrg({ payload }, { call, put }) {
|
|||
|
|
const ret = yield call(appService.getOrg, payload);
|
|||
|
|
if (ret) {
|
|||
|
|
const { Tenant = "", Data = [] } = ret;
|
|||
|
|
storage("lacal").setItem("Tenant", Tenant);
|
|||
|
|
storage("lacal").setItem("RootOrgId", Data[0]?.Node?.ID || "");
|
|||
|
|
yield put({ type: "save", payload: { Tenant } });
|
|||
|
|
}
|
|||
|
|
return ret;
|
|||
|
|
},
|
|||
|
|
// 获取 Token
|
|||
|
|
*getToken({ payload }, { call }) {
|
|||
|
|
return yield call(appService.getToken, payload);
|
|||
|
|
},
|
|||
|
|
// 刷新 Token,以保持登录状态
|
|||
|
|
*refreshToken({ payload }, { call, put, select }) {
|
|||
|
|
// 锁屏状态下不更新
|
|||
|
|
const { screenLocked } = yield select((state) => state.login);
|
|||
|
|
if (screenLocked) return;
|
|||
|
|
// 存在 payload 则只更新 payload 中的 token
|
|||
|
|
if (payload) {
|
|||
|
|
const { access_token, refreshToken, expiresIn } = payload;
|
|||
|
|
storage("lacal").setItem("accessToken", access_token);
|
|||
|
|
storage("lacal").setItem("refreshToken", refreshToken);
|
|||
|
|
storage("lacal").setItem("expiresIn", expiresIn);
|
|||
|
|
storage("lacal").setItem("refreshTimestamp", new Date().getTime());
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
// 如果刷新的时候已经是过期之后的时间了,则不再继续刷新 token
|
|||
|
|
const nowTimestamp = new Date().getTime();
|
|||
|
|
const refreshTimestamp = storage("lacal").getItem("refreshTimestamp").val;
|
|||
|
|
const expiresIn = storage("lacal").getItem("expiresIn").val;
|
|||
|
|
// 登陆过期
|
|||
|
|
if (
|
|||
|
|
refreshTimestamp &&
|
|||
|
|
refreshTimestamp + expiresIn * 1000 <= nowTimestamp
|
|||
|
|
) {
|
|||
|
|
console.log("过期了");
|
|||
|
|
localStorage.removeItem("accessToken");
|
|||
|
|
globalHistory.push({ pathname: "/login" });
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
// 接口刷新 token
|
|||
|
|
const RefreshToken = storage("lacal").getItem("refreshToken").val;
|
|||
|
|
const ret = yield call(appService.getToken, {
|
|||
|
|
RefreshToken,
|
|||
|
|
grant_type: 2,
|
|||
|
|
});
|
|||
|
|
if (ret && !ret.error) {
|
|||
|
|
const { access_token, refreshToken, expiresIn } = ret;
|
|||
|
|
storage("lacal").setItem("accessToken", access_token);
|
|||
|
|
storage("lacal").setItem("refreshToken", refreshToken);
|
|||
|
|
storage("lacal").setItem("expiresIn", expiresIn);
|
|||
|
|
storage("lacal").setItem("refreshTimestamp", new Date().getTime());
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
// 登录、获取信息
|
|||
|
|
*toLogin({ payload, loginPayload }, { call, put, select }) {
|
|||
|
|
const ret = yield call(appService.getLoginInfo, payload);
|
|||
|
|
if (ret) {
|
|||
|
|
if (loginPayload) {
|
|||
|
|
const {
|
|||
|
|
accessToken,
|
|||
|
|
refreshToken,
|
|||
|
|
expiresIn,
|
|||
|
|
username,
|
|||
|
|
password,
|
|||
|
|
userid,
|
|||
|
|
} = loginPayload;
|
|||
|
|
storage("lacal").setItem("accessToken", accessToken); // access_token存入localStorage
|
|||
|
|
storage("lacal").setItem("refreshToken", refreshToken);
|
|||
|
|
storage("lacal").setItem("expiresIn", expiresIn);
|
|||
|
|
storage("lacal").setItem("refreshTimestamp", new Date().getTime());
|
|||
|
|
storage("lacal").setItem("userid", userid);
|
|||
|
|
storage("lacal").setItem("loginUserVerify", { username, password }); // 登录凭证存入localStorage
|
|||
|
|
}
|
|||
|
|
storage("lacal").setItem("webOrgId", ret.User.ORG_ID);
|
|||
|
|
storage("lacal").setItem("DataRule", ret.DataRule || []);
|
|||
|
|
storage("lacal").setItem("OrgRule", ret.OrgRule || []);
|
|||
|
|
storage("lacal").setItem("departmentId", ret.User.DEPARTMENT_ID);
|
|||
|
|
storage("lacal").setItem("MineType", ret.User.MineType);
|
|||
|
|
storage("lacal").setItem("UserType", ret.UserType);
|
|||
|
|
const localStorage = window.localStorage;
|
|||
|
|
|
|||
|
|
ret.FormConfigVersion &&
|
|||
|
|
storage("lacal").setItem("formConfigVersion", ret.FormConfigVersion);
|
|||
|
|
// 拍平 Menus
|
|||
|
|
const flatMenus = [];
|
|||
|
|
const copyMenus = cloneDeep(ret.Menus);
|
|||
|
|
recurseMenu(copyMenus, undefined, flatMenus);
|
|||
|
|
ret.Menus = copyMenus;
|
|||
|
|
|
|||
|
|
const currentMineType = localStorage.getItem("currentMineType");
|
|||
|
|
if (currentMineType) {
|
|||
|
|
var filterObj = function (item) {
|
|||
|
|
if (item.Node.MineType && item.Node.MineType.indexOf(currentMineType) > -1) {
|
|||
|
|
if (item.Children.length !== 0) {
|
|||
|
|
item.Children = item.Children.filter(function (child) {
|
|||
|
|
if (child.Children.length !== 0) {
|
|||
|
|
return filterObj(child);
|
|||
|
|
} else {
|
|||
|
|
if (child.Node.MineType) {
|
|||
|
|
return child.Node.MineType.indexOf(currentMineType) > -1
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
if (item.Children.length > 0) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
if (item.Node.MineType) {
|
|||
|
|
return item.Node.MineType.indexOf(currentMineType) > -1;
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
var filter = ret.Menus.filter(function (item) {
|
|||
|
|
return filterObj(item);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
ret.Menus = filter;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 存储 model state
|
|||
|
|
yield put({
|
|||
|
|
type: "save",
|
|||
|
|
payload: {
|
|||
|
|
loginInfo: ret,
|
|||
|
|
OrgId: ret.User.ORG_ID,
|
|||
|
|
OrgCode: ret.User.Nav_Org ? ret.User.Nav_Org.CODE : "",
|
|||
|
|
baseConfig: ret.BaseConfig,
|
|||
|
|
userType: ret.UserType,
|
|||
|
|
roles: ret.Roles,
|
|||
|
|
rolePerm: ret.Nav_RolePerm,
|
|||
|
|
userId: ret.User.ID,
|
|||
|
|
user: ret.User,
|
|||
|
|
flatMenus,
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
// 不是很清楚为什么这里要清除这个 requestKey
|
|||
|
|
// const localStorage = window.localStorage
|
|||
|
|
if (localStorage) {
|
|||
|
|
for (let i = 0; i < localStorage.length; i++) {
|
|||
|
|
const key = localStorage.key(i);
|
|||
|
|
if (key.indexOf("_requestKey") > -1) {
|
|||
|
|
localStorage.removeItem(key);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 获取消息提醒
|
|||
|
|
const getNoticesParams = initFilter(
|
|||
|
|
ret.User.ORG_ID,
|
|||
|
|
"",
|
|||
|
|
"CREATE_TIME",
|
|||
|
|
1,
|
|||
|
|
1,
|
|||
|
|
ret.User.ID
|
|||
|
|
);
|
|||
|
|
yield put({ type: "getNotices", payload: getNoticesParams });
|
|||
|
|
}
|
|||
|
|
return ret;
|
|||
|
|
},
|
|||
|
|
// 验证登录状态
|
|||
|
|
*checkLoginStatus({ onSuccess, onFail }, { select }) {
|
|||
|
|
const { OrgId } = yield select((state) => state.login);
|
|||
|
|
if (!OrgId) {
|
|||
|
|
onFail instanceof Function && onFail();
|
|||
|
|
} else {
|
|||
|
|
onSuccess instanceof Function && onSuccess();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
// 获取消息通知
|
|||
|
|
*getNotices({ payload }, { call, put }) {
|
|||
|
|
const ret = yield call(appService.getNotices, payload);
|
|||
|
|
yield put({
|
|||
|
|
type: "save",
|
|||
|
|
payload: {
|
|||
|
|
Notifications: ret,
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
return ret;
|
|||
|
|
},
|
|||
|
|
// 获取告警日志
|
|||
|
|
*getAlarmLog({ payload }, { call }) {
|
|||
|
|
return yield call(appService.getAlarmLog, payload);
|
|||
|
|
},
|
|||
|
|
// 修改密码
|
|||
|
|
*modifyPassword({ payload }, { call }) {
|
|||
|
|
return yield call(appService.modifyPassword, payload);
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
reducers: {
|
|||
|
|
save(state, action) {
|
|||
|
|
return { ...state, ...action.payload };
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
};
|