diff --git a/doc/价格管理平台.bmpr b/doc/价格管理平台.bmpr
index 3d600bf..f82ae80 100644
Binary files a/doc/价格管理平台.bmpr and b/doc/价格管理平台.bmpr differ
diff --git a/package.json b/package.json
index 51e69db..7b26815 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "global.highlights.hub",
"private": true,
- "version": "0.1.0",
+ "version": "2.0.0",
"type": "module",
"scripts": {
"dev": "vite",
diff --git a/src/main.jsx b/src/main.jsx
index 37da44d..7be63e3 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -18,6 +18,7 @@ import ReservationNewest from "@/views/reservation/Newest";
import ReservationDetail from "@/views/reservation/Detail";
import ChangePassword from "@/views/account/ChangePassword";
import AccountProfile from "@/views/account/Profile";
+import AccountManagement from "@/views/account/Management";
import FeedbackIndex from "@/views/feedback/Index";
import FeedbackDetail from "@/views/feedback/Detail";
import FeedbackCustomerDetail from "@/views/feedback/CustomerDetail";
@@ -51,6 +52,7 @@ const router = createBrowserRouter([
{ path: "reservation/:reservationId", element: },
{ path: "account/change-password", element: },
{ path: "account/profile", element: },
+ { path: "account/management", element: },
{ path: "feedback", element: },
{ path: "feedback/:GRI_SN/:CII_SN/:RefNo", element: },
{ path: "feedback/:GRI_SN/:RefNo", element: },
diff --git a/src/stores/Reservation.js b/src/stores/Reservation.js
index 0e78634..686d191 100644
--- a/src/stores/Reservation.js
+++ b/src/stores/Reservation.js
@@ -19,7 +19,7 @@ export const fetchPlanDetail = async (travelAgencyId, reservationId) => {
if (json.errcode == 0) {
return {
- planDetail: json.PlanDetail[0],
+ planDetail: json.PlanDetail == null ? {} : json.PlanDetail[0],
planChangeList: json.PlanChange??[]
}
} else {
@@ -139,7 +139,7 @@ const useReservationStore = create((set, get) => ({
},
fetchAllGuideList: () => {
- const { userId, travelAgencyId } = usingStorage()
+ const { travelAgencyId } = usingStorage()
const fetchUrl = prepareUrl(HT_HOST + '/service-cusservice/PTGetGuideList')
.append('VEI_SN', travelAgencyId)
.build();
@@ -161,7 +161,8 @@ const useReservationStore = create((set, get) => ({
});
},
- getReservationDetail: async (travelAgencyId, reservationId) => {
+ getReservationDetail: async (reservationId) => {
+ const { travelAgencyId } = usingStorage()
const { planDetail, planChangeList } = await fetchPlanDetail(travelAgencyId, reservationId)
const attachListJson = await fetchAttachList(reservationId)
@@ -192,7 +193,8 @@ const useReservationStore = create((set, get) => ({
}))
},
- submitConfirmation: (userId, travelAgencyId, confirmText) => {
+ submitConfirmation: (confirmText) => {
+ const { userId, travelAgencyId } = usingStorage()
const { selectedConfirmation, getReservationDetail, reservationDetail } = get()
const formData = new FormData()
formData.append('PCI_SN', selectedConfirmation.key)
@@ -205,7 +207,6 @@ const useReservationStore = create((set, get) => ({
return postForm(postUrl, formData)
.then(json => {
if (json.errcode == 0 && json.Result.length == 1) {
- // this.fetchReservation(this.reservationDetail.reservationId);
getReservationDetail(travelAgencyId, reservationDetail.reservationId)
return json
}
diff --git a/src/views/account/Management.jsx b/src/views/account/Management.jsx
new file mode 100644
index 0000000..6045a6b
--- /dev/null
+++ b/src/views/account/Management.jsx
@@ -0,0 +1,375 @@
+import { NavLink, useLocation } from 'react-router-dom'
+import { useState, useEffect } from 'react'
+import { Row, Col, Space, Button, Table, Select, TreeSelect, Typography, Modal, App, Form, Input } from 'antd'
+import dayjs from 'dayjs'
+import { isEmpty } from '@/utils/commons'
+import { useTranslation } from 'react-i18next'
+import useFormStore from '@/stores/Form'
+import useReservationStore from '@/stores/Reservation'
+import SearchForm from '@/components/SearchForm'
+
+const { Title } = Typography
+
+const { SHOW_PARENT } = TreeSelect
+
+const permissionData = [
+ {
+ title: '机票管理',
+ value: '0-0',
+ key: '0-0',
+ children: [
+ {
+ title: '录入机票价格',
+ value: '0-0-0',
+ key: '0-0-0',
+ },
+ ],
+ },
+ {
+ title: '产品管理',
+ value: '0-1',
+ key: '0-1',
+ children: [
+ {
+ title: '录入产品价格',
+ value: '0-1-0',
+ key: '0-1-0',
+ },
+ {
+ title: '新增产品描述',
+ value: '0-1-1',
+ key: '0-1-1',
+ },
+ {
+ title: '复制供应商产品信息',
+ value: '0-1-2',
+ key: '0-1-2',
+ },
+ ],
+ },
+ {
+ title: '账号管理',
+ value: '2-1',
+ key: '2-1',
+ children: [
+ {
+ title: '重置账号密码',
+ value: '2-1-0',
+ key: '2-1-0',
+ },
+ {
+ title: '禁用账号',
+ value: '2-1-1',
+ key: '2-1-1',
+ },
+ {
+ title: '分配账号角色',
+ value: '2-1-2',
+ key: '2-1-2',
+ },
+ ],
+ },
+];
+
+function Management() {
+ const { t } = useTranslation()
+ const accountListColumns = [
+ {
+ title: t('account:username'),
+ dataIndex: 'username',
+ key: 'account:username',
+ },
+ {
+ title: t('account:realname'),
+ dataIndex: 'realname',
+ key: 'account:realname',
+ },
+ {
+ title: t('account:email'),
+ dataIndex: 'email',
+ key: 'account:email'
+ },
+ {
+ title: t('account:role'),
+ dataIndex: 'role',
+ key: 'account:role'
+ },
+ {
+ title: t('account:lastLogin'),
+ dataIndex: 'lastLogin',
+ key: 'account:lastLogin'
+ },
+ {
+ title: t('account:action'),
+ key: 'account:action',
+ dataIndex: 'account:action',
+ render: actionRender
+ },
+ ]
+
+ function actionRender() {
+ return (
+
+
+
+
+
+ )
+ }
+
+
+ const onPermissionChange = (newValue) => {
+ console.log('onChange ', newValue);
+ setPermissionValue(newValue);
+ }
+ const [permissionValue, setPermissionValue] = useState(['0-0-0'])
+ const [isAccountModalOpen, setAccountModalOpen] = useState(false)
+ const [isRoleModalOpen, setRoleModalOpen] = useState(false)
+ const [dataLoading, setDataLoading] = useState(false)
+ const [accountList, setaccountList] = useState([
+ {
+ username: 'bjyiran',
+ realname: '怡小芳',
+ email: 'xiaofang@yiran.com',
+ role: '国内供应商',
+ lastLogin: '2024-06-12 13:53'
+ },
+ {
+ username: 'int-robin',
+ realname: 'Robin',
+ email: 'robin@int.com',
+ role: '海外供应商',
+ lastLogin: '2024-06-12 13:53'
+ },
+ {
+ username: 'betty-wu',
+ realname: '吴雪',
+ email: 'betty@hainatravel.com',
+ role: '客服组',
+ lastLogin: '2024-06-12 13:53'
+ },
+ {
+ username: 'lancy',
+ realname: '吴金倩',
+ email: 'lancy@hainatravel.com',
+ role: '产品组',
+ lastLogin: '2024-06-12 13:53'
+ },
+ {
+ username: 'LYJ',
+ realname: '廖一军',
+ email: 'lyj@hainatravel.com',
+ role: 'Web 开发组,海外测试供应商',
+ lastLogin: '2024-06-12 13:53'
+ }
+ ])
+
+ const formValuesToSub = useFormStore((state) => state.formValuesToSub)
+
+ const [form] = Form.useForm()
+ const [fetchAllGuideList, fetchReservationList, reservationList, reservationPage, cityList, selectReservation, getCityListByReservationId] =
+ useReservationStore((state) =>
+ [state.fetchAllGuideList, state.fetchReservationList, state.reservationList, state.reservationPage, state.cityList, state.selectReservation, state.getCityListByReservationId])
+
+ const { notification } = App.useApp()
+
+ const handleAccountOk = () => {
+ }
+
+ const handleAccountCancel = () => {
+ setAccountModalOpen(false)
+ }
+
+ const handleRoleOk = () => {
+ }
+
+ const handleRoleCancel = () => {
+ setRoleModalOpen(false)
+ }
+
+ const onFinish = (values) => {
+ console.log(values)
+ }
+
+ const onFinishFailed = (error) => {
+ console.log('Failed:', error)
+ // form.resetFields()
+ }
+
+ // 默认重新搜索第一页,所有状态的计划
+ const onSearchClick = (current=1, status=null) => {
+ }
+
+ return (
+ <>
+
+ {t('account:management.newAccount')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Role Edit */}
+
+ {t('account:management.newRole')}
+
+
+
+
+
+
+
+
+
+ {t('account:management.tile')}
+ {
+ setDataLoading(true)
+ fetchReservationList(formVal)
+ .catch(ex => {
+ notification.error({
+ message: 'Notification',
+ description: ex.message,
+ placement: 'top',
+ duration: 4,
+ })
+ })
+ .finally(() => {
+ setDataLoading(false)
+ })
+ }}
+ />
+
+
+
+
+
+
+
+
+
+
+ { return `总数:${total}` }
+ }}
+ onChange={(pagination) => {onSearchClick(pagination.current)}}
+ columns={accountListColumns} dataSource={accountList}
+ />
+
+
+
+ >
+ )
+}
+
+export default Management
diff --git a/src/views/reservation/Detail.jsx b/src/views/reservation/Detail.jsx
index a214486..2e6f8f8 100644
--- a/src/views/reservation/Detail.jsx
+++ b/src/views/reservation/Detail.jsx
@@ -1,10 +1,10 @@
-import { useParams, useNavigate } from "react-router-dom"
+import { useParams } from "react-router-dom"
import { useEffect, useState } from 'react'
import { Row, Col, Space, Button, Table, Input, Typography, Modal, Tag, App } from 'antd'
import {
FileOutlined
} from '@ant-design/icons';
-import useAuthStore from '@/stores/Auth'
+import { usingStorage } from '@/hooks/usingStorage'
import useReservationStore from '@/stores/Reservation'
import { useTranslation } from 'react-i18next'
import BackBtn from '@/components/BackBtn'
@@ -69,7 +69,6 @@ function Detail() {
);
}
- const navigate = useNavigate();
const [isModalOpen, setIsModalOpen] = useState(false);
const [confirmLoading, setConfirmLoading] = useState(false);
const [confirmText, setConfirmText] = useState('');
@@ -78,7 +77,8 @@ function Detail() {
const { notification } = App.useApp();
const { reservationId } = useParams();
- const loginUser = useAuthStore((state) => state.loginUser)
+ const { travelAgencyId, loginToken } = usingStorage()
+
const [getReservationDetail, reservationDetail, confirmationList, selectConfirmation, submitConfirmation] =
useReservationStore((state) =>
[state.getReservationDetail, state.reservationDetail, state.confirmationList, state.selectConfirmation, state.submitConfirmation])
@@ -87,9 +87,9 @@ function Detail() {
'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=${loginUser.travelAgencyId}&token=${loginUser.token}&FileType=1`;
+ `https://p9axztuwd7x8a7.mycht.cn/service-fileServer/DownloadPlanDoc?GRI_SN=${reservationId}&VEI_SN=${travelAgencyId}&token=${loginToken}&FileType=1`;
const nameCardUrl =
- `https://p9axztuwd7x8a7.mycht.cn/service-fileServer/DownloadPlanDoc?GRI_SN=${reservationId}&VEI_SN=${loginUser.travelAgencyId}&token=${loginUser.token}&FileType=2`;
+ `https://p9axztuwd7x8a7.mycht.cn/service-fileServer/DownloadPlanDoc?GRI_SN=${reservationId}&VEI_SN=${travelAgencyId}&token=${loginToken}&FileType=2`;
const reservationPreviewUrl = officeWebViewerUrl + encodeURIComponent(reservationUrl);
const nameCardPreviewUrl = officeWebViewerUrl + encodeURIComponent(nameCardUrl);
@@ -103,7 +103,7 @@ function Detail() {
const handleOk = () => {
setConfirmLoading(true);
- submitConfirmation(loginUser.userId, loginUser.travelAgencyId, confirmText + '\n——————————————————————\n' +newConfirmText)
+ submitConfirmation(confirmText + '\n——————————————————————\n' +newConfirmText)
.finally(() => {
setNewConfirmText('');
setIsModalOpen(false);
@@ -116,7 +116,7 @@ function Detail() {
useEffect(() => {
setDataLoading(true);
- getReservationDetail(loginUser.travelAgencyId, reservationId)
+ getReservationDetail(reservationId)
.catch(ex => {
notification.error({
message: `Notification`,