Complete main UI #37

Merged
FatttSnake merged 192 commits from FatttSnake into dev 2024-02-23 16:31:17 +08:00
7 changed files with 260 additions and 92 deletions
Showing only changes of commit d5fb2cd48d - Show all commits

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

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1152 1024"><path d="M576 288a221.88 221.88 0 0 0-62.48 10 110.8 110.8 0 0 1 14.48 54 112 112 0 0 1-112 112 110.8 110.8 0 0 1-54-14.48A223.42 223.42 0 1 0 576 288z m569.04 194.8C1036.58 271.18 821.86 128 576 128S115.36 271.28 6.96 482.82a64.7 64.7 0 0 0 0 58.38C115.42 752.82 330.14 896 576 896s460.64-143.28 569.04-354.82a64.7 64.7 0 0 0 0-58.38zM576 800c-197.3 0-378.18-110-475.86-288C197.82 334 378.68 224 576 224s378.18 110 475.86 288C954.2 690 773.32 800 576 800z" /></svg>

After

Width:  |  Height:  |  Size: 530 B

View File

@@ -8,7 +8,7 @@ const Footer: React.FC = () => {
return ( return (
<> <>
<FitFullScreen backgroundColor={'#333'}> <FitFullScreen backgroundColor={'#333'}>
<FitCenter vertical={true} style={{ gap: '20px' }}> <FitCenter vertical={true} style={{ gap: 20 }}>
<div className={'icons'}> <div className={'icons'}>
<NavLink to={'https://github.com/FatttSnake'}> <NavLink to={'https://github.com/FatttSnake'}>
<Icon component={IconFatwebGithub} className={'icon'} /> <Icon component={IconFatwebGithub} className={'icon'} />

36
src/global.d.ts vendored
View File

@@ -95,21 +95,6 @@ interface UserWithRoleInfoVo {
groups: GroupVo[] groups: GroupVo[]
} }
interface UserAddEditParam {
id?: string
username: string
password?: string
locking?: boolean
expiration?: string
credentialsExpiration?: string
enable?: boolean
nickname?: string
avatar?: string
email?: string
roleIds: number[]
groupIds: number[]
}
interface UserInfoVo { interface UserInfoVo {
id: string id: string
userId: string userId: string
@@ -190,6 +175,27 @@ interface TableParam {
filters?: Record<string, _FilterValue | null> filters?: Record<string, _FilterValue | null>
} }
interface UserAddEditParam {
id?: string
username: string
password?: string
locking?: boolean
expiration?: string
credentialsExpiration?: string
enable?: boolean
nickname?: string
avatar?: string
email?: string
roleIds: number[]
groupIds: number[]
}
interface UserChangePasswordParam {
id: string
password: string
credentialsExpiration?: string
}
interface SysLogGetParam extends PageParam { interface SysLogGetParam extends PageParam {
searchRequestUrl?: string searchRequestUrl?: string
searchRegex?: boolean searchRegex?: boolean

View File

@@ -80,7 +80,7 @@ const HomeFramework: React.FC = () => {
ref={hideScrollbarRef} ref={hideScrollbarRef}
isPreventVerticalScroll={preventScroll} isPreventVerticalScroll={preventScroll}
isShowHorizontalScrollbar={true} isShowHorizontalScrollbar={true}
minWidth={'900px'} minWidth={900}
> >
<div className={'body'}> <div className={'body'}>
<div> <div>

View File

@@ -1,4 +1,4 @@
import React from 'react' import React, { useEffect, useState } from 'react'
import Icon from '@ant-design/icons' import Icon from '@ant-design/icons'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { import {
@@ -12,11 +12,12 @@ import {
DATABASE_SELECT_SUCCESS, DATABASE_SELECT_SUCCESS,
DATABASE_UPDATE_SUCCESS DATABASE_UPDATE_SUCCESS
} from '@/constants/common.constants' } from '@/constants/common.constants'
import { utcToLocalTime, isPastTime, localTimeToUtc, dayjsToUtc } from '@/utils/common' import { utcToLocalTime, isPastTime, localTimeToUtc, dayjsToUtc, getNowUtc } from '@/utils/common'
import { import {
r_sys_group_get_list, r_sys_group_get_list,
r_sys_role_get_list, r_sys_role_get_list,
r_sys_user_add, r_sys_user_add,
r_sys_user_change_password,
r_sys_user_delete, r_sys_user_delete,
r_sys_user_delete_list, r_sys_user_delete_list,
r_sys_user_get, r_sys_user_get,
@@ -28,13 +29,30 @@ import HideScrollbar from '@/components/common/HideScrollbar'
import FlexBox from '@/components/common/FlexBox' import FlexBox from '@/components/common/FlexBox'
import Card from '@/components/common/Card' import Card from '@/components/common/Card'
interface ChangePasswordFields extends UserChangePasswordParam {
passwordConfirm: string
needChangePassword: boolean
}
const User: React.FC = () => { const User: React.FC = () => {
const [modal, contextHolder] = AntdModal.useModal() const [modal, contextHolder] = AntdModal.useModal()
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
const [isDrawerEdit, setIsDrawerEdit] = useState(false)
const [isDrawerSubmittable, setIsDrawerSubmittable] = useState(false)
const [isDrawerSubmitting, setIsDrawerSubmitting] = useState(false)
const [roleData, setRoleData] = useState<RoleVo[]>([])
const [groupData, setGroupData] = useState<GroupVo[]>([])
const [isLoadingRole, setIsLoadingRole] = useState(false)
const [isLoadingGroup, setIsLoadingGroup] = useState(false)
const [avatar, setAvatar] = useState('')
const [form] = AntdForm.useForm<UserAddEditParam>() const [form] = AntdForm.useForm<UserAddEditParam>()
const formValues = AntdForm.useWatch([], form) const formValues = AntdForm.useWatch([], form)
const [newFormValues, setNewFormValues] = useState<UserAddEditParam>() const [newFormValues, setNewFormValues] = useState<UserAddEditParam>()
const [userData, setUserData] = useState<UserWithRoleInfoVo[]>([])
const [isLoading, setIsLoading] = useState(false) const [changePasswordForm] = AntdForm.useForm<ChangePasswordFields>()
const [tableParams, setTableParams] = useState<TableParam>({ const [tableParams, setTableParams] = useState<TableParam>({
pagination: { pagination: {
current: 1, current: 1,
@@ -42,25 +60,19 @@ const User: React.FC = () => {
position: ['bottomCenter'] position: ['bottomCenter']
} }
}) })
const [tableSelectedItem, setTableSelectedItem] = useState<React.Key[]>([])
const [userData, setUserData] = useState<UserWithRoleInfoVo[]>([])
const [isLoadingUserData, setIsLoadingUserData] = useState(false)
const [searchValue, setSearchValue] = useState('') const [searchValue, setSearchValue] = useState('')
const [isUseRegex, setIsUseRegex] = useState(false) const [isUseRegex, setIsUseRegex] = useState(false)
const [isRegexLegal, setIsRegexLegal] = useState(true) const [isRegexLegal, setIsRegexLegal] = useState(true)
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
const [isDrawerEdit, setIsDrawerEdit] = useState(false)
const [submittable, setSubmittable] = useState(false)
const [roleData, setRoleData] = useState<RoleVo[]>([])
const [groupData, setGroupData] = useState<GroupVo[]>([])
const [isLoadingRole, setIsLoadingRole] = useState(false)
const [isLoadingGroup, setIsLoadingGroup] = useState(false)
const [isSubmitting, setIsSubmitting] = useState(false)
const [tableSelectedItem, setTableSelectedItem] = useState<React.Key[]>([])
const [avatar, setAvatar] = useState('')
const dataColumns: _ColumnsType<UserWithRoleInfoVo> = [ const dataColumns: _ColumnsType<UserWithRoleInfoVo> = [
{ {
dataIndex: 'username', dataIndex: 'username',
title: '用户', title: '用户',
render: (value, record) => `${value}(${record.id})`, render: (value, record) => <AntdTooltip title={record.id}>{value}</AntdTooltip>,
width: '0' width: '0'
}, },
{ {
@@ -68,7 +80,13 @@ const User: React.FC = () => {
title: '头像', title: '头像',
render: (value) => ( render: (value) => (
<AntdAvatar <AntdAvatar
src={<img src={`data:image/png;base64,${value}`} alt={'avatar'} />} src={
<AntdImage
preview={{ mask: <Icon component={IconFatwebEye}></Icon> }}
src={`data:image/png;base64,${value}`}
alt={'avatar'}
/>
}
style={{ background: COLOR_BACKGROUND }} style={{ background: COLOR_BACKGROUND }}
/> />
), ),
@@ -127,25 +145,35 @@ const User: React.FC = () => {
}, },
{ {
title: '状态', title: '状态',
render: (_, record) => render: (_, record) => (
!record.locking && <AntdTooltip
(!record.expiration || !isPastTime(record.expiration)) && title={
(!record.credentialsExpiration || !isPastTime(record.credentialsExpiration)) && <>
record.enable ? ( <p>{utcToLocalTime(record.createTime)}</p>
<AntdTag color={'green'}></AntdTag> <p>{utcToLocalTime(record.updateTime)}</p>
) : ( </>
<> }
{record.locking ? <AntdTag></AntdTag> : undefined} >
{record.expiration && isPastTime(record.expiration) ? ( {!record.locking &&
<AntdTag></AntdTag> (!record.expiration || !isPastTime(record.expiration)) &&
) : undefined} (!record.credentialsExpiration || !isPastTime(record.credentialsExpiration)) &&
{record.credentialsExpiration && record.enable ? (
isPastTime(record.credentialsExpiration) ? ( <AntdTag color={'green'}></AntdTag>
<AntdTag></AntdTag> ) : (
) : undefined} <>
{!record.enable ? <AntdTag></AntdTag> : undefined} {record.locking ? <AntdTag></AntdTag> : undefined}
</> {record.expiration && isPastTime(record.expiration) ? (
), <AntdTag></AntdTag>
) : undefined}
{record.credentialsExpiration &&
isPastTime(record.credentialsExpiration) ? (
<AntdTag></AntdTag>
) : undefined}
{!record.enable ? <AntdTag></AntdTag> : undefined}
</>
)}
</AntdTooltip>
),
align: 'center' align: 'center'
}, },
{ {
@@ -155,6 +183,12 @@ const User: React.FC = () => {
render: (_, record) => ( render: (_, record) => (
<> <>
<AntdSpace size={'middle'}> <AntdSpace size={'middle'}>
<a
style={{ color: COLOR_PRODUCTION }}
onClick={handleOnChangePasswordBtnClick(record)}
>
</a>
<a <a
style={{ color: COLOR_PRODUCTION }} style={{ color: COLOR_PRODUCTION }}
onClick={handleOnEditBtnClick(record)} onClick={handleOnEditBtnClick(record)}
@@ -230,7 +264,7 @@ const User: React.FC = () => {
.then( .then(
(confirmed) => { (confirmed) => {
if (confirmed) { if (confirmed) {
setIsLoading(true) setIsLoadingUserData(true)
void r_sys_user_delete_list(tableSelectedItem) void r_sys_user_delete_list(tableSelectedItem)
.then((res) => { .then((res) => {
@@ -246,7 +280,7 @@ const User: React.FC = () => {
} }
}) })
.finally(() => { .finally(() => {
setIsLoading(false) setIsLoadingUserData(false)
}) })
} }
}, },
@@ -254,6 +288,115 @@ const User: React.FC = () => {
) )
} }
const handleOnChangePasswordBtnClick = (value: UserWithRoleInfoVo) => {
return () => {
changePasswordForm.setFieldValue('id', value.id)
changePasswordForm.setFieldValue('password', undefined)
changePasswordForm.setFieldValue('passwordConfirm', undefined)
changePasswordForm.setFieldValue(
'needChangePassword',
value.credentialsExpiration && isPastTime(value.credentialsExpiration)
)
void modal.confirm({
icon: <></>,
title: (
<>
<Icon
style={{ color: COLOR_PRODUCTION, marginRight: 10 }}
component={IconFatwebSetting}
/>
{value.username}
</>
),
content: (
<AntdForm
form={changePasswordForm}
style={{ marginTop: 20 }}
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
>
<AntdForm.Item name={'id'} label={'ID'} labelAlign={'right'}>
<AntdInput disabled />
</AntdForm.Item>
<AntdForm.Item
name={'password'}
label={'密码'}
rules={[
{
required: true
}
]}
>
<AntdInput.Password />
</AntdForm.Item>
<AntdForm.Item
name={'passwordConfirm'}
label={'确认密码'}
rules={[
{
required: true
},
({ getFieldValue }) => ({
validator(_, value) {
if (!value || getFieldValue('password') === value) {
return Promise.resolve()
}
return Promise.reject(new Error('两次密码输入不一致'))
}
})
]}
>
<AntdInput.Password />
</AntdForm.Item>
<AntdForm.Item
name={'needChangePassword'}
label={'需改密'}
valuePropName={'checked'}
rules={[{ type: 'boolean' }]}
>
<AntdSwitch />
</AntdForm.Item>
</AntdForm>
),
onOk: () =>
changePasswordForm
.validateFields()
.then(
() => {
return new Promise((resolve, reject) => {
void r_sys_user_change_password({
id: changePasswordForm.getFieldValue('id') as string,
password: changePasswordForm.getFieldValue(
'password'
) as string,
credentialsExpiration: (changePasswordForm.getFieldValue(
'needChangePassword'
) as boolean)
? getNowUtc()
: undefined
}).then((res) => {
const response = res.data
if (response.success) {
resolve(true)
} else {
reject(response.msg)
}
})
})
},
() => {
return new Promise((_, reject) => {
reject('输入有误')
})
}
)
.then(() => {
getUser()
})
})
}
}
const handleOnEditBtnClick = (value: UserWithRoleInfoVo) => { const handleOnEditBtnClick = (value: UserWithRoleInfoVo) => {
return () => { return () => {
setIsDrawerEdit(true) setIsDrawerEdit(true)
@@ -291,7 +434,7 @@ const User: React.FC = () => {
.then( .then(
(confirmed) => { (confirmed) => {
if (confirmed) { if (confirmed) {
setIsLoading(true) setIsLoadingUserData(true)
void r_sys_user_delete(value.id) void r_sys_user_delete(value.id)
.then((res) => { .then((res) => {
@@ -306,7 +449,7 @@ const User: React.FC = () => {
} }
}) })
.finally(() => { .finally(() => {
setIsLoading(false) setIsLoadingUserData(false)
}) })
} }
}, },
@@ -323,11 +466,11 @@ const User: React.FC = () => {
(option?.label ?? '').toLowerCase().includes(input.toLowerCase()) (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
const handleOnSubmit = () => { const handleOnSubmit = () => {
if (isSubmitting) { if (isDrawerSubmitting) {
return return
} }
setIsSubmitting(true) setIsDrawerSubmitting(true)
if (isDrawerEdit) { if (isDrawerEdit) {
void r_sys_user_update({ void r_sys_user_update({
@@ -355,7 +498,7 @@ const User: React.FC = () => {
} }
}) })
.finally(() => { .finally(() => {
setIsSubmitting(false) setIsDrawerSubmitting(false)
}) })
} else { } else {
void r_sys_user_add({ void r_sys_user_add({
@@ -384,7 +527,7 @@ const User: React.FC = () => {
} }
}) })
.finally(() => { .finally(() => {
setIsSubmitting(false) setIsDrawerSubmitting(false)
}) })
} }
} }
@@ -429,7 +572,7 @@ const User: React.FC = () => {
} }
const getUser = () => { const getUser = () => {
if (isLoading) { if (isLoadingUserData) {
return return
} }
@@ -438,7 +581,7 @@ const User: React.FC = () => {
return return
} }
setIsLoading(true) setIsLoadingUserData(true)
void r_sys_user_get() void r_sys_user_get()
.then((res) => { .then((res) => {
@@ -460,7 +603,7 @@ const User: React.FC = () => {
} }
}) })
.finally(() => { .finally(() => {
setIsLoading(false) setIsLoadingUserData(false)
}) })
} }
@@ -526,10 +669,10 @@ const User: React.FC = () => {
useEffect(() => { useEffect(() => {
form.validateFields({ validateOnly: true }).then( form.validateFields({ validateOnly: true }).then(
() => { () => {
setSubmittable(true) setIsDrawerSubmittable(true)
}, },
() => { () => {
setSubmittable(false) setIsDrawerSubmittable(false)
} }
) )
@@ -564,8 +707,19 @@ const User: React.FC = () => {
]) ])
const addAndEditForm = ( const addAndEditForm = (
<AntdForm form={form} disabled={isSubmitting}> <AntdForm
<div style={{ display: 'flex', justifyContent: 'center', marginBottom: '20px' }}> form={form}
disabled={isDrawerSubmitting}
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
>
<div
style={{
display: 'flex',
justifyContent: 'center',
marginBottom: 20
}}
>
<AntdTooltip title={'点击获取新头像'}> <AntdTooltip title={'点击获取新头像'}>
<AntdAvatar <AntdAvatar
src={ src={
@@ -577,7 +731,7 @@ const User: React.FC = () => {
/> />
} }
size={100} size={100}
style={{ background: COLOR_BACKGROUND }} style={{ background: COLOR_BACKGROUND, cursor: 'pointer' }}
onClick={getAvatar} onClick={getAvatar}
/> />
</AntdTooltip> </AntdTooltip>
@@ -646,7 +800,7 @@ const User: React.FC = () => {
valuePropName={'checked'} valuePropName={'checked'}
name={'locking'} name={'locking'}
label={'锁定'} label={'锁定'}
rules={[{ required: true, type: 'boolean' }]} rules={[{ type: 'boolean' }]}
> >
<AntdSwitch /> <AntdSwitch />
</AntdForm.Item> </AntdForm.Item>
@@ -684,7 +838,7 @@ const User: React.FC = () => {
valuePropName={'checked'} valuePropName={'checked'}
name={'enable'} name={'enable'}
label={'启用'} label={'启用'}
rules={[{ required: true, type: 'boolean' }]} rules={[{ type: 'boolean' }]}
> >
<AntdSwitch /> <AntdSwitch />
</AntdForm.Item> </AntdForm.Item>
@@ -756,7 +910,7 @@ const User: React.FC = () => {
columns={dataColumns} columns={dataColumns}
rowKey={(record) => record.id} rowKey={(record) => record.id}
pagination={tableParams.pagination} pagination={tableParams.pagination}
loading={isLoading} loading={isLoadingUserData}
onChange={handleOnTableChange} onChange={handleOnTableChange}
rowSelection={{ rowSelection={{
type: 'checkbox', type: 'checkbox',
@@ -769,17 +923,17 @@ const User: React.FC = () => {
const drawerToolbar = ( const drawerToolbar = (
<AntdSpace> <AntdSpace>
<AntdTooltip title={'刷新角色和用户组列表'}> <AntdTooltip title={'刷新角色和用户组列表'}>
<AntdButton onClick={handleOnDrawerRefresh} disabled={isSubmitting}> <AntdButton onClick={handleOnDrawerRefresh} disabled={isDrawerSubmitting}>
<Icon component={IconFatwebRefresh} /> <Icon component={IconFatwebRefresh} />
</AntdButton> </AntdButton>
</AntdTooltip> </AntdTooltip>
<AntdButton onClick={handleOnDrawerClose} disabled={isSubmitting}> <AntdButton onClick={handleOnDrawerClose} disabled={isDrawerSubmitting}>
</AntdButton> </AntdButton>
<AntdButton <AntdButton
type={'primary'} type={'primary'}
disabled={!submittable} disabled={!isDrawerSubmittable}
loading={isSubmitting} loading={isDrawerSubmitting}
onClick={handleOnSubmit} onClick={handleOnSubmit}
> >
@@ -806,8 +960,8 @@ const User: React.FC = () => {
width={'36vw'} width={'36vw'}
onClose={handleOnDrawerClose} onClose={handleOnDrawerClose}
open={isDrawerOpen} open={isDrawerOpen}
closable={!isSubmitting} closable={!isDrawerSubmitting}
maskClosable={!isSubmitting} maskClosable={!isDrawerSubmitting}
extra={drawerToolbar} extra={drawerToolbar}
> >
{addAndEditForm} {addAndEditForm}

View File

@@ -15,10 +15,12 @@ export const r_sys_user_info = () => request.get<UserWithPowerInfoVo>(URL_SYS_US
export const r_sys_user_get = () => request.get<PageVo<UserWithRoleInfoVo>>(URL_SYS_USER) export const r_sys_user_get = () => request.get<PageVo<UserWithRoleInfoVo>>(URL_SYS_USER)
export const r_sys_user_add = (param: UserAddEditParam) => request.post(URL_SYS_USER, { ...param }) export const r_sys_user_add = (param: UserAddEditParam) => request.post(URL_SYS_USER, param)
export const r_sys_user_update = (param: UserAddEditParam) => export const r_sys_user_update = (param: UserAddEditParam) => request.put(URL_SYS_USER, param)
request.put(URL_SYS_USER, { ...param })
export const r_sys_user_change_password = (param: UserChangePasswordParam) =>
request.patch(URL_SYS_USER, param)
export const r_sys_user_delete = (id: string) => request.delete(`${URL_SYS_USER}/${id}`) export const r_sys_user_delete = (id: string) => request.delete(`${URL_SYS_USER}/${id}`)
@@ -27,39 +29,36 @@ export const r_sys_user_delete_list = (ids: React.Key[]) => request.delete(URL_S
export const r_sys_power_get_list = () => request.get<PowerSetVo>(URL_SYS_POWER_LIST) export const r_sys_power_get_list = () => request.get<PowerSetVo>(URL_SYS_POWER_LIST)
export const r_sys_role_get = (param: RoleGetParam) => export const r_sys_role_get = (param: RoleGetParam) =>
request.get<PageVo<RoleWithPowerGetVo>>(URL_SYS_ROLE, { ...param }) request.get<PageVo<RoleWithPowerGetVo>>(URL_SYS_ROLE, param)
export const r_sys_role_get_list = () => request.get<RoleVo[]>(URL_SYS_ROLE_LIST) export const r_sys_role_get_list = () => request.get<RoleVo[]>(URL_SYS_ROLE_LIST)
export const r_sys_role_change_status = (param: RoleChangeStatusParam) => export const r_sys_role_change_status = (param: RoleChangeStatusParam) =>
request.patch<never>(URL_SYS_ROLE, { ...param }) request.patch<never>(URL_SYS_ROLE, param)
export const r_sys_role_add = (param: RoleAddEditParam) => request.post(URL_SYS_ROLE, { ...param }) export const r_sys_role_add = (param: RoleAddEditParam) => request.post(URL_SYS_ROLE, param)
export const r_sys_role_update = (param: RoleAddEditParam) => export const r_sys_role_update = (param: RoleAddEditParam) => request.put(URL_SYS_ROLE, param)
request.put(URL_SYS_ROLE, { ...param })
export const r_sys_role_delete = (id: string) => request.delete(`${URL_SYS_ROLE}/${id}`) export const r_sys_role_delete = (id: string) => request.delete(`${URL_SYS_ROLE}/${id}`)
export const r_sys_role_delete_list = (ids: React.Key[]) => request.delete(URL_SYS_ROLE, { ids }) export const r_sys_role_delete_list = (ids: React.Key[]) => request.delete(URL_SYS_ROLE, { ids })
export const r_sys_group_get = (param: GroupGetParam) => export const r_sys_group_get = (param: GroupGetParam) =>
request.get<PageVo<GroupWithRoleGetVo>>(URL_SYS_GROUP, { ...param }) request.get<PageVo<GroupWithRoleGetVo>>(URL_SYS_GROUP, param)
export const r_sys_group_get_list = () => request.get<GroupVo[]>(URL_SYS_GROUP_LIST) export const r_sys_group_get_list = () => request.get<GroupVo[]>(URL_SYS_GROUP_LIST)
export const r_sys_group_change_status = (param: GroupChangeStatusParam) => export const r_sys_group_change_status = (param: GroupChangeStatusParam) =>
request.patch<never>(URL_SYS_GROUP, { ...param }) request.patch<never>(URL_SYS_GROUP, param)
export const r_sys_group_add = (param: GroupAddEditParam) => export const r_sys_group_add = (param: GroupAddEditParam) => request.post(URL_SYS_GROUP, param)
request.post(URL_SYS_GROUP, { ...param })
export const r_sys_group_update = (param: GroupAddEditParam) => export const r_sys_group_update = (param: GroupAddEditParam) => request.put(URL_SYS_GROUP, param)
request.put(URL_SYS_GROUP, { ...param })
export const r_sys_group_delete = (id: string) => request.delete(`${URL_SYS_GROUP}/${id}`) export const r_sys_group_delete = (id: string) => request.delete(`${URL_SYS_GROUP}/${id}`)
export const r_sys_group_delete_list = (ids: React.Key[]) => request.delete(URL_SYS_GROUP, { ids }) export const r_sys_group_delete_list = (ids: React.Key[]) => request.delete(URL_SYS_GROUP, { ids })
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)

View File

@@ -145,6 +145,14 @@ export const getRedirectUrl = (path: string, redirectUrl: string): string => {
return `${path}?redirect=${encodeURIComponent(redirectUrl)}` return `${path}?redirect=${encodeURIComponent(redirectUrl)}`
} }
export const getNowLocalTime = (format: string = 'yyyy-MM-DD HH:mm:ssZ') => {
return moment().local().format(format)
}
export const getNowUtc = () => {
return moment().toISOString()
}
export const utcToLocalTime = (utcTime: string, format: string = 'yyyy-MM-DD HH:mm:ssZ') => { export const utcToLocalTime = (utcTime: string, format: string = 'yyyy-MM-DD HH:mm:ssZ') => {
return moment.utc(utcTime).local().format(format) return moment.utc(utcTime).local().format(format)
} }