Browse Source

update:template dict-data page

dev
powersir 11 months ago
parent
commit
dc22944a36
3 changed files with 213 additions and 198 deletions
  1. +202
    -0
      src/pages/custom/template/dict/dict-data.tsx
  2. +1
    -1
      src/pages/custom/template/dict/dict-detail.tsx
  3. +10
    -197
      src/pages/custom/template/dict/index.tsx

+ 202
- 0
src/pages/custom/template/dict/dict-data.tsx View File

@@ -0,0 +1,202 @@
import React, { useState, useEffect, useRef } from 'react';
import { useSetState } from 'ahooks';
import { Space, Table, Button, Divider, Card, Input } from 'antd';
import type { InputRef } from 'antd';
import type { ColumnsType, ColumnType, TableProps } from 'antd/es/table';
import { t } from '@/utils/i18n';
import { PlusOutlined, ExclamationCircleFilled, SearchOutlined } from '@ant-design/icons';
import { antdUtils } from '@/utils/antd';
import { useRequest } from '@/hooks/use-request';
import { DataDictVO, DataDictPageReqVO } from '@/models';
import DictEditor from './dict-editor';
import templateDictService from '@/request/service/template-dict';

export default (props: {
onSelectItem: (item: DataDictVO) => void;
}) => {
const { onSelectItem } = props;
const [dataDicts, setDataDicts] = useState<DataDictVO[]>();
const [searchState, setSearchState] = useSetState<DataDictPageReqVO>({
pageNo: 1,
pageSize: 10
});
const [total, setTotal] = useState(0)
const searchInput = useRef<InputRef>(null);
const [onSearching, setOnSearching] = useState(false);

const [editorVisable, seEditorVisable] = useState<boolean>(false);
const [editData, seEditData] = useState<DataDictVO>();

//获取字典分页数据
const { runAsync: getDictPageApi } = useRequest(templateDictService.getDictPageApi, { manual: true });
//删除字典数据
const { runAsync: deleteDictApi } = useRequest(templateDictService.deleteDictApi, { manual: true });

const load = async () => {
setOnSearching(true);
const [error, { data }] = await getDictPageApi(searchState);
setOnSearching(false);
if (!error) {
setDataDicts(data.list);
setTotal(data.total);
}
}

const showDeleteConfirm = (item: DataDictVO) => {
antdUtils.modal?.confirm({
title: `确认删除名称为: ${item.name} 的字典吗?`,
icon: <ExclamationCircleFilled />,
content: '请注意删除以后不可恢复!',
okText: '删除',
okType: 'danger',
cancelText: '取消',
onOk: async () => {
const [error, { code, msg }] = await deleteDictApi(item.id);
if (error || code !== 0) {
antdUtils.message?.open({ type: 'error', content: msg ?? '操作失败' })
} else {
antdUtils.message?.open({ type: 'success', content: '删除成功' })
}
await load();
},
onCancel() {
},
});
};

const getColumnSearchProps = (placeholder: string): ColumnType<DataDictVO> => ({
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters, close }) => (
<div style={{ padding: 8 }} onKeyDown={(e) => e.stopPropagation()}>
<Input.Search
ref={searchInput}
placeholder={placeholder}
value={selectedKeys[0]}
onChange={(e) => {
setSelectedKeys(e.target.value && e.target.value !== '' ? [e.target.value] : [])
}}
onSearch={(value) => {
if (value === '' && clearFilters) {
clearFilters!!()
}
confirm();
}}
onPressEnter={() => confirm()}
allowClear
style={{ marginBottom: 8, display: 'block' }}
enterButton="搜索"
size="middle"
loading={onSearching}
/>
</div>
),
filterIcon: (filtered: boolean) => (
<SearchOutlined style={{ color: filtered ? 'primaryColor' : undefined }} />
),
onFilterDropdownOpenChange: (visible) => {
if (visible) {
setTimeout(() => searchInput.current?.select(), 100);
}
},
});

const columns: ColumnsType<DataDictVO> = [
{
title: '名称',
dataIndex: 'name',
key: 'name',
align: 'center',
...getColumnSearchProps('请输入名称'),
},
{
title: '描述',
key: 'description',
dataIndex: 'description',
align: 'center',
// ...getColumnSearchProps('请输入描述'),
},
{
title: t("QkOmYwne" /* 操作 */),
key: 'action',
align: 'center',
render: (_, record) => (
<Space size="middle" split={(
<Divider type='vertical' />
)}>
<a
onClick={() => {
seEditData(record)
seEditorVisable(true);
}}>
编辑
</a>
<a
onClick={() => {
showDeleteConfirm(record)
}}>
删除
</a>
</Space>
),
width: 150,
},
];

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

const onChange: TableProps<DataDictVO>['onChange'] = (pagination, filters, sorter, extra) => {
const state: DataDictPageReqVO = {
name: filters.name ? filters.name[0] as string : undefined,
description: filters.description ? filters.description[0] as string : undefined,
pageNo: pagination.current,
pageSize: pagination.pageSize
}
setOnSearching(true);
setSearchState(state);
};

return (
<>
<div>
<Card className='mb-[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 />}
onClick={() => {
seEditData(undefined);
seEditorVisable(true);
}}> 新增 </Button>
</div>
<Table rowKey="id" scroll={{ x: true }} columns={columns} dataSource={dataDicts} className='bg-transparent'
onRow={(record) => {
return {
onClick: () => {
onSelectItem(record);
}
};
}}
onChange={onChange}
pagination={{
current: searchState.pageNo,
pageSize: searchState.pageSize,
total,
position: ['bottomRight']
}}
/>
</Card>
</div>
<DictEditor
onSave={() => {
load();
seEditorVisable(false);
}}
onCancel={() => { seEditorVisable(false) }}
visible={editorVisable}
data={editData}
/>
</>
);
};

+ 1
- 1
src/pages/custom/template/dict/dict-detail.tsx View File

@@ -120,7 +120,7 @@ export default forwardRef((props, ref) => {
return (
<>
<div>
<Card className='basis-3/5 mb-[10px] ml-[10px] dark:bg-[rgb(33,41,70)] bg-white roundle-lg px[12px]' bodyStyle={{
<Card className='mb-[10px] ml-[10px] dark:bg-[rgb(33,41,70)] bg-white roundle-lg px[12px]' bodyStyle={{
paddingTop: 0,
paddingBottom: 0
}}>


+ 10
- 197
src/pages/custom/template/dict/index.tsx View File

@@ -1,213 +1,26 @@
import React, { useState, useRef, useEffect } from 'react';
import { Space, Table, Button, Image, Divider, Card, Input } from 'antd';
import type { InputRef } from 'antd';
import type { ColumnType, ColumnsType } from 'antd/es/table';
import type { FilterConfirmProps, TableRowSelection } from 'antd/es/table/interface';
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 DictEditor from './dict-editor';
import DictDetailEditor from './dict-detail-editor';
import templateDictService from '@/request/service/template-dict';
import React, { useRef } from 'react';
import { DataDictVO } from '@/models';
import DictDetail from './dict-detail';
import DictData from './dict-data';
import type { DictDetailRef } from './dict-detail'

export default () => {

const [dataDicts, setDataDicts] = useState<DataDictVO[]>();
const [dictDetail, setDictDetail] = useState<DataDictDetailVO[]>();
const [total, setTotal] = useState(0);

const [editorVisable, seEditorVisable] = useState<boolean>(false);
const [editData, seEditData] = useState<DataDictVO>();

const [detailEditorVisable, seEdtailEditorVisable] = useState<boolean>(false);
const [editDetailData, seEditDetailData] = useState<DataDictDetailVO>();

const detailRef = useRef<DictDetailRef>()

//获取字典分页数据
const { runAsync: getDictPageApi } = useRequest(templateDictService.getDictPageApi, { manual: true });
//删除字典数据
const { runAsync: deleteDictApi } = useRequest(templateDictService.deleteDictApi, { manual: true });

const load = async () => {
const [error, { data }] = await getDictPageApi();
if (!error) {
setDataDicts(data.list);
setTotal(data.total);
}
}

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

const showDeleteConfirm = (item: DataDictVO) => {
antdUtils.modal?.confirm({
title: `确认删除名称为: ${item.name} 的字典吗?`,
icon: <ExclamationCircleFilled />,
content: '请注意删除以后不可恢复!',
okText: '删除',
okType: 'danger',
cancelText: '取消',
onOk: async () => {
const [error, { code, msg }] = await deleteDictApi(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={() => {

}}>
删除
</a>
</Space>
),
width: 150,
},
];


const updateDactDetail = (data: DataDictVO) => {
detailRef.current?.updateDictData(data)
}


const dictColumns: ColumnsType<DataDictVO> = [
{
title: '名称',
dataIndex: 'name',
key: 'name',
align: 'center',
},
{
title: '描述',
key: 'description',
dataIndex: 'description',
align: 'center',
},
{
title: t("QkOmYwne" /* 操作 */),
key: 'action',
align: 'center',
render: (_, record) => (
<Space size="middle" split={(
<Divider type='vertical' />
)}>
<a
onClick={() => {
seEditData(record)
seEditorVisable(true);
}}>
编辑
</a>
<a
onClick={() => {
showDeleteConfirm(record)
}}>
删除
</a>
</Space>
),
width: 150,
},
];

return (
<>
<div className='flex flex-row'>
<Card className='basis-2/5 w-[100px] mb-[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 />}
onClick={() => {
seEditData(undefined);
seEditorVisable(true);
}}> 新增 </Button>
</div>
<Table rowKey="id" scroll={{ x: true }} columns={dictColumns} dataSource={dataDicts} className='bg-transparent'
onRow={(record) => {
return {
onClick: () => {
updateDactDetail(record)
}
};
}}
pagination={{ position: ['bottomRight'] }}
/>
</Card>

<div className='basis-2/5 '>
<DictData
onSelectItem={(item: DataDictVO) => {
detailRef.current?.updateDictData(item);
}} />
</div>
<div className='basis-3/5 '>
<DictDetail ref={detailRef}/>
<DictDetail ref={detailRef} />
</div>
</div>
<DictEditor
onSave={() => {
load();
seEditorVisable(false);
}}
onCancel={() => { seEditorVisable(false) }}
visible={editorVisable}
data={editData}
/>

<DictDetailEditor
onSave={() => {
}}
onCancel={() => { seEdtailEditorVisable(false) }}
visible={detailEditorVisable}
data={editDetailData}
/>
</>
);
};

Loading…
Cancel
Save