|
@@ -1,5 +1,5 @@ |
|
|
import React, { useState, useEffect, useRef, useContext, MutableRefObject, forwardRef, useImperativeHandle } from 'react'; |
|
|
import React, { useState, useEffect, useRef, useContext, MutableRefObject, forwardRef, useImperativeHandle } from 'react'; |
|
|
import { Space, Table, Button, Input, Select, Divider, Form, Popconfirm } from 'antd'; |
|
|
|
|
|
|
|
|
import { Space, Table, Button, Input, Select, Divider, Form, Popconfirm, Modal, Radio } from 'antd'; |
|
|
import type { TableColumnsType } from 'antd'; |
|
|
import type { TableColumnsType } from 'antd'; |
|
|
import type { InputRef } from 'antd'; |
|
|
import type { InputRef } from 'antd'; |
|
|
import type { FormInstance } from 'antd/es/form'; |
|
|
import type { FormInstance } from 'antd/es/form'; |
|
@@ -13,16 +13,101 @@ import goodsClassifyService from '@/request/service/goods-classify'; |
|
|
import { formatDate } from '@/utils/formatTime'; |
|
|
import { formatDate } from '@/utils/formatTime'; |
|
|
import { useSetState } from 'ahooks'; |
|
|
import { useSetState } from 'ahooks'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const CreateClassify = (props: { |
|
|
|
|
|
visible: boolean; |
|
|
|
|
|
onCancel: (flag?: boolean) => void; |
|
|
|
|
|
onSave: (role: GoodsClassifyVO) => void; |
|
|
|
|
|
}) => { |
|
|
|
|
|
|
|
|
|
|
|
const { visible, onCancel, onSave } = props; |
|
|
|
|
|
|
|
|
|
|
|
const { runAsync: createApi } = useRequest(goodsClassifyService.createGoodsClassifyApi, { manual: true }); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const [saveLoading, setSaveLoading] = useState(false); |
|
|
|
|
|
const [form] = Form.useForm(); |
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
|
if (visible) { |
|
|
|
|
|
form.setFieldValue("isDefault", 1); |
|
|
|
|
|
} else { |
|
|
|
|
|
form.resetFields(); |
|
|
|
|
|
} |
|
|
|
|
|
}, [visible]); |
|
|
|
|
|
|
|
|
|
|
|
const save = async () => { |
|
|
|
|
|
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} |
|
|
|
|
|
// layout={{ |
|
|
|
|
|
// labelCol: { span: 4, }, |
|
|
|
|
|
// wrapperCol: { span: 16 } |
|
|
|
|
|
// }} |
|
|
|
|
|
onFinish={save} |
|
|
|
|
|
labelCol={{ flex: '0 0 100px' }} |
|
|
|
|
|
wrapperCol={{ span: 16 }} |
|
|
|
|
|
> |
|
|
|
|
|
<Form.Item name="classifyName" label="分类名称:" |
|
|
|
|
|
rules={[ |
|
|
|
|
|
{ |
|
|
|
|
|
required: true, |
|
|
|
|
|
message: '请输分类名称', |
|
|
|
|
|
}, |
|
|
|
|
|
]} |
|
|
|
|
|
> |
|
|
|
|
|
<Input /> |
|
|
|
|
|
</Form.Item> |
|
|
|
|
|
<Form.Item name="isDefault" 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); |
|
|
const EditableContext = React.createContext<FormInstance<any> | null>(null); |
|
|
|
|
|
|
|
|
interface EditableRowProps { |
|
|
interface EditableRowProps { |
|
|
index: number; |
|
|
index: number; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
type ClassifyProps = { |
|
|
|
|
|
ref: MutableRefObject<any> |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const EditableRow: React.FC<EditableRowProps> = ({ index, ...props }) => { |
|
|
const EditableRow: React.FC<EditableRowProps> = ({ index, ...props }) => { |
|
|
const [form] = Form.useForm(); |
|
|
const [form] = Form.useForm(); |
|
|
return ( |
|
|
return ( |
|
@@ -41,6 +126,7 @@ interface EditableCellProps { |
|
|
dataIndex: keyof GoodsClassifyVO; |
|
|
dataIndex: keyof GoodsClassifyVO; |
|
|
record: GoodsClassifyVO; |
|
|
record: GoodsClassifyVO; |
|
|
handleSave: (record: GoodsClassifyVO) => void; |
|
|
handleSave: (record: GoodsClassifyVO) => void; |
|
|
|
|
|
onEditing: (record: GoodsClassifyVO) => void; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const EditableCell: React.FC<EditableCellProps> = ({ |
|
|
const EditableCell: React.FC<EditableCellProps> = ({ |
|
@@ -108,11 +194,8 @@ type EditableTableProps = Parameters<typeof Table>[0]; |
|
|
type ColumnTypes = Exclude<EditableTableProps['columns'], undefined>; |
|
|
type ColumnTypes = Exclude<EditableTableProps['columns'], undefined>; |
|
|
|
|
|
|
|
|
export default forwardRef((props, ref) => { |
|
|
export default forwardRef((props, ref) => { |
|
|
useImperativeHandle(ref, () => { |
|
|
|
|
|
add: () => { |
|
|
|
|
|
console.log("add") |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
//TODO: pagination |
|
|
|
|
|
const [visible, setVisible] = useState<boolean>(false); |
|
|
const [dataSource, setDataSource] = useState<GoodsClassifyVO[]>([]); |
|
|
const [dataSource, setDataSource] = useState<GoodsClassifyVO[]>([]); |
|
|
const [searchFrom] = Form.useForm(); |
|
|
const [searchFrom] = Form.useForm(); |
|
|
|
|
|
|
|
@@ -133,35 +216,18 @@ export default forwardRef((props, ref) => { |
|
|
const [error, { data }] = await getPageApi(searchFrom.getFieldsValue()); |
|
|
const [error, { data }] = await getPageApi(searchFrom.getFieldsValue()); |
|
|
if (!error) { |
|
|
if (!error) { |
|
|
setDataSource(data.list); |
|
|
setDataSource(data.list); |
|
|
|
|
|
setTotal(data.total); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
const showDeleteConfirm = (data: GoodsClassifyVO) => { |
|
|
|
|
|
antdUtils.modal?.confirm({ |
|
|
|
|
|
title: '确认要将该分类删除吗?', |
|
|
|
|
|
icon: <ExclamationCircleFilled />, |
|
|
|
|
|
content: '请注意删除以后不可恢复!', |
|
|
|
|
|
okText: '删除', |
|
|
|
|
|
okType: 'danger', |
|
|
|
|
|
cancelText: '取消', |
|
|
|
|
|
onOk() { |
|
|
|
|
|
return new Promise(async (resolve) => { |
|
|
|
|
|
const [error, { code, msg }] = await deleteApi(data.id); |
|
|
|
|
|
if (error || code !== 0) { |
|
|
|
|
|
antdUtils.message?.open({ type: 'error', content: msg ?? '操作失败' }) |
|
|
|
|
|
} else { |
|
|
|
|
|
antdUtils.message?.open({ type: 'success', content: '删除成功' }) |
|
|
|
|
|
} |
|
|
|
|
|
await load(); |
|
|
|
|
|
resolve('') |
|
|
|
|
|
}).catch(() => antdUtils.message?.open({ |
|
|
|
|
|
type: 'error', |
|
|
|
|
|
content: '操作失败', |
|
|
|
|
|
})); |
|
|
|
|
|
}, |
|
|
|
|
|
onCancel() { |
|
|
|
|
|
}, |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
const deleteItem = async (data: GoodsClassifyVO) => { |
|
|
|
|
|
const [error, { code, msg }] = await deleteApi(data.id); |
|
|
|
|
|
if (error || code !== 0) { |
|
|
|
|
|
antdUtils.message?.open({ type: 'error', content: msg ?? '操作失败' }); |
|
|
|
|
|
} else { |
|
|
|
|
|
antdUtils.message?.open({ type: 'success', content: '删除成功' }); |
|
|
|
|
|
} |
|
|
|
|
|
await load(); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
const getColumnSearchProps = (placeholder: string): ColumnType<GoodsClassifyVO> => ({ |
|
|
const getColumnSearchProps = (placeholder: string): ColumnType<GoodsClassifyVO> => ({ |
|
@@ -221,9 +287,9 @@ export default forwardRef((props, ref) => { |
|
|
title: t("QkOmYwne" /* 操作 */), |
|
|
title: t("QkOmYwne" /* 操作 */), |
|
|
dataIndex: 'operation', |
|
|
dataIndex: 'operation', |
|
|
key: 'action', |
|
|
key: 'action', |
|
|
render: (value: GoodsClassifyVO) => |
|
|
|
|
|
|
|
|
render: (_, record, index) => |
|
|
dataSource.length >= 1 ? ( |
|
|
dataSource.length >= 1 ? ( |
|
|
<Popconfirm title="确认要将该分类删除吗?" onConfirm={() => showDeleteConfirm(value)}> |
|
|
|
|
|
|
|
|
<Popconfirm title="确认要将该分类删除吗?" onConfirm={() => deleteItem(dataSource[index])}> |
|
|
<a>删除</a> |
|
|
<a>删除</a> |
|
|
</Popconfirm> |
|
|
</Popconfirm> |
|
|
) : null, |
|
|
) : null, |
|
@@ -243,6 +309,7 @@ export default forwardRef((props, ref) => { |
|
|
dataIndex: col.dataIndex, |
|
|
dataIndex: col.dataIndex, |
|
|
title: col.title, |
|
|
title: col.title, |
|
|
handleSave, |
|
|
handleSave, |
|
|
|
|
|
|
|
|
}), |
|
|
}), |
|
|
}; |
|
|
}; |
|
|
}); |
|
|
}); |
|
@@ -276,18 +343,37 @@ export default forwardRef((props, ref) => { |
|
|
|
|
|
|
|
|
const onReset = () => { |
|
|
const onReset = () => { |
|
|
searchFrom.resetFields() |
|
|
searchFrom.resetFields() |
|
|
load() |
|
|
|
|
|
|
|
|
load(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return ( |
|
|
return ( |
|
|
<> |
|
|
<> |
|
|
<div> |
|
|
<div> |
|
|
|
|
|
<div className='flex justify-between content-center mb-2'> |
|
|
|
|
|
<div className='flex justify-normal items-center'> |
|
|
|
|
|
<Form layout='inline' form={searchFrom}> |
|
|
|
|
|
<Form.Item name="classifyName" label="分类名称"> |
|
|
|
|
|
<Input className='w-[150px]' placeholder='请输入名称' allowClear /> |
|
|
|
|
|
</Form.Item> |
|
|
|
|
|
</Form> |
|
|
|
|
|
<Space.Compact className="ml-5"> |
|
|
|
|
|
<Button type='primary' size='large' icon={<SearchOutlined />} onClick={load}> 搜索 </Button> |
|
|
|
|
|
<Button type='primary' size='large' icon={<UndoOutlined />} onClick={onReset}> 重置 </Button> |
|
|
|
|
|
</Space.Compact> |
|
|
|
|
|
</div> |
|
|
|
|
|
<Button type='primary' size='large' icon={<PlusOutlined />} onClick={() => { |
|
|
|
|
|
setVisible(true); |
|
|
|
|
|
}}> 新增分类 </Button> |
|
|
|
|
|
</div> |
|
|
<Table rowKey="id" |
|
|
<Table rowKey="id" |
|
|
scroll={{ x: true }} |
|
|
scroll={{ x: true }} |
|
|
columns={columns as ColumnTypes} |
|
|
columns={columns as ColumnTypes} |
|
|
dataSource={dataSource} |
|
|
dataSource={dataSource} |
|
|
components={components} |
|
|
components={components} |
|
|
rowClassName={() => 'editable-row'} |
|
|
rowClassName={() => 'editable-row'} |
|
|
|
|
|
onChange={(pagination) => { |
|
|
|
|
|
|
|
|
|
|
|
}} |
|
|
pagination={{ |
|
|
pagination={{ |
|
|
position: ['bottomRight'], |
|
|
position: ['bottomRight'], |
|
|
current: searchState.pageNo, |
|
|
current: searchState.pageNo, |
|
@@ -295,6 +381,17 @@ export default forwardRef((props, ref) => { |
|
|
total |
|
|
total |
|
|
}} /> |
|
|
}} /> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<CreateClassify |
|
|
|
|
|
visible={visible} |
|
|
|
|
|
onCancel={() => { |
|
|
|
|
|
setVisible(false); |
|
|
|
|
|
}} |
|
|
|
|
|
onSave={(values: GoodsClassifyVO) => { |
|
|
|
|
|
console.log(values) |
|
|
|
|
|
setVisible(false); |
|
|
|
|
|
load(); |
|
|
|
|
|
}} |
|
|
|
|
|
/> |
|
|
</> |
|
|
</> |
|
|
); |
|
|
); |
|
|
}); |
|
|
}); |
|
|