Merge branch 'develop' into develop
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"gin-vue-admin/global"
|
||||
"gin-vue-admin/model"
|
||||
"gin-vue-admin/model/response"
|
||||
"gin-vue-admin/service"
|
||||
"gin-vue-admin/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// /excel/importExcel 接口,与upload接口作用类似,只是把文件存到resource/excel目录下,用于导入Excel时存放Excel文件(ExcelImport.xlsx)
|
||||
// /excel/loadExcel接口,用于读取resource/excel目录下的文件((ExcelImport.xlsx)并加载为[]model.SysBaseMenu类型的示例数据
|
||||
// /excel/exportExcel 接口,用于读取前端传来的tableData,生成Excel文件并返回
|
||||
// /excel/downloadTemplate 接口,用于下载resource/excel目录下的 ExcelTemplate.xlsx 文件,作为导入的模板
|
||||
|
||||
// @Tags excel
|
||||
// @Summary 导出Excel
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/octet-stream
|
||||
// @Param data body model.ExcelInfo true "导出Excel文件信息"
|
||||
// @Success 200
|
||||
// @Router /excel/exportExcel [post]
|
||||
func ExportExcel(c *gin.Context) {
|
||||
var excelInfo model.ExcelInfo
|
||||
_ = c.ShouldBindJSON(&excelInfo)
|
||||
filePath := global.GVA_CONFIG.Excel.Dir + excelInfo.FileName
|
||||
err := service.ParseInfoList2Excel(excelInfo.InfoList, filePath)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("转换Excel失败!", zap.Any("err", err))
|
||||
response.FailWithMessage("转换Excel失败", c)
|
||||
return
|
||||
}
|
||||
c.Writer.Header().Add("success", "true")
|
||||
c.File(filePath)
|
||||
}
|
||||
|
||||
// @Tags excel
|
||||
// @Summary 导入Excel文件
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param file formData file true "导入Excel文件"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"导入成功"}"
|
||||
// @Router /excel/importExcel [post]
|
||||
func ImportExcel(c *gin.Context) {
|
||||
_, header, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("接收文件失败!", zap.Any("err", err))
|
||||
response.FailWithMessage("接收文件失败", c)
|
||||
return
|
||||
}
|
||||
_ = c.SaveUploadedFile(header, global.GVA_CONFIG.Excel.Dir+"ExcelImport.xlsx")
|
||||
response.OkWithMessage("导入成功", c)
|
||||
}
|
||||
|
||||
// @Tags excel
|
||||
// @Summary 加载Excel数据
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"加载数据成功"}"
|
||||
// @Router /excel/loadExcel [get]
|
||||
func LoadExcel(c *gin.Context) {
|
||||
menus, err := service.ParseExcel2InfoList()
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("加载数据失败", zap.Any("err", err))
|
||||
response.FailWithMessage("加载数据失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: menus,
|
||||
Total: int64(len(menus)),
|
||||
Page: 1,
|
||||
PageSize: 999,
|
||||
}, "加载数据成功", c)
|
||||
}
|
||||
|
||||
// @Tags excel
|
||||
// @Summary 下载模板
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param fileName query fileName true "模板名称"
|
||||
// @Success 200
|
||||
// @Router /excel/downloadTemplate [get]
|
||||
func DownloadTemplate(c *gin.Context) {
|
||||
fileName := c.Query("fileName")
|
||||
filePath := global.GVA_CONFIG.Excel.Dir + fileName
|
||||
ok, err := utils.PathExists(filePath)
|
||||
if !ok || err != nil {
|
||||
global.GVA_LOG.Error("文件不存在", zap.Any("err", err))
|
||||
response.FailWithMessage("文件不存在", c)
|
||||
return
|
||||
}
|
||||
c.Writer.Header().Add("success", "true")
|
||||
c.File(filePath)
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"gin-vue-admin/model/request"
|
||||
"gin-vue-admin/model/response"
|
||||
"gin-vue-admin/service"
|
||||
"gin-vue-admin/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
@@ -76,89 +75,6 @@ func GetFileList(c *gin.Context) {
|
||||
Total: total,
|
||||
Page: pageInfo.Page,
|
||||
PageSize: pageInfo.PageSize,
|
||||
},"获取成功", c)
|
||||
}, "获取成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags ExaFileUploadAndDownload
|
||||
// @Summary 导出Excel
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/octet-stream
|
||||
// @Param data body request.ExcelInfo true "导出Excel文件信息"
|
||||
// @Success 200
|
||||
// @Router /fileUploadAndDownload/exportExcel [post]
|
||||
func ExportExcel(c *gin.Context) {
|
||||
var excelInfo request.ExcelInfo
|
||||
c.ShouldBindJSON(&excelInfo)
|
||||
filePath := global.GVA_CONFIG.Excel.Dir+excelInfo.FileName
|
||||
err := service.ParseInfoList2Excel(excelInfo.InfoList, filePath)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("转换Excel失败!", zap.Any("err", err))
|
||||
response.FailWithMessage("转换Excel失败", c)
|
||||
return
|
||||
}
|
||||
c.Writer.Header().Add("success", "true")
|
||||
c.File(filePath)
|
||||
}
|
||||
|
||||
// @Tags ExaFileUploadAndDownload
|
||||
// @Summary 导入Excel文件
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param file formData file true "导入Excel文件"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"导入成功"}"
|
||||
// @Router /fileUploadAndDownload/importExcel [post]
|
||||
func ImportExcel(c *gin.Context) {
|
||||
_, header, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("接收文件失败!", zap.Any("err", err))
|
||||
response.FailWithMessage("接收文件失败", c)
|
||||
return
|
||||
}
|
||||
c.SaveUploadedFile(header, global.GVA_CONFIG.Excel.Dir+"ExcelImport.xlsx")
|
||||
response.OkWithMessage("导入成功", c)
|
||||
}
|
||||
|
||||
// @Tags ExaFileUploadAndDownload
|
||||
// @Summary 加载Excel数据
|
||||
// @Security ApiKeyAuth
|
||||
// @Produce application/json
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"加载数据成功"}"
|
||||
// @Router /fileUploadAndDownload/loadExcel [get]
|
||||
func LoadExcel(c *gin.Context) {
|
||||
menus, err := service.ParseExcel2InfoList()
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("加载数据失败", zap.Any("err", err))
|
||||
response.FailWithMessage("加载数据失败", c)
|
||||
return
|
||||
}
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: menus,
|
||||
Total: int64(len(menus)),
|
||||
Page: 1,
|
||||
PageSize: 999,
|
||||
},"加载数据成功", c)
|
||||
}
|
||||
|
||||
// @Tags ExaFileUploadAndDownload
|
||||
// @Summary 下载模板
|
||||
// @Security ApiKeyAuth
|
||||
// @accept multipart/form-data
|
||||
// @Produce application/json
|
||||
// @Param fileName query fileName true "模板名称"
|
||||
// @Success 200
|
||||
// @Router /fileUploadAndDownload/downloadTemplate [get]
|
||||
func DownloadTemplate(c *gin.Context) {
|
||||
fileName := c.Query("fileName")
|
||||
filePath := global.GVA_CONFIG.Excel.Dir+fileName
|
||||
ok, err := utils.PathExists(filePath)
|
||||
if !ok || err != nil {
|
||||
global.GVA_LOG.Error("文件不存在", zap.Any("err", err))
|
||||
response.FailWithMessage("文件不存在", c)
|
||||
return
|
||||
}
|
||||
c.Writer.Header().Add("success", "true")
|
||||
c.File(filePath)
|
||||
}
|
||||
@@ -1,19 +1,44 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"gin-vue-admin/global"
|
||||
"gin-vue-admin/model"
|
||||
"gin-vue-admin/model/response"
|
||||
"gin-vue-admin/service"
|
||||
"gin-vue-admin/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// @Tags AutoCode
|
||||
// @Summary 预览创建后的代码
|
||||
// @Security ApiKeyAuth
|
||||
// @accept application/json
|
||||
// @Produce application/json
|
||||
// @Param data body model.AutoCodeStruct true "预览创建代码"
|
||||
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
|
||||
// @Router /autoCode/preview [post]
|
||||
func PreviewTemp(c *gin.Context) {
|
||||
var a model.AutoCodeStruct
|
||||
_ = c.ShouldBindJSON(&a)
|
||||
if err := utils.Verify(a, utils.AutoCodeVerify); err != nil {
|
||||
response.FailWithMessage(err.Error(), c)
|
||||
return
|
||||
}
|
||||
autoCode, err := service.PreviewTemp(a)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("预览失败!", zap.Any("err", err))
|
||||
response.FailWithMessage("预览失败", c)
|
||||
} else {
|
||||
response.OkWithDetailed(gin.H{"autoCode": autoCode}, "预览成功", c)
|
||||
}
|
||||
}
|
||||
|
||||
// @Tags AutoCode
|
||||
// @Summary 自动代码模板
|
||||
// @Security ApiKeyAuth
|
||||
|
||||
@@ -44,7 +44,7 @@ func (m *_mysql) Init() {
|
||||
m._config.DisableForeignKeyConstraintWhenMigrating = true
|
||||
m.db, m.err = gorm.Open(mysql.New(mysql.Config{
|
||||
DSN: global.GVA_CONFIG.Mysql.Dsn(), // DSN data source name
|
||||
DefaultStringSize: 256, // string 类型字段的默认长度
|
||||
DefaultStringSize: 191, // string 类型字段的默认长度
|
||||
DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
|
||||
DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
|
||||
DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
|
||||
|
||||
@@ -92,6 +92,11 @@ var apis = []model.SysApi{
|
||||
{global.GVA_MODEL{ID: 77, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/workflowProcess/getMyNeed", "获取我的待办", "workflowProcess", "GET"},
|
||||
{global.GVA_MODEL{ID: 78, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/workflowProcess/getWorkflowMoveByID", "根据id获取当前节点详情和历史", "workflowProcess", "GET"},
|
||||
{global.GVA_MODEL{ID: 79, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/workflowProcess/completeWorkflowMove", "提交工作流", "workflowProcess", "POST"},
|
||||
{global.GVA_MODEL{ID: 80, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/autoCode/preview", "预览自动化代码", "autoCode", "POST"},
|
||||
{global.GVA_MODEL{ID: 81, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/excel/importExcel", "预览自动化代码", "autoCode", "POST"},
|
||||
{global.GVA_MODEL{ID: 82, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/excel/loadExcel", "预览自动化代码", "autoCode", "POST"},
|
||||
{global.GVA_MODEL{ID: 83, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/excel/exportExcel", "预览自动化代码", "autoCode", "POST"},
|
||||
{global.GVA_MODEL{ID: 84, CreatedAt: time.Now(), UpdatedAt: time.Now()}, "/excel/downloadTemplate", "预览自动化代码", "autoCode", "POST"},
|
||||
}
|
||||
|
||||
//@author: [SliverHorn](https://github.com/SliverHorn)
|
||||
|
||||
@@ -55,6 +55,7 @@ var carbines = []gormadapter.CasbinRule{
|
||||
{PType: "p", V0: "888", V1: "/customer/customer", V2: "GET"},
|
||||
{PType: "p", V0: "888", V1: "/customer/customerList", V2: "GET"},
|
||||
{PType: "p", V0: "888", V1: "/autoCode/createTemp", V2: "POST"},
|
||||
{PType: "p", V0: "888", V1: "/autoCode/preview", V2: "POST"},
|
||||
{PType: "p", V0: "888", V1: "/autoCode/getTables", V2: "GET"},
|
||||
{PType: "p", V0: "888", V1: "/autoCode/getDB", V2: "GET"},
|
||||
{PType: "p", V0: "888", V1: "/autoCode/getColumn", V2: "GET"},
|
||||
@@ -91,6 +92,10 @@ var carbines = []gormadapter.CasbinRule{
|
||||
{PType: "p", V0: "888", V1: "/workflowProcess/getMyStated", V2: "GET"},
|
||||
{PType: "p", V0: "888", V1: "/workflowProcess/getMyNeed", V2: "GET"},
|
||||
{PType: "p", V0: "888", V1: "/workflowProcess/getWorkflowMoveByID", V2: "GET"},
|
||||
{PType: "p", V0: "888", V1: "/excel/importExcel", V2: "POST"},
|
||||
{PType: "p", V0: "888", V1: "/excel/loadExcel", V2: "GET"},
|
||||
{PType: "p", V0: "888", V1: "/excel/exportExcel", V2: "POST"},
|
||||
{PType: "p", V0: "888", V1: "/excel/downloadTemplate", V2: "GET"},
|
||||
{PType: "p", V0: "8881", V1: "/base/login", V2: "POST"},
|
||||
{PType: "p", V0: "8881", V1: "/user/register", V2: "POST"},
|
||||
{PType: "p", V0: "8881", V1: "/api/createApi", V2: "POST"},
|
||||
|
||||
@@ -78,6 +78,7 @@ qiniu:
|
||||
secret-key: 'pgdbqEsf7ooZh7W3xokP833h3dZ_VecFXPDeG5JY'
|
||||
use-cdn-domains: false
|
||||
|
||||
|
||||
# aliyun oss configuration
|
||||
aliyun-oss:
|
||||
endpoint: 'yourEndpoint'
|
||||
@@ -86,6 +87,15 @@ aliyun-oss:
|
||||
bucket-name: 'yourBucketName'
|
||||
bucket-url: 'yourBucketUrl'
|
||||
|
||||
# tencent cos configuration
|
||||
tencent-cos:
|
||||
bucket: 'xxxxx-10005608'
|
||||
region: 'ap-shanghai'
|
||||
secret-id: 'xxxxxxxx'
|
||||
secret-key: 'xxxxxxxx'
|
||||
base-url: 'https://gin.vue.admin'
|
||||
path-prefix: 'gin-vue-admin'
|
||||
|
||||
# excel configuration
|
||||
excel:
|
||||
dir: './resource/excel/'
|
||||
@@ -14,5 +14,6 @@ type Server struct {
|
||||
Local Local `mapstructure:"local" json:"local" yaml:"local"`
|
||||
Qiniu Qiniu `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"`
|
||||
AliyunOSS AliyunOSS `mapstructure:"aliyun-oss" json:"aliyunOSS" yaml:"aliyun-oss"`
|
||||
Excel Excel `mapstructure:"excel" json:"excel" yaml:"excel"`
|
||||
TencentCOS TencentCOS `mapstructure:"tencent-cos" json:"tencentCOS" yaml:"tencent-cos"`
|
||||
Excel Excel `mapstructure:"excel" json:"excel" yaml:"excel"`
|
||||
}
|
||||
|
||||
@@ -14,10 +14,20 @@ type Qiniu struct {
|
||||
UseCdnDomains bool `mapstructure:"use-cdn-domains" json:"useCdnDomains" yaml:"use-cdn-domains"`
|
||||
}
|
||||
|
||||
|
||||
type AliyunOSS struct {
|
||||
Endpoint string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint"`
|
||||
AccessKeyId string `mapstructure:"access-key-id" json:"accessKeyId" yaml:"access-key-id"`
|
||||
AccessKeySecret string `mapstructure:"access-key-secret" json:"accessKeySecret" yaml:"access-key-secret"`
|
||||
BucketName string `mapstructure:"bucket-name" json:"bucketName" yaml:"bucket-name"`
|
||||
BucketUrl string `mapstructure:"bucket-url" json:"bucketUrl" yaml:"bucket-url"`
|
||||
|
||||
type TencentCOS struct {
|
||||
Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"`
|
||||
Region string `mapstructure:"region" json:"region" yaml:"region"`
|
||||
SecretID string `mapstructure:"secret-id" json:"secretID" yaml:"secret-id"`
|
||||
SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"`
|
||||
BaseURL string `mapstructure:"base-url" json:"baseURL" yaml:"base-url"`
|
||||
PathPrefix string `mapstructure:"path-prefix" json:"pathPrefix" yaml:"path-prefix"`
|
||||
|
||||
}
|
||||
|
||||
+3
-2
@@ -36,10 +36,10 @@ require (
|
||||
github.com/onsi/ginkgo v1.7.0 // indirect
|
||||
github.com/onsi/gomega v1.4.3 // indirect
|
||||
github.com/pelletier/go-toml v1.6.0 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/qiniu/api.v7/v7 v7.4.1
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/shirou/gopsutil v2.20.8+incompatible
|
||||
github.com/shirou/gopsutil v3.21.1+incompatible
|
||||
github.com/spf13/afero v1.2.2 // indirect
|
||||
github.com/spf13/cast v1.3.1 // indirect
|
||||
github.com/spf13/cobra v1.1.1
|
||||
@@ -48,6 +48,7 @@ require (
|
||||
github.com/swaggo/gin-swagger v1.2.0
|
||||
github.com/swaggo/swag v1.6.7
|
||||
github.com/tebeka/strftime v0.1.3 // indirect
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.19
|
||||
github.com/unrolled/secure v1.0.7
|
||||
go.uber.org/zap v1.10.0
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b // indirect
|
||||
|
||||
@@ -47,6 +47,7 @@ func Routers() *gin.Engine {
|
||||
router.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理
|
||||
router.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由
|
||||
router.InitWorkflowProcessRouter(PrivateGroup) // 工作流相关接口
|
||||
router.InitExcelRouter(PrivateGroup) // 表格导入导出
|
||||
}
|
||||
global.GVA_LOG.Info("router register success")
|
||||
return Router
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package model
|
||||
|
||||
type ExcelInfo struct {
|
||||
FileName string `json:"fileName"`
|
||||
InfoList []SysBaseMenu `json:"infoList"`
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package request
|
||||
|
||||
import "gin-vue-admin/model"
|
||||
|
||||
type ExcelInfo struct {
|
||||
FileName string `json:"fileName"`
|
||||
InfoList []model.SysBaseMenu `json:"infoList"`
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,16 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"gin-vue-admin/api/v1"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func InitExcelRouter(Router *gin.RouterGroup) {
|
||||
FileUploadAndDownloadGroup := Router.Group("excel")
|
||||
{
|
||||
FileUploadAndDownloadGroup.POST("/importExcel", v1.ImportExcel) // 导入Excel
|
||||
FileUploadAndDownloadGroup.GET("/loadExcel", v1.LoadExcel) // 加载Excel数据
|
||||
FileUploadAndDownloadGroup.POST("/exportExcel", v1.ExportExcel) // 导出Excel
|
||||
FileUploadAndDownloadGroup.GET("/downloadTemplate", v1.DownloadTemplate) // 下载模板文件
|
||||
}
|
||||
}
|
||||
-4
@@ -15,9 +15,5 @@ func InitFileUploadAndDownloadRouter(Router *gin.RouterGroup) {
|
||||
FileUploadAndDownloadGroup.GET("/findFile", v1.FindFile) // 查询当前文件成功的切片
|
||||
FileUploadAndDownloadGroup.POST("/breakpointContinueFinish", v1.BreakpointContinueFinish) // 查询当前文件成功的切片
|
||||
FileUploadAndDownloadGroup.POST("/removeChunk", v1.RemoveChunk) // 查询当前文件成功的切片
|
||||
FileUploadAndDownloadGroup.POST("/importExcel", v1.ImportExcel) // 导入Excel
|
||||
FileUploadAndDownloadGroup.GET("/loadExcel", v1.LoadExcel) // 加载Excel数据
|
||||
FileUploadAndDownloadGroup.POST("/exportExcel", v1.ExportExcel) // 导出Excel
|
||||
FileUploadAndDownloadGroup.GET("/downloadTemplate", v1.DownloadTemplate) // 下载模板文件
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
func InitAutoCodeRouter(Router *gin.RouterGroup) {
|
||||
AutoCodeRouter := Router.Group("autoCode")
|
||||
{
|
||||
AutoCodeRouter.POST("preview", v1.PreviewTemp) // 获取自动创建代码预览
|
||||
AutoCodeRouter.POST("createTemp", v1.CreateTemp) // 创建自动化代码
|
||||
AutoCodeRouter.GET("getTables", v1.GetTables) // 获取对应数据库的表
|
||||
AutoCodeRouter.GET("getDB", v1.GetDB) // 获取数据库
|
||||
|
||||
+121
-44
@@ -16,6 +16,11 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const (
|
||||
autoPath = "autoCode/"
|
||||
basePath = "resource/template"
|
||||
)
|
||||
|
||||
type tplData struct {
|
||||
template *template.Template
|
||||
locationPath string
|
||||
@@ -23,6 +28,71 @@ type tplData struct {
|
||||
autoMoveFilePath string
|
||||
}
|
||||
|
||||
//@author: [songzhibin97](https://github.com/songzhibin97)
|
||||
//@function: PreviewTemp
|
||||
//@description: 预览创建代码
|
||||
//@param: model.AutoCodeStruct
|
||||
//@return: map[string]string, error
|
||||
|
||||
func PreviewTemp(autoCode model.AutoCodeStruct) (map[string]string, error) {
|
||||
dataList, _, needMkdir, err := getNeedList(&autoCode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 写入文件前,先创建文件夹
|
||||
if err = utils.CreateDir(needMkdir...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 创建map
|
||||
ret := make(map[string]string)
|
||||
|
||||
// 生成map
|
||||
for _, value := range dataList {
|
||||
ext := ""
|
||||
if ext = filepath.Ext(value.autoCodePath); ext == ".txt" {
|
||||
continue
|
||||
}
|
||||
f, err := os.OpenFile(value.autoCodePath, os.O_CREATE|os.O_WRONLY, 0755)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = value.template.Execute(f, autoCode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_ = f.Close()
|
||||
f, err = os.OpenFile(value.autoCodePath, os.O_CREATE|os.O_RDONLY, 0755)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builder := strings.Builder{}
|
||||
builder.WriteString("```")
|
||||
|
||||
if ext != "" && strings.Contains(ext, ".") {
|
||||
builder.WriteString(strings.Replace(ext, ".", "", -1))
|
||||
}
|
||||
builder.WriteString("\n\n")
|
||||
data, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builder.Write(data)
|
||||
builder.WriteString("\n\n```")
|
||||
|
||||
pathArr := strings.Split(value.autoCodePath, string(os.PathSeparator))
|
||||
ret[pathArr[1]+"-"+pathArr[3]] = builder.String()
|
||||
_ = f.Close()
|
||||
|
||||
}
|
||||
defer func() { // 移除中间文件
|
||||
if err := os.RemoveAll(autoPath); err != nil {
|
||||
return
|
||||
}
|
||||
}()
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
//@author: [piexlmax](https://github.com/piexlmax)
|
||||
//@function: CreateTemp
|
||||
//@description: 创建代码
|
||||
@@ -30,52 +100,10 @@ type tplData struct {
|
||||
//@return: error
|
||||
|
||||
func CreateTemp(autoCode model.AutoCodeStruct) (err error) {
|
||||
basePath := "resource/template"
|
||||
// 获取 basePath 文件夹下所有tpl文件
|
||||
tplFileList, err := GetAllTplFile(basePath, nil)
|
||||
dataList, fileList, needMkdir, err := getNeedList(&autoCode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList := make([]tplData, 0, len(tplFileList))
|
||||
fileList := make([]string, 0, len(tplFileList))
|
||||
needMkdir := make([]string, 0, len(tplFileList)) // 当文件夹下存在多个tpl文件时,改为map更合理
|
||||
// 根据文件路径生成 tplData 结构体,待填充数据
|
||||
for _, value := range tplFileList {
|
||||
dataList = append(dataList, tplData{locationPath: value})
|
||||
}
|
||||
// 生成 *Template, 填充 template 字段
|
||||
for index, value := range dataList {
|
||||
dataList[index].template, err = template.ParseFiles(value.locationPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 生成文件路径,填充 autoCodePath 字段,readme.txt.tpl不符合规则,需要特殊处理
|
||||
// resource/template/web/api.js.tpl -> autoCode/web/autoCode.PackageName/api/autoCode.PackageName.js
|
||||
// resource/template/readme.txt.tpl -> autoCode/readme.txt
|
||||
autoPath := "autoCode/"
|
||||
for index, value := range dataList {
|
||||
trimBase := strings.TrimPrefix(value.locationPath, basePath+"/")
|
||||
if trimBase == "readme.txt.tpl" {
|
||||
dataList[index].autoCodePath = autoPath + "readme.txt"
|
||||
continue
|
||||
}
|
||||
|
||||
if lastSeparator := strings.LastIndex(trimBase, "/"); lastSeparator != -1 {
|
||||
origFileName := strings.TrimSuffix(trimBase[lastSeparator+1:], ".tpl")
|
||||
firstDot := strings.Index(origFileName, ".")
|
||||
if firstDot != -1 {
|
||||
dataList[index].autoCodePath = filepath.Join(autoPath, trimBase[:lastSeparator], autoCode.PackageName,
|
||||
origFileName[:firstDot], autoCode.PackageName+origFileName[firstDot:])
|
||||
}
|
||||
}
|
||||
|
||||
if lastSeparator := strings.LastIndex(dataList[index].autoCodePath, string(os.PathSeparator)); lastSeparator != -1 {
|
||||
needMkdir = append(needMkdir, dataList[index].autoCodePath[:lastSeparator])
|
||||
}
|
||||
}
|
||||
|
||||
// 写入文件前,先创建文件夹
|
||||
if err = utils.CreateDir(needMkdir...); err != nil {
|
||||
return err
|
||||
@@ -83,7 +111,6 @@ func CreateTemp(autoCode model.AutoCodeStruct) (err error) {
|
||||
|
||||
// 生成文件
|
||||
for _, value := range dataList {
|
||||
fileList = append(fileList, value.autoCodePath)
|
||||
f, err := os.OpenFile(value.autoCodePath, os.O_CREATE|os.O_WRONLY, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -276,3 +303,53 @@ func AutoCreateApi(a *model.AutoCodeStruct) (err error) {
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func getNeedList(autoCode *model.AutoCodeStruct) (dataList []tplData, fileList []string, needMkdir []string, err error) {
|
||||
// 获取 basePath 文件夹下所有tpl文件
|
||||
tplFileList, err := GetAllTplFile(basePath, nil)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
dataList = make([]tplData, 0, len(tplFileList))
|
||||
fileList = make([]string, 0, len(tplFileList))
|
||||
needMkdir = make([]string, 0, len(tplFileList)) // 当文件夹下存在多个tpl文件时,改为map更合理
|
||||
// 根据文件路径生成 tplData 结构体,待填充数据
|
||||
for _, value := range tplFileList {
|
||||
dataList = append(dataList, tplData{locationPath: value})
|
||||
}
|
||||
// 生成 *Template, 填充 template 字段
|
||||
for index, value := range dataList {
|
||||
dataList[index].template, err = template.ParseFiles(value.locationPath)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
}
|
||||
// 生成文件路径,填充 autoCodePath 字段,readme.txt.tpl不符合规则,需要特殊处理
|
||||
// resource/template/web/api.js.tpl -> autoCode/web/autoCode.PackageName/api/autoCode.PackageName.js
|
||||
// resource/template/readme.txt.tpl -> autoCode/readme.txt
|
||||
autoPath := "autoCode/"
|
||||
for index, value := range dataList {
|
||||
trimBase := strings.TrimPrefix(value.locationPath, basePath+"/")
|
||||
if trimBase == "readme.txt.tpl" {
|
||||
dataList[index].autoCodePath = autoPath + "readme.txt"
|
||||
continue
|
||||
}
|
||||
|
||||
if lastSeparator := strings.LastIndex(trimBase, "/"); lastSeparator != -1 {
|
||||
origFileName := strings.TrimSuffix(trimBase[lastSeparator+1:], ".tpl")
|
||||
firstDot := strings.Index(origFileName, ".")
|
||||
if firstDot != -1 {
|
||||
dataList[index].autoCodePath = filepath.Join(autoPath, trimBase[:lastSeparator], autoCode.PackageName,
|
||||
origFileName[:firstDot], autoCode.PackageName+origFileName[firstDot:])
|
||||
}
|
||||
}
|
||||
|
||||
if lastSeparator := strings.LastIndex(dataList[index].autoCodePath, string(os.PathSeparator)); lastSeparator != -1 {
|
||||
needMkdir = append(needMkdir, dataList[index].autoCodePath[:lastSeparator])
|
||||
}
|
||||
}
|
||||
for _, value := range dataList {
|
||||
fileList = append(fileList, value.autoCodePath)
|
||||
}
|
||||
return dataList, fileList, needMkdir, err
|
||||
}
|
||||
|
||||
@@ -89,12 +89,11 @@ func getBaseChildrenList(menu *model.SysBaseMenu, treeMap map[string][]model.Sys
|
||||
//@param: menu model.SysBaseMenu
|
||||
//@return: err error
|
||||
|
||||
func AddBaseMenu(menu model.SysBaseMenu) (err error) {
|
||||
func AddBaseMenu(menu model.SysBaseMenu) error {
|
||||
if !errors.Is(global.GVA_DB.Where("name = ?", menu.Name).First(&model.SysBaseMenu{}).Error, gorm.ErrRecordNotFound) {
|
||||
err = errors.New("存在重复name,请修改name")
|
||||
return errors.New("存在重复name,请修改name")
|
||||
}
|
||||
err = global.GVA_DB.Create(&menu).Error
|
||||
return err
|
||||
return global.GVA_DB.Create(&menu).Error
|
||||
}
|
||||
|
||||
//@author: [piexlmax](https://github.com/piexlmax)
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package upload
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"gin-vue-admin/global"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/tencentyun/cos-go-sdk-v5"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type TencentCOS struct{}
|
||||
|
||||
// UploadFile upload file to COS
|
||||
func (*TencentCOS) UploadFile(file *multipart.FileHeader) (string, string, error) {
|
||||
c := NewClient()
|
||||
f, openError := file.Open()
|
||||
if openError != nil {
|
||||
global.GVA_LOG.Error("function file.Open() Filed", zap.Any("err", openError.Error()))
|
||||
|
||||
return "", "", errors.New("function file.Open() Filed, err:" + openError.Error())
|
||||
}
|
||||
fileKey := fmt.Sprintf("%d%s", time.Now().Unix(), file.Filename)
|
||||
|
||||
_, err := c.Object.Put(context.Background(), global.GVA_CONFIG.TencentCOS.PathPrefix+"/"+fileKey, f, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return global.GVA_CONFIG.TencentCOS.BaseURL + "/" + global.GVA_CONFIG.TencentCOS.PathPrefix + "/" + fileKey, fileKey, nil
|
||||
}
|
||||
|
||||
// DeleteFile delete file form COS
|
||||
func (*TencentCOS) DeleteFile(key string) error {
|
||||
c := NewClient()
|
||||
name := global.GVA_CONFIG.TencentCOS.PathPrefix + "/" + key
|
||||
_, err := c.Object.Delete(context.Background(), name)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("function bucketManager.Delete() Filed", zap.Any("err", err.Error()))
|
||||
return errors.New("function bucketManager.Delete() Filed, err:" + err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewClient init COS client
|
||||
func NewClient() *cos.Client {
|
||||
u, _ := url.Parse("https://" + global.GVA_CONFIG.TencentCOS.Bucket + ".cos." + global.GVA_CONFIG.TencentCOS.Region + ".myqcloud.com")
|
||||
b := &cos.BaseURL{BucketURL: u}
|
||||
c := cos.NewClient(b, &http.Client{
|
||||
Transport: &cos.AuthorizationTransport{
|
||||
SecretID: global.GVA_CONFIG.TencentCOS.SecretID,
|
||||
SecretKey: global.GVA_CONFIG.TencentCOS.SecretKey,
|
||||
},
|
||||
})
|
||||
return c
|
||||
}
|
||||
@@ -28,7 +28,9 @@ func NewOss() OSS {
|
||||
return &Local{}
|
||||
case "qiniu":
|
||||
return &Qiniu{}
|
||||
case "tencent-cos":
|
||||
return &TencentCOS{}
|
||||
default:
|
||||
return &Local{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user