@@ -2,26 +2,12 @@ package weixinmsg
import (
"fmt"
"strings"
"time"
"github.com/astaxie/beego"
"git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin"
"git.rosy.net.cn/jx-callback/business/authz/autils"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxutils"
"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/globals"
"git.rosy.net.cn/jx-callback/globals/api"
"git.rosy.net.cn/jx-callback/globals/api2"
)
const (
@@ -93,63 +79,6 @@ var (
}
)
func GetWeixinOpenIDsFromStoreID ( storeID int ) ( retVal [ ] string ) {
db := dao . GetDB ( )
openIDMap := make ( map [ string ] int )
if globals . EnableWXAuth2 {
if userIDList , err2 := api2 . RoleMan . GetRoleUserList ( autils . NewStoreBossRole ( storeID ) ) ; err2 == nil {
for _ , v := range userIDList {
if authList , err2 := dao . GetUserBindAuthInfo ( db , v , model . AuthBindTypeAuth , [ ] string { weixin . AuthTypeMP } , "" , "" , "" ) ; err2 == nil {
for _ , v := range authList {
retVal = append ( retVal , v . AuthID )
openIDMap [ v . AuthID ] = 1
}
}
}
}
}
retVal = jxutils . StringMap2List ( openIDMap )
if ! globals . ReallyCallPlatformAPI {
// todo, 调试, 只发给我
globals . SugarLogger . Debugf ( "GetWeixinOpenIDsFromStoreID store:%d, openids:%v" , storeID , retVal )
if storeID == 100146 {
retVal = [ ] string { "oYN_ust9hXKEvEv0X6Mq6nlAWs_E" }
} else {
retVal = nil
}
}
return retVal
}
func SendMsgToStore ( storeID int , templateID , downloadURL , miniPageURL string , data interface { } ) ( err error ) {
globals . SugarLogger . Debugf ( "SendMsgToStore storeID:%d, templateID:%s, downloadURL:%s, miniPageURL:%s" , storeID , templateID , downloadURL , miniPageURL )
if storeID == 0 { // 测试,只发给我
// SmartMessageTemplateSend("oYN_ust9hXKEvEv0X6Mq6nlAWs_E", templateID, downloadURL, miniPageURL, data)
} else {
openIDs := GetWeixinOpenIDsFromStoreID ( storeID )
successCount := 0
for _ , openID := range openIDs {
realMiniPageURL := miniPageURL
// if testMiniProgramStoreMap[storeID] == 0 && debugOpenIDMap[openID] == 0 {
// realMiniPageURL = ""
// }
globals . SugarLogger . Debugf ( "SendMsgToStore storeID:%d, openID:%s, templateID:%s, downloadURL:%s, realMiniPageURL:%s" , storeID , openID , templateID , downloadURL , realMiniPageURL )
if err2 := SmartMessageTemplateSend ( openID , templateID , downloadURL , realMiniPageURL , data ) ; err2 == nil {
successCount ++
} else {
err = err2
}
}
if successCount > 0 {
err = nil // 只要成功一个都当成成功
}
if err != nil {
globals . SugarLogger . Debugf ( "SendMsgToStore all failed storeID:%d, templateID:%s, error:%v" , storeID , templateID , err )
}
}
return err
}
func SmartMessageTemplateSend ( userOpenID , templateID , downloadURL , miniPageURL string , data interface { } ) ( err error ) {
var miniProgram map [ string ] interface { }
if miniPageURL != "" {
@@ -167,728 +96,6 @@ func SmartMessageTemplateSend(userOpenID, templateID, downloadURL, miniPageURL s
return err
}
func getOrderDetailBrief ( order * model . GoodsOrder ) ( brief string ) {
sb := new ( strings . Builder )
sb . WriteString ( order . Skus [ 0 ] . SkuName )
sb . WriteString ( "等共" )
sb . WriteString ( utils . Int2Str ( order . Skus [ 0 ] . Count ) )
sb . WriteString ( "份(" )
sb . WriteString ( jxutils . IntPrice2StandardString ( order . Skus [ 0 ] . SalePrice ) )
sb . WriteString ( "元/份)等,预计收入" )
//TODO 2020-07-20 果园和菜市不同
var price int64
if beego . BConfig . RunMode == "jxgy" {
price = order . NewEarningPrice
} else {
if order . EarningType == model . EarningTypePoints {
price = order . ActualPayPrice
} else {
price = order . ShopPrice
}
}
sb . WriteString ( jxutils . IntPrice2StandardString ( price ) )
sb . WriteString ( "元" )
return sb . String ( )
}
func NotifyNewOrder ( order * model . GoodsOrder ) ( err error ) {
globals . SugarLogger . Debugf ( "NotifyNewOrder orderID:%s" , order . VendorOrderID )
if order . VendorID == model . VendorIDELM {
return nil
}
if ! model . IsOrderSolid ( order ) {
globals . SugarLogger . Infof ( "NotifyNewOrder orderID:%s is not solid" , order . VendorOrderID )
return nil
}
sb := new ( strings . Builder )
sb . WriteString ( "老板," )
sb . WriteString ( order . ConsigneeName )
sb . WriteString ( "购买了商品" )
sb . WriteString ( getOrderDetailBrief ( order ) )
data := map [ string ] interface { } {
"first" : map [ string ] interface { } {
"value" : sb . String ( ) ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"Day" : map [ string ] interface { } {
"value" : FormatDeliveryTime ( order ) ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"orderId" : map [ string ] interface { } {
"value" : order . VendorOrderID ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"orderType" : map [ string ] interface { } {
"value" : fmt . Sprintf ( "%s 第%d号订单" , model . VendorChineseNames [ order . VendorID ] , order . OrderSeq ) ,
"color" : VendorColors [ order . VendorID ] ,
} ,
"customerName" : map [ string ] interface { } {
"value" : order . ConsigneeName ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"customerPhone" : map [ string ] interface { } {
"value" : order . ConsigneeMobile ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
}
storeID := jxutils . GetSaleStoreIDFromOrder ( order )
return SendMsgToStore ( storeID , WX_NEWORDER_TEMPLATE_ID , globals . WxBackstageHost + fmt . Sprintf ( "%s%d" , WX_TO_ORDER_PAGE_URL , storeID ) , WX_MINI_TO_ORDER_PAGE_URL , data )
}
func NotifyWaybillStatus ( bill * model . Waybill , order * model . GoodsOrder , isBillAlreadyCandidate bool ) ( err error ) {
globals . SugarLogger . Debugf ( "NotifyWaybillStatus orderID:%s bill:%v" , order . VendorOrderID , bill )
if order . VendorID == model . VendorIDELM {
return nil
}
if ! model . IsOrderSolid ( order ) {
globals . SugarLogger . Infof ( "NotifyWaybillStatus orderID:%s is not solid" , order . VendorOrderID )
return nil
}
var title string
templateID := ""
remark := ""
titleColor := ""
switch bill . Status {
case model . WaybillStatusAccepted :
if bill . WaybillVendorID == model . VendorIDMTPS {
templateID = WX_MTPS_DELIVERY_GRABDONE_TEMPLATE_ID
} else if bill . WaybillVendorID == model . VendorIDDada {
templateID = WX_DADA_DELIVERY_GRABDONE_TEMPLATE_ID
}
remark = FormatDeliveryTime ( order )
if isBillAlreadyCandidate {
titleColor = WX_HIGHLEVEL_TEMPLATE_COLOR
title = fmt . Sprintf ( "%s 第%d号订单由于之前安排的配送员长时间没有取货, 我们已重新安排%s配送员%s负责配送。^_^" , model . VendorChineseNames [ bill . OrderVendorID ] , order . OrderSeq , model . VendorChineseNames [ bill . WaybillVendorID ] , bill . CourierName )
} else {
titleColor = WX_HIGHLEVEL_TEMPLATE_COLOR2
title = fmt . Sprintf ( "%s 第%d号订单长时间无人配送, 我们已安排%s配送员%s负责配送。^_^" , model . VendorChineseNames [ bill . OrderVendorID ] , order . OrderSeq , model . VendorChineseNames [ bill . WaybillVendorID ] , bill . CourierName )
}
case model . WaybillStatusDelivered :
if bill . WaybillVendorID == model . VendorIDMTPS {
templateID = WX_MTPS_DELIVERY_DONE_TEMPLATE_ID
} else if bill . WaybillVendorID == model . VendorIDDada {
templateID = WX_DADA_DELIVERY_DONE_TEMPLATE_ID
}
titleColor = VendorColors [ bill . OrderVendorID ]
title = fmt . Sprintf ( "%s 第%d号订单的配送完成" , model . VendorChineseNames [ bill . OrderVendorID ] , order . OrderSeq )
}
if templateID != "" {
data := map [ string ] interface { } {
"first" : map [ string ] interface { } {
"value" : title ,
"color" : titleColor ,
} ,
"keyword1" : map [ string ] interface { } {
"value" : bill . VendorOrderID ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"keyword2" : map [ string ] interface { } {
"value" : fmt . Sprintf ( "%s( %s) " , bill . CourierName , model . VendorChineseNames [ bill . WaybillVendorID ] ) ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"keyword3" : map [ string ] interface { } {
"value" : bill . CourierMobile ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"remark" : map [ string ] interface { } {
"value" : remark ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
}
err = SendMsgToStore ( jxutils . GetSaleStoreIDFromOrder ( order ) , templateID , "" , "" , data )
}
return err
}
func NotifyUserApplyCancel ( order * model . GoodsOrder , cancelReason string ) ( err error ) {
globals . SugarLogger . Debugf ( "NotifyUserApplyCancel orderID:%s" , order . VendorOrderID )
if order . VendorID == model . VendorIDELM {
return nil
}
if ! model . IsOrderSolid ( order ) {
globals . SugarLogger . Infof ( "NotifyUserApplyCancel orderID:%s is not solid" , order . VendorOrderID )
return nil
}
title := "老板,您有订单申请取消!请及时联系客户处理!"
data := map [ string ] interface { } {
"first" : map [ string ] interface { } {
"value" : title ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"keyword1" : map [ string ] interface { } { // 订单编号
"value" : fmt . Sprintf ( "%s第%d号订单, %s" , model . VendorChineseNames [ order . VendorID ] , order . OrderSeq , order . VendorOrderID ) ,
"color" : VendorColors [ order . VendorID ] ,
} ,
"keyword2" : map [ string ] interface { } { // 订单日期
"value" : utils . Time2Str ( order . OrderCreatedAt ) ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"keyword3" : map [ string ] interface { } { // 订单内容
"value" : cancelReason ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"remark" : map [ string ] interface { } {
"value" : order . ConsigneeMobile ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
}
storeID := jxutils . GetSaleStoreIDFromOrder ( order )
err = SendMsgToStore ( storeID , WX_ORDER_APPLY_CANCEL_TEMPLATE_ID , "" , "" , data )
return err
}
func NotifyOrderChanged ( order * model . GoodsOrder ) ( err error ) {
globals . SugarLogger . Debugf ( "NotifyOrderChanged orderID:%s" , order . VendorOrderID )
if order . VendorID == model . VendorIDELM {
return nil
}
title := fmt . Sprintf ( "您有订单的信息已被修改" )
data := map [ string ] interface { } {
"first" : map [ string ] interface { } {
"value" : title ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"keyword1" : map [ string ] interface { } {
"value" : order . VendorOrderID ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"keyword2" : map [ string ] interface { } {
"value" : "用户修改订单" ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"keyword3" : map [ string ] interface { } {
"value" : order . ConsigneeAddress + ", " + order . ConsigneeName + ", " + order . ConsigneeMobile + ", " + order . BuyerComment ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"keyword4" : map [ string ] interface { } {
"value" : utils . Time2Str ( order . OrderCreatedAt ) ,
"color" : VendorColors [ order . VendorID ] ,
} ,
"remark" : map [ string ] interface { } {
"value" : "请及时处理" ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
}
storeID := jxutils . GetSaleStoreIDFromOrder ( order )
err = SendMsgToStore ( storeID , WX_ORDER_CHANGE_INFO_TEMPLATE_ID , "" , "" , data )
return err
}
func NotifyOrderCanceled ( order * model . GoodsOrder ) ( err error ) {
globals . SugarLogger . Debugf ( "NotifyOrderCanceled orderID:%s" , order . VendorOrderID )
if order . VendorID == model . VendorIDELM {
return nil
}
if ! model . IsOrderSolid ( order ) {
globals . SugarLogger . Infof ( "NotifyOrderCanceled orderID:%s is not solid" , order . VendorOrderID )
return nil
}
title := fmt . Sprintf ( "老板,您的订单%s第%d号订单, %s被取消了! " , model . VendorChineseNames [ order . VendorID ] , order . OrderSeq , order . VendorOrderID )
data := map [ string ] interface { } {
"first" : map [ string ] interface { } {
"value" : title ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"orderProductPrice" : map [ string ] interface { } {
"value" : jxutils . IntPrice2StandardCurrencyString ( order . ActualPayPrice ) ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"orderProductName" : map [ string ] interface { } {
"value" : getOrderDetailBrief ( order ) ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"orderAddress" : map [ string ] interface { } {
"value" : order . ConsigneeAddress ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"orderName" : map [ string ] interface { } {
"value" : fmt . Sprintf ( "%s第%d号订单, %s" , model . VendorChineseNames [ order . VendorID ] , order . OrderSeq , order . VendorOrderID ) ,
"color" : VendorColors [ order . VendorID ] ,
} ,
"remark" : map [ string ] interface { } {
"value" : order . ConsigneeMobile ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
}
storeID := jxutils . GetSaleStoreIDFromOrder ( order )
err = SendMsgToStore ( storeID , WX_ORDER_ORDER_CANCELED_TEMPLATE_ID , "" , "" , data )
return err
}
func PushJDBadCommentToWeiXin ( comment * legacymodel . JxBadComments , isBadComment bool , order * model . GoodsOrder ) ( err error ) {
globals . SugarLogger . Debugf ( "PushJDBadCommentToWeiXin orderID:%s" , comment . OrderId )
sb := new ( strings . Builder )
sb . WriteString ( fmt . Sprintf ( "你收到了%s客户(" , model . VendorChineseNames [ int ( utils . Str2Int64WithDefault ( comment . OrderFlag , 0 ) ) ] ) )
sb . WriteString ( comment . Userphone )
sb . WriteString ( ")的一条" )
sb . WriteString ( utils . Int2Str ( comment . Score ) )
if isBadComment {
sb . WriteString ( "星差评, 请商家在1小时内及时联系客户处理!" )
} else {
sb . WriteString ( "星中评, 如有必要, 请商家在1小时内及时联系客户处理!" )
}
title := sb . String ( )
var orderInfo string
consigneeName := comment . Userphone
if order != nil {
orderInfo = fmt . Sprintf ( "%s第%d号订单, %s" , model . VendorChineseNames [ int ( utils . Str2Int64WithDefault ( comment . OrderFlag , 0 ) ) ] , order . OrderSeq , comment . OrderId )
consigneeName = order . ConsigneeName
} else {
orderInfo = fmt . Sprintf ( "%s订单, %s" , model . VendorChineseNames [ int ( utils . Str2Int64WithDefault ( comment . OrderFlag , 0 ) ) ] /*comment.OrderId*/ , "" )
}
data := map [ string ] interface { } {
"first" : map [ string ] interface { } {
"value" : title ,
"color" : WX_HIGHLEVEL_TEMPLATE_COLOR ,
} ,
"keyword1" : map [ string ] interface { } {
"value" : genJdCommentRemark ( comment ) ,
"color" : WX_TEMPLATE_VENDERCOLOR_BAD_COMMENTS ,
} ,
"keyword2" : map [ string ] interface { } {
"value" : comment . Score ,
"color" : WX_TEMPLATE_VENDERCOLOR_BAD_COMMENTS ,
} ,
"keyword3" : map [ string ] interface { } {
"value" : orderInfo ,
"color" : WX_TEMPLATE_VENDERCOLOR_BAD_COMMENTS ,
} ,
"keyword4" : map [ string ] interface { } {
"value" : consigneeName ,
"color" : WX_TEMPLATE_VENDERCOLOR_BAD_COMMENTS ,
} ,
"keyword5" : map [ string ] interface { } {
"value" : comment . Userphone ,
"color" : WX_TEMPLATE_VENDERCOLOR_BAD_COMMENTS ,
} ,
}
storeID := int ( utils . Str2Int64 ( comment . Jxstoreid ) )
err = SendMsgToStore ( storeID , WX_BAD_COMMENT_PUSH_TEMPLATE_ID , globals . WxBackstageHost + fmt . Sprintf ( "%s%d" , WX_TO_SHOW_COMMENTS_DETAIL_URL , storeID ) , WX_MINI_TO_SHOW_COMMENTS_DETAIL_URL , data )
return err
}
func NotifySaleBill ( storeID int , title , shopName , fileURL string ) ( err error ) {
globals . SugarLogger . Debugf ( "NotifySaleBill storeID:%d, fileURL:%s" , storeID , fileURL )
if title == "" {
title = "当期账单"
}
if shopName == "" {
shopName = globals . StoreName
}
data := map [ string ] interface { } {
"first" : map [ string ] interface { } {
"value" : "新的账单上传成功!" ,
"color" : "#00008B" ,
} ,
"keyword1" : map [ string ] interface { } {
"value" : title ,
} ,
"keyword2" : map [ string ] interface { } {
"value" : "点击查看详情" ,
"color" : "#00008B" ,
} ,
"keyword3" : map [ string ] interface { } {
"value" : shopName ,
} ,
"keyword4" : map [ string ] interface { } {
"value" : utils . GetCurTimeStr ( ) ,
} ,
"remark" : map [ string ] interface { } {
"value" : "手机买菜上京西,极速到家送惊喜" ,
} ,
}
return SendMsgToStore ( storeID , WX_SALE_BILL_TEMPLATE_ID , fileURL , "" , data )
}
func NotifyStoreOpRequestStatus ( isAccepted bool , storeID , nameID int , spuName string , originalUnitPrice , unitPrice int , rejectReason string ) ( err error ) {
globals . SugarLogger . Debugf ( "NotifyStoreOpRequestStatus isAccepted:%t, storeID:%d, nameID:%d, spuName:%s, originalUnitPrice:%d, unitPrice:%d, rejectReason:%s" , isAccepted , storeID , nameID , spuName , originalUnitPrice , unitPrice , rejectReason )
templateID := ""
fileURL := globals . WxBackstageHost + fmt . Sprintf ( "%s%d" , WX_TO_STORE_SKU_PAGE_URL , storeID )
data := make ( map [ string ] interface { } )
if isAccepted {
templateID = WX_CHANGE_APPROVED_TEMPLATE_ID
data = map [ string ] interface { } {
"first" : map [ string ] interface { } {
"value" : fmt . Sprintf ( "%s%s元, 修改为%s元, 已经通过审核。^_^" , spuName , jxutils . IntPrice2StandardString ( int64 ( originalUnitPrice ) ) , jxutils . IntPrice2StandardString ( int64 ( unitPrice ) ) ) ,
"color" : "#333333" ,
} ,
"keyword1" : map [ string ] interface { } {
"value" : "审核通过" ,
"color" : "#2E408E" ,
} ,
"keyword2" : map [ string ] interface { } {
"value" : utils . Time2Str ( time . Now ( ) ) ,
"color" : "#2E408E" ,
} ,
"remark" : map [ string ] interface { } {
"value" : "点击查看详情" ,
} ,
}
} else {
templateID = WX_CHANGE_REJECTED_TEMPLATE_ID
data = map [ string ] interface { } {
"first" : map [ string ] interface { } {
"value" : fmt . Sprintf ( "您好!抱歉的通知您。%s%s元, 修改为%s元, 未通过审核。原因: %s" , spuName , jxutils . IntPrice2StandardString ( int64 ( originalUnitPrice ) ) , jxutils . IntPrice2StandardString ( int64 ( unitPrice ) ) , rejectReason ) ,
"color" : "#E80000" ,
} ,
"keyword1" : map [ string ] interface { } {
"value" : "1" ,
"color" : "#2E408E" ,
} ,
"keyword2" : map [ string ] interface { } {
"value" : "审核不通过" ,
"color" : "#2E408E" ,
} ,
"keyword3" : map [ string ] interface { } {
"value" : utils . Time2Str ( time . Now ( ) ) ,
"color" : "#2E408E" ,
} ,
"keyword4" : map [ string ] interface { } {
"value" : "审核不通过" ,
"color" : "#2E408E" ,
} ,
"remark" : map [ string ] interface { } {
"value" : "请您及时到商品管理修改价格,修改后请重新提交。" ,
} ,
}
}
err = SendMsgToStore ( storeID , templateID , fileURL , WX_MINI_TO_STORE_SKU_PAGE_URL , data )
return err
}
func NotifyStoreMessage ( storeID , msgID , msgStatusID int , title , content string ) ( err error ) {
globals . SugarLogger . Debugf ( "NotifyStoreMessage storeID:%d, msgID:%d, title:%s, content:%s" , storeID , msgID , title , content )
templateID := WX_NORMAL_STORE_MSG_TEMPLATE_ID
fileURL := globals . WxBackstageHost + fmt . Sprintf ( WX_TO_SHOW_MSG , msgID , msgStatusID )
data := map [ string ] interface { } {
"first" : map [ string ] interface { } {
"value" : content ,
"color" : "#333333" ,
} ,
"keyword1" : map [ string ] interface { } {
"value" : title ,
"color" : "#2E408E" ,
} ,
"keyword2" : map [ string ] interface { } {
"value" : utils . GetCurTimeStr ( ) ,
"color" : "#2E408E" ,
} ,
"remark" : map [ string ] interface { } {
"value" : "" ,
} ,
}
return SendMsgToStore ( storeID , templateID , fileURL , fmt . Sprintf ( WX_MINI_TO_SHOW_MSG , msgID , msgStatusID ) , data )
}
func NotifyAfsOrderStatus ( afsOrder * model . AfsOrder ) ( err error ) {
globals . SugarLogger . Debugf ( "NotifyAfsOrderStatus orderID:%s" , afsOrder . VendorOrderID )
if afsOrder . VendorID == model . VendorIDELM {
return nil
}
var templateID , comment string
if afsOrder . Status == model . AfsOrderStatusWait4Approve {
templateID = WX_AFS_ORDER_WAIT4APPROVE_TEMPLATE_ID
comment = "您有新售后单,请尽快处理"
} else if afsOrder . Status == model . AfsOrderStatusWait4ReceiveGoods {
templateID = WX_AFS_ORDER_STATUS_CHANGED_TEMPLATE_ID
comment = "商家您好!如顾客商品已成功退回,请点击确认收货"
} else {
return err
}
order , err := partner . CurOrderManager . LoadOrder ( afsOrder . VendorOrderID , afsOrder . VendorID )
if err != nil {
return err
}
data := map [ string ] interface { } {
"first" : map [ string ] interface { } {
"value" : fmt . Sprintf ( "%s 第%d号订单, %s" , model . VendorChineseNames [ afsOrder . VendorID ] , order . OrderSeq , afsOrder . VendorOrderID ) ,
"color" : WX_HIGHLEVEL_TEMPLATE_COLOR2 ,
} ,
"keyword1" : map [ string ] interface { } {
"value" : afsOrder . AfsOrderID ,
"color" : WX_TEMPLATE_VENDERCOLOR_JDDJ ,
} ,
"keyword2" : map [ string ] interface { } {
"value" : model . OrderStatusName [ afsOrder . Status ] ,
"color" : WX_HIGHLEVEL_TEMPLATE_COLOR ,
} ,
"keyword3" : map [ string ] interface { } {
"value" : utils . Time2Str ( afsOrder . AfsCreatedAt ) ,
"color" : VendorColors [ order . VendorID ] ,
} ,
"remark" : map [ string ] interface { } {
"value" : comment ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
}
storeID := jxutils . GetSaleStoreIDFromAfsOrder ( afsOrder )
err = SendMsgToStore ( storeID , templateID , globals . WxBackstageHost + fmt . Sprintf ( "%s%d" , WX_TO_ORDER_PAGE_URL , storeID ) , WX_MINI_TO_ORDER_PAGE_URL , data )
return err
}
func FormatDeliveryTime ( order * model . GoodsOrder ) string {
var tmpTime time . Time
if order . ExpectedDeliveredTime == utils . DefaultTimeValue {
tmpTime = order . OrderCreatedAt . Add ( 1 * time . Hour )
} else {
tmpTime = order . ExpectedDeliveredTime
}
left := tmpTime . Sub ( time . Now ( ) ) / time . Minute
leftHours := left / 60
leftMinutes := left % 60
return fmt . Sprintf ( "请于%s前送达( 剩余时间%d小时%d分钟) " , utils . Time2Str ( tmpTime ) , leftHours , leftMinutes )
}
func genJdCommentRemark ( comment * legacymodel . JxBadComments ) string {
sb := new ( strings . Builder )
sb . WriteString ( "评价标签:" )
sb . WriteString ( comment . Vendertags )
sb . WriteString ( " 评价内容:" )
sb . WriteString ( comment . Scorecontent )
return sb . String ( )
}
func NotifyStoreStatusChanged ( openUserID , title , content string ) ( err error ) {
SmartMessageTemplateSend ( openUserID , WS_NOTIFY_STORE_STATUS_CHHANGED_TEMPLATE_ID , "" , "" , map [ string ] interface { } {
"first" : map [ string ] interface { } {
"value" : title ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"keyword1" : map [ string ] interface { } {
"value" : "" ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"keyword2" : map [ string ] interface { } {
"value" : utils . Time2Str ( time . Now ( ) ) ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"keyword3" : map [ string ] interface { } {
"value" : content ,
"color" : WX_HIGHLEVEL_TEMPLATE_COLOR ,
} ,
"keyword4" : map [ string ] interface { } {
"value" : "" ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"remark" : map [ string ] interface { } {
"value" : "" ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
} )
return err
}
func NotifyStoreAlertMessage ( storeID int , storeName , title , content string ) ( err error ) {
globals . SugarLogger . Debugf ( "NotifyStoreAlertMessage storeID:%d, storeName:%d, title:%s, content:%s" , storeID , storeName , title , content )
templateID := WX_STORE_ALERT_TEMPLATE_ID
data := map [ string ] interface { } {
"first" : map [ string ] interface { } {
"value" : "" ,
"color" : "#333333" ,
} ,
"keyword1" : map [ string ] interface { } {
"value" : storeName ,
"color" : "#2E408E" ,
} ,
"keyword2" : map [ string ] interface { } {
"value" : utils . GetCurTimeStr ( ) ,
"color" : "#2E408E" ,
} ,
"keyword3" : map [ string ] interface { } {
"value" : content ,
"color" : "#2E408E" ,
} ,
"remark" : map [ string ] interface { } {
"value" : "" ,
} ,
}
if false {
err = SendMsgToStore ( storeID , templateID , "" , "" , data )
}
return err
}
func SendStoreMessage ( ctx * jxcontext . Context , title , content string , storeIDs [ ] int , isAsync , isContinueWhenError bool ) ( hint string , err error ) {
db := dao . GetDB ( )
dao . Begin ( db )
defer func ( ) {
if r := recover ( ) ; r != nil {
dao . Rollback ( db )
panic ( r )
}
} ( )
msg := & model . Message {
Title : title ,
Content : content ,
Type : model . MessageTypeStore ,
}
dao . WrapAddIDCULDEntity ( msg , ctx . GetUserName ( ) )
if err = dao . CreateEntity ( db , msg ) ; err != nil {
dao . Rollback ( db )
return "" , err
}
msgStatusList := make ( [ ] * model . MessageStatus , len ( storeIDs ) )
for k , storeID := range storeIDs {
msgStatus := & model . MessageStatus {
MessageID : msg . ID ,
StoreID : storeID ,
Status : model . MessageStatusNew ,
}
dao . WrapAddIDCULDEntity ( msgStatus , ctx . GetUserName ( ) )
if err = dao . CreateEntity ( db , msgStatus ) ; err != nil {
dao . Rollback ( db )
return "" , err
}
msgStatusList [ k ] = msgStatus
}
dao . Commit ( db )
rootTask := tasksch . NewParallelTask ( "SendStoreMessage" , nil , ctx , func ( task * tasksch . ParallelTask , batchItemList [ ] interface { } , params ... interface { } ) ( retVal interface { } , err error ) {
db := dao . GetDB ( )
msgStatus := batchItemList [ 0 ] . ( * model . MessageStatus )
if err = NotifyStoreMessage ( msgStatus . StoreID , msgStatus . MessageID , msgStatus . ID , msg . Title , msg . Content ) ; err == nil {
msgStatus . Status = model . MessageStatusSendAllSuccess
} else {
msgStatus . Status = model . MessageStatusSendAllFailed
}
dao . WrapUpdateULEntity ( msgStatus , ctx . GetUserName ( ) )
// globals.SugarLogger.Debug(utils.Format4Output(msgStatus, false))
_ , err = dao . UpdateEntity ( db , msgStatus )
return nil , err
} , msgStatusList )
tasksch . HandleTask ( rootTask , nil , len ( msgStatusList ) > 5 ) . Run ( )
if ! isAsync {
_ , err = rootTask . GetResult ( 0 )
} else {
hint = rootTask . ID
}
return "" , err
}
func NotifyAdjustOrder ( order * model . GoodsOrder ) ( err error ) {
globals . SugarLogger . Debugf ( "NotifyAdjustOrder orderID:%s" , order . VendorOrderID )
if order . VendorID == model . VendorIDELM {
return nil
}
if ! model . IsOrderSolid ( order ) {
globals . SugarLogger . Infof ( "NotifyAdjustOrder orderID:%s is not solid" , order . VendorOrderID )
return nil
}
sb := new ( strings . Builder )
sb . WriteString ( "老板," )
sb . WriteString ( order . ConsigneeName )
sb . WriteString ( "调整了订单商品,请及时查看!" )
sb . WriteString ( getOrderDetailBrief ( order ) )
data := map [ string ] interface { } {
"first" : map [ string ] interface { } {
"value" : sb . String ( ) ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"keyword1" : map [ string ] interface { } {
"value" : jxutils . IntPrice2Standard ( order . NewEarningPrice ) ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"keyword2" : map [ string ] interface { } {
"value" : utils . Time2Str ( order . CreatedAt ) ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
"keyword3" : map [ string ] interface { } {
"value" : model . OrderStatusName [ order . Status ] ,
"color" : WX_NEW_ORDER_TEMPLATE_COLOR ,
} ,
}
storeID := jxutils . GetSaleStoreIDFromOrder ( order )
return SendMsgToStore ( storeID , WX_ADJUSTORDER_TEMPLATE_ID , globals . WxBackstageHost + fmt . Sprintf ( "%s%d" , WX_TO_ORDER_PAGE_URL , storeID ) , WX_MINI_TO_ORDER_PAGE_URL , data )
}
func SendUserMessage ( ctx * jxcontext . Context , title , content string , userIDs [ ] string , isAsync , isContinueWhenError bool ) ( hint string , err error ) {
db := dao . GetDB ( )
dao . Begin ( db )
defer func ( ) {
if r := recover ( ) ; r != nil {
dao . Rollback ( db )
panic ( r )
}
} ( )
msg := & model . Message {
Title : title ,
Content : content ,
Type : model . MessageTypeUser ,
}
dao . WrapAddIDCULDEntity ( msg , ctx . GetUserName ( ) )
if err = dao . CreateEntity ( db , msg ) ; err != nil {
dao . Rollback ( db )
return "" , err
}
msgStatusList := make ( [ ] * model . MessageStatus , len ( userIDs ) )
for k , userID := range userIDs {
msgStatus := & model . MessageStatus {
MessageID : msg . ID ,
UserID : userID ,
Status : model . MessageStatusNew ,
}
dao . WrapAddIDCULDEntity ( msgStatus , ctx . GetUserName ( ) )
if err = dao . CreateEntity ( db , msgStatus ) ; err != nil {
dao . Rollback ( db )
return "" , err
}
msgStatusList [ k ] = msgStatus
}
dao . Commit ( db )
rootTask := tasksch . NewParallelTask ( "SendUserMessage" , nil , ctx , func ( task * tasksch . ParallelTask , batchItemList [ ] interface { } , params ... interface { } ) ( retVal interface { } , err error ) {
db := dao . GetDB ( )
msgStatus := batchItemList [ 0 ] . ( * model . MessageStatus )
if err = NotifyUserMessage ( msgStatus . UserID , msg . Title , msg . Content ) ; err == nil {
msgStatus . Status = model . MessageStatusSendAllSuccess
} else {
msgStatus . Status = model . MessageStatusSendAllFailed
}
dao . WrapUpdateULEntity ( msgStatus , ctx . GetUserName ( ) )
_ , err = dao . UpdateEntity ( db , msgStatus )
return nil , err
} , msgStatusList )
tasksch . HandleTask ( rootTask , nil , len ( msgStatusList ) > 5 ) . Run ( )
if ! isAsync {
_ , err = rootTask . GetResult ( 0 )
} else {
hint = rootTask . ID
}
return "" , err
}
func NotifyUserMessage ( userID string , title , content string ) ( err error ) {
globals . SugarLogger . Debugf ( "NotifyUserMessage userID:%d, title:%s, content:%s" , userID , title , content )
templateID := WX_NORMAL_STORE_MSG_TEMPLATE_ID
data := map [ string ] interface { } {
"first" : map [ string ] interface { } {
"value" : content ,
"color" : "#333333" ,
} ,
"keyword1" : map [ string ] interface { } {
"value" : title ,
"color" : "#2E408E" ,
} ,
"keyword2" : map [ string ] interface { } {
"value" : utils . GetCurTimeStr ( ) ,
"color" : "#2E408E" ,
} ,
"remark" : map [ string ] interface { } {
"value" : "" ,
} ,
}
return SendMsgToUser ( userID , templateID , data )
}
func SendMsgToUser ( userID string , templateID string , data interface { } ) ( err error ) {
globals . SugarLogger . Debugf ( "SendMsgToUser userID:%d, templateID:%s" , userID , templateID )
authBinds , err := dao . GetUserBindAuthInfo ( dao . GetDB ( ) , userID , model . AuthBindTypeAuth , [ ] string { "weixinsns" } , "" , "" , "wx2bb99eb5d2c9b82c" )