package com.cyksj.web.controller.claude; import cn.hutool.core.date.DateTime; import com.cyksj.common.constant.Constant; import com.cyksj.dto.Result; import com.cyksj.enums.GatewayResponse; import com.cyksj.model.manage.views.OrderDonView; import com.cyksj.model.request.ClaudeCodeApiKeysReq; import com.cyksj.model.request.ClaudeCodeApiKeysStatusReq; import com.cyksj.model.request.ClaudeCodeDelReq; import com.cyksj.model.response.ClaudeCodePointsHistoryResp; import com.cyksj.model.response.claudecode.ClaudeCodeResp; import com.cyksj.model.views.ClaudeCodeUserApiKeysView; import com.cyksj.model.views.ClaudeCodeUserPackageView; import com.cyksj.model.views.RenewalView; import com.cyksj.service.claude.ClaudeCodeService; import com.cyksj.service.user.UserBindRelationService; import com.cyksj.web.util.StpUserUtil; import com.ejlchina.searcher.BeanSearcher; import com.ejlchina.searcher.SearchResult; import com.ejlchina.searcher.param.Operator; import com.ejlchina.searcher.util.MapUtils; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.util.List; /** * 项目名: yhlxj11111111 * 文件名: ClaudeCodeController * 创建者: JavaZou * 创建时间:2025/8/8 11:37 */ @RestController @RequestMapping("/applet/claude/code") @RequiredArgsConstructor public class ClaudeCodeController { private final ClaudeCodeService claudeCodeService; private final BeanSearcher beanSearcher; private final HttpServletRequest request; private final UserBindRelationService userBindRelationService; /** * 用户创建API KEY */ @PostMapping("/create/apiKeys") public Result createApiKeys(@RequestBody @Validated ClaudeCodeApiKeysReq req) throws Exception { long userId = StpUserUtil.getLoginIdAsLong(); req.setUserId(userId); claudeCodeService.createApiKeys(req); return GatewayResponse.SUCCESS.newBuilder().toResult(); } /** * 更新api key状态 */ // @PutMapping("/update/apiKeys/status") public Result updateApiKeysStatus(@RequestBody @Validated ClaudeCodeApiKeysStatusReq req) throws Exception { long userId = StpUserUtil.getLoginIdAsLong(); req.setUserId(userId); claudeCodeService.updateApiKeysStatus(req); return GatewayResponse.SUCCESS.newBuilder().toResult(); } /** * 用户api keys列表 */ @GetMapping("/get/apiKeys") public Result> getUserApiKeys() throws Exception { long userId = StpUserUtil.getLoginIdAsLong(); List userApiKeys = claudeCodeService.getUserApiKeys(userId); return GatewayResponse.SUCCESS.newBuilder().toResult(userApiKeys); } /** * 删除api key */ @DeleteMapping("/delete/apiKeys") public Result deleteApiKeysById(@RequestBody ClaudeCodeDelReq delReq) throws Exception { long userId = StpUserUtil.getLoginIdAsLong(); delReq.setUserId(userId); claudeCodeService.deleteApiKeysById(delReq); return GatewayResponse.SUCCESS.newBuilder().toResult(); } //================================================用户============================================================ /** * 查询用户套餐信息 */ @GetMapping("/get/user/package") public Result getUserPackage() throws Exception { long userId = StpUserUtil.getLoginIdAsLong(); ClaudeCodeUserPackageView claudeCodeUserPackageView = claudeCodeService.getUserPackage(userId); return GatewayResponse.SUCCESS.newBuilder().toResult(claudeCodeUserPackageView); } /** * 用户订阅车票信息 */ @GetMapping("/get/user/subs/info") public Result getUserSubsInfo() { long userId = StpUserUtil.getLoginIdAsLong(); List userIdList = userBindRelationService.getRelationUserIdList(userId, null); RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, MapUtils.flatBuilder(request.getParameterMap()) .field(RenewalView::getUserId, userIdList).op(Operator.InList) .field(RenewalView::getGoodsId, Constant.CLAUDE_CODE_GOODS_ID) .field(RenewalView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan) .build()); return GatewayResponse.SUCCESS.newBuilder().toResult(renewalView); } /** * 用户订阅历史 */ @GetMapping("/get/user/orders") public Result> getUserOrders() { long userId = StpUserUtil.getLoginIdAsLong(); List userIdList = userBindRelationService.getRelationUserIdList(userId, null); SearchResult search = beanSearcher.search(OrderDonView.class, MapUtils.flatBuilder(request.getParameterMap()) .field(OrderDonView::getUserId, userIdList).op(Operator.InList) .field(OrderDonView::getGoodsId, Constant.CLAUDE_CODE_GOODS_ID) .field(OrderDonView::getStatus, Constant.noOrderAllStatus).op(Operator.NotIn) .build()); return GatewayResponse.SUCCESS.newBuilder().toResult(search); } /** * 用户积分明细 */ @GetMapping("/get/user/points/detail") public Result getUserPointsDetail(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "10") Integer limit, String type) throws Exception { long userId = StpUserUtil.getLoginIdAsLong(); ClaudeCodePointsHistoryResp resp = claudeCodeService.getUserPointsDetail(userId, type, page, limit); return GatewayResponse.SUCCESS.newBuilder().toResult(resp); } /** * 用户使用数据统计 */ @GetMapping("/get/user/points/statistics/data") public Result getUserPointsStatisticsData() throws Exception { long userId = StpUserUtil.getLoginIdAsLong(); ClaudeCodeResp resp = claudeCodeService.getUserPointsStatisticsData(userId); return GatewayResponse.SUCCESS.newBuilder().toResult(resp); } /** * 仪表盘聚合 * 返回 当前订阅/余额卡片 + 今日汇总 + 今日请求列表 */ @GetMapping("/get/dashboard") public Result getUserDashboard() throws Exception { long userId = StpUserUtil.getLoginIdAsLong(); ClaudeCodeResp resp = claudeCodeService.getUserDashboard(userId); return GatewayResponse.SUCCESS.newBuilder().toResult(resp); } /** * 余额卡片 * 单独返回余额卡片数据 */ @GetMapping("/get/balance") public Result getUserBalance() throws Exception { long userId = StpUserUtil.getLoginIdAsLong(); ClaudeCodeResp resp = claudeCodeService.getUserBalance(userId); return GatewayResponse.SUCCESS.newBuilder().toResult(resp); } /** * 图表 + 明细联动(每小时聚合) * - `start` (string, required): `YYYY-MM-DD HH:MM:SS`,例如 `2025-08-08 12:00:00` * - `end` (string, required): `YYYY-MM-DD HH:MM:SS`,需大于 `start` * - `tz` (string, optional): 时区,默认 `Asia/Shanghai` * - `page` (int, optional): 明细页码,默认 1 * - `limit` (int, optional): 明细每页数量,默认 20,最大 100 * - `order` (string, optional): `asc|desc`,默认 `desc` * - `type` (string, optional): 明细类型过滤,`consume|purchase|recovery|refund|reward|adjustment|all`,默认 `all` */ @GetMapping("/get/credits/analytics") public Result getCreditsAnalytics(String start, String end, String tz, String page, String limit, String order, String type) throws Exception { long userId = StpUserUtil.getLoginIdAsLong(); ClaudeCodeResp resp = claudeCodeService.getCreditsAnalytics(userId, start, end, tz, page, limit, order, type); return GatewayResponse.SUCCESS.newBuilder().toResult(resp); } }