V1.0.4
1. 新增用户注册需要邮箱验证码 2. 机器码、软件权限控制、用户 隔离,除非超级管理员,其他用户只能看到自己下面的用户,管理员可以看到除超级管理员以外的所有
This commit is contained in:
parent
208b887f79
commit
9a2bc86427
@ -73,7 +73,13 @@ export default [
|
||||
name: 'laitoolOptions',
|
||||
path: '/options/laitoolOptions',
|
||||
component: './Options/LaitoolOptions/LaitoolOptions/index',
|
||||
access: 'canLaitoolOptions',
|
||||
access: 'canOptions',
|
||||
},
|
||||
{
|
||||
name: 'systemOptions',
|
||||
path: '/options/systemOptions',
|
||||
component: './Options/SystemOptions/index',
|
||||
access: 'canOptions',
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lms",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.4",
|
||||
"private": true,
|
||||
"description": "An out-of-box UI solution for enterprise applications",
|
||||
"scripts": {
|
||||
|
||||
@ -16,7 +16,6 @@ export default function access(initialState: { currentUser?: API.CurrentUser } |
|
||||
isAdminOrSuperAdmin: false,
|
||||
|
||||
canOptions: false,
|
||||
canLaitoolOptions: false,
|
||||
|
||||
canApplySoftwareControl: false,
|
||||
canSofrwareControlManagement: false,
|
||||
@ -51,14 +50,16 @@ export default function access(initialState: { currentUser?: API.CurrentUser } |
|
||||
canUserManagement: true,
|
||||
|
||||
canMachineManagement: true,
|
||||
canUpgradeMachine: true
|
||||
canUpgradeMachine: true,
|
||||
|
||||
canSofrwareControlManagement: true,
|
||||
}
|
||||
}
|
||||
|
||||
if (currentUser?.roleNames?.includes("Admin")) {
|
||||
access = {
|
||||
...access,
|
||||
canPrompt: true,
|
||||
canPrompt: false,
|
||||
|
||||
canUserManagement: true,
|
||||
canEditUser: true,
|
||||
@ -66,8 +67,7 @@ export default function access(initialState: { currentUser?: API.CurrentUser } |
|
||||
isAdmin: true,
|
||||
isAdminOrSuperAdmin: true,
|
||||
|
||||
canOptions: true,
|
||||
canLaitoolOptions: true,
|
||||
canOptions: false,
|
||||
|
||||
canMachineManagement: true,
|
||||
canEditMachine: true,
|
||||
@ -93,7 +93,6 @@ export default function access(initialState: { currentUser?: API.CurrentUser } |
|
||||
isAdminOrSuperAdmin: true,
|
||||
|
||||
canOptions: true,
|
||||
canLaitoolOptions: true,
|
||||
|
||||
canMachineManagement: true,
|
||||
canEditMachine: true,
|
||||
|
||||
@ -9,6 +9,7 @@ export default {
|
||||
|
||||
'menu.options': '配置管理',
|
||||
'menu.options.laitoolOptions': 'Laitool配置',
|
||||
'menu.options.systemOptions': '系统配置',
|
||||
|
||||
'menu.roleManagement': '角色管理',
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import { Form, Card, Row, Col, InputNumber, Button, Input, message } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea';
|
||||
import { useSoftStore } from '@/store/software';
|
||||
import { GetOptions, getOptionsStringValue, SaveOptions } from '@/services/services/options/optionsTool';
|
||||
import { OptionKeyName } from '@/services/enum/optionEnum';
|
||||
import { AllOptionKeyName, OptionKeyName } from '@/services/enum/optionEnum';
|
||||
|
||||
interface ImageOptionsProps {
|
||||
// Add your props here
|
||||
@ -19,7 +19,7 @@ const ImageOptions: React.FC<ImageOptionsProps> = ({ visible }) => {
|
||||
if (!visible) return;
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("加载信息中");
|
||||
GetOptions("image").then((res) => {
|
||||
GetOptions(AllOptionKeyName.Image).then((res) => {
|
||||
form.setFieldsValue({
|
||||
[OptionKeyName.LaitoolFluxApiModelList]: getOptionsStringValue(res, OptionKeyName.LaitoolFluxApiModelList, "{}"),
|
||||
});
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { AllOptionKeyName } from '@/services/enum/optionEnum';
|
||||
import { GetOptions, getOptionsStringValue, SaveOptions } from '@/services/services/options/optionsTool';
|
||||
import { useOptionsStore } from '@/store/options';
|
||||
import { useSoftStore } from '@/store/software';
|
||||
@ -23,7 +24,7 @@ const SimpleOptions: React.FC<SimpleOptionsProps> = ({ visible }) => {
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("加载信息中");
|
||||
// 这边加载所有的配音数据
|
||||
GetOptions("software").then((res) => {
|
||||
GetOptions(AllOptionKeyName.Software).then((res) => {
|
||||
setLaitoolOptions(res);
|
||||
form.setFieldsValue({
|
||||
LaitoolHomePage: getOptionsStringValue(res, 'LaitoolHomePage', ""),
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { AllOptionKeyName } from '@/services/enum/optionEnum';
|
||||
import { GetOptions, getOptionsStringValue, SaveOptions } from '@/services/services/options/optionsTool';
|
||||
import { useOptionsStore } from '@/store/options';
|
||||
import { useSoftStore } from '@/store/software';
|
||||
@ -40,7 +41,7 @@ const DubSettingTTsOptions: React.FC<DubSettingTTsOptionsProps> = ({ visible })
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("加载信息中");
|
||||
// 这边加载所有的配音数据
|
||||
GetOptions('tts').then((res) => {
|
||||
GetOptions(AllOptionKeyName.TTS).then((res) => {
|
||||
setTTsOptions(res);
|
||||
form.setFieldsValue({ edgeTTsRoles: getOptionsStringValue(res, 'EdgeTTsRoles', "{}") })
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@ import BasicOptions from '../BasicOptions';
|
||||
const LaitoolOptions: React.FC = () => {
|
||||
|
||||
const { initialState } = useModel('@@initialState');
|
||||
const [tabKey, setTabKey] = React.useState<string | undefined>(undefined);
|
||||
|
||||
const items = [{
|
||||
label: `软件设置`,
|
||||
@ -21,16 +20,12 @@ const LaitoolOptions: React.FC = () => {
|
||||
key: "dub",
|
||||
children: <DubSetting />,
|
||||
style: undefined,
|
||||
destroyInactiveTabPane : true
|
||||
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} />
|
||||
<Tabs defaultActiveKey="1" destroyInactiveTabPane={true} items={items} />
|
||||
</TemplateContainer>
|
||||
);
|
||||
};
|
||||
|
||||
207
src/pages/Options/SystemOptions/MailSettingOption.tsx
Normal file
207
src/pages/Options/SystemOptions/MailSettingOption.tsx
Normal file
@ -0,0 +1,207 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Form, Input, Button, Card, message, Switch, Modal } from 'antd';
|
||||
import { MailOutlined } from '@ant-design/icons';
|
||||
import { useSoftStore } from '@/store/software';
|
||||
import { GetOptions, getOptionsValue, GetSimpleOptions, SaveOptions } from '@/services/services/options/optionsTool';
|
||||
import { AllOptionKeyName, OptionKeyName } from '@/services/enum/optionEnum';
|
||||
import { request } from '@umijs/max';
|
||||
|
||||
interface MailSettingProps {
|
||||
visible?: boolean;
|
||||
}
|
||||
|
||||
interface MailConfig {
|
||||
smtpServer: string;
|
||||
port: number;
|
||||
username: string;
|
||||
password: string;
|
||||
senderEmail: string;
|
||||
enableSSL: boolean;
|
||||
enableMailService: boolean;
|
||||
testReceiveMail: string;
|
||||
}
|
||||
|
||||
const MailSettingOption: React.FC<MailSettingProps> = ({ visible }) => {
|
||||
const [form] = Form.useForm();
|
||||
const { setTopSpinning, setTopSpinTip, topSpinning } = useSoftStore();
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
const [modalApi, modalHolder] = Modal.useModal();
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch current mail settings
|
||||
fetchMailSettings();
|
||||
}, [visible]);
|
||||
|
||||
const fetchMailSettings = async () => {
|
||||
try {
|
||||
setTopSpinTip("正在加载邮箱设置");
|
||||
setTopSpinning(true);
|
||||
const response = await GetOptions(AllOptionKeyName.MailSetting);
|
||||
let mailSetting = getOptionsValue<MailConfig>(response, OptionKeyName.SMTPMailSetting, {
|
||||
smtpServer: '',
|
||||
port: 465,
|
||||
username: '',
|
||||
password: '',
|
||||
senderEmail: '',
|
||||
enableSSL: false,
|
||||
enableMailService: false,
|
||||
testReceiveMail: ''
|
||||
});
|
||||
form.setFieldsValue(mailSetting);
|
||||
messageApi.success("数据加载成功!");
|
||||
} catch (error: any) {
|
||||
messageApi.error("数据加载失败!" + error.message);
|
||||
} finally {
|
||||
setTopSpinning(false);
|
||||
}
|
||||
};
|
||||
|
||||
const onFinish = async (values: MailConfig) => {
|
||||
try {
|
||||
setTopSpinTip("正在保存邮箱设置");
|
||||
setTopSpinning(true);
|
||||
console.log(values);
|
||||
// Replace with actual API call
|
||||
await SaveOptions({
|
||||
[OptionKeyName.SMTPMailSetting]: JSON.stringify({
|
||||
...values,
|
||||
enableSSL: values.enableSSL ? true : false,
|
||||
enableMailService: values.enableMailService ? true : false
|
||||
}),
|
||||
[OptionKeyName.EnableMailService]: values.enableMailService ? String(true) : String(false)
|
||||
});
|
||||
messageApi.success('Mail settings saved successfully');
|
||||
} catch (error) {
|
||||
messageApi.error('Failed to save mail settings');
|
||||
} finally {
|
||||
setTopSpinning(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleTestEmail = async () => {
|
||||
try {
|
||||
|
||||
const confirmed = await modalApi.confirm({
|
||||
title: '温馨提示',
|
||||
content: '在执行词操作之前,请先保存邮件设置,否则无法发送测试邮件',
|
||||
okText: '发送',
|
||||
cancelText: '取消',
|
||||
});
|
||||
if (confirmed == false) {
|
||||
return;
|
||||
}
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip('正在发送测试邮件');
|
||||
|
||||
|
||||
let res = await request<ApiResponse.SuccessItem<string>>('/lms/LaitoolOptions/TestSendMail', {
|
||||
method: 'POST',
|
||||
});
|
||||
|
||||
if (res.code != 1) {
|
||||
messageApi.error(res.message);
|
||||
return;
|
||||
}
|
||||
messageApi.success('测试邮件发送成功,请查看收件箱');
|
||||
} catch (error) {
|
||||
messageApi.error('Failed to send test email');
|
||||
} finally {
|
||||
setTopSpinning(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Card title="邮箱设置" extra={<MailOutlined />}>
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
onFinish={onFinish}
|
||||
disabled={topSpinning}
|
||||
>
|
||||
<div style={{ display: 'flex', gap: '24px' }}>
|
||||
<Form.Item
|
||||
name="enableMailService"
|
||||
valuePropName="checked"
|
||||
label='开启/关闭邮箱服务'
|
||||
>
|
||||
<Switch checkedChildren="开启" unCheckedChildren="关闭" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="enableSSL"
|
||||
valuePropName="checked"
|
||||
label='启用SMTP SSL'
|
||||
>
|
||||
<Switch checkedChildren="开启" unCheckedChildren="关闭" />
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
||||
<Form.Item
|
||||
name="smtpServer"
|
||||
label="SMTP 服务器"
|
||||
rules={[{ required: true, message: '请输入SMTP服务器' }]}
|
||||
>
|
||||
<Input placeholder="e.g. smtp.exmail.qq.com" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="port"
|
||||
label="发信端口号"
|
||||
rules={[{ required: true, message: '请输入端口号' }]}
|
||||
>
|
||||
<Input type="number" placeholder="e.g. 465" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="username"
|
||||
label="发信用户名"
|
||||
rules={[{ required: true, message: '请输入用户名' }]}
|
||||
>
|
||||
<Input placeholder="用户名" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="password"
|
||||
label="SMTP访问凭证"
|
||||
rules={[{ required: true, message: '请输入SMTP访问凭证' }]}
|
||||
>
|
||||
<Input.Password placeholder="请输入SMTP访问凭证" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="senderEmail"
|
||||
label="发信邮箱"
|
||||
rules={[
|
||||
{ required: true, message: '请输入发送用户邮箱' },
|
||||
{ type: 'email', message: '请输入发送用户邮箱' }
|
||||
]}
|
||||
>
|
||||
<Input placeholder="e.g. noreply@example.com" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="testReceiveMail"
|
||||
label="测试收信邮箱"
|
||||
rules={[
|
||||
{ required: true, message: '请输入接收测试邮件的邮箱' },
|
||||
{ type: 'email', message: '请输入接收测试邮件的邮箱' }
|
||||
]}
|
||||
>
|
||||
<Input placeholder="e.g. test@example.com" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
<Button type="primary" htmlType="submit" loading={topSpinning} style={{ marginRight: 16 }}>
|
||||
保存邮箱设置
|
||||
</Button>
|
||||
<Button onClick={handleTestEmail} loading={topSpinning}>
|
||||
测试邮箱发送
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
{messageHolder}
|
||||
{modalHolder}
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default MailSettingOption;
|
||||
31
src/pages/Options/SystemOptions/index.tsx
Normal file
31
src/pages/Options/SystemOptions/index.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import TemplateContainer from '@/pages/TemplateContainer';
|
||||
import { useModel } from '@umijs/max';
|
||||
import { Tabs, TabsProps, theme } from 'antd';
|
||||
import React from 'react';
|
||||
import MailSettingOption from './MailSettingOption';
|
||||
|
||||
|
||||
const LaitoolOptions: React.FC = () => {
|
||||
|
||||
const { initialState } = useModel('@@initialState');
|
||||
const [activeKeys, setActiveKeys] = React.useState<string[]>([]);
|
||||
|
||||
const items = [{
|
||||
label: `邮件设置`,
|
||||
key: "mail",
|
||||
style: undefined,
|
||||
children: <MailSettingOption visible={activeKeys.includes('imageOptions')} />
|
||||
}]
|
||||
|
||||
const onChange = (key: string | string[]) => {
|
||||
setActiveKeys(Array.isArray(key) ? key : [key]);
|
||||
};
|
||||
|
||||
return (
|
||||
<TemplateContainer title={false} navTheme={initialState?.settings?.navTheme ?? "realDark"}>
|
||||
<Tabs defaultActiveKey="1" destroyInactiveTabPane={true} items={items} onChange={onChange} />
|
||||
</TemplateContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default LaitoolOptions;
|
||||
@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import TemplateContainer from '@/pages/TemplateContainer';
|
||||
import { useModel } from '@umijs/max';
|
||||
import { useAccess, 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';
|
||||
@ -9,6 +9,7 @@ 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';
|
||||
import { AllOptionKeyName } from '@/services/enum/optionEnum';
|
||||
|
||||
|
||||
interface SoftwareControlManagementProps {
|
||||
@ -24,6 +25,7 @@ const SoftwareControlManagement: FC<SoftwareControlManagementProps> = () => {
|
||||
const [softwareBasicInfo, setSoftwareBasicInfo] = useState<SoftwareModel.SoftwareBasicInfo[]>();
|
||||
const [softwareOptions, setSoftwareOptions] = useState<any>([]);
|
||||
const [data, setData] = React.useState<SoftwareModel.SoftwareControlBase[]>([]);
|
||||
const access = useAccess();
|
||||
const [tableParams, setTableParams] = useState<TableModel.TableParams>({
|
||||
pagination: {
|
||||
current: 1,
|
||||
@ -99,6 +101,7 @@ const SoftwareControlManagement: FC<SoftwareControlManagementProps> = () => {
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 100,
|
||||
hidden: !access.isAdminOrSuperAdmin,
|
||||
render: (_, record) => (
|
||||
<Dropdown
|
||||
menu={{
|
||||
@ -218,7 +221,7 @@ const SoftwareControlManagement: FC<SoftwareControlManagementProps> = () => {
|
||||
setTopSpinning(true);
|
||||
setTopSpinTip("加载信息中");
|
||||
let LaiToolTrialDays = 1;
|
||||
let res = await GetOptions("trial");
|
||||
let res = await GetOptions(AllOptionKeyName.Trial);
|
||||
days = Number(getOptionsStringValue(res, 'LaiToolTrialDays', "") || LaiToolTrialDays);
|
||||
setTopSpinning(false);
|
||||
}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Form, Input, Button, Spin, message } from 'antd';
|
||||
import { Form, Input, Button, Spin, message, Row, Col } from 'antd';
|
||||
import { UserRegistr } from '@/services/services/login';
|
||||
import { set } from 'lodash';
|
||||
import { history } from '@umijs/max';
|
||||
import { history, request } from '@umijs/max';
|
||||
|
||||
const Register: React.FC = () => {
|
||||
const [form] = Form.useForm();
|
||||
const [spinning, setSpinning] = useState(false);
|
||||
const [messageApi, messageHolder] = message.useMessage();
|
||||
const [countdown, setCountdown] = useState(0); // 倒计时状态
|
||||
|
||||
useEffect(() => {
|
||||
// 检查当前网址是不是包含query,并且?aff=后面有6位数字
|
||||
@ -18,12 +18,59 @@ const Register: React.FC = () => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 发送邮箱验证码
|
||||
const sendVerificationCode = async () => {
|
||||
try {
|
||||
debugger;
|
||||
const email = form.getFieldsValue().email;
|
||||
if (!email) {
|
||||
messageApi.warning('请先填写邮箱');
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证邮箱格式
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if (!emailRegex.test(email)) {
|
||||
messageApi.warning('请输入有效的邮箱格式');
|
||||
return;
|
||||
}
|
||||
|
||||
// 开始请求发送的接口
|
||||
|
||||
let res = await request<ApiResponse.SuccessItem<string>>(`/lms/User/SendVerificationCode`, {
|
||||
method: 'POST',
|
||||
data: { email }
|
||||
});
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
// 设置倒计时
|
||||
setCountdown(60);
|
||||
const timer = setInterval(() => {
|
||||
setCountdown((prevCountdown) => {
|
||||
if (prevCountdown <= 1) {
|
||||
clearInterval(timer);
|
||||
return 0;
|
||||
}
|
||||
return prevCountdown - 1;
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
messageApi.success('验证码已发送,请查收邮箱');
|
||||
} catch (error: any) {
|
||||
messageApi.error(error.message || '发送验证码失败');
|
||||
} finally {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
const onFinish = async (values: UserModel.UserRegisterParams) => {
|
||||
// 判断两次密码是否一致
|
||||
if (values.password !== values.confirm) {
|
||||
messageApi.warning('两次密码不一致!');
|
||||
return;
|
||||
}
|
||||
debugger
|
||||
|
||||
// 开始注册
|
||||
setSpinning(true);
|
||||
@ -41,8 +88,6 @@ const Register: React.FC = () => {
|
||||
finally {
|
||||
setSpinning(false);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
@ -80,6 +125,34 @@ const Register: React.FC = () => {
|
||||
<Input placeholder='邮箱号' />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="verificationCode"
|
||||
rules={[{ required: true, message: '请输入邮箱验证码!' }]}
|
||||
>
|
||||
<Row gutter={8}>
|
||||
<Col flex="auto">
|
||||
<Input placeholder='邮箱验证码' />
|
||||
</Col>
|
||||
<Col>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={sendVerificationCode}
|
||||
disabled={countdown > 0}
|
||||
style={{
|
||||
width: '100px',
|
||||
background: countdown > 0 ? '#f0f0f0' : '#1890ff',
|
||||
borderColor: countdown > 0 ? '#d9d9d9' : '#1890ff',
|
||||
color: countdown > 0 ? '#595959' : '#fff',
|
||||
fontWeight: 500,
|
||||
borderRadius: '4px',
|
||||
}}
|
||||
>
|
||||
{countdown > 0 ? `${countdown}秒后重试` : '获取验证码'}
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="password"
|
||||
rules={[
|
||||
|
||||
@ -2,12 +2,44 @@ export enum OptionType {
|
||||
String = 1,
|
||||
JSON = 2,
|
||||
Number = 3,
|
||||
Boolean = 4,
|
||||
}
|
||||
|
||||
|
||||
export enum AllOptionKeyName {
|
||||
/** 获取所有的 Option */
|
||||
All = "all",
|
||||
|
||||
/** 获取TTS相关的 Option */
|
||||
TTS = "tts",
|
||||
|
||||
/** 获取软件相关的 Option */
|
||||
Software = "software",
|
||||
|
||||
/** 软件试用相关 Option */
|
||||
Trial = "trial",
|
||||
|
||||
/** 出图相关的 Option */
|
||||
Image = "image",
|
||||
|
||||
/** 邮件设置相关 Option */
|
||||
MailSetting = "mailSetting",
|
||||
|
||||
}
|
||||
|
||||
|
||||
export enum OptionKeyName {
|
||||
|
||||
/** laitool Flux API 模型类型 */
|
||||
LaitoolFluxApiModelList = "LaitoolFluxApiModelList",
|
||||
|
||||
/// <summary>
|
||||
/// SMTP的邮件设置
|
||||
/// </summary>
|
||||
SMTPMailSetting = "SMTPMailSetting",
|
||||
|
||||
/// <summary>
|
||||
/// 是否开启邮箱服务
|
||||
/// </summary>
|
||||
EnableMailService = "EnableMailService",
|
||||
}
|
||||
@ -129,7 +129,8 @@ export async function UserRegistr(params: UserModel.UserRegisterParams): Promise
|
||||
email: params.email ?? '',
|
||||
password: secPassword,
|
||||
tokenId: publicKey.token,
|
||||
affiliateCode: params.affiliateCode
|
||||
affiliateCode: params.affiliateCode,
|
||||
verificationCode: params.verificationCode
|
||||
}
|
||||
let res = await request<ApiResponse.SuccessItem<string>>('/lms/User/Register', {
|
||||
method: 'POST',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { OptionType } from "@/services/enum/optionEnum";
|
||||
import { AllOptionKeyName, OptionKeyName, OptionType } from "@/services/enum/optionEnum";
|
||||
import { isEmpty } from "lodash";
|
||||
|
||||
/**
|
||||
@ -32,6 +32,8 @@ export function getOptionsValue<T>(options: OptionModel.Option[], keyName: strin
|
||||
return JSON.parse(option.value) as T;
|
||||
case OptionType.Number:
|
||||
return Number(option.value) as T;
|
||||
case OptionType.Boolean:
|
||||
return Boolean(option.value as string) as T;
|
||||
default:
|
||||
throw new Error(`Unsupported option type: ${option.type}`);
|
||||
}
|
||||
@ -74,6 +76,8 @@ export function getOptionsStringValue(options: OptionModel.Option[], keyName: st
|
||||
return String(option.value);
|
||||
case OptionType.Number:
|
||||
return String(Number(option.value));
|
||||
case OptionType.Boolean:
|
||||
return String(Boolean(option.value));
|
||||
default:
|
||||
throw new Error(`Unsupported option type: ${option.type}`);
|
||||
}
|
||||
@ -88,11 +92,11 @@ export function getOptionsStringValue(options: OptionModel.Option[], keyName: st
|
||||
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[]> {
|
||||
export async function GetOptions(optionsKey: AllOptionKeyName): Promise<OptionModel.Option[]> {
|
||||
let res = await request<ApiResponse.SuccessItem<OptionModel.Option[]>>(`/lms/LaitoolOptions/GetAllOptions/${optionsKey}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
@ -105,6 +109,25 @@ export async function GetOptions(optionsKey: string): Promise<OptionModel.Option
|
||||
return res.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取通用的选项,不会校验权限
|
||||
* @param optionsKey
|
||||
* @returns
|
||||
*/
|
||||
export async function GetSimpleOptions(optionsKey: OptionKeyName): Promise<OptionModel.Option[]> {
|
||||
debugger
|
||||
let res = await request<ApiResponse.SuccessItem<OptionModel.Option[]>>(`/lms/LaitoolOptions/GetSimpleOptions/${optionsKey}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
});
|
||||
if (res.code != 1) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
return res.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存选项
|
||||
* @param {string} key 选项的键
|
||||
@ -113,7 +136,7 @@ export async function GetOptions(optionsKey: string): Promise<OptionModel.Option
|
||||
* @throws {Error} 如果响应代码不是 1,则抛出错误
|
||||
*/
|
||||
export async function SaveOptions(options: object): Promise<void> {
|
||||
|
||||
debugger
|
||||
let data: { key: string; value: any; }[] = [];
|
||||
Object.entries(options).reduce((acc, [key, value]) => {
|
||||
data.push({ key: key, value: value.toString() });
|
||||
|
||||
2
src/services/typing/access.d.ts
vendored
2
src/services/typing/access.d.ts
vendored
@ -21,8 +21,6 @@ declare namespace AccessType {
|
||||
//#region 软件配置项操作权限
|
||||
/** 是不是可以操作配置型 */
|
||||
canOptions: boolean;
|
||||
/** 是不是可以操作软件配置项 */
|
||||
canLaitoolOptions: boolean;
|
||||
//#endregion
|
||||
|
||||
//#region 机器权限
|
||||
|
||||
1
src/services/typing/user.d.ts
vendored
1
src/services/typing/user.d.ts
vendored
@ -13,6 +13,7 @@ declare namespace UserModel {
|
||||
email?: string
|
||||
confirm?: string
|
||||
affiliateCode: string
|
||||
verificationCode: string
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user