diff --git a/server/internal/consts/gencodes.go b/server/internal/consts/gencodes.go index 5f87aaa..59272b0 100644 --- a/server/internal/consts/gencodes.go +++ b/server/internal/consts/gencodes.go @@ -3,7 +3,6 @@ // @Copyright Copyright (c) 2023 HotGo CLI // @Author Ms <133814250@qq.com> // @License https://github.com/bufanyun/hotgo/blob/master/LICENSE -// package consts // 生成代码类型 @@ -79,3 +78,18 @@ const ( GenCodesIndexPK = "PRI" // 主键索引 GenCodesIndexUNI = "UNI" // 唯一索引 ) + +// 表格字段显示位置 +const ( + ListShowHide = 1 // 不显示 + ListShowLeft = 2 // 居左显示 + ListShowCenter = 3 // 居中显示 + ListShowRight = 4 // 居右显示 +) + +var ListShowMap = map[int]string{ + ListShowHide: "不显示", + ListShowLeft: "居左显示", + ListShowCenter: "居中显示", + ListShowRight: "居右显示", +} diff --git a/server/internal/library/hggen/hggen.go b/server/internal/library/hggen/hggen.go index 1ae1543..01b3682 100644 --- a/server/internal/library/hggen/hggen.go +++ b/server/internal/library/hggen/hggen.go @@ -6,13 +6,16 @@ package hggen import ( - _ "hotgo/internal/library/hggen/internal/cmd/gendao" + "context" + "sort" _ "unsafe" - "context" + _ "hotgo/internal/library/hggen/internal/cmd/gendao" + "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/util/gconv" + "hotgo/internal/consts" "hotgo/internal/library/addons" "hotgo/internal/library/hggen/internal/cmd" @@ -23,7 +26,6 @@ import ( "hotgo/internal/model/input/form" "hotgo/internal/model/input/sysin" "hotgo/internal/service" - "sort" ) //go:linkname doGenDaoForArray hotgo/internal/library/hggen/internal/cmd/gendao.doGenDaoForArray @@ -130,6 +132,15 @@ func TableSelects(ctx context.Context, in *sysin.GenCodesSelectsInp) (res *sysin }) } + for k, v := range consts.ListShowMap { + res.ListShow = append(res.ListShow, &form.Select{ + Value: k, + Name: v, + Label: v, + }) + } + sort.Sort(res.ListShow) + res.Addons = addons.ModuleSelect() return } diff --git a/server/internal/library/hggen/views/column.go b/server/internal/library/hggen/views/column.go index e8f8a09..9052ea8 100644 --- a/server/internal/library/hggen/views/column.go +++ b/server/internal/library/hggen/views/column.go @@ -8,14 +8,17 @@ package views import ( "context" "fmt" + "strings" + "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/text/gregex" "github.com/gogf/gf/v2/text/gstr" "github.com/gogf/gf/v2/util/gconv" + + "hotgo/internal/consts" "hotgo/internal/library/hggen/internal/cmd/gendao" "hotgo/internal/model/input/sysin" - "strings" ) // DoTableColumns 获取指定表生成字段列表 @@ -40,6 +43,8 @@ func DoTableColumns(ctx context.Context, in *sysin.GenCodesColumnListInp, config } else { CustomAttributes(ctx, field, config) } + field.Width = 80 + field.ListShow = consts.ListShowLeft } return } diff --git a/server/internal/library/hggen/views/column_map.go b/server/internal/library/hggen/views/column_map.go index 43d03da..cd82c1a 100644 --- a/server/internal/library/hggen/views/column_map.go +++ b/server/internal/library/hggen/views/column_map.go @@ -3,11 +3,11 @@ // @Copyright Copyright (c) 2023 HotGo CLI // @Author Ms <133814250@qq.com> // @License https://github.com/bufanyun/hotgo/blob/master/LICENSE -// package views import ( "github.com/gogf/gf/v2/text/gstr" + "hotgo/internal/model/input/sysin" ) @@ -260,3 +260,15 @@ func HasSwitch(headOps []string, masterFields []*sysin.GenCodesColumnListModel) } return HasColumnWithFormMode(masterFields, "Switch") } + +// HasTableSort 是否包含表排序字段 +func HasTableSort(masterFields []*sysin.GenCodesColumnListModel) bool { + for _, field := range masterFields { + isSort := gstr.InArray(field.Attribute, "sort") + if isSort { + return isSort + } + } + + return false +} diff --git a/server/internal/library/hggen/views/curd.go b/server/internal/library/hggen/views/curd.go index d1f1607..da5c46b 100644 --- a/server/internal/library/hggen/views/curd.go +++ b/server/internal/library/hggen/views/curd.go @@ -7,12 +7,9 @@ package views import ( "context" - "github.com/gogf/gf/v2/errors/gerror" - "github.com/gogf/gf/v2/frame/g" - "github.com/gogf/gf/v2/os/gfile" - "github.com/gogf/gf/v2/os/gtime" - "github.com/gogf/gf/v2/os/gview" - "github.com/gogf/gf/v2/text/gstr" + "runtime" + "strings" + "hotgo/internal/consts" "hotgo/internal/library/hggen/internal/cmd/gendao" "hotgo/internal/library/hggen/internal/utility/utils" @@ -20,8 +17,13 @@ import ( "hotgo/internal/model/input/sysin" "hotgo/utility/convert" "hotgo/utility/file" - "runtime" - "strings" + + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gfile" + "github.com/gogf/gf/v2/os/gtime" + "github.com/gogf/gf/v2/os/gview" + "github.com/gogf/gf/v2/text/gstr" ) var Curd = gCurd{} @@ -41,6 +43,7 @@ type CurdStep struct { HasSwitch bool `json:"hasSwitch"` HasCheck bool `json:"hasCheck"` HasMenu bool `json:"hasMenu"` + HasSort bool `json:"hasSort"` } type CurdOptionsJoin struct { @@ -152,6 +155,7 @@ func initStep(in *CurdPreviewInput) { in.options.Step.HasSwitch = HasSwitch(in.options.ColumnOps, in.masterFields) in.options.Step.HasCheck = gstr.InArray(in.options.ColumnOps, "check") in.options.Step.HasMenu = gstr.InArray(in.options.AutoOps, "genMenuPermissions") + in.options.Step.HasSort = HasTableSort(in.masterFields) } func (l *gCurd) loadView(ctx context.Context, in *CurdPreviewInput) (err error) { diff --git a/server/internal/library/hggen/views/curd_generate_logic.go b/server/internal/library/hggen/views/curd_generate_logic.go index fd889d9..60a26bf 100644 --- a/server/internal/library/hggen/views/curd_generate_logic.go +++ b/server/internal/library/hggen/views/curd_generate_logic.go @@ -9,8 +9,10 @@ import ( "bytes" "context" "fmt" + "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/text/gstr" + "hotgo/internal/consts" "hotgo/internal/model/input/sysin" ) @@ -114,6 +116,9 @@ func (l *gCurd) generateLogicEdit(ctx context.Context, in *CurdPreviewInput) g.M func (l *gCurd) generateLogicListOrder(ctx context.Context, in *CurdPreviewInput) string { buffer := bytes.NewBuffer(nil) + if in.options.Step.HasSort { + buffer.WriteString("Handler(handler.Sorter(in)).") + } if in.options.Step.HasMaxSort { buffer.WriteString("OrderAsc(dao." + in.In.DaoName + ".Columns().Sort).") } diff --git a/server/internal/library/hggen/views/curd_generate_web_edit.go b/server/internal/library/hggen/views/curd_generate_web_edit.go index d8edf6d..9a88c5a 100644 --- a/server/internal/library/hggen/views/curd_generate_web_edit.go +++ b/server/internal/library/hggen/views/curd_generate_web_edit.go @@ -9,6 +9,7 @@ import ( "bytes" "context" "fmt" + "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/text/gstr" ) @@ -31,8 +32,18 @@ func (l *gCurd) generateWebEditFormItem(ctx context.Context, in *CurdPreviewInpu continue } + placeholder := fmt.Sprintf("请输入%s", field.Dc) + if len(field.Placeholder) > 0 { + placeholder = field.Placeholder + } + + showCondition := "" + if len(field.ShowCondition) > 0 { + showCondition = fmt.Sprintf(" v-if=\"%s\"", field.ShowCondition) + } + var ( - defaultComponent = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.Dc, field.TsName) + defaultComponent = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, placeholder, field.TsName) component string ) @@ -41,63 +52,63 @@ func (l *gCurd) generateWebEditFormItem(ctx context.Context, in *CurdPreviewInpu component = defaultComponent case FormModeInputNumber: - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.Dc, field.TsName) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, placeholder, field.TsName) case FormModeInputTextarea: - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.Dc, field.TsName) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, placeholder, field.TsName) case FormModeInputEditor: - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName, field.TsName) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, field.TsName, field.TsName) case FormModeInputDynamic: - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, field.TsName) case FormModeDate: - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, field.TsName) // case FormModeDateRange: // 必须要有两个字段,后面优化下 case FormModeTime: - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, field.TsName) // case FormModeTimeRange: // 必须要有两个字段,后面优化下 case FormModeRadio: - component = fmt.Sprintf("\n \n \n \n ", field.Dc, field.TsName, field.TsName, field.TsName, field.TsName, in.options.dictMap[field.TsName], field.TsName, field.TsName, field.TsName) + component = fmt.Sprintf("\n \n \n \n ", showCondition, field.Dc, field.TsName, field.TsName, field.TsName, field.TsName, in.options.dictMap[field.TsName], field.TsName, field.TsName, field.TsName) case FormModeCheckbox: - component = fmt.Sprintf("\n \n \n \n \n \n ", field.Dc, field.TsName, field.TsName, in.options.dictMap[field.TsName]) + component = fmt.Sprintf("\n \n \n \n \n \n ", showCondition, field.Dc, field.TsName, field.TsName, in.options.dictMap[field.TsName]) case FormModeSelect: if in.options.dictMap[field.TsName] != nil { - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName, in.options.dictMap[field.TsName]) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, field.TsName, in.options.dictMap[field.TsName]) } else { - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, field.TsName) } case FormModeSelectMultiple: - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName, in.options.dictMap[field.TsName]) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, field.TsName, in.options.dictMap[field.TsName]) case FormModeUploadImage: - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, field.TsName) case FormModeUploadImages: - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, field.TsName) case FormModeUploadFile: - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, field.TsName) case FormModeUploadFiles: - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, field.TsName) case FormModeSwitch: - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, field.TsName) case FormModeRate: - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName, field.GoName) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, field.TsName, field.GoName) case FormModeCitySelector: - component = fmt.Sprintf("\n \n ", field.Dc, field.TsName, field.TsName) + component = fmt.Sprintf("\n \n ", showCondition, field.Dc, field.TsName, field.TsName) default: component = defaultComponent diff --git a/server/internal/library/hggen/views/curd_generate_web_model.go b/server/internal/library/hggen/views/curd_generate_web_model.go index cfb8055..4323526 100644 --- a/server/internal/library/hggen/views/curd_generate_web_model.go +++ b/server/internal/library/hggen/views/curd_generate_web_model.go @@ -9,8 +9,12 @@ import ( "bytes" "context" "fmt" + "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/text/gstr" + + "hotgo/internal/consts" "hotgo/internal/model/input/sysin" "hotgo/utility/convert" ) @@ -52,6 +56,10 @@ func (l *gCurd) generateWebModelDefaultState(ctx context.Context, in *CurdPrevie } if value == "" { value = "''" + } else { + if field.TsType == consts.ConfigTypeString { + value = fmt.Sprintf("'%s'", value) + } } if field.Name == "status" { value = 1 @@ -256,15 +264,39 @@ func (l *gCurd) generateWebModelColumnsEach(buffer *bytes.Buffer, in *CurdPrevie if !field.IsList { continue } + + ListShowType := "left" + switch field.ListShow { + case consts.ListShowHide: + continue + + case consts.ListShowLeft: + ListShowType = "left" + + case consts.ListShowCenter: + ListShowType = "center" + + case consts.ListShowRight: + ListShowType = "right" + + } + + sorter := "" + if gstr.InArray(field.Attribute, "sort") { + sorter = "\n sorter: true," + } + var ( - defaultComponent = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n },\n", field.Dc, field.TsName) - component string + defaultComponent = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n align: '%s',\n width: %v,%s\n },\n", field.Dc, field.TsName, ListShowType, field.Width, sorter) + // defaultComponent = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n },\n", field.Dc, field.TsName) + component string ) // 这里根据编辑表单组件来进行推断,如果没有则使用默认input,这可能会导致和查询条件所需参数不符的情况 switch field.FormMode { case FormModeDate: - component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n return formatToDate(row.%s);\n },\n },\n", field.Dc, field.TsName, field.TsName) + component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n align: '%s',\n width: %v,%s\n render(row) {\n return formatToDate(row.%s);\n },\n },\n", field.Dc, field.TsName, ListShowType, field.Width, sorter, field.TsName) + // component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n return formatToDate(row.%s);\n },\n },\n", field.Dc, field.TsName, field.TsName) case FormModeRadio: fallthrough @@ -273,32 +305,40 @@ func (l *gCurd) generateWebModelColumnsEach(buffer *bytes.Buffer, in *CurdPrevie err = gerror.Newf("设置单选下拉框选项时,必须选择字典类型,字段名称:%v", field.Name) return } - component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n if (isNullObject(row.%s)) {\n return ``;\n }\n return h(\n NTag,\n {\n style: {\n marginRight: '6px',\n },\n type: getOptionTag(options.value.%s, row.%s),\n bordered: false,\n },\n {\n default: () => getOptionLabel(options.value.%s, row.%s),\n }\n );\n },\n },\n", field.Dc, field.TsName, field.TsName, in.options.dictMap[field.TsName], field.TsName, in.options.dictMap[field.TsName], field.TsName) + component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n align: '%s',\n width: %v,%s\n render(row) {\n if (isNullObject(row.%s)) {\n return ``;\n }\n return h(\n NTag,\n {\n style: {\n marginRight: '6px',\n },\n type: getOptionTag(options.value.%s, row.%s),\n bordered: false,\n },\n {\n default: () => getOptionLabel(options.value.%s, row.%s),\n }\n );\n },\n },\n", field.Dc, field.TsName, ListShowType, field.Width, sorter, field.TsName, in.options.dictMap[field.TsName], field.TsName, in.options.dictMap[field.TsName], field.TsName) + // component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n if (isNullObject(row.%s)) {\n return ``;\n }\n return h(\n NTag,\n {\n style: {\n marginRight: '6px',\n },\n type: getOptionTag(options.value.%s, row.%s),\n bordered: false,\n },\n {\n default: () => getOptionLabel(options.value.%s, row.%s),\n }\n );\n },\n },\n", field.Dc, field.TsName, field.TsName, in.options.dictMap[field.TsName], field.TsName, in.options.dictMap[field.TsName], field.TsName) case FormModeSelectMultiple: if g.IsEmpty(in.options.dictMap[field.TsName]) { err = gerror.Newf("设置多选下拉框选项时,必须选择字典类型,字段名称:%v", field.Name) return } - component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n if (isNullObject(row.%s) || !isArray(row.%s)) {\n return ``;\n }\n return row.%s.map((tagKey) => {\n return h(\n NTag,\n {\n style: {\n marginRight: '6px',\n },\n type: getOptionTag(options.value.%s, tagKey),\n bordered: false,\n },\n {\n default: () => getOptionLabel(options.value.%s, tagKey),\n }\n );\n });\n },\n },\n", field.Dc, field.TsName, field.TsName, field.TsName, field.TsName, in.options.dictMap[field.TsName], in.options.dictMap[field.TsName]) + component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n align: '%s',\n width: %v,%s\n render(row) {\n if (isNullObject(row.%s) || !isArray(row.%s)) {\n return ``;\n }\n return row.%s.map((tagKey) => {\n return h(\n NTag,\n {\n style: {\n marginRight: '6px',\n },\n type: getOptionTag(options.value.%s, tagKey),\n bordered: false,\n },\n {\n default: () => getOptionLabel(options.value.%s, tagKey),\n }\n );\n });\n },\n },\n", field.Dc, field.TsName, ListShowType, field.Width, sorter, field.TsName, field.TsName, field.TsName, in.options.dictMap[field.TsName], in.options.dictMap[field.TsName]) + // component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n if (isNullObject(row.%s) || !isArray(row.%s)) {\n return ``;\n }\n return row.%s.map((tagKey) => {\n return h(\n NTag,\n {\n style: {\n marginRight: '6px',\n },\n type: getOptionTag(options.value.%s, tagKey),\n bordered: false,\n },\n {\n default: () => getOptionLabel(options.value.%s, tagKey),\n }\n );\n });\n },\n },\n", field.Dc, field.TsName, field.TsName, field.TsName, field.TsName, in.options.dictMap[field.TsName], in.options.dictMap[field.TsName]) case FormModeUploadImage: - component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n return h(%s, {\n width: 32,\n height: 32,\n src: row.%s,\n onError: errorImg,\n style: {\n width: '32px',\n height: '32px',\n 'max-width': '100%%',\n 'max-height': '100%%',\n },\n });\n },\n },\n", field.Dc, field.TsName, "NImage", field.TsName) + component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n align: '%s',\n width: %v,%s\n render(row) {\n return h(%s, {\n width: 32,\n height: 32,\n src: row.%s,\n onError: errorImg,\n style: {\n width: '32px',\n height: '32px',\n 'max-width': '100%%',\n 'max-height': '100%%',\n },\n });\n },\n },", field.Dc, field.TsName, ListShowType, field.Width, sorter, "NImage", field.TsName) + // component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n return h(%s, {\n width: 32,\n height: 32,\n src: row.%s,\n onError: errorImg,\n style: {\n width: '32px',\n height: '32px',\n 'max-width': '100%%',\n 'max-height': '100%%',\n },\n });\n },\n },\n", field.Dc, field.TsName, "NImage", field.TsName) case FormModeUploadImages: - component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n if (isNullObject(row.%s)) {\n return ``;\n }\n return row.%s.map((image) => {\n return h(%s, {\n width: 32,\n height: 32,\n src: image,\n onError: errorImg,\n style: {\n width: '32px',\n height: '32px',\n 'max-width': '100%%',\n 'max-height': '100%%',\n 'margin-left': '2px',\n },\n });\n });\n },\n },\n", field.Dc, field.TsName, field.TsName, field.TsName, "NImage") + component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n align: '%s',\n width: %v,%s\n render(row) {\n if (isNullObject(row.%s)) {\n return ``;\n }\n return row.%s.map((image) => {\n return h(%s, {\n width: 32,\n height: 32,\n src: image,\n onError: errorImg,\n style: {\n width: '32px',\n height: '32px',\n 'max-width': '100%%',\n 'max-height': '100%%',\n 'margin-left': '2px',\n },\n });\n });\n },\n },\n", field.Dc, field.TsName, ListShowType, field.Width, sorter, field.TsName, field.TsName, "NImage") + // component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n if (isNullObject(row.%s)) {\n return ``;\n }\n return row.%s.map((image) => {\n return h(%s, {\n width: 32,\n height: 32,\n src: image,\n onError: errorImg,\n style: {\n width: '32px',\n height: '32px',\n 'max-width': '100%%',\n 'max-height': '100%%',\n 'margin-left': '2px',\n },\n });\n });\n },\n },\n", field.Dc, field.TsName, field.TsName, field.TsName, "NImage") case FormModeUploadFile: - component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n if (row.%s === '') {\n return ``;\n }\n return h(\n %s,\n {\n size: 'small',\n },\n {\n default: () => getFileExt(row.%s),\n }\n );\n },\n },\n", field.Dc, field.TsName, field.TsName, "NAvatar", field.TsName) + component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n align: '%s',\n width: %v,%s\n render(row) {\n if (row.%s === '') {\n return ``;\n }\n return h(\n %s,\n {\n size: 'small',\n },\n {\n default: () => getFileExt(row.%s),\n }\n );\n },\n },\n", field.Dc, field.TsName, ListShowType, field.Width, sorter, field.TsName, "NAvatar", field.TsName) + // component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n if (row.%s === '') {\n return ``;\n }\n return h(\n %s,\n {\n size: 'small',\n },\n {\n default: () => getFileExt(row.%s),\n }\n );\n },\n },\n", field.Dc, field.TsName, field.TsName, "NAvatar", field.TsName) case FormModeUploadFiles: - component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n if (isNullObject(row.%s)) {\n return ``;\n }\n return row.%s.map((attachfile) => {\n return h(\n %s,\n {\n size: 'small',\n style: {\n 'margin-left': '2px',\n },\n },\n {\n default: () => getFileExt(attachfile),\n }\n );\n });\n },\n },\n", field.Dc, field.TsName, field.TsName, field.TsName, "NAvatar") + component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n align: '%s',\n width: %v,%s\n render(row) {\n if (isNullObject(row.%s)) {\n return ``;\n }\n return row.%s.map((attachfile) => {\n return h(\n %s,\n {\n size: 'small',\n style: {\n 'margin-left': '2px',\n },\n },\n {\n default: () => getFileExt(attachfile),\n }\n );\n });\n },\n },\n", field.Dc, field.TsName, ListShowType, field.Width, sorter, field.TsName, field.TsName, "NAvatar") + // component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n if (isNullObject(row.%s)) {\n return ``;\n }\n return row.%s.map((attachfile) => {\n return h(\n %s,\n {\n size: 'small',\n style: {\n 'margin-left': '2px',\n },\n },\n {\n default: () => getFileExt(attachfile),\n }\n );\n });\n },\n },\n", field.Dc, field.TsName, field.TsName, field.TsName, "NAvatar") case FormModeSwitch: - component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n width: 100,\n render(row) {\n return h(%s, {\n value: row.%s === 1,\n checked: '开启',\n unchecked: '关闭',\n disabled: !hasPermission(['%s']),\n onUpdateValue: function (e) {\n console.log('onUpdateValue e:' + JSON.stringify(e));\n row.%s = e ? 1 : 2;\n Switch({ %s: row.%s, key: '%s', value: row.%s }).then((_res) => {\n $message.success('操作成功');\n });\n },\n });\n },\n },\n", field.Dc, field.TsName, "NSwitch", field.TsName, "/"+in.options.ApiPrefix+"/switch", field.TsName, in.pk.TsName, in.pk.TsName, field.TsName, field.TsName) + component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n align: '%s',\n width: %v,%s\n render(row) {\n return h(%s, {\n value: row.%s === 1,\n checked: '开启',\n unchecked: '关闭',\n disabled: !hasPermission(['%s']),\n onUpdateValue: function (e) {\n console.log('onUpdateValue e:' + JSON.stringify(e));\n row.%s = e ? 1 : 2;\n Switch({ %s: row.%s, key: '%s', value: row.%s }).then((_res) => {\n $message.success('操作成功');\n });\n },\n });\n },\n },\n", field.Dc, field.TsName, ListShowType, field.Width, sorter, "NSwitch", field.TsName, "/"+in.options.ApiPrefix+"/switch", field.TsName, in.pk.TsName, in.pk.TsName, field.TsName, field.TsName) + // component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n width: 100,\n render(row) {\n return h(%s, {\n value: row.%s === 1,\n checked: '开启',\n unchecked: '关闭',\n disabled: !hasPermission(['%s']),\n onUpdateValue: function (e) {\n console.log('onUpdateValue e:' + JSON.stringify(e));\n row.%s = e ? 1 : 2;\n Switch({ %s: row.%s, key: '%s', value: row.%s }).then((_res) => {\n $message.success('操作成功');\n });\n },\n });\n },\n },\n", field.Dc, field.TsName, "NSwitch", field.TsName, "/"+in.options.ApiPrefix+"/switch", field.TsName, in.pk.TsName, in.pk.TsName, field.TsName, field.TsName) case FormModeRate: - component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n return h(%s, {\n allowHalf: true,\n readonly: true,\n defaultValue: row.%s,\n });\n },\n },\n", field.Dc, field.TsName, "NRate", field.TsName) + component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n align: '%s',\n width: %v,%s\n render(row) {\n return h(%s, {\n allowHalf: true,\n readonly: true,\n defaultValue: row.%s,\n });\n },\n },\n", field.Dc, field.TsName, ListShowType, field.Width, sorter, "NRate", field.TsName) + // component = fmt.Sprintf(" {\n title: '%s',\n key: '%s',\n render(row) {\n return h(%s, {\n allowHalf: true,\n readonly: true,\n defaultValue: row.%s,\n });\n },\n },\n", field.Dc, field.TsName, "NRate", field.TsName) default: component = defaultComponent diff --git a/server/internal/model/gen_codes.go b/server/internal/model/gen_codes.go index 881f1e1..9529edc 100644 --- a/server/internal/model/gen_codes.go +++ b/server/internal/model/gen_codes.go @@ -20,19 +20,24 @@ type GenCodesColumn struct { Extra string `json:"extra" dc:"额外选项"` // 自定义生成属性 // Alias string `json:"alias" dc:"字段别名"` - GoName string `json:"goName" dc:"Go属性"` - GoType string `json:"goType" dc:"Go类型"` - TsName string `json:"tsName" dc:"Ts属性"` - TsType string `json:"tsType" dc:"Ts类型"` - IsList bool `json:"isList" dc:"列表"` - IsExport bool `json:"isExport" dc:"导出"` - IsSort bool `json:"isSort" dc:"排序"` - IsQuery bool `json:"isQuery" dc:"查询"` - QueryWhere string `json:"queryWhere" dc:"查询条件"` - IsEdit bool `json:"isEdit" dc:"编辑"` - Required bool `json:"required" dc:"必填"` - Unique bool `json:"unique" dc:"唯一性"` - FormMode string `json:"formMode" dc:"表单组件"` - FormRole string `json:"formRole" dc:"表单验证"` - DictType int64 `json:"dictType" dc:"字典类型ID"` + GoName string `json:"goName" dc:"Go属性"` + GoType string `json:"goType" dc:"Go类型"` + TsName string `json:"tsName" dc:"Ts属性"` + TsType string `json:"tsType" dc:"Ts类型"` + IsList bool `json:"isList" dc:"列表"` + IsExport bool `json:"isExport" dc:"导出"` + IsSort bool `json:"isSort" dc:"排序"` + IsQuery bool `json:"isQuery" dc:"查询"` + QueryWhere string `json:"queryWhere" dc:"查询条件"` + IsEdit bool `json:"isEdit" dc:"编辑"` + Required bool `json:"required" dc:"必填"` + Unique bool `json:"unique" dc:"唯一性"` + FormMode string `json:"formMode" dc:"表单组件"` + FormRole string `json:"formRole" dc:"表单验证"` + DictType int64 `json:"dictType" dc:"字典类型ID"` + ListShow int64 `json:"listShow" dc:"显示状态"` + Width int64 `json:"width" dc:"单元格宽度"` + Placeholder string `json:"placeholder" dc:"占位符"` + ShowCondition string `json:"showCondition" dc:"显示条件"` + Attribute []string `json:"attribute" dc:"其他属性"` } diff --git a/server/internal/model/input/sysin/gen_codes.go b/server/internal/model/input/sysin/gen_codes.go index 4b79187..e6c1afb 100644 --- a/server/internal/model/input/sysin/gen_codes.go +++ b/server/internal/model/input/sysin/gen_codes.go @@ -7,9 +7,11 @@ package sysin import ( "context" + "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/text/gregex" "github.com/gogf/gf/v2/util/gconv" + "hotgo/internal/consts" "hotgo/internal/model" "hotgo/internal/model/entity" @@ -89,6 +91,7 @@ type GenCodesSelectsModel struct { FormRole form.Selects `json:"formRole" dc:"表单验证"` DictMode []*DictTypeTree `json:"dictMode" dc:"字典类型"` WhereMode form.Selects `json:"whereMode" dc:"查询条件"` + ListShow form.Selects `json:"listShow" dc:"显示位置"` Addons form.Selects `json:"addons" dc:"插件选项"` } diff --git a/server/resource/generate/default/curd/input.go.template b/server/resource/generate/default/curd/input.go.template index 33fe824..1c33687 100644 --- a/server/resource/generate/default/curd/input.go.template +++ b/server/resource/generate/default/curd/input.go.template @@ -70,7 +70,8 @@ type @{.varName}ViewModel struct { // @{.varName}ListInp 获取@{.tableComment}列表 type @{.varName}ListInp struct { - form.PageReq + form.PageReq@{ if eq .options.Step.HasSort true} + form.Sorters@{end} @{.listInpColumns} } diff --git a/server/resource/generate/default/curd/web.index.vue.template b/server/resource/generate/default/curd/web.index.vue.template index 8fc6782..f4fc198 100644 --- a/server/resource/generate/default/curd/web.index.vue.template +++ b/server/resource/generate/default/curd/web.index.vue.template @@ -27,7 +27,8 @@ ref="actionRef" :actionColumn="actionColumn" :checked-row-keys="checkedIds" - @update:checked-row-keys="onCheckedRow" + @update:checked-row-keys="onCheckedRow"@{ if eq .options.Step.HasSort true} + @update:sorter="handleUpdateSorter"@{end} :scroll-x="1090" :resizeHeightOffset="-10000" size="small" @@ -90,7 +91,8 @@ import { useDialog, useMessage } from 'naive-ui'; import { BasicTable, TableAction } from '@/components/Table'; import { BasicForm, useForm } from '@/components/Form/index'; - import { usePermission } from '@/hooks/web/usePermission'; + import { usePermission } from '@/hooks/web/usePermission';@{ if eq .options.Step.HasSort true} + import { useSorter } from '@/hooks/common';@{end} @{.apiImport} import { State, columns, schemas, options, newState } from './model'; @{.iconsImport} @@ -106,7 +108,8 @@ const batchDeleteDisabled = ref(true); const checkedIds = ref([]); const showModal = ref(false); - const formParams = ref(); + const formParams = ref();@{ if eq .options.Step.HasSort true} + const { updateSorter: handleUpdateSorter, sortStatesRef: sortStatesRef } = useSorter(reloadTable);@{end} const actionColumn = reactive({ width: 300, @@ -167,7 +170,11 @@ }); const loadDataTable = async (res) => { - return await List({ ...searchFormRef.value?.formModel, ...res }); + return await List({ + ...searchFormRef.value?.formModel,@{ if eq .options.Step.HasSort true} + ...{ sorters: sortStatesRef.value },@{end} + ...res, + }); }; @{ if eq .options.Step.HasAdd true } function addTable() { diff --git a/web/src/views/apply/attachment/index.vue b/web/src/views/apply/attachment/index.vue index d4d8891..062a8c0 100644 --- a/web/src/views/apply/attachment/index.vue +++ b/web/src/views/apply/attachment/index.vue @@ -176,6 +176,8 @@ negativeText: '取消', onPositiveClick: () => { Delete({ id: checkedIds.value }).then((_res) => { + checkedIds.value = []; + batchDeleteDisabled.value = true; message.success('操作成功'); reloadTable(); }); diff --git a/web/src/views/apply/notice/index.vue b/web/src/views/apply/notice/index.vue index 6696da8..11b62a9 100644 --- a/web/src/views/apply/notice/index.vue +++ b/web/src/views/apply/notice/index.vue @@ -454,6 +454,8 @@ negativeText: '取消', onPositiveClick: () => { Delete({ id: checkedIds.value }).then((_res) => { + checkedIds.value = []; + batchDeleteDisabled.value = true; message.success('操作成功'); reloadTable(); }); diff --git a/web/src/views/asset/rechargeLog/list.vue b/web/src/views/asset/rechargeLog/list.vue index febed7c..8399c63 100644 --- a/web/src/views/asset/rechargeLog/list.vue +++ b/web/src/views/asset/rechargeLog/list.vue @@ -192,6 +192,8 @@ negativeText: '取消', onPositiveClick: () => { Delete({ id: checkedIds.value }).then((_res) => { + checkedIds.value = []; + batchDeleteDisabled.value = true; message.success('删除成功'); reloadTable(); }); diff --git a/web/src/views/develop/code/components/EditField.vue b/web/src/views/develop/code/components/EditField.vue new file mode 100644 index 0000000..0424053 --- /dev/null +++ b/web/src/views/develop/code/components/EditField.vue @@ -0,0 +1,263 @@ + + + + + diff --git a/web/src/views/develop/code/components/EditMasterCell.vue b/web/src/views/develop/code/components/EditMasterCell.vue index 5466683..a64300d 100644 --- a/web/src/views/develop/code/components/EditMasterCell.vue +++ b/web/src/views/develop/code/components/EditMasterCell.vue @@ -14,8 +14,8 @@ ref="actionRef" :canResize="true" :pagination="false" - :scroll-x="3000" :scroll-y="720" + :actionColumn="actionColumn" > diff --git a/web/src/views/log/log/index.vue b/web/src/views/log/log/index.vue index 52e6385..7ccaa07 100644 --- a/web/src/views/log/log/index.vue +++ b/web/src/views/log/log/index.vue @@ -242,6 +242,8 @@ negativeText: '取消', onPositiveClick: () => { Delete({ id: checkedIds.value }).then((_res) => { + checkedIds.value = []; + batchDeleteDisabled.value = true; message.success('操作成功'); reloadTable(); }); diff --git a/web/src/views/log/login-log/index.vue b/web/src/views/log/login-log/index.vue index 98419e8..d99d5a0 100644 --- a/web/src/views/log/login-log/index.vue +++ b/web/src/views/log/login-log/index.vue @@ -154,6 +154,8 @@ negativeText: '取消', onPositiveClick: () => { Delete({ id: checkedIds.value }).then((_res) => { + checkedIds.value = []; + batchDeleteDisabled.value = true; message.success('删除成功'); reloadTable(); }); diff --git a/web/src/views/log/sms-log/index.vue b/web/src/views/log/sms-log/index.vue index 2656371..435323e 100644 --- a/web/src/views/log/sms-log/index.vue +++ b/web/src/views/log/sms-log/index.vue @@ -273,6 +273,8 @@ negativeText: '不确定', onPositiveClick: () => { Delete({ id: checkedIds.value }).then((_res) => { + checkedIds.value = []; + batchDeleteDisabled.value = true; message.success('操作成功'); reloadTable(); }); diff --git a/web/src/views/org/post/post.vue b/web/src/views/org/post/post.vue index 69a1ecf..fcc45c8 100644 --- a/web/src/views/org/post/post.vue +++ b/web/src/views/org/post/post.vue @@ -296,6 +296,8 @@ negativeText: '取消', onPositiveClick: () => { Delete({ id: checkedIds.value }).then((_res) => { + checkedIds.value = []; + batchDeleteDisabled.value = true; message.success('操作成功'); reloadTable(); }); diff --git a/web/src/views/org/user/list.vue b/web/src/views/org/user/list.vue index 995fe93..8551cc6 100644 --- a/web/src/views/org/user/list.vue +++ b/web/src/views/org/user/list.vue @@ -464,6 +464,8 @@ negativeText: '取消', onPositiveClick: () => { Delete({ id: checkedIds.value }).then((_res) => { + checkedIds.value = []; + batchDeleteDisabled.value = true; message.success('操作成功'); reloadTable(); }); diff --git a/web/src/views/system/blacklist/index.vue b/web/src/views/system/blacklist/index.vue index 5f2c185..864af98 100644 --- a/web/src/views/system/blacklist/index.vue +++ b/web/src/views/system/blacklist/index.vue @@ -349,6 +349,8 @@ onPositiveClick: () => { Delete({ id: checkedIds.value }) .then((_res) => { + checkedIds.value = []; + batchDeleteDisabled.value = true; message.success('操作成功'); reloadTable(); }) diff --git a/web/src/views/system/cron/index.vue b/web/src/views/system/cron/index.vue index e7bf797..5bb6e04 100644 --- a/web/src/views/system/cron/index.vue +++ b/web/src/views/system/cron/index.vue @@ -469,6 +469,8 @@ negativeText: '取消', onPositiveClick: () => { Delete({ id: checkedIds.value }).then((_res) => { + checkedIds.value = []; + batchDeleteDisabled.value = true; message.success('操作成功'); reloadTable(); });