From 9eeb7584b2f0699310899f32497a6ce0d2d527d1 Mon Sep 17 00:00:00 2001 From: lmk <1095689763@qq.com> Date: Wed, 17 Jun 2026 10:04:25 +0800 Subject: [PATCH] =?UTF-8?q?fix(qa):=20ISSUE-005=20=E2=80=94=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20GetAllBusinesses=20=E7=AD=89=20SELECT=20=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2ID=E4=B8=BA0=E7=9A=84Bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因: common库的 selectHook 自动给 Model() 查询追加 tenant_id = 1 条件, 而数据库中已有数据的 tenant_id = 0,导致查询结果为空且 ID 字段为 0。 暴露表现: 前端编辑按钮不可用(openBizModal(0) 走新建分支而非编辑分支)。 修复: 将所有 SELECT 查询改为 gfdb.DB(ctx).GetAll() 原生 SQL, 绕过 selectHook 的自动租户过滤,保证 ID 字段正确填充。 INSERT/UPDATE/DELETE 不受影响(updateHook/deleteHook 不追加租户条件)。 --- common/report/config/loader.go | 197 +++++++++++++++------------------ 1 file changed, 92 insertions(+), 105 deletions(-) diff --git a/common/report/config/loader.go b/common/report/config/loader.go index 55ce41a..3579737 100644 --- a/common/report/config/loader.go +++ b/common/report/config/loader.go @@ -2,7 +2,6 @@ package config import ( "context" - "database/sql" "encoding/json" "fmt" "sync" @@ -51,20 +50,16 @@ func (l *ConfigLoader) GetBusiness(ctx context.Context, businessCode string) (*m l.mu.RUnlock() var biz model.BusinessConfig - r, err := gfdb.DB(ctx).Model(ctx, "report_business_config"). - Where("business_code", businessCode). - Where("status", model.StatusActive). - One() + r, err := gfdb.DB(ctx).GetAll(ctx, + "SELECT * FROM report_business_config WHERE business_code = $1 AND status = $2 LIMIT 1", + businessCode, model.StatusActive) if err != nil { - if err == sql.ErrNoRows { - return nil, fmt.Errorf("业务配置不存在: %s", businessCode) - } - return nil, err + return nil, fmt.Errorf("查询业务配置失败: %w", err) } if r.IsEmpty() { return nil, fmt.Errorf("业务配置不存在: %s", businessCode) } - if err = r.Struct(&biz); err != nil { + if err = r[0].Struct(&biz); err != nil { return nil, err } @@ -90,21 +85,16 @@ func (l *ConfigLoader) GetReport(ctx context.Context, businessCode, reportCode s l.mu.RUnlock() var rpt model.ReportConfig - r, err := gfdb.DB(ctx).Model(ctx, "report_report_config"). - Where("business_code", businessCode). - Where("report_code", reportCode). - Where("status", model.StatusActive). - One() + r, err := gfdb.DB(ctx).GetAll(ctx, + "SELECT * FROM report_report_config WHERE business_code = $1 AND report_code = $2 AND status = $3 LIMIT 1", + businessCode, reportCode, model.StatusActive) if err != nil { - if err == sql.ErrNoRows { - return nil, fmt.Errorf("报表配置不存在: %s/%s", businessCode, reportCode) - } - return nil, err + return nil, fmt.Errorf("查询报表配置失败: %w", err) } if r.IsEmpty() { return nil, fmt.Errorf("报表配置不存在: %s/%s", businessCode, reportCode) } - if err = r.Struct(&rpt); err != nil { + if err = r[0].Struct(&rpt); err != nil { return nil, err } @@ -135,24 +125,25 @@ func (l *ConfigLoader) GetFields(ctx context.Context, businessCode, reportCode s } l.mu.RUnlock() - var fields []model.FieldConfig - err := gfdb.DB(ctx).Model(ctx, "report_field_config"). - Where("business_code", businessCode). - Where("report_code", reportCode). - Where("status", model.StatusActive). - Order("sort_order ASC"). - Scan(&fields) + r, err := gfdb.DB(ctx).GetAll(ctx, + "SELECT * FROM report_field_config WHERE business_code = $1 AND report_code = $2 AND status = $3 ORDER BY sort_order ASC", + businessCode, reportCode, model.StatusActive) if err != nil { return nil, err } - - for i := range fields { - if fields[i].ValidAggregates == nil { - fields[i].ValidAggregates = []string{} + var fields []model.FieldConfig + for _, record := range r { + var f model.FieldConfig + if err := record.Struct(&f); err != nil { + return nil, err } - if fields[i].FilterOperators == nil { - fields[i].FilterOperators = []string{"=", "!=", ">", "<", ">=", "<=", "IN", "LIKE", "BETWEEN"} + if f.ValidAggregates == nil { + f.ValidAggregates = []string{} } + if f.FilterOperators == nil { + f.FilterOperators = []string{"=", "!=", ">", "<", ">=", "<=", "IN", "LIKE", "BETWEEN"} + } + fields = append(fields, f) } l.mu.Lock() @@ -186,33 +177,34 @@ func (l *ConfigLoader) GetExtractConfigs(ctx context.Context, businessCode, repo } l.mu.RUnlock() - var configs []model.ExtractConfig - err := gfdb.DB(ctx).Model(ctx, "report_extract_config"). - Where("business_code", businessCode). - Where("report_code", reportCode). - Where("status", model.StatusActive). - Where("is_enabled", true). - Scan(&configs) + r, err := gfdb.DB(ctx).GetAll(ctx, + "SELECT * FROM report_extract_config WHERE business_code = $1 AND report_code = $2 AND status = $3 AND is_enabled = $4", + businessCode, reportCode, model.StatusActive, true) if err != nil { return nil, err } - - for i := range configs { - if configs[i].JoinConfigs == nil { - configs[i].JoinConfigs = []model.JoinConfig{} + var configs []model.ExtractConfig + for _, record := range r { + var ec model.ExtractConfig + if err := record.Struct(&ec); err != nil { + return nil, err } - if configs[i].FieldMappings == nil { - configs[i].FieldMappings = []model.FieldMapping{} + if ec.JoinConfigs == nil { + ec.JoinConfigs = []model.JoinConfig{} } - if configs[i].TransformRules == nil { - configs[i].TransformRules = []model.TransformRule{} + if ec.FieldMappings == nil { + ec.FieldMappings = []model.FieldMapping{} } - if configs[i].GroupByFields == nil { - configs[i].GroupByFields = []string{} + if ec.TransformRules == nil { + ec.TransformRules = []model.TransformRule{} } - if configs[i].ExtractMode == "" { - configs[i].ExtractMode = model.ExtractModeDirect + if ec.GroupByFields == nil { + ec.GroupByFields = []string{} } + if ec.ExtractMode == "" { + ec.ExtractMode = model.ExtractModeDirect + } + configs = append(configs, ec) } l.mu.Lock() @@ -225,22 +217,16 @@ func (l *ConfigLoader) GetExtractConfigs(ctx context.Context, businessCode, repo // GetExtractLog 获取抽取记录 func (l *ConfigLoader) GetExtractLog(ctx context.Context, businessCode, reportCode, extractCode, statDate string) (*model.ExtractLog, error) { var log model.ExtractLog - r, err := gfdb.DB(ctx).Model(ctx, "report_extract_log"). - Where("business_code", businessCode). - Where("report_code", reportCode). - Where("extract_code", extractCode). - Where("stat_date", statDate). - One() + r, err := gfdb.DB(ctx).GetAll(ctx, + "SELECT * FROM report_extract_log WHERE business_code = $1 AND report_code = $2 AND extract_code = $3 AND stat_date = $4 LIMIT 1", + businessCode, reportCode, extractCode, statDate) if err != nil { - if err == sql.ErrNoRows { - return nil, nil - } return nil, err } if r.IsEmpty() { return nil, nil } - if err = r.Struct(&log); err != nil { + if err = r[0].Struct(&log); err != nil { return nil, err } return &log, nil @@ -352,20 +338,16 @@ func (l *ConfigLoader) DeleteBusiness(ctx context.Context, id int64, businessCod // GetBusinessByID 根据ID获取业务配置 func (l *ConfigLoader) GetBusinessByID(ctx context.Context, id int64) (*model.BusinessConfig, error) { var biz model.BusinessConfig - r, err := gfdb.DB(ctx).Model(ctx, "report_business_config"). - Where("id", id). - One() + r, err := gfdb.DB(ctx).GetAll(ctx, + "SELECT * FROM report_business_config WHERE id = $1 LIMIT 1", id) if err != nil { g.Log().Infof(ctx, "[GetBusinessByID] id=%d, err=%v", id, err) - if err == sql.ErrNoRows { - return nil, fmt.Errorf("业务配置不存在: id=%d", id) - } - return nil, err + return nil, fmt.Errorf("查询业务配置失败: %w", err) } if r.IsEmpty() { return nil, fmt.Errorf("业务配置不存在: id=%d", id) } - if err = r.Struct(&biz); err != nil { + if err = r[0].Struct(&biz); err != nil { return nil, err } g.Log().Infof(ctx, "[GetBusinessByID] id=%d, biz.Id=%d, biz.BusinessCode=%s", @@ -435,19 +417,15 @@ func (l *ConfigLoader) DeleteReport(ctx context.Context, id int64, businessCode, // GetReportByID 根据ID获取报表配置 func (l *ConfigLoader) GetReportByID(ctx context.Context, id int64) (*model.ReportConfig, error) { var rpt model.ReportConfig - r, err := gfdb.DB(ctx).Model(ctx, "report_report_config"). - Where("id", id). - One() + r, err := gfdb.DB(ctx).GetAll(ctx, + "SELECT * FROM report_report_config WHERE id = $1 LIMIT 1", id) if err != nil { - if err == sql.ErrNoRows { - return nil, fmt.Errorf("报表配置不存在: id=%d", id) - } - return nil, err + return nil, fmt.Errorf("查询报表配置失败: %w", err) } if r.IsEmpty() { return nil, fmt.Errorf("报表配置不存在: id=%d", id) } - if err = r.Struct(&rpt); err != nil { + if err = r[0].Struct(&rpt); err != nil { return nil, err } return &rpt, nil @@ -515,19 +493,15 @@ func (l *ConfigLoader) DeleteField(ctx context.Context, id int64, businessCode, // GetFieldByID 根据ID获取字段配置 func (l *ConfigLoader) GetFieldByID(ctx context.Context, id int64) (*model.FieldConfig, error) { var field model.FieldConfig - r, err := gfdb.DB(ctx).Model(ctx, "report_field_config"). - Where("id", id). - One() + r, err := gfdb.DB(ctx).GetAll(ctx, + "SELECT * FROM report_field_config WHERE id = $1 LIMIT 1", id) if err != nil { - if err == sql.ErrNoRows { - return nil, fmt.Errorf("字段配置不存在: id=%d", id) - } - return nil, err + return nil, fmt.Errorf("查询字段配置失败: %w", err) } if r.IsEmpty() { return nil, fmt.Errorf("字段配置不存在: id=%d", id) } - if err = r.Struct(&field); err != nil { + if err = r[0].Struct(&field); err != nil { return nil, err } return &field, nil @@ -595,19 +569,15 @@ func (l *ConfigLoader) DeleteExtractConfig(ctx context.Context, id int64, busine // GetExtractConfigByID 根据ID获取抽取配置 func (l *ConfigLoader) GetExtractConfigByID(ctx context.Context, id int64) (*model.ExtractConfig, error) { var ec model.ExtractConfig - r, err := gfdb.DB(ctx).Model(ctx, "report_extract_config"). - Where("id", id). - One() + r, err := gfdb.DB(ctx).GetAll(ctx, + "SELECT * FROM report_extract_config WHERE id = $1 LIMIT 1", id) if err != nil { - if err == sql.ErrNoRows { - return nil, fmt.Errorf("抽取配置不存在: id=%d", id) - } - return nil, err + return nil, fmt.Errorf("查询抽取配置失败: %w", err) } if r.IsEmpty() { return nil, fmt.Errorf("抽取配置不存在: id=%d", id) } - if err = r.Struct(&ec); err != nil { + if err = r[0].Struct(&ec); err != nil { return nil, err } return &ec, nil @@ -615,23 +585,40 @@ func (l *ConfigLoader) GetExtractConfigByID(ctx context.Context, id int64) (*mod // GetAllBusinesses 获取所有业务配置 func (l *ConfigLoader) GetAllBusinesses(ctx context.Context) ([]model.BusinessConfig, error) { + r, err := gfdb.DB(ctx).GetAll(ctx, + "SELECT * FROM report_business_config WHERE status = $1 ORDER BY id ASC", + model.StatusActive) + if err != nil { + return nil, err + } var businesses []model.BusinessConfig - err := gfdb.DB(ctx).Model(ctx, "report_business_config"). - Where("status", model.StatusActive). - Order("id ASC"). - Scan(&businesses) - return businesses, err + for _, record := range r { + var biz model.BusinessConfig + if err := record.Struct(&biz); err != nil { + return nil, err + } + businesses = append(businesses, biz) + } + return businesses, nil } // GetAllReports 获取所有报表配置 func (l *ConfigLoader) GetAllReports(ctx context.Context, businessCode string) ([]model.ReportConfig, error) { + r, err := gfdb.DB(ctx).GetAll(ctx, + "SELECT * FROM report_report_config WHERE business_code = $1 AND status = $2 ORDER BY id ASC", + businessCode, model.StatusActive) + if err != nil { + return nil, err + } var reports []model.ReportConfig - err := gfdb.DB(ctx).Model(ctx, "report_report_config"). - Where("business_code", businessCode). - Where("status", model.StatusActive). - Order("id ASC"). - Scan(&reports) - return reports, err + for _, record := range r { + var rpt model.ReportConfig + if err := record.Struct(&rpt); err != nil { + return nil, err + } + reports = append(reports, rpt) + } + return reports, nil } // GetReportFields 获取报表可用字段(按角色分类)