Просмотр исходного кода

update: goods attribute page

dev
powersir 10 месяцев назад
Родитель
Сommit
3d4ef49b35
3 измененных файлов: 271 добавлений и 15 удалений
  1. +11
    -1
      src/pages/goods/main/attribute/classify.tsx
  2. +130
    -7
      src/pages/goods/main/attribute/colors.tsx
  3. +130
    -7
      src/pages/goods/main/attribute/size.tsx

+ 11
- 1
src/pages/goods/main/attribute/classify.tsx Просмотреть файл

@@ -1,5 +1,5 @@
import React, { useState, useEffect, useRef, useContext, MutableRefObject, forwardRef, useImperativeHandle } from 'react';
import { Space, Table, Button, Input, Select, Divider, Form, Popconfirm, Modal, Radio } from 'antd';
import { Space, Table, Button, Input, Badge, Divider, Form, Popconfirm, Modal, Radio } from 'antd';
import type { TableColumnsType } from 'antd';
import type { InputRef } from 'antd';
import type { FormInstance } from 'antd/es/form';
@@ -274,6 +274,16 @@ export default forwardRef((props, ref) => {
width: '30%',
editable: true,
},
{
title: '是否默认属性',
key: 'isDefault',
dataIndex: 'isDefault',
width: 120,
align: 'center',
render: (value: number) => {
return (value === 1 ? <Badge status="success" text="是" /> : <Badge status="error" text="否" />)
}
},
{
title: '创建时间',
dataIndex: 'createTime',


+ 130
- 7
src/pages/goods/main/attribute/colors.tsx Просмотреть файл

@@ -1,5 +1,5 @@
import React, { useState, useEffect, useRef, useContext, forwardRef, useImperativeHandle } from 'react';
import { Space, Table, Button, Input, Select, Divider, Form, Popconfirm } from 'antd';
import { Space, Table, Button, Input, Modal, Radio, Form, Popconfirm, Badge } from 'antd';
import type { TableColumnsType } from 'antd';
import type { InputRef } from 'antd';
import type { FormInstance } from 'antd/es/form';
@@ -13,6 +13,101 @@ import goodsAttrService from '@/request/service/goods-attr';
import { formatDate } from '@/utils/formatTime';
import { useSetState } from 'ahooks';

const AttrEditor = (props: {
visible: boolean;
onCancel: (flag?: boolean) => void;
onSave: (role: GoodsAttrVO) => void;
}) => {

const { visible, onCancel, onSave } = props;

const { runAsync: createApi } = useRequest(goodsAttrService.createGoodsAttrApi, { manual: true });


const [saveLoading, setSaveLoading] = useState(false);
const [form] = Form.useForm();

useEffect(() => {
if (visible) {
form.setFieldValue("attrStatus", 1);
} else {
form.resetFields();
}
}, [visible]);

const save = async () => {
await form.validateFields();
setSaveLoading(true);
const fieldValues = form.getFieldsValue();
const [error, { msg, code }] = await createApi(fieldValues);
if (!error && code === 0) {
onSave(fieldValues);
} else {
antdUtils.message?.open({
type: 'error',
content: msg ?? '操作失败',
});
}
setSaveLoading(false);
}

return (
<>
<Modal
open={visible}
title={"新建"}
width={640}
onOk={save}
onCancel={() => onCancel()}
confirmLoading={saveLoading}
destroyOnClose
>
<Form
form={form}
onFinish={save}
labelCol={{ flex: '0 0 120px' }}
wrapperCol={{ span: 16 }}
>
<Form.Item name="attrNameCn" label="属性名称(中文):"
rules={[
{
required: true,
message: '请输属性中文名称',
},
]}
>
<Input />
</Form.Item>
<Form.Item name="attrNameEn" label="属性名称(英文):"
rules={[
{
required: true,
message: '请输属性英文名称',
},
]}
>
<Input />
</Form.Item>
<Form.Item name="attrStatus" label="可用状态:"
rules={[
{
required: true,
message: '请输选择',
},
]}
>
<Radio.Group options={[
{ value: 1, label: "正常使用" },
{ value: 2, label: "停止使用" }
]} optionType="default">
</Radio.Group>
</Form.Item>
</Form>
</Modal>
</>
)
};

const EditableContext = React.createContext<FormInstance<any> | null>(null);

interface EditableRowProps {
@@ -106,7 +201,8 @@ type ColumnTypes = Exclude<EditableTableProps['columns'], undefined>;
export default forwardRef((props, ref) => {
useImperativeHandle(ref, () => {
addItem
})
});
const [visible, setVisible] = useState<boolean>(false);
const [dataSource, setDataSource] = useState<GoodsAttrVO[]>([]);
const [searchFrom] = Form.useForm();

@@ -124,9 +220,10 @@ export default forwardRef((props, ref) => {
const { runAsync: deleteApi } = useRequest(goodsAttrService.deleteGoodsAttrApi, { manual: true });

const load = async () => {
const [error, { data }] = await getPageApi(searchFrom.getFieldsValue());
const [error, { data }] = await getPageApi(searchState);
if (!error) {
setDataSource(data.list);
setTotal(data.total);
}
};

@@ -196,6 +293,16 @@ export default forwardRef((props, ref) => {
width: '30%',
editable: true,
},
{
title: '状态',
key: 'attrStatus',
dataIndex: 'attrStatus',
width: 100,
align: 'center',
render: (value: number) => {
return (value === 1 ? <Badge status="success" text="已开启" /> : <Badge status="error" text="已关闭" />)
}
},
{
title: '创建时间',
dataIndex: 'createTime',
@@ -209,9 +316,9 @@ export default forwardRef((props, ref) => {
title: t("QkOmYwne" /* 操作 */),
dataIndex: 'operation',
key: 'action',
render: (value: GoodsAttrVO) =>
render: (_, record, index) =>
dataSource.length >= 1 ? (
<Popconfirm title="确认要将该属性删除吗?" onConfirm={() => deleteItem(value)}>
<Popconfirm title="确认要将该属性删除吗?" onConfirm={() => deleteItem(dataSource[index])}>
<a>删除</a>
</Popconfirm>
) : null,
@@ -260,7 +367,7 @@ export default forwardRef((props, ref) => {

useEffect(() => {
load();
}, []);
}, [searchState]);

const onReset = () => {
searchFrom.resetFields()
@@ -271,7 +378,7 @@ export default forwardRef((props, ref) => {
<>
<div>
<div className='flex flex-row-reverse mb-2'>
<Button type='primary' size='large' icon={<PlusOutlined />} > 新增颜色 </Button>
<Button type='primary' size='large' icon={<PlusOutlined />} onClick={() => { setVisible(true) }}> 新增颜色 </Button>
</div>
<Table rowKey="id"
scroll={{ x: true }}
@@ -279,6 +386,15 @@ export default forwardRef((props, ref) => {
dataSource={dataSource}
components={components}
rowClassName={() => 'editable-row'}
onChange={async (pagination, filters) => {
const state: GoodsAttrPageReqVO = {
attrNameCn: filters.attrNameCn ? filters.attrNameCn[0] as string : undefined,
attrNameEn: filters.attrNameEn ? filters.attrNameEn[0] as string : undefined,
pageNo: pagination.current ?? 1,
pageSize: pagination.pageSize
}
setSearchState(state);
}}
pagination={{
position: ['bottomRight'],
current: searchState.pageNo,
@@ -286,6 +402,13 @@ export default forwardRef((props, ref) => {
total
}} />
</div>
<AttrEditor
visible={visible}
onCancel={() => { setVisible(false) }}
onSave={(data: GoodsAttrVO) => {
setVisible(false);
load();
}} />
</>
);
});


+ 130
- 7
src/pages/goods/main/attribute/size.tsx Просмотреть файл

@@ -1,5 +1,5 @@
import React, { useState, useEffect, useRef, useContext, forwardRef, useImperativeHandle } from 'react';
import { Space, Table, Button, Input, Select, Divider, Form, Popconfirm } from 'antd';
import { Space, Table, Button, Input, Modal, Radio, Form, Popconfirm, Badge } from 'antd';
import type { TableColumnsType } from 'antd';
import type { InputRef } from 'antd';
import type { FormInstance } from 'antd/es/form';
@@ -13,6 +13,101 @@ import goodsAttrService from '@/request/service/goods-attr';
import { formatDate } from '@/utils/formatTime';
import { useSetState } from 'ahooks';

const AttrEditor = (props: {
visible: boolean;
onCancel: (flag?: boolean) => void;
onSave: (role: GoodsAttrVO) => void;
}) => {

const { visible, onCancel, onSave } = props;

const { runAsync: createApi } = useRequest(goodsAttrService.createGoodsAttrApi, { manual: true });


const [saveLoading, setSaveLoading] = useState(false);
const [form] = Form.useForm();

useEffect(() => {
if (visible) {
form.setFieldValue("attrStatus", 1);
} else {
form.resetFields();
}
}, [visible]);

const save = async () => {
await form.validateFields();
setSaveLoading(true);
const fieldValues = form.getFieldsValue();
const [error, { msg, code }] = await createApi(fieldValues);
if (!error && code === 0) {
onSave(fieldValues);
} else {
antdUtils.message?.open({
type: 'error',
content: msg ?? '操作失败',
});
}
setSaveLoading(false);
}

return (
<>
<Modal
open={visible}
title={"新建"}
width={640}
onOk={save}
onCancel={() => onCancel()}
confirmLoading={saveLoading}
destroyOnClose
>
<Form
form={form}
onFinish={save}
labelCol={{ flex: '0 0 120px' }}
wrapperCol={{ span: 16 }}
>
<Form.Item name="attrNameCn" label="属性名称(中文):"
rules={[
{
required: true,
message: '请输属性中文名称',
},
]}
>
<Input />
</Form.Item>
<Form.Item name="attrNameEn" label="属性名称(英文):"
rules={[
{
required: true,
message: '请输属性英文名称',
},
]}
>
<Input />
</Form.Item>
<Form.Item name="attrStatus" label="可用状态:"
rules={[
{
required: true,
message: '请输选择',
},
]}
>
<Radio.Group options={[
{ value: 1, label: "正常使用" },
{ value: 2, label: "停止使用" }
]} optionType="default">
</Radio.Group>
</Form.Item>
</Form>
</Modal>
</>
)
};

const EditableContext = React.createContext<FormInstance<any> | null>(null);

interface EditableRowProps {
@@ -106,7 +201,8 @@ type ColumnTypes = Exclude<EditableTableProps['columns'], undefined>;
export default forwardRef((props, ref) => {
useImperativeHandle(ref, () => {
addItem
})
});
const [visible, setVisible] = useState<boolean>(false);
const [dataSource, setDataSource] = useState<GoodsAttrVO[]>([]);
const [searchFrom] = Form.useForm();

@@ -124,9 +220,10 @@ export default forwardRef((props, ref) => {
const { runAsync: deleteApi } = useRequest(goodsAttrService.deleteGoodsAttrApi, { manual: true });

const load = async () => {
const [error, { data }] = await getPageApi(searchFrom.getFieldsValue());
const [error, { data }] = await getPageApi(searchState);
if (!error) {
setDataSource(data.list);
setTotal(data.total);
}
};

@@ -196,6 +293,16 @@ export default forwardRef((props, ref) => {
width: '30%',
editable: true,
},
{
title: '状态',
key: 'attrStatus',
dataIndex: 'attrStatus',
width: 100,
align: 'center',
render: (value: number) => {
return (value === 1 ? <Badge status="success" text="已开启" /> : <Badge status="error" text="已关闭" />)
}
},
{
title: '创建时间',
dataIndex: 'createTime',
@@ -209,9 +316,9 @@ export default forwardRef((props, ref) => {
title: t("QkOmYwne" /* 操作 */),
dataIndex: 'operation',
key: 'action',
render: (value: GoodsAttrVO) =>
render: (_, record, index) =>
dataSource.length >= 1 ? (
<Popconfirm title="确认要将该属性删除吗?" onConfirm={() => deleteItem(value)}>
<Popconfirm title="确认要将该属性删除吗?" onConfirm={() => deleteItem(dataSource[index])}>
<a>删除</a>
</Popconfirm>
) : null,
@@ -260,7 +367,7 @@ export default forwardRef((props, ref) => {

useEffect(() => {
load();
}, []);
}, [searchState]);

const onReset = () => {
searchFrom.resetFields()
@@ -271,7 +378,7 @@ export default forwardRef((props, ref) => {
<>
<div>
<div className='flex flex-row-reverse mb-2'>
<Button type='primary' size='large' icon={<PlusOutlined />} > 新增尺码 </Button>
<Button type='primary' size='large' icon={<PlusOutlined />} onClick={() => { setVisible(true) }}> 新增尺码 </Button>
</div>
<Table rowKey="id"
scroll={{ x: true }}
@@ -279,6 +386,15 @@ export default forwardRef((props, ref) => {
dataSource={dataSource}
components={components}
rowClassName={() => 'editable-row'}
onChange={async (pagination, filters) => {
const state: GoodsAttrPageReqVO = {
attrNameCn: filters.attrNameCn ? filters.attrNameCn[0] as string : undefined,
attrNameEn: filters.attrNameEn ? filters.attrNameEn[0] as string : undefined,
pageNo: pagination.current ?? 1,
pageSize: pagination.pageSize
}
setSearchState(state);
}}
pagination={{
position: ['bottomRight'],
current: searchState.pageNo,
@@ -286,6 +402,13 @@ export default forwardRef((props, ref) => {
total
}} />
</div>
<AttrEditor
visible={visible}
onCancel={() => { setVisible(false) }}
onSave={(data: GoodsAttrVO) => {
setVisible(false);
load();
}} />
</>
);
});


Загрузка…
Отмена
Сохранить