Ver código fonte

生成小程序二维码,头像使用oss

icole 4 anos atrás
pai
commit
02680eae17

+ 9 - 1
etc/i2bill-api.yaml

@@ -18,4 +18,12 @@ JwtAuth:
   AccessSecret: 6hy789iu87
   AccessExpire: 604800
 Domain: http://172.16.11.5:8888
-AesSecret: 95dc14b89d32fe91709bba8916f30f74
+AesSecret: 95dc14b89d32fe91709bba8916f30f74
+AliYunOss:
+  EndPoint: https://oss-cn-shanghai.aliyuncs.com
+  KeyId: LTAI5tGCifGfPKoJhfmctyUS
+  Secret: V9AkVP17c0bZBb1gW2HhTQntUyGVQm
+  Bucket: i2-mp
+  SignExpire: 30
+  SignHost: https://i2-files.oss-cn-shanghai.aliyuncs.com
+  FileUrl: https://files-cdn.i2edu.net

+ 2 - 0
go.mod

@@ -5,6 +5,8 @@ go 1.16
 require (
 	git.i2edu.net/i2/go-zero v1.0.1-0.20210616091154-7fac117e009f
 	git.i2edu.net/i2/i2-bill-erp v0.0.0-20210706060443-0dc13cb6dbeb
+	github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible
+	github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
 	github.com/clbanning/mxj v1.8.4 // indirect
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/go-sql-driver/mysql v1.6.0

+ 4 - 0
go.sum

@@ -28,7 +28,11 @@ github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZp
 github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
 github.com/alicebob/miniredis/v2 v2.14.1 h1:GjlbSeoJ24bzdLRs13HoMEeaRZx9kg5nHoRW7QV/nCs=
 github.com/alicebob/miniredis/v2 v2.14.1/go.mod h1:uS970Sw5Gs9/iK3yBg0l9Uj9s25wXxSpQUE9EaJ/Blg=
+github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible h1:hLUNPbx10wawWW7DeNExvTrlb90db3UnnNTFKHZEFhE=
+github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
 github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
+github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA=
+github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=

+ 3 - 0
i2bill.api

@@ -253,6 +253,9 @@ service i2bill-api {
 service i2bill-api {
 	@handler SystemFileUpload
 	post  /api/v1/system_file/upload returns(Response)
+	
+	@handler SystemFileDownload
+	get  /api/v1/system_file/download returns(Response)
 }
 
 // 城市树

+ 9 - 0
internal/config/config.go

@@ -23,4 +23,13 @@ type Config struct {
 		AccessSecret string
 		AccessExpire int64
 	}
+	AliYunOss struct {
+		EndPoint   string
+		KeyId      string
+		Secret     string
+		Bucket     string
+		SignExpire int64
+		SignHost   string
+		FileUrl    string //访问连接
+	}
 }

+ 108 - 0
internal/global/aliyun_oss.go

@@ -0,0 +1,108 @@
+package global
+
+import (
+	"fmt"
+	"git.i2edu.net/i2/i2-bill-api/internal/svc"
+	"git.i2edu.net/i2/i2-bill-api/internal/utils"
+	"git.i2edu.net/i2/i2-bill-api/model"
+	"github.com/aliyun/aliyun-oss-go-sdk/oss"
+	"io"
+	"mime/multipart"
+	"path"
+	"strings"
+	"time"
+)
+
+var aliYunBucket *oss.Bucket
+
+type AliYunOssUpDownloader struct {
+	bucket *oss.Bucket
+}
+
+func NewAliYunOssUpDownloader() *AliYunOssUpDownloader {
+	// 创建OSSClient实例。
+	client, err := oss.New(svc.ServiceConfig.AliYunOss.EndPoint, svc.ServiceConfig.AliYunOss.KeyId, svc.ServiceConfig.AliYunOss.Secret)
+	if err != nil {
+		fmt.Println("Error:", err)
+		return nil
+	}
+
+	// 获取存储空间。
+	aliYunBucket, err = client.Bucket(svc.ServiceConfig.AliYunOss.Bucket)
+	if err != nil {
+		fmt.Println("Error:", err)
+		return nil
+	}
+	return &AliYunOssUpDownloader{bucket: aliYunBucket}
+}
+
+/**
+ * @brief: 附件上传接口
+ * @param1 file: post 多媒体file
+ * @return1: 附件信息,主要包括id,url, hash和大小。其他字段会自动设置
+ * @return4: 错误信息
+ */
+func (aoud *AliYunOssUpDownloader) Upload(file multipart.File, header *multipart.FileHeader) (*model.I2billSysAttachment, error) {
+	attachId := utils.GetUUID()
+	dateStr := time.Now().Format("2006/01/02")
+
+	ext := strings.TrimSpace(path.Ext(header.Filename)) // 扩展名
+	objectKey := ""
+	if ext == "" {
+		objectKey = fmt.Sprintf("customer/files/att/%s/%s", dateStr, attachId)
+	} else {
+		objectKey = fmt.Sprintf("customer/files/att/%s/%s%s", dateStr, attachId, ext)
+	}
+
+	err := aoud.bucket.PutObject(objectKey, file)
+	if err != nil {
+		fmt.Println("aoud.bucket.PutObject err", err.Error())
+		return nil, err
+	}
+
+	attach := &model.I2billSysAttachment{}
+	attach.Id = attachId
+	attach.Url = objectKey
+	attach.Hash = ""
+	attach.Size = header.Size
+
+	return attach, nil
+
+}
+
+func (aoud *AliYunOssUpDownloader) UploadRead(file io.Reader, ext string) (*model.I2billSysAttachment, error) {
+	attachId := utils.GetUUID()
+	dateStr := time.Now().Format("2006/01/02")
+
+	objectKey := ""
+	if ext == "" {
+		objectKey = fmt.Sprintf("customer/files/att/%s/%s", dateStr, attachId)
+	} else {
+		objectKey = fmt.Sprintf("customer/files/att/%s/%s%s", dateStr, attachId, ext)
+	}
+
+	err := aoud.bucket.PutObject(objectKey, file)
+	if err != nil {
+		fmt.Println("aoud.bucket.PutObject err", err.Error())
+		return nil, err
+	}
+
+	attach := &model.I2billSysAttachment{}
+	attach.Id = attachId
+	attach.Url = objectKey
+	attach.Hash = ""
+	return attach, nil
+
+}
+
+func (aoud *AliYunOssUpDownloader) Download(attach *model.I2billSysAttachment) (io.ReadCloser, error) {
+	objectKey := attach.Url
+	r, err := aoud.bucket.GetObject(objectKey)
+	if err != nil {
+		fmt.Println("aoud.bucket.GetObject 错误", err.Error())
+		return r, err
+	}
+	defer r.Close()
+
+	return r, nil
+}

+ 5 - 0
internal/handler/routes.go

@@ -159,6 +159,11 @@ func RegisterHandlers(engine *rest.Server, serverCtx *svc.ServiceContext) {
 				Path:    "/api/v1/system_file/upload",
 				Handler: system.SystemFileUploadHandler(serverCtx),
 			},
+			{
+				Method:  http.MethodGet,
+				Path:    "/api/v1/system_file/download",
+				Handler: system.SystemFileDownloadHandler(serverCtx),
+			},
 		},
 		rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
 	)

+ 22 - 0
internal/handler/system/system_file_download_handler.go

@@ -0,0 +1,22 @@
+package system
+
+import (
+	"net/http"
+
+	"git.i2edu.net/i2/go-zero/rest/httpx"
+	"git.i2edu.net/i2/i2-bill-api/internal/logic/system"
+	"git.i2edu.net/i2/i2-bill-api/internal/svc"
+)
+
+func SystemFileDownloadHandler(ctx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+
+		l := system.NewSystemFileDownloadLogic(r.Context(), ctx)
+		resp, err := l.SystemFileDownload(w, r)
+		if err != nil {
+			httpx.Error(w, err)
+		} else if resp != nil {
+			httpx.OkJson(w, resp)
+		}
+	}
+}

+ 15 - 9
internal/logic/acquirer_mkt_qr/acquirer_mkt_qr_update_logic.go

@@ -2,10 +2,8 @@ package acquirer_mkt_qr
 
 import (
 	"context"
-	"encoding/base64"
 	"encoding/json"
 	"fmt"
-	"git.i2edu.net/i2/i2-bill-api/internal/utils"
 	"git.i2edu.net/i2/i2-bill-api/model"
 	"io/ioutil"
 	"net/http"
@@ -51,7 +49,7 @@ func (l *AcquirerMktQrUpdateLogic) AcquirerMktQrUpdate(r *http.Request) (*types.
 		logx.Error(err.Error())
 		return &types.Response{500, err.Error(), nil}, nil
 	}
-	var ty = "part"
+	//var ty = "part"
 	//mk
 	if userInfo.ErpId != "" {
 		erpId, err := model.GetErpUser("", userInfo.ErpId, l.svcCtx.Transformer)
@@ -62,7 +60,7 @@ func (l *AcquirerMktQrUpdateLogic) AcquirerMktQrUpdate(r *http.Request) (*types.
 		if erpId == "" {
 			return &types.Response{500, "未找到mk用户", nil}, nil
 		}
-		ty = "mk"
+		//ty = "mk"
 	} else {
 		//兼职
 		partUser, err := model.GetPartTimeXormByUserId(userId, l.svcCtx.DB)
@@ -107,17 +105,25 @@ func (l *AcquirerMktQrUpdateLogic) AcquirerMktQrUpdate(r *http.Request) (*types.
 	bean.DelFlag = 0
 	bean.UserId = userId
 	//生成二维码
-	scene, _ := utils.AesEncrypt([]byte(fmt.Sprintf("%d", userId)), []byte(l.svcCtx.Config.AesSecret))
-	sceneStr := fmt.Sprintf("sign=%s&type=%s", base64.StdEncoding.EncodeToString(scene), ty)
-	uri, err := l.svcCtx.Wechat.GenQrCode(sceneStr, "/pages/code/code")
+	//scene, _ := utils.AesEncrypt([]byte(fmt.Sprintf("%d", userId)), []byte(l.svcCtx.Config.AesSecret))
+	sceneStr := fmt.Sprintf("%d", userId)
+	atr, err := l.svcCtx.Wechat.GenQrCode(sceneStr, "pages/code/code")
 	if err != nil {
 		logx.Error(err.Error())
 		return &types.Response{500, err.Error(), nil}, nil
 	}
-	bean.Qr = uri
+	if atr == nil || atr.Url == "" {
+		return &types.Response{500, "二维码生成失败", nil}, nil
+	}
+	_, err = l.svcCtx.DB.Insert(atr)
+	if err != nil {
+		logx.Error(err.Error())
+		return &types.Response{500, err.Error(), nil}, nil
+	}
+	bean.Qr = atr.Url
 	_, err = l.svcCtx.DB.Insert(bean)
 	bean.Qr = strings.TrimLeft(bean.Qr, "/")
-	domain := strings.TrimRight(l.svcCtx.Config.Domain, "/")
+	domain := strings.TrimRight(l.svcCtx.Config.AliYunOss.FileUrl, "/")
 	bean.Qr = domain + "/" + bean.Qr
 	if err != nil {
 		return &types.Response{500, err.Error(), nil}, nil

+ 9 - 11
internal/logic/acquirer_student/acquirer_student_add_logic.go

@@ -2,10 +2,8 @@ package logic
 
 import (
 	"context"
-	"encoding/base64"
 	"git.i2edu.net/i2/i2-bill-api/internal/svc"
 	"git.i2edu.net/i2/i2-bill-api/internal/types"
-	"git.i2edu.net/i2/i2-bill-api/internal/utils"
 	"git.i2edu.net/i2/i2-bill-api/model"
 	"strconv"
 	"time"
@@ -30,17 +28,17 @@ func NewAcquirerStudentAddLogic(ctx context.Context, svcCtx *svc.ServiceContext)
 func (l *AcquirerStudentAddLogic) AcquirerStudentAdd(req types.EnrollAddReq) (*types.Response, error) {
 	// todo: add your logic here and delete this line
 	//解析id
-	sign, err := base64.StdEncoding.DecodeString(req.Sign)
-	if err != nil {
-		logx.Error(err.Error())
-		return &types.Response{500, "二维码已失效", nil}, nil
-	}
-	userIdByte, err := utils.AesDecrypt(sign, []byte(l.svcCtx.Config.AesSecret))
-	if err != nil {
-		logx.Error(err.Error())
+	//sign, err := hex.DecodeString(req.Sign)
+	sign := req.Sign
+	if sign != "" {
 		return &types.Response{500, "二维码已失效", nil}, nil
 	}
-	userId, err := strconv.ParseInt(string(userIdByte), 10, 64)
+	//userIdByte, err := utils.AesDecrypt(sign, []byte(l.svcCtx.Config.AesSecret))
+	//if err != nil {
+	//	logx.Error(err.Error())
+	//	return &types.Response{500, "二维码已失效", nil}, nil
+	//}
+	userId, err := strconv.ParseInt(sign, 10, 64)
 	if err != nil {
 		logx.Error(err.Error())
 		return &types.Response{500, err.Error(), nil}, nil

+ 1 - 1
internal/logic/logic_test.go

@@ -15,7 +15,7 @@ func TestCreateJWT(t *testing.T) {
 		"userId":     12,
 		"sessionKey": "sessionKey",
 	}
-	fmt.Println(l.CreateJWT(1625045504, "6hy789iu87", payloads, 604800))
+	fmt.Println(l.CreateJWT(1625650629, "6hy789iu87", payloads, 604800))
 }
 
 func TestRflect(t *testing.T) {

+ 55 - 0
internal/logic/system/system_file_download_logic.go

@@ -0,0 +1,55 @@
+package system
+
+import (
+	"context"
+	"git.i2edu.net/i2/i2-bill-api/internal/global"
+	"git.i2edu.net/i2/i2-bill-api/model"
+	"io"
+	"net/http"
+	"strconv"
+
+	"git.i2edu.net/i2/i2-bill-api/internal/svc"
+	"git.i2edu.net/i2/i2-bill-api/internal/types"
+
+	"git.i2edu.net/i2/go-zero/core/logx"
+)
+
+type SystemFileDownloadLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewSystemFileDownloadLogic(ctx context.Context, svcCtx *svc.ServiceContext) SystemFileDownloadLogic {
+	return SystemFileDownloadLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx,
+	}
+}
+
+func (l *SystemFileDownloadLogic) SystemFileDownload(w http.ResponseWriter, r *http.Request) (*types.Response, error) {
+	// todo: add your logic here and delete this line
+	r.ParseForm()
+	id := r.FormValue("id")
+	attachment := new(model.I2billSysAttachment)
+	_, err := l.svcCtx.DB.ID(id).Get(attachment)
+	if err != nil {
+		logx.Error(err.Error())
+		return &types.Response{500, err.Error(), nil}, nil
+	}
+	if attachment.Id == "" {
+		return &types.Response{200, "", nil}, nil
+	}
+	f, err := global.NewAliYunOssUpDownloader().Download(attachment)
+	if err != nil {
+		logx.Error(err.Error())
+		return &types.Response{500, err.Error(), nil}, nil
+	}
+	w.Header().Set("Content-Disposition", "attachment;filename=\""+attachment.Name+"\"")
+	w.Header().Set("Content-Type", "application/octet-stream")
+	w.Header().Set("Content-Length", strconv.FormatInt(int64(attachment.Size), 10))
+	w.WriteHeader(200)
+	io.Copy(w, f)
+	return nil, nil
+}

+ 28 - 108
internal/logic/system/system_file_upload_logic.go

@@ -2,13 +2,16 @@ package system
 
 import (
 	"context"
+	"encoding/json"
 	"fmt"
+	"git.i2edu.net/i2/i2-bill-api/internal/global"
 	"git.i2edu.net/i2/i2-bill-api/internal/svc"
 	"git.i2edu.net/i2/i2-bill-api/internal/types"
 	"io"
 	"net/http"
 	"os"
 	"path/filepath"
+	"strings"
 
 	"git.i2edu.net/i2/go-zero/core/logx"
 )
@@ -29,6 +32,31 @@ func NewSystemFileUploadLogic(ctx context.Context, svcCtx *svc.ServiceContext) S
 
 func (l *SystemFileUploadLogic) SystemFileUpload(r *http.Request) (*types.Response, error) {
 	// todo: add your logic here and delete this line
+	file, fileHeader, err := r.FormFile("file")
+	if err != nil {
+		logx.Error(err.Error())
+		return &types.Response{500, err.Error(), nil}, nil
+	}
+	res, err := global.NewAliYunOssUpDownloader().Upload(file, fileHeader)
+	if err != nil {
+		logx.Error(err.Error())
+		return &types.Response{500, err.Error(), nil}, nil
+	}
+	resp := make(map[string]interface{})
+	resByte, err := json.Marshal(res)
+	if err != nil {
+		logx.Error(err.Error())
+		return &types.Response{500, err.Error(), nil}, nil
+	}
+	if err := json.Unmarshal(resByte, &resp); err != nil {
+		logx.Error(err.Error())
+		return &types.Response{500, err.Error(), nil}, nil
+	}
+	resp["full_url"] = strings.TrimLeft(l.svcCtx.Config.AliYunOss.FileUrl, ",") + "/" + strings.TrimRight(res.Url, "/")
+	return &types.Response{200, "", resp}, nil
+}
+
+func localFileUpload(l SystemFileUploadLogic, r *http.Request) (*types.Response, error) {
 	userId := l.svcCtx.GetUserIdByJwt(l.ctx)
 	file, fileHeader, err := r.FormFile("file")
 	if err != nil {
@@ -56,112 +84,4 @@ func (l *SystemFileUploadLogic) SystemFileUpload(r *http.Request) (*types.Respon
 		return &types.Response{500, err.Error(), nil}, nil
 	}
 	return &types.Response{200, "", fileName}, nil
-
-	//
-	//file, fInfo, err := r.FormFile("file")
-	//if err != nil {
-	//	logx.Error(err.Error())
-	//	return &types.Response{500, err.Error(), nil}, nil
-	//}
-	//defer file.Close()
-	//
-	//var attach *sysmodel.SysAttachment = nil
-	//if _attachementUpDownloader != nil{
-	//	attach, err = _attachementUpDownloader.Upload(file, fInfo)
-	//	if err !=nil{
-	//		return nil, err
-	//	}
-	//}else{
-	//	return nil, errors.New("附件上传下载接口为nil")
-	//}
-	//
-	//userId := c.Ctx.GetString("user_id")
-	//
-	//if attach.Id == ""{
-	//	attach.Id = sysutils.NewUUID()
-	//}
-	//if attach.Size <= 0{
-	//	attach.Size = int32((fInfo.Size))
-	//}
-	//attach.Name = fInfo.Filename
-	//attach.CreateBy = userId
-	//attach.CreateTime = time.Now()
-	//attach.Ext = path.Ext(attach.Name)
-	//
-	//_, err = c.PlatformDbEngine.InsertOne(attach)
-	//if err != nil {
-	//	syslogs.Error("保存附件出错了:", err)
-	//	return nil, err
-	//}
-
-	//return attach, nil
-
 }
-
-/**
- * @brief: 默认
- */
-type defaultAttachUpDownloader struct {
-}
-
-/**
- * @brief: 附件上传接口
- * @param1 file: post 多媒体file
- * @param1 header: 文件相头信息
- * @return1: 附件信息,主要包括id,url, hash和大小。其他字段会自动设置
- * @return2: 错误信息
- */
-//func(d *defaultAttachUpDownloader)Upload(file multipart.File, header *multipart.FileHeader)(*sysmodel.SysAttachment, error){
-//	fileDir := fmt.Sprintf("files/")
-//	if err := mkdir(fileDir); err != nil {
-//		syslogs.Info("文件夹创建失败")
-//		return nil, err
-//	}
-//	attachId := sysutils.NewUUID()
-//	filePath := fileDir + attachId
-//	fW, err := os.Create(filePath)
-//	if err != nil {
-//		syslogs.Info("文件创建失败")
-//		return nil, err
-//	}
-//	defer fW.Close()
-//	length, err := io.Copy(fW, file)
-//	if err != nil {
-//		syslogs.Info("文件保存失败")
-//		return nil, err
-//	}
-//
-//	attach := &sysmodel.SysAttachment{}
-//	attach.Id = attachId
-//	attach.Url = "/api/v1/sys_attachment/download?id=" + attach.Id
-//	attach.Hash = ""
-//	attach.Size = int32(length)
-//
-//	return attach, nil
-//}
-//
-///**
-// * @brief: 附件下载
-// * @param1 ctx: 上下文
-// * @param2 id: 附件记录的id
-// */
-//func(d *defaultAttachUpDownloader)Download(c *entitys.CtrlContext, attach *sysmodel.SysAttachment){
-//	filePath := "files/" + attach.Id
-//
-//	c.Ctx.Writer.Header().Add("Content-Disposition", "attachment;filename=\""+sysutils.FormatForBrowse(c.Ctx.Request.UserAgent(), attach.Name)+"\"")
-//	c.Ctx.Writer.Header().Add("Content-Type", mime.TypeByExtension(attach.Ext))
-//	c.Ctx.Writer.Header().Add("Content-Length", strconv.FormatInt(int64(attach.Size), 10))
-//	c.Ctx.Writer.Header().Add("Accept-Ranges", "bytes")
-//
-//	if !sysutils.Exists(filePath) {
-//		c.Ctx.Writer.WriteHeader(400)
-//		return
-//	}
-//	fmt.Println("---->", c.Ctx.Writer.Header().Get("Content-Disposition"))
-//	fmt.Println("---->", c.Ctx.Writer.Header().Get("Content-Type"))
-//	fmt.Println("---->", c.Ctx.Writer.Header().Get("Content-Length"))
-//	fmt.Println("---->", c.Ctx.Writer.Header().Get("Accept-Ranges"))
-//
-//	c.Ctx.File(filePath)
-//}
-//

+ 1 - 1
internal/logic/user/get_user_logic.go

@@ -72,7 +72,7 @@ func (l *GetUserLogic) GetUser() (*types.InfoResponse, error) {
 		}
 	}
 	if !strings.HasPrefix(user.Avatar, "http") && user.Avatar != "" {
-		domain := strings.TrimRight(l.svcCtx.Config.Domain, "/")
+		domain := strings.TrimRight(l.svcCtx.Config.AliYunOss.FileUrl, "/")
 		filePath := strings.TrimLeft(user.Avatar, "/")
 		user.Avatar = fmt.Sprintf("%s/%s", domain, filePath)
 	}

+ 3 - 0
internal/svc/service_context.go

@@ -20,6 +20,8 @@ import (
 	"github.com/xormplus/xorm"
 )
 
+var ServiceConfig config.Config
+
 type ServiceContext struct {
 	Config                     config.Config
 	SqlConn                    sqlx.SqlConn
@@ -97,5 +99,6 @@ func NewServiceContext(c config.Config) *ServiceContext {
 		RdCli: svc.RdCli,
 		c:     c,
 	}
+	ServiceConfig = svc.Config
 	return svc
 }

+ 7 - 8
internal/svc/wechat.go

@@ -6,7 +6,6 @@ import (
 	"encoding/base64"
 	"encoding/json"
 	"fmt"
-	"path"
 	"time"
 
 	"git.i2edu.net/i2/i2-bill-api/internal/config"
@@ -35,7 +34,7 @@ type WechatPhonedecrypt struct {
 func (wc *Wechat) GetAccessToken() (string, error) {
 	token := ""
 	err := wc.RdCli.GetCache(cacheWechatTokenPrefix, &token)
-	if err == model.ErrRdsNotFound {
+	if err == model.ErrRdsNotFound || token == "" {
 		req := utils.Get("https://api.weixin.qq.com/cgi-bin/token")
 		req.Param("grant_type", "client_credential")
 		req.Param("secret", wc.c.Weixin.Secret)
@@ -128,17 +127,17 @@ func (wc *Wechat) DecryptMobile(sessionKey, encryptedData, iv string) (string, e
 }
 
 // GenQrCode defined TODO
-func (wc *Wechat) GenQrCode(scene, page string) (string, error) {
+func (wc *Wechat) GenQrCode(scene, page string) (*model.I2billSysAttachment, error) {
 	token, err := wc.GetAccessToken()
 	if err != nil {
-		return "", err
+		return nil, err
 	}
 	req := utils.Post("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + token)
 	req.JSONBody(map[string]interface{}{"scene": scene, "page": page})
-	ph := path.Join("asserts", "qrcode", utils.Md5(scene)+".png")
-	err = req.ToFile(ph)
+	//ph := path.Join("asserts", "qrcode", utils.Md5(scene)+".png")
+	attr, err := req.ToFile()
 	if err != nil {
-		return "", err
+		return nil, err
 	}
-	return ph, err
+	return attr, err
 }

+ 18 - 12
internal/utils/http.go

@@ -7,6 +7,8 @@ import (
 	"crypto/tls"
 	"encoding/json"
 	"encoding/xml"
+	"git.i2edu.net/i2/i2-bill-api/internal/global"
+	"git.i2edu.net/i2/i2-bill-api/model"
 	"io"
 	"io/ioutil"
 	"log"
@@ -552,26 +554,30 @@ func (b *HTTPRequest) Bytes() ([]byte, error) {
 
 // ToFile saves the body data in response to one file.
 // Calls Response inner.
-func (b *HTTPRequest) ToFile(filename string) error {
+func (b *HTTPRequest) ToFile() (*model.I2billSysAttachment, error) {
 	resp, err := b.getResponse()
 	if err != nil {
-		return err
+		return nil, err
 	}
 	if resp.Body == nil {
-		return nil
+		return nil, nil
 	}
 	defer resp.Body.Close()
-	err = pathExistAndMkdir(filename)
-	if err != nil {
-		return err
-	}
-	f, err := os.Create(filename)
+	//err = pathExistAndMkdir(filename)
+	//if err != nil {
+	//	return err
+	//}
+	//f, err := os.Create(filename)
+	//if err != nil {
+	//	return err
+	//}
+	//defer f.Close()
+	//_, err = io.Copy(f, resp.Body)
+	att, err := global.NewAliYunOssUpDownloader().UploadRead(resp.Body, ".png")
 	if err != nil {
-		return err
+		return nil, err
 	}
-	defer f.Close()
-	_, err = io.Copy(f, resp.Body)
-	return err
+	return att, err
 }
 
 // Check if the file directory exists. If it doesn't then it's created

+ 12 - 0
model/i2bill_sys_attachment.sql

@@ -0,0 +1,12 @@
+CREATE TABLE i2bill_sys_attachment  (
+  `id` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
+  `name` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
+  `size` int(0) NOT NULL,
+  `ext` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
+  `hash` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
+  `url` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
+  `create_by` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
+  `create_time` datetime(0) NOT NULL,
+  `del_flag` int(0) NOT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

+ 89 - 0
model/i2bill_sys_attachment_model.go

@@ -0,0 +1,89 @@
+package model
+
+import (
+	"database/sql"
+	"fmt"
+	"strings"
+	"time"
+
+	"git.i2edu.net/i2/go-zero/core/stores/sqlc"
+	"git.i2edu.net/i2/go-zero/core/stores/sqlx"
+	"git.i2edu.net/i2/go-zero/core/stringx"
+	"git.i2edu.net/i2/go-zero/tools/goctl/model/sql/builderx"
+)
+
+var (
+	i2billSysAttachmentFieldNames          = builderx.RawFieldNames(&I2billSysAttachment{})
+	i2billSysAttachmentRows                = strings.Join(i2billSysAttachmentFieldNames, ",")
+	i2billSysAttachmentRowsExpectAutoSet   = strings.Join(stringx.Remove(i2billSysAttachmentFieldNames, "`create_time`", "`update_time`"), ",")
+	i2billSysAttachmentRowsWithPlaceHolder = strings.Join(stringx.Remove(i2billSysAttachmentFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?"
+)
+
+type (
+	I2billSysAttachmentModel interface {
+		Insert(data I2billSysAttachment) (sql.Result, error)
+		FindOne(id string) (*I2billSysAttachment, error)
+		Update(data I2billSysAttachment) error
+		Delete(id string) error
+	}
+
+	defaultI2billSysAttachmentModel struct {
+		conn  sqlx.SqlConn
+		table string
+	}
+
+	I2billSysAttachment struct {
+		CreateTime time.Time `db:"create_time" json:"create_time"`
+		DelFlag    int64     `db:"del_flag" json:"del_flag"`
+		Name       string    `db:"name" json:"name"`
+		Size       int64     `db:"size" json:"size"`
+		Ext        string    `db:"ext" json:"ext"`
+		Hash       string    `db:"hash" json:"hash"`
+		Url        string    `db:"url" json:"url"`
+		Id         string    `db:"id" json:"id"`
+		CreateBy   string    `db:"create_by" json:"create_by"`
+	}
+)
+
+func NewI2billSysAttachmentModel(conn sqlx.SqlConn) I2billSysAttachmentModel {
+	return &defaultI2billSysAttachmentModel{
+		conn:  conn,
+		table: "`i2bill_sys_attachment`",
+	}
+}
+
+func (t *I2billSysAttachment) TableName() string {
+	return "i2bill_sys_attachment"
+}
+
+func (m *defaultI2billSysAttachmentModel) Insert(data I2billSysAttachment) (sql.Result, error) {
+	query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?)", m.table, i2billSysAttachmentRowsExpectAutoSet)
+	ret, err := m.conn.Exec(query, data.DelFlag, data.Name, data.Size, data.Ext, data.Hash, data.Url, data.Id, data.CreateBy)
+	return ret, err
+}
+
+func (m *defaultI2billSysAttachmentModel) FindOne(id string) (*I2billSysAttachment, error) {
+	query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", i2billSysAttachmentRows, m.table)
+	var resp I2billSysAttachment
+	err := m.conn.QueryRow(&resp, query, id)
+	switch err {
+	case nil:
+		return &resp, nil
+	case sqlc.ErrNotFound:
+		return nil, ErrNotFound
+	default:
+		return nil, err
+	}
+}
+
+func (m *defaultI2billSysAttachmentModel) Update(data I2billSysAttachment) error {
+	query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, i2billSysAttachmentRowsWithPlaceHolder)
+	_, err := m.conn.Exec(query, data.DelFlag, data.Name, data.Size, data.Ext, data.Hash, data.Url, data.CreateBy, data.Id)
+	return err
+}
+
+func (m *defaultI2billSysAttachmentModel) Delete(id string) error {
+	query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
+	_, err := m.conn.Exec(query, id)
+	return err
+}