web-base-pc/src/views/index/components/sidebarUserInfo.vue

746 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="sidebar-container">
<div class="sidebarTop">
<div class="sidebarHeader">
<img
:src="
userInfo.headPath ? userInfo.headPath : userInfo.countryCircularIcon
"
alt=""
/>
</div>
<div class="nameCountry">
<div class="username">{{ userInfo.memberCode }}</div>
<div v-if="userExtraInfo.registerAuthorityVal" class="authority-badge">
{{ userExtraInfo.registerAuthorityVal }}
</div>
<!-- <div class="username">{{ userData.registerAuthorityVal }}</div> -->
<!-- <img :src="userInfo.countrySquareIcon" alt="" /> -->
</div>
<!-- 如果是0表示没有奖衔 只显示等级徽章!-->
<div class="user-level-info">
<div class="honor_wrapper">
<div class="honor1">
<div class="honor-title-wrapper">
<div>结算等级</div>
<div class="honor-title">{{ userInfo.pkGradeVal }}</div>
</div>
</div>
</div>
<div class="honor_wrapper">
<div class="honor1">
<div class="honor-title-wrapper">
<div>荣誉奖衔</div>
<div
class="honor-title"
:class="{
'is-empty-awards':
!userInfo.pkAwardsVal || userInfo.pkAwardsVal === '无',
}"
>
{{
userInfo.pkAwardsVal && userInfo.pkAwardsVal !== "无"
? userInfo.pkAwardsVal
: "无"
}}
</div>
</div>
</div>
</div>
</div>
</div>
<!--! 用户卡片信息 -->
<div class="awardscard">
<!-- NEW: Awards Sprint Text -->
<!-- <div v-if="awards.tarAwardsName" class="awards-progress-summary">
<span class="descriptive-text">当前距离</span>
<span class="highlight-name">
{{ awards.tarAwardsName }}
</span>
<span class="descriptive-text">奖衔,小区仅需</span>
<span class="highlight-pv">
{{ sprintProgress.achieved }}
</span>
</div> -->
<div class="user-cards">
<div class="user-cards-left">
<div v-if="awards.tarAwardsName" class="progress-wrapper">
<div class="progress-wrapper__label">奖衔晋升</div>
<div class="sprint-progress-container">
<div
class="sprint-current-progress"
:style="{ width: sprintProgress.percentageString }"
></div>
<div class="sprint-progress-text">
晋升
<span class="target-award-name">{{
awards.tarAwardsName
}}</span>
小区仅需
<span class="achieved-value">{{
sprintProgress.achieved
}}</span>
</div>
</div>
</div>
<div class="progress-wrapper">
<div class="progress-wrapper__label">昨日业绩</div>
<div
:class="[
'progress-bar-container',
awards.aNewPv != 0 || awards.bNewPv != 0
? 'has-value'
: 'no-value',
]"
>
<div
class="left-bar"
:style="{
width: calculatePercent(awards.aNewPv, awards.bNewPv).left,
}"
></div>
<div
class="right-bar"
:style="{
width: calculatePercent(awards.aNewPv, awards.bNewPv).right,
}"
></div>
<div class="cha">
左区 {{ awards.aNewPv }}/右区 {{ awards.bNewPv }}
</div>
</div>
</div>
<div class="progress-wrapper">
<div class="progress-wrapper__label">当月业绩</div>
<div
:class="[
'progress-bar-container',
awards.aMonthPv != 0 || awards.bMonthPv != 0
? 'has-value'
: 'no-value',
]"
>
<div
class="left-bar"
:style="{
width: calculatePercent(awards.aMonthPv, awards.bMonthPv)
.left,
}"
></div>
<div
class="right-bar"
:style="{
width: calculatePercent(awards.aMonthPv, awards.bMonthPv)
.right,
}"
></div>
<div class="cha">
左区 {{ awards.aMonthPv }}/右区 {{ awards.bMonthPv }}
</div>
</div>
</div>
<div class="progress-wrapper">
<div class="progress-wrapper__label">历史业绩</div>
<div
:class="[
'progress-bar-container',
awards.aSumPv != 0 || awards.bSumPv != 0
? 'has-value'
: 'no-value',
]"
>
<div
class="left-bar"
:style="{
width: calculatePercent(awards.aSumPv, awards.bSumPv).left,
}"
></div>
<div
class="right-bar"
:style="{
width: calculatePercent(awards.aSumPv, awards.bSumPv).right,
}"
></div>
<div class="cha">
左区 {{ awards.aSumPv }}/右区 {{ awards.bSumPv }}
</div>
</div>
</div>
<!-- NEW: Awards Sprint Progress Bar -->
</div>
</div>
</div>
<!-- 会员有效!-->
<div
class="create-time"
v-if="userInfo.pkCountry == 1 && userInfo.expireDate"
>
有效期:{{ userInfo.expireDate }}
</div>
<!-- 注册时间!-->
<div class="create-time">注册时间:{{ userInfo.registerTime }}</div>
<div class="countDown">
<div class="divs">{{ userDay }}</div>
<div class="margin-s">天</div>
<div class="divs">{{ userHr }}</div>
<div class="margin-s">时</div>
<div class="divs">{{ userMin }}</div>
<div class="margin-s">分</div>
<div class="divs">{{ userSec }}</div>
<div class="margin-s"></div>
</div>
</div>
</template>
<script>
import * as sid from "@/api/sidebaruserinfo.js";
import { memberInfo } from "@/api/person.js";
import { mapGetters } from "vuex";
import user from "@/store/modules/user";
export default {
name: "sidebarUserInfo",
computed: {
user() {
return user;
},
...mapGetters(["userInfo"]),
sprintProgress() {
const targetPvStr = this.awards?.targetPv;
const sumRealPvStr = this.awards?.sumRealPv; // 这是"小区仅需"的量,即差距
const targetPv = parseFloat(targetPvStr);
const sumRealPv = parseFloat(sumRealPvStr);
let achievedPv = 0;
let percentage = 0;
const numericTargetPv =
Math.floor((isNaN(targetPv) ? 0 : targetPv) * 100) / 100;
if (!isNaN(targetPv) && targetPv > 0) {
// sumRealPv 是差距,所以已完成的是 targetPv - sumRealPv
achievedPv = targetPv - (isNaN(sumRealPv) ? 0 : sumRealPv);
achievedPv = Math.max(0, Math.min(achievedPv, targetPv));
percentage = (sumRealPvStr / targetPv) * 100;
} else if (
!isNaN(targetPv) &&
targetPv === 0 &&
!isNaN(sumRealPv) &&
sumRealPv <= 0
) {
// 如果目标是0且差距也是0或负数表示已满足或超越0目标则认为是100%
achievedPv = 0;
percentage = 100;
}
const clampedPercentage = Math.min(100, Math.max(0, percentage));
return {
percentageString: `${Math.floor(clampedPercentage)}%`,
achieved: (Math.floor(achievedPv * 100) / 100).toFixed(2),
target: numericTargetPv.toFixed(2),
rawPercentage: clampedPercentage,
};
},
},
data() {
return {
countTime: 11183423,
userDay: 0,
userHr: 0,
awards: {},
userMin: 0,
userSec: 0,
intervalTimer: "",
toLiveBtn: "",
isHandImg: true,
userExtraInfo: {},
};
},
created() {
this.countdown();
this.getUserAwards();
this.getMemberInfo();
},
beforeDestroy() {
clearInterval(this.intervalTimer);
},
methods: {
getMemberInfo() {
memberInfo().then((res) => {
this.userExtraInfo = res.data;
});
},
clickTap() {
this.$router.push({
path: "/personal",
query: {
id: 5,
},
});
},
defaultSrc() {
this.isHandImg = false;
},
calculatePercent(left, right) {
left = parseFloat(left);
right = parseFloat(right);
const total = left + right;
if (isNaN(left) || isNaN(right) || total === 0) {
return { left: "0%", right: "0%" };
}
const leftPercent = Math.round((left / total) * 10000) / 100.0 + "%";
const rightPercent = Math.round((right / total) * 10000) / 100.0 + "%";
return { left: leftPercent, right: rightPercent };
},
// 倒计时事件
countdown() {
const that = this;
that.intervalTimer = setInterval(() => {
let time = new Date(this.userInfo.registerTime).getTime() / 1000;
let time1 = new Date().getTime() / 1000;
let time2 = parseInt(time1 - time);
that.countTime = time2;
that.countTime++;
let day = parseInt(that.countTime / 60 / 60 / 24);
let hr = parseInt((that.countTime / 60 / 60) % 24);
let min = parseInt((that.countTime / 60) % 60);
let sec = parseInt(that.countTime % 60);
day = day > 9 ? day : "0" + day;
hr = hr > 9 ? hr : "0" + hr;
min = min > 9 ? min : "0" + min;
sec = sec > 9 ? sec : "0" + sec;
// that.toLiveBtn = `${day}天${hr}时${min}分${sec}秒`
that.userDay = day;
that.userHr = hr;
that.userMin = min;
that.userSec = sec;
}, 1000);
},
//获取用户真实奖衔
getUserAwards() {
sid.getUserAwards().then((res) => {
this.awards = res.data;
});
},
goRouter(index) {
//1等级2奖衔
this.$router.push({
path: "/roadtoGrowth",
query: { index: index },
});
},
},
};
</script>
<style lang="scss" scoped>
.avatar {
img {
width: 60px;
height: 60px;
border-radius: 50%;
margin-top: 10px;
padding: 0 15px;
}
}
.user-name {
color: #333;
font-size: 18px;
//width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
::v-deep .el-input--suffix .el-input__inner {
background: #fff !important;
}
::v-deep .el-input--suffix .el-input__inner {
background: #fff !important;
}
.seamless-warp {
//height: 196px;
overflow: hidden;
line-height: 14px;
text-align: left;
font-size: 12px;
.item {
margin: 0;
text-align: center;
margin-left: -40px;
li {
list-style: none;
}
.title {
font-size: 12px;
line-height: 20px;
}
}
}
.sidebar-container {
width: 380px;
box-sizing: border-box;
padding: 20px;
background: #f4f8fb;
box-shadow: 5px 5px 20px 0px rgba(0, 76, 140, 0.2);
border-radius: 10px 10px 10px 10px;
opacity: 1;
margin-right: 20px;
.sidebarTop {
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
.sidebarHeader {
img {
width: 80px;
height: 80px;
border-radius: 50%;
}
}
.nameCountry {
margin-top: 20px;
display: flex;
align-content: center;
align-items: center;
.username {
font-size: 22px;
margin-right: 12px;
font-weight: bold;
color: #005bac;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
}
}
.user-level-info {
display: flex;
width: 200px;
margin-top: 16px;
align-items: center;
justify-content: space-around;
}
}
.create-time {
margin: 10px auto 10px auto;
color: #004c8c;
font-size: 14px;
text-align: center;
}
.countDown {
display: flex;
padding: 0 40px;
line-height: 40px;
font-size: 14px;
color: #004c8c;
justify-content: center;
.margin-s {
margin: 0 10px;
}
.divs {
padding: 0 10px;
height: 40px;
border-radius: 8px 8px 8px 8px;
opacity: 1;
border: 1px solid #b3d1ee;
color: #005bac;
font-size: 18px;
text-align: center;
line-height: 40px;
}
}
.awardscard {
width: 100%;
margin: 0 auto;
margin-top: 10px;
background-image: linear-gradient(180deg, #005bac 0%, #003f8c 100%);
border-radius: 10px;
position: relative;
.user-cards {
cursor: pointer;
padding: 16px 10px 16px;
z-index: 1;
.user-card-bg {
position: absolute;
right: 0;
top: 0;
img {
width: 145px;
height: 145px;
}
}
.user-cards-left {
.progress-bar-container {
flex: 1;
height: 16px;
border-radius: 10px;
margin: 5px;
position: relative;
overflow: hidden;
}
.progress-bar-container.no-value {
background: rgba(255, 255, 255, 0.1);
}
.progress-bar-container.has-value {
background: rgba(255, 255, 255, 0.2);
}
.left-bar {
position: absolute;
left: 0;
top: 0;
height: 100%;
background: #28a2ff;
border-radius: 10px 0 0 10px;
z-index: 1;
}
.right-bar {
position: absolute;
right: 0;
top: 0;
height: 100%;
background-color: #87cefa;
border-radius: 0 10px 10px 0;
z-index: 1;
}
.schedule,
.schedule1 {
display: none;
}
.current-schedule {
display: none;
}
.progress-wrapper {
display: flex;
align-items: center;
margin-top: 8px;
}
.progress-wrapper:first-child {
margin-top: 0px;
}
.progress-wrapper__label {
margin-right: 10px;
font-size: 12px;
color: #b3d1ee;
width: 60px;
text-align: right;
}
.cha {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 12px;
white-space: nowrap;
color: #002244;
text-shadow: none;
z-index: 2;
}
.state {
font-size: 10px;
color: #fff;
margin: 10px 0 0 0px;
span {
font-size: 14px;
font-weight: 600;
}
}
}
}
}
}
.honor_wrapper {
width: 100%;
.honor1 {
width: 100%;
font-size: 14px;
display: flex;
align-items: center;
justify-content: space-between;
margin: 10px 0 0px 0;
.honor-title-wrapper {
flex: 1;
> div:first-child {
color: #003366;
margin-bottom: 2px;
}
}
.honor-title {
font-weight: 700;
font-size: 20px;
color: #002244;
text-shadow: 0 0 7px rgba(227, 173, 170, 0.5),
0 0 12px rgba(227, 173, 170, 0.3);
}
.honor-title.is-empty-awards {
font-weight: normal;
font-size: 18px;
color: #7986cb;
text-shadow: none;
}
}
}
.authority-badge {
display: inline-block;
position: relative;
padding: 4px 10px;
font-size: 13px;
font-weight: bold;
color: #4a3b31;
background: linear-gradient(135deg, #ffd700, #ffa500);
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
line-height: normal;
overflow: hidden;
cursor: default;
}
.authority-badge::before {
content: "";
position: absolute;
top: 0;
left: -120%;
width: 50%;
height: 100%;
background: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.6),
transparent
);
transform: skewX(-25deg);
animation: shine 2.5s infinite 1s;
}
@keyframes shine {
0% {
left: -120%;
}
50% {
left: 120%;
}
100% {
left: 120%;
}
}
.awards-progress-summary {
text-align: center;
padding: 10px 0 15px 0;
.descriptive-text {
font-size: 12px;
color: #e0e0e0;
opacity: 1;
margin-right: 4px;
}
.highlight-name,
.highlight-pv {
font-size: 16px;
font-weight: bold;
padding: 0 3px;
margin: 0 1px;
display: inline-block;
color: #ffffff;
text-shadow: 0px 0px 5px rgba(0, 0, 0, 0.5);
}
}
.sprint-progress-container {
flex: 1;
height: 16px;
background: rgba(255, 255, 255, 0.3);
border-radius: 10px;
position: relative;
overflow: hidden;
margin: 5px;
}
.sprint-current-progress {
position: absolute;
left: 0;
top: 0;
height: 100%;
border-radius: 10px;
background: linear-gradient(135deg, #1e90ff 0%, #4169e1 100%);
transition: width 0.6s ease-in-out;
box-shadow: none;
overflow: hidden;
}
.sprint-current-progress::before {
content: "";
position: absolute;
top: 0;
left: -100%;
width: 80%;
height: 100%;
background: linear-gradient(
90deg,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0.3) 50%,
rgba(255, 255, 255, 0) 100%
);
transform: skewX(-25deg);
animation: sweepingShimmer 2s infinite linear;
border-radius: inherit;
}
@keyframes sweepingShimmer {
0% {
left: -100%;
}
100% {
left: 120%;
}
}
.sprint-progress-text {
width: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
white-space: nowrap;
text-align: center;
font-size: 12px;
color: #ffffff;
font-weight: bold;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
z-index: 2;
.target-award-name,
.achieved-value {
font-size: 12px;
font-weight: 700;
color: #fff;
text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.7);
margin: 0 2px;
}
.target-award-name {
color: #ffd700;
}
.achieved-value {
color: #f0e68c;
}
}
</style>