package com.xuekairui.invite.controller; import com.xuekairui.common.Result; import com.xuekairui.invite.dto.*; import com.xuekairui.invite.service.InviteService; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.Map; /** * 邀请接口(用户端) */ @RestController @RequestMapping("/api/invite") @RequiredArgsConstructor public class InviteController { private final InviteService inviteService; /** * 获取我的邀请码 & 邀请链接 * GET /api/invite/code */ @GetMapping("/code") public Result getMyInviteCode(HttpServletRequest request) { Long userId = (Long) request.getAttribute("userId"); return Result.success(inviteService.getOrCreateInviteCode(userId)); } /** * 获取邀请统计(邀请人数、注册人数、累计奖励、摘要文本等) * GET /api/invite/stats */ @GetMapping("/stats") public Result getInviteStats(HttpServletRequest request) { Long userId = (Long) request.getAttribute("userId"); return Result.success(inviteService.getInviteStats(userId)); } /** * 获取邀请记录列表(含注册状态) * GET /api/invite/rewards */ @GetMapping("/rewards") public Result> getInviteRewards(HttpServletRequest request) { Long userId = (Long) request.getAttribute("userId"); return Result.success(inviteService.getInviteRewards(userId)); } /** * 获取可用额外爬虫次数(邀请奖励 + 运营发放) * GET /api/invite/extra-quota */ @GetMapping("/extra-quota") public Result getExtraQuota(HttpServletRequest request) { Long userId = (Long) request.getAttribute("userId"); return Result.success(inviteService.getAvailableExtraQuota(userId)); } /** * 补填邀请码(注册时未填,注册后有效窗口内可补填) * 补填成功后:邀请人获赠1个月高级会员时长 * POST /api/invite/bind * Body: {"inviteCode": "A3K7M9P2"} 或 {"inviteCode": "https://app.zhijiayun.com/invite/A3K7M9P2"} */ @PostMapping("/bind") public Result bindInviteCode(@RequestBody Map body, HttpServletRequest request) { Long userId = (Long) request.getAttribute("userId"); return Result.success(inviteService.bindInviteCode(userId, body.get("inviteCode"))); } // ========================================== // 公开接口(无需登录,浏览器访问) // ========================================== /** * 邀请落地页数据(公开,无需登录) * 浏览器打开邀请链接时调用,展示邀请人信息和下载链接 * 支持多渠道:windows、app、wechat、miniapp、dingtalk、feishu * GET /api/invite/page/{code}?channel=windows */ @GetMapping("/page/{code}") public Result getInvitePage( @PathVariable String code, @RequestParam(required = false) String channel) { return Result.success(inviteService.getInvitePage(code, channel)); } /** * 浏览器直接访问邀请链接入口(公开,无需登录) * 自动计入点击数,返回落地页数据 * GET /invite/{code} (默认 windows 渠道) * GET /invite/{code}?channel=wechat */ @GetMapping("/{code}") public Result openInviteLink( @PathVariable String code, @RequestParam(required = false) String channel) { return Result.success(inviteService.getInvitePage(code, channel)); } /** * 追踪邀请链接被打开(公开,无需登录) * POST /api/invite/click/{code} */ @PostMapping("/click/{code}") public Result trackClick(@PathVariable String code) { inviteService.trackClick(code); return Result.success(null); } /** * 解析邀请链接或邀请码(公开,无需登录) * 适用于:用户只复制了一段文字/链接,前端需要识别出邀请人和邀请码 * GET /api/invite/resolve-link?link=... */ @GetMapping("/resolve-link") public Result resolveInviteLink(@RequestParam String link) { return Result.success(inviteService.resolveInviteLink(link)); } }