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

release
赵鹏 2 years ago
commit 5b5698e644

@ -18,6 +18,8 @@ import ReservationNewest from "@/views/reservation/Newest";
import ReservationDetail from "@/views/reservation/Detail";
import ReservationPrint from "@/views/reservation/Print";
import ReservationNameCard from "@/views/reservation/NameCard";
import ChangePassword from "@/views/account/ChangePassword";
import AccountProfile from "@/views/account/Profile";
import FeedbackIndex from "@/views/feedback/Index";
import FeedbackDetail from "@/views/feedback/Detail";
import NoticeIndex from "@/views/notice/Index";
@ -45,6 +47,8 @@ const router = createBrowserRouter([
{ path: "reservation/:reservationId", element: <ReservationDetail />},
{ path: "reservation/:reservationId/print", element: <ReservationPrint />},
{ path: "reservation/:reservationId/name-card", element: <ReservationNameCard />},
{ path: "account/change-password", element: <ChangePassword />},
{ path: "account/profile", element: <AccountProfile />},
{ path: "feedback", element: <FeedbackIndex />},
{ path: "feedback/:GRI_SN", element: <FeedbackDetail />},
{ path: "notice", element: <NoticeIndex />},

@ -19,12 +19,7 @@ class Auth {
return fetchJSON(fetchUrl)
.then(json => {
if (json.errcode == 0) {
runInAction(() => {
this.login = {
userId: json.Result.WU_LMI_SN,
username: json.Result.WU_UserName,
}
});
return json.Result.WU_LMI_SN;
} else {
throw new Error(json.errmsg + ': ' + json.errcode);
}
@ -45,9 +40,29 @@ class Auth {
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
}
});
return json.Result.LoginName;
} else {
throw new Error(json.errmsg + ': ' + json.errcode);
}
});
}
changeUserPassword(password, newPassword) {
const fetchUrl = prepareUrl(HT_HOST + '/service-Cooperate/Cooperate/SetPassword')
.append('UserID', this.login.userId)
.append('password', password)
.append('NewPassword', newPassword)
.build();
return fetchJSON(fetchUrl)
.then(json => {
if (json.errcode == 0) {
console.info(json);
} else {
throw new Error(json.errmsg + ': ' + json.errcode);
}
@ -59,6 +74,8 @@ class Auth {
username: 'Vu Xuan Giang',
travelAgencyId: 32531, //30008供应商id对应HT的VEI_SN
travelAgencyName: 'ANP',
telephone: '000',
emailAddress: 'abc@123.com',
cityId: 0
}
}

@ -14,6 +14,7 @@ class Feedback {
feedbackImages = []; //图片列表
feedbackRate = []; //反馈评分
feedbackReview = []; //站外好评
feedbackInfo = []; //地接社反馈的信息
/*
地接社sn
@ -84,6 +85,24 @@ class Feedback {
});
}
//获取供应商反馈信息
getFeedbackInfo(VEI_SN, GRI_SN) {
let url = `/service-Cooperate/Cooperate/getVEIFeedbackInfo`;
url += `?GRI_SN=${GRI_SN}&VEI_SN=${VEI_SN}`;
return fetch(config.HT_HOST + url)
.then(response => response.json())
.then(json => {
console.log(json);
runInAction(() => {
this.feedbackInfo = json.Result;
});
return json.Result;
})
.catch(error => {
console.log("fetch data failed", error);
});
}
//提交供应商反馈信息
postFeedbackInfo(VEI_SN, GRI_SN, EOI_SN, info_content) {
let url = `/service-fileServer/FeedbackInfo`;
@ -92,18 +111,14 @@ class Feedback {
formData.append("GRI_SN", GRI_SN);
formData.append("EOI_SN", EOI_SN);
formData.append("FeedbackInfo", info_content);
fetch(config.HT_HOST + url, {
return fetch(config.HT_HOST + url, {
method: "POST",
body: formData,
headers: new Headers({
"Content-Type": "application/x-www-form-urlencoded",
}),
})
.then(response => response.json())
.then(json => {
console.log(json);
runInAction(() => {
});
runInAction(() => {});
})
.catch(error => {
console.log("fetch data failed", error);

@ -113,8 +113,8 @@ class Reservation {
let formData = new FormData();
formData.append('GRI_SN', this.selectedReservation.reservationId);
formData.append('VEI_SN', this.root.authStore.login.travelAgencyId);
formData.append('TGI_SN', cityId);
formData.append('CII_SN', guideId);
formData.append('TGI_SN', guideId);
formData.append('CII_SN', cityId);
formData.append('GetDate', this.selectedReservation.reservationDate);
formData.append('LMI_SN', this.root.authStore.login.userId);
const postUrl = HT_HOST + '/service-cusservice/PTAddGuide';

@ -10,30 +10,18 @@ import { useStore } from "@/stores/StoreContext.js";
const { Header, Content, Footer } = Layout;
const items = [
{
label: (
<a target="_blank" rel="noopener noreferrer" href="#">
Profile
</a>
),
label: (<Link to="/account/change-password">Change password</Link>),
key: "0",
},
{
label: (
<a target="_blank" rel="noopener noreferrer" href="#">
Privacy
</a>
),
label: (<Link to="/account/profile">Profile</Link>),
key: "1",
},
{
type: "divider",
},
{
label: (
<a target="_blank" rel="noopener noreferrer" href="#">
Logout
</a>
),
label: (<Link to="/login">Logout</Link>),
key: "3",
},
];
@ -72,7 +60,7 @@ function App() {
<Menu
theme="dark"
mode="horizontal"
defaultSelectedKeys={[href]}
selectedKeys={[href]}
items={[
{ key: "/reservation/newest", label: <Link to="/reservation/newest">Reservation</Link> },
{ key: "/feedback", label: <Link to="/feedback">Feedback</Link> },

@ -1,24 +1,53 @@
import { useNavigate } from "react-router-dom";
import { Button, Checkbox, Form, Input, Row, App } from 'antd';
import { useStore } from '@/stores/StoreContext.js';
function Login() {
const { authStore } = useStore();
const { notification } = App.useApp();
const navigate = useNavigate();
const [form] = Form.useForm();
const onFinish = (values) => {
console.log('Success:', values);
authStore.valdateUserPassword(values.username, values.password);
authStore.valdateUserPassword(values.username, values.password)
.then((userId) => {
authStore.fetchUserDetail(userId)
.then((user) => {
// navigate(-1) is equivalent to hitting the back button.
navigate("/reservation/newest");
})
.catch(ex => {
notification.error({
message: `Notification`,
description: ex.message,
placement: 'top',
duration: 4,
});
});
})
.catch(ex => {
notification.error({
message: `Notification`,
description: ex.message,
placement: 'top',
duration: 4,
});
});
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
return (
<Row justify="center" align="middle" style={{ minHeight: 500 }}>
<Form
name="basic"
// layout="vertical"
form={form}
size="large"
labelCol={{
span: 8,
}}
@ -47,7 +76,6 @@ function Login() {
>
<Input />
</Form.Item>
<Form.Item
label="Password"
name="password"
@ -60,7 +88,6 @@ function Login() {
>
<Input.Password />
</Form.Item>
<Form.Item
name="remember"
valuePropName="checked"
@ -71,14 +98,13 @@ function Login() {
>
<Checkbox>Remember me</Checkbox>
</Form.Item>
<Form.Item
wrapperCol={{
offset: 8,
span: 16,
}}
>
<Button type="primary" htmlType="submit">
<Button type="primary" htmlType="submit" style={{width: "100%"}}>
Submit
</Button>
</Form.Item>

@ -0,0 +1,105 @@
import { Button, Space, Form, Input, Row, Typography, App } from 'antd';
import { useStore } from '@/stores/StoreContext.js';
const { Title } = Typography;
function ChangePassword() {
const { authStore } = useStore();
const { notification } = App.useApp();
const [form] = Form.useForm();
const onFinish = (values) => {
authStore.changeUserPassword(values.currentPassword, values.newPassword)
.then(() => {
notification.success({
message: `Notification`,
description: 'Your password has been successfully updated.',
placement: 'top',
duration: 4,
});
})
.catch(() => {
notification.error({
message: `Notification`,
description: 'Failed to change password. Please try again.',
placement: 'top',
duration: 4,
});
});
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
// form.resetFields();
};
return (
<>
<Row justify="center" align="middle" style={{ minHeight: 500 }}>
<Form
name="basic"
form={form}
layout="vertical"
size="large"
style={{
maxWidth: 600,
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
<Form.Item><Title level={2}>Change your password</Title></Form.Item>
<Form.Item
label="Current password"
name="currentPassword"
rules={[
{
required: true,
message: 'Please input your password!',
},
]}
>
<Input />
</Form.Item>
<Form.Item
label="New password"
name="newPassword"
rules={[
{
required: true,
message: 'Please input your password!',
},
]}
>
<Input.Password />
</Form.Item>
<Form.Item
label="Reenter password"
name="reenterPassword"
rules={[
{
required: true,
message: 'Please reenter your password!',
},
]}
>
<Input.Password />
</Form.Item>
<Form.Item>
<Space size="middle">
<Button type="primary" htmlType="submit">
Save
</Button>
<Button htmlType="submit">
Cancel
</Button>
</Space>
</Form.Item>
</Form>
</Row>
</>
);
}
export default ChangePassword;

@ -0,0 +1,23 @@
import { Descriptions, Col, Row } from 'antd';
import { useStore } from '@/stores/StoreContext.js';
function Profile() {
const { authStore } = useStore();
const { login } = authStore;
return (
<Row>
<Col span={12} offset={6}>
<Descriptions title="User Profile" layout="vertical" column={2}>
<Descriptions.Item label="Username">{login.username}</Descriptions.Item>
<Descriptions.Item label="Telephone">{login.telephone}</Descriptions.Item>
<Descriptions.Item label="Email address">{login.emailAddress}</Descriptions.Item>
<Descriptions.Item label="Company">{login.travelAgencyName}</Descriptions.Item>
</Descriptions>
</Col>
</Row>
);
}
export default Profile;

@ -1,9 +1,8 @@
import { useParams, useNavigate } from "react-router-dom";
import { useEffect, useState } from "react";
import { useEffect } from "react";
import { observer } from "mobx-react";
import { toJS, runInAction } from "mobx";
import moment from "moment";
import { Row, Col, Space, Button, Divider, Form, Typography, Rate, Radio, Modal, Upload, Input } from "antd";
import { Row, Col, Space, Button, Divider, Form, Typography, Rate, Radio, Upload, Input, App } from "antd";
import { useStore } from "../../stores/StoreContext.js";
import { PlusOutlined } from "@ant-design/icons";
const { Title, Text, Paragraph } = Typography;
@ -13,14 +12,18 @@ function Detail() {
const navigate = useNavigate();
const { GRI_SN } = useParams();
const { feedbackStore, authStore } = useStore();
const { feedbackRate, feedbackReview, feedbackImages } = feedbackStore;
const [value, setValue] = useState(3);
const { feedbackRate, feedbackReview, feedbackImages, feedbackInfo } = feedbackStore;
const desc = ["none", "Unacceptable", "Poor", "Fair", "Very Good", "Excellent"];
const { notification } = App.useApp();
const [form] = Form.useForm();
useEffect(() => {
console.info("Detail.useEffect: " + GRI_SN);
feedbackStore.getFeedbackDetail(authStore.login.travelAgencyId, GRI_SN);
feedbackStore.getFeedbackImages(authStore.login.travelAgencyId, GRI_SN);
feedbackStore.getFeedbackInfo(authStore.login.travelAgencyId, GRI_SN).then(v => {
form.setFieldsValue({ info_content: v.EEF_Content });
});
}, [GRI_SN]);
const HWO_Guide = feedbackRate && feedbackRate.HWO_Guide ? feedbackRate.HWO_Guide : 0;
@ -53,6 +56,20 @@ function Detail() {
return true;
};
const onFinish = values => {
console.log("Success:", values);
if (values) {
feedbackStore.postFeedbackInfo(feedbackInfo.EEF_VEI_SN, feedbackInfo.EEF_GRI_SN, feedbackInfo.EEF_EOI_SN, values.info_content).then(() => {
notification.success({
message: `Notification`,
description: "提交成功",
placement: "top",
duration: 4,
});
});
}
};
return (
<Space direction="vertical" style={{ width: "100%" }}>
<Row gutter={16}>
@ -148,7 +165,7 @@ function Detail() {
<Row gutter={16}>
<Col span={4}></Col>
<Col span={18}>
<Form name="feedback_detail_from" labelCol={{ span: 5 }}>
<Form name="feedback_detail_from" onFinish={onFinish} labelCol={{ span: 5 }} form={form}>
<Divider orientation="left">上传照片</Divider>
<Form.Item>
<Upload
@ -166,19 +183,19 @@ function Detail() {
</div>
</Upload>
</Form.Item>
<Divider orientation="left">地接社反馈信息</Divider>
<Form.Item
name="info_content"
rules={[
{
required: true,
message: 'Please input your messages!',
message: "Please input your messages!",
},
]}>
<Input.TextArea name="info_content" rows={6}></Input.TextArea>
<Input.TextArea rows={6}></Input.TextArea>
</Form.Item>
<Form.Item>
<Button type="primary" onClick={() =>feedbackStore.postFeedbackInfo()}>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>

@ -72,10 +72,6 @@ function Newest() {
placeholder="Select a guide"
optionFilterProp="children"
onChange={(guideId) => {
console.log(`selected:`);
console.log(guideId);
console.log(`city:`);
console.log(city);
reservationStore.setupCityGuide(city.cityId, guideId);
}}
onSearch={(value) => {

Loading…
Cancel
Save