This commit is contained in:
张良(004796)
2024-03-28 18:20:50 +08:00
parent e955c21991
commit c25e43359c
14 changed files with 180 additions and 29 deletions

View File

@@ -18,7 +18,7 @@ public class Clear2HoursJob {
// 每隔小时执行一次
@Scheduled(cron = "0 0 0/2 * * ? *")
@Scheduled(cron = "0 0 0/1 * * ?")
public void clearRun() {
try {
log.info("定时删除动态== 开始");

View File

@@ -32,6 +32,11 @@ public class HomeRecommendJob {
}catch (Exception e){
log.error("刷新首页推荐用户失败",e);
}
try {
homeManager.refreshHomeAnchorTopCache();
}catch (Exception e){
log.error("刷新首页推荐置顶用户失败",e);
}
}

View File

@@ -1,4 +1,4 @@
package com.ruoyi.cai.controller;
package com.ruoyi.web.controller.cai.admin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -59,26 +59,21 @@ public class AnchorTopController extends BaseController {
return R.ok(anchorTopService.getById(id));
}
/**
* 新增主播限时置顶
*/
@GetMapping("/getAnchorTopByUserCode")
public R<AnchorTopAdminVo> getAnchorTopByUserCode(String usercode) {
AnchorTopAdminVo anchorTop = anchorTopService.getAnchorTopByUserCode(usercode);
return R.ok(anchorTop);
}
@SaCheckPermission("cai:anchorTop:add")
@Log(title = "主播限时置顶", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody AnchorTop bo) {
return toAjax(anchorTopService.save(bo));
}
/**
* 修改主播限时置顶
*/
@SaCheckPermission("cai:anchorTop:edit")
@Log(title = "主播限时置顶", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody AnchorTop bo) {
return toAjax(anchorTopService.updateById(bo));
public R<Void> add(@RequestBody AnchorTopAdminVo bo) {
boolean save = anchorTopService.saveOrUpdateAnchorTop(bo);
return R.ok();
}
/**

View File

@@ -17,6 +17,8 @@ public class RedisHttpConstant {
public static final String WITHDRAW_RANK_REDIS = REDIS_P + "withdrawRank:%s:%s";
public static final String RECHARGE_RANK_REDIS = REDIS_P + "rechargeRank:%s:%s";
public static final String ANCHOR_COUNT_REDIS = REDIS_P + "anchorCount:%s";
public static final String HOME_RECOMMEND_TOP_REDIS = REDIS_P + "homeRecommendAnchorTop";
public static final String HOME_RECOMMEND_REDIS = REDIS_P + "homeRecommendAnchor";
public static final String HOME_NEW_REDIS = REDIS_P + "homeNewAnchor";
public static final String HOME_ACTIVE_REDIS = REDIS_P + "homeActiveAnchor";

View File

@@ -43,6 +43,5 @@ public class AnchorTop implements Serializable {
private Long sortBy;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}

View File

@@ -30,7 +30,9 @@ public class AnchorTopAdminVo extends AnchorTop {
* 性别
*/
private Integer gender;
private Integer age;
private Long age;
private Integer status;
private Integer onlineStatus;
// 1-生效 2-过期 3-待生效
private Integer topStatus;
}

View File

@@ -3,6 +3,8 @@ package com.ruoyi.cai.dto.app.query.index;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "主播查询条件")
public class AnchorListQuery {
@@ -21,4 +23,6 @@ public class AnchorListQuery {
@Schema(hidden = true)
private Integer onlineStatus;
@Schema(hidden = true)
private List<Long> ignoreUserIds;
}

View File

@@ -17,7 +17,7 @@ public class AnchorListVo {
private Integer online;
@Schema(description = "用户ID")
private String userId;
private Long userId;
/**
* 头像
*/

View File

@@ -2,6 +2,7 @@ package com.ruoyi.cai.manager;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.cai.constant.RedisHttpConstant;
import com.ruoyi.cai.dto.admin.vo.AnchorTopAdminVo;
import com.ruoyi.cai.dto.app.query.index.AnchorListQuery;
import com.ruoyi.cai.dto.app.vo.AnchorListVo;
import com.ruoyi.cai.dto.app.vo.setting.AppHomeConfig;
@@ -10,9 +11,11 @@ import com.ruoyi.cai.enums.home.AnchorListQueryTypeEnum;
import com.ruoyi.cai.mq.AmqpProducer;
import com.ruoyi.cai.mq.handle.dto.LoginNotifyDTO;
import com.ruoyi.cai.service.AnchorService;
import com.ruoyi.cai.service.AnchorTopService;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.ServletUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
@@ -21,6 +24,7 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* 首页主播随机推荐
@@ -31,8 +35,16 @@ public class HomeManager {
@Autowired
private AnchorService anchorService;
@Autowired
private AnchorTopService anchorTopService;
@Autowired
private RedissonClient redissonClient;
public void refreshHomeAnchorTopCache(){
List<AnchorListVo> anchorTop = anchorTopService.anchorTop(4);
RBucket<List<AnchorListVo>> bucket = redissonClient.getBucket(RedisHttpConstant.HOME_RECOMMEND_TOP_REDIS);
bucket.set(anchorTop);
}
public void refreshHomeRecommendCache(){
PageQuery pageQuery = new PageQuery();
pageQuery.setPageSize(200);
@@ -86,7 +98,7 @@ public class HomeManager {
}else if(anchorListQueryTypeEnum == AnchorListQueryTypeEnum.NEW){
RBucket<List<AnchorListVo>> bucket = redissonClient.getBucket(RedisHttpConstant.HOME_NEW_REDIS);
vos = bucket.get();
} else {
} else { // 同城查询
if(query.getCityId() == null){
return Collections.emptyList();
}
@@ -95,11 +107,22 @@ public class HomeManager {
Collections.shuffle(vos);
Integer pageNum = pageQuery.getPageNum();
int startIndex = (pageNum - 1) * pageQuery.getPageSize();
if(startIndex > vos.size()){
if(startIndex > vos.size()){ // 超出范围
return Collections.emptyList();
}
int endIndex = Math.min(startIndex+pageQuery.getPageSize(), vos.size());
return vos.subList(startIndex, endIndex);
List<AnchorListVo> result = vos.subList(startIndex, endIndex);
if(anchorListQueryTypeEnum == AnchorListQueryTypeEnum.DEFAULT && pageNum == 1){
List<AnchorListVo> list = getAnchorTopList();
result.addAll(0, list);
}
return result;
}
public List<AnchorListVo> getAnchorTopList(){
RBucket<List<AnchorListVo>> bucketTop = redissonClient.getBucket(RedisHttpConstant.HOME_RECOMMEND_TOP_REDIS);
List<AnchorListVo> anchorListVos = bucketTop.get();
return anchorListVos == null ? Collections.emptyList() : anchorListVos;
}
public List<AnchorListVo> recommendFollows(Integer limit) {

View File

@@ -4,8 +4,11 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.cai.domain.AnchorTop;
import com.ruoyi.cai.dto.admin.vo.AnchorTopAdminVo;
import com.ruoyi.cai.dto.app.vo.AnchorListVo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 主播限时置顶Mapper接口
*
@@ -15,4 +18,6 @@ import org.apache.ibatis.annotations.Param;
public interface AnchorTopMapper extends BaseMapper<AnchorTop> {
Page<AnchorTopAdminVo> pageAdmin(@Param("build") Page<Object> build, @Param("bo") AnchorTopAdminVo bo);
List<AnchorListVo> anchorTop(@Param("limit") int limit);
}

View File

@@ -4,8 +4,11 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.cai.domain.AnchorTop;
import com.ruoyi.cai.dto.admin.vo.AnchorTopAdminVo;
import com.ruoyi.cai.dto.app.vo.AnchorListVo;
import com.ruoyi.common.core.domain.PageQuery;
import java.util.List;
/**
* 主播限时置顶Service接口
*
@@ -15,4 +18,10 @@ import com.ruoyi.common.core.domain.PageQuery;
public interface AnchorTopService extends IService<AnchorTop> {
Page<AnchorTopAdminVo> pageAdmin(PageQuery pageQuery, AnchorTopAdminVo bo);
boolean saveOrUpdateAnchorTop(AnchorTopAdminVo bo);
AnchorTopAdminVo getAnchorTopByUserCode(String usercode);
List<AnchorListVo> anchorTop(int limit);
}

View File

@@ -1,13 +1,22 @@
package com.ruoyi.cai.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.domain.AnchorTop;
import com.ruoyi.cai.domain.User;
import com.ruoyi.cai.dto.admin.vo.AnchorTopAdminVo;
import com.ruoyi.cai.dto.app.vo.AnchorListVo;
import com.ruoyi.cai.mapper.AnchorTopMapper;
import com.ruoyi.cai.service.AnchorTopService;
import com.ruoyi.cai.service.UserService;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 主播限时置顶Service业务层处理
@@ -18,8 +27,68 @@ import org.springframework.stereotype.Service;
@Service
public class AnchorTopServiceImpl extends ServiceImpl<AnchorTopMapper,AnchorTop> implements AnchorTopService {
@Autowired
private UserService userService;
@Override
public Page<AnchorTopAdminVo> pageAdmin(PageQuery pageQuery, AnchorTopAdminVo bo) {
return baseMapper.pageAdmin(pageQuery.build(), bo);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean saveOrUpdateAnchorTop(AnchorTopAdminVo bo) {
if(bo.getBeginTime() == null || bo.getEndTime() == null){
throw new ServiceException("请填写开始时间和结束时间");
}
if(bo.getBeginTime().isAfter(bo.getEndTime())){
throw new ServiceException("开始时间不能大于结束时间");
}
User user = userService.getByUserCode(bo.getUsercode());
if(user == null || user.getIsAnchor() != 1){
throw new ServiceException("用户不存在或不是主播");
}
if(bo.getSortBy() == null){
bo.setSortBy(0L);
}
AnchorTop one = this.getOne(Wrappers.lambdaQuery(AnchorTop.class).eq(AnchorTop::getUserId, user.getId()).last("limit 1"));
AnchorTop anchorTop = new AnchorTop();
if(one != null){
anchorTop.setId(one.getId());
}
anchorTop.setUserId(user.getId());
anchorTop.setBeginTime(bo.getBeginTime());
anchorTop.setEndTime(bo.getEndTime());
anchorTop.setSortBy(bo.getSortBy());
return this.saveOrUpdate(anchorTop);
}
@Override
public AnchorTopAdminVo getAnchorTopByUserCode(String usercode) {
User user = userService.getByUserCode(usercode);
if(user == null){
return null;
}
AnchorTop one = this.getOne(Wrappers.lambdaQuery(AnchorTop.class).eq(AnchorTop::getUserId, user.getId()).last("limit 1"));
if(one != null){
AnchorTopAdminVo vo = new AnchorTopAdminVo();
vo.setId(one.getId());
vo.setUsercode(user.getUsercode());
vo.setNickname(user.getNickname());
vo.setMobile(user.getMobile());
vo.setAge(user.getAge());
vo.setGender(user.getGender());
vo.setUserId(one.getUserId());
vo.setBeginTime(one.getBeginTime());
vo.setEndTime(one.getEndTime());
vo.setSortBy(one.getSortBy());
return vo;
}
return null;
}
@Override
public List<AnchorListVo> anchorTop(int limit) {
return baseMapper.anchorTop(limit);
}
}

View File

@@ -50,7 +50,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</if>
<if test="query.type != null">
<if test="query.type == 0">
order by t2.recommend_status desc
order by t2.recommend_status desc,t2.update_time desc
</if>
<if test="query.type == 1">
order by t3.last_live_time desc,t2.recommend_status desc
@@ -59,7 +59,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
order by t1.create_time desc, t2.recommend_status desc
</if>
</if>
order by t2.update_time desc
</select>

View File

@@ -3,11 +3,16 @@
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.cai.mapper.AnchorTopMapper">
<!--// 1-生效 2-过期 3-待生效-->
<select id="pageAdmin" resultType="com.ruoyi.cai.dto.admin.vo.AnchorTopAdminVo">
select t1.*,
t3.usercode,t3.nickname,t3.mobile,t3.avatar,t3.gender,t3.age,t3.status,
t4.status as online_status
t4.status as online_status,
<![CDATA[
case when t1.begin_time > now() then 3
when t1.end_time < now() then 2
else 1 end as top_status
]]>
from cai_anchor_top t1
left join cai_anchor t2 on t1.user_id = t2.user_id
left join cai_user t3 on t1.user_id = t3.id
@@ -25,9 +30,43 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="bo.onlineStatus != null">
and t4.status = #{bo.onlineStatus}
</if>
<if test="bo.topStatus != null">
<if test="bo.topStatus == 1">
<![CDATA[
and t1.begin_time <= now() and t1.end_time >= now()
]]>
</if>
<if test="bo.topStatus == 2">
<![CDATA[
and t1.end_time < now()
]]>
</if>
<if test="bo.topStatus == 3">
<![CDATA[
and t1.begin_time > now()
]]>
</if>
</if>
</where>
order by t1.sort_by desc
</select>
<select id="anchorTop" resultType="com.ruoyi.cai.dto.app.vo.AnchorListVo">
select
t1.id as user_id,t1.avatar,t1.gender,t1.city,t1.nickname,t1.usercode,
t1.city_id,t1.city,
t2.give_score,t2.price,t3.status as online
from cai_user t1
join cai_anchor t2 on t1.id = t2.user_id
join cai_user_online t3 on t1.id = t3.user_id
join cai_anchor_top t4 on t1.id = t4.user_id
where t1.status = 0 and t1.is_anchor = 1 and t2.index_display = 1 and t1.usercode > 100
and t3.status = 1
<![CDATA[
and t4.begin_time <= now() and t4.end_time >= now()
]]>
order by t4.sort_by desc
limit #{limit}
</select>
</mapper>