Files
learning-system-portal/src/views/ucurrency/Index.vue
2022-12-28 17:17:14 +08:00

923 lines
27 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="u-currency">
<div class="myubi">
<div class="ubi-hear">
<h6>我的U币:{{uinfo.uCurrency< 0 ? 0 :uinfo.uCurrency}}</h6><span class="pointer" @click="dialogVisible = true">U币规则
<i class="el-icon-arrow-right"></i> </span>
<el-button icon="el-icon-document" @click="exportRecord()">导出记录</el-button>
</div>
<div style="max-height:600px;overflow-y:auto;padding-right:30px;min-width: 370px;">
<div class="Ubi-hist">
<h6>U币历史记录</h6><span>最多保留近7天的记录</span>
<div v-show="isShowChart" >
<div style="height:290px;min-width: 350px;" ref="chart"></div>
</div>
</div>
<div v-if="uCoinRecord.length > 0">
<div class="my-Recording" v-for="(day, index) in uCoinRecord" :key="index">
<h3>{{day.dayNmae}}</h3>
<div class="Recording-info" v-for="info in day.list">
<div class="info-tit">{{info.content}}</div>
<div class="info-Gold"><img :src="`${webBaseUrl}/images/Uimg.png`" alt="">{{info.uvalue > 0? '+':''}}
{{info.uvalue}}</div>
</div>
</div>
</div>
<div v-else class="home-no-list" style="margin-top:150px">
<img class="img" style="width:76px;height:76px" :src="`${webBaseUrl}/images/homeWu/u-wu.png`" alt=""
srcset="">
<p class="text">最近7天您可能太忙了快开始努力获得U币吧</p>
</div>
</div>
</div>
<div class="experience">
<div class="exp-hear">
<div class="exp-hear-text">
学习天数排行榜
<el-tooltip placement="top" effect="light">
<div slot="content" style="line-height:13px;">
<!--
所有用户经验值TOP排行榜单通过学习贡献等行为可以获得经验值 </br>
系统已经根据您在4月23日新系统上线之后产生的学习数据对经验值进行</br>
<span style="line-height:15px;">了初始化更早的数据以及老系统中产生的数据将在2022年底一次性</span></br>
补充到您的经验值中请您耐心等待
-->
所有用户学习天数TOP排行榜单每活跃学习1天可累计学习天数
</div>
<svg-icon style="margin-left: 5px;font-size:20px;padding-top: 4px;" icon-class="doubt"></svg-icon>
</el-tooltip>
<span class="exp-hear-textbor"></span>
</div>
<div class="exp-hear-xiala">
<el-dropdown trigger="click" @command="handleCommand">
<span class="el-dropdown-link pointer">
{{name}}<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="total">累计</el-dropdown-item>
<!-- <el-dropdown-item command="weeks">本周</el-dropdown-item>
<el-dropdown-item command="months">本月</el-dropdown-item>
<el-dropdown-item command="years">本年</el-dropdown-item> -->
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
<div class="myselftext">
<div class="myranking">
累计排名 : <span> {{currentUserRankingTotalData.rankNo}}</span>
</div>
<div class="myexperience">
累计学习天数 : <span>{{currentUserRankingTotalData.rankValue}}</span>
</div>
</div>
<!-- 注释经验值等级进度条
<div class="exp-bar">
<h6>{{currentUserRankingTotalData.rankValue}}/{{currentUserRankingTotalData.endValue}}</h6>
<div class="exp-barbox">
<el-progress :percentage="currentUserRankingTotalData.rankValue*100/currentUserRankingTotalData.endValue" color="#387DF7"></el-progress>
</div>
<div class="exp-barname">
<span>{{current.start}}</span>
<span>{{current.end}}</span>
</div>
</div>
-->
<div class="exp-table">
<div class="table-hear">
<div style="margin-left:5px">排名</div>
<div style="margin-left:5px">姓名</div>
<div class="bm">部门</div>
<div class="jy">学习天数</div>
</div>
<div>
<div class="table-hear" style="margin-top:40px;border-bottom: 1px solid #ddd;padding-bottom:20px"
v-for="(ran,index) in rankingData" :key="ran.id">
<div class="tab-rank">
<img v-if="index == 0" :src="`${webBaseUrl}/images/rank1.png`" alt="" />
<img v-if="index == 1" :src="`${webBaseUrl}/images/rank2.png`" alt="" />
<img v-if="index == 2" :src="`${webBaseUrl}/images/rank3.png`" alt="" />
<div v-if="index > 2" style="line-height: 40px;padding-left:15px;font-size: 16px;color: #333333;">
{{index+1}}</div>
</div>
<div class="tab-name">
<author-img :avatar="ran.authorInfo.avatar" :aid="ran.authorInfo.aid" :sex="ran.authorInfo.sex">
</author-img> <span>{{ran.authorInfo.name}}</span>
</div>
<div class="bm tab-bm" style="margin-left:30px;">{{cutOrgNamePath(ran.authorInfo.orgInfo)}}</div>
<div class="jy tab-jy">
<div v-if="cycle == 'total'" style="font-size: 18px;color: #333333;font-weight: 600;">{{ran.total}}</div>
<div v-if="cycle == 'months'" style="font-size: 18px;color: #333333;font-weight: 600;">{{ran.months}}</div>
<div v-if="cycle == 'years'" style="font-size: 18px;color: #333333;font-weight: 600;">{{ran.years}}</div>
<div v-if="cycle == 'weeks'" style="font-size: 18px;color: #333333;font-weight: 600;">{{ran.weeks}}</div>
</div>
</div>
</div>
<div v-if="currentUserRankingData.rankingNo>5" style="margin-top:20px;border-bottom: 1px solid #ddd;padding-bottom:40px">
<div v-if="currentUserRankingData.rankingNo>5" class="omit">
<div>.</div> <div>.</div> <div>.</div>
</div>
</div>
<div v-if="currentUserRankingData.rankingNo>4" class="table-hear" style="margin-top:40px;border-bottom: 1px solid #ddd;padding-bottom:20px">
<div style="color: #0059FF;line-height: 40px;padding-left:15px;font-size: 16px;" class="tab-rank">
{{currentUserRankingData.rankingNo}}</div>
<div class="tab-name">
<author-img :avatar="userInfo.avatar" :aid="userInfo.aid"
:sex="userInfo.sex"></author-img> <span style="color: #0059FF;">{{userInfo.name}}</span>
</div>
<div class="bm tab-bm" style="margin-left:30px;color: #0059FF;">{{cutOrgNamePath(userInfo.departFullName)}}
</div>
<div class="jy tab-jy">
<div v-if="cycle == 'total'" style="font-size: 18px;color: #333333;font-weight: 600;color: #0059FF;">{{currentUserRankingData.total}}</div>
<div v-if="cycle == 'months'" style="font-size: 18px;color: #333333;font-weight: 600;color: #0059FF;">{{currentUserRankingData.months}}</div>
<div v-if="cycle == 'years'" style="font-size: 18px;color: #333333;font-weight: 600;color: #0059FF;">{{currentUserRankingData.years}}</div>
<div v-if="cycle == 'weeks'" style="font-size: 18px;color: #333333;font-weight: 600;color: #0059FF;">{{currentUserRankingData.weeks}}</div>
</div>
</div>
</div>
</div>
<el-dialog :visible.sync="dialogVisible" :show-close="false" width="716px" top="13%">
<div class="dialog-box">
<div class="box-top">
<p style="font-size: 26px;font-weight: 600;margin-bottom: 4px;">U币规则</p>
<p style="font-size: 14px;line-height: 20px;">学员每日通过积分规则获得积分的上限为150积分当天达到上限后 不能通过积分规则获得积分</p>
</div>
<div style="max-height:420px;overflow-y: auto;">
<div class="box-table">
<p class="table-title portal-title-tow"><span></span>学习</p>
<el-table :data="tableData" style="">
<el-table-column prop="name" label="分类" width="180" align="center"></el-table-column>
<el-table-column prop="name" label="描述" width="180" align="center">
<template slot-scope="scope">
<p v-for="(rem,index) in scope.row.hear" :key="index">{{rem}}</p>
<p style="font-size:12px;color: #999999;" v-if="scope.row.label">{{scope.row.label}}</p>
</template>
</el-table-column>
<el-table-column label="经验值/U币" align="center">
<template slot-scope="scope">
<p style="font-size:16px;color: #333333;font-weight: 600;" v-for="(val,index) in scope.row.value" :key="index">{{val}}
</p>
</template>
</el-table-column>
<el-table-column prop="upperlimit" label="每日上限" align="center">
</el-table-column>
</el-table>
</div>
<div class="box-table">
<p class="table-title portal-title-tow"><span></span>知识贡献</p>
<el-table :data="tableList" style="">
<el-table-column prop="name" label="分类" width="180" align="center">
</el-table-column>
<el-table-column prop="name" label="描述" width="180" align="center">
<template slot-scope="scope">
<p v-for="(rem,index) in scope.row.hear" :key="index">{{rem}}</p>
</template>
</el-table-column>
<el-table-column label="经验值/U币" align="center">
<template slot-scope="scope">
<p style="font-size:16px;color: #333333;font-weight: 600;" v-for="(val,index) in scope.row.value"
:key="index">{{val}}</p>
</template>
</el-table-column>
<el-table-column prop="upperlimit" align="center" label="每日上限">
</el-table-column>
</el-table>
</div>
</div>
<!--
<div class="dialog-close" @click="dialogVisible=false">
<img style="width:86px;height:86px" :src="`${webBaseUrl}/images/homeWu/u-close.png`" alt="">
</div>
-->
</div>
</el-dialog>
</div>
</template>
<script>
import apiStat from '@/api/phase2/stat.js';
import { mapGetters } from 'vuex';
import {getUType } from '@/utils/tools.js'
import authorImg from '@/components/Portal/authorImg.vue';
import author from '@/components/Portal/authorInfo.vue';
import apiUser from "@/api/system/user.js";
import * as echarts from 'echarts'
import {
translate,
experienceValue,
cutOrgNamePath
} from "@/utils/tools.js";
export default {
computed: {
...mapGetters(['userInfo']),
},
components: {
authorImg,
author
},
data() {
return {
percentageNum:0,
cutOrgNamePath:cutOrgNamePath,
chatData:[],
isShowChart:false,
current: {
percentage: 0
},
experienceValue,
translate,
cycle: 'total',
name: '累计',
getUType,
dialogVisible: false,
tableData: [{
name: '试听学习',
hear: ['每日累计学习10分钟', '每日累计学习20分钟', '每日累计学习30分钟', '每日累计学习45分钟', '每日累计学习60分钟', ],
value: ['+10', '+20', '+30', '+40', "+50"],
upperlimit: 50
},
{
name: '案例学习',
hear: ['完成一个案例的阅读', ],
value: ['+5'],
upperlimit: 30,
label: '最低3分钟'
},
{
name: '文章学习',
hear: ['完成一个文章的阅读', ],
value: ['+5'],
upperlimit: 30,
label: '最低2分钟'
},
],
tableList: [{
name: '发布音视频课程',
hear: ['完成一个音视频课发布', ],
value: ['+60'],
upperlimit: null
},
{
name: '面授课记录',
hear: ['有一个完成的面授课记录(<4h', '有一个完成的面授课记录(>=4h'],
value: ['+40', '+60'],
upperlimit: null
},
{
name: '发布文章',
hear: ['每发布1篇文章', ],
value: ['+40'],
upperlimit: null
},
{
name: '发布案例',
hear: ['每发布1篇案例', ],
value: ['+50'],
upperlimit: null
},
{
name: '发布笔记',
hear: ['每发布公开笔记1篇', ],
value: ["+5"],
upperlimit: 30
},
{
name: '发表评论',
hear: ['在课程问答案例中发表1个评论', ],
value: ['+2'],
upperlimit: 20
},
],
uCoinRecord: [],
chart: null,
currentUserRankingData: {},
currentUserRankingTotalData:{
rankNo:0, // 经验值累计排名
rankValue:0 ,// 经验值累计,
endValue:0 // 累计经验值进度条最大值
},
rankingData: [],
uinfo: {
uCurrency: 0 // 用户累计U币
},
}
},
mounted() {
this.getList();
this.getRanking();
this.getLevel();
},
watch:{
isShowChart(val) {
if(val) {
this.initChat(this.chatData);
}
}
},
updated() {
this.chart && this.chart.resize();
},
methods: {
handleCommand(e) {
this.cycle = e;
this.name = this.translate(e)
this.getRanking();
},
getRanking() {
let data = {
aid: this.userInfo.aid, // #用户id
statType: 11, // #统计类型 10学习时长 11 学习天数 20表经验值 30表u币 40表获取天数
field: this.cycle, // #统计周期 todays-当天,weeks-周,months-月,years-年 total-总计
num: 5, // #显示的条数
}
apiStat.getRanking(data).then(res => {
if (res.status == 200) {
if (res.result.currentUserRankingData) {
res.result.currentUserRankingData.authorInfo = {
aid: "",
name: "",
orgInfo: "",
avatar: "",
sex: null
}
this.getUserData([res.result.currentUserRankingData.aid], [res.result.currentUserRankingData])
this.currentUserRankingData = res.result.currentUserRankingData;
if(this.cycle == 'total'){
// this.current = this.experienceValue(res.result.currentUserRankingData.total);
this.currentUserRankingTotalData.rankNo = res.result.currentUserRankingData.rankingNo;
this.currentUserRankingTotalData.rankValue = res.result.currentUserRankingData.total;
// this.currentUserRankingTotalData.endValue = this.current.endValue;
}
}
const ids = [];
res.result.rankingData.forEach(item => {
ids.push(item.aid)
item.authorInfo = {
aid: "",
name: "",
orgInfo: "",
avatar: "",
sex: null
}
})
this.getUserData(ids, res.result.rankingData)
this.rankingData = res.result.rankingData;
}
})
},
getUserData(ids, list) {
const noReapetIds = [...new Set(ids)];
apiUser.getByIds(noReapetIds).then(res => {
if (res.status == 200) {
list.forEach((item, index) => {
res.result.some(author => {
if (author.aid == item.aid) {
item.authorInfo = author;
return true;
} else {
return false;
}
});
});
} else {
this.$message.error(res.message);
}
});
},
exportRecord() {
let downUrl='';
// let curHost=window.location.host;
// console.log(window.location.host,'window.location.host');
// if(curHost=='localhost' || curHost='127.0.0.1'){
// downUrl=process.env.VUE_APP_BOE_WEB_URL+process.env.VUE_APP_CESOURCE_BASE_API+'/xboe/m/stat/usercoinrecord/export?aid=' + this.userInfo.aid;
// }else{
// //let urlPre = window.location.protocol + '//' + window.location.host;
// downUrl=process.env.VUE_APP_CESOURCE_BASE_API+'/xboe/m/stat/usercoinrecord/export?aid=' + this.userInfo.aid;
// }
downUrl=process.env.VUE_APP_STAT_BASE_API+'/xboe/m/stat/usercoinrecord/export';
const el = document.createElement('a');
el.style.display = 'none';
el.setAttribute('target', '_blank');
el.setAttribute('download', '我的U币记录');
el.href = downUrl;
document.body.appendChild(el);
el.click();
document.body.removeChild(el);
},
initChat(chatData) {
this.chart = echarts.init(this.$refs.chart);
const option = {
tooltip: {
trigger: 'item'
},
legend: {
top: 'center',
right: 60,
orient: 'vertical',
itemWidth: 8,
itemHeight: 8,
borderRadius: '50%',
itemGap: 26,
selectedMode: false,
formatter: function(name) {
let data = option.series[0].data;
let total = 0;
let tarValue = 0; //每一项值
for (let i = 0; i < data.length; i++) {
total += data[i].value;
if (data[i].name == name) {
tarValue = data[i].value;
}
}
let p = total != 0 ? Math.round((tarValue / total) * 100) + '%' : 0 + '%';
return ` ${p} ${name}`
}
},
series: [{
// name: 'name',
type: 'pie',
radius: ['50%', '40%'],
avoidLabelOverlap: false,
center: ['32%', '50%'],
itemStyle: {
borderRadius: 0,
borderColor: '#fff',
borderWidth: 2,
normal: {
color: function(colors) {
let colorList = ['#5bb9fe', '#f7b36b', '#72e5d5', '#e1e1f9'];
return colorList[colors.dataIndex];
},
}
},
label: {
show: true,
position: 'center',
formatter:`{total|${this.percentageNum}%}\n{active|来源top3}`,
rich:{
total:{
fontSize:20,
color:'#000',
},
active: {
fontSize:16,
color:'#333',
lineHeight:30,
}
}
},
labelLine: {
show: false
},
data: chatData,
}]
};
this.chart.setOption(option);
},
getList() {
apiStat.userCoinList(this.userInfo.aid, 7).then(res => {
if (res.status == 200) {
this.uCoinRecord = [];
for (let key in res.result.uCoinRecord) {
this.uCoinRecord.push({
dayNmae: key,
list: res.result.uCoinRecord[key]
})
}
let chatData = [];
let total = null;
let top3 = null;
let totalList = [];
for (let key in res.result.chatData) {
if(res.result.chatData[key] > 0) {
this.isShowChart = true;
if(key !== 'other') {
top3 += res.result.chatData[key];
}
}
total += res.result.chatData[key];
totalList.push(res.result.chatData[key]);
chatData.push({
value: res.result.chatData[key],
name: this.getUType(key)
})
}
this.percentageNum = ((top3/total)*100).toFixed(2);
this.chatData = chatData;
this.initChat(chatData);
}
})
},
getLevel() { //获取用户累计U币
apiStat.getUserStatTotalInfo(this.userInfo.aid).then(res => {
if (res.status == 200) {
this.uinfo.uCurrency = res.result.uvalue;
this.$bus.$emit('u-Currency',res.result.uvalue)
}
});
},
}
}
</script>
<style lang="scss" scoped>
.u-currency {
padding: 10px 18px;
display: flex;
justify-content: space-between;
overflow-x: auto;
}
.experience {
font-size: 16px;
min-width: 480px;
font-weight: 600;
color: #333333;
}
.myubi {
flex: 1;
padding-right: 30px;
}
::v-deep .el-dialog {
border-radius: 8px;
}
::v-deep .el-dialog__header {
display: none;
}
::v-deep .el-dialog__body {
padding: 0;
// ::v-deep .el-table td.el-table__cell{
// font-size: 14px;
// color: #333333;
// }
}
::v-deep .el-table__body-wrapper {
font-size: 14px;
color: #333333;
}
.dialog-box {
position: relative;
.dialog-close {
position: absolute;
left: 50%;
transform: translate(-50%);
bottom: -127px;
}
.box-top {
color: #FBA511;
padding: 26px 212px 17px 61px;
background: url('../../../public/images/homeWu/u-bg.png') no-repeat;
}
.box-table {
padding: 26px 14px 40px 66px;
.table-title {
margin-bottom: 18px;
span {
display: inline-block;
width: 6px;
height: 18px;
background: #0060FF;
border-radius: 4px;
margin-right: 10px;
}
}
}
}
.Recording-info {
margin-top: 12px;
height: 45px;
border-bottom: 1px solid #ddd;
.info-tit {
float: left;
font-size: 14px;
font-weight: 400;
color: #333333;
line-height: 40px;
}
.info-Gold {
float: right;
font-size: 18px;
color: #333333;
font-weight: 400;
line-height: 40px;
img {
width: 54px;
height: 32px;
vertical-align: middle;
}
}
}
.Ubi-hist {
margin-top: 15px;
h6 {
font-size: 16px;
font-weight: 600;
color: #333333;
margin: 0;
float: left;
}
span {
font-size: 14px;
font-weight: 600;
color: #999999;
}
}
.ubi-hear {
height: 40px;
button {
width: 140px;
height: 40px;
margin-right: 30px;
border-radius: 2px;
border: 1px solid rgba(153, 153, 153, 0.35);
float: right;
}
span {
font-size: 14px;
font-weight: 400;
color: #333333;
line-height: 40px;
}
h6 {
margin: 0;
margin-right: 18px;
line-height: 40px;
float: left;
color: #333333;
font-size: 18px;
font-weight: 600;
}
}
.omit {
padding-left: 20px;
div {
font-size: 30px;
line-height: 10px;
color: #D8D8D8;
}
}
.exp-table {
//width: 100%;
padding-left: 25px;
padding-right: 20px;
.table-hear {
display: flex;
div {
min-width: 90px;
font-size: 14px;
font-weight: 400;
color: #999999;
}
.bm {
flex: 1;
margin-left: 20px;
}
.jy {
margin-left: auto;
text-align: right;
margin-right: 0;
text-align: center;
}
}
}
.myselftext {
height: 75px;
padding: 0 25px;
//width: 100%;
display: flex;
.myranking {
flex: 1;
line-height: 75px;
font-size: 14px;
font-weight: 400;
color: #666666;
span {
color: #333;
font-weight: 600;
font-size: 18px;
}
}
.myexperience {
text-align: right;
line-height: 75px;
margin-left: 120px;
font-size: 14px;
font-weight: 400;
margin-right: -45px;
color: #666666;
span {
color: #333;
font-weight: 600;
font-size: 18px;
}
}
}
.tab-jy {
padding-top: 10px;
div {
line-height: 28px;
width: 70px;
text-align: center;
font-size: 18px;
color: #333333;
font-weight: 600;
height: 28px;
background: #F7F8FA;
border-radius: 14px;
}
}
.tab-bm {
line-height: 40px;
}
.tab-name {
display: flex;
min-width:98px;
::v-deep .item-author {
min-width: 50px !important;
}
img {
width: 40px;
height: 40px;
vertical-align: middle;
}
span {
display: block;
margin-top: 10px;
color: #333333;
font-size: 14px;
font-weight: 600;
}
}
.tab-rank {
img {
width: 40px;
height: 40px;
}
}
.experience {
flex: 1;
.exp-hear {
//width: 100%;
height: 65px;
background: url('../../../public/images/expbg.png') no-repeat 100% / 100%;
.exp-hear-text {
float: left;
line-height: 65px;
margin-left: 25px;
font-size: 18px;
font-weight: 600;
color: #333333;
position: relative;
z-index: 888;
.exp-hear-textbor {
width: 108px;
height: 10px;
background: #9CC7FC;
border-radius: 9px;
display: inline-block;
position: absolute;
left: 0;
z-index: -1;
top: 60%;
}
}
.exp-hear-xiala {
line-height: 65px;
float: right;
margin-right: 15px;
}
}
.exp-bar {
//width: 100%;
h6 {
font-size: 14px;
color: #666666;
font-weight: 600;
margin: 0;
margin-left: 50px;
}
.exp-barname {
//width: 100%;
padding: 20px 35px;
display: flex;
span {
flex: 1;
}
}
.exp-barbox {
//width: 100%;
height: 8px;
// background: #ECF1FE;
border-radius: 6px;
margin-left: 25px;
margin-top: 3px;
position: relative;
z-index: 1;
::v-deep .el-progress__text {
display: none;
}
.exp-bar-cont {
width: 230px;
height: 6px;
background: #0059FF;
border-radius: 6px;
opacity: 0.56;
position: absolute;
left: 0;
z-index: 999;
}
}
}
}
</style>