产品编辑页面: 组件 editable

perf/export-docx
Lei OT 11 months ago
parent a63887a7b6
commit ab527e36c2

@ -24,10 +24,12 @@ import { postJSON, postForm } from '@/utils/request';
import RequireAuth from '@/components/RequireAuth'
import { PERM_ROLE_NEW } from '@/config'
import { create } from 'zustand';
import { PERM_PRODUCTS_MANAGEMENT } from '@/config';
import { PERM_PRODUCTS_MANAGEMENT, PERM_PRODUCTS_OFFER_AUDIT, PERM_PRODUCTS_OFFER_PUT } from '@/config';
import { usingStorage } from '@/hooks/usingStorage';
import ProductsTree from './Detail/ProductsTree';
import ProductInfo from './Detail/ProductInfo';
import useAuthStore from '@/stores/Auth';
function Detail() {
const { t } = useTranslation();
const productsTypesMapVal = useProductsTypesMapVal();
@ -859,6 +861,18 @@ function Detail() {
};
const isPermitted = useAuthStore((state) => state.isPermitted);
const [editable, setEditable] = useState(true);
useEffect(() => {
const notAudit = activeAgency.audit_state_id < 0 || activeAgency.audit_state_id === 3;
const hasAuditPer = isPermitted(PERM_PRODUCTS_OFFER_AUDIT);
const hasEditPer = isPermitted(PERM_PRODUCTS_OFFER_PUT);
setEditable(hasAuditPer ? true : (notAudit && hasEditPer));
// setEditable(true); // debug: 0
// console.log('editable', hasAuditPer, (notAudit && hasEditPer));
return () => {};
}, [activeAgency, editingProduct])
//
const newProduct = useNewProductRecord();
// const { language } = useDefaultLgc();
@ -872,7 +886,6 @@ function Detail() {
copyNewProduct.lgc_details[0].lgc = language;
setEditingProduct(copyNewProduct);
setAddProductVisible(false);
// todo: , active
return false;
const tempAddData = {
info: {
@ -1069,7 +1082,7 @@ function Detail() {
return (
<SecondHeaderWrapper loading={loading} backTo={false} header={
<Header title={activeAgency.travel_agency_name} refresh={handleGetAgencyProducts} handleNewProduct={() => setAddProductVisible(true)} handleSubmitForAudit={submitReview} />
<Header title={activeAgency.travel_agency_name} refresh={handleGetAgencyProducts} handleNewProduct={() => setAddProductVisible(true)} handleSubmitForAudit={submitReview} editable={editable} />
// <YearSelector title={activeAgency.travel_agency_name} refresh={handleGetAgencyProducts} onStateChange={handleStateChange}/>
}>
{isEmpty(agencyProducts) ? <Empty /> :
@ -1079,7 +1092,7 @@ function Detail() {
<ProductsTree className='basis-64 sticky top-16 overflow-y-auto shrink-0' style={{ height: 'calc(100vh - 150px)' }} />
<Divider type={'vertical'} className='mx-1 h-auto' />
<div className=' flex-auto grow-0 min-w-[800px]'>
<ProductInfo />
<ProductInfo editable={editable} />
{/* <Row> */}
{/* <Col span={6} className=' relative'> */}
{/* <Card className='w-[inherit] fixed overflow-y-auto max-h-[80%] max-w-[22%] overflow-x-auto'>

@ -12,7 +12,7 @@ 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';
const Header = ({ refresh, ...props }) => {
const Header = ({ refresh, editable, ...props }) => {
const { travel_agency_id, use_year, audit_state } = useParams();
const { t } = useTranslation();
const isPermitted = useAuthStore((state) => state.isPermitted);
@ -24,7 +24,7 @@ const Header = ({ refresh, ...props }) => {
const yearOptions = [];
const currentYear = dayjs().year();
const baseYear = use_year ? Number(use_year === 'all' ? currentYear : use_year) : currentYear;
for (let i = baseYear - 3; i <= baseYear + 3; i++) {
for (let i = baseYear - 5; i <= baseYear + 5; i++) {
yearOptions.push({ label: i, value: i });
}
@ -134,7 +134,9 @@ const Header = ({ refresh, ...props }) => {
{/* <PrintContractPDF /> */}
</RequireAuth>
{/* 编辑 */}
<RequireAuth subject={PERM_PRODUCTS_OFFER_PUT}>
<Divider type='vertical' />
{editable &&
<><RequireAuth subject={PERM_PRODUCTS_OFFER_PUT}>
<Button size='small' type={'primary'} onClick={props.handleNewProduct}>
{t('New')}{t('products:#')}
</Button>
@ -144,6 +146,8 @@ const Header = ({ refresh, ...props }) => {
{t('Submit')}{t('Audit')}
</Button>
</RequireAuth>
</>
}
</div>
);
};

@ -11,22 +11,12 @@ import CitySelector from '@/components/CitySelector';
import { at, isEmpty, pick } from '@/utils/commons';
import ProductInfoForm from './ProductInfoForm';
const ProductInfo = ({ ...props }) => {
const ProductInfo = ({ editable, ...props }) => {
const { t } = useTranslation();
const isPermitted = useAuthStore((state) => state.isPermitted);
const productsTypesMapVal = useProductsTypesMapVal();
const [activeAgency, agencyProducts, editingProduct, setEditingProduct] = useProductsStore((state) => [state.activeAgency, state.agencyProducts, state.editingProduct, state.setEditingProduct]);
const [editable, setEditable] = useState(true);
useEffect(() => {
const notAudit = activeAgency.audit_state_id < 0 || activeAgency.audit_state_id === 3;
const hasAuditPer = isPermitted(PERM_PRODUCTS_OFFER_AUDIT);
const hasEditPer = isPermitted(PERM_PRODUCTS_OFFER_PUT);
setEditable(notAudit && hasEditPer);
// setEditable(true); // test: 0
return () => {};
}, [activeAgency, editingProduct])
const onSave = (err, values, forms) => {
values.travel_agency_id = activeAgency.travel_agency_id;
const poster = {

@ -1,4 +1,4 @@
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { Form, Input, Row, Col, Select, DatePicker, Space, Button, InputNumber, Radio, Checkbox, Divider } from 'antd';
import { objectMapper, at, isEmpty } from '@/utils/commons';
import { DATE_FORMAT, SMALL_DATETIME_FORMAT } from '@/config';
@ -17,11 +17,14 @@ import { useProductsTypesMapVal, useProductsTypesFieldsets } from '@/hooks/usePr
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';
const { RangePicker } = DatePicker;
const InfoForm = ({ formInstance, onSubmit, onReset, onValuesChange, editable, showSubmit, confirmText, formName, loading, ...props }) => {
const { t } = useTranslation('products');
const isPermitted = useAuthStore((state) => state.isPermitted);
const [agencyProducts, editingProduct, setEditingProduct] = useProductsStore((state) => [state.agencyProducts, state.editingProduct, state.setEditingProduct]);
const weekdays = useWeekdays();
const [form] = Form.useForm();
@ -46,6 +49,8 @@ const InfoForm = ({ formInstance, onSubmit, onReset, onValuesChange, editable, s
return () => {};
}, [editingProduct?.info?.id]);
const ignoreEditable = isPermitted(PERM_PRODUCTS_OFFER_AUDIT);
const onFinish = (values) => {
console.log('Received values of form, origin form value: \n', values);
const dest = formValuesMapper(values);
@ -75,7 +80,7 @@ const InfoForm = ({ formInstance, onSubmit, onReset, onValuesChange, editable, s
<>
<Form form={form} disabled={!(editable || false)} name={formName || 'product_info'} onFinish={onFinish} onValuesChange={onIValuesChange} initialValues={editingProduct?.info}>
<Row>
{getFields({ sort, initialValue: editingProduct?.info, hides, shows, fieldProps, fieldComProps, form, t, dataSets: { weekdays }, editable })}
{getFields({ sort, initialValue: editingProduct?.info, hides, shows, fieldProps, fieldComProps, form, t, dataSets: { weekdays }, editable, ignoreEditable })}
{/* {showSubmit && (
<Col flex='1 0 90px' className='flex justify-end items-start'>
<Space align='center'>
@ -88,7 +93,7 @@ const InfoForm = ({ formInstance, onSubmit, onReset, onValuesChange, editable, s
</Row>
{/* <Divider className='my-1' /> */}
<ProductInfoLgc editable={editable} formInstance={form} />
<ProductInfoLgc editable={editable} ignoreEditable={ignoreEditable} formInstance={form} />
<ProductInfoQuotation editable={editable} formInstance={form} />
<Form.Item hidden name={'id'} label={'ID'}>
@ -97,7 +102,7 @@ const InfoForm = ({ formInstance, onSubmit, onReset, onValuesChange, editable, s
{editable && (
<Form.Item>
<div className='flex justify-around'>
<Button type='primary' htmlType='submit'>
<Button type='primary' htmlType='submit' loading={loading}>
{t('common:Save')}
</Button>
</div>
@ -112,10 +117,10 @@ function getFields(props) {
const { fieldProps, fieldComProps, form, t, dataSets } = props;
// console.log('getFields', props.initialValue);
const styleProps = {};
// !props.editable ? {
// variant: 'borderless',
// className: '!text-slate-500',
// } : {};
const editableProps = (name) => {
const disabled = props.ignoreEditable ? false : (isEmpty(props.initialValue?.[name]) && props.editable ? false : true)
return { disabled, className: disabled ? '!text-slate-500' : '' };
}
const bigCol = 4 * 2;
const midCol = 8;
const layoutProps = {
@ -143,15 +148,15 @@ function getFields(props) {
'code',
99,
<Form.Item name='code' label={t('Code')} {...fieldProps.code} _initialValue={at(props, 'initialValue.code')[0]}>
<Input allowClear {...fieldComProps.code} {...styleProps} />
<Input allowClear {...fieldComProps.code} {...styleProps} {...editableProps('code')} />
</Form.Item>,
fieldProps?.code?.col || midCol
),
item(
'city', // todo:
99,
<Form.Item name='city' label={t('City')} {...fieldProps.city} _initialValue={at(props, 'initialValue.city')[0]}>
<CitySelector {...styleProps} />
<Form.Item name='city' label={t('City')} {...fieldProps.city} _initialValue={at(props, 'initialValue.city_id')[0]}>
<CitySelector {...styleProps} {...editableProps('city_id')} />
</Form.Item>,
fieldProps?.city?.col || midCol
),
@ -159,7 +164,7 @@ function getFields(props) {
'dept', // todo:
99,
<Form.Item name='dept' label={t('Dept')} {...fieldProps.dept}>
<DeptSelector labelInValue={false} isLeaf {...styleProps} />
<DeptSelector labelInValue={false} isLeaf {...styleProps} {...editableProps('dept')} />
</Form.Item>,
fieldProps?.dept?.col || midCol
),
@ -167,7 +172,7 @@ function getFields(props) {
'duration',
99,
<Form.Item name='duration' label={t('Duration')} {...fieldProps.duration}>
<InputNumber suffix={'H'} max={24} {...styleProps} />
<InputNumber suffix={'H'} max={24} {...styleProps} {...editableProps('duration')} />
{/* <Input allowClear {...fieldComProps.duration} suffix={'H'} /> */}
</Form.Item>,
fieldProps?.duration?.col || midCol
@ -176,7 +181,7 @@ function getFields(props) {
'km',
99,
<Form.Item name='km' label={t('KM')} {...fieldProps.km}>
<InputNumber suffix={'KM'} min={0.1} {...styleProps} />
<InputNumber suffix={'KM'} min={0.1} {...styleProps} {...editableProps('km')} />
</Form.Item>,
fieldProps?.km?.col || midCol
),
@ -185,7 +190,7 @@ function getFields(props) {
99,
<Form.Item name='recommends_rate' label={t('RecommendsRate')} {...fieldProps.recommends_rate}>
{/* <Input placeholder={t('RecommendsRate')} allowClear /> */}
<Select {...styleProps}
<Select {...styleProps} {...editableProps('recommends_rate')}
style={{ width: '100%' }}
labelInValue
options={[
@ -227,7 +232,7 @@ function getFields(props) {
{ value: '153001', label: '在计划显示,不在报价信显示' },
{ value: 0, label: '计划和报价信都要显示' },
{ value: '153001, 153002', label: '计划和报价信都不用显示' },
]} {...styleProps} />
]} {...styleProps} {...editableProps('display_to_c')} />
</Form.Item>,
fieldProps?.display_to_c?.col || midCol
),
@ -236,7 +241,7 @@ function getFields(props) {
99,
<Form.Item name='open_weekdays' label={t('OpenWeekdays')} initialValue={['1', '2', '3', '4', '5', '6', '7']} {...fieldProps.open_weekdays}>
{/* 默认全部 */}
<Checkbox.Group options={dataSets.weekdays} {...styleProps} />
<Checkbox.Group options={dataSets.weekdays} {...styleProps} {...editableProps('open_weekdays')} />
</Form.Item>,
fieldProps?.open_weekdays?.col || 24
),
@ -244,7 +249,7 @@ function getFields(props) {
'remarks',
99,
<Form.Item name='remarks' label={t('Remarks')} {...fieldProps.remarks}>
<Input.TextArea allowClear rows={2} maxLength={2000} {...fieldComProps.remarks} {...styleProps} />
<Input.TextArea allowClear rows={2} maxLength={2000} {...fieldComProps.remarks} {...styleProps} {...editableProps('remarks')} />
</Form.Item>,
fieldProps?.remarks?.col || 24
),

@ -9,7 +9,7 @@ import { useTranslation } from 'react-i18next';
import { useDefaultLgc } from '@/i18n/LanguageSwitcher';
import { cloneDeep, isEmpty } from '@/utils/commons';
const ProductInfoLgc = ({ editable, formInstance, ...props }) => {
const ProductInfoLgc = ({ editable, ignoreEditable, formInstance, ...props }) => {
const { t } = useTranslation();
const { language: languageHT } = useDefaultLgc();
const [isPermitted, currentUser] = useAuthStore((state) => [state.isPermitted, state.currentUser]);
@ -35,17 +35,17 @@ const ProductInfoLgc = ({ editable, formInstance, ...props }) => {
children: (
<>
<Form.Item name={[li, 'title']} label={t('products:Title')} initialValue={ele.title}>
<Input className=' !text-slate-500'
<Input className={' !text-slate-600'} allowClear
// onChange={(e) => handleChange('title', e.target.value)}
// disabled={isCanEditable}
disabled={!isEmpty(ele.title) || !editable}
disabled={ignoreEditable ? false : (!isEmpty(ele.title) || !editable)}
/>
</Form.Item>
<Form.Item name={[li, 'description']} label={t('products:Description')} initialValue={ele.descriptions}>
<Input.TextArea className='!text-slate-500'
rows={3}
<Input.TextArea className={'!text-slate-600'}
rows={3} allowClear
// onChange={(e) => handleChange('description', e.target.value)}
disabled={!isEmpty(ele.descriptions) || !editable}
disabled={ignoreEditable ? false : (!isEmpty(ele.descriptions) || !editable)}
/>
</Form.Item>
<Form.Item hidden name={[li, 'lgc']} initialValue={ele.lgc}>

Loading…
Cancel
Save