feat: 完成前端业务闭环与后端联调

This commit is contained in:
2026-08-24 23:37:56 +08:00
parent c59e36f933
commit 9ad572907b
175 changed files with 10711 additions and 1740 deletions
+138 -6
View File
@@ -175,6 +175,28 @@
}}</text>
</button>
<!-- #ifdef APP-PLUS -->
<view class="third-party-login">
<text class="third-party-login__divider">其他登录方式</text>
<button
class="auth-plain-button wechat-login"
:disabled="submitting || sendingCode || tacVisible || wechatProviderState !== 'ready'"
:aria-busy="submitting"
hover-class="tap-fade"
@click="submitWechatLogin"
>
<text class="wechat-login__mark"></text>
<text>{{
wechatProviderState === "checking"
? "正在检查微信登录"
: wechatProviderState === "ready"
? "微信登录"
: "微信登录尚未配置"
}}</text>
</button>
</view>
<!-- #endif -->
<view class="register-entry">
<text>还没有账号</text>
<button
@@ -218,14 +240,14 @@
<text>我已阅读并同意</text>
<button
class="auth-plain-button agreement-link"
@click="prepareAgreement"
@click="openComplianceDocument('user_agreement')"
>
用户协议
</button>
<text></text>
<button
class="auth-plain-button agreement-link"
@click="prepareAgreement"
@click="openComplianceDocument('privacy_policy')"
>
隐私政策
</button>
@@ -294,6 +316,7 @@ const tacVisible = ref(false);
const tacContext = ref(null);
const sendingCode = ref(false);
const submitting = ref(false);
const wechatProviderState = ref("unknown");
const authenticationCommitted = ref(false);
const cooldownSeconds = ref(0);
const sentPhone = ref("");
@@ -363,7 +386,36 @@ const restoreAuthenticatedSession = () => {
void enterAuthenticatedRoot();
};
onShow(restoreAuthenticatedSession);
const detectWechatProvider = () => {
if (wechatProviderState.value !== "unknown") return;
// #ifdef APP-PLUS
if (typeof uni?.getProvider !== "function") {
wechatProviderState.value = "unavailable";
return;
}
wechatProviderState.value = "checking";
uni.getProvider({
service: "oauth",
success: ({ provider = [] } = {}) => {
if (!pageActive) return;
wechatProviderState.value = provider.includes("weixin")
? "ready"
: "unavailable";
},
fail: () => {
if (pageActive) wechatProviderState.value = "unavailable";
},
});
// #endif
// #ifndef APP-PLUS
wechatProviderState.value = "unavailable";
// #endif
};
onShow(() => {
restoreAuthenticatedSession();
detectWechatProvider();
});
const blockBusyAction = () => {
if (!sendingCode.value && !submitting.value) return false;
@@ -685,7 +737,43 @@ const prepareRegister = () => {
return openPage("A04", {}, "A01");
};
const prepareAgreement = () => showFeedback("协议页面准备中");
const openComplianceDocument = (documentKey) => {
if (blockBusyAction()) return;
return openPage("M13", { documentKey }, "A01");
};
const requestWechatAuthorizationCode = () =>
new Promise((resolve, reject) => {
uni.login({
provider: "weixin",
onlyAuthorize: true,
success: ({ code } = {}) => resolve(code),
fail: reject,
});
});
const submitWechatLogin = async () => {
if (submitting.value || wechatProviderState.value !== "ready") return;
if (authenticationCommitted.value) return enterAuthenticatedRoot();
if (!requireAgreement()) return;
submitting.value = true;
try {
const code = await requestWechatAuthorizationCode();
await authApi.loginWithWechat(
{ code },
{ requestController: signInSubmissionRequestController },
);
if (!pageActive) return;
authenticationCommitted.value = true;
await enterAuthenticatedRoot();
} catch (error) {
if (!pageActive || isRequestCancelled(error)) return;
const errorText = String(error?.errMsg || error?.message || "");
showFeedback(/cancel|取消/i.test(errorText) ? "已取消微信登录" : errorText || "微信登录失败,请稍后重试");
} finally {
if (pageActive) submitting.value = false;
}
};
</script>
<style scoped lang="scss">
@@ -906,7 +994,7 @@ const prepareAgreement = () => showFeedback("协议页面准备中");
.agreement-row {
display: flex;
align-items: center;
flex-wrap: nowrap;
flex-wrap: wrap;
justify-content: center;
min-height: var(--app-touch-min);
font-size: clamp(12px, 22rpx, 14px);
@@ -934,12 +1022,56 @@ const prepareAgreement = () => showFeedback("协议页面准备中");
.agreement-copy {
display: flex;
flex: 0 0 auto;
flex-wrap: wrap;
align-items: center;
justify-content: center;
min-width: 0;
padding-top: 2rpx;
}
.agreement-copy text {
white-space: nowrap;
white-space: normal;
}
.third-party-login {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 22rpx;
gap: 16rpx;
}
.third-party-login__divider {
color: rgba(76, 57, 41, 0.62);
font-size: clamp(12px, 21rpx, 15px);
}
.wechat-login {
display: inline-flex;
min-height: 72rpx;
align-items: center;
justify-content: center;
padding: 0 30rpx;
border: 1rpx solid rgba(66, 107, 88, 0.38);
border-radius: 999rpx;
color: #315943;
font-size: clamp(14px, 23rpx, 17px);
gap: 12rpx;
}
.wechat-login[disabled] {
opacity: 0.52;
}
.wechat-login__mark {
display: inline-flex;
width: 38rpx;
height: 38rpx;
align-items: center;
justify-content: center;
border-radius: 50%;
background: #2f9e57;
color: #fff;
font-size: clamp(11px, 18rpx, 14px);
}
.agreement-link {