From 1084db4b96f0eb50193aee8102576d271521cb83 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Wed, 26 Jun 2024 12:06:10 +0800 Subject: [PATCH 01/12] =?UTF-8?q?=E6=90=9C=E7=B4=A2=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/SearchForm.jsx | 4 ++-- src/views/account/Management.jsx | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/SearchForm.jsx b/src/components/SearchForm.jsx index f6bad2c..9f985b9 100644 --- a/src/components/SearchForm.jsx +++ b/src/components/SearchForm.jsx @@ -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/views/account/Management.jsx b/src/views/account/Management.jsx index 6c2c323..737ff5a 100644 --- a/src/views/account/Management.jsx +++ b/src/views/account/Management.jsx @@ -243,6 +243,7 @@ function Management() { fieldProps: { dates: { label: t('group:ArrivalDate') }, }, + sort: { username: 1, realname: 2, dates: 3}, }} onSubmit={(err, formValues, filedsVal) => { console.info(formValues) From 6f446d852a4a5a6524654e37494564c3150cb332 Mon Sep 17 00:00:00 2001 From: Jimmy Liow Date: Wed, 26 Jun 2024 13:56:34 +0800 Subject: [PATCH 02/12] =?UTF-8?q?feat:=20=E7=99=BB=E9=99=86=E8=B6=85?= =?UTF-8?q?=E6=97=B6=E5=88=B7=E6=96=B0=E8=A6=81=E9=87=8D=E6=96=B0=E7=99=BB?= =?UTF-8?q?=E9=99=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/stores/Auth.js | 5 +++-- src/views/App.jsx | 16 +++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/stores/Auth.js b/src/stores/Auth.js index b462a1d..18dfc3b 100644 --- a/src/stores/Auth.js +++ b/src/stores/Auth.js @@ -130,7 +130,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() } } @@ -143,7 +143,8 @@ const useAuthStore = create(obervseLifecycle((set, get) => ({ loginTimeout: () => { const { tokenInterval } = get() - // TODO: 这里没有清理 token,刷新后可以正常使用系统 + const { clearStorage } = usingStorage() + clearStorage() clearInterval(tokenInterval) set(() => ({ tokenTimeout: true diff --git a/src/views/App.jsx b/src/views/App.jsx index 22d0737..2ac059d 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(() => { From d0a4453ce6d6a5ff2f7d3807a75b71c342376f95 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Wed, 26 Jun 2024 14:02:07 +0800 Subject: [PATCH 03/12] =?UTF-8?q?=E4=BA=A7=E5=93=81=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E7=9A=84=20i8n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/locales/en/common.json | 5 +++-- public/locales/en/products.json | 7 +++++++ public/locales/zh/common.json | 15 ++++++++------- public/locales/zh/products.json | 11 +++++++++-- src/components/SearchForm.jsx | 2 +- src/hooks/useDatePresets.js | 22 ++++++++++++++++++++-- src/views/products/Detail/Extras.jsx | 14 +++++++------- 7 files changed, 55 insertions(+), 21 deletions(-) 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 4997e31..79bb594 100644 --- a/public/locales/en/products.json +++ b/public/locales/en/products.json @@ -39,6 +39,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/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 55005ce..65cb019 100644 --- a/public/locales/zh/products.json +++ b/public/locales/zh/products.json @@ -37,11 +37,18 @@ "AuState": "审核状态", "CreatedBy": "提交人员", "CreateDate": "提交时间", - - "AuditedBy": "审核人员", "AuditDate": "审核时间", + "OpenHours": "游览时间", + "Duration": "游览时长", + "KM": "公里数", + "RecommendsRate": "推荐指数", + "OpenWeekdays": "周开放日", + "DisplayToC": "报价信显示", + "Dept": "小组", + + "productProject": "产品项目", "Code": "代码", "City": "城市", diff --git a/src/components/SearchForm.jsx b/src/components/SearchForm.jsx index 9f985b9..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'; 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/views/products/Detail/Extras.jsx b/src/views/products/Detail/Extras.jsx index b5e0f1b..4caf981 100644 --- a/src/views/products/Detail/Extras.jsx +++ b/src/views/products/Detail/Extras.jsx @@ -1,9 +1,9 @@ -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'; @@ -63,7 +63,7 @@ const NewAddonModal = ({ onPick, ...props }) => { return ( <> setOpen(false)} destroyOnClose> @@ -119,14 +119,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(); }; @@ -151,7 +151,7 @@ const Extras = ({ productId, onChange, ...props }) => { dataIndex: 'operation', width: '4rem', render: (_, r) => ( - handleDelAddon(r)} > + handleDelAddon(r)} okText={t('Yes')} > From 461263839bbf215a425fdf78b4ba1205580fa4ab Mon Sep 17 00:00:00 2001 From: Lei OT Date: Wed, 26 Jun 2024 14:50:51 +0800 Subject: [PATCH 04/12] =?UTF-8?q?=E4=BA=A7=E5=93=81=E7=AE=A1=E7=90=86:=20?= =?UTF-8?q?=E5=AE=A2=E6=9C=8D=E9=A6=96=E9=A1=B5:=20=E6=A0=B8=E5=AF=B9?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E7=BB=93=E6=9E=9C=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/products/Manage.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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: '', From bebb8c0a093c0fec50805352ff15c160bd2a975b Mon Sep 17 00:00:00 2001 From: Lei OT Date: Wed, 26 Jun 2024 14:55:06 +0800 Subject: [PATCH 05/12] =?UTF-8?q?feat:=20=E4=BB=8E=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E8=AF=AD=E8=A8=80=E8=8E=B7=E5=8F=96=E9=BB=98=E8=AE=A4=E7=9A=84?= =?UTF-8?q?HT=E8=AF=AD=E7=A7=8D=E7=BC=96=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/i18n/LanguageSwitcher.jsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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(() => { From fcef4c486ba4561455fa311cc1fe9b8635f2627b Mon Sep 17 00:00:00 2001 From: Jimmy Liow Date: Wed, 26 Jun 2024 15:28:52 +0800 Subject: [PATCH 06/12] =?UTF-8?q?feat:=20=E8=B4=A6=E5=8F=B7=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E7=AE=A1=E7=90=86=E5=A2=9E=E5=8A=A0=E4=B8=AD=E6=96=87?= =?UTF-8?q?=EF=BC=9B=E7=BB=9F=E4=B8=80=20userId=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/locales/zh/account.json | 21 ++++- src/stores/Auth.js | 4 +- src/views/App.jsx | 5 +- src/views/account/Management.jsx | 80 +++++++++---------- src/views/account/RoleList.jsx | 129 ++++++++++++++++--------------- 5 files changed, 133 insertions(+), 106 deletions(-) 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/src/stores/Auth.js b/src/stores/Auth.js index 18dfc3b..59c10c9 100644 --- a/src/stores/Auth.js +++ b/src/stores/Auth.js @@ -85,7 +85,7 @@ 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) @@ -95,7 +95,7 @@ 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) // loadPageSpy(`${json.Result.VName}-${json.Result.LoginName}`) diff --git a/src/views/App.jsx b/src/views/App.jsx index 2ac059d..7ac41a7 100644 --- a/src/views/App.jsx +++ b/src/views/App.jsx @@ -160,8 +160,9 @@ function App() { items: [...[ { label: {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' }, ] diff --git a/src/views/account/Management.jsx b/src/views/account/Management.jsx index 517f03f..8a498dc 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 => { @@ -189,7 +187,6 @@ function Management() { duration: 60, }) }) - console.log('ResetPassword') }, onCancel() { }, @@ -204,32 +201,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) => (
+ name='AccountForm' + form={accountForm} + layout='vertical' + size='large' + style={{ + maxWidth: 600, + }} + onFinish={onAccountFinish} + onFinishFailed={onAccountFailed} + autoComplete='off' + > {dom}
)} > - - - + + + -
- {t('account:management.tile')} + {t('account:accountList')} { @@ -316,7 +318,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) => (
+ name='RoleForm' + form={roleForm} + layout='vertical' + size='large' + style={{ + maxWidth: 600, + }} + onFinish={onRoleFinish} + onFinishFailed={onRoleFailed} + autoComplete='off' + > {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, From d8b141cda8d672080c9cbbcb5ebaa4fe953bd44a Mon Sep 17 00:00:00 2001 From: Jimmy Liow Date: Wed, 26 Jun 2024 15:50:02 +0800 Subject: [PATCH 07/12] =?UTF-8?q?feat:=20=E4=BD=BF=E7=94=A8=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=E4=BD=9C=E4=B8=BA=E9=BB=98=E8=AE=A4=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=EF=BC=9B=E5=88=A0=E9=99=A4=20GA=20=E6=95=B0=E6=8D=AE=E6=94=B6?= =?UTF-8?q?=E9=9B=86=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.jsx | 3 +-- src/stores/Auth.js | 4 ++-- src/views/App.jsx | 19 ++++++++----------- src/views/Index.jsx | 13 ------------- src/views/Login.jsx | 2 +- 5 files changed, 12 insertions(+), 29 deletions(-) delete mode 100644 src/views/Index.jsx diff --git a/src/main.jsx b/src/main.jsx index c6764aa..d3f498d 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"; @@ -60,7 +59,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: }, diff --git a/src/stores/Auth.js b/src/stores/Auth.js index 59c10c9..6e59ed9 100644 --- a/src/stores/Auth.js +++ b/src/stores/Auth.js @@ -85,7 +85,7 @@ const useAuthStore = create(obervseLifecycle((set, get) => ({ const { startTokenInterval, loadUserPermission } = get() const { setStorage } = usingStorage() - const { token: loginToken } = await fetchLoginToken(usr, pwd) + const { token: loginToken, WU_ID: userId } = await fetchLoginToken(usr, pwd) const userDetail = await fetchUserDetail(loginToken) await loadUserPermission(userId) @@ -95,7 +95,7 @@ const useAuthStore = create(obervseLifecycle((set, get) => ({ })) setStorage(KEY_LOGIN_TOKEN, loginToken) - setStorage(KEY_USER_ID, userDetail.LMI_SN) + setStorage(KEY_USER_ID, userId)//userDetail.LMI_SN) setStorage(KEY_TRAVEL_AGENCY_ID, userDetail.LMI_VEI_SN) appendRequestParams('token', loginToken) // loadPageSpy(`${json.Result.VName}-${json.Result.LoginName}`) diff --git a/src/views/App.jsx b/src/views/App.jsx index 7ac41a7..516c02d 100644 --- a/src/views/App.jsx +++ b/src/views/App.jsx @@ -60,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 => { @@ -71,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 ( - ); + ) } 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]) From 4b77aa689e8a7c9396533fdaf3ffade85365ffc0 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Wed, 26 Jun 2024 15:57:36 +0800 Subject: [PATCH 08/12] =?UTF-8?q?=E4=BA=A7=E5=93=81=E7=BC=BA=E5=B0=91?= =?UTF-8?q?=E8=8B=B1=E6=96=87=E5=90=8D=E7=A7=B0=E6=97=B6,=20=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E8=AF=AD=E7=A7=8D=E8=A1=A8=E4=B8=AD=E6=96=87=E5=90=8D?= =?UTF-8?q?=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/products/Audit.jsx | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/views/products/Audit.jsx b/src/views/products/Audit.jsx index 72a5742..2cbb8b1 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,7 +85,7 @@ const PriceTable = ({ dataSource, refresh }) => { }; const columns = [ - { key: 'title', dataIndex: ['info', 'title'], width: '16rem', title: t('Title'), onCell: (r, index) => ({ rowSpan: r.rowSpan }) }, + { 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 || '' }, { 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'), }, @@ -135,16 +137,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} /> ), From 81f1c9cea9e27ae394a81a2a67327220cb952d91 Mon Sep 17 00:00:00 2001 From: Jimmy Liow Date: Wed, 26 Jun 2024 16:39:23 +0800 Subject: [PATCH 09/12] fix: wu_id -> lmi_sn --- src/main.jsx | 8 +++++--- src/stores/Account.js | 18 +++++++++--------- src/stores/Auth.js | 10 +++++----- src/views/account/Management.jsx | 4 +--- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main.jsx b/src/main.jsx index d3f498d..054b935 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -44,6 +44,8 @@ const { loginToken, userId } = usingStorage() const initAppliction = async () => { if (isNotEmpty(loginToken)) { appendRequestParams('token', loginToken) + appendRequestParams('lmi_sn', userId) + } if (isNotEmpty(userId)) { @@ -70,14 +72,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:}, ] }, { 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 6e59ed9..8374151 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,7 +95,7 @@ const useAuthStore = create(obervseLifecycle((set, get) => ({ })) setStorage(KEY_LOGIN_TOKEN, loginToken) - setStorage(KEY_USER_ID, userId)//userDetail.LMI_SN) + setStorage(KEY_USER_ID, userDetail.LMI_SN) setStorage(KEY_TRAVEL_AGENCY_ID, userDetail.LMI_VEI_SN) appendRequestParams('token', loginToken) // loadPageSpy(`${json.Result.VName}-${json.Result.LoginName}`) diff --git a/src/views/account/Management.jsx b/src/views/account/Management.jsx index 8a498dc..676ed9a 100644 --- a/src/views/account/Management.jsx +++ b/src/views/account/Management.jsx @@ -106,7 +106,6 @@ function Management() { } const onAccountSeleted = async (account) => { - console.info(account) setTravelAgencyList([{ label: account.travelAgencyName, value: account.travelAgencyId @@ -154,7 +153,6 @@ function Management() { } const handleTravelAgencyChange = (newValue) => { - console.info(newValue) setCurrentTravelAgency(newValue) } @@ -222,8 +220,8 @@ function Management() { )} > + - Date: Wed, 26 Jun 2024 17:02:18 +0800 Subject: [PATCH 10/12] =?UTF-8?q?debug:=20=E6=90=9C=E7=B4=A2=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E7=BB=91=E5=AE=9A=E7=9A=84=E9=99=84=E5=8A=A0=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE;=20=E4=BB=B7=E6=A0=BCvalue=E6=94=B9=E4=B8=BAadult=5Fc?= =?UTF-8?q?ost;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/locales/en/products.json | 1 + public/locales/zh/products.json | 3 ++- src/hooks/useProductsSets.js | 33 ++++++++++++++++++---------- src/views/products/Audit.jsx | 4 ++-- src/views/products/Detail/Extras.jsx | 15 ++++++------- 5 files changed, 34 insertions(+), 22 deletions(-) diff --git a/public/locales/en/products.json b/public/locales/en/products.json index 6a62774..2a07ae5 100644 --- a/public/locales/en/products.json +++ b/public/locales/en/products.json @@ -1,4 +1,5 @@ { + "ProductType": "ProductType", "type": { "Experience": "Experience", "Car": "Transport Services", diff --git a/public/locales/zh/products.json b/public/locales/zh/products.json index 65cb019..1e1083b 100644 --- a/public/locales/zh/products.json +++ b/public/locales/zh/products.json @@ -1,4 +1,5 @@ { + "ProductType": "项目类型", "type": { "Experience": "综费", "Car": "车费", @@ -78,7 +79,7 @@ "GroupSize": "人等", "UseDates": "使用日期", - "Weekdays": "有效日/周X", + "Weekdays": "周末", "OnWeekdays": "周: ", "Unlimited": "不限", diff --git a/src/hooks/useProductsSets.js b/src/hooks/useProductsSets.js index 0dd63f7..5ee66d3 100644 --- a/src/hooks/useProductsSets.js +++ b/src/hooks/useProductsSets.js @@ -1,5 +1,7 @@ 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'; /** * 产品管理 相关的预设数据 @@ -89,17 +91,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个图 + 'C': [['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/views/products/Audit.jsx b/src/views/products/Audit.jsx index 2cbb8b1..ca38cfd 100644 --- a/src/views/products/Audit.jsx +++ b/src/views/products/Audit.jsx @@ -86,8 +86,8 @@ const PriceTable = ({ dataSource, refresh }) => { const columns = [ { 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 || '' }, - { 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: 'adult', title: t('AgeType.Adult'), render: (_, { adult_cost, currency, unit_name }) => `${adult_cost} ${currency} / ${unit_name}` }, + { key: 'child', title: t('AgeType.Child'), render: (_, { child_cost, currency, unit_name }) => `${child_cost} ${currency} / ${unit_name}` }, // {key: 'price', title: t('Currency'), }, // {key: 'currency', title: t('Currency'), }, // {key: 'unit', title: t('Unit'), }, diff --git a/src/views/products/Detail/Extras.jsx b/src/views/products/Detail/Extras.jsx index 4caf981..c22a2fb 100644 --- a/src/views/products/Detail/Extras.jsx +++ b/src/views/products/Detail/Extras.jsx @@ -24,27 +24,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_name'], width: '6rem', title: t('products:ProductType') }, { 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', @@ -143,7 +142,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%', }, { From cc2bf23bf5d4c0344afa6a3b765e1d158356bd7c Mon Sep 17 00:00:00 2001 From: Lei OT Date: Thu, 27 Jun 2024 11:14:52 +0800 Subject: [PATCH 11/12] =?UTF-8?q?feat:=20=E4=BA=A7=E5=93=81=E7=AE=A1?= =?UTF-8?q?=E7=90=86:=20`=E9=A4=90`=20=E7=B1=BB=E5=9E=8B=E4=BD=BF=E7=94=A8?= =?UTF-8?q?`R`=20;=20=E4=BC=98=E5=8C=96=E5=AE=A1=E6=A0=B8=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E4=BB=B7=E6=A0=BC=E8=A1=A8;=20=E9=99=84=E5=8A=A0?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E8=A1=A8=E6=98=BE=E7=A4=BA=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?;=20=E8=B6=85=E5=85=AC=E9=87=8CUltra=20Service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/locales/en/products.json | 10 ++-- public/locales/zh/products.json | 10 ++-- src/hooks/useProductsSets.js | 78 +++++++++++++++------------- src/views/products/Audit.jsx | 8 ++- src/views/products/Detail/Extras.jsx | 5 +- 5 files changed, 62 insertions(+), 49 deletions(-) diff --git a/public/locales/en/products.json b/public/locales/en/products.json index 2a07ae5..0e90423 100644 --- a/public/locales/en/products.json +++ b/public/locales/en/products.json @@ -1,5 +1,5 @@ { - "ProductType": "ProductType", + "ProductType": "Product Type", "type": { "Experience": "Experience", "Car": "Transport Services", @@ -8,8 +8,7 @@ "Attractions": "Attractions", "Meals": "Meals", "Extras": "Extras", - "Overtravel": "超公里", - "Special": "Special" + "UltraService": "Ultra Service" }, "EditComponents": { "info": "Product Information", @@ -30,6 +29,11 @@ "Rejected": "Reject", "Published": "Publish" }, + "PriceUnit": { + "0": "Person", + "1": "Group", + "title": "Price Unit" + }, "Status": "Status", "State": "State", diff --git a/public/locales/zh/products.json b/public/locales/zh/products.json index 1e1083b..8c592fb 100644 --- a/public/locales/zh/products.json +++ b/public/locales/zh/products.json @@ -3,13 +3,12 @@ "type": { "Experience": "综费", "Car": "车费", - "Guide": "导服", + "Guide": "导游", "Package": "包价线路", "Attractions": "景点", "Meals": "餐费", "Extras": "附加项目", - "Overtravel": "超公里", - "Special": "特殊项目" + "UltraService": "超公里" }, "EditComponents": { "info": "产品信息", @@ -30,6 +29,11 @@ "Rejected": "审核拒绝", "Published": "审核发布" }, + "PriceUnit": { + "0": "每人", + "1": "每团", + "title": "报价单位" + }, "Status": "状态", "State": "状态", diff --git a/src/hooks/useProductsSets.js b/src/hooks/useProductsSets.js index 5ee66d3..015fa8a 100644 --- a/src/hooks/useProductsSets.js +++ b/src/hooks/useProductsSets.js @@ -6,39 +6,39 @@ import { PERM_OVERSEA, PERM_AIR_TICKET, PERM_PRODUCTS_MANAGEMENT } from '@/confi /** * 产品管理 相关的预设数据 * 项目类型 -酒店预定 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 = () => { @@ -48,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([]); @@ -102,7 +106,7 @@ export const useProductsTypesFieldsets = (type) => { '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个图 - 'C': [['city_id',], ['description',]], + 'R': [['city_id',], ['description',]], '8': [[],[]], // todo: ? }; const thisTypeFieldset = (_type) => { diff --git a/src/views/products/Audit.jsx b/src/views/products/Audit.jsx index ca38cfd..9a23e0d 100644 --- a/src/views/products/Audit.jsx +++ b/src/views/products/Audit.jsx @@ -85,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 }), render: (text, r) => text || r.lgc_details?.['2']?.title || '' }, - { key: 'adult', title: t('AgeType.Adult'), render: (_, { adult_cost, currency, unit_name }) => `${adult_cost} ${currency} / ${unit_name}` }, - { key: 'child', title: t('AgeType.Child'), render: (_, { child_cost, currency, unit_name }) => `${child_cost} ${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', diff --git a/src/views/products/Detail/Extras.jsx b/src/views/products/Detail/Extras.jsx index c22a2fb..2ee8587 100644 --- a/src/views/products/Detail/Extras.jsx +++ b/src/views/products/Detail/Extras.jsx @@ -8,12 +8,15 @@ 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); @@ -37,7 +40,7 @@ const NewAddonModal = ({ onPick, ...props }) => { // todo: 如何显示价格表 const searchResultColumns = [ - { key: 'ptype', dataIndex: ['info', 'product_type_name'], width: '6rem', title: t('products:ProductType') }, + { 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'), From ff6071cd2fbf602d1fdcc9f078ce8eddb7cbc3c6 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Thu, 27 Jun 2024 11:20:02 +0800 Subject: [PATCH 12/12] =?UTF-8?q?wu=5Fid=20=E6=94=B9=20lmi=5Fsn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.jsx | 2 +- src/stores/Auth.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.jsx b/src/main.jsx index f7a0b42..02f2244 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -53,7 +53,7 @@ const initAppliction = async () => { } if (isNotEmpty(userId)) { - appendRequestParams('wu_id', userId) + appendRequestParams('lmi_sn', userId) await fireAuth() } } diff --git a/src/stores/Auth.js b/src/stores/Auth.js index 421d4cb..344e147 100644 --- a/src/stores/Auth.js +++ b/src/stores/Auth.js @@ -98,7 +98,7 @@ const useAuthStore = create(obervseLifecycle((set, get) => ({ 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() }, @@ -172,4 +172,4 @@ const useAuthStore = create(obervseLifecycle((set, get) => ({ }))) -export default useAuthStore \ No newline at end of file +export default useAuthStore