Go: IM系统显示好友列表和群 (4)

概述

  • 在即时通讯(IM)系统开发中,好友列表和群组管理是两个核心功能,它们为用户提供了便捷的交流平台
  • 使用Go语言(通常简称为Go)来构建这些功能,可以充分利用其高并发、简洁易读以及强大的标准库支持等优势
  • 本文将概述如何使用Go语言设计和实现一个IM系统中的好友列表显示和群组管理功能

基于MVC的目录设计

im-project
├── go.mod
├── main.go          主程序
├── model            模型层
│     ├── community.go
│     └── contact.go
├── views            模板层
│     └── chat
│           ├── concat.html
│           └── login.html
├── ctrl             控制器层
│     └── contact.go
├── service          服务包
│     └── contact.go
├── utils            工具包
│     └── parse.go

主程序

在 main.go 核心代码

package main

import (
	"net/http"
	"im-project/ctrl"
)

func main() {
	// 其他略 ...
	
	http.HandleFunc("/contact/addfriend", ctrl.Addfriend)
	http.HandleFunc("/contact/loadfriend", ctrl.LoadFriend)
	http.HandleFunc("/contact/createcommunity", ctrl.CreateCommunity)
	http.HandleFunc("/contact/joincommunity", ctrl.JoinCommunity)
	http.HandleFunc("/contact/loadcommunity", ctrl.LoadCommunity)
	
	// 其他略 ...
}
  • 这里可见,有添加好友,加载好友列表,加入群聊,加载群聊
  • /contact/addfriend 参数userid,dstid 这里假设自动添加好友, 简化了加好友的流程
  • 比如用户10000添加好友10086, 就会往contact表中添加俩条记录
    • 一条ownerid =10000, dstobj=10086
    • 一条ownerid =10086, dstobj= 10000
  • /contact/loadfriend 显示全部好友, 参数userid
  • /contact/createcommunity 建群, 头像pic, 名称name, 备注memo, 创建者userid
  • /contact/loadcommunity 显示全部群 参数userid
  • /contact/joincommunity 加群, 参数userid,dstid

模型层


在 model/contact.go 中, 这里是联系人(好友或群)

package model

import "time"

//好友和群都存在这个表里面, 可根据具体业务做拆分
type Contact struct {
	Id            int64     `xorm:"pk autoincr bigint(20)" form:"id" json:"id"`
	Ownerid       int64	    `xorm:"bigint(20)" form:"ownerid" json:"ownerid"`    // 记录是谁的
	Dstobj        int64	    `xorm:"bigint(20)" form:"dstobj" json:"dstobj"`      // 对端信息
	Cate          int	    `xorm:"int(11)" form:"cate" json:"cate"`             // 类型: 用户 | 群
	Memo          string	`xorm:"varchar(120)" form:"memo" json:"memo"`        // 备注
	Createat      time.Time	`xorm:"datetime" form:"createat" json:"createat"`    // 创建时间
}

const (
  CONCAT_CATE_USER = 0x01
  CONCAT_CATE_COMUNITY = 0x02
)

在 model/community.go 中, 这里单指群模型

package model

import "time"

type Community struct {
	Id         int64     `xorm:"pk autoincr bigint(20)" form:"id" json:"id"`
	Name       string 		`xorm:"varchar(30)" form:"name" json:"name"`        // 名称
	Ownerid    int64	`xorm:"bigint(20)" form:"ownerid" json:"ownerid"`       // 群主ID
	Icon	   string 		`xorm:"varchar(250)" form:"icon" json:"icon"`       // 群 logo
	Cate       int	`xorm:"int(11)" form:"cate" json:"cate"`                    // 类型
	Memo       string	`xorm:"varchar(120)" form:"memo" json:"memo"`           // 描述
	Createat   time.Time	`xorm:"datetime" form:"createat" json:"createat"`   // 创建时间
}
const (
	COMMUNITY_CATE_COM = 0x01
)

服务包

service/contact.go

package service

import (
	"time"
	"im-project/model"
	"errors"
)

type ContactService struct {}

//自动添加好友
func (service *ContactService) AddFriend(
	userid,//用户id 10086,
	dstid int64 ) error {
	//如果加自己
	if userid==dstid {
		return errors.New("不能添加自己为好友啊")
	}
	//判断是否已经加了好友
	tmp := model.Contact{}
	//查询是否已经是好友
	// 条件的链式操作
	DbEngin.Where("ownerid = ?",userid).
		And("dstid = ?",dstid).
		And("cate = ?",model.CONCAT_CATE_USER).
		Get(&tmp)
	//获得1条记录
	//count()
	//如果存在记录说明已经是好友了不加
	if tmp.Id>0{
		return errors.New("该用户已经被添加过啦")
	}
	//事务,
	session := DbEngin.NewSession();
	session.Begin()
	//插自己的
	_,e2 := session.InsertOne(model.Contact{
		Ownerid:userid,
		Dstobj:dstid,
		Cate:model.CONCAT_CATE_USER,
		Createat:time.Now(),
	})
	//插对方的
	_,e3 := session.InsertOne(model.Contact{
		Ownerid:dstid,
		Dstobj:userid,
		Cate:model.CONCAT_CATE_USER,
		Createat:time.Now(),
	})
	//没有错误
	if  e2==nil && e3==nil{
		//提交
		session.Commit()
		return nil
	}else{
		//回滚
		session.Rollback()
		if e2!=nil{
			return e2
		}else{
			return e3
		}
	}
}

func (service *ContactService) SearchComunity(userId int64) ([]model.Community){
	conconts := make([]model.Contact,0)
	comIds :=make([]int64,0)

	DbEngin.Where("ownerid = ? and cate = ?",userId,model.CONCAT_CATE_COMUNITY).Find(&conconts)
	for _,v := range conconts{
		comIds = append(comIds,v.Dstobj);
	}
	coms := make([]model.Community,0)
	if len(comIds)== 0{
		return coms
	}
	DbEngin.In("id",comIds).Find(&coms)
	return coms
}

//加群
func (service *ContactService) JoinCommunity(userId,comId int64) error{
	cot := model.Contact{
		Ownerid:userId,
		Dstobj:comId,
		Cate:model.CONCAT_CATE_COMUNITY,
	}
	DbEngin.Get(&cot)
	if(cot.Id==0){
		cot.Createat = time.Now()
		_,err := DbEngin.InsertOne(cot)
		return err
	}else{
		return nil
	}


}
//建群
func (service *ContactService) CreateCommunity(comm model.Community) (ret model.Community,err error){
	if len(comm.Name)==0{
		err = errors.New("缺少群名称")
		return ret,err
	}
	if comm.Ownerid==0{
		err = errors.New("请先登录")
		return ret,err
	}
	com := model.Community{
		Ownerid:comm.Ownerid,
	}
	num,err := DbEngin.Count(&com)

	if(num>5){
		err = errors.New("一个用户最多只能创见5个群")
		return com,err
	}else{
		comm.Createat=time.Now()
		session := DbEngin.NewSession()
		session.Begin()
		_,err = session.InsertOne(&comm)
		if err!=nil{
			session.Rollback();
			return com,err
		}
		_,err =session.InsertOne(
			model.Contact{
				Ownerid:comm.Ownerid,
				Dstobj:comm.Id,
				Cate:model.CONCAT_CATE_COMUNITY,
				Createat:time.Now(),
			})
		if err!=nil{
			session.Rollback();
		}else{
			session.Commit()
		}
		return com,err
	}
}

//查找好友
func (service *ContactService) SearchFriend(userId int64) ([]model.User){
	conconts := make([]model.Contact,0)
	objIds :=make([]int64,0)
	DbEngin.Where("ownerid = ? and cate = ?",userId,model.CONCAT_CATE_USER).Find(&conconts)
	for _,v := range conconts{
		objIds = append(objIds,v.Dstobj);
	}
	coms := make([]model.User,0)
	if len(objIds)== 0{
		return coms
	}
	DbEngin.In("id",objIds).Find(&coms)
	return coms
}

控制器

ctrl/contact.go

package ctrl

import (
	"net/http"
	"im-project/util"
	"im-project/service"
	"im-project/args"
)

var contactService service.ContactService

func Addfriend(w http.ResponseWriter, req *http.Request) {
	//定义一个参数结构体
	/*
	request.ParseForm()
	mobile := request.PostForm.Get("mobile")
	passwd := request.PostForm.Get("passwd")
	*/
	var arg args.ContactArg
	util.Bind(req,&arg)
	// 调用service
	err := contactService.AddFriend(arg.Userid,arg.Dstid)
	if err!=nil {
		util.RespFail(w,err.Error())
	} else {
		util.RespOk(w,nil,"好友添加成功")
	}
}

func LoadFriend(w http.ResponseWriter, req *http.Request){
	var arg args.ContactArg
	//如果这个用的上,那么可以直接
	util.Bind(req,&arg)

	users := contactService.SearchFriend(arg.Userid)
	util.RespOkList(w,users,len(users))
}

func LoadCommunity(w http.ResponseWriter, req *http.Request){
	var arg args.ContactArg
	//如果这个用的上,那么可以直接
	util.Bind(req,&arg)
	comunitys := contactService.SearchComunity(arg.Userid)
	util.RespOkList(w,comunitys,len(comunitys))
}

func JoinCommunity(w http.ResponseWriter, req *http.Request){
	var arg args.ContactArg

	//如果这个用的上,那么可以直接
	util.Bind(req,&arg)
	err := contactService.JoinCommunity(arg.Userid,arg.Dstid);
	if err!=nil{
		util.RespFail(w,err.Error())
	}else {
		util.RespOk(w,nil,"")
	}
}

模板层


这里, 不再赘述UI层的相关编码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Wang's Blog

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

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

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

打赏作者

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

抵扣说明:

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

余额充值