fix(qa): ISSUE-005 — 修复 GetAllBusinesses 等 SELECT 查询ID为0的Bug

根因: 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 不追加租户条件)。
This commit is contained in:
lmk
2026-06-17 10:04:25 +08:00
parent 9e283f67a0
commit 9eeb7584b2
+92 -105
View File
@@ -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 获取报表可用字段(按角色分类)