多语种信息编辑

perf/export-docx
Lei OT 11 months ago
parent b2dcec8c37
commit f6b0dd8d04

@ -1,34 +1,25 @@
import { useEffect, useState } from 'react';
import { Form, Input, Row, Col, Select, DatePicker, Space, Button, InputNumber, Radio, Checkbox, Divider } from 'antd';
import { objectMapper, at, isEmpty, isNotEmpty } from '@/utils/commons';
import { DATE_FORMAT, SMALL_DATETIME_FORMAT } from '@/config';
// import useFormStore from '@/stores/Form';
import { Form, Input, Row, Col, Select, Button, InputNumber, Checkbox } from 'antd';
import { objectMapper, isEmpty, isNotEmpty } from '@/utils/commons';
import { useTranslation } from 'react-i18next';
import { useWeekdays } from '@/hooks/useDatePresets';
import DeptSelector from '@/components/DeptSelector';
import CitySelector from '@/components/CitySelector';
import { fetchJSON } from '@/utils/request';
import { HT_HOST } from '@/config';
// import SearchInput from './SearchInput';
// import AuditStateSelector from './AuditStateSelector';
import { useProductsTypesMapVal, useProductsTypesFieldsets } from '@/hooks/useProductsSets';
import useProductsStore, { postProductsSaveAction } from '@/stores/Products/Index';
import { useProductsTypesFieldsets } from '@/hooks/useProductsSets';
import useProductsStore from '@/stores/Products/Index';
import ProductInfoLgc from './ProductInfoLgc';
import ProductInfoQuotation from './ProductInfoQuotation';
import useAuthStore from '@/stores/Auth';
import { PERM_PRODUCTS_MANAGEMENT, PERM_PRODUCTS_OFFER_AUDIT, PERM_PRODUCTS_OFFER_PUT } from '@/config';
import { useHTLanguageSets, useHTLanguageSetsMapVal } from '@/hooks/useHTLanguageSets';
import { PERM_PRODUCTS_OFFER_AUDIT } from '@/config';
import { useHTLanguageSetsMapVal } from '@/hooks/useHTLanguageSets';
const { RangePicker } = DatePicker;
const InfoForm = ({ onSubmit, onReset, onValuesChange, editable: _editable, showSubmit, confirmText, formName, ...props }) => {
const { t } = useTranslation('products');
const HTLanguageSetsMapVal = useHTLanguageSetsMapVal();
const isPermitted = useAuthStore((state) => state.isPermitted);
const [loading, setLoading, agencyProducts, editingProduct, setEditingProduct] = useProductsStore((state) => [state.loading, state.setLoading, state.agencyProducts, state.editingProduct, state.setEditingProduct]);
const [loading, editingProduct] = useProductsStore((state) => [state.loading, state.editingProduct]);
const weekdays = useWeekdays();
const HTLanguageSetsMapVal = useHTLanguageSetsMapVal();
const [form] = Form.useForm();
const { sort, hides, fieldProps, fieldComProps } = {
sort: '',
@ -48,6 +39,7 @@ const InfoForm = ({ onSubmit, onReset, onValuesChange, editable: _editable, show
form.resetFields();
form.setFieldValue('city', { value: editingProduct?.info?.city_id, label: editingProduct?.info?.city_name });
form.setFieldValue('dept', { value: editingProduct?.info?.dept_id, label: editingProduct?.info?.dept_name });
form.setFieldValue('lgc_details', editingProduct?.lgc_details || []);
const isNew = isEmpty(editingProduct?.info?.id) || _editable; // ; =
const ignoreEditable0 = topPerm || isNew; //
@ -56,8 +48,7 @@ const InfoForm = ({ onSubmit, onReset, onValuesChange, editable: _editable, show
// console.log('+++++++++++++++++++', '\ntopPerm', topPerm, '\nisNew', isNew, '\nignoreEditable0', ignoreEditable0, '\neditable0', editable0, '\n_editable', _editable);
setEditable(editable0);
return () => {};
}, [editingProduct?.info?.id, _editable])
}, [editingProduct?.info?.id, _editable]);
const onFinish = (values) => {
console.log('Received values of form, origin form value: \n', values);
@ -68,9 +59,9 @@ const InfoForm = ({ onSubmit, onReset, onValuesChange, editable: _editable, show
}
};
const onFinishFailed = ({ values, errorFields, }) => {
const onFinishFailed = ({ values, errorFields }) => {
console.log('form validate failed', '\nform values:', values, '\nerrorFields', errorFields);
}
};
const handleReset = () => {
form.setFieldsValue({
@ -82,19 +73,24 @@ const InfoForm = ({ onSubmit, onReset, onValuesChange, editable: _editable, show
};
const onIValuesChange = (changedValues, allValues) => {
const dest = formValuesMapper(allValues);
// console.log('form onValuesChange', Object.keys(changedValues), args);
// console.log('form onValuesChange', Object.keys(changedValues), changedValues);
if (typeof onValuesChange === 'function') {
onValuesChange(dest);
}
};
const onFieldsChange = (hangedFields, allFields) => {
console.log('onFieldsChange', hangedFields, allFields);
};
return (
<>
<Form
form={form}
disabled={!(editable || false)}
name={formName || 'product_info'}
// preserve={false}
onFinish={onFinish}
onValuesChange={onIValuesChange}
// onFieldsChange={onFieldsChange}
initialValues={editingProduct?.info}
onFinishFailed={onFinishFailed}>
<Row>
@ -110,23 +106,24 @@ const InfoForm = ({ onSubmit, onReset, onValuesChange, editable: _editable, show
)} */}
</Row>
{/* <Divider className='my-1' /> */}
<Form.Item
name={'lgc_details'}
initialValue={[]}
rules={[
() => ({
transform(value) {
return value.filter(Boolean);
},
validator(_, value) {
const invalidLgcName = (value).filter(l => isEmpty(l.title)).map(x => HTLanguageSetsMapVal[x.lgc].label).join(', ');
if (isNotEmpty(invalidLgcName)) {
return Promise.reject(new Error(`请完善多语种信息: ${invalidLgcName}`));
}
return Promise.resolve();
},
}),
]}>
<Form.Item name={'lgc_details_mapped'}
rules={[
() => ({
transform(value) {
return Object.values(value).filter(_v => !isEmpty(_v));
},
validator: async (_, valueArr) => {
const invalidLgcName = valueArr
.filter((l) => isEmpty(l.title))
.map((x) => HTLanguageSetsMapVal[x.lgc].label)
.join(', ');
if (isNotEmpty(invalidLgcName)) {
return Promise.reject(new Error(`请完善多语种信息: ${invalidLgcName}`));
}
return Promise.resolve();
},
}),
]}>
<ProductInfoLgc editable={editable} ignoreEditable={ignoreEditable} formInstance={form} />
</Form.Item>
@ -159,7 +156,7 @@ function getFields(props) {
// const disabled = props.ignoreEditable ? false : (isEmpty(props.initialValue?.[name]) && props.editable ? false : true)
const disabled = !props.editable;
return { disabled, className: disabled ? '!text-slate-500' : '' };
}
};
const bigCol = 4 * 2;
const midCol = 8;
const layoutProps = {
@ -178,7 +175,7 @@ function getFields(props) {
name,
render,
'hide': false,
'col': { lg: { span: customCol }, md: { span: mdCol < 8 ? 10 : (mdCol > 24 ? 24 : mdCol) }, flex: mdCol < 8 ? '1 0' : '' },
'col': { lg: { span: customCol }, md: { span: mdCol < 8 ? 10 : mdCol > 24 ? 24 : mdCol }, flex: mdCol < 8 ? '1 0' : '' },
};
};
let baseChildren = [];
@ -186,7 +183,7 @@ function getFields(props) {
item(
'code',
99,
<Form.Item name='code' label={t('Code')} {...fieldProps.code} rules={[{required: true}]}>
<Form.Item name='code' label={t('Code')} {...fieldProps.code} rules={[{ required: true }]}>
<Input allowClear {...fieldComProps.code} {...styleProps} {...editableProps('code')} />
</Form.Item>,
fieldProps?.code?.col || midCol
@ -229,7 +226,9 @@ function getFields(props) {
99,
<Form.Item name='recommends_rate' label={t('RecommendsRate')} {...fieldProps.recommends_rate}>
{/* <Input placeholder={t('RecommendsRate')} allowClear /> */}
<Select {...styleProps} {...editableProps('recommends_rate')}
<Select
{...styleProps}
{...editableProps('recommends_rate')}
style={{ width: '100%' }}
labelInValue={false}
options={[
@ -260,18 +259,23 @@ function getFields(props) {
// },
// }),
// ]}
>
>
{/* <Checkbox.Group
options={[
{ value: 153001, label: '报价信不显示' },
{ value: 153002, label: '计划不显示' },
]}
/> */}
<Select labelInValue={false} options={[
{ value: '153001', label: '在计划显示,不在报价信显示' },
{ value: 0, label: '计划和报价信都要显示' },
{ value: '153001, 153002', label: '计划和报价信都不用显示' },
]} {...styleProps} {...editableProps('display_to_c')} />
<Select
labelInValue={false}
options={[
{ value: '153001', label: '在计划显示,不在报价信显示' },
{ value: 0, label: '计划和报价信都要显示' },
{ value: '153001, 153002', label: '计划和报价信都不用显示' },
]}
{...styleProps}
{...editableProps('display_to_c')}
/>
</Form.Item>,
fieldProps?.display_to_c?.col || midCol
),
@ -342,25 +346,34 @@ function getFields(props) {
const formValuesMapper = (values) => {
const destinationObject = {
'city': [{ key: 'city_id', transform: (value) => value?.value || value?.key || '' }, { key: 'city_name', transform: (value) => value?.label || '' }],
'dept': { key: 'dept', transform: (value) => typeof value === 'string' ? value : (value?.value || value?.key || '') },
'city': [
{ key: 'city_id', transform: (value) => value?.value || value?.key || '' },
{ key: 'city_name', transform: (value) => value?.label || '' },
],
'dept': { key: 'dept', transform: (value) => (typeof value === 'string' ? value : value?.value || value?.key || '') },
'open_weekdays': { key: 'open_weekdays', transform: (value) => (Array.isArray(value) ? value.join(',') : value) },
'recommends_rate': { key: 'recommends_rate', transform: (value) => typeof value === 'string' ? value : (value?.value || value?.key || '') },
'lgc_details': [
{
key: 'lgc_details',
transform: (value) => {
const _val = value.filter((s) => s !== undefined).map((e) => ({ title: '', ...e, description: e.description || '' }));
return _val || '';
},
},
{
key: 'lgc_details_mapped',
transform: (value) => {
const _val = value.filter((s) => s !== undefined);
return _val.reduce((r, c) => ({ ...r, [c.lgc]: c }), {});
},
},
'recommends_rate': { key: 'recommends_rate', transform: (value) => (typeof value === 'string' ? value : value?.value || value?.key || '') },
// 'lgc_details': [
// {
// key: 'lgc_details',
// transform: (value) => {
// const _val = value.filter((s) => s !== undefined).map((e) => ({ title: '', ...e, description: e.description || '' }));
// return _val || '';
// },
// },
// {
// key: 'lgc_details_mapped_tmp',
// transform: (value) => {
// const _val = value.filter((s) => s !== undefined);
// return _val.reduce((r, c) => ({ ...r, [c.lgc]: c }), {});
// },
// },
// ],
'lgc_details_mapped': [
{ key: 'lgc_details', transform: (value) => {
const valueArr = Object.values(value).filter(_v => !isEmpty(_v));
return valueArr;
}},
],
};
let dest = {};
@ -377,5 +390,4 @@ const formValuesMapper = (values) => {
return { info, lgc_details, lgc_details_mapped, quotation };
};
export default InfoForm;

@ -1,17 +1,17 @@
import { useEffect, useState, useRef } from 'react';
import { useEffect, useState } from 'react';
import { Input, Tabs, Modal, Select, Form } from 'antd';
import useProductsStore from '@/stores/Products/Index';
import { useHTLanguageSets, useHTLanguageSetsMapVal } from '@/hooks/useHTLanguageSets';
import { useTranslation } from 'react-i18next';
import { useDefaultLgc } from '@/i18n/LanguageSwitcher';
import { isEmpty } from '@/utils/commons';
import { cloneDeep, isEmpty, isNotEmpty } from '@/utils/commons';
const ProductInfoLgc = ({ editable, ignoreEditable, formInstance, ...props }) => {
const { t } = useTranslation();
const { language: languageHT } = useDefaultLgc();
const HTLanguageSetsMapVal = useHTLanguageSetsMapVal();
const allLgcOptions = useHTLanguageSets();
const [ editingProduct, ] = useProductsStore((state) => [ state.editingProduct, ]);
const [editingProduct] = useProductsStore((state) => [state.editingProduct]);
const [activeKey, setActiveKey] = useState();
const [items, setItems] = useState([]);
@ -19,35 +19,41 @@ const ProductInfoLgc = ({ editable, ignoreEditable, formInstance, ...props }) =>
const existsLgc = (editingProduct?.lgc_details || []).map((ele, li) => ({
...ele,
label: HTLanguageSetsMapVal[ele.lgc].label,
key: `${editingProduct.info.id}-${ele.id}`,
// key: `${editingProduct.info.id}-${ele.id}`,
key: ele.lgc,
closable: false, // isPermitted(PERM_PRODUCTS_MANAGEMENT) ? true : false,
forceRender: true,
children: (
<>
<Form.Item name={[li, 'title']} label={t('products:Title')} initialValue={ele.title}>
<Input className={' !text-slate-600'} allowClear
<Form.Item>
<Form.Item name={['lgc_details_mapped', `${ele.lgc}`, 'title']} label={t('products:Title')} initialValue={ele.title} rules={[{ required: true }]}>
<Input
className={' !text-slate-600'}
allowClear
// onChange={(e) => handleChange('title', e.target.value)}
// disabled={isCanEditable}
// disabled={ignoreEditable ? false : (!isEmpty(ele.title) || !editable)}
disabled={ignoreEditable ? false : (!editable)}
disabled={ignoreEditable ? false : !editable}
// disabled={!editable}
/>
</Form.Item>
<Form.Item name={[li, 'description']} label={t('products:Description')} initialValue={ele.descriptions}>
<Input.TextArea className={'!text-slate-600'}
rows={3} allowClear
<Form.Item name={['lgc_details_mapped', `${ele.lgc}`, 'description']} label={t('products:Description')} initialValue={ele.descriptions}>
<Input.TextArea
className={'!text-slate-600'}
rows={3}
allowClear
// onChange={(e) => handleChange('description', e.target.value)}
// disabled={ignoreEditable ? false : (!isEmpty(ele.descriptions) || !editable)}
disabled={ignoreEditable ? false : (!editable)}
disabled={ignoreEditable ? false : !editable}
// disabled={!editable}
/>
</Form.Item>
<Form.Item hidden name={[li, 'lgc']} initialValue={ele.lgc}>
<Form.Item hidden name={['lgc_details_mapped', `${ele.lgc}`, 'lgc']} initialValue={ele.lgc}>
<Input />
</Form.Item>
<Form.Item hidden name={[li, 'id']} initialValue={ele.id}>
<Form.Item hidden name={['lgc_details_mapped', `${ele.lgc}`, 'id']} initialValue={ele.id}>
<Input />
</Form.Item>
</>
</Form.Item>
),
}));
setItems(existsLgc);
@ -60,37 +66,44 @@ const ProductInfoLgc = ({ editable, ignoreEditable, formInstance, ...props }) =>
return () => {};
}, [editingProduct]);
const onChange = (newActiveKey) => {
const onLgcTabChange = (newActiveKey) => {
setActiveKey(newActiveKey);
};
const addLgc = (lgcItem) => {
const newActiveKey = lgcItem.value; // `newTab${newTabIndex.current++}`;
const i = 8+Number(lgcItem.value);
// const currentLgcOptions = structuredClone(lgcOptions);
const currentLgcOptions = cloneDeep(lgcOptions);
currentLgcOptions.splice(
currentLgcOptions.findIndex((ele) => ele.value === lgcItem.value),
1
);
setLgcOptions(currentLgcOptions);
const newActiveKey = lgcItem.value;
const newPanes = [...items];
newPanes.push({
...lgcItem,
forceRender: true,
key: lgcItem.value,
children: (
<>
<Form.Item name={[i, 'title']} label={t('products:Title')} initialValue={''} rules={[{required: true}]}>
<Input />
<Form.Item>
<Form.Item name={['lgc_details_mapped', `${lgcItem.value}`, 'title']} preserve={false} label={t('products:Title')} rules={[{ required: true }]}>
<Input allowClear />
</Form.Item>
<Form.Item name={[i, 'description']} label={t('products:Description')} initialValue={''}>
<Input.TextArea rows={3} />
<Form.Item name={['lgc_details_mapped', `${lgcItem.value}`, 'description']} preserve={false} label={t('products:Description')}>
<Input.TextArea rows={3} allowClear />
</Form.Item>
<Form.Item hidden name={[i, 'lgc']} initialValue={lgcItem.value}>
<Form.Item hidden name={['lgc_details_mapped', `${lgcItem.value}`, 'lgc']} preserve={false} initialValue={lgcItem.value}>
<Input />
</Form.Item>
<Form.Item hidden name={[i, 'id']} initialValue={''}>
<Form.Item hidden name={['lgc_details_mapped', `${lgcItem.value}`, 'id']} preserve={false} initialValue={''}>
<Input />
</Form.Item>
</>
</Form.Item>
),
});
setItems(newPanes);
setActiveKey(newActiveKey);
const currentLgcOptions = structuredClone(lgcOptions);
currentLgcOptions.splice(currentLgcOptions.findIndex(ele => ele.value === lgcItem.value), 1);
setLgcOptions(currentLgcOptions);
setSelectNewLgc(null);
};
const remove = (targetKey) => {
@ -111,7 +124,7 @@ const ProductInfoLgc = ({ editable, ignoreEditable, formInstance, ...props }) =>
}
setItems(newPanes);
setActiveKey(newActiveKey);
setLgcOptions([...lgcOptions, ...items.filter(item => item.key === targetKey)]);
setLgcOptions([...lgcOptions, ...items.filter((item) => item.key === targetKey)]);
};
const onEdit = (targetKey, action) => {
if (action === 'add') {
@ -136,10 +149,17 @@ const ProductInfoLgc = ({ editable, ignoreEditable, formInstance, ...props }) =>
};
return (
<>
<Form.List name={'lgc_details'}>
{(fields, { add, remove }) => <Tabs type='editable-card' size='small' onChange={onChange} activeKey={activeKey} onEdit={onEdit} items={items} hideAdd={isEmpty(lgcOptions) || !editable} tabPosition='top' />}
</Form.List>
<Modal title='选择语言' open={newLgcModalVisible} onOk={handleOk} onCancel={() => setNewLgcModalVisible(false)}>
<Tabs
type='editable-card'
size='small'
onChange={onLgcTabChange}
activeKey={activeKey}
onEdit={onEdit}
items={items}
hideAdd={isEmpty(lgcOptions) || !editable}
tabPosition='top'
/>
<Modal title={'选择语言'} open={newLgcModalVisible} onOk={handleOk} onCancel={() => setNewLgcModalVisible(false)}>
<Select
showSearch
labelInValue

Loading…
Cancel
Save