Add sensitive word settings management
This commit is contained in:
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_ARGUMENT_NOT_VALID = 10053
|
||||||
export const SYSTEM_INVALID_CAPTCHA_CODE = 10054
|
export const SYSTEM_INVALID_CAPTCHA_CODE = 10054
|
||||||
export const SYSTEM_REQUEST_TOO_FREQUENT = 10055
|
export const SYSTEM_REQUEST_TOO_FREQUENT = 10055
|
||||||
|
export const SYSTEM_MATCH_SENSITIVE_WORD = 10056
|
||||||
|
|
||||||
export const PERMISSION_LOGIN_SUCCESS = 20000
|
export const PERMISSION_LOGIN_SUCCESS = 20000
|
||||||
export const PERMISSION_PASSWORD_CHANGE_SUCCESS = 20001
|
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 = '/system/settings'
|
||||||
export const URL_SYS_SETTINGS_BASE = `${URL_SYS_SETTINGS}/base`
|
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_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 = '/system/statistics'
|
||||||
export const URL_SYS_STATISTICS_SOFTWARE = `${URL_SYS_STATISTICS}/software`
|
export const URL_SYS_STATISTICS_SOFTWARE = `${URL_SYS_STATISTICS}/software`
|
||||||
export const URL_SYS_STATISTICS_HARDWARE = `${URL_SYS_STATISTICS}/hardware`
|
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
|
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 {
|
interface SoftwareInfoVo {
|
||||||
os: string
|
os: string
|
||||||
bitness: number
|
bitness: number
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
|
|||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<AntdConfigProvider
|
<AntdConfigProvider
|
||||||
theme={{
|
theme={{
|
||||||
token: { colorPrimary: COLOR_MAIN },
|
token: { colorPrimary: COLOR_MAIN, colorLinkHover: COLOR_MAIN },
|
||||||
components: {
|
components: {
|
||||||
Tree: {
|
Tree: {
|
||||||
colorBgContainer: 'transparent'
|
colorBgContainer: 'transparent'
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import {
|
|||||||
DATABASE_DUPLICATE_KEY,
|
DATABASE_DUPLICATE_KEY,
|
||||||
H_CAPTCHA_SITE_KEY,
|
H_CAPTCHA_SITE_KEY,
|
||||||
PERMISSION_REGISTER_SUCCESS,
|
PERMISSION_REGISTER_SUCCESS,
|
||||||
SYSTEM_INVALID_CAPTCHA_CODE
|
SYSTEM_INVALID_CAPTCHA_CODE,
|
||||||
|
SYSTEM_MATCH_SENSITIVE_WORD
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
import { useUpdatedEffect } from '@/util/hooks'
|
import { useUpdatedEffect } from '@/util/hooks'
|
||||||
import { getLoginStatus, setToken } from '@/util/auth'
|
import { getLoginStatus, setToken } from '@/util/auth'
|
||||||
@@ -85,6 +86,10 @@ const SignUp: React.FC = () => {
|
|||||||
void message.error('验证码有误,请重试')
|
void message.error('验证码有误,请重试')
|
||||||
setIsSigningUp(false)
|
setIsSigningUp(false)
|
||||||
break
|
break
|
||||||
|
case SYSTEM_MATCH_SENSITIVE_WORD:
|
||||||
|
void message.error('用户名包含敏感词,请重试')
|
||||||
|
setIsSigningUp(false)
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
void message.error('服务器出错了,请稍后重试')
|
void message.error('服务器出错了,请稍后重试')
|
||||||
setIsSigningUp(false)
|
setIsSigningUp(false)
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ import React from 'react'
|
|||||||
import {
|
import {
|
||||||
COLOR_BACKGROUND,
|
COLOR_BACKGROUND,
|
||||||
PERMISSION_ACCOUNT_NEED_INIT,
|
PERMISSION_ACCOUNT_NEED_INIT,
|
||||||
PERMISSION_NO_VERIFICATION_REQUIRED
|
PERMISSION_NO_VERIFICATION_REQUIRED,
|
||||||
|
PERMISSION_VERIFY_SUCCESS,
|
||||||
|
SYSTEM_MATCH_SENSITIVE_WORD
|
||||||
} from '@/constants/common.constants'
|
} from '@/constants/common.constants'
|
||||||
import { useUpdatedEffect } from '@/util/hooks'
|
import { useUpdatedEffect } from '@/util/hooks'
|
||||||
import { getLoginStatus, getUserInfo, requestUserInfo } from '@/util/auth'
|
import { getLoginStatus, getUserInfo, requestUserInfo } from '@/util/auth'
|
||||||
@@ -115,21 +117,27 @@ const Verify: React.FC = () => {
|
|||||||
nickname: verifyParam.nickname
|
nickname: verifyParam.nickname
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
const response = res.data
|
const response = res.data
|
||||||
if (response.success) {
|
switch (response.code) {
|
||||||
void message.success('恭喜你,完成了')
|
case PERMISSION_VERIFY_SUCCESS:
|
||||||
setTimeout(() => {
|
void message.success('恭喜你,完成了')
|
||||||
void requestUserInfo().then(() => {
|
setTimeout(() => {
|
||||||
refreshRouter()
|
void requestUserInfo().then(() => {
|
||||||
if (searchParams.has('redirect')) {
|
refreshRouter()
|
||||||
navigate(searchParams.get('redirect') ?? '/')
|
if (searchParams.has('redirect')) {
|
||||||
} else {
|
navigate(searchParams.get('redirect') ?? '/')
|
||||||
navigate('/')
|
} else {
|
||||||
}
|
navigate('/')
|
||||||
})
|
}
|
||||||
}, 1500)
|
})
|
||||||
} else {
|
}, 1500)
|
||||||
void message.error('出错了,请稍后重试')
|
break
|
||||||
setIsVerifying(false)
|
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) {
|
if (loading) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
|
|
||||||
void r_sys_settings_base_get().then((res) => {
|
void r_sys_settings_base_get().then((res) => {
|
||||||
const response = res.data
|
const response = res.data
|
||||||
if (response.success) {
|
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 Permission from '@/components/common/Permission'
|
||||||
import BaseSettings from '@/pages/system/settings/BaseSettings'
|
import BaseSettings from '@/pages/system/settings/BaseSettings'
|
||||||
import MailSettings from '@/pages/system/settings/MailSettings'
|
import MailSettings from '@/pages/system/settings/MailSettings'
|
||||||
|
import SensitiveWordSettings from '@/pages/system/settings/SensitiveWordSettings'
|
||||||
|
|
||||||
interface SettingsCardProps extends React.PropsWithChildren {
|
interface SettingsCardProps extends React.PropsWithChildren {
|
||||||
icon: IconComponent
|
icon: IconComponent
|
||||||
@@ -38,7 +39,12 @@ export const SettingsCard: React.FC<SettingsCardProps> = (props) => {
|
|||||||
</Permission>
|
</Permission>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
</FlexBox>
|
</FlexBox>
|
||||||
<LoadingMask hidden={!props.loading}>{props.children}</LoadingMask>
|
<LoadingMask
|
||||||
|
maskContent={<AntdSkeleton active paragraph={{ rows: 6 }} />}
|
||||||
|
hidden={!props.loading}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</LoadingMask>
|
||||||
</FlexBox>
|
</FlexBox>
|
||||||
</Card>
|
</Card>
|
||||||
)
|
)
|
||||||
@@ -54,6 +60,9 @@ const Settings: React.FC = () => {
|
|||||||
<Permission operationCode={'system:settings:query:base'}>
|
<Permission operationCode={'system:settings:query:base'}>
|
||||||
<BaseSettings />
|
<BaseSettings />
|
||||||
</Permission>
|
</Permission>
|
||||||
|
<Permission operationCode={'system:settings:query:sensitive'}>
|
||||||
|
<SensitiveWordSettings />
|
||||||
|
</Permission>
|
||||||
</FlexBox>
|
</FlexBox>
|
||||||
<FlexBox className={'root-col'}>
|
<FlexBox className={'root-col'}>
|
||||||
<Permission operationCode={'system:settings:query:mail'}>
|
<Permission operationCode={'system:settings:query:mail'}>
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import {
|
|||||||
URL_SYS_STATISTICS_STORAGE,
|
URL_SYS_STATISTICS_STORAGE,
|
||||||
URL_SYS_STATISTICS_ONLINE,
|
URL_SYS_STATISTICS_ONLINE,
|
||||||
URL_SYS_STATISTICS_ACTIVE,
|
URL_SYS_STATISTICS_ACTIVE,
|
||||||
URL_SYS_SETTINGS_BASE
|
URL_SYS_SETTINGS_BASE,
|
||||||
|
URL_SYS_SETTINGS_SENSITIVE
|
||||||
} from '@/constants/urls.constants'
|
} from '@/constants/urls.constants'
|
||||||
import request from '@/services/index'
|
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) =>
|
export const r_sys_settings_mail_send = (param: MailSendParam) =>
|
||||||
request.post(URL_SYS_SETTINGS_MAIL, param)
|
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 = () =>
|
export const r_sys_statistics_software = () =>
|
||||||
request.get<SoftwareInfoVo>(URL_SYS_STATISTICS_SOFTWARE)
|
request.get<SoftwareInfoVo>(URL_SYS_STATISTICS_SOFTWARE)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user