@@ -1,6 +1,6 @@ | |||
import React, { useEffect, useState } from 'react' | |||
import { Form, Input, InputNumber, Modal } from 'antd'; | |||
import dictService from '@/request/service/template-dict'; | |||
import dictService from '@/request/service/template-dict-detail'; | |||
import { useRequest } from '@/hooks/use-request'; | |||
import type { DataDictDetailVO } from '@/models' | |||
import { antdUtils } from '@/utils/antd'; | |||
@@ -14,13 +14,14 @@ export default (props: { | |||
visible: boolean; | |||
onCancel: (flag?: boolean) => void; | |||
onSave: (role: DataDictDetailVO) => void; | |||
dictId?: number; | |||
data?: DataDictDetailVO | null; | |||
}) => { | |||
const { visible, onCancel, onSave, data } = props; | |||
const { visible, onCancel, onSave, dictId, data } = props; | |||
const { runAsync: updateApi } = useRequest(dictService.updateDictDetailApi, { manual: true }); | |||
const { runAsync: createApi } = useRequest(dictService.deleteDictDetailApi, { manual: true }); | |||
const { runAsync: updateApi } = useRequest(dictService.updateApi, { manual: true }); | |||
const { runAsync: createApi } = useRequest(dictService.createApi, { manual: true }); | |||
const isEdit = !!data; | |||
@@ -41,7 +42,7 @@ export default (props: { | |||
const save = async () => { | |||
setSaveLoading(true); | |||
const fieldValues = form.getFieldsValue(); | |||
const newValue = isEdit ? { ...data, ...fieldValues } : fieldValues; | |||
const newValue = isEdit ? { ...data, ...fieldValues } : {...fieldValues, dictId}; | |||
const [error, { msg, code }] = isEdit ? await updateApi(newValue) : await createApi(newValue); | |||
if (!error && code === 0) { | |||
onSave(newValue); | |||
@@ -0,0 +1,157 @@ | |||
import React, { useState, useRef, useEffect, forwardRef, useImperativeHandle } from 'react'; | |||
import { Space, Table, Button, Image, Divider, Card, Input } from 'antd'; | |||
import type { InputRef } from 'antd'; | |||
import type { ColumnsType } from 'antd/es/table'; | |||
import { t } from '@/utils/i18n'; | |||
import { PlusOutlined, ExclamationCircleFilled, DeleteOutlined, SearchOutlined } from '@ant-design/icons'; | |||
import { antdUtils } from '@/utils/antd'; | |||
import { useRequest } from '@/hooks/use-request'; | |||
import { DataDictVO, DataDictDetailVO } from '@/models'; | |||
import DictDetailEditor from './dict-detail-editor'; | |||
import templateDictDetailService from '@/request/service/template-dict-detail'; | |||
export interface DictDetailRef { | |||
updateDictData: (dictData: DataDictVO) => void; | |||
} | |||
export default forwardRef((props, ref) => { | |||
const [dict, setDict] = useState<DataDictVO>(); | |||
const [dictDetail, setDictDetail] = useState<DataDictDetailVO[]>(); | |||
const [total, setTotal] = useState(0); | |||
const [detailEditorVisable, seEdtailEditorVisable] = useState<boolean>(false); | |||
const [editDetailData, seEditDetailData] = useState<DataDictDetailVO | null>(); | |||
const { runAsync: getPageApi } = useRequest(templateDictDetailService.getPageApi, { manual: true }); | |||
const { runAsync: deleteApi } = useRequest(templateDictDetailService.deleteApi, { manual: true }); | |||
useImperativeHandle(ref, () => ({ | |||
updateDictData: (dictData: DataDictVO) => { | |||
setDict(dictData); | |||
}, | |||
})); | |||
const load = async () => { | |||
//TODO: setup pagenation | |||
const [error, { data }] = await getPageApi({ dictId: dict?.id }); | |||
if (!error) { | |||
setDictDetail(data.list); | |||
setTotal(data.total); | |||
} | |||
} | |||
useEffect(() => { | |||
if (dict) { | |||
load(); | |||
} | |||
}, [dict]); | |||
const showDeleteConfirm = (item: DataDictDetailVO) => { | |||
antdUtils.modal?.confirm({ | |||
title: `确认删除标签为: ${item.label} 的字典吗?`, | |||
icon: <ExclamationCircleFilled />, | |||
content: '请注意删除以后不可恢复!', | |||
okText: '删除', | |||
okType: 'danger', | |||
cancelText: '取消', | |||
onOk: async () => { | |||
const [error, { code, msg }] = await deleteApi(item.id); | |||
if (error || code !== 0) { | |||
antdUtils.message?.open({ type: 'error', content: msg ?? '操作失败' }) | |||
} else { | |||
antdUtils.message?.open({ type: 'success', content: '删除成功' }) | |||
} | |||
await load(); | |||
}, | |||
onCancel() { | |||
}, | |||
}); | |||
}; | |||
const columns: ColumnsType<DataDictDetailVO> = [ | |||
{ | |||
title: '字典标签', | |||
dataIndex: 'label', | |||
key: 'label', | |||
align: 'center', | |||
width: 150, | |||
}, | |||
{ | |||
title: '字典值', | |||
key: 'value', | |||
dataIndex: 'value', | |||
align: 'center', | |||
}, | |||
{ | |||
title: '排序', | |||
key: 'dictSort', | |||
dataIndex: 'dictSort', | |||
width: 100, | |||
}, | |||
{ | |||
title: t("QkOmYwne" /* 操作 */), | |||
key: 'action', | |||
render: (_, record) => ( | |||
<Space size="middle" split={( | |||
<Divider type='vertical' /> | |||
)}> | |||
<a | |||
onClick={() => { | |||
seEditDetailData(record); | |||
seEdtailEditorVisable(true); | |||
}}> | |||
编辑 | |||
</a> | |||
<a | |||
onClick={() => { | |||
showDeleteConfirm(record) | |||
}}> | |||
删除 | |||
</a> | |||
</Space> | |||
), | |||
width: 150, | |||
}, | |||
]; | |||
return ( | |||
<> | |||
<div> | |||
<Card className='basis-3/5 mb-[10px] ml-[10px] dark:bg-[rgb(33,41,70)] bg-white roundle-lg px[12px]' bodyStyle={{ | |||
paddingTop: 0, | |||
paddingBottom: 0 | |||
}}> | |||
<div className="py-[8px] flex justify-between w-full"> | |||
<div className='py-[5px]'> | |||
{dict? <span className='text-center text-lg font-semibold'>所属字典: {dict?.name}</span> : null} | |||
</div> | |||
<Button className="ml-5" type='primary' size='middle' | |||
icon={<PlusOutlined />} | |||
onClick={() => { | |||
seEditDetailData(null); | |||
seEdtailEditorVisable(true); | |||
}} | |||
disabled={!dict}> 新增 </Button> | |||
</div> | |||
<Table rowKey="id" scroll={{ x: true }} columns={columns} dataSource={dictDetail} className='bg-transparent' | |||
pagination={{ position: ['bottomRight'] }} | |||
/> | |||
</Card> | |||
</div> | |||
<DictDetailEditor | |||
onSave={() => { | |||
load(); | |||
seEdtailEditorVisable(false); | |||
}} | |||
onCancel={() => { seEdtailEditorVisable(false) }} | |||
visible={detailEditorVisable} | |||
data={editDetailData} | |||
dictId={dict?.id} | |||
/> | |||
</> | |||
); | |||
}); |
@@ -11,111 +11,8 @@ import { DataDictVO, DataDictDetailVO } from '@/models'; | |||
import DictEditor from './dict-editor'; | |||
import DictDetailEditor from './dict-detail-editor'; | |||
import templateDictService from '@/request/service/template-dict'; | |||
// const dataDicts: DataDictVO[] = [ | |||
// { | |||
// "id": 43, | |||
// "name": "爆款词", | |||
// "description": "爆款词" | |||
// }, | |||
// { | |||
// "id": 42, | |||
// "name": "T-T", | |||
// "description": "t-shirt" | |||
// }, | |||
// { | |||
// "id": 41, | |||
// "name": "T-shirt Background", | |||
// "description": "T桖背景" | |||
// } | |||
// ] | |||
const dictDetailsA: DataDictDetailVO[] = [ | |||
{ | |||
"id": 114, | |||
"dictId": 43, | |||
"label": "tshirt for women", | |||
"value": "tshirt for women", | |||
"dictSort": 1 | |||
}, | |||
{ | |||
"id": 113, | |||
"dictId": 43, | |||
"label": "oversize t shirt black", | |||
"value": "oversize t shirt black", | |||
"dictSort": 1 | |||
}, | |||
{ | |||
"id": 112, | |||
"dictId": 43, | |||
"label": "oversize t shirt", | |||
"value": "oversize t shirt", | |||
"dictSort": 1 | |||
} | |||
] | |||
const dictDetailsB: DataDictDetailVO[] = [ | |||
{ | |||
"id": 107, | |||
"dictId": 42, | |||
"label": "three", | |||
"value": "three", | |||
"dictSort": 3 | |||
}, | |||
{ | |||
"id": 106, | |||
"dictId": 42, | |||
"label": "two", | |||
"value": "two", | |||
"dictSort": 2 | |||
}, | |||
{ | |||
"id": 105, | |||
"dictId": 42, | |||
"label": "one", | |||
"value": "one", | |||
"dictSort": 1 | |||
} | |||
] | |||
const dictDetailsC: DataDictDetailVO[] = [ | |||
{ | |||
"id": 111, | |||
"dictId": 41, | |||
"label": "Soothing hot springs", | |||
"value": "Hot spring photos, hot spring water, beautiful scenery, no one, film quality, 8K, meticulous", | |||
"dictSort": 5 | |||
}, | |||
{ | |||
"id": 110, | |||
"dictId": 41, | |||
"label": "Great Eiffel Tower", | |||
"value": "Keywords Paris Tower, photo, high quality, 8K,", | |||
"dictSort": 4 | |||
}, | |||
{ | |||
"id": 109, | |||
"dictId": 41, | |||
"label": "Iconic Eiffel Tower", | |||
"value": "Keywords Paris Tower, photo, high quality, 8K,", | |||
"dictSort": 3 | |||
}, | |||
{ | |||
"id": 108, | |||
"dictId": 41, | |||
"label": "Pleasant Tunisia", | |||
"value": "Venice, photos, high quality, 8K, water, details, film quality, rendering, beautiful scenery.", | |||
"dictSort": 2 | |||
}, | |||
{ | |||
"id": 104, | |||
"dictId": 41, | |||
"label": "Trendy Tunisia", | |||
"value": "Venice, photos, high quality, 8K, water, details, film quality, rendering, beautiful scenery.", | |||
"dictSort": 1 | |||
} | |||
] | |||
import DictDetail from './dict-detail'; | |||
import type { DictDetailRef } from './dict-detail' | |||
export default () => { | |||
@@ -129,6 +26,8 @@ export default () => { | |||
const [detailEditorVisable, seEdtailEditorVisable] = useState<boolean>(false); | |||
const [editDetailData, seEditDetailData] = useState<DataDictDetailVO>(); | |||
const detailRef = useRef<DictDetailRef>() | |||
//获取字典分页数据 | |||
const { runAsync: getDictPageApi } = useRequest(templateDictService.getDictPageApi, { manual: true }); | |||
//删除字典数据 | |||
@@ -218,13 +117,7 @@ export default () => { | |||
const updateDactDetail = (data: DataDictVO) => { | |||
if (data.id == 43) { | |||
setDictDetail(dictDetailsA) | |||
} else if (data.id == 42) { | |||
setDictDetail(dictDetailsB) | |||
} else { | |||
setDictDetail(dictDetailsC) | |||
} | |||
detailRef.current?.updateDictData(data) | |||
} | |||
@@ -293,17 +186,10 @@ export default () => { | |||
pagination={{ position: ['bottomRight'] }} | |||
/> | |||
</Card> | |||
<Card className='basis-3/5 mb-[10px] ml-[10px] dark:bg-[rgb(33,41,70)] bg-white roundle-lg px[12px]' bodyStyle={{ | |||
paddingTop: 0, | |||
paddingBottom: 0 | |||
}}> | |||
<div className="py-[8px] flex flex-row-reverse"> | |||
<Button className="ml-5" type='primary' size='middle' icon={<PlusOutlined />}> 新增 </Button> | |||
</div> | |||
<Table rowKey="id" scroll={{ x: true }} columns={columns} dataSource={dictDetail} className='bg-transparent' | |||
pagination={{ position: ['bottomRight'] }} | |||
/> | |||
</Card> | |||
<div className='basis-3/5 '> | |||
<DictDetail ref={detailRef}/> | |||
</div> | |||
</div> | |||
<DictEditor | |||
onSave={() => { | |||