From 1e7cf9e65d4f5442dcc5591d95f545216a90627d Mon Sep 17 00:00:00 2001 From: krank Date: Fri, 10 Jan 2025 16:33:59 +0800 Subject: [PATCH 01/13] =?UTF-8?q?feat:=20AI=E8=AF=86=E5=9B=BE=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/pathInfo.json | 1 + web/src/view/systemTools/autoCode/picture.vue | 525 ++++++++++++++++++ web/tailwind.config.js | 102 ++++ 3 files changed, 628 insertions(+) create mode 100644 web/src/view/systemTools/autoCode/picture.vue diff --git a/web/src/pathInfo.json b/web/src/pathInfo.json index e08798c0..9160de6d 100644 --- a/web/src/pathInfo.json +++ b/web/src/pathInfo.json @@ -53,6 +53,7 @@ "/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/autoCode/picture.vue": "Picture", "/src/view/systemTools/autoCodeAdmin/index.vue": "AutoCodeAdmin", "/src/view/systemTools/autoPkg/autoPkg.vue": "AutoPkg", "/src/view/systemTools/exportTemplate/exportTemplate.vue": "ExportTemplate", diff --git a/web/src/view/systemTools/autoCode/picture.vue b/web/src/view/systemTools/autoCode/picture.vue new file mode 100644 index 00000000..ae24d435 --- /dev/null +++ b/web/src/view/systemTools/autoCode/picture.vue @@ -0,0 +1,525 @@ + + + diff --git a/web/tailwind.config.js b/web/tailwind.config.js index 35531e00..58169450 100644 --- a/web/tailwind.config.js +++ b/web/tailwind.config.js @@ -18,6 +18,108 @@ module.exports = { } } }, + safelist: [ + /* + 1) 常见的自定义颜色写法,如 bg-[#xxxxxx]、text-[#xxxxxx]、border-[#xxxxxx] + 如果 LLM/接口频繁返回各种 [#RRGGBB] 形式,这个 pattern 可以保留它们的CSS。 + */ + { pattern: /^bg-\[.*\]$/ }, + { pattern: /^text-\[.*\]$/ }, + { pattern: /^border-\[.*\]$/ }, + + /* + 2) Tailwind 默认调色板里的常见前缀 + 下面以 (red|green|blue|gray|indigo|...) 为例,你可根据自己项目加减。 + 同时包括不同深度 (50,100,200,...,900),也可再详细拆分。 + */ + { + pattern: /^(bg|text|border)-(red|green|blue|gray|indigo|yellow|purple|pink|cyan|teal|orange|amber|lime|emerald|fuchsia|rose|sky|violet|stone|neutral)-(50|100|200|300|400|500|600|700|800|900)$/ + }, + + /* + 3) 大小相关(padding、margin等): + m-*, p-* 以及更精细的 mt-*, mb-*... + 匹配数字、1/2、px、等常见写法(也包括 m-auto)。 + 你可以根据自己需求加减。 + */ + { pattern: /^m-[0-9]+$/ }, + { pattern: /^mx-[0-9]+$/ }, + { pattern: /^my-[0-9]+$/ }, + { pattern: /^mt-[0-9]+$/ }, + { pattern: /^mr-[0-9]+$/ }, + { pattern: /^mb-[0-9]+$/ }, + { pattern: /^ml-[0-9]+$/ }, + { pattern: /^m-(auto|px)$/ }, + + { pattern: /^p-[0-9]+$/ }, + { pattern: /^px-[0-9]+$/ }, + { pattern: /^py-[0-9]+$/ }, + { pattern: /^pt-[0-9]+$/ }, + { pattern: /^pr-[0-9]+$/ }, + { pattern: /^pb-[0-9]+$/ }, + { pattern: /^pl-[0-9]+$/ }, + { pattern: /^p-(auto|px)$/ }, + + /* + 4) 宽高相关: w-*, h-*,以及自定义的 w-[300px]、h-[50vh] 等。 + */ + { pattern: /^w-.*$/ }, + { pattern: /^h-.*$/ }, + + /* + 5) 文本尺寸/排版 + 常见如 text-sm, text-lg, text-xl, text-2xl... 也可加正则覆盖 text-[数字]xl + */ + { pattern: /^text-(xs|sm|base|lg|xl|2xl|3xl|4xl|5xl|6xl)$/ }, + { pattern: /^text-\d+xl$/ }, + + /* + 6) Flex 相关 + */ + "flex", + { pattern: /^flex-(row|col|wrap|nowrap|row-reverse|col-reverse)$/ }, + { pattern: /^items-(start|end|center|baseline|stretch)$/ }, + { pattern: /^justify-(start|end|center|between|around|evenly)$/ }, + { pattern: /^content-(start|end|center|between|around|evenly)$/ }, + + /* + 7) 边框 & 圆角 & 阴影 + */ + { pattern: /^rounded(-(none|sm|md|lg|xl|2xl|3xl|full))?$/ }, + { pattern: /^rounded-[trbl]{1,2}(-(none|sm|md|lg|xl|2xl|3xl|full))?$/ }, // 形如 rounded-t-lg、rounded-bl-md + { pattern: /^shadow(-(sm|md|lg|xl|2xl|inner|none))?$/ }, + { pattern: /^border(-(0|2|4|8))?$/ }, + { pattern: /^border-[trbl]{1,2}(-(0|2|4|8))?$/ }, + + /* + 8) 文本对齐 & 显示模式 + */ + { pattern: /^text-(left|center|right|justify)$/ }, + { pattern: /^(block|inline|inline-block|inline-flex|hidden)$/ }, + + /* + 9) 状态变体(如 hover:, focus:, active: 等) + 允许 hover:bg-red-500、focus:border-blue-500 等 + 这里用 .+ 去捕获前缀后所有东西,不过要小心可能会保留过多无用CSS + */ + { pattern: /^hover:.+$/ }, + { pattern: /^focus:.+$/ }, + { pattern: /^active:.+$/ }, + + /* + 10) 你自己项目中最常出现的其他 patterns (可自行添加): + - z-[数字] + - absolute / relative / fixed / sticky + - top-[数字] / left-[数字] + - grid / gap-[数字] + - ... + */ + // { pattern: /^z-\d+$/ }, + // "absolute", "relative", "fixed", "sticky", + // { pattern: /^top-\[.*\]$/ }, + // { pattern: /^left-\[.*\]$/ }, + // "grid", { pattern: /^gap-\d+$/ }, + ], darkMode: 'class', plugins: [] } From 06ec433b4e106e585bfe8016a571f1d18875295d Mon Sep 17 00:00:00 2001 From: ByteZhou-2018 <1843607154@qq.com> Date: Tue, 18 Mar 2025 21:35:10 +0800 Subject: [PATCH 02/13] Optimize GORM database initialization by extracting duplicate logic --- server/initialize/gorm_mysql.go | 36 +++++++++++++------------------- server/initialize/gorm_oracle.go | 23 +++++++------------- server/initialize/gorm_pgsql.go | 25 +++++++--------------- server/initialize/gorm_sqlite.go | 18 ++++++---------- 4 files changed, 36 insertions(+), 66 deletions(-) diff --git a/server/initialize/gorm_mysql.go b/server/initialize/gorm_mysql.go index 6e496a4d..61e50ba2 100644 --- a/server/initialize/gorm_mysql.go +++ b/server/initialize/gorm_mysql.go @@ -12,18 +12,31 @@ import ( // GormMysql 初始化Mysql数据库 // Author [piexlmax](https://github.com/piexlmax) // Author [SliverHorn](https://github.com/SliverHorn) +// Author [ByteZhou-2018](https://github.com/ByteZhou-2018) func GormMysql() *gorm.DB { m := global.GVA_CONFIG.Mysql + return initMysqlDatabase(m) +} + +// GormMysqlByConfig 通过传入配置初始化Mysql数据库 +func GormMysqlByConfig(m config.Mysql) *gorm.DB { + return initMysqlDatabase(m) +} + +// initMysqlDatabase 初始化Mysql数据库的辅助函数 +func initMysqlDatabase(m config.Mysql) *gorm.DB { if m.Dbname == "" { return nil } + mysqlConfig := mysql.Config{ DSN: m.Dsn(), // DSN data source name DefaultStringSize: 191, // string 类型字段的默认长度 SkipInitializeWithVersion: false, // 根据版本自动配置 } + if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil { - return nil + panic(err) } else { db.InstanceSet("gorm:table_options", "ENGINE="+m.Engine) sqlDB, _ := db.DB() @@ -32,24 +45,3 @@ func GormMysql() *gorm.DB { return db } } - -// GormMysqlByConfig 初始化Mysql数据库用过传入配置 -func GormMysqlByConfig(m config.Mysql) *gorm.DB { - if m.Dbname == "" { - return nil - } - mysqlConfig := mysql.Config{ - DSN: m.Dsn(), // DSN data source name - DefaultStringSize: 191, // string 类型字段的默认长度 - SkipInitializeWithVersion: false, // 根据版本自动配置 - } - if db, err := gorm.Open(mysql.New(mysqlConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil { - panic(err) - } else { - db.InstanceSet("gorm:table_options", "ENGINE=InnoDB") - sqlDB, _ := db.DB() - sqlDB.SetMaxIdleConns(m.MaxIdleConns) - sqlDB.SetMaxOpenConns(m.MaxOpenConns) - return db - } -} diff --git a/server/initialize/gorm_oracle.go b/server/initialize/gorm_oracle.go index 4d18c8a8..513359f0 100644 --- a/server/initialize/gorm_oracle.go +++ b/server/initialize/gorm_oracle.go @@ -15,32 +15,25 @@ import ( // 如果需要Oracle库 放开import里的注释 把下方 mysql.Config 改为 oracle.Config ; mysql.New 改为 oracle.New func GormOracle() *gorm.DB { m := global.GVA_CONFIG.Oracle - if m.Dbname == "" { - return nil - } - oracleConfig := mysql.Config{ - DSN: m.Dsn(), // DSN data source name - DefaultStringSize: 191, // string 类型字段的默认长度 - } - if db, err := gorm.Open(mysql.New(oracleConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil { - panic(err) - } else { - sqlDB, _ := db.DB() - sqlDB.SetMaxIdleConns(m.MaxIdleConns) - sqlDB.SetMaxOpenConns(m.MaxOpenConns) - return db - } + return initOracleDatabase(m) } // GormOracleByConfig 初始化Oracle数据库用过传入配置 func GormOracleByConfig(m config.Oracle) *gorm.DB { + return initOracleDatabase(m) +} + +// initOracleDatabase 初始化Oracle数据库的辅助函数 +func initOracleDatabase(m config.Oracle) *gorm.DB { if m.Dbname == "" { return nil } + oracleConfig := mysql.Config{ DSN: m.Dsn(), // DSN data source name DefaultStringSize: 191, // string 类型字段的默认长度 } + if db, err := gorm.Open(mysql.New(oracleConfig), internal.Gorm.Config(m.Prefix, m.Singular)); err != nil { panic(err) } else { diff --git a/server/initialize/gorm_pgsql.go b/server/initialize/gorm_pgsql.go index 625c8738..9dbcfd91 100644 --- a/server/initialize/gorm_pgsql.go +++ b/server/initialize/gorm_pgsql.go @@ -13,25 +13,16 @@ import ( // Author [SliverHorn](https://github.com/SliverHorn) func GormPgSql() *gorm.DB { p := global.GVA_CONFIG.Pgsql - if p.Dbname == "" { - return nil - } - pgsqlConfig := postgres.Config{ - DSN: p.Dsn(), // DSN data source name - PreferSimpleProtocol: false, - } - if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config(p.Prefix, p.Singular)); err != nil { - return nil - } else { - sqlDB, _ := db.DB() - sqlDB.SetMaxIdleConns(p.MaxIdleConns) - sqlDB.SetMaxOpenConns(p.MaxOpenConns) - return db - } + return initPgSqlDatabase(p) } -// GormPgSqlByConfig 初始化 Postgresql 数据库 通过参数 +// GormPgSqlByConfig 初始化 Postgresql 数据库 通过指定参数 func GormPgSqlByConfig(p config.Pgsql) *gorm.DB { + return initPgSqlDatabase(p) +} + +// initPgSqlDatabase 初始化 Postgresql 数据库的辅助函数 +func initPgSqlDatabase(p config.Pgsql) *gorm.DB { if p.Dbname == "" { return nil } @@ -40,7 +31,7 @@ func GormPgSqlByConfig(p config.Pgsql) *gorm.DB { PreferSimpleProtocol: false, } if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config(p.Prefix, p.Singular)); err != nil { - panic(err) + return nil } else { sqlDB, _ := db.DB() sqlDB.SetMaxIdleConns(p.MaxIdleConns) diff --git a/server/initialize/gorm_sqlite.go b/server/initialize/gorm_sqlite.go index 04126410..9d158bf1 100644 --- a/server/initialize/gorm_sqlite.go +++ b/server/initialize/gorm_sqlite.go @@ -11,22 +11,16 @@ import ( // GormSqlite 初始化Sqlite数据库 func GormSqlite() *gorm.DB { s := global.GVA_CONFIG.Sqlite - if s.Dbname == "" { - return nil - } - - if db, err := gorm.Open(sqlite.Open(s.Dsn()), internal.Gorm.Config(s.Prefix, s.Singular)); err != nil { - panic(err) - } else { - sqlDB, _ := db.DB() - sqlDB.SetMaxIdleConns(s.MaxIdleConns) - sqlDB.SetMaxOpenConns(s.MaxOpenConns) - return db - } + return initSqliteDatabase(s) } // GormSqliteByConfig 初始化Sqlite数据库用过传入配置 func GormSqliteByConfig(s config.Sqlite) *gorm.DB { + return initSqliteDatabase(s) +} + +// initSqliteDatabase 初始化Sqlite数据库辅助函数 +func initSqliteDatabase(s config.Sqlite) *gorm.DB { if s.Dbname == "" { return nil } From 4964518486f812c46fe1c2bd7bf1b7a4c2865071 Mon Sep 17 00:00:00 2001 From: ByteZhou-2018 <1843607154@qq.com> Date: Tue, 18 Mar 2025 21:57:51 +0800 Subject: [PATCH 03/13] fix pgsql return error to panic --- server/initialize/gorm_pgsql.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/initialize/gorm_pgsql.go b/server/initialize/gorm_pgsql.go index 9dbcfd91..6abde589 100644 --- a/server/initialize/gorm_pgsql.go +++ b/server/initialize/gorm_pgsql.go @@ -31,7 +31,7 @@ func initPgSqlDatabase(p config.Pgsql) *gorm.DB { PreferSimpleProtocol: false, } if db, err := gorm.Open(postgres.New(pgsqlConfig), internal.Gorm.Config(p.Prefix, p.Singular)); err != nil { - return nil + panic(err) } else { sqlDB, _ := db.DB() sqlDB.SetMaxIdleConns(p.MaxIdleConns) From 83eb193f1bbd7e7d247e94c79f195602360f84a3 Mon Sep 17 00:00:00 2001 From: huiyifyj Date: Tue, 1 Apr 2025 16:26:31 +0800 Subject: [PATCH 04/13] fix UseWithCtx method to check for nil context - Add nil check for context parameter. - UseWithCtx method return explicit type rather than interface. Replace base64Captcha.Store return type with *RedisStore for better type safety. --- server/utils/captcha/redis.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/server/utils/captcha/redis.go b/server/utils/captcha/redis.go index a13b7cc1..ffb4dbf7 100644 --- a/server/utils/captcha/redis.go +++ b/server/utils/captcha/redis.go @@ -5,7 +5,6 @@ import ( "time" "github.com/flipped-aurora/gin-vue-admin/server/global" - "github.com/mojocn/base64Captcha" "go.uber.org/zap" ) @@ -23,8 +22,10 @@ type RedisStore struct { Context context.Context } -func (rs *RedisStore) UseWithCtx(ctx context.Context) base64Captcha.Store { - rs.Context = ctx +func (rs *RedisStore) UseWithCtx(ctx context.Context) *RedisStore { + if ctx == nil { + rs.Context = ctx + } return rs } From 8bec94336bc266f2dfb20f66a6f4ecb9ddc5609e Mon Sep 17 00:00:00 2001 From: huiyifyj Date: Tue, 1 Apr 2025 16:46:36 +0800 Subject: [PATCH 05/13] test: fix missing `isPackage` argument called method --- server/service/system/auto_code_package_test.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/server/service/system/auto_code_package_test.go b/server/service/system/auto_code_package_test.go index 94285e97..d2a54739 100644 --- a/server/service/system/auto_code_package_test.go +++ b/server/service/system/auto_code_package_test.go @@ -2,10 +2,11 @@ package system import ( "context" - model "github.com/flipped-aurora/gin-vue-admin/server/model/system" - "github.com/flipped-aurora/gin-vue-admin/server/model/system/request" "reflect" "testing" + + model "github.com/flipped-aurora/gin-vue-admin/server/model/system" + "github.com/flipped-aurora/gin-vue-admin/server/model/system/request" ) func Test_autoCodePackage_Create(t *testing.T) { @@ -53,9 +54,10 @@ func Test_autoCodePackage_Create(t *testing.T) { func Test_autoCodePackage_templates(t *testing.T) { type args struct { - ctx context.Context - entity model.SysAutoCodePackage - info request.AutoCode + ctx context.Context + entity model.SysAutoCodePackage + info request.AutoCode + isPackage bool } tests := []struct { name string @@ -78,6 +80,7 @@ func Test_autoCodePackage_templates(t *testing.T) { Abbreviation: "user", HumpPackageName: "user", }, + isPackage: false, }, wantErr: false, }, @@ -85,7 +88,7 @@ func Test_autoCodePackage_templates(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { s := &autoCodePackage{} - gotCode, gotEnter, gotCreates, err := s.templates(tt.args.ctx, tt.args.entity, tt.args.info) + gotCode, gotEnter, gotCreates, err := s.templates(tt.args.ctx, tt.args.entity, tt.args.info, tt.args.isPackage) if (err != nil) != tt.wantErr { t.Errorf("templates() error = %v, wantErr %v", err, tt.wantErr) return From e439bff2bc592cb5da401e4253d0aa254752f292 Mon Sep 17 00:00:00 2001 From: pixelmaxQM Date: Mon, 7 Apr 2025 13:00:14 +0800 Subject: [PATCH 06/13] =?UTF-8?q?feat:=20=E8=B0=83=E6=95=B4=E4=B8=AA?= =?UTF-8?q?=E4=BA=BA=E9=85=8D=E7=BD=AE=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=AF=8F?= =?UTF-8?q?=E6=AC=A1=E6=94=B9=E5=8F=98=E8=87=AA=E5=8A=A8=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=EF=BC=8C=E5=8F=B3=E4=B8=8A=E8=A7=92=E4=BF=9D=E5=AD=98=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E9=87=8D=E7=BD=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/pinia/modules/app.js | 23 ++++++++++++++++++++++- web/src/view/layout/setting/index.vue | 24 +++++++++++++----------- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/web/src/pinia/modules/app.js b/web/src/pinia/modules/app.js index 8b322353..e0858cd5 100644 --- a/web/src/pinia/modules/app.js +++ b/web/src/pinia/modules/app.js @@ -99,6 +99,26 @@ export const useAppStore = defineStore('app', () => { config.transition_type = e } + const baseCoinfg = { + darkMode: 'auto', + primaryColor: '#3b82f6', + show_watermark: false, + grey: false, + weakness: false, + side_mode: 'normal', + showTabs: true, + transition_type: 'fade', + layout_side_width: 200, + layout_side_collapsed_width: 60, + layout_side_item_height: 40 + } + + const resetConfig = () => { + for (let baseCoinfgKey in baseCoinfg) { + config[baseCoinfgKey] = baseCoinfg[baseCoinfgKey] + } + } + // 监听色弱模式和灰色模式 watchEffect(() => { document.documentElement.classList.toggle('html-weakenss', config.weakness) @@ -128,6 +148,7 @@ export const useAppStore = defineStore('app', () => { toggleConfigSideItemHeight, toggleConfigWatermark, toggleSideMode, - toggleTransition + toggleTransition, + resetConfig } }) diff --git a/web/src/view/layout/setting/index.vue b/web/src/view/layout/setting/index.vue index 12a7f2aa..5bbd33cd 100644 --- a/web/src/view/layout/setting/index.vue +++ b/web/src/view/layout/setting/index.vue @@ -9,7 +9,7 @@
@@ -144,6 +144,8 @@ import { ElMessage } from 'element-plus' import { setSelfSetting } from '@/api/user' import Title from './title.vue' + import { watch } from 'vue'; + const appStore = useAppStore() const { config, device } = storeToRefs(appStore) defineOptions({ @@ -185,24 +187,24 @@ ] const saveConfig = async () => { - /*const input = document.createElement("textarea"); - input.value = JSON.stringify(config.value); - // 添加回车 - input.value = input.value.replace(/,/g, ",\n"); - document.body.appendChild(input); - input.select(); - document.execCommand("copy"); - document.body.removeChild(input); - ElMessage.success("复制成功, 请自行保存到本地文件中");*/ const res = await setSelfSetting(config.value) + console.log(config.value) if (res.code === 0) { localStorage.setItem('originSetting', JSON.stringify(config.value)) ElMessage.success('保存成功') - drawer.value = false } } const customColor = ref('') + + const resetConfig = () => { + appStore.resetConfig() + } + + + watch(config, async () => { + await saveConfig(); + }, { deep: true }); + + +
+ diff --git a/web/src/view/systemTools/autoCode/picture.vue b/web/src/view/systemTools/autoCode/picture.vue index ae24d435..8069b8b4 100644 --- a/web/src/view/systemTools/autoCode/picture.vue +++ b/web/src/view/systemTools/autoCode/picture.vue @@ -4,7 +4,7 @@ href="https://www.bilibili.com/video/BV1kv4y1g7nT?p=3" title="此功能为开发环境使用,不建议发布到生产,具体使用效果请点我观看。" /> -