package financial import ( "context" "errors" "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/jxcontext" "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/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" "github.com/qiniu/api.v7/storage" ) type tUploadFileInfo struct { FileHeader *multipart.FileHeader StoreID int } func SendFilesToStores(ctx *jxcontext.Context, files []*multipart.FileHeader, title, shopName string, isAsync bool, userName string) (hint string, err error) { globals.SugarLogger.Debugf("SendFilesToStores, fileCount:%d isAsync:%t, userName:%s", len(files), isAsync, userName) if len(files) == 0 { return "", errors.New("没有文件上传!") } 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.NewParallelTask("SendFilesToStores", tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { fileInfo := batchItemList[0].(*tUploadFileInfo) fileHeader := fileInfo.FileHeader storeID := fileInfo.StoreID file, err := fileHeader.Open() globals.SugarLogger.Debugf("SendFilesToStores upload file:%s", fileHeader.Filename) if err == nil { ret := storage.PutRet{} key := "storeBill_" + utils.Int2Str(storeID) + "_" + strings.ToLower(utils.GetUUID()) + path.Ext(fileHeader.Filename) formUploader := storage.NewFormUploader(cfg) for i := 0; i < 3; i++ { if err = formUploader.Put(context.Background(), &ret, upToken, key, file, fileHeader.Size, &storage.PutExtra{}); err == nil { break } } file.Close() if err == nil { db := dao.GetDB() billRec := &legacymodel.StoreBill{ Date: time.Now(), Url: jxutils.ComposeQiniuResURL(strings.Replace(ret.Key, "http://", "https://", -1)), StoreId: storeID, BillName: fileHeader.Filename, ShopName: shopName, BillTitle: title, } if err = dao.CreateEntity(db, billRec); err == nil { err = weixinmsg.NotifySaleBill(storeID, title, shopName, fmt.Sprintf("%s/billshow/?path=%s", globals.BackstageHost, billRec.Url)) if err != nil { globals.SugarLogger.Infof("SendFilesToStores NotifySaleBill file:%s error:%v", fileHeader.Filename, err) } err = nil // 忽略微信发送错误 } else { globals.SugarLogger.Warnf("SendFilesToStores CreateEntity file:%s error:%v", fileHeader.Filename, err) } } else { globals.SugarLogger.Warnf("SendFilesToStores file:%s failed with error:%v", fileHeader.Filename, err) } } else { globals.SugarLogger.Warnf("SendFilesToStores open file:%s failed with error:%v", fileHeader.Filename, err) } return retVal, err }, fileList) tasksch.HandleTask(task, nil, true).Run() hint = task.ID if !isAsync { _, err = task.GetResult(0) } return task.ID, err } func GetStoreBills(ctx *jxcontext.Context, storeID int) (bills []*legacymodel.StoreBill, err error) { db := dao.GetDB() if err = dao.GetRows(db, &bills, ` SELECT * FROM store_bill WHERE store_id = ? ORDER BY date DESC LIMIT 10 `, storeID); err != nil { return nil, err } return bills, err }