feat: 复制供应商产品

feature/price_manager
Lei OT 1 year ago
parent e4cc07eefe
commit 65064937f0

@ -3,14 +3,14 @@
"Experience": "Experience", "Experience": "Experience",
"Car": "Transport Services", "Car": "Transport Services",
"Guide": "Guide Services", "Guide": "Guide Services",
"Package": "Package", "Package": "Package Tour",
"Attractions": "Attractions", "Attractions": "Attractions",
"Meals": "Meals", "Meals": "Meals",
"Extras": "Extras", "Extras": "Extras",
"Overtravel": "超公里", "Overtravel": "超公里",
"Special": "Special" "Special": "Special"
}, },
"Components": { "EditComponents": {
"info": "Product Information", "info": "Product Information",
"Quotation": "Quotation", "Quotation": "Quotation",
"Extras": "Add-on" "Extras": "Add-on"

@ -10,7 +10,7 @@
"Overtravel": "超公里", "Overtravel": "超公里",
"Special": "特殊项目" "Special": "特殊项目"
}, },
"Components": { "EditComponents": {
"info": "产品信息", "info": "产品信息",
"Quotation": "报价", "Quotation": "报价",
"Extras": "附加项目" "Extras": "附加项目"

@ -21,7 +21,7 @@ export const fetchVendorList = async (q) => {
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => { const SearchForm = ({ initialValue, onSubmit, onReset, confirmText, formName, loading, ...props }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const presets = useDatePresets(); const presets = useDatePresets();
const [formValues, setFormValues] = useFormStore((state) => [state.formValues, state.setFormValues]); const [formValues, setFormValues] = useFormStore((state) => [state.formValues, state.setFormValues]);
@ -36,7 +36,6 @@ const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => {
shows: [], shows: [],
...props.fieldsConfig, ...props.fieldsConfig,
}; };
const { confirmText } = props;
const readValues = { ...initialValue, ...formValues }; const readValues = { ...initialValue, ...formValues };
const formValuesMapper = (values) => { const formValuesMapper = (values) => {
@ -109,14 +108,14 @@ const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => {
}; };
return ( return (
<> <>
<Form form={form} name='advanced_search' className='orders-search-form' onFinish={onFinish} onValuesChange={onValuesChange}> <Form form={form} name={formName || 'advanced_search'} className='orders-search-form' onFinish={onFinish} onValuesChange={onValuesChange}>
{/* <EditableContext.Provider value={form}> */} {/* <EditableContext.Provider value={form}> */}
<Row gutter={16}> <Row gutter={16}>
{getFields({ sort, initialValue: readValues, hides, shows, fieldProps, fieldComProps, form, presets, t })} {getFields({ sort, initialValue: readValues, hides, shows, fieldProps, fieldComProps, form, presets, t })}
{/* 'textAlign': 'right' */} {/* 'textAlign': 'right' */}
<Col flex='1 0 90px' className='flex justify-normal items-start' > <Col flex='1 0 90px' className='flex justify-normal items-start' >
<Space align='center'> <Space align='center'>
<Button size={'middle'} type='primary' htmlType='submit'> <Button size={'middle'} type='primary' htmlType='submit' loading={loading}>
{confirmText || t('Search')} {confirmText || t('Search')}
</Button> </Button>
{/* <Button size="small" onClick={onReset}> {/* <Button size="small" onClick={onReset}>

@ -9,6 +9,17 @@ export const searchAgencyAction = async (param) => {
const { errcode, result } = await fetchJSON(`${HT_HOST}/Service_BaseInfoWeb/products_search`, param); const { errcode, result } = await fetchJSON(`${HT_HOST}/Service_BaseInfoWeb/products_search`, param);
return errcode !== 0 ? [] : result; return errcode !== 0 ? [] : result;
}; };
export const copyAgencyDataAction = async (from, to) => {
const postbody = { source_agency: from, target_agency: to };
const formData = new FormData();
Object.keys(postbody).forEach((key) => {
formData.append(key, postbody[key]);
});
const { errcode, result } = await postForm(`${HT_HOST}/agency/products/copy`, formData);
return errcode === 0 ? true : false;
};
export const getAgencyProductsAction = async (param) => { export const getAgencyProductsAction = async (param) => {
const _param = { ...param, use_year: (param.use_year || '').replace('all', ''), audit_state: (param.audit_state || '').replace('all', '') }; 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); const { errcode, result } = await fetchJSON(`${HT_HOST}/Service_BaseInfoWeb/travel_agency_products`, _param);
@ -41,7 +52,7 @@ export const getAgencyProductExtrasAction = async (param) => {
return errcode !== 0 ? [] : result; return errcode !== 0 ? [] : result;
}; };
export const postProductsQuoteAudit = async (auditState, quoteRow) => { export const postProductsQuoteAuditAction = async (auditState, quoteRow) => {
const postbody = { const postbody = {
audit_state: auditState, audit_state: auditState,
id: quoteRow.id, id: quoteRow.id,
@ -56,7 +67,7 @@ export const postProductsQuoteAudit = async (auditState, quoteRow) => {
// return errcode !== 0 ? {} : result; // return errcode !== 0 ? {} : result;
}; };
export const postProductsAudit = async (auditState, infoRow) => { export const postProductsAuditAction = async (auditState, infoRow) => {
const postbody = { const postbody = {
audit_state: auditState, audit_state: auditState,
id: infoRow.id, id: infoRow.id,

@ -4,7 +4,7 @@ import { App, Button, Collapse, Table, Space, Divider } from 'antd';
import { useProductsTypes, useProductsAuditStatesMapVal } from '@/hooks/useProductsSets'; import { useProductsTypes, useProductsAuditStatesMapVal } from '@/hooks/useProductsSets';
import SecondHeaderWrapper from '@/components/SecondHeaderWrapper'; import SecondHeaderWrapper from '@/components/SecondHeaderWrapper';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import useProductsStore, { postProductsQuoteAudit } from '@/stores/Products/Index'; import useProductsStore, { postProductsQuoteAuditAction, } from '@/stores/Products/Index';
import { isEmpty } from '@/utils/commons'; import { isEmpty } from '@/utils/commons';
// import PrintContractPDF from './PrintContractPDF'; // import PrintContractPDF from './PrintContractPDF';
@ -14,7 +14,7 @@ const Header = ({ title, agency, refresh, ...props }) => {
const [activeAgency] = useProductsStore((state) => [state.activeAgency]); const [activeAgency] = useProductsStore((state) => [state.activeAgency]);
const { message, notification } = App.useApp(); const { message, notification } = App.useApp();
const handleAuditItem = (state, row) => { const handleAuditItem = (state, row) => {
postProductsQuoteAudit(state, { id: row.id, travel_agency_id: activeAgency.travel_agency_id }) postProductsQuoteAuditAction(state, { id: row.id, travel_agency_id: activeAgency.travel_agency_id })
.then((json) => { .then((json) => {
if (json.errcode === 0) { if (json.errcode === 0) {
message.success(json.errmsg); message.success(json.errmsg);
@ -63,7 +63,7 @@ const PriceTable = ({ dataSource, refresh }) => {
const stateMapVal = useProductsAuditStatesMapVal(); const stateMapVal = useProductsAuditStatesMapVal();
const handleAuditPriceItem = (state, row) => { const handleAuditPriceItem = (state, row) => {
postProductsQuoteAudit(state, { id: row.id, travel_agency_id: activeAgency.travel_agency_id }) postProductsQuoteAuditAction(state, { id: row.id, travel_agency_id: activeAgency.travel_agency_id })
.then((json) => { .then((json) => {
if (json.errcode === 0) { if (json.errcode === 0) {
message.success(json.errmsg); message.success(json.errmsg);

@ -2,7 +2,7 @@ import { createContext, useContext, useEffect, useState } from 'react';
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { App, Table, Button, Modal, Popconfirm } from 'antd'; import { App, Table, Button, Modal, Popconfirm } from 'antd';
import useProductsStore, { postProductsQuoteAudit, getAgencyProductExtrasAction, getAgencyProductsAction, addProductExtraAction, delProductExtrasAction } from '@/stores/Products/Index'; import useProductsStore, { getAgencyProductExtrasAction, getAgencyProductsAction, addProductExtraAction, delProductExtrasAction } from '@/stores/Products/Index';
import { isEmpty, cloneDeep } from '@/utils/commons'; import { isEmpty, cloneDeep } from '@/utils/commons';
import SearchForm from '@/components/SearchForm'; import SearchForm from '@/components/SearchForm';
@ -163,7 +163,7 @@ const Extras = ({ productId, onChange, ...props }) => {
return ( return (
<> <>
<RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}> <RequireAuth subject={PERM_PRODUCTS_MANAGEMENT}>
<h2>{t('products:Components.Extras')}</h2> <h2>{t('products:EditComponents.Extras')}</h2>
<Table dataSource={extrasData} columns={columns} bordered pagination={false} rowKey={(r) => r.info.id} /> <Table dataSource={extrasData} columns={columns} bordered pagination={false} rowKey={(r) => r.info.id} />
<NewAddonModal onPick={handleNewAddOn} /> <NewAddonModal onPick={handleNewAddOn} />
</RequireAuth> </RequireAuth>

@ -1,14 +1,16 @@
import { useEffect } from 'react'; import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom'; import { Link, useNavigate } from 'react-router-dom';
import { Row, Col, Space, Table } from 'antd'; import { App, Space, Table, Button, Modal } from 'antd';
import SearchForm from '@/components/SearchForm'; import SearchForm from '@/components/SearchForm';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import useProductsStore from '@/stores/Products/Index'; import useProductsStore, { copyAgencyDataAction } from '@/stores/Products/Index';
import useFormStore from '@/stores/Form'; import useFormStore from '@/stores/Form';
import { objectMapper } from '@/utils/commons'; import { objectMapper } from '@/utils/commons';
function Index() { function Index() {
const { notification, message } = App.useApp();
const navigate = useNavigate()
const { t } = useTranslation(); const { t } = useTranslation();
const [loading, agencyList, searchAgency] = useProductsStore((state) => [state.loading, state.agencyList, state.searchAgency]); const [loading, agencyList, searchAgency] = useProductsStore((state) => [state.loading, state.agencyList, state.searchAgency]);
const [searchValues, setSearchValues] = useProductsStore((state) => [state.searchValues, state.setSearchValues]); const [searchValues, setSearchValues] = useProductsStore((state) => [state.searchValues, state.setSearchValues]);
@ -21,6 +23,24 @@ function Index() {
searchAgency(searchParam); searchAgency(searchParam);
} }
const [copyModalVisible, setCopyModalVisible] = useState(false);
const [sourceAgency, setSourceAgency] = useState({});
const [copyLoading, setCopyLoading] = useState(false);
const handleCopyAgency = async (toID) => {
setCopyLoading(true);
const success = await copyAgencyDataAction(sourceAgency.travel_agency_id, toID);
setCopyLoading(false);
success ? message.success('复制成功') : message.error('复制失败');
setCopyModalVisible(false);
navigate(`/products/${toID}/${searchValues.use_year || 'all'}/${searchValues.audit_state || 'all'}/edit`);
};
const openCopyModal = (from) => {
setSourceAgency(from);
setCopyModalVisible(true);
};
useEffect(() => { useEffect(() => {
// handleSearchAgency(); // handleSearchAgency();
}, []); }, []);
@ -41,6 +61,7 @@ function Index() {
<Space size={'large'}> <Space size={'large'}>
<Link to={`/products/${r.travel_agency_id}/${searchValues.use_year || 'all'}/${searchValues.audit_state || 'all'}/edit`}>{t('Edit')}</Link> <Link to={`/products/${r.travel_agency_id}/${searchValues.use_year || 'all'}/${searchValues.audit_state || 'all'}/edit`}>{t('Edit')}</Link>
<Link to={`/products/${r.travel_agency_id}/${searchValues.use_year || 'all'}/${searchValues.audit_state || 'all'}/audit`}>{t('Audit')}</Link> <Link to={`/products/${r.travel_agency_id}/${searchValues.use_year || 'all'}/${searchValues.audit_state || 'all'}/audit`}>{t('Audit')}</Link>
<Button type='link' onClick={() => openCopyModal(r)}>{t('Copy')}</Button>
</Space> </Space>
), ),
}, },
@ -69,19 +90,27 @@ function Index() {
handleSearchAgency(formVal); handleSearchAgency(formVal);
}} }}
/> />
<Row> <Table bordered={true} columns={columns} dataSource={agencyList} pagination={{ defaultPageSize: 20, showTotal: showTotal }} loading={loading} rowKey={'travel_agency_id'} />
<Col md={24} lg={24} xxl={24}>
<Table {/* 复制弹窗 */}
bordered={true} <Modal width={600} open={copyModalVisible} title={`复制供应商产品`} footer={false} onCancel={() => setCopyModalVisible(false)} destroyOnClose>
columns={columns} <div className='py-2'>复制源: {sourceAgency.travel_agency_name}</div>
dataSource={agencyList} <SearchForm formName='copyform' loading={copyLoading}
pagination={{ defaultPageSize: 20, showTotal: showTotal }} confirmText={t('Confirm')}
loading={loading} fieldsConfig={{
rowKey={'travel_agency_id'} shows: ['agency'],
/> fieldProps: {
</Col> agency: { label: `目标${t('products:Vendor')}`, col: 12 },
<Col md={24} lg={24} xxl={24}></Col> },
</Row> fieldComProps: {
agency: { mode: null }, //
},
}}
onSubmit={(err, formVal, filedsVal) => {
handleCopyAgency(formVal.agency);
}}
/>
</Modal>
</Space> </Space>
); );
} }

Loading…
Cancel
Save