diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index 8ed1854..c87b7cd 100644
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -26,8 +26,9 @@
"Export": "Export",
"Copy": "Copy",
- "sureCancel": "Sure you want to cancel?",
- "sureDelete":"Sure you want to delete?",
+ "sureCancel": "Are you sure to cancel?",
+ "sureDelete":"Are you sure to delete?",
+ "Yes": "Yes",
"Success": "Success",
"Failed": "Failed",
diff --git a/public/locales/en/products.json b/public/locales/en/products.json
index b170ecf..0e90423 100644
--- a/public/locales/en/products.json
+++ b/public/locales/en/products.json
@@ -1,4 +1,5 @@
{
+ "ProductType": "Product Type",
"type": {
"Experience": "Experience",
"Car": "Transport Services",
@@ -7,8 +8,7 @@
"Attractions": "Attractions",
"Meals": "Meals",
"Extras": "Extras",
- "Overtravel": "超公里",
- "Special": "Special"
+ "UltraService": "Ultra Service"
},
"EditComponents": {
"info": "Product Information",
@@ -29,6 +29,11 @@
"Rejected": "Reject",
"Published": "Publish"
},
+ "PriceUnit": {
+ "0": "Person",
+ "1": "Group",
+ "title": "Price Unit"
+ },
"Status": "Status",
"State": "State",
@@ -39,6 +44,13 @@
"CreateDate": "Create Date",
"AuditedBy": "Audited By",
"AuditDate": "Audit Date",
+ "OpenHours": "Open Hours",
+ "Duration": "Duration",
+ "KM": "KM",
+ "RecommendsRate": "RecommendsRate",
+ "OpenWeekdays": "Open Weekdays",
+ "DisplayToC": "DisplayToC",
+ "Dept": "Dept",
"productProject": "Product project",
"Code": "Code",
diff --git a/public/locales/zh/account.json b/public/locales/zh/account.json
index a7caf37..35c0dc0 100644
--- a/public/locales/zh/account.json
+++ b/public/locales/zh/account.json
@@ -8,5 +8,24 @@
"CurrentPassword": "请输入密码。",
"NewPassword": "请输入新密码。",
"ReenterPassword": "请重复输入密码。"
- }
+ },
+ "createdOn": "创建时间",
+ "action": "操作",
+ "action.edit": "编辑",
+ "action.disable": "禁用",
+ "action.resetPassword": "重置密码",
+
+ "accountList": "管理账号",
+ "newAccount": "新增账号",
+ "detail": "详细信息",
+ "username": "用户名",
+ "realname": "姓名",
+ "travelAgencyName": "供应商名称",
+ "email": "邮箱地址",
+ "lastLogin": "最后登陆时间",
+
+ "roleList": "管理角色",
+ "newRole": "新增角色",
+ "roleName": "角色名称",
+ "permission": "权限"
}
\ No newline at end of file
diff --git a/public/locales/zh/common.json b/public/locales/zh/common.json
index 82b43f9..459ff35 100644
--- a/public/locales/zh/common.json
+++ b/public/locales/zh/common.json
@@ -28,6 +28,7 @@
"sureCancel": "确定取消?",
"sureDelete":"确定删除?",
+ "Yes": "是",
"Success": "成功",
"Failed": "失败",
@@ -62,13 +63,13 @@
"thisYear": "今年"
},
"weekdays": {
- "1": "一",
- "2": "二",
- "3": "三",
- "4": "四",
- "5": "五",
- "6": "六",
- "7": "日"
+ "1": "周一",
+ "2": "周二",
+ "3": "周三",
+ "4": "周四",
+ "5": "周五",
+ "6": "周六",
+ "7": "周日"
},
"weekdaysShort": {
"1": "一",
diff --git a/public/locales/zh/products.json b/public/locales/zh/products.json
index 1d7ebff..3fe9c47 100644
--- a/public/locales/zh/products.json
+++ b/public/locales/zh/products.json
@@ -1,14 +1,14 @@
{
+ "ProductType": "项目类型",
"type": {
"Experience": "综费",
"Car": "车费",
- "Guide": "导服",
+ "Guide": "导游",
"Package": "包价线路",
"Attractions": "景点",
"Meals": "餐费",
"Extras": "附加项目",
- "Overtravel": "超公里",
- "Special": "特殊项目"
+ "UltraService": "超公里"
},
"EditComponents": {
"info": "产品信息",
@@ -29,6 +29,11 @@
"Rejected": "审核拒绝",
"Published": "审核发布"
},
+ "PriceUnit": {
+ "0": "每人",
+ "1": "每团",
+ "title": "报价单位"
+ },
"Status": "状态",
"State": "状态",
@@ -37,11 +42,18 @@
"AuState": "审核状态",
"CreatedBy": "提交人员",
"CreateDate": "提交时间",
-
-
"AuditedBy": "审核人员",
"AuditDate": "审核时间",
+ "OpenHours": "游览时间",
+ "Duration": "游览时长",
+ "KM": "公里数",
+ "RecommendsRate": "推荐指数",
+ "OpenWeekdays": "周开放日",
+ "DisplayToC": "报价信显示",
+ "Dept": "小组",
+
+
"productProject": "产品项目",
"Code": "简码",
"City": "城市",
@@ -71,7 +83,7 @@
"GroupSize": "人等",
"UseDates": "使用日期",
- "Weekdays": "有效日/周X",
+ "Weekdays": "周末",
"OnWeekdays": "周: ",
"Unlimited": "不限",
diff --git a/src/components/SearchForm.jsx b/src/components/SearchForm.jsx
index f6bad2c..f896792 100644
--- a/src/components/SearchForm.jsx
+++ b/src/components/SearchForm.jsx
@@ -3,7 +3,7 @@ import { Form, Input, Row, Col, Select, DatePicker, Space, Button } from 'antd';
import { objectMapper, at } from '@/utils/commons';
import { DATE_FORMAT, SMALL_DATETIME_FORMAT } from '@/config';
import useFormStore from '@/stores/Form';
-import useDatePresets from '@/hooks/useDatePresets';
+import {useDatePresets} from '@/hooks/useDatePresets';
import { useTranslation } from 'react-i18next';
import { fetchJSON } from '@/utils/request';
@@ -209,7 +209,7 @@ function getFields(props) {
),
item(
'username',
- 3,
+ 99,
,
@@ -217,7 +217,7 @@ function getFields(props) {
),
item(
'realname',
- 4,
+ 99,
,
diff --git a/src/hooks/useDatePresets.js b/src/hooks/useDatePresets.js
index 87397b9..2eb4c7d 100644
--- a/src/hooks/useDatePresets.js
+++ b/src/hooks/useDatePresets.js
@@ -1,8 +1,9 @@
import { useEffect, useState } from 'react';
import dayjs from "dayjs";
import { useTranslation } from 'react-i18next';
+import i18n from '@/i18n';
-const useDatePresets = () => {
+export const useDatePresets = () => {
const [presets, setPresets] = useState([]);
const { t, i18n } = useTranslation();
@@ -39,4 +40,21 @@ const useDatePresets = () => {
return presets;
}
-export default useDatePresets;
+export const useWeekdays = () => {
+ const [data, setData] = useState([]);
+ const { t, i18n } = useTranslation();
+ useEffect(() => {
+ const newData = [
+ { value: '1', label: t('weekdays.1') },
+ { value: '2', label: t('weekdays.2') },
+ { value: '3', label: t('weekdays.3') },
+ { value: '4', label: t('weekdays.4') },
+ { value: '5', label: t('weekdays.5') },
+ { value: '6', label: t('weekdays.6') },
+ { value: '7', label: t('weekdays.7') },
+ ];
+ setData(newData);
+ return () => {};
+ }, [i18n.language]);
+ return data;
+};
diff --git a/src/hooks/useProductsSets.js b/src/hooks/useProductsSets.js
index 0dd63f7..015fa8a 100644
--- a/src/hooks/useProductsSets.js
+++ b/src/hooks/useProductsSets.js
@@ -1,42 +1,44 @@
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
+import useAuthStore from '@/stores/Auth';
+import { PERM_OVERSEA, PERM_AIR_TICKET, PERM_PRODUCTS_MANAGEMENT } from '@/config';
/**
* 产品管理 相关的预设数据
* 项目类型
-酒店预定 1
-火车 2
-飞机票务 3
-游船 4
-快巴 5
-旅行社(综费) 6
-景点 7
-特殊项目 8
-其他 9
-酒店 A
-超公里 B
-餐费 C
-小包价 D
-站 X
-购物 S
-餐 R
-娱乐 E
-精华线路 T
-客人testimonial F
-线路订单 O
-省 P
-信息 I
-国家 G
-城市 K
-图片 H
-地图 M
-包价线路 L
-节日节庆 V
-火车站 N
-手机租赁 Z
- * * webht 类型, 20240624 新增HT类型
-Q 导游
-J 车费
+ * * 酒店预定 1
+ * * 火车 2
+ * * 飞机票务 3
+ * * 游船 4
+ * * 快巴 5
+ * * 旅行社(综费) 6
+ * * 景点 7
+ * * 特殊项目 8
+ * * 其他 9
+ * * 酒店 A
+ * * 超公里 B
+ * * 餐费 C
+ * * 小包价 D
+ * * 站 X
+ * * 购物 S
+ * * 餐 R (餐厅)
+ * * 娱乐 E
+ * * 精华线路 T
+ * * 客人testimonial F
+ * * 线路订单 O
+ * * 省 P
+ * * 信息 I
+ * * 国家 G
+ * * 城市 K
+ * * 图片 H
+ * * 地图 M
+ * * 包价线路 L (已废弃)
+ * * 节日节庆 V
+ * * 火车站 N
+ * * 手机租赁 Z
+ * * ---- webht 类型, 20240624 新增HT类型 ----
+ * * 导游 Q
+ * * 车费 J
*/
export const useProductsTypes = () => {
@@ -46,20 +48,24 @@ export const useProductsTypes = () => {
useEffect(() => {
const newData = [
{ label: t('products:type.Experience'), value: '6', key: '6' },
- { label: t('products:type.Overtravel'), value: 'B', key: 'B' },
+ { label: t('products:type.UltraService'), value: 'B', key: 'B' },
{ label: t('products:type.Car'), value: 'J', key: 'J' },
{ label: t('products:type.Guide'), value: 'Q', key: 'Q' },
{ label: t('products:type.Package'), value: 'D', key: 'D' }, // 包价线路
{ label: t('products:type.Attractions'), value: '7', key: '7' },
- { label: t('products:type.Meals'), value: 'C', key: 'C' },
+ { label: t('products:type.Meals'), value: 'R', key: 'R' },
{ label: t('products:type.Extras'), value: '8', key: '8' },
- // { label: t('products:type.Special'), value: 'Special', key: 'Special' },
];
setTypes(newData);
}, [i18n.language]);
return types;
};
+export const useProductsTypesMapVal = (value) => {
+ const stateSets = useProductsTypes();
+ const stateMapVal = stateSets.reduce((r, c) => ({ ...r, [`${c.value}`]: c }), {});
+ return stateMapVal;
+};
export const useProductsAuditStates = () => {
const [types, setTypes] = useState([]);
@@ -89,17 +95,26 @@ export const useProductsAuditStatesMapVal = (value) => {
/**
* @ignore
*/
-export const useProductsTypesFieldsets = (type, role) => {
- const infoDefault = ['code', 'title'];
+export const useProductsTypesFieldsets = (type) => {
+ const [isPermitted] = useAuthStore((state) => [state.isPermitted]);
+ const infoDefault = [['code'], ['title']];
const infoAdmin = ['remarks', 'dept', 'display_to_c'];
const infoTypesMap = {
- '6': [],
- 'B': ['city_id', 'km'],
- 'J': ['description', 'city_id', 'recommends_rate', 'duration', 'display_to_c'],
- 'Q': ['description', 'city_id', 'duration', ],
- 'D': ['description', 'city_id', 'recommends_rate','duration',],
- '7': ['description', 'city_id', 'recommends_rate', 'duration', 'display_to_c', 'open_weekdays'], // todo: 怎么是2个图
- 'C': ['description', 'city_id',],
- '8': [], // todo: ?
+ '6': [[],[]],
+ 'B': [['city_id', 'km'], []],
+ 'J': [['city_id', 'recommends_rate', 'duration', 'display_to_c'], ['description',]],
+ 'Q': [['city_id', 'duration', ], ['description',]],
+ 'D': [['city_id', 'recommends_rate','duration',], ['description',]],
+ '7': [['city_id', 'recommends_rate', 'duration', 'display_to_c', 'open_weekdays'], ['description',]], // todo: 怎么是2个图
+ 'R': [['city_id',], ['description',]],
+ '8': [[],[]], // todo: ?
};
-};
+ const thisTypeFieldset = (_type) => {
+ const adminSet = isPermitted(PERM_PRODUCTS_MANAGEMENT) ? infoAdmin : [];
+ return [
+ [...infoDefault[0], ...infoTypesMap[_type][0], ...adminSet],
+ [...infoDefault[1], ...infoTypesMap[_type][1]]
+ ];
+ };
+ return thisTypeFieldset(type);
+}
diff --git a/src/i18n/LanguageSwitcher.jsx b/src/i18n/LanguageSwitcher.jsx
index dd1a743..f09a07e 100644
--- a/src/i18n/LanguageSwitcher.jsx
+++ b/src/i18n/LanguageSwitcher.jsx
@@ -8,16 +8,15 @@ const i18n_to_htcode = {
'en': 1,
};
-export const useLanguage = () => {
+export const useDefaultLgc = () => {
const { i18n } = useTranslation();
- return { language: i18n.language, };
+ return { language: i18n_to_htcode[i18n.language], };
};
-
/**
* 语言选择组件
*/
const Language = () => {
- const { t, i18n } = useTranslation();
+const { t, i18n } = useTranslation();
const [selectedKeys, setSelectedKeys] = useState([i18n.language]);
useEffect(() => {
diff --git a/src/main.jsx b/src/main.jsx
index eb70c92..02f2244 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -9,7 +9,6 @@ import App from "@/views/App";
import Standlone from "@/views/Standlone";
import Login from "@/views/Login";
import Logout from "@/views/Logout";
-import Index from "@/views/index";
import ErrorPage from "@/components/ErrorPage";
import RequireAuth from '@/components/RequireAuth'
import ReservationNewest from "@/views/reservation/Newest";
@@ -49,10 +48,12 @@ const initAppliction = async () => {
if (isNotEmpty(loginToken)) {
appendRequestParams('token', loginToken)
+ appendRequestParams('lmi_sn', userId)
+
}
if (isNotEmpty(userId)) {
- appendRequestParams('wu_id', userId)
+ appendRequestParams('lmi_sn', userId)
await fireAuth()
}
}
@@ -65,7 +66,7 @@ const router = createBrowserRouter([
element: ,
errorElement: ,
children: [
- { index: true, element: },
+ { index: true, element: },
{ path: "account/change-password", element: },
{ path: "account/profile", element: },
{ path: "account/management", element: },
@@ -76,14 +77,14 @@ const router = createBrowserRouter([
{ path: "feedback/:GRI_SN/:CII_SN/:RefNo", element: },
{ path: "feedback/:GRI_SN/:RefNo", element: },
{ path: "report", element: },
- { path: "notice", element: },
- { path: "notice/:CCP_BLID", element: },
+ { path: "notice", element: },
+ { path: "notice/:CCP_BLID", element: },
{ path: "invoice",element:},
{ path: "invoice/detail/:GMDSN/:GSN",element:},
{ path: "invoice/paid",element:},
{ path: "invoice/paid/detail/:flid", element: },
{ path: "airticket",element: },
- { path: "airticket/plan/:coli_sn",element:},
+ { path: "airticket/plan/:coli_sn",element:},
{ path: "products",element: },
{ path: "products/:travel_agency_id/:use_year/:audit_state/audit",element:},
{ path: "products/:travel_agency_id/:use_year/:audit_state/edit",element:},
diff --git a/src/stores/Account.js b/src/stores/Account.js
index 804299a..01010d8 100644
--- a/src/stores/Account.js
+++ b/src/stores/Account.js
@@ -70,11 +70,11 @@ const useAccountStore = create((set, get) => ({
accountList: [],
- disableAccount: async (accountId) => {
+ disableAccount: async (userId) => {
const formData = new FormData()
- formData.append('wu_id', accountId)
- // enable disable
+ formData.append('lmi_sn', userId)
+ // enable | disable
formData.append('account_status', 'disable')
const result = await postAccountStatus(formData)
@@ -82,10 +82,10 @@ const useAccountStore = create((set, get) => ({
console.info(result)
},
- resetAccountPassword: async (accountId, password) => {
+ resetAccountPassword: async (userId, password) => {
const formData = new FormData()
- formData.append('wu_id', accountId)
+ formData.append('lmi_sn', userId)
formData.append('newPassword', password)
return postAccountPassword(formData)
@@ -111,8 +111,8 @@ const useAccountStore = create((set, get) => ({
saveOrUpdateAccount: async (formValues) => {
const { userId } = usingStorage()
const formData = new FormData()
- formData.append('wu_id', formValues.userId)
- formData.append('lmi_sn', formValues.lmi_sn)
+ formData.append('wu_id', formValues.accountId)
+ formData.append('lmi_sn', formValues.userId)
formData.append('lmi2_sn', formValues.lmi2_sn)
formData.append('user_name', formValues.username)
formData.append('real_name', formValues.realname)
@@ -138,8 +138,8 @@ const useAccountStore = create((set, get) => ({
const mapAccoutList = resultArray.map((r) => {
return {
- userId: r.wu_id,
- lmi_sn: r.lmi_sn,
+ accountId: r.wu_id,
+ userId: r.lmi_sn,
lmi2_sn: r.lmi2_sn,
username: r.user_name,
realname: r.real_name,
diff --git a/src/stores/Auth.js b/src/stores/Auth.js
index c413edb..344e147 100644
--- a/src/stores/Auth.js
+++ b/src/stores/Auth.js
@@ -36,7 +36,7 @@ export const fetchUserDetail = async (loginToken) => {
export const fetchPermissionListByUserId = async (userId) => {
const { errcode, result } = await fetchJSON(
- `${HT_HOST}/service-CooperateSOA/get_account_permission_list`, { wu_id: userId})
+ `${HT_HOST}/service-CooperateSOA/get_account_permission_list`, { lmi_sn: userId})
return errcode !== 0 ? {} : result
}
@@ -71,7 +71,7 @@ const useAuthStore = create(obervseLifecycle((set, get) => ({
// 以上是 Hardcode 判断
// 以下是权限列表从数据库读取后使用的方法
return permissionList.some((value) => {
- if (value.indexOf(WILDCARD_TOKEN) > -1) {
+ if (value.indexOf(WILDCARD_TOKEN) == 0) {
return true
}
if (value === perm) {
@@ -85,9 +85,9 @@ const useAuthStore = create(obervseLifecycle((set, get) => ({
const { startTokenInterval, loadUserPermission } = get()
const { setStorage } = usingStorage()
- const { token: loginToken, WU_ID: userId } = await fetchLoginToken(usr, pwd)
+ const { token: loginToken } = await fetchLoginToken(usr, pwd)
const userDetail = await fetchUserDetail(loginToken)
- await loadUserPermission(userId)
+ await loadUserPermission(userDetail.LMI_SN)
set(() => ({
tokenTimeout: false,
@@ -95,10 +95,10 @@ const useAuthStore = create(obervseLifecycle((set, get) => ({
}))
setStorage(KEY_LOGIN_TOKEN, loginToken)
- setStorage(KEY_USER_ID, userId)
+ setStorage(KEY_USER_ID, userDetail.LMI_SN)
setStorage(KEY_TRAVEL_AGENCY_ID, userDetail.LMI_VEI_SN)
appendRequestParams('token', loginToken)
- appendRequestParams('wu_id', userDetail.LMI_SN)
+ appendRequestParams('lmi_sn', userDetail.LMI_SN)
// loadPageSpy(`${json.Result.VName}-${json.Result.LoginName}`)
startTokenInterval()
},
@@ -131,7 +131,7 @@ const useAuthStore = create(obervseLifecycle((set, get) => ({
const now = new Date()
const diffTime = now.getTime() - lastReqDate.getTime()
const diffHours = diffTime/1000/60/60
- if (diffHours > 4) {
+ if (diffHours > 1) {
loginTimeout()
}
}
@@ -144,7 +144,8 @@ const useAuthStore = create(obervseLifecycle((set, get) => ({
loginTimeout: () => {
const { tokenInterval } = get()
- // TODO: 这里没有清理 token,刷新后可以正常使用系统
+ const { clearStorage } = usingStorage()
+ clearStorage()
clearInterval(tokenInterval)
set(() => ({
tokenTimeout: true
@@ -171,4 +172,4 @@ const useAuthStore = create(obervseLifecycle((set, get) => ({
})))
-export default useAuthStore
\ No newline at end of file
+export default useAuthStore
diff --git a/src/views/App.jsx b/src/views/App.jsx
index 0ebcff4..3541d9b 100644
--- a/src/views/App.jsx
+++ b/src/views/App.jsx
@@ -4,7 +4,7 @@ import { Layout, Menu, ConfigProvider, theme, Dropdown, Space, Row, Col, Badge,
import { DownOutlined } from '@ant-design/icons';
import 'antd/dist/reset.css';
import AppLogo from '@/assets/logo-gh.png';
-import { isEmpty } from '@/utils/commons';
+import { isEmpty, isNotEmpty } from '@/utils/commons';
import Language from '../i18n/LanguageSwitcher';
import { useTranslation } from 'react-i18next';
import zhLocale from 'antd/locale/zh_CN';
@@ -43,13 +43,15 @@ function App() {
const needToLogin = href !== '/login' && isEmpty(loginToken)
useEffect(() => {
- fetchUserDetail(loginToken)
- .then(u => {
- setUserDetail({
- username: u.LoginName,
- travelAgencyName: u.VName,
+ if (isNotEmpty(loginToken)) {
+ fetchUserDetail(loginToken)
+ .then(u => {
+ setUserDetail({
+ username: u.LoginName,
+ travelAgencyName: u.VName,
+ })
})
- })
+ }
}, [loginToken])
useEffect(() => {
@@ -58,10 +60,6 @@ function App() {
}
}, [href])
- useEffect(() => {
- window.gtag('event', 'page_view', { page_location: window.location.href });
- }, [location])
-
const onSubmit = () => {
validateUserPassword(userDetail?.username, password)
.catch(ex => {
@@ -69,23 +67,24 @@ function App() {
alert(t('Validation.LoginFailed'))
})
setPassword('')
- };
+ }
- const splitPath = href.split('/');
- let defaultPath = 'reservation';
+ const splitPath = href.split('/')
+ let defaultPath = 'notice'
if (splitPath.length > 1) {
- defaultPath = splitPath[1];
+ defaultPath = splitPath[1]
}
const {
token: { colorBgContainer },
- } = theme.useToken();
+ } = theme.useToken()
const [antdLng, setAntdLng] = useState(enLocale);
useEffect(() => {
setAntdLng(i18n.language === 'en' ? enLocale : zhLocale);
- }, [i18n.language]);
+ }, [i18n.language])
+
return (
{t('ChangePassword')}, key: '0' },
{ label: {t('Profile')}, key: '1' },
- isPermitted(PERM_ACCOUNT_MANAGEMENT) ? { label: {t('account:management.tile')}, key: '3' } : null,
- isPermitted(PERM_ROLE_NEW) ? { label: {t('account:management.roleList')}, key: '4' } : null,
+ { type: 'divider' },
+ isPermitted(PERM_ACCOUNT_MANAGEMENT) ? { label: {t('account:accountList')}, key: '3' } : null,
+ isPermitted(PERM_ROLE_NEW) ? { label: {t('account:roleList')}, key: '4' } : null,
{ type: 'divider' },
{ label: {t('Logout')}, key: '99' },
]
@@ -195,7 +195,7 @@ function App() {
- );
+ )
}
export default App
diff --git a/src/views/Index.jsx b/src/views/Index.jsx
deleted file mode 100644
index 9034490..0000000
--- a/src/views/Index.jsx
+++ /dev/null
@@ -1,13 +0,0 @@
-export default function Index() {
- return (
-
- Global Highlights Hub
-
- Check out{" "}
-
- the docs at chinahighlights.com
-
- .
-
- );
-}
\ No newline at end of file
diff --git a/src/views/Login.jsx b/src/views/Login.jsx
index b973b96..f9c3008 100644
--- a/src/views/Login.jsx
+++ b/src/views/Login.jsx
@@ -17,7 +17,7 @@ function Login() {
useEffect (() => {
if (loginStatus === 302) {
- navigate('/reservation/newest')
+ navigate('/')
}
}, [loginStatus])
diff --git a/src/views/account/Management.jsx b/src/views/account/Management.jsx
index 517f03f..d3e3d2d 100644
--- a/src/views/account/Management.jsx
+++ b/src/views/account/Management.jsx
@@ -1,14 +1,12 @@
-import { useState, useEffect } from 'react'
-import { Row, Col, Space, Button, Table, Select, TreeSelect, Typography, Modal, App, Form, Input } from 'antd'
+import SearchForm from '@/components/SearchForm'
+import useAccountStore, { fetchRoleList, fetchTravelAgencyByName } from '@/stores/Account'
+import useFormStore from '@/stores/Form'
+import { isEmpty } from '@/utils/commons'
import { ExclamationCircleFilled } from '@ant-design/icons'
-import { useTranslation } from 'react-i18next'
-import { fetchTravelAgencyByName } from '@/stores/Account'
+import { App, Button, Col, Form, Input, Modal, Row, Select, Space, Table, Typography } from 'antd'
import dayjs from 'dayjs'
-import { isEmpty } from '@/utils/commons'
-import useAccountStore from '@/stores/Account'
-import useFormStore from '@/stores/Form'
-import { fetchRoleList } from '@/stores/Account'
-import SearchForm from '@/components/SearchForm'
+import { useEffect, useState } from 'react'
+import { useTranslation } from 'react-i18next'
const { Title } = Typography
@@ -26,7 +24,7 @@ function Management() {
dataIndex: 'realname',
},
{
- title: t('account:travelAgency'),
+ title: t('account:travelAgencyName'),
dataIndex: 'travelAgencyName',
},
{
@@ -34,7 +32,7 @@ function Management() {
dataIndex: 'email',
},
{
- title: t('account:role'),
+ title: t('account:roleName'),
dataIndex: 'role'
},
{
@@ -43,7 +41,7 @@ function Management() {
render: (text) => (isEmpty(text) ? '' : dayjs(text).format('YYYY-MM-DD HH:mm:ss'))
},
{
- title: t('account:action'),
+ title: t('account:action.edit'),
dataIndex: 'account:action',
render: actionRender
},
@@ -78,7 +76,7 @@ function Management() {
const formValues = useFormStore(state => state.formValues)
const { notification, modal } = App.useApp()
- useEffect (() => {
+ useEffect(() => {
fetchRoleList()
.then((roleList) => {
setRoleAllList(roleList.map(r => {
@@ -108,7 +106,6 @@ function Management() {
}
const onAccountSeleted = async (account) => {
- console.info(account)
setTravelAgencyList([{
label: account.travelAgencyName,
value: account.travelAgencyId
@@ -156,7 +153,6 @@ function Management() {
}
const handleTravelAgencyChange = (newValue) => {
- console.info(newValue)
setCurrentTravelAgency(newValue)
}
@@ -189,7 +185,6 @@ function Management() {
duration: 60,
})
})
- console.log('ResetPassword')
},
onCancel() {
},
@@ -204,32 +199,32 @@ function Management() {
autoFocus: true,
htmlType: 'submit',
}}
- title={t('account:management.newAccount')}
+ title={t('account:detail')}
open={isAccountModalOpen} onOk={() => setAccountModalOpen(false)} onCancel={() => setAccountModalOpen(false)}
destroyOnClose={true}
clearOnDestroy={true}
modalRender={(dom) => (
)}
>
-
-
-
+
+
+
-
- {t('account:management.tile')}
+ {t('account:accountList')}
{
handelAccountSearch()
@@ -316,7 +317,7 @@ function Management() {
-
+
diff --git a/src/views/account/RoleList.jsx b/src/views/account/RoleList.jsx
index 13a1501..71909f1 100644
--- a/src/views/account/RoleList.jsx
+++ b/src/views/account/RoleList.jsx
@@ -1,12 +1,14 @@
-import { useState, useEffect } from 'react'
-import { Row, Col, Space, Button, Table, TreeSelect, Typography, Modal, App, Form, Input } from 'antd'
-import { useTranslation } from 'react-i18next'
-import useAccountStore from '@/stores/Account'
-import { fetchRoleList, fetchPermissionList, fetchPermissionListByRoleId } from '@/stores/Account'
-import dayjs from 'dayjs'
-import { isEmpty } from '@/utils/commons'
import RequireAuth from '@/components/RequireAuth'
import { PERM_ROLE_NEW } from '@/config'
+import useAccountStore, { fetchPermissionList, fetchPermissionListByRoleId, fetchRoleList } from '@/stores/Account'
+import { isEmpty } from '@/utils/commons'
+import {
+ SyncOutlined,
+} from '@ant-design/icons'
+import { App, Button, Col, Form, Input, Modal, Row, Space, Table, Tag, TreeSelect, Typography } from 'antd'
+import dayjs from 'dayjs'
+import { useEffect, useState } from 'react'
+import { useTranslation } from 'react-i18next'
const { Title } = Typography
@@ -15,7 +17,7 @@ function RoleList() {
const roleListColumns = [
{
- title: t('account:rolename'),
+ title: t('account:roleName'),
dataIndex: 'role_name',
},
{
@@ -30,8 +32,10 @@ function RoleList() {
},
]
- function actionRender(text, role) {
- if (role.role_id > 1) {
+ function actionRender(_, role) {
+ if (role.role_id == 1) {
+ return (} color='warning'>不能修改)
+ } else {
return (
)
@@ -49,7 +53,7 @@ function RoleList() {
}, {})
}
- useEffect (() => {
+ useEffect(() => {
setDataLoading(true)
fetchRoleList()
.then(r => {
@@ -110,7 +114,7 @@ function RoleList() {
const { notification, modal } = App.useApp()
const onRoleSeleted = (role) => {
- fetchPermissionListByRoleId({role_id: role.role_id})
+ fetchPermissionListByRoleId({ role_id: role.role_id })
.then(result => {
role.res_array = result.map(r => r.res_id)
roleForm.setFieldsValue(role)
@@ -154,71 +158,71 @@ function RoleList() {
autoFocus: true,
htmlType: 'submit',
}}
- title={t('account:management.newRole')}
+ title={t('account:detail')}
open={isRoleModalOpen} onOk={() => setRoleModalOpen(false)} onCancel={() => setRoleModalOpen(false)}
destroyOnClose={true}
clearOnDestroy={true}
modalRender={(dom) => (
)}
>
-
-
-
-
-
-
-
+
+
+
+
+
+
+
- {t('account:management.roleList')}
+ {t('account:roleList')}
-
+
@@ -230,6 +234,7 @@ function RoleList() {
loading={dataLoading}
rowKey='role_id'
pagination={{
+ pageSize: 20,
showQuickJumper: true,
showLessItems: true,
showSizeChanger: true,
diff --git a/src/views/products/Audit.jsx b/src/views/products/Audit.jsx
index 9646fd7..f654d20 100644
--- a/src/views/products/Audit.jsx
+++ b/src/views/products/Audit.jsx
@@ -62,6 +62,8 @@ const PriceTable = ({ dataSource, refresh }) => {
const { message, notification } = App.useApp();
const stateMapVal = useProductsAuditStatesMapVal();
+ // console.log(dataSource);
+
const handleAuditPriceItem = (state, row) => {
postProductsQuoteAuditAction(state, { id: row.id, travel_agency_id: activeAgency.travel_agency_id })
.then((json) => {
@@ -83,11 +85,9 @@ const PriceTable = ({ dataSource, refresh }) => {
};
const columns = [
- { key: 'title', dataIndex: ['info', 'title'], width: '16rem', title: t('Title'), onCell: (r, index) => ({ rowSpan: r.rowSpan }) },
- { key: 'adult', title: t('AgeType.Adult'), render: (_, { value, currency, unit_name }) => `${value} ${currency} / ${unit_name}` },
- { key: 'child', title: t('AgeType.Child'), render: (_, { value, currency, unit_name }) => `${value} ${currency} / ${unit_name}` },
- // {key: 'price', title: t('Currency'), },
- // {key: 'currency', title: t('Currency'), },
+ { key: 'title', dataIndex: ['info', 'title'], width: '16rem', title: t('Title'), onCell: (r, index) => ({ rowSpan: r.rowSpan }), render: (text, r) => text || r.lgc_details?.['2']?.title || r.lgc_details?.['1']?.title || '' },
+ { key: 'adult', title: t('AgeType.Adult'), render: (_, { adult_cost, currency, unit_id, unit_name }) => `${adult_cost} ${currency} / ${t(`PriceUnit.${unit_id}`)}` },
+ { key: 'child', title: t('AgeType.Child'), render: (_, { child_cost, currency, unit_id, unit_name }) => `${child_cost} ${currency} / ${t(`PriceUnit.${unit_id}`)}` },
// {key: 'unit', title: t('Unit'), },
{
key: 'groupSize',
@@ -135,16 +135,33 @@ const TypesPanels = (props) => {
const [activeKey, setActiveKey] = useState([]);
const [showTypes, setShowTypes] = useState([]);
useEffect(() => {
- // 只显示有产品的类型; 展开产品的价格表, 合并名称列
+ // 只显示有产品的类型; 展开产品的价格表, 合并名称列; 转化为价格主表, 携带产品属性信息
const hasDataTypes = Object.keys(agencyProducts);
const _show = productsTypes
.filter((kk) => hasDataTypes.includes(kk.value))
.map((ele) => ({
...ele,
+ extra: t('Table.Total', { total: agencyProducts[ele.value].length }),
children: (
r.concat(c.quotation.map((q, i) => ({ ...q, weekdays: q.weekdays.split(',').filter(Boolean).map(w => t(`weekdaysShort.${w}`)).join(', '), info: c.info, rowSpan: i === 0 ? c.quotation.length : 0 }))), [])}
+ dataSource={agencyProducts[ele.value].reduce(
+ (r, c) =>
+ r.concat(
+ c.quotation.map((q, i) => ({
+ ...q,
+ weekdays: q.weekdays
+ .split(',')
+ .filter(Boolean)
+ .map((w) => t(`weekdaysShort.${w}`))
+ .join(', '),
+ info: c.info,
+ lgc_details: c.lgc_details.reduce((rlgc, clgc) => ({...r, [clgc.lgc]: clgc}), {}),
+ rowSpan: i === 0 ? c.quotation.length : 0,
+ }))
+ ),
+ []
+ )}
refresh={props.refresh}
/>
),
diff --git a/src/views/products/Detail/Extras.jsx b/src/views/products/Detail/Extras.jsx
index b5e0f1b..2ee8587 100644
--- a/src/views/products/Detail/Extras.jsx
+++ b/src/views/products/Detail/Extras.jsx
@@ -1,19 +1,22 @@
-import { createContext, useContext, useEffect, useState } from 'react';
+import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { App, Table, Button, Modal, Popconfirm } from 'antd';
-import useProductsStore, { getAgencyProductExtrasAction, getAgencyProductsAction, addProductExtraAction, delProductExtrasAction } from '@/stores/Products/Index';
-import { isEmpty, cloneDeep } from '@/utils/commons';
+import { getAgencyProductExtrasAction, getAgencyProductsAction, addProductExtraAction, delProductExtrasAction } from '@/stores/Products/Index';
+import { cloneDeep } from '@/utils/commons';
import SearchForm from '@/components/SearchForm';
import RequireAuth from '@/components/RequireAuth';
import { PERM_PRODUCTS_MANAGEMENT } from '@/config';
+import { useProductsTypesMapVal } from '@/hooks/useProductsSets';
const NewAddonModal = ({ onPick, ...props }) => {
const { travel_agency_id, use_year } = useParams();
const { t } = useTranslation();
const { notification, message } = App.useApp();
+ const productsTypesMapVal = useProductsTypesMapVal();
+
const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false); // bind loading
const [searchLoading, setSearchLoading] = useState(false);
@@ -24,27 +27,26 @@ const NewAddonModal = ({ onPick, ...props }) => {
const { starttime, endtime, ...param } = copyObject;
setSearchLoading(true);
setSearchResult([]);
- const result = await getAgencyProductsAction({ ...param, audit_state: '1', travel_agency_id, use_year });
+ // debug: audit_state: '1',
+ const result = await getAgencyProductsAction({ ...param, audit_state: '0', travel_agency_id, use_year });
setSearchResult(result?.products || []);
setSearchLoading(false);
};
const handleAddExtras = async (item) => {
- // const success = await fetchBindOrder({ coli_sn, conversationid: currentConversationID });
- // success ? message.success('绑定成功') : message.error('绑定失败');
- // setOpen(false);
if (typeof onPick === 'function') {
onPick(item);
}
};
- // todo:
+ // todo: 如何显示价格表
const searchResultColumns = [
+ { key: 'ptype', dataIndex: ['info', 'product_type_id'], width: '6rem', title: t('products:ProductType'), render: (text, r) => productsTypesMapVal[text].label },
{ key: 'title', dataIndex: ['info', 'title'], width: '16rem', title: t('products:Title') },
{
title: t('products:price'),
- dataIndex: ['quotation', '0', 'value'],
+ dataIndex: ['quotation', '0', 'adult_cost'],
width: '10rem',
- render: (_, { quotation }) => `${quotation[0].value} ${quotation[0].currency} / ${quotation[0].unit_name}`, // todo: 成人 儿童
+ render: (_, { quotation }) => `${quotation[0].adult_cost} ${quotation[0].currency} / ${quotation[0].unit_name}`, // todo: 成人 儿童
},
{
key: 'action',
@@ -63,7 +65,7 @@ const NewAddonModal = ({ onPick, ...props }) => {
return (
<>
setOpen(false)} destroyOnClose>
@@ -119,14 +121,14 @@ const Extras = ({ productId, onChange, ...props }) => {
setExtrasData(prev => [].concat(prev, [item]));
// todo: 提交后端; 重复绑定同一个
const newSuccess = await addProductExtraAction({ travel_agency_id, id: productId, extras: [2] });
- newSuccess ? message.success(t('Success')) : message.error(t('Failed'));
+ newSuccess ? message.success(t('Action')+t('Success')) : message.error(t('Action')+t('Failed'));
await handleGetAgencyProductExtras();
}
const handleDelAddon = async (item) => {
// todo: 提交后端
const delSuccess = await delProductExtrasAction({ travel_agency_id, id: productId, extras: [2] });
- delSuccess ? message.success(t('Success')) : message.error(t('Failed'));
+ delSuccess ? message.success(t('Action')+t('Success')) : message.error(t('Action')+t('Failed'));
await handleGetAgencyProductExtras();
};
@@ -143,7 +145,7 @@ const Extras = ({ productId, onChange, ...props }) => {
dataIndex: ['quotation', '0', 'value'],
width: '10rem',
- render: (_, { quotation }) => `${quotation[0].value} ${quotation[0].currency} / ${quotation[0].unit_name}`, // todo: 成人 儿童
+ render: (_, { quotation }) => `${quotation[0].adult_cost} ${quotation[0].currency} / ${quotation[0].unit_name}`, // todo: 成人 儿童
},
// { title: t('products:Types'), dataIndex: 'age_type', width: '40%', },
{
@@ -151,7 +153,7 @@ const Extras = ({ productId, onChange, ...props }) => {
dataIndex: 'operation',
width: '4rem',
render: (_, r) => (
- handleDelAddon(r)} >
+ handleDelAddon(r)} okText={t('Yes')} >
diff --git a/src/views/products/Manage.jsx b/src/views/products/Manage.jsx
index 3e5d3b6..65cfc6b 100644
--- a/src/views/products/Manage.jsx
+++ b/src/views/products/Manage.jsx
@@ -49,10 +49,10 @@ function Index() {
const columns = [
{ title: t('products:Vendor'), key: 'vendor', dataIndex: 'travel_agency_name' },
- { title: t('products:CreatedBy'), key: 'created_by', dataIndex: 'created_by' },
+ { title: t('products:CreatedBy'), key: 'created_by', dataIndex: 'created_by_name' },
{ title: t('products:CreateDate'), key: 'create_date', dataIndex: 'create_date' },
{ title: t('products:AuState'), key: 'audit_state', dataIndex: 'audit_state' },
- { title: t('products:AuditedBy'), key: 'audited_by', dataIndex: 'audited_by' },
+ { title: t('products:AuditedBy'), key: 'audited_by', dataIndex: 'audited_by_name' },
{ title: t('products:AuditDate'), key: 'audit_date', dataIndex: 'audit_date' },
{
title: '',