Files
junhong_cmp_fiber/internal/handler/admin/asset.go
huang b9c3875c08
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m3s
feat: 新增数据库迁移,重命名 device_no 为 virtual_no,新增 iot_card.virtual_no 和 package.virtual_ratio 字段
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-14 18:27:28 +08:00

187 lines
5.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package admin
import (
"strconv"
"github.com/gofiber/fiber/v2"
assetService "github.com/break/junhong_cmp_fiber/internal/service/asset"
deviceService "github.com/break/junhong_cmp_fiber/internal/service/device"
iotCardService "github.com/break/junhong_cmp_fiber/internal/service/iot_card"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/errors"
"github.com/break/junhong_cmp_fiber/pkg/middleware"
"github.com/break/junhong_cmp_fiber/pkg/response"
)
// AssetHandler 资产管理处理器
// 提供统一的资产解析、实时状态、套餐查询、停复机等接口
type AssetHandler struct {
assetService *assetService.Service
deviceService *deviceService.Service
iotCardStopResume *iotCardService.StopResumeService
}
// NewAssetHandler 创建资产管理处理器
func NewAssetHandler(
assetSvc *assetService.Service,
deviceSvc *deviceService.Service,
iotCardStopResume *iotCardService.StopResumeService,
) *AssetHandler {
return &AssetHandler{
assetService: assetSvc,
deviceService: deviceSvc,
iotCardStopResume: iotCardStopResume,
}
}
// Resolve 通过任意标识符解析资产(设备或卡)
// GET /api/admin/assets/resolve/:identifier
func (h *AssetHandler) Resolve(c *fiber.Ctx) error {
userType := middleware.GetUserTypeFromContext(c.UserContext())
if userType == constants.UserTypeEnterprise {
return errors.New(errors.CodeForbidden, "企业账号暂不支持此接口")
}
identifier := c.Params("identifier")
if identifier == "" {
return errors.New(errors.CodeInvalidParam, "标识符不能为空")
}
result, err := h.assetService.Resolve(c.UserContext(), identifier)
if err != nil {
return err
}
return response.Success(c, result)
}
// RealtimeStatus 获取资产实时状态
// GET /api/admin/assets/:asset_type/:id/realtime-status
func (h *AssetHandler) RealtimeStatus(c *fiber.Ctx) error {
assetType := c.Params("asset_type")
id, err := strconv.ParseUint(c.Params("id"), 10, 64)
if err != nil {
return errors.New(errors.CodeInvalidParam, "无效的资产ID")
}
result, err := h.assetService.GetRealtimeStatus(c.UserContext(), assetType, uint(id))
if err != nil {
return err
}
return response.Success(c, result)
}
// Refresh 刷新资产状态(调网关同步)
// POST /api/admin/assets/:asset_type/:id/refresh
func (h *AssetHandler) Refresh(c *fiber.Ctx) error {
assetType := c.Params("asset_type")
id, err := strconv.ParseUint(c.Params("id"), 10, 64)
if err != nil {
return errors.New(errors.CodeInvalidParam, "无效的资产ID")
}
result, err := h.assetService.Refresh(c.UserContext(), assetType, uint(id))
if err != nil {
return err
}
return response.Success(c, result)
}
// Packages 获取资产所有套餐列表
// GET /api/admin/assets/:asset_type/:id/packages
func (h *AssetHandler) Packages(c *fiber.Ctx) error {
assetType := c.Params("asset_type")
id, err := strconv.ParseUint(c.Params("id"), 10, 64)
if err != nil {
return errors.New(errors.CodeInvalidParam, "无效的资产ID")
}
result, err := h.assetService.GetPackages(c.UserContext(), assetType, uint(id))
if err != nil {
return err
}
return response.Success(c, result)
}
// CurrentPackage 获取资产当前生效套餐
// GET /api/admin/assets/:asset_type/:id/current-package
func (h *AssetHandler) CurrentPackage(c *fiber.Ctx) error {
assetType := c.Params("asset_type")
id, err := strconv.ParseUint(c.Params("id"), 10, 64)
if err != nil {
return errors.New(errors.CodeInvalidParam, "无效的资产ID")
}
result, err := h.assetService.GetCurrentPackage(c.UserContext(), assetType, uint(id))
if err != nil {
return err
}
return response.Success(c, result)
}
// StopDevice 设备停机(批量停机设备下所有已实名卡)
// POST /api/admin/assets/device/:device_id/stop
func (h *AssetHandler) StopDevice(c *fiber.Ctx) error {
deviceID, err := strconv.ParseUint(c.Params("device_id"), 10, 64)
if err != nil {
return errors.New(errors.CodeInvalidParam, "无效的设备ID")
}
result, err := h.deviceService.StopDevice(c.UserContext(), uint(deviceID))
if err != nil {
return err
}
return response.Success(c, result)
}
// StartDevice 设备复机(批量复机设备下所有已实名卡)
// POST /api/admin/assets/device/:device_id/start
func (h *AssetHandler) StartDevice(c *fiber.Ctx) error {
deviceID, err := strconv.ParseUint(c.Params("device_id"), 10, 64)
if err != nil {
return errors.New(errors.CodeInvalidParam, "无效的设备ID")
}
if err := h.deviceService.StartDevice(c.UserContext(), uint(deviceID)); err != nil {
return err
}
return response.Success(c, nil)
}
// StopCard 单卡停机通过ICCID
// POST /api/admin/assets/card/:iccid/stop
func (h *AssetHandler) StopCard(c *fiber.Ctx) error {
iccid := c.Params("iccid")
if iccid == "" {
return errors.New(errors.CodeInvalidParam, "ICCID不能为空")
}
if err := h.iotCardStopResume.ManualStopCard(c.UserContext(), iccid); err != nil {
return err
}
return response.Success(c, nil)
}
// StartCard 单卡复机通过ICCID
// POST /api/admin/assets/card/:iccid/start
func (h *AssetHandler) StartCard(c *fiber.Ctx) error {
iccid := c.Params("iccid")
if iccid == "" {
return errors.New(errors.CodeInvalidParam, "ICCID不能为空")
}
if err := h.iotCardStopResume.ManualStartCard(c.UserContext(), iccid); err != nil {
return err
}
return response.Success(c, nil)
}