增加线上配置分享功能+用户后台登录,不影响首页渲染
This commit is contained in:
@@ -4,27 +4,48 @@ const { request } = require('./utils/api')
|
|||||||
|
|
||||||
App({
|
App({
|
||||||
onLaunch() {
|
onLaunch() {
|
||||||
// 自动静默登录:wx.login 获取 code,再请求后端接口换取 openid
|
// 优先从本地缓存恢复登录态,避免阻塞页面
|
||||||
|
const cached = wx.getStorageSync('userInfo')
|
||||||
|
if (cached && cached.openid) {
|
||||||
|
this.globalData.userInfo = cached
|
||||||
|
this.globalData.isLoggedIn = true
|
||||||
|
}
|
||||||
|
// 静默登录获取最新 session,不阻塞页面
|
||||||
this.silentLogin()
|
this.silentLogin()
|
||||||
},
|
},
|
||||||
|
|
||||||
silentLogin() {
|
silentLogin() {
|
||||||
wx.login({
|
this._loginPromise = new Promise((resolve) => {
|
||||||
success: (loginRes) => {
|
this._loginResolve = resolve
|
||||||
if (loginRes.code) {
|
wx.login({
|
||||||
this.loginWithCode(loginRes.code)
|
success: (loginRes) => {
|
||||||
} else {
|
if (loginRes.code) {
|
||||||
console.error('wx.login 失败', loginRes.errMsg)
|
this.loginWithCode(loginRes.code)
|
||||||
|
} else {
|
||||||
|
console.error('wx.login 失败', loginRes.errMsg)
|
||||||
|
this.handleLoginFail()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('wx.login 调用失败', err)
|
||||||
this.handleLoginFail()
|
this.handleLoginFail()
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
fail: (err) => {
|
|
||||||
console.error('wx.login 调用失败', err)
|
|
||||||
this.handleLoginFail()
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回登录完成的 Promise,供页面 await 使用
|
||||||
|
* @param {boolean} useCache - 是否在已有缓存时立即 resolve
|
||||||
|
* @returns {Promise<object|null>}
|
||||||
|
*/
|
||||||
|
waitLogin(useCache = false) {
|
||||||
|
if (useCache && this.globalData.isLoggedIn) {
|
||||||
|
return Promise.resolve(this.globalData.userInfo)
|
||||||
|
}
|
||||||
|
return this._loginPromise || Promise.resolve(this.globalData.userInfo || null)
|
||||||
|
},
|
||||||
|
|
||||||
async loginWithCode(code) {
|
async loginWithCode(code) {
|
||||||
try {
|
try {
|
||||||
const data = await request({
|
const data = await request({
|
||||||
@@ -39,22 +60,25 @@ App({
|
|||||||
}
|
}
|
||||||
this.globalData.userInfo = userInfo
|
this.globalData.userInfo = userInfo
|
||||||
this.globalData.isLoggedIn = true
|
this.globalData.isLoggedIn = true
|
||||||
|
this.globalData.loginFailed = false
|
||||||
wx.setStorageSync('userInfo', userInfo)
|
wx.setStorageSync('userInfo', userInfo)
|
||||||
if (this.loginReadyCallback) {
|
if (this._loginResolve) this._loginResolve(userInfo)
|
||||||
this.loginReadyCallback(userInfo)
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('后端登录失败', err)
|
console.error('后端登录失败', err)
|
||||||
this.handleLoginFail()
|
// 如果有缓存登录态,登录失败不立即清除,让页面继续使用缓存
|
||||||
|
if (!this.globalData.isLoggedIn) {
|
||||||
|
this.handleLoginFail()
|
||||||
|
} else {
|
||||||
|
this.globalData.loginFailed = true
|
||||||
|
if (this._loginResolve) this._loginResolve(this.globalData.userInfo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
handleLoginFail() {
|
handleLoginFail() {
|
||||||
this.globalData.isLoggedIn = false
|
this.globalData.isLoggedIn = false
|
||||||
this.globalData.loginFailed = true
|
this.globalData.loginFailed = true
|
||||||
if (this.loginReadyCallback) {
|
if (this._loginResolve) this._loginResolve(null)
|
||||||
this.loginReadyCallback(null)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
globalData: {
|
globalData: {
|
||||||
|
|||||||
@@ -34,20 +34,15 @@ Page({
|
|||||||
},
|
},
|
||||||
|
|
||||||
onLoad() {
|
onLoad() {
|
||||||
if (app.globalData.isLoggedIn) {
|
this._awaitLoginAndInit()
|
||||||
|
},
|
||||||
|
|
||||||
|
async _awaitLoginAndInit() {
|
||||||
|
const userInfo = await app.waitLogin(true)
|
||||||
|
if (userInfo) {
|
||||||
this.initPage()
|
this.initPage()
|
||||||
} else if (app.globalData.loginFailed) {
|
|
||||||
this.showLoginTipAndGoBack()
|
|
||||||
} else {
|
} else {
|
||||||
// 登录异步未完成,等待回调
|
this.showLoginTipAndGoBack()
|
||||||
app.loginReadyCallback = (userInfo) => {
|
|
||||||
app.loginReadyCallback = null
|
|
||||||
if (userInfo) {
|
|
||||||
this.initPage()
|
|
||||||
} else {
|
|
||||||
this.showLoginTipAndGoBack()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -292,5 +287,18 @@ Page({
|
|||||||
console.error('提交预约失败', err)
|
console.error('提交预约失败', err)
|
||||||
wx.showToast({ title: '提交失败,请重试', icon: 'none' })
|
wx.showToast({ title: '提交失败,请重试', icon: 'none' })
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onShareAppMessage(res) {
|
||||||
|
return {
|
||||||
|
title: '访客预约',
|
||||||
|
path: '/pages/index/index'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onShareTimeline() {
|
||||||
|
return {
|
||||||
|
title: '访客预约'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
+31
-30
@@ -11,45 +11,33 @@ Page({
|
|||||||
},
|
},
|
||||||
|
|
||||||
onLoad() {
|
onLoad() {
|
||||||
|
// 首页不阻塞,直接渲染;有缓存登录态时立即加载数据
|
||||||
if (app.globalData.isLoggedIn) {
|
if (app.globalData.isLoggedIn) {
|
||||||
this.onLoginReady()
|
this.setData({ isLoggedIn: true })
|
||||||
} else if (app.globalData.loginFailed) {
|
|
||||||
this.onLoginFailed()
|
|
||||||
} else {
|
|
||||||
app.loginReadyCallback = (userInfo) => {
|
|
||||||
if (userInfo) {
|
|
||||||
this.onLoginReady()
|
|
||||||
} else {
|
|
||||||
this.onLoginFailed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onShow() {
|
|
||||||
if (app.globalData.isLoggedIn) {
|
|
||||||
this.loadLatestRecord()
|
this.loadLatestRecord()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onLoginReady() {
|
async onShow() {
|
||||||
this.setData({ isLoggedIn: true, loginFailed: false })
|
// 每次显示时等待登录完成,再加载最新数据
|
||||||
this.loadLatestRecord()
|
const userInfo = await app.waitLogin(true)
|
||||||
|
if (userInfo) {
|
||||||
|
this.setData({ isLoggedIn: true, loginFailed: false })
|
||||||
|
this.loadLatestRecord()
|
||||||
|
} else {
|
||||||
|
this.setData({ isLoggedIn: false, loginFailed: true })
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onLoginFailed() {
|
async onRetry() {
|
||||||
this.setData({ isLoggedIn: false, loginFailed: true })
|
|
||||||
},
|
|
||||||
|
|
||||||
onRetry() {
|
|
||||||
this.setData({ loginFailed: false })
|
this.setData({ loginFailed: false })
|
||||||
app.silentLogin()
|
app.silentLogin()
|
||||||
app.loginReadyCallback = (userInfo) => {
|
const userInfo = await app.waitLogin()
|
||||||
if (userInfo) {
|
if (userInfo) {
|
||||||
this.onLoginReady()
|
this.setData({ isLoggedIn: true, loginFailed: false })
|
||||||
} else {
|
this.loadLatestRecord()
|
||||||
this.onLoginFailed()
|
} else {
|
||||||
}
|
this.setData({ loginFailed: true })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -85,5 +73,18 @@ Page({
|
|||||||
|
|
||||||
showQrcode(e) {
|
showQrcode(e) {
|
||||||
this.selectComponent('#qrcodeModal').show(e.currentTarget.dataset.id)
|
this.selectComponent('#qrcodeModal').show(e.currentTarget.dataset.id)
|
||||||
|
},
|
||||||
|
|
||||||
|
onShareAppMessage(res) {
|
||||||
|
return {
|
||||||
|
title: '访客预约',
|
||||||
|
path: '/pages/index/index'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onShareTimeline() {
|
||||||
|
return {
|
||||||
|
title: '访客预约'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
+4
-11
@@ -1,16 +1,9 @@
|
|||||||
<!--index.wxml-->
|
<!--index.wxml-->
|
||||||
<view class="page">
|
<view class="page">
|
||||||
<!-- loading 遮罩 -->
|
<!-- 登录失败提示条(不遮挡页面) -->
|
||||||
<view class="loading-mask" wx:if="{{!isLoggedIn && !loginFailed}}">
|
<view class="login-fail-bar" wx:if="{{loginFailed && !isLoggedIn}}">
|
||||||
<view class="loading-spinner"></view>
|
<text>网络异常,无法获取身份信息</text>
|
||||||
<text class="loading-text">正在获取身份信息...</text>
|
<text class="retry-link" bindtap="onRetry">重试</text>
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 登录失败 -->
|
|
||||||
<view class="loading-mask" wx:if="{{loginFailed}}">
|
|
||||||
<text class="fail-icon">⚠️</text>
|
|
||||||
<text class="fail-text">网络异常,请重试</text>
|
|
||||||
<view class="retry-btn" bindtap="onRetry">重新加载</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="header">
|
<view class="header">
|
||||||
|
|||||||
+12
-55
@@ -21,67 +21,24 @@ page {
|
|||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* loading 遮罩 */
|
/* 登录失败提示条(不遮挡页面) */
|
||||||
.loading-mask {
|
.login-fail-bar {
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background: #f0f5fa;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: space-between;
|
||||||
z-index: 999;
|
background: #fff3e0;
|
||||||
}
|
color: #e6a23c;
|
||||||
|
font-size: 24rpx;
|
||||||
.loading-spinner {
|
padding: 16rpx 24rpx;
|
||||||
width: 64rpx;
|
border-radius: 12rpx;
|
||||||
height: 64rpx;
|
|
||||||
border: 6rpx solid #dbeafe;
|
|
||||||
border-top: 6rpx solid #5b9bd5;
|
|
||||||
border-radius: 50%;
|
|
||||||
animation: spin 0.8s linear infinite;
|
|
||||||
margin-bottom: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes spin {
|
|
||||||
from { transform: rotate(0deg); }
|
|
||||||
to { transform: rotate(360deg); }
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading-text {
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #7f8fa6;
|
|
||||||
letter-spacing: 2rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 登录失败 */
|
|
||||||
.fail-icon {
|
|
||||||
font-size: 80rpx;
|
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fail-text {
|
.login-fail-bar .retry-link {
|
||||||
font-size: 28rpx;
|
color: #5b9bd5;
|
||||||
color: #7f8fa6;
|
|
||||||
margin-bottom: 32rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.retry-btn {
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #fff;
|
|
||||||
background: linear-gradient(135deg, #5b9bd5, #4a8bc2);
|
|
||||||
padding: 16rpx 56rpx;
|
|
||||||
border-radius: 40rpx;
|
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
letter-spacing: 2rpx;
|
flex-shrink: 0;
|
||||||
box-shadow: 0 4rpx 16rpx rgba(91, 155, 213, 0.3);
|
margin-left: 20rpx;
|
||||||
}
|
|
||||||
|
|
||||||
.retry-btn:active {
|
|
||||||
opacity: 0.85;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-title {
|
.header-title {
|
||||||
|
|||||||
+29
-29
@@ -13,19 +13,16 @@ Page({
|
|||||||
},
|
},
|
||||||
|
|
||||||
onLoad() {
|
onLoad() {
|
||||||
if (app.globalData.isLoggedIn) {
|
this._awaitLoginAndLoad()
|
||||||
this.onLoginReady()
|
},
|
||||||
} else if (app.globalData.loginFailed) {
|
|
||||||
this.onLoginFailed()
|
async _awaitLoginAndLoad() {
|
||||||
|
const userInfo = await app.waitLogin(true)
|
||||||
|
if (userInfo) {
|
||||||
|
this.setData({ isLoggedIn: true, loginFailed: false })
|
||||||
|
this.loadRecords()
|
||||||
} else {
|
} else {
|
||||||
app.loginReadyCallback = (userInfo) => {
|
this.setData({ isLoggedIn: false, loginFailed: true, loading: false })
|
||||||
app.loginReadyCallback = null
|
|
||||||
if (userInfo) {
|
|
||||||
this.onLoginReady()
|
|
||||||
} else {
|
|
||||||
this.onLoginFailed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -36,25 +33,15 @@ Page({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onLoginReady() {
|
async onRetry() {
|
||||||
this.setData({ isLoggedIn: true, loginFailed: false })
|
|
||||||
this.loadRecords()
|
|
||||||
},
|
|
||||||
|
|
||||||
onLoginFailed() {
|
|
||||||
this.setData({ isLoggedIn: false, loginFailed: true, loading: false })
|
|
||||||
},
|
|
||||||
|
|
||||||
onRetry() {
|
|
||||||
this.setData({ loginFailed: false, loading: true })
|
this.setData({ loginFailed: false, loading: true })
|
||||||
app.silentLogin()
|
app.silentLogin()
|
||||||
app.loginReadyCallback = (userInfo) => {
|
const userInfo = await app.waitLogin()
|
||||||
app.loginReadyCallback = null
|
if (userInfo) {
|
||||||
if (userInfo) {
|
this.setData({ isLoggedIn: true, loginFailed: false })
|
||||||
this.onLoginReady()
|
this.loadRecords()
|
||||||
} else {
|
} else {
|
||||||
this.onLoginFailed()
|
this.setData({ loginFailed: true })
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -122,5 +109,18 @@ Page({
|
|||||||
|
|
||||||
showQrcode(e) {
|
showQrcode(e) {
|
||||||
this.selectComponent('#qrcodeModal').show(e.currentTarget.dataset.id)
|
this.selectComponent('#qrcodeModal').show(e.currentTarget.dataset.id)
|
||||||
|
},
|
||||||
|
|
||||||
|
onShareAppMessage(res) {
|
||||||
|
return {
|
||||||
|
title: '访客预约',
|
||||||
|
path: '/pages/index/index'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onShareTimeline() {
|
||||||
|
return {
|
||||||
|
title: '访客预约'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -94,5 +94,18 @@ Page({
|
|||||||
this.setData({ verifying: false })
|
this.setData({ verifying: false })
|
||||||
wx.showToast({ title: err.message || '核销失败,请稍后重试', icon: 'none' })
|
wx.showToast({ title: err.message || '核销失败,请稍后重试', icon: 'none' })
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onShareAppMessage(res) {
|
||||||
|
return {
|
||||||
|
title: '访客预约',
|
||||||
|
path: '/pages/index/index'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onShareTimeline() {
|
||||||
|
return {
|
||||||
|
title: '访客预约'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
+1
-1
@@ -5,7 +5,7 @@ const ENV_CONFIG = {
|
|||||||
release: 'https://smartguest.bmser.com:8091',
|
release: 'https://smartguest.bmser.com:8091',
|
||||||
trial: 'https://smartguest.bmser.com:8091',
|
trial: 'https://smartguest.bmser.com:8091',
|
||||||
// develop: 'https://192.168.123.76:8080'
|
// develop: 'https://192.168.123.76:8080'
|
||||||
develop: 'https://10.50.13.191:8091'
|
develop: 'https://10.50.13.185:8091'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自动判断当前运行环境
|
// 自动判断当前运行环境
|
||||||
|
|||||||
Reference in New Issue
Block a user