提交 25bf8bff authored 作者: 詹银鑫's avatar 詹银鑫

feat: 添加验证码功能和接口联调

上级 84db1843
...@@ -6,6 +6,11 @@ export const getLogin = (data?: object) => { ...@@ -6,6 +6,11 @@ export const getLogin = (data?: object) => {
return http.request<LoginResult>("post", "/api/auth/login", { data }); return http.request<LoginResult>("post", "/api/auth/login", { data });
}; };
/** 获取验证码 */
export const getCaptcha = (time?: string) => {
return http.request<CaptchaResult>("get", "/api/auth/captchaNumber/" + time);
};
/** 刷新`token` */ /** 刷新`token` */
export const refreshTokenApi = (data?: object) => { export const refreshTokenApi = (data?: object) => {
return http.request<RefreshTokenResult>("post", "/refresh-token", { data }); return http.request<RefreshTokenResult>("post", "/refresh-token", { data });
...@@ -255,3 +260,9 @@ export type RefreshTokenResult = { ...@@ -255,3 +260,9 @@ export type RefreshTokenResult = {
expires: Date; expires: Date;
}; };
}; };
export type CaptchaResult = {
code: string;
success: boolean;
data: string;
};
import { ref, onMounted } from "vue"; import { ref, onMounted } from "vue";
import { getCaptcha } from "@/api/systems";
import { useUserStoreHook } from "@/store/modules/user";
/** /**
* 绘制图形验证码 * 绘制图形验证码
* @param width - 图形宽度 * @param width - 图形宽度
...@@ -44,16 +45,20 @@ function randomColor(min: number, max: number) { ...@@ -44,16 +45,20 @@ function randomColor(min: number, max: number) {
function draw(dom: HTMLCanvasElement, width: number, height: number) { function draw(dom: HTMLCanvasElement, width: number, height: number) {
let imgCode = ""; let imgCode = "";
let captchaCode = "";
const NUMBER_STRING = "0123456789"; const now = new Date().getTime().toString();
getCaptcha(now).then(res => {
if (res.code === "0") {
captchaCode = res.data;
useUserStoreHook().SET_VERIFYCODE(captchaCode);
useUserStoreHook().SET_CAPTCHATIME(now);
const ctx = dom.getContext("2d"); const ctx = dom.getContext("2d");
if (!ctx) return imgCode; if (!ctx) return imgCode;
ctx.fillStyle = randomColor(180, 230); ctx.fillStyle = randomColor(180, 230);
ctx.fillRect(0, 0, width, height); ctx.fillRect(0, 0, width, height);
for (let i = 0; i < 4; i += 1) { for (let i = 0; i < captchaCode.length; i += 1) {
const text = NUMBER_STRING[randomNum(0, NUMBER_STRING.length)]; // const text = NUMBER_STRING[randomNum(0, NUMBER_STRING.length)];
const text = captchaCode[i];
imgCode += text; imgCode += text;
const fontSize = randomNum(18, 41); const fontSize = randomNum(18, 41);
const deg = randomNum(-30, 30); const deg = randomNum(-30, 30);
...@@ -81,5 +86,9 @@ function draw(dom: HTMLCanvasElement, width: number, height: number) { ...@@ -81,5 +86,9 @@ function draw(dom: HTMLCanvasElement, width: number, height: number) {
ctx.fillStyle = randomColor(150, 200); ctx.fillStyle = randomColor(150, 200);
ctx.fill(); ctx.fill();
} }
return imgCode; return imgCode as string;
} else {
return "";
}
});
} }
...@@ -44,7 +44,9 @@ export const useUserStore = defineStore("pure-user", { ...@@ -44,7 +44,9 @@ export const useUserStore = defineStore("pure-user", {
// 登录页的免登录存储几天,默认7天 // 登录页的免登录存储几天,默认7天
loginDay: 7, loginDay: 7,
token: localStorage.getItem("token") || "", token: localStorage.getItem("token") || "",
refreshToken: localStorage.getItem("refreshToken") || "" refreshToken: localStorage.getItem("refreshToken") || "",
// 拿到验证码的时间戳
captchaTime: ""
}), }),
actions: { actions: {
/** 存储头像 */ /** 存储头像 */
...@@ -83,6 +85,10 @@ export const useUserStore = defineStore("pure-user", { ...@@ -83,6 +85,10 @@ export const useUserStore = defineStore("pure-user", {
SET_LOGINDAY(value: number) { SET_LOGINDAY(value: number) {
this.loginDay = Number(value); this.loginDay = Number(value);
}, },
/** 设置登录时验证码时间戳 */
SET_CAPTCHATIME(value: string) {
this.captchaTime = value;
},
/** 登入 */ /** 登入 */
async loginByUsername(data) { async loginByUsername(data) {
return new Promise<UserResult>((resolve, reject) => { return new Promise<UserResult>((resolve, reject) => {
......
...@@ -49,4 +49,5 @@ export type userType = { ...@@ -49,4 +49,5 @@ export type userType = {
loginDay?: number; loginDay?: number;
token: string; token: string;
refreshToken: string; refreshToken: string;
captchaTime: string;
}; };
...@@ -70,6 +70,7 @@ import Info from "~icons/ri/information-line"; ...@@ -70,6 +70,7 @@ import Info from "~icons/ri/information-line";
import Keyhole from "~icons/ri/shield-keyhole-line"; import Keyhole from "~icons/ri/shield-keyhole-line";
// 引入 token 操作工具函数 // 引入 token 操作工具函数
import { setToken, getToken } from "@/utils/auth"; import { setToken, getToken } from "@/utils/auth";
import { any } from "vue-types";
/** /**
* 定义组件选项 * 定义组件选项
...@@ -127,15 +128,17 @@ const ruleForm = reactive({ ...@@ -127,15 +128,17 @@ const ruleForm = reactive({
const onLogin = async (formEl: FormInstance | undefined) => { const onLogin = async (formEl: FormInstance | undefined) => {
if (!formEl) return; if (!formEl) return;
// 对表单进行验证 // 对表单进行验证
console.log("ruleForm", formEl);
await formEl.validate(valid => { await formEl.validate(valid => {
if (valid) { if (valid) {
// 验证通过,设置加载状态 // 验证通过,设置加载状态
loading.value = true; loading.value = true;
console.log("ruleForm", ruleForm);
useUserStoreHook() useUserStoreHook()
.loginByUsername({ .loginByUsername({
username: ruleForm.username, username: ruleForm.username,
password: MD5(ruleForm.password).toString() password: MD5(ruleForm.password).toString(),
timer: useUserStoreHook().captchaTime,
captcha: ruleForm.verifyCode
}) })
.then(res => { .then(res => {
if (res.status === 200 || res.success) { if (res.status === 200 || res.success) {
...@@ -146,7 +149,6 @@ const onLogin = async (formEl: FormInstance | undefined) => { ...@@ -146,7 +149,6 @@ const onLogin = async (formEl: FormInstance | undefined) => {
expires: res.data.expires expires: res.data.expires
// expires: new Date(Date.now() + 9999999 * 1000) // expires: new Date(Date.now() + 9999999 * 1000)
}); });
console.log("getToken", getToken);
// 初始化路由 // 初始化路由
return initRouter().then(() => { return initRouter().then(() => {
disabled.value = true; disabled.value = true;
...@@ -314,7 +316,7 @@ watch(loginDay, value => { ...@@ -314,7 +316,7 @@ watch(loginDay, value => {
</Motion> </Motion>
<!-- 注释掉的验证码输入项 --> <!-- 注释掉的验证码输入项 -->
<!-- <Motion :delay="200"> <Motion :delay="200">
<el-form-item prop="verifyCode"> <el-form-item prop="verifyCode">
<el-input <el-input
v-model="ruleForm.verifyCode" v-model="ruleForm.verifyCode"
...@@ -327,7 +329,7 @@ watch(loginDay, value => { ...@@ -327,7 +329,7 @@ watch(loginDay, value => {
</template> </template>
</el-input> </el-input>
</el-form-item> </el-form-item>
</Motion> --> </Motion>
<!-- 记住登录和忘记密码区域 --> <!-- 记住登录和忘记密码区域 -->
<Motion :delay="250"> <Motion :delay="250">
......
...@@ -51,6 +51,11 @@ const loginRules = reactive<FormRules>({ ...@@ -51,6 +51,11 @@ const loginRules = reactive<FormRules>({
* @param callback - 验证回调函数,用于返回验证结果 * @param callback - 验证回调函数,用于返回验证结果
*/ */
validator: (rule, value, callback) => { validator: (rule, value, callback) => {
console.log("value", value);
console.log(
"useUserStoreHook().verifyCode",
useUserStoreHook().verifyCode
);
if (value === "") { if (value === "") {
// 验证码为空时,返回错误信息 // 验证码为空时,返回错误信息
callback(new Error(transformI18n($t("login.pureVerifyCodeReg")))); callback(new Error(transformI18n($t("login.pureVerifyCodeReg"))));
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论