fix 优化deleted_by字段的crud生成功能

fix 优化数据`hotgo.sql`文件字段默认值和初始数据
fix 修复web端字典空数据可能引发的潜在问题
This commit is contained in:
孟帅 2024-08-27 19:19:08 +08:00
parent 33e5252516
commit 37b2b82130
14 changed files with 165 additions and 504 deletions

View File

@ -33,6 +33,7 @@ type SysGenCurdDemoColumns struct {
Status string // 状态 Status string // 状态
CreatedBy string // 创建者 CreatedBy string // 创建者
UpdatedBy string // 更新者 UpdatedBy string // 更新者
DeletedBy string // 删除者
CreatedAt string // 创建时间 CreatedAt string // 创建时间
UpdatedAt string // 修改时间 UpdatedAt string // 修改时间
DeletedAt string // 删除时间 DeletedAt string // 删除时间
@ -53,6 +54,7 @@ var sysGenCurdDemoColumns = SysGenCurdDemoColumns{
Status: "status", Status: "status",
CreatedBy: "created_by", CreatedBy: "created_by",
UpdatedBy: "updated_by", UpdatedBy: "updated_by",
DeletedBy: "deleted_by",
CreatedAt: "created_at", CreatedAt: "created_at",
UpdatedAt: "updated_at", UpdatedAt: "updated_at",
DeletedAt: "deleted_at", DeletedAt: "deleted_at",

View File

@ -34,6 +34,7 @@ var defaultEditSwitch = map[string]bool{
"tree": false, "tree": false,
"created_by": false, "created_by": false,
"updated_by": false, "updated_by": false,
"deleted_by": false,
"created_at": false, "created_at": false,
"updated_at": false, "updated_at": false,
"deleted_at": false, "deleted_at": false,

View File

@ -256,7 +256,7 @@ func IsSelectFormMode(formMode string) bool {
func HasColumn(fields []*sysin.GenCodesColumnListModel, column string) bool { func HasColumn(fields []*sysin.GenCodesColumnListModel, column string) bool {
for _, field := range fields { for _, field := range fields {
if field.GoName == column { if field.Name == column {
return true return true
} }
} }
@ -273,14 +273,14 @@ func HasColumnWithFormMode(fields []*sysin.GenCodesColumnListModel, formMode str
} }
func HasMaxSort(fields []*sysin.GenCodesColumnListModel) bool { func HasMaxSort(fields []*sysin.GenCodesColumnListModel) bool {
return HasColumn(fields, "Sort") return HasColumn(fields, "sort")
} }
func HasStatus(headOps []string, fields []*sysin.GenCodesColumnListModel) bool { func HasStatus(headOps []string, fields []*sysin.GenCodesColumnListModel) bool {
if !gstr.InArray(headOps, "status") { if !gstr.InArray(headOps, "status") {
return false return false
} }
return HasColumn(fields, "Status") return HasColumn(fields, "status")
} }
func HasSwitch(fields []*sysin.GenCodesColumnListModel) bool { func HasSwitch(fields []*sysin.GenCodesColumnListModel) bool {

View File

@ -23,6 +23,7 @@ const (
LogicEditUnique = "\t// 验证'%s'唯一\n\tif err = hgorm.IsUnique(ctx, &dao.%s, g.Map{dao.%s.Columns().%s: in.%s}, \"%s已存在\", in.Id); err != nil {\n\t\treturn\n\t}\n" LogicEditUnique = "\t// 验证'%s'唯一\n\tif err = hgorm.IsUnique(ctx, &dao.%s, g.Map{dao.%s.Columns().%s: in.%s}, \"%s已存在\", in.Id); err != nil {\n\t\treturn\n\t}\n"
LogicSwitchUpdate = "g.Map{\n\t\tin.Key: in.Value,\n%s}" LogicSwitchUpdate = "g.Map{\n\t\tin.Key: in.Value,\n%s}"
LogicStatusUpdate = "g.Map{\n\t\tdao.%s.Columns().Status: in.Status,\n%s}" LogicStatusUpdate = "g.Map{\n\t\tdao.%s.Columns().Status: in.Status,\n%s}"
LogicDeletedUpdate = "g.Map{\n%s}"
) )
func (l *gCurd) logicTplData(ctx context.Context, in *CurdPreviewInput) (data g.Map, err error) { func (l *gCurd) logicTplData(ctx context.Context, in *CurdPreviewInput) (data g.Map, err error) {
@ -35,9 +36,31 @@ func (l *gCurd) logicTplData(ctx context.Context, in *CurdPreviewInput) (data g.
data["switchFields"] = l.generateLogicSwitchFields(ctx, in) data["switchFields"] = l.generateLogicSwitchFields(ctx, in)
data["switchUpdate"] = l.generateLogicSwitchUpdate(ctx, in) data["switchUpdate"] = l.generateLogicSwitchUpdate(ctx, in)
data["statusUpdate"] = l.generateLogicStatusUpdate(ctx, in) data["statusUpdate"] = l.generateLogicStatusUpdate(ctx, in)
data["deletedUpdate"] = l.generateLogicDeletedUpdate(ctx, in)
return return
} }
func (l *gCurd) generateLogicDeletedUpdate(ctx context.Context, in *CurdPreviewInput) string {
isDestroy := false
var update string
for _, field := range in.masterFields {
if field.GoName == "DeletedBy" {
update += "\t\tdao." + in.In.DaoName + ".Columns().DeletedBy: contexts.GetUserId(ctx),\n"
isDestroy = true
}
if field.GoName == "DeletedAt" {
update += "\t\tdao." + in.In.DaoName + ".Columns().DeletedAt: gtime.Now(),\n"
}
}
if !isDestroy {
return ""
}
update += "\t"
return fmt.Sprintf(LogicDeletedUpdate, update)
}
func (l *gCurd) generateLogicStatusUpdate(ctx context.Context, in *CurdPreviewInput) string { func (l *gCurd) generateLogicStatusUpdate(ctx context.Context, in *CurdPreviewInput) string {
var update string var update string
for _, field := range in.masterFields { for _, field := range in.masterFields {

View File

@ -81,6 +81,7 @@ var MemberSummary = gdb.HookHandler{
var ( var (
createdByIds []int64 createdByIds []int64
updatedByIds []int64 updatedByIds []int64
deletedByIds []int64
memberIds []int64 memberIds []int64
) )
@ -91,6 +92,9 @@ var MemberSummary = gdb.HookHandler{
if record["updated_by"].Int64() > 0 { if record["updated_by"].Int64() > 0 {
updatedByIds = append(updatedByIds, record["updated_by"].Int64()) updatedByIds = append(updatedByIds, record["updated_by"].Int64())
} }
if record["deleted_by"].Int64() > 0 {
deletedByIds = append(deletedByIds, record["deleted_by"].Int64())
}
if record["member_id"].Int64() > 0 { if record["member_id"].Int64() > 0 {
memberIds = append(memberIds, record["member_id"].Int64()) memberIds = append(memberIds, record["member_id"].Int64())
} }
@ -98,6 +102,7 @@ var MemberSummary = gdb.HookHandler{
memberIds = append(memberIds, createdByIds...) memberIds = append(memberIds, createdByIds...)
memberIds = append(memberIds, updatedByIds...) memberIds = append(memberIds, updatedByIds...)
memberIds = append(memberIds, deletedByIds...)
memberIds = convert.UniqueSlice(memberIds) memberIds = convert.UniqueSlice(memberIds)
if len(memberIds) == 0 { if len(memberIds) == 0 {
return return
@ -128,6 +133,9 @@ var MemberSummary = gdb.HookHandler{
if record["updated_by"].Int64() > 0 { if record["updated_by"].Int64() > 0 {
record["updatedBySumma"] = gvar.New(findMember(record["updated_by"])) record["updatedBySumma"] = gvar.New(findMember(record["updated_by"]))
} }
if record["deleted_by"].Int64() > 0 {
record["deletedBySumma"] = gvar.New(findMember(record["deleted_by"]))
}
if record["member_id"].Int64() > 0 { if record["member_id"].Int64() > 0 {
record["memberBySumma"] = gvar.New(findMember(record["member_id"])) record["memberBySumma"] = gvar.New(findMember(record["member_id"]))
} }

View File

@ -25,6 +25,7 @@ import (
"github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx" "github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv" "github.com/gogf/gf/v2/util/gconv"
) )
@ -161,7 +162,10 @@ func (s *sSysCurdDemo) Edit(ctx context.Context, in *sysin.CurdDemoEditInp) (err
// Delete 删除CURD列表 // Delete 删除CURD列表
func (s *sSysCurdDemo) Delete(ctx context.Context, in *sysin.CurdDemoDeleteInp) (err error) { func (s *sSysCurdDemo) Delete(ctx context.Context, in *sysin.CurdDemoDeleteInp) (err error) {
if _, err = s.Model(ctx).WherePri(in.Id).Delete(); err != nil { if _, err = s.Model(ctx).WherePri(in.Id).Data(g.Map{
dao.SysGenCurdDemo.Columns().DeletedBy: contexts.GetUserId(ctx),
dao.SysGenCurdDemo.Columns().DeletedAt: gtime.Now(),
}).Update(); err != nil {
err = gerror.Wrap(err, "删除CURD列表失败请稍后重试") err = gerror.Wrap(err, "删除CURD列表失败请稍后重试")
return return
} }

View File

@ -25,6 +25,7 @@ type SysGenCurdDemo struct {
Status interface{} // 状态 Status interface{} // 状态
CreatedBy interface{} // 创建者 CreatedBy interface{} // 创建者
UpdatedBy interface{} // 更新者 UpdatedBy interface{} // 更新者
DeletedBy interface{} // 删除者
CreatedAt *gtime.Time // 创建时间 CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 修改时间 UpdatedAt *gtime.Time // 修改时间
DeletedAt *gtime.Time // 删除时间 DeletedAt *gtime.Time // 删除时间

View File

@ -23,6 +23,7 @@ type SysGenCurdDemo struct {
Status int `json:"status" orm:"status" description:"状态"` Status int `json:"status" orm:"status" description:"状态"`
CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者"` CreatedBy int64 `json:"createdBy" orm:"created_by" description:"创建者"`
UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者"` UpdatedBy int64 `json:"updatedBy" orm:"updated_by" description:"更新者"`
DeletedBy int64 `json:"deletedBy" orm:"deleted_by" description:"删除者"`
CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"`
UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"修改时间"` UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"修改时间"`
DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"删除时间"` DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"删除时间"`

View File

@ -27,8 +27,8 @@ type CurdDemoUpdateFields struct {
Image string `json:"image" dc:"单图"` Image string `json:"image" dc:"单图"`
Attachfile string `json:"attachfile" dc:"附件"` Attachfile string `json:"attachfile" dc:"附件"`
CityId int64 `json:"cityId" dc:"所在城市"` CityId int64 `json:"cityId" dc:"所在城市"`
Sort int `json:"sort" dc:"排序"`
Switch int `json:"switch" dc:"显示开关"` Switch int `json:"switch" dc:"显示开关"`
Sort int `json:"sort" dc:"排序"`
UpdatedBy int64 `json:"updatedBy" dc:"更新者"` UpdatedBy int64 `json:"updatedBy" dc:"更新者"`
} }
@ -40,8 +40,8 @@ type CurdDemoInsertFields struct {
Image string `json:"image" dc:"单图"` Image string `json:"image" dc:"单图"`
Attachfile string `json:"attachfile" dc:"附件"` Attachfile string `json:"attachfile" dc:"附件"`
CityId int64 `json:"cityId" dc:"所在城市"` CityId int64 `json:"cityId" dc:"所在城市"`
Sort int `json:"sort" dc:"排序"`
Switch int `json:"switch" dc:"显示开关"` Switch int `json:"switch" dc:"显示开关"`
Sort int `json:"sort" dc:"排序"`
CreatedBy int64 `json:"createdBy" dc:"创建者"` CreatedBy int64 `json:"createdBy" dc:"创建者"`
} }
@ -123,13 +123,13 @@ type CurdDemoListModel struct {
Description string `json:"description" dc:"描述"` Description string `json:"description" dc:"描述"`
Image string `json:"image" dc:"单图"` Image string `json:"image" dc:"单图"`
Attachfile string `json:"attachfile" dc:"附件"` Attachfile string `json:"attachfile" dc:"附件"`
Sort int `json:"sort" dc:"排序"`
Switch int `json:"switch" dc:"显示开关"` Switch int `json:"switch" dc:"显示开关"`
Sort int `json:"sort" dc:"排序"`
CreatedBy int64 `json:"createdBy" dc:"创建者"` CreatedBy int64 `json:"createdBy" dc:"创建者"`
CreatedBySumma *hook.MemberSumma `json:"createdBySumma" dc:"创建者摘要信息"` CreatedBySumma *hook.MemberSumma `json:"createdBySumma" dc:"创建者摘要信息"`
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
UpdatedBy int64 `json:"updatedBy" dc:"更新者"` UpdatedBy int64 `json:"updatedBy" dc:"更新者"`
UpdatedBySumma *hook.MemberSumma `json:"updatedBySumma" dc:"更新者摘要信息"` UpdatedBySumma *hook.MemberSumma `json:"updatedBySumma" dc:"更新者摘要信息"`
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
UpdatedAt *gtime.Time `json:"updatedAt" dc:"修改时间"` UpdatedAt *gtime.Time `json:"updatedAt" dc:"修改时间"`
TestCategoryName string `json:"testCategoryName" dc:"关联分类"` TestCategoryName string `json:"testCategoryName" dc:"关联分类"`
} }
@ -142,11 +142,11 @@ type CurdDemoExportModel struct {
Image string `json:"image" dc:"单图"` Image string `json:"image" dc:"单图"`
Attachfile string `json:"attachfile" dc:"附件"` Attachfile string `json:"attachfile" dc:"附件"`
CityId int64 `json:"cityId" dc:"所在城市"` CityId int64 `json:"cityId" dc:"所在城市"`
Sort int `json:"sort" dc:"排序"`
Switch int `json:"switch" dc:"显示开关"` Switch int `json:"switch" dc:"显示开关"`
Sort int `json:"sort" dc:"排序"`
CreatedBy int64 `json:"createdBy" dc:"创建者"` CreatedBy int64 `json:"createdBy" dc:"创建者"`
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
UpdatedBy int64 `json:"updatedBy" dc:"更新者"` UpdatedBy int64 `json:"updatedBy" dc:"更新者"`
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
TestCategoryName string `json:"testCategoryName" dc:"关联分类"` TestCategoryName string `json:"testCategoryName" dc:"关联分类"`
} }

View File

@ -150,10 +150,15 @@ func (s *s@{.servFunName}) Delete(ctx context.Context, in *@{.templateGroup}in.@
if count > 0 { if count > 0 {
return gerror.New("请先删除该@{.tableComment}下的所有下级!") return gerror.New("请先删除该@{.tableComment}下的所有下级!")
}@{end} }@{end}
@{ if eq .deletedUpdate "" }
if _, err = s.Model(ctx@{ if eq .options.Step.HasNotFilterAuth true } ,&handler.Option{FilterAuth: false}@{end}).WherePri(in.@{.pk.GoName}).Delete();err != nil { if _, err = s.Model(ctx@{ if eq .options.Step.HasNotFilterAuth true } ,&handler.Option{FilterAuth: false}@{end}).WherePri(in.@{.pk.GoName}).Delete();err != nil {
err = gerror.Wrap(err, "删除@{.tableComment}失败,请稍后重试!") err = gerror.Wrap(err, "删除@{.tableComment}失败,请稍后重试!")
return return
} }@{else}
if _, err = s.Model(ctx@{ if eq .options.Step.HasNotFilterAuth true } ,&handler.Option{FilterAuth: false}@{end}).WherePri(in.@{.pk.GoName}).Data(@{.deletedUpdate}).Update();err != nil {
err = gerror.Wrap(err, "删除@{.tableComment}失败,请稍后重试!")
return
}@{end}
return return
}@{end} }@{end}

File diff suppressed because one or more lines are too long

View File

@ -21,11 +21,13 @@ export type FuncDictType = 'testCategoryOption';
// 可以把常用的字典类型加入进来这样会有IDE提示 // 可以把常用的字典类型加入进来这样会有IDE提示
export type DictType = DefaultDictType | EnumsDictType | FuncDictType | string; export type DictType = DefaultDictType | EnumsDictType | FuncDictType | string;
export type DictListClass = 'default' | 'error' | 'primary' | 'info' | 'success' | 'warning';
export interface Option { export interface Option {
label: string; label: string;
value: string | number; value: string | number;
key: string | number; key: string | number;
listClass: 'default' | 'error' | 'primary' | 'info' | 'success' | 'warning'; listClass: DictListClass;
extra: any; extra: any;
} }
@ -88,7 +90,7 @@ export const useDictStore = defineStore({
return local; return local;
} }
const opts = this.options[type] ?? []; const opts = this.options[type] ?? [];
if (opts === undefined || opts?.length === 0) { if (!opts || opts?.length === 0) {
return null; return null;
} }
return opts; return opts;
@ -96,6 +98,9 @@ export const useDictStore = defineStore({
// 获取选项名称 // 获取选项名称
getLabel(type: DictType, value: any) { getLabel(type: DictType, value: any) {
if (value === null || value === undefined) {
return ``;
}
const opts = this.checkOptionValue(type); const opts = this.checkOptionValue(type);
if (!opts) { if (!opts) {
return ``; return ``;
@ -109,10 +114,10 @@ export const useDictStore = defineStore({
}, },
// 获取选项标签类型 // 获取选项标签类型
getType( getType(type: DictType, value: any): DictListClass {
type: DictType, if (value === null || value === undefined) {
value: any return `default`;
): 'default' | 'error' | 'primary' | 'info' | 'success' | 'warning' { }
const opts = this.checkOptionValue(type); const opts = this.checkOptionValue(type);
if (!opts) { if (!opts) {
return `default`; return `default`;
@ -127,6 +132,9 @@ export const useDictStore = defineStore({
// 获取选项额外的数据配置 // 获取选项额外的数据配置
getExtra(type: DictType, value: any): any { getExtra(type: DictType, value: any): any {
if (value === null || value === undefined) {
return null;
}
const opts = this.checkOptionValue(type); const opts = this.checkOptionValue(type);
if (!opts) { if (!opts) {
return null; return null;
@ -141,6 +149,9 @@ export const useDictStore = defineStore({
// 是否存在指定选项值 // 是否存在指定选项值
hasValue(type: DictType, value: any): boolean { hasValue(type: DictType, value: any): boolean {
if (value === null || value === undefined) {
return false;
}
const opts = this.checkOptionValue(type); const opts = this.checkOptionValue(type);
if (!opts) { if (!opts) {
return false; return false;

View File

@ -52,17 +52,17 @@
<CitySelector v-model:value="formValue.cityId" /> <CitySelector v-model:value="formValue.cityId" />
</n-form-item> </n-form-item>
</n-gi> </n-gi>
<n-gi span="1">
<n-form-item label="排序" path="sort">
<n-input-number placeholder="请输入排序" v-model:value="formValue.sort" />
</n-form-item>
</n-gi>
<n-gi span="1"> <n-gi span="1">
<n-form-item label="显示开关" path="switch"> <n-form-item label="显示开关" path="switch">
<n-switch :unchecked-value="2" :checked-value="1" v-model:value="formValue.switch" <n-switch :unchecked-value="2" :checked-value="1" v-model:value="formValue.switch"
/> />
</n-form-item> </n-form-item>
</n-gi> </n-gi>
<n-gi span="1">
<n-form-item label="排序" path="sort">
<n-input-number placeholder="请输入排序" v-model:value="formValue.sort" />
</n-form-item>
</n-gi>
</n-grid> </n-grid>
</n-form> </n-form>
</n-spin> </n-spin>

View File

@ -14,23 +14,24 @@ const $message = window['$message'];
export class State { export class State {
public id = 0; // ID public id = 0; // ID
public categoryId = null; // 测试分类
public title = ''; // 标题 public title = ''; // 标题
public description = ''; // 描述 public description = ''; // 描述
public content = ''; // 内容 public content = ''; // 内容
public image = ''; // 单图 public image = ''; // 单图
public attachfile = ''; // 附件 public attachfile = ''; // 附件
public cityId = null; // 所在城市 public cityId = null; // 所在城市
public sort = 0; // 排序
public switch = 2; // 显示开关 public switch = 2; // 显示开关
public sort = 0; // 排序
public status = 1; // 状态 public status = 1; // 状态
public createdBy = 0; // 创建者 public createdBy = 0; // 创建者
public createdBySumma?: null | MemberSumma = null; // 创建者摘要信息 public createdBySumma?: null | MemberSumma = null; // 创建者摘要信息
public createdAt = ''; // 创建时间
public updatedBy = 0; // 更新者 public updatedBy = 0; // 更新者
public updatedBySumma?: null | MemberSumma = null; // 更新者摘要信息 public updatedBySumma?: null | MemberSumma = null; // 更新者摘要信息
public deletedBy = 0; // 删除者
public createdAt = ''; // 创建时间
public updatedAt = ''; // 修改时间 public updatedAt = ''; // 修改时间
public deletedAt = ''; // 删除时间 public deletedAt = ''; // 删除时间
public categoryId = null; // 测试分类
constructor(state?: Partial<State>) { constructor(state?: Partial<State>) {
if (state) { if (state) {
@ -187,12 +188,6 @@ export const columns = [
return renderFile(row.attachfile); return renderFile(row.attachfile);
}, },
}, },
{
title: '排序',
key: 'sort',
align: 'left',
width: 100,
},
{ {
title: '显示开关', title: '显示开关',
key: 'switch', key: 'switch',
@ -214,6 +209,12 @@ export const columns = [
}); });
}, },
}, },
{
title: '排序',
key: 'sort',
align: 'left',
width: 100,
},
{ {
title: '创建者', title: '创建者',
key: 'createdBy', key: 'createdBy',
@ -223,12 +224,6 @@ export const columns = [
return renderPopoverMemberSumma(row.createdBySumma); return renderPopoverMemberSumma(row.createdBySumma);
}, },
}, },
{
title: '创建时间',
key: 'createdAt',
align: 'left',
width: 180,
},
{ {
title: '更新者', title: '更新者',
key: 'updatedBy', key: 'updatedBy',
@ -238,6 +233,12 @@ export const columns = [
return renderPopoverMemberSumma(row.updatedBySumma); return renderPopoverMemberSumma(row.updatedBySumma);
}, },
}, },
{
title: '创建时间',
key: 'createdAt',
align: 'left',
width: 180,
},
{ {
title: '修改时间', title: '修改时间',
key: 'updatedAt', key: 'updatedAt',