From 4b30915a101f8cd414ceea538010c27091ced38b Mon Sep 17 00:00:00 2001 From: ccy <55274652@qq.com> Date: Fri, 26 Dec 2025 15:23:06 +0800 Subject: [PATCH] =?UTF-8?q?websocket=E5=88=B7=E6=96=B0=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Edit/AlarmEditModal.js | 4 +- src/feui/alarm-notice/index.js | 37 ++++++- src/files/edit/SK018.js | 2 +- src/layout/Header.js | 2 +- src/layout/Main.js | 2 +- src/models/login.js | 138 ++++++++++++++++++++++++++ src/utils/request.js | 2 +- 7 files changed, 177 insertions(+), 10 deletions(-) diff --git a/src/components/Edit/AlarmEditModal.js b/src/components/Edit/AlarmEditModal.js index 16ad837..a46ea95 100644 --- a/src/components/Edit/AlarmEditModal.js +++ b/src/components/Edit/AlarmEditModal.js @@ -3,13 +3,13 @@ import React from 'react' import { connect } from 'dva' // 组件库 import { Modal, Form, Input, InputNumber, message, Tabs, Button, Row, Col } from 'antd' -import { LayoutCard, AlarmNotice } from '@woowalker/feui' +import { LayoutCard, AlarmNotice } from '../../feui' // eslint-disable-next-line no-unused-vars import FormPage from '../FormPage' import ListPage from '../Table/ListPage' // eslint-disable-next-line no-unused-vars import editPage from '../../models/editPage' -import { Socket } from '@woowalker/feui' +import { Socket } from '../../feui' import config from '../../config' // 样式 import styles from './edit.css' diff --git a/src/feui/alarm-notice/index.js b/src/feui/alarm-notice/index.js index 5fd9976..12c7cb7 100644 --- a/src/feui/alarm-notice/index.js +++ b/src/feui/alarm-notice/index.js @@ -1,19 +1,25 @@ import React, { useState, useEffect, useRef } from 'react' import PropTypes from 'prop-types' import { connect } from 'dva' -import { Icon, Badge } from 'antd' +import { Icon, Badge, Modal } from 'antd' import { Scrollbars } from 'react-custom-scrollbars' import IFComponent from '../common/IFComponent' import Socket from '../utils/socket' import { isEqual } from 'lodash' -function AlarmNotice (props) { +function AlarmNotice(props) { const [visible, setVisible] = useState(false) const [msg, setMsg] = useState({ AlarmId: null, TotalCount: 0, Message: '' }) + + const loginRef = useRef(props.login) + useEffect(() => { + loginRef.current = props.login + }, [props.login]) + useEffect(() => { let timer = -1 if (msg && !msg.TotalCount && !msg.Message && visible) { @@ -36,6 +42,7 @@ function AlarmNotice (props) { if (UserId && OrgId) { const socketIns = new Socket({ url: props.webSocketHost, + autoReconnect: true, onopen: handleSocketOpened, onmessage: handleSocketOnMsg }) @@ -48,7 +55,7 @@ function AlarmNotice (props) { }, [props.login.userId, props.login.OrgId, props.login.Tenant]) const handleSocketOpened = (socketIns) => { - const { user, userId: UserId, OrgId, Tenant } = props.login + const { user, userId: UserId, OrgId, Tenant } = loginRef.current const openedPayload = { TypeCode: 'P0001', Tenant, @@ -56,6 +63,7 @@ function AlarmNotice (props) { UserId, UserName: user.NAME, OrgId, + Tenant, ClientType: 0 }) } @@ -65,16 +73,37 @@ function AlarmNotice (props) { const handleSocketOnMsg = (data) => { if (data) { + console.log('收到消息', data) const { TypeCode, Data } = JSON.parse(data) if (TypeCode === 'M0003' && Data) { Data.Message && !isEqual(Data.Message, refOfMsg.current.Message) && !visible && setVisible(true) setMsg(Data) + } else if (TypeCode === 'MQ02') { + console.log('触发权限变更通知', data) + Modal.warning({ + title: '权限变更通知', + content: '当前用户权限已变更!', + okText: '确认', + onOk: () => { + const { userId, OrgId, Tenant } = loginRef.current + props.dispatch({ + type: 'login/getLoginInfo', + payload: { + UserId: userId, + OrgId, + Tenant, + onlyData: false, + noReload: true + } + }) + } + }) } } } const handleSocketSendMsg = (Data, socketIns) => { - const { userId: UserId, OrgId, Tenant } = props.login + const { userId: UserId, OrgId, Tenant } = loginRef.current // 这里 Data 需要 JSON.stringify(Data) 是因为后端限制 const payload = { TypeCode: 'M0003', Tenant, Data: JSON.stringify({ UserId, OrgId, ...Data }) } socketIns = socketIns || socket.current diff --git a/src/files/edit/SK018.js b/src/files/edit/SK018.js index f9c3a0d..3b58551 100644 --- a/src/files/edit/SK018.js +++ b/src/files/edit/SK018.js @@ -53,7 +53,7 @@ export default { await dispatch({ type: 'custom/save', payload: { - ['engineeringPlanEditClick' +(record ? record.CHECK_CONTENTS_ID : "") ]: true + ['engineeringPlanEditClick' + (record ? record.CHECK_CONTENTS_ID : "")]: true }, }); }; diff --git a/src/layout/Header.js b/src/layout/Header.js index 830b17e..6f2b771 100644 --- a/src/layout/Header.js +++ b/src/layout/Header.js @@ -2,7 +2,7 @@ import React, { useState, useMemo, useEffect } from 'react'; import { connect } from 'dva'; import { withRouter } from 'dva/router'; import { Dropdown, Icon, Menu, message, Button, Modal } from 'antd'; -import { HeaderSearch as OPTSearch, PictureThumb } from '@woowalker/feui'; +import { HeaderSearch as OPTSearch, PictureThumb } from '../feui'; import ModifyPassword from '../components/MainPage/ModifyPassword'; import FoUserInfoShow from '../components/MainPage/FoUserInfoShow'; import FeedbackQuestion from '../components/MainPage/FeedbackQuestion'; diff --git a/src/layout/Main.js b/src/layout/Main.js index 4468cce..0b9552d 100644 --- a/src/layout/Main.js +++ b/src/layout/Main.js @@ -64,7 +64,7 @@ class Main extends React.Component { {matchBackend ? : } {/* 去掉首页报警框 */} - {/* {matchLogin ? null : } */} + {matchLogin ? null : } ) } diff --git a/src/models/login.js b/src/models/login.js index 8562e74..f9a7152 100644 --- a/src/models/login.js +++ b/src/models/login.js @@ -245,6 +245,144 @@ export default { } }, // 登录、获取信息 + *getLoginInfo({ payload, loginPayload }, { call, put, select }) { + const loginUserVerify = storage("lacal").getItem("loginUserVerify").val || {}; + const { username, password } = loginUserVerify; + const webOrgId = storage("lacal").getItem("webOrgId").val; + const formConfigVersion = storage("lacal").getItem("formConfigVersion").val; + + const newPayload = { + ...payload, + Parameter1: payload.Parameter1 || username, + Parameter2: payload.Parameter2 || password, + Parameter4: payload.Parameter4 || webOrgId, + Parameter5: payload.Parameter5 || formConfigVersion, + Parameter7: true, + }; + + const ret = yield call(appService.getLoginInfo, newPayload); + 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("webUserInfo", ret.User); + 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); + storage("lacal").setItem("baseConfig", ret.BaseConfig); + storage("lacal").setItem("roles", ret.Roles || []); + storage("lacal").setItem("rolePerm", ret.Nav_RolePerm || {}); + 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 safeFlatMenus = flatMenus.map(m => ({ ID: m.ID, NAME: m.NAME, CODE: m.CODE, MENU_LEVEL: m.MENU_LEVEL, idLevels: m.idLevels, nameLevels: m.nameLevels, menuLevels: m.menuLevels, Nav_MenuForm: m.Nav_MenuForm, IS_RESIDENT: m.IS_RESIDENT, ICON: m.ICON, IS_BACKEND: m.IS_BACKEND, MineType: m.MineType })); + const pruneMenus = (arr) => arr.map(it => ({ Node: { ID: it.Node.ID, NAME: it.Node.NAME, CODE: it.Node.CODE, MENU_LEVEL: it.Node.MENU_LEVEL, MineType: it.Node.MineType, Nav_MenuForm: it.Node.Nav_MenuForm, IS_RESIDENT: it.Node.IS_RESIDENT, ICON: it.Node.ICON, IS_BACKEND: it.Node.IS_BACKEND }, Children: (it.Children && it.Children.length) ? pruneMenus(it.Children) : [] })); + const safeMenus = pruneMenus(copyMenus); + storage("lacal").setItem("menus", safeMenus); + storage("lacal").setItem("flatMenus", safeFlatMenus); + + const currentMineType = localStorage.getItem("currentMineType"); + if (currentMineType) { + storage("lacal").setItem("currentMineType", 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, + currentMineType: currentMineType, + 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 }); + + // 刷新页面以应用新的权限 + if (!payload.noReload) { + window.location.reload(); + } + } + return ret; + }, + // 登录、获取信息 *toLogin({ payload, loginPayload }, { call, put, select }) { const ret = yield call(appService.getLoginInfo, payload); if (ret) { diff --git a/src/utils/request.js b/src/utils/request.js index b5c153d..eb86aa0 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -17,7 +17,7 @@ export function request(url, options, onlyData, requestKey, onException) { if (response.status === 401) { window.localStorage.removeItem('accessToken') history.replace({ pathname: '/login' }) - throw new Error('token过期') + //throw new Error('token过期') } requestKey && window.localStorage.removeItem(requestKey) return response.json()