diff --git a/src/hooks/useProductsSets.js b/src/hooks/useProductsSets.js index 01cb409..850fca9 100644 --- a/src/hooks/useProductsSets.js +++ b/src/hooks/useProductsSets.js @@ -89,7 +89,7 @@ export const useProductsAuditStates = () => { return types; }; -export const useProductsAuditStatesMapVal = (value) => { +export const useProductsAuditStatesMapVal = () => { const stateSets = useProductsAuditStates(); const stateMapVal = stateSets.reduce((r, c) => ({ ...r, [`${c.value}`]: c }), {}); return stateMapVal; diff --git a/src/views/products/Detail/Header.jsx b/src/views/products/Detail/Header.jsx index 04c3f12..4d0f0cf 100644 --- a/src/views/products/Detail/Header.jsx +++ b/src/views/products/Detail/Header.jsx @@ -7,24 +7,18 @@ import { useTranslation } from "react-i18next"; import useProductsStore, { postAgencyProductsAuditAction, postAgencyAuditAction, - getAgencyAllExtrasAction, } from "@/stores/Products/Index"; import { isEmpty, objectMapper } from "@/utils/commons"; import useAuthStore from "@/stores/Auth"; import RequireAuth from "@/components/RequireAuth"; -// import PrintContractPDF from './PrintContractPDF'; import { PERM_PRODUCTS_OFFER_AUDIT, PERM_PRODUCTS_OFFER_PUT } from "@/config"; import dayjs from "dayjs"; import VendorSelector from "@/components/VendorSelector"; import AuditStateSelector from "@/components/AuditStateSelector"; import { usingStorage } from "@/hooks/usingStorage"; -import AgencyContract from "../Print/AgencyContract"; -// import AgencyContract from "../Print/AgencyContract_v0903"; -import { saveAs } from "file-saver"; -import { Packer } from "docx"; - import AgencyPreview from "../Print/AgencyPreview"; +import ExportDocxBtn from "../Print/ExportDocxBtn"; const Header = ({ refresh, ...props }) => { const location = useLocation(); @@ -44,7 +38,6 @@ const Header = ({ refresh, ...props }) => { state.setSwitchParams, ]); // const [activeAgencyState] = useProductsStore((state) => [state.activeAgencyState]); - const [agencyProducts] = useProductsStore((state) => [state.agencyProducts]); const stateMapVal = useProductsAuditStatesMapVal(); const { message, notification } = App.useApp(); const navigate = useNavigate(); @@ -58,10 +51,6 @@ const Header = ({ refresh, ...props }) => { yearOptions.push({ label: i, value: i }); } - const { getRemarkList } = useProductsStore((selector) => ({ - getRemarkList: selector.getRemarkList, - })); - const [param, setParam] = useState({ pick_year: baseYear, pick_agency: travel_agency_id, @@ -168,31 +157,6 @@ const Header = ({ refresh, ...props }) => { }); }; - const handleDownload = async () => { - // await refresh(); - const agencyExtras = await getAgencyAllExtrasAction(switchParams); - const remarks = await getRemarkList() - const remarksMappedByType = remarks.reduce((r, v) => ({...r, [v.product_type_id]: v}), {}); - const documentCreator = new AgencyContract(); - const doc = documentCreator.create([ - switchParams, - activeAgency, - agencyProducts, - agencyExtras, - // remarks, - remarksMappedByType, - ]); - - const _d = dayjs().format("YYYYMMDD_HH.mm.ss.SSS"); // Date.now().toString(32) - const _state = pickAuditState.value ? pickAuditState.label : ''; - Packer.toBlob(doc).then((blob) => { - saveAs( - blob, - `${activeAgency.travel_agency_name}${pickYear}年地接合同-${_state}-${_d}.docx` - ); - }); - }; - return (
@@ -241,14 +205,7 @@ const Header = ({ refresh, ...props }) => {
- {/* */} - {/* todo: export, 审核完成之后才能导出 */} - - - {/* */} - + {/* {activeAgencyState === 0 && ( */} <> diff --git a/src/views/products/Print/AgencyPreview.jsx b/src/views/products/Print/AgencyPreview.jsx index e3e7337..058ac92 100644 --- a/src/views/products/Print/AgencyPreview.jsx +++ b/src/views/products/Print/AgencyPreview.jsx @@ -1,18 +1,24 @@ import { useState } from 'react'; -import { useParams } from 'react-router-dom'; +import { useParams, Link } from 'react-router-dom'; import { Button, Drawer, Card, Table } from 'antd'; import { useTranslation } from 'react-i18next'; import useProductsStore, { getAgencyAllExtrasAction } from '@/stores/Products/Index'; import { useProductsTypes, formatGroupSize } from '@/hooks/useProductsSets'; import { chunkBy, splitTable_6, splitTable_7, splitTable_8, splitTable_B, splitTable_D, splitTable_J, splitTable_Q, splitTable_R } from '@/hooks/useProductsQuotationFormat'; -import { groupBy } from '@/utils/commons'; +import { groupBy, isNotEmpty } from '@/utils/commons'; +import useAuthStore from '@/stores/Auth'; +import { PERM_PRODUCTS_MANAGEMENT, PERM_PRODUCTS_OFFER_AUDIT, PERM_PRODUCTS_OFFER_PUT } from '@/config'; +import ExportDocxBtn from './ExportDocxBtn'; const AgencyPreview = ({ params, ...props }) => { + const isPermitted = useAuthStore(state => state.isPermitted); + const { t } = useTranslation(); const { travel_agency_id, use_year } = params; const productsTypes = useProductsTypes(); const [agencyProducts] = useProductsStore((state) => [state.agencyProducts]); + const [setEditingProduct] = useProductsStore((state) => [state.setEditingProduct]); const [previewMode, setPreviewMode] = useState(false); const [tables, setTables] = useState([]); @@ -52,6 +58,27 @@ const AgencyPreview = ({ params, ...props }) => { const cityRowHighlights = (record) => (record.info.isCityRow ? 'font-bold text-center ' : '') + const renderTitle = (text, r) => { + const title = text || r.lgc_details?.['2']?.title || r.lgc_details?.['1']?.title || ''; + const itemLink = isPermitted(PERM_PRODUCTS_OFFER_AUDIT) + ? `/products/${travel_agency_id}/${use_year}/all/edit` + : isPermitted(PERM_PRODUCTS_OFFER_PUT) + ? `/products/edit` + : ''; + return ( +
+ {isNotEmpty(itemLink) && (r.info?.isCityRow !== true) ? ( +
setEditingProduct({ info: r.info })}> + {title} +
+ ) : ( + title + )} + {r.info.id} +
+ ); + }; + const renderTable_6 = () => { // console.log('666666'); if (!('6' in agencyProducts)) { @@ -525,19 +552,28 @@ const AgencyPreview = ({ params, ...props }) => {
{(SS || []).length === 1 ? (
- {SS[0].unit_id === '0' ? '' : `${formatGroupSize(SS[0].group_size_min, SS[0].group_size_max, true)}, ${SS[0].unit_name}`} + {SS[0].unit_id === '0' && SS[0].group_size_min <= 1 && SS[0].group_size_max === 1000 ? ( + + ) : ( + <> + {formatGroupSize(SS[0].group_size_min, SS[0].group_size_max, true)} + {SS[0].unit_name} + + )} {SS[0].adult_cost} {SS[0].child_cost}
) : ( - (SS || []).map((ele, qi) => -
-
- {formatGroupSize(ele.group_size_min, ele.group_size_max, true)}, {ele.unit_name} - {ele.adult_cost} - {ele.child_cost} + (SS || []).map((ele, qi) => ( +
+
+ {formatGroupSize(ele.group_size_min, ele.group_size_max, true)} + {ele.unit_name} + {ele.adult_cost} + {ele.child_cost} +
-
) + )) )}
), @@ -563,11 +599,12 @@ const AgencyPreview = ({ params, ...props }) => {
- {ele.rows.map((d, di) => ( -
- {d.use_dates_start.replace(`${use_year}.`, '')}~{d.use_dates_end.replace(`${use_year}.`, '')} -
- ))}
+ {ele.rows.map((d, di) => ( +
+ {d.use_dates_start.replace(`${use_year}.`, '')}~{d.use_dates_end.replace(`${use_year}.`, '')} +
+ ))} +
{ele.adult_cost} {ele.child_cost}
@@ -576,10 +613,23 @@ const AgencyPreview = ({ params, ...props }) => {
), }, - { title: '特殊项目', width: '9rem', key: 'extras', render: (_, r) => { - const _extras = extras[r.info.id] || []; - return (
{_extras.map(e =>
{e.info.product_title}【{e.info.product_type_name}】
)}
); - }}, + { + title: '特殊项目', + width: '9rem', + key: 'extras', + render: (_, r) => { + const _extras = extras[r.info.id] || []; + return ( +
+ {_extras.map((e) => ( +
+ {e.info.product_title}【{e.info.product_type_name}】 +
+ ))} +
+ ); + }, + }, ]} /> @@ -762,10 +812,19 @@ const AgencyPreview = ({ params, ...props }) => { - setPreviewMode(false)} > -
- {renderTableByType(tables)} -
+ +
+ {t('Preview')} + +
+ + } + width={'70%'} + open={previewMode} + onClose={() => setPreviewMode(false)}> +
{renderTableByType(tables)}
); diff --git a/src/views/products/Print/ExportDocxBtn.jsx b/src/views/products/Print/ExportDocxBtn.jsx new file mode 100644 index 0000000..b8ad1f6 --- /dev/null +++ b/src/views/products/Print/ExportDocxBtn.jsx @@ -0,0 +1,59 @@ +import { Button } from 'antd'; +import { useProductsAuditStatesMapVal } from '@/hooks/useProductsSets'; +import { useTranslation } from 'react-i18next'; +import useProductsStore, { getAgencyAllExtrasAction } from '@/stores/Products/Index'; +import RequireAuth from '@/components/RequireAuth'; +import { PERM_PRODUCTS_OFFER_AUDIT } from '@/config'; +import dayjs from 'dayjs'; + +import AgencyContract from '../Print/AgencyContract'; +import { saveAs } from 'file-saver'; +import { Packer } from 'docx'; +import { isEmpty } from '@/utils/commons'; + +const ExportDocxBtn = ({ params = { travel_agency_id: '', use_year: '', audit_state: '' }, ...props }) => { + const { t } = useTranslation(); + const [agencyProducts] = useProductsStore((state) => [state.agencyProducts]); + const [activeAgency] = useProductsStore((state) => [state.activeAgency]); + const { travel_agency_id, use_year, audit_state } = params; + + const auditStatesMap = useProductsAuditStatesMapVal(); + + const { getRemarkList } = useProductsStore((selector) => ({ + getRemarkList: selector.getRemarkList, + })); + const handleDownload = async () => { + // await refresh(); + const agencyExtras = await getAgencyAllExtrasAction(params); + const remarks = await getRemarkList(); + const remarksMappedByType = remarks.reduce((r, v) => ({ ...r, [v.product_type_id]: v }), {}); + const documentCreator = new AgencyContract(); + const doc = documentCreator.create([ + params, + activeAgency, + agencyProducts, + agencyExtras, + // remarks, + remarksMappedByType, + ]); + + const _d = dayjs().format('YYYYMMDD_HH.mm.ss.SSS'); // Date.now().toString(32) + // console.log(params); + const _state = isEmpty(audit_state) ? '' : auditStatesMap[audit_state].label; + Packer.toBlob(doc).then((blob) => { + saveAs(blob, `${activeAgency.travel_agency_name}${use_year}年地接合同-${_state}-${_d}.docx`); + }); + }; + return ( + <> + {/* todo: export, 审核完成之后才能导出 */} + + + {/* */} + + + ); +}; +export default ExportDocxBtn;