Merge branch 'develop' into develop

This commit is contained in:
奇淼(piexlmax
2020-11-25 02:55:43 -06:00
committed by GitHub
138 changed files with 5601 additions and 4694 deletions
+30
View File
@@ -14,6 +14,12 @@ import (
const breakpointDir = "./breakpointDir/"
const finishDir = "./fileDir/"
//@author: [piexlmax](https://github.com/piexlmax)
//@function: BreakPointContinue
//@description: 断点续传
//@param: content []byte, fileName string, contentNumber int, contentTotal int, fileMd5 string
//@return: error, string
func BreakPointContinue(content []byte, fileName string, contentNumber int, contentTotal int, fileMd5 string) (error, string) {
path := breakpointDir + fileMd5 + "/"
err := os.MkdirAll(path, os.ModePerm)
@@ -25,6 +31,12 @@ func BreakPointContinue(content []byte, fileName string, contentNumber int, cont
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: CheckMd5
//@description: 检查Md5
//@param: content []byte, chunkMd5 string
//@return: CanUpload bool
func CheckMd5(content []byte, chunkMd5 string) (CanUpload bool) {
fileMd5 := MD5V(content)
if fileMd5 == chunkMd5 {
@@ -34,6 +46,12 @@ func CheckMd5(content []byte, chunkMd5 string) (CanUpload bool) {
}
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: makeFileContent
//@description: 创建切片内容
//@param: content []byte, fileName string, FileDir string, contentNumber int
//@return: error, string
func makeFileContent(content []byte, fileName string, FileDir string, contentNumber int) (error, string) {
path := FileDir + fileName + "_" + strconv.Itoa(contentNumber)
f, err := os.Create(path)
@@ -49,6 +67,12 @@ func makeFileContent(content []byte, fileName string, FileDir string, contentNum
return nil, path
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: makeFileContent
//@description: 创建切片文件
//@param: fileName string, FileMd5 string
//@return: error, string
func MakeFile(fileName string, FileMd5 string) (error, string) {
rd, err := ioutil.ReadDir(breakpointDir + FileMd5)
if err != nil {
@@ -72,6 +96,12 @@ func MakeFile(fileName string, FileMd5 string) (error, string) {
return nil, finishDir + fileName
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: RemoveChunk
//@description: 移除切片
//@param: FileMd5 string
//@return: error
func RemoveChunk(FileMd5 string) error {
err := os.RemoveAll(breakpointDir + FileMd5)
return err
+204
View File
@@ -0,0 +1,204 @@
package utils
import (
"bytes"
"context"
"fmt"
"io"
"os"
"os/exec"
"runtime"
"sync"
)
//@author: [songzhibin97](https://github.com/songzhibin97)
//@interface_name: RunTask
//@description: Task接口
type RunTask interface {
AddTask()
RunTask()
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@struct_name: T
//@description: Task任务
type T struct {
sync.Mutex
// 获取事件channel
ch chan struct{}
closeChan chan struct{}
// 记录process对象
p *os.Process
// 执行任务
f func(chan struct{}) error
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@function: NewT
//@description: T的实例化方法
//@return: *T
func NewT() *T {
return newT(nil)
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@function: newT
//@description:
//@param: f func(chan struct{}) error
//@return: *T
func newT(f func(chan struct{}) error) *T {
t := &T{
Mutex: sync.Mutex{},
ch: make(chan struct{}, 1),
closeChan: make(chan struct{}),
f: f,
}
if f == nil {
t.f = t.DefaultF
}
return t
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: *T
//@function: AddTask
//@description: 添加任务
func (t *T) AddTask() {
if len(t.ch) == 1 {
return
}
t.Lock()
defer t.Unlock()
if len(t.ch) == 1 {
// 代表已经有任务了
// 直接丢弃这次任务
return
}
t.ch <- struct{}{}
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: *T
//@function: RunTask
//@description: 启动任务
func (t *T) RunTask() {
fmt.Println("进入")
// 这里做的make 是用于关闭上一个执行的任务
ch := make(chan struct{})
// 先run服务
go t.f(ch)
for {
_, ok := <-t.ch
if !ok {
return
}
ch <- struct{}{}
// 等待上一个关闭
<-t.closeChan
go t.f(ch)
}
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: t *T
//@function: DefaultF
//@description: 默认的StartFunction
//@param: ch chan struct{}
//@return: error
func (t *T) DefaultF(ch chan struct{}) error {
var buildCmd *exec.Cmd
var cmd *exec.Cmd
// 检测系统是否有编译环境
_, err := exec.LookPath("go")
if err != nil {
return err
}
// build
switch runtime.GOOS {
case "windows":
buildCmd = exec.Command("go", "build", "-o", "server.exe", "main.go")
default:
buildCmd = exec.Command("go", "build", "-o", "server", "main.go")
}
//cmd = exec.Command("go", "run", "main.go")
err = buildCmd.Run()
if err != nil {
return err
}
fmt.Println("build 执行完成")
// 执行
switch runtime.GOOS {
case "windows":
cmd = exec.Command("server.exe")
default:
cmd = exec.Command("./server")
}
// 开始执行任务
ctx, cancel := context.WithCancel(context.Background())
err = t.echo(cmd, ctx)
<-ch
// 回收资源
fmt.Println("pid:", t.p.Pid, "->Kill")
err = t.p.Kill()
cancel()
// 发送关闭完成信号
t.closeChan <- struct{}{}
return err
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: t *T
//@function: echo
//@description: 封装回显
//@param: cmd *exec.Cmd, ctx context.Context
//@return: error
func (t *T) echo(cmd *exec.Cmd, ctx context.Context) error {
var stdoutBuf bytes.Buffer
stdoutIn, _ := cmd.StdoutPipe()
var errStdout error
stdout := io.MultiWriter(os.Stdout, &stdoutBuf)
err := cmd.Start()
if err != nil {
return err
}
go func(ctx context.Context) {
_, errStdout = io.Copy(stdout, stdoutIn)
select {
case <-ctx.Done():
return
default:
}
}(ctx)
t.p = cmd.Process
fmt.Println("pid", t.p.Pid)
go func() {
_ = cmd.Wait()
if errStdout != nil {
fmt.Printf("failed to capture stdout or stderr\n")
}
fmt.Printf("%s\n", string(stdoutBuf.Bytes()))
select {
case <-ctx.Done():
//_ = os.Stdout.Close()
return
default:
}
}()
return nil
}
+174
View File
@@ -0,0 +1,174 @@
package utils
import (
"errors"
"fmt"
"github.com/fsnotify/fsnotify"
"io/ioutil"
"os"
"path/filepath"
)
//@author: [songzhibin97](https://github.com/songzhibin97)
//@struct_name: Watch
//@description: 监控对象
type Watch struct {
*fsnotify.Watcher
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@function: NewWatch
//@description: Watch的实例化方法
//@return: *Watch
func NewWatch() *Watch {
obj, _ := fsnotify.NewWatcher()
return &Watch{obj}
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: w *Watch
//@function: Watch
//@description: 监控对象
//@param: path string, t *T
//@return: error
func (w *Watch) Watch(path string, t *T) error {
// 先转化为绝对路径
path, err := filepath.Abs(path)
if err != nil {
return err
}
// 判断是单个文件还是目录文件
fileInfo, err := os.Stat(path)
if err != nil {
return err
}
// 判断是否是目录 添加监控
if fileInfo.IsDir() {
// dir
err = w.watchDir(path)
} else {
err = w.watchFile(path)
}
if err != nil {
return err
}
c := make(chan error)
// 启动监控
go func() {
for {
select {
case even, ok := <-w.Events:
if !ok {
// close
fmt.Println("Errors close")
c <- errors.New("errors close")
return
}
// 判断事件
switch {
case even.Op&fsnotify.Create == fsnotify.Create:
//这里获取新创建文件的信息,如果是目录,则加入监控中
fmt.Println("创建文件 : ", even.Name)
//t.AddTask()
_ = w.Add(even.Name)
case even.Op&fsnotify.Write == fsnotify.Write:
fmt.Println("修改文件 : ", even.Name)
w.addTask(t, even.Name)
case even.Op&fsnotify.Remove == fsnotify.Remove || even.Op&fsnotify.Rename == fsnotify.Rename:
fmt.Println("删除或重命名文件 : ", even.Name)
_ = w.Remove(even.Name)
w.addTask(t, even.Name)
}
case err = <-w.Errors:
fmt.Println("even Error:", err)
c <- err
return
}
}
}()
return <-c
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: w *Watch
//@function: watchDir
//@description: 处理监控目录
//@param: path string
//@return: error
func (w *Watch) watchDir(path string) error {
// 先将自己添加到监控
err := w.Add(path)
if err != nil {
return err
}
fileSlice, err := ioutil.ReadDir(path)
if err != nil {
return err
}
for _, f := range fileSlice {
fPath := filepath.Join(path, f.Name())
if !f.IsDir() {
// 判断是否可监控的文件
if chickPower(fPath) {
err = w.watchFile(fPath)
if err != nil {
return err
}
}
} else {
err := w.watchDir(fPath)
if err != nil {
return err
}
}
}
return err
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: w *Watch
//@function: watchDir
//@description: 处理监控单文件
//@param: path string
//@return: error
func (w *Watch) watchFile(path string) error {
var err error
if chickPower(path) {
err = w.Add(path)
}
return err
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@function: chickPower
//@description: 判断是否在可控范围内
//@param: path string
//@return: error
func chickPower(name string) bool {
name = filepath.Ext(name)
return name == ".go" || name == ".yaml"
}
//@author: [songzhibin97](https://github.com/songzhibin97)
//@object: w *Watch
//@function: addTask
//@description: 偏函数 简化发送任务
//@param: path string
//@return: error
func (w *Watch) addTask(t *T, name string) {
if chickPower(name) {
fmt.Println("Add Task->>>>>>")
t.AddTask()
}
}
+10 -10
View File
@@ -6,11 +6,11 @@ import (
"os"
)
// @title PathExists
// @description 文件目录是否存在
// @auth (2020/04/05 20:22)
// @param path string
// @return err error
//@author: [piexlmax](https://github.com/piexlmax)
//@function: PathExists
//@description: 文件目录是否存在
//@param: path string
//@return: bool, error
func PathExists(path string) (bool, error) {
_, err := os.Stat(path)
@@ -23,11 +23,11 @@ func PathExists(path string) (bool, error) {
return false, err
}
// @title createDir
// @description 批量创建文件夹
// @auth (2020/04/05 20:22)
// @param dirs string
// @return err error
//@author: [piexlmax](https://github.com/piexlmax)
//@function: CreateDir
//@description: 批量创建文件夹
//@param: dirs ...string
//@return: err error
func CreateDir(dirs ...string) (err error) {
for _, v := range dirs {
+24 -1
View File
@@ -11,12 +11,23 @@ import (
"github.com/jordan-wright/email"
)
//@author: [maplepie](https://github.com/maplepie)
//@function: Email
//@description: Email发送方法
//@param: subject string, body string
//@return: error
func Email(subject string, body string) error {
to := strings.Split(global.GVA_CONFIG.Email.To, ",")
return send(to, subject, body)
}
// ErrorToEmail Error 发送邮件
//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: ErrorToEmail
//@description: 给email中间件错误发送邮件到指定邮箱
//@param: subject string, body string
//@return: error
func ErrorToEmail(subject string, body string) error {
to := strings.Split(global.GVA_CONFIG.Email.To, ",")
if to[len(to)-1] == "" { // 判断切片的最后一个元素是否为空,为空则移除
@@ -25,11 +36,23 @@ func ErrorToEmail(subject string, body string) error {
return send(to, subject, body)
}
//@author: [maplepie](https://github.com/maplepie)
//@function: EmailTest
//@description: Email测试方法
//@param: subject string, body string
//@return: error
func EmailTest(subject string, body string) error {
to := []string{global.GVA_CONFIG.Email.From}
return send(to, subject, body)
}
//@author: [maplepie](https://github.com/maplepie)
//@function: send
//@description: Email发送方法
//@param: subject string, body string
//@return: error
func send(to []string, subject string, body string) error {
from := global.GVA_CONFIG.Email.From
nickname := global.GVA_CONFIG.Email.Nickname
+41
View File
@@ -0,0 +1,41 @@
package utils
import (
"os"
"path/filepath"
)
//@author: [songzhibin97](https://github.com/songzhibin97)
//@function: FileMove
//@description: 文件移动供外部调用
//@param: src string, dst string(src: 源位置,绝对路径or相对路径, dst: 目标位置,绝对路径or相对路径,必须为文件夹)
//@return: err error
func FileMove(src string, dst string) (err error) {
if dst == "" {
return nil
}
src, err = filepath.Abs(src)
if err != nil {
return err
}
dst, err = filepath.Abs(dst)
if err != nil {
return err
}
var revoke = false
dir := filepath.Dir(dst)
Redirect:
_, err = os.Stat(dir)
if err != nil {
err = os.MkdirAll(dir, 0755)
if err != nil {
return err
}
if !revoke {
revoke = true
goto Redirect
}
}
return os.Rename(src, dst)
}
+12 -2
View File
@@ -6,7 +6,12 @@ import (
"strings"
)
// 利用反射将结构体转化为map
//@author: [piexlmax](https://github.com/piexlmax)
//@function: StructToMap
//@description: 利用反射将结构体转化为map
//@param: obj interface{}
//@return: map[string]interface{}
func StructToMap(obj interface{}) map[string]interface{} {
obj1 := reflect.TypeOf(obj)
obj2 := reflect.ValueOf(obj)
@@ -18,7 +23,12 @@ func StructToMap(obj interface{}) map[string]interface{} {
return data
}
//将数组格式化为字符串
//@author: [piexlmax](https://github.com/piexlmax)
//@function: ArrayToString
//@description: 将数组格式化为字符串
//@param: array []interface{}
//@return: string
func ArrayToString(array []interface{}) string {
return strings.Replace(strings.Trim(fmt.Sprint(array), "[]"), " ", ",", -1)
}
+6
View File
@@ -5,6 +5,12 @@ import (
"encoding/hex"
)
//@author: [piexlmax](https://github.com/piexlmax)
//@function: MD5V
//@description: md5加密
//@param: str []byte
//@return: string
func MD5V(str []byte) string {
h := md5.New()
h.Write(str)
+5 -1
View File
@@ -11,7 +11,11 @@ import (
"time"
)
// GetWriteSyncer zap logger中加入file-rotatelogs
//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: GetWriteSyncer
//@description: zap logger中加入file-rotatelogs
//@return: zapcore.WriteSyncer, error
func GetWriteSyncer() (zapcore.WriteSyncer, error) {
fileWriter, err := zaprotatelogs.New(
path.Join(global.GVA_CONFIG.Zap.Director, "%Y-%m-%d.log"),
+5 -1
View File
@@ -9,7 +9,11 @@ import (
"time"
)
// GetWriteSyncer zap logger中加入file-rotatelogs
//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: GetWriteSyncer
//@description: zap logger中加入file-rotatelogs
//@return: zapcore.WriteSyncer, error
func GetWriteSyncer() (zapcore.WriteSyncer, error) {
fileWriter, err := zaprotatelogs.New(
path.Join(global.GVA_CONFIG.Zap.Director, "%Y-%m-%d.log"),
+20 -4
View File
@@ -50,7 +50,11 @@ type Disk struct {
UsedPercent int `json:"usedPercent"`
}
// InitOS OS信息
//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: InitCPU
//@description: OS信息
//@return: o Os, err error
func InitOS() (o Os) {
o.GOOS = runtime.GOOS
o.NumCPU = runtime.NumCPU()
@@ -60,7 +64,11 @@ func InitOS() (o Os) {
return o
}
// InitCPU CPU信息
//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: InitCPU
//@description: CPU信息
//@return: c Cpu, err error
func InitCPU() (c Cpu, err error) {
if cores, err := cpu.Counts(false); err != nil {
return c, err
@@ -75,7 +83,11 @@ func InitCPU() (c Cpu, err error) {
return c, nil
}
// InitRAM ARM信息
//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: InitRAM
//@description: ARM信息
//@return: r Rrm, err error
func InitRAM() (r Rrm, err error) {
if u, err := mem.VirtualMemory(); err != nil{
return r, err
@@ -87,7 +99,11 @@ func InitRAM() (r Rrm, err error) {
return r, nil
}
// InitDisk 硬盘信息
//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: InitDisk
//@description: 硬盘信息
//@return: d Disk, err error
func InitDisk() (d Disk, err error) {
if u, err := disk.Usage("/"); err != nil{
return d, err
+20 -4
View File
@@ -14,8 +14,16 @@ import (
type Local struct{}
// UploadFile 上传文件
func (l Local) UploadFile(file *multipart.FileHeader) (string, string, error) {
//@author: [piexlmax](https://github.com/piexlmax)
//@author: [ccfish86](https://github.com/ccfish86)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@object: *Local
//@function: UploadFile
//@description: 上传文件
//@param: file *multipart.FileHeader
//@return: string, string, error
func (*Local) UploadFile(file *multipart.FileHeader) (string, string, error) {
// 读取文件后缀
ext := path.Ext(file.Filename)
// 读取文件名并加密
@@ -55,8 +63,16 @@ func (l Local) UploadFile(file *multipart.FileHeader) (string, string, error) {
return p, filename, nil
}
// DeleteFile 删除文件
func (l Local) DeleteFile(key string) error {
//@author: [piexlmax](https://github.com/piexlmax)
//@author: [ccfish86](https://github.com/ccfish86)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@object: *Local
//@function: DeleteFile
//@description: 删除文件
//@param: key string
//@return: error
func (*Local) DeleteFile(key string) error {
p := global.GVA_CONFIG.Local.Path + "/" + key
if strings.Contains(p, global.GVA_CONFIG.Local.Path) {
if err := os.Remove(p); err != nil {
+25 -3
View File
@@ -14,7 +14,15 @@ import (
type Qiniu struct{}
// Upload 上传文件
//@author: [piexlmax](https://github.com/piexlmax)
//@author: [ccfish86](https://github.com/ccfish86)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@object: *Qiniu
//@function: UploadFile
//@description: 上传文件
//@param: file *multipart.FileHeader
//@return: string, string, error
func (*Qiniu) UploadFile(file *multipart.FileHeader) (string, string, error) {
putPolicy := storage.PutPolicy{Scope: global.GVA_CONFIG.Qiniu.Bucket}
mac := qbox.NewMac(global.GVA_CONFIG.Qiniu.AccessKey, global.GVA_CONFIG.Qiniu.SecretKey)
@@ -39,7 +47,15 @@ func (*Qiniu) UploadFile(file *multipart.FileHeader) (string, string, error) {
return global.GVA_CONFIG.Qiniu.ImgPath + "/" + ret.Key, ret.Key, nil
}
// DeleteFile 删除文件
//@author: [piexlmax](https://github.com/piexlmax)
//@author: [ccfish86](https://github.com/ccfish86)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@object: *Qiniu
//@function: DeleteFile
//@description: 删除文件
//@param: key string
//@return: error
func (*Qiniu) DeleteFile(key string) error {
mac := qbox.NewMac(global.GVA_CONFIG.Qiniu.AccessKey, global.GVA_CONFIG.Qiniu.SecretKey)
cfg := qiniuConfig()
@@ -51,7 +67,13 @@ func (*Qiniu) DeleteFile(key string) error {
return nil
}
// config 根据配置文件进行返回七牛云的配置
//@author: [SliverHorn](https://github.com/SliverHorn)
//@object: *Qiniu
//@function: qiniuConfig
//@description: 根据配置文件进行返回七牛云的配置
//@param: key string
//@return: error
func qiniuConfig() *storage.Config {
cfg := storage.Config{
UseHTTPS: global.GVA_CONFIG.Qiniu.UseHTTPS,
+11 -1
View File
@@ -5,13 +5,23 @@ import (
"mime/multipart"
)
var Oss OSS
//@author: [ccfish86](https://github.com/ccfish86)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@interface_name: OSS
//@description: OSS接口
type OSS interface {
UploadFile(file *multipart.FileHeader) (string, string, error)
DeleteFile(key string) error
}
//@author: [ccfish86](https://github.com/ccfish86)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@function: NewOss
//@description: OSS接口
//@description: OSS的实例化方法
//@return: OSS
func NewOss() OSS {
switch global.GVA_CONFIG.System.OssType {
case "local":
-54
View File
@@ -1,54 +0,0 @@
package utils
import (
"gin-vue-admin/global"
"go.uber.org/zap"
"io"
"mime/multipart"
"os"
"path"
"strings"
"time"
)
func UploadFileLocal(file *multipart.FileHeader) (err error, localPath string, key string) {
// 读取文件后缀
ext := path.Ext(file.Filename)
// 读取文件名并加密
fileName := strings.TrimSuffix(file.Filename, ext)
fileName = MD5V([]byte(fileName))
// 拼接新文件名
lastName := fileName + "_" + time.Now().Format("20060102150405") + ext
// 读取全局变量的定义路径
savePath := global.GVA_CONFIG.Local.Path
// 尝试创建此路径
err = os.MkdirAll(savePath, os.ModePerm)
if err != nil {
global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err))
return err, "", ""
}
// 拼接路径和文件名
dst := savePath + "/" + lastName
// 下面为上传逻辑
// 打开文件 defer 关闭
src, err := file.Open()
if err != nil {
global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err))
return err, "", ""
}
defer src.Close()
// 创建文件 defer 关闭
out, err := os.Create(dst)
if err != nil {
global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err))
return err, "", ""
}
defer out.Close()
// 传输(拷贝)文件
_, err = io.Copy(out, src)
if err != nil {
global.GVA_LOG.Error("upload local file fail:", zap.Any("err", err))
return err, "", ""
}
return nil, dst, lastName
}
-67
View File
@@ -1,67 +0,0 @@
package utils
import (
"context"
"fmt"
"gin-vue-admin/global"
"github.com/qiniu/api.v7/v7/auth/qbox"
"github.com/qiniu/api.v7/v7/storage"
"go.uber.org/zap"
"mime/multipart"
"time"
)
// 接收两个参数 一个文件流 一个 bucket 你的七牛云标准空间的名字
func UploadRemote(file *multipart.FileHeader) (err error, path string, key string) {
putPolicy := storage.PutPolicy{
Scope: global.GVA_CONFIG.Qiniu.Bucket,
}
mac := qbox.NewMac(global.GVA_CONFIG.Qiniu.AccessKey, global.GVA_CONFIG.Qiniu.SecretKey)
upToken := putPolicy.UploadToken(mac)
cfg := storage.Config{}
// 空间对应的机房
cfg.Zone = &storage.ZoneHuadong
// 是否使用https域名
cfg.UseHTTPS = false
// 上传是否使用CDN上传加速
cfg.UseCdnDomains = false
formUploader := storage.NewFormUploader(&cfg)
ret := storage.PutRet{}
putExtra := storage.PutExtra{
Params: map[string]string{
"x:name": "github logo",
},
}
f, e := file.Open()
if e != nil {
fmt.Println(e)
return e, "", ""
}
dataLen := file.Size
fileKey := fmt.Sprintf("%d%s", time.Now().Unix(), file.Filename) // 文件名格式 自己可以改 建议保证唯一性
err = formUploader.Put(context.Background(), &ret, upToken, fileKey, f, dataLen, &putExtra)
if err != nil {
global.GVA_LOG.Error("upload file fail:", zap.Any("err", err))
return err, "", ""
}
return err, global.GVA_CONFIG.Qiniu.ImgPath + "/" + ret.Key, ret.Key
}
func DeleteFile(key string) error {
mac := qbox.NewMac(global.GVA_CONFIG.Qiniu.AccessKey, global.GVA_CONFIG.Qiniu.SecretKey)
cfg := storage.Config{
// 是否使用https域名进行资源管理
UseHTTPS: false,
}
// 指定空间所在的区域,如果不指定将自动探测
// 如果没有特殊需求,默认不需要指定
// cfg.Zone=&storage.ZoneHuabei
bucketManager := storage.NewBucketManager(mac, &cfg)
err := bucketManager.Delete(global.GVA_CONFIG.Qiniu.Bucket, key)
if err != nil {
fmt.Println(err)
return err
}
return nil
}
+73 -11
View File
@@ -13,7 +13,12 @@ type RulesMap map[string]Rules
var CustomizeMap = make(map[string]Rules)
// 注册自定义规则方案建议在路由初始化层即注册
//@author: [piexlmax](https://github.com/piexlmax)
//@function: RegisterRule
//@description: 注册自定义规则方案建议在路由初始化层即注册
//@param: key string, rule Rules
//@return: err error
func RegisterRule(key string, rule Rules) (err error) {
if CustomizeMap[key] != nil {
return errors.New(key + "已注册,无法重复注册")
@@ -23,42 +28,83 @@ func RegisterRule(key string, rule Rules) (err error) {
}
}
// 非空 不能为其对应类型的0值
//@author: [piexlmax](https://github.com/piexlmax)
//@function: NotEmpty
//@description: 非空 不能为其对应类型的0值
//@param: key string, rule Rules
//@return: err error
func NotEmpty() string {
return "notEmpty"
}
// 小于入参(<) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
//@author: [piexlmax](https://github.com/piexlmax)
//@function: Lt
//@description: 小于入参(<) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
//@param: mark string
//@return: string
func Lt(mark string) string {
return "lt=" + mark
}
// 小于等于入参(<=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
//@author: [piexlmax](https://github.com/piexlmax)
//@function: Le
//@description: 小于等于入参(<=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
//@param: mark string
//@return: string
func Le(mark string) string {
return "le=" + mark
}
// 等于入参(==) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
//@author: [piexlmax](https://github.com/piexlmax)
//@function: Eq
//@description: 等于入参(==) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
//@param: mark string
//@return: string
func Eq(mark string) string {
return "eq=" + mark
}
// 不等于入参(!=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
//@author: [piexlmax](https://github.com/piexlmax)
//@function: Ne
//@description: 不等于入参(!=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
//@param: mark string
//@return: string
func Ne(mark string) string {
return "ne=" + mark
}
// 大于等于入参(>=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
//@author: [piexlmax](https://github.com/piexlmax)
//@function: Ge
//@description: 大于等于入参(>=) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
//@param: mark string
//@return: string
func Ge(mark string) string {
return "ge=" + mark
}
// 大于入参(>) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
//@author: [piexlmax](https://github.com/piexlmax)
//@function: Gt
//@description: 大于入参(>) 如果为string array Slice则为长度比较 如果是 int uint float 则为数值比较
//@param: mark string
//@return: string
func Gt(mark string) string {
return "gt=" + mark
}
// 校验方法 接收两个参数 入参实例,规则map
//
//@author: [piexlmax](https://github.com/piexlmax)
//@function: Verify
//@description: 校验方法
//@param: st interface{}, roleMap Rules(入参实例,规则map)
//@return: err error
func Verify(st interface{}, roleMap Rules) (err error) {
compareMap := map[string]bool{
"lt": true,
@@ -99,7 +145,12 @@ func Verify(st interface{}, roleMap Rules) (err error) {
return nil
}
// 长度和数字的校验方法 根据类型自动校验
//@author: [piexlmax](https://github.com/piexlmax)
//@function: compareVerify
//@description: 长度和数字的校验方法 根据类型自动校验
//@param: value reflect.Value, VerifyStr string
//@return: bool
func compareVerify(value reflect.Value, VerifyStr string) bool {
switch value.Kind() {
case reflect.String, reflect.Slice, reflect.Array:
@@ -115,7 +166,12 @@ func compareVerify(value reflect.Value, VerifyStr string) bool {
}
}
// 非空校验
//@author: [piexlmax](https://github.com/piexlmax)
//@function: isBlank
//@description: 非空校验
//@param: value reflect.Value
//@return: bool
func isBlank(value reflect.Value) bool {
switch value.Kind() {
case reflect.String:
@@ -134,6 +190,12 @@ func isBlank(value reflect.Value) bool {
return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface())
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: compare
//@description: 比较函数
//@param: value interface{}, VerifyStr string
//@return: bool
func compare(value interface{}, VerifyStr string) bool {
VerifyStrArr := strings.Split(VerifyStr, "=")
val := reflect.ValueOf(value)
+20
View File
@@ -0,0 +1,20 @@
package utils
var (
IdVerify = Rules{"ID": {NotEmpty()}}
ApiVerify = Rules{"Path": {NotEmpty()}, "Description": {NotEmpty()}, "ApiGroup": {NotEmpty()}, "Method": {NotEmpty()}}
MenuVerify = Rules{"Path": {NotEmpty()}, "ParentId": {NotEmpty()}, "Name": {NotEmpty()}, "Component": {NotEmpty()}, "Sort": {Ge("0")}}
MenuMetaVerify = Rules{"Title": {NotEmpty()}}
LoginVerify = Rules{"CaptchaId": {NotEmpty()}, "Captcha": {NotEmpty()}, "Username": {NotEmpty()}, "Password": {NotEmpty()}}
SetUserVerify = Rules{"ID": {NotEmpty()}, "Username": {NotEmpty()}, "NickName": {NotEmpty()}, "HeaderImg": {NotEmpty()}}
RegisterVerify = Rules{"Username": {NotEmpty()}, "NickName": {NotEmpty()}, "Password": {NotEmpty()}, "AuthorityId": {NotEmpty()}}
PageInfoVerify = Rules{"Page": {NotEmpty()}, "PageSize": {NotEmpty()}}
CustomerVerify = Rules{"CustomerName": {NotEmpty()}, "CustomerPhoneData": {NotEmpty()}}
AutoCodeVerify = Rules{"Abbreviation": {NotEmpty()}, "StructName": {NotEmpty()}, "PackageName": {NotEmpty()}, "Fields": {NotEmpty()}}
WorkFlowVerify = Rules{"WorkflowNickName": {NotEmpty()}, "WorkflowName": {NotEmpty()}, "WorkflowDescription": {NotEmpty()}, "WorkflowStepInfo": {NotEmpty()}}
AuthorityVerify = Rules{"AuthorityId": {NotEmpty()}, "AuthorityName": {NotEmpty()}, "ParentId": {NotEmpty()}}
AuthorityIdVerify = Rules{"AuthorityId": {NotEmpty()}}
OldAuthorityVerify = Rules{"OldAuthorityId": {NotEmpty()}}
ChangePasswordVerify = Rules{"Username": {NotEmpty()}, "Password": {NotEmpty()}, "NewPassword": {NotEmpty()}}
SetUserAuthorityVerify = Rules{"UUID": {NotEmpty()}, "AuthorityId": {NotEmpty()}}
)
+14 -4
View File
@@ -7,26 +7,36 @@ import (
"strings"
)
func ZipFiles(filename string, files []string, oldform, newform string) error {
//@author: [piexlmax](https://github.com/piexlmax)
//@function: ZipFiles
//@description: 压缩文件
//@param: filename string, files []string, oldform, newform string
//@return: error
func ZipFiles(filename string, files []string, oldForm, newForm string) error {
newZipFile, err := os.Create(filename)
if err != nil {
return err
}
defer newZipFile.Close()
defer func() {
_ = newZipFile.Close()
}()
zipWriter := zip.NewWriter(newZipFile)
defer zipWriter.Close()
defer func() {
_ = zipWriter.Close()
}()
// 把files添加到zip中
for _, file := range files {
err = func(file string) error {
zipFile, err := os.Open(file)
if err != nil {
return err
}
defer zipFile.Close()
// 获取file的基础信息
info, err := zipFile.Stat()
if err != nil {