From 5bb211afcd05c0163c50975cc5b8c849a2520337 Mon Sep 17 00:00:00 2001 From: zhangwenjian Date: Sat, 19 Sep 2026 15:18:29 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix=F0=9F=90=9B:=20Preview=20now=20sets=20t?= =?UTF-8?q?ab.MLTBName=20before=20rendering,=20matching=20NOActionsGen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MLTBName (table_name with underscores turned to dashes, e.g. "user_profile" -> "user-profile") is a gorm:"-" field - table.Get never fills it in, the caller has to. NOActionsGen has done so since it existed; Preview never did, so every template's import path that reads it (from '@/api/{PackageName}/{MLTBName}' in vue.go.template, present in both the pre-Vue3 template and F4's rewrite) rendered with the module segment missing - "from '@/api/admin/'" - in the preview dialog only. The real generated file was always correct. Pre-existing, not introduced by this PRD, but worth fixing now: F3/F9 added two more Preview panes (the language packs) on top of an assumption - that Preview's output stands in for what NOActionsGen actually writes - that was never true for this field. Checked the rest of gen.go for the same "only set on the write path" shape; MLTBName is the only one - every other field Preview's templates read comes straight off the sys_tables/sys_columns rows table.Get already loads. Verified with a throwaway harness driving Gen.Preview through a real gin Context and sqlite-backed db, parsing the JSON response and reading back template/vue.go.template's import line. Confirmed red first (temporarily removed the added line): "from '@/api/verify010/'". Restored it: "from '@/api/verify010/verify-widget'". --- app/other/apis/tools/gen.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/other/apis/tools/gen.go b/app/other/apis/tools/gen.go index 49bf3caa..02701620 100644 --- a/app/other/apis/tools/gen.go +++ b/app/other/apis/tools/gen.go @@ -123,6 +123,14 @@ func (e Gen) Preview(c *gin.Context) { } tab, _ := table.Get(db, false) + // MLTBName (table_name with underscores turned to dashes) is a gorm:"-" + // field - table.Get never fills it in, so every template that reads it + // (the .vue/.ts import paths, e.g. "@/api/{PackageName}/{MLTBName}") + // silently rendered it empty here. NOActionsGen has set this since it + // existed (see below); Preview never did, which is why the two paths + // are not interchangeable stand-ins for each other and should not be + // assumed to be. + tab.MLTBName = strings.Replace(tab.TBName, "_", "-", -1) // R2: infer a width for any column the config page left at colWidth's 0 // sentinel, before vue.go.template reads .ColWidth - see column_width.go. applyInferredColumnWidths(tab.Columns) From 30bcb57f41298b8f8028cff1184a6e01cbdc5089 Mon Sep 17 00:00:00 2001 From: zhangwenjian Date: Sat, 19 Sep 2026 15:21:30 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix=F0=9F=90=9B:=20put=20the=20rules=20comp?= =?UTF-8?q?uted's=20comma=20at=20the=20end=20of=20the=20previous=20line?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rules block joined entries with a $first-flag comma the same way defaultQuery and defaultModel do, but on its own line rather than all on one -- so the comma for every entry but the first sat at the start of its line instead of the end of the one before it. @stylistic/comma-style requires the opposite, and pnpm lint fails on any table with two or more required insert fields (one comma is enough to trip it; a table with 0-1 required fields never renders a second entry to get it wrong). Reproduced first: rendering a four-required-field fixture reported three comma-style errors, matching what integration testing found on qa010_widget and qa010_natural. Fixed by moving the separator so it trails the previous entry instead of leading the next one: the else branch now emits ",\n " -- comma, then the newline and indent -- rather than "\n , ", so the comma lands on the line that already has content instead of opening a fresh one. Also fixed while reproducing, found by the same fixture: dictLabel was imported whenever any column had a DictType, but it is only called from the list column's dictionary branch. A table using a dictionary solely in its insert form (no such column in the list) imported dictLabel and never called it, tripping no-unused-vars. $hasDict now only gates useDict; a new $hasDictList gates dictLabel specifically. Verified against three fixtures via a throwaway go-admin-ui worktree (deleted afterwards) with hand-written API-module stubs standing in for F5: the regression fixture (four required fields, confirmed red before the fix, green after), and the two fixtures from the original F4 verification round (full branch coverage, and the all-flags-off edge case), all of which stayed green. pnpm type-check and pnpm lint both ran clean with zero errors, on Node 24.11.0 (this machine's default node is 20.19.0; the project's engines field wants >=22). --- template/v4/vue.go.template | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/template/v4/vue.go.template b/template/v4/vue.go.template index c2c56c9f..72da9422 100644 --- a/template/v4/vue.go.template +++ b/template/v4/vue.go.template @@ -36,6 +36,7 @@ anything outside itself. */ -}} {{- $hasDict := false -}} +{{- $hasDictList := false -}} {{- $hasFk := false -}} {{- $hasDatetime := false -}} {{- $hasRules := false -}} @@ -43,6 +44,7 @@ {{- $pkType := "number" -}} {{- range .Columns -}} {{- if ne .DictType "" }}{{$hasDict = true}}{{end -}} + {{- if and (eq .IsList "1") (eq .FkTableName "") (ne .DictType "") }}{{$hasDictList = true}}{{end -}} {{- if ne .FkTableName "" }}{{$hasFk = true}}{{end -}} {{- if eq .HtmlType "datetime" }}{{$hasDatetime = true}}{{end -}} {{- if eq .IsQuery "1" }}{{$hasQuery = true}}{{end -}} @@ -242,8 +244,12 @@ import ProTable from '@/components/ProTable/index.vue' import DateCell from '@/components/DateCell/index.vue' {{- end}} {{- if $hasDict}} +{{- if $hasDictList}} import { useTable, useForm, useRemove, useDict, dictLabel } from '@/composables' {{- else}} +import { useTable, useForm, useRemove, useDict } from '@/composables' +{{- end}} +{{- else}} import { useTable, useForm, useRemove } from '@/composables' {{- end}} import { @@ -313,12 +319,12 @@ const { t } = useI18n() directly under the labelled field it failed to validate. */}} -const rules = computed(() => ({ - {{- $rFirst := true}} +const rules = computed(() => ({ {{$rFirst := true}} {{- range .Columns}} {{- if and (eq .IsInsert "1") (eq .IsRequired "1") (not .Pk) (ne .GoField "CreatedAt") (ne .GoField "UpdatedAt") (ne .GoField "DeletedAt") (ne .GoField "UpdateBy") (ne .GoField "CreateBy")}} {{- $key := printf "gen.%s.%s.%s" $package $business .JsonField}} - {{if $rFirst}}{{$rFirst = false}}{{else}}, {{end}}{{.JsonField}}: [{ required: true, message: t('{{$key}}'), trigger: '{{if or (eq .HtmlType "select") (eq .HtmlType "radio") (eq .HtmlType "datetime") (eq .HtmlType "checkbox")}}change{{else}}blur{{end}}' }] + {{- if $rFirst}}{{$rFirst = false}}{{else}}, + {{end}}{{.JsonField}}: [{ required: true, message: t('{{$key}}'), trigger: '{{if or (eq .HtmlType "select") (eq .HtmlType "radio") (eq .HtmlType "datetime") (eq .HtmlType "checkbox")}}change{{else}}blur{{end}}' }] {{- end}} {{- end}} }))