From e9b7aec5219c997bc6acce03d232c99d83237ecb Mon Sep 17 00:00:00 2001 From: Lei OT Date: Fri, 21 Jun 2024 14:20:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BA=A7=E5=93=81=E7=AE=A1=E7=90=86:?= =?UTF-8?q?=20=E6=90=9C=E7=B4=A2+=E5=B9=B4=E4=BB=BD,=E7=8A=B6=E6=80=81;=20?= =?UTF-8?q?=E4=BA=A7=E5=93=81=E7=B1=BB=E5=9E=8B=E6=8E=92=E5=BA=8F;=20?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8=E9=A1=B5:=20=E6=88=90=E4=BA=BA,=E5=84=BF?= =?UTF-8?q?=E7=AB=A5=E4=BB=B7;=20=E8=AF=AD=E7=A7=8D=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/locales/en/products.json | 5 +- public/locales/zh/products.json | 7 +- src/components/SearchForm.jsx | 35 ++- src/components/SearchInput.jsx | 1 + .../{usePresets.js => useDatePresets.js} | 4 +- src/hooks/useLanguageSets.js | 14 ++ src/hooks/useProductsSets.js | 1 + src/main.jsx | 4 +- src/stores/Products/Index.js | 236 +----------------- src/views/products/Audit.jsx | 51 ++-- src/views/products/Index.jsx | 27 +- 11 files changed, 111 insertions(+), 274 deletions(-) rename src/hooks/{usePresets.js => useDatePresets.js} (91%) create mode 100644 src/hooks/useLanguageSets.js diff --git a/public/locales/en/products.json b/public/locales/en/products.json index 6033e89..b5e7694 100644 --- a/public/locales/en/products.json +++ b/public/locales/en/products.json @@ -7,6 +7,7 @@ "Attractions": "Attractions", "Meals": "Meals", "Extras": "Extras", + "Overtravel": "超公里", "Special": "Special" }, "auditState": { @@ -20,7 +21,7 @@ "New": "New", "Pending": "Pending", "Approved": "Approve", - "Rejected": "Rejecte", + "Rejected": "Reject", "Published": "Publish" }, "Status": "Status", @@ -42,6 +43,8 @@ "UseDates": "Use Dates", "Weekdays": "Weekdays", + "UseYear": "Use Year", + "AgeType": { "Type": "Age Type", "Adult": "Adult", diff --git a/public/locales/zh/products.json b/public/locales/zh/products.json index 01f7836..9f1f8b6 100644 --- a/public/locales/zh/products.json +++ b/public/locales/zh/products.json @@ -6,7 +6,8 @@ "Package": "包价线路", "Attractions": "景点", "Meals": "餐费", - "Extras": "附加", + "Extras": "附加项目", + "Overtravel": "超公里", "Special": "特殊项目" }, "auditState": { @@ -21,7 +22,7 @@ "Pending": "待审核", "Approved": "审核通过", "Rejected": "审核拒绝", - "Published": "发布上线" + "Published": "审核发布" }, "Status": "状态", "State": "状态", @@ -41,6 +42,8 @@ "UseDates": "使用日期", "Weekdays": "有效日/周X", + "UseYear": "年份", + "AgeType": { "Type": "人群", "Adult": "成人", diff --git a/src/components/SearchForm.jsx b/src/components/SearchForm.jsx index 6a53cac..a669294 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 usePresets from '@/hooks/usePresets'; +import useDatePresets from '@/hooks/useDatePresets'; import { useTranslation } from 'react-i18next'; import { fetchJSON } from '@/utils/request'; @@ -14,8 +14,8 @@ import AuditStateSelector from './AuditStateSelector'; //供应商列表 -export const fetchVendorList = async () => { - const { errcode, result } = await fetchJSON(`${HT_HOST}/Service_BaseInfoWeb/VendorList`) +export const fetchVendorList = async (q) => { + const { errcode, result } = await fetchJSON(`${HT_HOST}/Service_BaseInfoWeb/VendorList`, { q }) return errcode !== 0 ? [] : result } @@ -23,7 +23,7 @@ const { RangePicker } = DatePicker; const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => { const { t } = useTranslation(); - const presets = usePresets(); + const presets = useDatePresets(); const [formValues, setFormValues] = useFormStore((state) => [state.formValues, state.setFormValues]); const [formValuesToSub, setFormValuesToSub] = useFormStore((state) => [state.formValuesToSub, state.setFormValuesToSub]); const [form] = Form.useForm(); @@ -57,6 +57,9 @@ const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => { return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.value : ''; }, }, + 'year': [ + { key: 'year', transform: (arrVal) => (arrVal ? arrVal.format('YYYY') : '') }, + ], }; let dest = {}; const { dates, ...omittedValue } = values; @@ -165,15 +168,15 @@ function getFields(props) { 'referenceNo', 99, - + , fieldProps?.referenceNo?.col || 6 ), item( 'PNR', 99, - - + + , fieldProps?.PNR?.col || 4 ), @@ -208,11 +211,26 @@ function getFields(props) { /** * */ + item( + 'year', + 99, + + + , + fieldProps?.year?.col || 3 + ), item( 'agency', 99, - + , fieldProps?.agency?.col || 6 ), @@ -224,7 +242,6 @@ function getFields(props) { , fieldProps?.audit_state?.col || 3 ), - ]; baseChildren = baseChildren .map((x) => { diff --git a/src/components/SearchInput.jsx b/src/components/SearchInput.jsx index d816647..dcf2657 100644 --- a/src/components/SearchInput.jsx +++ b/src/components/SearchInput.jsx @@ -31,6 +31,7 @@ function DebounceSelect({ fetchOptions, debounceTimeout = 800, ...props }) { showSearch allowClear maxTagCount={1} + dropdownStyle={{width: '16rem'}} {...props} onSearch={debounceFetcher} notFoundContent={fetching ? : null} diff --git a/src/hooks/usePresets.js b/src/hooks/useDatePresets.js similarity index 91% rename from src/hooks/usePresets.js rename to src/hooks/useDatePresets.js index aa046e6..87397b9 100644 --- a/src/hooks/usePresets.js +++ b/src/hooks/useDatePresets.js @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import dayjs from "dayjs"; import { useTranslation } from 'react-i18next'; -const usePresets = () => { +const useDatePresets = () => { const [presets, setPresets] = useState([]); const { t, i18n } = useTranslation(); @@ -39,4 +39,4 @@ const usePresets = () => { return presets; } -export default usePresets; +export default useDatePresets; diff --git a/src/hooks/useLanguageSets.js b/src/hooks/useLanguageSets.js new file mode 100644 index 0000000..1dab4b1 --- /dev/null +++ b/src/hooks/useLanguageSets.js @@ -0,0 +1,14 @@ +export const useLanguageSets = () => { + const newData = [ + { key: '1', value: '1', label: 'English' }, + { key: '2', value: '2', label: 'Chinese (中文)' }, + { key: '3', value: '3', label: 'Japanese (日本語)' }, + { key: '4', value: '4', label: 'German (Deutsch)' }, + { key: '5', value: '5', label: 'French (Français)' }, + { key: '6', value: '6', label: 'Spanish (Español)' }, + { key: '7', value: '7', label: 'Russian (Русский)' }, + { key: '8', value: '8', label: 'Italian (Italiano)' }, + ]; + + return newData; +}; diff --git a/src/hooks/useProductsSets.js b/src/hooks/useProductsSets.js index 0994b3f..5f3a85b 100644 --- a/src/hooks/useProductsSets.js +++ b/src/hooks/useProductsSets.js @@ -27,6 +27,7 @@ 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.Car'), value: 'Car', key: 'Car' }, { label: t('products:type.Guide'), value: 'Guide', key: 'Guide' }, { label: t('products:type.Package'), value: 'D', key: 'D' }, diff --git a/src/main.jsx b/src/main.jsx index 3733462..a4556b5 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -69,8 +69,8 @@ const router = createBrowserRouter([ { path: "invoice/paid/detail/:flid",element:}, { path: "airticket",element:}, { path: "products",element:}, - { path: "products/:travel_agency_id/audit",element:}, - { path: "products/:travel_agency_id",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/Products/Index.js b/src/stores/Products/Index.js index 51d3010..a18f098 100644 --- a/src/stores/Products/Index.js +++ b/src/stores/Products/Index.js @@ -10,7 +10,8 @@ export const searchAgencyAction = async (param) => { return errcode !== 0 ? [] : result; }; export const getAgencyProductsAction = async (param) => { - const { errcode, result } = await fetchJSON(`${HT_HOST}/Service_BaseInfoWeb/travel_agency_products`, param); + const _param = { ...param, use_year: (param.use_year || '').replace('all', ''), audit_state: (param.audit_state || '').replace('all', '') }; + const { errcode, result } = await fetchJSON(`${HT_HOST}/Service_BaseInfoWeb/travel_agency_products`, _param); return errcode !== 0 ? { agency: {}, products: [] } : result; }; @@ -47,238 +48,10 @@ export const postProductsAudit = async (auditState, infoRow) => { const initialState = { loading: false, + searchValues: {}, agencyList: [], activeAgency: {}, - agencyProducts: groupBy([ - { - "info": { - "id": "640000198509289851", - "title": "如拉下完公", - "code": "grlkt", - "type": "Guide", - "audit_state": "1", - "create_date": "2022-01-13", - "created_by": "郝涛", - "travel_agency_id": "710000200712195349", - "travel_agency_name": "国得气验", - "lastedit_memo": "划百引程级门会需代领主属快。", - "remarks": "及决对金利低集小理电和按常如门。", - "duration": 2, - "duration_unit": "m", - "open_weekdays": "6", - "recommends_rate": 3, - "dept": 1, - "display_to_c": "2", - "km": 27, - "city_id": 77, - "city_name": "称命" - }, - "quotation": [ - { - "id": "21000020030611324X", - "value": 70, - "currency": "CNY", - "unit": "团", - "age_type": "儿童", - "group_size_min": 4, - "group_size_max": 4, - "use_dates_start": "2004-01-19", - "use_dates_end": "1990-03-10", - "weekdays": "4", - "audit_state": "ea pariatur", - "lastedit_memo": "sunt" - }, - { - "id": "610000197306240177", - "value": 86, - "currency": "CNY", - "unit": "人", - "age_type": "儿童", - "group_size_min": 6, - "group_size_max": 8, - "use_dates_start": "1996-12-16", - "use_dates_end": "1974-11-19", - "weekdays": "4", - "audit_state": "aliqua aute quis ipsum", - "lastedit_memo": "commodo adipisicing ea ipsum" - } - ], - "lgc_details": [ - { - "lgc": "mollit", - "title": "林运但", - "description": "学克信图走法因心委周说步将且文手越。", - "id": "35" - }, - { - "lgc": "et laborum", - "title": "备上引深量知量", - "description": "到听少文话包由北层中争二调原务越明在。", - "id": "74" - }, - { - "lgc": "minim velit", - "title": "安都始新", - "description": "取影压前手府要青白支大而。", - "id": "23" - } - ] - }, - { - "info": { - "id": "41000019901227754X", - "title": "据划京少国取", - "code": "ore", - "type": "Guide", - "audit_state": "2", - "create_date": "1979-01-31", - "created_by": "陆芳", - "travel_agency_id": "110000198612200137", - "travel_agency_name": "少平酸型", - "lastedit_memo": "八想军也装运知长示各院步济水。", - "remarks": "千改原统实专回列参目党却是样与后收。", - "duration": 3, - "duration_unit": "d", - "open_weekdays": "5", - "recommends_rate": 5, - "dept": 1, - "display_to_c": "2", - "km": 30, - "city_id": 62, - "city_name": "业入" - }, - "quotation": [ - { - "id": "37000019760525515X", - "value": 93, - "currency": "CNY", - "unit": "团", - "age_type": "成人", - "group_size_min": 7, - "group_size_max": 11, - "use_dates_start": "1992-11-22", - "use_dates_end": "1997-07-16", - "weekdays": "7", - "audit_state": "id nulla irure cupidatat", - "lastedit_memo": "quis aute reprehenderit consectetur" - }, - { - "id": "150000199506023175", - "value": 90, - "currency": "CNY", - "unit": "人", - "age_type": "儿童", - "group_size_min": 9, - "group_size_max": 10, - "use_dates_start": "2007-09-11", - "use_dates_end": "2013-07-27", - "weekdays": "5", - "audit_state": "commodo ad ut", - "lastedit_memo": "id anim incididunt" - } - ], - "lgc_details": [ - { - "lgc": "adipisicing elit Excepteur in", - "title": "很很结龙认", - "description": "事起复京长立然将采共层列工。", - "id": "43" - }, - { - "lgc": "dolore fugiat", - "title": "专中小", - "description": "示史想当集认点离反而原化精满并计前。", - "id": "28" - }, - { - "lgc": "sunt consectetur ea cillum", - "title": "他率带没", - "description": "节经厂面际是统表王活基书色活至是干验。", - "id": "83" - }, - { - "lgc": "incididunt labore fugiat", - "title": "精话西改", - "description": "须事金性别民学少拉个且须专需断连。", - "id": "97" - }, - { - "lgc": "dolore id", - "title": "文技话", - "description": "上任成条到则查支外很素给务府三。", - "id": "99" - } - ] - }, - { - "info": { - "id": "44000019990112280X", - "title": "节到和", - "code": "ixlmndtmz", - "type": "Meals", - "audit_state": "1", - "create_date": "2006-12-30", - "created_by": "易敏", - "travel_agency_id": "640000197111288408", - "travel_agency_name": "术备带走", - "lastedit_memo": "认队什教调问传改万消然声地全。", - "remarks": "属须厂几问总识看部群该克员方。", - "duration": 2, - "duration_unit": "m", - "open_weekdays": "6", - "recommends_rate": 3, - "dept": 2, - "display_to_c": "1", - "km": 13, - "city_id": 55, - "city_name": "铁以" - }, - "quotation": [ - { - "id": "13000019860219219X", - "value": 88, - "currency": "CNY", - "unit": "团", - "age_type": "儿童", - "group_size_min": 2, - "group_size_max": 4, - "use_dates_start": "1991-03-19", - "use_dates_end": "1974-03-13", - "weekdays": "3", - "audit_state": "officia voluptate ad adipisicing dolore", - "lastedit_memo": "Duis amet veniam enim" - }, - { - "id": "420000201706118123", - "value": 61, - "currency": "CNY", - "unit": "人", - "age_type": "儿童", - "group_size_min": 4, - "group_size_max": 10, - "use_dates_start": "1992-04-23", - "use_dates_end": "1970-07-19", - "weekdays": "5", - "audit_state": "commodo labore", - "lastedit_memo": "ullamco anim culpa do in" - } - ], - "lgc_details": [ - { - "lgc": "ut minim", - "title": "回等这意", - "description": "农满界个整千书得被写况空派会想头无。", - "id": "40" - }, - { - "lgc": "laborum id elit irure commodo", - "title": "增正数白养土子", - "description": "么划才共别程以元于族完难变。", - "id": "84" - } - ] - } -], row => row.info.type), + agencyProducts: {}, }; export const useProductsStore = create( devtools((set, get) => ({ @@ -287,6 +60,7 @@ export const useProductsStore = create( // state actions setLoading: loading => set({ loading }), + setSearchValues: searchValues => set({ searchValues }), setAgencyList: (agencyList) => set({ agencyList }), setActiveAgency: activeAgency => set({ activeAgency }), setAgencyProducts: agencyProducts => set({ agencyProducts }), diff --git a/src/views/products/Audit.jsx b/src/views/products/Audit.jsx index c548de2..e055cc3 100644 --- a/src/views/products/Audit.jsx +++ b/src/views/products/Audit.jsx @@ -7,15 +7,18 @@ import { useTranslation } from 'react-i18next'; import useProductsStore, { postProductsQuoteAudit } from '@/stores/Products/Index'; import { isEmpty } from '@/utils/commons'; -const Header = ({ title, agency, ...props}) => { +const Header = ({ title, agency, refresh, ...props}) => { const { t } = useTranslation(); - const [activeAgency, ] = useProductsStore((state) => [state.activeAgency]); + const [activeAgency, ] = useProductsStore((state) => [state.activeAgency, ]); const { message, notification } = App.useApp(); const handleAuditItem = (state, row) => { postProductsQuoteAudit(state, {id: row.id, travel_agency_id: activeAgency.travel_agency_id}) .then((json) => { if (json.errcode === 0) { - message.success('✔'); + message.success(json.errmsg); + if (typeof refresh === 'function') { + refresh(); + } } }) .catch((ex) => { @@ -34,8 +37,14 @@ const Header = ({ title, agency, ...props}) => { {/* */} {/* */} - + {/* */} + {/* todo: export */} @@ -43,9 +52,9 @@ const Header = ({ title, agency, ...props}) => { ); }; -const PriceTable = ({dataSource, loading}) => { +const PriceTable = ({dataSource,refresh}) => { const { t } = useTranslation('products'); - const [activeAgency, ] = useProductsStore((state) => [state.activeAgency]); + const [loading, activeAgency, ] = useProductsStore((state) => [state.loading, state.activeAgency, ]); const { message, notification } = App.useApp(); const stateMapVal = useProductsAuditStatesMapVal(); @@ -53,7 +62,10 @@ const PriceTable = ({dataSource, loading}) => { postProductsQuoteAudit(state, {id: row.id, travel_agency_id: activeAgency.travel_agency_id}) .then((json) => { if (json.errcode === 0) { - message.success('✔'); + message.success(json.errmsg); + if (typeof refresh === 'function') { + refresh(); + } } }) .catch((ex) => { @@ -68,11 +80,11 @@ const PriceTable = ({dataSource, loading}) => { const columns = [ { key: 'title', dataIndex: ['info', 'title'], title: t('Title'), onCell: (r, index) => ({ rowSpan: r.rowSpan }) }, - { key: 'value', title: t('Quotation'), render: (_, { value, currency, unit_name }) => `${value} ${currency} / ${unit_name}` }, + { 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: 'unit', title: t('Unit'), }, - { key: 'ageType', dataIndex: ['age_type'], title: t('AgeType.Type') }, { key: 'groupSize', dataIndex: ['group_size_min'], @@ -94,24 +106,24 @@ const PriceTable = ({dataSource, loading}) => { }, }, { - title: '', + title: '价格审核', key: 'action', render: (_, r) => r.audit_state_id <= 0 ?( - + ) : null, }, ]; - return r.id} />; + return
r.id} />; } /** * */ -const TypesPanels = () => { - const [loading, agencyProducts] = useProductsStore((state) => [state.loading, state.agencyProducts]); +const TypesPanels = (props) => { + const [loading, agencyProducts, ] = useProductsStore((state) => [state.loading, state.agencyProducts]); // console.log(agencyProducts); const productsTypes = useProductsTypes(); const [activeKey, setActiveKey] = useState([]); @@ -125,8 +137,9 @@ const TypesPanels = () => { ...ele, children: ( r.concat(c.quotation.map((q, i) => ({ ...q, info: c.info, rowSpan: i === 0 ? c.quotation.length : 0 }))), [])} + refresh={props.refresh} /> ), })); @@ -146,11 +159,11 @@ const TypesPanels = () => { } const Audit = ({ ...props }) => { - const { travel_agency_id } = useParams(); + const { travel_agency_id, use_year, audit_state } = useParams(); const [activeAgency, getAgencyProducts] = useProductsStore((state) => [state.activeAgency, state.getAgencyProducts]); const handleGetAgencyProducts = () => { - getAgencyProducts({ travel_agency_id }); + getAgencyProducts({ travel_agency_id, use_year, audit_state }); } useEffect(() => { @@ -161,9 +174,9 @@ const Audit = ({ ...props }) => { return ( <> - }> + }>
- +
); diff --git a/src/views/products/Index.jsx b/src/views/products/Index.jsx index 02d57ec..5a6385c 100644 --- a/src/views/products/Index.jsx +++ b/src/views/products/Index.jsx @@ -11,16 +11,18 @@ import { objectMapper } from '@/utils/commons'; function Index() { const { t } = useTranslation(); const [loading, agencyList, searchAgency] = useProductsStore((state) => [state.loading, state.agencyList, state.searchAgency]); + const [searchValues, setSearchValues] = useProductsStore((state) => [state.searchValues, state.setSearchValues]); const formValuesToSub = useFormStore(state => state.formValuesToSub); const handleSearchAgency = (formVal = undefined) => { const { starttime, endtime, ...param } = formVal || formValuesToSub; const searchParam = objectMapper(param, { agency: 'travel_agency_id', startdate: 'edit_date1', enddate: 'edit_date2' }); + setSearchValues(searchParam); searchAgency(searchParam); } useEffect(() => { - handleSearchAgency(); + // handleSearchAgency(); }, []); const showTotal = (total) => t('Table.Total', { total }); @@ -37,8 +39,8 @@ function Index() { key: 'action', render: (_, r) => ( - {t('Edit')} - {t('Audit')} + {t('Edit')} + {t('Audit')} ), }, @@ -47,19 +49,21 @@ function Index() { { handleSearchAgency(formVal); @@ -67,7 +71,14 @@ function Index() { />
-
+