可正常启用
This commit is contained in:
parent
71a60043b3
commit
82997245a4
@ -1,12 +1,13 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { Table, Button, Modal, Form, Input, Space, message, InputNumber, Switch, Select, Tag } from 'antd';
|
import { Table, Button, Modal, Form, Input, Space, message, InputNumber, Switch, Select, Tag, ColorPicker } from 'antd';
|
||||||
import { PlusOutlined, EditOutlined, DeleteOutlined, TagOutlined } from '@ant-design/icons';
|
import { PlusOutlined, EditOutlined, DeleteOutlined, TagOutlined, SettingOutlined } from '@ant-design/icons';
|
||||||
import type { RoleResponse, RoleTagResponse } from './types';
|
import type { RoleResponse, RoleTagResponse } from './types';
|
||||||
import { useTableData } from '@/hooks/useTableData';
|
import { useTableData } from '@/hooks/useTableData';
|
||||||
import type { FixedType } from 'rc-table/lib/interface';
|
import type { FixedType } from 'rc-table/lib/interface';
|
||||||
import type { TablePaginationConfig } from 'antd/es/table';
|
import type { TablePaginationConfig } from 'antd/es/table';
|
||||||
import type { FilterValue, SorterResult } from 'antd/es/table/interface';
|
import type { FilterValue, SorterResult } from 'antd/es/table/interface';
|
||||||
import { assignTags, getAllTags } from './service';
|
import { assignTags, getAllTags } from './service';
|
||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
const RolePage: React.FC = () => {
|
const RolePage: React.FC = () => {
|
||||||
const {
|
const {
|
||||||
@ -36,6 +37,9 @@ const RolePage: React.FC = () => {
|
|||||||
const [selectedRole, setSelectedRole] = useState<RoleResponse | null>(null);
|
const [selectedRole, setSelectedRole] = useState<RoleResponse | null>(null);
|
||||||
const [selectedTags, setSelectedTags] = useState<number[]>([]);
|
const [selectedTags, setSelectedTags] = useState<number[]>([]);
|
||||||
const [allTags, setAllTags] = useState<RoleTagResponse[] | null>([]);
|
const [allTags, setAllTags] = useState<RoleTagResponse[] | null>([]);
|
||||||
|
const [tagManageVisible, setTagManageVisible] = useState(false);
|
||||||
|
const [editingTag, setEditingTag] = useState<RoleTagResponse | null>(null);
|
||||||
|
const [tagForm] = Form.useForm();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getAllTags().then(response => {
|
getAllTags().then(response => {
|
||||||
@ -81,7 +85,7 @@ const RolePage: React.FC = () => {
|
|||||||
|
|
||||||
const handleAssignTags = (record: RoleResponse) => {
|
const handleAssignTags = (record: RoleResponse) => {
|
||||||
setSelectedRole(record);
|
setSelectedRole(record);
|
||||||
if (record.tags) {
|
if (record.tags && record.tags.length > 0) {
|
||||||
setSelectedTags(record.tags.map(tag => tag.id));
|
setSelectedTags(record.tags.map(tag => tag.id));
|
||||||
} else {
|
} else {
|
||||||
setSelectedTags([]);
|
setSelectedTags([]);
|
||||||
@ -89,7 +93,7 @@ const RolePage: React.FC = () => {
|
|||||||
setTagModalVisible(true);
|
setTagModalVisible(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTagSubmit = async () => {
|
const handleAssignTagSubmit = async () => {
|
||||||
if (selectedRole) {
|
if (selectedRole) {
|
||||||
await assignTags(selectedRole.id, selectedTags);
|
await assignTags(selectedRole.id, selectedTags);
|
||||||
setTagModalVisible(false);
|
setTagModalVisible(false);
|
||||||
@ -97,6 +101,54 @@ const RolePage: React.FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleTagManage = () => {
|
||||||
|
setTagManageVisible(true);
|
||||||
|
setEditingTag(null);
|
||||||
|
tagForm.resetFields();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTagManageSubmit = async () => {
|
||||||
|
try {
|
||||||
|
const values = await tagForm.validateFields();
|
||||||
|
const tagService = {
|
||||||
|
baseUrl: '/api/v1/role-tag'
|
||||||
|
};
|
||||||
|
|
||||||
|
const formData = {
|
||||||
|
...values,
|
||||||
|
color: values.color.toHexString?.() || values.color
|
||||||
|
};
|
||||||
|
|
||||||
|
if (values.id) {
|
||||||
|
await request.put(`${tagService.baseUrl}/${values.id}`, formData, {
|
||||||
|
successMessage: '更新标签成功'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await request.post(tagService.baseUrl, formData, {
|
||||||
|
successMessage: '创建标签成功'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setTagManageVisible(false);
|
||||||
|
const tags = await getAllTags();
|
||||||
|
setAllTags(tags);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('操作失败:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTagDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
await request.delete(`/api/v1/role-tag/${id}`, {
|
||||||
|
successMessage: '删除标签成功'
|
||||||
|
});
|
||||||
|
// 刷新标签列表
|
||||||
|
const tags = await getAllTags();
|
||||||
|
setAllTags(tags);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除标签失败:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: 'ID',
|
title: 'ID',
|
||||||
@ -225,9 +277,14 @@ const RolePage: React.FC = () => {
|
|||||||
return (
|
return (
|
||||||
<div style={{ padding: '24px' }}>
|
<div style={{ padding: '24px' }}>
|
||||||
<div style={{ marginBottom: 16 }}>
|
<div style={{ marginBottom: 16 }}>
|
||||||
<Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
|
<Space>
|
||||||
新增角色
|
<Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
|
||||||
</Button>
|
新增角色
|
||||||
|
</Button>
|
||||||
|
<Button icon={<SettingOutlined />} onClick={handleTagManage}>
|
||||||
|
标签管理
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Table
|
<Table
|
||||||
@ -290,7 +347,7 @@ const RolePage: React.FC = () => {
|
|||||||
<Modal
|
<Modal
|
||||||
title="分配标签"
|
title="分配标签"
|
||||||
open={tagModalVisible}
|
open={tagModalVisible}
|
||||||
onOk={handleTagSubmit}
|
onOk={handleAssignTagSubmit}
|
||||||
onCancel={() => setTagModalVisible(false)}
|
onCancel={() => setTagModalVisible(false)}
|
||||||
width={600}
|
width={600}
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
@ -313,6 +370,109 @@ const RolePage: React.FC = () => {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
title="标签管理"
|
||||||
|
open={tagManageVisible}
|
||||||
|
onCancel={() => {
|
||||||
|
setTagManageVisible(false);
|
||||||
|
setEditingTag(null);
|
||||||
|
}}
|
||||||
|
width={800}
|
||||||
|
footer={null}
|
||||||
|
>
|
||||||
|
<div style={{ marginBottom: 16 }}>
|
||||||
|
<Button type="primary" icon={<PlusOutlined />} onClick={() => {
|
||||||
|
tagForm.resetFields();
|
||||||
|
setEditingTag(null);
|
||||||
|
}}>
|
||||||
|
新增标签
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Table
|
||||||
|
dataSource={allTags}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
title: '标签名称',
|
||||||
|
dataIndex: 'name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '颜色',
|
||||||
|
dataIndex: 'color',
|
||||||
|
render: (color: string) => (
|
||||||
|
<div style={{
|
||||||
|
backgroundColor: color,
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
borderRadius: 4
|
||||||
|
}} />
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '描述',
|
||||||
|
dataIndex: 'description'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
render: (_, record) => (
|
||||||
|
<Space>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
icon={<EditOutlined />}
|
||||||
|
onClick={() => {
|
||||||
|
tagForm.setFieldsValue(record);
|
||||||
|
setEditingTag(record);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
danger
|
||||||
|
icon={<DeleteOutlined />}
|
||||||
|
onClick={() => handleTagDelete(record.id)}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
rowKey="id"
|
||||||
|
pagination={false}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{(editingTag || !editingTag) && (
|
||||||
|
<Form form={tagForm} layout="vertical" style={{ marginTop: 16 }}>
|
||||||
|
<Form.Item name="id" hidden>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name="name"
|
||||||
|
label="标签名称"
|
||||||
|
rules={[{ required: true }]}
|
||||||
|
>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name="color"
|
||||||
|
label="标签颜色"
|
||||||
|
rules={[{ required: true }]}
|
||||||
|
>
|
||||||
|
<ColorPicker />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item name="description" label="描述">
|
||||||
|
<Input.TextArea />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item>
|
||||||
|
<Button type="primary" onClick={handleTagManageSubmit}>
|
||||||
|
保存
|
||||||
|
</Button>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
124
frontend/src/pages/System/RoleTag/index.tsx
Normal file
124
frontend/src/pages/System/RoleTag/index.tsx
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Table, Button, Modal, Form, Input, Space, ColorPicker } from 'antd';
|
||||||
|
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
|
||||||
|
import type { RoleTagResponse } from './types';
|
||||||
|
import { useTableData } from '@/hooks/useTableData';
|
||||||
|
import type { Color } from 'antd/es/color-picker';
|
||||||
|
|
||||||
|
const RoleTagPage: React.FC = () => {
|
||||||
|
const {
|
||||||
|
list: tags,
|
||||||
|
loading,
|
||||||
|
handleCreate,
|
||||||
|
handleUpdate,
|
||||||
|
handleDelete
|
||||||
|
} = useTableData({
|
||||||
|
service: {
|
||||||
|
baseUrl: '/api/v1/role-tag'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const [modalVisible, setModalVisible] = useState(false);
|
||||||
|
const [editingTag, setEditingTag] = useState<RoleTagResponse | null>(null);
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: '标签名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
key: 'name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '颜色',
|
||||||
|
dataIndex: 'color',
|
||||||
|
key: 'color',
|
||||||
|
render: (color: string) => (
|
||||||
|
<div style={{
|
||||||
|
backgroundColor: color,
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
borderRadius: 4
|
||||||
|
}} />
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '描述',
|
||||||
|
dataIndex: 'description',
|
||||||
|
key: 'description'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
render: (_: any, record: RoleTagResponse) => (
|
||||||
|
<Space>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
icon={<EditOutlined />}
|
||||||
|
onClick={() => handleEdit(record)}
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
danger
|
||||||
|
icon={<DeleteOutlined />}
|
||||||
|
onClick={() => handleDelete(record.id)}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ padding: '24px' }}>
|
||||||
|
<div style={{ marginBottom: 16 }}>
|
||||||
|
<Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
|
||||||
|
新增标签
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Table
|
||||||
|
loading={loading}
|
||||||
|
columns={columns}
|
||||||
|
dataSource={tags}
|
||||||
|
rowKey="id"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
title={editingTag ? '编辑标签' : '新增标签'}
|
||||||
|
open={modalVisible}
|
||||||
|
onOk={handleSubmit}
|
||||||
|
onCancel={() => setModalVisible(false)}
|
||||||
|
>
|
||||||
|
<Form form={form} layout="vertical">
|
||||||
|
<Form.Item
|
||||||
|
name="name"
|
||||||
|
label="标签名称"
|
||||||
|
rules={[{ required: true }]}
|
||||||
|
>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
name="color"
|
||||||
|
label="标签颜色"
|
||||||
|
rules={[{ required: true }]}
|
||||||
|
>
|
||||||
|
<ColorPicker />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
name="description"
|
||||||
|
label="描述"
|
||||||
|
>
|
||||||
|
<Input.TextArea />
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RoleTagPage;
|
||||||
Loading…
Reference in New Issue
Block a user