diff --git a/frontend/src/assets/login/email.png b/frontend/src/assets/login/email.png
new file mode 100644
index 0000000..b61d780
Binary files /dev/null and b/frontend/src/assets/login/email.png differ
diff --git a/frontend/src/assets/login/login.png b/frontend/src/assets/login/login.png
new file mode 100644
index 0000000..6b5509f
Binary files /dev/null and b/frontend/src/assets/login/login.png differ
diff --git a/frontend/src/components/desktop/LockDesktop.vue b/frontend/src/components/desktop/LockDesktop.vue
index 890fec8..ad289d1 100644
--- a/frontend/src/components/desktop/LockDesktop.vue
+++ b/frontend/src/components/desktop/LockDesktop.vue
@@ -48,7 +48,7 @@
返回
@@ -157,10 +157,7 @@
- 返回
+ 返回
@@ -175,10 +172,7 @@
- 返回
+ 返回
@@ -186,21 +180,26 @@
-
-
+
+
-
-
+
@@ -208,7 +207,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 返回
+
+ 登录
+
+
+
+
+
+
+
+
+
+
+
+
+
+
返回
+
+
+ 登录
@@ -246,7 +327,7 @@
import router from "@/system/router";
import { RestartApp } from "@/util/goutil";
import { notifyError } from "@/util/msg";
- import { onMounted, ref, watchEffect } from "vue";
+ import { computed, onMounted, ref, watchEffect } from "vue";
import { useRoute } from "vue-router";
const route = useRoute();
const store = useLoginStore();
@@ -255,11 +336,31 @@
const config = getSystemConfig();
const lockClassName = ref("screen-show");
+ const backToLogin = () => {
+ store.ThirdPartyLoginMethod = "login";
+ localStorage.removeItem("ThirdPartyPlatform");
+ };
+
const phoneForm = ref({
phone: "",
code: "",
});
+ const emailForm = ref({
+ email: "",
+ code: "",
+ });
+
+ const thirdpartyCode = ref("");
+
+ const validateAndLoginByThirdparty = () => {
+ if (thirdpartyCode.value === "") {
+ notifyError("请输入第三方登录码");
+ return;
+ }
+ onLogin(thirdpartyCode.value);
+ };
+
// 声明 DTFrameLogin 和 WwLogin 方法
declare global {
interface Window {
@@ -303,8 +404,8 @@
state?: string; // 登录成功后获取到的state
}
- onMounted(() => {
- getThirdpartyList();
+ onMounted(async () => {
+ await getThirdpartyList();
});
const getThirdpartyList = async () => {
@@ -312,10 +413,20 @@
config.userInfo.url + "/user/thirdparty/list"
);
if (result.ok) {
- await result.json();
+ const data = await result.json();
+ store.thirdpartyList = data.data.list;
+ console.log(data);
+ }
+ };
+
+ const isPlatformAvailable = (platform: string) => {
+ for (let i = 0; i < store.thirdpartyList.length; i++) {
+ if (store.thirdpartyList[i] === platform) {
+ return true;
+ }
}
+ return false;
};
-
const onDingDingScan = () => {
store.ThirdPartyLoginMethod = "dingding";
@@ -375,9 +486,34 @@
const sendCodeButtonText = ref("发送验证码");
const isSendCodeButtonDisabled = ref(false);
- const onSendCode = () => {
- console.log("发送验证码");
- startCountdown();
+ const onSendCode = async () => {
+ try {
+ const response = await fetch(
+ config.userInfo.url + "/user/emailcode",
+ {
+ method: "POST",
+ body: JSON.stringify({ email: emailForm.value.email }),
+ }
+ );
+
+ console.log(response);
+
+ if (!response.ok) {
+ notifyError("发送验证码失败,请重试");
+ return;
+ }
+
+ const result = await response.json();
+ if (result.success) {
+ console.log("验证码发送成功");
+ startEmailCountdown();
+ } else {
+ notifyError(result.message || "发送验证码失败,请重试");
+ }
+ } catch (error) {
+ console.error("发送验证码时发生错误", error);
+ notifyError("发送验证码时发生错误,请重试");
+ }
};
const startCountdown = () => {
@@ -397,6 +533,26 @@
}, 1000);
};
+ const sendEmailCodeButtonText = ref("发送验证码");
+ const isSendEmailCodeButtonDisabled = ref(false);
+
+ const startEmailCountdown = () => {
+ let countdown = 2;
+ isSendEmailCodeButtonDisabled.value = true;
+ sendEmailCodeButtonText.value = `${countdown}秒后重试`;
+
+ const interval = setInterval(() => {
+ countdown--;
+ if (countdown > 0) {
+ sendEmailCodeButtonText.value = `${countdown}秒后重试`;
+ } else {
+ clearInterval(interval);
+ sendEmailCodeButtonText.value = "发送验证码";
+ isSendEmailCodeButtonDisabled.value = false;
+ }
+ }, 1000);
+ };
+
const thirdPartyPlatforms = [
{
name: "qyweixin",
@@ -418,8 +574,22 @@
name: "gitee",
icon: new URL("@/assets/login/gitee.png", import.meta.url).href,
},
+ {
+ name: "email",
+ icon: new URL("@/assets/login/email.png", import.meta.url).href,
+ },
+ {
+ name: "thirdparty",
+ icon: new URL("@/assets/login/login.png", import.meta.url).href,
+ },
];
+ const availablePlatforms = computed(() => {
+ return thirdPartyPlatforms.filter((platform) =>
+ isPlatformAvailable(platform.name)
+ );
+ });
+
function loginSuccess() {
lockClassName.value = "screen-hidean";
setTimeout(() => {
@@ -436,7 +606,7 @@
userPassword.value = sys._options.login?.password || "";
} else {
userName.value = config.userInfo.username;
- userPassword.value = config.userInfo.password;
+ // userPassword.value = config.userInfo.password;
}
});
@@ -463,8 +633,9 @@
qq: "qq",
dingding: "dingtalk_scan",
phone: "sms_code",
+ email: "email",
+ thirdparty: "third_api",
};
-
// 获取对应的参数名称
const codeParam = platform ? platformCodeMap[platform] : null;
@@ -472,12 +643,27 @@
let param;
if (codeParam) {
if (platform === "phone") {
- param = { phone: phoneForm.value.phone, sms_code: code };
+ param = {
+ phone: phoneForm.value.phone,
+ sms_code: phoneForm.value.code,
+ };
+ } else if (platform === "email") {
+ param = {
+ email: emailForm.value.email,
+ code: emailForm.value.code,
+ };
+ } else if (platform === "thirdparty") {
+ param = {
+ unionid: thirdpartyCode.value,
+ };
} else {
param = { code: code };
}
} else {
- param = { username: userName.value, password: userPassword.value };
+ param = {
+ username: userName.value,
+ password: userPassword.value,
+ };
}
const login_type = codeParam ? codeParam : "password";
@@ -488,7 +674,7 @@
localStorage.removeItem("ThirdPartyPlatform");
loginSuccess();
} else {
- notifyError("登录失败,请重试");
+ console.log("登录失败");
}
}
}
@@ -510,6 +696,11 @@
message: "用户名长度应在3到20个字符之间",
trigger: "blur",
},
+ {
+ pattern: /^[a-zA-Z0-9]+$/,
+ message: "用户名只能包含英文和数字",
+ trigger: "blur",
+ },
],
password: [
{ required: true, message: "密码不能为空", trigger: "blur" },
@@ -635,6 +826,16 @@
return await authWithPhone();
};
break;
+ case "email":
+ loginFunction = async function () {
+ return await authWithEmail();
+ };
+ break;
+ case "thirdparty":
+ loginFunction = async function () {
+ return await authWithThirdParty();
+ };
+ break;
default:
notifyError("不支持的第三方登录平台");
return;
@@ -648,13 +849,14 @@
}
};
- const authWithPhone = async (): Promise => {
- store.ThirdPartyLoginMethod = "phone";
+ const authWithThirdParty = async (): Promise => {
+ store.ThirdPartyLoginMethod = "thirdparty";
return true;
};
- const loginByPhone = async () => {
- await onLogin();
+ const authWithPhone = async (): Promise => {
+ store.ThirdPartyLoginMethod = "phone";
+ return true;
};
const authWithDingDing = async (): Promise => {
@@ -762,6 +964,41 @@
// store.page = "phone";
// return true;
};
+
+ const authWithEmail = async (): Promise => {
+ store.ThirdPartyLoginMethod = "email";
+ return true;
+ };
+
+ const loginByEmail = async () => {
+ await onLogin();
+ };
+
+ const phoneLoginFormRef: any = ref(null);
+
+ const phoneLoginRules = {
+ phone: [
+ { required: true, message: "手机号不能为空", trigger: "blur" },
+ {
+ pattern: /^\d{11}$/,
+ message: "手机号格式不正确,必须为11位有效数字",
+ trigger: "blur",
+ },
+ ],
+ code: [
+ { required: true, message: "验证码不能为空", trigger: "blur" },
+ {
+ pattern: /^\d{4,6}$/,
+ message: "验证码必须为4到6位数字",
+ trigger: "blur",
+ },
+ ],
+ };
+
+ const validateAndLoginByPhone = async () => {
+ await phoneLoginFormRef.value.validate();
+ onLogin();
+ };