Files
junhong_cmp_fiber/internal/handler/admin/authorization.go
huang fdcff33058
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m9s
feat: 实现企业卡授权和授权记录管理功能
主要功能:
- 添加企业卡授权/回收接口 (POST /enterprises/:id/allocate-cards, recall-cards)
- 添加授权记录管理接口 (GET/PUT /authorizations)
- 实现代理用户数据权限过滤(只能查看自己店铺下企业的授权记录)
- 添加 GORM callback 支持授权记录表的数据权限过滤

技术改进:
- 原生 SQL 查询手动添加数据权限过滤(ListWithJoin, GetByIDWithJoin)
- 移除卡授权预检接口(allocate-cards/preview),保留内部方法
- 完善单元测试和集成测试覆盖
2026-01-26 15:07:03 +08:00

158 lines
4.4 KiB
Go

package admin
import (
"strconv"
"time"
"github.com/gofiber/fiber/v2"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
enterpriseCardService "github.com/break/junhong_cmp_fiber/internal/service/enterprise_card"
"github.com/break/junhong_cmp_fiber/pkg/errors"
"github.com/break/junhong_cmp_fiber/pkg/response"
)
type AuthorizationHandler struct {
service *enterpriseCardService.AuthorizationService
}
func NewAuthorizationHandler(service *enterpriseCardService.AuthorizationService) *AuthorizationHandler {
return &AuthorizationHandler{service: service}
}
func (h *AuthorizationHandler) List(c *fiber.Ctx) error {
var req dto.AuthorizationListReq
if err := c.QueryParser(&req); err != nil {
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
}
result, err := h.service.ListRecords(c.UserContext(), enterpriseCardService.ListRecordsRequest{
EnterpriseID: req.EnterpriseID,
ICCID: req.ICCID,
AuthorizerType: req.AuthorizerType,
Status: req.Status,
StartTime: req.StartTime,
EndTime: req.EndTime,
Page: req.Page,
PageSize: req.PageSize,
})
if err != nil {
return err
}
items := make([]dto.AuthorizationItem, len(result.Items))
for i, r := range result.Items {
authorizedAt, _ := time.ParseInLocation("2006-01-02 15:04:05", r.AuthorizedAt, time.Local)
var revokedAt *time.Time
if r.RevokedAt != nil {
t, _ := time.ParseInLocation("2006-01-02 15:04:05", *r.RevokedAt, time.Local)
revokedAt = &t
}
items[i] = dto.AuthorizationItem{
ID: r.ID,
EnterpriseID: r.EnterpriseID,
EnterpriseName: r.EnterpriseName,
CardID: r.CardID,
ICCID: r.ICCID,
MSISDN: r.MSISDN,
AuthorizedBy: r.AuthorizedBy,
AuthorizerName: r.AuthorizerName,
AuthorizerType: r.AuthorizerType,
AuthorizedAt: authorizedAt,
RevokedBy: r.RevokedBy,
RevokerName: r.RevokerName,
RevokedAt: revokedAt,
Status: r.Status,
Remark: r.Remark,
}
}
return response.SuccessWithPagination(c, items, result.Total, result.Page, result.Size)
}
func (h *AuthorizationHandler) GetDetail(c *fiber.Ctx) error {
idStr := c.Params("id")
id, err := strconv.ParseUint(idStr, 10, 64)
if err != nil {
return errors.New(errors.CodeInvalidParam, "无效的授权记录ID")
}
r, err := h.service.GetRecordDetail(c.UserContext(), uint(id))
if err != nil {
return err
}
authorizedAt, _ := time.ParseInLocation("2006-01-02 15:04:05", r.AuthorizedAt, time.Local)
var revokedAt *time.Time
if r.RevokedAt != nil {
t, _ := time.ParseInLocation("2006-01-02 15:04:05", *r.RevokedAt, time.Local)
revokedAt = &t
}
result := dto.AuthorizationItem{
ID: r.ID,
EnterpriseID: r.EnterpriseID,
EnterpriseName: r.EnterpriseName,
CardID: r.CardID,
ICCID: r.ICCID,
MSISDN: r.MSISDN,
AuthorizedBy: r.AuthorizedBy,
AuthorizerName: r.AuthorizerName,
AuthorizerType: r.AuthorizerType,
AuthorizedAt: authorizedAt,
RevokedBy: r.RevokedBy,
RevokerName: r.RevokerName,
RevokedAt: revokedAt,
Status: r.Status,
Remark: r.Remark,
}
return response.Success(c, result)
}
func (h *AuthorizationHandler) UpdateRemark(c *fiber.Ctx) error {
idStr := c.Params("id")
id, err := strconv.ParseUint(idStr, 10, 64)
if err != nil {
return errors.New(errors.CodeInvalidParam, "无效的授权记录ID")
}
var req dto.UpdateAuthorizationRemarkReq
if err := c.BodyParser(&req); err != nil {
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
}
r, err := h.service.UpdateRecordRemark(c.UserContext(), uint(id), req.Remark)
if err != nil {
return err
}
authorizedAt, _ := time.ParseInLocation("2006-01-02 15:04:05", r.AuthorizedAt, time.Local)
var revokedAt *time.Time
if r.RevokedAt != nil {
t, _ := time.ParseInLocation("2006-01-02 15:04:05", *r.RevokedAt, time.Local)
revokedAt = &t
}
result := dto.AuthorizationItem{
ID: r.ID,
EnterpriseID: r.EnterpriseID,
EnterpriseName: r.EnterpriseName,
CardID: r.CardID,
ICCID: r.ICCID,
MSISDN: r.MSISDN,
AuthorizedBy: r.AuthorizedBy,
AuthorizerName: r.AuthorizerName,
AuthorizerType: r.AuthorizerType,
AuthorizedAt: authorizedAt,
RevokedBy: r.RevokedBy,
RevokerName: r.RevokerName,
RevokedAt: revokedAt,
Status: r.Status,
Remark: r.Remark,
}
return response.Success(c, result)
}