Browse Source

Merge branch 'master' of https://gitee.com/godoos/godoos

master
godo 5 months ago
parent
commit
aae305b43d
  1. BIN
      frontend/src/assets/login/email.png
  2. BIN
      frontend/src/assets/login/login.png
  3. 305
      frontend/src/components/desktop/LockDesktop.vue
  4. 3
      frontend/src/stores/login.ts
  5. 8
      frontend/src/system/dinglogin.ts
  6. 14
      frontend/src/system/index.ts
  7. 3
      frontend/src/system/qiyeweixinlogin.ts
  8. 62
      frontend/src/system/third_login.ts
  9. 2
      go.mod
  10. 1
      go.sum

BIN
frontend/src/assets/login/email.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
frontend/src/assets/login/login.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

305
frontend/src/components/desktop/LockDesktop.vue

@ -48,7 +48,7 @@
</div>
<div class="third-party-login">
<img
v-for="platform in thirdPartyPlatforms"
v-for="platform in availablePlatforms"
:key="platform.name"
:src="platform.icon"
:alt="platform.name"
@ -141,7 +141,7 @@
<el-form-item>
<el-button
style="background-color: gray; color: white"
@click="store.ThirdPartyLoginMethod = 'login'"
@click="backToLogin"
>返回</el-button
>
</el-form-item>
@ -157,10 +157,7 @@
</el-row>
<el-row>
<el-col :span="24">
<el-button
@click="store.ThirdPartyLoginMethod = 'login'"
>返回</el-button
>
<el-button @click="backToLogin">返回</el-button>
</el-col>
</el-row>
</div>
@ -175,10 +172,7 @@
</el-row>
<el-row>
<el-col :span="24">
<el-button
@click="store.ThirdPartyLoginMethod = 'login'"
>返回</el-button
>
<el-button @click="backToLogin">返回</el-button>
</el-col>
</el-row>
</div>
@ -186,21 +180,26 @@
<div v-else-if="store.ThirdPartyLoginMethod === 'phone'">
<el-row>
<el-col :span="24">
<el-form>
<el-form-item>
<el-form
:model="phoneForm"
:rules="phoneLoginRules"
ref="phoneLoginFormRef"
>
<el-form-item prop="phone">
<el-input
v-model="phoneForm.phone"
placeholder="请输入手机号"
prefix-icon="Iphone"
/>
</el-form-item>
<!-- 验证码 -->
<el-row :gutter="24">
<el-col :span="17">
<el-form-item>
<el-form-item prop="code">
<el-input
v-model="phoneForm.code"
placeholder="请输入验证码"
prefix-icon="Key"
/>
</el-form-item>
</el-col>
@ -208,7 +207,7 @@
<el-form-item>
<button
class="send-code-btn"
@click.prevent="onSendCode"
@click.prevent="startCountdown"
:disabled="isSendCodeButtonDisabled"
>
{{ sendCodeButtonText }}
@ -223,13 +222,95 @@
<el-col :span="12">
<el-button
style="background-color: gray; color: white"
@click="store.ThirdPartyLoginMethod = 'login'"
@click="backToLogin"
>返回</el-button
>
</el-col>
<el-col :span="12">
<el-button @click="validateAndLoginByPhone"
>登录</el-button
>
</el-col>
</el-row>
</div>
<div v-else-if="store.ThirdPartyLoginMethod === 'email'">
<el-row>
<el-col :span="24">
<el-form>
<el-form-item>
<el-input
v-model="emailForm.email"
placeholder="请输入邮箱"
prefix-icon="Message"
/>
</el-form-item>
<el-row :gutter="24">
<el-col :span="17">
<el-form-item>
<el-input
v-model="emailForm.code"
placeholder="请输入验证码"
prefix-icon="Key"
/>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item>
<button
class="send-code-btn"
@click.prevent="onSendCode()"
:disabled="
isSendEmailCodeButtonDisabled
"
>
{{ sendEmailCodeButtonText }}
</button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="12">
<el-button
style="background-color: gray; color: white"
@click="backToLogin"
>返回</el-button
>
</el-col>
<el-col :span="12">
<el-button @click="loginByEmail">登录</el-button>
</el-col>
</el-row>
</div>
<div v-else-if="store.ThirdPartyLoginMethod === 'thirdparty'">
<el-row :gutter="24">
<el-col :span="24">
<el-form
label-position="right"
label-width="100px"
>
<el-form-item label="用户特征码">
<el-input
v-model="thirdpartyCode"
placeholder="请输入用户特征码"
/>
</el-form-item>
</el-form>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="12">
<el-button
@click="loginByPhone"
@click="backToLogin"
style="background-color: gray; color: white"
>返回</el-button
>
</el-col>
<el-col :span="12">
<el-button @click="validateAndLoginByThirdparty"
>登录</el-button
>
</el-col>
@ -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<boolean> => {
store.ThirdPartyLoginMethod = "phone";
const authWithThirdParty = async (): Promise<boolean> => {
store.ThirdPartyLoginMethod = "thirdparty";
return true;
};
const loginByPhone = async () => {
await onLogin();
const authWithPhone = async (): Promise<boolean> => {
store.ThirdPartyLoginMethod = "phone";
return true;
};
const authWithDingDing = async (): Promise<boolean> => {
@ -762,6 +964,41 @@
// store.page = "phone";
// return true;
};
const authWithEmail = async (): Promise<boolean> => {
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();
};
</script>
<style scoped lang="scss">

3
frontend/src/stores/login.ts

@ -11,6 +11,8 @@ export const useLoginStore = defineStore("login", () => {
const tempClientId = ref<string>("");
const ThirdPartyLoginMethod = ref("login");
const thirdpartyList = ref([]);
const registerInfo = ref({
"username": "",
"nickname": "",
@ -29,5 +31,6 @@ export const useLoginStore = defineStore("login", () => {
tempToken,
tempClientId,
registerInfo,
thirdpartyList,
};
},);

8
frontend/src/system/dinglogin.ts

@ -14,11 +14,11 @@ export function loadScript(url: string): Promise<void> {
})
}
const currentUrl = window.location.origin
// const currentUrl = window.location.origin
export async function authWithDing(): Promise<boolean> {
try {
const res = await fetch(currentUrl + "/user/ding/conf");
const res = await fetch("http://server001.godoos.com/user/ding/conf");
const data = await res.json();
console.log(data)
if (data.success) {
@ -61,13 +61,13 @@ async function toLogin(code: string): Promise<boolean> {
code,
},
};
const res = await fetch(currentUrl + "/user/login", {
const res = await fetch("http://server001.godoos.com/user/login", {
method: "POST",
body: JSON.stringify(data),
});
const jsondata = await res.json();
if (jsondata.success) {
jsondata.data.url = currentUrl;
jsondata.data.url = "http://server001.godoos.com";
config.userInfo = jsondata.data;
config.userType = "member";
setSystemConfig(config);

14
frontend/src/system/index.ts

@ -108,12 +108,12 @@ export class System {
const login_type = new URLSearchParams(window.location.search).get("login_type");
if (login_type === "dingding") {
let islogin = await authWithDing();
alert(islogin);
if (!islogin) {
alert("登录失败,无法继续操作");
return;
}
}
// 企业微信登录
if (login_type === "qiyeweixin") {
let islogin = await authWithWechat();
if (!islogin) {
@ -122,6 +122,16 @@ export class System {
}
}
// // 第三方登录
// if (login_type === "thirdapi") {
// const unionid = new URLSearchParams(window.location.search).get("unionid");
// if (unionid) {
// let islogin = await authWithThirdParty(unionid);
// if (!islogin) {
// return;
// }
// }
// }
// 判断是否登录
await this.isLogin();
@ -268,7 +278,7 @@ export class System {
window.location.href = "/";
return true;
} else {
notifyError(jsondata.message);
notifyError("登录失败");
return false;
}
};

3
frontend/src/system/qiyeweixinlogin.ts

@ -5,7 +5,6 @@ export async function authWithWechat(): Promise<boolean> {
const queryParams = new URLSearchParams(window.location.search);
const code = queryParams.get("code");
if (!code) {
alert("登录失败,无法继续操作");
return false;
}
return await toLogin(code);
@ -36,7 +35,7 @@ async function toLogin(code: string): Promise<boolean> {
return true;
}
} catch (error) {
alert(error);
console.error(error);
}
return false;
}

62
frontend/src/system/third_login.ts

@ -0,0 +1,62 @@
import { GetClientId } from "@/util/clientid";
import { useLoginStore } from "@/stores/login";
import { notifyError } from "@/util/msg";
import { getSystemConfig, setSystemConfig } from "./config";
const config = getSystemConfig();
export async function authWithThirdParty(unionid: string): Promise<boolean> {
const data = {
login_type: "third_api",
client_id: GetClientId(),
param: {
unionid,
},
};
try {
const res = await fetch("http://server001.godoos.com/user/login", {
method: "POST",
body: JSON.stringify(data),
});
const jsondata = await res.json();
if (jsondata.success) {
jsondata.data.url = "http://server001.godoos.com";
config.userInfo = jsondata.data;
config.userType = "member";
setSystemConfig(config);
if (jsondata.code == 10000) {
const loginStore = useLoginStore();
loginStore.ThirdPartyLoginMethod = "register";
// 注册信息
loginStore.registerInfo = {
username: jsondata.data.username,
nickname: jsondata.data.nickname,
password: jsondata.data.password,
email: jsondata.data.email,
phone: jsondata.data.phone,
third_user_id: jsondata.data.third_user_id,
union_id: jsondata.data.union_id,
patform: jsondata.data.patform,
confirmPassword: "",
}
return true;
}
// config.userInfo.username = "";
// config.userInfo.password = "";
// setSystemConfig(config);
window.location.href = "/";
return true;
}
notifyError("登录失败");
setTimeout(() => {
window.location.href = "/";
}, 5000);
} catch (error) {
notifyError("登录失败");
console.error(error);
}
return false;
}

2
go.mod

@ -45,7 +45,7 @@ require (
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
)

1
go.sum

@ -140,6 +140,7 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

Loading…
Cancel
Save