diff --git a/server/api/v1/system/auto_code_template.go b/server/api/v1/system/auto_code_template.go index 9b9f8ad49..f551c12e0 100644 --- a/server/api/v1/system/auto_code_template.go +++ b/server/api/v1/system/auto_code_template.go @@ -98,11 +98,24 @@ func (a *AutoCodeTemplateApi) AddFunc(c *gin.Context) { response.FailWithMessage(err.Error(), c) return } - err = autoCodeTemplateService.AddFunc(info) + var tempMap map[string]string + if info.IsPreview { + info.Router = "填充router" + info.FuncName = "填充funcName" + info.Method = "填充method" + info.Description = "填充description" + tempMap, err = autoCodeTemplateService.GetApiAndServer(info) + } else { + err = autoCodeTemplateService.AddFunc(info) + } if err != nil { global.GVA_LOG.Error(global.Translate("sys_auto_code.injectFail"), zap.Error(err)) response.FailWithMessage(global.Translate("sys_auto_code.injectFail"), c) } else { + if info.IsPreview { + response.OkWithDetailed(tempMap, global.Translate("sys_auto_code.injectSuccess"), c) + return + } response.OkWithMessage(global.Translate("sys_auto_code.injectSuccess"), c) } } diff --git a/server/config/config.go b/server/config/config.go index 24f3fffee..9eabe9f79 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -26,6 +26,7 @@ type Server struct { TencentCOS TencentCOS `mapstructure:"tencent-cos" json:"tencent-cos" yaml:"tencent-cos"` AwsS3 AwsS3 `mapstructure:"aws-s3" json:"aws-s3" yaml:"aws-s3"` CloudflareR2 CloudflareR2 `mapstructure:"cloudflare-r2" json:"cloudflare-r2" yaml:"cloudflare-r2"` + Minio Minio `mapstructure:"minio" json:"minio" yaml:"minio"` Excel Excel `mapstructure:"excel" json:"excel" yaml:"excel"` diff --git a/server/config/oss_minio.go b/server/config/oss_minio.go new file mode 100644 index 000000000..a0faac74a --- /dev/null +++ b/server/config/oss_minio.go @@ -0,0 +1,11 @@ +package config + +type Minio struct { + Endpoint string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint"` + AccessKeyId string `mapstructure:"access-key-id" json:"access-key-id" yaml:"access-key-id"` + AccessKeySecret string `mapstructure:"access-key-secret" json:"access-key-secret" yaml:"access-key-secret"` + BucketName string `mapstructure:"bucket-name" json:"bucket-name" yaml:"bucket-name"` + UseSSL bool `mapstructure:"use-ssl" json:"use-ssl" yaml:"use-ssl"` + BasePath string `mapstructure:"base-path" json:"base-path" yaml:"base-path"` + BucketUrl string `mapstructure:"bucket-url" json:"bucket-url" yaml:"bucket-url"` +} diff --git a/server/core/server.go b/server/core/server.go index 7d8288d0b..f1d644292 100644 --- a/server/core/server.go +++ b/server/core/server.go @@ -40,7 +40,7 @@ func RunWindowsServer() { fmt.Printf(` %s gin-vue-admin - %s: v2.7.6 + %s: v2.7.7 %s %s: https://github.com/flipped-aurora/gin-vue-admin %s: https://plugin.gin-vue-admin.com diff --git a/server/docs/docs.go b/server/docs/docs.go index 09c1dc1db..caf962a6b 100644 --- a/server/docs/docs.go +++ b/server/docs/docs.go @@ -8087,7 +8087,7 @@ const docTemplate = `{ // SwaggerInfo holds exported Swagger Info so clients can modify it var SwaggerInfo = &swag.Spec{ - Version: "v2.7.6", + Version: "v2.7.7", Host: "", BasePath: "", Schemes: []string{}, diff --git a/server/docs/swagger.json b/server/docs/swagger.json index 4cbbd6002..80aa541c9 100644 --- a/server/docs/swagger.json +++ b/server/docs/swagger.json @@ -4,7 +4,7 @@ "description": "使用gin+vue进行极速开发的全栈开发基础平台", "title": "Gin-Vue-Admin Swagger API接口文档", "contact": {}, - "version": "v2.7.6" + "version": "v2.7.7" }, "paths": { "/api/createApi": { diff --git a/server/docs/swagger.yaml b/server/docs/swagger.yaml index 2a75c7df1..430abdb26 100644 --- a/server/docs/swagger.yaml +++ b/server/docs/swagger.yaml @@ -1634,7 +1634,7 @@ info: contact: {} description: 使用gin+vue进行极速开发的全栈开发基础平台 title: Gin-Vue-Admin Swagger API接口文档 - version: v2.7.6 + version: v2.7.7 paths: /api/createApi: post: diff --git a/server/go.mod b/server/go.mod index 210c210af..3f1ccd045 100644 --- a/server/go.mod +++ b/server/go.mod @@ -21,6 +21,7 @@ require ( github.com/huaweicloud/huaweicloud-sdk-go-obs v3.24.9+incompatible github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible github.com/mholt/archiver/v4 v4.0.0-alpha.8 + github.com/minio/minio-go/v7 v7.0.78 github.com/mojocn/base64Captcha v1.3.6 github.com/nicksnyder/go-i18n/v2 v2.2.0 github.com/otiai10/copy v1.14.0 @@ -81,6 +82,7 @@ require ( github.com/gammazero/toposort v0.1.1 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/glebarez/go-sqlite v1.22.0 // indirect + github.com/go-ini/ini v1.67.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect @@ -118,6 +120,7 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/microsoft/go-mssqldb v1.7.2 // indirect + github.com/minio/md5-simd v1.1.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -134,6 +137,7 @@ require ( github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/richardlehane/mscfb v1.0.4 // indirect github.com/richardlehane/msoleps v1.0.4 // indirect + github.com/rs/xid v1.6.0 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect diff --git a/server/go.sum b/server/go.sum index 03df950b6..f6bada71e 100644 --- a/server/go.sum +++ b/server/go.sum @@ -42,7 +42,6 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0/go.mod h1:wP83 github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 h1:DzHpqpoJVaCgOUdVHxE8QB52S6NiVdDQvGlny1qvPqA= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= @@ -140,6 +139,8 @@ github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GM github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= +github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= @@ -292,6 +293,7 @@ github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -332,6 +334,10 @@ github.com/mholt/archiver/v4 v4.0.0-alpha.8/go.mod h1:5f7FUYGXdJWUjESffJaYR4R60V github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU= github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA= github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA= +github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= +github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= +github.com/minio/minio-go/v7 v7.0.78 h1:LqW2zy52fxnI4gg8C2oZviTaKHcBV36scS+RzJnxUFs= +github.com/minio/minio-go/v7 v7.0.78/go.mod h1:84gmIilaX4zcvAWWzJ5Z1WI5axN+hAbM5w25xf8xvC0= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -406,6 +412,8 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= diff --git a/server/main.go b/server/main.go index 0b89ddb3c..2bfab92f4 100644 --- a/server/main.go +++ b/server/main.go @@ -15,7 +15,7 @@ import ( //go:generate go mod download // @title Gin-Vue-Admin Swagger API接口文档 -// @version v2.7.6 +// @version v2.7.7 // @description 使用gin+vue进行极速开发的全栈开发基础平台 // @securityDefinitions.apikey ApiKeyAuth // @in header diff --git a/server/model/system/request/sys_auto_code.go b/server/model/system/request/sys_auto_code.go index 3b2e5b45d..44de979b2 100644 --- a/server/model/system/request/sys_auto_code.go +++ b/server/model/system/request/sys_auto_code.go @@ -3,6 +3,7 @@ package request import ( "encoding/json" "fmt" + "github.com/flipped-aurora/gin-vue-admin/server/global" model "github.com/flipped-aurora/gin-vue-admin/server/model/system" "github.com/pkg/errors" "go/token" @@ -26,7 +27,9 @@ type AutoCode struct { AutoCreateMenuToSql bool `json:"autoCreateMenuToSql" example:"false"` // 是否自动创建menu AutoCreateBtnAuth bool `json:"autoCreateBtnAuth" example:"false"` // 是否自动创建按钮权限 OnlyTemplate bool `json:"onlyTemplate" example:"false"` // 是否只生成模板 + IsAdd bool `json:"isAdd" example:"false"` // 是否新增 Fields []*AutoCodeField `json:"fields"` + Module string `json:"-"` DictTypes []string `json:"-"` PrimaryField *AutoCodeField `json:"primaryField"` DataSourceMap map[string]*DataSource `json:"-"` @@ -43,11 +46,12 @@ type AutoCode struct { } type DataSource struct { - DBName string `json:"dbName"` - Table string `json:"table"` - Label string `json:"label"` - Value string `json:"value"` - Association int `json:"association"` // 关联关系 1 一对一 2 一对多 + DBName string `json:"dbName"` + Table string `json:"table"` + Label string `json:"label"` + Value string `json:"value"` + Association int `json:"association"` // 关联关系 1 一对一 2 一对多 + HasDeletedAt bool `json:"hasDeletedAt"` } func (r *AutoCode) Apis() []model.SysApi { @@ -110,6 +114,7 @@ func (r *AutoCode) Menu(template string) model.SysBaseMenu { // Pretreatment 预处理 // Author [SliverHorn](https://github.com/SliverHorn) func (r *AutoCode) Pretreatment() error { + r.Module = global.GVA_CONFIG.AutoCode.Module if token.IsKeyword(r.Abbreviation) { r.Abbreviation = r.Abbreviation + "_" } // go 关键字处理 @@ -182,6 +187,11 @@ func (r *AutoCode) Pretreatment() error { } } } // GvaModel + { + if r.IsAdd && r.PrimaryField == nil { + r.PrimaryField = new(AutoCodeField) + } + } // 新增字段模式下不关注主键 if r.Package == "" { return errors.New("Package为空!") } // 增加判断:Package不为空 @@ -248,6 +258,11 @@ type AutoFunc struct { Method string `json:"method"` // 方法 IsPlugin bool `json:"isPlugin"` // 是否插件 IsAuth bool `json:"isAuth"` // 是否鉴权 + IsPreview bool `json:"isPreview"` // 是否预览 + IsAi bool `json:"isAi"` // 是否AI + ApiFunc string `json:"apiFunc"` // API方法 + ServerFunc string `json:"serverFunc"` // 服务方法 + JsFunc string `json:"jsFunc"` // JS方法 } type InitMenu struct { diff --git a/server/model/system/request/sys_auto_code_package.go b/server/model/system/request/sys_auto_code_package.go index 8494cb178..679303a56 100644 --- a/server/model/system/request/sys_auto_code_package.go +++ b/server/model/system/request/sys_auto_code_package.go @@ -1,6 +1,7 @@ package request import ( + "github.com/flipped-aurora/gin-vue-admin/server/global" model "github.com/flipped-aurora/gin-vue-admin/server/model/system" ) @@ -9,11 +10,13 @@ type SysAutoCodePackageCreate struct { Label string `json:"label" example:"展示名"` Template string `json:"template" example:"模版"` PackageName string `json:"packageName" example:"包名"` + Module string `json:"-" example:"模块"` } func (r *SysAutoCodePackageCreate) AutoCode() AutoCode { return AutoCode{ Package: r.PackageName, + Module: global.GVA_CONFIG.AutoCode.Module, } } @@ -23,5 +26,6 @@ func (r *SysAutoCodePackageCreate) Create() model.SysAutoCodePackage { Label: r.Label, Template: r.Template, PackageName: r.PackageName, + Module: global.GVA_CONFIG.AutoCode.Module, } } diff --git a/server/model/system/sys_auto_code_package.go b/server/model/system/sys_auto_code_package.go index e87e88538..4099192f6 100644 --- a/server/model/system/sys_auto_code_package.go +++ b/server/model/system/sys_auto_code_package.go @@ -10,6 +10,7 @@ type SysAutoCodePackage struct { Label string `json:"label" gorm:"comment:展示名"` Template string `json:"template" gorm:"comment:模版"` PackageName string `json:"packageName" gorm:"comment:包名"` + Module string `json:"-" example:"模块"` } func (s *SysAutoCodePackage) TableName() string { diff --git a/server/resource/lang/ar.json b/server/resource/lang/ar.json index 4c0d5ea49..3d7935ab9 100644 --- a/server/resource/lang/ar.json +++ b/server/resource/lang/ar.json @@ -308,7 +308,13 @@ "updateRole": "تحديث معلومات الدور", "userLoginRequired": "تسجيل دخول المستخدم (مطلوب)", "userRegistration": "تسجيل المستخدم", - "tableDataInitFail": "فشل في تهيئة بيانات الجدول" + "tableDataInitFail": "فشل في تهيئة بيانات الجدول", + "newParameter": "براميتر جديد", + "deleteParameter": "حذف براميتر", + "batchDeleteParameters": "حذف مجموعة براميترات", + "updateParameters": "تحديث البراميترات", + "getParametersById": "الحصول على البراميتر بال ID", + "getParametersList": "الحصول على قائمة البراميترات" }, "group": { "announcement": "الإعلان", @@ -330,7 +336,8 @@ "systemService": "خدمات النظام", "systemUser": "مستخدم النظام", "tableTemplate": "قالب الجدول", - "templateConfiguration": "تكوين القالب" + "templateConfiguration": "تكوين القالب", + "parameterManagement": "إدارة البراميترات" } }, "authority": { @@ -391,7 +398,8 @@ "website": "الموقع الرسمي", "buttonKey": "مفتاح الزر", "buttonComment": "تعليق الزر", - "menuID": "معرف القائمة" + "menuID": "معرف القائمة", + "parameterManagement" : "إدارة البراميترات" } }, "announcement": { diff --git a/server/resource/lang/en.json b/server/resource/lang/en.json index c060cd037..e2db925b3 100644 --- a/server/resource/lang/en.json +++ b/server/resource/lang/en.json @@ -315,7 +315,13 @@ "updateRole": "Update Role", "userLoginRequired": "User login (required)", "userRegistration": "User registration", - "tableDataInitFail": "Table data initialization failed" + "tableDataInitFail": "Table data initialization failed", + "newParameter": "New Parameter", + "deleteParameter": "Delete Parameter", + "batchDeleteParameters": "Batch Delete Parameters", + "updateParameters": "Update Parameters", + "getParametersById": "Get Parameters By ID", + "getParametersList": "Get Parameters List" }, "group": { "announcement": "Announcement", @@ -337,7 +343,8 @@ "systemService": "System Service", "systemUser": "System User", "tableTemplate": "Table Templates", - "templateConfiguration": "Template Configuration" + "templateConfiguration": "Template Configuration", + "parameterManagement": "Parameter Management" } }, "authority": { @@ -399,7 +406,8 @@ "website": "Official Website", "buttonKey": "Button Key", "buttonComment": "Button Comment", - "menuID": "Menu ID" + "menuID": "Menu ID", + "parameterManagement" : "Parameter Management" } }, "announcement": { diff --git a/server/resource/lang/zh-TW.json b/server/resource/lang/zh-TW.json index 8df56f6d8..de2f72a9e 100644 --- a/server/resource/lang/zh-TW.json +++ b/server/resource/lang/zh-TW.json @@ -339,7 +339,14 @@ "systemService": "系統服務", "systemUser": "系統用戶", "tableTemplate": "表格模板", - "templateConfiguration": "模板配置" + "templateConfiguration": "模板配置", + "parameterManagement": "參數管理", + "newParameter": "新參數", + "deleteParameter": "刪除參數", + "batchDeleteParameters": "批量刪除參數", + "updateParameters": "更新參數", + "getParametersById": "根據ID獲取參數", + "getParametersList": "取得參數列表" } }, "authority": { @@ -401,7 +408,8 @@ "website": "官方網站", "buttonKey": "按鈕關鍵key", "buttonComment": "按鈕備註", - "menuID": "菜單ID" + "menuID": "菜單ID", + "parameterManagement" : "參數管理" } }, "announcement": { diff --git a/server/resource/lang/zh.json b/server/resource/lang/zh.json index b1953ef62..f6180ec91 100644 --- a/server/resource/lang/zh.json +++ b/server/resource/lang/zh.json @@ -319,7 +319,13 @@ "updateRole": "更新角色信息", "userLoginRequired": "用户登录(必选)", "userRegistration": "用户注册", - "tableDataInitFail": "表数据初始化失败" + "tableDataInitFail": "表数据初始化失败", + "newParameter": "新建参数", + "deleteParameter": "删除参数", + "batchDeleteParameters": "批量删除参数", + "updateParameters": "更新参数", + "getParametersById": "根据ID获取参数", + "getParametersList": "获取参数列表" }, "group": { "announcement": "公告", @@ -341,7 +347,8 @@ "systemService": "系统服务", "systemUser": "系统用户", "tableTemplate": "表格模板", - "templateConfiguration": "模板配置" + "templateConfiguration": "模板配置", + "parameterManagement": "参数管理" } }, "authority": { @@ -403,7 +410,8 @@ "website": "官方网站", "buttonKey": "按钮关键key", "buttonComment": "按钮备注", - "menuID": "菜单ID" + "menuID": "菜单ID", + "parameterManagement" : "参数管理" } }, "announcement": { diff --git a/server/resource/package/server/api/api.go.tpl b/server/resource/package/server/api/api.go.tpl index d72f250eb..42ae67a0d 100644 --- a/server/resource/package/server/api/api.go.tpl +++ b/server/resource/package/server/api/api.go.tpl @@ -2,17 +2,17 @@ package {{.Package}} import ( {{if not .OnlyTemplate}} - "github.com/flipped-aurora/gin-vue-admin/server/global" - "github.com/flipped-aurora/gin-vue-admin/server/model/common/response" - "github.com/flipped-aurora/gin-vue-admin/server/model/{{.Package}}" - {{.Package}}Req "github.com/flipped-aurora/gin-vue-admin/server/model/{{.Package}}/request" + "{{.Module}}/global" + "{{.Module}}/model/common/response" + "{{.Module}}/model/{{.Package}}" + {{.Package}}Req "{{.Module}}/model/{{.Package}}/request" "github.com/gin-gonic/gin" "go.uber.org/zap" {{- if .AutoCreateResource}} - "github.com/flipped-aurora/gin-vue-admin/server/utils" + "{{.Module}}/utils" {{- end }} {{- else}} - "github.com/flipped-aurora/gin-vue-admin/server/model/common/response" + "{{.Module}}/model/common/response" "github.com/gin-gonic/gin" {{- end}} ) diff --git a/server/resource/package/server/model/model.go.tpl b/server/resource/package/server/model/model.go.tpl index 138456796..f1f979c59 100644 --- a/server/resource/package/server/model/model.go.tpl +++ b/server/resource/package/server/model/model.go.tpl @@ -1,10 +1,35 @@ +{{- if .IsAdd}} +// 在结构体中新增如下字段 +{{- range .Fields}} +{{- if eq .FieldType "enum" }} +{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};type:enum({{.DataTypeLong}});comment:{{.Comment}};" {{- if .Require }} binding:"required"{{- end -}}` +{{- else if eq .FieldType "picture" }} +{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` +{{- else if eq .FieldType "video" }} +{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` +{{- else if eq .FieldType "file" }} +{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"` +{{- else if eq .FieldType "pictures" }} +{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"` +{{- else if eq .FieldType "richtext" }} +{{.FieldName}} *string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}}` +{{- else if eq .FieldType "json" }} +{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"object"` +{{- else if eq .FieldType "array" }} +{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"` +{{- else }} +{{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` +{{- end }} {{ if .FieldDesc }}//{{.FieldDesc}} {{ end }} +{{- end }} + +{{ else }} // 自动生成模板{{.StructName}} package {{.Package}} {{- if not .OnlyTemplate}} import ( {{- if .GvaModel }} - "github.com/flipped-aurora/gin-vue-admin/server/global" + "{{.Module}}/global" {{- end }} {{- if or .HasTimer }} "time" @@ -33,15 +58,13 @@ type {{.StructName}} struct { {{- else if eq .FieldType "pictures" }} {{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"` {{- else if eq .FieldType "richtext" }} - {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}}` + {{.FieldName}} *string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}}` {{- else if eq .FieldType "json" }} {{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"object"` {{- else if eq .FieldType "array" }} {{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"` - {{- else if ne .FieldType "string" }} - {{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` {{- else }} - {{.FieldName}} {{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` + {{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` {{- end }} {{ if .FieldDesc }}//{{.FieldDesc}} {{ end }} {{- end }} {{- if .AutoCreateResource }} @@ -57,4 +80,7 @@ type {{.StructName}} struct { func ({{.StructName}}) TableName() string { return "{{.TableName}}" } +{{ end }} + + {{ end }} \ No newline at end of file diff --git a/server/resource/package/server/model/request/request.go.tpl b/server/resource/package/server/model/request/request.go.tpl index e97a0fd7a..ee5816da3 100644 --- a/server/resource/package/server/model/request/request.go.tpl +++ b/server/resource/package/server/model/request/request.go.tpl @@ -1,8 +1,29 @@ +{{- if .IsAdd}} +// 在结构体中新增如下字段 +{{- range .Fields}} + {{- if ne .FieldSearchType ""}} + {{- if eq .FieldSearchType "BETWEEN" "NOT BETWEEN"}} +Start{{.FieldName}} *{{.FieldType}} `json:"start{{.FieldName}}" form:"start{{.FieldName}}"` +End{{.FieldName}} *{{.FieldType}} `json:"end{{.FieldName}}" form:"end{{.FieldName}}"` + {{- else }} + {{- if or (eq .FieldType "enum") (eq .FieldType "picture") (eq .FieldType "pictures") (eq .FieldType "video") (eq .FieldType "json") }} +{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` + {{- else }} +{{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` + {{- end }} + {{- end }} + {{- end}} +{{- end }} +{{- if .NeedSort}} +Sort string `json:"sort" form:"sort"` +Order string `json:"order" form:"order"` +{{- end}} +{{- else }} package request import ( {{- if not .OnlyTemplate }} - "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" + "{{.Module}}/model/common/request" {{ if or .HasSearchTimer .GvaModel}}"time"{{ end }} {{- end }} ) @@ -19,12 +40,10 @@ type {{.StructName}}Search struct{ Start{{.FieldName}} *{{.FieldType}} `json:"start{{.FieldName}}" form:"start{{.FieldName}}"` End{{.FieldName}} *{{.FieldType}} `json:"end{{.FieldName}}" form:"end{{.FieldName}}"` {{- else }} - {{- if or (eq .FieldType "enum") (eq .FieldType "picture") (eq .FieldType "pictures") (eq .FieldType "video") (eq .FieldType "richtext") (eq .FieldType "json") }} + {{- if or (eq .FieldType "enum") (eq .FieldType "picture") (eq .FieldType "pictures") (eq .FieldType "video") (eq .FieldType "json") }} {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` - {{- else if ne .FieldType "string" }} - {{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` {{- else }} - {{.FieldName}} {{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` + {{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` {{- end }} {{- end }} {{- end}} @@ -36,3 +55,4 @@ type {{.StructName}}Search struct{ {{- end}} {{- end}} } +{{- end }} diff --git a/server/resource/package/server/router/router.go.tpl b/server/resource/package/server/router/router.go.tpl index 9a4ba9de0..cac47ab78 100644 --- a/server/resource/package/server/router/router.go.tpl +++ b/server/resource/package/server/router/router.go.tpl @@ -1,7 +1,7 @@ package {{.Package}} import ( - {{if .OnlyTemplate}}// {{ end}}"github.com/flipped-aurora/gin-vue-admin/server/middleware" + {{if .OnlyTemplate}}// {{ end}}"{{.Module}}/middleware" "github.com/gin-gonic/gin" ) diff --git a/server/resource/package/server/service/service.go.tpl b/server/resource/package/server/service/service.go.tpl index 1c44daf87..29c5864cb 100644 --- a/server/resource/package/server/service/service.go.tpl +++ b/server/resource/package/server/service/service.go.tpl @@ -1,10 +1,66 @@ +{{- $db := "" }} +{{- if eq .BusinessDB "" }} + {{- $db = "global.GVA_DB" }} +{{- else}} + {{- $db = printf "global.MustGetGlobalDBByDBName(\"%s\")" .BusinessDB }} +{{- end}} + +{{- if .IsAdd}} + +// Get{{.StructName}}InfoList 新增搜索语句 + {{- range .Fields}} + {{- if .FieldSearchType}} + {{- if or (eq .FieldType "enum") (eq .FieldType "pictures") (eq .FieldType "picture") (eq .FieldType "video") (eq .FieldType "json") }} +if info.{{.FieldName}} != "" { + {{- if or (eq .FieldType "enum") }} + db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+ {{ end }}*info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) + {{- else}} +// 数据类型为复杂类型,请根据业务需求自行实现复杂类型的查询业务 + {{- end}} +} + {{- else if eq .FieldSearchType "BETWEEN" "NOT BETWEEN"}} +if info.Start{{.FieldName}} != nil && info.End{{.FieldName}} != nil { + db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ? AND ? ",info.Start{{.FieldName}},info.End{{.FieldName}}) +} + {{- else}} +if info.{{.FieldName}} != nil { + db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+{{ end }}*info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) +} + {{- end }} + {{- end }} + {{- end }} + + +// Get{{.StructName}}InfoList 新增排序语句 请自行在搜索语句中添加orderMap内容 + {{- range .Fields}} + {{- if .Sort}} +orderMap["{{.ColumnName}}"] = true + {{- end}} + {{- end}} + + +{{- if .HasDataSource }} +// Get{{.StructName}}DataSource()方法新增关联语句 + {{range $key, $value := .DataSourceMap}} +{{$key}} := make([]map[string]any, 0) +{{ $dataDB := "" }} +{{- if eq $value.DBName "" }} +{{ $dataDB = $db }} +{{- else}} +{{ $dataDB = printf "global.MustGetGlobalDBByDBName(\"%s\")" $value.DBName }} +{{- end}} +{{$dataDB}}.Table("{{$value.Table}}"){{- if $value.HasDeletedAt}}.Where("deleted_at IS NULL"){{ end }}.Select("{{$value.Label}} as label,{{$value.Value}} as value").Scan(&{{$key}}) +res["{{$key}}"] = {{$key}} + {{- end }} +{{- end }} +{{- else}} package {{.Package}} import ( {{- if not .OnlyTemplate }} - "github.com/flipped-aurora/gin-vue-admin/server/global" - "github.com/flipped-aurora/gin-vue-admin/server/model/{{.Package}}" - {{.Package}}Req "github.com/flipped-aurora/gin-vue-admin/server/model/{{.Package}}/request" + "{{.Module}}/global" + "{{.Module}}/model/{{.Package}}" + {{.Package}}Req "{{.Module}}/model/{{.Package}}/request" {{- if .AutoCreateResource }} "gorm.io/gorm" {{- end}} @@ -13,13 +69,6 @@ import ( type {{.StructName}}Service struct {} -{{- $db := "" }} -{{- if eq .BusinessDB "" }} - {{- $db = "global.GVA_DB" }} -{{- else}} - {{- $db = printf "global.MustGetGlobalDBByDBName(\"%s\")" .BusinessDB }} -{{- end}} - {{- if not .OnlyTemplate }} // Create{{.StructName}} 创建{{.Description}}记录 // Author [yourname](https://github.com/yourname) @@ -96,10 +145,10 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}InfoLis {{- end }} {{- range .Fields}} {{- if .FieldSearchType}} - {{- if or (eq .FieldType "string") (eq .FieldType "enum") (eq .FieldType "pictures") (eq .FieldType "picture") (eq .FieldType "video") (eq .FieldType "richtext") (eq .FieldType "json") }} + {{- if or (eq .FieldType "enum") (eq .FieldType "pictures") (eq .FieldType "picture") (eq .FieldType "video") (eq .FieldType "json") }} if info.{{.FieldName}} != "" { - {{- if or (eq .FieldType "enum") (eq .FieldType "string") }} - db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+ {{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) + {{- if or (eq .FieldType "enum")}} + db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+ {{ end }}*info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) {{- else}} // 数据类型为复杂类型,请根据业务需求自行实现复杂类型的查询业务 {{- end}} @@ -110,7 +159,7 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}InfoLis } {{- else}} if info.{{.FieldName}} != nil { - db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+{{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) + db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+{{ end }}*info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) } {{- end }} {{- end }} @@ -155,7 +204,7 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}DataSou {{- else}} {{ $dataDB = printf "global.MustGetGlobalDBByDBName(\"%s\")" $value.DBName }} {{- end}} - {{$dataDB}}.Table("{{$value.Table}}").Select("{{$value.Label}} as label,{{$value.Value}} as value").Scan(&{{$key}}) + {{$dataDB}}.Table("{{$value.Table}}"){{- if $value.HasDeletedAt}}.Where("deleted_at IS NULL"){{ end }}.Select("{{$value.Label}} as label,{{$value.Value}} as value").Scan(&{{$key}}) res["{{$key}}"] = {{$key}} {{- end }} return @@ -166,3 +215,4 @@ func ({{.Abbreviation}}Service *{{.StructName}}Service)Get{{.StructName}}Public( // 此方法为获取数据源定义的数据 // 请自行实现 } +{{- end }} \ No newline at end of file diff --git a/server/resource/package/web/view/form.vue.tpl b/server/resource/package/web/view/form.vue.tpl index 8269af454..af023eee9 100644 --- a/server/resource/package/web/view/form.vue.tpl +++ b/server/resource/package/web/view/form.vue.tpl @@ -1,4 +1,165 @@ -{{- $top := . -}} +{{- if .IsAdd }} +// 新增表单中增加如下代码 +{{- range .Fields}} + {{- if .Form}} + + {{- if .CheckDataSource}} + + + + {{- else }} + {{- if eq .FieldType "bool" }} + + {{- end }} + {{- if eq .FieldType "string" }} + {{- if .DictType}} + + + + {{- else }} + + {{- end }} + {{- end }} + {{- if eq .FieldType "richtext" }} + + {{- end }} + {{- if eq .FieldType "json" }} + // 此字段为json结构,可以前端自行控制展示和数据绑定模式 需绑定json的key为 formData.{{.FieldJson}} 后端会按照json的类型进行存取 + {{"{{"}} formData.{{.FieldJson}} {{"}}"}} + {{- end }} + {{- if eq .FieldType "array" }} + + {{- end }} + {{- if eq .FieldType "int" }} + + {{- end }} + {{- if eq .FieldType "time.Time" }} + + {{- end }} + {{- if eq .FieldType "float64" }} + + {{- end }} + {{- if eq .FieldType "enum" }} + + + + {{- end }} + {{- if eq .FieldType "picture" }} + + {{- end }} + {{- if eq .FieldType "pictures" }} + + {{- end }} + {{- if eq .FieldType "video" }} + + {{- end }} + {{- if eq .FieldType "file" }} + + {{- end }} + {{- end }} + + {{- end }} + {{- end }} + +// 字典增加如下代码 + {{- range $index, $element := .DictTypes}} +const {{ $element }}Options = ref([]) + {{- end }} + +// init方法中增加如下调用 + +{{- range $index, $element := .DictTypes }} + {{ $element }}Options.value = await getDictFunc('{{$element}}') +{{- end }} + +// 基础formData结构增加如下字段 +{{- range .Fields}} + {{- if .Form}} + {{- if eq .FieldType "bool" }} +{{.FieldJson}}: false, + {{- end }} + {{- if eq .FieldType "string" }} +{{.FieldJson}}: '', + {{- end }} + {{- if eq .FieldType "richtext" }} +{{.FieldJson}}: '', + {{- end }} + {{- if eq .FieldType "int" }} +{{.FieldJson}}: {{- if or .DictType .DataSource}} undefined{{ else }} 0{{- end }}, + {{- end }} + {{- if eq .FieldType "time.Time" }} +{{.FieldJson}}: new Date(), + {{- end }} + {{- if eq .FieldType "float64" }} +{{.FieldJson}}: 0, + {{- end }} + {{- if eq .FieldType "picture" }} +{{.FieldJson}}: "", + {{- end }} + {{- if eq .FieldType "video" }} +{{.FieldJson}}: "", + {{- end }} + {{- if eq .FieldType "pictures" }} +{{.FieldJson}}: [], + {{- end }} + {{- if eq .FieldType "file" }} +{{.FieldJson}}: [], + {{- end }} + {{- if eq .FieldType "json" }} +{{.FieldJson}}: {}, + {{- end }} + {{- if eq .FieldType "array" }} +{{.FieldJson}}: [], + {{- end }} + {{- end }} + {{- end }} +// 验证规则中增加如下字段 + +{{- range .Fields }} + {{- if .Form }} + {{- if eq .Require true }} +{{.FieldJson }} : [{ + required: true, + message: '{{ .ErrorText }}', + trigger: ['input','blur'], +}, + {{- if eq .FieldType "string" }} +{ + whitespace: true, + message: '不能只输入空格', + trigger: ['input', 'blur'], +} + {{- end }} +], + {{- end }} + {{- end }} + {{- end }} + +{{- if .HasDataSource }} +// 请引用 +get{{.StructName}}DataSource, + +// 获取数据源 +const dataSource = ref([]) +const getDataSourceFunc = async()=>{ + const res = await get{{.StructName}}DataSource() + if (res.code === 0) { + dataSource.value = res.data + } +} +getDataSourceFunc() +{{- end }} +{{- else }} {{- if not .OnlyTemplate }} — - + {{- else}} {{- end}} {{- else}} {{- end}} - {{ end }}{{ end }}{{ end }}{{ end }} — - + {{- else}} {{- end}} @@ -368,7 +723,7 @@ - + {{- range .Fields}} {{- if .Desc }} @@ -909,4 +1264,10 @@ defineOptions({ +<<<<<<< HEAD {{- end}} +======= +{{- end }} + +{{- end }} +>>>>>>> main diff --git a/server/resource/plugin/server/api/api.go.template b/server/resource/plugin/server/api/api.go.template index 03321c74f..edf465180 100644 --- a/server/resource/plugin/server/api/api.go.template +++ b/server/resource/plugin/server/api/api.go.template @@ -2,17 +2,17 @@ package api import ( {{if not .OnlyTemplate}} - "github.com/flipped-aurora/gin-vue-admin/server/global" - "github.com/flipped-aurora/gin-vue-admin/server/model/common/response" - "github.com/flipped-aurora/gin-vue-admin/server/plugin/{{.Package}}/model" - "github.com/flipped-aurora/gin-vue-admin/server/plugin/{{.Package}}/model/request" + "{{.Module}}/global" + "{{.Module}}/model/common/response" + "{{.Module}}/plugin/{{.Package}}/model" + "{{.Module}}/plugin/{{.Package}}/model/request" "github.com/gin-gonic/gin" "go.uber.org/zap" {{- if .AutoCreateResource}} - "github.com/flipped-aurora/gin-vue-admin/server/utils" + "{{.Module}}/utils" {{- end }} {{- else }} - "github.com/flipped-aurora/gin-vue-admin/server/model/common/response" + "{{.Module}}/model/common/response" "github.com/gin-gonic/gin" {{- end }} ) diff --git a/server/resource/plugin/server/initialize/api.go.template b/server/resource/plugin/server/initialize/api.go.template index adf5d64cf..dfbea23d9 100644 --- a/server/resource/plugin/server/initialize/api.go.template +++ b/server/resource/plugin/server/initialize/api.go.template @@ -2,8 +2,8 @@ package initialize import ( "context" - model "github.com/flipped-aurora/gin-vue-admin/server/model/system" - "github.com/flipped-aurora/gin-vue-admin/server/plugin/plugin-tool/utils" + model "{{.Module}}/model/system" + "{{.Module}}/plugin/plugin-tool/utils" ) func Api(ctx context.Context) { diff --git a/server/resource/plugin/server/initialize/gorm.go.template b/server/resource/plugin/server/initialize/gorm.go.template index 0988bccff..52c818319 100644 --- a/server/resource/plugin/server/initialize/gorm.go.template +++ b/server/resource/plugin/server/initialize/gorm.go.template @@ -3,8 +3,7 @@ package initialize import ( "context" "fmt" - "github.com/flipped-aurora/gin-vue-admin/server/global" - + "{{.Module}}/global" "github.com/pkg/errors" "go.uber.org/zap" ) diff --git a/server/resource/plugin/server/initialize/menu.go.template b/server/resource/plugin/server/initialize/menu.go.template index 06993db3d..8774f356c 100644 --- a/server/resource/plugin/server/initialize/menu.go.template +++ b/server/resource/plugin/server/initialize/menu.go.template @@ -2,8 +2,8 @@ package initialize import ( "context" - model "github.com/flipped-aurora/gin-vue-admin/server/model/system" - "github.com/flipped-aurora/gin-vue-admin/server/plugin/plugin-tool/utils" + model "{{.Module}}/model/system" + "{{.Module}}/plugin/plugin-tool/utils" ) func Menu(ctx context.Context) { diff --git a/server/resource/plugin/server/initialize/router.go.template b/server/resource/plugin/server/initialize/router.go.template index f7f8ed0fb..fbf03a3aa 100644 --- a/server/resource/plugin/server/initialize/router.go.template +++ b/server/resource/plugin/server/initialize/router.go.template @@ -1,8 +1,8 @@ package initialize import ( - "github.com/flipped-aurora/gin-vue-admin/server/global" - "github.com/flipped-aurora/gin-vue-admin/server/middleware" + "{{.Module}}/global" + "{{.Module}}/middleware" "github.com/gin-gonic/gin" ) diff --git a/server/resource/plugin/server/initialize/viper.go.template b/server/resource/plugin/server/initialize/viper.go.template index a1887ac28..e759ad637 100644 --- a/server/resource/plugin/server/initialize/viper.go.template +++ b/server/resource/plugin/server/initialize/viper.go.template @@ -2,8 +2,8 @@ package initialize import ( "fmt" - "github.com/flipped-aurora/gin-vue-admin/server/global" - "github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .Package }}/plugin" + "{{.Module}}/global" + "{{.Module}}/plugin/{{ .Package }}/plugin" "github.com/pkg/errors" "go.uber.org/zap" ) diff --git a/server/resource/plugin/server/model/model.go.template b/server/resource/plugin/server/model/model.go.template index 153ab3ba1..0f9528db3 100644 --- a/server/resource/plugin/server/model/model.go.template +++ b/server/resource/plugin/server/model/model.go.template @@ -1,9 +1,34 @@ +{{- if .IsAdd}} +// 在结构体中新增如下字段 +{{- range .Fields}} +{{- if eq .FieldType "enum" }} +{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};type:enum({{.DataTypeLong}});comment:{{.Comment}};" {{- if .Require }} binding:"required"{{- end -}}` +{{- else if eq .FieldType "picture" }} +{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` +{{- else if eq .FieldType "video" }} +{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` +{{- else if eq .FieldType "file" }} +{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"` +{{- else if eq .FieldType "pictures" }} +{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"` +{{- else if eq .FieldType "richtext" }} +{{.FieldName}} *string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}}` +{{- else if eq .FieldType "json" }} +{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"object"` +{{- else if eq .FieldType "array" }} +{{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"` +{{- else }} +{{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` +{{- end }} {{ if .FieldDesc }}//{{.FieldDesc}} {{ end }} +{{- end }} + +{{ else }} package model {{- if not .OnlyTemplate}} import ( {{- if .GvaModel }} - "github.com/flipped-aurora/gin-vue-admin/server/global" + "{{.Module}}/global" {{- end }} {{- if or .HasTimer }} "time" @@ -32,15 +57,13 @@ type {{.StructName}} struct { {{- else if eq .FieldType "pictures" }} {{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"` {{- else if eq .FieldType "richtext" }} - {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}}` + {{.FieldName}} *string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}}` {{- else if eq .FieldType "json" }} {{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"object"` {{- else if eq .FieldType "array" }} {{.FieldName}} datatypes.JSON `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}type:text;" {{- if .Require }} binding:"required"{{- end -}} swaggertype:"array,object"` - {{- else if ne .FieldType "string" }} - {{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` {{- else }} - {{.FieldName}} {{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` + {{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" gorm:"{{- if ne .FieldIndexType "" -}}{{ .FieldIndexType }};{{- end -}}{{- if .PrimaryKey -}}primarykey;{{- end -}}{{- if .DefaultValue -}}default:{{ .DefaultValue }};{{- end -}}column:{{.ColumnName}};comment:{{.Comment}};{{- if .DataTypeLong -}}size:{{.DataTypeLong}};{{- end -}}" {{- if .Require }} binding:"required"{{- end -}}` {{- end }} {{ if .FieldDesc }}//{{.FieldDesc}}{{ end }} {{- end }} {{- if .AutoCreateResource }} @@ -57,3 +80,4 @@ func ({{.StructName}}) TableName() string { return "{{.TableName}}" } {{ end }} +{{ end }} \ No newline at end of file diff --git a/server/resource/plugin/server/model/request/request.go.template b/server/resource/plugin/server/model/request/request.go.template index cf2a56944..2100a6415 100644 --- a/server/resource/plugin/server/model/request/request.go.template +++ b/server/resource/plugin/server/model/request/request.go.template @@ -1,7 +1,28 @@ +{{- if .IsAdd}} +// 在结构体中新增如下字段 +{{- range .Fields}} + {{- if ne .FieldSearchType ""}} + {{- if eq .FieldSearchType "BETWEEN" "NOT BETWEEN"}} +Start{{.FieldName}} *{{.FieldType}} `json:"start{{.FieldName}}" form:"start{{.FieldName}}"` +End{{.FieldName}} *{{.FieldType}} `json:"end{{.FieldName}}" form:"end{{.FieldName}}"` + {{- else }} + {{- if or (eq .FieldType "enum") (eq .FieldType "picture") (eq .FieldType "pictures") (eq .FieldType "video") (eq .FieldType "json") }} +{{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` + {{- else }} +{{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` + {{- end }} + {{- end }} + {{- end}} +{{- end }} +{{- if .NeedSort}} +Sort string `json:"sort" form:"sort"` +Order string `json:"order" form:"order"` +{{- end}} +{{- else }} package request {{- if not .OnlyTemplate}} import ( - "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" + "{{.Module}}/model/common/request" {{ if or .HasSearchTimer .GvaModel}}"time"{{ end }} ) {{- end}} @@ -18,12 +39,10 @@ type {{.StructName}}Search struct{ Start{{.FieldName}} *{{.FieldType}} `json:"start{{.FieldName}}" form:"start{{.FieldName}}"` End{{.FieldName}} *{{.FieldType}} `json:"end{{.FieldName}}" form:"end{{.FieldName}}"` {{- else }} - {{- if or (eq .FieldType "enum") (eq .FieldType "picture") (eq .FieldType "pictures") (eq .FieldType "video") (eq .FieldType "richtext") (eq .FieldType "json") }} + {{- if or (eq .FieldType "enum") (eq .FieldType "picture") (eq .FieldType "pictures") (eq .FieldType "video") (eq .FieldType "json") }} {{.FieldName}} string `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` - {{- else if ne .FieldType "string" }} - {{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` {{- else }} - {{.FieldName}} {{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` + {{.FieldName}} *{{.FieldType}} `json:"{{.FieldJson}}" form:"{{.FieldJson}}" ` {{- end }} {{- end }} {{- end}} @@ -33,5 +52,6 @@ type {{.StructName}}Search struct{ Sort string `json:"sort" form:"sort"` Order string `json:"order" form:"order"` {{- end}} -{{- end}} +{{- end }} } +{{- end }} \ No newline at end of file diff --git a/server/resource/plugin/server/plugin.go.template b/server/resource/plugin/server/plugin.go.template index 42c59f599..255b7af00 100644 --- a/server/resource/plugin/server/plugin.go.template +++ b/server/resource/plugin/server/plugin.go.template @@ -2,8 +2,8 @@ package {{ .Package }} import ( "context" - "github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .Package }}/initialize" - interfaces "github.com/flipped-aurora/gin-vue-admin/server/utils/plugin/v2" + "{{.Module}}/plugin/{{ .Package }}/initialize" + interfaces "{{.Module}}/utils/plugin/v2" "github.com/gin-gonic/gin" ) diff --git a/server/resource/plugin/server/plugin/plugin.go.template b/server/resource/plugin/server/plugin/plugin.go.template index 9129584bb..7e25e0700 100644 --- a/server/resource/plugin/server/plugin/plugin.go.template +++ b/server/resource/plugin/server/plugin/plugin.go.template @@ -1,5 +1,5 @@ package plugin -import "github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .Package }}/config" +import "{{.Module}}/plugin/{{ .Package }}/config" var Config config.Config diff --git a/server/resource/plugin/server/router/router.go.template b/server/resource/plugin/server/router/router.go.template index cc5cd2677..34bf4d891 100644 --- a/server/resource/plugin/server/router/router.go.template +++ b/server/resource/plugin/server/router/router.go.template @@ -1,7 +1,7 @@ package router import ( - {{if .OnlyTemplate }} // {{end}}"github.com/flipped-aurora/gin-vue-admin/server/middleware" + {{if .OnlyTemplate }} // {{end}}"{{.Module}}/middleware" "github.com/gin-gonic/gin" ) diff --git a/server/resource/plugin/server/service/service.go.template b/server/resource/plugin/server/service/service.go.template index e62426d44..1707eed25 100644 --- a/server/resource/plugin/server/service/service.go.template +++ b/server/resource/plugin/server/service/service.go.template @@ -1,10 +1,66 @@ +{{- $db := "" }} +{{- if eq .BusinessDB "" }} + {{- $db = "global.GVA_DB" }} +{{- else}} + {{- $db = printf "global.MustGetGlobalDBByDBName(\"%s\")" .BusinessDB }} +{{- end}} + +{{- if .IsAdd}} + +// Get{{.StructName}}InfoList 新增搜索语句 + {{- range .Fields}} + {{- if .FieldSearchType}} + {{- if or (eq .FieldType "enum") (eq .FieldType "pictures") (eq .FieldType "picture") (eq .FieldType "video") (eq .FieldType "json") }} +if info.{{.FieldName}} != "" { + {{- if or (eq .FieldType "enum") }} + db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+ {{ end }}*info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) + {{- else}} +// 数据类型为复杂类型,请根据业务需求自行实现复杂类型的查询业务 + {{- end}} +} + {{- else if eq .FieldSearchType "BETWEEN" "NOT BETWEEN"}} +if info.Start{{.FieldName}} != nil && info.End{{.FieldName}} != nil { + db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ? AND ? ",info.Start{{.FieldName}},info.End{{.FieldName}}) +} + {{- else}} +if info.{{.FieldName}} != nil { + db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+{{ end }}*info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) +} + {{- end }} + {{- end }} + {{- end }} + + +// Get{{.StructName}}InfoList 新增排序语句 请自行在搜索语句中添加orderMap内容 + {{- range .Fields}} + {{- if .Sort}} +orderMap["{{.ColumnName}}"] = true + {{- end}} + {{- end}} + + +{{- if .HasDataSource }} +// Get{{.StructName}}DataSource()方法新增关联语句 + {{range $key, $value := .DataSourceMap}} +{{$key}} := make([]map[string]any, 0) +{{ $dataDB := "" }} +{{- if eq $value.DBName "" }} +{{ $dataDB = $db }} +{{- else}} +{{ $dataDB = printf "global.MustGetGlobalDBByDBName(\"%s\")" $value.DBName }} +{{- end}} +{{$dataDB}}.Table("{{$value.Table}}"){{- if $value.HasDeletedAt}}.Where("deleted_at IS NULL"){{ end }}.Select("{{$value.Label}} as label,{{$value.Value}} as value").Scan(&{{$key}}) +res["{{$key}}"] = {{$key}} + {{- end }} +{{- end }} +{{- else}} package service import ( {{- if not .OnlyTemplate }} - "github.com/flipped-aurora/gin-vue-admin/server/global" - "github.com/flipped-aurora/gin-vue-admin/server/plugin/{{.Package}}/model" - "github.com/flipped-aurora/gin-vue-admin/server/plugin/{{.Package}}/model/request" + "{{.Module}}/global" + "{{.Module}}/plugin/{{.Package}}/model" + "{{.Module}}/plugin/{{.Package}}/model/request" {{- if .AutoCreateResource }} "gorm.io/gorm" {{- end}} @@ -97,10 +153,10 @@ func (s *{{.Abbreviation}}) Get{{.StructName}}InfoList(info request.{{.StructNam {{- end }} {{- range .Fields}} {{- if .FieldSearchType}} - {{- if or (eq .FieldType "string") (eq .FieldType "enum") (eq .FieldType "pictures") (eq .FieldType "picture") (eq .FieldType "video") (eq .FieldType "richtext") (eq .FieldType "json") }} + {{- if or (eq .FieldType "enum") (eq .FieldType "pictures") (eq .FieldType "picture") (eq .FieldType "video") (eq .FieldType "json") }} if info.{{.FieldName}} != "" { - {{- if or (eq .FieldType "enum") (eq .FieldType "string") }} - db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+ {{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) + {{- if or (eq .FieldType "enum")}} + db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+ {{ end }}*info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) {{- else}} // 数据类型为复杂类型,请根据业务需求自行实现复杂类型的查询业务 {{- end}} @@ -111,7 +167,7 @@ func (s *{{.Abbreviation}}) Get{{.StructName}}InfoList(info request.{{.StructNam } {{- else}} if info.{{.FieldName}} != nil { - db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+{{ end }}info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) + db = db.Where("{{.ColumnName}} {{.FieldSearchType}} ?",{{if eq .FieldSearchType "LIKE"}}"%"+{{ end }}*info.{{.FieldName}}{{if eq .FieldSearchType "LIKE"}}+"%"{{ end }}) } {{- end }} {{- end }} @@ -155,7 +211,7 @@ func (s *{{.Abbreviation}})Get{{.StructName}}DataSource() (res map[string][]map[ {{- else}} {{ $dataDB = printf "global.MustGetGlobalDBByDBName(\"%s\")" $value.DBName }} {{- end}} - {{$dataDB}}.Table("{{$value.Table}}").Select("{{$value.Label}} as label,{{$value.Value}} as value").Scan(&{{$key}}) + {{$dataDB}}.Table("{{$value.Table}}"){{- if $value.HasDeletedAt}}.Where("deleted_at IS NULL"){{ end }}.Select("{{$value.Label}} as label,{{$value.Value}} as value").Scan(&{{$key}}) res["{{$key}}"] = {{$key}} {{- end }} return @@ -165,4 +221,5 @@ func (s *{{.Abbreviation}})Get{{.StructName}}DataSource() (res map[string][]map[ func (s *{{.Abbreviation}})Get{{.StructName}}Public() { -} \ No newline at end of file +} +{{- end }} \ No newline at end of file diff --git a/server/resource/plugin/web/form/form.vue.template b/server/resource/plugin/web/form/form.vue.template index f829660fd..d689061a5 100644 --- a/server/resource/plugin/web/form/form.vue.template +++ b/server/resource/plugin/web/form/form.vue.template @@ -1,4 +1,168 @@ +<<<<<<< HEAD {{- $top := . -}} +======= +{{- if .IsAdd }} +// 新增表单中增加如下代码 +{{- range .Fields}} + {{- if .Form}} + + {{- if .CheckDataSource}} + + + + {{- else }} + {{- if eq .FieldType "bool" }} + + {{- end }} + {{- if eq .FieldType "string" }} + {{- if .DictType}} + + + + {{- else }} + + {{- end }} + {{- end }} + {{- if eq .FieldType "richtext" }} + + {{- end }} + {{- if eq .FieldType "json" }} + // 此字段为json结构,可以前端自行控制展示和数据绑定模式 需绑定json的key为 formData.{{.FieldJson}} 后端会按照json的类型进行存取 + {{"{{"}} formData.{{.FieldJson}} {{"}}"}} + {{- end }} + {{- if eq .FieldType "array" }} + + {{- end }} + {{- if eq .FieldType "int" }} + + {{- end }} + {{- if eq .FieldType "time.Time" }} + + {{- end }} + {{- if eq .FieldType "float64" }} + + {{- end }} + {{- if eq .FieldType "enum" }} + + + + {{- end }} + {{- if eq .FieldType "picture" }} + + {{- end }} + {{- if eq .FieldType "pictures" }} + + {{- end }} + {{- if eq .FieldType "video" }} + + {{- end }} + {{- if eq .FieldType "file" }} + + {{- end }} + {{- end }} + + {{- end }} + {{- end }} + +// 字典增加如下代码 + {{- range $index, $element := .DictTypes}} +const {{ $element }}Options = ref([]) + {{- end }} + +// init方法中增加如下调用 + +{{- range $index, $element := .DictTypes }} + {{ $element }}Options.value = await getDictFunc('{{$element}}') +{{- end }} + +// 基础formData结构增加如下字段 +{{- range .Fields}} + {{- if .Form}} + {{- if eq .FieldType "bool" }} +{{.FieldJson}}: false, + {{- end }} + {{- if eq .FieldType "string" }} +{{.FieldJson}}: '', + {{- end }} + {{- if eq .FieldType "richtext" }} +{{.FieldJson}}: '', + {{- end }} + {{- if eq .FieldType "int" }} +{{.FieldJson}}: {{- if or .DictType .DataSource}} undefined{{ else }} 0{{- end }}, + {{- end }} + {{- if eq .FieldType "time.Time" }} +{{.FieldJson}}: new Date(), + {{- end }} + {{- if eq .FieldType "float64" }} +{{.FieldJson}}: 0, + {{- end }} + {{- if eq .FieldType "picture" }} +{{.FieldJson}}: "", + {{- end }} + {{- if eq .FieldType "video" }} +{{.FieldJson}}: "", + {{- end }} + {{- if eq .FieldType "pictures" }} +{{.FieldJson}}: [], + {{- end }} + {{- if eq .FieldType "file" }} +{{.FieldJson}}: [], + {{- end }} + {{- if eq .FieldType "json" }} +{{.FieldJson}}: {}, + {{- end }} + {{- if eq .FieldType "array" }} +{{.FieldJson}}: [], + {{- end }} + {{- end }} + {{- end }} +// 验证规则中增加如下字段 + +{{- range .Fields }} + {{- if .Form }} + {{- if eq .Require true }} +{{.FieldJson }} : [{ + required: true, + message: '{{ .ErrorText }}', + trigger: ['input','blur'], +}, + {{- if eq .FieldType "string" }} +{ + whitespace: true, + message: '不能只输入空格', + trigger: ['input', 'blur'], +} + {{- end }} +], + {{- end }} + {{- end }} + {{- end }} + +{{- if .HasDataSource }} +// 请引用 +get{{.StructName}}DataSource, +// 获取数据源 +const dataSource = ref([]) +const getDataSourceFunc = async()=>{ + const res = await get{{.StructName}}DataSource() + if (res.code === 0) { + dataSource.value = res.data + } +} +getDataSourceFunc() +{{- end }} +{{- else }} +>>>>>>> main {{- if not .OnlyTemplate}} — - + {{- else}} {{- end}} @@ -131,7 +483,7 @@ — - + {{- else}} {{- end}} @@ -368,7 +720,9 @@ - + + + {{- range .Fields}} {{- if .Desc }} @@ -913,4 +1267,5 @@ defineOptions({ -{{- end}} \ No newline at end of file +{{- end}} +{{- end}} diff --git a/server/service/system/auto_code_package.go b/server/service/system/auto_code_package.go index c5b5766e9..e814223c3 100644 --- a/server/service/system/auto_code_package.go +++ b/server/service/system/auto_code_package.go @@ -119,10 +119,99 @@ func (s *autoCodePackage) Delete(ctx context.Context, info common.GetById) error // @author: [piexlmax](https://github.com/piexlmax) // @author: [SliverHorn](https://github.com/SliverHorn) func (s *autoCodePackage) All(ctx context.Context) (entities []model.SysAutoCodePackage, err error) { + server := make([]model.SysAutoCodePackage, 0) + plugin := make([]model.SysAutoCodePackage, 0) + serverPath := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "service") + pluginPath := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "plugin") + serverDir, err := os.ReadDir(serverPath) + if err != nil { + return nil, errors.Wrap(err, "读取service文件夹失败!") + } + pluginDir, err := os.ReadDir(pluginPath) + if err != nil { + return nil, errors.Wrap(err, "读取plugin文件夹失败!") + } + for i := 0; i < len(serverDir); i++ { + if serverDir[i].IsDir() { + serverPackage := model.SysAutoCodePackage{ + PackageName: serverDir[i].Name(), + Template: "package", + Label: serverDir[i].Name() + "包", + Desc: "系统自动读取" + serverDir[i].Name() + "包", + Module: global.GVA_CONFIG.AutoCode.Module, + } + server = append(server, serverPackage) + } + } + for i := 0; i < len(pluginDir); i++ { + if pluginDir[i].IsDir() { + dirNameMap := map[string]bool{ + "api": true, + "config": true, + "initialize": true, + "model": true, + "plugin": true, + "router": true, + "service": true, + } + dir, e := os.ReadDir(filepath.Join(pluginPath, pluginDir[i].Name())) + if e != nil { + return nil, errors.Wrap(err, "读取plugin文件夹失败!") + } + //dir目录需要包含所有的dirNameMap + for k := 0; k < len(dir); k++ { + if dir[k].IsDir() { + if _, ok := dirNameMap[dir[k].Name()]; ok { + delete(dirNameMap, dir[k].Name()) + } + } + } + if len(dirNameMap) != 0 { + continue + } + pluginPackage := model.SysAutoCodePackage{ + PackageName: pluginDir[i].Name(), + Template: "plugin", + Label: pluginDir[i].Name() + "插件", + Desc: "系统自动读取" + pluginDir[i].Name() + "插件,使用前请确认是否为v2版本插件", + Module: global.GVA_CONFIG.AutoCode.Module, + } + plugin = append(plugin, pluginPackage) + } + } + err = global.GVA_DB.WithContext(ctx).Find(&entities).Error if err != nil { return nil, errors.Wrap(err, global.Translate("service.failedToGetAllPackages")) } + entitiesMap := make(map[string]model.SysAutoCodePackage) + for i := 0; i < len(entities); i++ { + entitiesMap[entities[i].PackageName] = entities[i] + } + createEntity := []model.SysAutoCodePackage{} + for i := 0; i < len(server); i++ { + if _, ok := entitiesMap[server[i].PackageName]; !ok { + if server[i].Template == "package" { + createEntity = append(createEntity, server[i]) + } + } + } + for i := 0; i < len(plugin); i++ { + if _, ok := entitiesMap[plugin[i].PackageName]; !ok { + if plugin[i].Template == "plugin" { + createEntity = append(createEntity, plugin[i]) + } + } + } + + if len(createEntity) > 0 { + err = global.GVA_DB.WithContext(ctx).Create(&createEntity).Error + if err != nil { + return nil, errors.Wrap(err, "同步失败!") + } + entities = append(entities, createEntity...) + } + return entities, nil } diff --git a/server/service/system/auto_code_template.go b/server/service/system/auto_code_template.go index c14b72fac..86b7aaf02 100644 --- a/server/service/system/auto_code_template.go +++ b/server/service/system/auto_code_template.go @@ -308,6 +308,32 @@ func (s *autoCodeTemplate) AddFunc(info request.AutoFunc) error { return nil } +func (s *autoCodeTemplate) GetApiAndServer(info request.AutoFunc) (map[string]string, error) { + autoPkg := model.SysAutoCodePackage{} + err := global.GVA_DB.First(&autoPkg, "package_name = ?", info.Package).Error + if err != nil { + return nil, err + } + if autoPkg.Template != "package" { + info.IsPlugin = true + } + + apiStr, err := s.getTemplateStr("api.go", info) + if err != nil { + return nil, err + } + serverStr, err := s.getTemplateStr("server.go", info) + if err != nil { + return nil, err + } + jsStr, err := s.getTemplateStr("api.js", info) + if err != nil { + return nil, err + } + return map[string]string{"api": apiStr, "server": serverStr, "js": jsStr}, nil + +} + func (s *autoCodeTemplate) getTemplateStr(t string, info request.AutoFunc) (string, error) { tempPath := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "resource", "function", t+".tpl") files, err := template.ParseFiles(tempPath) @@ -392,10 +418,19 @@ func (s *autoCodeTemplate) addTemplateToFile(t string, info request.AutoFunc) er switch t { case "api.go": + if info.IsAi && info.ApiFunc != "" { + getTemplateStr = info.ApiFunc + } target = filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "api", "v1", info.Package, info.HumpPackageName+".go") case "server.go": + if info.IsAi && info.ServerFunc != "" { + getTemplateStr = info.ServerFunc + } target = filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "service", info.Package, info.HumpPackageName+".go") case "api.js": + if info.IsAi && info.JsFunc != "" { + getTemplateStr = info.JsFunc + } target = filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Web, "api", info.Package, info.PackageName+".js") } if info.IsPlugin { diff --git a/server/service/system/sys_export_template.go b/server/service/system/sys_export_template.go index 868c07e7d..b39d72408 100644 --- a/server/service/system/sys_export_template.go +++ b/server/service/system/sys_export_template.go @@ -155,7 +155,7 @@ func (sysExportTemplateService *SysExportTemplateService) ExportExcel(templateID var tableTitle []string var selectKeyFmt []string for _, key := range columns { - selectKeyFmt = append(selectKeyFmt, fmt.Sprintf("`%s`", key)) + selectKeyFmt = append(selectKeyFmt, fmt.Sprintf("%s", key)) tableTitle = append(tableTitle, templateInfoMap[key]) } @@ -168,7 +168,7 @@ func (sysExportTemplateService *SysExportTemplateService) ExportExcel(templateID if len(template.JoinTemplate) > 0 { for _, join := range template.JoinTemplate { - db = db.Joins(join.JOINS + "`" + join.Table + "`" + " ON " + join.ON) + db = db.Joins(join.JOINS + " " + join.Table + " ON " + join.ON) } } diff --git a/server/source/system/api.go b/server/source/system/api.go index a5b4abb62..1f713d858 100644 --- a/server/source/system/api.go +++ b/server/source/system/api.go @@ -178,13 +178,13 @@ func (i *initApi) InitializeData(ctx context.Context) (context.Context, error) { {ApiGroup: "system.api.group.announcement", Method: "GET", Path: "/info/findInfo", Description: "system.api.desc.getAnnouncementByID"}, {ApiGroup: "system.api.group.announcement", Method: "GET", Path: "/info/getInfoList", Description: "system.api.desc.getAnnouncementList"}, - {ApiGroup: "参数管理", Method: "POST", Path: "/sysParams/createSysParams", Description: "新建参数"}, - {ApiGroup: "参数管理", Method: "DELETE", Path: "/sysParams/deleteSysParams", Description: "删除参数"}, - {ApiGroup: "参数管理", Method: "DELETE", Path: "/sysParams/deleteSysParamsByIds", Description: "批量删除参数"}, - {ApiGroup: "参数管理", Method: "PUT", Path: "/sysParams/updateSysParams", Description: "更新参数"}, - {ApiGroup: "参数管理", Method: "GET", Path: "/sysParams/findSysParams", Description: "根据ID获取参数"}, - {ApiGroup: "参数管理", Method: "GET", Path: "/sysParams/getSysParamsList", Description: "获取参数列表"}, - {ApiGroup: "参数管理", Method: "GET", Path: "/sysParams/getSysParam", Description: "获取参数列表"}, + {ApiGroup: "system.api.group.parameterManagement", Method: "POST", Path: "/sysParams/createSysParams", Description: "system.api.desc.newParameter"}, + {ApiGroup: "system.api.group.parameterManagement", Method: "DELETE", Path: "/sysParams/deleteSysParams", Description: "system.api.desc.deleteParameter"}, + {ApiGroup: "system.api.group.parameterManagement", Method: "DELETE", Path: "/sysParams/deleteSysParamsByIds", Description: "system.api.desc.batchDeleteParameters"}, + {ApiGroup: "system.api.group.parameterManagement", Method: "PUT", Path: "/sysParams/updateSysParams", Description: "system.api.desc.updateParameters"}, + {ApiGroup: "system.api.group.parameterManagement", Method: "GET", Path: "/sysParams/findSysParams", Description: "system.api.desc.getParametersById"}, + {ApiGroup: "system.api.group.parameterManagement", Method: "GET", Path: "/sysParams/getSysParamsList", Description: "system.api.desc.getParametersList"}, + {ApiGroup: "system.api.group.parameterManagement", Method: "GET", Path: "/sysParams/getSysParam", Description: "system.api.desc.getParametersList"}, } if err := db.Create(&entities).Error; err != nil { return ctx, errors.Wrap(err, sysModel.SysApi{}.TableName()+" "+global.Translate("general.tabelDataInitFail")) diff --git a/server/source/system/menu.go b/server/source/system/menu.go index a43e6f542..feafaee70 100644 --- a/server/source/system/menu.go +++ b/server/source/system/menu.go @@ -82,7 +82,7 @@ func (i *initMenu) InitializeData(ctx context.Context) (next context.Context, er {MenuLevel: 0, Hidden: false, ParentId: 24, Path: "plugin-email", Name: "plugin-email", Component: "plugin/email/view/index.vue", Sort: 4, Meta: Meta{Title: "system.menu.emailPlugin", Icon: "message"}}, {MenuLevel: 0, Hidden: false, ParentId: 15, Path: "exportTemplate", Name: "exportTemplate", Component: "view/systemTools/exportTemplate/exportTemplate.vue", Sort: 5, Meta: Meta{Title: "system.menu.tableTemplate", Icon: "reading"}}, {MenuLevel: 0, Hidden: false, ParentId: 24, Path: "anInfo", Name: "anInfo", Component: "plugin/announcement/view/info.vue", Sort: 5, Meta: Meta{Title: "system.menu.announcementManage", Icon: "scaleToOriginal"}}, - {MenuLevel: 0, Hidden: false, ParentId: 3, Path: "sysParams", Name: "sysParams", Component: "view/superAdmin/params/sysParams.vue", Sort: 7, Meta: Meta{Title: "参数管理", Icon: "compass"}}, + {MenuLevel: 0, Hidden: false, ParentId: 3, Path: "sysParams", Name: "sysParams", Component: "view/superAdmin/params/sysParams.vue", Sort: 7, Meta: Meta{Title: "system.menu.parameterManagement", Icon: "compass"}}, } if err = db.Create(&entities).Error; err != nil { return ctx, errors.Wrap(err, SysBaseMenu{}.TableName()+" "+global.Translate("general.tabelDataInitFail")) diff --git a/server/utils/timer/timed_task.go b/server/utils/timer/timed_task.go index b8c4edfab..9f761436f 100644 --- a/server/utils/timer/timed_task.go +++ b/server/utils/timer/timed_task.go @@ -137,7 +137,7 @@ func (t *timer) AddTaskByJobWithSeconds(cronName string, spec string, job interf return id, err } -// FindTask 获取对应cronName的cron 可能会为空 +// FindCron 获取对应cronName的cron 可能会为空 func (t *timer) FindCron(cronName string) (*taskManager, bool) { t.Lock() defer t.Unlock() diff --git a/server/utils/upload/minio_oss.go b/server/utils/upload/minio_oss.go new file mode 100644 index 000000000..3a6af72ce --- /dev/null +++ b/server/utils/upload/minio_oss.go @@ -0,0 +1,98 @@ +package upload + +import ( + "bytes" + "context" + "errors" + "io" + "mime/multipart" + "path/filepath" + "strings" + "time" + + "github.com/flipped-aurora/gin-vue-admin/server/global" + "github.com/flipped-aurora/gin-vue-admin/server/utils" + "github.com/minio/minio-go/v7" + "github.com/minio/minio-go/v7/pkg/credentials" + "go.uber.org/zap" +) + +var MinioClient *Minio // 优化性能,但是不支持动态配置 + +type Minio struct { + Client *minio.Client + bucket string +} + +func GetMinio(endpoint, accessKeyID, secretAccessKey, bucketName string, useSSL bool) (*Minio, error) { + if MinioClient != nil { + return MinioClient, nil + } + // Initialize minio client object. + minioClient, err := minio.New(endpoint, &minio.Options{ + Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""), + Secure: useSSL, // Set to true if using https + }) + if err != nil { + return nil, err + } + // 尝试创建bucket + err = minioClient.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{}) + if err != nil { + // Check to see if we already own this bucket (which happens if you run this twice) + exists, errBucketExists := minioClient.BucketExists(context.Background(), bucketName) + if errBucketExists == nil && exists { + // log.Printf("We already own %s\n", bucketName) + } else { + return nil, err + } + } + MinioClient = &Minio{Client: minioClient, bucket: bucketName} + return MinioClient, nil +} + +func (m *Minio) UploadFile(file *multipart.FileHeader) (filePathres, key string, uploadErr error) { + f, openError := file.Open() + // mutipart.File to os.File + if openError != nil { + global.GVA_LOG.Error("function file.Open() Failed", zap.Any("err", openError.Error())) + return "", "", errors.New("function file.Open() Failed, err:" + openError.Error()) + } + + filecontent := bytes.Buffer{} + _, err := io.Copy(&filecontent, f) + if err != nil { + global.GVA_LOG.Error("读取文件失败", zap.Any("err", err.Error())) + return "", "", errors.New("读取文件失败, err:" + err.Error()) + } + f.Close() // 创建文件 defer 关闭 + + + // 对文件名进行加密存储 + ext := filepath.Ext(file.Filename) + filename := utils.MD5V([]byte(strings.TrimSuffix(file.Filename, ext))) + ext + if global.GVA_CONFIG.Minio.BasePath == "" { + filePathres = "uploads" + "/" + time.Now().Format("2006-01-02") + "/" + filename + } else { + filePathres = global.GVA_CONFIG.Minio.BasePath + "/" + time.Now().Format("2006-01-02") + "/" + filename + } + + // 设置超时10分钟 + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*10) + defer cancel() + + // Upload the file with PutObject 大文件自动切换为分片上传 + info, err := m.Client.PutObject(ctx, global.GVA_CONFIG.Minio.BucketName, filePathres, &filecontent, file.Size, minio.PutObjectOptions{ContentType: "application/octet-stream"}) + if err != nil { + global.GVA_LOG.Error("上传文件到minio失败", zap.Any("err", err.Error())) + return "", "", errors.New("上传文件到minio失败, err:" + err.Error()) + } + return global.GVA_CONFIG.Minio.BucketUrl + "/" + info.Key, filePathres, nil +} + +func (m *Minio) DeleteFile(key string) error { + // Delete the object from MinIO + ctx, _ := context.WithTimeout(context.Background(), time.Second*5) + err := m.Client.RemoveObject(ctx, m.bucket, key, minio.RemoveObjectOptions{}) + return err +} diff --git a/server/utils/upload/upload.go b/server/utils/upload/upload.go index 72fa44429..28266ab18 100644 --- a/server/utils/upload/upload.go +++ b/server/utils/upload/upload.go @@ -33,6 +33,13 @@ func NewOss() OSS { return &AwsS3{} case "cloudflare-r2": return &CloudflareR2{} + case "minio": + minioClient, err := GetMinio(global.GVA_CONFIG.Minio.Endpoint, global.GVA_CONFIG.Minio.AccessKeyId, global.GVA_CONFIG.Minio.AccessKeySecret, global.GVA_CONFIG.Minio.BucketName, global.GVA_CONFIG.Minio.UseSSL) + if err != nil { + global.GVA_LOG.Warn("你配置了使用minio,但是初始化失败,请检查minio可用性或安全配置: " + err.Error()) + panic("minio初始化失败") // 建议这样做,用户自己配置了minio,如果报错了还要把服务开起来,使用起来也很危险 + } + return minioClient default: return &Local{} } diff --git a/web/package.json b/web/package.json index d0d60e467..bd9f284e3 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "gin-vue-admin", - "version": "2.7.6", + "version": "2.7.7", "private": true, "scripts": { "serve": "node openDocument.js && vite --host --mode development", @@ -10,6 +10,10 @@ "fix-memory-limit": "cross-env LIMIT=4096 increase-memory-limit" }, "dependencies": { + "@codemirror/lang-go": "^6.0.1", + "@codemirror/lang-javascript": "^6.2.2", + "@codemirror/lang-vue": "^0.1.3", + "@codemirror/theme-one-dark": "^6.1.2", "@element-plus/icons-vue": "^2.3.1", "@form-create/designer": "^3.2.6", "@form-create/element-ui": "^3.2.10", @@ -21,10 +25,11 @@ "@wangeditor/editor-for-vue": "^5.1.12", "axios": "^1.7.7", "chokidar": "^4.0.0", + "codemirror": "^6.0.1", "core-js": "^3.38.1", "default-passive-events": "^2.0.0", "echarts": "5.5.1", - "element-plus": "^2.8.4", + "element-plus": "^2.8.5", "highlight.js": "^11.10.0", "js-cookie": "^3.0.5", "marked": "14.1.1", @@ -41,6 +46,7 @@ "vform3-builds": "^3.0.10", "vite-auto-import-svg": "^1.1.0", "vue": "^3.5.7", + "vue-codemirror": "^6.1.1", "vue-echarts": "^7.0.3", "vue-router": "^4.4.3", "vuedraggable": "^4.1.0", diff --git a/web/src/api/autoCode.js b/web/src/api/autoCode.js index 544330902..bca38a00d 100644 --- a/web/src/api/autoCode.js +++ b/web/src/api/autoCode.js @@ -139,31 +139,40 @@ export const pubPlug = (params) => { }) } - export const llmAuto = (data) => { return service({ url: '/autoCode/llmAuto', method: 'post', - data:{...data,mode:'ai'}, + data: { ...data, mode: 'ai' }, timeout: 1000 * 60 * 10, - loadingOption:{ + loadingOption: { lock: true, - fullscreen:true, - text: `小淼正在思考,请稍候...`, + fullscreen: true, + text: `小淼正在思考,请稍候...` } }) } - export const butler = (data) => { return service({ url: '/autoCode/llmAuto', method: 'post', - data:{...data,mode:'butler'}, - timeout: 1000 * 60 * 10, + data: { ...data, mode: 'butler' }, + timeout: 1000 * 60 * 10 }) } + +export const eye = (data) => { + return service({ + url: '/autoCode/llmAuto', + method: 'post', + data: { ...data, mode: 'eye' }, + timeout: 1000 * 60 * 10 + }) +} + + export const addFunc = (data) => { return service({ url: '/autoCode/addFunc', @@ -186,4 +195,4 @@ export const initAPI = (data) => { method: 'post', data }) -} +} \ No newline at end of file diff --git a/web/src/core/config.js b/web/src/core/config.js index 12463af9c..582ac01f2 100644 --- a/web/src/core/config.js +++ b/web/src/core/config.js @@ -13,7 +13,7 @@ const config = { export const viteLogo = (env) => { if (config.showViteLogo) { console.log(greenText(`> 欢迎使用Gin-Vue-Admin,开源地址:https://github.com/flipped-aurora/gin-vue-admin`)); - console.log(greenText(`> 当前版本:v2.7.6`)); + console.log(greenText(`> 当前版本:v2.7.7`)); console.log(greenText(`> 加群方式:微信:shouzi_1994 QQ群:470239250`)); console.log(greenText(`> 项目地址:https://github.com/flipped-aurora/gin-vue-admin`)); console.log(greenText(`> 插件市场:https://plugin.gin-vue-admin.com`)); diff --git a/web/src/core/gin-vue-admin.js b/web/src/core/gin-vue-admin.js index 08ed12503..615ed30e5 100644 --- a/web/src/core/gin-vue-admin.js +++ b/web/src/core/gin-vue-admin.js @@ -10,7 +10,7 @@ export default { register(app) console.log(` 欢迎使用 Gin-Vue-Admin - 当前版本:v2.7.6 + 当前版本:v2.7.7 加群方式:微信:shouzi_1994 QQ群:622360840 项目地址:https://github.com/flipped-aurora/gin-vue-admin 插件市场:https://plugin.gin-vue-admin.com diff --git a/web/src/locales/ar.json b/web/src/locales/ar.json index a1f64efde..68e0db3d6 100644 --- a/web/src/locales/ar.json +++ b/web/src/locales/ar.json @@ -74,16 +74,6 @@ "setPermissions": "تعيين الأذونات", "routeNote": "ملاحظة: عند الوصول إلى هذا المسار، سيتم تنشيط القائمة الموجودة على الجانب الأيسر بالاسم المحدد (مضاءة). يمكن أن تكون فارغة، وفي حالة كانت فارغة سيتم استخدام اسم المسار." }, - "autoCodeAdmin": { - "deleteHistoryConfirm": "هذه العملية ستحذف هذا التاريخ، هل تريد المتابعة؟", - "notRolledBack": "لم يتراجع", - "reuse": "الارسال المتعدد", - "rollBack": "العوده", - "rollBackMark": "علامة الاستعادة", - "rollbackConfirm": "سيؤدي هذا الإجراء إلى حذف الملفات التي تم إنشاؤها تلقائيا و APIs، هل تريد المتابعة؟", - "rollbackSuccess": "نجاح الاستعادة", - "rolledBack": "التراجع" - }, "error": { "message1": "تم اختطاف الصفحة بواسطة قوى غامضة، يرجى الاتصال بنا للإصلاح", "message2": "المشكلة الشائعة هي أن هذا الدور الحالي ليس لديه هذا المسار، إذا كنت متأكدًا من أنك تريد استخدام هذا المسار، يرجى الانتقال إلى إدارة الأدوار لتخصيصه", @@ -116,7 +106,7 @@ "modify": "تعديل", "editSuccess": "تم التحرير بنجاح!", "enable": "تمكين", - "endData": "تاريخ الانتهاء", + "endDate": "تاريخ الانتهاء", "expand": "توسيع", "filter": "تصفية", "hint": "تلميح", @@ -536,6 +526,23 @@ "basicPageNote": "إذا تم اختيار نعم، فلن يتم عرض القائمة الجانبية والمعلومات العلوية.", "": "" }, + "params": { + "paramName": "إسم البراميتر", + "paramKey": "مفتاح البراميتر", + "paramValue": "قيمة البراميتر", + "paramDesc": "وصف البراميتر", + "enterParamName": "أدخل إسم البراميتر", + "enterParamKey": "أدخل مفتاح البراميتر", + "enterParamValue": "أدخل قيمة البراميتر", + "enterParamDesc": "أدخل وصف البراميتر", + "instruction": "تعليمات الاستخدام", + "instructionNote1": "يمكن للواجهة الأمامية إدخال ", + "instructionNote2": " ثم إدخال ", + "instructionNote3": " للحصول على البراميترات المقابلة ", + "instructionNote4": "يمكن للواجهة الخلفية إدخال ", + "instructionNote5": " ثم طلب ", + "instructionNote6": " للحصول على القيمة المقابلة." + }, "user": { "addUser": "إضافة مستخدم", "anotherUserEdit": "يوجد مستخدم آخر قيد التحرير حاليًا", @@ -820,7 +827,9 @@ "selectTemplateNote": "يرجى اختيار القالب", "cannotStartWithNumberNote": "لا يمكن أن يبدأ برقم", "addSuccess": "تمت الإضافة بنجاح", - "deletePackageNote": "هذا الإجراء سيحذف فقط تخزين الحزمة في قاعدة البيانات، يرجى حذف الهيكل المقابل في الخلفية يدويًا للحفاظ على التناسق مع قاعدة البيانات" + "deletePackageNote": "هذا الإجراء سيحذف فقط تخزين الحزمة في قاعدة البيانات، يرجى حذف الهيكل المقابل في الخلفية يدويًا للحفاظ على التناسق مع قاعدة البيانات", + "cannotBeChinese": "لا يمكن استخدام الاحرف الصينية", + "cannotStartWithNumber": "لا يمكن البداء برقم" }, "autoCode": { "getAiPath": "الحصول على مسار الذكاء الإصطناعى", @@ -829,6 +838,7 @@ "aiNote1": "【مجاني تمامًا】انتقل إلى", "aiNote2": "المركز الشخصي لسوق المكونات الإضافية ", "aiNote3": "قم بتقديم طلب للحصول على AIPath واملأ خاصية ai-path في config.yaml لاستخدامها.", + "imageRecognition": "التعرف على الصور", "actionBar": "شريط الإجراءات:", "autoAPIDBCreate": "إنشاء API تلقائيًا", "autoAPIDBTip": "ملاحظة: تسجيل API الذي تم إنشاؤه تلقائيًا في قاعدة البيانات", @@ -852,17 +862,20 @@ "entStructDesc": "يرجى إدخال وصف الهيكل", "entStructName": "يرجى إدخال اسم الهيكل", "errNoFields": "يرجى ملء حقل واحد على الأقل", - "errSameFiledName": "يوجد حقل بنفس اسم الهيكل", + "errSameFieldName": "يوجد حقل بنفس اسم الهيكل", + "errJsonFieldNameAsTemplate": "يوجد حقل JSON بنفس اسم القالب", "errSameStructDescAbbr": "structName واختصار الهيكل لا يمكن أن يكونا نفس الشيء", "existDB": "انقر هنا لإنشاء الكود من قاعدة بيانات موجودة", "field": "حقل", - "fieldDataType": "نوع بيانات ��لحقل", + "fieldDataType": "نوع بيانات الحقل", "fieldDesc": "مفتاح متعدد اللغات للحقل", "fieldIndex": "فهرس", "fieldLen": "طول حقل قاعدة البيانات", "fileName": "اسم الملف", "fileNameNote": "الاسم الافتراضي للملف الذي تم إنشاؤه (يوصى بأن يكون بصيغة الجمل، بدءًا بحرف صغير، مثل sysXxxXxxx)", "generateCode": "توليد الكود", + "viewCode": "رؤية الكود", + "previewCode": "مراجعة الكود", "moveDown": "تحريك لأسفل", "moveUp": "تحريك لأعلى", "selectDB": "يرجى اختيار قاعدة بيانات", @@ -871,15 +884,10 @@ "structAbbreviationNote": "سيتم استخدام الاختصار كاسم كائن المعلمة ومجموعة المسار", "structChineseName": "اسم الهيكل", "structChineseNameNote": "الوصف المستخدم كوصفي API التلقائي", - "structName": "اسم الهيكل", "structNameNote": "تحويل الحرف الأول تلقائيًا إلى حرف كبير", "table": "الجدول", "tableName": "اسم الجدول", "tableNameNote": "تحديد اسم الجدول (اختياري)", - "aiContent": "Xiao Qi لديه احتمال فشل، مفتوح لجميع المستخدمين (إذا فشل، فقط أعد توليده).", - "XiaoMiaoDesc": "Xiao Miao يمكنه تصميم أي شيء تقريبًا، لكنه يتطلب نقاطًا. يحصل المستخدمون المرخصون تلقائيًا على نقاط أساسية خلال مرحلة الاختبار، يحتاج المستخدمون مفتوحو المصدر إلى ملء نموذج للتقديم.", - "XiaoQi": "Xiao Qi", - "XiaoMiao": "Xiao Miao", "createdFromDB": "تم الإنشاء من قاعدة البيانات", "businessLibrary": "مكتبة الأعمال", "businessLibraryNotice": "ملاحظة: تحتاج إلى تكوين قواعد بيانات متعددة في db-list مسبقًا. إذا لم يتم تكوينها، تحتاج إلى تكوينها وإعادة تشغيل الخدمة قبل استخدامها. (يمكنك اختيار جدول المكتبة المقابل هنا، والذي يمكن فهمه على أنه اختيار الجدول من أي مكتبة)", @@ -897,6 +905,8 @@ "templateChoose": "اختر القالب", "libraryNote": "ملاحظة: تحتاج إلى تكوين قواعد بيانات متعددة في db-list مسبقًا. إذا كان هذا العنصر فارغًا، سيتم إنشاء الكود التلقائي باستخدام مكتبة gva الرئيسية (global.GVA_DB). إذا تم ملؤه، سيتم إنشاء الكود للمكتبة المحددة (global.MustGetGlobalDBByDBName(dbname))", "useGvaNote": "ملاحظة: سيشمل الهيكل global.Model تلقائيًا العمليات المتعلقة بالمفتاح الأساسي والحذف الناعم", + "aiClearDataNote": "سيقوم محرك الذكاء الاصطناعي بمسح البيانات الحالية. هل تريد المتابعة؟", + "fillJsonDataNote": "يرجى ملء سمات json للعرض الأمامي لهيكل الشجرة", "groupInfos": { "useGvaStructure": "استخدام هيكل GVA", "note1": "ملاحظة: تسجيل API الذي تم إنشاؤه تلقائيًا في قاعدة البيانات", @@ -994,6 +1004,21 @@ "array": "مصفوفة" } }, + "autoCodeAdmin": { + "structName": "اسم الهيكل", + "structDesc" : "وصف الهيكل", + "deleteHistoryConfirm": "هذه العملية ستحذف هذا التاريخ، هل تريد المتابعة؟", + "notRolledBack": "لم يتراجع", + "reuse": "الارسال المتعدد", + "rollBack": "العوده", + "rollBackMark": "علامة الاستعادة", + "rollbackConfirm": "سيؤدي هذا الإجراء إلى حذف الملفات التي تم إنشاؤها تلقائيا و APIs، هل تريد المتابعة؟", + "rollbackSuccess": "نجاح الاستعادة", + "rolledBack": "التراجع", + "addField": "إضافة حقل", + "xiaoMiaoIsThinking": "Xiaomiao يفكر، يرجى الانتظار...", + "aiWritingNote": "توجد حاليًا عوامل غير مستقرة في كتابة تعليمات الذكاء الاصطناعي. يرجى الانتباه إلى ضبط بعض المحتويات يدويًا بعد إنشاء الكود." + }, "exportTemplate": { "syncTableExportFeature": "توفر هذه الوظيفة وظيفة تصدير الجدول المتزامنة ووظيفة تصدير الجدول غير المتزامنة لحجم البيانات الكبير. يمكنك اختيار تخصيصها.", "templateIdentifier": "مُعرّف القالب", @@ -1024,6 +1049,7 @@ "database": "قاعدة البيانات", "gvaLibrary": "مكتبة GVA", "templateInfo": "معلومات القالب", + "code": "الكود", "addTo": "إضافة إلى", "templateName2": "اسم القالب:", "templateNameNote": "يرجى إدخال اسم القالب", @@ -1056,7 +1082,17 @@ "selectDBAndTable": "يرجى اختيار مكتبة الأعمال والجدول قبل المتابعة", "templateInfoFormatError": "تنسيق معلومات القالب غير صحيح، يرجى التحقق", "exportConditionError": "يرجى ملء شروط التصدير بالكامل", - "completeAssociationError": "يرجى ملء شروط الارتباط بالكامل" + "completeAssociationError": "يرجى ملء شروط الارتباط بالكامل", + "xiaoMiaoIsThinking": "يقوم Xaio Miao بالتفكير الآن...", + "tableToBeUsed": "الجدول المستخدم", + "selectWhenUSingAi": "يرجى التحديد عند استخدام الذكاء الاصطناعي", + "aiHelpWriting": "مساعدة الذكاء الاصطناعي في الكتابة", + "aiNote": "حاول وصف وظيفة التصدير التي تريد القيام بها ودع الذكاء الاصطناعي يساعدك على إكمالها. قبل القيام بذلك، يرجى تحديد مكتبة الأعمال حيث يوجد الجدول الذي تريد تصديره. إذا لم تقم بالاختيار، فسيتم استخدام مكتبة gva بشكل افتراضي.", + "helpWrite": "مساعدة في الكتابة", + "autoComplete": "الإكمال التلقائي", + "autoGenerateTemplates": "إنشاء القوالب تلقائيا", + "selectTableToExport": "الرجاء تحديد الجدول الذي يجب تصديره أولاً", + "aiAutoCompleteFail": "فشل الإكمال التلقائي بواسطة الذكاء الاصطناعي وتم ضبطه على الإكمال المنطقي" }, "installPlugin": { "dragOrClickUpload": "اسحب أو انقر للتحميل", diff --git a/web/src/locales/en.json b/web/src/locales/en.json index 17cc0a0dc..438f0d4c8 100644 --- a/web/src/locales/en.json +++ b/web/src/locales/en.json @@ -75,20 +75,6 @@ "roleIdError": "Must be a positive integer", "": "" }, - "autoCodeAdmin": { - "deleteHistoryConfirm": "This operation will delete this history, do you want to continue?", - "notRolledBack": "Not Rolled Back", - "reuse": "Reuse", - "rollBack": "Rollback", - "rollBackDeleteTable": "Rollback (Delete Table)", - "rollBackWithoutDeleteTable": "Rollback (Without Delete Table)", - "rollBackMark": "Rollback mark", - "rollbackConfirm": "This operation will delete the automatically created files and api, do you want to continue?", - "includeDBTables": " (including database tables!), ", - "rollBackContinue": " do you want to continue?", - "rollbackSuccess": "Rollback successfully!", - "rolledBack": "Rolled back" - }, "error": { "message1": "The page has been sucked away by mysterious forces, please contact us to fix it.", "message2": "The common problem is that there is no current route for this role, if you are sure you want to use this route, please go to Role Management to assign it.", @@ -121,7 +107,7 @@ "modify": "Modify", "editSuccess": "Edited successfully!", "enable": "Enable", - "endData": "End Date", + "endDate": "End Date", "expand": "Expand", "filter": "Filter", "hint": "Hint", @@ -256,7 +242,6 @@ "simpleWhite": "Light Mode" }, "system": { - "": "", "envValues": "Environment values", "multiLogin": "Multi-login interception", "ossType": "Oss Type", @@ -543,6 +528,23 @@ "basicPageNote": "If you select Yes for this option, the left menu and top information will not be displayed.", "": "" }, + "params": { + "paramName": "Parameter Name", + "paramKey": "Parameter Key", + "paramValue": "Parameter Value", + "paramDesc": "Parameter Description", + "enterParamName": "Enter Parameter Name", + "enterParamKey": "Enter Parameter Key", + "enterParamValue": "Enter Parameter Value", + "enterParamDesc": "Enter Parameter Description", + "instruction": "Instructions", + "instructionNote1": "The frontend can ", + "instructionNote2": " and then call ", + "instructionNote3": " to get the corresponding parameters.", + "instructionNote4": "The backend needs to ", + "instructionNote5": " then call ", + "instructionNote6": " to get the corresponding value." + }, "user": { "addUser": "Add User", "anotherUserEdit": "There is currently a user who is editing", @@ -828,7 +830,8 @@ "cannotStartWithNumberNote": "Cannot start with a number", "addSuccess": "Added successfully", "deletePackageNote": "This operation only deletes the pkg storage in the database. Please delete the corresponding directory structure of the backend by yourself to keep it consistent with the database!", - "": "" + "cannotBeChinese": "Input cannot be Chinese.", + "cannotStartWithNumber": "Input cannot start with numbers." }, "autoCode": { "getAiPath": "Get AI Path", @@ -837,6 +840,7 @@ "aiNote1": "【Completely Free】Go to ", "aiNote2": "Personal Center of Plugin Market ", "aiNote3": "Apply for AIPath and fill in the ai-path property in config.yaml to use it.", + "imageRecognition": "Image recognition", "actionBar": "Action Bar:", "autoAPIDBCreate": "Automatically Create API", "autoAPIDBTip": "Note: Register the automatically generated API into the database", @@ -860,7 +864,8 @@ "entStructDesc": "Please enter the struct description", "entStructName": "Please enter the struct name", "errNoFields": "Please fill in at least one field", - "errSameFiledName": "There is a field with the same name as the struct", + "errSameFieldName": "There is a field with the same name as the struct", + "errJsonFieldNameAsTemplate": "There is a field JSON with the same name as the template", "errSameStructDescAbbr": "structName and struct abbreviation cannot be the same", "existDB": "Click here to create code from an existing database", "field": "Field", @@ -871,6 +876,8 @@ "fileName": "File Name", "fileNameNote": "Default name of the generated file (recommended to be in camel case, starting with a lowercase letter, such as sysXxxXxxx)", "generateCode": "Generate Code", + "viewCode": "View Code", + "previewCode": "Preview Code", "moveDown": "Move Down", "moveUp": "Move Up", "selectDB": "Please select a database", @@ -879,15 +886,10 @@ "structAbbreviationNote": "The abbreviation will be used as the parameter object name and route group", "structChineseName": "Struct Name", "structChineseNameNote": "Description used as automatic API description", - "structName": "Struct Name", "structNameNote": "First letter automatically converted to uppercase", "table": "Table", "tableName": "Table Name", "tableNameNote": "Specify table name (optional)", - "aiContent": "Xiao Qi has a failure probability, open to all users (if it fails, just regenerate it).", - "XiaoMiaoDesc": "Xiao Miao can design almost anything, but it requires points. Authorized users automatically get basic points during the testing phase, open source users need to fill out a form to apply.", - "XiaoQi": "Xiao Qi", - "XiaoMiao": "Xiao Miao", "createdFromDB": "Created from Database", "businessLibrary": "Business Library", "businessLibraryNotice": "Note: You need to configure multiple databases in db-list in advance. If not configured, you need to configure and restart the service before using it. (You can select the corresponding library table here, which can be understood as selecting the table from which library)", @@ -905,6 +907,8 @@ "templateChoose": "Choose Template", "libraryNote": "Note: You need to configure multiple databases in db-list in advance. If this item is empty, the automated code will be created using the gva main library (global.GVA_DB). If filled in, the code will be created for the specified library (global.MustGetGlobalDBByDBName(dbname))", "useGvaNote": "Note: The struct global.Model will automatically include primary key and soft delete related operations", + "aiClearDataNote": "AI generation will clear the current data, do you want to continue?", + "fillJsonDataNote": "Please fill in the front-end display json properties of the tree structure", "groupInfos": { "useGvaStructure": "GVA Structure", "note1": "Note: Register the automatically generated API into the database", @@ -1002,6 +1006,25 @@ "array": "Array" } }, + "autoCodeAdmin": { + "structName": "Struct Name", + "structDesc" : "Structure Description", + "deleteHistoryConfirm": "This operation will delete this history, do you want to continue?", + "notRolledBack": "Not Rolled Back", + "reuse": "Reuse", + "rollBack": "Rollback", + "rollBackDeleteTable": "Rollback (Delete Table)", + "rollBackWithoutDeleteTable": "Rollback (Without Delete Table)", + "rollBackMark": "Rollback mark", + "rollbackConfirm": "This operation will delete the automatically created files and api, do you want to continue?", + "includeDBTables": " (including database tables!), ", + "rollBackContinue": " do you want to continue?", + "rollbackSuccess": "Rollback successfully!", + "rolledBack": "Rolled back", + "addField": "Add Field", + "xiaoMiaoIsThinking": "Xiao Miao is thinking, please wait...", + "aiWritingNote": "Currently, AI writing is unstable. Please pay attention to manually adjust some content after generating the code." + }, "exportTemplate": { "syncTableExportFeature": "This function provides synchronous table export function and asynchronous table export function for large data volume. You can choose to customize it.", "templateIdentifier": "Template Identifier", @@ -1032,6 +1055,7 @@ "database": "Database", "gvaLibrary": "GVA Library", "templateInfo": "Template Information", + "code": "Code", "addTo": "Add To", "templateName2": "Template Name:", "templateNameNote": "Please enter a template name", @@ -1064,7 +1088,17 @@ "selectDBAndTable": "Please select the business library and selection table before operating", "templateInfoFormatError": "The template information format is incorrect, please check", "exportConditionError": "Please fill in the complete export conditions", - "completeAssociationError": "Please fill in the complete association" + "completeAssociationError": "Please fill in the complete association", + "xiaoMiaoIsThinking": "Xiao Miao Is Thinking...", + "tableToBeUsed": "Table To Be Used", + "selectWhenUSingAi": "Please select when using AI", + "aiHelpWriting": "AI Help Writing", + "aiNote": "Try to describe the export function you want to do and let AI help you complete it. Before that, please select the business library where the table you want to export is located. If you do not make a selection, the gva library will be used by default.", + "helpWrite": "Help Write", + "autoComplete": "Autocomplete", + "autoGenerateTemplates": "Automatically Generate Templates", + "selectTableToExport": "Please select the table you want to export.", + "aiAutoCompleteFail": "AI auto-completion failed, and has been adjusted to logical completion" }, "installPlugin": { "dragOrClickUpload": "Drag or click to upload", diff --git a/web/src/locales/zh-TW.json b/web/src/locales/zh-TW.json index f33adc5eb..dbd78f3af 100644 --- a/web/src/locales/zh-TW.json +++ b/web/src/locales/zh-TW.json @@ -26,20 +26,6 @@ "roleIdError": "必須為正整數", "": "" }, - "autoCodeAdmin": { - "deleteHistoryConfirm": "此操作將刪除本歷史, 是否繼續?", - "notRolledBack": "未回滾", - "reuse": "復用", - "rollBack": "回滾", - "rollBackDeleteTable": "回滾(刪表)", - "rollBackWithoutDeleteTable": "回滾(不刪表)", - "rollBackMark": "回滾標記", - "rollbackConfirm": "此操作將刪除自動創建的文件和API, 是否繼續?", - "includeDBTables": "(包含數據庫表!),", - "rollBackContinue": " 是否繼續?", - "rollbackSuccess": "回滾成功", - "rolledBack": "已回滾" - }, "datas": { "datasNote": "此功能僅用於創建角色和角色的many2many關係表,具體使用還須自己結合表實現業務,詳情參考示例代碼(客戶示例)此功能不建議使用,建議使用插件市場【組織管理功能(點擊前往)】來管理資源權限。", "resourceSetupSuccess": "資源設定成功", @@ -76,7 +62,7 @@ "edit": "編輯", "editSuccess": "編輯成功!", "enable": "開啟", - "endData": "結束日期", + "endDate": "結束日期", "expand": "展開", "filter": "篩選", "hint": "提示", @@ -353,6 +339,23 @@ "basicPageNote": "此項選擇為是,則不會展示左側菜單以及頂部信息。", "": "" }, + "params": { + "paramName": "參數名稱", + "paramKey": "参数键", + "paramValue": "参数值", + "paramDesc": "参数说明", + "enterParamName": "请输入参数名称", + "enterParamKey": "请输入参数键", + "enterParamValue": "请输入参数值", + "enterParamDesc": "请输入参数说明", + "instruction": "使用说明", + "instructionNote1": "前端可以通过引入", + "instructionNote2": "然后通过", + "instructionNote3": "来获取对应的参数。", + "instructionNote4": "后端需要提前", + "instructionNote5": "然后调用", + "instructionNote6": "来获取对应的 value 值。" + }, "user": { "addUser": "新增用戶", "anotherUserEdit": "當前存在正在編輯的用戶", @@ -666,170 +669,196 @@ "cancelRestart": "取消重啟" }, "autoCode": { - "actionBar": "操作欄:", - "aiCodeNote": "【Beta】試試描述你的表,讓AI幫你完成。\n目前正在測試階段,遇到問題請及時反饋。\n此功能需要到插件市場個人中心獲取自己的AI-Path,把AI-Path填入config.yaml下的autocode--\u003eai-path,重啟項目即可使用。", - "autoAPIDBCreate": "自動創建API", - "autoAPIDBTip": "註:把自動生成的API註冊進數據庫", - "autoCodeNote": "此功能為開發環境使用,不建議發布到生產,具體使用效果請點我觀看。", - "autoMoveFiles": "自動移動文件", - "autoMoveFilesTip": "註:自動遷移生成的文件到ymal配置的對應位置", - "codeGenDownload": "自動化代碼創建成功,正在下載", - "codeGenMoveSuccess": "自動化代碼創建成功,自動移動成功", - "codePreview": "預覽代碼", - "columnName": "數據庫字段", - "comment": "數據庫字段描述", - "componentContent": "組件內容", - "confirmDelete": "確定刪除嗎?", - "copy": "複製", - "createUsingTable": "使用此表創建", - "createdByAI": "使用AI創建", - "dbName": "數據庫名", + "getAiPath": "获取AiPath", + "aiCodeNote": "现已完全免费\n试试描述你的表,让AI帮你完成。\n此功能需要到插件市场个人中心获取自己的AI-Path,把AI-Path填入config.yaml下的autocode-->ai-path,重启项目即可使用。\n按下 Ctrl+Enter 或 Cmd+Enter 直接生成", + "aiNote1": "【完全免费】前往", + "aiNote2": "插件市场个人中心", + "aiNote3": "申请AIPath,填入config.yaml的ai-path属性即可使用。", + "imageRecognition": "识图", + "actionBar": "操作栏:", + "autoAPIDBCreate": "自动创建API", + "autoAPIDBTip": "注:把自动生成的API注册进数据库", + "autoCodeNote": "此功能为开发环境使用,不建议发布到生产,具体使用效果请点我观看。", + "autoMoveFiles": "自动移动文件", + "autoMoveFilesTip": "注:自动迁移生成的文件到ymal配置的对应位置", + "codeGenDownload": "自动化代码创建成功,正在下载", + "codeGenMoveSuccess": "自动化代码创建成功,自动移动成功", + "codePreview": "预览代码", + "columnName": "数据库字段", + "comment": "数据库字段描述", + "componentContent": "组件内容", + "confirmDelete": "确定删除吗?", + "copy": "复制", + "createUsingTable": "使用此表创建", + "createdByAI": "使用AI创建", + "dbName": "数据库名", "dictionary": "字典", - "entFileName": "文件名稱:sysXxxxXxxx", - "entStructAbbreviation": "請輸入結構體簡稱", - "entStructDesc": "請輸入結構體描述", - "entStructName": "請輸入結構體名稱", - "errNoFields": "請填寫至少一個field", - "errSameFiledName": "存在與結構體同名的字段", - "errSameStructDescAbbr": "structName和struct簡稱不能相同", - "existDB": "點這裡從現有數據庫創建代碼", + "entFileName": "文件名称:sysXxxxXxxx", + "entStructAbbreviation": "请输入结构体简称", + "entStructDesc": "请输入结构体描述", + "entStructName": "请输入结构体名称", + "errNoFields": "请填写至少一个field", + "errSameFieldName": "存在与结构体同名的字段", + "errJsonFieldNameAsTemplate": "存在与模板同名的的字段JSON", + "errSameStructDescAbbr": "structName和struct简称不能相同", + "existDB": "点这里从现有数据库创建代码", "field": "字段", - "fieldDataType": "Field數據類型", - "fieldDesc": "字段多語言Key", + "fieldDataType": "Field数据类型", + "fieldDesc": "字段多语言Key", "fieldIndex": "序列", - "fieldLen": "數據庫字段長度", - "fileName": "文件名稱", - "fileNameNote": "生成文件的默認名稱(建議為駝峰格式,首字母小寫,如sysXxxXxxx)", - "generateCode": "生成代碼", + "fieldLen": "数据库字段长度", + "fileName": "文件名称", + "fileNameNote": "生成文件的默认名称(建议为驼峰格式,首字母小写,如sysXxxXxxx)", + "generateCode": "生成代码", + "viewCode": "查看代码", + "previewCode": "预览代码", "moveDown": "下移", "moveUp": "上移", - "selectDB": "請選擇數據庫", - "selectTable": "請選擇表", - "structAbbreviation": "Struct簡稱", - "structAbbreviationNote": "簡稱會作為入參對象名和路由group", - "structChineseName": "Struct名稱", - "structChineseNameNote": "描述作為自動api描述", - "structName": "Struct名稱", - "structNameNote": "首字母自動轉換大寫", + "selectDB": "请选择数据库", + "selectTable": "请选择表", + "structAbbreviation": "Struct简称", + "structAbbreviationNote": "简称会作为入参对象名和路由group", + "structChineseName": "Struct名称", + "structChineseNameNote": "描述作为自动api描述", + "structNameNote": "首字母自动转换大写", "table": "表", "tableName": "表名", "tableNameNote": "指定表名(非必填)", - "aiContent": "小奇存在失敗概率,面向所有用戶開放使用(失敗了重新生成一下就好)。", - "XiaoMiaoDesc": "小淼基本啥也能設計出來,但是需要消耗積分,測試階段授權用戶自動獲得基礎積分,開源用戶需要填表申請。", - "XiaoQi": "小奇", - "XiaoMiao": "小淼", - "createdFromDB": "從數據庫創建", - "businessLibrary": "業務庫", - "businessLibraryNotice": "註:需要提前到db-list自行配置多數據庫,如未配置需配置後重啟服務方可使用。(此處可選擇對應庫表,可理解為從哪個庫選擇表)", - "selectBusinessLibrary": "選擇業務庫", - "selectTableBtn": "選擇此表", - "automationStructure": "自動化結構", - "structureName": "結構名稱", - "structureSimpleName": "結構簡稱", - "StructureOverview": "結構簡介", - "structNameInput": "請輸入Struct簡稱", - "fineNameInput": "請輸入文件名稱", - "capitalizeFirstLetterAutomatically": "首字母自動大寫", - "objectNameAndRouteGroup": "簡稱作為參數對象名和路由組", - "templateChoose": "選擇模板", - "libraryNote": "註:需要提前到db-list自行配置多數據庫,此項為空則會使用gva本庫創建自動化代碼(global.GVA_DB),填寫後則會創建指定庫的代碼(global.MustGetGlobalDBByDBName(dbname))", - "useGvaNote": "註:會自動在結構體global.Model其中包含主鍵和軟刪除相關操作配置", + "createdFromDB": "从数据库创建", + "businessLibrary": "业务库", + "businessLibraryNotice": "注:需要提前到db-list自行配置多数据库,如未配置需配置后重启服务方可使用。(此处可选择对应库表,可理解为从哪个库选择表)", + "selectBusinessLibrary": "选择业务库", + "selectTableBtn": "选择此表", + "automationStructure": "自动化结构", + "structureName": "结构名称", + "structureSimpleName": "结构简称", + "StructureOverview": "结构简介", + "structNameInput": "请输入Struct简称", + "structNameIs": "结构体名称为", + "fineNameInput": "请输入文件名称", + "capitalizeFirstLetterAutomatically": "首字母自动大写", + "objectNameAndRouteGroup": "简称作为参数对象名和路由组", + "templateChoose": "选择模板", + "libraryNote": "注:需要提前到db-list自行配置多数据库,此项为空则会使用gva本库创建自动化代码(global.GVA_DB),填写后则会创建指定库的代码(global.MustGetGlobalDBByDBName(dbname))", + "useGvaNote": "注:会自动在结构体global.Model其中包含主键和软删除相关操作配置", + "aiClearDataNote": "AI生成会清空当前数据,是否继续?", + "fillJsonDataNote": "请填写树型结构的前端展示json属性", "groupInfos": { - "useGvaStructure": "使用GVA結構", - "note1": "註:把自動生成的API註冊進數據庫", - "autoCreateApi": "自動創建API", - "note2": "註:把自動生成的菜單註冊進數據庫", - "autoCreateMenu": "自動創建菜單", - "note3": "註:自動同步數據庫表結構,如果不需要可以選擇關閉。", - "syncTableStructure": "同步表結構", - "note4": "註:會自動產生頁面內的按鈕權限配置,若不在角色管理中進行按鈕分配則按鈕不可見", - "createButtonPermissions": "創建按鈕權限", - "note5": "註:會自動在結構體添加 created_by updated_by deleted_by,方便用戶進行資源權限控制", - "createResourceIdentifier": "創建資源標識", - "note6": "註:使用基礎模板將不會生成任何結構體和CURD,僅僅配置enter等屬性方便自行開發非CURD邏輯", - "basicTemplate": "基礎模板" + "useGvaStructure": "使用GVA结构", + "note1": "注:把自动生成的API注册进数据库", + "autoCreateApi": "自动创建API", + "note2": "注:把自动生成的菜单注册进数据库", + "autoCreateMenu": "自动创建菜单", + "note3": "注:自动同步数据库表结构,如果不需要可以选择关闭。", + "syncTableStructure": "同步表结构", + "note4": "注:会自动产生页面内的按钮权限配置,若不在角色管理中进行按钮分配则按钮不可见", + "createButtonPermissions": "创建按钮权限", + "note5": "注:会自动在结构体添加 created_by updated_by deleted_by,方便用户进行资源权限控制", + "createResourceIdentifier": "创建资源标识", + "note6": "注:使用基础模板将不会生成任何结构体和CURD,仅仅配置enter等属性方便自行开发非CURD逻辑", + "basicTemplate": "基础模板" }, "addField": "新增字段", - "primaryKey": "主鍵", - "fieldName": "字段名稱", + "primaryKey": "主键", + "fieldName": "字段名称", "chineseName": "中文名", - "defaultValue": "默認值", + "defaultValue": "默认值", "required": "必填", - "createEdit": "新建/編輯", - "importExport": "導入/導出", + "createEdit": "新建/编辑", + "importExport": "导入/导出", "fieldJson": "字段Json", - "fieldType": "字段類型", - "selectFieldType": "請選擇字段類型", - "indexType": "索引類型", - "selectIndexType": "請選擇字段索引類型", - "selectSearchCondition": "請選擇字段查詢條件", - "advancedEdit": "高級編輯", - "exportJson": "導出json", - "importJson": "導出json", - "clearTemp": "清除暫存", - "temporary": "暫存", - "selectPackage": "請選擇package", - "gvaStructureNote": "如果您開啟GVA默認結構,會自動添加ID,CreatedAt,UpdatedAt,DeletedAt字段,此行為將自動清除您目前在下方創建的重名字段,是否繼續?", + "fieldType": "字段类型", + "selectFieldType": "请选择字段类型", + "indexType": "索引类型", + "selectIndexType": "请选择字段索引类型", + "selectSearchCondition": "请选择字段查询条件", + "advancedEdit": "高级编辑", + "exportJson": "导出json", + "importJson": "导出json", + "clearTemp": "清除暂存", + "temporary": "暂存", + "selectPackage": "请选择package", + "gvaStructureNote": "如果您开启GVA默认结构,会自动添加ID,CreatedAt,UpdatedAt,DeletedAt字段,此行为将自动清除您目前在下方创建的重名字段,是否继续?", "note": "注意", - "primaryKeyRequirement": "您至少需要創建一個主鍵才能保證自動化代碼的可行性", - "fillFieldTypes": "請填寫所有字段類型後進行提交", - "packageNameConflict": "package和結構體簡稱不可同名", - "jsonImportSuccess": "JSON 文件導入成功", - "invalidJsonFile": "無效的 JSON 文件", - "basicTemplateNote": "使用基礎模板將不會生成任何結構體和CURD,僅僅配置enter等屬性方便自行開發非CURD邏輯", + "primaryKeyRequirement": "您至少需要创建一个主键才能保证自动化代码的可行性", + "fillFieldTypes": "请填写所有字段类型后进行提交", + "packageNameConflict": "package和结构体简称不可同名", + "jsonImportSuccess": "JSON 文件导入成功", + "invalidJsonFile": "无效的 JSON 文件", + "basicTemplateNote": "使用基础模板将不会生成任何结构体和CURD,仅仅配置enter等属性方便自行开发非CURD逻辑", "fieldDialog": { - "associativeDictionary": "關聯字典", - "autoFill": "自動填充", - "dataTypeNote": "數據庫類型長度", - "entColumnName": "請輸入數據庫字段", - "entFieldDataType": "請選擇field數據類型", - "entFieldDesc": "請輸入field短介紹", - "entFieldJson": "請輸入field格式化json", - "entFieldName": "請輸入field英文名", - "note": "id , created_at , updated_at , deleted_at 會自动生成請勿重復創建。搜索時如果條件為LIKE只支持字符串", - "selectDataType": "請選擇field數據類型", - "selectDictionary": "請選擇字典", - "selectSearchType": "請選擇Field查詢條件", - "enumValue": "枚舉值", - "typeLength": "類型長度", + "associativeDictionary": "关联字典", + "autoFill": "自动填充", + "dataTypeNote": "数据库类型长度", + "entColumnName": "请输入数据库字段", + "entFieldDataType": "请选择field数据类型", + "entFieldDesc": "请输入field短介绍", + "entFieldJson": "请输入field格式化json", + "entFieldName": "请输入field英文名", + "note": "id , created_at , updated_at , deleted_at 会自动生成请勿重复创建。搜索时如果条件为LIKE只支持字符串", + "selectDataType": "请选择field数据类型", + "selectDictionary": "请选择字典", + "selectSearchType": "请选择Field查询条件", + "enumValue": "枚举值", + "typeLength": "类型长度", "enumExample": "例:'北京','天津'", - "dataTypeLength": "數據庫類型長度", - "enterDefaultValueNote": "請輸入默認值", - "frontendCreateEdit": "前端新建/編輯", + "dataTypeLength": "数据库类型长度", + "enterDefaultValueNote": "请输入默认值", + "frontendCreateEdit": "前端新建/编辑", "frontendTableColmuns": "前端表格列", - "frontendDetails": "前端詳情", + "frontendDetails": "前端详情", "sort": "是否排序", "required": "是否必填", "canBeCleared": "是否可清空", - "hideSearch": "隱藏查詢條件", - "verificationError": "校驗失敗文案", - "dataSourceConfigNote": "數據源配置(此配置為高級配置,如編程基礎不牢,可能導致自動化代碼不可用)", - "associationMode": "關聯模式", + "hideSearch": "隐藏查询条件", + "verificationError": "校验失败文案", + "dataSourceConfigNote": "数据源配置(此配置为高级配置,如编程基础不牢,可能导致自动化代码不可用)", + "dataSourceNameNote": "数据库【不填则为GVA库】", + "associationMode": "关联模式", "oneToOne": "一对一", "oneToMany": "一对多", - "selectDataSourceTable": "請選擇數據源表", - "selectDataToStore": "請先選擇需要存儲的數據", - "storage": "存儲: ", - "type": "類型:", - "fileDesc": ",字段說明:", - "selectDataToDisplay": "請先選擇需要展示的數據", + "selectDataSourceTable": "请选择数据源表", + "selectDataToStore": "请先选择需要存储的数据", + "storage": "存储: ", + "type": "类型:", + "fileDesc": ",字段说明:", + "selectDataToDisplay": "请先选择需要展示的数据", "display": "展示: ", - "enumValueValidationError": "枚舉值校驗錯誤", - "oneToManyNote": "一对多關聯模式下,數據類型會改變為數組,後端表現為json,具體表現為數組模式,是否繼續?", - "string": "字串", + "enumValueValidationError": "枚举值校验错误", + "oneToManyNote": "一对多关联模式下,数据类型会改变为数组,后端表现为json,具体表现为数组模式,是否继续?", + "string": "字符串", "richText": "富文本", - "integer": "整數", - "boolean": "布林", - "float": "浮點數", - "time": "時間", - "enum": "列舉", - "singleImage": "單圖", - "multipleImages": "多圖", - "video": "視頻", + "integer": "整数", + "boolean": "布尔", + "float": "浮点数", + "time": "时间", + "enum": "枚举", + "singleImage": "单图", + "multipleImages": "多图", + "video": "视频", "file": "文件", - "array": "數組" + "array": "数组" } }, + "autoCodeAdmin": { + "structName": "Struct名称", + "structDesc" : "结构体描述", + "deleteHistoryConfirm": "此操作將刪除本歷史, 是否繼續?", + "notRolledBack": "未回滾", + "reuse": "復用", + "rollBack": "回滾", + "rollBackDeleteTable": "回滾(刪表)", + "rollBackWithoutDeleteTable": "回滾(不刪表)", + "rollBackMark": "回滾標記", + "rollbackConfirm": "此操作將刪除自動創建的文件和API, 是否繼續?", + "includeDBTables": "(包含數據庫表!),", + "rollBackContinue": " 是否繼續?", + "rollbackSuccess": "回滾成功", + "rolledBack": "已回滾", + "addField": "增加字段", + "xiaoMiaoIsThinking": "小淼正在思考,请稍候...", + "aiWritingNote": "当前ai帮写存在不稳定因素,生成代码后请注意手动调整部分内容" + }, "autoPkg": { "addSuccess": "添加成功", "autoPkgNote": "此功能為開發環境使用,不建議發布到生產,具體使用效果請看視頻https://www.bilibili.com/video/BV1kv4y1g7nT?p=3", @@ -864,7 +893,9 @@ "addMethodSuccess": "增加方法成功", "deleteFilesNote": "此操作將刪除自動創建的文件和api(會刪除表!!!), 是否繼續?", "deleteFilesConfirmation": "此操作將刪除自動創建的文件和api(會刪除表!!!), 請繼續確認!!!", - "willDeleteTable": "會刪除表" + "willDeleteTable": "會刪除表", + "cannotBeChinese": "不能为中文", + "cannotStartWithNumber": "不能够以数字开头" }, "exportTemplate": { "syncTableExportFeature": "本功能提供同步的表格導出功能,大數據量的異步表格導出功能,可以選擇點我定制", diff --git a/web/src/locales/zh.json b/web/src/locales/zh.json index ee75a21ef..d2ced95fd 100644 --- a/web/src/locales/zh.json +++ b/web/src/locales/zh.json @@ -75,20 +75,6 @@ "roleIdError": "必须为正整数", "": "" }, - "autoCodeAdmin": { - "deleteHistoryConfirm": "此操作将删除本历史, 是否继续?", - "notRolledBack": "未回滚", - "reuse": "复用", - "rollBack": "回滚", - "rollBackDeleteTable": "回滚(删表)", - "rollBackWithoutDeleteTable": "回滚(不删表)", - "rollBackMark": "回滚标记", - "rollbackConfirm": "此操作将删除自动创建的文件和api, 是否继续?", - "includeDBTables": "(包含数据库表!),", - "rollBackContinue": " 是否继续?", - "rollbackSuccess": "回滚成功", - "rolledBack": "已回滚" - }, "error": { "message1": "页面被神秘力量吸走了,请联系我们修复", "message2": "常见问题为当前此角色无当前路由,如果确定要使用本路由,请到角色管理进行分配", @@ -121,7 +107,7 @@ "modify": "修改", "editSuccess": "编辑成功!", "enable": "开启", - "endData": "结束日期", + "endDate": "结束日期", "expand": "展开", "filter": "筛选", "hint": "提示", @@ -544,6 +530,23 @@ "basicPageNote": "此项选择为是,则不会展示左侧菜单以及顶部信息。", "": "" }, + "params": { + "paramName": "参数名称", + "paramKey": "参数键", + "paramValue": "参数值", + "paramDesc": "参数说明", + "enterParamName": "请输入参数名称", + "enterParamKey": "请输入参数键", + "enterParamValue": "请输入参数值", + "enterParamDesc": "请输入参数说明", + "instruction": "使用说明", + "instructionNote1": "前端可以通过引入", + "instructionNote2": "然后通过", + "instructionNote3": "来获取对应的参数。", + "instructionNote4": "后端需要提前", + "instructionNote5": "然后调用", + "instructionNote6": "来获取对应的 value 值。" + }, "user": { "addUser": "新增用户", "anotherUserEdit": "当前存在正在编辑的用户", @@ -821,6 +824,7 @@ "aiNote1": "【完全免费】前往", "aiNote2": "插件市场个人中心", "aiNote3": "申请AIPath,填入config.yaml的ai-path属性即可使用。", + "imageRecognition": "识图", "actionBar": "操作栏:", "autoAPIDBCreate": "自动创建API", "autoAPIDBTip": "注:把自动生成的API注册进数据库", @@ -844,7 +848,8 @@ "entStructDesc": "请输入结构体描述", "entStructName": "请输入结构体名称", "errNoFields": "请填写至少一个field", - "errSameFiledName": "存在与结构体同名的字段", + "errSameFieldName": "存在与结构体同名的字段", + "errJsonFieldNameAsTemplate": "存在与模板同名的的字段JSON", "errSameStructDescAbbr": "structName和struct简称不能相同", "existDB": "点这里从现有数据库创建代码", "field": "字段", @@ -855,6 +860,8 @@ "fileName": "文件名称", "fileNameNote": "生成文件的默认名称(建议为驼峰格式,首字母小写,如sysXxxXxxx)", "generateCode": "生成代码", + "viewCode": "查看代码", + "previewCode": "预览代码", "moveDown": "下移", "moveUp": "上移", "selectDB": "请选择数据库", @@ -868,10 +875,6 @@ "table": "表", "tableName": "表名", "tableNameNote": "指定表名(非必填)", - "aiContent": "小奇存在失败概率,面向所有用户开放使用(失败了重新生成一下就好)。", - "XiaoMiaoDesc": "小淼基本啥也能设计出来,但是需要消耗积分,测试阶段授权用户自动获得基础积分,开源用户需要填表申请。", - "XiaoQi": "小奇", - "XiaoMiao": "小淼", "createdFromDB": "从数据库创建", "businessLibrary": "业务库", "businessLibraryNotice": "注:需要提前到db-list自行配置多数据库,如未配置需配置后重启服务方可使用。(此处可选择对应库表,可理解为从哪个库选择表)", @@ -889,6 +892,8 @@ "templateChoose": "选择模板", "libraryNote": "注:需要提前到db-list自行配置多数据库,此项为空则会使用gva本库创建自动化代码(global.GVA_DB),填写后则会创建指定库的代码(global.MustGetGlobalDBByDBName(dbname))", "useGvaNote": "注:会自动在结构体global.Model其中包含主键和软删除相关操作配置", + "aiClearDataNote": "AI生成会清空当前数据,是否继续?", + "fillJsonDataNote": "请填写树型结构的前端展示json属性", "groupInfos": { "useGvaStructure": "使用GVA结构", "note1": "注:把自动生成的API注册进数据库", @@ -986,6 +991,25 @@ "array": "数组" } }, + "autoCodeAdmin": { + "structName": "结构体名", + "structDesc" : "结构体描述", + "deleteHistoryConfirm": "此操作将删除本历史, 是否继续?", + "notRolledBack": "未回滚", + "reuse": "复用", + "rollBack": "回滚", + "rollBackDeleteTable": "回滚(删表)", + "rollBackWithoutDeleteTable": "回滚(不删表)", + "rollBackMark": "回滚标记", + "rollbackConfirm": "此操作将删除自动创建的文件和api, 是否继续?", + "includeDBTables": "(包含数据库表!),", + "rollBackContinue": " 是否继续?", + "rollbackSuccess": "回滚成功", + "rolledBack": "已回滚", + "addField": "增加字段", + "xiaoMiaoIsThinking": "小淼正在思考,请稍候...", + "aiWritingNote": "当前ai帮写存在不稳定因素,生成代码后请注意手动调整部分内容" + }, "autoPkg": { "addSuccess": "添加成功", "autoPkgNote": "此功能为开发环境使用,不建议发布到生产,具体使用效果请看视频https://www.bilibili.com/video/BV1kv4y1g7nT?p=3", @@ -1010,7 +1034,6 @@ "enterMethodDescription": "请输入方法介绍", "enterMethodName": "请输入方法名", "selectMethod": "请选择方法", - "structName": "结构体名", "frontendFileName": "前端文件名", "backendFileName": "后端文件名", "abbreviation": "缩写", @@ -1020,7 +1043,9 @@ "addMethodSuccess": "增加方法成功", "deleteFilesNote": "此操作将删除自动创建的文件和api(会删除表!!!), 是否继续?", "deleteFilesConfirmation": "此操作将删除自动创建的文件和api(会删除表!!!), 请继续确认!!!", - "willDeleteTable": "会删除表" + "willDeleteTable": "会删除表", + "cannotBeChinese": "不能为中文", + "cannotStartWithNumber": "不能够以数字开头" }, "exportTemplate": { "syncTableExportFeature": "本功能提供同步的表格导出功能,大数据量的异步表格导出功能,可以选择点我定制", @@ -1058,6 +1083,7 @@ "database": "数据库", "gvaLibrary": "GVA库", "templateInfo": "模板信息", + "code": "代码", "addTo": "添加", "templateName2": "模板名称:", "templateNameNote": "请输入模板名称", @@ -1090,7 +1116,17 @@ "selectDBAndTable": "请先选择业务库及选择表后再进行操作", "templateInfoFormatError": "模板信息格式不正确,请检查", "exportConditionError": "请填写完整的导出条件", - "completeAssociationError": "请填写完整的关联" + "completeAssociationError": "请填写完整的关联", + "xiaoMiaoIsThinking": "小淼正在思考...", + "tableToBeUsed": "需用到的表", + "selectWhenUSingAi": "使用AI的情况下请选择", + "aiHelpWriting": "AI帮写", + "aiNote": "试试描述你要做的导出功能让AI帮你完成,在此之前请选择你需要导出的表所在的业务库,如不做选择,则默认使用gva库", + "helpWrite": "帮写", + "autoComplete": "自动补全", + "autoGenerateTemplates": "自动生成模板", + "selectTableToExport": "请先选择需要参与导出的表", + "aiAutoCompleteFail": "AI自动补全失败,已调整为逻辑填写" }, "installPlugin": { "dragOrClickUpload": "拖拽或点击上传", diff --git a/web/src/pathInfo.json b/web/src/pathInfo.json index 45a341ca0..e08798c04 100644 --- a/web/src/pathInfo.json +++ b/web/src/pathInfo.json @@ -1,5 +1,15 @@ { "/src/view/about/index.vue": "About", + "/src/view/dashboard/components/banner.vue": "Banner", + "/src/view/dashboard/components/card.vue": "Card", + "/src/view/dashboard/components/charts-content-numbers.vue": "ChartsContentNumbers", + "/src/view/dashboard/components/charts-people-numbers.vue": "ChartsPeopleNumbers", + "/src/view/dashboard/components/charts.vue": "Charts", + "/src/view/dashboard/components/notice.vue": "Notice", + "/src/view/dashboard/components/pluginTable.vue": "PluginTable", + "/src/view/dashboard/components/quickLinks.vue": "QuickLinks", + "/src/view/dashboard/components/table.vue": "Table", + "/src/view/dashboard/components/wiki.vue": "Wiki", "/src/view/dashboard/index.vue": "Dashboard", "/src/view/error/index.vue": "Error", "/src/view/error/reload.vue": "Reload", @@ -13,7 +23,10 @@ "/src/view/layout/aside/asideComponent/menuItem.vue": "MenuItem", "/src/view/layout/aside/combinationMode.vue": "GvaAside", "/src/view/layout/aside/headMode.vue": "GvaAside", + "/src/view/layout/aside/index.vue": "Index", "/src/view/layout/aside/normalMode.vue": "GvaAside", + "/src/view/layout/header/index.vue": "Index", + "/src/view/layout/header/tools.vue": "Tools", "/src/view/layout/index.vue": "GvaLayout", "/src/view/layout/screenfull/index.vue": "Screenfull", "/src/view/layout/search/search.vue": "BtnBox", @@ -30,6 +43,7 @@ "/src/view/superAdmin/dictionary/sysDictionary.vue": "SysDictionary", "/src/view/superAdmin/dictionary/sysDictionaryDetail.vue": "SysDictionaryDetail", "/src/view/superAdmin/index.vue": "SuperAdmin", + "/src/view/superAdmin/menu/components/components-cascader.vue": "ComponentsCascader", "/src/view/superAdmin/menu/icon.vue": "Icon", "/src/view/superAdmin/menu/menu.vue": "Menus", "/src/view/superAdmin/operation/sysOperationRecord.vue": "SysOperationRecord", @@ -37,12 +51,15 @@ "/src/view/superAdmin/user/user.vue": "User", "/src/view/system/state.vue": "State", "/src/view/systemTools/autoCode/component/fieldDialog.vue": "FieldDialog", + "/src/view/systemTools/autoCode/component/previewCodeDialog.vue": "PreviewCodeDialog", "/src/view/systemTools/autoCode/index.vue": "AutoCode", "/src/view/systemTools/autoCodeAdmin/index.vue": "AutoCodeAdmin", "/src/view/systemTools/autoPkg/autoPkg.vue": "AutoPkg", "/src/view/systemTools/exportTemplate/exportTemplate.vue": "ExportTemplate", "/src/view/systemTools/formCreate/index.vue": "FormGenerator", "/src/view/systemTools/index.vue": "System", + "/src/view/systemTools/installPlugin/index.vue": "Index", + "/src/view/systemTools/pubPlug/pubPlug.vue": "PubPlug", "/src/view/systemTools/system/system.vue": "Config", "/src/plugin/announcement/form/info.vue": "InfoForm", "/src/plugin/announcement/view/info.vue": "Info", diff --git a/web/src/plugin/announcement/view/info.vue b/web/src/plugin/announcement/view/info.vue index c2111b592..27349d973 100644 --- a/web/src/plugin/announcement/view/info.vue +++ b/web/src/plugin/announcement/view/info.vue @@ -13,7 +13,7 @@ — - + diff --git a/web/src/style/element_visiable.scss b/web/src/style/element_visiable.scss index e85342c6c..fad0754e3 100644 --- a/web/src/style/element_visiable.scss +++ b/web/src/style/element_visiable.scss @@ -1,8 +1,9 @@ +@use '@/style/main.scss'; +@use "@/style/reset"; + @tailwind base; @tailwind components; @tailwind utilities; -@import '@/style/main.scss'; -@import "@/style/reset"; .el-button { font-weight: 400; diff --git a/web/src/style/main.scss b/web/src/style/main.scss index 18c5dd906..12318e5ac 100644 --- a/web/src/style/main.scss +++ b/web/src/style/main.scss @@ -1,5 +1,5 @@ -@import '@/style/iconfont.css'; +@use '@/style/iconfont.css'; .html-grey{ filter: grayscale(100%); diff --git a/web/src/style/reset.scss b/web/src/style/reset.scss index d70c71fec..745bcdb07 100644 --- a/web/src/style/reset.scss +++ b/web/src/style/reset.scss @@ -7,7 +7,6 @@ * 2. Prevent adjustments of font size after orientation changes in iOS. */ -@import '@/style/iconfont.css'; html { line-height: 1.15; /* 1 */ diff --git a/web/src/view/about/index.vue b/web/src/view/about/index.vue index f175a704d..1daf5065e 100644 --- a/web/src/view/about/index.vue +++ b/web/src/view/about/index.vue @@ -82,10 +82,10 @@ class="w-8 h-8 rounded-full" :src="item.avatar_url" > - {{ item.login }} + >{{ item.login }} diff --git a/web/src/view/layout/aside/asideComponent/menuItem.vue b/web/src/view/layout/aside/asideComponent/menuItem.vue index b20bbfb60..a43b24afd 100644 --- a/web/src/view/layout/aside/asideComponent/menuItem.vue +++ b/web/src/view/layout/aside/asideComponent/menuItem.vue @@ -1,7 +1,7 @@ - 查询 - 重置 - 展开 - 收起 + {{ t('general.search') }} + {{ t('general.reset') }} + {{ t('general.expand') }} + {{ t('general.collapse') }}
- 新增 - 删除 + {{ t('general.add') }} + {{ t('general.delete') }}
- + - - - - - + + + + + @@ -85,56 +85,57 @@ - - + + - - + + - - + + - - + +
-

使用说明

+

{{ t('view.superAdmin.params.instruction') }}

- 前端可以通过引入 import { getParams } from '@/utils/dictionary' 然后通过 await getParams(key) 来获取对应的参数。 -

-

- 后端可以调用 new(system.SysParamsService).GetSysParam(key) 来获取对应的 value 值。 + {{ t('view.superAdmin.params.instructionNote1') }} import { getParams } from '@/utils/dictionary' {{ t('view.superAdmin.params.instructionNote2') }} await getParams("{{formData.key}}") {{ t('view.superAdmin.params.instructionNote3') }}

- 后端需要提前 import "github.com/flipped-aurora/gin-vue-admin/server/service/system" + {{ t('view.superAdmin.params.instructionNote4') }} import "github.com/flipped-aurora/gin-vue-admin/server/service/system"

+

+ {{ t('view.superAdmin.params.instructionNote5') }} new(system.SysParamsService).GetSysParam("{{formData.key}}") {{ t('view.superAdmin.params.instructionNote6') }} +

+
- + {{ detailFrom.name }} - + {{ detailFrom.key }} - + {{ detailFrom.value }} - + {{ detailFrom.desc }} @@ -157,6 +158,9 @@ import { import { getDictFunc, formatDate, formatBoolean, filterDict ,filterDataSource, returnArrImg, onDownloadFile } from '@/utils/format' import { ElMessage, ElMessageBox } from 'element-plus' import { ref, reactive } from 'vue' +import { useI18n } from 'vue-i18n' // added by mohamed hassan to support multilingual + +const { t } = useI18n() // added by mohamed hassan to support multilingual defineOptions({ name: 'SysParams' @@ -184,7 +188,7 @@ const rule = reactive({ }, { whitespace: true, - message: '不能只输入空格', + message: t('general.noOnlySpace'), trigger: ['input', 'blur'], } ], @@ -195,7 +199,7 @@ const rule = reactive({ }, { whitespace: true, - message: '不能只输入空格', + message: t('general.noOnlySpace'), trigger: ['input', 'blur'], } ], @@ -206,7 +210,7 @@ const rule = reactive({ }, { whitespace: true, - message: '不能只输入空格', + message: t('general.noOnlySpace'), trigger: ['input', 'blur'], } ], @@ -216,11 +220,11 @@ const searchRule = reactive({ createdAt: [ { validator: (rule, value, callback) => { if (searchInfo.value.startCreatedAt && !searchInfo.value.endCreatedAt) { - callback(new Error('请填写结束日期')) + callback(new Error(t('general.placeInputEndData'))) } else if (!searchInfo.value.startCreatedAt && searchInfo.value.endCreatedAt) { - callback(new Error('请填写开始日期')) + callback(new Error(t('general.placeInputStartData'))) } else if (searchInfo.value.startCreatedAt && searchInfo.value.endCreatedAt && (searchInfo.value.startCreatedAt.getTime() === searchInfo.value.endCreatedAt.getTime() || searchInfo.value.startCreatedAt.getTime() > searchInfo.value.endCreatedAt.getTime())) { - callback(new Error('开始日期应当早于结束日期')) + callback(new Error(t('general.startDataMustBeforeEndData'))) } else { callback() } @@ -298,9 +302,9 @@ const handleSelectionChange = (val) => { // 删除行 const deleteRow = (row) => { - ElMessageBox.confirm('确定要删除吗?', '提示', { - confirmButtonText: '确定', - cancelButtonText: '取消', + ElMessageBox.confirm(t('general.deleteConfirm'), t('general.hint'), { + confirmButtonText: t('general.confirm'), + cancelButtonText: t('general.cancel'), type: 'warning' }).then(() => { deleteSysParamsFunc(row) @@ -309,16 +313,16 @@ const deleteRow = (row) => { // 多选删除 const onDelete = async() => { - ElMessageBox.confirm('确定要删除吗?', '提示', { - confirmButtonText: '确定', - cancelButtonText: '取消', + ElMessageBox.confirm(t('general.deleteConfirm'), t('general.hint'), { + confirmButtonText: t('general.confirm'), + cancelButtonText: t('general.cancel'), type: 'warning' }).then(async() => { const IDs = [] if (multipleSelection.value.length === 0) { ElMessage({ type: 'warning', - message: '请选择要删除的数据' + message: t('general.selectDataToDelete') }) return } @@ -330,7 +334,7 @@ const onDelete = async() => { if (res.code === 0) { ElMessage({ type: 'success', - message: '删除成功' + message: t('general.deleteSuccess') }) if (tableData.value.length === IDs.length && page.value > 1) { page.value-- diff --git a/web/src/view/systemTools/autoCode/component/fieldDialog.vue b/web/src/view/systemTools/autoCode/component/fieldDialog.vue index 5b045a8f2..7720305c3 100644 --- a/web/src/view/systemTools/autoCode/component/fieldDialog.vue +++ b/web/src/view/systemTools/autoCode/component/fieldDialog.vue @@ -459,6 +459,7 @@ const getDBTableList = async () => { const dbColumnList = ref([]) const selectDB = async (val,isInit) => { + middleDate.value.dataSource.hasDeletedAt = false middleDate.value.dataSource.table = val const res = await getColumn({ businessDB: middleDate.value.dataSource.dbName, @@ -467,13 +468,18 @@ const selectDB = async (val,isInit) => { if (res.code === 0) { let list = res.data.columns; // 确保这里正确获取到 tables 数组 - dbColumnList.value = list.map(item => ({ - columnName: item.columnName, - value: item.columnName, - type: item.dataType, - isPrimary: item.primaryKey, - comment: item.columnComment - })); + dbColumnList.value = list.map(item => { + if(item.columnName === 'deleted_at'){ + middleDate.value.dataSource.hasDeletedAt = true + } + return{ + columnName: item.columnName, + value: item.columnName, + type: item.dataType, + isPrimary: item.primaryKey, + comment: item.columnComment + } + }); if (dbColumnList.value.length > 0 && !isInit) { middleDate.value.dataSource.label = dbColumnList.value[0].columnName middleDate.value.dataSource.value = dbColumnList.value[0].columnName diff --git a/web/src/view/systemTools/autoCode/component/previewCodeDialg.vue b/web/src/view/systemTools/autoCode/component/previewCodeDialog.vue similarity index 77% rename from web/src/view/systemTools/autoCode/component/previewCodeDialg.vue rename to web/src/view/systemTools/autoCode/component/previewCodeDialog.vue index fa68febb6..cb03178b9 100644 --- a/web/src/view/systemTools/autoCode/component/previewCodeDialg.vue +++ b/web/src/view/systemTools/autoCode/component/previewCodeDialog.vue @@ -1,7 +1,7 @@ @@ -19,14 +19,26 @@ import { Marked } from "marked"; import { markedHighlight } from "marked-highlight"; import hljs from 'highlight.js' import { ElMessage } from 'element-plus' -import { onMounted, ref } from 'vue' +import { onMounted, ref, watchEffect } from 'vue' import {useAppStore} from "@/pinia"; -import { useI18n } from 'vue-i18n' // added by mohamed hassan to support multilanguage +import { useI18n } from 'vue-i18n' // added by mohamed hassan to support multilingual -const { t } = useI18n() // added by mohamed hassan to support multilanguage +const { t } = useI18n() // added by mohamed hassan to support multilingual const appStore = useAppStore() +const useCode = ref({}) + +const createKey = [ + "enter.go", + "gorm_biz.go", + "router_biz.go", + "api", + "router", + "initialize", + "gen.go", +] + onMounted(() => { const isDarkMode = appStore.config.darkMode === 'dark'; if (isDarkMode) { @@ -42,6 +54,19 @@ const props = defineProps({ default() { return {} } + }, + isAdd: { + type: Boolean, + default: false + } +}) + +watchEffect(() => { + for (const key in props.previewCode) { + if (props.isAdd && createKey.some(createKeyItem => key.includes(createKeyItem))) { + continue; + } + useCode.value[key] = props.previewCode[key] } }) @@ -51,7 +76,6 @@ onMounted(() => { markedHighlight({ langPrefix: 'hljs language-', highlight(code, lang, info) { - console.log(code,lang,info) const language = hljs.getLanguage(lang) ? lang : 'plaintext'; if (lang === 'vue') { return hljs.highlight(code, { language: 'html' }).value; @@ -60,11 +84,11 @@ onMounted(() => { } }) ); - for (const key in props.previewCode) { + for (const key in useCode.value) { if (activeName.value === '') { activeName.value = key } - document.getElementById(key).innerHTML = marked.parse(props.previewCode[key]) + document.getElementById(key).innerHTML = marked.parse(useCode.value[key]) } }) diff --git a/web/src/view/systemTools/autoCode/index.vue b/web/src/view/systemTools/autoCode/index.vue index beb3fc75d..186adfa25 100644 --- a/web/src/view/systemTools/autoCode/index.vue +++ b/web/src/view/systemTools/autoCode/index.vue @@ -1,99 +1,135 @@