From 431e690f022014a4c0f0a650569d12587b990f5d Mon Sep 17 00:00:00 2001 From: landaiqing <3517283258@qq.com> Date: Mon, 12 Aug 2024 22:24:16 +0800 Subject: [PATCH] :sparkles: add rotate captcha --- components.d.ts | 4 -- index.html | 20 +++---- package.json | 1 + public/schisandra.svg | 77 +++++++++++++++++++++++++++ public/vite.svg | 1 - src/api/captcha/index.ts | 23 +++++++++ src/locales/language/en.ts | 5 ++ src/locales/language/zh.ts | 6 +++ src/main.ts | 3 ++ src/store/modules/themeStore.ts | 6 +-- src/utils/alova/service.ts | 8 +-- src/views/Login/LoginFooter.vue | 2 +- src/views/Login/LoginPage.vue | 92 +++++++++++++++++++++++++++++---- src/views/Login/index.scss | 18 +++++++ src/views/QRLogin/QRLogin.vue | 2 +- src/views/TestI18n.vue | 12 ++++- src/views/TestTheme.vue | 6 ++- yarn.lock | 9 +++- 18 files changed, 257 insertions(+), 38 deletions(-) create mode 100644 public/schisandra.svg delete mode 100644 public/vite.svg create mode 100644 src/api/captcha/index.ts diff --git a/components.d.ts b/components.d.ts index 4774356..e8fbc45 100644 --- a/components.d.ts +++ b/components.d.ts @@ -28,7 +28,6 @@ declare module 'vue' { ATooltip: typeof import('ant-design-vue/es')['Tooltip'] BoxDog: typeof import('./src/components/BoxDog/BoxDog.vue')['default'] DynamicTitle: typeof import('./src/components/DynamicTitle/DynamicTitle.vue')['default'] - FoegetPage: typeof import('./src/views/Forget/FoegetPage.vue')['default'] ForgetPage: typeof import('./src/views/Forget/ForgetPage.vue')['default'] LockOutlined: typeof import('@ant-design/icons-vue')['LockOutlined'] LoginFooter: typeof import('./src/views/Login/LoginFooter.vue')['default'] @@ -36,15 +35,12 @@ declare module 'vue' { NotFound: typeof import('./src/views/404/NotFound.vue')['default'] QRLogin: typeof import('./src/views/QRLogin/QRLogin.vue')['default'] QRLoginFooter: typeof import('./src/views/QRLogin/QRLoginFooter.vue')['default'] - RegisterFooter: typeof import('./src/views/Register/RegisterFooter.vue')['default'] - RegisterPage: typeof import('./src/views/Register/RegisterPage.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] SafetyOutlined: typeof import('@ant-design/icons-vue')['SafetyOutlined'] TabletOutlined: typeof import('@ant-design/icons-vue')['TabletOutlined'] TestI18n: typeof import('./src/views/TestI18n.vue')['default'] TestTheme: typeof import('./src/views/TestTheme.vue')['default'] - TotoroCom: typeof import('./src/components/Totoro/TotoroCom.vue')['default'] UserOutlined: typeof import('@ant-design/icons-vue')['UserOutlined'] } } diff --git a/index.html b/index.html index d5ace2b..61f9d56 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,13 @@ - - - - - <%- title %> - - -
- - + + + + + <%- title %> + + +
+ + diff --git a/package.json b/package.json index 7bc1bf6..80fb778 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "axios": "^1.7.3", "crypto-js": "^4.2.0", "eslint": "9.9.0", + "go-captcha-vue": "^2", "json-stringify-safe": "^5.0.1", "less": "^4.2.0", "localforage": "^1.10.0", diff --git a/public/schisandra.svg b/public/schisandra.svg new file mode 100644 index 0000000..089d7a9 --- /dev/null +++ b/public/schisandra.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/vite.svg b/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/api/captcha/index.ts b/src/api/captcha/index.ts new file mode 100644 index 0000000..18377e8 --- /dev/null +++ b/src/api/captcha/index.ts @@ -0,0 +1,23 @@ +import {service} from "@/utils/alova/service.ts"; + +export const getRotatedCaptchaData = () => { + return service.Get('/api/captcha/rotate/get', { + meta: { + ignoreToken: true + }, + }); + +}; +export const checkRotatedCaptcha = (angle: any, key: any) => { + return service.Post('/api/captcha/rotate/check', { + angle: angle, + key: key, + }, + { + meta: { + ignoreToken: true + }, + } + ); + +}; diff --git a/src/locales/language/en.ts b/src/locales/language/en.ts index d1f9b59..e9b7890 100644 --- a/src/locales/language/en.ts +++ b/src/locales/language/en.ts @@ -29,6 +29,11 @@ export default { repasswordValidate: "please enter the confirmation password", forgetPassword: "forget password", resetPassword: "reset password", + captchaSuccess: "captcha success!", + captchaError: "captcha failed!", + rotateCaptchaTitle: "Please drag the slider to complete the puzzle", + systemError: "System error, please try again later", + captchaExpired: "captcha expired, please try again", }, error: { networkError: 'Network error, please try again later', diff --git a/src/locales/language/zh.ts b/src/locales/language/zh.ts index c1c8825..72927b4 100644 --- a/src/locales/language/zh.ts +++ b/src/locales/language/zh.ts @@ -29,6 +29,12 @@ export default { repasswordValidate: "请输入确认密码", forgetPassword: "忘记密码", resetPassword: "重置密码", + captchaSuccess: "验证成功!", + captchaError: "验证失败!", + rotateCaptchaTitle: "请拖动滑块完成拼图", + systemError: "系统错误!请稍后再试!", + captchaExpired: "验证码已过期,请重新获取!", + }, error: { networkError: '网络连接失败!', diff --git a/src/main.ts b/src/main.ts index 28c684e..f097f06 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,9 +5,12 @@ import '@/assets/styles/global.scss'; import i18n from "@/locales/index.ts"; import {setupStore} from "@/store/pinia.ts"; import router from "@/router/router.ts"; +import "go-captcha-vue/dist/style.css" +import GoCaptcha from "go-captcha-vue" const app = createApp(App); setupStore(app); app.use(router); app.use(i18n); +app.use(GoCaptcha) app.mount('#app'); diff --git a/src/store/modules/themeStore.ts b/src/store/modules/themeStore.ts index b4edcbf..8b3ee55 100644 --- a/src/store/modules/themeStore.ts +++ b/src/store/modules/themeStore.ts @@ -5,13 +5,13 @@ import variables from '@/assets/styles/colors.module.scss'; import {parse, stringify} from "zipson/lib"; /** - * theme 配置 开启持久化 + * theme 配置 */ export const useThemeStore = defineStore( 'theme', () => { - const themeName = ref('green'); // 主题名称 - const darkMode = ref('light'); // 颜色模式 + const themeName = ref('green'); // 主题名称 + const darkMode = ref('light'); // 颜色模式 const darkModeComp = computed(() => { document.documentElement.setAttribute('data-dark', darkMode.value); return darkMode.value; diff --git a/src/utils/alova/service.ts b/src/utils/alova/service.ts index 12a0507..d25062d 100644 --- a/src/utils/alova/service.ts +++ b/src/utils/alova/service.ts @@ -17,10 +17,10 @@ export const service = createAlova({ requestAdapter: axiosRequestAdapter(), l2Cache: localforageStorageAdapter, cacheFor: { - GET: { - mode: 'restore', - expire: 10 * 1000 - }, + // GET: { + // mode: 'restore', + // expire: 10 * 1000 + // }, }, cacheLogger: import.meta.env.VITE_NODE_ENV === 'development', // 设置全局的请求拦截器 diff --git a/src/views/Login/LoginFooter.vue b/src/views/Login/LoginFooter.vue index eb9bb92..54bde68 100644 --- a/src/views/Login/LoginFooter.vue +++ b/src/views/Login/LoginFooter.vue @@ -15,7 +15,7 @@ import {GithubOutlined, QqOutlined, QrcodeOutlined} from "@ant-design/icons-vue"; import {useI18n} from "vue-i18n"; import {h} from "vue"; -import {useRouter} from 'vue-router' +import {useRouter} from 'vue-router'; const router = useRouter(); const {t} = useI18n(); diff --git a/src/views/Login/LoginPage.vue b/src/views/Login/LoginPage.vue index a3426a9..25ee0ab 100644 --- a/src/views/Login/LoginPage.vue +++ b/src/views/Login/LoginPage.vue @@ -33,7 +33,8 @@ - + @@ -126,6 +127,18 @@ +
+ + +
diff --git a/src/views/TestTheme.vue b/src/views/TestTheme.vue index 25b709d..213149a 100644 --- a/src/views/TestTheme.vue +++ b/src/views/TestTheme.vue @@ -17,6 +17,10 @@
test
+ 获取验证码 + @@ -25,10 +29,8 @@ import variables from "@/assets/styles/colors.module.scss"; import useStore from "@/store/index.ts"; - const app = useStore().theme; -