From 2ad323edbbba48902f4837a3971af366799bb247 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Thu, 27 Jun 2024 15:01:46 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=AE=A2=E6=9C=8D=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=E4=BB=B7=E6=A0=BC:=20=E8=B6=85=E5=85=AC=E9=87=8C+=E5=85=AC?= =?UTF-8?q?=E9=87=8C=E6=95=B0=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/products/Audit.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/views/products/Audit.jsx b/src/views/products/Audit.jsx index 9a23e0d..803507f 100644 --- a/src/views/products/Audit.jsx +++ b/src/views/products/Audit.jsx @@ -56,7 +56,7 @@ const Header = ({ title, agency, refresh, ...props }) => { ); }; -const PriceTable = ({ dataSource, refresh }) => { +const PriceTable = ({ productType, dataSource, refresh }) => { const { t } = useTranslation('products'); const [loading, activeAgency] = useProductsStore((state) => [state.loading, state.activeAgency]); const { message, notification } = App.useApp(); @@ -86,6 +86,7 @@ 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 || r.lgc_details?.['1']?.title || '' }, + ...(productType === 'B' ? [{ key: 'km', dataIndex: ['info', 'km'], title: t('KM')}] : []), { 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'), }, @@ -145,6 +146,7 @@ const TypesPanels = (props) => { children: ( r.concat( From 07b196fc6685383112a60698889cc46e7f75c880 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Thu, 27 Jun 2024 15:03:10 +0800 Subject: [PATCH 2/5] =?UTF-8?q?test:=20=E8=B0=83=E6=95=B4antd=E9=97=B4?= =?UTF-8?q?=E8=B7=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/App.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/views/App.jsx b/src/views/App.jsx index 3541d9b..b4fb2e2 100644 --- a/src/views/App.jsx +++ b/src/views/App.jsx @@ -90,6 +90,8 @@ function App() { theme={{ token: { colorPrimary: '#00b96b', + // "sizeStep": 3, + // "sizeUnit": 3, }, algorithm: theme.defaultAlgorithm, }}> From 80c1b986714463650f84d49b1b459efadd3d1c2b Mon Sep 17 00:00:00 2001 From: Lei OT Date: Fri, 28 Jun 2024 09:19:46 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E4=BA=A7=E5=93=81=E7=AE=A1=E7=90=86:=20?= =?UTF-8?q?=E9=99=84=E5=8A=A0=E9=A1=B9=E7=9B=AE=20=E6=B7=BB=E5=8A=A0/?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/stores/Products/Index.js | 8 ++++---- src/views/products/Detail/Extras.jsx | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/stores/Products/Index.js b/src/stores/Products/Index.js index fe2fb9f..a5c87cd 100644 --- a/src/stores/Products/Index.js +++ b/src/stores/Products/Index.js @@ -27,18 +27,18 @@ export const getAgencyProductsAction = async (param) => { }; /** - * todo: + * */ export const addProductExtraAction = async (body) => { - const { errcode, result } = await postJSON(`${HT_HOST}/products/extras`, body); + const { errcode, result } = await postJSON(`${HT_HOST}/Service_BaseInfoWeb/products_extras_add`, body); return errcode === 0 ? true : false; }; /** - * todo: + * */ export const delProductExtrasAction = async (body) => { - const { errcode, result } = await postJSON(`${HT_HOST}/products/extras/del`, body); + const { errcode, result } = await postJSON(`${HT_HOST}/Service_BaseInfoWeb/products_extras_del`, body); return errcode === 0 ? true : false; }; diff --git a/src/views/products/Detail/Extras.jsx b/src/views/products/Detail/Extras.jsx index 2ee8587..0f2d23c 100644 --- a/src/views/products/Detail/Extras.jsx +++ b/src/views/products/Detail/Extras.jsx @@ -3,7 +3,7 @@ import { useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { App, Table, Button, Modal, Popconfirm } from 'antd'; import { getAgencyProductExtrasAction, getAgencyProductsAction, addProductExtraAction, delProductExtrasAction } from '@/stores/Products/Index'; -import { cloneDeep } from '@/utils/commons'; +import { cloneDeep, pick } from '@/utils/commons'; import SearchForm from '@/components/SearchForm'; import RequireAuth from '@/components/RequireAuth'; @@ -46,7 +46,7 @@ const NewAddonModal = ({ onPick, ...props }) => { title: t('products:price'), dataIndex: ['quotation', '0', 'adult_cost'], width: '10rem', - render: (_, { quotation }) => `${quotation[0].adult_cost} ${quotation[0].currency} / ${quotation[0].unit_name}`, // todo: 成人 儿童 + render: (_, { quotation }) => `${quotation[0].adult_cost} ${quotation[0].currency} / ${quotation[0].unit_name}`, }, { key: 'action', @@ -120,15 +120,15 @@ const Extras = ({ productId, onChange, ...props }) => { const handleNewAddOn = async (item) => { setExtrasData(prev => [].concat(prev, [item])); // todo: 提交后端; 重复绑定同一个 - const newSuccess = await addProductExtraAction({ travel_agency_id, id: productId, extras: [2] }); - newSuccess ? message.success(t('Action')+t('Success')) : message.error(t('Action')+t('Failed')); + const _item = pick(item.info, ['id', 'title', 'code']); + const newSuccess = await addProductExtraAction({ travel_agency_id, id: productId, extras: [_item] }); + newSuccess ? message.success(`${t('Success')}`) : message.error(`${t('Failed')}`); await handleGetAgencyProductExtras(); } const handleDelAddon = async (item) => { - // todo: 提交后端 - const delSuccess = await delProductExtrasAction({ travel_agency_id, id: productId, extras: [2] }); - delSuccess ? message.success(t('Action')+t('Success')) : message.error(t('Action')+t('Failed')); + const delSuccess = await delProductExtrasAction({ travel_agency_id, id: productId, extras: [item.info.id] }); + delSuccess ? message.success(`${t('Success')}`) : message.error(`${t('Failed')}`); await handleGetAgencyProductExtras(); }; From 579689f3e028a74c27aa8a773745c9c188390073 Mon Sep 17 00:00:00 2001 From: Jimmy Liow Date: Fri, 28 Jun 2024 11:37:56 +0800 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20=E5=88=A0=E9=99=A4=20GA=20JS?= =?UTF-8?q?=EF=BC=9B=E8=8F=9C=E5=8D=95=E6=98=BE=E7=A4=BA=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=A7=93=E5=90=8D=EF=BC=9B=E7=94=A8=E6=88=B7=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=A7=93=E5=90=8D=E5=92=8C=E8=A7=92=E8=89=B2?= =?UTF-8?q?=EF=BC=9BAuth=20=E5=A2=9E=E5=8A=A0=E5=88=9D=E5=A7=8B=E6=8C=87?= =?UTF-8?q?=EF=BC=8C=E7=BB=9F=E4=B8=80=E7=99=BB=E9=99=86=E5=92=8C=E8=B6=85?= =?UTF-8?q?=E6=97=B6=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 7 ----- public/locales/en/common.json | 1 + public/locales/zh/common.json | 1 + src/stores/Account.js | 4 ++- src/stores/Auth.js | 45 +++++++++++--------------------- src/views/App.jsx | 4 +-- src/views/account/Management.jsx | 6 +++-- src/views/account/Profile.jsx | 5 ++-- 8 files changed, 29 insertions(+), 44 deletions(-) diff --git a/index.html b/index.html index 83cb221..c316114 100644 --- a/index.html +++ b/index.html @@ -14,13 +14,6 @@ 100%{-webkit-transform:translate(150px)} } - -
diff --git a/public/locales/en/common.json b/public/locales/en/common.json index a513e2a..85155ad 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -22,6 +22,7 @@ "Login": "Login", "Username": "Username", + "Realname": "Realname", "Password": "Password", "ChangePassword": "Change password", diff --git a/public/locales/zh/common.json b/public/locales/zh/common.json index 59c417e..1ffb8ae 100644 --- a/public/locales/zh/common.json +++ b/public/locales/zh/common.json @@ -22,6 +22,7 @@ "Login": "登录", "Username": "账号", + "Realname": "姓名", "Password": "密码", "ChangePassword": "修改密码", diff --git a/src/stores/Account.js b/src/stores/Account.js index a57b6db..47abc92 100644 --- a/src/stores/Account.js +++ b/src/stores/Account.js @@ -1,5 +1,6 @@ import { create } from 'zustand' import { fetchJSON, postForm } from '@/utils/request' +import { isEmpty } from '@/utils/commons' import { HT_HOST } from "@/config" import { usingStorage } from '@/hooks/usingStorage' @@ -147,6 +148,7 @@ const useAccountStore = create((set, get) => ({ const resultArray = await fetchAccountList(searchParams) + console.info(resultArray) const mapAccoutList = resultArray.map((r) => { return { accountId: r.wu_id, @@ -160,7 +162,7 @@ const useAccountStore = create((set, get) => ({ travelAgencyId: r.travel_agency_id, disabled: r.wu_limitsign, // 数据库支持逗号分隔多角色(5,6,7),目前界面只需单个。 - roleId: parseInt(r.roles), + roleId: isEmpty(r.roles) ? 0 : parseInt(r.roles), role: r.roles_name, } }) diff --git a/src/stores/Auth.js b/src/stores/Auth.js index 56e7a80..cc47621 100644 --- a/src/stores/Auth.js +++ b/src/stores/Auth.js @@ -43,8 +43,18 @@ async function fetchLastRequet() { return errcode !== 0 ? {} : result } +const initialState = { + tokenInterval: null, + tokenTimeout: true, + loginStatus: 0, + defaltRoute: '', + permissionList: [] +} + const useAuthStore = create(lifecycleware((set, get) => ({ + ...initialState, + onAuth: async () => { const { startTokenInterval, loadUserPermission } = get() const { userId, loginToken } = usingStorage() @@ -98,16 +108,11 @@ const useAuthStore = create(lifecycleware((set, get) => ({ const { clearStorage } = usingStorage() clearStorage() clearInterval(tokenInterval) - set(() => ({ - defaultRoute: '/', - loginStatus: 0, - tokenInterval: null, - tokenTimeout: true - })) + set(initialState) }, startTokenInterval: () => { - const { loginTimeout } = get() + const { logout } = get() async function checkTokenTimeout() { const { LastReqDate } = await fetchLastRequet() @@ -116,27 +121,17 @@ const useAuthStore = create(lifecycleware((set, get) => ({ const diffTime = now.getTime() - lastReqDate.getTime() const diffHours = diffTime/1000/60/60 if (diffHours > 1) { - loginTimeout() + logout() } } - const interval = setInterval(() => checkTokenTimeout(), 1000*60*20) + const interval = setInterval(() => checkTokenTimeout(), 1000*60*10) set(() => ({ tokenInterval: interval })) }, - loginTimeout: () => { - const { tokenInterval } = get() - const { clearStorage } = usingStorage() - clearStorage() - clearInterval(tokenInterval) - set(() => ({ - tokenTimeout: true - })) - }, - - // 迁移到 Account.js + // TODO: 迁移到 Account.js changeUserPassword: (password, newPassword) => { const { userId } = usingStorage() const formData = new FormData(); @@ -174,16 +169,6 @@ const useAuthStore = create(lifecycleware((set, get) => ({ }) }, - tokenInterval: null, - - tokenTimeout: false, - - loginStatus: 0, - - defaltRoute: '', - - permissionList: [], - }))) export default useAuthStore \ No newline at end of file diff --git a/src/views/App.jsx b/src/views/App.jsx index 22b385d..564e93e 100644 --- a/src/views/App.jsx +++ b/src/views/App.jsx @@ -48,6 +48,7 @@ function App() { .then(u => { setUserDetail({ username: u.LoginName, + realname: u.real_name, travelAgencyName: u.VName, }) }) @@ -157,7 +158,6 @@ function App() { items: [...[ { label: {t('ChangePassword')}, key: '0' }, { label: {t('Profile')}, key: '1' }, - { 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' }, @@ -169,7 +169,7 @@ function App() { > e.preventDefault()}> - {userDetail?.username} + {userDetail?.realname} diff --git a/src/views/account/Management.jsx b/src/views/account/Management.jsx index 94d1a30..7e0d236 100644 --- a/src/views/account/Management.jsx +++ b/src/views/account/Management.jsx @@ -81,13 +81,15 @@ function Management() { useEffect(() => { fetchRoleList() .then((roleList) => { - setRoleAllList(roleList.map(r => { + const roleListMap = roleList.map(r => { return { value: r.role_id, label: r.role_name, disabled: r.role_id === 1 } - })) + }) + roleListMap.unshift({ value: 0, label: '未设置', disabled: true }); + setRoleAllList(roleListMap) }) }, []) diff --git a/src/views/account/Profile.jsx b/src/views/account/Profile.jsx index 1691081..ce8b3e1 100644 --- a/src/views/account/Profile.jsx +++ b/src/views/account/Profile.jsx @@ -15,7 +15,8 @@ function Profile() { .then(json => { setUserDetail({ username: json.LoginName, - telephone: json.LkPhone, + realname: json.real_name, + rolesName: json.roles_name, emailAddress: json.LMI_listmail, travelAgencyName: json.VName, }) @@ -28,7 +29,7 @@ function Profile() { {userDetail?.username} - {userDetail?.telephone} + {userDetail?.realname}({userDetail?.rolesName}) {userDetail?.emailAddress} {userDetail?.travelAgencyName} From 42cb1d583febd6e986c53e369c2f00fc86f29033 Mon Sep 17 00:00:00 2001 From: Lei OT Date: Fri, 28 Jun 2024 14:15:14 +0800 Subject: [PATCH 5/5] style: products Audit --- src/assets/global.css | 3 +++ src/hooks/useProductsSets.js | 2 +- src/views/products/Audit.jsx | 14 +++++++++++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/assets/global.css b/src/assets/global.css index ca0ad13..65679f1 100644 --- a/src/assets/global.css +++ b/src/assets/global.css @@ -21,3 +21,6 @@ justify-content: center; width: 100%; } +.ant-table-wrapper.border-collapse table { + border-collapse: collapse; +} diff --git a/src/hooks/useProductsSets.js b/src/hooks/useProductsSets.js index 015fa8a..2917489 100644 --- a/src/hooks/useProductsSets.js +++ b/src/hooks/useProductsSets.js @@ -51,10 +51,10 @@ export const useProductsTypes = () => { { 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: 'R', key: 'R' }, { label: t('products:type.Extras'), value: '8', key: '8' }, + { label: t('products:type.Package'), value: 'D', key: 'D' }, // 包价线路 ]; setTypes(newData); }, [i18n.language]); diff --git a/src/views/products/Audit.jsx b/src/views/products/Audit.jsx index 803507f..825f956 100644 --- a/src/views/products/Audit.jsx +++ b/src/views/products/Audit.jsx @@ -84,8 +84,15 @@ const PriceTable = ({ productType, dataSource, refresh }) => { }); }; + const rowStyle = (r, tri) => { + const trCls = tri%2 !== 0 ? ' bg-stone-50' : ''; + const [infoI, quoteI] = r.rowSpanI; + const bigTrCls = quoteI === 0 && tri !== 0 ? 'border-collapse border-double border-0 border-t-4 border-stone-300' : ''; + return [trCls, bigTrCls].join(' '); + }; + 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 || r.lgc_details?.['1']?.title || '' }, + { key: 'title', dataIndex: ['info', 'title'], width: '16rem', title: t('Title'), onCell: (r, index) => ({ rowSpan: r.rowSpan, }), className: 'bg-white', render: (text, r) => text || r.lgc_details?.['2']?.title || r.lgc_details?.['1']?.title || '' }, ...(productType === 'B' ? [{ key: 'km', dataIndex: ['info', 'km'], title: t('KM')}] : []), { 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}`)}` }, @@ -122,7 +129,7 @@ const PriceTable = ({ productType, dataSource, refresh }) => { ) : null, }, ]; - return r.id} />; + return
r.id} />; }; /** @@ -148,7 +155,7 @@ const TypesPanels = (props) => { // loading={loading} productType={ele.value} dataSource={agencyProducts[ele.value].reduce( - (r, c) => + (r, c, ri) => r.concat( c.quotation.map((q, i) => ({ ...q, @@ -160,6 +167,7 @@ const TypesPanels = (props) => { info: c.info, lgc_details: c.lgc_details.reduce((rlgc, clgc) => ({...r, [clgc.lgc]: clgc}), {}), rowSpan: i === 0 ? c.quotation.length : 0, + rowSpanI: [ri, i], })) ), []