Files
learning-system-portal/src/views/ucurrency/Index.vue

848 lines
25 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}}</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">
<div class="Ubi-hist">
<h6>U币历史记录</h6><span>最多保留近7天的记录</span>
<div style="height:290px;min-width: 350px;" ref="chart"></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">
<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">
经验值排行榜<svg-icon style="margin-left: 5px;font-size:20px;padding-top: 4px;" icon-class="doubt"></svg-icon>
<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" style="height:550px;overflow-y:auto">
<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;">{{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>4" class="omit">
<div>.</div>
<div>.</div>
<div>.</div>
</div>
<div class="table-hear" style="margin-top:40px;border-bottom: 1px solid #ddd;padding-bottom:20px"
v-if="currentUserRankingData.authorInfo && currentUserRankingData.authorInfo.aid && currentUserRankingData.rankingNo>4">
<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="currentUserRankingData.authorInfo.avatar" :aid="currentUserRankingData.authorInfo.aid"
:sex="currentUserRankingData.authorInfo.sex"></author-img> <span
style="color: #0059FF;">{{currentUserRankingData.authorInfo.name}}</span>
</div>
<div class="bm tab-bm" style="margin-left:30px;color: #0059FF;">{{currentUserRankingData.authorInfo.orgInfo}}
</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">
<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"></el-table-column>
<el-table-column prop="name" label="描述" width="180">
<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 align="right" label="经验值/U币">
<template slot-scope="scope">
<p style="font-size:16px;color: #999999;" v-for="(val,index) in scope.row.value" :key="index">{{val}}
</p>
</template>
</el-table-column>
<el-table-column prop="upperlimit" align="right" label="每日上限">
</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">
</el-table-column>
<el-table-column prop="name" label="描述" width="180">
<template slot-scope="scope">
<p v-for="(rem,index) in scope.row.hear" :key="index">{{rem}}</p>
</template>
</el-table-column>
<el-table-column align="right" label="经验值/U币">
<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="right" 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
} from "@/utils/tools.js";
export default {
computed: {
...mapGetters(['userInfo']),
},
components: {
authorImg,
author
},
data() {
return {
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();
},
methods: {
handleCommand(e) {
this.cycle = e;
this.name = this.translate(e)
this.getRanking();
},
getRanking() {
let data = {
aid: this.userInfo.aid, // #用户id
statType: 20, // #统计类型 10学习时长 11 学习天数 20表经验值 30表u币 40表获取天数
field: this.cycle, // #统计周期 todays-当天,weeks-周,months-月,years-年 total-总计
num: 4, // #显示的条数
}
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: 100,
orient: 'vertical',
itemWidth: 8,
itemHeight: 8,
borderRadius: '50%',
itemGap: 26,
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: false,
position: 'center',
},
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 = [];
for (let key in res.result.chatData) {
chatData.push({
value: res.result.chatData[key],
name: this.getUType(key)
})
}
this.initChat(chatData);
}
})
},
getLevel() { //获取用户累计U币
apiStat.getUserStatTotalInfo(this.userInfo.aid).then(res => {
if (res.status == 200) {
this.uinfo.uCurrency = 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: auto;
font-size: 14px;
font-weight: 400;
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>