Optimize file name

This commit is contained in:
2024-01-05 13:51:38 +08:00
parent 3d8e55cbea
commit 6c8c6088d1
41 changed files with 177 additions and 162 deletions

View File

@@ -0,0 +1,81 @@
import React from 'react'
import { useUpdatedEffect } from '@/util/hooks'
import { hasPermission } from '@/util/auth'
import { r_sys_settings_base_get, r_sys_settings_base_update } from '@/services/system'
import { SettingsCard } from '@/pages/System/Settings'
const Base: React.FC = () => {
const [baseForm] = AntdForm.useForm<BaseSettingsParam>()
const baseFormValues = AntdForm.useWatch([], baseForm)
const [loading, setLoading] = useState(false)
const handleOnReset = () => {
getBaseSettings()
}
const handleOnSave = () => {
void r_sys_settings_base_update(baseFormValues).then((res) => {
const response = res.data
if (response.success) {
void message.success('保存设置成功')
getBaseSettings()
} else {
void message.error('保存设置失败,请稍后重试')
}
})
}
const getBaseSettings = () => {
if (loading) {
return
}
setLoading(true)
void r_sys_settings_base_get().then((res) => {
const response = res.data
if (response.success) {
const data = response.data
data && baseForm.setFieldsValue(data)
setLoading(false)
}
})
}
useUpdatedEffect(() => {
getBaseSettings()
}, [])
return (
<>
<SettingsCard
icon={IconOxygenEmail}
title={'基础'}
loading={loading}
onReset={handleOnReset}
onSave={handleOnSave}
modifyOperationCode={'system:settings:modify:base'}
>
<AntdForm
form={baseForm}
labelCol={{ flex: '7em' }}
disabled={!hasPermission('system:settings:modify:base')}
>
<AntdForm.Item label={'应用名称'} name={'appName'}>
<AntdInput />
</AntdForm.Item>
<AntdForm.Item label={'应用 URL'} name={'appUrl'}>
<AntdInput />
</AntdForm.Item>
<AntdForm.Item label={'验证邮箱 URL'} name={'verifyUrl'}>
<AntdInput placeholder={'验证码使用 ${verifyCode} 代替'} />
</AntdForm.Item>
<AntdForm.Item label={'找回密码 URL'} name={'retrieveUrl'}>
<AntdInput placeholder={'验证码使用 ${retrieveCode} 代替'} />
</AntdForm.Item>
</AntdForm>
</SettingsCard>
</>
)
}
export default Base

View File

@@ -0,0 +1,155 @@
import React from 'react'
import Icon from '@ant-design/icons'
import { useUpdatedEffect } from '@/util/hooks'
import { hasPermission } from '@/util/auth'
import {
r_sys_settings_mail_get,
r_sys_settings_mail_send,
r_sys_settings_mail_update
} from '@/services/system'
import { SettingsCard } from '@/pages/System/Settings'
const Mail: React.FC = () => {
const [modal, contextHolder] = AntdModal.useModal()
const [mailForm] = AntdForm.useForm<MailSettingsParam>()
const mailFormValues = AntdForm.useWatch([], mailForm)
const [loading, setLoading] = useState(false)
const [mailSendForm] = AntdForm.useForm<MailSendParam>()
const handleOnTest = () => {
void modal.confirm({
title: '发送测试邮件',
content: (
<>
<AntdForm form={mailSendForm}>
<AntdForm.Item
name={'to'}
label={'接收人'}
style={{ marginTop: 10 }}
rules={[{ required: true, type: 'email' }]}
>
<AntdInput />
</AntdForm.Item>
</AntdForm>
<AntdTag style={{ whiteSpace: 'normal' }}>
使
</AntdTag>
</>
),
onOk: () =>
mailSendForm.validateFields().then(
() => {
return new Promise((resolve) => {
void r_sys_settings_mail_send({
to: mailSendForm.getFieldValue('to') as string
}).then((res) => {
const response = res.data
if (response.success) {
void message.success('发送成功')
resolve(true)
} else {
void message.error('发送失败,请检查配置后重试')
resolve(true)
}
})
})
},
() => {
return new Promise((_, reject) => {
reject('未输入接收者')
})
}
)
})
}
const handleOnReset = () => {
getMailSettings()
}
const handleOnSave = () => {
void r_sys_settings_mail_update(mailFormValues).then((res) => {
const response = res.data
if (response.success) {
void message.success('保存设置成功')
getMailSettings()
} else {
void message.error('保存设置失败,请稍后重试')
}
})
}
const getMailSettings = () => {
if (loading) {
return
}
setLoading(true)
void r_sys_settings_mail_get().then((res) => {
const response = res.data
if (response.success) {
const data = response.data
data && mailForm.setFieldsValue(data)
setLoading(false)
}
})
}
useUpdatedEffect(() => {
getMailSettings()
}, [])
return (
<>
<SettingsCard
icon={IconOxygenEmail}
title={'邮件'}
loading={loading}
onReset={handleOnReset}
onSave={handleOnSave}
modifyOperationCode={'system:settings:modify:mail'}
expand={
<AntdButton onClick={handleOnTest} title={'测试'}>
<Icon component={IconOxygenTest} />
</AntdButton>
}
>
<AntdForm
form={mailForm}
labelCol={{ flex: '8em' }}
disabled={!hasPermission('system:settings:modify:mail')}
>
<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={'securityType'}>
<AntdSelect>
<AntdSelect.Option key={'None'}>None</AntdSelect.Option>
<AntdSelect.Option key={'SSL/TLS'}>SSL/TLS</AntdSelect.Option>
<AntdSelect.Option key={'StartTls'}>StartTls</AntdSelect.Option>
</AntdSelect>
</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.Item label={'发送者名称'} name={'fromName'}>
<AntdInput />
</AntdForm.Item>
</AntdForm>
</SettingsCard>
{contextHolder}
</>
)
}
export default Mail

View File

@@ -0,0 +1,163 @@
import React, { useState } from 'react'
import Icon from '@ant-design/icons'
import { DATABASE_DUPLICATE_KEY, DATABASE_INSERT_SUCCESS } from '@/constants/common.constants'
import { useUpdatedEffect } from '@/util/hooks'
import {
r_sys_settings_sensitive_add,
r_sys_settings_sensitive_delete,
r_sys_settings_sensitive_get,
r_sys_settings_sensitive_update
} from '@/services/system'
import { SettingsCard } from '@/pages/System/Settings'
const SensitiveWord: React.FC = () => {
const [dataSource, setDataSource] = useState<SensitiveWordVo[]>()
const [targetKeys, setTargetKeys] = useState<string[]>([])
const [selectedKeys, setSelectedKeys] = useState<string[]>([])
const [loading, setLoading] = useState(false)
const [isAdding, setIsAdding] = useState(false)
const [newWord, setNewWord] = useState('')
const handleOnReset = () => {
getSensitiveWordSettings()
}
const handleOnSave = () => {
targetKeys &&
void r_sys_settings_sensitive_update({ ids: targetKeys }).then((res) => {
const response = res.data
if (response.success) {
void message.success('保存成功')
getSensitiveWordSettings()
} else {
void message.error('保存失败,请稍后重试')
}
})
}
const handleOnDelete = () => {
void r_sys_settings_sensitive_delete(selectedKeys[0]).then((res) => {
const response = res.data
if (response.success) {
void message.success('删除成功')
getSensitiveWordSettings()
} else {
void message.error('删除失败,请稍后重试')
}
})
}
const getSensitiveWordSettings = () => {
if (loading) {
return
}
setLoading(true)
void r_sys_settings_sensitive_get().then((res) => {
const response = res.data
if (response.success) {
const data = response.data
data && setDataSource(data)
data && setTargetKeys(data.filter((value) => value.enable).map((value) => value.id))
setLoading(false)
}
})
}
const handleOnChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setNewWord(e.target.value)
}
const handleOnAdd = () => {
if (isAdding) {
return
}
setIsAdding(true)
void r_sys_settings_sensitive_add({ word: newWord, enable: false })
.then((res) => {
const response = res.data
switch (response.code) {
case DATABASE_INSERT_SUCCESS:
void message.success('添加成功')
setNewWord('')
getSensitiveWordSettings()
break
case DATABASE_DUPLICATE_KEY:
void message.error('该词已存在')
break
default:
void message.error('出错了,请稍后重试')
}
})
.finally(() => {
setIsAdding(false)
})
}
useUpdatedEffect(() => {
getSensitiveWordSettings()
}, [])
return (
<>
<SettingsCard
icon={IconOxygenSensitive}
title={'敏感词'}
loading={loading}
onReset={handleOnReset}
onSave={handleOnSave}
modifyOperationCode={'system:settings:modify:sensitive'}
>
<AntdTransfer
listStyle={{ width: '100%', height: 400 }}
oneWay
showSearch
pagination
disabled={isAdding}
titles={[
<span
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end'
}}
>
{selectedKeys?.length === 1 ? (
<AntdTooltip title={'删除选中项'}>
<Icon
style={{ fontSize: '1.2em' }}
component={IconOxygenDelete}
onClick={handleOnDelete}
/>
</AntdTooltip>
) : undefined}
</span>,
'拦截'
]}
dataSource={dataSource}
targetKeys={targetKeys}
selectedKeys={selectedKeys}
onChange={setTargetKeys}
onSelectChange={setSelectedKeys}
rowKey={(item) => item.id}
render={(item) => item.word}
/>
<AntdInput
value={newWord}
onChange={handleOnChange}
onPressEnter={handleOnAdd}
disabled={isAdding}
suffix={
<AntdButton type={'primary'} onClick={handleOnAdd} disabled={isAdding}>
<Icon component={IconOxygenPlus} />
</AntdButton>
}
></AntdInput>
</SettingsCard>
</>
)
}
export default SensitiveWord

View File

@@ -0,0 +1,79 @@
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 LoadingMask from '@/components/common/LoadingMask'
import Permission from '@/components/common/Permission'
import Base from '@/pages/System/Settings/Base'
import Mail from '@/pages/System/Settings/Mail'
import SensitiveWord from '@/pages/System/Settings/SensitiveWord'
interface SettingsCardProps extends React.PropsWithChildren {
icon: IconComponent
title: string
loading?: boolean
modifyOperationCode?: string
expand?: React.ReactNode
onReset?: () => void
onSave?: () => void
}
export 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>
{!props.loading ? (
<Permission operationCode={props.modifyOperationCode}>
{props.expand}
<AntdButton onClick={props.onReset} title={'重置'}>
<Icon component={IconOxygenBack} />
</AntdButton>
<AntdButton className={'bt-save'} onClick={props.onSave} title={'保存'}>
<Icon component={IconOxygenSave} />
</AntdButton>
</Permission>
) : undefined}
</FlexBox>
<LoadingMask
maskContent={<AntdSkeleton active paragraph={{ rows: 6 }} />}
hidden={!props.loading}
>
{props.children}
</LoadingMask>
</FlexBox>
</Card>
)
}
const Settings: React.FC = () => {
return (
<>
<FitFullscreen data-component={'system-settings'}>
<HideScrollbar isShowVerticalScrollbar autoHideWaitingTime={500}>
<FlexBox direction={'horizontal'} className={'root-content'}>
<FlexBox className={'root-col'}>
<Permission operationCode={'system:settings:query:base'}>
<Base />
</Permission>
<Permission operationCode={'system:settings:query:sensitive'}>
<SensitiveWord />
</Permission>
</FlexBox>
<FlexBox className={'root-col'}>
<Permission operationCode={'system:settings:query:mail'}>
<Mail />
</Permission>
</FlexBox>
</FlexBox>
</HideScrollbar>
</FitFullscreen>
</>
)
}
export default Settings