Bläddra i källkod

feature(跟进评论): OMS跟进记录、评论接口调整,增加对评论的回复功能--合并冲突

likai 1 år sedan
förälder
incheckning
ac84590175

+ 75 - 0
opms_parent/app/handler/plat/followup_comment.go

@@ -2,6 +2,7 @@ package plat
 
 import (
 	"context"
+	"dashoo.cn/opms_libary/myerrors"
 
 	"dashoo.cn/common_definition/comm_def"
 	"github.com/gogf/gf/frame/g"
@@ -30,6 +31,57 @@ func (h *FollowUpCommentHandler) GetList(ctx context.Context, req *model.SearchP
 	return nil
 }
 
+// GetNeedReplyComments 获取本人需要回复的评论列表
+// Swagger:FollowUpComment 跟进 获取本人需要回复的评论列表
+func (h *FollowUpCommentHandler) GetNeedReplyComments(ctx context.Context, req *model.SearchNeedReplyCommentsReq, rsp *comm_def.CommonMsg) error {
+	followupCommentService, err := server.NewFollowupCommentService(ctx)
+	if err != nil {
+
+		return err
+	}
+	g.Log().Info("搜索值", req)
+	total, list, err := followupCommentService.NeedReplyList(req)
+	if err != nil {
+		return err
+	}
+	rsp.Data = g.Map{"list": list, "total": total}
+	return nil
+}
+
+// GetNeedReplyCount 获取本人需要回复的评论数量
+// Swagger:FollowUpComment 跟进 获取本人需要回复的评论数量
+func (h *FollowUpCommentHandler) GetNeedReplyCount(ctx context.Context, req *model.SearchNeedReplyCommentsReq, rsp *comm_def.CommonMsg) error {
+	followupCommentService, err := server.NewFollowupCommentService(ctx)
+	if err != nil {
+
+		return err
+	}
+	g.Log().Info("搜索值", req)
+	total, err := followupCommentService.NeedReplyCount(req)
+	if err != nil {
+		return err
+	}
+	rsp.Data = g.Map{"total": total}
+	return nil
+}
+
+// GetLatestComments 获取最新50条数据
+// Swagger:FollowUpComment 跟进 获取最新50条数据
+func (h *FollowUpCommentHandler) GetLatestComments(ctx context.Context, req *model.SearchPlatFollowupCommentReq, rsp *comm_def.CommonMsg) error {
+	followupCommentService, err := server.NewFollowupCommentService(ctx)
+	if err != nil {
+
+		return err
+	}
+	g.Log().Info("搜索值", req)
+	total, list, err := followupCommentService.LatestComments(req)
+	if err != nil {
+		return err
+	}
+	rsp.Data = g.Map{"list": list, "total": total}
+	return nil
+}
+
 // Create 添加跟进评论
 // Swagger:FollowUpComment 跟进 评论添加
 func (h *FollowUpCommentHandler) Create(ctx context.Context, req *model.AddPlatFollowupCommentReq, rsp *comm_def.CommonMsg) error {
@@ -47,3 +99,26 @@ func (h *FollowUpCommentHandler) Create(ctx context.Context, req *model.AddPlatF
 	}
 	return nil
 }
+
+// Reply 回复跟进评论
+// Swagger:FollowUpComment 跟进 回复跟进评论
+func (h *FollowUpCommentHandler) Reply(ctx context.Context, req *model.AddPlatFollowupCommentReq, rsp *comm_def.CommonMsg) error {
+	// 参数校验
+	if err := gvalid.CheckStruct(ctx, req, nil); err != nil {
+		return err
+	}
+	// 参数校验
+	if req.Pid == 0 {
+		return myerrors.TipsError("回复的评论Id不能为空")
+	}
+
+	followupCommentService, err := server.NewFollowupCommentService(ctx)
+	if err != nil {
+		return err
+	}
+	err = followupCommentService.Reply(req)
+	if err != nil {
+		return err
+	}
+	return nil
+}

+ 22 - 22
opms_parent/app/model/plat/plat_followup.go

@@ -36,27 +36,27 @@ type SearchPlatFollowupReq struct {
 
 // 添加数据
 type AddPlatFollowupReq struct {
-	FollowType    string                    `orm:"follow_type"    json:"followType"    v:"required#跟进类型不能为空"`                    // 跟进类型(10电话20邮件30拜访)
-	FollowDate    *gtime.Time               `orm:"follow_date"    json:"followDate"    v:"required#跟进时间不能为空"`                    // 跟进时间
-	FollowContent string                    `orm:"follow_content" json:"followContent" v:"required#跟进内容不能为空"`                    // 跟进内容
-	FurtherPlan   string                    `orm:"further_plan"   json:"furtherPlan" v:"required#下一步跟进计划和目标不能为空"`                // 下一步跟进计划和目标
-	Effect        string                    `orm:"effect"         json:"effect" v:"required#达成效果不能为空"`                           // 达成效果
-	Issue         string                    `orm:"issue"          json:"issue" v:"required#问题或困难不能为空"`                           // 问题或困难
+	FollowType    string                    `orm:"follow_type"    json:"followType"    v:"required#跟进类型不能为空"`                            // 跟进类型(10电话20邮件30拜访)
+	FollowDate    *gtime.Time               `orm:"follow_date"    json:"followDate"    v:"required#跟进时间不能为空"`                            // 跟进时间
+	FollowContent string                    `orm:"follow_content" json:"followContent" v:"required#跟进内容不能为空"`                            // 跟进内容
+	FurtherPlan   string                    `orm:"further_plan"   json:"furtherPlan" v:"required#下一步跟进计划和目标不能为空"`                  // 下一步跟进计划和目标
+	Effect        string                    `orm:"effect"         json:"effect" v:"required#达成效果不能为空"`                                   // 达成效果
+	Issue         string                    `orm:"issue"          json:"issue" v:"required#问题或困难不能为空"`                                  // 问题或困难
 	TargetId      int                       `orm:"target_id"      json:"targetId"      v:"required|min:1#跟进对象ID不能为空|跟进对象ID不能为空"` // 跟进对象ID
-	TargetType    string                    `orm:"target_type"    json:"targetType"    v:"required#跟进对象类型不能为空"`                  // 跟进对象类型(10客户,20项目,30合同,40回款)
-	TargetName    string                    `orm:"target_name"    json:"targetName"    v:"required#跟进对象不能为空"`                    // 跟进对象
-	CustId        int                       `orm:"cust_id"        json:"custId"`                                                 // 关联客户
-	CustName      string                    `orm:"cust_name"      json:"custName"`                                               // 客户名称
-	ContactType   string                    `orm:"contact_type"   json:"contactType"`                                            // 联系人类型(10客户 20 渠道)
-	ContactsId    int                       `orm:"contacts_id"    json:"contactsId"`                                             // 关联联系人
-	ContactsName  string                    `orm:"contacts_name"  json:"contactsName"`                                           // 联系人姓名
-	Reminders     string                    `orm:"reminders"      json:"reminders"`                                              // 提醒对象
-	NextTime      *gtime.Time               `orm:"next_time"      json:"nextTime"`                                               // 下次联系时间
-	Remark        string                    `orm:"remark"         json:"remark"`                                                 // 备注
-	DistId        int                       `orm:"dist_id"        json:"distId"`                                                 // 经销商id
-	DistName      string                    `orm:"dist_name"      json:"distName"`                                               // 经销商名称
-	VisitorName   string                    `orm:"visitor_name"   json:"visitorName"`                                            // 协访人员
-	Files         []*AddPlatFollowupFileReq `json:"files"`                                                                       // 附件
+	TargetType    string                    `orm:"target_type"    json:"targetType"    v:"required#跟进对象类型不能为空"`                        // 跟进对象类型(10客户,20项目,30合同,40回款)
+	TargetName    string                    `orm:"target_name"    json:"targetName"    v:"required#跟进对象不能为空"`                            // 跟进对象
+	CustId        int                       `orm:"cust_id"        json:"custId"`                                                                 // 关联客户
+	CustName      string                    `orm:"cust_name"      json:"custName"`                                                               // 客户名称
+	ContactType   string                    `orm:"contact_type"   json:"contactType"`                                                            // 联系人类型(10客户 20 渠道)
+	ContactsId    int                       `orm:"contacts_id"    json:"contactsId"`                                                             // 关联联系人
+	ContactsName  string                    `orm:"contacts_name"  json:"contactsName"`                                                           // 联系人姓名
+	Reminders     string                    `orm:"reminders"      json:"reminders"`                                                              // 提醒对象
+	NextTime      *gtime.Time               `orm:"next_time"      json:"nextTime"`                                                               // 下次联系时间
+	Remark        string                    `orm:"remark"         json:"remark"`                                                                 // 备注
+	DistId        int                       `orm:"dist_id"        json:"distId"`                                                                 // 经销商id
+	DistName      string                    `orm:"dist_name"      json:"distName"`                                                               // 经销商名称
+	VisitorName   string                    `orm:"visitor_name"   json:"visitorName"`                                                            // 协访人员
+	Files         []*AddPlatFollowupFileReq `json:"files"`                                                                                       // 附件
 	//FollowContentType string      `orm:"follow_content_type" json:"followContentType" v:"required#跟进内容类型不能为空"`               // 跟进内容类型
 	//SupportName       string      `orm:"support_name"   json:"supportName"`                                                            // 总部支持人员
 }
@@ -64,8 +64,8 @@ type AddPlatFollowupReq struct {
 // 跟进记录详情展示,且展示第一级评论数据
 type FollowupInfo struct {
 	PlatFollowup
-	Comments      []*PlatFollowupComment `json:"comments"`      // 评论
-	CommentNumber int                    `json:"commentNumber"` // 评论数量
+	Comments      []*FollowupCommentEx `json:"comments"`      // 评论
+	CommentNumber int                  `json:"commentNumber"` // 评论数量
 }
 
 // 跟进记录详情展示,按日期返回前端结果

+ 17 - 0
opms_parent/app/model/plat/plat_followup_comment.go

@@ -21,6 +21,11 @@ type SearchPlatFollowupCommentReq struct {
 	request.PageReq
 }
 
+// 获取本人需要回复的评论列表请求参数
+type SearchNeedReplyCommentsReq struct {
+	request.PageReq
+}
+
 // 添加数据
 type AddPlatFollowupCommentReq struct {
 	FollowId string `orm:"follow_id"    json:"followId"     v:"required#关联跟进不能为空"` // 关联跟进
@@ -28,3 +33,15 @@ type AddPlatFollowupCommentReq struct {
 	Pid      int    `orm:"pid"          json:"pid"`                                // 回复对象ID
 	Remark   string `orm:"remark"       json:"remark"`                             // 备注
 }
+
+type FollowupCommentEx struct {
+	PlatFollowupComment
+	ReplyComments []*FollowupCommentEx `json:"replyComments"`
+}
+
+type FollowupCommentEx2 struct {
+	PlatFollowupComment
+	TargetType    string                `orm:"target_type"    json:"targetType"    v:"required#跟进对象类型不能为空"` // 跟进对象类型(10客户,20项目,30合同,40回款)
+	TargetName    string                `orm:"target_name"    json:"targetName"    v:"required#跟进对象不能为空"`   // 跟进对象
+	ReplyComments []*FollowupCommentEx2 `json:"replyComments"`
+}

+ 38 - 10
opms_parent/app/service/plat/plat_followup.go

@@ -248,22 +248,50 @@ func (s *followupService) GetListByDay(req *model.SearchPlatFollowupReq) (total
 	if err != nil && err != sql.ErrNoRows {
 		return
 	}
-	// 查询一级评论
-	var comments []model.PlatFollowupComment
-	err = s.Dao.InnerJoin(plat.PlatFollowupComment.Table, "plat_followup.id=plat_followup_comment.follow_id").Where("plat_followup_comment.pid=0 OR plat_followup_comment.pid IS NULL").Fields("plat_followup_comment.*").Structs(&comments)
+	var followupIdArr = []int{-1}
+	for _, followup := range originalFollowupList {
+		followupIdArr = append(followupIdArr, followup.Id)
+	}
+	// 全部评论
+	var allComments []*model.FollowupCommentEx
+	commentMap := make(map[int]*model.FollowupCommentEx, 0)
+	// 一级评论
+	var comments []*model.FollowupCommentEx
+	// 回复评论
+	var replyComments []*model.FollowupCommentEx
+	err = followupModel.InnerJoin(plat.PlatFollowupComment.Table, "plat_followup.id=plat_followup_comment.follow_id").Fields("plat_followup_comment.*").Structs(&allComments)
 	if err != nil && err != sql.ErrNoRows {
 		return
 	}
+	// 挑拣数据
+	for index, comment := range allComments {
+		commentMap[comment.Id] = allComments[index]
+		if comment.Pid == 0 {
+			comments = append(comments, allComments[index])
+		} else {
+			replyComments = append(replyComments, allComments[index])
+		}
+	}
+	// 构造回复评论
+	for _, replyComment := range replyComments {
+		if _, ok := commentMap[replyComment.Pid]; ok {
+			if commentMap[replyComment.Pid].ReplyComments == nil {
+				commentMap[replyComment.Pid].ReplyComments = make([]*model.FollowupCommentEx, 0)
+			}
+			commentMap[replyComment.Pid].ReplyComments = append(commentMap[replyComment.Pid].ReplyComments, replyComment)
+		}
+	}
+
 	// 构造数据
 	var days []string
 	followupMap := make(map[string][]*model.FollowupInfo, 0)
-	commentMap := make(map[int][]*model.PlatFollowupComment, 0)
+	followupCommentMap := make(map[int][]*model.FollowupCommentEx, 0)
 	// 评论数据map
 	for index, comment := range comments {
-		if _, ok := commentMap[comment.FollowId]; !ok {
-			commentMap[comment.FollowId] = make([]*model.PlatFollowupComment, 0)
+		if _, ok := followupCommentMap[comment.FollowId]; !ok {
+			followupCommentMap[comment.FollowId] = make([]*model.FollowupCommentEx, 0)
 		}
-		commentMap[comment.FollowId] = append(commentMap[comment.FollowId], &comments[index])
+		followupCommentMap[comment.FollowId] = append(followupCommentMap[comment.FollowId], comments[index])
 	}
 	// 跟进记录map
 	for index, followup := range originalFollowupList {
@@ -272,11 +300,11 @@ func (s *followupService) GetListByDay(req *model.SearchPlatFollowupReq) (total
 			followupMap[followup.FollowDate.Format("Y-m-d")] = make([]*model.FollowupInfo, 0)
 		}
 		if followup.Comments == nil {
-			originalFollowupList[index].Comments = make([]*model.PlatFollowupComment, 0)
+			originalFollowupList[index].Comments = make([]*model.FollowupCommentEx, 0)
 		}
 		// 为跟进记录填充评论数据
-		if _, ok := commentMap[followup.Id]; ok {
-			originalFollowupList[index].Comments = append(originalFollowupList[index].Comments, commentMap[followup.Id]...)
+		if _, ok := followupCommentMap[followup.Id]; ok {
+			originalFollowupList[index].Comments = append(originalFollowupList[index].Comments, followupCommentMap[followup.Id]...)
 		}
 		originalFollowupList[index].CommentNumber = len(originalFollowupList[index].Comments)
 		followupMap[followup.FollowDate.Format("Y-m-d")] = append(followupMap[followup.FollowDate.Format("Y-m-d")], &originalFollowupList[index])

+ 134 - 5
opms_parent/app/service/plat/plat_followup_comment.go

@@ -31,14 +31,14 @@ func NewFollowupCommentService(ctx context.Context) (svc *followupCommentService
 }
 
 // 跟进记录留言信息列表
-func (s *followupCommentService) GetList(req *model.SearchPlatFollowupCommentReq) (total int, followupCommentList []*model.PlatFollowupComment, err error) {
+func (s *followupCommentService) GetList(req *model.SearchPlatFollowupCommentReq) (total int, followupCommentList []*model.FollowupCommentEx, err error) {
 	followupCommentModel := s.Dao.M
 
 	if req.FollowId != "" {
-		followupCommentModel = followupCommentModel.Where("follow_id", req.FollowId)
+		followupCommentModel = followupCommentModel.Where("plat_followup_comment.follow_id", req.FollowId)
 	}
 	if req.Pid != "" {
-		followupCommentModel = followupCommentModel.Where("pid", req.Pid)
+		followupCommentModel = followupCommentModel.Where("plat_followup_comment.pid", req.Pid)
 	}
 	total, err = followupCommentModel.Count()
 	if err != nil {
@@ -47,11 +47,122 @@ func (s *followupCommentService) GetList(req *model.SearchPlatFollowupCommentReq
 		return
 	}
 
-	err = followupCommentModel.Order("created_time DESC").Scan(&followupCommentList)
+	err = followupCommentModel.Order("plat_followup_comment.created_time DESC").Scan(&followupCommentList)
+	if err != nil && err != sql.ErrNoRows {
+		g.Log().Error(err)
+		err = myerrors.DbError("获取数据失败。")
+		return
+	}
+	// 获取回复数据
+	var replyComments []*model.FollowupCommentEx
+	err = followupCommentModel.InnerJoin("plat_followup_comment b", "b.pid=plat_followup_comment.id").Fields("b.*").Order("b.id ASC").Scan(&replyComments)
+	if err != nil && err != sql.ErrNoRows {
+		g.Log().Error(err)
+		err = myerrors.DbError("获取数据失败。")
+		return
+	}
+
+	commentMap := make(map[int]*model.FollowupCommentEx)
+	for index, comment := range followupCommentList {
+		commentMap[comment.Id] = followupCommentList[index]
+	}
+	// 构造回复数据
+	for _, comment := range replyComments {
+		if commentMap[comment.Pid].ReplyComments == nil {
+			commentMap[comment.Pid].ReplyComments = make([]*model.FollowupCommentEx, 0)
+		}
+		commentMap[comment.Pid].ReplyComments = append(commentMap[comment.Pid].ReplyComments, comment)
+	}
+
+	return
+}
+
+// NeedReplyList 本人需要回复的评论列表
+func (s *followupCommentService) NeedReplyList(req *model.SearchNeedReplyCommentsReq) (total int, followupCommentList []*model.PlatFollowupComment, err error) {
+	followupModel := s.FollowupDao.As("a").M.InnerJoin(plat.PlatFollowupComment.Table+" b", "a.id=b.follow_id").LeftJoin(plat.PlatFollowupComment.Table+" reply", "b.id=reply.pid")
+	// 本人创建的评论
+	followupModel = followupModel.Where("a."+s.Dao.C.CreatedBy, s.GetCxtUserId())
+	// 第一级的 未回复的 评论
+	followupModel = followupModel.Where("(b.pid=0 OR b.pid IS NULL) AND reply.id IS NULL")
+	// 分组去重
+	followupModel = followupModel.Group("b.id")
+
+	total, err = followupModel.Count()
+	if err != nil {
+		g.Log().Error(err)
+		err = myerrors.DbError("获取总行数失败。")
+		return
+	}
+
+	err = followupModel.Order("b.created_time ASC").Fields("b.*").Scan(&followupCommentList)
 	return
 }
 
-// 添加信息
+// NeedReplyCount 本人需要回复的评论数量
+func (s *followupCommentService) NeedReplyCount(req *model.SearchNeedReplyCommentsReq) (total int, err error) {
+	followupModel := s.FollowupDao.As("a").M.InnerJoin(plat.PlatFollowupComment.Table+" b", "a.id=b.follow_id").LeftJoin(plat.PlatFollowupComment.Table+" reply", "b.id=reply.pid")
+	// 本人创建的评论
+	followupModel = followupModel.Where("a."+s.Dao.C.CreatedBy, s.GetCxtUserId())
+	// 第一级的 未回复的 评论
+	followupModel = followupModel.Where("(b.pid=0 OR b.pid IS NULL) AND reply.id IS NULL")
+	// 分组去重
+	followupModel = followupModel.Group("b.id")
+
+	total, err = followupModel.Count()
+	if err != nil {
+		g.Log().Error(err)
+		err = myerrors.DbError("获取总行数失败。")
+		return
+	}
+
+	return
+}
+
+// LatestComments 获取最新50条数据
+func (s *followupCommentService) LatestComments(req *model.SearchPlatFollowupCommentReq) (total int, followupCommentList []*model.FollowupCommentEx2, err error) {
+	// 默认50条数据
+	if req.PageSize == 0 {
+		req.PageSize = 50
+	}
+	if req.PageNum == 0 {
+		req.PageNum = 1
+	}
+
+	followupCommentModel := s.Dao.M.InnerJoin("plat_followup c", "plat_followup_comment.follow_id=c.id")
+	// 只查询第一层评论
+	followupCommentModel = followupCommentModel.Where("plat_followup_comment.pid=0 OR plat_followup_comment.pid IS NULL")
+
+	err = followupCommentModel.Order("plat_followup_comment.created_time DESC").Page(req.GetPage()).Fields("plat_followup_comment.*,c.target_type,c.target_name").Scan(&followupCommentList)
+	if err != nil && err != sql.ErrNoRows {
+		g.Log().Error(err)
+		err = myerrors.DbError("获取数据失败。")
+		return
+	}
+	// 获取回复数据
+	var replyComments []*model.FollowupCommentEx2
+	err = followupCommentModel.InnerJoin("plat_followup_comment b", "b.pid=plat_followup_comment.id").Fields("b.*,c.target_type,c.target_name").Order("b.id ASC").Scan(&replyComments)
+	if err != nil && err != sql.ErrNoRows {
+		g.Log().Error(err)
+		err = myerrors.DbError("获取数据失败。")
+		return
+	}
+
+	commentMap := make(map[int]*model.FollowupCommentEx2)
+	for index, comment := range followupCommentList {
+		commentMap[comment.Id] = followupCommentList[index]
+	}
+	// 构造回复数据
+	for _, comment := range replyComments {
+		if commentMap[comment.Pid].ReplyComments == nil {
+			commentMap[comment.Pid].ReplyComments = make([]*model.FollowupCommentEx2, 0)
+		}
+		commentMap[comment.Pid].ReplyComments = append(commentMap[comment.Pid].ReplyComments, comment)
+	}
+
+	return
+}
+
+// 添加评论
 func (s *followupCommentService) Create(req *model.AddPlatFollowupCommentReq) (err error) {
 	followup, err := s.FollowupDao.WherePri(req.FollowId).One()
 	if err != nil {
@@ -97,3 +208,21 @@ func (s *followupCommentService) Create(req *model.AddPlatFollowupCommentReq) (e
 
 	return
 }
+
+// Reply 回复评论
+func (s *followupCommentService) Reply(req *model.AddPlatFollowupCommentReq) (err error) {
+	platFollowupComment := new(model.PlatFollowupComment)
+	if err = gconv.Struct(req, platFollowupComment); err != nil {
+		return
+	}
+	// 填充创建信息
+	service.SetCreatedInfo(platFollowupComment, s.GetCxtUserId(), s.GetCxtUserName())
+	// 填充更新信息
+	//service.SetUpdatedInfo(platFollowupComment, s.GetCxtUserId(), s.GetCxtUserName())
+	_, err = s.Dao.Insert(platFollowupComment)
+	if err != nil {
+		return
+	}
+
+	return
+}