七(10)springtask-RabbitMq-内容审核

课程总结

1、用户冻结/解冻

2、数据统计

使用RabbitMQ传递日志消息

SpringTask定时任务进行数据统计

不足之处:数据延迟

3、内容审核

基于RabbitMQ异步执行

阿里云内容审核

一. 用户冻结解冻

用户冻结/解冻使用管理员在后台系统对用户的惩罚措施。对于发布不当言论或者违法违规内容的用户,可以暂时、永久禁止其登录,评论,发布动态、

后台中解冻/冻结,就是将用户状态写入数据库中

APP端用户在进行登录,评论,发布动态时检测Redis中冻结状态

image-20210629194728510

1-1 用户冻结

1. 接口文档

image-20220929201009505

2. ManageController
//用户冻结
@PostMapping("/users/freeze")
public ResponseEntity freeze(@RequestBody Map params) {
   
    Map map =  managerService.userFreeze(params);
    return ResponseEntity.ok(map);
}
3. ManageService
    //用户冻结
    public Map userFreeze(Map params) {
   
        //1、构造key
        String userId = params.get("userId").toString();
        String key = Constants.USER_FREEZE + userId;
        //2、构造失效时间
        Integer freezingTime = Integer.valueOf(params.get("freezingTime").toString()); //冻结时间,1为冻结3天,2为冻结7天,3为永久冻结
        int days = 0;
        if(freezingTime == 1) {
   
            days = 3;
        }else if(freezingTime == 2) {
   
            days = 7;
        }
        //3、将数据存入redis
        String value = JSON.toJSONString(params);
        if(days>0) {
   
            redisTemplate.opsForValue().set(key,value,days, TimeUnit.MINUTES);
        }else {
   
            redisTemplate.opsForValue().set(key,value);
        }
        Map retMap = new HashMap();
        retMap.put("message","冻结成功");
        return retMap;
    }

1-2 用户解冻

1. 接口文档
image-20220929202031405
2. ManageController
//用户解冻
@PostMapping("/users/unfreeze")
public ResponseEntity unfreeze(@RequestBody  Map params) {
   
    Map map =  managerService.userUnfreeze(params);
    return ResponseEntity.ok(map);
}
3. ManageService
//用户解冻
public Map userUnfreeze(Map params) {
   
    Long userId = (Long) params.get("userId");
    String reasonsForThawing = (String) params.get("reasonsForThawing");
    //删除redis数据
    redisTemplate.delete(Constants.FREEZE_USER+userId);
    Map map = new HashMap();
    map.put("message","解冻成功");
    return map;
}

1-3 查询数据列表

1. UserInfo

添加字段

//用户状态,1为正常,2为冻结
@TableField(exist = false)
private String userStatus = "1";
2. ManageService

修改代码

public ResponseEntity findById(Long userId) {
   
    UserInfo info = userInfoApi.findById(userId);
    if(redisTemplate.hasKey(Constants.FREEZE_USER+info.getId())) {
   
        info.setUserStatus("2");
    }
    return ResponseEntity.ok(info);
}
    //用户列表
    public PageResult findAllUsers(Integer page, Integer pagesize) {
   
        IPage<UserInfo> iPage = userInfoApi.findAll(page, pagesize);
        List<UserInfo> list = iPage.getRecords();
        for (UserInfo userInfo : list) {
   
            String key = Constants.USER_FREEZE + userInfo.getId();
            if(redisTemplate.hasKey(key)) {
   
                userInfo.setUserStatus("2");
            }
        }
        return new PageResult(page, pagesize, iPage.getTotal(), iPage.getRecords());
    }

1-4 判断用户是否冻结

用户登录, 发布评论, 发布动态判断冻结状态

登录, 评论, 发布动态对应不同的状态

@Service
public class UserFreezeService {
   

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     * 判断用户是否被冻结,已被冻结,抛出异常
     *  参数:冻结范围,用户id
     *
     *  检测登录:
     *     checkUserStatus(“1”,106)
     */
    public void checkUserStatus(String state,Long userId) {
   
        //1、拼接key,从redis中查询数据
        String key = Constants.USER_FREEZE + userId;
        String value = redisTemplate.opsForValue().get(key);
        //2、如果数据存在,且冻结范围一致,抛出异常
        if(!StringUtils.isEmpty(value)) {
   
            Map map = JSON.parseObject(value, Map.class);
            String freezingRange = (String) map.get("freezingRange");
            if(state.equals(freezingRange)) {
   
                throw new BusinessException(ErrorResult.builder().errMessage("用户被冻结").build());
            }
        }
     }
}
1. 登录功能检测状态

往往在获取验证码是进行判断

UserService

	 /**
     * 发送短信验证码
     * @param phone
     */
	public void sendMsg(String phone) {
   
        //根据手机号查询用户,如果用户存在,判断是否被冻结
        User user = userApi.findByMobile(phone);
        if(user != null) {
   
            userFreezeService.checkUserStatus("1",user.getId());
        }

        //1、随机生成6位数字
        //String code = RandomStringUtils.randomNumeric(6);
        String code = "123456";
        //2、调用template对象,发送手机短信
        //template.sendSms(phone,code);
        //3、将验证码存入到redis
        redisTemplate.opsForValue().set("CHECK_CODE_"+phone,code, Duration.ofMinutes(5));
    }

二. 数据统计

2-1 解决方案

image-20220930094251540

数据库表

image-20220930094330968

image-20220930094419589

2-2 数据采集

1、探花系统将用户操作日志写入RabbitMQ

2、管理后台获取最新消息,构造日志数据存入数据库

1. 部署RabbitMQ

探花交友所需的第三方服务组件,已经以Docker-Compose准备好了。仅仅需要进入相关目录,以命令形式启动运行即可

#进入目录
cd /root/docker-file/rmq/
#创建容器并启动
docker-compose up –d
#查看容器
docker ps -a

服务地址:192.168.136.160:5672

管理后台:http://192.168.136.160:15672/

2. 消息类型说明

探花项目间使用RabbitMQ收发消息,这里采用topic类型消息

日志消息key规则:log.xxx

image-20210629200544075

步骤

image-20220930095259820

image-20220930095316903

3. 实体类对象

Log

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Log {
   
    /**
     * id
     */
    private Long id;
    /**
     * 用户id
     */
    private Long userId;
    /**
     * 操作时间
     */
    private String logTime;

    /**
     * 操作类型,
     * 0101为登录,0102为注册,
     * 0201为发动态,0202为浏览动态,0203为动态点赞,0204为动态喜欢,0205为评论,0206为动态取消点赞,0207为动态取消喜欢,
     * 0301为发小视频,0302为小视频点赞,0303为小视频取消点赞,0304为小视频评论
     */
    private String type;

    /**
     * 登陆地点
     */
    private String place;
    /**
     * 登陆设备
     */
    private String equipment;

    public Log(Long userId, String logTime, String type) {
   
        this.userId = userId;
        this.logTime = logTime;
        this.type = type;
    }
}

Analysis

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Analysis{
   

    private Long id;
    /**
     * 日期
     */
    private Date recordDate;
    /**
     * 新注册用户数
     */
    private Integer numRegistered = 0;
    /**
     * 活跃用户数
     */
    private Integer numActive = 0;
    /**
     * 登陆次数
     */
    private Integer numLogin = 0;
    /**
     * 次日留存用户数
     */
    private Integer numRetention1d = 0;

    private Date created;
}
4. 发送日志消息

消息发送工具类

@Service
public class MqMessageService {
   

    @Autowired
    private AmqpTemplate amqpTemplate;

    //发送日志消息
    public void sendLogService(Long userId,String type,String key,String busId) {
   
        try {
   
            Map map = new HashMap();
            map.put("userId",userId.toString());
            map.put("type",type);
            map.put("logTime",new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
            map.put("busId",busId);
            String message = JSON.toJSONString(map);
            amqpTemplate.convertAndSend("tanhua.log.exchange",
                    "log."+key,message);
        } catch (AmqpException e) {
   
            e.printStackTrace();
        }
    }

    //发送动态审核消息
    public void sendAudiService(String movementId) {
   
        try {
   
            amqpTemplate.convertAndSend("tanhua.audit.exchange",
                    "audit.movement",movementId);
        } catch (AmqpException e) {
   
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 中使用 RabbitMQ 时,我们可以通过在配置文件中配置绑定关系,将交换机和队列进行绑定。具体步骤如下: 1. 在 application.properties 或 application.yml 中配置 RabbitMQ 连接信息: ``` spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest ``` 2. 创建一个交换机和一个队列,并将它们绑定在一起: ``` @Configuration public class RabbitConfig { @Bean public Queue queue() { return new Queue("myqueue", true); } @Bean public DirectExchange exchange() { return new DirectExchange("myexchange"); } @Bean public Binding binding(Queue queue, DirectExchange exchange) { return BindingBuilder.bind(queue).to(exchange).with("mykey"); } } ``` 3. 在需要发送消息的地方,注入 RabbitTemplate 并调用 convertAndSend 方法: ``` @Autowired private RabbitTemplate rabbitTemplate; public void sendMessage(String message) { rabbitTemplate.convertAndSend("myexchange", "mykey", message); } ``` 4. 在需要接收消息的地方,注入 SimpleMessageListenerContainer 并实现 MessageListener 接口: ``` @Autowired private Queue queue; @Bean public SimpleMessageListenerContainer container(ConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) { SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(); container.setConnectionFactory(connectionFactory); container.setQueueNames(queue.getName()); container.setMessageListener(listenerAdapter); return container; } @Bean public MessageListenerAdapter listenerAdapter() { return new MessageListenerAdapter(new MyMessageListener()); } public class MyMessageListener implements MessageListener { @Override public void onMessage(Message message) { String body = new String(message.getBody()); System.out.println("Received message: " + body); } } ``` 通过以上步骤,我们就可以实现交换机和队列的绑定,以及在队列中发送和接收消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值