Complete main UI #37
1
src/assets/svg/sensitive.svg
Normal file
1
src/assets/svg/sensitive.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M962.56 972.8L61.44 972.8C30.72 972.8 0 942.08 0 911.36c0-40.96 30.72-61.44 61.44-61.44l51.2-1e-8 235.52-665.59999999c20.47999999-81.92 102.4-143.36 194.56-122.88 61.44000001 10.24 112.64 61.44 122.88 122.88l235.52 665.59999999 51.2 1e-8c40.96 0 71.68 20.47999999 71.68 61.44 0 30.72-30.72 61.44-61.44 61.44zM512 819.2c30.72 0 61.44-20.47999999 61.44-61.44 0-30.72-30.72-61.44-61.44-71.68-30.72 0-61.44 30.72-61.44 61.44 0 40.96 20.47999999 61.44 61.44 71.68z m0-512c-40.96 0-61.44 20.47999999-61.44000001 51.2l1e-8 30.72S481.28 614.4 512 604.15999999c20.48 10.24 61.44-215.04 61.44-215.03999999L573.44000001 358.4c0-40.96-30.72-61.44-61.44000001-51.2z" /></svg>
|
||||
|
After Width: | Height: | Size: 735 B |
@@ -31,6 +31,7 @@ export const SYSTEM_REQUEST_ILLEGAL = 10052
|
||||
export const SYSTEM_ARGUMENT_NOT_VALID = 10053
|
||||
export const SYSTEM_INVALID_CAPTCHA_CODE = 10054
|
||||
export const SYSTEM_REQUEST_TOO_FREQUENT = 10055
|
||||
export const SYSTEM_MATCH_SENSITIVE_WORD = 10056
|
||||
|
||||
export const PERMISSION_LOGIN_SUCCESS = 20000
|
||||
export const PERMISSION_PASSWORD_CHANGE_SUCCESS = 20001
|
||||
|
||||
@@ -17,6 +17,7 @@ export const URL_SYS_GROUP_LIST = '/system/group/list'
|
||||
export const URL_SYS_SETTINGS = '/system/settings'
|
||||
export const URL_SYS_SETTINGS_BASE = `${URL_SYS_SETTINGS}/base`
|
||||
export const URL_SYS_SETTINGS_MAIL = `${URL_SYS_SETTINGS}/mail`
|
||||
export const URL_SYS_SETTINGS_SENSITIVE = `${URL_SYS_SETTINGS}/sensitive`
|
||||
export const URL_SYS_STATISTICS = '/system/statistics'
|
||||
export const URL_SYS_STATISTICS_SOFTWARE = `${URL_SYS_STATISTICS}/software`
|
||||
export const URL_SYS_STATISTICS_HARDWARE = `${URL_SYS_STATISTICS}/hardware`
|
||||
|
||||
17
src/global.d.ts
vendored
17
src/global.d.ts
vendored
@@ -357,6 +357,23 @@ interface MailSendParam {
|
||||
to: string
|
||||
}
|
||||
|
||||
interface SensitiveWordVo {
|
||||
id: string
|
||||
word: string
|
||||
useFor: string[]
|
||||
enable: boolean
|
||||
}
|
||||
|
||||
interface SensitiveWordAddParam {
|
||||
word: string
|
||||
useFor?: string[]
|
||||
enable?: boolean
|
||||
}
|
||||
|
||||
interface SensitiveWordUpdateParam {
|
||||
ids: string[]
|
||||
}
|
||||
|
||||
interface SoftwareInfoVo {
|
||||
os: string
|
||||
bitness: number
|
||||
|
||||
@@ -10,7 +10,7 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||
<React.StrictMode>
|
||||
<AntdConfigProvider
|
||||
theme={{
|
||||
token: { colorPrimary: COLOR_MAIN },
|
||||
token: { colorPrimary: COLOR_MAIN, colorLinkHover: COLOR_MAIN },
|
||||
components: {
|
||||
Tree: {
|
||||
colorBgContainer: 'transparent'
|
||||
|
||||
@@ -5,7 +5,8 @@ import {
|
||||
DATABASE_DUPLICATE_KEY,
|
||||
H_CAPTCHA_SITE_KEY,
|
||||
PERMISSION_REGISTER_SUCCESS,
|
||||
SYSTEM_INVALID_CAPTCHA_CODE
|
||||
SYSTEM_INVALID_CAPTCHA_CODE,
|
||||
SYSTEM_MATCH_SENSITIVE_WORD
|
||||
} from '@/constants/common.constants'
|
||||
import { useUpdatedEffect } from '@/util/hooks'
|
||||
import { getLoginStatus, setToken } from '@/util/auth'
|
||||
@@ -85,6 +86,10 @@ const SignUp: React.FC = () => {
|
||||
void message.error('验证码有误,请重试')
|
||||
setIsSigningUp(false)
|
||||
break
|
||||
case SYSTEM_MATCH_SENSITIVE_WORD:
|
||||
void message.error('用户名包含敏感词,请重试')
|
||||
setIsSigningUp(false)
|
||||
break
|
||||
default:
|
||||
void message.error('服务器出错了,请稍后重试')
|
||||
setIsSigningUp(false)
|
||||
|
||||
@@ -2,7 +2,9 @@ import React from 'react'
|
||||
import {
|
||||
COLOR_BACKGROUND,
|
||||
PERMISSION_ACCOUNT_NEED_INIT,
|
||||
PERMISSION_NO_VERIFICATION_REQUIRED
|
||||
PERMISSION_NO_VERIFICATION_REQUIRED,
|
||||
PERMISSION_VERIFY_SUCCESS,
|
||||
SYSTEM_MATCH_SENSITIVE_WORD
|
||||
} from '@/constants/common.constants'
|
||||
import { useUpdatedEffect } from '@/util/hooks'
|
||||
import { getLoginStatus, getUserInfo, requestUserInfo } from '@/util/auth'
|
||||
@@ -115,21 +117,27 @@ const Verify: React.FC = () => {
|
||||
nickname: verifyParam.nickname
|
||||
}).then((res) => {
|
||||
const response = res.data
|
||||
if (response.success) {
|
||||
void message.success('恭喜你,完成了')
|
||||
setTimeout(() => {
|
||||
void requestUserInfo().then(() => {
|
||||
refreshRouter()
|
||||
if (searchParams.has('redirect')) {
|
||||
navigate(searchParams.get('redirect') ?? '/')
|
||||
} else {
|
||||
navigate('/')
|
||||
}
|
||||
})
|
||||
}, 1500)
|
||||
} else {
|
||||
void message.error('出错了,请稍后重试')
|
||||
setIsVerifying(false)
|
||||
switch (response.code) {
|
||||
case PERMISSION_VERIFY_SUCCESS:
|
||||
void message.success('恭喜你,完成了')
|
||||
setTimeout(() => {
|
||||
void requestUserInfo().then(() => {
|
||||
refreshRouter()
|
||||
if (searchParams.has('redirect')) {
|
||||
navigate(searchParams.get('redirect') ?? '/')
|
||||
} else {
|
||||
navigate('/')
|
||||
}
|
||||
})
|
||||
}, 1500)
|
||||
break
|
||||
case SYSTEM_MATCH_SENSITIVE_WORD:
|
||||
void message.error('昵称包含敏感词,请重试')
|
||||
setIsVerifying(false)
|
||||
break
|
||||
default:
|
||||
void message.error('出错了,请稍后重试')
|
||||
setIsVerifying(false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ const BaseSettings: React.FC = () => {
|
||||
if (loading) {
|
||||
return
|
||||
}
|
||||
|
||||
setLoading(true)
|
||||
|
||||
void r_sys_settings_base_get().then((res) => {
|
||||
const response = res.data
|
||||
if (response.success) {
|
||||
|
||||
163
src/pages/system/settings/SensitiveWordSettings.tsx
Normal file
163
src/pages/system/settings/SensitiveWordSettings.tsx
Normal 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 SensitiveWordSettings: 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 SensitiveWordSettings
|
||||
@@ -9,6 +9,7 @@ import LoadingMask from '@/components/common/LoadingMask'
|
||||
import Permission from '@/components/common/Permission'
|
||||
import BaseSettings from '@/pages/system/settings/BaseSettings'
|
||||
import MailSettings from '@/pages/system/settings/MailSettings'
|
||||
import SensitiveWordSettings from '@/pages/system/settings/SensitiveWordSettings'
|
||||
|
||||
interface SettingsCardProps extends React.PropsWithChildren {
|
||||
icon: IconComponent
|
||||
@@ -38,7 +39,12 @@ export const SettingsCard: React.FC<SettingsCardProps> = (props) => {
|
||||
</Permission>
|
||||
) : undefined}
|
||||
</FlexBox>
|
||||
<LoadingMask hidden={!props.loading}>{props.children}</LoadingMask>
|
||||
<LoadingMask
|
||||
maskContent={<AntdSkeleton active paragraph={{ rows: 6 }} />}
|
||||
hidden={!props.loading}
|
||||
>
|
||||
{props.children}
|
||||
</LoadingMask>
|
||||
</FlexBox>
|
||||
</Card>
|
||||
)
|
||||
@@ -54,6 +60,9 @@ const Settings: React.FC = () => {
|
||||
<Permission operationCode={'system:settings:query:base'}>
|
||||
<BaseSettings />
|
||||
</Permission>
|
||||
<Permission operationCode={'system:settings:query:sensitive'}>
|
||||
<SensitiveWordSettings />
|
||||
</Permission>
|
||||
</FlexBox>
|
||||
<FlexBox className={'root-col'}>
|
||||
<Permission operationCode={'system:settings:query:mail'}>
|
||||
|
||||
@@ -15,7 +15,8 @@ import {
|
||||
URL_SYS_STATISTICS_STORAGE,
|
||||
URL_SYS_STATISTICS_ONLINE,
|
||||
URL_SYS_STATISTICS_ACTIVE,
|
||||
URL_SYS_SETTINGS_BASE
|
||||
URL_SYS_SETTINGS_BASE,
|
||||
URL_SYS_SETTINGS_SENSITIVE
|
||||
} from '@/constants/urls.constants'
|
||||
import request from '@/services/index'
|
||||
|
||||
@@ -85,6 +86,18 @@ export const r_sys_settings_mail_update = (param: MailSettingsParam) =>
|
||||
export const r_sys_settings_mail_send = (param: MailSendParam) =>
|
||||
request.post(URL_SYS_SETTINGS_MAIL, param)
|
||||
|
||||
export const r_sys_settings_sensitive_get = () =>
|
||||
request.get<SensitiveWordVo[]>(URL_SYS_SETTINGS_SENSITIVE)
|
||||
|
||||
export const r_sys_settings_sensitive_add = (param: SensitiveWordAddParam) =>
|
||||
request.post(URL_SYS_SETTINGS_SENSITIVE, param)
|
||||
|
||||
export const r_sys_settings_sensitive_update = (param: SensitiveWordUpdateParam) =>
|
||||
request.put(URL_SYS_SETTINGS_SENSITIVE, param)
|
||||
|
||||
export const r_sys_settings_sensitive_delete = (id: string) =>
|
||||
request.delete(`${URL_SYS_SETTINGS_SENSITIVE}/${id}`)
|
||||
|
||||
export const r_sys_statistics_software = () =>
|
||||
request.get<SoftwareInfoVo>(URL_SYS_STATISTICS_SOFTWARE)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user