houyaf 3 years ago
parent
commit
03ec5a02ca

+ 1 - 0
go.mod

@@ -64,6 +64,7 @@ require (
 	github.com/nats-io/nats.go v1.23.0 // indirect
 	github.com/nats-io/nkeys v0.3.0 // indirect
 	github.com/nats-io/nuid v1.0.1 // indirect
+	github.com/robfig/cron/v3 v3.0.0 // indirect
 	github.com/rs/xid v1.4.0 // indirect
 	github.com/russross/blackfriday/v2 v2.1.0 // indirect
 	github.com/schollz/closestmatch v2.1.0+incompatible // indirect

+ 11 - 0
job/hello_job.go

@@ -0,0 +1,11 @@
+package job
+
+import "fmt"
+
+type HelloJob func()
+
+func (h HelloJob) Run() {
+    fmt.Println("Hello Job")
+}
+
+

+ 8 - 0
job/job_launch.go

@@ -0,0 +1,8 @@
+package job
+
+import "github.com/robfig/cron/v3"
+
+func init() {
+    c := cron.New()
+    c.AddJob("*/5 * * * * *", new(HelloJob))
+}

+ 0 - 70
paas/minio.go

@@ -1,70 +0,0 @@
-package paas
-
-import (
-    "github.com/kataras/iris/v12"
-    "github.com/minio/minio-go/v7"
-    "github.com/minio/minio-go/v7/pkg/credentials"
-    "log"
-)
-
-type MinioClient struct {
-    ctx           iris.Context
-    client        *minio.Client
-    fileBucket    string
-    iconBucket    string
-    location      string
-}
-
-func NewClient(ctx iris.Context) *MinioClient {
-    var minioHost  = ""
-    var minioPort  = ""
-    var accessKey  = ""
-    var secretKey  = ""
-    minioClient, err := minio.New(
-            minioHost + ":"+ minioPort,
-            &minio.Options{
-                Creds: credentials.NewStaticV4(accessKey, secretKey, ""),
-                Secure: false,
-        })
-    if err != nil {
-        log.Fatalf("connect minio server fail %s url %s", err.Error(), err.Error(), minioHost+":"+minioPort)
-    }
-    
-    return &MinioClient{
-        ctx: ctx,
-        client: minioClient,
-        location: "us-east-1",
-        fileBucket: "file",
-        iconBucket: "icon",
-    }
-}
-
-func (c *MinioClient) checkBuckets() bool {
-   b1 := c.checkBucket(c.fileBucket)
-   b2 := c.checkBucket(c.iconBucket)
-   return b1&&b2
-}
-
-func (c *MinioClient) checkBucket(bucketName string) bool {
-    isExist, err1 := c.client.BucketExists(c.ctx, bucketName)
-    if err1 != nil {
-        log.Fatalf("checkBucket error " + err1.Error())
-        return false
-    }
-    
-    if !isExist {
-        err2 := c.client.MakeBucket(c.ctx, bucketName, minio.MakeBucketOptions{Region: c.location})
-        if err2 != nil {
-            log.Fatalf("checkBucket error " + err2.Error())
-            return false
-        }
-    }
-    return true
-}
-
-func (c *MinioClient) uploadObject(objectName, localFileName string) {
-    _, err := c.client.FPutObject(c.ctx, c.fileBucket, objectName, localFileName, minio.PutObjectOptions{})
-    if err != nil {
-        log.Fatalf("upload object error" + err.Error())
-    }
-}

+ 14 - 0
service/upload_service.go

@@ -0,0 +1,14 @@
+package service
+
+type UploadService interface {}
+
+type uploadService struct {
+
+}
+
+
+func NewUploadService() UploadService {
+    return &uploadService{
+    }
+}
+

+ 6 - 0
three_party/go_cron.go

@@ -0,0 +1,6 @@
+package three_party
+
+// client version and secret, it should be from client side
+const (
+
+)

+ 280 - 0
three_party/minio.go

@@ -0,0 +1,280 @@
+package three_party
+
+import (
+    "errors"
+    "fmt"
+    uuid "github.com/iris-contrib/go.uuid"
+    "github.com/kataras/iris/v12"
+    "github.com/minio/minio-go/v7"
+    "github.com/minio/minio-go/v7/pkg/credentials"
+    "io"
+    "log"
+    "mime/multipart"
+    "os"
+    "path/filepath"
+    "strings"
+    "sync"
+    "time"
+)
+
+var defaultFileBucket = "file"
+var defaultIconBucket = "icon"
+var defaultLocation   = "us-east-1"
+var minioServerPool *sync.Pool
+
+// client version and secret, it should be from client side
+const (
+    UploadDir    string = "./public/upload/"
+    UrlBase      string = "/upload/"
+)
+
+// DstFile 文件
+type DstFile struct {
+    Name string `json:"name"`
+    Src  string `json:"src"`
+}
+
+func init() {
+    minioServerPool = &sync.Pool{
+        New: func() interface{}{
+            return &MinioServe{}
+        },
+    }
+}
+
+type MinioFileObject struct {
+    BucketName  string
+    ObjectName  string
+    FilePath    string
+    ContentType string
+    Config      MinioConfig
+}
+
+type MinioConfig struct {
+    MinioHost  string `json:"minioHost"`
+    MinioPort  int64  `json:"minioPort"`
+    AccessKey  string `json:"accessKey"`
+    SecretKey  string `json:"secretKey"`
+    UseSSL     bool   `json:"useSSL"`
+}
+
+
+func (c *MinioConfig) Validate() error {
+    if c.MinioHost == "" {
+        return errors.New("minio host not specified")
+    }
+    
+    if c.MinioPort <= 0 {
+        return errors.New("minio port not specified")
+    }
+    
+    if c.AccessKey == "" {
+        return errors.New("minio access key is not specified")
+    }
+    
+    if c.SecretKey == "" {
+        return errors.New("minio secret key is not specified")
+    }
+    return nil
+}
+
+func (c *MinioConfig) GetClient()(*minio.Client, error) {
+    if err := c.Validate(); err != nil {
+        return nil, err
+    }
+    
+    endPoint := fmt.Sprintf("%s:%d", c.MinioHost, c.MinioPort)
+    minioClient, err := minio.New(
+        endPoint,
+        &minio.Options{
+            Creds: credentials.NewStaticV4(c.AccessKey, c.SecretKey, ""),
+            Secure: c.UseSSL,
+        })
+    
+    if err != nil {
+        log.Fatalf("connect minio server fail %s url %s", err.Error(), endPoint)
+    }
+    return minioClient, nil
+}
+
+type MinioServerOption func(*MinioServe)
+type MinioServe struct {
+    Client *minio.Client
+}
+
+func NewMinioServer(opts ...MinioServerOption)(*MinioServe, error){
+    m := &MinioServe{}
+    for _, opt := range opts {
+        opt(m)
+    }
+    
+    return m, nil
+}
+
+func (m *MinioServe) Reset() {
+    m.Client = nil
+}
+
+func (m *MinioServe) checkBucket(ctx iris.Context, bucketName string) bool {
+    isExist, err1 := m.Client.BucketExists(ctx, bucketName)
+    if err1 != nil {
+        log.Fatalf("checkBucket error " + err1.Error())
+        return false
+    }
+    
+    if !isExist {
+        err2 := m.Client.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{Region: defaultLocation})
+        if err2 != nil {
+            log.Fatalf("checkBucket error " + err2.Error())
+            return false
+        }
+    }
+    return true
+}
+
+func (m *MinioServe) CheckBuckets(ctx iris.Context) bool {
+    b1 := m.checkBucket(ctx, defaultFileBucket)
+    b2 := m.checkBucket(ctx, defaultIconBucket)
+    return b1&&b2
+}
+
+func (m *MinioServe) UploadFile(ctx iris.Context, obj *MinioFileObject)(*minio.UploadInfo, error) {
+    bBucketExist := m.CheckBuckets(ctx)
+    if !bBucketExist {
+        return nil, nil
+    }
+    
+    info, err := m.Client.FPutObject(ctx, obj.BucketName, obj.ObjectName, obj.FilePath, minio.PutObjectOptions{
+        ContentType: obj.ContentType,
+    })
+    
+    if err != nil {
+        return &info, err
+    }
+    
+    return &info, nil
+}
+
+
+func acquireMinioServer() *MinioServe {
+    return minioServerPool.Get().(*MinioServe)
+}
+
+func releaseMinioServer(m *MinioServe) {
+    m.Reset()
+    minioServerPool.Put(m)
+}
+
+
+func UploadFile(ctx iris.Context) (*DstFile,error){
+    file ,info ,err := ctx.FormFile("uploadfile")
+    if err != nil {
+        return nil ,err
+    }
+    defer file.Close()
+    
+    oldFileName := info.Filename
+    destFile, url := GenerateNewFileName(oldFileName)
+    
+    out, err := os.OpenFile(destFile, os.O_WRONLY|os.O_CREATE, 0666)
+    if err != nil{
+        return nil, err
+    }
+    
+    defer out.Close()
+    _ ,err = io.Copy(out, file)
+    if err != nil {
+        return nil, err
+    }
+    
+    outfile := &DstFile{Name: oldFileName ,Src:url }
+    
+    return outfile, nil
+}
+
+// UploadMultiFiles Upload Multi Files
+func UploadMultiFiles(ctx iris.Context)(int, []DstFile, error){
+    
+    maxSize := ctx.Application().ConfigurationReadOnly().GetPostMaxMemory()
+    
+    err := ctx.Request().ParseMultipartForm(maxSize)
+    if err != nil {
+        return 0 , nil, err
+    }
+    
+    form     := ctx.Request().MultipartForm
+    files    := form.File["files[]"]
+    count    := len(files)
+    
+    failures := 0
+    dstIndex := 1
+    
+    outFiles := []DstFile{}
+    for _, file := range files {
+        url, err := SaveUploadFile(file)
+        if err != nil {
+            failures++
+        }else{
+            out := DstFile{Name: file.Filename ,Src:url}
+            outFiles = append(outFiles, out)
+            dstIndex++
+        }
+    }
+    
+    num := count - failures
+    
+    return  num ,outFiles ,nil
+}
+
+func SaveUploadFile(fh *multipart.FileHeader)(string, error){
+    src ,err := fh.Open()
+    if err != nil {
+        return "" ,err
+    }
+    defer src.Close()
+    
+    oldFileName := fh.Filename
+    srcFile, urlFile := GenerateNewFileName(oldFileName)
+    
+    out, err := os.OpenFile(srcFile ,os.O_WRONLY|os.O_CREATE ,os.FileMode(0666))
+    if err != nil {
+        return "" ,err
+    }
+    
+    defer out.Close()
+    
+    _, err = io.Copy(out, src)
+    
+    return urlFile, err
+}
+
+// CreateDateDir Create date directory
+func CreateDateDir() (srcPath, urlPath string) {
+    folderName := time.Now().Format("20060102")
+    src  := filepath.Join(UploadDir, folderName)
+    url  := filepath.Join(UrlBase, folderName)
+    _, err := os.Stat(srcPath)
+    if os.IsNotExist(err ){
+        _ = os.Mkdir(src, os.ModePerm)
+        _ = os.Chmod(src, os.ModePerm)
+    }
+    
+    return src ,url
+}
+
+// GenerateNewFileName Generate new file name
+func GenerateNewFileName(oldFileName string) (srcPath, urlPath string) {
+    u1, _ := uuid.NewV4()
+    newFileName := u1.String()
+    src , url := CreateDateDir()
+    
+    dotIndex := strings.LastIndex(oldFileName, ".")
+    if dotIndex != -1 && dotIndex != 0 {
+        newFileName += oldFileName[dotIndex:]
+    }
+    
+    src = filepath.Join(src, newFileName)
+    url = filepath.Join(url, newFileName)
+    
+    return src, url
+}

+ 3 - 3
utils/local_upload.go

@@ -42,7 +42,7 @@ func UploadFile(ctx iris.Context) (*DstFile,error){
     }
     
     defer out.Close()
-    _ ,err = io.Copy(out,file)
+    _ ,err = io.Copy(out, file)
     if err != nil {
         return nil, err
     }
@@ -89,13 +89,12 @@ func UploadFileBase64(ctx iris.Context) (*DstFile,error){
 
 // UploadMultiFiles Upload Multi Files
 func UploadMultiFiles(ctx iris.Context)(int, []DstFile, error){
-    outFiles := []DstFile{}
     
     maxSize := ctx.Application().ConfigurationReadOnly().GetPostMaxMemory()
     
     err := ctx.Request().ParseMultipartForm(maxSize)
     if err != nil {
-        return 0 , outFiles, err
+        return 0 , nil, err
     }
     
     form     := ctx.Request().MultipartForm
@@ -105,6 +104,7 @@ func UploadMultiFiles(ctx iris.Context)(int, []DstFile, error){
     failures := 0
     dstIndex := 1
     
+    outFiles := []DstFile{}
     for _, file := range files {
         url, err := SaveUploadFile(file)
         if err != nil {

+ 3 - 3
web/controllers/app_controller.go

@@ -1,9 +1,9 @@
 package controllers
 
 import (
-    "github.com/kataras/iris/v12/mvc"
-    "xps/datamodels"
-    "xps/service"
+	"github.com/kataras/iris/v12/mvc"
+	"xps/datamodels"
+	"xps/service"
 )
 
 type AppController struct {

+ 3 - 3
web/controllers/app_permit_controller.go

@@ -1,9 +1,9 @@
 package controllers
 
 import (
-    "github.com/kataras/iris/v12/mvc"
-    "xps/datamodels"
-    "xps/service"
+	"github.com/kataras/iris/v12/mvc"
+	"xps/datamodels"
+	"xps/service"
 )
 
 type AppPermitController struct {

+ 2 - 2
web/controllers/login_controller.go

@@ -1,8 +1,8 @@
 package controllers
 
 import (
-    "github.com/kataras/iris/v12/mvc"
-    "xps/service"
+	"github.com/kataras/iris/v12/mvc"
+	"xps/service"
 )
 
 type LoginController struct {

+ 3 - 3
web/controllers/model_controller.go

@@ -1,9 +1,9 @@
 package controllers
 
 import (
-    "github.com/kataras/iris/v12/mvc"
-    "xps/datamodels"
-    "xps/service"
+	"github.com/kataras/iris/v12/mvc"
+	"xps/datamodels"
+	"xps/service"
 )
 
 type ModelController struct {

+ 3 - 3
web/controllers/model_object_attr_controller.go

@@ -1,9 +1,9 @@
 package controllers
 
 import (
-    "github.com/kataras/iris/v12/mvc"
-    "xps/datamodels"
-    "xps/service"
+	"github.com/kataras/iris/v12/mvc"
+	"xps/datamodels"
+	"xps/service"
 )
 
 type ModelObjectAttrController struct {

+ 3 - 3
web/controllers/oc_type_controller.go

@@ -1,9 +1,9 @@
 package controllers
 
 import (
-"github.com/kataras/iris/v12/mvc"
-"xps/datamodels"
-"xps/service"
+    "github.com/kataras/iris/v12/mvc"
+    "xps/datamodels"
+    "xps/service"
 )
 
 type OcTypeController struct {

+ 3 - 3
web/controllers/position_controller.go

@@ -1,9 +1,9 @@
 package controllers
 
 import (
-    "github.com/kataras/iris/v12/mvc"
-    "xps/datamodels"
-    "xps/service"
+	"github.com/kataras/iris/v12/mvc"
+	"xps/datamodels"
+	"xps/service"
 )
 
 type PositionController struct {

+ 3 - 3
web/controllers/role_controller.go

@@ -1,9 +1,9 @@
 package controllers
 
 import (
-    "github.com/kataras/iris/v12/mvc"
-    "xps/datamodels"
-    "xps/service"
+	"github.com/kataras/iris/v12/mvc"
+	"xps/datamodels"
+	"xps/service"
 )
 
 type RoleController struct {

+ 3 - 3
web/controllers/task_cat_controller.go

@@ -1,9 +1,9 @@
 package controllers
 
 import (
-    "github.com/kataras/iris/v12/mvc"
-    "xps/datamodels"
-    "xps/service"
+	"github.com/kataras/iris/v12/mvc"
+	"xps/datamodels"
+	"xps/service"
 )
 
 type TaskCatController struct {

+ 30 - 7
web/controllers/upload_controller.go

@@ -3,6 +3,7 @@ package controllers
 import (
 	"github.com/kataras/iris/v12"
 	"github.com/kataras/iris/v12/mvc"
+    services "xps/service"
 	"xps/utils"
 )
 
@@ -13,16 +14,18 @@ type DstFile struct {
 
 type UploadController struct {
 	Ctx iris.Context
-	//Service   services.UploadService
+	Service   services.UploadService
 }
 
 func (c *UploadController) BeforeActivation(b mvc.BeforeActivation) {
-	b.Handle("POST", "/upload1", "Upload")
-	b.Handle("POST", "/upload2", "MultiUpload")
+	b.Handle("POST", "/file", "UploadFile")
+	b.Handle("POST", "/files", "UploadFiles")
+	b.Handle("POST", "/image", "UploadImage")
+	b.Handle("POST", "/images", "UploadImages")
 }
 
-// Upload :Single Upload
-func (c *UploadController) Upload() *JsonResult {
+// UploadFile :Single Upload
+func (c *UploadController) UploadFile() *JsonResult {
 	file, err := utils.UploadFile(c.Ctx)
 	if err != nil {
 		return ResultErr(err.Error(), nil)
@@ -31,8 +34,28 @@ func (c *UploadController) Upload() *JsonResult {
 	}
 }
 
-// MultiUpload :Multiple Upload
-func (c *UploadController) MultiUpload() *JsonResult {
+// UploadFiles :Multiple Upload
+func (c *UploadController) UploadFiles() *JsonResult {
+	_, files, err := utils.UploadMultiFiles(c.Ctx)
+	if err != nil {
+		return ResultErr(err.Error(), nil)
+	} else {
+		return ResultOk("获取成功", files)
+	}
+}
+
+// UploadImage UploadFile :Single Image Upload
+func (c *UploadController) UploadImage() *JsonResult {
+	file, err := utils.UploadFile(c.Ctx)
+	if err != nil {
+		return ResultErr(err.Error(), nil)
+	} else {
+		return ResultOk("获取成功", file)
+	}
+}
+
+// UploadImages UploadFiles :Multiple Upload
+func (c *UploadController) UploadImages() *JsonResult {
 	_, files, err := utils.UploadMultiFiles(c.Ctx)
 	if err != nil {
 		return ResultErr(err.Error(), nil)

+ 12 - 0
web/router/routes.go

@@ -321,6 +321,18 @@ func Configure(b *bootstrap.Bootstrapper) {
 		docFileApp.Handle(new(controllers.DocFileController))
 	}
 	
+	// Upload
+	uploadParty := b.Party("/upload", crs).AllowMethods(iris.MethodOptions)
+	{
+		uploadParty.Use(middleware.AuthToken)
+		
+		uploadService := service.NewUploadService()
+		uploadApp := mvc.New(artParty.Party(""))
+		uploadApp.Register(uploadService)
+		uploadApp.Handle(new(controllers.UploadController))
+		
+	}
+	
 	// x
 	xParty := b.Party("/x", crs).AllowMethods(iris.MethodOptions)
 	{