完成 useStorage

feature/price_manager
Jimmy Liow 1 year ago
parent 6e66a31bb0
commit 83d08dd099

Binary file not shown.

@ -0,0 +1,50 @@
export function useStorage() {
const setSession = (key, value) => {
if (window.sessionStorage) {
const sessionStorage = window.sessionStorage
return sessionStorage.setItem(key, value)
} else {
console.error('browser not support sessionStorage.')
}
}
const camelCasedWords = (string) => {
if (typeof string !== 'string' || string.length === 0) {
return string;
}
return string.split('_').map((word, index) => {
if (index === 0) {
return ''
} else if (index === 1) {
return word.toLowerCase()
} else {
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
}
}).join('')
}
const storageObject = {}
if (window.sessionStorage) {
const sessionStorage = window.sessionStorage
for (let i = 0; i < sessionStorage.length; i++) {
const key = sessionStorage.key(i)
const value = sessionStorage.getItem(key)
const propName = camelCasedWords(key)
storageObject[propName] = value
}
return {
...storageObject,
setStorage: (key, value) => {
setSession(key, value)
}
}
} else {
console.error('browser not support sessionStorage.')
return {}
}
}

@ -1,13 +1,15 @@
import { makeAutoObservable, runInAction } from "mobx";
import { create } from 'zustand'
import { appendRequestParams, fetchJSON, postForm } from '@/utils/request';
import { HT_HOST } from "@/config";
import { isNotEmpty, prepareUrl } from '@/utils/commons';
import { loadPageSpy } from '@/pageSpy';
import { create } from 'zustand'
import { useStorage } from '@/hooks/useStorage'
const KEY_LOGIN_TOKEN = 'KEY_LOGIN_TOKEN';
const KEY_TRAVEL_AGENCY_ID = 'KEY_TRAVEL_AGENCY_ID';
const KEY_USER_ID = 'KEY_USER_ID';
const KEY_LOGIN_TOKEN = 'KEY_LOGIN_TOKEN'
const KEY_TRAVEL_AGENCY_ID = 'KEY_TRAVEL_AGENCY_ID'
const KEY_USER_ID = 'KEY_USER_ID'
const useAuthStore = create((set, get) => ({
@ -45,11 +47,12 @@ const useAuthStore = create((set, get) => ({
},
validateUserPassword: async (usr, pwd) => {
const { setStorage } = useStorage()
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)
@ -59,8 +62,9 @@ const useAuthStore = create((set, get) => ({
return 0;
}
}
const token = await fetchLoginToken()
appendRequestParams('token', token)
const loginToken = await fetchLoginToken()
setStorage(KEY_LOGIN_TOKEN, loginToken)
appendRequestParams('token', loginToken)
const fetchUrl = prepareUrl(HT_HOST + '/service-CooperateSOA/GetLinkManInfo').build()
@ -69,7 +73,7 @@ const useAuthStore = create((set, get) => ({
if (json.errcode == 0) {
set(() => ({
loginUser: {
token: token,
token: loginToken,
timeout: false,
userId: json.Result.LMI_SN,
username: json.Result.LoginName,
@ -81,6 +85,9 @@ const useAuthStore = create((set, get) => ({
},
loginStatus: 302
}))
setStorage(KEY_USER_ID, json.Result.LMI_SN)
setStorage(KEY_TRAVEL_AGENCY_ID, json.Result.LMI_VEI_SN)
// loadPageSpy(`${json.Result.VName}-${json.Result.LoginName}`)
// this.startTokenInterval()
} else {

@ -1,8 +1,39 @@
import { makeAutoObservable, runInAction } from "mobx";
import { fetchJSON, postForm } from '@/utils/request';
import { HT_HOST } from "@/config";
import { prepareUrl } from '@/utils/commons';
import { makeAutoObservable, runInAction } from "mobx"
import { create } from 'zustand'
import { fetchJSON, postForm } from '@/utils/request'
import { HT_HOST } from "@/config"
import { prepareUrl } from '@/utils/commons'
import { useStorage } from '@/hooks/useStorage'
export const fetchCityList = async (travelAgencyId, reservationId) => {
const { errcode, Result } = await fetchJSON(
`${HT_HOST}/service-cusservice/PTGetCityGuide`,
{ VEI_SN: travelAgencyId, GRI_SN: reservationId, LGC: 1 })
return errcode !== 0 ? {} : Result;
}
export const fetchPlanDetail = async (travelAgencyId, reservationId) => {
const json = await fetchJSON(
`${HT_HOST}/service-cusservice/GetPlanInfo`,
{ VEI_SN: travelAgencyId, GRI_SN: reservationId })
if (json.errcode == 0) {
return {
planDetail: json.PlanDetail[0],
planChangeList: json.PlanChange??[]
}
} else {
return {}
}
}
export const fetchAttachList = async (reservationId) => {
const { errcode, result } = await fetchJSON(
`${HT_HOST}/service-fileServer/PlanChangeFileList`,
{ GRI_SN: reservationId })
return errcode !== 0 ? {} : result;
}
const useReservationStore = create((set, get) => ({
@ -28,7 +59,41 @@ const useReservationStore = create((set, get) => ({
confirmationList: [
],
fetchReservationList: (travelAgencyId, formVal, current=1) => {
getCityListByReservationId: async (reservationId) => {
const { travelAgencyId } = useStorage()
set(() => ({
cityList: []
}))
const cityListJson = await fetchCityList(travelAgencyId, reservationId)
const mapCityList = cityListJson.map((data) => {
return {
key: data.CII_SN,
cityId: data.CII_SN,
cityName: data.CityName,
tourGuideId: data.TGI_SN,
tourGuide: data.GuideName
}
})
set(() => ({
cityList: mapCityList
}))
},
selectReservation: (reservation) => {
set(() => ({
selectedReservation: reservation
}))
},
selectConfirmation: (confirmation) => {
set(() => ({
selectedConfirmation: confirmation
}))
},
fetchReservationList: (formVal, current=1) => {
const { travelAgencyId } = useStorage()
const { reservationPage } = get()
// 设置为 0后端会重新计算总数当跳转第 X 页时可用原来的总数。
const totalNum = current == 1 ? 0 : reservationPage.total;
@ -37,7 +102,7 @@ const useReservationStore = create((set, get) => ({
.append('GroupNo', formVal.referenceNo)
.append('DateStart', formVal.startdate)
.append('DateEnd', formVal.enddate)
.append('NotConfirm', '')//status)
.append('NotConfirm', '')//status)// Todo: 待解决
.append('TotalNum', totalNum)
.append('PageSize', reservationPage.size)
.append('PageIndex', current)
@ -73,7 +138,8 @@ const useReservationStore = create((set, get) => ({
});
},
fetchAllGuideList: (travelAgencyId) => {
fetchAllGuideList: () => {
const { userId, travelAgencyId } = useStorage()
const fetchUrl = prepareUrl(HT_HOST + '/service-cusservice/PTGetGuideList')
.append('VEI_SN', travelAgencyId)
.build();
@ -94,103 +160,13 @@ const useReservationStore = create((set, get) => ({
}
});
},
}))
export default useReservationStore
export class Reservation {
constructor(root) {
makeAutoObservable(this, { rootStore: false });
this.root = root;
}
fetchReservationList(current, status=null) {
const fromDate = this.arrivalDateRange.length == 0 ? null : this.arrivalDateRange[0].format('YYYY-MM-DD');
const thruDate = this.arrivalDateRange.length == 0 ? null : this.arrivalDateRange[1].format('YYYY-MM-DD');
this.reservationPage.current = current;
// 设置为 0后端会重新计算总数当跳转第 X 页时可用原来的总数。
const totalNum = current == 1 ? 0 : this.reservationPage.total;
const fetchUrl = prepareUrl(HT_HOST + '/service-cusservice/GetPlanSearchList')
.append('VEI_SN', this.root.authStore.login.travelAgencyId)
.append('GroupNo', this.referenceNo)
.append('DateStart', fromDate)
.append('DateEnd', thruDate)
.append('NotConfirm', status)
.append('TotalNum', totalNum)
.append('PageSize', this.reservationPage.size)
.append('PageIndex', this.reservationPage.current)
.append("token", this.root.authStore.login.token)
.build();
return fetchJSON(fetchUrl)
.then(json => {
if (json.errcode == 0) {
runInAction(() => {
this.reservationList = (json?.Result??[]).map((data, index) => {
return {
key: data.vas_gri_sn,
reservationId: data.vas_gri_sn,
referenceNumber: data.GriName,
arrivalDate: data.GetGDate,
pax: data.PersonNum,
status: data.GState,
reservationDate: data.SendDate,
guide: data.Guide
}
});
this.reservationPage.total = (json?.Result??[{RsTotal: 0}])[0].RsTotal;
});
} else {
throw new Error(json.errmsg + ': ' + json.errcode);
}
});
}
fetchReservation(reservationId) {
const fetchDetailUrl = prepareUrl(HT_HOST + '/service-cusservice/GetPlanInfo')
.append('VEI_SN', this.root.authStore.login.travelAgencyId)
.append('GRI_SN', reservationId)
.append("token", this.root.authStore.login.token)
.build();
// https://p9axztuwd7x8a7.mycht.cn/service-fileServer/PlanChangeFileList
const fetchAttachmentUrl = prepareUrl(HT_HOST + '/service-fileServer/PlanChangeFileList')
.append('GRI_SN', reservationId)
.append("token", this.root.authStore.login.token)
.build();
const attachmentPromise = fetchJSON(fetchAttachmentUrl)
.then(json => {
if (json.errcode == 0) {
return json;
} else {
throw new Error(json.errmsg + ': ' + json.errcode);
}
});
const detailPromise = fetchJSON(fetchDetailUrl)
.then(json => {
if (json.errcode == 0) {
return json;
} else {
throw new Error(json.errmsg + ': ' + json.errcode);
}
});
getReservationDetail: async (travelAgencyId, reservationId) => {
const { planDetail, planChangeList } = await fetchPlanDetail(travelAgencyId, reservationId)
const attachListJson = await fetchAttachList(reservationId)
return Promise.all([attachmentPromise, detailPromise])
.then(results => {
const attachList = results[0].result;
const planDetail = results[1].PlanDetail[0];
const planChange = results[1]?.PlanChange??[];
runInAction(() => {
this.reservationDetail = {
referenceNumber: planDetail.GRI_Name,
tourGuide: planDetail.Guide,
arrivalDate: planDetail.eoi_getdate,
reservationId: reservationId
};
this.confirmationList = planChange.map((data, index) => {
const filterAttchList = attachList.filter(attch => {
const mapConfirmationList = planChangeList.map((data) => {
const filterAttchList = attachListJson.filter(attch => {
return attch.PCI_SN === data.PCI_SN;
});
return {
@ -203,40 +179,47 @@ export class Reservation {
VAS_SN: data.PCI_VAS_SN,
attachmentList: filterAttchList
}
});
});
});
}
})
fetchCityList(reservationId) {
const fetchUrl = prepareUrl(HT_HOST + '/service-cusservice/PTGetCityGuide')
.append('VEI_SN', this.root.authStore.login.travelAgencyId)
.append('GRI_SN', reservationId)
.append('LGC', 1)
.append("token", this.root.authStore.login.token)
.build();
set(() => ({
reservationDetail: {
referenceNumber: planDetail.GRI_Name,
tourGuide: planDetail.Guide,
arrivalDate: planDetail.eoi_getdate,
reservationId: reservationId
},
confirmationList: mapConfirmationList
}))
},
runInAction(() => {
this.cityList = [];
});
return fetchJSON(fetchUrl)
submitConfirmation: (userId, travelAgencyId, confirmText) => {
const { selectedConfirmation, getReservationDetail, reservationDetail } = get()
const formData = new FormData()
formData.append('PCI_SN', selectedConfirmation.key)
formData.append('OPSN', userId)
formData.append('ConfirmText', confirmText)
formData.append('VAS_SN', selectedConfirmation.VAS_SN)
const postUrl = HT_HOST + '/service-cusservice/PTConfirmPlanChange'
return postForm(postUrl, formData)
.then(json => {
runInAction(() => {
if (json.errcode == 0) {
this.cityList = (json?.Result??[]).map((data, index) => {
return {
key: data.CII_SN,
cityId: data.CII_SN,
cityName: data.CityName,
tourGuideId: data.TGI_SN,
tourGuide: data.GuideName
if (json.errcode == 0 && json.Result.length == 1) {
// this.fetchReservation(this.reservationDetail.reservationId);
getReservationDetail(travelAgencyId, reservationDetail.reservationId)
return json
}
});
} else {
throw new Error(json.errmsg + ': ' + json.errcode);
}
});
});
}))
export default useReservationStore
export class Reservation {
constructor(root) {
makeAutoObservable(this, { rootStore: false });
this.root = root;
}
updateReservationGuide() {
@ -284,33 +267,6 @@ export class Reservation {
});
}
submitConfirmation(confirmText) {
let formData = new FormData();
formData.append('PCI_SN', this.selectedConfirmation.key);
formData.append('OPSN', this.root.authStore.login.userId);
formData.append('ConfirmText', confirmText);
formData.append('VAS_SN', this.selectedConfirmation.VAS_SN);
formData.append("token", this.root.authStore.login.token);
const postUrl = HT_HOST + '/service-cusservice/PTConfirmPlanChange';
return postForm(postUrl, formData)
.then(json => {
if (json.errcode == 0 && json.Result.length == 1) {
this.fetchReservation(this.reservationDetail.reservationId);
return json;
}
});
}
editReservation(reservation) {
this.selectedReservation = reservation;
}
editConfirmation(confirmation) {
this.selectedConfirmation = confirmation;
}
updatePropertyValue(name, value) {
runInAction(() => {
this[name] = value;

@ -45,7 +45,7 @@ function checkStatus(response) {
}
}
function checkBizCode(responseJson){
function checkBizCode(responseJson) {
if (responseJson.errcode === 0) {
return responseJson;
} else {

@ -6,8 +6,9 @@ import { Row, Col, Space, Button, Table, Input, Typography, Modal, Tag, App } fr
import {
FileOutlined
} from '@ant-design/icons';
import { useStore } from '@/stores/StoreContext.js';
import useAuthStore from '@/stores/Auth'
import { useTranslation } from 'react-i18next';
import useReservationStore from '@/stores/Reservation'
const { Title, Paragraph } = Typography;
const { TextArea } = Input;
@ -77,16 +78,19 @@ function Detail() {
const [dataLoading, setDataLoading] = useState(false);
const { notification } = App.useApp();
const { reservationId } = useParams();
const { authStore, reservationStore } = useStore();
const { reservationDetail, confirmationList } = reservationStore;
const { login } = authStore;
const loginUser = useAuthStore((state) => state.loginUser)
const [getReservationDetail, reservationDetail, confirmationList, selectConfirmation, submitConfirmation] =
useReservationStore((state) =>
[state.getReservationDetail, state.reservationDetail, state.confirmationList, state.selectConfirmation, state.submitConfirmation])
const officeWebViewerUrl =
'https://view.officeapps.live.com/op/embed.aspx?wdPrint=1&wdHideGridlines=0&wdHideComments=1&wdEmbedCode=0&src=';
// https://www.chinahighlights.com/public/reservationW220420009.doc
const reservationUrl =
`https://p9axztuwd7x8a7.mycht.cn/service-fileServer/DownloadPlanDoc?GRI_SN=${reservationId}&VEI_SN=${login.travelAgencyId}&token=${login.token}&FileType=1`;
`https://p9axztuwd7x8a7.mycht.cn/service-fileServer/DownloadPlanDoc?GRI_SN=${reservationId}&VEI_SN=${loginUser.travelAgencyId}&token=${loginUser.token}&FileType=1`;
const nameCardUrl =
`https://p9axztuwd7x8a7.mycht.cn/service-fileServer/DownloadPlanDoc?GRI_SN=${reservationId}&VEI_SN=${login.travelAgencyId}&token=${login.token}&FileType=2`;
`https://p9axztuwd7x8a7.mycht.cn/service-fileServer/DownloadPlanDoc?GRI_SN=${reservationId}&VEI_SN=${loginUser.travelAgencyId}&token=${loginUser.token}&FileType=2`;
const reservationPreviewUrl = officeWebViewerUrl + encodeURIComponent(reservationUrl);
const nameCardPreviewUrl = officeWebViewerUrl + encodeURIComponent(nameCardUrl);
@ -95,12 +99,12 @@ function Detail() {
setIsModalOpen(true);
const formattedText = confirm.PCI_ConfirmText;//.replace(/\;/g, "\n\n");
setConfirmText(formattedText);
reservationStore.editConfirmation(confirm);
selectConfirmation(confirm);
};
const handleOk = () => {
setConfirmLoading(true);
reservationStore.submitConfirmation(confirmText + '\n——————————————————————\n' +newConfirmText)
submitConfirmation(loginUser.userId, loginUser.travelAgencyId, confirmText + '\n——————————————————————\n' +newConfirmText)
.finally(() => {
setNewConfirmText('');
setIsModalOpen(false);
@ -113,7 +117,7 @@ function Detail() {
useEffect(() => {
setDataLoading(true);
reservationStore.fetchReservation(reservationId)
getReservationDetail(loginUser.travelAgencyId, reservationId)
.catch(ex => {
notification.error({
message: `Notification`,
@ -187,4 +191,4 @@ function Detail() {
);
}
export default observer(Detail);
export default Detail;

@ -4,7 +4,6 @@ import { Row, Col, Space, Button, Table, Typography, Modal, App, Select } from '
import dayjs from 'dayjs'
import { isEmpty } from '@/utils/commons'
import { useTranslation } from 'react-i18next'
import useAuthStore from '@/stores/Auth'
import useFormStore from '@/stores/Form'
import useReservationStore from '@/stores/Reservation'
import SearchForm from '@/components/SearchForm'
@ -97,7 +96,7 @@ function Newest() {
filterOption={(input, option) =>
(option?.label ?? '').toLowerCase().includes(input.toLowerCase())
}
options={toJS(guideSelectOptions)}
options={guideSelectOptions}
/>
)
}
@ -107,20 +106,20 @@ function Newest() {
const [dataLoading, setDataLoading] = useState(false)
const [guideSelectOptions, setGuideSelectOptions] = useState([])
const formValues = useFormStore((state) => state.formValues);
const loginUser = useAuthStore((state) => state.loginUser)
const [fetchAllGuideList, fetchReservationList, reservationList, reservationPage, cityList] =
const formValues = useFormStore((state) => state.formValues)
const [fetchAllGuideList, fetchReservationList, reservationList, reservationPage, cityList, selectReservation, getCityListByReservationId] =
useReservationStore((state) =>
[state.fetchAllGuideList, state.fetchReservationList, state.reservationList, state.reservationPage, state.cityList])
[state.fetchAllGuideList, state.fetchReservationList, state.reservationList, state.reservationPage, state.cityList, state.selectReservation, state.getCityListByReservationId])
const { notification } = App.useApp();
const { notification } = App.useApp()
useEffect (() => {
if (location.search !== '?back') {
//
onSearchClick(1, 1)
}
fetchAllGuideList(loginUser.travelAgencyId)
fetchAllGuideList()
.then((guideList) => {
const selectOptions = guideList.map((data, index) => {
return {
@ -130,19 +129,16 @@ function Newest() {
})
setGuideSelectOptions(selectOptions)
})
return () => {
// unmount...
};
}, [])
const showCityGuideModal = (reservation) => {
setDataLoading(true)
setIsModalOpen(true)
reservationStore.editReservation(reservation);
reservationStore.fetchCityList(reservation.reservationId)
selectReservation(reservation);
getCityListByReservationId(reservation.reservationId)
.catch(ex => {
notification.error({
message: `Notification`,
message: 'Notification',
description: ex.message,
placement: 'top',
duration: 4,
@ -151,14 +147,14 @@ function Newest() {
.finally(() => {
setDataLoading(false);
})
};
}
const handleOk = () => {
reservationStore.updateReservationGuide()
.finally(() => {
setIsModalOpen(false);
setDataLoading(false);
})
};
}
const handleCancel = () => {
setIsModalOpen(false);
setDataLoading(false);
@ -167,7 +163,7 @@ function Newest() {
//
const onSearchClick = (current=1, status=null) => {
setDataLoading(true)
fetchReservationList(loginUser.travelAgencyId, formValues, current)
fetchReservationList(formValues, current)
.catch(ex => {
notification.error({
message: `Notification`,
@ -228,14 +224,14 @@ function Newest() {
}}
onSubmit={(err, formVal, filedsVal) => {
setDataLoading(true)
fetchReservationList(loginUser.travelAgencyId, formVal)
fetchReservationList(travelAgencyId, formVal)
.catch(ex => {
notification.error({
message: 'Notification',
description: ex.message,
placement: 'top',
duration: 4,
});
})
})
.finally(() => {
setDataLoading(false)
@ -256,7 +252,7 @@ function Newest() {
total: reservationPage.total,
simple: true
}}
onChange={(pagination, filters, sorter, extra) => {onSearchClick(pagination.current)}}
onChange={(pagination) => {onSearchClick(pagination.current)}}
columns={reservationListColumns} dataSource={reservationList}
/>
</Col>

Loading…
Cancel
Save