新增软件管理权限,包括申请,管理,删除,添加使用时间等
This commit is contained in:
@@ -66,7 +66,6 @@ const ModifyMachine: React.FC<ModifyMachineProps> = ({ id, setFormRef, open }) =
|
||||
};
|
||||
|
||||
const onOk = (value: DatePickerProps['value'] | RangePickerProps['value']) => {
|
||||
console.log('onOk: ', value);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -145,8 +144,6 @@ const ModifyMachine: React.FC<ModifyMachineProps> = ({ id, setFormRef, open }) =
|
||||
<DatePicker
|
||||
showTime
|
||||
onChange={(value, dateString) => {
|
||||
console.log('Selected Time: ', value);
|
||||
console.log('Formatted Selected Time: ', dateString);
|
||||
}}
|
||||
onOk={onOk}
|
||||
/>
|
||||
|
||||
@@ -7,7 +7,6 @@ import TrailOptions from './TrialOptions';
|
||||
const DubSetting: React.FC = () => {
|
||||
|
||||
const onChange = (key: string | string[]) => {
|
||||
console.log(key);
|
||||
};
|
||||
|
||||
const items: CollapseProps['items'] = [
|
||||
|
||||
@@ -13,7 +13,6 @@ const DubSettingTTsOptions: React.FC = () => {
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
|
||||
async function onFinish(values: any): Promise<void> {
|
||||
console.log('Received values of form: ', values);
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("正在保存EdgeTTs配置");
|
||||
try {
|
||||
@@ -32,7 +31,6 @@ const DubSettingTTsOptions: React.FC = () => {
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
console.log("DubSettingTTsOptions", ttsOptions)
|
||||
form.setFieldsValue({ edgeTTsRoles: getOptionsStringValue(ttsOptions, 'EdgeTTsRoles', "{}") })
|
||||
}, [ttsOptions])
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ const DubSetting: React.FC = () => {
|
||||
const { setTopSpinning, setTopSpinTip } = useSoftStore();
|
||||
|
||||
const onChange = (key: string | string[]) => {
|
||||
console.log(key);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -22,9 +21,8 @@ const DubSetting: React.FC = () => {
|
||||
setTTsOptions(res);
|
||||
}
|
||||
).catch((err) => {
|
||||
console.log(err);
|
||||
console.error(err);
|
||||
}).finally(() => {
|
||||
console.log('finally');
|
||||
setTopSpinning(false);
|
||||
});
|
||||
|
||||
|
||||
@@ -123,7 +123,6 @@ const PromptManagement: React.FC = () => {
|
||||
okText: "确认",
|
||||
cancelText: "取消"
|
||||
});
|
||||
console.log(confirmed)
|
||||
if (confirmed) {
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("正在删除数据。。。")
|
||||
|
||||
@@ -82,7 +82,6 @@ const PromptManagement: React.FC<PromptManagementProps> = ({ type, setFormRef, i
|
||||
};
|
||||
|
||||
const onFinishFailed: FormProps<Prompt.AddPromptType>['onFinishFailed'] = (errorInfo) => {
|
||||
console.log('Failed:', errorInfo);
|
||||
};
|
||||
|
||||
return (<>
|
||||
|
||||
@@ -52,7 +52,6 @@ const PromptManagement: React.FC = () => {
|
||||
page: tableParams.pagination?.current ?? 1,
|
||||
} as Prompt.PromptTypeQueryCondition;
|
||||
|
||||
console.log("fetchData", params)
|
||||
let promptRes = await QueryPromptypeCollection(params)
|
||||
setData(promptRes.collection);
|
||||
setTableParams({
|
||||
|
||||
@@ -15,7 +15,6 @@ const AddRoleForm: React.FC<AddRoleModalProps> = ({ setFormRef }) => {
|
||||
}, [form, setFormRef]);
|
||||
|
||||
const onFinish = async (values: any) => {
|
||||
console.log('Success:', values);
|
||||
setLoading(true);
|
||||
try {
|
||||
await AddRole(values.name, values.remark);
|
||||
|
||||
@@ -41,7 +41,6 @@ const ManageRoleModal: React.FC<ManageRoleModalProps> = ({ roleId, setFormRef })
|
||||
}, [roleId]);
|
||||
|
||||
async function onFinish(values: RoleModel.Collection): Promise<void> {
|
||||
console.log("onFinish", values);
|
||||
setLoading(true);
|
||||
setSpinTip("更新中...");
|
||||
try {
|
||||
|
||||
@@ -35,7 +35,6 @@ const RoleManagement: React.FC = () => {
|
||||
},
|
||||
});
|
||||
useEffect(() => {
|
||||
console.log("RoleManagement useEffect");
|
||||
// 初始化加载数据
|
||||
QueryRoleList(tableParams, form.getFieldsValue())
|
||||
.then((res) => {
|
||||
@@ -49,7 +48,6 @@ const RoleManagement: React.FC = () => {
|
||||
setLoading(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
messageApi.error(error.message);
|
||||
}).finally(() => {
|
||||
setLoading(false);
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import TemplateContainer from '@/pages/TemplateContainer';
|
||||
import { useModel } from '@umijs/max';
|
||||
import { Button, Dropdown, Form, Input, message, Modal, Select, Table, TableProps, Tag } from 'antd';
|
||||
import { FilterValue, SorterResult, TableCurrentDataSource, TablePaginationConfig } from 'antd/es/table/interface';
|
||||
import { Software, SoftwareControl } from '@/services/services/software';
|
||||
import moment from 'moment';
|
||||
import { DeleteOutlined, EditOutlined, MenuOutlined, PlusSquareOutlined } from '@ant-design/icons';
|
||||
|
||||
|
||||
interface SoftwareControlManagementProps {
|
||||
// Add your props here
|
||||
}
|
||||
|
||||
const SoftwareControlManagement: FC<SoftwareControlManagementProps> = () => {
|
||||
const { initialState } = useModel('@@initialState');
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
const [loading, setLoading] = React.useState<boolean>(false);
|
||||
const [modalApi, modalHolder] = Modal.useModal();
|
||||
const [form] = Form.useForm();
|
||||
const [softwareBasicInfo, setSoftwareBasicInfo] = useState<SoftwareModel.SoftwareBasicInfo[]>();
|
||||
const [softwareOptions, setSoftwareOptions] = useState<any>([]);
|
||||
const [data, setData] = React.useState<SoftwareModel.SoftwareControlBase[]>([]);
|
||||
const [tableParams, setTableParams] = useState<TableModel.TableParams>({
|
||||
pagination: {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
showQuickJumper: true,
|
||||
totalBoundaryShowSizeChanger: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
const columns: TableProps<SoftwareModel.SoftwareControlBase>['columns'] = [
|
||||
{
|
||||
title: '软件代码',
|
||||
dataIndex: 'software',
|
||||
width: 100,
|
||||
key: 'softwareCode',
|
||||
render: (software) => <span> {software.softwareCode}</span >
|
||||
},
|
||||
{
|
||||
title: '软件名称',
|
||||
dataIndex: 'software',
|
||||
key: 'softwareName',
|
||||
render: (software) => <span>{software.softwareName}</span>,
|
||||
},
|
||||
{
|
||||
title: '所属用户ID',
|
||||
dataIndex: 'user',
|
||||
key: 'userId',
|
||||
render: (user) => <span>{user.id}</span>,
|
||||
},
|
||||
{
|
||||
title: '所属用户名称',
|
||||
dataIndex: 'user',
|
||||
key: 'userName',
|
||||
render: (user) => <span>{user.nickName}</span>,
|
||||
},
|
||||
{
|
||||
title: '创建者',
|
||||
dataIndex: 'createdUser',
|
||||
key: 'createdUserNickName',
|
||||
render: (createdUser) => <span>{createdUser.nickName}</span>,
|
||||
},
|
||||
{
|
||||
title: '更新者',
|
||||
dataIndex: 'updatedUser',
|
||||
key: 'updatedUserNickName',
|
||||
render: (updatedUser) => <span>{updatedUser.nickName}</span>,
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
dataIndex: 'updatedTime',
|
||||
key: 'updatedTime',
|
||||
width: 200,
|
||||
render: (updatedTime) => updatedTime ? moment(updatedTime).format('YYYY-MM-DD HH:mm:ss') : 'null',
|
||||
},
|
||||
{
|
||||
title: '到期时间',
|
||||
dataIndex: 'expirationTime',
|
||||
key: 'expirationTime',
|
||||
width: 200,
|
||||
render: (expirationTime) => expirationTime ? moment(expirationTime).format('YYYY-MM-DD HH:mm:ss') : 'null',
|
||||
},
|
||||
{
|
||||
title: '是否永久',
|
||||
dataIndex: 'isForever',
|
||||
key: 'isForever',
|
||||
width: 100,
|
||||
render: (isForever) => isForever ? <Tag color="green">是</Tag> : <Tag color="red">否</Tag>,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 100,
|
||||
render: (_, record) => (
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: [
|
||||
{
|
||||
key: 'edit',
|
||||
label: '编辑',
|
||||
icon: <EditOutlined />,
|
||||
onClick: () => {
|
||||
// 编辑
|
||||
messageApi.warning("暂不支持编辑");
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'addMouth',
|
||||
label: '添加月付',
|
||||
style: { color: '#38a2fc' },
|
||||
icon: <PlusSquareOutlined />,
|
||||
onClick: async () => {
|
||||
// 延长到期时间
|
||||
await AddSoftwareControlExpirationTime(record.id, 30);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'addQuarterly',
|
||||
label: '添加季付',
|
||||
style: { color: '#38a2fc' },
|
||||
icon: <PlusSquareOutlined />,
|
||||
onClick: async () => {
|
||||
// 延长到期时间
|
||||
await AddSoftwareControlExpirationTime(record.id, 90);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'addHalfYear',
|
||||
label: '添加半年',
|
||||
style: { color: '#38a2fc' },
|
||||
icon: <PlusSquareOutlined />,
|
||||
onClick: async () => {
|
||||
// 延长到期时间
|
||||
await AddSoftwareControlExpirationTime(record.id, 180);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'addYear',
|
||||
label: '添加年付',
|
||||
style: { color: '#38a2fc' },
|
||||
icon: <PlusSquareOutlined />,
|
||||
onClick: async () => {
|
||||
// 延长到期时间
|
||||
await AddSoftwareControlExpirationTime(record.id, 365);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'addForever',
|
||||
label: '永久',
|
||||
style: { color: '#38a2fc' },
|
||||
icon: <PlusSquareOutlined />,
|
||||
onClick: async () => {
|
||||
// 延长到期时间
|
||||
await AddSoftwareControlExpirationTime(record.id, 0);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
label: '停用权限',
|
||||
danger: true,
|
||||
icon: <DeleteOutlined />,
|
||||
onClick: async () => {
|
||||
await DeleteSoftwareControl(record.id);
|
||||
}
|
||||
},
|
||||
],
|
||||
}}
|
||||
>
|
||||
<Button type="text" color="primary" variant="filled" icon={<MenuOutlined />} />
|
||||
</Dropdown>
|
||||
),
|
||||
}
|
||||
];
|
||||
|
||||
async function DeleteSoftwareControl(id: string) {
|
||||
try {
|
||||
const confirmed = await modalApi.confirm({
|
||||
title: "确认停用",
|
||||
content: "确定停用吗,重置到期时间和永久选项"
|
||||
});
|
||||
if (confirmed) {
|
||||
setLoading(true);
|
||||
await SoftwareControl.AddSoftwareControlExpirationTime(id, 0, false);
|
||||
// 重新查询
|
||||
await QueryUserSoftwareControlCollection();
|
||||
messageApi.success("停用成功");
|
||||
} else {
|
||||
messageApi.info("取消停用");
|
||||
}
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function AddSoftwareControlExpirationTime(id: string, days: number) {
|
||||
try {
|
||||
const confirmed = await modalApi.confirm({
|
||||
title: "确认添加",
|
||||
content: `确认添加 ${days == 0 ? "永久" : days + " 天"} 吗?`
|
||||
});
|
||||
if (confirmed) {
|
||||
setLoading(true);
|
||||
await SoftwareControl.AddSoftwareControlExpirationTime(id, days, days == 0);
|
||||
// 重新查询
|
||||
await QueryUserSoftwareControlCollection();
|
||||
if (days == 0) {
|
||||
messageApi.success("添加永久成功");
|
||||
} else {
|
||||
messageApi.success("添加 " + days + " 天成功");
|
||||
}
|
||||
} else {
|
||||
messageApi.info("取消添加");
|
||||
}
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function QueryUserSoftwareControlCollection(options?: SoftwareModel.SoftwareControlQueryParams) {
|
||||
try {
|
||||
setLoading(true);
|
||||
let res = await SoftwareControl.GetUserSoftwareControlCollection(tableParams, options ?? {});
|
||||
setData(res.collection);
|
||||
setTableParams({
|
||||
pagination: {
|
||||
...tableParams.pagination,
|
||||
total: res.total
|
||||
}
|
||||
});
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
QueryUserSoftwareControlCollection().then();
|
||||
Software.GetSoftwareBaseCollection().then((res) => {
|
||||
setSoftwareBasicInfo(res);
|
||||
let options = []
|
||||
for (let i = 0; i < res.length; i++) {
|
||||
const element = res[i];
|
||||
let option = {
|
||||
label: element.isUse == false ? element.softwareName + "(未启用)" : element.softwareName,
|
||||
value: element.id
|
||||
}
|
||||
options.push(option);
|
||||
}
|
||||
setSoftwareOptions(options);
|
||||
}).catch((error) => {
|
||||
messageApi.error(error.message);
|
||||
})
|
||||
}, []);
|
||||
|
||||
async function TableChangeHandle(pagination: TablePaginationConfig, filters: Record<string, FilterValue | null>, sorter: SorterResult<SoftwareModel.SoftwareControlBase> | SorterResult<SoftwareModel.SoftwareControlBase>[], extra: TableCurrentDataSource<SoftwareModel.SoftwareControlBase>): Promise<void> {
|
||||
await QueryUserSoftwareControlCollection();
|
||||
setTableParams({
|
||||
pagination: {
|
||||
...tableParams.pagination,
|
||||
current: pagination.current,
|
||||
pageSize: pagination.pageSize,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async function QuerySoftwareControlByCondition(values: any) {
|
||||
await QueryUserSoftwareControlCollection(values);
|
||||
}
|
||||
|
||||
return (
|
||||
<TemplateContainer navTheme={initialState?.settings?.navTheme ?? "realDark"}>
|
||||
<Form
|
||||
layout='inline'
|
||||
form={form}
|
||||
onFinish={QuerySoftwareControlByCondition}
|
||||
>
|
||||
<Form.Item label="用户ID" name='userId' style={{ marginBottom: 5 }}>
|
||||
<Input placeholder="请输入用户ID" />
|
||||
</Form.Item>
|
||||
<Form.Item label="软件" name='softwareId' style={{ marginBottom: 5 }}>
|
||||
<Select placeholder="请选择用户名称" style={{ width: 200 }} options={softwareOptions} />
|
||||
</Form.Item>
|
||||
<Form.Item label="是否永久" name='IsForever' style={{ marginBottom: 5 }}>
|
||||
<Select placeholder="请选择是否永久" style={{ width: 200 }} options={[{ label: "是", value: true }, { label: "否", value: false }]} />
|
||||
</Form.Item>
|
||||
<Form.Item label="备注" name='remark' style={{ marginBottom: 5 }}>
|
||||
<Input placeholder="请输入备注" />
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button type="primary" htmlType="submit">查询</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<div>
|
||||
<Table<SoftwareModel.SoftwareControlBase> columns={columns} dataSource={data} rowKey={(record) => record.id} pagination={tableParams.pagination} onChange={TableChangeHandle} loading={loading} />
|
||||
</div>
|
||||
{messageHolder}
|
||||
{modalHolder}
|
||||
</TemplateContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default SoftwareControlManagement;
|
||||
@@ -130,7 +130,6 @@ const Login: React.FC = () => {
|
||||
setUserLoginState({
|
||||
status: 'error',
|
||||
});
|
||||
console.log(error);
|
||||
message.error(error.message);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -19,7 +19,6 @@ const Register: React.FC = () => {
|
||||
}, []);
|
||||
|
||||
const onFinish = async (values: UserModel.UserRegisterParams) => {
|
||||
console.log('Received values of form: ', values);
|
||||
// 判断两次密码是否一致
|
||||
if (values.password !== values.confirm) {
|
||||
messageApi.warning('两次密码不一致!');
|
||||
|
||||
@@ -2,16 +2,19 @@ import TemplateContainer from '@/pages/TemplateContainer';
|
||||
import { GetUserAgentInfo, GetUserInfo } from '@/services/services/user';
|
||||
import { RedoOutlined } from '@ant-design/icons';
|
||||
import { useModel } from '@umijs/max';
|
||||
import { Avatar, Button, Card, Col, Input, message, Modal, Row, Spin, Tag } from 'antd';
|
||||
import { Avatar, Badge, Button, Card, Col, FloatButton, Input, message, Modal, Row, Spin, Tag } from 'antd';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import UserCenterUserInfo from '../UserCenterUserInfo';
|
||||
import UserCenterAgentMessage from '../UserCenterAgentMessage';
|
||||
import UserCenterUserInfo from './UserCenterUserInfo';
|
||||
import UserCenterAgentMessage from './UserCenterAgentMessage';
|
||||
import { useSoftStore } from '@/store/software';
|
||||
import { SoftwareControl } from '@/services/services/software';
|
||||
import UserSoftwareInfo from './UserSoftwareInfo';
|
||||
|
||||
const UserCenter: React.FC = () => {
|
||||
const { initialState, setInitialState } = useModel('@@initialState');
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
const [modalApi, modalHolder] = Modal.useModal();
|
||||
const [badgeCount, setBadgeCount] = useState(0);
|
||||
const { setTopSpinTip, setTopSpinning } = useSoftStore();
|
||||
const [userAgentUserInfo, setUserAgentUserInfo] = useState<UserModel.UserAgentInfo>();
|
||||
|
||||
@@ -26,13 +29,62 @@ const UserCenter: React.FC = () => {
|
||||
let agentInfo = await GetUserAgentInfo();
|
||||
setUserAgentUserInfo(agentInfo);
|
||||
}).catch((error) => {
|
||||
console.log(error)
|
||||
messageApi.error(error.message);
|
||||
}).finally(() => {
|
||||
setTopSpinning(false);
|
||||
})
|
||||
// 加载当前用户可申请的的软件控制权限
|
||||
SoftwareControl.GetUserSoftwareControlCount(initialState?.currentUser?.id).then((res) => {
|
||||
setBadgeCount(res);
|
||||
}).catch((error) => {
|
||||
messageApi.error(error.message);
|
||||
})
|
||||
}
|
||||
}, [])
|
||||
|
||||
/**
|
||||
* 申请用户软件控制权限
|
||||
*/
|
||||
async function ApplyUserSoftwareControlHandle() {
|
||||
let userID = initialState?.currentUser?.id;
|
||||
if (!userID) {
|
||||
messageApi.error("用户信息不存在");
|
||||
return;
|
||||
}
|
||||
// 重新获取用户关联信息
|
||||
const userCanApplyCount = await SoftwareControl.GetUserSoftwareControlCount(userID);
|
||||
if (userCanApplyCount <= 0) {
|
||||
messageApi.warning("您已经没有可申请的软件控制权限了");
|
||||
return;
|
||||
}
|
||||
// 开始调用申请接口
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("正在申请软件控制权限。。。");
|
||||
try {
|
||||
await SoftwareControl.ApplyUserSoftwareControl(userID);
|
||||
// 提示成功
|
||||
messageApi.success("申请成功");
|
||||
setBadgeCount(0);
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
} finally {
|
||||
setTopSpinning(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示软件控制权限
|
||||
*/
|
||||
async function ShowSoftwareControlHandle() {
|
||||
modalApi.info({
|
||||
title: "用户软件控制权限",
|
||||
content: <UserSoftwareInfo userId={initialState?.currentUser?.id} />,
|
||||
width: 800,
|
||||
footer: null,
|
||||
closable: true,
|
||||
});
|
||||
}
|
||||
|
||||
function renderTitie() {
|
||||
return (
|
||||
<div style={{ display: 'flex' }}>
|
||||
@@ -81,6 +133,18 @@ const UserCenter: React.FC = () => {
|
||||
</div>
|
||||
<strong style={{ fontSize: 24, color: "goldenrod" }}>{initialState?.currentUser?.affiliateCode}</strong>
|
||||
</Col>
|
||||
<Col span={3} style={{ minWidth: 100 }}>
|
||||
<div>
|
||||
<span>软件控制权限</span>
|
||||
|
||||
</div>
|
||||
{
|
||||
badgeCount > 0 ? <Badge count={badgeCount}>
|
||||
<Button variant="filled" color="default" onClick={ApplyUserSoftwareControlHandle}> 申请</Button>
|
||||
</Badge> : <Button variant="filled" color="default" onClick={ApplyUserSoftwareControlHandle}> 申请</Button>
|
||||
}
|
||||
<Button color="primary" variant="filled" style={{ marginLeft: 10 }} onClick={ShowSoftwareControlHandle} > 查看</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
</div>
|
||||
@@ -0,0 +1,103 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { message, Space, Table, Tag } from 'antd';
|
||||
import type { TablePaginationConfig, TableProps } from 'antd';
|
||||
import { FilterValue, SorterResult, TableCurrentDataSource } from 'antd/es/table/interface';
|
||||
import { SoftwareControl } from '@/services/services/software';
|
||||
import { useModel } from '@umijs/max';
|
||||
import moment from 'moment';
|
||||
|
||||
|
||||
const columns: TableProps<SoftwareModel.SoftwareControlBase>['columns'] = [
|
||||
{
|
||||
title: '软件代码',
|
||||
dataIndex: 'software',
|
||||
width: 100,
|
||||
key: 'softwareCode',
|
||||
render: (software) => <span> {software.softwareCode}</span >
|
||||
},
|
||||
{
|
||||
title: '软件名称',
|
||||
dataIndex: 'software',
|
||||
key: 'softwareName',
|
||||
render: (software) => <span>{software.softwareName}</span>,
|
||||
},
|
||||
{
|
||||
title: '到期时间',
|
||||
dataIndex: 'expirationTime',
|
||||
key: 'expirationTime',
|
||||
width: 200,
|
||||
render: (expirationTime) => expirationTime ? moment(expirationTime).format('YYYY-MM-DD HH:mm:ss') : 'null',
|
||||
},
|
||||
{
|
||||
title: '是否永久',
|
||||
dataIndex: 'isForever',
|
||||
key: 'isForever',
|
||||
width: 100,
|
||||
render: (isForever) => isForever ? <Tag color="green">是</Tag> : <Tag color="red">否</Tag>,
|
||||
}
|
||||
];
|
||||
|
||||
interface UserSoftwareInfoProps {
|
||||
userId?: number;
|
||||
}
|
||||
|
||||
const UserSoftwareInfo: React.FC<UserSoftwareInfoProps> = ({ userId }) => {
|
||||
const [data, setData] = React.useState<SoftwareModel.SoftwareControlBase[]>([]);
|
||||
const [loading, setLoading] = React.useState<boolean>(false);
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
const [tableParams, setTableParams] = useState<TableModel.TableParams>({
|
||||
pagination: {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
showQuickJumper: true,
|
||||
totalBoundaryShowSizeChanger: true,
|
||||
},
|
||||
});
|
||||
|
||||
async function QueryUserSoftwareControlCollection() {
|
||||
try {
|
||||
if (userId == null) {
|
||||
messageApi.error("用户ID不能为空");
|
||||
}
|
||||
setLoading(true);
|
||||
let res = await SoftwareControl.GetUserSoftwareControlCollection(tableParams, {
|
||||
userId: userId
|
||||
});
|
||||
setData(res.collection);
|
||||
setTableParams({
|
||||
pagination: {
|
||||
...tableParams.pagination,
|
||||
total: res.total
|
||||
}
|
||||
})
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
QueryUserSoftwareControlCollection().then();
|
||||
}, []);
|
||||
|
||||
async function TableChangeHandle(pagination: TablePaginationConfig, filters: Record<string, FilterValue | null>, sorter: SorterResult<SoftwareModel.SoftwareControlBase> | SorterResult<SoftwareModel.SoftwareControlBase>[], extra: TableCurrentDataSource<SoftwareModel.SoftwareControlBase>): Promise<void> {
|
||||
await QueryUserSoftwareControlCollection();
|
||||
setTableParams({
|
||||
pagination: {
|
||||
...tableParams.pagination,
|
||||
current: pagination.current,
|
||||
pageSize: pagination.pageSize,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Table<SoftwareModel.SoftwareControlBase> columns={columns} dataSource={data} rowKey={(record) => record.id} pagination={tableParams.pagination} onChange={TableChangeHandle} loading={loading} />
|
||||
{messageHolder}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default UserSoftwareInfo;
|
||||
+71
-11
@@ -4,11 +4,13 @@ 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, Form, Input, InputNumber, message, Modal, Select, SelectProps, Table, Tag, Tooltip } from "antd";
|
||||
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'];
|
||||
@@ -134,6 +136,33 @@ const UserManagement: React.FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 给指定用户申请软件控制权限
|
||||
* @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',
|
||||
@@ -200,17 +229,48 @@ const UserManagement: React.FC = () => {
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
width: '120px',
|
||||
width: '80px',
|
||||
hidden: !access.isAdminOrSuperAdmin,
|
||||
render: (text, record) => (
|
||||
<div style={{ display: "flex" }}>
|
||||
<Button hidden={!access.canEditUser} size='small' style={{ marginRight: 5 }} type="primary" onClick={() => {
|
||||
setUserId(record.id);
|
||||
setOpenModal(true);
|
||||
}}>编辑</Button>
|
||||
<Button hidden={!access.canDeleteUser} danger size='small' type="primary" onClick={() => {
|
||||
messageApi.error("暂不支持删除用户");
|
||||
}} >删除</Button>
|
||||
</div>
|
||||
<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>
|
||||
),
|
||||
},
|
||||
];
|
||||
Reference in New Issue
Block a user