|
@@ -18,7 +18,7 @@
|
|
|
v-if="qrData"
|
|
v-if="qrData"
|
|
|
></canvas>
|
|
></canvas>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="refresh-btn" @click="generateQRCode">
|
|
|
|
|
|
|
+ <view class="refresh-btn" @click="refreshAndGenerate">
|
|
|
<text class="refresh-text">刷新二维码</text>
|
|
<text class="refresh-text">刷新二维码</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
@@ -35,6 +35,7 @@ import drawQrcode from 'weapp-qrcode'
|
|
|
|
|
|
|
|
const user = ref<{ nickname?: string; role?: string | number; openid?: string; wx_openid?: string }>({})
|
|
const user = ref<{ nickname?: string; role?: string | number; openid?: string; wx_openid?: string }>({})
|
|
|
const qrData = ref('')
|
|
const qrData = ref('')
|
|
|
|
|
+const isFetching = ref(false)
|
|
|
|
|
|
|
|
const getPageTitle = (role: string | number | undefined) => {
|
|
const getPageTitle = (role: string | number | undefined) => {
|
|
|
const roleMap: { [key: number]: string } = {
|
|
const roleMap: { [key: number]: string } = {
|
|
@@ -76,6 +77,64 @@ const loadUser = () => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// 从后端刷新用户信息(仅在用户手动触发刷新时调用)
|
|
|
|
|
+const fetchUserInfo = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const token = uni.getStorageSync('token')
|
|
|
|
|
+ if (!token) return
|
|
|
|
|
+ if (isFetching.value) return
|
|
|
|
|
+ isFetching.value = true
|
|
|
|
|
+ uni.showLoading({ title: '加载中...' })
|
|
|
|
|
+ const response: any = await uni.request({
|
|
|
|
|
+ url: 'https://wx.baiyun.work/user_info',
|
|
|
|
|
+ method: 'POST',
|
|
|
|
|
+ header: {
|
|
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
|
|
+ 'Authorization': `Bearer ${token}`
|
|
|
|
|
+ },
|
|
|
|
|
+ data: {}
|
|
|
|
|
+ })
|
|
|
|
|
+ uni.hideLoading()
|
|
|
|
|
+ console.log('User info response:', response)
|
|
|
|
|
+ const resp = response.data as any
|
|
|
|
|
+ if (response.statusCode === 401) {
|
|
|
|
|
+ // Token 无效,清除并跳转登录
|
|
|
|
|
+ uni.removeStorageSync('token')
|
|
|
|
|
+ uni.removeStorageSync('role')
|
|
|
|
|
+ user.value = {}
|
|
|
|
|
+ uni.reLaunch({ url: '/pages/public/login/index' })
|
|
|
|
|
+ isFetching.value = false
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (resp && resp.code === 200 && resp.data) {
|
|
|
|
|
+ user.value = resp.data
|
|
|
|
|
+ uni.setStorageSync('user_info', resp.data)
|
|
|
|
|
+ // 如果缺少必要信息,引导用户补全
|
|
|
|
|
+ if (!resp.data.nickname || !resp.data.avatar) {
|
|
|
|
|
+ uni.navigateTo({ url: '/pages/patient/profile/infos/base-info' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ uni.hideLoading()
|
|
|
|
|
+ console.error('Fetch user info error:', err)
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ isFetching.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 手动刷新:先从后端拉取最新用户信息,再重新生成二维码
|
|
|
|
|
+const refreshAndGenerate = async () => {
|
|
|
|
|
+ await fetchUserInfo()
|
|
|
|
|
+ // fetchUserInfo 可能会在 token 无效时跳转登录,下面仅在本地有用户信息时重绘二维码
|
|
|
|
|
+ if (user.value && (user.value.wx_openid || user.value.openid)) {
|
|
|
|
|
+ generateQRCode()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 如果后端未返回 openid 等,仍尝试使用本地缓存绘制
|
|
|
|
|
+ loadUser()
|
|
|
|
|
+ generateQRCode()
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
const generateQRCode = () => {
|
|
const generateQRCode = () => {
|
|
|
console.log('Generating QR code, user data:', user.value)
|
|
console.log('Generating QR code, user data:', user.value)
|
|
|
if (!user.value.wx_openid || !user.value.role) {
|
|
if (!user.value.wx_openid || !user.value.role) {
|
|
@@ -104,6 +163,12 @@ const generateQRCode = () => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
onShow(() => {
|
|
onShow(() => {
|
|
|
|
|
+ // 首次进入时不主动向后端请求数据(首页已获取),但需要检查登录态
|
|
|
|
|
+ const token = uni.getStorageSync('token')
|
|
|
|
|
+ if (!token) {
|
|
|
|
|
+ uni.reLaunch({ url: '/pages/public/login/index' })
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
loadUser()
|
|
loadUser()
|
|
|
generateQRCode()
|
|
generateQRCode()
|
|
|
})
|
|
})
|
|
@@ -144,7 +209,6 @@ onShow(() => {
|
|
|
position: relative;
|
|
position: relative;
|
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
|
border: 1rpx solid rgba(255, 255, 255, 0.2);
|
|
border: 1rpx solid rgba(255, 255, 255, 0.2);
|
|
|
- animation: cardEntrance 0.6s ease-out;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* 渐变边框效果 */
|
|
/* 渐变边框效果 */
|
|
@@ -237,7 +301,6 @@ onShow(() => {
|
|
|
0 8rpx 20rpx rgba(0, 0, 0, 0.1);
|
|
0 8rpx 20rpx rgba(0, 0, 0, 0.1);
|
|
|
position: relative;
|
|
position: relative;
|
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
|
- transition: all 0.3s ease;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* 二维码装饰角 */
|
|
/* 二维码装饰角 */
|
|
@@ -265,7 +328,6 @@ onShow(() => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.qr-container:active {
|
|
.qr-container:active {
|
|
|
- transform: scale(0.98);
|
|
|
|
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
|
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -279,11 +341,11 @@ onShow(() => {
|
|
|
@keyframes cardEntrance {
|
|
@keyframes cardEntrance {
|
|
|
0% {
|
|
0% {
|
|
|
opacity: 0;
|
|
opacity: 0;
|
|
|
- transform: translateY(30rpx) scale(0.95);
|
|
|
|
|
|
|
+ transform: translate3d(0, 30rpx, 0) scale(0.95);
|
|
|
}
|
|
}
|
|
|
100% {
|
|
100% {
|
|
|
opacity: 1;
|
|
opacity: 1;
|
|
|
- transform: translateY(0) scale(1);
|
|
|
|
|
|
|
+ transform: translate3d(0, 0, 0) scale(1);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -331,11 +393,9 @@ onShow(() => {
|
|
|
font-size: 28rpx;
|
|
font-size: 28rpx;
|
|
|
font-weight: 500;
|
|
font-weight: 500;
|
|
|
box-shadow: 0 4rpx 12rpx rgba(102, 126, 234, 0.3);
|
|
box-shadow: 0 4rpx 12rpx rgba(102, 126, 234, 0.3);
|
|
|
- transition: all 0.3s ease;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.refresh-btn:active {
|
|
.refresh-btn:active {
|
|
|
- transform: scale(0.95);
|
|
|
|
|
box-shadow: 0 2rpx 6rpx rgba(102, 126, 234, 0.4);
|
|
box-shadow: 0 2rpx 6rpx rgba(102, 126, 234, 0.4);
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|