diff --git a/public/locales/en/products.json b/public/locales/en/products.json index 03bdb46..281e485 100644 --- a/public/locales/en/products.json +++ b/public/locales/en/products.json @@ -59,6 +59,7 @@ "tourTime": "Tour time", "recommendationRate": "Recommends rate", "Name": "Name", + "Price":"Price", "Description":"Description", "supplierQuotation": "Supplier quotation", "addQuotation": "Add quotation", @@ -95,6 +96,7 @@ }, "CopyFormMsg": { + "target": "Target ", "requiredVendor": "Please pick a target vendor", "requiredTypes": "Please select product types", "requiredDept": "Please pick a owner department" @@ -111,5 +113,5 @@ "Weekdays": "Weekdays" }, - "#": "#" + "#": "Products" } diff --git a/public/locales/zh/products.json b/public/locales/zh/products.json index dd07133..e43e37e 100644 --- a/public/locales/zh/products.json +++ b/public/locales/zh/products.json @@ -96,6 +96,7 @@ }, "CopyFormMsg": { + "target": "目标", "requiredVendor": "请选择目标供应商", "requiredTypes": "请选择产品类型", "requiredDept": "请选择所属小组" @@ -112,5 +113,5 @@ "Operation": "Operation" }, - "#": "#" + "#": "产品" } diff --git a/src/components/ProductsTypesSelector.jsx b/src/components/ProductsTypesSelector.jsx new file mode 100644 index 0000000..ca61815 --- /dev/null +++ b/src/components/ProductsTypesSelector.jsx @@ -0,0 +1,23 @@ +import { Select } from 'antd'; +import { useProductsTypes } from '@/hooks/useProductsSets'; +import { useTranslation } from 'react-i18next'; + +import { fetchJSON } from '@/utils/request'; +import { HT_HOST } from '@/config'; + +//供应商列表 +export const fetchVendorList = async (q) => { + const { errcode, result } = await fetchJSON(`${HT_HOST}/Service_BaseInfoWeb/VendorList`, { q }) + return errcode !== 0 ? [] : result +} + +const ProductsTypesSelector = ({...props}) => { + const productsTypes = useProductsTypes(); + const { t } = useTranslation(); + return ( + <> + - - ); -}; - const SearchForm = ({ initialValue, onSubmit, onReset, confirmText, formName, formLayout, loading, ...props }) => { const { t } = useTranslation(); const presets = useDatePresets(); @@ -283,7 +264,7 @@ function getFields(props) { 'products_types', 99, - + , fieldProps?.products_types?.col || 6 ), diff --git a/src/stores/Products/Index.js b/src/stores/Products/Index.js index 5e4ccbf..6a92b8a 100644 --- a/src/stores/Products/Index.js +++ b/src/stores/Products/Index.js @@ -25,7 +25,7 @@ export const copyAgencyDataAction = async (postbody) => { Object.keys(postbody).forEach((key) => { formData.append(key, postbody[key]); }); - const { errcode, result } = await postForm(`${HT_HOST}/agency/products/copy`, formData); + const { errcode, result } = await postForm(`${HT_HOST}/Service_BaseInfoWeb/agency_products_copy`, formData); return errcode === 0 ? true : false; }; diff --git a/src/views/products/Detail/CopyProducts.jsx b/src/views/products/Detail/CopyProducts.jsx new file mode 100644 index 0000000..6b4d151 --- /dev/null +++ b/src/views/products/Detail/CopyProducts.jsx @@ -0,0 +1,160 @@ +import { useState, useEffect } from 'react'; +import { App, Form, Modal, DatePicker, Divider } from 'antd'; +import { isEmpty, objectMapper } from '@/utils/commons'; +import { useTranslation } from 'react-i18next'; + +import SearchInput from '@/components/SearchInput'; +import DeptSelector from '@/components/DeptSelector'; +import ProductsTypesSelector, { fetchVendorList } from '@/components/ProductsTypesSelector'; +import dayjs from 'dayjs'; +import arraySupport from 'dayjs/plugin/arraySupport'; +import { copyAgencyDataAction } from '@/stores/Products/Index'; + +import useAuthStore from '@/stores/Auth'; +import RequireAuth from '@/components/RequireAuth'; +import { PERM_PRODUCTS_MANAGEMENT } from '@/config'; + +dayjs.extend(arraySupport); + +export const CopyProductsForm = ({ action, initialValues, onFormInstanceReady, source, ...props }) => { + const { t } = useTranslation(); + const [form] = Form.useForm(); + + const isPermitted = useAuthStore((state) => state.isPermitted); + + useEffect(() => { + onFormInstanceReady(form); + }, []); + + const onValuesChange = (changeValues, allValues) => {}; + return ( +
+ {action === '#' && + + } + + + + {action === '#' && + + + + } + + + + + current <= dayjs([source.sourceYear, 12, 31])} /> + +
+ ); +}; +const formValuesMapper = (values) => { + const destinationObject = { + 'agency': { + key: 'target_agency', + transform: (value) => { + return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.value : ''; + }, + }, + 'source_use_year': [{ key: 'source_use_year', transform: (arrVal) => (arrVal ? arrVal.format('YYYY') : '') }], + 'target_use_year': [{ key: 'target_use_year', transform: (arrVal) => (arrVal ? arrVal.format('YYYY') : '') }], + 'products_types': { + key: 'products_types', + transform: (value) => { + return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.value : ''; + }, + }, + 'dept': { + key: 'dept', + transform: (value) => { + return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.value : ''; + }, + }, + }; + let dest = {}; + const { agency, year, ...omittedValue } = values; + dest = { ...omittedValue, ...objectMapper(values, destinationObject) }; + for (const key in dest) { + if (Object.prototype.hasOwnProperty.call(dest, key)) { + dest[key] = typeof dest[key] === 'string' ? (dest[key] || '').trim() : dest[key]; + } + } + // omit empty + // Object.keys(dest).forEach((key) => (dest[key] == null || dest[key] === '' || dest[key].length === 0) && delete dest[key]); + return dest; +}; +/** + * + */ +export const CopyProductsFormModal = ({ source, action = '#' | 'o', open, onSubmit, onCancel, initialValues, loading, copyModalVisible, setCopyModalVisible }) => { + const { t } = useTranslation(); + const { notification, message } = App.useApp(); + const [formInstance, setFormInstance] = useState(); + + const [copyLoading, setCopyLoading] = useState(false); + const handleCopyAgency = async (param) => { + param.target_agency = isEmpty(param.target_agency) ? source.sourceAgency.travel_agency_id : param.target_agency; + setCopyLoading(true); + console.log(param); + const toID = param.target_agency; + const success = await copyAgencyDataAction({...param, source_agency: source.sourceAgency.travel_agency_id}); + setCopyLoading(false); + success ? message.success(t('Success')) : message.error(t('Failed')); + + if (typeof onSubmit === 'function') { + onSubmit(param); + } + // setCopyModalVisible(false); + // navigate(`/products/${toID}/${searchValues.use_year || 'all'}/${searchValues.audit_state || 'all'}/edit`); + }; + return ( + { + onCancel(); + formInstance?.resetFields(); + }} + destroyOnClose + onOk={async () => { + try { + const values = await formInstance?.validateFields(); + // formInstance?.resetFields(); + const dest = formValuesMapper(values); + handleCopyAgency(dest); + } catch (error) { + console.log('Failed:', error); + } + }}> + +
+ {t('products:CopyFormMsg.Source')}: {source.sourceAgency.travel_agency_name} + + {source.sourceYear} +
+
+ { + setFormInstance(instance); + }} + /> +
+ ); +}; +export default CopyProductsFormModal; diff --git a/src/views/products/Manage.jsx b/src/views/products/Manage.jsx index 0a58e1d..1aa105c 100644 --- a/src/views/products/Manage.jsx +++ b/src/views/products/Manage.jsx @@ -1,12 +1,16 @@ import { useEffect, useState } from 'react'; import { Link, useNavigate } from 'react-router-dom'; -import { App, Space, Table, Button, Modal } from 'antd'; +import { App, Space, Table, Button, Modal, Divider } from 'antd'; import SearchForm from '@/components/SearchForm'; import dayjs from 'dayjs'; +import arraySupport from 'dayjs/plugin/arraySupport'; import { useTranslation } from 'react-i18next'; import useProductsStore, { copyAgencyDataAction } from '@/stores/Products/Index'; import useFormStore from '@/stores/Form'; import { objectMapper } from '@/utils/commons'; +import CopyProductsFormModal from './Detail/CopyProducts'; + +dayjs.extend(arraySupport); function Index() { const { notification, message } = App.useApp(); @@ -16,6 +20,8 @@ function Index() { const [searchValues, setSearchValues] = useProductsStore((state) => [state.searchValues, state.setSearchValues]); const formValuesToSub = useFormStore(state => state.formValuesToSub); + const useYear = formValuesToSub.year; + const handleSearchAgency = (formVal = undefined) => { const { starttime, endtime, ...param } = formVal || formValuesToSub; const searchParam = objectMapper(param, { agency: 'travel_agency_ids', startdate: 'edit_date1', enddate: 'edit_date2', year: 'use_year' }); @@ -25,21 +31,22 @@ function Index() { const [copyModalVisible, setCopyModalVisible] = useState(false); const [sourceAgency, setSourceAgency] = useState({}); + const [copyAction, setCopyAction] = useState(); const [copyLoading, setCopyLoading] = useState(false); const handleCopyAgency = async (param) => { - setCopyLoading(true); - const postbody = objectMapper(param, { agency: 'target_agency', }); - const toID = postbody.target_agency; - const success = await copyAgencyDataAction({...postbody, source_agency: sourceAgency.travel_agency_id}); - setCopyLoading(false); - success ? message.success('复制成功') : message.error('复制失败'); + // setCopyLoading(true); + const toID = param.target_agency; + // const success = await copyAgencyDataAction({...param, source_agency: sourceAgency.travel_agency_id}); + // setCopyLoading(false); + // success ? message.success('复制成功') : message.error('复制失败'); setCopyModalVisible(false); navigate(`/products/${toID}/${searchValues.use_year || 'all'}/${searchValues.audit_state || 'all'}/edit`); }; - const openCopyModal = (from) => { + const openCopyModal = (from, action) => { setSourceAgency(from); + setCopyAction(action); setCopyModalVisible(true); }; @@ -51,8 +58,8 @@ function Index() { const columns = [ { title: t('products:Vendor'), key: 'vendor', dataIndex: 'travel_agency_name' }, - { title: t('products:CreatedBy'), key: 'created_by', dataIndex: 'created_by_name' }, - { title: t('products:CreateDate'), key: 'create_date', dataIndex: 'create_date' }, + { title: t('products:CreatedBy'), key: 'poster_by', dataIndex: 'poster_name' }, + { title: t('products:CreateDate'), key: 'poster_date', dataIndex: 'poster_date' }, { title: t('products:AuState'), key: 'audit_state', dataIndex: 'audit_state' }, { title: t('products:AuditedBy'), key: 'audited_by', dataIndex: 'audited_by_name' }, { title: t('products:AuditDate'), key: 'audit_date', dataIndex: 'audit_date' }, @@ -63,7 +70,8 @@ function Index() { {t('Edit')} {t('Audit')} - + + ), }, @@ -72,19 +80,19 @@ function Index() { { handleSearchAgency(formVal); @@ -93,28 +101,16 @@ function Index() { {/* 复制弹窗 */} - setCopyModalVisible(false)} destroyOnClose> -
复制源: {sourceAgency.travel_agency_name}
- { - handleCopyAgency(formVal); - }} - /> -
+ setCopyModalVisible(false)} + onSubmit={(formVal) => { + handleCopyAgency(formVal); + }} + {...{copyModalVisible, setCopyModalVisible}} + /> ); }