|
|
@@ -3,7 +3,61 @@
|
|
|
<view class="page-container">
|
|
|
<view class="content">
|
|
|
<view class="user-info">
|
|
|
-
|
|
|
+ <view class="avatar-section">
|
|
|
+ <view class="avatar">
|
|
|
+ <view class="avatar-frame">
|
|
|
+ <image class="avatar-img" :src="avatarSrc" mode="aspectFill" />
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="user-details">
|
|
|
+ <text class="username">{{ user.nickname || '慢病患者' }}</text>
|
|
|
+ <text class="user-age" v-if="user.age">年龄: {{ user.age }}</text>
|
|
|
+ <text class="user-id" v-if="user.openid">ID: {{ user.openid }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="function-container">
|
|
|
+ <view class="function-row">
|
|
|
+ <view class="function-item health-data">
|
|
|
+ <view class="item-content">
|
|
|
+ <view class="title-row">
|
|
|
+ <view class="item-line"></view>
|
|
|
+ <text class="item-title">健康数据</text>
|
|
|
+ </view>
|
|
|
+ <text class="item-desc">查看您的健康数据</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="function-item reminder">
|
|
|
+ <view class="item-content">
|
|
|
+ <view class="title-row">
|
|
|
+ <view class="item-line"></view>
|
|
|
+ <text class="item-title">提醒管理</text>
|
|
|
+ </view>
|
|
|
+ <text class="item-desc">管理健康提醒</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="function-row">
|
|
|
+ <view class="function-item doctor">
|
|
|
+ <view class="item-content">
|
|
|
+ <view class="title-row">
|
|
|
+ <view class="item-line"></view>
|
|
|
+ <text class="item-title">我的医生</text>
|
|
|
+ </view>
|
|
|
+ <text class="item-desc">联系您的医生</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="function-item profile">
|
|
|
+ <view class="item-content">
|
|
|
+ <view class="title-row">
|
|
|
+ <view class="item-line"></view>
|
|
|
+ <text class="item-title">个人中心</text>
|
|
|
+ </view>
|
|
|
+ <text class="item-desc">管理个人信息</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
@@ -12,10 +66,87 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { ref } from 'vue'
|
|
|
+import { ref, computed } from 'vue'
|
|
|
+import { onShow } from '@dcloudio/uni-app'
|
|
|
import CustomNav from '@/components/custom-nav.vue'
|
|
|
import TabBar from '@/components/tab-bar.vue'
|
|
|
|
|
|
+const user = ref<{ avatar?: string; nickname?: string; openid?: string; age?: number }>({})
|
|
|
+
|
|
|
+const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'
|
|
|
+
|
|
|
+const avatarSrc = computed(() => {
|
|
|
+ const a = user.value?.avatar
|
|
|
+ if (!a) return defaultAvatarUrl
|
|
|
+ try {
|
|
|
+ const s = String(a)
|
|
|
+ if (/^(https?:\/\/|data:|wxfile:\/\/|file:\/\/|\/static\/)/i.test(s)) {
|
|
|
+ return s
|
|
|
+ }
|
|
|
+ if (/^(\.|\/|temp)/i.test(s)) return s
|
|
|
+ } catch (e) {
|
|
|
+ // fallback
|
|
|
+ }
|
|
|
+ return defaultAvatarUrl
|
|
|
+})
|
|
|
+
|
|
|
+const loadUser = () => {
|
|
|
+ try {
|
|
|
+ const u = uni.getStorageSync('user_info')
|
|
|
+ if (u) {
|
|
|
+ user.value = u
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ // ignore
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const fetchUserInfo = async () => {
|
|
|
+ try {
|
|
|
+ const token = uni.getStorageSync('token')
|
|
|
+ if (!token) return
|
|
|
+ uni.showLoading({ title: '加载中...' })
|
|
|
+ const response = 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) {
|
|
|
+ uni.removeStorageSync('token')
|
|
|
+ uni.removeStorageSync('role')
|
|
|
+ user.value = {}
|
|
|
+ uni.reLaunch({ url: '/pages/public/login/index' })
|
|
|
+ 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/public/profile/infos/base-info' })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ uni.hideLoading()
|
|
|
+ console.error('Fetch user info error:', err)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onShow(() => {
|
|
|
+ const token = uni.getStorageSync('token')
|
|
|
+ if (!token) {
|
|
|
+ uni.reLaunch({ url: '/pages/public/login/index' })
|
|
|
+ } else {
|
|
|
+ fetchUserInfo()
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
function handleScan(res: any) {
|
|
|
console.log('[index] scan result', res)
|
|
|
const resultText = res?.result || ''
|
|
|
@@ -42,7 +173,137 @@ function handleScan(res: any) {
|
|
|
}
|
|
|
|
|
|
.user-info {
|
|
|
+ /* background-color: #fff; */
|
|
|
+ padding: 40rpx;
|
|
|
+ margin-top: 10rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.avatar-section {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.avatar {
|
|
|
+ width: 120rpx;
|
|
|
+ height: 120rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ border: 1px solid rgba(128, 128, 128, 0.5);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ margin-right: 30rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.avatar-frame {
|
|
|
width: 100%;
|
|
|
- height: 100px;
|
|
|
+ height: 100%;
|
|
|
+ border-radius: 50%;
|
|
|
+ overflow: hidden;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.avatar-img {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ object-fit: cover;
|
|
|
+}
|
|
|
+
|
|
|
+.user-details {
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.username {
|
|
|
+ font-size: 36rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 10rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.user-age {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 10rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.user-id {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+}
|
|
|
+
|
|
|
+.function-container {
|
|
|
+ padding-inline: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.function-row {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.function-row:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.function-item {
|
|
|
+ flex: 1;
|
|
|
+ height: 160rpx;
|
|
|
+ background-color: #fff;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ margin: 0 10rpx;
|
|
|
+ position: relative;
|
|
|
+ box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.item-content {
|
|
|
+ position: absolute;
|
|
|
+ top: 20rpx;
|
|
|
+ left: 20rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+
|
|
|
+.title-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 10rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.item-line {
|
|
|
+ width: 6rpx;
|
|
|
+ height: 48rpx;
|
|
|
+ margin-right: 15rpx;
|
|
|
+ border-radius: 10rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.health-data .item-line {
|
|
|
+ background-color: #2ed573;
|
|
|
+}
|
|
|
+
|
|
|
+.reminder .item-line {
|
|
|
+ background-color: #3742fa;
|
|
|
+}
|
|
|
+
|
|
|
+.doctor .item-line {
|
|
|
+ background-color: #ffa502;
|
|
|
+}
|
|
|
+
|
|
|
+.profile .item-line {
|
|
|
+ background-color: #9c88ff;
|
|
|
+}
|
|
|
+
|
|
|
+.item-title {
|
|
|
+ font-size: 36rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+}
|
|
|
+
|
|
|
+.item-desc {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
}
|
|
|
</style>
|