Compare commits
No commits in common. "abdfbe7b00360e6120362ed5ff49f897e0b91206" and "e5046e4742b10bac89d39c625152762e491b7399" have entirely different histories.
abdfbe7b00
...
e5046e4742
@ -41,7 +41,7 @@ export default [
|
||||
path: '/userCenter',
|
||||
name: 'userCenter',
|
||||
icon: 'User',
|
||||
component: './User/UserCenter/UserCenter.tsx',
|
||||
component: './User/UserCenter/index',
|
||||
},
|
||||
{
|
||||
name: 'prompt',
|
||||
@ -59,21 +59,6 @@ export default [
|
||||
name: 'prompt-management',
|
||||
path: '/prompt/prompt-management',
|
||||
component: './Prompt/PromptManagement/index',
|
||||
access: 'canPrompt',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'options',
|
||||
path: '/options',
|
||||
icon: 'Tool',
|
||||
access: 'canOptions',
|
||||
routes: [
|
||||
{
|
||||
name: 'laitoolOptions',
|
||||
path: '/options/laitoolOptions',
|
||||
component: './Options/LaitoolOptions/LaitoolOptions/index',
|
||||
access: 'canLaitoolOptions',
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -89,7 +74,7 @@ export default [
|
||||
name: 'userManagement',
|
||||
icon: 'User',
|
||||
access: 'canUserManagement',
|
||||
component: './User/UserManage/UserManagement/index',
|
||||
component: './User/UserManagement/index',
|
||||
},
|
||||
{
|
||||
path: '/machineManagement',
|
||||
@ -98,13 +83,6 @@ export default [
|
||||
access: 'canMachineManagement',
|
||||
component: './Machine/MachineManagement/index',
|
||||
},
|
||||
{
|
||||
path: '/sofrwareControlManagement',
|
||||
name: 'sofrwareControlManagement',
|
||||
icon: 'Reconciliation',
|
||||
access: 'canSofrwareControlManagement',
|
||||
component: './Software/SofrwareControl/SofrwareControlManagement',
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/welcome',
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lms",
|
||||
"version": "1.0.1",
|
||||
"name": "ant-design-pro",
|
||||
"version": "6.0.0",
|
||||
"private": true,
|
||||
"description": "An out-of-box UI solution for enterprise applications",
|
||||
"scripts": {
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
* */
|
||||
export default function access(initialState: { currentUser?: API.CurrentUser } | undefined): AccessType.AccessType {
|
||||
const { currentUser } = initialState ?? {};
|
||||
console.log("currentUser", currentUser);
|
||||
console.log("userRole", currentUser?.roleNames);
|
||||
|
||||
let access = {
|
||||
canPrompt: false,
|
||||
@ -15,17 +17,11 @@ export default function access(initialState: { currentUser?: API.CurrentUser } |
|
||||
isSuperAdmin: false,
|
||||
isAdminOrSuperAdmin: false,
|
||||
|
||||
canOptions: false,
|
||||
canLaitoolOptions: false,
|
||||
|
||||
canApplySoftwareControl: false,
|
||||
canSofrwareControlManagement: false,
|
||||
|
||||
canMachineManagement: false,
|
||||
canAddMachine: true,
|
||||
canEditMachine: false,
|
||||
canDeleteMachine: false,
|
||||
canUpgradeMachine: true,
|
||||
canUpgradeMachine: false,
|
||||
canDisableMachine: true
|
||||
} as AccessType.AccessType;
|
||||
|
||||
@ -49,7 +45,7 @@ export default function access(initialState: { currentUser?: API.CurrentUser } |
|
||||
access = {
|
||||
...access,
|
||||
canUserManagement: true,
|
||||
|
||||
|
||||
canMachineManagement: true,
|
||||
canUpgradeMachine: true
|
||||
}
|
||||
@ -58,7 +54,6 @@ export default function access(initialState: { currentUser?: API.CurrentUser } |
|
||||
if (currentUser?.roleNames?.includes("Admin")) {
|
||||
access = {
|
||||
...access,
|
||||
canPrompt: true,
|
||||
|
||||
canUserManagement: true,
|
||||
canEditUser: true,
|
||||
@ -66,16 +61,10 @@ export default function access(initialState: { currentUser?: API.CurrentUser } |
|
||||
isAdmin: true,
|
||||
isAdminOrSuperAdmin: true,
|
||||
|
||||
canOptions: true,
|
||||
canLaitoolOptions: true,
|
||||
|
||||
canMachineManagement: true,
|
||||
canEditMachine: true,
|
||||
canDeleteMachine: true,
|
||||
canUpgradeMachine: true,
|
||||
|
||||
canApplySoftwareControl: true,
|
||||
canSofrwareControlManagement: true
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,18 +81,11 @@ export default function access(initialState: { currentUser?: API.CurrentUser } |
|
||||
isSuperAdmin: true,
|
||||
isAdminOrSuperAdmin: true,
|
||||
|
||||
canOptions: true,
|
||||
canLaitoolOptions: true,
|
||||
|
||||
canMachineManagement: true,
|
||||
canEditMachine: true,
|
||||
canDeleteMachine: true,
|
||||
canUpgradeMachine: true,
|
||||
|
||||
canApplySoftwareControl: true,
|
||||
canSofrwareControlManagement: true
|
||||
};
|
||||
}
|
||||
console.log("accsee", access);
|
||||
return access;
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import type { RunTimeLayoutConfig } from '@umijs/max';
|
||||
import { history, Link, request as q } from '@umijs/max';
|
||||
import defaultSettings from '../config/defaultSettings';
|
||||
import { errorConfig } from './requestErrorConfig';
|
||||
import { UserInfo, getCurrentUser as queryCurrentUser } from './services/services/user';
|
||||
import { GetUserInfo, getCurrentUser as queryCurrentUser } from './services/services/user';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { TokenStorage } from './services/define/tokenStorage';
|
||||
import { App, ConfigProvider } from 'antd';
|
||||
@ -46,17 +46,19 @@ export async function getInitialState(): Promise<{
|
||||
};
|
||||
|
||||
const GetUsrInfo = async (id: number) => {
|
||||
const userInfo = await UserInfo.GetUserInfo(id);
|
||||
const userInfo = await GetUserInfo(id);
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
// 如果不是登录页面,执行
|
||||
const { location } = history;
|
||||
debugger;
|
||||
if (location.pathname !== loginPath && !location.pathname.startsWith('/user/register')) {
|
||||
let currentUserString = localStorage.getItem('userInfo');
|
||||
let currentUser = currentUserString ? JSON.parse(currentUserString) : null;
|
||||
let token = localStorage.getItem('token') ?? null;
|
||||
if (token == null || currentUser == null) {
|
||||
console.log('没有登录,重定向到登录页面123')
|
||||
history.push('/user/login');
|
||||
return {
|
||||
fetchUserInfo,
|
||||
@ -182,6 +184,7 @@ export function rootContainer(container: React.ReactNode) {
|
||||
*/
|
||||
export const request = {
|
||||
...errorConfig,
|
||||
prefix: "https://localhost:44362",
|
||||
timeout: 60000,
|
||||
};
|
||||
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
import React from 'react';
|
||||
import Icon from '@ant-design/icons'
|
||||
import { AntdIconProps } from '@ant-design/icons/lib/components/AntdIcon';
|
||||
|
||||
const DiceIcon: React.FC<AntdIconProps> = (props) => {
|
||||
let ico = <svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512" width="1.5em"
|
||||
height="1.5em" ><path d="M440.88 129.37L288.16 40.62a64.14 64.14 0 0 0-64.33 0L71.12 129.37a4 4 0 0 0 0 6.9L254 243.85a4 4 0 0 0 4.06 0L440.9 136.27a4 4 0 0 0-.02-6.9zM256 152c-13.25 0-24-7.16-24-16s10.75-16 24-16s24 7.16 24 16s-10.75 16-24 16z" fill="currentColor"></path><path d="M238 270.81L54 163.48a4 4 0 0 0-6 3.46v173.92a48 48 0 0 0 23.84 41.39L234 479.48a4 4 0 0 0 6-3.46V274.27a4 4 0 0 0-2-3.46zM96 368c-8.84 0-16-10.75-16-24s7.16-24 16-24s16 10.75 16 24s-7.16 24-16 24zm96-32c-8.84 0-16-10.75-16-24s7.16-24 16-24s16 10.75 16 24s-7.16 24-16 24z" fill="currentColor"></path><path d="M458 163.51L274 271.56a4 4 0 0 0-2 3.45V476a4 4 0 0 0 6 3.46l162.15-97.23A48 48 0 0 0 464 340.86V167a4 4 0 0 0-6-3.49zM320 424c-8.84 0-16-10.75-16-24s7.16-24 16-24s16 10.75 16 24s-7.16 24-16 24zm0-88c-8.84 0-16-10.75-16-24s7.16-24 16-24s16 10.75 16 24s-7.16 24-16 24zm96 32c-8.84 0-16-10.75-16-24s7.16-24 16-24s16 10.75 16 24s-7.16 24-16 24zm0-88c-8.84 0-16-10.75-16-24s7.16-24 16-24s16 10.75 16 24s-7.16 24-16 24z" fill="currentColor"></path></svg>;
|
||||
return (
|
||||
<Icon {...props} component={() => (
|
||||
ico
|
||||
)} />
|
||||
|
||||
);
|
||||
};
|
||||
export default DiceIcon;
|
||||
@ -49,6 +49,7 @@ export const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({ menu, childre
|
||||
/** 此方法会跳转到 redirect 参数所在的位置 */
|
||||
const redirect = urlParams.get('redirect');
|
||||
// Note: There may be security issues, please note
|
||||
console.log('没有登录,重定向到登录页面12333333333333333')
|
||||
if (window.location.pathname !== '/user/login' && !redirect) {
|
||||
history.replace({
|
||||
pathname: '/user/login',
|
||||
|
||||
@ -15,7 +15,7 @@ const clearCache = () => {
|
||||
caches.delete(key);
|
||||
});
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
.catch((e) => console.log(e));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -7,15 +7,11 @@ export default {
|
||||
'menu.prompt.prompt-type': '提示词类型',
|
||||
'menu.prompt.prompt-management': '提示词管理',
|
||||
|
||||
'menu.options': '配置管理',
|
||||
'menu.options.laitoolOptions': 'Laitool配置',
|
||||
|
||||
'menu.roleManagement': '角色管理',
|
||||
|
||||
'menu.userManagement': '用户管理',
|
||||
|
||||
'menu.machineManagement': '机器码管理',
|
||||
'menu.sofrwareControlManagement': '软件控制管理',
|
||||
|
||||
'menu.more-blocks': '更多区块',
|
||||
'menu.home': '首页',
|
||||
|
||||
@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
|
||||
import { Form, Input, Button, FormInstance, Spin, message, Select, DatePicker, InputNumber } from 'antd';
|
||||
import moment from 'moment';
|
||||
import { AddMachineData } from '@/services/services/machine';
|
||||
import { useAccess, useModel } from '@umijs/max';
|
||||
import { useModel } from '@umijs/max';
|
||||
|
||||
interface AddMachineModalProps {
|
||||
setFormRef: (form: FormInstance) => void;
|
||||
@ -13,7 +13,6 @@ const AddMachineForm: React.FC<AddMachineModalProps> = ({ setFormRef }) => {
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
const { initialState } = useModel('@@initialState');
|
||||
const access = useAccess();
|
||||
|
||||
useEffect(() => {
|
||||
setFormRef(form);
|
||||
@ -29,8 +28,9 @@ const AddMachineForm: React.FC<AddMachineModalProps> = ({ setFormRef }) => {
|
||||
}, [form, setFormRef]);
|
||||
|
||||
const onFinish = async (values: MachineModel.AddMachineParams) => {
|
||||
if (values.userId == null) {
|
||||
messageApi.error("请填写所属用户ID");
|
||||
if (values.useStatus == 0 && !values.deactivationTime) {
|
||||
messageApi.error("试用机器码需要设置停用时间")
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
try {
|
||||
@ -60,12 +60,48 @@ const AddMachineForm: React.FC<AddMachineModalProps> = ({ setFormRef }) => {
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item<MachineModel.AddMachineParams>
|
||||
label="使用状态"
|
||||
name="useStatus"
|
||||
rules={[{ required: true, message: 'Please input the role name!' }]}
|
||||
>
|
||||
<Select onChange={(value) => {
|
||||
if (value == 1) {
|
||||
form.setFieldsValue({ deactivationTime: null })
|
||||
} else {
|
||||
const currentDate = new Date();
|
||||
const nextDayDate = new Date(currentDate);
|
||||
nextDayDate.setDate(currentDate.getDate() + 1);
|
||||
form.setFieldsValue({ deactivationTime: moment(nextDayDate) })
|
||||
}
|
||||
}}>
|
||||
<Select.Option value={0}>试用</Select.Option>
|
||||
<Select.Option value={1}>永久</Select.Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Form.Item<MachineModel.AddMachineParams>
|
||||
label="状态"
|
||||
name="status"
|
||||
rules={[{ required: true, message: 'Please input the role name!' }]}
|
||||
>
|
||||
<Select >
|
||||
<Select.Option value={0}>冻结</Select.Option>
|
||||
<Select.Option value={1}>激活</Select.Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item<MachineModel.AddMachineParams>
|
||||
label="停用时间"
|
||||
name="deactivationTime"
|
||||
>
|
||||
<DatePicker showTime />
|
||||
</Form.Item>
|
||||
<Form.Item<MachineModel.AddMachineParams>
|
||||
label="所属用户ID"
|
||||
name="userId"
|
||||
rules={[{ required: true, message: 'Please input the role name!' }]}
|
||||
>
|
||||
<InputNumber disabled={!access.isAdminOrSuperAdmin} style={{ width: 200 }} keyboard={false} min={0} changeOnWheel={false} controls={false} />
|
||||
<InputNumber style={{ width: 200 }} keyboard={false} min={0} changeOnWheel={false} controls={false} />
|
||||
</Form.Item>
|
||||
<Form.Item<MachineModel.AddMachineParams>
|
||||
label="备注"
|
||||
|
||||
@ -4,13 +4,13 @@ import TemplateContainer from "@/pages/TemplateContainer";
|
||||
import { DeactivationMachine, MachinePermanent, QueryMachineList } from "@/services/services/machine";
|
||||
import { FormatDate } from "@/util/time";
|
||||
import { useAccess, useModel } from "@umijs/max";
|
||||
import { Button, Dropdown, Form, Input, Menu, message, Modal, Select, SelectProps, Spin, Table, Tag } from "antd";
|
||||
import { Button, Form, Input, message, Modal, Select, SelectProps, Spin, Table, Tag } from "antd";
|
||||
import { ColumnsType, TablePaginationConfig } from "antd/es/table";
|
||||
import { FilterValue, SorterResult, TableCurrentDataSource } from "antd/es/table/interface";
|
||||
import { delay, set } from "lodash";
|
||||
import { useEffect, useState } from "react";
|
||||
import ModifyMachine from "../ModifyMachine";
|
||||
import { DownOutlined, EditOutlined, MenuOutlined, MoreOutlined, PlusOutlined, SafetyCertificateOutlined, StopOutlined } from "@ant-design/icons";
|
||||
import { PlusOutlined } from "@ant-design/icons";
|
||||
import AddMachineForm from "../AddMachineForm";
|
||||
|
||||
const MachineManagement: React.FC = () => {
|
||||
@ -35,7 +35,6 @@ const MachineManagement: React.FC = () => {
|
||||
const [openAddModal, setOpenAddModal] = useState<boolean>(false);
|
||||
const [spinning, setSpinning] = useState<boolean>(false);
|
||||
const [spinTip, setSpinTip] = useState<string>('');
|
||||
const [modal, modalHolder] = Modal.useModal();
|
||||
|
||||
useEffect(() => {
|
||||
QueryMachineList(tableParams, form.getFieldsValue())
|
||||
@ -58,23 +57,12 @@ const MachineManagement: React.FC = () => {
|
||||
}, []);
|
||||
|
||||
async function SetMachinePermanent(id: string): Promise<void> {
|
||||
|
||||
setSpinning(true);
|
||||
setSpinTip('正在设置为永久。。。');
|
||||
try {
|
||||
let cofirmRes = await modal.confirm({
|
||||
title: '激活提示',
|
||||
content: '即将同步软件控制权限信息至绑定机器码,会消耗一次授权次数,是否继续?',
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
});
|
||||
if (!cofirmRes) {
|
||||
messageApi.warning("取消操作");
|
||||
return;
|
||||
}
|
||||
|
||||
setSpinning(true);
|
||||
setSpinTip('正在激活/同步。。。');
|
||||
//
|
||||
await MachinePermanent(id);
|
||||
messageApi.success('激活同步信息成功');
|
||||
messageApi.success('设置为永久成功');
|
||||
setSpinning(false);
|
||||
// 重新加载数据
|
||||
await QueryMachineBasic(form.getFieldsValue(), tableParams.pagination);
|
||||
@ -178,14 +166,16 @@ const MachineManagement: React.FC = () => {
|
||||
render: (text) => FormatDate(text),
|
||||
width: '160px',
|
||||
},
|
||||
{
|
||||
title: '使用状态',
|
||||
dataIndex: 'useStatus',
|
||||
render: (text, record) => <Tag color={record.useStatus === 1 ? 'green' : 'red'}>{record.useStatus === 1 ? '永久' : '试用'}</Tag>,
|
||||
width: '100px',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
render: (text, record) => (
|
||||
<Tag color={record.status === 1 ? 'blue' : 'red'}>
|
||||
{record.status === 1 ? '激活' : '冻结'}
|
||||
</Tag>
|
||||
),
|
||||
render: (text, record) => <Tag color={record.status === 1 ? 'blue' : 'red'}>{record.status === 1 ? '激活' : '冻结'}</Tag>,
|
||||
width: '100px',
|
||||
},
|
||||
{
|
||||
@ -200,45 +190,17 @@ const MachineManagement: React.FC = () => {
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
width: 100,
|
||||
render: (text, record) => {
|
||||
const menuItems = [
|
||||
{
|
||||
key: "edit",
|
||||
icon: <EditOutlined />,
|
||||
hidden: !access.isAdminOrSuperAdmin,
|
||||
label: "编辑",
|
||||
onClick: () => {
|
||||
setOpenModal(true);
|
||||
setFormRef(form);
|
||||
setId(record.id);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "permanent",
|
||||
icon: <SafetyCertificateOutlined />,
|
||||
hidden: !access.canUpgradeMachine,
|
||||
style: {
|
||||
color: '#4caaff'
|
||||
},
|
||||
label: "激活",
|
||||
onClick: async () => await SetMachinePermanent(record.id),
|
||||
},
|
||||
{
|
||||
key: "disable",
|
||||
icon: <StopOutlined />,
|
||||
hidden: !access.canDisableMachine,
|
||||
danger: true,
|
||||
label: "停用",
|
||||
onClick: async () => await ChangeDeactivationMachine(record.id),
|
||||
},
|
||||
].filter(Boolean);
|
||||
return (
|
||||
<Dropdown menu={{ items: menuItems }} trigger={["hover"]}>
|
||||
<Button type="text" color="primary" variant="filled" icon={<MenuOutlined />} />
|
||||
</Dropdown>
|
||||
);
|
||||
},
|
||||
width: '200px',
|
||||
render: (text, record) => (
|
||||
<div>
|
||||
<Button hidden={!access.canEditMachine} style={{ marginRight: 5 }} type="primary" size="small"
|
||||
onClick={() => { setOpenModal(true); setFormRef(form); setId(record.id) }}>编辑</Button>
|
||||
<Button hidden={!access.canUpgradeMachine} type="primary" style={{ marginRight: 5 }} size="small"
|
||||
onClick={async () => await SetMachinePermanent(record.id)}>永久</Button>
|
||||
<Button hidden={!access.canDisableMachine} type="primary" danger size="small"
|
||||
onClick={async () => await ChangeDeactivationMachine(record.id)}>停用</Button>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
@ -306,7 +268,6 @@ const MachineManagement: React.FC = () => {
|
||||
<AddMachineForm setFormRef={setFormRef} />
|
||||
</Modal>
|
||||
{messageHolder}
|
||||
{modalHolder}
|
||||
</TemplateContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@ -66,6 +66,7 @@ const ModifyMachine: React.FC<ModifyMachineProps> = ({ id, setFormRef, open }) =
|
||||
};
|
||||
|
||||
const onOk = (value: DatePickerProps['value'] | RangePickerProps['value']) => {
|
||||
console.log('onOk: ', value);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -98,7 +99,7 @@ const ModifyMachine: React.FC<ModifyMachineProps> = ({ id, setFormRef, open }) =
|
||||
label="机器码"
|
||||
name="machineId"
|
||||
>
|
||||
<Input disabled={!(initialState?.currentUser?.roleNames?.includes("Admin") || initialState?.currentUser?.roleNames.includes("Super Admin"))} />
|
||||
<Input disabled={initialState?.currentUser?.roleNames?.includes("Admin") || initialState?.currentUser?.roleNames.includes("Super Admin")} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
|
||||
@ -108,7 +109,7 @@ const ModifyMachine: React.FC<ModifyMachineProps> = ({ id, setFormRef, open }) =
|
||||
name="useStatus"
|
||||
rules={[{ required: true, message: 'Please input your username!' }]}
|
||||
>
|
||||
<Select disabled>
|
||||
<Select>
|
||||
<Select.Option value={0}>试用</Select.Option>
|
||||
<Select.Option value={1}>永久</Select.Option>
|
||||
</Select>
|
||||
@ -120,7 +121,7 @@ const ModifyMachine: React.FC<ModifyMachineProps> = ({ id, setFormRef, open }) =
|
||||
name="status"
|
||||
rules={[{ required: true, message: 'Please input your username!' }]}
|
||||
>
|
||||
<Select disabled>
|
||||
<Select>
|
||||
<Select.Option value={0}>冻结</Select.Option>
|
||||
<Select.Option value={1}>激活</Select.Option>
|
||||
</Select>
|
||||
@ -142,8 +143,10 @@ const ModifyMachine: React.FC<ModifyMachineProps> = ({ id, setFormRef, open }) =
|
||||
name="deactivationTime"
|
||||
>
|
||||
<DatePicker
|
||||
showTime disabled
|
||||
showTime
|
||||
onChange={(value, dateString) => {
|
||||
console.log('Selected Time: ', value);
|
||||
console.log('Formatted Selected Time: ', dateString);
|
||||
}}
|
||||
onOk={onOk}
|
||||
/>
|
||||
|
||||
@ -1,98 +0,0 @@
|
||||
import { GetOptions, getOptionsStringValue, SaveOptions } from '@/services/services/options/optionsTool';
|
||||
import { useOptionsStore } from '@/store/options';
|
||||
import { useSoftStore } from '@/store/software';
|
||||
import { Button, Card, Form, Input } from 'antd';
|
||||
import TextArea from 'antd/es/input/TextArea';
|
||||
import { message } from 'antd/lib';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
const SimpleOptions: React.FC = () => {
|
||||
|
||||
const { setTopSpinning, setTopSpinTip } = useSoftStore();
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
const { laitoolOptions, setLaitoolOptions } = useOptionsStore();
|
||||
const [form] = Form.useForm();
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("加载信息中");
|
||||
// 这边加载所有的配音数据
|
||||
GetOptions("software").then((res) => {
|
||||
setLaitoolOptions(res);
|
||||
form.setFieldsValue({
|
||||
LaitoolHomePage: getOptionsStringValue(res, 'LaitoolHomePage', ""),
|
||||
LaitoolUpdateContent: getOptionsStringValue(res, 'LaitoolUpdateContent', ""),
|
||||
LaitoolNotice: getOptionsStringValue(res, 'LaitoolNotice', ""),
|
||||
LaitoolVersion: getOptionsStringValue(res, 'LaitoolVersion', ""),
|
||||
});
|
||||
}
|
||||
).catch((err: any) => {
|
||||
messageApi.error(err.message);
|
||||
}).finally(() => {
|
||||
setTopSpinning(false);
|
||||
});
|
||||
|
||||
}, []);
|
||||
|
||||
|
||||
async function onFinish(values: any): Promise<void> {
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("正在保存通用设置");
|
||||
try {
|
||||
// 这边保存所有的配音数据
|
||||
await SaveOptions(values);
|
||||
// 判断Option中的key是不是在属性上
|
||||
for (let key in values) {
|
||||
setLaitoolOptions(laitoolOptions.map((item: OptionModel.Option) => {
|
||||
if (item.key === key) {
|
||||
item.value = values[key]
|
||||
}
|
||||
return item
|
||||
}));
|
||||
}
|
||||
messageApi.success('设置成功');
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
} finally {
|
||||
setTopSpinning(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Form name="trigger" form={form} layout="vertical" autoComplete="off" onFinish={onFinish}>
|
||||
<Form.Item
|
||||
label="软件版本号"
|
||||
name="LaitoolVersion"
|
||||
>
|
||||
<Input placeholder='请输入版本号' />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="首页内容"
|
||||
name="LaitoolHomePage"
|
||||
>
|
||||
<TextArea autoSize={{ minRows: 3, maxRows: 6 }} placeholder="支持HTML和网址,网址用iframe,可以内嵌所有的网页" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="更新内容"
|
||||
name="LaitoolUpdateContent"
|
||||
>
|
||||
<TextArea autoSize={{ minRows: 3, maxRows: 6 }} placeholder="支持HTML和网址,网址用iframe" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="通知"
|
||||
name="LaitoolNotice"
|
||||
>
|
||||
<TextArea autoSize={{ minRows: 3, maxRows: 6 }} placeholder="支持HTML和网址,网址用iframe" />
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button color="primary" variant="filled" htmlType="submit">设置通用设置</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
{messageHolder}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SimpleOptions;
|
||||
@ -1,78 +0,0 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { GetOptions, getOptionsStringValue, SaveOptions } from '@/services/services/options/optionsTool';
|
||||
import { Button, Col, Form, Input, InputNumber, message, Row, Space } from 'antd';
|
||||
import { useSoftStore } from '@/store/software';
|
||||
|
||||
type TrailOptionsProps = {
|
||||
LaiToolTrialDays: number;
|
||||
}
|
||||
|
||||
const TrailOptions: React.FC = () => {
|
||||
|
||||
const [form] = Form.useForm();
|
||||
const { setTopSpinning, setTopSpinTip } = useSoftStore();
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
|
||||
useEffect(() => {
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("加载信息中");
|
||||
GetOptions("trial").then((res) => {
|
||||
form.setFieldsValue({
|
||||
LaiToolTrialDays: getOptionsStringValue(res, 'LaiToolTrialDays', ""),
|
||||
});
|
||||
}).catch((err: any) => {
|
||||
messageApi.error(err.message);
|
||||
}).finally(() => {
|
||||
setTopSpinning(false);
|
||||
});
|
||||
|
||||
}, []);
|
||||
|
||||
const formStyle: React.CSSProperties = {
|
||||
maxWidth: 'none',
|
||||
padding: 24,
|
||||
};
|
||||
|
||||
const onFinish = async (values: TrailOptionsProps) => {
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("正在保存试用设置");
|
||||
try {
|
||||
await SaveOptions(values);
|
||||
messageApi.success('保存软件试用设置成功');
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
} finally {
|
||||
setTopSpinning(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Form form={form} layout="vertical" name="advanced_search" style={formStyle} onFinish={onFinish}>
|
||||
<Row gutter={24} >
|
||||
<Col span={8} >
|
||||
<Form.Item
|
||||
label="软件最大试用天数"
|
||||
name="LaiToolTrialDays"
|
||||
rules={[{ required: true, message: '请输入软件最大试用天数' }]}
|
||||
>
|
||||
<InputNumber min={1} max={10} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={8} >
|
||||
|
||||
</Col>
|
||||
<Col span={8} >
|
||||
|
||||
</Col>
|
||||
</Row>
|
||||
<Form.Item>
|
||||
<Button color="primary" variant="filled" htmlType="submit">保存试用设置</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
{messageHolder}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TrailOptions;
|
||||
@ -1,29 +0,0 @@
|
||||
import { Card, Collapse, CollapseProps, Form } from 'antd';
|
||||
import React, { useEffect } from 'react';
|
||||
import SimpleOptions from './SimpleOptions';
|
||||
import TrailOptions from './TrialOptions';
|
||||
|
||||
|
||||
const DubSetting: React.FC = () => {
|
||||
|
||||
const onChange = (key: string | string[]) => {
|
||||
};
|
||||
|
||||
const items: CollapseProps['items'] = [
|
||||
{
|
||||
key: 'simpleOptions',
|
||||
label: '通用配置',
|
||||
children: <SimpleOptions></SimpleOptions>,
|
||||
}, {
|
||||
key: 'trailOptions',
|
||||
label: '试用设置',
|
||||
children: <TrailOptions />,
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<Collapse items={items} bordered={false} ghost onChange={onChange} />
|
||||
);
|
||||
};
|
||||
|
||||
export default DubSetting;
|
||||
@ -1,62 +0,0 @@
|
||||
import { getOptionsStringValue, SaveOptions } from '@/services/services/options/optionsTool';
|
||||
import { useOptionsStore } from '@/store/options';
|
||||
import { useSoftStore } from '@/store/software';
|
||||
import { Button, Card, Col, Form, Input, message, Row } from 'antd';
|
||||
import TextArea from 'antd/es/input/TextArea';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
const DubSettingTTsOptions: React.FC = () => {
|
||||
|
||||
const [form] = Form.useForm();
|
||||
const { ttsOptions, setTTsOptions } = useOptionsStore();
|
||||
const { topSpinning, setTopSpinning, topSpinTip, setTopSpinTip } = useSoftStore();
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
|
||||
async function onFinish(values: any): Promise<void> {
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("正在保存EdgeTTs配置");
|
||||
try {
|
||||
await SaveOptions(values);
|
||||
setTTsOptions(ttsOptions.map((item: OptionModel.Option) => {
|
||||
if (item.key === "EdgeTTsRoles") {
|
||||
item.value = values.edgeTTsRoles
|
||||
}
|
||||
return item
|
||||
}));
|
||||
messageApi.success('设置成功');
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
} finally {
|
||||
setTopSpinning(false);
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
form.setFieldsValue({ edgeTTsRoles: getOptionsStringValue(ttsOptions, 'EdgeTTsRoles', "{}") })
|
||||
}, [ttsOptions])
|
||||
|
||||
|
||||
return (
|
||||
<Card title="配置" >
|
||||
<Form form={form} name="advanced_search" onFinish={onFinish} layout="vertical">
|
||||
<Row gutter={24}>
|
||||
<Col span={8}>
|
||||
<Form.Item
|
||||
label="语音合成角色"
|
||||
name="edgeTTsRoles"
|
||||
>
|
||||
<TextArea placeholder="请输入EdgeTTs合成角色,JSON格式" autoSize={{ minRows: 6, maxRows: 6 }} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Form.Item wrapperCol={{ offset: 0, span: 16 }}>
|
||||
<Button color="primary" variant="filled" htmlType="submit">
|
||||
保存EdgeTTs配置
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
{messageHolder}
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default DubSettingTTsOptions;
|
||||
@ -1,49 +0,0 @@
|
||||
import { Card, Collapse, CollapseProps, Form } from 'antd';
|
||||
import React, { useEffect } from 'react';
|
||||
import DubSettingTTsOptions from './DubSettingTTsOptions';
|
||||
import { useOptionsStore } from '@/store/options';
|
||||
import { useSoftStore } from '@/store/software';
|
||||
import { GetOptions } from '@/services/services/options/optionsTool';
|
||||
|
||||
|
||||
const DubSetting: React.FC = () => {
|
||||
const { ttsOptions, setTTsOptions } = useOptionsStore();
|
||||
const { setTopSpinning, setTopSpinTip } = useSoftStore();
|
||||
|
||||
const onChange = (key: string | string[]) => {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("加载信息中");
|
||||
// 这边加载所有的配音数据
|
||||
GetOptions('tts').then((res) => {
|
||||
setTTsOptions(res);
|
||||
}
|
||||
).catch((err) => {
|
||||
console.error(err);
|
||||
}).finally(() => {
|
||||
setTopSpinning(false);
|
||||
});
|
||||
|
||||
}, []);
|
||||
|
||||
const items: CollapseProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
label: '配置',
|
||||
children: <p></p>,
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
label: <strong>Edge TTS</strong>,
|
||||
children: <DubSettingTTsOptions />,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Collapse items={items} bordered={false} ghost onChange={onChange} />
|
||||
);
|
||||
};
|
||||
|
||||
export default DubSetting;
|
||||
@ -1,38 +0,0 @@
|
||||
import TemplateContainer from '@/pages/TemplateContainer';
|
||||
import { useModel } from '@umijs/max';
|
||||
import { Tabs, TabsProps, theme } from 'antd';
|
||||
import React from 'react';
|
||||
import DubSetting from '../DubSetting';
|
||||
import BasicOptions from '../BasicOptions';
|
||||
|
||||
|
||||
const LaitoolOptions: React.FC = () => {
|
||||
|
||||
const { initialState } = useModel('@@initialState');
|
||||
const [tabKey, setTabKey] = React.useState<string | undefined>(undefined);
|
||||
|
||||
const items = [{
|
||||
label: `软件设置`,
|
||||
key: "software",
|
||||
children: <BasicOptions />,
|
||||
style: undefined,
|
||||
}, {
|
||||
label: `配音设置`,
|
||||
key: "dub",
|
||||
children: <DubSetting />,
|
||||
style: undefined,
|
||||
destroyInactiveTabPane : true
|
||||
}]
|
||||
|
||||
const onChange = (key: string) => {
|
||||
setTabKey(key);
|
||||
};
|
||||
|
||||
return (
|
||||
<TemplateContainer title={false} navTheme={initialState?.settings?.navTheme ?? "realDark"}>
|
||||
<Tabs defaultActiveKey="1" destroyInactiveTabPane={true} items={items} onChange={onChange} />
|
||||
</TemplateContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default LaitoolOptions;
|
||||
153
src/pages/Prompt/ManagePrompt/index.tsx
Normal file
153
src/pages/Prompt/ManagePrompt/index.tsx
Normal file
@ -0,0 +1,153 @@
|
||||
|
||||
import { addPrompt, getPromptDetail, modifyPrompt } from '@/services/services/prompt';
|
||||
import { Button, Col, Form, FormProps, Input, InputNumber, message, Row, Select, Space, Switch } from 'antd';
|
||||
import React from 'react';
|
||||
import react, { useEffect, useState } from 'react';
|
||||
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 14 },
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
interface PromptManagementProps {
|
||||
type: string; // 接收的类型
|
||||
promptType: Prompt.PromptTypeListItem[] | undefined; // 提示词类型
|
||||
id: string | undefined; // 提示词id
|
||||
}
|
||||
|
||||
const PromptManagement: React.FC<PromptManagementProps> = ({ type, promptType, id }) => {
|
||||
|
||||
const [form] = Form.useForm();
|
||||
const [promptTypeOptions, setPromptTypeOptions] = useState<{ label: string, value: string }[]>([]);
|
||||
const [data, setData] = useState<Prompt.AddPrompt>();
|
||||
|
||||
// 使用 useEffect 设置表单初始值
|
||||
useEffect(() => {
|
||||
form.resetFields();
|
||||
if (type == 'edit') {
|
||||
// 在编辑的时候,初始化数据
|
||||
getPromptDetail(id ?? "").then((res: API.SuccessItem | API.ErrorItem) => {
|
||||
if (res.code === 1) {
|
||||
const fetchedData = res.data;
|
||||
setData(fetchedData);
|
||||
form.setFieldsValue({
|
||||
...fetchedData,
|
||||
status: fetchedData.status === 'enable',
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.resetFields();
|
||||
}
|
||||
|
||||
let ops: react.SetStateAction<{ label: string; value: string; }[]> = []
|
||||
promptType?.forEach(item => {
|
||||
ops.push({ label: item.name, value: item.id })
|
||||
})
|
||||
setPromptTypeOptions(ops)
|
||||
|
||||
}, [type, id, form, promptType]);
|
||||
|
||||
const modifyCode = (value: string) => {
|
||||
let code = promptType?.find(item => item.id == value)?.code
|
||||
form.setFieldsValue({ promptTypeCode: code })
|
||||
}
|
||||
|
||||
|
||||
const onFinish: FormProps<Prompt.AddPrompt>['onFinish'] = async (values) => {
|
||||
values.status = values.status ? "enable" : "disable";
|
||||
if (type == "add") {
|
||||
// 添加
|
||||
let addRes = await addPrompt(values)
|
||||
if (addRes.code != 1) {
|
||||
message.error("添加失败," + addRes.message);
|
||||
return
|
||||
}
|
||||
message.success("添加成功");
|
||||
} else {
|
||||
// 修改
|
||||
let editRes = await modifyPrompt({ ...values, id: data?.id });
|
||||
if (editRes.code != 1) {
|
||||
message.error("修改失败," + editRes.message);
|
||||
return
|
||||
}
|
||||
message.success("修改成功");
|
||||
}
|
||||
};
|
||||
|
||||
const onFinishFailed: FormProps<Prompt.AddPrompt>['onFinishFailed'] = (errorInfo) => {
|
||||
console.log('Failed:', errorInfo);
|
||||
};
|
||||
|
||||
|
||||
return (<>
|
||||
<Form
|
||||
form={form}
|
||||
preserve={false}
|
||||
{...formItemLayout}
|
||||
labelAlign="right"
|
||||
variant="filled"
|
||||
onFinish={onFinish}
|
||||
onFinishFailed={onFinishFailed}
|
||||
initialValues={data}>
|
||||
<Row>
|
||||
<Col flex="auto">
|
||||
<Form.Item<Prompt.AddPrompt> label="名称" name="name" rules={[{ required: true },]}>
|
||||
<Input placeholder="请输入提示词名称" />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPrompt> label="类型" name="promptTypeId" rules={[{ required: true }]} >
|
||||
<Select options={promptTypeOptions} allowClear onChange={modifyCode} >
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPrompt> label="备注" name="remark">
|
||||
<Input placeholder="请输入提示词备注" />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPrompt> label="编码" name="promptTypeCode">
|
||||
<Input placeholder="请输入提示词类型编码" disabled={true} />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPrompt> label="创建者" >
|
||||
<Input placeholder="请输入提示词创建者" disabled={true} value={data?.createUser?.nickname} />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPrompt> label="修改者">
|
||||
<Input placeholder="请输入提示词修改者" disabled={true} value={data?.updateUser?.nickname} />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPrompt> label="修改时间" name="updateTime">
|
||||
<Input placeholder="请输入提示词修改时间" disabled={true} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col flex="auto" style={{ marginLeft: "20px" }}>
|
||||
<Form.Item<Prompt.AddPrompt> label="描述" name="description">
|
||||
<Input placeholder="请输入提示词描述" />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPrompt> label="版本" name="version">
|
||||
<InputNumber style={{ width: "100%" }} placeholder="请输入提示词版本" />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPrompt> label="状态" name="status">
|
||||
<Switch checkedChildren="启用" unCheckedChildren="停用" defaultChecked />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPrompt> label="提示词设定" name="promptString" rules={[{ required: true }]}>
|
||||
<Input.TextArea autoSize={
|
||||
{ minRows: 6, maxRows: 6 }
|
||||
} placeholder="请输入提示词设定" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Form.Item style={{ display: "flex", justifyContent: "flex-end", alignItems: "flex-end" }} >
|
||||
<Button type="primary" htmlType="submit">
|
||||
Submit
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form >
|
||||
</>)
|
||||
|
||||
}
|
||||
|
||||
export default PromptManagement;
|
||||
112
src/pages/Prompt/ManagePromptType/index.tsx
Normal file
112
src/pages/Prompt/ManagePromptType/index.tsx
Normal file
@ -0,0 +1,112 @@
|
||||
|
||||
import { addPromptType, editPromptType } from '@/services/services/prompt';
|
||||
import { Button, Col, Form, FormProps, Input, InputNumber, message, Row, Select, Space, Switch } from 'antd';
|
||||
import React from 'react';
|
||||
import react, { useEffect, useState } from 'react';
|
||||
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 14 },
|
||||
},
|
||||
};
|
||||
|
||||
interface PromptManagementProps {
|
||||
type: string; // Replace 'string' with the actual type of the 'type' prop
|
||||
data?: Prompt.AddPromptType; // 初始化的提示词数据
|
||||
}
|
||||
|
||||
|
||||
const PromptManagement: React.FC<PromptManagementProps> = ({ type, data }) => {
|
||||
const [form] = Form.useForm();
|
||||
// 使用 useEffect 设置表单初始值
|
||||
useEffect(() => {
|
||||
form.resetFields();
|
||||
if (type === 'edit' && data) {
|
||||
form.setFieldsValue(data);
|
||||
} else {
|
||||
}
|
||||
|
||||
data?.status == "enable" ? form.setFieldsValue({ status: true }) : form.setFieldsValue({ status: false });
|
||||
}, [type, data, form]);
|
||||
|
||||
const onFinish: FormProps<Prompt.AddPromptType>['onFinish'] = async (values) => {
|
||||
// 处理values
|
||||
values.status = values.status ? "enable" : "disable";
|
||||
if (type == "add") {
|
||||
let addRes = await addPromptType(values);
|
||||
if (addRes.code != 1) {
|
||||
message.error("添加失败," + addRes.message);
|
||||
return
|
||||
}
|
||||
message.success("添加成功");
|
||||
} else {
|
||||
let editRes = await editPromptType({ ...values, id: data?.id });
|
||||
if (editRes.code != 1) {
|
||||
message.error("修改失败," + editRes.message);
|
||||
return
|
||||
}
|
||||
message.success("修改成功");
|
||||
}
|
||||
};
|
||||
|
||||
const onFinishFailed: FormProps<Prompt.AddPromptType>['onFinishFailed'] = (errorInfo) => {
|
||||
console.log('Failed:', errorInfo);
|
||||
};
|
||||
|
||||
return (<>
|
||||
<Form
|
||||
preserve={false}
|
||||
form={form}
|
||||
{...formItemLayout}
|
||||
labelAlign="right"
|
||||
variant="filled"
|
||||
onFinish={onFinish}
|
||||
onFinishFailed={onFinishFailed}
|
||||
clearOnDestroy={true}
|
||||
initialValues={data}>
|
||||
<Row>
|
||||
<Col flex="auto">
|
||||
<Form.Item<Prompt.AddPromptType> label="名称" name="name" rules={[{ required: true }]}>
|
||||
<Input placeholder="请输入提示词类型名称" />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPromptType> label="编码" name="code" rules={[{ required: true }]}>
|
||||
<Input placeholder="请输入提示词描述" />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPromptType> label="创建者" >
|
||||
<Input disabled={true} placeholder="请输入提示词创建者" value={data?.createUser?.nickname} />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPromptType> label="修改者" >
|
||||
<Input disabled={true} placeholder="请输入提示词修改者" value={data?.updateUser?.nickname} />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPromptType> label="修改时间" name="updateTime">
|
||||
<Input disabled={true} placeholder="请输入提示词修改时间" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col flex="auto" style={{ marginLeft: "20px" }}>
|
||||
<Form.Item<Prompt.AddPromptType> label="状态" name="status">
|
||||
<Switch disabled={type === "add"} checkedChildren="启用" unCheckedChildren="停用" defaultChecked />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPromptType> label="提示词设定" name="remark">
|
||||
<Input.TextArea autoSize={
|
||||
{ minRows: 6, maxRows: 6 }
|
||||
} placeholder="请输入提示词设定" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Form.Item style={{ display: "flex", justifyContent: "flex-end", alignItems: "flex-end" }} >
|
||||
<Button type="primary" htmlType="submit">
|
||||
Submit
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form >
|
||||
</>)
|
||||
|
||||
}
|
||||
|
||||
export default PromptManagement;
|
||||
@ -1,162 +0,0 @@
|
||||
|
||||
import { AddPrompt, GetPromptInfo, ModifyPrompt } from '@/services/services/prompt';
|
||||
import { Button, Col, Form, FormInstance, FormProps, Input, InputNumber, message, Row, Select, Space, Spin, Switch } from 'antd';
|
||||
import React, { version } from 'react';
|
||||
import react, { useEffect, useState } from 'react';
|
||||
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 14 },
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
interface PromptManagementProps {
|
||||
type: string; // 接收的类型
|
||||
promptTypeOptions: Prompt.PromptTypeOptions[] | undefined; // 提示词类型
|
||||
setFormRef: (form: FormInstance) => void;
|
||||
id: string | undefined; // 提示词id
|
||||
open: boolean; // 是否打开
|
||||
}
|
||||
|
||||
const PromptManagement: React.FC<PromptManagementProps> = ({ type, promptTypeOptions, setFormRef, id, open }) => {
|
||||
|
||||
const [form] = Form.useForm();
|
||||
const [data, setData] = useState<Prompt.PromptItem>();
|
||||
const [spinning, setSpinning] = useState<boolean>(true);
|
||||
const [spinTip, setSpinTip] = useState<string>('加载中数据中。。。');
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
|
||||
useEffect(() => {
|
||||
setFormRef(form);
|
||||
setData(undefined);
|
||||
}, [form, setFormRef]);
|
||||
|
||||
|
||||
// 使用 useEffect 设置表单初始值
|
||||
useEffect(() => {
|
||||
setSpinning(true);
|
||||
setSpinTip('加载中数据中。。。');
|
||||
if (type == 'edit') {
|
||||
// 在编辑的时候,初始化数据
|
||||
if (id !== undefined && open) {
|
||||
GetPromptInfo(id).then((res: Prompt.PromptItem) => {
|
||||
setData(res);
|
||||
form.setFieldsValue(res);
|
||||
setSpinning(false)
|
||||
}).catch((error: any) => {
|
||||
messageApi.error(error.message);
|
||||
}).finally(() => {
|
||||
setSpinning(false);
|
||||
});
|
||||
}
|
||||
data?.status == "enable" ? form.setFieldsValue({ status: true }) : form.setFieldsValue({ status: false });
|
||||
} else {
|
||||
setSpinning(false);
|
||||
form.resetFields();
|
||||
form.setFieldsValue({ status: true, version: 1 });
|
||||
}
|
||||
}, [type, id, form, promptTypeOptions, open]);
|
||||
|
||||
|
||||
const onFinish: FormProps<Prompt.PromptItem>['onFinish'] = async (values) => {
|
||||
setSpinning(true);
|
||||
setSpinTip("正在修改数据。。。");
|
||||
try {
|
||||
values.status = values.status ? "enable" : "disable";
|
||||
if (type == "add") {
|
||||
// 添加
|
||||
let promptId = await AddPrompt(values)
|
||||
setData({ ...values, id: promptId });
|
||||
messageApi.success("添加提示词成功");
|
||||
} else {
|
||||
// 修改
|
||||
if (id == undefined) {
|
||||
messageApi.error("未知提示词ID");
|
||||
} else {
|
||||
await ModifyPrompt(id, values);
|
||||
messageApi.success("修改提示词数据成功");
|
||||
}
|
||||
}
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
} finally {
|
||||
setSpinning(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
return (<>
|
||||
<Spin spinning={spinning} tip={spinTip}>
|
||||
{messageHolder}
|
||||
<Form
|
||||
form={form}
|
||||
preserve={false}
|
||||
{...formItemLayout}
|
||||
labelAlign="right"
|
||||
variant="filled"
|
||||
onFinish={onFinish}
|
||||
initialValues={data}>
|
||||
<Row>
|
||||
<Col flex="auto">
|
||||
<Form.Item<Prompt.PromptItem> label="名称" name="name" rules={[{ required: true },]}>
|
||||
<Input placeholder="请输入提示词名称" />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.PromptItem> label="类型" name="promptTypeId" rules={[{ required: true }]} >
|
||||
<Select options={promptTypeOptions?.map(item => {
|
||||
return {
|
||||
label: item.name,
|
||||
value: item.id
|
||||
}
|
||||
})} allowClear >
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.PromptItem> label="备注" name="remark">
|
||||
<Input placeholder="请输入提示词备注" />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.PromptItem> label="创建者" >
|
||||
<Input placeholder="请输入提示词创建者" disabled={true} value={data?.createdUser?.nickName} />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.PromptItem> label="修改者" >
|
||||
<Input placeholder="请输入提示词修改者" disabled={true} value={data?.updatedUser?.nickName} />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.PromptItem> label="修改时间" name="updateTime">
|
||||
<Input placeholder="请输入提示词修改时间" disabled={true} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col flex="auto" style={{ marginLeft: "20px" }}>
|
||||
<Form.Item<Prompt.PromptItem> label="描述" name="description">
|
||||
<Input placeholder="请输入提示词描述" />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.PromptItem> label="版本" name="version">
|
||||
<InputNumber style={{ width: "100%" }} placeholder="请输入提示词版本" />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.PromptItem> label="状态" name="status">
|
||||
<Switch checkedChildren="启用" unCheckedChildren="停用" defaultChecked />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.PromptItem> label="提示词设定" name="promptString" rules={[{ required: true }]}>
|
||||
<Input.TextArea autoSize={
|
||||
{ minRows: 6, maxRows: 6 }
|
||||
} placeholder="请输入提示词设定" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Form.Item style={{ display: "flex", justifyContent: "flex-end", alignItems: "flex-end" }} >
|
||||
<Button type="primary" htmlType="submit">
|
||||
Submit
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form >
|
||||
</Spin>
|
||||
</>)
|
||||
|
||||
}
|
||||
|
||||
export default PromptManagement;
|
||||
@ -1,199 +1,157 @@
|
||||
import { PageContainer } from '@ant-design/pro-components';
|
||||
import { useModel } from '@umijs/max';
|
||||
import { Card, Form, GetProp, Input, message, Modal, Select, Table, TablePaginationConfig, TableProps, theme, Tooltip } from 'antd';
|
||||
import { Card, Form, GetProp, Input, message, Modal, Table, TablePaginationConfig, TableProps, theme } from 'antd';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { EllipsisOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import type { ActionType, ProColumns } from '@ant-design/pro-components';
|
||||
import { ProTable, TableDropdown } from '@ant-design/pro-components';
|
||||
import { Button, Dropdown, Space, Tag } from 'antd';
|
||||
import { useRef } from 'react';
|
||||
import { ColumnsType, SorterResult } from 'antd/es/table/interface';
|
||||
import qs from 'qs';
|
||||
import { DeletePrompt, GetPromptTypeOptions, QueryPromptCollection, QueryPromptypeCollection } from '@/services/services/prompt';
|
||||
import ManagePrompt from './ManagePrompt/index';
|
||||
import { useFormReset } from '@/hooks/useFormReset';
|
||||
import TextArea from 'antd/es/input/TextArea';
|
||||
import { useSoftStore } from '@/store/software';
|
||||
import TemplateContainer from '@/pages/TemplateContainer';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import { getPromptSample, getPrompyType } from '@/services/services/prompt';
|
||||
import ManagePrompt from '../ManagePrompt/index';
|
||||
export const waitTimePromise = async (time: number = 100) => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve(true);
|
||||
}, time);
|
||||
});
|
||||
};
|
||||
|
||||
export const waitTime = async (time: number = 100) => {
|
||||
await waitTimePromise(time);
|
||||
};
|
||||
|
||||
|
||||
interface TableParams {
|
||||
pagination?: TablePaginationConfig;
|
||||
sortField?: SorterResult<any>['field'];
|
||||
sortOrder?: SorterResult<any>['order'];
|
||||
filters?: Parameters<GetProp<TableProps, 'onChange'>>[1];
|
||||
}
|
||||
|
||||
interface TableParams {
|
||||
pagination?: TablePaginationConfig;
|
||||
sortField?: SorterResult<any>['field'];
|
||||
sortOrder?: SorterResult<any>['order'];
|
||||
filters?: Parameters<GetProp<TableProps, 'onChange'>>[1];
|
||||
}
|
||||
|
||||
const getRandomuserParams = (params: TableParams) => ({
|
||||
results: params.pagination?.pageSize,
|
||||
page: params.pagination?.current,
|
||||
...params,
|
||||
});
|
||||
|
||||
const PromptManagement: React.FC = () => {
|
||||
const { token } = theme.useToken();
|
||||
const { initialState } = useModel('@@initialState');
|
||||
const [data, setData] = useState<Prompt.PromptItem[]>();
|
||||
|
||||
const [data, setData] = useState<[Prompt.PromptListItem][]>();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [form] = Form.useForm();
|
||||
const [open, setOpen] = React.useState<boolean>(false);
|
||||
const [type, setType] = useState<string>("add");
|
||||
const [promptId, setPromptId] = useState<string>();
|
||||
const [promptTypeOptions, setPromptTypeOptions] = useState<Prompt.PromptTypeOptions[]>();
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
const { setFormRef, resetForm } = useFormReset();
|
||||
const [modal, modalHolder] = Modal.useModal();
|
||||
const { setTopSpinTip, setTopSpinning } = useSoftStore();
|
||||
|
||||
const [tableParams, setTableParams] = useState<TableModel.TableParams>({
|
||||
const [type, setType] = useState<string>("add");
|
||||
const [editData, setEditData] = useState<Prompt.AddPrompt>();
|
||||
const [promptType, setPromptType] = useState<Prompt.PromptTypeListItem[]>();
|
||||
const [formKey, setFormKey] = useState(Date.now().toString());
|
||||
|
||||
const [tableParams, setTableParams] = useState<TableParams>({
|
||||
pagination: {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
showQuickJumper: true,
|
||||
totalBoundaryShowSizeChanger: true,
|
||||
},
|
||||
});
|
||||
|
||||
const columns: ColumnsType<Prompt.PromptItem> = [
|
||||
const columns: ColumnsType<Prompt.PromptListItem> = [
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
width: '220px',
|
||||
sorter: true,
|
||||
width: '120px',
|
||||
},
|
||||
{
|
||||
title: '提示词类型',
|
||||
dataIndex: 'promptType',
|
||||
width: '200px',
|
||||
render: (_, record) => {
|
||||
return record.promptType?.name;
|
||||
},
|
||||
title: 'Gender',
|
||||
dataIndex: 'gender',
|
||||
filters: [
|
||||
{ text: 'Male', value: 'male' },
|
||||
{ text: 'Female', value: 'female' },
|
||||
],
|
||||
width: '200',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
width: '70px',
|
||||
render: (dom, en) => <>
|
||||
<Tag color={en.status == "enable" ? "green" : "red"}> {en.status == "enable" ? '启用' : "停用"} </Tag>
|
||||
</>
|
||||
},
|
||||
{
|
||||
title: '提示词设定',
|
||||
dataIndex: 'promptString',
|
||||
ellipsis: {
|
||||
showTitle: false,
|
||||
},
|
||||
render: (promptString) => (
|
||||
<span style={{ cursor: "pointer" }} onClick={() => showPrompt(promptString)}>
|
||||
{promptString}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
dataIndex: 'description',
|
||||
width: '200px',
|
||||
ellipsis: {
|
||||
showTitle: false,
|
||||
},
|
||||
render: (remark) => (
|
||||
<Tooltip placement="topLeft" title={remark}>
|
||||
{remark}
|
||||
</Tooltip>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
dataIndex: 'remark',
|
||||
width: '200px',
|
||||
ellipsis: {
|
||||
showTitle: false,
|
||||
},
|
||||
render: (remark) => (
|
||||
<Tooltip placement="topLeft" title={remark}>
|
||||
{remark}
|
||||
</Tooltip>
|
||||
),
|
||||
title: 'Email',
|
||||
dataIndex: 'email',
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
dataIndex: 'option',
|
||||
width: '200px',
|
||||
render: (_, record) => <>
|
||||
<Button size='middle' style={{ marginRight: "5px" }} type="primary" onClick={() => {
|
||||
debugger
|
||||
setEditData(record)
|
||||
setType("edit")
|
||||
setOpen(true)
|
||||
setPromptId(record.id)
|
||||
}}>编辑</Button>
|
||||
<Button size='middle' type="primary" danger onClick={async () => await DeletePromptHandle(record.id)}>删除</Button>
|
||||
}}>编辑</Button>,
|
||||
<Button size='middle' type="primary" danger>删除</Button>,
|
||||
</>
|
||||
}
|
||||
];
|
||||
|
||||
async function DeletePromptHandle(id: string) {
|
||||
try {
|
||||
if (id == null) {
|
||||
messageApi.error("未知提示词ID");
|
||||
}
|
||||
let confirmed = await modal.confirm({
|
||||
title: "删除提示词",
|
||||
content: "确定删除提示词吗?",
|
||||
okText: "确认",
|
||||
cancelText: "取消"
|
||||
});
|
||||
if (confirmed) {
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("正在删除数据。。。")
|
||||
await DeletePrompt(id);
|
||||
messageApi.success("删除提示词成功");
|
||||
setTopSpinning(false);
|
||||
await fetchData();
|
||||
} else {
|
||||
messageApi.info("取消删除操作");
|
||||
}
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
} finally {
|
||||
setTopSpinning(false);
|
||||
}
|
||||
}
|
||||
|
||||
function showPrompt(content: string) {
|
||||
modal.info({
|
||||
width: 800,
|
||||
title: '',
|
||||
footer: null,
|
||||
icon: null,
|
||||
closable: true,
|
||||
closeIcon: true,
|
||||
content: (
|
||||
<TextArea style={{ marginTop: "10px" }} defaultValue={content} autoSize>
|
||||
</TextArea >)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const fetchData = async () => {
|
||||
debugger
|
||||
setLoading(true);
|
||||
try {
|
||||
let param: Prompt.PromptQueryCondition = {
|
||||
...form.getFieldsValue(),
|
||||
page: tableParams.pagination?.current,
|
||||
pageSize: tableParams.pagination?.pageSize
|
||||
}
|
||||
let promptRes = await QueryPromptCollection(param);
|
||||
|
||||
setData(promptRes.collection);
|
||||
let promptRes = await getPromptSample("all", tableParams.pagination?.pageSize, tableParams.pagination?.current)
|
||||
|
||||
if (promptRes.code == 1) {
|
||||
message.success("获取提示词设置成功")
|
||||
setData(promptRes.data)
|
||||
setLoading(false);
|
||||
setTableParams({
|
||||
...tableParams,
|
||||
pagination: {
|
||||
...tableParams.pagination,
|
||||
total: promptRes.total,
|
||||
total: promptRes.data.count,
|
||||
// 200 is mock data, you should read it from server
|
||||
// total: data.totalCount,
|
||||
},
|
||||
});
|
||||
message.success("获取提示词成功")
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
} finally {
|
||||
} else {
|
||||
setLoading(false);
|
||||
message.error("获取提示词设置失败")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
GetPromptTypeOptions().then((res: Prompt.PromptTypeOptions[]) => {
|
||||
setPromptTypeOptions(res);
|
||||
}).catch((error: any) => {
|
||||
messageApi.error(error.message);
|
||||
// 加载提示词类型
|
||||
getPrompyType(100, 1).then(res => {
|
||||
if (res.code == 1) {
|
||||
setPromptType(res.data)
|
||||
} else {
|
||||
message.error("获取提示词类型失败")
|
||||
}
|
||||
});
|
||||
}, [tableParams.pagination?.current,
|
||||
tableParams.pagination?.pageSize]);
|
||||
}, [
|
||||
tableParams.pagination?.current,
|
||||
tableParams.pagination?.pageSize,
|
||||
tableParams?.sortOrder,
|
||||
tableParams?.sortField,
|
||||
JSON.stringify(tableParams.filters),
|
||||
]);
|
||||
|
||||
const handleTableChange = (pagination: any) => {
|
||||
const handleTableChange: TableProps['onChange'] = (pagination, filters, sorter) => {
|
||||
setTableParams({
|
||||
pagination,
|
||||
filters,
|
||||
sortOrder: Array.isArray(sorter) ? undefined : sorter.order,
|
||||
sortField: Array.isArray(sorter) ? undefined : sorter.field,
|
||||
});
|
||||
|
||||
// `dataSource` is useless since `pageSize` changed
|
||||
@ -203,7 +161,7 @@ const PromptManagement: React.FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<TemplateContainer navTheme={initialState?.settings?.navTheme ?? "realDark"}>
|
||||
<PageContainer>
|
||||
<Card
|
||||
style={{
|
||||
borderRadius: 8,
|
||||
@ -222,50 +180,32 @@ const PromptManagement: React.FC = () => {
|
||||
<Form
|
||||
layout='inline'
|
||||
form={form}
|
||||
onFinish={fetchData}
|
||||
>
|
||||
<Form.Item label="名称" name="name">
|
||||
<Form.Item label="名称">
|
||||
<Input placeholder="请输入查询提示词的名称" />
|
||||
</Form.Item>
|
||||
<Form.Item label="提示词类型" name="promptTypeId">
|
||||
<Select allowClear style={{ width: 200 }} options={promptTypeOptions?.map(item => {
|
||||
return {
|
||||
label: item.name,
|
||||
value: item.id
|
||||
}
|
||||
})} placeholder="请选择提示词类型" />
|
||||
</Form.Item>
|
||||
<Form.Item label="状态" name="status" >
|
||||
<Select style={{ width: 200 }} placeholder="请选择提示词状态" allowClear >
|
||||
<Select.Option value="enable">启用</Select.Option>
|
||||
<Select.Option value="disable">停用</Select.Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Form.Item label="备注" name="remark">
|
||||
<Input placeholder="请输入提示词备注" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item >
|
||||
<Button type="default" onClick={async () => {
|
||||
form.resetFields();
|
||||
await fetchData();
|
||||
}}>重置</Button>
|
||||
<Button type="primary">查询</Button>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item >
|
||||
<Button type="primary" htmlType='submit'>查询</Button>
|
||||
<Button type="default">重置</Button>
|
||||
</Form.Item>
|
||||
<Form.Item style={{ display: "flex", justifyContent: "flex-end", alignItems: "flex-end" }}>
|
||||
<div >
|
||||
<Button icon={<PlusOutlined />} type="primary" style={{ marginBottom: 10 }} onClick={() => {
|
||||
<Button type="primary" style={{ marginBottom: 10 }} onClick={() => {
|
||||
setOpen(true)
|
||||
setType("add")
|
||||
setFormKey(Date.now().toString()); // 每次打开 Modal 时更新 formKey,强制子组件重新渲染
|
||||
}}>
|
||||
新建数据
|
||||
</Button>
|
||||
</div>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<Table
|
||||
columns={columns}
|
||||
@ -283,7 +223,7 @@ const PromptManagement: React.FC = () => {
|
||||
onCancel={async () => {
|
||||
setOpen(false)
|
||||
await fetchData()
|
||||
resetForm(); // 每次打开 Modal 时更新 formKey,强制子组件重新渲染
|
||||
setFormKey(Date.now().toString()); // 每次打开 Modal 时更新 formKey,强制子组件重新渲染
|
||||
}}
|
||||
width={800}
|
||||
footer={null}
|
||||
@ -291,11 +231,9 @@ const PromptManagement: React.FC = () => {
|
||||
forceRender={true}
|
||||
destroyOnClose={true}
|
||||
>
|
||||
<ManagePrompt setFormRef={setFormRef} type={type} id={promptId} promptTypeOptions={promptTypeOptions} open={open} />
|
||||
<ManagePrompt key={formKey} type={type} id={editData?.id} promptType={promptType} />
|
||||
</Modal>
|
||||
{messageHolder}
|
||||
{modalHolder}
|
||||
</TemplateContainer>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -1,141 +0,0 @@
|
||||
|
||||
|
||||
import { AddPromptType, EditPromptType, GetPromptTypeInfo } from '@/services/services/prompt';
|
||||
import createSoftStore, { useSoftStore } from '@/store/software';
|
||||
import { Button, Col, Form, FormInstance, FormProps, Input, InputNumber, message, Row, Select, Space, Spin, Switch } from 'antd';
|
||||
import React from 'react';
|
||||
import react, { useEffect, useState } from 'react';
|
||||
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 14 },
|
||||
},
|
||||
};
|
||||
|
||||
interface PromptManagementProps {
|
||||
type: string; // Replace 'string' with the actual type of the 'type' prop
|
||||
setFormRef: (form: FormInstance) => void;
|
||||
id: string | undefined;
|
||||
open: boolean;
|
||||
}
|
||||
|
||||
const PromptManagement: React.FC<PromptManagementProps> = ({ type, setFormRef, id, open }) => {
|
||||
const [form] = Form.useForm();
|
||||
const [data, setData] = useState<Prompt.PromptTypeItem>();
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
const [spinning, setSpinning] = useState<boolean>(true);
|
||||
const [spinTip, setSpinTip] = useState<string>('加载中数据中。。。');
|
||||
|
||||
useEffect(() => {
|
||||
setFormRef(form);
|
||||
setData(undefined);
|
||||
}, [form, setFormRef]);
|
||||
|
||||
// 使用 useEffect 设置表单初始值
|
||||
useEffect(() => {
|
||||
if (type === 'edit') {
|
||||
setSpinning(true);
|
||||
// 远程加载数据
|
||||
if (id !== undefined && open) {
|
||||
GetPromptTypeInfo(id).then((res) => {
|
||||
setData(res);
|
||||
form.setFieldsValue(res);
|
||||
messageApi.success('数据加载成功');
|
||||
}).catch((error: any) => {
|
||||
messageApi.error(error.message);
|
||||
}).finally(() => {
|
||||
setSpinning(false);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
setSpinning(false);
|
||||
}
|
||||
data?.status == "enable" ? form.setFieldsValue({ status: true }) : form.setFieldsValue({ status: false });
|
||||
}, [type, form, open, setFormRef, id]);
|
||||
|
||||
const onFinish: FormProps<Prompt.AddPromptType>['onFinish'] = async (values) => {
|
||||
try {
|
||||
setSpinning(true);
|
||||
setSpinTip("正在修改数据。。。");
|
||||
// 处理values
|
||||
values.status = values.status ? "enable" : "disable";
|
||||
if (type == "add") {
|
||||
let addRes = await AddPromptType(values);
|
||||
messageApi.success(addRes);
|
||||
} else if (type == "edit") {
|
||||
let res = await EditPromptType({ ...values, id: data?.id });
|
||||
messageApi.success(res);
|
||||
} else {
|
||||
messageApi.error("未知操作类型");
|
||||
}
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
} finally {
|
||||
setSpinning(false);
|
||||
}
|
||||
};
|
||||
|
||||
const onFinishFailed: FormProps<Prompt.AddPromptType>['onFinishFailed'] = (errorInfo) => {
|
||||
};
|
||||
|
||||
return (<>
|
||||
{messageHolder}
|
||||
|
||||
<Spin spinning={spinning} tip={spinTip}>
|
||||
<Form
|
||||
preserve={false}
|
||||
form={form}
|
||||
{...formItemLayout}
|
||||
labelAlign="right"
|
||||
variant="filled"
|
||||
onFinish={onFinish}
|
||||
onFinishFailed={onFinishFailed}
|
||||
clearOnDestroy={true}
|
||||
initialValues={data}>
|
||||
<Row>
|
||||
<Col flex="auto">
|
||||
<Form.Item<Prompt.AddPromptType> label="名称" name="name" rules={[{ required: true }]}>
|
||||
<Input placeholder="请输入提示词类型名称" />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPromptType> label="编码" name="code" rules={[{ required: true }]}>
|
||||
<Input placeholder="请输入提示词描述" />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPromptType> label="创建者" >
|
||||
<Input disabled={true} placeholder="请输入提示词创建者" value={data?.createdUser?.nickName} />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPromptType> label="修改者" >
|
||||
<Input disabled={true} placeholder="请输入提示词修改者" value={data?.updatedUser?.nickName} />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPromptType> label="修改时间" name="updateTime">
|
||||
<Input disabled={true} placeholder="请输入提示词修改时间" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col flex="auto" style={{ marginLeft: "20px" }}>
|
||||
<Form.Item<Prompt.AddPromptType> label="状态" name="status">
|
||||
<Switch checkedChildren="启用" unCheckedChildren="停用" defaultChecked />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.AddPromptType> label="备注" name="remark">
|
||||
<Input.TextArea autoSize={
|
||||
{ minRows: 6, maxRows: 6 }
|
||||
} placeholder="请输入备注" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Form.Item style={{ display: "flex", justifyContent: "flex-end", alignItems: "flex-end" }} >
|
||||
<Button type="primary" htmlType="submit">
|
||||
Submit
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form >
|
||||
</Spin>
|
||||
</>)
|
||||
|
||||
}
|
||||
|
||||
export default PromptManagement;
|
||||
@ -1,14 +1,17 @@
|
||||
import { PageContainer } from '@ant-design/pro-components';
|
||||
import { useModel } from '@umijs/max';
|
||||
import { Card, Form, GetProp, Input, message, Modal, Select, Table, TablePaginationConfig, TableProps, theme } from 'antd';
|
||||
import { Card, Form, GetProp, Input, message, Modal, Table, TablePaginationConfig, TableProps, theme } from 'antd';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Button, Tag } from 'antd';
|
||||
import { ColumnsType } from 'antd/es/table/interface';
|
||||
import ManagePromptType from './ManagePromptType';
|
||||
import TemplateContainer from '@/pages/TemplateContainer';
|
||||
import { DeletePromptType, QueryPromptypeCollection } from '@/services/services/prompt';
|
||||
import { useFormReset } from '@/hooks/useFormReset';
|
||||
import { useSoftStore } from '@/store/software';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import { EllipsisOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import type { ActionType, ProColumns } from '@ant-design/pro-components';
|
||||
import { ProTable, TableDropdown } from '@ant-design/pro-components';
|
||||
import { Button, Dropdown, Space, Tag } from 'antd';
|
||||
import { useRef } from 'react';
|
||||
import { ColumnsType, SorterResult } from 'antd/es/table/interface';
|
||||
import qs from 'qs';
|
||||
import { getPromptSample, getPrompyType } from '@/services/services/prompt';
|
||||
import ManagePromptType from '../ManagePromptType';
|
||||
import { set } from 'lodash';
|
||||
export const waitTimePromise = async (time: number = 100) => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
@ -22,56 +25,67 @@ export const waitTime = async (time: number = 100) => {
|
||||
};
|
||||
|
||||
|
||||
interface TableParams {
|
||||
pagination?: TablePaginationConfig;
|
||||
sortField?: SorterResult<any>['field'];
|
||||
sortOrder?: SorterResult<any>['order'];
|
||||
filters?: Parameters<GetProp<TableProps, 'onChange'>>[1];
|
||||
}
|
||||
|
||||
interface TableParams {
|
||||
pagination?: TablePaginationConfig;
|
||||
sortField?: SorterResult<any>['field'];
|
||||
sortOrder?: SorterResult<any>['order'];
|
||||
filters?: Parameters<GetProp<TableProps, 'onChange'>>[1];
|
||||
}
|
||||
|
||||
const getRandomuserParams = (params: TableParams) => ({
|
||||
results: params.pagination?.pageSize,
|
||||
page: params.pagination?.current,
|
||||
...params,
|
||||
});
|
||||
|
||||
|
||||
const PromptManagement: React.FC = () => {
|
||||
const { token } = theme.useToken();
|
||||
const { initialState } = useModel('@@initialState');
|
||||
const [data, setData] = useState<Prompt.PromptTypeItem[]>();
|
||||
|
||||
const [data, setData] = useState<[Prompt.PromptTypeListItem][]>();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [form] = Form.useForm();
|
||||
const [open, setOpen] = React.useState<boolean>(false);
|
||||
|
||||
const [type, setType] = useState<string>("add");
|
||||
const [promptTypeId, setPromptTypeId] = useState<string>();
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
const [modal, modalHolder] = Modal.useModal();
|
||||
const { setFormRef, resetForm } = useFormReset();
|
||||
const { setTopSpinning, setTopSpinTip } = useSoftStore();
|
||||
const [tableParams, setTableParams] = useState<TableModel.TableParams>({
|
||||
const [editData, setEditData] = useState<Prompt.AddPromptType>();
|
||||
|
||||
const [tableParams, setTableParams] = useState<TableParams>({
|
||||
pagination: {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
showQuickJumper: true,
|
||||
totalBoundaryShowSizeChanger: true,
|
||||
},
|
||||
});
|
||||
|
||||
const fetchData = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
let params = {
|
||||
...form.getFieldsValue(),
|
||||
pageSize: tableParams.pagination?.pageSize ?? 10,
|
||||
page: tableParams.pagination?.current ?? 1,
|
||||
} as Prompt.PromptTypeQueryCondition;
|
||||
|
||||
let promptRes = await QueryPromptypeCollection(params)
|
||||
setData(promptRes.collection);
|
||||
let promptRes = await getPrompyType(tableParams.pagination?.pageSize, tableParams.pagination?.current)
|
||||
if (promptRes.code == 1) {
|
||||
message.success("获取提示词类型成功")
|
||||
setData(promptRes.data)
|
||||
setLoading(false);
|
||||
setTableParams({
|
||||
...tableParams,
|
||||
pagination: {
|
||||
...tableParams.pagination,
|
||||
total: promptRes.total,
|
||||
total: promptRes.data.count,
|
||||
},
|
||||
});
|
||||
|
||||
message.success("获取提示词类型成功")
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
} finally {
|
||||
} else {
|
||||
setLoading(false);
|
||||
message.error("获取提示词类型失败")
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const columns: ColumnsType<Prompt.PromptTypeItem> = [
|
||||
const columns: ColumnsType<Prompt.PromptTypeListItem> = [
|
||||
{
|
||||
title: '编码',
|
||||
dataIndex: 'code',
|
||||
@ -88,7 +102,7 @@ const PromptManagement: React.FC = () => {
|
||||
dataIndex: 'status',
|
||||
width: '100px',
|
||||
render: (dom, en) => <>
|
||||
<Tag color={en.status == "enable" ? "green" : "red"}> {en.status == "enable" ? '启用' : "停用"} </Tag>
|
||||
<Tag color={en.status == "enable" ? "green" : "red"}>启用</Tag>
|
||||
</>
|
||||
},
|
||||
{
|
||||
@ -101,61 +115,16 @@ const PromptManagement: React.FC = () => {
|
||||
width: 220,
|
||||
render: (dom, ent) => <>
|
||||
<Button size='middle' style={{ marginRight: "5px" }} type="primary" onClick={() => {
|
||||
debugger
|
||||
setEditData(ent)
|
||||
setType("edit")
|
||||
setPromptTypeId(ent.id)
|
||||
setOpen(true)
|
||||
}}>编辑</Button>
|
||||
<Button size='middle' type="primary" danger onClick={async () => await DeletePromptTypeHandle(ent.id)}>删除</Button>
|
||||
}}>编辑</Button>,
|
||||
<Button size='middle' type="primary" danger>删除</Button>,
|
||||
</>
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
async function DeletePromptTypeHandle(id: string) {
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("正在删除数据。。。")
|
||||
try {
|
||||
// 调用删除的方法
|
||||
let res = await DeletePromptType(id, false);
|
||||
if (res.code == 6001) {
|
||||
// 提示词,删除失败是不是删除对应的关联的提示词数据
|
||||
const confirmed = await modal.confirm({
|
||||
title: "删除提示词类型提醒",
|
||||
content: (
|
||||
<div>
|
||||
<span>正在删除的提示词类型有关联提示词预设数据,是不是同步删除对应的关联数据!</span>
|
||||
<br />
|
||||
<span>点击确认,删除相关数据!!!</span>
|
||||
</div>
|
||||
),
|
||||
okText: "确认",
|
||||
cancelText: "取消"
|
||||
})
|
||||
if (confirmed) {
|
||||
// 开始删除
|
||||
let confirmDelete = await DeletePromptType(id, true);
|
||||
if (confirmDelete.code != 1) {
|
||||
throw new Error(confirmDelete.message);
|
||||
}
|
||||
}
|
||||
else {
|
||||
messageApi.error("取消删除");
|
||||
return;
|
||||
}
|
||||
} else if (res.code == 1) {
|
||||
// 删除成功
|
||||
} else {
|
||||
throw new Error(res.message)
|
||||
}
|
||||
message.success("删除成功")
|
||||
setTopSpinning(false);
|
||||
await fetchData()
|
||||
} catch (error: any) {
|
||||
message.error(error.message)
|
||||
} finally {
|
||||
setTopSpinning(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
@ -167,10 +136,12 @@ const PromptManagement: React.FC = () => {
|
||||
JSON.stringify(tableParams.filters),
|
||||
]);
|
||||
|
||||
|
||||
const handleTableChange = (pagination: TablePaginationConfig) => {
|
||||
const handleTableChange: TableProps['onChange'] = (pagination, filters, sorter) => {
|
||||
setTableParams({
|
||||
pagination,
|
||||
filters,
|
||||
sortOrder: Array.isArray(sorter) ? undefined : sorter.order,
|
||||
sortField: Array.isArray(sorter) ? undefined : sorter.field,
|
||||
});
|
||||
|
||||
// `dataSource` is useless since `pageSize` changed
|
||||
@ -180,7 +151,7 @@ const PromptManagement: React.FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<TemplateContainer navTheme={initialState?.settings?.navTheme ?? "realDark"}>
|
||||
<PageContainer>
|
||||
<Card
|
||||
style={{
|
||||
borderRadius: 8,
|
||||
@ -199,42 +170,32 @@ const PromptManagement: React.FC = () => {
|
||||
<Form
|
||||
layout='inline'
|
||||
form={form}
|
||||
onFinish={fetchData}
|
||||
>
|
||||
<Form.Item<Prompt.PromptTypeQueryCondition> label="名称" name="name">
|
||||
<Input placeholder="请输入查询提示词类型的名称" />
|
||||
<Form.Item label="名称">
|
||||
<Input placeholder="请输入查询提示词的名称" />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.PromptTypeQueryCondition> label="编码" name="code">
|
||||
<Input placeholder="请输入查询提示词类型的编码" />
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.PromptTypeQueryCondition> label="状态" name="status">
|
||||
<Select placeholder="请选择查询提示词类型的状态" style={{ width: 200 }}>
|
||||
<Select.Option value="enable">启用</Select.Option>
|
||||
<Select.Option value="disable">停用</Select.Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Form.Item<Prompt.PromptTypeQueryCondition> label="备注" name="remark">
|
||||
<Input placeholder="请输入查询提示词类型的备注" />
|
||||
|
||||
<Form.Item >
|
||||
<Button type="primary">查询</Button>
|
||||
</Form.Item>
|
||||
<Form.Item >
|
||||
<Button type="default">重置</Button>
|
||||
</Form.Item>
|
||||
<Form.Item >
|
||||
<Button type="primary" htmlType='submit' >查询</Button>
|
||||
</Form.Item>
|
||||
<Form.Item style={{ display: "flex", justifyContent: "flex-end", alignItems: "flex-end" }}>
|
||||
<div >
|
||||
<Button type="primary" icon={<PlusOutlined />} style={{ marginBottom: 10 }} onClick={() => {
|
||||
<Button type="primary" style={{ marginBottom: 10 }} onClick={() => {
|
||||
setOpen(true)
|
||||
setType("add")
|
||||
}}>
|
||||
新建提示词类型
|
||||
新建数据
|
||||
</Button>
|
||||
</div>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<Table
|
||||
columns={columns}
|
||||
rowKey={(record) => record.id}
|
||||
@ -251,8 +212,7 @@ const PromptManagement: React.FC = () => {
|
||||
onCancel={async () => {
|
||||
setOpen(false)
|
||||
await fetchData()
|
||||
setPromptTypeId(undefined)
|
||||
resetForm();
|
||||
setEditData(undefined)
|
||||
}}
|
||||
width={800}
|
||||
footer={null}
|
||||
@ -260,11 +220,9 @@ const PromptManagement: React.FC = () => {
|
||||
forceRender={true}
|
||||
destroyOnClose
|
||||
>
|
||||
<ManagePromptType type={type} setFormRef={setFormRef} id={promptTypeId} open={open} />
|
||||
<ManagePromptType type={type} data={editData} />
|
||||
</Modal>
|
||||
{messageHolder}
|
||||
{modalHolder}
|
||||
</TemplateContainer>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ 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,6 +41,7 @@ const ManageRoleModal: React.FC<ManageRoleModalProps> = ({ roleId, setFormRef })
|
||||
}, [roleId]);
|
||||
|
||||
async function onFinish(values: RoleModel.Collection): Promise<void> {
|
||||
console.log("onFinish", values);
|
||||
setLoading(true);
|
||||
setSpinTip("更新中...");
|
||||
try {
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { useModel } from '@/.umi/plugin-model';
|
||||
import { PageContainer } from '@ant-design/pro-components';
|
||||
import { Button, Card, Form, Input, message, Modal, Table } from 'antd';
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import TemplateContainer from '@/pages/TemplateContainer';
|
||||
@ -6,13 +8,14 @@ import { ColumnsType, TablePaginationConfig } from 'antd/es/table';
|
||||
import { DeleteRoleById, QueryRoleList } from '@/services/services/role';
|
||||
import { FormatDate } from '@/util/time';
|
||||
import ManageRoleModal from '../ManageRoleModal';
|
||||
import { isEmpty, set } from 'lodash';
|
||||
import { useFormReset } from '@/hooks/useFormReset';
|
||||
import AddRoleForm from '../AddRoleForm';
|
||||
import { FilterValue, SorterResult, TableCurrentDataSource } from 'antd/es/table/interface';
|
||||
import { useModel } from '@umijs/max';
|
||||
|
||||
|
||||
const RoleManagement: React.FC = () => {
|
||||
|
||||
const { initialState } = useModel('@@initialState');
|
||||
const [data, setData] = useState<RoleModel.Collection[]>(); // 数据
|
||||
const [form] = Form.useForm();
|
||||
@ -24,7 +27,6 @@ const RoleManagement: React.FC = () => {
|
||||
const [modal, contextHolder] = Modal.useModal();
|
||||
const [modalTitle, setModalTitle] = useState<string>("编辑角色");
|
||||
const [type, setType] = useState<string>("edit");
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
|
||||
const [tableParams, setTableParams] = useState<TableModel.TableParams>({
|
||||
pagination: {
|
||||
@ -38,6 +40,7 @@ const RoleManagement: React.FC = () => {
|
||||
// 初始化加载数据
|
||||
QueryRoleList(tableParams, form.getFieldsValue())
|
||||
.then((res) => {
|
||||
debugger;
|
||||
setData(res.collection);
|
||||
setTableParams({
|
||||
pagination: {
|
||||
@ -48,10 +51,9 @@ const RoleManagement: React.FC = () => {
|
||||
setLoading(false);
|
||||
})
|
||||
.catch((error) => {
|
||||
messageApi.error(error.message);
|
||||
}).finally(() => {
|
||||
message.error(error.message);
|
||||
setLoading(false);
|
||||
})
|
||||
});
|
||||
}, []);
|
||||
|
||||
async function modalCancel() {
|
||||
@ -62,7 +64,7 @@ const RoleManagement: React.FC = () => {
|
||||
let res = await QueryRoleList(tableParams, form.getFieldsValue());
|
||||
setData(res.collection);
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
message.error(error.message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@ -80,7 +82,7 @@ const RoleManagement: React.FC = () => {
|
||||
}
|
||||
})
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
message.error(error.message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@ -99,9 +101,9 @@ const RoleManagement: React.FC = () => {
|
||||
try {
|
||||
await DeleteRoleById(roleId);
|
||||
await QueryRoleByName(form.getFieldsValue());
|
||||
messageApi.success("删除角色成功");
|
||||
message.success("删除角色成功");
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
message.error(error.message);
|
||||
}
|
||||
},
|
||||
onCancel: async () => {
|
||||
@ -189,7 +191,7 @@ const RoleManagement: React.FC = () => {
|
||||
}
|
||||
})
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
message.error(error.message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@ -232,7 +234,6 @@ const RoleManagement: React.FC = () => {
|
||||
}
|
||||
</Modal>
|
||||
{contextHolder}
|
||||
{messageHolder}
|
||||
</TemplateContainer>
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,337 +0,0 @@
|
||||
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';
|
||||
import { GetOptions, getOptionsStringValue } from '@/services/services/options/optionsTool';
|
||||
import { useSoftStore } from '@/store/software';
|
||||
|
||||
|
||||
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 { setTopSpinning, setTopSpinTip } = useSoftStore();
|
||||
|
||||
|
||||
|
||||
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: 'addTrail',
|
||||
label: '添加试用',
|
||||
style: { color: '#faad14' },
|
||||
icon: <PlusSquareOutlined />,
|
||||
onClick: async () => {
|
||||
// 添加试用
|
||||
await AddSoftwareControlExpirationTime(record.id, 1, true);
|
||||
}
|
||||
},
|
||||
{
|
||||
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(tableParams, form.getFieldsValue());
|
||||
messageApi.success("停用成功");
|
||||
} else {
|
||||
messageApi.info("取消停用");
|
||||
}
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function AddSoftwareControlExpirationTime(id: string, days: number, isTry = false) {
|
||||
try {
|
||||
if (isTry) {
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("加载信息中");
|
||||
let LaiToolTrialDays = 1;
|
||||
let res = await GetOptions("trial");
|
||||
days = Number(getOptionsStringValue(res, 'LaiToolTrialDays', "") || LaiToolTrialDays);
|
||||
setTopSpinning(false);
|
||||
}
|
||||
|
||||
const confirmed = await modalApi.confirm({
|
||||
title: "确认添加",
|
||||
content: `确认添加 ${days == 0 ? "永久" : days + " 天"} 吗?`
|
||||
});
|
||||
if (confirmed) {
|
||||
setLoading(true);
|
||||
await SoftwareControl.AddSoftwareControlExpirationTime(id, days, days == 0, isTry);
|
||||
// 重新查询
|
||||
await QueryUserSoftwareControlCollection(tableParams, form.getFieldsValue());
|
||||
if (days == 0) {
|
||||
messageApi.success("添加永久成功");
|
||||
} else {
|
||||
messageApi.success("添加 " + days + " 天成功");
|
||||
}
|
||||
} else {
|
||||
messageApi.info("取消添加");
|
||||
}
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
setTopSpinning(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function QueryUserSoftwareControlCollection(tableParams: TableModel.TableParams, options?: SoftwareModel.SoftwareControlQueryParams) {
|
||||
try {
|
||||
debugger
|
||||
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(tableParams, form.getFieldsValue()).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({ pagination }, form.getFieldsValue());
|
||||
setTableParams({
|
||||
pagination: {
|
||||
...tableParams.pagination,
|
||||
current: pagination.current,
|
||||
pageSize: pagination.pageSize
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
async function QuerySoftwareControlByCondition(values: any) {
|
||||
await QueryUserSoftwareControlCollection(tableParams, 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;
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React from 'react';
|
||||
import { PageContainer } from '@ant-design/pro-layout';
|
||||
import { Card, Spin } from 'antd';
|
||||
import { useSoftStore } from '@/store/software';
|
||||
@ -7,10 +7,9 @@ interface TemplateContainerProps {
|
||||
children: React.ReactNode;
|
||||
navTheme: string;
|
||||
style?: React.CSSProperties;
|
||||
title?: React.ReactNode | false;
|
||||
}
|
||||
|
||||
const TemplateContainer: React.FC<TemplateContainerProps> = ({ children, navTheme, style, title }) => {
|
||||
const TemplateContainer: React.FC<TemplateContainerProps> = ({ children, navTheme, style }) => {
|
||||
|
||||
const { topSpinning, topSpinTip } = useSoftStore();
|
||||
|
||||
@ -21,7 +20,7 @@ const TemplateContainer: React.FC<TemplateContainerProps> = ({ children, navThem
|
||||
|
||||
return (
|
||||
<Spin spinning={topSpinning} tip={topSpinTip}>
|
||||
<PageContainer title={title}>
|
||||
<PageContainer>
|
||||
<Card
|
||||
style={{
|
||||
...style,
|
||||
|
||||
@ -130,6 +130,7 @@ const Login: React.FC = () => {
|
||||
setUserLoginState({
|
||||
status: 'error',
|
||||
});
|
||||
console.log(error);
|
||||
message.error(error.message);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { QueryRoleOption } from '@/services/services/role';
|
||||
import { UserInfo } from '@/services/services/user';
|
||||
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';
|
||||
@ -38,7 +38,7 @@ const ModifyUser: React.FC<ModifyUserProps> = ({ userId, setFormRef, open }) =>
|
||||
setLoading(false);
|
||||
})
|
||||
|
||||
UserInfo.GetUserInfo(userId).then((res) => {
|
||||
GetUserInfo(userId).then((res) => {
|
||||
let tempRes = {
|
||||
...res,
|
||||
createdDate: FormatDate(res.createdDate)
|
||||
@ -55,7 +55,7 @@ const ModifyUser: React.FC<ModifyUserProps> = ({ userId, setFormRef, open }) =>
|
||||
setLoading(true);
|
||||
setSpinTip("修改中...");
|
||||
try {
|
||||
await UserInfo.UpdatedUserInfo(values);
|
||||
await UpdatedUserInfo(values);
|
||||
messageApi.success("用户修改成功");
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message);
|
||||
@ -113,7 +113,7 @@ const ModifyUser: React.FC<ModifyUserProps> = ({ userId, setFormRef, open }) =>
|
||||
<Form.Item
|
||||
label="用户名称"
|
||||
name="userName"
|
||||
rules={[{ required: true, message: '请填写用户名称!' }]}
|
||||
rules={[{ required: true, message: 'Please input your username!' }]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
@ -123,7 +123,7 @@ const ModifyUser: React.FC<ModifyUserProps> = ({ userId, setFormRef, open }) =>
|
||||
<Form.Item
|
||||
label="用户昵称"
|
||||
name="nickName"
|
||||
rules={[{ required: true, message: '请填写用户昵称!' }]}
|
||||
rules={[{ required: true, message: 'Please input your username!' }]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
@ -132,7 +132,7 @@ const ModifyUser: React.FC<ModifyUserProps> = ({ userId, setFormRef, open }) =>
|
||||
<Form.Item
|
||||
label="邮箱"
|
||||
name="email"
|
||||
rules={[{ required: true, message: '请填写邮箱!' }]}
|
||||
rules={[{ required: true, message: 'Please input your username!' }]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
@ -149,7 +149,7 @@ const ModifyUser: React.FC<ModifyUserProps> = ({ userId, setFormRef, open }) =>
|
||||
<Form.Item
|
||||
label="角色名称"
|
||||
name="roleNames"
|
||||
rules={[{ required: true, message: '请选择角色名称!' }]}
|
||||
rules={[{ required: true, message: 'Please input your username!' }]}
|
||||
>
|
||||
<Select
|
||||
mode="multiple"
|
||||
@ -165,7 +165,7 @@ const ModifyUser: React.FC<ModifyUserProps> = ({ userId, setFormRef, open }) =>
|
||||
<Form.Item
|
||||
label="可激活设备"
|
||||
name="allDeviceCount"
|
||||
rules={[{ required: true, message: '请设置可激活设置!' }]}
|
||||
rules={[{ required: true, message: 'Please input your username!' }]}
|
||||
>
|
||||
<InputNumber min={0} step="1" />
|
||||
</Form.Item>
|
||||
@ -174,7 +174,7 @@ const ModifyUser: React.FC<ModifyUserProps> = ({ userId, setFormRef, open }) =>
|
||||
<Form.Item
|
||||
label="代理分成"
|
||||
name="agentPercent"
|
||||
rules={[{ required: true, message: '请设置代理分成!' }]}
|
||||
rules={[{ required: true, message: 'Please input your username!' }]}
|
||||
>
|
||||
<InputNumber min={0.1} max={0.7} step="0.01" />
|
||||
</Form.Item>
|
||||
@ -183,7 +183,7 @@ const ModifyUser: React.FC<ModifyUserProps> = ({ userId, setFormRef, open }) =>
|
||||
<Form.Item
|
||||
label="免费换绑次数"
|
||||
name="freeCount"
|
||||
rules={[{ required: true, message: '请设置免费换绑次数!' }]}
|
||||
rules={[{ required: true, message: 'Please input your username!' }]}
|
||||
>
|
||||
<InputNumber min={1} max={10} step="1" />
|
||||
</Form.Item>
|
||||
@ -192,20 +192,11 @@ const ModifyUser: React.FC<ModifyUserProps> = ({ userId, setFormRef, open }) =>
|
||||
<Form.Item
|
||||
label="注册时间"
|
||||
name="createdDate"
|
||||
rules={[{ required: true, message: '请选择注册时间!' }]}
|
||||
rules={[{ required: true, message: 'Please input your username!' }]}
|
||||
>
|
||||
<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 }}>
|
||||
@ -19,6 +19,7 @@ const Register: React.FC = () => {
|
||||
}, []);
|
||||
|
||||
const onFinish = async (values: UserModel.UserRegisterParams) => {
|
||||
console.log('Received values of form: ', values);
|
||||
// 判断两次密码是否一致
|
||||
if (values.password !== values.confirm) {
|
||||
messageApi.warning('两次密码不一致!');
|
||||
|
||||
@ -1,97 +0,0 @@
|
||||
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);
|
||||
} 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;
|
||||
@ -1,20 +1,17 @@
|
||||
import TemplateContainer from '@/pages/TemplateContainer';
|
||||
import { UserInfo } from '@/services/services/user';
|
||||
import { GetUserAgentInfo, GetUserInfo } from '@/services/services/user';
|
||||
import { RedoOutlined } from '@ant-design/icons';
|
||||
import { useModel } from '@umijs/max';
|
||||
import { Avatar, Badge, Button, Card, Col, FloatButton, Input, message, Modal, Row, Spin, Tag } from 'antd';
|
||||
import { Avatar, Button, Card, Col, 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>();
|
||||
|
||||
@ -23,68 +20,19 @@ const UserCenter: React.FC = () => {
|
||||
// 初始化加载用户信息
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("正在获取用户信息。。。");
|
||||
UserInfo.GetUserInfo(initialState?.currentUser?.id).then(async (res) => {
|
||||
GetUserInfo(initialState?.currentUser?.id).then(async (res) => {
|
||||
setInitialState({ ...initialState, currentUser: res });
|
||||
localStorage.setItem('userInfo', JSON.stringify(res));
|
||||
let agentInfo = await UserInfo.GetUserAgentInfo();
|
||||
let agentInfo = await GetUserAgentInfo();
|
||||
setUserAgentUserInfo(agentInfo);
|
||||
}).catch((error) => {
|
||||
messageApi.error(error.message);
|
||||
console.log(error)
|
||||
}).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' }}>
|
||||
@ -133,18 +81,6 @@ 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>
|
||||
@ -5,7 +5,7 @@ import renderTitle from '../UserRenderList';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { useModel } from '@umijs/max';
|
||||
import { useSoftStore } from '@/store/software';
|
||||
import { UserInfo } from '@/services/services/user';
|
||||
import { EnableAgent, GetUserAgentInfo, GetUserInfo } from '@/services/services/user';
|
||||
|
||||
type UserCenterAgentMessageProps = {
|
||||
userAgentUserInfo: UserModel.UserAgentInfo | undefined;
|
||||
@ -28,15 +28,15 @@ const UserCenterAgentMessage: React.FC<UserCenterAgentMessageProps> = ({ userAge
|
||||
setTopSpinTip("正在启用代理。。。");
|
||||
// 开始调用启用代理的接口
|
||||
try {
|
||||
await UserInfo.EnableAgent();
|
||||
await EnableAgent();
|
||||
messageApi.success("启用代理成功");
|
||||
// 冲i性能加载用户信息
|
||||
if (initialState?.currentUser?.id) {
|
||||
let res = await UserInfo.GetUserInfo(initialState?.currentUser?.id);
|
||||
let res = await GetUserInfo(initialState?.currentUser?.id);
|
||||
localStorage.setItem('userInfo', JSON.stringify(res));
|
||||
setInitialState({ ...initialState, currentUser: res });
|
||||
// 重新加载代理信息
|
||||
let agentInfo = await UserInfo.GetUserAgentInfo();
|
||||
let agentInfo = await GetUserAgentInfo();
|
||||
setUserAgentUserInfo(agentInfo);
|
||||
}
|
||||
} catch (error: any) {
|
||||
@ -1,58 +0,0 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Form, Input, Button, message, Tooltip } from 'antd';
|
||||
import DiceIcon from '@/components/Icon/DiceIcon';
|
||||
import { generateRandomPassword } from '@/util/password';
|
||||
import { set, toArray } from 'lodash';
|
||||
import { useSoftStore } from '@/store/software';
|
||||
import { UserInfo } from '@/services/services/user';
|
||||
|
||||
interface ResetUserPasswordProps {
|
||||
userId: number;
|
||||
}
|
||||
|
||||
const ResetUserPassword: React.FC<ResetUserPasswordProps> = ({ userId }) => {
|
||||
const [newPassword, setNewPassword] = useState<string>('');
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
const { setTopSpinning, setTopSpinTip } = useSoftStore();
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginTop: '16px' }}>
|
||||
<Input
|
||||
value={newPassword}
|
||||
onChange={(e) => setNewPassword(e.target.value)}
|
||||
placeholder="请输入新密码"
|
||||
/>
|
||||
<Button
|
||||
icon={<DiceIcon />}
|
||||
color="primary"
|
||||
variant="filled"
|
||||
onClick={() => {
|
||||
let newPw = generateRandomPassword();
|
||||
console.log(newPw);
|
||||
setNewPassword(newPw);
|
||||
}}
|
||||
/>
|
||||
<Tooltip title="确认重置用户密码">
|
||||
<Button type="primary" onClick={async () => {
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip('正在重置密码。。。');
|
||||
// 调用重置密码的方法
|
||||
try {
|
||||
await UserInfo.ResetUserPassword(userId, newPassword);
|
||||
} catch (error: any) {
|
||||
messageApi.error('密码重置失败, ' + error.message);
|
||||
} finally {
|
||||
setTopSpinning(false);
|
||||
}
|
||||
messageApi.success('密码重置成功 ' + newPassword);
|
||||
// setPasswordModel(false);
|
||||
}}>
|
||||
确认重置
|
||||
</Button>
|
||||
</Tooltip>
|
||||
{messageHolder}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ResetUserPassword;
|
||||
@ -1,20 +1,14 @@
|
||||
import { useFormReset } from "@/hooks/useFormReset";
|
||||
import TemplateContainer from "@/pages/TemplateContainer";
|
||||
import { QueryRoleOption } from "@/services/services/role";
|
||||
import { UserInfo } from "@/services/services/user";
|
||||
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 { Button, Form, Input, InputNumber, message, Modal, Select, SelectProps, Table, Tag } 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 Icon, { DeleteOutlined, EditOutlined, KeyOutlined, MenuOutlined, SyncOutlined } from "@ant-design/icons";
|
||||
import { SoftwareControl } from "@/services/services/software";
|
||||
import { CustomIconComponentProps } from "@ant-design/icons/lib/components/Icon";
|
||||
import DiceIcon from "@/components/Icon/DiceIcon";
|
||||
import { generateRandomPassword } from "@/util/password";
|
||||
import ResetUserPassword from "./ResetUserPassword";
|
||||
|
||||
const UserManagement: React.FC = () => {
|
||||
type TagRender = SelectProps['tagRender'];
|
||||
@ -33,11 +27,12 @@ const UserManagement: React.FC = () => {
|
||||
totalBoundaryShowSizeChanger: true,
|
||||
},
|
||||
});
|
||||
|
||||
const [modal, contextHolder] = Modal.useModal();
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [userId, setUserId] = useState<number>(0);
|
||||
const [openModal, setOpenModal] = useState<boolean>(false);
|
||||
const [roleNames, setRoleNames] = useState<SelectProps['options']>([]);
|
||||
const [modal, modaltHolder] = Modal.useModal();
|
||||
|
||||
|
||||
|
||||
@ -53,7 +48,7 @@ const UserManagement: React.FC = () => {
|
||||
messageApi.error(error.message);
|
||||
})
|
||||
|
||||
UserInfo.QueryUserList(tableParams, form.getFieldsValue())
|
||||
QueryUserList(tableParams, form.getFieldsValue())
|
||||
.then((res) => {
|
||||
setData(res.collection);
|
||||
setTableParams({
|
||||
@ -76,7 +71,7 @@ const UserManagement: React.FC = () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
let tableParamsParams = pagination ? { pagination } : tableParams;
|
||||
let res = await UserInfo.QueryUserList(tableParamsParams, params ?? form.getFieldsValue());
|
||||
let res = await QueryUserList(tableParamsParams, params ?? form.getFieldsValue());
|
||||
setData(res.collection);
|
||||
setTableParams({
|
||||
pagination: {
|
||||
@ -94,7 +89,7 @@ const UserManagement: React.FC = () => {
|
||||
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 UserInfo.QueryUserList({ pagination }, form.getFieldsValue());
|
||||
let queryUser = await QueryUserList({ pagination }, form.getFieldsValue());
|
||||
setData(queryUser.collection);
|
||||
setTableParams({
|
||||
pagination: {
|
||||
@ -141,44 +136,6 @@ const UserManagement: React.FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
async function ResetUserPasswordFunc(userId: number) {
|
||||
modal.info({
|
||||
title: '重置密码',
|
||||
width: 500,
|
||||
closable: true,
|
||||
content: <ResetUserPassword userId={userId} />,
|
||||
footer: null
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 给指定用户申请软件控制权限
|
||||
* @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',
|
||||
@ -217,85 +174,32 @@ const UserManagement: React.FC = () => {
|
||||
title: '创建时间',
|
||||
dataIndex: 'createdDate',
|
||||
render: (text, record) => FormatDate(record.createdDate),
|
||||
width: '160px',
|
||||
width: '200px',
|
||||
},
|
||||
{
|
||||
title: '上次登录时间',
|
||||
dataIndex: 'lastLoginDate',
|
||||
render: (text, record) => FormatDate(record.lastLoginDate),
|
||||
width: '160px',
|
||||
width: '200px',
|
||||
},
|
||||
{
|
||||
title: '上次登录IP',
|
||||
dataIndex: 'lastLoginIp',
|
||||
width: '120px',
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
dataIndex: 'remark',
|
||||
hidden: !access.isAdminOrSuperAdmin,
|
||||
ellipsis: {
|
||||
showTitle: false,
|
||||
},
|
||||
render: (remark) => (
|
||||
<Tooltip placement="topLeft" title={remark}>
|
||||
{remark}
|
||||
</Tooltip>
|
||||
),
|
||||
width: '200px',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
width: '80px',
|
||||
hidden: !access.isAdminOrSuperAdmin,
|
||||
width: '120px',
|
||||
render: (text, record) => (
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: [
|
||||
{
|
||||
key: 'edit',
|
||||
label: '编辑',
|
||||
icon: <EditOutlined />,
|
||||
hidden: !access.canEditUser,
|
||||
primary: true,
|
||||
onClick: () => {
|
||||
setUserId(record.id);
|
||||
setOpenModal(true);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'resetPassword',
|
||||
label: '重置密码',
|
||||
icon: <KeyOutlined />,
|
||||
hidden: !access.isSuperAdmin,
|
||||
onClick: async () => {
|
||||
await ResetUserPasswordFunc(record.id);
|
||||
}
|
||||
},
|
||||
{
|
||||
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>
|
||||
<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>
|
||||
),
|
||||
},
|
||||
];
|
||||
@ -341,16 +245,6 @@ const UserManagement: React.FC = () => {
|
||||
</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>
|
||||
@ -369,7 +263,6 @@ const UserManagement: React.FC = () => {
|
||||
<ModifyUser setFormRef={setFormRef} open={openModal} userId={userId} />
|
||||
</Modal>
|
||||
{messageHolder}
|
||||
{modaltHolder}
|
||||
</TemplateContainer>
|
||||
);
|
||||
};
|
||||
@ -38,7 +38,7 @@ const refreshToken = async () => {
|
||||
"deviceInfo": "2"
|
||||
},
|
||||
});
|
||||
|
||||
debugger
|
||||
if (response.code == 1) {
|
||||
localStorage.setItem('token', response.data);
|
||||
return true;
|
||||
@ -53,7 +53,7 @@ const refreshToken = async () => {
|
||||
const retryRequest = async (url: string, opts: RequestOptions) => {
|
||||
if (url) {
|
||||
try {
|
||||
|
||||
debugger
|
||||
const response = await request(url, {
|
||||
...opts,
|
||||
headers: {
|
||||
@ -96,30 +96,38 @@ export const errorConfig: RequestConfig = {
|
||||
if (opts?.skipErrorHandler) throw error;
|
||||
// 我们的 errorThrower 抛出的错误。
|
||||
if (error.name === 'BizError') {
|
||||
|
||||
debugger
|
||||
} else if (error.response) {
|
||||
// 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
|
||||
const { status } = error.response;
|
||||
if (status === 401) {
|
||||
console.log('401 error', url);
|
||||
if (url.toLowerCase().includes('/refreshtoken')) {
|
||||
console.log('refresh token error');
|
||||
message.error('登录已过期,请重新登录');
|
||||
localStorage.removeItem('token');
|
||||
localStorage.removeItem('refreshToken');
|
||||
localStorage.removeItem('userInfo');
|
||||
history.push('/user/login');
|
||||
} else {
|
||||
console.log('normal 401 error, try to refresh token');
|
||||
// 尝试刷新 token
|
||||
const refreshSuccess = await refreshToken();
|
||||
console.log('refresh token result', refreshSuccess);
|
||||
if (refreshSuccess) {
|
||||
console.log('refresh token success, retry request');
|
||||
// 刷新成功,重试原请求
|
||||
// 这里需要实现重试逻辑,可能需要修改您的请求库
|
||||
message.success('已重新获取授权,正在重试请求');
|
||||
// 刷新成功,重试原请求
|
||||
try {
|
||||
console.log('retry request', opts);
|
||||
const retryResponse = await retryRequest(url, opts);
|
||||
// 如果重试成功,返回重试的响应
|
||||
console.log('retry success', retryResponse);
|
||||
return retryResponse;
|
||||
} catch (retryError) {
|
||||
console.log('retry error', retryError);
|
||||
message.error('重试请求失败,请重新登录');
|
||||
localStorage.removeItem('token');
|
||||
localStorage.removeItem('refreshToken');
|
||||
@ -128,6 +136,7 @@ export const errorConfig: RequestConfig = {
|
||||
}
|
||||
// 重试原请求的逻辑
|
||||
} else {
|
||||
console.log('refresh token failed');
|
||||
// 刷新失败,重定向到登录页面
|
||||
message.error('授权已过期,请重新登录');
|
||||
localStorage.removeItem('token');
|
||||
@ -141,13 +150,13 @@ export const errorConfig: RequestConfig = {
|
||||
// history.push('/user/login'); // 重定向到登录页面
|
||||
}
|
||||
} else if (error.request) {
|
||||
|
||||
debugger
|
||||
// 请求已经成功发起,但没有收到响应
|
||||
// \`error.request\` 在浏览器中是 XMLHttpRequest 的实例,
|
||||
// 而在node.js中是 http.ClientRequest 的实例
|
||||
message.error('None response! Please retry.');
|
||||
} else {
|
||||
|
||||
debugger
|
||||
// 发送请求时出了点问题
|
||||
message.error('Request error, please retry.');
|
||||
}
|
||||
@ -161,7 +170,7 @@ export const errorConfig: RequestConfig = {
|
||||
// 拦截请求配置,进行个性化处理。
|
||||
// 添加校验头
|
||||
// config.baseURL = 'https://localhost:44362';
|
||||
config.baseURL = window.location.origin.includes('localhost') ? 'https://localhost:44362' : window.location.origin;
|
||||
config.baseURL = 'http://101.35.233.173:5000';
|
||||
const headers = {
|
||||
...config.headers, // 保留已有的请求头
|
||||
'Authorization': `Bearer ${localStorage.getItem('token')}`, // 添加新的请求头
|
||||
|
||||
@ -65,6 +65,7 @@ export class TokenStorage {
|
||||
const request = objectStore.put({ id: 'token', value: token });
|
||||
|
||||
transaction.oncomplete = () => {
|
||||
console.log('Token saved');
|
||||
resolve();
|
||||
};
|
||||
|
||||
@ -85,6 +86,7 @@ export class TokenStorage {
|
||||
request.onsuccess = (event) => {
|
||||
const result = (event.target as IDBRequest).result;
|
||||
if (result) {
|
||||
console.log('Token:', result.value);
|
||||
let claims: any = null;
|
||||
if (result.value) {
|
||||
const decodedToken = jwtDecode(result.value);
|
||||
@ -98,6 +100,7 @@ export class TokenStorage {
|
||||
}
|
||||
resolve(claims);
|
||||
} else {
|
||||
console.log('Token not found');
|
||||
resolve(null);
|
||||
}
|
||||
};
|
||||
@ -119,8 +122,10 @@ export class TokenStorage {
|
||||
request.onsuccess = (event) => {
|
||||
const result = (event.target as IDBRequest).result;
|
||||
if (result) {
|
||||
console.log('Token:', result.value);
|
||||
resolve(result.value);
|
||||
} else {
|
||||
console.log('Token not found');
|
||||
reject(new Error("Token not found"));
|
||||
}
|
||||
};
|
||||
@ -140,6 +145,7 @@ export class TokenStorage {
|
||||
const request = objectStore.delete('token');
|
||||
|
||||
transaction.oncomplete = () => {
|
||||
console.log('Token deleted');
|
||||
resolve();
|
||||
};
|
||||
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
export enum OptionType {
|
||||
String = 1,
|
||||
JSON = 2,
|
||||
Number = 3,
|
||||
}
|
||||
@ -1,7 +1,9 @@
|
||||
// @ts-ignore
|
||||
/* eslint-disable */
|
||||
import { request, useModel } from '@umijs/max';
|
||||
import CryptoJS from 'crypto-js';
|
||||
import { TokenStorage } from '../define/tokenStorage';
|
||||
import { errorMessage, successMessage } from './response';
|
||||
import { getCurrentUser } from './user';
|
||||
import forge from 'node-forge';
|
||||
|
||||
@ -122,14 +124,14 @@ export async function login(body: API.LoginParams, options?: { [key: string]: an
|
||||
export async function UserRegistr(params: UserModel.UserRegisterParams): Promise<void> {
|
||||
let publicKey = await getPublicKey();
|
||||
// 加密密码
|
||||
|
||||
debugger;
|
||||
let secPassword = encryptPassword(publicKey.publicKey, params.password);
|
||||
let bodyData = {
|
||||
userName: params.userName,
|
||||
email: params.email ?? '',
|
||||
password: secPassword,
|
||||
tokenId: publicKey.token,
|
||||
affiliateCode: params.affiliateCode
|
||||
affiliateCode : params.affiliateCode
|
||||
}
|
||||
let res = await request<ApiResponse.SuccessItem<string>>('/lms/User/Register', {
|
||||
method: 'POST',
|
||||
|
||||
@ -17,6 +17,7 @@ async function QueryMachineList(tableParams: TableModel.TableParams, userParams:
|
||||
let res = await request<ApiResponse.SuccessItem<MachineModel.QueryMachineData>>(`/lms/Machine/QueryMachineCollection?${query}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
console.log(QueryMachineList, res)
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
@ -58,6 +59,7 @@ async function GetMachineInfo(id: string): Promise<MachineModel.MachineInfo> {
|
||||
let res = await request<ApiResponse.SuccessItem<MachineModel.MachineInfo>>(`/lms/Machine/GetMachineDetail/${id}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
console.log("GetMachineInfo", res)
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
@ -75,6 +77,7 @@ async function ModifyMachineData(id: string, params: MachineModel.ModifyMachineP
|
||||
...params,
|
||||
deactivationTime: deactivationTimeString
|
||||
}
|
||||
console.log("ModifyMachineData", params)
|
||||
let res = await request<ApiResponse.SuccessItem<null>>(`/lms/Machine/ModifyMachine/${id}`, {
|
||||
method: 'POST',
|
||||
data: data
|
||||
@ -92,12 +95,8 @@ async function AddMachineData(params: MachineModel.AddMachineParams) {
|
||||
let deactivationTimeString = params.deactivationTime ? params.deactivationTime.toISOString() : undefined;
|
||||
let data = {
|
||||
...params,
|
||||
deactivationTime: deactivationTimeString,
|
||||
useStatus: 0, // 这边设置默认就是试用,然后状态时激活,不需要用户再次设置
|
||||
status: 1,
|
||||
deactivationTime: deactivationTimeString
|
||||
}
|
||||
debugger
|
||||
console.log(data)
|
||||
let res = await request<ApiResponse.SuccessItem<null>>(`/lms/Machine/AddMachine`, {
|
||||
method: 'POST',
|
||||
data: data
|
||||
|
||||
@ -1,133 +0,0 @@
|
||||
import { OptionType } from "@/services/enum/optionEnum";
|
||||
import { isEmpty } from "lodash";
|
||||
|
||||
/**
|
||||
* 获取指定键名的选项值。
|
||||
*
|
||||
* @template T - 返回值的类型。
|
||||
* @param {OptionModel.Option[]} options - 选项数组。
|
||||
* @param {string} keyName - 要查找的键名。
|
||||
* @param {T} [defaultValue] - 默认值,当选项值为空时返回。
|
||||
* @returns {T} - 指定键名的选项值。
|
||||
* @throws {Error} - 当选项数组为空时抛出错误。
|
||||
* @throws {Error} - 当找不到指定键名的选项时抛出错误。
|
||||
* @throws {Error} - 当处理选项值时发生错误时抛出错误。
|
||||
*/
|
||||
export function getOptionsValue<T>(options: OptionModel.Option[], keyName: string, defaultValue?: T): T {
|
||||
|
||||
const option = options.find(x => x.key === keyName);
|
||||
if (!option) {
|
||||
throw new Error(`Option with key '${keyName}' not found`);
|
||||
}
|
||||
|
||||
if (isEmpty(option.value) && defaultValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
try {
|
||||
switch (option.type) {
|
||||
case OptionType.String:
|
||||
return option.value as T;
|
||||
case OptionType.JSON:
|
||||
return JSON.parse(option.value) as T;
|
||||
case OptionType.Number:
|
||||
return Number(option.value) as T;
|
||||
default:
|
||||
throw new Error(`Unsupported option type: ${option.type}`);
|
||||
}
|
||||
} catch (error: any) {
|
||||
throw new Error(`Error processing option '${keyName}': ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定键名的选项字符串值。
|
||||
*
|
||||
* @param options - 包含选项的数组。
|
||||
* @param keyName - 要查找的选项键名。
|
||||
* @param defaultValue - 如果未找到选项或选项值为空时返回的默认值(可选)。
|
||||
* @returns 对应键名的选项字符串值。
|
||||
* @throws 如果选项数组为空时抛出错误。
|
||||
* @throws 如果未找到指定键名的选项且未提供默认值时抛出错误。
|
||||
* @throws 如果处理选项值时发生错误抛出错误。
|
||||
*/
|
||||
export function getOptionsStringValue(options: OptionModel.Option[], keyName: string, defaultValue?: string): string | undefined {
|
||||
// if (options.length === 0) {
|
||||
// throw new Error("Options array is empty");
|
||||
// }
|
||||
const option = options.find(x => x.key === keyName);
|
||||
if (!option) {
|
||||
if (defaultValue !== undefined) {
|
||||
return defaultValue;
|
||||
}
|
||||
throw new Error(`Option with key '${keyName}' not found`);
|
||||
}
|
||||
|
||||
if (isEmpty(option.value)) {
|
||||
return defaultValue ?? undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
switch (option.type) {
|
||||
case OptionType.String:
|
||||
case OptionType.JSON:
|
||||
return String(option.value);
|
||||
case OptionType.Number:
|
||||
return String(Number(option.value));
|
||||
default:
|
||||
throw new Error(`Unsupported option type: ${option.type}`);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
throw new Error(`Error processing option '${keyName}': ${error.message}`);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
import { request } from "@umijs/max";
|
||||
|
||||
/**
|
||||
* 获取 TTS 选项
|
||||
* @returns {Promise<OptionModel.Option[]>} 返回一个包含 OptionModel.Option 对象的 Promise
|
||||
* @throws {Error} 如果响应代码不是 1,则抛出错误
|
||||
*/
|
||||
export async function GetOptions(optionsKey: string): Promise<OptionModel.Option[]> {
|
||||
let res = await request<ApiResponse.SuccessItem<OptionModel.Option[]>>(`/lms/LaitoolOptions/GetAllOptions/${optionsKey}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
});
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
return res.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存选项
|
||||
* @param {string} key 选项的键
|
||||
* @param {string} value 选项的值
|
||||
* @returns {Promise<void>} 返回一个 Promise
|
||||
* @throws {Error} 如果响应代码不是 1,则抛出错误
|
||||
*/
|
||||
export async function SaveOptions(options: object): Promise<void> {
|
||||
|
||||
let data: { key: string; value: any; }[] = [];
|
||||
Object.entries(options).reduce((acc, [key, value]) => {
|
||||
data.push({ key: key, value: value.toString() });
|
||||
return "";
|
||||
}, {});
|
||||
|
||||
let res = await request<ApiResponse.SuccessItem<boolean>>('/lms/LaitoolOptions/ModifyOptions', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: data
|
||||
});
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
}
|
||||
@ -1,94 +1,79 @@
|
||||
import { request } from '@umijs/max';
|
||||
import { errorMessage } from './response';
|
||||
import { objectToQueryString } from './common';
|
||||
|
||||
//#region 提示词数据相关
|
||||
|
||||
/**
|
||||
* 获取提示词预设的集合
|
||||
* @param param 查询的参数
|
||||
* 获取提示词数据
|
||||
* @param typeId 提示类型的Id,要是获取全部,就是all
|
||||
* @param pageSize 每页的大小
|
||||
* @param current 当前也
|
||||
* @param options 其余请求操作项
|
||||
* @returns
|
||||
*/
|
||||
export async function QueryPromptCollection(param: Prompt.PromptQueryCondition): Promise<Prompt.PromptResponse> {
|
||||
let query = objectToQueryString(param)
|
||||
let res = await request<ApiResponse.SuccessItem<Prompt.PromptResponse>>(`/lms/Prompt/QueryPromptStringCollection/?${query}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
return res.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取提示词的详细信息
|
||||
* @param id 指定的提示词ID
|
||||
*/
|
||||
export async function GetPromptInfo(id: string): Promise<Prompt.PromptItem> {
|
||||
let res = await request<ApiResponse.SuccessItem<Prompt.PromptItem>>(`/lms/Prompt/GetPromptInfo/${id}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
return res.data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加提示词数据
|
||||
* @param data 提示词数据
|
||||
* @returns
|
||||
*/
|
||||
export async function AddPrompt(data: Prompt.PromptItem): Promise<string> {
|
||||
let res = await request('/lms/Prompt/AddPrompt', {
|
||||
method: 'POST',
|
||||
data: {
|
||||
name: data.name,
|
||||
promptTypeId: data.promptTypeId,
|
||||
promptString: data.promptString,
|
||||
description: data.description,
|
||||
remark: data.remark,
|
||||
status: data.status,
|
||||
version: data.version,
|
||||
}
|
||||
})
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
return res.data as string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改提示词数据
|
||||
* @param id 提示词数据ID
|
||||
* @param params 参数
|
||||
*/
|
||||
export async function ModifyPrompt(id: string, params: Prompt.PromptItem): Promise<void> {
|
||||
let res = await request(`/lms/Prompt/ModifyPrompt/${id}`, {
|
||||
method: "POST",
|
||||
data: {
|
||||
...params
|
||||
}
|
||||
})
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
export async function getPromptSample(typeId: string, pageSize: number | undefined, current: number | undefined, options?: { [key: string]: any }): Promise<API.SuccessItem | API.ErrorItem> {
|
||||
try {
|
||||
debugger
|
||||
return await request(`/api/Prompt/GetPromptString/${typeId}/${pageSize}/${current}`, {
|
||||
method: 'GET',
|
||||
...(options || {}),
|
||||
});
|
||||
} catch (error: any) {
|
||||
return errorMessage(error.toString())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除提示词数据
|
||||
* @param id 要删除的提示词ID
|
||||
*/
|
||||
export async function DeletePrompt(id: string): Promise<void> {
|
||||
let res = await request(`/lms/Prompt/DeletePrompt/${id}`, {
|
||||
method: 'DELETE',
|
||||
})
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
export async function getPromptDetail(id: string): Promise<API.SuccessItem | API.ErrorItem> {
|
||||
try {
|
||||
debugger
|
||||
return await request(`/api/Prompt/GetPromptDetailById/${id}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
} catch (error: any) {
|
||||
return errorMessage(error.toString())
|
||||
}
|
||||
}
|
||||
|
||||
export async function addPrompt(data: Prompt.AddPrompt): Promise<API.SuccessItem | API.ErrorItem> {
|
||||
try {
|
||||
return await request('/api/Prompt/AddPromptString', {
|
||||
method: 'POST',
|
||||
data: {
|
||||
name: data.name,
|
||||
promptTypeId: data.promptTypeId,
|
||||
promptTypeCode: data.promptTypeCode,
|
||||
promptString: data.promptString,
|
||||
description: data.description,
|
||||
remark: data.remark,
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error: any) {
|
||||
return errorMessage(error.toString())
|
||||
}
|
||||
}
|
||||
|
||||
export async function modifyPrompt(data: Prompt.AddPrompt): Promise<API.SuccessItem | API.ErrorItem> {
|
||||
try {
|
||||
return await request('/api/Prompt/ModifyPromptString', {
|
||||
method: 'POST',
|
||||
data: {
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
promptTypeId: data.promptTypeId,
|
||||
promptTypeCode: data.promptTypeCode,
|
||||
promptString: data.promptString,
|
||||
description: data.description,
|
||||
remark: data.remark,
|
||||
status: data.status,
|
||||
version: data.version,
|
||||
}
|
||||
});
|
||||
} catch (error: any) {
|
||||
return errorMessage(error.toString())
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
@ -100,101 +85,60 @@ export async function DeletePrompt(id: string): Promise<void> {
|
||||
* @param current 页码
|
||||
* @returns
|
||||
*/
|
||||
export async function QueryPromptypeCollection(param: Prompt.PromptTypeQueryCondition): Promise<Prompt.PromptTypeResponse> {
|
||||
let query = objectToQueryString(param)
|
||||
let res = await request<ApiResponse.SuccessItem<Prompt.PromptTypeResponse>>(`/lms/Prompt/QueryPromptypeCollection/?${query}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
export async function getPrompyType(pageSize: number | undefined, current: number | undefined): Promise<API.SuccessItem | API.ErrorItem> {
|
||||
try {
|
||||
return await request(`/api/Prompt/GetPromptType/${pageSize}/${current}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
} catch (error: any) {
|
||||
return errorMessage(error.toString())
|
||||
}
|
||||
return res.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有的提示词类型的ID和Name,可以用作选项
|
||||
* @returns
|
||||
*/
|
||||
export async function GetPromptTypeOptions(): Promise<Prompt.PromptTypeOptions[]> {
|
||||
let res = await request<ApiResponse.SuccessItem<Prompt.PromptTypeOptions[]>>(`/lms/Prompt/GetPromptTypeOptions`, {
|
||||
method: 'GET',
|
||||
});
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
return res.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取提示词类型的详细数据,通过ID
|
||||
* @param id 提示词类型ID
|
||||
* @returns
|
||||
*/
|
||||
export async function GetPromptTypeInfo(id: string): Promise<Prompt.PromptTypeItem> {
|
||||
let res = await request<ApiResponse.SuccessItem<Prompt.PromptTypeItem>>(`/lms/Prompt/GetPromptTypeInfo/${id}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
return res.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加提示词类型
|
||||
* @param data 添加的类型
|
||||
*/
|
||||
export async function AddPromptType(data: Prompt.AddPromptType): Promise<string> {
|
||||
let res = await request('/lms/Prompt/AddPromptType', {
|
||||
method: 'POST',
|
||||
data: {
|
||||
name: data.name,
|
||||
code: data.code,
|
||||
status: data.status,
|
||||
remark: data.remark,
|
||||
}
|
||||
})
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
export async function addPromptType(data: Prompt.AddPromptType): Promise<API.SuccessItem | API.ErrorItem> {
|
||||
try {
|
||||
let res = await request('/api/Prompt/AddPromptType', {
|
||||
method: 'POST',
|
||||
data: {
|
||||
name: data.name,
|
||||
code: data.code,
|
||||
remark: data.remark,
|
||||
}
|
||||
})
|
||||
return res
|
||||
|
||||
} catch (error: any) {
|
||||
return errorMessage(error.toString())
|
||||
}
|
||||
return res.data as string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改提示词类型
|
||||
* @param data 修改的数据
|
||||
*/
|
||||
export async function EditPromptType(data: Prompt.AddPromptType): Promise<string> {
|
||||
let id = data.id;
|
||||
if (id == null || id == undefined) {
|
||||
throw new Error("修改提示词类型的ID不能为空")
|
||||
}
|
||||
let res = await request(`/lms/Prompt/ModityPromptType/${id}`, {
|
||||
method: 'POST',
|
||||
data: {
|
||||
name: data.name,
|
||||
code: data.code,
|
||||
remark: data.remark,
|
||||
status: data.status,
|
||||
}
|
||||
})
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
return res.data as string;
|
||||
}
|
||||
export async function editPromptType(data: Prompt.AddPromptType): Promise<API.SuccessItem | API.ErrorItem> {
|
||||
try {
|
||||
debugger
|
||||
let res = await request('/api/Prompt/ModifyPromptType', {
|
||||
method: 'POST',
|
||||
data: {
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
code: data.code,
|
||||
remark: data.remark,
|
||||
status: data.status,
|
||||
}
|
||||
})
|
||||
return res;
|
||||
|
||||
/**
|
||||
* 删除提示词类型数据,并且关联删除提示词数据
|
||||
* @param id 提示词类型ID
|
||||
* @param deletePrompt 是不是删除对应的提示词数据
|
||||
* @returns
|
||||
*/
|
||||
export async function DeletePromptType(id: string, deletePrompt: boolean): Promise<API.SuccessItem> {
|
||||
let res = await request(`/lms/Prompt/DeletePromptType/${id}/${deletePrompt}`, {
|
||||
method: 'DELETE',
|
||||
})
|
||||
return res;
|
||||
} catch (error: any) {
|
||||
console.log(error)
|
||||
return errorMessage("修改提示词数据失败")
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
@ -21,6 +21,7 @@ export async function QueryRoleList(tableParams: TableModel.TableParams, rolePar
|
||||
let res = await request<ApiResponse.SuccessItem<RoleModel.QueryRoleData>>(`/lms/Role/QueryRoleCollection?${query}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
console.log("QueryRoleList", res);
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
@ -34,6 +35,7 @@ export async function QueryRoleOption() {
|
||||
let res = await request<ApiResponse.SuccessItem<string[]>>(`/lms/Role/QueryRoleOption`, {
|
||||
method: 'GET',
|
||||
});
|
||||
console.log("QueryRoleOption", res);
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
@ -47,9 +49,11 @@ export async function QueryRoleOption() {
|
||||
* @returns
|
||||
*/
|
||||
export async function GetRoleById(roleId: number): Promise<RoleModel.Collection> {
|
||||
console.log("GetRoleById", roleId);
|
||||
let res = await request<ApiResponse.SuccessItem<RoleModel.Collection>>(`/lms/Role/QueryRoleById/${roleId}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
console.log("GetRoleByIdRes", res);
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
@ -70,6 +74,7 @@ export async function UpdeteRole(roleId: number, roleName: string, roleRemark: s
|
||||
remark: roleRemark
|
||||
}
|
||||
});
|
||||
console.log("UpdeteRole", res);
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
@ -84,6 +89,7 @@ export async function DeleteRoleById(roleId: number): Promise<void> {
|
||||
let res = await request<ApiResponse.SuccessItem<void>>(`/lms/Role/DeleteRole/${roleId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
console.log("DeleteRole", res);
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
@ -105,6 +111,7 @@ export async function AddRole(roleNmae: string, roleRemark: string): Promise<voi
|
||||
remark: roleRemark
|
||||
}
|
||||
});
|
||||
console.log("AddRole", res);
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
|
||||
@ -1,96 +0,0 @@
|
||||
|
||||
import { request } from '@umijs/max';
|
||||
import { objectToQueryString } from './common';
|
||||
|
||||
/**
|
||||
* 获取用户的软件控制权限数量
|
||||
* @param userId
|
||||
* @returns
|
||||
*/
|
||||
async function GetUserSoftwareControlCount(userId: number) {
|
||||
let res = await request<ApiResponse.SuccessItem<number>>(`/lms/SoftWare/GetUserSoftwareControlCount/${userId}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
if (res.code == 1) {
|
||||
return res.data;
|
||||
}
|
||||
throw new Error(res.message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请指定的用户的软件控制权限
|
||||
* @param userId
|
||||
* @returns
|
||||
*/
|
||||
async function ApplyUserSoftwareControl(userId: number) {
|
||||
let res = await request<ApiResponse.SuccessItem<boolean>>(`/lms/SoftWare/ApplySoftwareControl/${userId}`, {
|
||||
method: 'POST',
|
||||
});
|
||||
if (res.code == 1) {
|
||||
return res.data;
|
||||
}
|
||||
throw new Error(res.message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定用户的软件控制权限列表
|
||||
* @param tableParams 表数据参数
|
||||
* @param queryParams 查询参数
|
||||
* @returns
|
||||
*/
|
||||
async function GetUserSoftwareControlCollection(tableParams: TableModel.TableParams, queryParams: SoftwareModel.SoftwareControlQueryParams) {
|
||||
debugger
|
||||
let data = {
|
||||
...queryParams,
|
||||
page: tableParams.pagination?.current,
|
||||
pageSize: tableParams.pagination?.pageSize,
|
||||
}
|
||||
let query = objectToQueryString(data)
|
||||
let res = await request<ApiResponse.SuccessItem<SoftwareModel.QuerySoftwareControlData>>(`/lms/SoftWare/GetSoftwareControlCollection?${query}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
return res.data;
|
||||
}
|
||||
|
||||
async function AddSoftwareControlExpirationTime(id: string, days: number, isForever: boolean, isTry = false) {
|
||||
let res = await request<ApiResponse.SuccessItem<null>>(`/lms/SoftWare/ModifySoftwareControlValidity/${id}`, {
|
||||
method: 'POST',
|
||||
data: {
|
||||
expirationTime: days,
|
||||
isForever: isForever,
|
||||
isTry: isTry
|
||||
}
|
||||
});
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
}
|
||||
|
||||
export const SoftwareControl = {
|
||||
GetUserSoftwareControlCount,
|
||||
ApplyUserSoftwareControl,
|
||||
GetUserSoftwareControlCollection,
|
||||
AddSoftwareControlExpirationTime
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取软件初始信息的集合
|
||||
* @returns
|
||||
*/
|
||||
async function GetSoftwareBaseCollection() {
|
||||
let res = await request<ApiResponse.SuccessItem<SoftwareModel.SoftwareBasicInfo[]>>(`/lms/SoftWare/GetSoftwareBaseCollection`, {
|
||||
method: 'GET',
|
||||
});
|
||||
if (res.code == 1) {
|
||||
return res.data;
|
||||
}
|
||||
throw new Error(res.message);
|
||||
}
|
||||
|
||||
export const Software = {
|
||||
GetSoftwareBaseCollection
|
||||
}
|
||||
@ -74,6 +74,7 @@ async function QueryUserList(tableParams: TableModel.TableParams, userParams: Us
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
console.log("QueryUserList", res);
|
||||
return res.data;
|
||||
|
||||
}
|
||||
@ -91,10 +92,6 @@ async function EnableAgent() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户的代理信息
|
||||
* @returns
|
||||
*/
|
||||
async function GetUserAgentInfo(): Promise<UserModel.UserAgentInfo> {
|
||||
let res = await request<ApiResponse.SuccessItem<UserModel.UserAgentInfo>>(`/lms/User/GetUserAgentInfo`, {
|
||||
method: 'GET',
|
||||
@ -105,28 +102,10 @@ async function GetUserAgentInfo(): Promise<UserModel.UserAgentInfo> {
|
||||
return res.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置指定用户的用户名和密码
|
||||
* @param userId
|
||||
* @param newPassword
|
||||
*/
|
||||
async function ResetUserPassword(userId: number, newPassword: string): Promise<void> {
|
||||
let res = await request<ApiResponse.SuccessItem<null>>(`/lms/User/ResetPassword/${userId}`, {
|
||||
method: 'post',
|
||||
data: {
|
||||
newPassword: newPassword,
|
||||
}
|
||||
});
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
}
|
||||
|
||||
export const UserInfo = {
|
||||
export {
|
||||
QueryUserList,
|
||||
GetUserInfo,
|
||||
UpdatedUserInfo,
|
||||
EnableAgent,
|
||||
GetUserAgentInfo,
|
||||
ResetUserPassword,
|
||||
}
|
||||
16
src/services/typing/access.d.ts
vendored
16
src/services/typing/access.d.ts
vendored
@ -18,13 +18,6 @@ declare namespace AccessType {
|
||||
isAdminOrSuperAdmin: boolean;
|
||||
//#endregion
|
||||
|
||||
//#region 软件配置项操作权限
|
||||
/** 是不是可以操作配置型 */
|
||||
canOptions: boolean;
|
||||
/** 是不是可以操作软件配置项 */
|
||||
canLaitoolOptions: boolean;
|
||||
//#endregion
|
||||
|
||||
//#region 机器权限
|
||||
/** 是不是显示机器码管理的菜单 */
|
||||
canMachineManagement: boolean
|
||||
@ -39,14 +32,5 @@ declare namespace AccessType {
|
||||
/** 是不是有停用机器码的权限 */
|
||||
canDisableMachine: boolean;
|
||||
//#endregion
|
||||
|
||||
|
||||
//#region 软件控制权限
|
||||
|
||||
/** 是否可以同步用户软件控制权限 */
|
||||
canApplySoftwareControl: boolean;
|
||||
/** 是否可以查看软件控制管理 */
|
||||
canSofrwareControlManagement: boolean;
|
||||
//#endregion
|
||||
}
|
||||
}
|
||||
15
src/services/typing/options/dub.d.ts
vendored
15
src/services/typing/options/dub.d.ts
vendored
@ -1,15 +0,0 @@
|
||||
declare namespace DubModel {
|
||||
|
||||
//#region EdgeTTs
|
||||
|
||||
/** Edge TTS 的配音角色数据 */
|
||||
type EdgeTTsRole = {
|
||||
value: string,
|
||||
gender: string | 'Female' | "Male",
|
||||
label: string,
|
||||
lang: string,
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
}
|
||||
9
src/services/typing/options/option.d.ts
vendored
9
src/services/typing/options/option.d.ts
vendored
@ -1,9 +0,0 @@
|
||||
|
||||
declare namespace OptionModel {
|
||||
|
||||
type Option = {
|
||||
key: string;
|
||||
value: string;
|
||||
type: OptionType;
|
||||
}
|
||||
}
|
||||
100
src/services/typing/prompt.d.ts
vendored
100
src/services/typing/prompt.d.ts
vendored
@ -1,6 +1,25 @@
|
||||
|
||||
declare namespace Prompt {
|
||||
|
||||
type PromptListItem = {
|
||||
key: string;
|
||||
id: string;
|
||||
name: string;
|
||||
promptTypeId: string;
|
||||
promptTypeCode: string;
|
||||
promptString: string;
|
||||
description?: string;
|
||||
remark?: string;
|
||||
createUser: API.SubUserResponse;
|
||||
createTime: Date;
|
||||
updateUser: API.SubUserResponse;
|
||||
updateTime: Date;
|
||||
status: string;
|
||||
version: number;
|
||||
count: number;
|
||||
}
|
||||
|
||||
|
||||
type AddPrompt = {
|
||||
id?: string;
|
||||
name: string;
|
||||
@ -17,89 +36,23 @@ declare namespace Prompt {
|
||||
version: number;
|
||||
}
|
||||
|
||||
//#region 提示词相关
|
||||
|
||||
/** 查询提示词预设的参数模型结构 */
|
||||
type PromptQueryCondition = {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
name?: string;
|
||||
promptTypeId?: string;
|
||||
status?: string;
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
type PromptItem = {
|
||||
id: string;
|
||||
name: string;
|
||||
promptTypeId: string;
|
||||
promptTypeCode: string;
|
||||
promptString: string;
|
||||
description?: string;
|
||||
remark?: string;
|
||||
createdUser: UserModel.UserBasic;
|
||||
createTime: Date;
|
||||
updatedUser: UserModel.UserBasic;
|
||||
updateTime: Date;
|
||||
status: string;
|
||||
version: number;
|
||||
promptType: PromptTypeBasic;
|
||||
|
||||
}
|
||||
|
||||
/** 返回的提示词类型的完整数据数据结构 */
|
||||
type PromptResponse = {
|
||||
collection: PromptItem[];
|
||||
total: number;
|
||||
current: number;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 提示词类型相关
|
||||
|
||||
interface PromptTypeBasic {
|
||||
type PromptTypeListItem = {
|
||||
key: string;
|
||||
id: string;
|
||||
name: string;
|
||||
code: string;
|
||||
remark?: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
type PromptTypeOptions = {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
/** 提示词类型的collection的数据结构 */
|
||||
interface PromptTypeItem extends PromptTypeBasic {
|
||||
id: string;
|
||||
name: string;
|
||||
code: string;
|
||||
remark?: string;
|
||||
status: string;
|
||||
createdUser: UserModel.UserBasic;
|
||||
createUser: API.SubUserResponse;
|
||||
createTime: Date;
|
||||
updatedUser: UserModel.UserBasic;
|
||||
updateUser: API.SubUserResponse;
|
||||
updateTime: Date;
|
||||
coubt: number;
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
/** 查询提示词的参数模型结构 */
|
||||
type PromptTypeQueryCondition = {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
name?: string;
|
||||
code?: string;
|
||||
status?: string;
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
/** 返回的提示词类型的完整数据数据结构 */
|
||||
type PromptTypeResponse = {
|
||||
collection: PromptTypeItem[];
|
||||
total: number;
|
||||
current: number;
|
||||
}
|
||||
|
||||
type AddPromptType = {
|
||||
id?: string;
|
||||
@ -111,5 +64,4 @@ declare namespace Prompt {
|
||||
updateUser: API.SubUserResponse;
|
||||
updateTime: Date;
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
47
src/services/typing/software.d.ts
vendored
47
src/services/typing/software.d.ts
vendored
@ -1,47 +0,0 @@
|
||||
declare namespace SoftwareModel {
|
||||
|
||||
interface SoftwareBasicInfo {
|
||||
id: string;
|
||||
softwareName: string;
|
||||
softwareCode: string;
|
||||
isUse: boolean;
|
||||
}
|
||||
|
||||
interface SoftwareBase {
|
||||
id: string;
|
||||
softwareName: string;
|
||||
softwareCode: string;
|
||||
createdUserId: number;
|
||||
updatedUserId: number;
|
||||
createdTime: Date;
|
||||
updatedTime: Date;
|
||||
remark: string;
|
||||
isUse: boolean;
|
||||
}
|
||||
|
||||
interface SoftwareControlBase {
|
||||
id: string;
|
||||
user: UserModel.UserBasic;
|
||||
software: SoftwareBase;
|
||||
createdUser: UserModel.UserBasic;
|
||||
createdTime: Date;
|
||||
updatedUser: UserModel.UserBasic;
|
||||
updatedTime: Date;
|
||||
remark: string;
|
||||
expirationTime: string;
|
||||
isForever: boolean;
|
||||
}
|
||||
|
||||
type SoftwareControlQueryParams = {
|
||||
userId?: number;
|
||||
softwareId?: string;
|
||||
isForever?: boolean;
|
||||
remark?: string
|
||||
};
|
||||
|
||||
type QuerySoftwareControlData = {
|
||||
collection: SoftwareControlBase[];
|
||||
current: number;
|
||||
total: number;
|
||||
}
|
||||
}
|
||||
11
src/services/typing/user.d.ts
vendored
11
src/services/typing/user.d.ts
vendored
@ -29,26 +29,21 @@ declare namespace UserModel {
|
||||
affiliateMoney: number,
|
||||
}
|
||||
|
||||
interface UserBasic {
|
||||
//#region 用户基本的数据信息
|
||||
interface UserInfo {
|
||||
id: number;
|
||||
nickName: string;
|
||||
userName: string;
|
||||
avatar?: string;
|
||||
email: string;
|
||||
phoneNumber?: string;
|
||||
|
||||
}
|
||||
|
||||
//#region 用户基本的数据信息
|
||||
interface UserInfo extends UserBasic {
|
||||
roleNames: string[];
|
||||
allDeviceCount: number;
|
||||
agentPercent: number;
|
||||
freeCount: number;
|
||||
affiliateCode: string;
|
||||
createdDate: Date;
|
||||
options: userOptions;
|
||||
remark?: string;
|
||||
options: userOptions
|
||||
}
|
||||
|
||||
type userOptions = {
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
import { create } from 'zustand';
|
||||
|
||||
export const useOptionsStore = create((set: (arg0: any) => any) => ({
|
||||
|
||||
/**EdgeTTS role List */
|
||||
ttsOptions: [] as OptionModel.Option[],
|
||||
setTTsOptions: (value: string) => set({ ttsOptions: value }),
|
||||
|
||||
/** Laitool 基础配置 */
|
||||
laitoolOptions: [] as OptionModel.Option[],
|
||||
setLaitoolOptions: (value: string) => set({ laitoolOptions: value }),
|
||||
|
||||
})) as any;
|
||||
@ -1,26 +1,14 @@
|
||||
import { create } from 'zustand';
|
||||
import defaultSettings from '../../config/defaultSettings';
|
||||
|
||||
interface SoftStoreState {
|
||||
token: string | null;
|
||||
currentUser: any;
|
||||
settings: typeof defaultSettings;
|
||||
topSpinning: boolean;
|
||||
topSpinTip: string;
|
||||
setTopSpinning: (spinning: boolean) => void;
|
||||
setTopSpinTip: (tip: string) => void;
|
||||
}
|
||||
|
||||
const createSoftStore = (initialState: Partial<SoftStoreState> = {}) => create<SoftStoreState>((set) => ({
|
||||
export const useSoftStore = create((set: (arg0: any) => any) => ({
|
||||
token: null,
|
||||
currentUser: null,
|
||||
settings: defaultSettings,
|
||||
topSpinning: false,
|
||||
topSpinTip: "加载中...",
|
||||
setTopSpinning: (spinning: boolean) => set({ topSpinning: spinning }),
|
||||
setTopSpinTip: (tip: string) => set({ topSpinTip: tip }),
|
||||
...initialState, // 合并初始状态
|
||||
}));
|
||||
|
||||
export const useSoftStore = createSoftStore();
|
||||
export default createSoftStore;
|
||||
topSpinning: false,
|
||||
setTopSpinning: (spinning: boolean) => set({ topSpinning: spinning }),
|
||||
|
||||
topSpinTip: "加载中...",
|
||||
setTopSpinTip: (tip: string) => set({ topSpinTip: tip }),
|
||||
})) as any;
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
export function generateRandomPassword(): string {
|
||||
const upperCase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
const lowerCase = 'abcdefghijklmnopqrstuvwxyz';
|
||||
const numbers = '0123456789';
|
||||
const special = '@$!%*?.&';
|
||||
|
||||
let password = '';
|
||||
|
||||
// Ensure at least one character from each category
|
||||
password += upperCase[Math.floor(Math.random() * upperCase.length)];
|
||||
password += lowerCase[Math.floor(Math.random() * lowerCase.length)];
|
||||
password += numbers[Math.floor(Math.random() * numbers.length)];
|
||||
password += special[Math.floor(Math.random() * special.length)];
|
||||
|
||||
// Fill the rest randomly
|
||||
const allChars = upperCase + lowerCase + numbers + special;
|
||||
for (let i = password.length; i < 12; i++) {
|
||||
password += allChars[Math.floor(Math.random() * allChars.length)];
|
||||
}
|
||||
|
||||
// Shuffle the password
|
||||
password = password.split('').sort(() => Math.random() - 0.5).join('');
|
||||
|
||||
return password;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user