feat: 实现企业卡授权和授权记录管理功能
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m9s

主要功能:
- 添加企业卡授权/回收接口 (POST /enterprises/:id/allocate-cards, recall-cards)
- 添加授权记录管理接口 (GET/PUT /authorizations)
- 实现代理用户数据权限过滤(只能查看自己店铺下企业的授权记录)
- 添加 GORM callback 支持授权记录表的数据权限过滤

技术改进:
- 原生 SQL 查询手动添加数据权限过滤(ListWithJoin, GetByIDWithJoin)
- 移除卡授权预检接口(allocate-cards/preview),保留内部方法
- 完善单元测试和集成测试覆盖
This commit is contained in:
2026-01-26 15:07:03 +08:00
parent 45aa7deb87
commit fdcff33058
42 changed files with 4782 additions and 298 deletions

View File

@@ -0,0 +1,48 @@
package dto
import "time"
type AuthorizationListReq struct {
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"`
EnterpriseID *uint `json:"enterprise_id" query:"enterprise_id" description:"按企业ID筛选"`
ICCID string `json:"iccid" query:"iccid" description:"按ICCID模糊查询"`
AuthorizerType *int `json:"authorizer_type" query:"authorizer_type" description:"授权人类型2=平台3=代理"`
Status *int `json:"status" query:"status" description:"状态0=已回收1=有效"`
StartTime string `json:"start_time" query:"start_time" description:"授权时间起格式2006-01-02"`
EndTime string `json:"end_time" query:"end_time" description:"授权时间止格式2006-01-02"`
}
type AuthorizationItem struct {
ID uint `json:"id" description:"授权记录ID"`
EnterpriseID uint `json:"enterprise_id" description:"企业ID"`
EnterpriseName string `json:"enterprise_name" description:"企业名称"`
CardID uint `json:"card_id" description:"卡ID"`
ICCID string `json:"iccid" description:"ICCID"`
MSISDN string `json:"msisdn" description:"手机号"`
AuthorizedBy uint `json:"authorized_by" description:"授权人ID"`
AuthorizerName string `json:"authorizer_name" description:"授权人名称"`
AuthorizerType int `json:"authorizer_type" description:"授权人类型2=平台3=代理"`
AuthorizedAt time.Time `json:"authorized_at" description:"授权时间"`
RevokedBy *uint `json:"revoked_by,omitempty" description:"回收人ID"`
RevokerName string `json:"revoker_name,omitempty" description:"回收人名称"`
RevokedAt *time.Time `json:"revoked_at,omitempty" description:"回收时间"`
Status int `json:"status" description:"状态1=有效0=已回收"`
Remark string `json:"remark" description:"备注"`
}
type AuthorizationListResp struct {
Items []AuthorizationItem `json:"items" description:"授权记录列表"`
Total int64 `json:"total" description:"总记录数"`
Page int `json:"page" description:"当前页码"`
Size int `json:"size" description:"每页数量"`
}
type AuthorizationDetailReq struct {
ID uint `json:"-" params:"id" path:"id" validate:"required" required:"true" description:"授权记录ID"`
}
type UpdateAuthorizationRemarkReq struct {
ID uint `json:"-" params:"id" path:"id" validate:"required" required:"true" description:"授权记录ID"`
Remark string `json:"remark" validate:"max=500" description:"备注最多500字"`
}

View File

@@ -7,16 +7,20 @@ import (
)
// EnterpriseCardAuthorization 企业卡授权模型
// 记录企业被授权可见的卡卡的归属owner始终是代理商店铺
// 注意:不使用 BaseModel因为已有 AuthorizedBy/RevokedBy 字段
type EnterpriseCardAuthorization struct {
gorm.Model
BaseModel `gorm:"embedded"`
EnterpriseID uint `gorm:"column:enterprise_id;index;not null;comment:企业ID" json:"enterprise_id"`
IotCardID uint `gorm:"column:iot_card_id;index;not null;comment:IoT卡ID" json:"iot_card_id"`
ShopID uint `gorm:"column:shop_id;index;not null;comment:店铺ID授权方" json:"shop_id"`
AuthorizedBy uint `gorm:"column:authorized_by;not null;comment:授权ID" json:"authorized_by"`
AuthorizedAt *time.Time `gorm:"column:authorized_at;default:now();comment:授权时间" json:"authorized_at"`
Status int `gorm:"column:status;type:int;default:1;comment:状态 1=有效 0=已回收" json:"status"`
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;index" json:"deleted_at,omitempty"`
EnterpriseID uint `gorm:"column:enterprise_id;not null;comment:被授权企业ID" json:"enterprise_id"`
CardID uint `gorm:"column:card_id;not null;comment:授权ID" json:"card_id"`
AuthorizedBy uint `gorm:"column:authorized_by;not null;comment:授权人账号ID" json:"authorized_by"`
AuthorizedAt time.Time `gorm:"column:authorized_at;not null;default:CURRENT_TIMESTAMP;comment:授权时间" json:"authorized_at"`
AuthorizerType int `gorm:"column:authorizer_type;not null;comment:授权人类型2=平台用户 3=代理账号" json:"authorizer_type"`
RevokedBy *uint `gorm:"column:revoked_by;comment:回收人账号ID" json:"revoked_by"`
RevokedAt *time.Time `gorm:"column:revoked_at;comment:回收时间" json:"revoked_at"`
Remark string `gorm:"column:remark;type:varchar(500);default:'';comment:授权备注" json:"remark"`
}
func (EnterpriseCardAuthorization) TableName() string {