This commit is contained in:
张良(004796)
2024-01-22 12:43:40 +08:00
parent 827c12b2ca
commit 351642d1d4
17 changed files with 469 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
package com.ruoyi.cai.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.cai.domain.UserErrorLog;
import com.ruoyi.cai.dto.admin.vo.UserErrorLogAdminVo;
import com.ruoyi.cai.service.UserErrorLogService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.enums.BusinessType;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
/**
* 用户异常记录
*
* @author 77
* @date 2024-01-22
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/cai/userErrorLog")
public class UserErrorLogController extends BaseController {
private final UserErrorLogService userErrorLogService;
/**
* 查询用户异常记录列表
*/
@SaCheckPermission("cai:userErrorLog:list")
@GetMapping("/list")
public TableDataInfo<UserErrorLogAdminVo> list(UserErrorLogAdminVo bo, PageQuery pageQuery) {
Page<UserErrorLogAdminVo> page = userErrorLogService.pageAdmin(pageQuery, bo);
return TableDataInfo.build(page);
}
/**
* 获取用户异常记录详细信息
*
* @param id 主键
*/
@SaCheckPermission("cai:userErrorLog:query")
@GetMapping("/{id}")
public R<UserErrorLog> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(userErrorLogService.getById(id));
}
/**
* 新增用户异常记录
*/
@SaCheckPermission("cai:userErrorLog:add")
@Log(title = "用户异常记录", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody UserErrorLog bo) {
return toAjax(userErrorLogService.save(bo));
}
/**
* 修改用户异常记录
*/
@SaCheckPermission("cai:userErrorLog:edit")
@Log(title = "用户异常记录", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody UserErrorLog bo) {
return toAjax(userErrorLogService.updateById(bo));
}
/**
* 删除用户异常记录
*
* @param ids 主键串
*/
@SaCheckPermission("cai:userErrorLog:remove")
@Log(title = "用户异常记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(userErrorLogService.removeBatchByIds(Arrays.asList(ids)));
}
}

View File

@@ -1,7 +1,9 @@
package com.ruoyi.cai.controller.app;
import com.ruoyi.cai.dto.app.query.UserReportReq;
import com.ruoyi.cai.dto.app.query.push.PushErrorReq;
import com.ruoyi.cai.service.ReportService;
import com.ruoyi.cai.service.UserErrorLogService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.enums.BusinessType;
@@ -21,6 +23,8 @@ public class OtherController {
@Autowired
private ReportService reportService;
@Autowired
private UserErrorLogService userErrorLogService;
@PostMapping("/report")
@Operation(summary = "举报")
@@ -31,4 +35,13 @@ public class OtherController {
reportService.report(reportRes);
return R.ok();
}
@PostMapping("/pushError")
@Operation(summary = "上报异常行为(截屏,录屏)")
@Log(title = "上报异常行为(截屏,录屏)", businessType = BusinessType.OTHER, isSaveDb = false)
public R<Void> pushError(@RequestBody PushErrorReq req){
req.setUserId(LoginHelper.getUserId());
userErrorLogService.pushError(req);
return R.ok();
}
}

View File

@@ -0,0 +1,45 @@
package com.ruoyi.cai.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import java.math.BigDecimal;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 用户异常记录对象 cai_user_error_log
*
* @author 77
* @date 2024-01-22
*/
@Data
@TableName("cai_user_error_log")
public class UserErrorLog implements Serializable {
private static final long serialVersionUID=1L;
/**
*
*/
@TableId(value = "id",type = IdType.AUTO)
private Long id;
/**
* 类型 1-截屏 2-录屏
*/
private Integer type;
/**
* 用户ID
*/
private Long userId;
/**
* 异常行为发生的地方, video=直播other=其他
*/
private String homeIndex;
private LocalDateTime createTime;
}

View File

@@ -16,6 +16,7 @@ import java.time.LocalDateTime;
*/
@Data
@TableName("cai_user_risk_log")
@Deprecated
public class UserRiskLog implements Serializable {
private static final long serialVersionUID=1L;

View File

@@ -0,0 +1,35 @@
package com.ruoyi.cai.dto.admin.vo;
import com.ruoyi.cai.domain.UserErrorLog;
import com.ruoyi.common.annotation.Sensitive;
import com.ruoyi.common.enums.SensitiveStrategy;
import lombok.Data;
@Data
public class UserErrorLogAdminVo extends UserErrorLog {
/**
* 用户号/ID号
*/
private String usercode;
/**
* 昵称
*/
private String nickname;
/**
* 手机号
*/
@Sensitive(strategy = SensitiveStrategy.PHONE)
private String mobile;
/**
* 头像
*/
private String avatar;
/**
* 性别
*/
private Integer gender;
private Integer age;
private Integer isAnchor;
}

View File

@@ -0,0 +1,15 @@
package com.ruoyi.cai.dto.app.query.push;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "上报异常模式入参")
public class PushErrorReq {
@Schema(description = "用户ID",hidden = true)
private Long userId;
@Schema(description = "1-截屏 2-录屏")
private Integer type;
@Schema(description = "异常行为发生的地方, video=直播other=其他")
private String homeIndex = "other";
}

View File

@@ -0,0 +1,17 @@
package com.ruoyi.cai.enums.user;
import lombok.Getter;
@Getter
public enum UserErrorLogHomeIndexEnum {
VIDEO("video","直播"),
OTHER("other","其他"),
;
private final String code;
private final String name;
UserErrorLogHomeIndexEnum(String code, String name) {
this.code = code;
this.name = name;
}
}

View File

@@ -0,0 +1,28 @@
package com.ruoyi.cai.enums.user;
import lombok.Getter;
@Getter
public enum UserErrorLogType {
SCREEN_SHOT(1,"截屏"),
SCREEN_RECORDING(2,"录屏"),
;
private final Integer code;
private final String name;
UserErrorLogType(Integer code, String name) {
this.code = code;
this.name = name;
}
public static UserErrorLogType getByCode(Integer type) {
UserErrorLogType[] values = values();
for (UserErrorLogType value : values) {
if(value.getCode().equals(type)){
return value;
}
}
return null;
}
}

View File

@@ -15,4 +15,8 @@ import org.apache.ibatis.annotations.Param;
public interface LowHeightRiskMapper extends BaseMapper<LowHeightRisk> {
Page<LowHeightRiskAdminVo> pageAdmin(@Param("build") Page<Object> build, @Param("bo") LowHeightRiskAdminVo bo);
void incsScreenShot(@Param("id") Long id);
void incsScreenRecording(@Param("id") Long id);
}

View File

@@ -0,0 +1,18 @@
package com.ruoyi.cai.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.cai.domain.UserErrorLog;
import com.ruoyi.cai.dto.admin.vo.UserErrorLogAdminVo;
import org.apache.ibatis.annotations.Param;
/**
* 用户异常记录Mapper接口
*
* @author 77
* @date 2024-01-22
*/
public interface UserErrorLogMapper extends BaseMapper<UserErrorLog> {
Page<UserErrorLogAdminVo> pageAdmin(@Param("build") Page<Object> build, @Param("bo") UserErrorLogAdminVo bo);
}

View File

@@ -3,6 +3,7 @@ package com.ruoyi.cai.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.cai.domain.LowHeightRisk;
import com.ruoyi.cai.domain.UserErrorLog;
import com.ruoyi.cai.dto.admin.vo.LowHeightRiskAdminVo;
import com.ruoyi.common.core.domain.PageQuery;
@@ -15,4 +16,6 @@ import com.ruoyi.common.core.domain.PageQuery;
public interface LowHeightRiskService extends IService<LowHeightRisk> {
Page<LowHeightRiskAdminVo> pageAdmin(PageQuery pageQuery, LowHeightRiskAdminVo bo);
void incsNum(UserErrorLog log);
}

View File

@@ -0,0 +1,21 @@
package com.ruoyi.cai.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.cai.domain.UserErrorLog;
import com.ruoyi.cai.dto.admin.vo.UserErrorLogAdminVo;
import com.ruoyi.cai.dto.app.query.push.PushErrorReq;
import com.ruoyi.common.core.domain.PageQuery;
/**
* 用户异常记录Service接口
*
* @author 77
* @date 2024-01-22
*/
public interface UserErrorLogService extends IService<UserErrorLog> {
void pushError(PushErrorReq req);
Page<UserErrorLogAdminVo> pageAdmin(PageQuery pageQuery, UserErrorLogAdminVo bo);
}

View File

@@ -1,14 +1,19 @@
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.LowHeightRisk;
import com.ruoyi.cai.domain.UserErrorLog;
import com.ruoyi.cai.dto.admin.vo.LowHeightRiskAdminVo;
import com.ruoyi.cai.enums.user.UserErrorLogType;
import com.ruoyi.cai.mapper.LowHeightRiskMapper;
import com.ruoyi.cai.service.LowHeightRiskService;
import com.ruoyi.common.core.domain.PageQuery;
import org.springframework.stereotype.Service;
import java.util.concurrent.locks.ReentrantLock;
/**
* 高风险用户记录Service业务层处理
*
@@ -22,4 +27,33 @@ public class LowHeightRiskServiceImpl extends ServiceImpl<LowHeightRiskMapper, L
public Page<LowHeightRiskAdminVo> pageAdmin(PageQuery pageQuery, LowHeightRiskAdminVo bo) {
return baseMapper.pageAdmin(pageQuery.build(),bo);
}
@Override
public void incsNum(UserErrorLog log){
if(log == null || log.getUserId() == null){
return;
}
LowHeightRisk one = this.getOne(Wrappers.lambdaQuery(LowHeightRisk.class)
.eq(LowHeightRisk::getUserId, log.getUserId()));
if(one == null){
ReentrantLock lock = new ReentrantLock();
try {
lock.lock();
one = this.getOne(Wrappers.lambdaQuery(LowHeightRisk.class)
.eq(LowHeightRisk::getUserId, log.getUserId()));
if(one == null){
one = new LowHeightRisk();
one.setUserId(log.getUserId());
}
this.save(one);
}finally {
lock.unlock();
}
}
if(UserErrorLogType.SCREEN_SHOT.getCode().equals(log.getType())){
baseMapper.incsScreenShot(one.getId());
}else if(UserErrorLogType.SCREEN_RECORDING.getCode().equals(log.getType())){
baseMapper.incsScreenRecording(one.getId());
}
}
}

View File

@@ -0,0 +1,77 @@
package com.ruoyi.cai.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.domain.UserErrorLog;
import com.ruoyi.cai.dto.admin.UserForbidDTO;
import com.ruoyi.cai.dto.admin.vo.UserErrorLogAdminVo;
import com.ruoyi.cai.dto.app.query.push.PushErrorReq;
import com.ruoyi.cai.enums.ForbidTimeEnum;
import com.ruoyi.cai.enums.ForbidTypeEnum;
import com.ruoyi.cai.enums.user.UserErrorLogHomeIndexEnum;
import com.ruoyi.cai.enums.user.UserErrorLogType;
import com.ruoyi.cai.manager.UserForbidManager;
import com.ruoyi.cai.mapper.UserErrorLogMapper;
import com.ruoyi.cai.service.LowHeightRiskService;
import com.ruoyi.cai.service.UserErrorLogService;
import com.ruoyi.common.core.domain.PageQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* 用户异常记录Service业务层处理
*
* @author 77
* @date 2024-01-22
*/
@Service
@Slf4j
public class UserErrorLogServiceImpl extends ServiceImpl<UserErrorLogMapper,UserErrorLog> implements UserErrorLogService {
@Autowired
private LowHeightRiskService lowHeightRiskService;
@Autowired
private UserForbidManager userForbidManager;
@Override
@Transactional(rollbackFor = Exception.class)
public void pushError(PushErrorReq req) {
UserErrorLogType logType = UserErrorLogType.getByCode(req.getType());
if(logType == null){
log.error("记录高危风险失败,参数异常! req={}", JSON.toJSONString(req));
return;
}
if(req.getHomeIndex() == null){
req.setHomeIndex(UserErrorLogHomeIndexEnum.OTHER.getCode());
}
UserErrorLog log = new UserErrorLog();
log.setType(req.getType());
log.setUserId(req.getUserId());
log.setHomeIndex(req.getHomeIndex());
this.save(log);
lowHeightRiskService.incsNum(log);
// 记录风险
if(UserErrorLogHomeIndexEnum.VIDEO.getCode().equals(log.getHomeIndex())){ // 直播的直接封号
String remark = String.format("于%s 直播期间%s封10年",
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
logType.getName());
UserForbidDTO dto = new UserForbidDTO();
dto.setForbidTime(ForbidTimeEnum.YEAR_10.getCode());
dto.setForbidType(ForbidTypeEnum.USER.getCode());
dto.setMember(req.getUserId()+"");
dto.setRemark(remark);
userForbidManager.forbid(dto);
}
}
@Override
public Page<UserErrorLogAdminVo> pageAdmin(PageQuery pageQuery, UserErrorLogAdminVo bo) {
return baseMapper.pageAdmin(pageQuery.build(),bo);
}
}

View File

@@ -12,6 +12,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="state" column="state"/>
<result property="createTime" column="create_time"/>
</resultMap>
<update id="incsScreenShot">
update cai_low_height_risk
set screenshot_num = screenshot_num + 1
where id = #{id}
</update>
<update id="incsScreenRecording">
update cai_low_height_risk
set screen_recording_num = screen_recording_num + 1
where id = #{id}
</update>
<select id="pageAdmin" resultType="com.ruoyi.cai.dto.admin.vo.LowHeightRiskAdminVo">
select
t1.*,t2.age,t2.avatar,t2.usercode,t2.nickname,t2.mobile,t2.gender

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.cai.mapper.UserErrorLogMapper">
<resultMap type="com.ruoyi.cai.domain.UserErrorLog" id="UserErrorLogResult">
<result property="id" column="id"/>
<result property="type" column="type"/>
<result property="userId" column="user_id"/>
<result property="homeIndex" column="home_index"/>
<result property="createTime" column="create_time"/>
</resultMap>
<select id="pageAdmin" resultType="com.ruoyi.cai.dto.admin.vo.UserErrorLogAdminVo">
select t1.*,t2.usercode,t2.nickname,t2.mobile,t2.avatar,t2.gender,t2.is_anchor,t2.age
from cai_user_error_log t1
left join cai_user t2 on t1.user_id = t2.id
<where>
<if test="bo.mobile != null and bo.mobile != ''">
and t2.mobile = #{bo.mobile}
</if>
<if test="bo.usercode != null and bo.usercode != ''">
and t2.usercode = #{bo.usercode}
</if>
<if test="bo.type != null">
and t1.type = #{bo.type}
</if>
<if test="bo.homeIndex != null">
and t1.home_index = #{bo.homeIndex}
</if>
</where>
order by t1.create_time desc
</select>
</mapper>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.CaiUserErrorLogMapper">
<resultMap type="com.ruoyi.system.domain.CaiUserErrorLog" id="CaiUserErrorLogResult">
<result property="id" column="id"/>
<result property="type" column="type"/>
<result property="userId" column="user_id"/>
<result property="homeIndex" column="home_index"/>
<result property="createTime" column="create_time"/>
</resultMap>
</mapper>