diff --git a/README.md b/README.md index 38d3a02..1f070c7 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,12 @@ Global Highlights Hub 海外供应商平台 npm version [ | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git] npm version premajor --no-git-tag-version -npm version prerelease --no-git-tag-version +1.0.0 -> 2.0.0-0 +--preid beta | alpha | rc +npm version prerelease --preid beta --no-git-tag-version +2.0.0-0 -> 2.0.0-1 -> 2.0.0-2 ..n -> 2.0.0-n npm version patch --no-git-tag-version +2.0.0-n -> 2.0.0 "push:tag": "npm version patch && git.exe push --progress "origin" main:main" "push:tag": "npm version patch && git push origin master" diff --git a/package.json b/package.json index 79be5b1..ac1a9b2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "global-highlights-hub", "private": true, - "version": "2.0.0-0", + "version": "2.0.0-alpha.0", "type": "module", "scripts": { "dev": "vite", diff --git a/public/locales/en/products.json b/public/locales/en/products.json index 667c143..03bdb46 100644 --- a/public/locales/en/products.json +++ b/public/locales/en/products.json @@ -13,7 +13,7 @@ "EditComponents": { "info": "Product Information", "Quotation": "Quotation", - "Extras": "Add-on" + "Extras": "Components" }, "auditState": { "New": "New", @@ -49,7 +49,7 @@ "KM": "KM", "RecommendsRate": "RecommendsRate", "OpenWeekdays": "Open Weekdays", - "DisplayToC": "DisplayToC", + "DisplayToC": "Display To C", "Dept": "Dept", "productProject": "Product project", @@ -94,18 +94,22 @@ "Child": "Child" }, - "save":"save", - "edit":"edit", - "delete":"delete", - "cancel":"cancel", - "sureCancel":"Sure you want to cancel?", - "sureDelete":"Sure you want to delete?", - "CopyFormMsg": { "requiredVendor": "Please pick a target vendor", "requiredTypes": "Please select product types", "requiredDept": "Please pick a owner department" }, + "quotationTable": { + "Adult": "Adult", + "Child": "Child", + "Currency": "Currency", + "Unit": "Unit", + "GroupSize": "Group Size", + "UseDates": "Use Dates", + "Operation": "Operation", + "Weekdays": "Weekdays" + }, + "#": "#" } diff --git a/public/locales/zh/products.json b/public/locales/zh/products.json index 239af49..dd07133 100644 --- a/public/locales/zh/products.json +++ b/public/locales/zh/products.json @@ -13,7 +13,7 @@ "EditComponents": { "info": "产品信息", "Quotation": "报价", - "Extras": "附加项目" + "Extras": "绑定项目" }, "auditState": { "New": "新增", @@ -95,18 +95,22 @@ "Child": "儿童" }, - "save":"保存", - "edit":"编辑", - "delete":"删除", - "cancel":"取消", - "sureCancel": "确定取消?", - "sureDelete":"确定删除?", - "CopyFormMsg": { "requiredVendor": "请选择目标供应商", "requiredTypes": "请选择产品类型", "requiredDept": "请选择所属小组" }, + "quotationTable": { + "Adult": "成人", + "Child": "儿童", + "Currency": "币种", + "Unit": "类型", + "GroupSize": "人等", + "UseDates": "使用日期", + "Weekdays": "周末", + "Operation": "Operation" + }, + "#": "#" } diff --git a/src/components/DeptSelector.jsx b/src/components/DeptSelector.jsx index ab8911c..0524f0f 100644 --- a/src/components/DeptSelector.jsx +++ b/src/components/DeptSelector.jsx @@ -39,7 +39,6 @@ export const DeptSelector = ({show_all, isLeaf,...props}) => {
{ { 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:}, + { path: "products/edit",element:}, ] }, { diff --git a/src/pageSpy/index.jsx b/src/pageSpy/index.jsx index 0bfcd65..10c4c03 100644 --- a/src/pageSpy/index.jsx +++ b/src/pageSpy/index.jsx @@ -3,7 +3,7 @@ import { PROJECT_NAME } from '@/config'; export const loadPageSpy = (title) => { - if (window.$pageSpy) return + if (import.meta.env.DEV || window.$pageSpy) return const PageSpySrc = [ 'https://page-spy.mycht.cn/page-spy/index.min.js', diff --git a/src/stores/Products/Index.js b/src/stores/Products/Index.js index 02989f6..139d030 100644 --- a/src/stores/Products/Index.js +++ b/src/stores/Products/Index.js @@ -88,6 +88,7 @@ const initialState = { agencyList: [], activeAgency: {}, agencyProducts: {}, + editingProduct: {}, }; export const useProductsStore = create( devtools((set, get) => ({ @@ -100,6 +101,7 @@ export const useProductsStore = create( setAgencyList: (agencyList) => set({ agencyList }), setActiveAgency: (activeAgency) => set({ activeAgency }), setAgencyProducts: (agencyProducts) => set({ agencyProducts }), + setEditingProduct: (editingProduct) => set({ editingProduct }), reset: () => set(initialState), diff --git a/src/views/products/Audit.jsx b/src/views/products/Audit.jsx index 37d2bd5..d9ec03d 100644 --- a/src/views/products/Audit.jsx +++ b/src/views/products/Audit.jsx @@ -58,7 +58,9 @@ const Header = ({ title, agency, refresh, ...props }) => { const PriceTable = ({ productType, dataSource, refresh }) => { const { t } = useTranslation('products'); + const { travel_agency_id, use_year, audit_state } = useParams(); const [loading, activeAgency] = useProductsStore((state) => [state.loading, state.activeAgency]); + const [setEditingProduct] = useProductsStore((state) => [state.setEditingProduct]); const { message, notification } = App.useApp(); const stateMapVal = useProductsAuditStatesMapVal(); @@ -92,7 +94,10 @@ const PriceTable = ({ productType, dataSource, refresh }) => { }; const columns = [ - { 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 || '' }, + { key: 'title', dataIndex: ['info', 'title'], width: '16rem', title: t('Title'), onCell: (r, index) => ({ rowSpan: r.rowSpan, }), className: 'bg-white', render: (text, r) => { + const title = text || r.lgc_details?.['2']?.title || r.lgc_details?.['1']?.title || ''; + return setEditingProduct(r.info)}>{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}`)}` }, @@ -114,11 +119,12 @@ const PriceTable = ({ productType, dataSource, refresh }) => { key: 'state', title: t('State'), render: (_, r) => { - return {stateMapVal[`${r.audit_state_id}`]?.label}; + const stateCls = `text-${stateMapVal[`${r.audit_state_id}`]?.color} `; + return {stateMapVal[`${r.audit_state_id}`]?.label}; }, }, { - title: '价格审核', + title: '', key: 'action', render: (_, r) => r.audit_state_id <= 0 ? ( diff --git a/src/views/products/Detail.jsx b/src/views/products/Detail.jsx index 61d2cfa..cab7064 100644 --- a/src/views/products/Detail.jsx +++ b/src/views/products/Detail.jsx @@ -8,6 +8,7 @@ import { useProductsTypes } from '@/hooks/useProductsSets'; import Extras from './Detail/Extras'; import { groupBy } from '@/utils/commons'; import { useParams } from 'react-router-dom'; +import useProductsStore from '@/stores/Products/Index'; import { useHTLanguageSets } from '@/hooks/useHTLanguageSets'; import { useDefaultLgc } from '@/i18n/LanguageSwitcher'; import BatchImportPrice from './Detail/BatchImportPrice1'; @@ -37,6 +38,7 @@ function Detail() { const HTLanguageSets = useHTLanguageSets(); const { Search } = Input; + const [editingProduct, setEditingProduct] = useProductsStore((state) => [state.editingProduct, state.setEditingProduct]); const [expandedKeys, setExpandedKeys] = useState([]); const [searchValue, setSearchValue] = useState(''); @@ -51,53 +53,53 @@ function Detail() { const productProject = { "6": [], "B": [ - { code: "code", name: t('products:Code') }, - { code: "city_name", name: t('products:City') }, - { code: "km", name: t('products:KM') }, - { code: "remarks", name: t('products:Remarks') } + { code: "code", name: t('products:Code'), nameKey: 'products:Code' }, + { code: "city_name", name: t('products:City'), nameKey: 'products:City' }, + { code: "km", name: t('products:KM'), nameKey: 'products:KM' }, + { code: "remarks", name: t('products:Remarks'), nameKey: 'products:Remarks' } ], "J": [ - { code: "code", name: t('products:Code') }, - { code: "city_name", name: t('products:City') }, - { code: "recommends_rate", name: t('products:recommendationRate') }, - { code: "duration", name: t('products:Duration') }, - { code: "dept_name", name: t('products:Dept') }, - { code: "display_to_c", name: t('products:DisplayToC') }, - { code: "remarks", name: t('products:Remarks') }, + { code: "code", name: t('products:Code'), nameKey: 'products:Code' }, + { code: "city_name", name: t('products:City'), nameKey: 'products:City' }, + { code: "recommends_rate", name: t('products:recommendationRate'), nameKey: 'products:recommendationRate' }, + { code: "duration", name: t('products:Duration'), nameKey: 'products:Duration' }, + { code: "dept_name", name: t('products:Dept'), nameKey: 'products:Dept' }, + { code: "display_to_c", name: t('products:DisplayToC'), nameKey: 'products:DisplayToC' }, + { code: "remarks", name: t('products:Remarks'), nameKey: 'products:Remarks' }, ], "Q": [ - { code: "code", name: t('products:Code') }, - { code: "city_name", name: t('products:City') }, - { code: "recommends_rate", name: t('products:recommendationRate') }, - { code: "duration", name: t('products:Duration') }, - { code: "dept_name", name: t('products:Dept') }, - { code: "display_to_c", name: t('products:DisplayToC') }, - { code: "remarks", name: t('products:Remarks') }, + { code: "code", name: t('products:Code'), nameKey: 'products:Code' }, + { code: "city_name", name: t('products:City'), nameKey: 'products:City' }, + { code: "recommends_rate", name: t('products:recommendationRate'), nameKey: 'products:recommendationRate' }, + { code: "duration", name: t('products:Duration'), nameKey: 'products:Duration' }, + { code: "dept_name", name: t('products:Dept'), nameKey: 'products:Dept' }, + { code: "display_to_c", name: t('products:DisplayToC'), nameKey: 'products:DisplayToC' }, + { code: "remarks", name: t('products:Remarks'), nameKey: 'products:Remarks' }, ], "D": [ - { code: "code", name: t('products:Code') }, - { code: "city_name", name: t('products:City') }, - { code: "recommends_rate", name: t('products:recommendationRate') }, - { code: "duration", name: t('products:Duration') }, - { code: "dept_name", name: t('products:Dept') }, - { code: "display_to_c", name: t('products:DisplayToC') }, - { code: "remarks", name: t('products:Remarks') }, + { code: "code", name: t('products:Code'), nameKey: 'products:Code' }, + { code: "city_name", name: t('products:City'), nameKey: 'products:City' }, + { code: "recommends_rate", name: t('products:recommendationRate'), nameKey: 'products:recommendationRate' }, + { code: "duration", name: t('products:Duration'), nameKey: 'products:Duration' }, + { code: "dept_name", name: t('products:Dept'), nameKey: 'products:Dept' }, + { code: "display_to_c", name: t('products:DisplayToC'), nameKey: 'products:DisplayToC' }, + { code: "remarks", name: t('products:Remarks'), nameKey: 'products:Remarks' }, ], "7": [ - { code: "code", name: t('products:Code') }, - { code: "city_name", name: t('products:City') }, - { code: "recommends_rate", name: t('products:recommendationRate') }, - { code: "duration", name: t('products:Duration') }, - { code: "open_weekdays", name: t('products:OpenWeekdays') }, - { code: "remarks", name: t('products:Remarks') }, + { code: "code", name: t('products:Code'), nameKey: 'products:Code' }, + { code: "city_name", name: t('products:City'), nameKey: 'products:City' }, + { code: "recommends_rate", name: t('products:recommendationRate'), nameKey: 'products:recommendationRate' }, + { code: "duration", name: t('products:Duration'), nameKey: 'products:Duration' }, + { code: "open_weekdays", name: t('products:OpenWeekdays'), nameKey: 'products:OpenWeekdays' }, + { code: "remarks", name: t('products:Remarks'), nameKey: 'products:Remarks' }, ], "8": [ { code: "code", name: t('products:Code') }, { code: "city_name", name: t('products:City') }, ], "R": [ - { code: "code", name: t('products:Code') }, - { code: "city_name", name: t('products:City') }, + { code: "code", name: t('products:Code'), nameKey: 'products:Code' }, + { code: "city_name", name: t('products:City'), nameKey: 'products:City' }, ] } const [selectedCategory, setSelectedCategory] = useState(productProject.B); @@ -128,10 +130,12 @@ function Detail() { children: (productsData[type.value] || []).map(product => ({ title: product.info.title, key: `${type.value}-${product.info.id}`, + _raw: product, })) })); }; + const treeData = generateTreeData(productsTypes, groupedProducts); console.log("treeData", treeData) setTreeData(treeData); @@ -444,14 +448,16 @@ function Detail() { const editable = isEditing(record); return editable ? ( - handleSave(record.id)} style={{ marginRight: 8 }}>{t('products:save')} - {t('products:cancel')} + {/* handleSave(record.id)} style={{ marginRight: 8 }}>{t('Save')} */} + + + {/* {t('Cancel')} */} ) : ( - edit(record)} style={{ marginRight: 8 }}>{t('products:edit')} - handleDelete(record.id)}> - {t('products:delete')} + edit(record)} style={{ marginRight: 8 }}>{t('Edit')} + handleDelete(record.id)}> + {t('Delete')} ); @@ -559,6 +565,8 @@ function Detail() { setRemainderLanguage(HTLanguageSets.filter(item => item.key !== language.toString())) + setEditingProduct(node._raw); + let initialQuotationData = null; let infoData = null; let lgcDetailsData = null; @@ -616,8 +624,8 @@ function Detail() { return (
- - + +
供应商 }, + // { title: 供应商 }, { title: 综费 }, - { title: '文章列表' } + { title: editingProduct?.info?.title || t('New') } ]} /> } > -

{t('products:productProject')}

+

{t('products:EditComponents.info')}

{selectedCategory.map((item, index) => ( + {item.code === "duration" ? ( @@ -667,6 +676,7 @@ function Detail() {
{tags.map(tag => ( handleTagClick(tag)} color={tag === selectedTag ? 'blue' : undefined} @@ -711,12 +721,12 @@ function Detail() { /> - + {/* */} - + {/* */}

{t('products:supplierQuotation')}

- 批量添加 - - - - + + + + + {/* */} + + {/* */} - - - diff --git a/src/views/products/Detail/Extras.jsx b/src/views/products/Detail/Extras.jsx index 0f2d23c..e3b162c 100644 --- a/src/views/products/Detail/Extras.jsx +++ b/src/views/products/Detail/Extras.jsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useState, useSyncExternalStore } from 'react'; import { useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { App, Table, Button, Modal, Popconfirm } from 'antd'; @@ -24,11 +24,12 @@ const NewAddonModal = ({ onPick, ...props }) => { const onSearchProducts = async (values) => { const copyObject = cloneDeep(values); - const { starttime, endtime, ...param } = copyObject; + const { starttime, endtime, year, ...param } = copyObject; setSearchLoading(true); setSearchResult([]); // debug: audit_state: '1', - const result = await getAgencyProductsAction({ ...param, audit_state: '0', travel_agency_id, use_year }); + const search_year = year || use_year; + const result = await getAgencyProductsAction({ ...param, travel_agency_id, use_year: search_year, audit_state: '0', }); setSearchResult(result?.products || []); setSearchLoading(false); }; @@ -71,7 +72,7 @@ const NewAddonModal = ({ onPick, ...props }) => { setOpen(false)} destroyOnClose>