diff --git a/src/assets/css/pages/system/settings.scss b/src/assets/css/pages/system/settings.scss
new file mode 100644
index 0000000..0b999c9
--- /dev/null
+++ b/src/assets/css/pages/system/settings.scss
@@ -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;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/assets/svg/back.svg b/src/assets/svg/back.svg
new file mode 100644
index 0000000..ca98267
--- /dev/null
+++ b/src/assets/svg/back.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/svg/email.svg b/src/assets/svg/email.svg
new file mode 100644
index 0000000..d87d895
--- /dev/null
+++ b/src/assets/svg/email.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/svg/save.svg b/src/assets/svg/save.svg
new file mode 100644
index 0000000..c4692fa
--- /dev/null
+++ b/src/assets/svg/save.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/constants/urls.constants.ts b/src/constants/urls.constants.ts
index 181effc..a6c8539 100644
--- a/src/constants/urls.constants.ts
+++ b/src/constants/urls.constants.ts
@@ -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_GROUP = '/system/group'
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`
diff --git a/src/global.d.ts b/src/global.d.ts
index 76bf786..7b4085a 100644
--- a/src/global.d.ts
+++ b/src/global.d.ts
@@ -294,3 +294,23 @@ interface GroupChangeStatusParam {
interface AvatarBase64Vo {
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
+}
diff --git a/src/pages/system/Settings.tsx b/src/pages/system/Settings.tsx
new file mode 100644
index 0000000..61a79cd
--- /dev/null
+++ b/src/pages/system/Settings.tsx
@@ -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 = (props) => {
+ return (
+
+
+
+
+ {props.title}
+
+
+
+
+
+
+
+ {props.children}
+
+
+ )
+}
+
+const MailSettings: React.FC<{ mail?: MailSettingsVo; onSave?: () => void }> = (props) => {
+ const [mailForm] = AntdForm.useForm()
+ 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 (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+const Settings: React.FC = () => {
+ const [systemSetting, setSystemSetting] = useState()
+
+ 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 (
+ <>
+
+
+
+
+
+
+
+ >
+ )
+}
+
+export default Settings
diff --git a/src/router/system.tsx b/src/router/system.tsx
index caf5d4c..b965fb8 100644
--- a/src/router/system.tsx
+++ b/src/router/system.tsx
@@ -11,6 +11,16 @@ const system: RouteJsonObject[] = [
icon: React.lazy(() => import('~icons/fatweb/setting.jsx')),
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',
absolutePath: '/system/user',
diff --git a/src/services/system.tsx b/src/services/system.tsx
index 6dfd943..f23c38d 100644
--- a/src/services/system.tsx
+++ b/src/services/system.tsx
@@ -7,7 +7,9 @@ import {
URL_SYS_ROLE_LIST,
URL_SYS_GROUP,
URL_SYS_GROUP_LIST,
- URL_SYS_LOG
+ URL_SYS_LOG,
+ URL_SYS_SETTINGS,
+ URL_SYS_SETTINGS_MAIL
} from '@/constants/urls.constants'
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) =>
request.get>(URL_SYS_LOG, param)
+
+export const r_sys_settings_get = () => request.get(URL_SYS_SETTINGS)
+
+export const r_sys_settings_mail_update = (param: MailSettingsParam) =>
+ request.put(URL_SYS_SETTINGS_MAIL, param)