Add mail settings management to system settings page

This commit is contained in:
2023-12-04 17:12:22 +08:00
parent 6ff5e11f9d
commit d3bdbd0199
9 changed files with 206 additions and 2 deletions

View File

@@ -0,0 +1,38 @@
@use '@/assets/css/constants' as constants;
.root-content {
padding: 30px;
gap: 10px;
.settings-card {
padding: 20px;
gap: 20px;
> .head {
align-items: center;
gap: 5px;
.icon {
font-size: constants.$SIZE_ICON_MD;
flex: 0 0 auto;
}
.title {
display: flex;
font-size: 1.2em;
}
.bt {
flex: 0 0 auto;
}
.bt-reset {
color: constants.$font-main-color;
}
.bt-save {
color: constants.$main-color;
}
}
}
}

1
src/assets/svg/back.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M471.893333 149.333333a42.666667 42.666667 0 0 0-73.258666-29.781333l-343.893334 352.981333a42.666667 42.666667 0 0 0-0.768 58.709334l343.893334 372.352a42.666667 42.666667 0 0 0 73.984-28.928v-190.677334c56.917333-5.248 116.821333-1.365333 179.882666 11.989334 65.834667 13.994667 150.528 76.032 253.909334 202.24a42.666667 42.666667 0 0 0 75.477333-31.36c-15.445333-152.32-73.984-281.301333-176.170667-384.853334-92.757333-93.994667-204.373333-146.432-333.098666-156.586666V149.333333z" /></svg>

After

Width:  |  Height:  |  Size: 570 B

1
src/assets/svg/email.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M926.47619 355.644952V780.190476a73.142857 73.142857 0 0 1-73.142857 73.142857H170.666667a73.142857 73.142857 0 0 1-73.142857-73.142857V355.644952l304.103619 257.828572a170.666667 170.666667 0 0 0 220.745142 0L926.47619 355.644952zM853.333333 170.666667a74.044952 74.044952 0 0 1 26.087619 4.778666 72.704 72.704 0 0 1 30.622477 22.186667 73.508571 73.508571 0 0 1 10.678857 17.67619c3.169524 7.509333 5.12 15.652571 5.607619 24.210286L926.47619 243.809524v24.380952L559.469714 581.241905a73.142857 73.142857 0 0 1-91.306666 2.901333l-3.632762-2.925714L97.52381 268.190476v-24.380952a72.899048 72.899048 0 0 1 40.155428-65.292191A72.97219 72.97219 0 0 1 170.666667 170.666667h682.666666z" /></svg>

After

Width:  |  Height:  |  Size: 770 B

1
src/assets/svg/save.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" ><path d="M931.882 259.882l-167.764-167.764A96 96 0 0 0 696.236 64H160C106.98 64 64 106.98 64 160v704c0 53.02 42.98 96 96 96h704c53.02 0 96-42.98 96-96V327.764a96 96 0 0 0-28.118-67.882zM512 832c-70.692 0-128-57.308-128-128 0-70.692 57.308-128 128-128s128 57.308 128 128c0 70.692-57.308 128-128 128z m192-609.04V424c0 13.254-10.746 24-24 24H216c-13.254 0-24-10.746-24-24V216c0-13.254 10.746-24 24-24h457.04c6.366 0 12.47 2.528 16.97 7.03l6.96 6.96A23.992 23.992 0 0 1 704 222.96z" /></svg>

After

Width:  |  Height:  |  Size: 553 B

View File

@@ -9,5 +9,8 @@ export const URL_SYS_POWER_LIST = '/system/power/list'
export const URL_SYS_ROLE_LIST = '/system/role/list' export const URL_SYS_ROLE_LIST = '/system/role/list'
export const URL_SYS_GROUP = '/system/group' export const URL_SYS_GROUP = '/system/group'
export const URL_SYS_GROUP_LIST = '/system/group/list' export const URL_SYS_GROUP_LIST = '/system/group/list'
export const URL_SYS_SETTINGS = '/system/settings'
export const URL_SYS_SETTINGS_MAIL = `${URL_SYS_SETTINGS}/mail`
export const URL_API_V1_AVATAR_RANDOM_BASE64 = '/api/v1/avatar/base64' export const URL_API_V1 = '/api/v1'
export const URL_API_V1_AVATAR_RANDOM_BASE64 = `${URL_API_V1}/avatar/base64`

20
src/global.d.ts vendored
View File

@@ -294,3 +294,23 @@ interface GroupChangeStatusParam {
interface AvatarBase64Vo { interface AvatarBase64Vo {
base64: string base64: string
} }
interface SystemSettingVo {
mail: MailSettingsVo
}
interface MailSettingsVo {
host?: string
port?: number
username?: string
password?: string
from?: string
}
interface MailSettingsParam {
host?: string
port?: number
username?: string
password?: string
from?: string
}

View File

@@ -0,0 +1,123 @@
import React from 'react'
import Icon from '@ant-design/icons'
import '@/assets/css/pages/system/settings.scss'
import FitFullScreen from '@/components/common/FitFullScreen'
import HideScrollbar from '@/components/common/HideScrollbar'
import Card from '@/components/common/Card'
import FlexBox from '@/components/common/FlexBox'
import { useUpdatedEffect } from '@/util/hooks.tsx'
import { r_sys_settings_get, r_sys_settings_mail_update } from '@/services/system.tsx'
interface SettingsCardProps extends React.PropsWithChildren {
icon: IconComponent
title: string
onReset?: () => void
onSave?: () => void
}
const SettingsCard: React.FC<SettingsCardProps> = (props) => {
return (
<Card>
<FlexBox className={'settings-card'}>
<FlexBox direction={'horizontal'} className={'head'}>
<Icon component={props.icon} className={'icon'} />
<div className={'title'}>{props.title}</div>
<AntdButton className={'bt bt-reset'} onClick={props.onReset}>
<Icon component={IconFatwebBack} />
</AntdButton>
<AntdButton className={'bt bt-save'} onClick={props.onSave}>
<Icon component={IconFatwebSave} />
</AntdButton>
</FlexBox>
{props.children}
</FlexBox>
</Card>
)
}
const MailSettings: React.FC<{ mail?: MailSettingsVo; onSave?: () => void }> = (props) => {
const [mailForm] = AntdForm.useForm<MailSettingsParam>()
const mailFormValues = AntdForm.useWatch([], mailForm)
const handleOnReset = () => {
props.mail && mailForm.setFieldsValue(props.mail)
}
const handleOnSave = () => {
void r_sys_settings_mail_update(mailFormValues).then((res) => {
const response = res.data
if (response.success) {
void message.success('保存设置成功')
props.onSave && props.onSave()
} else {
void message.error('保存设置失败,请稍后重试')
}
})
}
useUpdatedEffect(() => {
props.mail && mailForm.setFieldsValue(props.mail)
}, [props.mail])
return (
<SettingsCard
icon={IconFatwebEmail}
title={'邮件'}
onReset={handleOnReset}
onSave={handleOnSave}
>
<AntdForm form={mailForm} labelCol={{ flex: '8em' }}>
<AntdForm.Item label={'SMTP 服务器'} name={'host'}>
<AntdInput />
</AntdForm.Item>
<AntdForm.Item label={'端口'} name={'port'}>
<AntdInputNumber min={0} max={65535} style={{ width: '100%' }} />
</AntdForm.Item>
<AntdForm.Item label={'用户名'} name={'username'}>
<AntdInput />
</AntdForm.Item>
<AntdForm.Item label={'密码'} name={'password'}>
<AntdInput.Password />
</AntdForm.Item>
<AntdForm.Item label={'发送者'} name={'from'}>
<AntdInput />
</AntdForm.Item>
</AntdForm>
</SettingsCard>
)
}
const Settings: React.FC = () => {
const [systemSetting, setSystemSetting] = useState<SystemSettingVo>()
const getSystemSetting = () => {
void r_sys_settings_get().then((res) => {
const response = res.data
if (response.success) {
const data = response.data
data && setSystemSetting(data)
}
})
}
const handleOnSave = () => {
getSystemSetting()
}
useUpdatedEffect(() => {
getSystemSetting()
}, [])
return (
<>
<FitFullScreen>
<HideScrollbar isShowVerticalScrollbar autoHideWaitingTime={500}>
<FlexBox className={'root-content'}>
<MailSettings mail={systemSetting?.mail} onSave={handleOnSave} />
</FlexBox>
</HideScrollbar>
</FitFullScreen>
</>
)
}
export default Settings

View File

@@ -11,6 +11,16 @@ const system: RouteJsonObject[] = [
icon: React.lazy(() => import('~icons/fatweb/setting.jsx')), icon: React.lazy(() => import('~icons/fatweb/setting.jsx')),
menu: true menu: true
}, },
{
path: 'settings',
absolutePath: '/system/settings',
id: 'system-settings',
component: React.lazy(() => import('@/pages/system/Settings')),
name: '系统设置',
icon: React.lazy(() => import('~icons/fatweb/setting.jsx')),
menu: true,
autoHide: true
},
{ {
path: 'user', path: 'user',
absolutePath: '/system/user', absolutePath: '/system/user',

View File

@@ -7,7 +7,9 @@ import {
URL_SYS_ROLE_LIST, URL_SYS_ROLE_LIST,
URL_SYS_GROUP, URL_SYS_GROUP,
URL_SYS_GROUP_LIST, URL_SYS_GROUP_LIST,
URL_SYS_LOG URL_SYS_LOG,
URL_SYS_SETTINGS,
URL_SYS_SETTINGS_MAIL
} from '@/constants/urls.constants' } from '@/constants/urls.constants'
import request from '@/services/index' import request from '@/services/index'
@@ -63,3 +65,8 @@ export const r_sys_group_delete_list = (ids: React.Key[]) => request.delete(URL_
export const r_sys_log_get = (param: SysLogGetParam) => export const r_sys_log_get = (param: SysLogGetParam) =>
request.get<PageVo<SysLogGetVo>>(URL_SYS_LOG, param) request.get<PageVo<SysLogGetVo>>(URL_SYS_LOG, param)
export const r_sys_settings_get = () => request.get<SystemSettingVo>(URL_SYS_SETTINGS)
export const r_sys_settings_mail_update = (param: MailSettingsParam) =>
request.put(URL_SYS_SETTINGS_MAIL, param)