Skip to content

Commit a5d2cc1

Browse files
奇淼(piexlmaxsongzhibin97
andauthored
自动插件模式鉴定调整 (flipped-aurora#1161)
* fix: flipped-aurora#1160 * 自动插件模式鉴定调整 Co-authored-by: songzhibin97 <718428482@qq.com>
1 parent 2f5d2f5 commit a5d2cc1

File tree

6 files changed

+113
-65
lines changed

6 files changed

+113
-65
lines changed

server/api/v1/system/sys_auto_code.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,11 +246,27 @@ func (autoApi *AutoCodeApi) InstallPlugin(c *gin.Context) {
246246
response.FailWithMessage(err.Error(), c)
247247
return
248248
}
249-
err = autoCodeService.InstallPlugin(header)
249+
web, server, err := autoCodeService.InstallPlugin(header)
250+
webStr := "web插件安装成功"
251+
serverStr := "server插件安装成功"
252+
if web == -1 {
253+
webStr = "web端插件未成功安装,请按照文档自行解压安装,如果为纯后端插件请忽略此条提示"
254+
}
255+
if server == -1 {
256+
serverStr = "server端插件未成功安装,请按照文档自行解压安装,如果为纯前端插件请忽略此条提示"
257+
}
250258
if err != nil {
251259
response.FailWithMessage(err.Error(), c)
252260
return
253261
} else {
254-
response.OkWithMessage("插件安装成功,请按照说明配置使用", c)
262+
response.OkWithData([]interface{}{
263+
gin.H{
264+
"code": web,
265+
"msg": webStr,
266+
},
267+
gin.H{
268+
"code": server,
269+
"msg": serverStr,
270+
}}, c)
255271
}
256272
}

server/config.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,12 @@ Timer:
182182
- tableName: "sys_operation_records"
183183
compareField: "created_at"
184184
interval: "2160h"
185+
with_seconds: false
185186
- tableName: "jwt_blacklists"
186187
compareField: "created_at"
187188
interval: "168h"
189+
with_seconds: false
190+
188191

189192
# 跨域配置
190193
# 需要配合 server/initialize/router.go#L32 使用

server/config/timer.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package config
22

33
type Timer struct {
4-
Start bool `mapstructure:"start" json:"start" yaml:"start"` // 是否启用
5-
Spec string `mapstructure:"spec" json:"spec" yaml:"spec"` // CRON表达式
6-
Detail []Detail `mapstructure:"detail" json:"detail" yaml:"detail"`
4+
Start bool `mapstructure:"start" json:"start" yaml:"start"` // 是否启用
5+
Spec string `mapstructure:"spec" json:"spec" yaml:"spec"` // CRON表达式
6+
WithSeconds bool `mapstructure:"with_seconds" json:"with_seconds" yaml:"with_seconds"` // 是否精确到秒
7+
Detail []Detail `mapstructure:"detail" json:"detail" yaml:"detail"`
78
}
89

910
type Detail struct {

server/initialize/timer.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package initialize
33
import (
44
"fmt"
55

6+
"github.com/robfig/cron/v3"
7+
68
"github.com/flipped-aurora/gin-vue-admin/server/config"
79
"github.com/flipped-aurora/gin-vue-admin/server/global"
810
"github.com/flipped-aurora/gin-vue-admin/server/utils"
@@ -12,12 +14,16 @@ func Timer() {
1214
if global.GVA_CONFIG.Timer.Start {
1315
for i := range global.GVA_CONFIG.Timer.Detail {
1416
go func(detail config.Detail) {
17+
var option []cron.Option
18+
if global.GVA_CONFIG.Timer.WithSeconds {
19+
option = append(option, cron.WithSeconds())
20+
}
1521
_, err := global.GVA_Timer.AddTaskByFunc("ClearDB", global.GVA_CONFIG.Timer.Spec, func() {
1622
err := utils.ClearTable(global.GVA_DB, detail.TableName, detail.CompareField, detail.Interval)
1723
if err != nil {
1824
fmt.Println("timer error:", err)
1925
}
20-
})
26+
}, option...)
2127
if err != nil {
2228
fmt.Println("add timer error:", err)
2329
}

server/service/system/sys_auto_code.go

Lines changed: 75 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,10 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8-
cp "github.com/otiai10/copy"
9-
"go.uber.org/zap"
108
"go/ast"
119
"go/format"
1210
"go/parser"
1311
"go/token"
14-
"golang.org/x/text/cases"
15-
"golang.org/x/text/language"
1612
"io"
1713
"io/ioutil"
1814
"log"
@@ -23,6 +19,11 @@ import (
2319
"strings"
2420
"text/template"
2521

22+
cp "github.com/otiai10/copy"
23+
"go.uber.org/zap"
24+
"golang.org/x/text/cases"
25+
"golang.org/x/text/language"
26+
2627
"github.com/flipped-aurora/gin-vue-admin/server/resource/autocode_template/subcontract"
2728

2829
"github.com/flipped-aurora/gin-vue-admin/server/global"
@@ -827,91 +828,112 @@ func (autoCodeService *AutoCodeService) CreatePlug(plug system.AutoPlugReq) erro
827828
os.MkdirAll(dirPath, 0755)
828829
}
829830
file := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, fmt.Sprintf(global.GVA_CONFIG.AutoCode.SPlug, plug.Snake+"/"+tpl[len(plugPath):len(tpl)-4]))
830-
f, _ := os.OpenFile(file, os.O_WRONLY|os.O_CREATE, 0666)
831+
f, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE, 0666)
832+
if err != nil {
833+
zap.L().Error("open file", zap.String("tpl", tpl), zap.Error(err), zap.Any("plug", plug))
834+
return err
835+
}
836+
defer f.Close()
837+
831838
err = temp.Execute(f, plug)
832839
if err != nil {
833840
zap.L().Error("exec err", zap.String("tpl", tpl), zap.Error(err), zap.Any("plug", plug))
834841
return err
835842
}
836-
defer f.Close()
837843
}
838844
return nil
839845
}
840846

841-
func (autoCodeService *AutoCodeService) InstallPlugin(file *multipart.FileHeader) (err error) {
842-
const GVAPLUGPATH = "./gva-plug-temp/"
843-
defer os.RemoveAll(GVAPLUGPATH)
844-
_, err = os.Stat(GVAPLUGPATH)
847+
func (autoCodeService *AutoCodeService) InstallPlugin(file *multipart.FileHeader) (web, server int, err error) {
848+
const GVAPLUGPINATH = "./gva-plug-temp/"
849+
defer os.RemoveAll(GVAPLUGPINATH)
850+
_, err = os.Stat(GVAPLUGPINATH)
845851
if os.IsNotExist(err) {
846-
os.Mkdir(GVAPLUGPATH, os.ModePerm)
852+
os.Mkdir(GVAPLUGPINATH, os.ModePerm)
847853
}
848854

849855
src, err := file.Open()
850856
if err != nil {
851-
return err
857+
return -1, -1, err
852858
}
853859
defer src.Close()
854860

855-
out, err := os.Create(GVAPLUGPATH + file.Filename)
861+
out, err := os.Create(GVAPLUGPINATH + file.Filename)
856862
if err != nil {
857-
return err
863+
return -1, -1, err
858864
}
859865
defer out.Close()
860866

861867
_, err = io.Copy(out, src)
862868

863-
paths, err := utils.Unzip(GVAPLUGPATH+file.Filename, GVAPLUGPATH)
864-
var webIndex = 0
865-
var serverIndex = 0
869+
paths, err := utils.Unzip(GVAPLUGPINATH+file.Filename, GVAPLUGPINATH)
870+
paths = filterFile(paths)
871+
var webIndex = -1
872+
var serverIndex = -1
866873
for i := range paths {
867874
paths[i] = filepath.ToSlash(paths[i])
868875
pathArr := strings.Split(paths[i], "/")
869-
if pathArr[len(pathArr)-2] == "server" && pathArr[len(pathArr)-1] == "plugin" {
870-
serverIndex = i + 1
876+
ln := len(pathArr)
877+
if ln < 2 {
878+
continue
879+
}
880+
if pathArr[ln-2] == "server" && pathArr[ln-1] == "plugin" {
881+
serverIndex = i
871882
}
872-
if pathArr[len(pathArr)-2] == "web" && pathArr[len(pathArr)-1] == "plugin" {
873-
webIndex = i + 1
883+
if pathArr[ln-2] == "web" && pathArr[ln-1] == "plugin" {
884+
webIndex = i
874885
}
875886
}
876-
if webIndex == 0 && serverIndex == 0 {
877-
fmt.Println("非标准插件,请按照文档自动迁移使用")
878-
return errors.New("非标准插件,请按照文档自动迁移使用")
887+
if webIndex == -1 && serverIndex == -1 {
888+
zap.L().Error("非标准插件,请按照文档自动迁移使用")
889+
return webIndex, serverIndex, errors.New("非标准插件,请按照文档自动迁移使用")
879890
}
880891

881-
if webIndex != 0 {
882-
webNameArr := strings.Split(filepath.ToSlash(paths[webIndex]), "/")
883-
webName := webNameArr[len(webNameArr)-1]
884-
var form = filepath.ToSlash(global.GVA_CONFIG.AutoCode.Root + global.GVA_CONFIG.AutoCode.Server + "/" + paths[webIndex])
885-
var to = filepath.ToSlash(global.GVA_CONFIG.AutoCode.Root + global.GVA_CONFIG.AutoCode.Web + "/plugin/" + webName)
886-
_, err := os.Stat(to)
887-
if err == nil {
888-
fmt.Println("web 已存在同名插件,请自行手动安装")
889-
return errors.New("web 已存在同名插件,请自行手动安装")
890-
}
891-
err = cp.Copy(form, to)
892+
if webIndex != -1 {
893+
err = installation(paths[webIndex], global.GVA_CONFIG.AutoCode.Server, global.GVA_CONFIG.AutoCode.Web)
892894
if err != nil {
893-
return err
895+
return webIndex, serverIndex, err
894896
}
895897
}
896898

897-
if serverIndex != 0 {
898-
serverNameArr := strings.Split(filepath.ToSlash(paths[serverIndex]), "/")
899-
serverName := serverNameArr[len(serverNameArr)-1]
900-
var form = filepath.ToSlash(global.GVA_CONFIG.AutoCode.Root + global.GVA_CONFIG.AutoCode.Server + "/" + paths[serverIndex])
901-
var to = filepath.ToSlash(global.GVA_CONFIG.AutoCode.Root + global.GVA_CONFIG.AutoCode.Server + "/plugin/" + serverName)
902-
_, err := os.Stat(to)
903-
if err == nil {
904-
fmt.Println("server 已存在同名插件,请自行手动安装")
905-
return errors.New("server 已存在同名插件,请自行手动安装")
906-
}
907-
err = cp.Copy(form, to)
908-
if err != nil {
909-
return err
899+
if serverIndex != -1 {
900+
err = installation(paths[serverIndex], global.GVA_CONFIG.AutoCode.Server, global.GVA_CONFIG.AutoCode.Server)
901+
}
902+
return webIndex, serverIndex, err
903+
}
904+
905+
func installation(path string, formPath string, toPath string) error {
906+
arr := strings.Split(filepath.ToSlash(path), "/")
907+
ln := len(arr)
908+
if ln < 3 {
909+
return errors.New("arr")
910+
}
911+
name := arr[ln-3]
912+
913+
var form = filepath.ToSlash(global.GVA_CONFIG.AutoCode.Root + formPath + "/" + path)
914+
var to = filepath.ToSlash(global.GVA_CONFIG.AutoCode.Root + toPath + "/plugin/")
915+
_, err := os.Stat(to + name)
916+
if err == nil {
917+
zap.L().Error("autoPath 已存在同名插件,请自行手动安装", zap.String("to", to))
918+
return errors.New(toPath + "已存在同名插件,请自行手动安装")
919+
}
920+
return cp.Copy(form, to, cp.Options{Skip: skipMacSpecialDocument})
921+
}
922+
923+
func filterFile(paths []string) []string {
924+
np := make([]string, 0, len(paths))
925+
for _, path := range paths {
926+
if ok, _ := skipMacSpecialDocument(path); ok {
927+
continue
910928
}
929+
np = append(np, path)
911930
}
912-
if err != nil {
913-
return err
914-
} else {
915-
return nil
931+
return np
932+
}
933+
934+
func skipMacSpecialDocument(src string) (bool, error) {
935+
if strings.Contains(src, ".DS_Store") || strings.Contains(src, "__MACOSX") {
936+
return true, nil
916937
}
938+
return false, nil
917939
}

server/utils/timer/timed_task.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import (
77
)
88

99
type Timer interface {
10-
AddTaskByFunc(taskName string, spec string, task func()) (cron.EntryID, error)
11-
AddTaskByJob(taskName string, spec string, job interface{ Run() }) (cron.EntryID, error)
10+
AddTaskByFunc(taskName string, spec string, task func(), option ...cron.Option) (cron.EntryID, error)
11+
AddTaskByJob(taskName string, spec string, job interface{ Run() }, option ...cron.Option) (cron.EntryID, error)
1212
FindCron(taskName string) (*cron.Cron, bool)
1313
StartTask(taskName string)
1414
StopTask(taskName string)
@@ -24,23 +24,23 @@ type timer struct {
2424
}
2525

2626
// AddTaskByFunc 通过函数的方法添加任务
27-
func (t *timer) AddTaskByFunc(taskName string, spec string, task func()) (cron.EntryID, error) {
27+
func (t *timer) AddTaskByFunc(taskName string, spec string, task func(), option ...cron.Option) (cron.EntryID, error) {
2828
t.Lock()
2929
defer t.Unlock()
3030
if _, ok := t.taskList[taskName]; !ok {
31-
t.taskList[taskName] = cron.New(cron.WithSeconds())
31+
t.taskList[taskName] = cron.New(option...)
3232
}
3333
id, err := t.taskList[taskName].AddFunc(spec, task)
3434
t.taskList[taskName].Start()
3535
return id, err
3636
}
3737

3838
// AddTaskByJob 通过接口的方法添加任务
39-
func (t *timer) AddTaskByJob(taskName string, spec string, job interface{ Run() }) (cron.EntryID, error) {
39+
func (t *timer) AddTaskByJob(taskName string, spec string, job interface{ Run() }, option ...cron.Option) (cron.EntryID, error) {
4040
t.Lock()
4141
defer t.Unlock()
4242
if _, ok := t.taskList[taskName]; !ok {
43-
t.taskList[taskName] = cron.New()
43+
t.taskList[taskName] = cron.New(option...)
4444
}
4545
id, err := t.taskList[taskName].AddJob(spec, job)
4646
t.taskList[taskName].Start()

0 commit comments

Comments
 (0)