315 lines
9.6 KiB
TypeScript
315 lines
9.6 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { useIntl } from 'umi';
|
|
import { Card, Table, Button, Modal, Form, Input, Space, message, Select, TreeSelect, Popconfirm, Tag } from 'antd';
|
|
import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined, EditOutlined } from '@ant-design/icons';
|
|
import { getCategoryList, getAllCategories, addCategory, updateCategory, deleteCategory } from '@/servers/api/friendLink';
|
|
import { useFriendLinkDict } from '@/dicts/friendLinkDict';
|
|
import styles from './friendLinkManage.less';
|
|
|
|
const { Option } = Select;
|
|
const { TextArea } = Input;
|
|
|
|
// 友情链接分类类型定义已移至全局typings.d.ts
|
|
|
|
const FriendLinkCategory: React.FC = () => {
|
|
const intl = useIntl();
|
|
const { categoryTypeOptions, getCategoryTypeText } = useFriendLinkDict();
|
|
const [loading, setLoading] = useState<boolean>(false);
|
|
const [modalVisible, setModalVisible] = useState<boolean>(false);
|
|
const [isEdit, setIsEdit] = useState<boolean>(false);
|
|
const [currentCategory, setCurrentCategory] = useState<API.CategoryType | null>(null);
|
|
const [categoryData, setCategoryData] = useState<API.CategoryType[]>([]);
|
|
const [pagination, setPagination] = useState({
|
|
current: 1,
|
|
pageSize: 10,
|
|
total: 0,
|
|
});
|
|
const [form] = Form.useForm();
|
|
|
|
// 获取分类列表
|
|
const fetchCategoryList = async (pageNo = 1, pageSize = 10) => {
|
|
setLoading(true);
|
|
try {
|
|
const res = await getCategoryList({
|
|
basePageRequest: {
|
|
pageNo,
|
|
pageSize,
|
|
},
|
|
});
|
|
|
|
if (res.data && res.success) {
|
|
setCategoryData(res.data.records);
|
|
setPagination({
|
|
current: res.data.current,
|
|
pageSize: res.data.size,
|
|
total: res.data.total,
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to fetch category list', error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
// 首次加载时获取数据
|
|
useEffect(() => {
|
|
fetchCategoryList();
|
|
}, []);
|
|
// 处理分页变化
|
|
const handleTableChange = (paginationParams: any) => {
|
|
fetchCategoryList(paginationParams.current, paginationParams.pageSize);
|
|
};
|
|
|
|
// 处理添加分类
|
|
const handleAddCategory = () => {
|
|
setIsEdit(false);
|
|
setCurrentCategory(null);
|
|
form.resetFields();
|
|
form.setFieldsValue({
|
|
parentId: '0', // 设置默认父级为顶级
|
|
type: '0', // 设置默认类型为普通展示
|
|
orderBy: '1', // 设置默认排序为1
|
|
});
|
|
setModalVisible(true);
|
|
};
|
|
|
|
// 处理编辑分类
|
|
const handleEditCategory = (record: API.CategoryType) => {
|
|
setIsEdit(true);
|
|
setCurrentCategory(record);
|
|
form.setFieldsValue({
|
|
name: record.name,
|
|
type: record.type,
|
|
parentId: record.parentId,
|
|
orderBy: record.orderBy,
|
|
remark: record.remark,
|
|
});
|
|
setModalVisible(true);
|
|
};
|
|
|
|
// 处理删除分类
|
|
const handleDeleteCategory = async (id: string) => {
|
|
try {
|
|
const res = await deleteCategory(id);
|
|
if (res.success) {
|
|
message.success(intl.formatMessage({ id: 'friendLink.category.delete.success' }));
|
|
fetchCategoryList(pagination.current, pagination.pageSize);
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to delete category', error);
|
|
}
|
|
};
|
|
|
|
// 显示删除确认框
|
|
const showDeleteConfirm = (record: API.CategoryType) => {
|
|
Modal.confirm({
|
|
title: intl.formatMessage({ id: 'friendLink.category.delete.confirm.title' }),
|
|
icon: <ExclamationCircleOutlined />,
|
|
content: intl.formatMessage(
|
|
{ id: 'friendLink.category.delete.confirm.content' },
|
|
{ name: record.name }
|
|
),
|
|
okText: intl.formatMessage({ id: 'common.confirm' }),
|
|
okType: 'danger',
|
|
cancelText: intl.formatMessage({ id: 'common.cancel' }),
|
|
onOk() {
|
|
handleDeleteCategory(record.id);
|
|
},
|
|
});
|
|
};
|
|
|
|
// 处理表单提交
|
|
const handleModalSubmit = () => {
|
|
form.validateFields().then(async (values) => {
|
|
try {
|
|
if (isEdit && currentCategory) {
|
|
// 编辑模式
|
|
const res = await updateCategory({
|
|
...values,
|
|
id: currentCategory.id,
|
|
});
|
|
if (res.success) {
|
|
message.success(intl.formatMessage({ id: 'friendLink.category.update.success' }));
|
|
setModalVisible(false);
|
|
fetchCategoryList(pagination.current, pagination.pageSize);
|
|
}
|
|
} else {
|
|
// 新增模式
|
|
const res = await addCategory(values);
|
|
if (res.success) {
|
|
message.success(intl.formatMessage({ id: 'friendLink.category.add.success' }));
|
|
setModalVisible(false);
|
|
fetchCategoryList(pagination.current, pagination.pageSize);
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Submit failed', error);
|
|
}
|
|
});
|
|
};
|
|
|
|
// 渲染分类类型标签
|
|
const renderCategoryType = (type: string) => {
|
|
const color = type === '1' ? 'blue' : 'default';
|
|
return (
|
|
<Tag color={color}>
|
|
{getCategoryTypeText(type)}
|
|
</Tag>
|
|
);
|
|
};
|
|
|
|
// 表格列定义
|
|
const columns = [
|
|
{
|
|
title: intl.formatMessage({ id: 'friendLink.category.name' }),
|
|
dataIndex: 'name',
|
|
key: 'name',
|
|
},
|
|
{
|
|
title: intl.formatMessage({ id: 'friendLink.category.type' }),
|
|
dataIndex: 'type',
|
|
key: 'type',
|
|
render: (type: string) => renderCategoryType(type),
|
|
},
|
|
{
|
|
title: intl.formatMessage({ id: 'friendLink.category.sort' }),
|
|
dataIndex: 'orderBy',
|
|
key: 'orderBy',
|
|
width: 100,
|
|
},
|
|
{
|
|
title: intl.formatMessage({ id: 'friendLink.category.form.remark' }),
|
|
dataIndex: 'remark',
|
|
key: 'remark',
|
|
width: 200,
|
|
ellipsis: true,
|
|
},
|
|
{
|
|
title: intl.formatMessage({ id: 'friendLink.category.operation' }),
|
|
key: 'operation',
|
|
width: 150,
|
|
render: (_: any, record: API.CategoryType) => (
|
|
<Space size="middle">
|
|
<Button type="link" onClick={() => handleEditCategory(record)}>
|
|
{intl.formatMessage({ id: 'friendLink.category.edit' })}
|
|
</Button>
|
|
<Button type="link" danger onClick={() => showDeleteConfirm(record)}>
|
|
{intl.formatMessage({ id: 'friendLink.category.delete' })}
|
|
</Button>
|
|
</Space>
|
|
),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div className="common-container">
|
|
<div className="filter-action-row">
|
|
<div></div>
|
|
<div className="right-buttons">
|
|
<Button
|
|
type="primary"
|
|
ghost
|
|
icon={<PlusOutlined />}
|
|
onClick={handleAddCategory}
|
|
>
|
|
{intl.formatMessage({ id: 'friendLink.category.add' })}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="content-area">
|
|
<Table
|
|
rowKey="id"
|
|
columns={columns}
|
|
dataSource={categoryData}
|
|
loading={loading}
|
|
pagination={pagination}
|
|
onChange={handleTableChange}
|
|
/>
|
|
</div>
|
|
|
|
{/* 新增/编辑分类模态框 */}
|
|
<Modal
|
|
title={
|
|
isEdit
|
|
? intl.formatMessage({ id: 'friendLink.category.form.title.edit' })
|
|
: intl.formatMessage({ id: 'friendLink.category.form.title.add' })
|
|
}
|
|
visible={modalVisible}
|
|
onOk={handleModalSubmit}
|
|
onCancel={() => setModalVisible(false)}
|
|
destroyOnClose
|
|
>
|
|
<Form
|
|
form={form}
|
|
layout="vertical"
|
|
>
|
|
<Form.Item
|
|
name="name"
|
|
label={intl.formatMessage({ id: 'friendLink.category.form.name' })}
|
|
rules={[{
|
|
required: true,
|
|
message: intl.formatMessage({ id: 'friendLink.category.form.name.required' })
|
|
}]}
|
|
>
|
|
<Input placeholder={intl.formatMessage({ id: 'friendLink.category.form.name.placeholder' })} />
|
|
</Form.Item>
|
|
|
|
<Form.Item
|
|
name="type"
|
|
label={intl.formatMessage({ id: 'friendLink.category.form.type' })}
|
|
rules={[{
|
|
required: true,
|
|
message: intl.formatMessage({ id: 'friendLink.category.form.type.required' })
|
|
}]}
|
|
>
|
|
<Select placeholder={intl.formatMessage({ id: 'friendLink.category.form.type.placeholder' })}>
|
|
{categoryTypeOptions.map((option) => (
|
|
<Option key={option.value} value={option.value}>
|
|
{option.label}
|
|
</Option>
|
|
))}
|
|
</Select>
|
|
</Form.Item>
|
|
|
|
{/* 父级分类项,已完全隐藏 */}
|
|
<Form.Item name="parentId" hidden initialValue="0">
|
|
<Input />
|
|
</Form.Item>
|
|
|
|
<Form.Item
|
|
name="orderBy"
|
|
label={intl.formatMessage({ id: 'friendLink.category.form.sort' })}
|
|
rules={[{
|
|
required: true,
|
|
message: intl.formatMessage({ id: 'friendLink.category.form.sort.required' })
|
|
}]}
|
|
>
|
|
<Input
|
|
type="number"
|
|
placeholder={intl.formatMessage({ id: 'friendLink.category.form.sort.placeholder' })}
|
|
/>
|
|
</Form.Item>
|
|
|
|
<Form.Item
|
|
name="remark"
|
|
label={intl.formatMessage({ id: 'friendLink.category.form.remark' })}
|
|
rules={[{
|
|
required: true,
|
|
message: intl.formatMessage({ id: 'friendLink.category.form.remark.required' })
|
|
}]}
|
|
>
|
|
<TextArea
|
|
rows={4}
|
|
placeholder={intl.formatMessage({ id: 'friendLink.category.form.remark.placeholder' })}
|
|
/>
|
|
</Form.Item>
|
|
</Form>
|
|
</Modal>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default FriendLinkCategory;
|