package orderman import ( "fmt" "math/rand" "time" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" "git.rosy.net.cn/jx-callback/business/jxutils/weixinmsg" "git.rosy.net.cn/jx-callback/business/model" "git.rosy.net.cn/jx-callback/business/model/dao" "git.rosy.net.cn/jx-callback/business/model/legacymodel" "git.rosy.net.cn/jx-callback/business/partner" "git.rosy.net.cn/jx-callback/globals" ) const ( COMMENT_NOT_RESOLVED = 0 //未解决的差评状态 COMMENT_RESOLVED = 1 //已解决的差评状态 JX_BAD_COMMENTS_MAX_LEVEL = 2 // 差评最大分 JX_MIDDLE_COMMENTS_MAX_LEVEL = 4 // 中评最大分 COMMENTS_SCORE_ONE_ORTWO_BEGIN_DELAY_TIME = 1 * 60 //评论回复一星或二星回复延迟开始时间区间 COMMENTS_SCORE_ONE_ORTWO_END_DELAY_TIME = 3 * 60 //评论回复一星或二星回复延迟结束时间区间 COMMENTS_SCORE_THREE_BEGIN_DELAY_TIME = 2 * 60 //评论回复三星回复延迟开始时间区间 COMMENTS_SCORE_THREE_END_DELAY_TIME = 4 * 60 //评论回复三星回复延迟结束时间区间 COMMENTS_SCORE_FOUR_ORFIVE_BEGIN_DELAY_TIME = 2 * 60 //评论回复四星或五星回复延迟开始时间区间 COMMENTS_SCORE_FOUR_ORFIVE_END_DELAY_TIME = 5 * 60 //评论回复四星或五星回复延迟结束时间区间 MAX_REAPLY_TIME = 18 * time.Hour ) type tReplyConfig struct { delayGapBegin int delayGapEnd int comments []string } var ( replyConfig = map[int]*tReplyConfig{ 1: &tReplyConfig{ delayGapBegin: COMMENTS_SCORE_ONE_ORTWO_BEGIN_DELAY_TIME, delayGapEnd: COMMENTS_SCORE_ONE_ORTWO_END_DELAY_TIME, comments: []string{ "非常抱歉让您没有得到十分满意的购物体验,我们会及时与您联系进行确认并解决问题!", }, }, 3: &tReplyConfig{ delayGapBegin: COMMENTS_SCORE_THREE_BEGIN_DELAY_TIME, delayGapEnd: COMMENTS_SCORE_THREE_END_DELAY_TIME, comments: []string{ "感谢您对我们的肯定,祝您生活愉快!欢迎再次光临,谢谢!", fmt.Sprintf("感谢您对%s的关照,我们会更加精益求精。", globals.StoreName), "感谢您的光临,您的支持是我们前进的动力!", }, }, 4: &tReplyConfig{ delayGapBegin: COMMENTS_SCORE_FOUR_ORFIVE_BEGIN_DELAY_TIME, delayGapEnd: COMMENTS_SCORE_FOUR_ORFIVE_END_DELAY_TIME, comments: []string{ "感谢您的信赖!我们会不断提升菜品质量以及优质的服务,期待与您的再次相遇!", "感谢您的支持,愿您天天好心情!", "感谢您的认可!您的支持是我们前进的动力。", "感谢您的肯定与支持!我们会坚持把最好的服务带给您,期待和您的再次相遇!", }, }, } ) func (c *OrderManager) OnOrderComments(orderCommentList []*model.OrderComment) (err error) { globals.SugarLogger.Debug("OnOrderComments") db := dao.GetDB() for _, orderComment := range orderCommentList { globals.SugarLogger.Debugf("OnOrderComments, orderID:%s", orderComment.VendorOrderID) comment2 := &legacymodel.JxBadComments{ OrderId: orderComment.VendorOrderID, } err = dao.GetEntity(db, comment2, "OrderId") if err == nil || dao.IsNoRowsError(err) { isNewComment := false if dao.IsNoRowsError(err) { err = nil isNewComment = true if orderComment.IsReplied == 0 && time.Now().Sub(orderComment.CommentCreatedAt) < time.Duration(orderComment.ModifyDuration)*time.Hour { if storeDetail, err2 := dao.GetStoreDetail(db, orderComment.StoreID, orderComment.VendorID); err2 == nil { if storeDetail.AutoReplyType == model.AutoReplyAll || orderComment.Score > JX_BAD_COMMENTS_MAX_LEVEL && storeDetail.AutoReplyType == model.AutoReplyGoodComment { c.replyOrderComment(storeDetail.VendorOrgCode, orderComment) } } } } if isNewComment /*&& orderComment.Score <= JX_BAD_COMMENTS_MAX_LEVEL*/ || !isNewComment && orderComment.Score > JX_BAD_COMMENTS_MAX_LEVEL { // 如果是直接非差评,或补评仍然是差评,忽略 if isNewComment { comment2.Createtime = utils.Time2Str(orderComment.CommentCreatedAt) comment2.Score = int(orderComment.Score) comment2.Scorecontent = orderComment.Content comment2.Vendertags = orderComment.TagList comment2.Msg = orderComment.OriginalMsg comment2.Status = COMMENT_NOT_RESOLVED comment2.OrderFlag = utils.Int2Str(orderComment.VendorID) comment2.Maxmodifytime = int(orderComment.ModifyDuration) order, _ := partner.CurOrderManager.LoadOrder(orderComment.VendorOrderID, orderComment.VendorID) if order != nil { orderComment.StoreID = jxutils.GetSaleStoreIDFromOrder(order) if order.ConsigneeMobile2 != "" { orderComment.ConsigneeMobile = order.ConsigneeMobile2 } else { if handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID); handler != nil { if order2, _ := handler.GetOrder(order.VendorOrgCode, order.VendorOrderID); order2 != nil && order.ConsigneeMobile != order2.ConsigneeMobile { order.ConsigneeMobile = order2.ConsigneeMobile partner.CurOrderManager.UpdateOrderFields(order, []string{"ConsigneeMobile"}) } } orderComment.ConsigneeMobile = order.ConsigneeMobile } } else { if storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, orderComment.VendorStoreID, orderComment.VendorID); err == nil { orderComment.StoreID = storeDetail.ID } } if orderComment.StoreID > 0 { comment2.Jxstoreid = utils.Int2Str(orderComment.StoreID) } comment2.Userphone = orderComment.ConsigneeMobile if comment2.Jxstoreid != "" && orderComment.Score <= JX_MIDDLE_COMMENTS_MAX_LEVEL && time.Now().Sub(orderComment.CommentCreatedAt) < MAX_REAPLY_TIME { comment2.LastPushTime = utils.Time2Str(time.Now()) comment2.PushNo = 1 weixinmsg.PushJDBadCommentToWeiXin(comment2, orderComment.Score <= JX_BAD_COMMENTS_MAX_LEVEL, order) } } else { // 修改评价,高于JX_BAD_COMMENTS_MAX_LEVEL if orderComment.CommentCreatedAt.Sub(str2Time(comment2.Createtime)) == 0 || orderComment.CommentCreatedAt.Sub(str2Time(comment2.Updatetime)) == 0 { comment2 = nil // 重复 } else { comment2.Updatetime = utils.Time2Str(orderComment.CommentCreatedAt) comment2.UpdatedMsg = orderComment.OriginalMsg comment2.UpdatedScore = int(orderComment.Score) comment2.UpdatedScorecontent = orderComment.Content comment2.UpdatedVendertags = orderComment.TagList comment2.Status = COMMENT_RESOLVED if comment2.Jxstoreid != "" && orderComment.Score <= JX_MIDDLE_COMMENTS_MAX_LEVEL && time.Now().Sub(orderComment.CommentCreatedAt) < MAX_REAPLY_TIME { comment2.LastPushTime = utils.Time2Str(time.Now()) comment2.PushNo++ comment3 := *comment2 comment3.Createtime = comment2.Updatetime comment3.Score = comment2.UpdatedScore comment3.Scorecontent = comment2.UpdatedScorecontent comment3.Vendertags = comment2.UpdatedVendertags order, _ := partner.CurOrderManager.LoadOrder(orderComment.VendorOrderID, orderComment.VendorID) weixinmsg.PushJDBadCommentToWeiXin(&comment3, orderComment.Score <= JX_BAD_COMMENTS_MAX_LEVEL, order) } } } if err == nil { if isNewComment { err = dao.CreateEntity(db, comment2) } else if comment2 != nil { _, err = dao.UpdateEntity(db, comment2) } } } } if err != nil { globals.SugarLogger.Warnf("OnOrderComments orderID:%s failed with error:%v", orderComment.VendorOrderID, err) break } } return err } func (c *OrderManager) replyOrderComment(vendorOrgCode string, orderComment *model.OrderComment) (err error) { score := int(orderComment.Score) if score <= 2 { score = 1 } else if score >= 5 { score = 4 } config := replyConfig[score] delaySeconds := config.delayGapBegin + rand.Intn(config.delayGapEnd-config.delayGapBegin) content := config.comments[rand.Intn(len(config.comments))] globals.SugarLogger.Debugf("replyOrderComment orderID:%s, delaySeconds:%d, content:%s", orderComment.VendorOrderID, delaySeconds, content) utils.AfterFuncWithRecover(time.Duration(delaySeconds)*time.Second, func() { if handler := partner.GetPurchaseOrderHandlerFromVendorID(orderComment.VendorID); handler != nil { if err = handler.ReplyOrderComment(jxcontext.AdminCtx, vendorOrgCode, orderComment, content); err != nil { globals.SugarLogger.Debugf("replyOrderComment orderID:%s, error:%v", orderComment.VendorOrderID, err) } } else { globals.SugarLogger.Warnf("replyOrderComment can not find handler orderID:%s", orderComment.VendorOrderID) } }) // todo 这里直接延时,可以导致服务器重启时漏掉回复,但如果用管理任务,又会导致大量评价任务存在与任务列表中 // task := tasksch.NewParallelTask(fmt.Sprintf("回复订单:%s评价", orderComment.VendorOrderID), nil, jxcontext.AdminCtx, // func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { // return retVal, err // }, []int{0}) // tasksch.HandleTask(task, nil, true).Run() return err } func str2Time(timeStr string) time.Time { if timeStr == "" { return utils.DefaultTimeValue } return utils.Str2Time(timeStr) }