package controller import ( "context" "github.com/gin-gonic/gin" "github.com/topfans/backend/pkg/models" "github.com/topfans/backend/gateway/pkg/response" "github.com/topfans/backend/gateway/service" ) // DownloadUrlResponse 下载页公开接口响应 type DownloadUrlResponse struct { URL string `json:"url"` Version string `json:"version"` Type string `json:"type"` } // AppDownloadSvc AppDownloadController 依赖的 service 接口 type AppDownloadSvc interface { GetAllNativeApp(ctx context.Context) ([]models.AppDownloadConfig, error) SyncVersion(ctx context.Context, req *service.SyncVersionRequest) error } // AppDownloadController App下载页控制器 // 注意:不走 Dubbo RPC,不依赖 Dubbo client,因此构造函数无需返回 error type AppDownloadController struct { svc AppDownloadSvc } // NewAppDownloadController 构造函数 func NewAppDownloadController(svc AppDownloadSvc) *AppDownloadController { return &AppDownloadController{svc: svc} } // GetDownloadUrls GET /api/v1/app/download-urls // @Summary 获取 App 下载地址 // @Description 返回 Android/iOS 最新 native_app 下载地址,供 HTML 分享页调用 // @Tags App下载页 // @Produce json // @Success 200 {object} response.Response{data=map[string]DownloadUrlResponse} // @Router /api/v1/app/download-urls [get] func (ctrl *AppDownloadController) GetDownloadUrls(c *gin.Context) { ctx := c.Request.Context() configs, err := ctrl.svc.GetAllNativeApp(ctx) if err != nil { response.InternalError(c, "获取下载地址失败") return } // 组装响应:map[platform] -> {url, version, type} data := make(map[string]interface{}) for _, cfg := range configs { data[cfg.Platform] = &DownloadUrlResponse{ URL: cfg.DownloadURL, Version: cfg.Version, Type: cfg.Type, } } // 确保 android/ios 键始终存在 for _, p := range []string{"android", "ios"} { if _, ok := data[p]; !ok { data[p] = nil } } response.Success(c, data) } // SyncVersion POST /api/v1/admin/app/versions/sync // @Summary 同步 App 下载地址 // @Description 接收 uniCloud 云函数推送的最新版本下载地址(内部接口,走 Nginx IP 白名单) // @Tags Admin // @Accept json // @Produce json // @Param body body service.SyncVersionRequest true "版本信息" // @Success 200 {object} response.Response // @Router /api/v1/admin/app/versions/sync [post] func (ctrl *AppDownloadController) SyncVersion(c *gin.Context) { var req service.SyncVersionRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "invalid request: "+err.Error()) return } ctx := c.Request.Context() if err := ctrl.svc.SyncVersion(ctx, &req); err != nil { response.InternalError(c, "同步版本信息失败") return } response.Success(c, nil) }