@@ -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', | |||
@@ -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(); | |||
}} /> | |||
</> | |||
); | |||
}); | |||
@@ -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(); | |||
}} /> | |||
</> | |||
); | |||
}); | |||