一、场景
1、子表:cp_member_point_history
cp_member_point_history表中字段:cp_point_reward_id 是cp_point_reward的主键id
当本表中的cp_point_reward_id字段为0(即:没有可关联主表的)
sql
CREATE TABLE `cp_member_point_history` (
`id` bigint NOT NULL AUTO_INCREMENT,
`point` int DEFAULT NULL COMMENT '获取积分',
`cp_point_reward_id` bigint DEFAULT NULL COMMENT '外键 cp_point_reward 主键id',
`show_status` tinyint(1) DEFAULT NULL COMMENT '是否删除:0、可用,1:删除',
`updated_at` datetime DEFAULT NULL COMMENT '更新时间',
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户积分变更历史';
2、主表:cp_point_reward
sql
CREATE TABLE `cp_point_reward` (
`id` bigint NOT NULL AUTO_INCREMENT,
`point` int DEFAULT NULL COMMENT '消耗积分',
`name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '奖品名称',
`reward` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '奖品说明',
`reward_status` int DEFAULT NULL COMMENT '1:上架、2:下架(默认是1)',
`show_status` tinyint(1) DEFAULT NULL COMMENT '是否删除:0、可用,1:删除',
`updated_at` datetime DEFAULT NULL COMMENT '更新时间',
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='积分奖品';
3、golang 使用 ent 源码
当 左连接 WithCpPointRewardMPH()时,无法进行关联时,则下面循环时,直接报错panic
go
package cpMemberPointHistory
import (
"context"
"fmt"
"github.com/suyuan32/simple-admin-common/utils/pointy"
"github.com/zeromicro/go-zero/core/logx"
)
type GetCpMemberPointHistoryListLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewGetCpMemberPointHistoryListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetCpMemberPointHistoryListLogic {
return &GetCpMemberPointHistoryListLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l *GetCpMemberPointHistoryListLogic) GetCpMemberPointHistoryList(in *cpgobusiness.CpMemberPointHistoryListReq) (*cpgobusiness.CpMemberPointHistoryListResp, error) {
var predicates []predicate.CpMemberPointHistory
if in.CpMemberId != nil {
predicates = append(predicates, cpmemberpointhistory.CpMemberID(*in.CpMemberId))
}
if in.CpPointRewardId != nil {
predicates = append(predicates, cpmemberpointhistory.CpPointRewardID(*in.CpPointRewardId))
}
if in.CpResourceId != nil {
predicates = append(predicates, cpmemberpointhistory.CpResourceID(*in.CpResourceId))
}
result, err := l.svcCtx.DB.CpMemberPointHistory.Query().Where(predicates...).
WithCpMemberMPH().
WithCpPointRewardMPH().
WithCpResourceMPH().Page(l.ctx, in.Page, in.PageSize, func(pager *ent.CpMemberPointHistoryPager) {
pager.Order = ent.Desc(cpmemberpointhistory.FieldID)
})
if err != nil {
return nil, dberrorhandler.DefaultEntError(l.Logger, err, in)
}
resp := &cpgobusiness.CpMemberPointHistoryListResp{}
resp.Total = result.PageDetails.Total
for _, v := range result.List {
Template := &cpgobusiness.CpMemberPointHistoryInfo{
Id: &v.ID,
CreatedAt: pointy.GetPointer(v.CreatedAt.UnixMilli()),
UpdatedAt: pointy.GetPointer(v.UpdatedAt.UnixMilli()),
ShowStatus: pointy.GetPointer(int64(v.ShowStatus)),
CpMemberId: &v.CpMemberID,
Point: &v.Point,
ChangeType: &v.ChangeType,
CpResourceId: &v.CpResourceID,
CpPointRewardId: &v.CpPointRewardID,
GainType: &v.GainType,
Name: &v.Edges.CpMemberMPH.Name,
Phone: &v.Edges.CpMemberMPH.Phone,
NickName: &v.Edges.CpMemberMPH.NickName,
Gender: &v.Edges.CpMemberMPH.Gender,
PointName: pointy.GetPointer(""),
ResourceTitle: &v.Edges.CpResourceMPH.Title,
}
if v.Edges.CpPointRewardMPH != nil {
fmt.Println("------------ v.Edges.CpPointRewardMPH.Name:", v.Edges.CpPointRewardMPH.Name)
Template.PointName = &v.Edges.CpPointRewardMPH.Name
}
resp.Data = append(resp.Data, Template)
}
return resp, nil
}
4、解决方案
问题:
报错的位置在:&v.Edges.CpPointRewardMPH.Name
因为 v.Edges.CpPointRewardMPH
为nil
解决
先判断 v.Edges.CpPointRewardMPH 是否为空
如果不为空,则赋值
go
if v.Edges.CpPointRewardMPH != nil {
fmt.Println("------------ v.Edges.CpPointRewardMPH.Name:", v.Edges.CpPointRewardMPH.Name)
Template.PointName = &v.Edges.CpPointRewardMPH.Name
}