diff --git a/app/user/cmd/api/desc/query/query.api b/app/user/cmd/api/desc/query/query.api index 9441289..2a20a10 100644 --- a/app/user/cmd/api/desc/query/query.api +++ b/app/user/cmd/api/desc/query/query.api @@ -27,15 +27,20 @@ type ( ) type Query { - Id int64 `json:"id"` // 主键ID - OrderId int64 `json:"order_id"` // 订单ID - UserId int64 `json:"user_id"` // 用户ID - ProductName string `json:"product_name"` // 产品ID + Id int64 `json:"id"` // 主键ID + OrderId int64 `json:"order_id"` // 订单ID + UserId int64 `json:"user_id"` // 用户ID + ProductName string `json:"product_name"` // 产品ID QueryParams map[string]interface{} `json:"query_params"` - QueryData []map[string]interface{} `json:"query_data"` - CreateTime string `json:"create_time"` // 创建时间 - UpdateTime string `json:"update_time"` // 更新时间 - QueryState string `json:"query_state"` // 查询状态 + QueryData []QueryItem `json:"query_data"` + CreateTime string `json:"create_time"` // 创建时间 + UpdateTime string `json:"update_time"` // 更新时间 + QueryState string `json:"query_state"` // 查询状态 +} + +type QueryItem { + Feature interface{} `json:"feature"` + Data interface{} `json:"data"` // 这里可以是 map 或 具体的 struct } // 获取查询临时订单 diff --git a/app/user/cmd/api/internal/logic/query/querydetailbyorderidlogic.go b/app/user/cmd/api/internal/logic/query/querydetailbyorderidlogic.go index 0951230..cf1ddac 100644 --- a/app/user/cmd/api/internal/logic/query/querydetailbyorderidlogic.go +++ b/app/user/cmd/api/internal/logic/query/querydetailbyorderidlogic.go @@ -5,6 +5,7 @@ import ( "database/sql" "encoding/hex" "encoding/json" + "fmt" "github.com/jinzhu/copier" "github.com/pkg/errors" "time" @@ -123,6 +124,10 @@ func (l *QueryDetailByOrderIdLogic) QueryDetailByOrderId(req *types.QueryDetailB if processErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 报告结果处理失败: %v", processErr) } + updateFeatureAndProductFeatureErr := l.UpdateFeatureAndProductFeature(queryModel.ProductId, &query.QueryData) + if updateFeatureAndProductFeatureErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 报告结果处理失败: %v", updateFeatureAndProductFeatureErr) + } // 复制报告数据 err = copier.Copy(&query, queryModel) if err != nil { @@ -139,23 +144,96 @@ func (l *QueryDetailByOrderIdLogic) QueryDetailByOrderId(req *types.QueryDetailB } // ProcessQueryData 解密和反序列化 QueryData -func ProcessQueryData(queryData sql.NullString, target *[]map[string]interface{}, key []byte) error { +func ProcessQueryData(queryData sql.NullString, target *[]types.QueryItem, key []byte) error { queryDataStr := lzUtils.NullStringToString(queryData) if queryDataStr == "" { return nil } - // 解密 queryData + + // 解密数据 decryptedData, decryptErr := crypto.AesDecrypt(queryDataStr, key) if decryptErr != nil { return decryptErr } - // 反序列化解密后的数据 - unmarshalErr := json.Unmarshal(decryptedData, target) + // 解析 JSON 数组 + var decryptedArray []map[string]interface{} + unmarshalErr := json.Unmarshal(decryptedData, &decryptedArray) if unmarshalErr != nil { return unmarshalErr } + // 确保 target 具有正确的长度 + if len(*target) == 0 { + *target = make([]types.QueryItem, len(decryptedArray)) + } + + // 填充解密后的数据到 target + for i := 0; i < len(decryptedArray); i++ { + // 直接填充解密数据到 Data 字段 + (*target)[i].Data = decryptedArray[i] + } + return nil +} +func (l *QueryDetailByOrderIdLogic) UpdateFeatureAndProductFeature(productID int64, target *[]types.QueryItem) error { + // 遍历 target 数组,使用倒序遍历,以便删除元素时不影响索引 + for i := len(*target) - 1; i >= 0; i-- { + queryItem := &(*target)[i] + + // 确保 Data 为 map 类型 + data, ok := queryItem.Data.(map[string]interface{}) + if !ok { + return fmt.Errorf("queryItem.Data 必须是 map[string]interface{} 类型") + } + + // 从 Data 中获取 apiID + apiID, ok := data["apiID"].(string) + if !ok { + return fmt.Errorf("queryItem.Data 中的 apiID 必须是字符串类型") + } + + // 查询 Feature + feature, err := l.svcCtx.FeatureModel.FindOneByApiId(l.ctx, apiID) + if err != nil { + // 如果 Feature 查不到,也要删除当前 QueryItem + *target = append((*target)[:i], (*target)[i+1:]...) + continue + } + + // 查询 ProductFeatureModel + builder := l.svcCtx.ProductFeatureModel.SelectBuilder().Where("product_id = ?", productID) + productFeatures, err := l.svcCtx.ProductFeatureModel.FindAll(l.ctx, builder, "") + if err != nil { + return fmt.Errorf("查询 ProductFeatureModel 错误: %v", err) + } + + // 遍历 productFeatures,找到与 feature.ID 关联且 enable == 1 的项 + var featureData map[string]interface{} + foundFeature := false + + for _, pf := range productFeatures { + if pf.FeatureId == feature.Id { // 确保和 Feature 关联 + foundFeature = true + if pf.Enable == 1 { + featureData = map[string]interface{}{ + "featureName": feature.Name, + "sort": pf.Sort, + } + break // 找到第一个符合条件的就退出循环 + } + } + } + + // 如果没有符合条件的 feature 或者 featureData 为空,则删除当前 queryItem + if !foundFeature || featureData == nil { + *target = append((*target)[:i], (*target)[i+1:]...) + continue + } + + // 更新 queryItem 的 Feature 字段(不是数组) + queryItem.Feature = featureData + } + return nil } diff --git a/app/user/cmd/api/internal/logic/query/querydetailbyordernologic.go b/app/user/cmd/api/internal/logic/query/querydetailbyordernologic.go index d5594e4..35dac9f 100644 --- a/app/user/cmd/api/internal/logic/query/querydetailbyordernologic.go +++ b/app/user/cmd/api/internal/logic/query/querydetailbyordernologic.go @@ -3,6 +3,7 @@ package query import ( "context" "encoding/hex" + "fmt" "github.com/jinzhu/copier" "github.com/pkg/errors" "time" @@ -119,6 +120,10 @@ func (l *QueryDetailByOrderNoLogic) QueryDetailByOrderNo(req *types.QueryDetailB if processErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 报告结果处理失败: %v", processErr) } + updateFeatureAndProductFeatureErr := l.UpdateFeatureAndProductFeature(queryModel.ProductId, &query.QueryData) + if updateFeatureAndProductFeatureErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 报告结果处理失败: %v", updateFeatureAndProductFeatureErr) + } // 复制报告数据 err = copier.Copy(&query, queryModel) if err != nil { @@ -133,3 +138,64 @@ func (l *QueryDetailByOrderNoLogic) QueryDetailByOrderNo(req *types.QueryDetailB Query: query, }, nil } +func (l *QueryDetailByOrderNoLogic) UpdateFeatureAndProductFeature(productID int64, target *[]types.QueryItem) error { + // 遍历 target 数组,使用倒序遍历,以便删除元素时不影响索引 + for i := len(*target) - 1; i >= 0; i-- { + queryItem := &(*target)[i] + + // 确保 Data 为 map 类型 + data, ok := queryItem.Data.(map[string]interface{}) + if !ok { + return fmt.Errorf("queryItem.Data 必须是 map[string]interface{} 类型") + } + + // 从 Data 中获取 apiID + apiID, ok := data["apiID"].(string) + if !ok { + return fmt.Errorf("queryItem.Data 中的 apiID 必须是字符串类型") + } + + // 查询 Feature + feature, err := l.svcCtx.FeatureModel.FindOneByApiId(l.ctx, apiID) + if err != nil { + // 如果 Feature 查不到,也要删除当前 QueryItem + *target = append((*target)[:i], (*target)[i+1:]...) + continue + } + + // 查询 ProductFeatureModel + builder := l.svcCtx.ProductFeatureModel.SelectBuilder().Where("product_id = ?", productID) + productFeatures, err := l.svcCtx.ProductFeatureModel.FindAll(l.ctx, builder, "") + if err != nil { + return fmt.Errorf("查询 ProductFeatureModel 错误: %v", err) + } + + // 遍历 productFeatures,找到与 feature.ID 关联且 enable == 1 的项 + var featureData map[string]interface{} + foundFeature := false + + for _, pf := range productFeatures { + if pf.FeatureId == feature.Id { // 确保和 Feature 关联 + foundFeature = true + if pf.Enable == 1 { + featureData = map[string]interface{}{ + "featureName": feature.Name, + "sort": pf.Sort, + } + break // 找到第一个符合条件的就退出循环 + } + } + } + + // 如果没有符合条件的 feature 或者 featureData 为空,则删除当前 queryItem + if !foundFeature || featureData == nil { + *target = append((*target)[:i], (*target)[i+1:]...) + continue + } + + // 更新 queryItem 的 Feature 字段(不是数组) + queryItem.Feature = featureData + } + + return nil +} diff --git a/app/user/cmd/api/internal/logic/query/queryexamplelogic.go b/app/user/cmd/api/internal/logic/query/queryexamplelogic.go index b5c19ef..567adfa 100644 --- a/app/user/cmd/api/internal/logic/query/queryexamplelogic.go +++ b/app/user/cmd/api/internal/logic/query/queryexamplelogic.go @@ -3,6 +3,7 @@ package query import ( "context" "encoding/hex" + "fmt" "github.com/jinzhu/copier" "github.com/pkg/errors" "tydata-server/app/user/cmd/api/internal/svc" @@ -69,6 +70,10 @@ func (l *QueryExampleLogic) QueryExample(req *types.QueryExampleReq) (resp *type if processErr != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "示例报告, 报告结果处理失败: %v", processErr) } + updateFeatureAndProductFeatureErr := l.UpdateFeatureAndProductFeature(queryModel.ProductId, &query.QueryData) + if updateFeatureAndProductFeatureErr != nil { + return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "报告查询, 报告结果处理失败: %v", updateFeatureAndProductFeatureErr) + } // 复制报告数据 err = copier.Copy(&query, queryModel) if err != nil { @@ -83,3 +88,64 @@ func (l *QueryExampleLogic) QueryExample(req *types.QueryExampleReq) (resp *type Query: query, }, nil } +func (l *QueryExampleLogic) UpdateFeatureAndProductFeature(productID int64, target *[]types.QueryItem) error { + // 遍历 target 数组,使用倒序遍历,以便删除元素时不影响索引 + for i := len(*target) - 1; i >= 0; i-- { + queryItem := &(*target)[i] + + // 确保 Data 为 map 类型 + data, ok := queryItem.Data.(map[string]interface{}) + if !ok { + return fmt.Errorf("queryItem.Data 必须是 map[string]interface{} 类型") + } + + // 从 Data 中获取 apiID + apiID, ok := data["apiID"].(string) + if !ok { + return fmt.Errorf("queryItem.Data 中的 apiID 必须是字符串类型") + } + + // 查询 Feature + feature, err := l.svcCtx.FeatureModel.FindOneByApiId(l.ctx, apiID) + if err != nil { + // 如果 Feature 查不到,也要删除当前 QueryItem + *target = append((*target)[:i], (*target)[i+1:]...) + continue + } + + // 查询 ProductFeatureModel + builder := l.svcCtx.ProductFeatureModel.SelectBuilder().Where("product_id = ?", productID) + productFeatures, err := l.svcCtx.ProductFeatureModel.FindAll(l.ctx, builder, "") + if err != nil { + return fmt.Errorf("查询 ProductFeatureModel 错误: %v", err) + } + + // 遍历 productFeatures,找到与 feature.ID 关联且 enable == 1 的项 + var featureData map[string]interface{} + foundFeature := false + + for _, pf := range productFeatures { + if pf.FeatureId == feature.Id { // 确保和 Feature 关联 + foundFeature = true + if pf.Enable == 1 { + featureData = map[string]interface{}{ + "featureName": feature.Name, + "sort": pf.Sort, + } + break // 找到第一个符合条件的就退出循环 + } + } + } + + // 如果没有符合条件的 feature 或者 featureData 为空,则删除当前 queryItem + if !foundFeature || featureData == nil { + *target = append((*target)[:i], (*target)[i+1:]...) + continue + } + + // 更新 queryItem 的 Feature 字段(不是数组) + queryItem.Feature = featureData + } + + return nil +} diff --git a/app/user/cmd/api/internal/service/apirequestService.go b/app/user/cmd/api/internal/service/apirequestService.go index 58da4b0..0d8d18f 100644 --- a/app/user/cmd/api/internal/service/apirequestService.go +++ b/app/user/cmd/api/internal/service/apirequestService.go @@ -59,8 +59,10 @@ func (a *ApiRequestService) ProcessRequests(params []byte, productID int64) ([]b return nil, findProductFeatureErr } var featureIDs []int64 + isImportantMap := make(map[int64]int64, len(productFeatureList)) for _, pf := range productFeatureList { featureIDs = append(featureIDs, pf.FeatureId) + isImportantMap[pf.FeatureId] = pf.IsImportant } if len(featureIDs) == 0 { return nil, errors.New("featureIDs 是空的") @@ -79,6 +81,7 @@ func (a *ApiRequestService) ProcessRequests(params []byte, productID int64) ([]b errorsCh = make(chan error, len(featureList)) errorCount int32 errorLimit = len(featureList) + retryNum = 5 ) for i, feature := range featureList { @@ -95,9 +98,26 @@ func (a *ApiRequestService) ProcessRequests(params []byte, productID int64) ([]b ApiID: feature.ApiId, Success: false, } - // 请求参数预处理 - resp, preprocessErr := a.PreprocessRequestApi(params, feature.ApiId) timestamp := time.Now().Format("2006-01-02 15:04:05") + var ( + resp json.RawMessage + preprocessErr error + ) + // 若 isImportantMap[feature.ID] == 1,则表示需要在出错时重试 + isImportant := isImportantMap[feature.Id] == 1 + tryCount := 0 + for { + tryCount++ + resp, preprocessErr = a.PreprocessRequestApi(params, feature.ApiId) + if preprocessErr == nil { + break + } + if isImportant && tryCount < retryNum { + continue + } else { + break + } + } if preprocessErr != nil { result.Timestamp = timestamp result.Error = preprocessErr.Error() @@ -123,7 +143,7 @@ func (a *ApiRequestService) ProcessRequests(params []byte, productID int64) ([]b close(resultsCh) close(errorsCh) }() - // 收集所有结果并合并 + // 收集所有结果并合并z var responseData []APIResponseData for result := range resultsCh { responseData = append(responseData, result) diff --git a/app/user/cmd/api/internal/types/types.go b/app/user/cmd/api/internal/types/types.go index a9c729e..68953b7 100644 --- a/app/user/cmd/api/internal/types/types.go +++ b/app/user/cmd/api/internal/types/types.go @@ -82,15 +82,15 @@ type ProductResponse struct { } type Query struct { - Id int64 `json:"id"` // 主键ID - OrderId int64 `json:"order_id"` // 订单ID - UserId int64 `json:"user_id"` // 用户ID - ProductName string `json:"product_name"` // 产品ID - QueryParams map[string]interface{} `json:"query_params"` - QueryData []map[string]interface{} `json:"query_data"` - CreateTime string `json:"create_time"` // 创建时间 - UpdateTime string `json:"update_time"` // 更新时间 - QueryState string `json:"query_state"` // 查询状态 + Id int64 `json:"id"` // 主键ID + OrderId int64 `json:"order_id"` // 订单ID + UserId int64 `json:"user_id"` // 用户ID + ProductName string `json:"product_name"` // 产品ID + QueryParams map[string]interface{} `json:"query_params"` + QueryData []QueryItem `json:"query_data"` + CreateTime string `json:"create_time"` // 创建时间 + UpdateTime string `json:"update_time"` // 更新时间 + QueryState string `json:"query_state"` // 查询状态 } type QueryDetailByOrderIdReq struct { @@ -125,6 +125,11 @@ type QueryExampleResp struct { Query } +type QueryItem struct { + Feature interface{} `json:"feature"` + Data interface{} `json:"data"` // 这里可以是 map 或 具体的 struct +} + type QueryListReq struct { Page int64 `form:"page"` // 页码 PageSize int64 `form:"page_size"` // 每页数据量 diff --git a/app/user/model/productFeatureModel_gen.go b/app/user/model/productFeatureModel_gen.go index 1f11798..9a2bd1e 100644 --- a/app/user/model/productFeatureModel_gen.go +++ b/app/user/model/productFeatureModel_gen.go @@ -7,7 +7,6 @@ import ( "database/sql" "fmt" "strings" - model2 "tydata-server/deploy/script/model" "time" @@ -57,14 +56,17 @@ type ( } ProductFeature struct { - Id int64 `db:"id"` // 主键ID - ProductId int64 `db:"product_id"` // 产品ID - FeatureId int64 `db:"feature_id"` // 功能ID - CreateTime time.Time `db:"create_time"` // 创建时间 - UpdateTime time.Time `db:"update_time"` // 更新时间 - DeleteTime sql.NullTime `db:"delete_time"` // 删除时间 - DelState int64 `db:"del_state"` // 删除状态 - Version int64 `db:"version"` // 版本号 + Id int64 `db:"id"` // 主键ID + ProductId int64 `db:"product_id"` // 产品ID + FeatureId int64 `db:"feature_id"` // 功能ID + CreateTime time.Time `db:"create_time"` // 创建时间 + UpdateTime time.Time `db:"update_time"` // 更新时间 + DeleteTime sql.NullTime `db:"delete_time"` // 删除时间 + DelState int64 `db:"del_state"` // 删除状态 + Version int64 `db:"version"` // 版本号 + Sort int64 `db:"sort"` + IsImportant int64 `db:"is_important"` + Enable int64 `db:"enable"` } ) @@ -80,11 +82,11 @@ func (m *defaultProductFeatureModel) Insert(ctx context.Context, session sqlx.Se tydataProductFeatureIdKey := fmt.Sprintf("%s%v", cacheTydataProductFeatureIdPrefix, data.Id) tydataProductFeatureProductIdFeatureIdKey := fmt.Sprintf("%s%v:%v", cacheTydataProductFeatureProductIdFeatureIdPrefix, data.ProductId, data.FeatureId) return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { - query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?)", m.table, productFeatureRowsExpectAutoSet) + query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?)", m.table, productFeatureRowsExpectAutoSet) if session != nil { - return session.ExecCtx(ctx, query, data.ProductId, data.FeatureId, data.DeleteTime, data.DelState, data.Version) + return session.ExecCtx(ctx, query, data.ProductId, data.FeatureId, data.DeleteTime, data.DelState, data.Version, data.Sort, data.IsImportant, data.Enable) } - return conn.ExecCtx(ctx, query, data.ProductId, data.FeatureId, data.DeleteTime, data.DelState, data.Version) + return conn.ExecCtx(ctx, query, data.ProductId, data.FeatureId, data.DeleteTime, data.DelState, data.Version, data.Sort, data.IsImportant, data.Enable) }, tydataProductFeatureIdKey, tydataProductFeatureProductIdFeatureIdKey) } @@ -99,7 +101,7 @@ func (m *defaultProductFeatureModel) FindOne(ctx context.Context, id int64) (*Pr case nil: return &resp, nil case sqlc.ErrNotFound: - return nil, model2.ErrNotFound + return nil, ErrNotFound default: return nil, err } @@ -119,7 +121,7 @@ func (m *defaultProductFeatureModel) FindOneByProductIdFeatureId(ctx context.Con case nil: return &resp, nil case sqlc.ErrNotFound: - return nil, model2.ErrNotFound + return nil, ErrNotFound default: return nil, err } @@ -135,9 +137,9 @@ func (m *defaultProductFeatureModel) Update(ctx context.Context, session sqlx.Se return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, productFeatureRowsWithPlaceHolder) if session != nil { - return session.ExecCtx(ctx, query, newData.ProductId, newData.FeatureId, newData.DeleteTime, newData.DelState, newData.Version, newData.Id) + return session.ExecCtx(ctx, query, newData.ProductId, newData.FeatureId, newData.DeleteTime, newData.DelState, newData.Version, newData.Sort, newData.IsImportant, newData.Enable, newData.Id) } - return conn.ExecCtx(ctx, query, newData.ProductId, newData.FeatureId, newData.DeleteTime, newData.DelState, newData.Version, newData.Id) + return conn.ExecCtx(ctx, query, newData.ProductId, newData.FeatureId, newData.DeleteTime, newData.DelState, newData.Version, newData.Sort, newData.IsImportant, newData.Enable, newData.Id) }, tydataProductFeatureIdKey, tydataProductFeatureProductIdFeatureIdKey) } @@ -158,9 +160,9 @@ func (m *defaultProductFeatureModel) UpdateWithVersion(ctx context.Context, sess sqlResult, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { query := fmt.Sprintf("update %s set %s where `id` = ? and version = ? ", m.table, productFeatureRowsWithPlaceHolder) if session != nil { - return session.ExecCtx(ctx, query, newData.ProductId, newData.FeatureId, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion) + return session.ExecCtx(ctx, query, newData.ProductId, newData.FeatureId, newData.DeleteTime, newData.DelState, newData.Version, newData.Sort, newData.IsImportant, newData.Enable, newData.Id, oldVersion) } - return conn.ExecCtx(ctx, query, newData.ProductId, newData.FeatureId, newData.DeleteTime, newData.DelState, newData.Version, newData.Id, oldVersion) + return conn.ExecCtx(ctx, query, newData.ProductId, newData.FeatureId, newData.DeleteTime, newData.DelState, newData.Version, newData.Sort, newData.IsImportant, newData.Enable, newData.Id, oldVersion) }, tydataProductFeatureIdKey, tydataProductFeatureProductIdFeatureIdKey) if err != nil { return err @@ -170,7 +172,7 @@ func (m *defaultProductFeatureModel) UpdateWithVersion(ctx context.Context, sess return err } if updateCount == 0 { - return model2.ErrNoRowsUpdate + return ErrNoRowsUpdate } return nil diff --git a/deploy/script/model/productFeatureModel.go b/deploy/script/model/productFeatureModel.go new file mode 100644 index 0000000..5b77422 --- /dev/null +++ b/deploy/script/model/productFeatureModel.go @@ -0,0 +1,27 @@ +package model + +import ( + "github.com/zeromicro/go-zero/core/stores/cache" + "github.com/zeromicro/go-zero/core/stores/sqlx" +) + +var _ ProductFeatureModel = (*customProductFeatureModel)(nil) + +type ( + // ProductFeatureModel is an interface to be customized, add more methods here, + // and implement the added methods in customProductFeatureModel. + ProductFeatureModel interface { + productFeatureModel + } + + customProductFeatureModel struct { + *defaultProductFeatureModel + } +) + +// NewProductFeatureModel returns a model for the database table. +func NewProductFeatureModel(conn sqlx.SqlConn, c cache.CacheConf) ProductFeatureModel { + return &customProductFeatureModel{ + defaultProductFeatureModel: newProductFeatureModel(conn, c), + } +} diff --git a/deploy/script/model/productFeatureModel_gen.go b/deploy/script/model/productFeatureModel_gen.go new file mode 100644 index 0000000..9a2bd1e --- /dev/null +++ b/deploy/script/model/productFeatureModel_gen.go @@ -0,0 +1,410 @@ +// Code generated by goctl. DO NOT EDIT! + +package model + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "time" + + "github.com/Masterminds/squirrel" + "github.com/pkg/errors" + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/cache" + "github.com/zeromicro/go-zero/core/stores/sqlc" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" + "tydata-server/common/globalkey" +) + +var ( + productFeatureFieldNames = builder.RawFieldNames(&ProductFeature{}) + productFeatureRows = strings.Join(productFeatureFieldNames, ",") + productFeatureRowsExpectAutoSet = strings.Join(stringx.Remove(productFeatureFieldNames, "`id`", "`create_time`", "`update_time`"), ",") + productFeatureRowsWithPlaceHolder = strings.Join(stringx.Remove(productFeatureFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?" + + cacheTydataProductFeatureIdPrefix = "cache:tydata:productFeature:id:" + cacheTydataProductFeatureProductIdFeatureIdPrefix = "cache:tydata:productFeature:productId:featureId:" +) + +type ( + productFeatureModel interface { + Insert(ctx context.Context, session sqlx.Session, data *ProductFeature) (sql.Result, error) + FindOne(ctx context.Context, id int64) (*ProductFeature, error) + FindOneByProductIdFeatureId(ctx context.Context, productId int64, featureId int64) (*ProductFeature, error) + Update(ctx context.Context, session sqlx.Session, data *ProductFeature) (sql.Result, error) + UpdateWithVersion(ctx context.Context, session sqlx.Session, data *ProductFeature) error + Trans(ctx context.Context, fn func(context context.Context, session sqlx.Session) error) error + SelectBuilder() squirrel.SelectBuilder + DeleteSoft(ctx context.Context, session sqlx.Session, data *ProductFeature) error + FindSum(ctx context.Context, sumBuilder squirrel.SelectBuilder, field string) (float64, error) + FindCount(ctx context.Context, countBuilder squirrel.SelectBuilder, field string) (int64, error) + FindAll(ctx context.Context, rowBuilder squirrel.SelectBuilder, orderBy string) ([]*ProductFeature, error) + FindPageListByPage(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*ProductFeature, error) + FindPageListByPageWithTotal(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*ProductFeature, int64, error) + FindPageListByIdDESC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*ProductFeature, error) + FindPageListByIdASC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*ProductFeature, error) + Delete(ctx context.Context, session sqlx.Session, id int64) error + } + + defaultProductFeatureModel struct { + sqlc.CachedConn + table string + } + + ProductFeature struct { + Id int64 `db:"id"` // 主键ID + ProductId int64 `db:"product_id"` // 产品ID + FeatureId int64 `db:"feature_id"` // 功能ID + CreateTime time.Time `db:"create_time"` // 创建时间 + UpdateTime time.Time `db:"update_time"` // 更新时间 + DeleteTime sql.NullTime `db:"delete_time"` // 删除时间 + DelState int64 `db:"del_state"` // 删除状态 + Version int64 `db:"version"` // 版本号 + Sort int64 `db:"sort"` + IsImportant int64 `db:"is_important"` + Enable int64 `db:"enable"` + } +) + +func newProductFeatureModel(conn sqlx.SqlConn, c cache.CacheConf) *defaultProductFeatureModel { + return &defaultProductFeatureModel{ + CachedConn: sqlc.NewConn(conn, c), + table: "`product_feature`", + } +} + +func (m *defaultProductFeatureModel) Insert(ctx context.Context, session sqlx.Session, data *ProductFeature) (sql.Result, error) { + data.DelState = globalkey.DelStateNo + tydataProductFeatureIdKey := fmt.Sprintf("%s%v", cacheTydataProductFeatureIdPrefix, data.Id) + tydataProductFeatureProductIdFeatureIdKey := fmt.Sprintf("%s%v:%v", cacheTydataProductFeatureProductIdFeatureIdPrefix, data.ProductId, data.FeatureId) + return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { + query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?)", m.table, productFeatureRowsExpectAutoSet) + if session != nil { + return session.ExecCtx(ctx, query, data.ProductId, data.FeatureId, data.DeleteTime, data.DelState, data.Version, data.Sort, data.IsImportant, data.Enable) + } + return conn.ExecCtx(ctx, query, data.ProductId, data.FeatureId, data.DeleteTime, data.DelState, data.Version, data.Sort, data.IsImportant, data.Enable) + }, tydataProductFeatureIdKey, tydataProductFeatureProductIdFeatureIdKey) +} + +func (m *defaultProductFeatureModel) FindOne(ctx context.Context, id int64) (*ProductFeature, error) { + tydataProductFeatureIdKey := fmt.Sprintf("%s%v", cacheTydataProductFeatureIdPrefix, id) + var resp ProductFeature + err := m.QueryRowCtx(ctx, &resp, tydataProductFeatureIdKey, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) error { + query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", productFeatureRows, m.table) + return conn.QueryRowCtx(ctx, v, query, id, globalkey.DelStateNo) + }) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultProductFeatureModel) FindOneByProductIdFeatureId(ctx context.Context, productId int64, featureId int64) (*ProductFeature, error) { + tydataProductFeatureProductIdFeatureIdKey := fmt.Sprintf("%s%v:%v", cacheTydataProductFeatureProductIdFeatureIdPrefix, productId, featureId) + var resp ProductFeature + err := m.QueryRowIndexCtx(ctx, &resp, tydataProductFeatureProductIdFeatureIdKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { + query := fmt.Sprintf("select %s from %s where `product_id` = ? and `feature_id` = ? and del_state = ? limit 1", productFeatureRows, m.table) + if err := conn.QueryRowCtx(ctx, &resp, query, productId, featureId, globalkey.DelStateNo); err != nil { + return nil, err + } + return resp.Id, nil + }, m.queryPrimary) + switch err { + case nil: + return &resp, nil + case sqlc.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultProductFeatureModel) Update(ctx context.Context, session sqlx.Session, newData *ProductFeature) (sql.Result, error) { + data, err := m.FindOne(ctx, newData.Id) + if err != nil { + return nil, err + } + tydataProductFeatureIdKey := fmt.Sprintf("%s%v", cacheTydataProductFeatureIdPrefix, data.Id) + tydataProductFeatureProductIdFeatureIdKey := fmt.Sprintf("%s%v:%v", cacheTydataProductFeatureProductIdFeatureIdPrefix, data.ProductId, data.FeatureId) + return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { + query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, productFeatureRowsWithPlaceHolder) + if session != nil { + return session.ExecCtx(ctx, query, newData.ProductId, newData.FeatureId, newData.DeleteTime, newData.DelState, newData.Version, newData.Sort, newData.IsImportant, newData.Enable, newData.Id) + } + return conn.ExecCtx(ctx, query, newData.ProductId, newData.FeatureId, newData.DeleteTime, newData.DelState, newData.Version, newData.Sort, newData.IsImportant, newData.Enable, newData.Id) + }, tydataProductFeatureIdKey, tydataProductFeatureProductIdFeatureIdKey) +} + +func (m *defaultProductFeatureModel) UpdateWithVersion(ctx context.Context, session sqlx.Session, newData *ProductFeature) error { + + oldVersion := newData.Version + newData.Version += 1 + + var sqlResult sql.Result + var err error + + data, err := m.FindOne(ctx, newData.Id) + if err != nil { + return err + } + tydataProductFeatureIdKey := fmt.Sprintf("%s%v", cacheTydataProductFeatureIdPrefix, data.Id) + tydataProductFeatureProductIdFeatureIdKey := fmt.Sprintf("%s%v:%v", cacheTydataProductFeatureProductIdFeatureIdPrefix, data.ProductId, data.FeatureId) + sqlResult, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { + query := fmt.Sprintf("update %s set %s where `id` = ? and version = ? ", m.table, productFeatureRowsWithPlaceHolder) + if session != nil { + return session.ExecCtx(ctx, query, newData.ProductId, newData.FeatureId, newData.DeleteTime, newData.DelState, newData.Version, newData.Sort, newData.IsImportant, newData.Enable, newData.Id, oldVersion) + } + return conn.ExecCtx(ctx, query, newData.ProductId, newData.FeatureId, newData.DeleteTime, newData.DelState, newData.Version, newData.Sort, newData.IsImportant, newData.Enable, newData.Id, oldVersion) + }, tydataProductFeatureIdKey, tydataProductFeatureProductIdFeatureIdKey) + if err != nil { + return err + } + updateCount, err := sqlResult.RowsAffected() + if err != nil { + return err + } + if updateCount == 0 { + return ErrNoRowsUpdate + } + + return nil +} + +func (m *defaultProductFeatureModel) DeleteSoft(ctx context.Context, session sqlx.Session, data *ProductFeature) error { + data.DelState = globalkey.DelStateYes + data.DeleteTime = sql.NullTime{Time: time.Now(), Valid: true} + if err := m.UpdateWithVersion(ctx, session, data); err != nil { + return errors.Wrapf(errors.New("delete soft failed "), "ProductFeatureModel delete err : %+v", err) + } + return nil +} + +func (m *defaultProductFeatureModel) FindSum(ctx context.Context, builder squirrel.SelectBuilder, field string) (float64, error) { + + if len(field) == 0 { + return 0, errors.Wrapf(errors.New("FindSum Least One Field"), "FindSum Least One Field") + } + + builder = builder.Columns("IFNULL(SUM(" + field + "),0)") + + query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql() + if err != nil { + return 0, err + } + + var resp float64 + err = m.QueryRowNoCacheCtx(ctx, &resp, query, values...) + switch err { + case nil: + return resp, nil + default: + return 0, err + } +} + +func (m *defaultProductFeatureModel) FindCount(ctx context.Context, builder squirrel.SelectBuilder, field string) (int64, error) { + + if len(field) == 0 { + return 0, errors.Wrapf(errors.New("FindCount Least One Field"), "FindCount Least One Field") + } + + builder = builder.Columns("COUNT(" + field + ")") + + query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql() + if err != nil { + return 0, err + } + + var resp int64 + err = m.QueryRowNoCacheCtx(ctx, &resp, query, values...) + switch err { + case nil: + return resp, nil + default: + return 0, err + } +} + +func (m *defaultProductFeatureModel) FindAll(ctx context.Context, builder squirrel.SelectBuilder, orderBy string) ([]*ProductFeature, error) { + + builder = builder.Columns(productFeatureRows) + + if orderBy == "" { + builder = builder.OrderBy("id DESC") + } else { + builder = builder.OrderBy(orderBy) + } + + query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql() + if err != nil { + return nil, err + } + + var resp []*ProductFeature + err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...) + switch err { + case nil: + return resp, nil + default: + return nil, err + } +} + +func (m *defaultProductFeatureModel) FindPageListByPage(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*ProductFeature, error) { + + builder = builder.Columns(productFeatureRows) + + if orderBy == "" { + builder = builder.OrderBy("id DESC") + } else { + builder = builder.OrderBy(orderBy) + } + + if page < 1 { + page = 1 + } + offset := (page - 1) * pageSize + + query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql() + if err != nil { + return nil, err + } + + var resp []*ProductFeature + err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...) + switch err { + case nil: + return resp, nil + default: + return nil, err + } +} + +func (m *defaultProductFeatureModel) FindPageListByPageWithTotal(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*ProductFeature, int64, error) { + + total, err := m.FindCount(ctx, builder, "id") + if err != nil { + return nil, 0, err + } + + builder = builder.Columns(productFeatureRows) + + if orderBy == "" { + builder = builder.OrderBy("id DESC") + } else { + builder = builder.OrderBy(orderBy) + } + + if page < 1 { + page = 1 + } + offset := (page - 1) * pageSize + + query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql() + if err != nil { + return nil, total, err + } + + var resp []*ProductFeature + err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...) + switch err { + case nil: + return resp, total, nil + default: + return nil, total, err + } +} + +func (m *defaultProductFeatureModel) FindPageListByIdDESC(ctx context.Context, builder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*ProductFeature, error) { + + builder = builder.Columns(productFeatureRows) + + if preMinId > 0 { + builder = builder.Where(" id < ? ", preMinId) + } + + query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id DESC").Limit(uint64(pageSize)).ToSql() + if err != nil { + return nil, err + } + + var resp []*ProductFeature + err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...) + switch err { + case nil: + return resp, nil + default: + return nil, err + } +} + +func (m *defaultProductFeatureModel) FindPageListByIdASC(ctx context.Context, builder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*ProductFeature, error) { + + builder = builder.Columns(productFeatureRows) + + if preMaxId > 0 { + builder = builder.Where(" id > ? ", preMaxId) + } + + query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id ASC").Limit(uint64(pageSize)).ToSql() + if err != nil { + return nil, err + } + + var resp []*ProductFeature + err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...) + switch err { + case nil: + return resp, nil + default: + return nil, err + } +} + +func (m *defaultProductFeatureModel) Trans(ctx context.Context, fn func(ctx context.Context, session sqlx.Session) error) error { + + return m.TransactCtx(ctx, func(ctx context.Context, session sqlx.Session) error { + return fn(ctx, session) + }) + +} + +func (m *defaultProductFeatureModel) SelectBuilder() squirrel.SelectBuilder { + return squirrel.Select().From(m.table) +} +func (m *defaultProductFeatureModel) Delete(ctx context.Context, session sqlx.Session, id int64) error { + data, err := m.FindOne(ctx, id) + if err != nil { + return err + } + + tydataProductFeatureIdKey := fmt.Sprintf("%s%v", cacheTydataProductFeatureIdPrefix, id) + tydataProductFeatureProductIdFeatureIdKey := fmt.Sprintf("%s%v:%v", cacheTydataProductFeatureProductIdFeatureIdPrefix, data.ProductId, data.FeatureId) + _, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) { + query := fmt.Sprintf("delete from %s where `id` = ?", m.table) + if session != nil { + return session.ExecCtx(ctx, query, id) + } + return conn.ExecCtx(ctx, query, id) + }, tydataProductFeatureIdKey, tydataProductFeatureProductIdFeatureIdKey) + return err +} +func (m *defaultProductFeatureModel) formatPrimary(primary interface{}) string { + return fmt.Sprintf("%s%v", cacheTydataProductFeatureIdPrefix, primary) +} +func (m *defaultProductFeatureModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary interface{}) error { + query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", productFeatureRows, m.table) + return conn.QueryRowCtx(ctx, v, query, primary, globalkey.DelStateNo) +} + +func (m *defaultProductFeatureModel) tableName() string { + return m.table +}