589 lines
15 KiB
Vue
589 lines
15 KiB
Vue
<template>
|
||
<view class="main_div max_page">
|
||
<nav-bar :is_seat="false"></nav-bar>
|
||
<view class="bg_div">
|
||
<image src="/static/images/me/bg.png" class="bg_img"></image>
|
||
<view class="user_data_div">
|
||
<!-- 用户个人信息 -->
|
||
<view class="personal_information">
|
||
<view class="profile" @click="click_update_avatar()">
|
||
<image class="img_100" v-if='user_info.imagePath' :src="user_info.imagePath"></image>
|
||
<image-preview v-else-if="user_info.imageAddr" class="img_100"
|
||
:src="user_info.imageAddr"></image-preview>
|
||
<image v-else class="img_100" src="/static/images/me/default_user_avatar.png"></image>
|
||
</view>
|
||
<view class="personal_information_data">
|
||
<view class="name_sex_div">
|
||
<view class="name">
|
||
{{ user_info.userName }}
|
||
</view>
|
||
<view class="sex">
|
||
<image v-if="user_info.gender === 'f'" class="img_100"
|
||
src="/static/images/me/wuman.png"></image>
|
||
<image v-if="user_info.gender === 'm'" class="img_100" src="/static/images/me/man.png">
|
||
</image>
|
||
</view>
|
||
<view class="fl1"></view>
|
||
</view>
|
||
<view class="work_number_div">工号:{{ user_info.loginName }}</view>
|
||
<view class="fl1"></view>
|
||
|
||
</view>
|
||
|
||
<!-- 显示当前选中的徽章 -->
|
||
<!-- <view class="dan" @click="changeBadge">
|
||
<view class="dan_img">
|
||
<image class="img_100" :src="`/static/images/me/${badgeList[currentIndex].png}`"
|
||
mode="heightFix" alt="当前徽章"></image>
|
||
</view>
|
||
<view class="dan_text">{{ badgeList[currentIndex].name }}</view>
|
||
</view> -->
|
||
</view>
|
||
<!-- 用户学习时间信息 -->
|
||
<view class="study_information">
|
||
<view class="item">
|
||
<view class="top">累计学习时长</view>
|
||
<view class="bottom">
|
||
<uv-count-to :startVal="statistics_data['startStdtTmLen']"
|
||
:endVal="statistics_data['stdtTmLen']" :useEasing="true" :decimals="1"
|
||
ref="stdtTmLenRef"></uv-count-to>h
|
||
</view>
|
||
</view>
|
||
<view class="item">
|
||
<view class="top">累计完成任务</view>
|
||
<view class="bottom">
|
||
<uv-count-to :startVal="statistics_data['startAccmTaskCnt']"
|
||
:endVal="statistics_data['accmTaskCnt']" :useEasing="true"
|
||
ref="accmTaskCntRef"></uv-count-to>
|
||
</view>
|
||
</view>
|
||
<view class="item">
|
||
<view class="top">累计获得积分</view>
|
||
<view class="bottom">
|
||
<uv-count-to :startVal="statistics_data['startAccmPoint']"
|
||
:endVal="statistics_data['accmPoint']" :useEasing="true"
|
||
ref="accmPointRef"></uv-count-to>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 4个导航 -->
|
||
<view class="navigation_div">
|
||
|
||
<!-- <scroll-view class="scroll-view" :scroll-x="true" :show-scrollbar="false"> -->
|
||
<scroll-view class="scroll-view" scroll-x="true" :show-scrollbar="false">
|
||
<view class="scroll-view-item">
|
||
<view class="item">
|
||
|
||
<image class="icon" src="@/static/images/me/study.png"></image>
|
||
<view class="title">学习记录</view>
|
||
</view>
|
||
</view>
|
||
<view class="scroll-view-item">
|
||
<view class="item">
|
||
<image class="icon" src="@/static/images/me/todo.png"></image>
|
||
<view class="title">练习记录</view>
|
||
</view>
|
||
</view>
|
||
<view class="scroll-view-item">
|
||
<view class="item">
|
||
<image class="icon" src="@/static/images/me/examination.png"></image>
|
||
<view class="title">考试记录</view>
|
||
</view>
|
||
</view>
|
||
<view class="scroll-view-item">
|
||
<view class="item">
|
||
<image class="icon" src="@/static/images/me/report.png"></image>
|
||
<view class="title">竞赛记录</view>
|
||
</view>
|
||
</view>
|
||
<view class="scroll-view-item">
|
||
<view class="item">
|
||
<image class="icon" src="@/static/images/me/report.png"></image>
|
||
<view class="title">AI陪练记录</view>
|
||
</view>
|
||
</view>
|
||
<view class="scroll-view-item">
|
||
<view class="item">
|
||
<image class="icon" src="@/static/images/me/report.png"></image>
|
||
<view class="title">AI问答记录</view>
|
||
</view>
|
||
</view>
|
||
|
||
</scroll-view>
|
||
<!-- </scroll-view> -->
|
||
|
||
</view>
|
||
<view class="cell_div">
|
||
<uv-cell-group :border="false">
|
||
<uv-cell title="消息通知" :isLink="true" @click="goTest()"></uv-cell>
|
||
<uv-cell title="我的收藏" :isLink="true"></uv-cell>
|
||
<uv-cell title="排行榜" :isLink="true" :clickable="false" :border="false"></uv-cell>
|
||
</uv-cell-group>
|
||
</view>
|
||
<view class="cell_div">
|
||
<uv-cell-group :border="false">
|
||
<uv-cell title="设置" :isLink="true" @click="common.navigateTo('/pages/setting/index')"></uv-cell>
|
||
<uv-cell title="退出登录" :isLink="true" :clickable="false" :border="false"
|
||
@click="click_loginout()"></uv-cell>
|
||
</uv-cell-group>
|
||
</view>
|
||
<tabbar-shadow></tabbar-shadow>
|
||
<avatar-cropper v-if="avatarCropperStatus" mode="ratio" :imageUrl="avatarCropperUrl" :width="500" :height="500"
|
||
:delay="150" @cancel="onCancel" @confirm="onConfirm"></avatar-cropper>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import {
|
||
ref,
|
||
computed,
|
||
reactive,
|
||
nextTick
|
||
} from 'vue';
|
||
import {
|
||
onLoad,
|
||
onShow
|
||
} from '@dcloudio/uni-app';
|
||
import common from '@/common/common';
|
||
import {
|
||
getUserInfo
|
||
} from '@/common/common';
|
||
import {
|
||
onPullDownRefresh
|
||
} from '@dcloudio/uni-app';
|
||
import {
|
||
loginOut
|
||
} from '@/api/login.js';
|
||
import {
|
||
queryTraStdyStatisticsSelf
|
||
} from '@/api/user.js';
|
||
import {
|
||
useSocketStore
|
||
} from "@/store/socket.js"
|
||
import {
|
||
updateDfSysUserExtandInfoImageAddr
|
||
} from "@/api/user.js"
|
||
import {
|
||
uploadFile
|
||
} from '@/api/common'
|
||
import {
|
||
setMascot
|
||
} from "@/common/mascot.js"
|
||
import {
|
||
queryCurrentUser
|
||
} from '@/api/login.js';
|
||
const badgeList = [{
|
||
"name": "黑铁",
|
||
"png": "badge_1.png",
|
||
},
|
||
{
|
||
"name": "青铜",
|
||
"png": "badge_2.png",
|
||
},
|
||
{
|
||
"name": "白银",
|
||
"png": "badge_3.png",
|
||
},
|
||
{
|
||
"name": "黄金",
|
||
"png": "badge_4.png",
|
||
},
|
||
{
|
||
"name": "铂金",
|
||
"png": "badge_5.png",
|
||
},
|
||
{
|
||
"name": "钻石",
|
||
"png": "badge_6.png",
|
||
},
|
||
{
|
||
"name": "王者",
|
||
"png": "badge_7.png",
|
||
}
|
||
]
|
||
const currentIndex = ref(0);
|
||
const changeBadge = () => {
|
||
// 计算下一个索引,如果当前是最后一个则回到0
|
||
currentIndex.value = (currentIndex.value + 1) % badgeList.length;
|
||
};
|
||
const socketStore = useSocketStore()
|
||
const accmTaskCntRef = ref(null);
|
||
const accmPointRef = ref(null);
|
||
const stdtTmLenRef = ref(null);
|
||
const statistics_data = reactive({
|
||
stdtTmLen: 0, // 累计学习时长
|
||
accmTaskCnt: 0, // 累计完成任务
|
||
accmPoint: 0, // 累计获得积分
|
||
startStdtTmLen: 0, // 起始累计学习时长
|
||
startAccmTaskCnt: 0, // 起始累计完成任务
|
||
startAccmPoint: 0, // 起始累计获得积分
|
||
request_time: 0, // 上次请求时间
|
||
init: function() {
|
||
// 初始化统计数据
|
||
console.log('初始化统计数据');
|
||
const me_statistics_data = common.getValue('statistics_data'); // 获取缓存
|
||
if (me_statistics_data) {
|
||
this.stdtTmLen = me_statistics_data.stdtTmLen;
|
||
this.accmTaskCnt = me_statistics_data.accmTaskCnt;
|
||
this.accmPoint = me_statistics_data.accmPoint;
|
||
}
|
||
},
|
||
get_statistics_data: async function() {
|
||
try {
|
||
const time_now = Date.now();
|
||
let statistics_data = common.getValue('statistics_data') || {};
|
||
if (time_now - this.request_time > 300) {
|
||
this.request_time = time_now;
|
||
// 获取最新数据
|
||
const res = await queryTraStdyStatisticsSelf();
|
||
if (res && res.body) {
|
||
// 合并新数据与缓存数据,确保只更新有效字段
|
||
statistics_data = {
|
||
...statistics_data,
|
||
stdtTmLen: res.body.stdtTmLen || 0,
|
||
accmTaskCnt: res.body.accmTaskCnt || 0,
|
||
accmPoint: res.body.accmPoint || 0
|
||
};
|
||
|
||
common.setValue('statistics_data', statistics_data);
|
||
}
|
||
}
|
||
|
||
// 解构赋值获取最新值
|
||
const {
|
||
accmPoint = 0, accmTaskCnt = 0, stdtTmLen = 0
|
||
} = statistics_data;
|
||
|
||
// 更新数据并触发动画
|
||
if (accmPoint !== this.accmPoint) {
|
||
this.startAccmPoint = this.accmPoint;
|
||
this.accmPoint = accmPoint;
|
||
accmPointRef.value?.start();
|
||
}
|
||
|
||
if (accmTaskCnt !== this.accmTaskCnt) {
|
||
this.startAccmTaskCnt = this.accmTaskCnt;
|
||
this.accmTaskCnt = accmTaskCnt;
|
||
accmTaskCntRef.value?.start();
|
||
}
|
||
|
||
if (stdtTmLen !== this.stdtTmLen) {
|
||
this.startStdtTmLen = this.stdtTmLen;
|
||
this.stdtTmLen = stdtTmLen;
|
||
stdtTmLenRef.value?.start();
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('获取统计数据失败:', error);
|
||
// 可以在这里添加更多的错误处理逻辑,比如显示错误提示
|
||
}
|
||
}
|
||
});
|
||
const user_info = reactive({
|
||
userName: '',
|
||
userId: '',
|
||
imageAddr: '',
|
||
});
|
||
const goTest = () => {
|
||
console.log('goTest');
|
||
common.navigateTo('/pages/test/index');
|
||
};
|
||
|
||
|
||
const click_loginout = () => {
|
||
common.show('确定退出登录?').then(async (res) => {
|
||
console.log(res);
|
||
if (!res) return;
|
||
try {
|
||
common.loading('正在退出登录');
|
||
socketStore.closeSocket()
|
||
await loginOut();
|
||
} catch (e) {}
|
||
common.hideLoading();
|
||
// 主动退出登录后,再次登录应该进首页
|
||
common.reLaunch('/pages/login/login');
|
||
});
|
||
};
|
||
onLoad(() => {
|
||
statistics_data['init'](); // 初始化数据
|
||
})
|
||
onShow(() => {
|
||
setMascot()
|
||
Object.assign(user_info, getUserInfo());
|
||
statistics_data['get_statistics_data'](); // 获取统计数据
|
||
});
|
||
onPullDownRefresh(() => {
|
||
console.log('下拉刷新');
|
||
uni.stopPullDownRefresh();
|
||
});
|
||
|
||
// 头像
|
||
const avatarCropperStatus = ref(true)
|
||
const avatarCropperUrl = ref('');
|
||
// 点击修改头像
|
||
const click_update_avatar = (value) => {
|
||
uni.chooseImage({
|
||
count: 1,
|
||
sizeType: ["compressed"],
|
||
success: (res) => {
|
||
avatarCropperUrl.value = res.tempFilePaths[0];
|
||
avatarCropperStatus.value = true
|
||
},
|
||
});
|
||
};
|
||
// 选择头像取消
|
||
const onCancel = (value) => {
|
||
avatarCropperStatus.value = false
|
||
}
|
||
// 选择头像确定
|
||
const onConfirm = (file) => {
|
||
avatarCropperStatus.value = false
|
||
nextTick(async () => {
|
||
common.loading('更新头像中')
|
||
try {
|
||
const data = {
|
||
bizScen: 'S3007',
|
||
thumbnailFlag: true,
|
||
thumbImgSize: 100
|
||
}
|
||
// 上传图片
|
||
const res = await uploadFile(file.tempFilePath, data)
|
||
// 更新个人信息
|
||
await updateDfSysUserExtandInfoImageAddr({
|
||
imageAddr: res.thumbFileId
|
||
})
|
||
// 更新个人信息
|
||
const userData = await queryCurrentUser()
|
||
console.log('userData', userData);
|
||
common.msg('修改成功')
|
||
user_info.imageAddr = userData.imageAddr
|
||
user_info.imagePath = ''
|
||
} catch {
|
||
common.msg('修改失败')
|
||
}
|
||
common.hideLoading()
|
||
})
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
$bg-margin-left: 50rpx;
|
||
|
||
|
||
|
||
|
||
|
||
// 下方单元格
|
||
.cell_div {
|
||
margin: 30rpx $bg-margin-left 0 $bg-margin-left;
|
||
background: #ffffff;
|
||
border-radius: 15rpx;
|
||
z-index: 101;
|
||
overflow: hidden;
|
||
|
||
// 为了让线缩进来24单位
|
||
:deep(.uv-line) {
|
||
width: calc(100% - 48rpx) !important;
|
||
margin: 0 24rpx !important;
|
||
}
|
||
|
||
:deep(.uv-cell__body) {
|
||
padding: 12px 15px;
|
||
}
|
||
}
|
||
|
||
// 快捷导航栏
|
||
.navigation_div {
|
||
margin: 30rpx $bg-margin-left 0 $bg-margin-left;
|
||
padding: 24rpx 0 20rpx 0;
|
||
background-color: #ffffff;
|
||
border-radius: 23rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-around;
|
||
z-index: 101;
|
||
|
||
.scroll-view {
|
||
white-space: nowrap;
|
||
width: 100%;
|
||
|
||
}
|
||
|
||
.scroll-view-item {
|
||
display: inline-block;
|
||
padding: 32rpx 22rpx 36rpx 26rpx;
|
||
}
|
||
|
||
.item {
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
align-items: center;
|
||
|
||
// background-color: red;
|
||
.icon {
|
||
width: 88rpx;
|
||
height: 86rpx;
|
||
}
|
||
|
||
.title {
|
||
margin-top: 10rpx;
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 25rpx;
|
||
color: #323e57;
|
||
line-height: 35rpx;
|
||
text-align: left;
|
||
font-style: normal;
|
||
}
|
||
}
|
||
}
|
||
|
||
.bg_div {
|
||
display: flex;
|
||
flex-direction: column;
|
||
position: relative;
|
||
padding: 0 $bg-margin-left;
|
||
z-index: 50;
|
||
|
||
.bg_img {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
z-index: -1;
|
||
height: 858rpx;
|
||
}
|
||
|
||
// 个人信息
|
||
.user_data_div {
|
||
margin-top: 158rpx;
|
||
background: linear-gradient(180deg, rgba(241, 245, 255, 0.5) 0%, #f6f9fe 50%, #ffffff 100%);
|
||
border-radius: 14rpx;
|
||
border: 2rpx solid #ffffff;
|
||
box-shadow: #f6f8ff 0 0 2rpx;
|
||
|
||
.personal_information {
|
||
padding: 20rpx 26rpx 0 26rpx;
|
||
display: flex;
|
||
|
||
// 个人头像框框
|
||
.profile {
|
||
border-radius: 100%;
|
||
border: 2px solid #ffffff;
|
||
width: 108rpx;
|
||
height: 108rpx;
|
||
overflow: hidden;
|
||
}
|
||
|
||
// 头像右边的信息
|
||
.personal_information_data {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
margin-left: 26rpx;
|
||
overflow: hidden;
|
||
|
||
// 上边的姓名性别盒子
|
||
.name_sex_div {
|
||
display: flex;
|
||
margin-top: 6rpx;
|
||
justify-content: space-between;
|
||
|
||
.name {
|
||
font-family: PingFangSC;
|
||
font-weight: 600;
|
||
font-size: 28rpx;
|
||
color: #000000;
|
||
line-height: 40rpx;
|
||
}
|
||
|
||
.sex {
|
||
margin-left: 10rpx;
|
||
width: 30rpx;
|
||
height: 30rpx;
|
||
}
|
||
|
||
}
|
||
|
||
.work_number_div {
|
||
font-family: PingFangSC;
|
||
font-weight: 400;
|
||
font-size: 25rpx;
|
||
color: #666666;
|
||
line-height: 38rpx;
|
||
text-align: left;
|
||
font-style: normal;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
}
|
||
}
|
||
}
|
||
|
||
.dan {
|
||
display: flex;
|
||
flex-direction: column;
|
||
font-size: 16rpx;
|
||
align-items: center;
|
||
|
||
.dan_img {
|
||
height: 50rpx;
|
||
|
||
|
||
}
|
||
|
||
.dan_text {}
|
||
}
|
||
|
||
.study_information {
|
||
display: flex;
|
||
justify-content: space-around;
|
||
z-index: 20;
|
||
margin: 30rpx 50rpx;
|
||
|
||
.item {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
|
||
.top {
|
||
font-family: PingFangSC, PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 25rpx;
|
||
color: #666666;
|
||
line-height: 35rpx;
|
||
text-align: center;
|
||
font-style: normal;
|
||
}
|
||
|
||
.bottom {
|
||
margin-top: 5%;
|
||
font-weight: bold;
|
||
font-size: 50rpx;
|
||
color: #000000;
|
||
line-height: 58rpx;
|
||
text-align: left;
|
||
font-style: normal;
|
||
text-align: center;
|
||
|
||
// 数字滚动组件
|
||
:deep(.uv-count-num) {
|
||
font-weight: bold !important;
|
||
font-size: 50rpx !important;
|
||
color: #000000 !important;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.main_div {
|
||
display: flex;
|
||
flex-direction: column;
|
||
background-color: #f6f8ff;
|
||
}
|
||
</style> |