Merge branch 'main' of github.com:hainatravel/GHHub

# Conflicts:
#	src/stores/Root.js
#	src/views/Login.jsx
feature/price_manager
Jimmy Liow 1 year ago
commit 4fff1229fd

@ -1,5 +1,5 @@
import { makeAutoObservable, runInAction } from "mobx";
import { fetchJSON, postForm } from '@/utils/request';
import { appendRequestParams, fetchJSON, postForm } from '@/utils/request';
import { HT_HOST } from "@/config";
import { isNotEmpty, prepareUrl } from '@/utils/commons';
import { loadPageSpy } from '@/pageSpy';
@ -193,6 +193,7 @@ export class Auth {
this.login.userId = root.getSession(KEY_USER_ID);
this.login.travelAgencyId = root.getSession(KEY_TRAVEL_AGENCY_ID);
if (isNotEmpty(this.login.token)) {
appendRequestParams('token', this.login.token);
this.fetchUserDetail();
}
}
@ -211,6 +212,7 @@ export class Auth {
this.login.timeout = false;
});
this.root.putSession(KEY_LOGIN_TOKEN, json.Result.token);
appendRequestParams('token', json.Result.token);
return json.Result.WU_LMI_SN;
} else {
throw new Error(json.errmsg + ': ' + json.errcode);

@ -1,73 +1,53 @@
import { makeAutoObservable, runInAction } from "mobx";
import * as config from "@/config";
class Notice {
constructor(root) {
makeAutoObservable(this, { rootStore: false });
this.root = root;
}
import { create } from 'zustand';
import { devtools } from 'zustand/middleware';
noticeList = []; //公告列表
noticeUnRead = 0; //未读公告数量
noticeInfo = { CCP_BLID: 0, CCP_BLTitle: "", CCP_BLContent: "", CCP_LastEditTime: "" }; //公告详情
import { fetchJSON, } from '@/utils/request';
const { HT_HOST } = config;
/*
LMI_SN 登录用户SN用户sn用来判断是否已读公告
*/
getBulletinList(LMI_SN) {
let url = `/service-Cooperate/Cooperate/GetBulletinList`;
url += `?LMI_SN=${LMI_SN}`;
url+=`&token=${this.root.authStore.login.token}`;
fetch(config.HT_HOST + url)
.then(response => response.json())
.then(json => {
runInAction(() => {
this.noticeList = json.Result;
});
})
.catch(error => {
console.log("fetch data failed", error);
});
}
/**
* Notice 相关的请求
*/
/*
LMI_SN 登录用户sn 用户sn用来设置已读公告请求过一次详情页表示已读
CCP_BLID 公告sn
*/
getNoticeDetail(LMI_SN, CCP_BLID) {
let url = `/service-Cooperate/Cooperate/GetBulletinDetail`;
url += `?LMI_SN=${LMI_SN}&CCP_BLID=${CCP_BLID}`;
url+=`&token=${this.root.authStore.login.token}`;
fetch(config.HT_HOST + url)
.then(response => response.json())
.then(json => {
console.log(json);
runInAction(() => {
this.noticeInfo = json.Result;
});
})
.catch(error => {
console.log("fetch data failed", error);
});
}
export const fetchBulletinList = async (LMI_SN) => {
const { errcode, Result } = await fetchJSON(`${HT_HOST}/service-Cooperate/Cooperate/GetBulletinList`, { LMI_SN });
return errcode !== 0 ? [] : Result;
};
//检查是否有未读公告
getBulletinUnReadCount(LMI_SN) {
let url = `/service-Cooperate/Cooperate/GetBulletinUnReadCount`;
url += `?LMI_SN=${LMI_SN}`;
url+=`&token=${this.root.authStore.login.token}`;
fetch(config.HT_HOST + url)
.then(response => response.json())
.then(json => {
console.log(json);
runInAction(() => {
this.noticeUnRead = json.Result.CCP_BulletinCount;
});
})
.catch(error => {
console.log("fetch data failed", error);
});
}
export const fetchBulletinUnReadCount = async (LMI_SN) => {
const { errcode, Result } = await fetchJSON(`${HT_HOST}/service-Cooperate/Cooperate/GetBulletinUnReadCount`, { LMI_SN });
return errcode !== 0 ? 0 : Result.CCP_BulletinCount;
}
export default Notice;
export const fetchNoticeDetail = async (LMI_SN, CCP_BLID) => {
const { errcode, Result } = await fetchJSON(`${HT_HOST}/service-Cooperate/Cooperate/GetBulletinDetail`, { LMI_SN, CCP_BLID });
return errcode !== 0 ? {} : Result;
}
/**
* Notice Store
*/
const initialState = {
noticeUnRead: 0, //未读公告数量
};
export const useNoticeStore = create(
devtools((set, get) => ({
// 初始化状态
...initialState,
// state actions
setNoticeUnRead: (noticeUnRead) => set(() => ({ noticeUnRead })),
reset: () => set(initialState),
// side effects
getBulletinUnReadCount: async (LMI_SN) => {
const { setNoticeUnRead } = get();
const noticeUnRead = await fetchBulletinUnReadCount(LMI_SN);
setNoticeUnRead(noticeUnRead);
},
}))
);
export default useNoticeStore;

@ -1,7 +1,6 @@
import { makeAutoObservable } from "mobx";
import { Reservation } from "./Reservation";
import Feedback from "./Feedback";
import Notice from "./Notice";
import { Auth } from "./Auth";
import Invoice from "./Invoice";
import Report from "./Report";
@ -10,7 +9,6 @@ class Root {
constructor() {
this.reservationStore = new Reservation(this);
this.feedbackStore = new Feedback(this);
this.noticeStore = new Notice(this);
this.authStore = new Auth(this);
this.invoiceStore = new Invoice(this);
this.reportStore = new Report(this);
@ -46,4 +44,4 @@ class Root {
}
}
export default Root;
export default Root;

@ -18,6 +18,20 @@ function getRequestHeader() {
}, {});
}
const initParams = [];
export function appendRequestParams(n, v) {
initParams.push({
name: n,
value: v
})
}
function getRequestInitParams() {
return initParams.reduce((acc, item) => {
acc[item.name] = item.value;
return acc;
}, {});
}
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response
@ -31,6 +45,14 @@ function checkStatus(response) {
}
}
function checkBizCode(responseJson){
if (responseJson.errcode === 0) {
return responseJson;
} else {
throw new Error(responseJson.errmsg + ': ' + responseJson.errcode);
}
}
export function fetchText(url) {
const headerObj = getRequestHeader()
return fetch(url, {
@ -46,7 +68,9 @@ export function fetchText(url) {
})
}
export function fetchJSON(url, data) {
export function fetchJSON(url, data = {}) {
const initParams = getRequestInitParams();
Object.assign(data, initParams);
const params = data ? new URLSearchParams(data).toString() : '';
const ifp = url.includes('?') ? '&' : '?';
const headerObj = getRequestHeader();
@ -59,6 +83,7 @@ export function fetchJSON(url, data) {
}
}).then(checkStatus)
.then(response => response.json())
.then(checkBizCode)
.catch(error => {
throw error;
});
@ -92,6 +117,7 @@ export function postJSON(url, obj) {
}
}).then(checkStatus)
.then(response => response.json())
.then(checkBizCode)
.catch(error => {
throw error
})

@ -15,6 +15,7 @@ import zhLocale from 'antd/locale/zh_CN';
import enLocale from 'antd/locale/en_US';
import 'dayjs/locale/zh-cn';
import { BUILD_VERSION, } from '@/config';
import useNoticeStore from '@/stores/Notice';
const { Header, Content, Footer } = Layout;
const { Title } = Typography;
@ -23,10 +24,10 @@ function App() {
const { t, i18n } = useTranslation();
const [password, setPassword] = useState('');
const { authStore, noticeStore } = useStore();
const { authStore } = useStore();
const { notification } = AntApp.useApp();
const login = toJS(authStore.login);
const { noticeUnRead } = noticeStore;
const noticeUnRead = useNoticeStore((state) => state.noticeUnRead);
const href = useHref();
const loginToken = login.token;
const navigate = useNavigate();

@ -4,11 +4,12 @@ import { Button, Checkbox, Form, Input, Row, App } from 'antd';
import { useStore } from '@/stores/StoreContext.js';
import { useTranslation } from 'react-i18next';
import useAuthStore from '@/stores/Auth'
import useNoticeStore from '@/stores/Notice';
function Login() {
const { t, i18n } = useTranslation();
const { authStore, noticeStore } = useStore();
const { authStore } = useStore();
const [valdateUserPassword, fetchUserDetail, loginStatus] =
useAuthStore((state) => [state.valdateUserPassword, state.fetchUserDetail, state.loginStatus])
const { notification } = App.useApp();
@ -16,6 +17,8 @@ function Login() {
const location = useLocation()
const [form] = Form.useForm()
const getBulletinUnReadCount = useNoticeStore((state) => state.getBulletinUnReadCount);
useEffect (() => {
if (location.search === '?out') {
authStore.logout();

@ -1,42 +1,43 @@
import { NavLink, useParams } from "react-router-dom";
import { useEffect, useState } from "react";
import { observer } from "mobx-react";
import { toJS } from "mobx";
import { Row, Col, Space, Button, Table, Input, Typography, Badge, Divider } from "antd";
import { useStore } from "@/stores/StoreContext.js";
import * as config from "@/config";
import * as comm from "@/utils/commons";
import dayjs from "dayjs";
import { NavLink, useParams } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { Row, Col, Space, Typography, Divider } from 'antd';
import { useStore } from '@/stores/StoreContext.js';
import * as comm from '@/utils/commons';
import { useTranslation } from 'react-i18next';
import { fetchNoticeDetail } from '@/stores/Notice';
const { Title, Paragraph, Text } = Typography;
const { Title, Paragraph } = Typography;
function Detail() {
const { noticeStore, authStore } = useStore();
const { noticeInfo } = noticeStore;
const { CCP_BLID } = useParams();
const { t } = useTranslation();
const { authStore } = useStore();
const { CCP_BLID } = useParams();
useEffect(() => {
console.info("notice detail .useEffect " + CCP_BLID);
noticeStore.getNoticeDetail(authStore.login.userId, CCP_BLID);
}, []);
const [noticeInfo, setNoticeInfo] = useState({});
useEffect(() => {
// console.info("notice detail .useEffect " + CCP_BLID);
fetchNoticeDetail(authStore.login.userId, CCP_BLID).then((res) => {
setNoticeInfo(res);
});
}, []);
return (
<Space direction="vertical" style={{ width: "100%" }}>
<Row gutter={16}>
<Col span={4}></Col>
<Col span={16}>
<Title level={1}>{noticeInfo.CCP_BLTitle}</Title>
<Divider orientation="right">{noticeInfo.CCP_LastEditTime}</Divider>
<Paragraph>
<div dangerouslySetInnerHTML={{ __html: comm.escape2Html(noticeInfo.CCP_BLContent) }}></div>
</Paragraph>
</Col>
<Col span={4}>
<NavLink to="/notice">Back</NavLink>
</Col>
</Row>
</Space>
);
return (
<Space direction='vertical' style={{ width: '100%' }}>
<Row gutter={16}>
<Col span={4}></Col>
<Col span={16}>
<Title level={1}>{noticeInfo.CCP_BLTitle}</Title>
<Divider orientation='right'>{noticeInfo.CCP_LastEditTime}</Divider>
<Paragraph>
<div dangerouslySetInnerHTML={{ __html: comm.escape2Html(noticeInfo.CCP_BLContent) }}></div>
</Paragraph>
</Col>
<Col span={4}>
<NavLink to='/notice'>{t('Back')}</NavLink>
</Col>
</Row>
</Space>
);
}
export default observer(Detail);
export default Detail;

@ -1,23 +1,20 @@
import { NavLink } from "react-router-dom";
import { useEffect, useState } from "react";
import { observer } from "mobx-react";
import { toJS } from "mobx";
import { Row, Col, Space, Button, Table, Input, Typography, Badge, List } from "antd";
import { Row, Col, Space, Typography, Badge, List } from "antd";
import { useStore } from "@/stores/StoreContext.js";
import * as config from "@/config";
import * as comm from "@/utils/commons";
import dayjs from "dayjs";
const { Title, Paragraph, Text } = Typography;
import useNoticeStore, { fetchBulletinList } from '@/stores/Notice';
function Index() {
const { noticeStore, authStore } = useStore();
const { noticeList } = noticeStore;
const { authStore } = useStore();
const getBulletinUnReadCount = useNoticeStore((state) => state.getBulletinUnReadCount);
const [noticeList, setNoticeList] = useState([]);
useEffect(() => {
console.info("notice.useEffect");
noticeStore.getBulletinList(authStore.login.userId);
noticeStore.getBulletinUnReadCount(authStore.login.userId); //
// console.info("notice.useEffect", authStore.login.userId);
fetchBulletinList(authStore.login.userId).then(data => {
setNoticeList(data);
});
getBulletinUnReadCount(authStore.login.userId); //
}, []);
return (
@ -26,7 +23,7 @@ function Index() {
<Col span={4}></Col>
<Col span={16}>
<List
dataSource={toJS(noticeList)}
dataSource={(noticeList)}
renderItem={item => (
<List.Item>
<Typography.Text>[{item.CCP_LastEditTime}]</Typography.Text>
@ -40,4 +37,4 @@ function Index() {
);
}
export default observer(Index);
export default (Index);

@ -182,7 +182,7 @@ function Index() {
<Divider orientation="center">
<Typography.Title level={3} type="success">Primary Data</Typography.Title>
</Divider>
<div className="ant-table-wrapper ant-spin-nested-loading css-3op25v css-dev-only-do-not-override-3op25v ">
<div className="ant-table-wrapper ant-spin-nested-loading css-1x2egda css-dev-only-do-not-override-1x2egda ">
<div className="ant-spin-container ant-table ant-table-bordered">
<div className="ant-table-container">
<div className="ant-table-content">
@ -191,7 +191,7 @@ function Index() {
<tr>
<th scope="col">Groups</th>
<th scope="col">Number of People</th>
<th scope="col">Transaction AmountUSD)</th>
<th scope="col">Transaction Amount (USD)</th>
<th scope="col">Evaluation Score</th>
<th scope="col">TP Reviews</th>
<th scope="col">TP Reviews Rate</th>
@ -229,7 +229,7 @@ function Index() {
<Divider orientation="center">
<Typography.Title level={3} type="success">DMC Assessment Criteria</Typography.Title>
</Divider>
<div className="ant-table-wrapper ant-spin-nested-loading css-3op25v css-dev-only-do-not-override-3op25v ">
<div className="ant-table-wrapper ant-spin-nested-loading css-1x2egda css-dev-only-do-not-override-1x2egda">
<div className="ant-spin-container ant-table ant-table-bordered">
<div className="ant-table-container">
<div className="ant-table-content">
@ -426,7 +426,7 @@ function Index() {
<Divider orientation="center">
<Typography.Title level={3} type="success">Evaluation Scores</Typography.Title>
</Divider>
<div className="ant-table-wrapper ant-spin-nested-loading css-3op25v css-dev-only-do-not-override-3op25v ">
<div className="ant-table-wrapper ant-spin-nested-loading css-1x2egda css-dev-only-do-not-override-1x2egda ">
<div className="ant-spin-container ant-table ant-table-bordered">
<div className="ant-table-container">
<div className="ant-table-content">
@ -466,7 +466,7 @@ function Index() {
<td>{evaluationScores.FRTHotel}</td>
</tr>
<tr className="ant-table-row ant-table-row-level-0">
<td>Travel Advisor's Planning</td>
<td>Travel Advisor&rsquo;s Planning</td>
<td>{evaluationScores.FRTAdvisor}</td>
</tr>
</tbody>

Loading…
Cancel
Save