新增软件管理权限,包括申请,管理,删除,添加使用时间等

This commit is contained in:
2024-12-27 21:49:11 +08:00
parent ae15530766
commit 7781c6c95c
36 changed files with 728 additions and 74 deletions
@@ -0,0 +1,223 @@
import { QueryRoleOption } from '@/services/services/role';
import { GetUserInfo, UpdatedUserInfo } from '@/services/services/user';
import { FormatDate } from '@/util/time';
import { useModel } from '@umijs/max';
import { Button, Col, Form, FormInstance, Input, InputNumber, message, Row, Select, SelectProps, Spin, Tag } from 'antd';
import React, { useEffect, useState } from 'react';
interface ModifyUserProps {
userId: number;
setFormRef: (form: FormInstance) => void;
open: boolean;
}
const ModifyUser: React.FC<ModifyUserProps> = ({ userId, setFormRef, open }) => {
const [form] = Form.useForm();
type TagRender = SelectProps['tagRender'];
const [messageApi, messageHolder] = message.useMessage();
const [loading, setLoading] = useState<boolean>(true);
const [spinTip, setSpinTip] = useState<string>("加载中...");
const [roleNames, setRoleNames] = useState<SelectProps['options']>([]);
useEffect(() => {
setFormRef(form);
}, [form, setFormRef]);
useEffect(() => {
setLoading(true);
QueryRoleOption().then((res: string[]) => {
let temRoleNames = res.filter(item => item != "Super Admin").map((item) => {
return {
value: item
}
});
setRoleNames(temRoleNames);
}).catch((error: any) => {
messageApi.error(error.message);
setLoading(false);
})
GetUserInfo(userId).then((res) => {
let tempRes = {
...res,
createdDate: FormatDate(res.createdDate)
}
form.setFieldsValue(tempRes);
}).catch((error) => {
messageApi.error(error.message);
}).finally(() => { setLoading(false); });
}, [userId, open, form, setFormRef]);
async function onFinish(values: any): Promise<void> {
setLoading(true);
setSpinTip("修改中...");
try {
await UpdatedUserInfo(values);
messageApi.success("用户修改成功");
} catch (error: any) {
messageApi.error(error.message);
} finally {
setLoading(false);
}
}
const tagRender: TagRender = (props) => {
const { label, value, closable, onClose } = props;
const onPreventMouseDown = (event: React.MouseEvent<HTMLSpanElement>) => {
event.preventDefault();
event.stopPropagation();
};
return (
<Tag
color="cyan"
onMouseDown={onPreventMouseDown}
closable={closable}
onClose={onClose}
style={{ marginInlineEnd: 4 }}
>
{label}
</Tag>
);
};
return (
<>
<Spin spinning={loading} tip={spinTip}>
<Form
name="basic"
labelCol={{ span: 8 }}
wrapperCol={{ span: 16 }}
style={{ width: 800 }}
onFinish={onFinish}
autoComplete="off"
form={form}
initialValues={{
allDeviceCount: 1,
agentPercent: 0.5,
freeCount: 5
}}
>
<Row>
<Col span={12}>
<Form.Item
label="用户ID"
name="id"
>
<Input disabled={true} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="用户名称"
name="userName"
rules={[{ required: true, message: '请填写用户名称!' }]}
>
<Input />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="用户昵称"
name="nickName"
rules={[{ required: true, message: '请填写用户昵称!' }]}
>
<Input />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="邮箱"
name="email"
rules={[{ required: true, message: '请填写邮箱!' }]}
>
<Input />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="电话号码"
name="phoneNumber"
>
<Input />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="角色名称"
name="roleNames"
rules={[{ required: true, message: '请选择角色名称!' }]}
>
<Select
mode="multiple"
tagRender={tagRender}
style={{ width: '260px' }}
options={roleNames}
allowClear
placeholder="请选择角色分组"
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="可激活设备"
name="allDeviceCount"
rules={[{ required: true, message: '请设置可激活设置!' }]}
>
<InputNumber min={0} step="1" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="代理分成"
name="agentPercent"
rules={[{ required: true, message: '请设置代理分成!' }]}
>
<InputNumber min={0.1} max={0.7} step="0.01" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="免费换绑次数"
name="freeCount"
rules={[{ required: true, message: '请设置免费换绑次数!' }]}
>
<InputNumber min={1} max={10} step="1" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="注册时间"
name="createdDate"
rules={[{ required: true, message: '请选择注册时间!' }]}
>
<Input disabled={true} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="备注"
name="remark"
rules={[{ required: true, message: '请输入备注!' }]}
>
<Input />
</Form.Item>
</Col>
</Row>
<Form.Item wrapperCol={{ offset: 4, span: 3 }}>
<Button type="primary" htmlType="submit">
</Button>
</Form.Item>
</Form>
</Spin>
{messageHolder}
</>
);
};
export default ModifyUser;
@@ -0,0 +1,351 @@
import { useFormReset } from "@/hooks/useFormReset";
import TemplateContainer from "@/pages/TemplateContainer";
import { QueryRoleOption } from "@/services/services/role";
import { QueryUserList } from "@/services/services/user";
import { FormatDate } from "@/util/time";
import { useAccess, useModel } from "@umijs/max";
import { Button, Dropdown, Form, Input, InputNumber, message, Modal, Select, SelectProps, Table, Tag, Tooltip } from "antd";
import { ColumnsType, TablePaginationConfig } from "antd/es/table";
import { FilterValue, SorterResult, TableCurrentDataSource } from "antd/es/table/interface";
import { useEffect, useState } from "react";
import ModifyUser from "../ModifyUser";
import { DeleteOutlined, EditOutlined, MenuOutlined, SyncOutlined } from "@ant-design/icons";
import { SoftwareControl } from "@/services/services/software";
const UserManagement: React.FC = () => {
type TagRender = SelectProps['tagRender'];
const { initialState } = useModel('@@initialState');
const [data, setData] = useState<UserModel.UserCollection[]>(); // 数据
const [messageApi, messageHolder] = message.useMessage();
const [form] = Form.useForm();
const access = useAccess();
const { setFormRef, resetForm } = useFormReset();
const [tableParams, setTableParams] = useState<TableModel.TableParams>({
pagination: {
current: 1,
pageSize: 10,
showQuickJumper: true,
totalBoundaryShowSizeChanger: true,
},
});
const [loading, setLoading] = useState<boolean>(true);
const [userId, setUserId] = useState<number>(0);
const [openModal, setOpenModal] = useState<boolean>(false);
const [roleNames, setRoleNames] = useState<SelectProps['options']>([]);
useEffect(() => {
QueryRoleOption().then((res: string[]) => {
let temRoleNames = res.filter(item => item !== "Super Admin").map((item) => {
return {
value: item
}
});
setRoleNames(temRoleNames);
}).catch((error: any) => {
messageApi.error(error.message);
})
QueryUserList(tableParams, form.getFieldsValue())
.then((res) => {
setData(res.collection);
setTableParams({
pagination: {
...tableParams.pagination,
total: res.total
}
})
setLoading(false);
})
.catch((error: any) => {
messageApi.error(error.message);
})
.finally(() => {
setLoading(false);
})
}, []);
async function QueryUserBasic(params: UserModel.QueryUserParams | null, pagination: TablePaginationConfig | null): Promise<void> {
setLoading(true);
try {
let tableParamsParams = pagination ? { pagination } : tableParams;
let res = await QueryUserList(tableParamsParams, params ?? form.getFieldsValue());
setData(res.collection);
setTableParams({
pagination: {
...tableParams.pagination,
total: res.total
}
})
} catch (error: any) {
message.error(error.message);
} finally {
setLoading(false);
}
}
async function handleTableChange(pagination: TablePaginationConfig, filters: Record<string, FilterValue | null>, sorter: SorterResult<UserModel.UserCollection> | SorterResult<UserModel.UserCollection>[], extra: TableCurrentDataSource<UserModel.UserCollection>): Promise<void> {
setLoading(true);
try {
let queryUser = await QueryUserList({ pagination }, form.getFieldsValue());
setData(queryUser.collection);
setTableParams({
pagination: {
...pagination,
total: queryUser.total
}
})
} catch (error: any) {
message.error(error.message);
} finally {
setLoading(false);
}
}
async function modalCancel(): Promise<void> {
setOpenModal(false);
setUserId(0);
resetForm();
// 这边调用加载数据的方法
await QueryUserBasic(null, null);
}
async function QueryUserListByCondition(values: any): Promise<void> {
await QueryUserBasic(values, null);
}
const tagRender: TagRender = (props) => {
const { label, value, closable, onClose } = props;
const onPreventMouseDown = (event: React.MouseEvent<HTMLSpanElement>) => {
event.preventDefault();
event.stopPropagation();
};
return (
<Tag
color="cyan"
onMouseDown={onPreventMouseDown}
closable={closable}
onClose={onClose}
style={{ marginInlineEnd: 4 }}
>
{label}
</Tag>
);
};
/**
* 给指定用户申请软件控制权限
* @param userId 用户ID
* @returns
*/
async function ApplySoftwareControlHandle(userId: number) {
if (!access.isAdminOrSuperAdmin) {
messageApi.error("您没有权限执行此操作");
return;
}
try {
setLoading(true);
let userCanApplyCount = await SoftwareControl.GetUserSoftwareControlCount(userId);
if (userCanApplyCount <= 0) {
messageApi.warning("用户已经没有可申请的软件控制权限了");
return;
}
// 开始申请
await SoftwareControl.ApplyUserSoftwareControl(userId);
messageApi.success("用户软件控制权限申请成功");
} catch (error: any) {
messageApi.error(error.message);
} finally {
setLoading(false);
}
}
const columns: ColumnsType<UserModel.UserCollection> = [
{
title: 'ID',
dataIndex: 'id',
sorter: true,
width: '60px',
},
{
title: '用户名',
dataIndex: 'userName',
width: '140px',
},
{
title: '用户昵称',
dataIndex: 'nickName',
width: '140px',
},
{
title: '邀请人',
dataIndex: 'parentId',
width: '140px',
hidden: !access.isAdminOrSuperAdmin,
},
{
title: '角色',
dataIndex: 'roleNames',
render: (text, record) => {
let res = record.roleNames.map((item) => {
return <Tag key={item} color="cyan">{item}</Tag>
});
return res;
},
width: '260px',
},
{
title: '创建时间',
dataIndex: 'createdDate',
render: (text, record) => FormatDate(record.createdDate),
width: '160px',
},
{
title: '上次登录时间',
dataIndex: 'lastLoginDate',
render: (text, record) => FormatDate(record.lastLoginDate),
width: '160px',
},
{
title: '上次登录IP',
dataIndex: 'lastLoginIp',
width: '120px',
},
{
title: '备注',
dataIndex: 'remark',
hidden: !access.isAdminOrSuperAdmin,
ellipsis: {
showTitle: false,
},
render: (remark) => (
<Tooltip placement="topLeft" title={remark}>
{remark}
</Tooltip>
),
},
{
title: '操作',
width: '80px',
hidden: !access.isAdminOrSuperAdmin,
render: (text, record) => (
<Dropdown
menu={{
items: [
{
key: 'edit',
label: '编辑',
icon: <EditOutlined />,
hidden: !access.canEditUser,
primary: true,
onClick: () => {
setUserId(record.id);
setOpenModal(true);
}
},
{
key: 'apply',
label: '初始化权限',
icon: <SyncOutlined />,
hidden: !access.canApplySoftwareControl,
primary: true,
onClick: async () => {
await ApplySoftwareControlHandle(record.id);
}
},
{
key: 'delete',
label: '删除',
icon: <DeleteOutlined />,
hidden: !access.canDeleteUser,
danger: true,
onClick: () => {
messageApi.error("暂不支持删除用户");
}
}
].filter(item => !item.hidden)
}}
>
<Button color="primary" variant="filled" icon={<MenuOutlined />} />
</Dropdown>
),
},
];
return (
<TemplateContainer navTheme={initialState?.settings?.navTheme ?? "realDark"}>
<div>
<Form
layout='inline'
form={form}
onFinish={QueryUserListByCondition}
>
<Form.Item label="用户ID" name='userId' style={{ marginBottom: 5 }}>
<Input placeholder="请输入用户ID" />
</Form.Item>
<Form.Item label="用户名称" name='userName' style={{ marginBottom: 5 }}>
<Input placeholder="请输入用户名称" />
</Form.Item>
<Form.Item label="用户昵称" name='nickName' style={{ marginBottom: 5 }}>
<Input placeholder="请输入用户昵称" />
</Form.Item>
{access.isAdminOrSuperAdmin ?
<Form.Item label="所属用户ID" name='parentId' style={{ marginBottom: 5 }}>
<Input />
</Form.Item> :
null}
<Form.Item label="电话号码" name='phoneNumber' style={{ marginBottom: 5 }}>
<Input placeholder="请输入电话号码" />
</Form.Item>
<Form.Item label="邮箱" name='email' style={{ marginBottom: 5 }}>
<Input placeholder="请输入邮箱号" />
</Form.Item>
{
access.isAdminOrSuperAdmin ?
<Form.Item label="角色分组" name='roleNames' style={{ marginBottom: 5 }}>
<Select
mode="multiple"
tagRender={tagRender}
style={{ width: '260px' }}
options={roleNames}
placeholder="请选择角色分组"
/>
</Form.Item> :
null
}
<Form.Item>
</Form.Item>
{
access.isAdminOrSuperAdmin ?
<Form.Item label="备注" name='remark' style={{ marginBottom: 5 }}>
<Input placeholder="请输入备注" />
</Form.Item> :
null
}
<Form.Item>
<Button type="primary" htmlType='submit'></Button>
</Form.Item>
</Form>
<Table<UserModel.UserCollection>
columns={columns}
rowKey={(record) => record.id}
dataSource={data}
pagination={tableParams.pagination}
loading={loading}
onChange={handleTableChange}
/>
</div>
<Modal width={840} title="编辑用户" maskClosable={false} open={openModal} footer={null} onCancel={modalCancel}>
<ModifyUser setFormRef={setFormRef} open={openModal} userId={userId} />
</Modal>
{messageHolder}
</TemplateContainer>
);
};
export default UserManagement;