微信聊天小程序-微聊(uniapp+springboot+wbsocket+rocketMq)

 一、ER设计

        涉及两个库:crm、base,其中crm里2张表(consumer、consumer_wx_info);base里3张表(chat_apply_record、chat_friend_role、chat_msg_record)

图:

详细表结构:

consumer  ---- 主要存用户注册信息

CREATE TABLE `consumer` (
  `c_id` int NOT NULL AUTO_INCREMENT COMMENT 'cid',
  `w_code` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '账号',
  `name` varchar(25) DEFAULT NULL COMMENT '姓名',
  `avatar_url` varchar(255) DEFAULT NULL COMMENT '头像',
  `sex` varchar(5) DEFAULT NULL COMMENT '性别',
  `birth` date DEFAULT NULL COMMENT '生日',
  `email` varchar(30) DEFAULT NULL COMMENT '邮箱',
  `phone` varchar(11) DEFAULT NULL COMMENT '手机',
  `address` varchar(255) DEFAULT NULL COMMENT '地址',
  `status` tinyint DEFAULT '1' COMMENT '状态',
  `w_code_update_time` date DEFAULT NULL COMMENT 'wCode更改时间',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `create_by` varchar(25) NOT NULL COMMENT '创建人',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `update_by` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '更新人',
  `dr` tinyint NOT NULL DEFAULT '0' COMMENT '删除',
  PRIMARY KEY (`c_id`),
  UNIQUE KEY `cid_cus_index` (`c_id`) USING BTREE,
  UNIQUE KEY `cus_wxCode_index` (`w_code`) USING BTREE,
  UNIQUE KEY `cus_phone_index` (`phone`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

consumer_wx_info  --主要存用户微信相关信息,从微信获取到的openid、用户信息等

CREATE TABLE `consumer_wx_info` (
  `u_id` int NOT NULL AUTO_INCREMENT COMMENT '自增ID',
  `c_id` int DEFAULT NULL COMMENT 'cid',
  `nick_name` varchar(50) DEFAULT NULL COMMENT '昵称',
  `avatar_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '头像',
  `openid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'openid',
  `unionid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'unionid',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `dr` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除状态',
  PRIMARY KEY (`u_id`) USING BTREE,
  UNIQUE KEY `openid_index` (`openid`) USING BTREE COMMENT 'openid索引',
  KEY `cid_key` (`c_id`),
  CONSTRAINT `cid_key` FOREIGN KEY (`c_id`) REFERENCES `consumer` (`c_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

chat_apply_record -- 好友申请记录表,主要存好友申请记录

CREATE TABLE `chat_apply_record` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '自增ID',
  `apply_c_id` int NOT NULL COMMENT '申请人',
  `receive_c_id` int NOT NULL COMMENT '接收人',
  `info` text COMMENT '备注信息',
  `apply_status` int NOT NULL DEFAULT '0' COMMENT '是否同意(0-待审核,1-已同意,2-已过期)',
  `apply_time` datetime DEFAULT NULL COMMENT '同意时间',
  `create_time` datetime NOT NULL COMMENT '申请时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `cpr_applyId_receive_index` (`apply_c_id`,`receive_c_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

chat_friend_role -- 好友关系联系表

CREATE TABLE `chat_friend_role` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '自增ID',
  `c_id_a` int NOT NULL COMMENT '申请人用户ID',
  `remark_a` varchar(25) DEFAULT NULL COMMENT '申请人备注',
  `c_id_b` int NOT NULL COMMENT '接收人用户ID',
  `remark_b` varchar(25) DEFAULT NULL COMMENT '接收人备注',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '申请加为好友时间',
  `dr` int NOT NULL DEFAULT '0' COMMENT '删除',
  PRIMARY KEY (`id`),
  UNIQUE KEY `cfr_cid_index` (`c_id_a`,`c_id_b`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

chat_msg_record --聊天记录表,主要存聊天信息

CREATE TABLE `chat_msg_record` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '自增主键ID',
  `s_c_id` int NOT NULL COMMENT '发送用户ID',
  `r_c_id` int NOT NULL COMMENT '接收用户ID',
  `type` varchar(10) NOT NULL COMMENT '消息类型',
  `content` text COMMENT '内容',
  `voice_length` int DEFAULT NULL COMMENT '语音时间长度',
  `send_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '发送时间',
  `dr` int NOT NULL DEFAULT '0' COMMENT '删除',
  `read` int NOT NULL DEFAULT '0' COMMENT '已读',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

然后还有一个存储过程以及函数方法,两者都放在base库里面

        存储过程用来使好友申请记录过期,函数是用来获取用户名称首字母

存储过程 -- expire_apply_record

CREATE DEFINER=`root`@`%` PROCEDURE `expire_apply_record`(
	IN  p_datetime DATETIME,
  OUT p_status TINYINT,
	OUT p_cost_time VARCHAR(20),
	OUT p_msg VARCHAR(100),
	OUT p_exception VARCHAR(2000))
BEGIN
	DECLARE p_state_msg VARCHAR(255) DEFAULT 'N/A';
  DECLARE p_error_msg1 VARCHAR(255);
  DECLARE p_error_msg2 VARCHAR(255);
  DECLARE p_begin_time DATETIME;

	-- SQLEXCEPTION
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
      GET DIAGNOSTICS CONDITION 1 p_error_msg1 = RETURNED_SQLSTATE, p_error_msg2 = MESSAGE_TEXT;
      SET p_status = FALSE;
			SET p_exception = CONCAT('执行异常,在【',p_state_msg,'】出错,详细:',p_error_msg1, ' : ', p_error_msg2);
    END;

  SET p_status = TRUE;
  SET p_begin_time = CURRENT_TIMESTAMP(3);
	
		
	-- NEXTWORK
	UPDATE base.chat_apply_record 
	SET apply_status = 2 
	WHERE
		create_time < SUBDATE( now( ), INTERVAL 7 DAY );		
		
	SET p_msg = CONCAT('本次总共更新:',ROW_COUNT(),'条数据');
	SET p_cost_time = TIMEDIFF(CURRENT_TIMESTAMP(3), p_begin_time);

END

2个函数:

FIRSTLETTER

CREATE DEFINER=`root`@`%` FUNCTION `FIRSTLETTER`(P_NAME VARCHAR(255)) RETURNS varchar(255) CHARSET utf8mb3
BEGIN
    DECLARE V_RETURN VARCHAR(255);
	DECLARE V_FIRST_CHAR VARCHAR(255);
	#这块主要意思是假如传入的是英文串的话,只取首字母
	set V_FIRST_CHAR =UPPER(LEFT(CONVERT(P_NAME USING gbk),1));
	set V_RETURN = V_FIRST_CHAR;
#如果是这些特殊符号,直接返回#	
IF V_FIRST_CHAR in ('(',')','《','》','1','2','3','4','5','6','7','8','9','0','*','+','-','=','/','\\','{','}','[',']','(',')','(',')')
THEN SET V_RETURN = '#';
#两个不相等只有一个情况,V_FIRST_CHAR是中文汉字或者中文符号。
elseif LENGTH( V_FIRST_CHAR) <> CHARACTER_LENGTH( V_FIRST_CHAR )
			then	
				SET V_RETURN = ELT(INTERVAL(CONV(HEX(left(CONVERT(P_NAME USING gbk),1)),16,10), 
					0xB0A1,0xB0C5,0xB2C1,0xB4EE,0xB6EA,0xB7A2,0xB8C1,0xB9FE,0xBBF7, 
					0xBFA6,0xC0AC,0xC2E8,0xC4C3,0xC5B6,0xC5BE,0xC6DA,0xC8BB,
					0xC8F6,0xCBFA,0xCDDA,0xCEF4,0xD1B9,0xD4D1),    
					'A','B','C','D','E','F','G','H','J','K','L','M','N','O','P','Q','R','S','T','W','X','Y','Z');
#如果是下面的直接原样输出					
elseif V_FIRST_CHAR in ('A','B','C','D','E','F','G','H','J','K','L','M','N','O','P','Q','R','S','T','W','X','Y','Z')
												
			then SET V_RETURN = V_RETURN;
#其他的输出#				
else 
			SET V_RETURN = '#';
END IF;
		#为空的话输出#
		RETURN IFNULL(V_RETURN,'#');
END

PINYIN

CREATE DEFINER=`root`@`%` FUNCTION `PINYIN`(P_NAME VARCHAR(255)) RETURNS varchar(255) CHARSET utf8mb4
BEGIN
    DECLARE V_COMPARE VARCHAR(255);
    DECLARE V_RETURN VARCHAR(255);
    DECLARE I INT;
    SET I = 1;
    SET V_RETURN = '';
	#循环截取字符
    while I < LENGTH(P_NAME) do
        SET V_COMPARE = SUBSTR(P_NAME, I, 1);
        IF (V_COMPARE != '') THEN
		    #字符串拼接
            SET V_RETURN = CONCAT(V_RETURN, base.FIRSTLETTER(V_COMPARE));
        END IF;
        SET I = I + 1;
    end while;
    IF (ISNULL(V_RETURN) or V_RETURN = '') THEN
        SET V_RETURN = P_NAME;
    END IF;
    RETURN V_RETURN;
END

数据库全部准备完毕 。。。。。。。。。。。

二、后端代码块

        后端代码主要就三大功能组 --- 用户消息系统

        主要讲解消息系统,其他模块代码已上传 ,可自行查看

        在消息系统中我们为了保证消息的实时性需要使用websocket实现实时通信,而mq的作用就相当于消息队列,为了让消息准确发送,所以接下来注重讲解消息通过mq消息队列通知websocket发送实时消息

        一、mq消息队列模块

               主要两大功能块-- 消费者、生产者;生产者是在发送消息时,把消息放入mq消息队列,消费者是在用户进入系统后连接上websocket后进行消费消息;

                生产者模块这儿我们主要使用顺序队列消息,主要是为了保证消息发送的顺序性,然后按照消息发送的时间按序发送给在线用户

                消费者主要是实现一个监听作用

       下面是整个MQ代码结构,包含4个方法,生产者、消费者、配置、枚举类(定义topic)

                

MQConsumer -- 提供消费者消费方法,也算是一个配置类

package com.wm.mq;

import lombok.extern.log4j.Log4j2;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Log4j2
@Component
public class MQConsumer {

    @Value("${rocketMqConfig.groupName}")  //组名
    private String groupName;

    @Value("${rocketMqConfig.nameSrvAddr}")  //mqserver地址
    private String nameSrvAddr;


    public DefaultMQPushConsumer consumer(MQTopic mqTopic) {
        try {
            DefaultMQPushConsumer consumer = new DefaultMQPushConsumer();
            consumer.setConsumerGroup(groupName);
            consumer.setNamesrvAddr(nameSrvAddr);
            consumer.subscribe(mqTopic.topic,mqTopic.tags);
            consumer.setMessageModel(MessageModel.CLUSTERING);
            return consumer;  //上面是配置项,然后返回一个consumer容器,在需要消费时可直接使用该容器的一些消费方法
        } catch (MQClientException e) {
            log.error(e);
        }
        return null;
    }

}

MQProducer -- 提供生产消息方法,本系统就只用到其中的顺序消息

package com.wm.mq;

import jakarta.annotation.Resource;
import lombok.extern.log4j.Log4j2;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageQueue;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;


@Log4j2
@Component
public class MQProducer {

    private DefaultMQProducer defaultMQProducer;

    @Resource
    public void setDefaultMQProducer(DefaultMQProducer defaultMQProducer
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二九筒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值