dark
2 months ago
7 changed files with 408 additions and 221 deletions
-
1package.json
-
139src/components/captcha/SlideCapt.tsx
-
2src/components/captcha/index.ts
-
18src/components/captcha/style.ts
-
6src/components/captcha/types.ts
-
214src/pages/use/login/index.tsx
-
53src/service/system.ts
@ -0,0 +1,139 @@ |
|||||
|
import React, { memo, useCallback, useEffect, useState } from 'react' |
||||
|
import { Popover, message } from 'antd' |
||||
|
import GoCaptcha from 'go-captcha-react' |
||||
|
import { SlideCaptchaCheckData } from './types.ts' |
||||
|
import { SlideData, SlidePoint } from 'go-captcha-react/dist/components/Slide/meta/data' |
||||
|
import { SlideConfig } from 'go-captcha-react/dist/components/Slide/meta/config' |
||||
|
import { Props } from 'go-captcha-react/dist/components/Button' |
||||
|
import { useStyle } from './style.ts' |
||||
|
|
||||
|
export interface SlideCaptProps { |
||||
|
api: { |
||||
|
getCaptcha: () => Promise<any>, |
||||
|
checkCaptcha: (params: SlideCaptchaCheckData) => Promise<any>, |
||||
|
}, |
||||
|
config?: SlideConfig |
||||
|
value?: string |
||||
|
onChange?: (value?: string) => void |
||||
|
} |
||||
|
|
||||
|
const SlideCapt = ({ config, api, value, onChange }: SlideCaptProps) => { |
||||
|
|
||||
|
const { styles } = useStyle() |
||||
|
const [ open, setOpen ] = useState(false) |
||||
|
const [ state, setState ] = useState<Props>({}) |
||||
|
const [ data, setData ] = useState<SlideData>() |
||||
|
const [ innerKey, setKey ] = useState(value) |
||||
|
|
||||
|
const fetchCaptcha = useCallback(() => { |
||||
|
|
||||
|
return api.getCaptcha().then(res => { |
||||
|
if (res.code === 0) { |
||||
|
const data = res.data |
||||
|
setKey(data['captcha_key'] || '') |
||||
|
setData({ |
||||
|
image: data['image_base64'] || '', |
||||
|
thumb: data['tile_base64'] || '', |
||||
|
thumbX: data['tile_x'] || 0, |
||||
|
thumbY: data['tile_y'] || 0, |
||||
|
thumbWidth: data['tile_width'] || 0, |
||||
|
thumbHeight: data['tile_height'] || 0, |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
}) |
||||
|
|
||||
|
|
||||
|
}, [ api.getCaptcha, setData ]) |
||||
|
|
||||
|
const refresh = useCallback(() => { |
||||
|
fetchCaptcha() |
||||
|
}, [ fetchCaptcha ]) |
||||
|
|
||||
|
const confirm = useCallback((point: SlidePoint, clear: (fn?: any) => void) => { |
||||
|
|
||||
|
api.checkCaptcha({ |
||||
|
point: [ point.x, point.y ].join(','), |
||||
|
key: innerKey! |
||||
|
}).then(res => { |
||||
|
// console.log(res)
|
||||
|
if (res.code === 0 && res.data.is_ok) { |
||||
|
message.success(`验证成功`) |
||||
|
|
||||
|
//验证成功,onChange通知出去,外部需要key做为校验
|
||||
|
onChange?.(innerKey) |
||||
|
|
||||
|
setState(prevState => ({ |
||||
|
...prevState, type: 'success', title: '校验成功', |
||||
|
})) |
||||
|
setOpen(false) |
||||
|
} else { |
||||
|
message.error('验证失败') |
||||
|
setState(prevState => ({ |
||||
|
...prevState, type: 'error', title: '点击进行校验', |
||||
|
})) |
||||
|
} |
||||
|
setTimeout(() => { |
||||
|
clear() |
||||
|
fetchCaptcha() |
||||
|
}, 1000) |
||||
|
|
||||
|
}).catch(() => { |
||||
|
setTimeout(() => { |
||||
|
clear() |
||||
|
fetchCaptcha() |
||||
|
}, 1000) |
||||
|
}) |
||||
|
|
||||
|
}, [ api.checkCaptcha, setData, state, setState, setOpen, innerKey, fetchCaptcha ]) |
||||
|
|
||||
|
useEffect(() => { |
||||
|
|
||||
|
if (open) { |
||||
|
fetchCaptcha() |
||||
|
} |
||||
|
|
||||
|
}, [ open ]) |
||||
|
|
||||
|
return ( |
||||
|
<div className={styles.container}> |
||||
|
<Popover |
||||
|
content={ |
||||
|
<GoCaptcha.Slide |
||||
|
config={{ |
||||
|
width: 300, |
||||
|
height: 217, |
||||
|
showTheme: false, |
||||
|
verticalPadding: 5, |
||||
|
horizontalPadding: 5, |
||||
|
...config, |
||||
|
}} |
||||
|
style={{ color: 'red' }} |
||||
|
data={data!} |
||||
|
events={{ |
||||
|
refresh, |
||||
|
confirm, |
||||
|
close: () => { |
||||
|
setOpen(false) |
||||
|
} |
||||
|
}} |
||||
|
/> |
||||
|
} |
||||
|
open={open} |
||||
|
onOpenChange={setOpen} |
||||
|
forceRender={true} |
||||
|
trigger="click"> |
||||
|
<GoCaptcha.Button |
||||
|
title={'点击进行校验'} |
||||
|
{...state} |
||||
|
clickEvent={ |
||||
|
() => { |
||||
|
setOpen(true) |
||||
|
} |
||||
|
}/> |
||||
|
</Popover> |
||||
|
</div> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
export default memo(SlideCapt) |
@ -0,0 +1,2 @@ |
|||||
|
|
||||
|
export * from './SlideCapt.tsx' |
@ -0,0 +1,18 @@ |
|||||
|
|
||||
|
import { createStyles } from '@/theme' |
||||
|
|
||||
|
export const useStyle = createStyles(({ token, css, cx, prefixCls }, props: any) => { |
||||
|
const prefix = `${prefixCls}-${token?.proPrefix}-captcha-component` |
||||
|
|
||||
|
const container = css`
|
||||
|
|
||||
|
> div{ |
||||
|
width: 100% !important; |
||||
|
} |
||||
|
|
||||
|
`
|
||||
|
|
||||
|
return { |
||||
|
container: cx(prefix, props?.className, container), |
||||
|
} |
||||
|
}) |
@ -0,0 +1,6 @@ |
|||||
|
|
||||
|
|
||||
|
export interface SlideCaptchaCheckData { |
||||
|
point: string |
||||
|
key: string |
||||
|
} |
@ -1,72 +1,79 @@ |
|||||
import { IPageResult } from "@/global"; |
|
||||
import request from "../request.ts"; |
|
||||
import { createCURD } from "@/service/base.ts"; |
|
||||
import { System } from "@/types"; |
|
||||
|
import { IPageResult } from '@/global' |
||||
|
import request from '../request.ts' |
||||
|
import { createCURD } from '@/service/base.ts' |
||||
|
import { System } from '@/types' |
||||
|
|
||||
const systemServ = { |
const systemServ = { |
||||
dept: { |
dept: { |
||||
...createCURD<any, System.IDepartment>("/sys/dept"), |
|
||||
|
...createCURD<any, System.IDepartment>('/sys/dept'), |
||||
tree: () => { |
tree: () => { |
||||
return request.get<{ tree: System.IDepartment }>("/sys/dept/tree"); |
|
||||
|
return request.get<{ tree: System.IDepartment }>('/sys/dept/tree') |
||||
}, |
}, |
||||
}, |
}, |
||||
menus: { |
menus: { |
||||
...createCURD<any, System.IMenu>("/sys/menu"), |
|
||||
|
...createCURD<any, System.IMenu>('/sys/menu'), |
||||
}, |
}, |
||||
uplogin: (data: any) => { |
uplogin: (data: any) => { |
||||
return request.post<System.LoginResponse>("/sys/login", data); |
|
||||
|
return request.post<System.LoginResponse>('/sys/login', data) |
||||
}, |
}, |
||||
emailCode: (data: any) => { |
emailCode: (data: any) => { |
||||
return request.post<System.LoginResponse>("/sys/email", data); |
|
||||
|
return request.post<System.LoginResponse>('/sys/email', data) |
||||
}, |
}, |
||||
|
|
||||
emailLogin: (data: any) => { |
emailLogin: (data: any) => { |
||||
return request.post<System.LoginResponse>("/sys/email/login", data); |
|
||||
|
return request.post<System.LoginResponse>('/sys/email/login', data) |
||||
}, |
}, |
||||
emailRegister: (data: any) => { |
emailRegister: (data: any) => { |
||||
return request.post<System.LoginResponse>("/sys/email/reg", data); |
|
||||
|
return request.post<System.LoginResponse>('/sys/email/reg', data) |
||||
}, |
}, |
||||
|
|
||||
|
|
||||
telegramCode: (data: any) => { |
telegramCode: (data: any) => { |
||||
return request.post<System.LoginResponse>("/sys/telegram", data); |
|
||||
|
return request.post<System.LoginResponse>('/sys/telegram', data) |
||||
}, |
}, |
||||
|
|
||||
telegramLogin: (data: any) => { |
telegramLogin: (data: any) => { |
||||
return request.post<System.LoginResponse>("/sys/login/telegram", data); |
|
||||
|
return request.post<System.LoginResponse>('/sys/login/telegram', data) |
||||
}, |
}, |
||||
pwdRetrieve: (data: any) => { |
pwdRetrieve: (data: any) => { |
||||
return request.post<System.LoginResponse>("/sys/email/pws", data); |
|
||||
|
return request.post<System.LoginResponse>('/sys/email/pws', data) |
||||
}, |
}, |
||||
|
|
||||
|
//验证码
|
||||
|
captcha: () => { |
||||
|
return request.get('/sys/captcha') |
||||
|
}, |
||||
|
|
||||
|
captchaCheck: (data: any) => { |
||||
|
return request.post('/sys/captcha/check', data) |
||||
|
}, |
||||
|
|
||||
logout: () => { |
logout: () => { |
||||
//
|
//
|
||||
}, |
}, |
||||
user: { |
user: { |
||||
...createCURD<any, System.IUser>("/sys/user"), |
|
||||
|
...createCURD<any, System.IUser>('/sys/user'), |
||||
current: () => { |
current: () => { |
||||
return request.get<System.IUserInfo>("/sys/user/info"); |
|
||||
|
return request.get<System.IUserInfo>('/sys/user/info') |
||||
}, |
}, |
||||
menus: () => { |
menus: () => { |
||||
return request.get<IPageResult<System.IMenu[]>>("/sys/user/menus"); |
|
||||
|
return request.get<IPageResult<System.IMenu[]>>('/sys/user/menus') |
||||
}, |
}, |
||||
resetPassword: (id: number) => { |
resetPassword: (id: number) => { |
||||
return request.post<any>(`/sys/user/reset/password`, { id }); |
|
||||
|
return request.post<any>(`/sys/user/reset/password`, { id }) |
||||
}, |
}, |
||||
}, |
}, |
||||
role: { |
role: { |
||||
...createCURD<any, System.IRole>("/sys/role"), |
|
||||
|
...createCURD<any, System.IRole>('/sys/role'), |
||||
}, |
}, |
||||
logs: { |
logs: { |
||||
login: { |
login: { |
||||
...createCURD<any, ILoginLog>("/sys/log/login"), |
|
||||
|
...createCURD<any, ILoginLog>('/sys/log/login'), |
||||
clear: (params: { start: string; end: string }) => { |
clear: (params: { start: string; end: string }) => { |
||||
return request.post<any>("/sys/log/login/clear", params); |
|
||||
|
return request.post<any>('/sys/log/login/clear', params) |
||||
}, |
}, |
||||
}, |
}, |
||||
}, |
}, |
||||
}; |
|
||||
|
} |
||||
|
|
||||
export default systemServ; |
|
||||
|
export default systemServ |
Write
Preview
Loading…
Cancel
Save
Reference in new issue