diff --git a/business/jxstore/cms/cms.go b/business/jxstore/cms/cms.go index b4f3ed751..a9de6d720 100644 --- a/business/jxstore/cms/cms.go +++ b/business/jxstore/cms/cms.go @@ -62,10 +62,11 @@ func GetQiniuUploadToken(suffix string) (upTokenInfo map[string]interface{}, err Scope: globals.QiniuBucket, Expires: qiniuTokenExpires, } - upTokenInfo = make(map[string]interface{}) - upTokenInfo["token"] = putPolicy.UploadToken(api.QiniuAPI) - upTokenInfo["expires"] = putPolicy.Expires - upTokenInfo["fileName"] = genPicFileName(suffix) + upTokenInfo = map[string]interface{}{ + "token": putPolicy.UploadToken(api.QiniuAPI), + "expires": putPolicy.Expires, + "fileName": genPicFileName(suffix), + } return upTokenInfo, err } diff --git a/business/jxstore/financial/financial.go b/business/jxstore/financial/financial.go new file mode 100644 index 000000000..325117601 --- /dev/null +++ b/business/jxstore/financial/financial.go @@ -0,0 +1,83 @@ +package financial + +import ( + "context" + "fmt" + "mime/multipart" + "path" + "strings" + "time" + + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxutils" + "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" + "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/globals" + "git.rosy.net.cn/jx-callback/globals/api" + "github.com/qiniu/api.v7/storage" +) + +type tUploadFileInfo struct { + FileHeader *multipart.FileHeader + StoreID int +} + +func SendFilesToStores(files []*multipart.FileHeader, isAsync bool, userName string) (msg string, err error) { + fileList := make([]*tUploadFileInfo, len(files)) + for k, fileHeader := range files { + fileList[k] = &tUploadFileInfo{ + FileHeader: fileHeader, + } + fileNameParts := strings.Split(fileHeader.Filename, "_") + if len(fileNameParts) < 3 { + return "", fmt.Errorf("文件名:%s不规范,没有包含三个必要的部分", fileHeader.Filename) + } + fileList[k].StoreID = int(utils.Str2Int64WithDefault(fileNameParts[0], 0)) + if fileList[k].StoreID < 100000 || fileList[k].StoreID > 1000000 { + return "", fmt.Errorf("文件名:%s不规范,不以合法的京西门店ID开始", fileHeader.Filename) + } + } + putPolicy := storage.PutPolicy{ + Scope: globals.QiniuBucket, + Expires: 10 * 60, + } + upToken := putPolicy.UploadToken(api.QiniuAPI) + cfg := &storage.Config{} + task := tasksch.RunManagedTask("SendFilesToStores", false, nil, 0, 1, userName, func(batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { + fileInfo := batchItemList[0].(*tUploadFileInfo) + fileHeader := fileInfo.FileHeader + storeID := fileInfo.StoreID + file, err := fileHeader.Open() + if err == nil { + ret := storage.PutRet{} + key := "storeBill_" + utils.Int2Str(storeID) + "_" + strings.ToLower(utils.GetUUID()) + path.Ext(fileHeader.Filename) + formUploader := storage.NewFormUploader(cfg) + err = formUploader.Put(context.Background(), &ret, upToken, key, file, fileHeader.Size, nil) + file.Close() + // globals.SugarLogger.Debug(utils.Format4Output(ret, false)) + if err == nil { + db := dao.GetDB() + billRec := &model.StoreBill{ + Date: time.Now(), + Url: jxutils.ComposeQiniuResURL(ret.Key), + StoreId: storeID, + BillName: fileHeader.Filename, + } + if err = dao.CreateEntity(db, billRec); err == nil { + err = weixinmsg.NotifySaleBill(storeID, billRec.Url) + } + } + } + return retVal, err + }, fileList) + + if isAsync { + return "Running", nil + } + if _, err = task.GetResult(0); err == nil { + return "Done", nil + } + return "", err +} diff --git a/business/jxutils/jxutils.go b/business/jxutils/jxutils.go index d700f5640..c12351800 100644 --- a/business/jxutils/jxutils.go +++ b/business/jxutils/jxutils.go @@ -344,3 +344,7 @@ func MakeValidationMapFromSlice(validValues []string, flag int) map[string]int { } return retVal } + +func ComposeQiniuResURL(key string) string { + return "http://image.jxc4.com/" + key +} diff --git a/business/jxutils/weixinmsg/weixinmsg.go b/business/jxutils/weixinmsg/weixinmsg.go index ab3628a8f..2d0c19a00 100644 --- a/business/jxutils/weixinmsg/weixinmsg.go +++ b/business/jxutils/weixinmsg/weixinmsg.go @@ -33,6 +33,8 @@ const ( WX_DADA_DELIVERY_GRABDONE_TEMPLATE_ID = "h4dkON6AgnHz1XmaksEUB_8Bcir4V8MSexUhC149pPE" //微信达达众包配送员接单推送 WX_DADA_DELIVERY_DONE_TEMPLATE_ID = "YXdCrQAHZlcZX1htYUiarrLmtkmKAjp7rynjwObgODo" //微信达达众包配送员配送完成推送 + + WX_SALE_BILL_TEMPLATE_ID = "eTUuFZMWH7IsVBfcxNMpmaHYaxRkUaD6zG8wSGJDcic" ) var ( @@ -241,6 +243,33 @@ func PushJDBadCommentToWeiXin(comment *model.JxBadComments) (err error) { return SendMsgToStore(storeID, WX_BAD_COMMENT_PUSH_TEMPLATE_ID, fmt.Sprintf("%s%d", WX_TO_SHOW_COMMENTS_DETAIL_URL, storeID), data) } +func NotifySaleBill(storeID int, fileURL string) (err error) { + globals.SugarLogger.Debugf("NotifySaleBill storeID:%d, fileURL:%s", storeID, fileURL) + data := map[string]interface{}{ + "first": map[string]interface{}{ + "value": "新的账单上传成功!", + "color": "#00008B", + }, + "keyword1": map[string]interface{}{ + "value": "账单", + }, + "keyword2": map[string]interface{}{ + "value": "点击查看详情", + "color": "#00008B", + }, + "keyword3": map[string]interface{}{ + "value": "京西菜市", + }, + "keyword4": map[string]interface{}{ + "value": utils.GetCurTimeStr(), + }, + "remark": map[string]interface{}{ + "value": "手机买菜上京西,极速到家送惊喜", + }, + } + return SendMsgToStore(storeID, WX_SALE_BILL_TEMPLATE_ID, fileURL, data) +} + func FormatDeliveryTime(order *model.GoodsOrder) string { var tmpTime time.Time if order.ExpectedDeliveredTime == utils.DefaultTimeValue { diff --git a/business/model/legacy.go b/business/model/legacy.go index 0c797ea55..da26dc360 100644 --- a/business/model/legacy.go +++ b/business/model/legacy.go @@ -1,5 +1,7 @@ package model +import "time" + type WeiXins struct { ID int `orm:"column(id)" json:"id"` JxStoreID int `orm:"column(jxstoreid)" json:"storeID"` @@ -56,3 +58,21 @@ type JxBadComments struct { func (*JxBadComments) TableName() string { return "jx_bad_comments" } + +type StoreBill struct { + Id int `orm:"column(id);auto"` + Date time.Time `orm:"column(date);type(datetime)"` + Url string `orm:"column(url);size(255)"` + StoreId int `orm:"column(store_id)"` + BillName string `orm:"column(bill_name);size(30)"` +} + +func (t *StoreBill) TableName() string { + return "store_bill" +} + +func (*StoreBill) TableIndex() [][]string { + return [][]string{ + []string{"StoreId", "Date"}, + } +} diff --git a/controllers/financial.go b/controllers/financial.go new file mode 100644 index 000000000..c8a9c3046 --- /dev/null +++ b/controllers/financial.go @@ -0,0 +1,43 @@ +package controllers + +import ( + "io" + + "github.com/astaxie/beego" + + "git.rosy.net.cn/jx-callback/business/jxstore/financial" +) + +type FinancialController struct { + beego.Controller +} + +// @Title 发送文件给门店 +// @Description 发送文件给门店,调用GET方法得到浏览器端参考的上传HTML实现,userfiles +// @Param token header string true "认证token" +// @Param isAsync query bool false "是否异步,缺省是同步" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /SendFilesToStores [post,get] +func (c *FinancialController) SendFilesToStores() { + if c.Ctx.Input.IsGet() { + w := c.Ctx.ResponseWriter + // 上传页面 + w.Header().Add("Content-Type", "text/html") + w.WriteHeader(200) + html := ` +
+` + io.WriteString(w, html) + } else if c.Ctx.Input.IsPost() { + c.callSendFilesToStores(func(params *tFinancialSendFilesToStoresParams) (retVal interface{}, errCode string, err error) { + r := c.Ctx.Request + files := r.MultipartForm.File["userfiles"] + retVal, err = financial.SendFilesToStores(files, params.IsAsync, "test") + return retVal, "", err + }) + } +} diff --git a/globals/beegodb/beegodb.go b/globals/beegodb/beegodb.go index 9f3aeb247..c98574be8 100644 --- a/globals/beegodb/beegodb.go +++ b/globals/beegodb/beegodb.go @@ -14,6 +14,7 @@ func Init() { orm.RegisterModel(new(legacymodel.Config)) orm.RegisterModel(new(legacymodel.BlackClient)) orm.RegisterModel(new(model.JxBadComments)) + orm.RegisterModel(new(model.StoreBill)) orm.RegisterModel(new(model.GoodsOrder)) orm.RegisterModel(new(model.OrderSku)) diff --git a/routers/commentsRouter_controllers.go b/routers/commentsRouter_controllers.go index 73363a8bd..feb38a2e0 100644 --- a/routers/commentsRouter_controllers.go +++ b/routers/commentsRouter_controllers.go @@ -95,6 +95,14 @@ func init() { MethodParams: param.Make(), Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:FinancialController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:FinancialController"], + beego.ControllerComments{ + Method: "SendFilesToStores", + Router: `/SendFilesToStores`, + AllowHTTPMethods: []string{"post","get"}, + MethodParams: param.Make(), + Params: nil}) + beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:OrderController"], beego.ControllerComments{ Method: "CreateWaybillOnProviders", diff --git a/routers/router.go b/routers/router.go index ea6f0add7..0296fb6bb 100644 --- a/routers/router.go +++ b/routers/router.go @@ -56,6 +56,11 @@ func init() { &controllers.TaskController{}, ), ), + beego.NSNamespace("/financial", + beego.NSInclude( + &controllers.FinancialController{}, + ), + ), ) beego.AddNamespace(ns)