增加自动化代码选择业务库功能,增加无边框页面功能。 (#1264)

* feat:增加无边框页面路由

* 更改基础页面文字说明

* 修复安装插件路径穿越漏洞

* 添加业务库数据库选择功能

Co-authored-by: dzwvip <dzwvip@qq.com>
Co-authored-by: znonymous <fly1029@yeah.net>
This commit is contained in:
奇淼(piexlmax
2022-10-23 21:04:17 +08:00
committed by GitHub
parent 525b3a0da9
commit 05f8ae2aae
15 changed files with 283 additions and 45 deletions

View File

@@ -106,13 +106,15 @@ func (autoApi *AutoCodeApi) CreateTemp(c *gin.Context) {
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前所有数据库"
// @Router /autoCode/getDatabase [get]
func (autoApi *AutoCodeApi) GetDB(c *gin.Context) {
dbs, err := autoCodeService.Database().GetDB()
businessDB := c.Query("businessDB")
dbs, err := autoCodeService.Database(businessDB).GetDB(businessDB)
var dbList []map[string]interface{}
for _, db := range global.GVA_CONFIG.DBList {
var item = make(map[string]interface{})
item["aliasName"] = db.AliasName
item["dbName"] = db.Dbname
item["disable"] = db.Disable
item["dbtype"] = db.Type
dbList = append(dbList, item)
}
if err != nil {
@@ -133,7 +135,8 @@ func (autoApi *AutoCodeApi) GetDB(c *gin.Context) {
// @Router /autoCode/getTables [get]
func (autoApi *AutoCodeApi) GetTables(c *gin.Context) {
dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname)
tables, err := autoCodeService.Database().GetTables(dbName)
businessDB := c.Query("businessDB")
tables, err := autoCodeService.Database(businessDB).GetTables(businessDB, dbName)
if err != nil {
global.GVA_LOG.Error("查询table失败!", zap.Error(err))
response.FailWithMessage("查询table失败", c)
@@ -151,9 +154,10 @@ func (autoApi *AutoCodeApi) GetTables(c *gin.Context) {
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "获取当前表所有字段"
// @Router /autoCode/getColumn [get]
func (autoApi *AutoCodeApi) GetColumn(c *gin.Context) {
businessDB := c.Query("businessDB")
dbName := c.DefaultQuery("dbName", global.GVA_CONFIG.Mysql.Dbname)
tableName := c.Query("tableName")
columns, err := autoCodeService.Database().GetColumn(tableName, dbName)
columns, err := autoCodeService.Database(businessDB).GetColumn(businessDB, tableName, dbName)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)

View File

@@ -12,6 +12,7 @@ type Server struct {
// gorm
Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
Pgsql Pgsql `mapstructure:"pgsql" json:"pgsql" yaml:"pgsql"`
Oracle Oracle `mapstructure:"oracle" json:"oracle" yaml:"oracle"`
DBList []SpecializedDB `mapstructure:"db-list" json:"db-list" yaml:"db-list"`
// oss
Local Local `mapstructure:"local" json:"local" yaml:"local"`

View File

@@ -0,0 +1,14 @@
package config
type Oracle struct {
GeneralDB `yaml:",inline" mapstructure:",squash"`
}
func (m *Oracle) Dsn() string {
return "oracle://" + m.Username + ":" + m.Password + "@" + m.Path + ":" + m.Port + "/" + m.Dbname + "?" + m.Config
}
func (m *Oracle) GetLogMode() string {
return m.LogMode
}

View File

@@ -19,6 +19,8 @@ func DBList() {
dbMap[info.AliasName] = GormMysqlByConfig(config.Mysql{GeneralDB: info.GeneralDB})
case "pgsql":
dbMap[info.AliasName] = GormPgSqlByConfig(config.Pgsql{GeneralDB: info.GeneralDB})
case "oracle":
dbMap[info.AliasName] = GormOracleByConfig(config.Oracle{GeneralDB: info.GeneralDB})
default:
continue
}

View File

@@ -0,0 +1,54 @@
package initialize
import (
//"github.com/dzwvip/oracle"
"github.com/flipped-aurora/gin-vue-admin/server/config"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/initialize/internal"
//_ "github.com/godror/godror"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
// GormOracle 初始化oracle数据库
// 如果需要Oracle库 放开import里的注释 把下方 mysql.Config 改为 oracle.Config ; mysql.New 改为 oracle.New
func GormOracle() *gorm.DB {
m := global.GVA_CONFIG.Oracle
if m.Dbname == "" {
return nil
}
oracleConfig := mysql.Config{
DSN: m.Dsn(), // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
}
if db, err := gorm.Open(mysql.New(oracleConfig), internal.Gorm.Config()); err != nil {
panic(err)
} else {
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
return db
}
}
// GormOracleByConfig 初始化Oracle数据库用过传入配置
func GormOracleByConfig(m config.Oracle) *gorm.DB {
if m.Dbname == "" {
return nil
}
oracleConfig := mysql.Config{
DSN: m.Dsn(), // DSN data source name
DefaultStringSize: 191, // string 类型字段的默认长度
}
if db, err := gorm.Open(mysql.New(oracleConfig), internal.Gorm.Config()); err != nil {
panic(err)
} else {
sqlDB, _ := db.DB()
sqlDB.SetMaxIdleConns(m.MaxIdleConns)
sqlDB.SetMaxOpenConns(m.MaxOpenConns)
return db
}
}

View File

@@ -33,6 +33,8 @@ func (g *_gorm) Config() *gorm.Config {
logMode = &global.GVA_CONFIG.Mysql
case "pgsql":
logMode = &global.GVA_CONFIG.Pgsql
case "oracle":
logMode = &global.GVA_CONFIG.Oracle
default:
logMode = &global.GVA_CONFIG.Mysql
}

View File

@@ -6,18 +6,39 @@ import (
)
type Database interface {
GetDB() (data []response.Db, err error)
GetTables(dbName string) (data []response.Table, err error)
GetColumn(tableName string, dbName string) (data []response.Column, err error)
GetDB(businessDB string) (data []response.Db, err error)
GetTables(businessDB string, dbName string) (data []response.Table, err error)
GetColumn(businessDB string, tableName string, dbName string) (data []response.Column, err error)
}
func (autoCodeService *AutoCodeService) Database() Database {
switch global.GVA_CONFIG.System.DbType {
case "mysql":
return AutoCodeMysql
case "pgsql":
return AutoCodePgsql
default:
func (autoCodeService *AutoCodeService) Database(businessDB string) Database {
if businessDB == "" {
switch global.GVA_CONFIG.System.DbType {
case "mysql":
return AutoCodeMysql
case "pgsql":
return AutoCodePgsql
default:
return AutoCodeMysql
}
} else {
for _, info := range global.GVA_CONFIG.DBList {
if info.AliasName == businessDB {
switch info.Type {
case "mysql":
return AutoCodeMysql
case "pgsql":
return AutoCodePgsql
case "oracle":
return AutoCodeOracle
default:
return AutoCodeMysql
}
}
}
return AutoCodeMysql
}
}

View File

@@ -12,27 +12,36 @@ type autoCodeMysql struct{}
// GetDB 获取数据库的所有数据库名
// Author [piexlmax](https://github.com/piexlmax)
// Author [SliverHorn](https://github.com/SliverHorn)
func (s *autoCodeMysql) GetDB() (data []response.Db, err error) {
func (s *autoCodeMysql) GetDB(businessDB string) (data []response.Db, err error) {
var entities []response.Db
sql := "SELECT SCHEMA_NAME AS `database` FROM INFORMATION_SCHEMA.SCHEMATA;"
err = global.GVA_DB.Raw(sql).Scan(&entities).Error
if businessDB == "" {
err = global.GVA_DB.Raw(sql).Scan(&entities).Error
} else {
err = global.GVA_DBList[businessDB].Raw(sql).Scan(&entities).Error
}
return entities, err
}
// GetTables 获取数据库的所有表名
// Author [piexlmax](https://github.com/piexlmax)
// Author [SliverHorn](https://github.com/SliverHorn)
func (s *autoCodeMysql) GetTables(dbName string) (data []response.Table, err error) {
func (s *autoCodeMysql) GetTables(businessDB string, dbName string) (data []response.Table, err error) {
var entities []response.Table
sql := `select table_name as table_name from information_schema.tables where table_schema = ?`
err = global.GVA_DB.Raw(sql, dbName).Scan(&entities).Error
if businessDB == "" {
err = global.GVA_DB.Raw(sql, dbName).Scan(&entities).Error
} else {
err = global.GVA_DBList[businessDB].Raw(sql, dbName).Scan(&entities).Error
}
return entities, err
}
// GetColumn 获取指定数据库和指定数据表的所有字段名,类型值等
// Author [piexlmax](https://github.com/piexlmax)
// Author [SliverHorn](https://github.com/SliverHorn)
func (s *autoCodeMysql) GetColumn(tableName string, dbName string) (data []response.Column, err error) {
func (s *autoCodeMysql) GetColumn(businessDB string, tableName string, dbName string) (data []response.Column, err error) {
var entities []response.Column
sql := `
SELECT COLUMN_NAME column_name,
@@ -50,6 +59,11 @@ func (s *autoCodeMysql) GetColumn(tableName string, dbName string) (data []respo
WHERE table_name = ?
AND table_schema = ?
`
err = global.GVA_DB.Raw(sql, tableName, dbName).Scan(&entities).Error
if businessDB == "" {
err = global.GVA_DB.Raw(sql, tableName, dbName).Scan(&entities).Error
} else {
err = global.GVA_DBList[businessDB].Raw(sql, tableName, dbName).Scan(&entities).Error
}
return entities, err
}

View File

@@ -0,0 +1,54 @@
package system
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/system/response"
)
var AutoCodeOracle = new(autoCodeOracle)
type autoCodeOracle struct{}
// GetDB 获取数据库的所有数据库名
// Author [piexlmax](https://github.com/piexlmax)
// Author [SliverHorn](https://github.com/SliverHorn)
func (s *autoCodeOracle) GetDB(businessDB string) (data []response.Db, err error) {
var entities []response.Db
sql := `SELECT lower(username) AS "database" FROM all_users`
err = global.GVA_DBList[businessDB].Raw(sql).Scan(&entities).Error
return entities, err
}
// GetTables 获取数据库的所有表名
// Author [piexlmax](https://github.com/piexlmax)
// Author [SliverHorn](https://github.com/SliverHorn)
func (s *autoCodeOracle) GetTables(businessDB string, dbName string) (data []response.Table, err error) {
var entities []response.Table
sql := `select lower(table_name) as "table_name" from all_tables where lower(owner) = ?`
err = global.GVA_DBList[businessDB].Raw(sql, dbName).Scan(&entities).Error
return entities, err
}
// GetColumn 获取指定数据库和指定数据表的所有字段名,类型值等
// Author [piexlmax](https://github.com/piexlmax)
// Author [SliverHorn](https://github.com/SliverHorn)
func (s *autoCodeOracle) GetColumn(businessDB string, tableName string, dbName string) (data []response.Column, err error) {
var entities []response.Column
sql := `
select lower(a.COLUMN_NAME) as "column_name",
(CASE WHEN a.DATA_TYPE = 'NUMBER' AND a.DATA_SCALE=0 THEN 'int' else lower(a.DATA_TYPE) end) as "data_type",
(CASE WHEN a.DATA_TYPE = 'NUMBER' THEN a.DATA_PRECISION else a.DATA_LENGTH end) as "data_type_long",
b.COMMENTS as "column_comment"
from all_tab_columns a , all_col_comments b
where a.OWNER = b.OWNER
and a.TABLE_NAME = b.TABLE_NAME
and a.COLUMN_NAME = b.COLUMN_NAME
and lower(a.table_name) = ?
and lower(a.OWNER) = ?
`
err = global.GVA_DBList[businessDB].Raw(sql, tableName, dbName).Scan(&entities).Error
return entities, err
}

View File

@@ -16,23 +16,29 @@ type autoCodePgsql struct{}
// GetDB 获取数据库的所有数据库名
// Author [piexlmax](https://github.com/piexlmax)
// Author [SliverHorn](https://github.com/SliverHorn)
func (a *autoCodePgsql) GetDB() (data []response.Db, err error) {
func (a *autoCodePgsql) GetDB(businessDB string) (data []response.Db, err error) {
var entities []response.Db
sql := `SELECT datname as database FROM pg_database WHERE datistemplate = false`
err = global.GVA_DB.Raw(sql).Scan(&entities).Error
if businessDB == "" {
err = global.GVA_DB.Raw(sql).Scan(&entities).Error
} else {
err = global.GVA_DBList[businessDB].Raw(sql).Scan(&entities).Error
}
return entities, err
}
// GetTables 获取数据库的所有表名
// Author [piexlmax](https://github.com/piexlmax)
// Author [SliverHorn](https://github.com/SliverHorn)
func (a *autoCodePgsql) GetTables(dbName string) (data []response.Table, err error) {
func (a *autoCodePgsql) GetTables(businessDB string, dbName string) (data []response.Table, err error) {
var entities []response.Table
sql := `select table_name as table_name from information_schema.tables where table_catalog = ? and table_schema = ?`
db, _err := gorm.Open(postgres.Open(global.GVA_CONFIG.Pgsql.LinkDsn(dbName)), &gorm.Config{Logger: logger.Default.LogMode(logger.Info)})
if _err != nil {
return nil, errors.Wrapf(err, "[pgsql] 连接 数据库(%s)的表失败!", dbName)
}
err = db.Raw(sql, dbName, "public").Scan(&entities).Error
return entities, err
}
@@ -40,7 +46,7 @@ func (a *autoCodePgsql) GetTables(dbName string) (data []response.Table, err err
// GetColumn 获取指定数据库和指定数据表的所有字段名,类型值等
// Author [piexlmax](https://github.com/piexlmax)
// Author [SliverHorn](https://github.com/SliverHorn)
func (a *autoCodePgsql) GetColumn(tableName string, dbName string) (data []response.Column, err error) {
func (a *autoCodePgsql) GetColumn(businessDB string, tableName string, dbName string) (data []response.Column, err error) {
// todo 数据获取不全, 待完善sql
sql := `
SELECT psc.COLUMN_NAME AS COLUMN_NAME,

View File

@@ -2,12 +2,14 @@ package utils
import (
"archive/zip"
"fmt"
"io"
"os"
"path/filepath"
"strings"
)
//解压
// 解压
func Unzip(zipFile string, destDir string) ([]string, error) {
zipReader, err := zip.OpenReader(zipFile)
var paths []string
@@ -17,6 +19,9 @@ func Unzip(zipFile string, destDir string) ([]string, error) {
defer zipReader.Close()
for _, f := range zipReader.File {
if strings.Index(f.Name, "../") > -1 {
return []string{}, fmt.Errorf("%s 文件名不合法", f.Name)
}
fpath := filepath.Join(destDir, f.Name)
paths = append(paths, fpath)
if f.FileInfo().IsDir() {