feat: 复制供应商产品

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

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

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

@ -21,7 +21,7 @@ export const fetchVendorList = async (q) => {
const { RangePicker } = DatePicker;
const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => {
const SearchForm = ({ initialValue, onSubmit, onReset, confirmText, formName, loading, ...props }) => {
const { t } = useTranslation();
const presets = useDatePresets();
const [formValues, setFormValues] = useFormStore((state) => [state.formValues, state.setFormValues]);
@ -36,7 +36,6 @@ const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => {
shows: [],
...props.fieldsConfig,
};
const { confirmText } = props;
const readValues = { ...initialValue, ...formValues };
const formValuesMapper = (values) => {
@ -109,14 +108,14 @@ const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => {
};
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}> */}
<Row gutter={16}>
{getFields({ sort, initialValue: readValues, hides, shows, fieldProps, fieldComProps, form, presets, t })}
{/* 'textAlign': 'right' */}
<Col flex='1 0 90px' className='flex justify-normal items-start' >
<Space align='center'>
<Button size={'middle'} type='primary' htmlType='submit'>
<Button size={'middle'} type='primary' htmlType='submit' loading={loading}>
{confirmText || t('Search')}
</Button>
{/* <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);
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) => {
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);
@ -41,7 +52,7 @@ export const getAgencyProductExtrasAction = async (param) => {
return errcode !== 0 ? [] : result;
};
export const postProductsQuoteAudit = async (auditState, quoteRow) => {
export const postProductsQuoteAuditAction = async (auditState, quoteRow) => {
const postbody = {
audit_state: auditState,
id: quoteRow.id,
@ -56,7 +67,7 @@ export const postProductsQuoteAudit = async (auditState, quoteRow) => {
// return errcode !== 0 ? {} : result;
};
export const postProductsAudit = async (auditState, infoRow) => {
export const postProductsAuditAction = async (auditState, infoRow) => {
const postbody = {
audit_state: auditState,
id: infoRow.id,

@ -4,7 +4,7 @@ import { App, Button, Collapse, Table, Space, Divider } from 'antd';
import { useProductsTypes, useProductsAuditStatesMapVal } from '@/hooks/useProductsSets';
import SecondHeaderWrapper from '@/components/SecondHeaderWrapper';
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 PrintContractPDF from './PrintContractPDF';
@ -14,7 +14,7 @@ const Header = ({ title, agency, refresh, ...props }) => {
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 })
postProductsQuoteAuditAction(state, { id: row.id, travel_agency_id: activeAgency.travel_agency_id })
.then((json) => {
if (json.errcode === 0) {
message.success(json.errmsg);
@ -63,7 +63,7 @@ const PriceTable = ({ dataSource, refresh }) => {
const stateMapVal = useProductsAuditStatesMapVal();
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) => {
if (json.errcode === 0) {
message.success(json.errmsg);

@ -2,7 +2,7 @@ import { createContext, useContext, useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
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 SearchForm from '@/components/SearchForm';
@ -163,7 +163,7 @@ const Extras = ({ productId, onChange, ...props }) => {
return (
<>
<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} />
<NewAddonModal onPick={handleNewAddOn} />
</RequireAuth>

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

Loading…
Cancel
Save