feat: 更新微信小程序登录流程和演示环境配置
This commit is contained in:
@@ -7,8 +7,8 @@ VITE_APP_PORT = 4096
|
|||||||
VITE_APP_BASE_API = '/dev-api'
|
VITE_APP_BASE_API = '/dev-api'
|
||||||
|
|
||||||
# API 服务器的 URL
|
# API 服务器的 URL
|
||||||
#VITE_APP_API_URL = http://localhost:8989
|
VITE_APP_API_URL = http://localhost:8000
|
||||||
VITE_APP_API_URL = https://api.youlai.tech
|
# VITE_APP_API_URL = https://api.youlai.tech
|
||||||
|
|
||||||
# WebSocket 服务器的 URL,不配置默认关闭 WebSocket
|
# WebSocket 服务器的 URL,不配置默认关闭 WebSocket
|
||||||
#VITE_APP_WS_ENDPOINT= ws://localhost:4096/ws
|
#VITE_APP_WS_ENDPOINT= ws://localhost:4096/ws
|
||||||
2
components.d.ts
vendored
2
components.d.ts
vendored
@@ -1,4 +1,4 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
/* prettier-ignore */
|
/* prettier-ignore */
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
// Generated by vite-plugin-uni-components
|
// Generated by vite-plugin-uni-components
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "vue-uniapp-template",
|
"name": "youlai-uniapp-template",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:app": "uni -p app",
|
"dev:app": "uni -p app",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import request, { publicRequest } from "@/utils/request";
|
import request, { publicRequest } from "@/utils/request";
|
||||||
|
|
||||||
const AUTH_BASE_URL = "/api/v1/auth";
|
const AUTH_BASE_URL = "/api/v1/auth";
|
||||||
|
const WECHAT_MINIAPP_AUTH_BASE_URL = "/api/v1/wechat/miniapp/auth";
|
||||||
|
|
||||||
export interface LoginData {
|
export interface LoginData {
|
||||||
username: string;
|
username: string;
|
||||||
@@ -40,7 +41,7 @@ export interface WechatMiniappPhoneLoginData {
|
|||||||
export interface WechatMiniappBindMobileData {
|
export interface WechatMiniappBindMobileData {
|
||||||
openid: string;
|
openid: string;
|
||||||
mobile: string;
|
mobile: string;
|
||||||
code: string;
|
smsCode: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AuthAPI = {
|
const AuthAPI = {
|
||||||
@@ -57,6 +58,8 @@ const AuthAPI = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送短信验证码
|
* 发送短信验证码
|
||||||
|
*
|
||||||
|
* 演示环境说明:短信服务未配置,验证码固定为 123456
|
||||||
*/
|
*/
|
||||||
sendSmsLoginCode(mobile: string): Promise<void> {
|
sendSmsLoginCode(mobile: string): Promise<void> {
|
||||||
const mobileSafe = encodeURIComponent(mobile);
|
const mobileSafe = encodeURIComponent(mobile);
|
||||||
@@ -79,34 +82,46 @@ const AuthAPI = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信小程序登录(个人小程序)
|
* 微信小程序静默登录
|
||||||
|
*
|
||||||
|
* 适用场景:个人小程序
|
||||||
|
* - 已绑定手机号的用户:直接返回 token,登录成功
|
||||||
|
* - 未绑定手机号的用户:返回 openid,需调用绑定手机号接口
|
||||||
*/
|
*/
|
||||||
wechatMiniappLogin(code: string): Promise<WechatMiniappLoginResult> {
|
wechatMiniappSilentLogin(code: string): Promise<WechatMiniappLoginResult> {
|
||||||
return publicRequest<WechatMiniappLoginResult>({
|
return publicRequest<WechatMiniappLoginResult>({
|
||||||
url: `${AUTH_BASE_URL}/wechat-miniapp/login?code=${encodeURIComponent(code)}`,
|
url: `${WECHAT_MINIAPP_AUTH_BASE_URL}/silent-login?code=${encodeURIComponent(code)}`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信小程序一键登录(企业小程序)
|
* 微信小程序手机号快捷登录
|
||||||
|
*
|
||||||
|
* 适用场景:企业认证小程序(已开通手机号快捷登录权限)
|
||||||
|
* 一步完成登录,无需绑定流程,自动创建新用户
|
||||||
*/
|
*/
|
||||||
wechatMiniappPhoneLogin(data: WechatMiniappPhoneLoginData): Promise<LoginResult> {
|
wechatMiniappPhoneLogin(data: WechatMiniappPhoneLoginData): Promise<LoginResult> {
|
||||||
|
const loginCodeSafe = encodeURIComponent(data.loginCode);
|
||||||
|
const phoneCodeSafe = encodeURIComponent(data.phoneCode);
|
||||||
return publicRequest<LoginResult>({
|
return publicRequest<LoginResult>({
|
||||||
url: `${AUTH_BASE_URL}/wechat-miniapp/phone-login`,
|
url: `${WECHAT_MINIAPP_AUTH_BASE_URL}/phone-login?loginCode=${loginCodeSafe}&phoneCode=${phoneCodeSafe}`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data,
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信小程序绑定手机号
|
* 微信小程序绑定手机号
|
||||||
|
*
|
||||||
|
* 演示环境说明:短信服务未配置,验证码固定为 123456
|
||||||
*/
|
*/
|
||||||
wechatMiniappBindMobile(data: WechatMiniappBindMobileData): Promise<LoginResult> {
|
wechatMiniappBindMobile(data: WechatMiniappBindMobileData): Promise<LoginResult> {
|
||||||
|
const openidSafe = encodeURIComponent(data.openid);
|
||||||
|
const mobileSafe = encodeURIComponent(data.mobile);
|
||||||
|
const smsCodeSafe = encodeURIComponent(data.smsCode);
|
||||||
return publicRequest<LoginResult>({
|
return publicRequest<LoginResult>({
|
||||||
url: `${AUTH_BASE_URL}/wechat-miniapp/bind-mobile`,
|
url: `${WECHAT_MINIAPP_AUTH_BASE_URL}/bind-mobile?openid=${openidSafe}&mobile=${mobileSafe}&smsCode=${smsCodeSafe}`,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data,
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,14 @@ const UserAPI = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** 解绑第三方账号 */
|
||||||
|
unbindSocial(platform: string) {
|
||||||
|
return request({
|
||||||
|
url: `${USER_BASE_URL}/social?platform=${encodeURIComponent(platform)}`,
|
||||||
|
method: "DELETE",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送手机/邮箱验证码
|
* 发送手机/邮箱验证码
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -152,15 +152,10 @@
|
|||||||
"backgroundColorTop": "@bgColorTop",
|
"backgroundColorTop": "@bgColorTop",
|
||||||
"backgroundColorBottom": "@bgColorBottom",
|
"backgroundColorBottom": "@bgColorBottom",
|
||||||
"enablePullDownRefresh": false,
|
"enablePullDownRefresh": false,
|
||||||
"onReachBottomDistance": 50,
|
"onReachBottomDistance": 50
|
||||||
"animationType": "pop-in",
|
|
||||||
"animationDuration": 300
|
|
||||||
},
|
},
|
||||||
"tabBar": {
|
"tabBar": {
|
||||||
"custom": true,
|
"custom": true,
|
||||||
"customize": true,
|
|
||||||
"overlay": true,
|
|
||||||
"height": "0",
|
|
||||||
"color": "@tabColor",
|
"color": "@tabColor",
|
||||||
"selectedColor": "@tabSelectedColor",
|
"selectedColor": "@tabSelectedColor",
|
||||||
"backgroundColor": "@tabBgColor",
|
"backgroundColor": "@tabBgColor",
|
||||||
@@ -179,4 +174,4 @@
|
|||||||
},
|
},
|
||||||
"__esModule": true,
|
"__esModule": true,
|
||||||
"subPackages": []
|
"subPackages": []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,11 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 演示环境提示 -->
|
||||||
|
<view v-if="loginMode === 'SMS'" class="demo-tip">
|
||||||
|
<text class="demo-tip-text">演示环境验证码:123456</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 登录按钮 -->
|
<!-- 登录按钮 -->
|
||||||
<button class="btn-primary" :disabled="loading || !canSubmit" @click="handleLogin">
|
<button class="btn-primary" :disabled="loading || !canSubmit" @click="handleLogin">
|
||||||
{{ loading ? "登录中..." : "登 录" }}
|
{{ loading ? "登录中..." : "登 录" }}
|
||||||
@@ -87,7 +92,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- #ifdef MP-WECHAT -->
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
<!-- 微信登录区域 -->
|
<!-- 微信登录区域 -->
|
||||||
<view v-else class="form-area">
|
<view v-else class="form-area">
|
||||||
<!-- 企业一键登录 -->
|
<!-- 企业一键登录 -->
|
||||||
@@ -96,7 +101,7 @@
|
|||||||
open-type="getPhoneNumber"
|
open-type="getPhoneNumber"
|
||||||
@getphonenumber="handleWechatPhoneLogin"
|
@getphonenumber="handleWechatPhoneLogin"
|
||||||
>
|
>
|
||||||
<wd-icon name="wechat" size="20" color="#fff" class="mr-2" />
|
<image class="btn-wechat-icon" src="/static/icons/weixin.png" mode="aspectFit" />
|
||||||
微信一键登录
|
微信一键登录
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -108,7 +113,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
|
|
||||||
<!-- #ifdef MP-WECHAT -->
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
<!-- 分割线 -->
|
<!-- 分割线 -->
|
||||||
<view v-if="loginMode !== 'WECHAT'" class="divider">
|
<view v-if="loginMode !== 'WECHAT'" class="divider">
|
||||||
<view class="divider-line" />
|
<view class="divider-line" />
|
||||||
@@ -118,9 +123,12 @@
|
|||||||
|
|
||||||
<!-- 微信登录入口 -->
|
<!-- 微信登录入口 -->
|
||||||
<view v-if="loginMode !== 'WECHAT'" class="wechat-entry">
|
<view v-if="loginMode !== 'WECHAT'" class="wechat-entry">
|
||||||
<view class="wechat-icon" @click="loginMode = 'WECHAT'">
|
<image
|
||||||
<wd-icon name="wechat" size="24" color="#fff" />
|
class="wechat-icon-img"
|
||||||
</view>
|
src="/static/icons/weixin.png"
|
||||||
|
mode="aspectFit"
|
||||||
|
@click="loginMode = 'WECHAT'"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
|
|
||||||
@@ -183,6 +191,11 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 演示环境提示 -->
|
||||||
|
<view class="demo-tip">
|
||||||
|
<text class="demo-tip-text">演示环境验证码:123456</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
<button class="btn-bind" :disabled="bindLoading" @click="handleBindMobile">
|
<button class="btn-bind" :disabled="bindLoading" @click="handleBindMobile">
|
||||||
{{ bindLoading ? "绑定中..." : "确认绑定" }}
|
{{ bindLoading ? "绑定中..." : "确认绑定" }}
|
||||||
</button>
|
</button>
|
||||||
@@ -221,7 +234,7 @@ const smsTimer = ref<ReturnType<typeof setInterval> | null>(null);
|
|||||||
const formData = ref({
|
const formData = ref({
|
||||||
username: "admin",
|
username: "admin",
|
||||||
password: "123456",
|
password: "123456",
|
||||||
code: "1234",
|
code: "123456",
|
||||||
});
|
});
|
||||||
|
|
||||||
const redirect = ref("/pages/index/index");
|
const redirect = ref("/pages/index/index");
|
||||||
@@ -459,7 +472,7 @@ const handleBindMobile = async () => {
|
|||||||
await userStore.bindMobileForWechatMiniapp({
|
await userStore.bindMobileForWechatMiniapp({
|
||||||
openid: wechatOpenid.value,
|
openid: wechatOpenid.value,
|
||||||
mobile,
|
mobile,
|
||||||
code,
|
smsCode: code,
|
||||||
});
|
});
|
||||||
await userStore.getInfo();
|
await userStore.getInfo();
|
||||||
showBindMobilePopup.value = false;
|
showBindMobilePopup.value = false;
|
||||||
@@ -502,8 +515,8 @@ const navigateToAgreement = (type: string) => {
|
|||||||
|
|
||||||
.bg-circle {
|
.bg-circle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border-radius: 50%;
|
|
||||||
filter: blur(64px);
|
filter: blur(64px);
|
||||||
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-circle-1 {
|
.bg-circle-1 {
|
||||||
@@ -515,8 +528,8 @@ const navigateToAgreement = (type: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bg-circle-2 {
|
.bg-circle-2 {
|
||||||
bottom: -80px;
|
|
||||||
right: -80px;
|
right: -80px;
|
||||||
|
bottom: -80px;
|
||||||
width: 320px;
|
width: 320px;
|
||||||
height: 320px;
|
height: 320px;
|
||||||
background-color: rgba(59, 130, 246, 0.15);
|
background-color: rgba(59, 130, 246, 0.15);
|
||||||
@@ -562,9 +575,9 @@ const navigateToAgreement = (type: string) => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
background-color: rgba(255, 255, 255, 0.95);
|
background-color: rgba(255, 255, 255, 0.95);
|
||||||
|
backdrop-filter: blur(24px);
|
||||||
border-radius: 24px;
|
border-radius: 24px;
|
||||||
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
|
||||||
backdrop-filter: blur(24px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.dark) .login-card {
|
:global(.dark) .login-card {
|
||||||
@@ -573,8 +586,8 @@ const navigateToAgreement = (type: string) => {
|
|||||||
|
|
||||||
// 卡片头部
|
// 卡片头部
|
||||||
.card-header {
|
.card-header {
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 32px;
|
margin-bottom: 32px;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-title {
|
.card-title {
|
||||||
@@ -589,9 +602,9 @@ const navigateToAgreement = (type: string) => {
|
|||||||
|
|
||||||
.card-desc {
|
.card-desc {
|
||||||
display: block;
|
display: block;
|
||||||
|
margin-top: 8px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #6b7280;
|
color: #6b7280;
|
||||||
margin-top: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.dark) .card-desc {
|
:global(.dark) .card-desc {
|
||||||
@@ -641,11 +654,11 @@ const navigateToAgreement = (type: string) => {
|
|||||||
|
|
||||||
// 主按钮
|
// 主按钮
|
||||||
.btn-primary {
|
.btn-primary {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@@ -659,18 +672,18 @@ const navigateToAgreement = (type: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
opacity: 0.5;
|
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 微信按钮
|
// 微信按钮
|
||||||
.btn-wechat {
|
.btn-wechat {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@@ -683,13 +696,19 @@ const navigateToAgreement = (type: string) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-wechat-icon {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
// 绑定按钮
|
// 绑定按钮
|
||||||
.btn-bind {
|
.btn-bind {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@@ -703,11 +722,11 @@ const navigateToAgreement = (type: string) => {
|
|||||||
|
|
||||||
// 验证码按钮
|
// 验证码按钮
|
||||||
.sms-btn {
|
.sms-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
padding: 0 16px;
|
padding: 0 16px;
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@@ -751,10 +770,10 @@ const navigateToAgreement = (type: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.switch-link {
|
.switch-link {
|
||||||
|
margin-left: 4px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #2563eb;
|
color: #2563eb;
|
||||||
margin-left: 4px;
|
|
||||||
border-bottom: 1px solid #2563eb;
|
border-bottom: 1px solid #2563eb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -790,19 +809,13 @@ const navigateToAgreement = (type: string) => {
|
|||||||
// 微信登录入口
|
// 微信登录入口
|
||||||
.wechat-entry {
|
.wechat-entry {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
|
||||||
gap: 32px;
|
gap: 32px;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wechat-icon {
|
.wechat-icon-img {
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background-color: #22c55e;
|
|
||||||
border-radius: 50%;
|
|
||||||
box-shadow: 0 4px 6px -1px rgba(34, 197, 94, 0.3);
|
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
transform: scale(0.95);
|
transform: scale(0.95);
|
||||||
@@ -813,8 +826,8 @@ const navigateToAgreement = (type: string) => {
|
|||||||
.agreement {
|
.agreement {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
margin-top: 24px;
|
|
||||||
padding-top: 16px;
|
padding-top: 16px;
|
||||||
|
margin-top: 24px;
|
||||||
border-top: 1px solid #f3f4f6;
|
border-top: 1px solid #f3f4f6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -824,8 +837,8 @@ const navigateToAgreement = (type: string) => {
|
|||||||
|
|
||||||
.agreement-text {
|
.agreement-text {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #6b7280;
|
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
color: #6b7280;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.dark) .agreement-text {
|
:global(.dark) .agreement-text {
|
||||||
@@ -847,17 +860,37 @@ const navigateToAgreement = (type: string) => {
|
|||||||
|
|
||||||
.bind-title {
|
.bind-title {
|
||||||
display: block;
|
display: block;
|
||||||
|
margin-bottom: 24px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #111827;
|
color: #111827;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.dark) .bind-title {
|
:global(.dark) .bind-title {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 演示环境提示
|
||||||
|
.demo-tip {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.demo-tip-text {
|
||||||
|
padding: 4px 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #f59e0b;
|
||||||
|
background-color: #fef3c7;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.dark) .demo-tip-text {
|
||||||
|
color: #fbbf24;
|
||||||
|
background-color: rgba(251, 191, 36, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
// 暗黑模式适配
|
// 暗黑模式适配
|
||||||
:deep(.wd-checkbox__label) {
|
:deep(.wd-checkbox__label) {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -865,7 +898,7 @@ const navigateToAgreement = (type: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
:deep(.wd-popup__close) {
|
:deep(.wd-popup__close) {
|
||||||
right: 16px;
|
|
||||||
top: 16px;
|
top: 16px;
|
||||||
|
right: 16px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -21,6 +21,9 @@
|
|||||||
is-link
|
is-link
|
||||||
@click="handleOpenDialog(DialogType.EMAIL)"
|
@click="handleOpenDialog(DialogType.EMAIL)"
|
||||||
/>
|
/>
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<wd-cell title="微信" value="解绑" is-link @click="handleUnbindWechat" />
|
||||||
|
<!-- #endif -->
|
||||||
</wd-cell-group>
|
</wd-cell-group>
|
||||||
</wd-card>
|
</wd-card>
|
||||||
|
|
||||||
@@ -211,6 +214,25 @@ const mobileTimer = ref<ReturnType<typeof setInterval> | null>(null);
|
|||||||
const emailCountdown = ref(0);
|
const emailCountdown = ref(0);
|
||||||
const emailTimer = ref<ReturnType<typeof setTimeout> | null>(null);
|
const emailTimer = ref<ReturnType<typeof setTimeout> | null>(null);
|
||||||
|
|
||||||
|
const handleUnbindWechat = async () => {
|
||||||
|
uni.showModal({
|
||||||
|
title: "提示",
|
||||||
|
content: "确定要解绑微信吗?解绑后将无法使用微信小程序登录",
|
||||||
|
success: async (res) => {
|
||||||
|
if (!res.confirm) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await UserAPI.unbindSocial("WECHAT_MINI");
|
||||||
|
uni.showToast({ title: "解绑成功", icon: "success" });
|
||||||
|
loadUserProfile();
|
||||||
|
} catch (e) {
|
||||||
|
console.error("解绑微信失败", e);
|
||||||
|
uni.showToast({ title: "解绑失败", icon: "none" });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/** 加载用户信息 */
|
/** 加载用户信息 */
|
||||||
const loadUserProfile = async () => {
|
const loadUserProfile = async () => {
|
||||||
userProfile.value = await UserAPI.getProfile();
|
userProfile.value = await UserAPI.getProfile();
|
||||||
|
|||||||
@@ -44,10 +44,10 @@ export const useUserStore = defineStore("user", () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 微信小程序登录(个人小程序)
|
// 微信小程序静默登录
|
||||||
const loginByWechatMiniapp = (code: string) => {
|
const loginByWechatMiniapp = (code: string) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
AuthAPI.wechatMiniappLogin(code)
|
AuthAPI.wechatMiniappSilentLogin(code)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (data.accessToken) {
|
if (data.accessToken) {
|
||||||
setAccessToken(data.accessToken);
|
setAccessToken(data.accessToken);
|
||||||
|
|||||||
4
src/types/auto-imports.d.ts
vendored
4
src/types/auto-imports.d.ts
vendored
@@ -1,4 +1,4 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
/* prettier-ignore */
|
/* prettier-ignore */
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
// noinspection JSUnusedGlobalSymbols
|
// noinspection JSUnusedGlobalSymbols
|
||||||
@@ -325,4 +325,4 @@ declare module 'vue' {
|
|||||||
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
|
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
|
||||||
readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
|
readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
2
src/types/uni-pages.d.ts
vendored
2
src/types/uni-pages.d.ts
vendored
@@ -1,4 +1,4 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
/* prettier-ignore */
|
/* prettier-ignore */
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
// Generated by vite-plugin-uni-pages
|
// Generated by vite-plugin-uni-pages
|
||||||
|
|||||||
Reference in New Issue
Block a user