diff --git a/src/main.jsx b/src/main.jsx index 9114460..b1eca60 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,5 +1,4 @@ import React from "react"; -import { configure } from "mobx"; import ReactDOM from "react-dom/client"; import { createBrowserRouter, @@ -32,19 +31,32 @@ import InvoicePaidDetail from "@/views/invoice/PaidDetail"; import Airticket from "@/views/airticket/Index"; import AirticketPlan from "@/views/airticket/Plan"; import { ThemeContext } from '@/stores/ThemeContext' +import { usingStorage } from '@/hooks/usingStorage' +import { isNotEmpty } from '@/utils/commons' +import { appendRequestParams } from '@/utils/request' +import useAuthStore from '@/stores/Auth' import { PERM_ACCOUNT_MANAGEMENT, PERM_ROLE_NEW, PERM_OVERSEA, PERM_AIR_TICKET } from '@/config' import './i18n'; -configure({ - useProxies: "ifavailable", - enforceActions: "observed", - computedRequiresReaction: true, - observableRequiresReaction: false, - reactionRequiresObservable: true, - disableErrorBoundaries: process.env.NODE_ENV == "production" -}); +onInit(() => { + + const { loginToken, userId } = usingStorage() + + if (isNotEmpty(loginToken)) { + appendRequestParams('token', loginToken) + + console.info('loginToken') + } + + if (isNotEmpty(userId)) { + useAuthStore.getState().loadUserPermission(userId) + console.info('loadUserPermission') + } +}) + +onInit() const router = createBrowserRouter([ { @@ -80,7 +92,7 @@ const router = createBrowserRouter([ { path: "/logout", element: }, ] } -]); +]) ReactDOM.createRoot(document.getElementById("root")).render( @@ -92,4 +104,4 @@ ReactDOM.createRoot(document.getElementById("root")).render( /> // -); +) diff --git a/src/stores/Auth.js b/src/stores/Auth.js index d2371d7..e7fc4bb 100644 --- a/src/stores/Auth.js +++ b/src/stores/Auth.js @@ -9,6 +9,8 @@ const KEY_TRAVEL_AGENCY_ID = 'G-INT:TRAVEL_AGENCY_ID' const KEY_USER_ID = 'G-INT:USER_ID' const KEY_USER_DETAIL = 'G-JSON:USER_DETAIL' +const WILDCARD_TOKEN = '*' + export const fetchLoginToken = async (username, password) => { const formData = new FormData() @@ -28,6 +30,13 @@ export const fetchUserDetail = async (loginToken) => { return errcode !== 0 ? {} : Result } +export const fetchPermissionListByUserId = async (userId) => { + + const { errcode, result } = await fetchJSON( + `${HT_HOST}/service-CooperateSOA/get_account_permission_list`, { wu_id: userId}) + return errcode !== 0 ? {} : result +} + async function fetchLastRequet() { const { errcode, result } = await fetchJSON(`${HT_HOST}/service-CooperateSOA/GetLastReqDate`) return errcode !== 0 ? {} : result @@ -41,68 +50,60 @@ const useAuthStore = create((set, get) => ({ loginStatus: 0, - loginUser: { - token: '', - telephone: '', - emailAddress: '', - cityId: 0, - permissionList: [], - }, + permissionList: [], isPermitted: (perm) => { + const { permissionList } = get() // 测试权限使用: // if (perm === '/account/management') return false // if (perm === '/account/role/new') return false - return true + // return true // 以上是 Hardcode 判断 // 以下是权限列表从数据库读取后使用的方法 - // return this.permissionList.some((value, key, arry) => { - // if (value.indexOf(WILDCARD_TOKEN) > -1) { - // return true - // } - // if (value === perm) { - // return true - // } - // return false - // }) - + return permissionList.some((value, key, arry) => { + if (value.indexOf(WILDCARD_TOKEN) > -1) { + return true + } + if (value === perm) { + return true + } + return false + }) }, validateUserPassword: async (usr, pwd) => { - const { startTokenInterval } = get() + const { startTokenInterval, loadUserPermission } = get() const { setStorage } = usingStorage() - const { token: loginToken } = await fetchLoginToken(usr, pwd) - - const userDetail = await fetchUserDetail(loginToken) + const { token: loginToken, WU_ID: userId } = await fetchLoginToken(usr, pwd) + await loadUserPermission(userId) set(() => ({ - loginUser: { - telephone: userDetail.LkPhone, - emailAddress: userDetail.LMI_listmail, - cityId: userDetail.citysn, - }, tokenTimeout: false, loginStatus: 302 })) setStorage(KEY_LOGIN_TOKEN, loginToken) - setStorage(KEY_USER_ID, userDetail.LMI_SN) + setStorage(KEY_USER_ID, userId) setStorage(KEY_TRAVEL_AGENCY_ID, userDetail.LMI_VEI_SN) - setStorage(KEY_USER_DETAIL, {username: userDetail.LoginName, travelAgencyName: userDetail.VName}) appendRequestParams('token', loginToken) // loadPageSpy(`${json.Result.VName}-${json.Result.LoginName}`) startTokenInterval() }, + loadUserPermission: async(userId) => { + const permissionResult = await fetchPermissionListByUserId(userId) + set(() => ({ + permissionList: permissionResult.map(p => p.res_pattern) + })) + }, + logout: () => { const { tokenInterval } = get() const { clearStorage } = usingStorage() clearStorage() clearInterval(tokenInterval) set(() => ({ - loginUser: { - }, loginStatus: 0, tokenInterval: null, tokenTimeout: true diff --git a/src/views/App.jsx b/src/views/App.jsx index 607dfe3..1882319 100644 --- a/src/views/App.jsx +++ b/src/views/App.jsx @@ -5,7 +5,6 @@ import { DownOutlined } from '@ant-design/icons'; import 'antd/dist/reset.css'; import AppLogo from '@/assets/logo-gh.png'; import { isEmpty } from '@/utils/commons'; -import { appendRequestParams } from '@/utils/request' import Language from '../i18n/LanguageSwitcher'; import { useTranslation } from 'react-i18next'; import zhLocale from 'antd/locale/zh_CN'; @@ -15,6 +14,7 @@ import ErrorBoundary from '@/components/ErrorBoundary' import { BUILD_VERSION, } from '@/config'; import useNoticeStore from '@/stores/Notice'; import useAuthStore from '@/stores/Auth' +import { fetchUserDetail} from '@/stores/Auth' import { usingStorage } from '@/hooks/usingStorage' import { PERM_ACCOUNT_MANAGEMENT, PERM_ROLE_NEW, PERM_OVERSEA, PERM_AIR_TICKET } from '@/config' @@ -23,14 +23,16 @@ const { Header, Content, Footer } = Layout; const { Title } = Typography; function App() { + const { t, i18n } = useTranslation(); const [password, setPassword] = useState('') + const [userDetail, setUserDetail] = useState({}) const [validateUserPassword, tokenTimeout, isPermitted] = useAuthStore( (state) => [state.validateUserPassword, state.tokenTimeout, state.isPermitted]) - const { loginToken, userDetail } = usingStorage() + const { loginToken } = usingStorage() const noticeUnRead = useNoticeStore((state) => state.noticeUnRead) const href = useHref() @@ -40,9 +42,16 @@ function App() { // 除了路由 /p...以外都需要登陆系统 const needToLogin = href !== '/login' && isEmpty(loginToken) - if (!needToLogin) { - appendRequestParams('token', loginToken) - } + useEffect(() => { + console.info('app.useEffect.loginToken: ' + loginToken) + fetchUserDetail(loginToken) + .then(u => { + setUserDetail({ + username: u.LoginName, + travelAgencyName: u.VName, + }) + }) + }, [loginToken]) useEffect(() => { if (needToLogin) { @@ -52,7 +61,7 @@ function App() { useEffect(() => { window.gtag('event', 'page_view', { page_location: window.location.href }); - }, [location]); + }, [location]) const onSubmit = () => { validateUserPassword(userDetail?.username, password) diff --git a/src/views/account/Management.jsx b/src/views/account/Management.jsx index d3d181c..517f03f 100644 --- a/src/views/account/Management.jsx +++ b/src/views/account/Management.jsx @@ -139,8 +139,8 @@ function Management() { // form.resetFields() } - // [{ value: 33032, label: 'test海外地接B' }] const handleTravelAgencySearch = (newValue) => { + setDataLoading(true) fetchTravelAgencyByName(newValue) .then(result => { setTravelAgencyList(result.map(r => { @@ -150,6 +150,9 @@ function Management() { } })) }) + .finally(() => { + setDataLoading(false) + }) } const handleTravelAgencyChange = (newValue) => { @@ -275,6 +278,7 @@ function Management() { options={travelAgencyList} value={currentTravelAgency} onChange={handleTravelAgencyChange} + loading={dataLoading} showSearch filterOption={false} onSearch={handleTravelAgencySearch} diff --git a/src/views/account/RoleList.jsx b/src/views/account/RoleList.jsx index 3e57a52..13a1501 100644 --- a/src/views/account/RoleList.jsx +++ b/src/views/account/RoleList.jsx @@ -85,7 +85,7 @@ function RoleList() { disableCheckbox: p.res_id == 1, title: p.res_name, value: p.res_id, - key: p.res_name, + key: p.res_id, } }) }