This commit is contained in:
@jyuhsin
2024-11-23 11:40:20 +08:00
parent 87f14ce8e4
commit 9cf6ec2b5e
3 changed files with 290 additions and 0 deletions
@@ -0,0 +1,88 @@
package io.v.nutz.mobile.mine;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import io.v.nutz.annontation.ViReturn;
import io.v.nutz.base.service.BaseService;
import io.v.nutz.trainEducation.models.TrainEduVideoWatchRecord;
import io.v.nutz.trainSignUp.models.TrainSignUpUser;
import io.v.nutz.web.commons.utils.ShiroUtil;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.*;
@IocBean
@At("/mobile/mine")
@Ok("json:full")
public class MobileMineController {
@Inject
private BaseService baseService;
@Inject
private Dao dao;
@At("")
@Ok("beetl:/mobile/mine/index.html")
public void index() {}
@At
@ViReturn
public Object getTrainActivity(Integer year) {
NutMap map = new NutMap();
//查询当前登录用户报名的所有活动
List<TrainSignUpUser> signUpUsers = dao.query(TrainSignUpUser.class, Cnd.where("userId", "=", ShiroUtil.getUserId())
.groupBy("activityId"));
//根据年份获取
if(year == null) {
map.put("count", signUpUsers.size());
year = DateUtil.thisYear();
} else {
Integer finalYear = year;
long count = signUpUsers.stream().filter(o -> Objects.equals(DateUtil.year(o.getSignUpTime()), finalYear)).count();
map.put("count", count);
}
List<Map<String, Object>> result = new ArrayList<>();
int brearYear = year - 5;
for (int i = year; i > brearYear; i--) {
Integer finalYear1 = i;
long count = signUpUsers.stream().filter(o -> Objects.equals(DateUtil.year(o.getSignUpTime()), finalYear1)).count();
result.add(Map.of("label", i, "value", count));
}
map.put("result", result);
return map;
}
@At
@ViReturn
public Object getVideo(Integer year) {
NutMap map = new NutMap();
List<TrainEduVideoWatchRecord> videoWatchRecords = dao.query(TrainEduVideoWatchRecord.class, Cnd.where("userId", "=", ShiroUtil.getUserId())
.groupBy("videoId"));
//根据年份获取
if(year == null) {
map.put("count", videoWatchRecords.size());
year = DateUtil.thisYear();
} else {
Integer finalYear = year;
long count = videoWatchRecords.stream().filter(o -> Objects.equals(DateUtil.year(o.getWatchTime()), finalYear)).count();
map.put("count", count);
}
List<Map<String, Object>> result = new ArrayList<>();
int brearYear = year - 5;
for (int i = year; i > brearYear; i--) {
Integer finalYear1 = i;
long count = videoWatchRecords.stream().filter(o -> Objects.equals(DateUtil.year(o.getWatchTime()), finalYear1)).count();
result.add(Map.of("label", i, "value", count));
}
map.put("result", result);
return map;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

@@ -0,0 +1,202 @@
<!--#
layout("/mobile/platform.html"){
#-->
<style>
.van-doc-card {
margin: 16px;
padding: 4px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0 8px 12px #ebedf0;
line-height: 20px;
font-size: 12px;
}
.van-cell {
padding: 8px 8px;
}
.main_content {
height: 230px;
background: linear-gradient(to top right, rgb(238, 163, 175), rgb(149, 214, 240));
border-radius: 0 0 20px 20px;
}
.user_info_container {
display: flex;
justify-content: space-between;
align-items: center;
padding: 40px 30px 40px;
}
.basic {
font-weight: bold;
}
.avatar {
background-color: lightgray;
width: 50px;
height: 50px;
border-radius: 50px;
text-align: center;
line-height: 50px;
}
.count_content {
text-align: center;
margin-bottom: 8px;
color: white;
}
.user_info_form {
position: relative;
top: -55px;
}
.query {
text-align: right;
color: white;
font-size: 14px;
margin-right: 20px;
}
</style>
<div id="app" v-cloak>
<div class="main_content">
<div class="user_info_container">
<div class="basic">
<div>Hi~</div>
<div>${@shiro.getPrincipalProperty('username')}老师,欢迎您!</div>
</div>
<div>
<div class="avatar">{{getShortName()}}</div>
</div>
</div>
<div class="count_content">
<van-badge :content="trainActivityCount" style="margin-right: 50px">
<div class="activity">品牌活动</div>
</van-badge>
<van-badge :content="videoCount">
<div>培训教育</div>
</van-badge>
</div>
<div class="query">
<span @click="openQuery()">筛选</span>
<van-icon name="exchange" style="position: relative; top: 2px"></van-icon>
</div>
<div class="van-doc-card" style="margin-top: 6px">
<van-cell icon="friends-o" title="性别" value="${@shiro.getPrincipalProperty('sex')}"></van-cell>
<van-cell icon="phone-o" title="手机号" value="${@shiro.getPrincipalProperty('mobile')}"></van-cell>
<van-cell icon="bar-chart-o" title="所属单位" value="${@shiro.getPrincipalProperty('unit').getName()}"></van-cell>
<van-cell icon="cluster-o" title="所属工会" value="${@shiro.getPrincipalProperty('union').getUnionname()}"></van-cell>
</div>
<div class="summary_content van-doc-card">
<div class="van-sidebar-item van-sidebar-item--select ml15 p10">
品牌活动
</div>
<canvas id="trainActivity" style="width: 100%; height: 170px"></canvas>
</div>
<div class="summary_content van-doc-card">
<div class="van-sidebar-item van-sidebar-item--select ml15 p10">
培训教育
</div>
<canvas id="trainVideo" style="width: 100%; height: 170px"></canvas>
</div>
</div>
<van-action-sheet
v-model="yearShow"
:actions="yearActions"
cancel-text="取消"
close-on-click-action
@cancel="yearShow = false"
@select="yearSelect"
></van-action-sheet>
</div>
<script src="https://gw.alipayobjects.com/os/lib/antv/f2/3.7.0/dist/f2.min.js"></script>
<script>
const vue = new Vue({
el: '#app',
data() {
return {
yearActions: [],
yearShow: false,
trainActivityCount: 0,
videoCount: 0,
pageForm: {
year: null,
}
}
},
methods: {
openQuery() {
this.yearShow = true
},
async yearSelect(action, index) {
if (action.name === '全部') {
this.pageForm.year = null
} else {
this.pageForm.year = action.name.replaceAll('年', '')
}
await this.init()
},
getShortName() {
const userName = "${@shiro.getPrincipalProperty('username')}"
return userName.length > 2 ? userName.substring(0, 2) : userName.substring(0, 1)
},
async getTrainActivity() {
const resp = await $.get('/mobile/mine/getTrainActivity', this.pageForm)
this.trainActivityCount = resp.data.count
const chart = new F2.Chart({
id: 'trainActivity',
pixelRatio: window.devicePixelRatio
})
chart.source(resp.data.result)
chart.scale({
label: {
range: [0, 1]
},
value: {
tickCount: 5,
min: 0
}
})
chart.area().position('label*value').color('l(90) 0:#1890FF 1:#f7f7f7').shape('smooth')
chart.line().position('label*value').color('l(90) 0:#1890FF 1:#f7f7f7').shape('smooth')
chart.render()
},
async getVideo() {
const resp = await $.get('/mobile/mine/getVideo', this.pageForm)
this.videoCount = resp.data.count
const chart = new F2.Chart({
id: 'trainVideo',
pixelRatio: window.devicePixelRatio
})
chart.source(resp.data.result)
chart.scale({
label: {
range: [0, 1]
},
value: {
tickCount: 5,
min: 0
}
})
chart.area().position('label*value').color('l(90) 0:#1890FF 1:#f7f7f7').shape('smooth')
chart.line().position('label*value').color('l(90) 0:#1890FF 1:#f7f7f7').shape('smooth')
chart.render()
},
async init() {
await this.getTrainActivity()
await this.getVideo()
}
},
async created() {
await this.init()
for (let i = new Date().getFullYear() - 6; i <= new Date().getFullYear(); i++) {
this.yearActions.unshift({name: i + '年'},)
}
this.yearActions.unshift({name: '全部'})
}
})
</script>
<!--#
}
#-->