登陆验证使用 Zustand

feature/price_manager
Jimmy Liow 1 year ago
parent 384be3171b
commit abf527a53d

@ -11,12 +11,20 @@ const KEY_USER_ID = 'KEY_USER_ID';
const useAuthStore = create((set, get) => ({ const useAuthStore = create((set, get) => ({
tokenInterval: null,
loginStatus: 0,
loginUser: { loginUser: {
userId: -1, token: '',
username: '', userId: 0, // LMI_SN
avatarUrl: '', username: '0',
mobile: '', travelAgencyId: 0, // VEI_SN
email: '', travelAgencyName: '',
telephone: '',
emailAddress: '',
cityId: 0,
timeout: false,
permissionList: [], permissionList: [],
}, },
@ -36,15 +44,147 @@ const useAuthStore = create((set, get) => ({
}, },
login: async (authCode) => { valdateUserPassword: async (usr, pwd) => {
const formData = new FormData()
formData.append('username', usr)
formData.append('Password', pwd)
async function fetchLoginToken() {
const postUrl = HT_HOST + '/service-CooperateSOA/Login'
const json = await postForm(postUrl, formData)
if (json.errcode == 0 && isNotEmpty(json.Result)) {
return json.Result.token;
} else {
return 0;
}
}
const token = await fetchLoginToken()
console.info('token: ' + token)
const fetchUrl = prepareUrl(HT_HOST + '/service-CooperateSOA/GetLinkManInfo')
.append('token', token)
.build()
return fetchJSON(fetchUrl)
.then(json => {
if (json.errcode == 0) {
set(() => ({
loginUser: {
token: token,
timeout: false,
userId: json.Result.LMI_SN,
username: json.Result.LoginName,
travelAgencyId: json.Result.LMI_VEI_SN,
travelAgencyName: json.Result.VName,
telephone: json.Result.LkPhone,
emailAddress: json.Result.LMI_listmail,
cityId: json.Result.citysn,
},
loginStatus: 302
}))
// loadPageSpy(`${json.Result.VName}-${json.Result.LoginName}`)
// this.startTokenInterval()
} else {
throw new Error(json.errmsg + ': ' + json.errcode)
}
})
}, },
logout: () => { logout: () => {
window.sessionStorage.clearSession()
set(() => ({
loginUser: {
timeout: true
}
}))
},
fetchUserDetail: () => {
const { loginUser } = get()
const fetchUrl = prepareUrl(HT_HOST + '/service-CooperateSOA/GetLinkManInfo')
.append('token', loginUser.token)
.build();
return fetchJSON(fetchUrl)
.then(json => {
if (json.errcode == 0) {
set((state) => ({
loginUser: {
...state.loginUser,
userId: json.Result.LMI_SN,
username: json.Result.LoginName,
travelAgencyId: json.Result.LMI_VEI_SN,
travelAgencyName: json.Result.VName,
telephone: json.Result.LkPhone,
emailAddress: json.Result.LMI_listmail,
cityId: json.Result.citysn,
}
}))
// loadPageSpy(`${json.Result.VName}-${json.Result.LoginName}`)
// this.startTokenInterval()
return loginUser
} else {
throw new Error(json.errmsg + ': ' + json.errcode)
}
});
}, },
startTokenInterval: () => {
const { loginUser } = get()
async function fetchLastRequet() {
const fetchUrl = prepareUrl(HT_HOST + '/service-CooperateSOA/GetLastReqDate')
.append('token', loginUser.token)
.build();
const json = await fetchJSON(fetchUrl)
if (json.errcode == 0 && isNotEmpty(json.result)) {
return json.result.LastReqDate;
} else {
return 0;
}
}
async function checkTokenTimeout() {
const lastRequest = await fetchLastRequet();
const lastReqDate = new Date(lastRequest);
const now = new Date();
const diffTime = now.getTime() - lastReqDate.getTime();
const diffHours = diffTime/1000/60/60;
if (diffHours > 4) {
authStore.logout();
}
}
const interval = setInterval(() => checkTokenTimeout(), 1000*60*20)
set(() => ({
tokenInterval: interval
}))
},
changeUserPassword: (password, newPassword) => {
const { loginUser } = get()
const formData = new FormData();
formData.append('UserID', loginUser.userId);
formData.append('Password', password);
formData.append('NewPassword', newPassword);
formData.append('token', loginUser.token);
const postUrl = HT_HOST + '/service-CooperateSOA/SetPassword';
return postForm(postUrl, formData)
.then(json => {
if (json.errcode == 0) {
return json;
} else {
throw new Error(json.errmsg + ': ' + json.errcode);
}
});
},
})) }))
class Auth { export default useAuthStore
export class Auth {
constructor(root) { constructor(root) {
makeAutoObservable(this, { rootStore: false }); makeAutoObservable(this, { rootStore: false });
@ -161,24 +301,6 @@ class Auth {
}); });
} }
//供应商列表
fetchVendorList(){
const authStore = this;
const fetchUrl = prepareUrl(HT_HOST + '/service-cusservice/PTGetHWVendorList')
.append('token', authStore.login.token)
.build();
return fetchJSON(fetchUrl)
.then(json => {
//console.log(json);
if (json.errcode == 0) {
runInAction(() => {
this.VendorList = json.Result;
});
}
});
}
login = { login = {
token: '', token: '',
userId: 0, // LMI_SN userId: 0, // LMI_SN
@ -192,4 +314,4 @@ class Auth {
} }
} }
export default Auth; // export Auth;

@ -2,8 +2,37 @@ import { makeAutoObservable, runInAction } from "mobx";
import { fetchJSON, postForm } from '@/utils/request'; import { fetchJSON, postForm } from '@/utils/request';
import { HT_HOST } from "@/config"; import { HT_HOST } from "@/config";
import { prepareUrl } from '@/utils/commons'; import { prepareUrl } from '@/utils/commons';
import { create } from 'zustand'
class Reservation { const useReservationStore = create((set, get) => ({
fetchAllGuideList: (travelAgencyId, token) => {
const fetchUrl = prepareUrl(HT_HOST + '/service-cusservice/PTGetGuideList')
.append('VEI_SN', travelAgencyId)
.append("token", token)
.build();
return fetchJSON(fetchUrl)
.then(json => {
if (json.errcode == 0) {
const guideList = (json?.Result??[]).map((data, index) => {
return {
guideId: data.TGI_SN,
guideName: data.TGI2_Name,
mobileNo: data.TGI_Mobile
}
});
return guideList;
} else {
throw new Error(json.errmsg + ': ' + json.errcode);
}
});
},
}))
export default useReservationStore
export class Reservation {
constructor(root) { constructor(root) {
makeAutoObservable(this, { rootStore: false }); makeAutoObservable(this, { rootStore: false });
@ -267,5 +296,3 @@ class Reservation {
confirmationList = [ confirmationList = [
]; ];
} }
export default Reservation;

@ -1,8 +1,8 @@
import { makeAutoObservable } from "mobx"; import { makeAutoObservable } from "mobx";
import Reservation from "./Reservation"; import { Reservation } from "./Reservation";
import Feedback from "./Feedback"; import Feedback from "./Feedback";
import Notice from "./Notice"; import Notice from "./Notice";
import Auth from "./Auth"; import { Auth } from "./Auth";
import Invoice from "./Invoice"; import Invoice from "./Invoice";
import Report from "./Report"; import Report from "./Report";

@ -3,15 +3,18 @@ import { useEffect } from 'react';
import { Button, Checkbox, Form, Input, Row, App } from 'antd'; import { Button, Checkbox, Form, Input, Row, App } from 'antd';
import { useStore } from '@/stores/StoreContext.js'; import { useStore } from '@/stores/StoreContext.js';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import useAuthStore from '@/stores/Auth'
function Login() { function Login() {
const { t, i18n } = useTranslation(); const { t, i18n } = useTranslation();
const { authStore, noticeStore } = useStore(); const { authStore, noticeStore } = useStore();
const [valdateUserPassword, fetchUserDetail, loginStatus] =
useAuthStore((state) => [state.valdateUserPassword, state.fetchUserDetail, state.loginStatus])
const { notification } = App.useApp(); const { notification } = App.useApp();
const navigate = useNavigate(); const navigate = useNavigate()
const location = useLocation(); const location = useLocation()
const [form] = Form.useForm(); const [form] = Form.useForm()
useEffect (() => { useEffect (() => {
if (location.search === '?out') { if (location.search === '?out') {
@ -23,23 +26,19 @@ function Login() {
}; };
}, []); }, []);
useEffect (() => {
if (loginStatus === 302) {
// navigate("/reservation/newest")
}
}, [loginStatus]);
const onFinish = (values) => { const onFinish = (values) => {
authStore.valdateUserPassword(values.username, values.password) valdateUserPassword(values.username, values.password)
.then((userId) => { .then((userId) => {
noticeStore.getBulletinUnReadCount(userId); // noticeStore.getBulletinUnReadCount(userId);
authStore.fetchUserDetail()
.then((user) => { console.info('valdateUserPassword')
// navigate(-1) is equivalent to hitting the back button. //
navigate("/reservation/newest");
})
.catch(ex => {
notification.error({
message: `Notification`,
description: 'Failed to get user information.',
placement: 'top',
duration: 4,
});
});
}) })
.catch(ex => { .catch(ex => {
notification.error({ notification.error({
@ -53,68 +52,71 @@ function Login() {
const onFinishFailed = (errorInfo) => { const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo); console.log('Failed:', errorInfo);
}; }
console.info('loginStatus: ' + loginStatus)
return ( if (loginStatus === 302) {
<Row justify="center" align="middle" style={{ minHeight: 500 }}> } else {
<Form return (
name="basic" <Row justify="center" align="middle" style={{ minHeight: 500 }}>
// layout="vertical" <Form
form={form} name="basic"
size="large" // layout="vertical"
labelCol={{ form={form}
span: 8, size="large"
}} labelCol={{
wrapperCol={{ span: 8,
span: 16, }}
}}
style={{
maxWidth: 600,
}}
initialValues={{
remember: true,
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
<Form.Item
label={t("Username")}
name="username"
rules={[
{
required: true,
message: 'Please input your username!',
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("Password")}
name="password"
rules={[
{
required: true,
message: 'Please input your password!',
},
]}
>
<Input.Password />
</Form.Item>
<Form.Item
wrapperCol={{ wrapperCol={{
offset: 8,
span: 16, span: 16,
}} }}
style={{
maxWidth: 600,
}}
initialValues={{
remember: true,
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
> >
<Button type="primary" htmlType="submit" style={{width: "100%"}}> <Form.Item
{t('Login')} label={t("Username")}
</Button> name="username"
</Form.Item> rules={[
</Form> {
</Row> required: true,
); message: 'Please input your username!',
},
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("Password")}
name="password"
rules={[
{
required: true,
message: 'Please input your password!',
},
]}
>
<Input.Password />
</Form.Item>
<Form.Item
wrapperCol={{
offset: 8,
span: 16,
}}
>
<Button type="primary" htmlType="submit" style={{width: "100%"}}>
{t('Login')}
</Button>
</Form.Item>
</Form>
</Row>
);
}
} }
export default Login; export default Login;

@ -8,6 +8,8 @@ import { useStore } from '@/stores/StoreContext.js';
import { isEmpty } from "@/utils/commons"; import { isEmpty } from "@/utils/commons";
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import usePresets from '@/hooks/usePresets'; import usePresets from '@/hooks/usePresets';
import useAuthStore from '@/stores/Auth'
import useReservationStore from '@/stores/Reservation'
const { Title } = Typography; const { Title } = Typography;
@ -108,6 +110,10 @@ function Newest() {
const [dataLoading, setDataLoading] = useState(false); const [dataLoading, setDataLoading] = useState(false);
const [guideSelectOptions, setGuideSelectOptions] = useState([]); const [guideSelectOptions, setGuideSelectOptions] = useState([]);
const { reservationStore } = useStore(); const { reservationStore } = useStore();
const loginUser = useAuthStore((state) => state.loginUser)
const fetchAllGuideList = useReservationStore((state) => state.fetchAllGuideList)
const { reservationList, reservationPage, referenceNo, arrivalDateRange, cityList } = reservationStore; const { reservationList, reservationPage, referenceNo, arrivalDateRange, cityList } = reservationStore;
const { notification } = App.useApp(); const { notification } = App.useApp();
@ -116,7 +122,7 @@ function Newest() {
// //
onSearchClick(1, 1); onSearchClick(1, 1);
} }
reservationStore.fetchAllGuideList() fetchAllGuideList(loginUser.travelAgencyId, loginUser.token)
.then((guideList) => { .then((guideList) => {
const selectOptions = guideList.map((data, index) => { const selectOptions = guideList.map((data, index) => {
return { return {
@ -124,7 +130,7 @@ function Newest() {
label: data.guideName label: data.guideName
} }
}); });
setGuideSelectOptions(selectOptions); // setGuideSelectOptions(selectOptions);
}); });
return () => { return () => {
// unmount... // unmount...

Loading…
Cancel
Save