Pārlūkot izejas kodu

新增 claude 镜像

chenbiao 2 gadi atpakaļ
vecāks
revīzija
0aaa2ce891

+ 11 - 0
netflix-dao/src/main/java/com/cyksj/mapper/ClaudeSessionMapper.java

@@ -0,0 +1,11 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.ClaudeSession;
+
+/**
+ * @author chan
+ * @date 2024/8/9 10:47
+ */
+public interface ClaudeSessionMapper extends BaseMapper<ClaudeSession> {
+}

+ 36 - 1
netflix-dao/src/main/java/com/cyksj/model/entity/ClaudeSession.java

@@ -1,8 +1,43 @@
 package com.cyksj.model.entity;
 
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Data;
+
+import java.util.Date;
+
 /**
  * @author chan
  * @date 2024/8/8 18:46
  */
-public class ClaudeSession {
+@Data
+@SearchBean(tables = "claude_session cs")
+public class ClaudeSession extends BaseEntity {
+
+    @TableField("deleted_at")
+    @DbField("deleted_at")
+    private Date deletedAt;
+
+    private String email;
+
+    private String password;
+
+    private Boolean status;
+
+    private Boolean isPlus;
+
+    @DbField("carID")
+    @TableField("carID")
+    private String carID;
+
+    @DbField("officialSession")
+    @TableField("officialSession")
+    private String officialSession;
+
+    private String remark;
+
+    private Long sort;
+
+    private double score;
 }

+ 41 - 0
netflix-dao/src/main/java/com/cyksj/model/views/ClaudeUserView.java

@@ -0,0 +1,41 @@
+package com.cyksj.model.views;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @author chan
+ * @date 2024/8/9 12:01
+ */
+@Data
+@Builder
+public class ClaudeUserView {
+
+    /**
+     * 规格名称
+     */
+    private String skuName;
+
+    /**
+     * 过期时间
+     */
+    private Date expireTime;
+
+    /**
+     * 限制时间
+     */
+    private Long limitTime;
+
+    /**
+     * 限制次数
+     */
+    private Integer limitNum;
+
+    /**
+     * 使用次数
+     */
+    private Long use;
+}

+ 4 - 2
netflix-service/src/main/java/com/cyksj/service/claude/ClaudeService.java

@@ -1,9 +1,9 @@
 package com.cyksj.service.claude;
 
-import com.cyksj.model.entity.ChatgptUser;
 import com.cyksj.model.entity.ClaudeUser;
 import com.cyksj.model.request.gpt.ConversationRequest;
 import com.cyksj.model.response.ConversationLimitResponse;
+import com.cyksj.model.views.ClaudeUserView;
 
 import java.time.LocalDateTime;
 
@@ -12,6 +12,8 @@ import java.time.LocalDateTime;
  * @date 2024/8/8 18:34
  */
 public interface ClaudeService {
+    ClaudeUserView getUserInfo(long userId, Long relationId);
+
     ClaudeUser findByUserTokenAndExpireTimeAfter(String userToken, LocalDateTime now);
 
     ConversationLimitResponse conversationLimit(String userToken, ClaudeUser user);
@@ -22,7 +24,7 @@ public interface ClaudeService {
 
     void saveConversationRecord(String userToken, ConversationRequest conversationRequest);
 
-    Boolean checkCarAccount(Long userId, Long relationId);
+    ClaudeUser checkCarAccount(Long userId, Long relationId);
 
     String getCarLoginUrl(Long userId, Long relationId, String carId);
 

+ 12 - 0
netflix-service/src/main/java/com/cyksj/service/claude/ClaudeSessionService.java

@@ -0,0 +1,12 @@
+package com.cyksj.service.claude;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.cyksj.model.entity.ClaudeSession;
+
+/**
+ * @author chan
+ * @date 2024/8/9 10:46
+ */
+public interface ClaudeSessionService extends IService<ClaudeSession>  {
+    void getSession(String email, String password, String officialSession, Boolean isPlus);
+}

+ 28 - 4
netflix-service/src/main/java/com/cyksj/service/claude/impl/ClaudeServiceImpl.java

@@ -5,12 +5,15 @@ import cn.hutool.core.lang.UUID;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.constant.Constant;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.util.StringUtil;
 import com.cyksj.mapper.*;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.request.gpt.ConversationRequest;
 import com.cyksj.model.response.ConversationLimitResponse;
+import com.cyksj.model.views.ChatGptUserView;
+import com.cyksj.model.views.ClaudeUserView;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.claude.ClaudeService;
 import com.cyksj.service.sys.SysConfigService;
@@ -21,6 +24,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.springframework.dao.DuplicateKeyException;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Set;
@@ -54,6 +58,27 @@ public class ClaudeServiceImpl implements ClaudeService {
 
     private final ClaudeUserConversationRecordMapper claudeUserConversationRecordMapper;
 
+    @Override
+    public ClaudeUserView getUserInfo(long userId, Long relationId) {
+        ClaudeUser claudeUser = checkCarAccount(userId, relationId);
+        if (claudeUser != null) {
+
+            GroupsRelation groupsRelation = getGroupsRelation(userId, relationId);
+            GroupsTrips groupsTrips = getGroupsTrips(groupsRelation);
+            GoodsDonSku goodsDonSku = skuMapper.selectById(groupsTrips.getSkuId());
+
+            return ClaudeUserView.builder()
+                    .skuName(goodsDonSku.getSubTitle())
+                    .expireTime(claudeUser.getExpireTime())
+                    .limitNum(claudeUser.getLimitNum())
+                    .limitTime(claudeUser.getLimitTime())
+                    .use(Math.min(claudeUser.getLimitNum(), getConversationCount(claudeUser.getUserToken(), claudeUser.getLimitTime())))
+                    .build();
+        } else {
+            throw BusinessRuntimeException.getInstance("您还未购买该车票");
+        }
+    }
+
     @Override
     public ClaudeUser findByUserTokenAndExpireTimeAfter(String userToken, LocalDateTime now) {
         return claudeUserMapper.selectOne(Wrappers.lambdaQuery(ClaudeUser.class).eq(ClaudeUser::getUserToken, userToken).gt(ClaudeUser::getExpireTime, now));
@@ -133,16 +158,15 @@ public class ClaudeServiceImpl implements ClaudeService {
     }
 
     @Override
-    public Boolean checkCarAccount(Long userId, Long relationId) {
+    public ClaudeUser checkCarAccount(Long userId, Long relationId) {
         GroupsRelation groupsRelation = getGroupsRelation(userId, relationId);
         GroupsTrips groupsTrips = getGroupsTrips(groupsRelation);
         GoodsDonSku goodsDonSku = skuMapper.selectById(groupsTrips.getSkuId());
 
         if (goodsDonSku != null && goodsDonSku.getGoodsId() == 75 && goodsDonSku.getIsMirror() && goodsDonSku.getIsCar()) {
-            ClaudeUser claudeUser = getClaudeUser(userId, relationId, groupsRelation, goodsDonSku);
-            return true;
+            return getClaudeUser(userId, relationId, groupsRelation, goodsDonSku);
         } else {
-            return false;
+            return null;
         }
     }
 

+ 67 - 0
netflix-service/src/main/java/com/cyksj/service/claude/impl/ClaudeSessionServiceImpl.java

@@ -0,0 +1,67 @@
+package com.cyksj.service.claude.impl;
+
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.Method;
+import cn.hutool.json.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.mapper.ClaudeSessionMapper;
+import com.cyksj.model.entity.ClaudeSession;
+import com.cyksj.service.claude.ClaudeSessionService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author chan
+ * @date 2024/8/9 10:46
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class ClaudeSessionServiceImpl extends ServiceImpl<ClaudeSessionMapper, ClaudeSession> implements ClaudeSessionService {
+
+
+    private static final String MIRROR_CLAUDE_DOMAIN = "https://claudeplus.com.cn";
+
+    @Override
+    public void getSession(String email, String password, String officialSession, Boolean isPlus) {
+        ClaudeSession one = this.getOne(Wrappers.lambdaQuery(ClaudeSession.class).orderByDesc(ClaudeSession::getId).last(" limit 1"));
+        if (isPlus == null) {
+            isPlus = true;
+        }
+        try {
+            JSONObject loginResult = getLoginResult(email, password, officialSession, isPlus ? "Claude-PRO-" + one.getId() + 1 : "Claude-" + one.getId() + 1);
+
+            //{
+            //    "code": 1000,
+            //        "message": "BaseResMessage",
+            //        "data": {
+            //    "id": 1
+            //}
+            //}
+
+            if (!loginResult.getInt("code").equals(1000)) {
+                log.error("新增claude 镜像账号异常,res:{}", loginResult);
+            }
+        } catch (Exception e) {
+            throw BusinessRuntimeException.getInstance("登录获取token错误 error:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 获取登录结果
+     */
+    private JSONObject getLoginResult(String email, String password, String officialSession, String carId) throws Exception {
+        HttpRequest request = new HttpRequest(MIRROR_CLAUDE_DOMAIN + "/adminapi/chatgpt/session/add");
+        request.form("email", email);
+        request.form("password", password);
+        request.form("officialSession", officialSession);
+        request.form("carID", carId);
+        HttpResponse execute = request.method(Method.POST).execute();
+        return new JSONObject(execute.body());
+    }
+
+}

+ 105 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/mirror/CmsClaudeController.java

@@ -0,0 +1,105 @@
+package com.cyksj.web.controller.manage.mirror;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.model.entity.ClaudeSession;
+import com.cyksj.model.views.ChatgptCarSessionView;
+import com.cyksj.redis.RedisService;
+import com.cyksj.service.claude.ClaudeSessionService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Optional;
+
+/**
+ * @author chan
+ * @date 2024/8/9 10:02
+ */
+@Slf4j
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/manage/mirror/claude")
+public class CmsClaudeController {
+
+    private final BeanSearcher beanSearcher;
+
+    private final ClaudeSessionService claudeSessionService;
+
+    private final RedisService redisService;
+
+    private final HttpServletRequest request;
+
+    /**
+     * 获取镜像车队账号列表
+     */
+    @GetMapping("/get")
+    public Result<SearchResult<ChatgptCarSessionView>> getMirrorCarSession() {
+        SearchResult<ChatgptCarSessionView> search = beanSearcher.search(ChatgptCarSessionView.class, MapUtils.flatBuilder(request.getParameterMap())
+                .orderBy(ChatgptCarSessionView::getId).desc()
+                .build());
+        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+    }
+
+    /**
+     * 编辑镜像车队账号列表
+     */
+    @PutMapping("/update")
+    public Result<String> updateMirrorCarSession(@RequestBody ClaudeSession claudeSession) {
+        Long id = claudeSession.getId();
+        ClaudeSession dbChatSession = claudeSessionService.getById(id);
+        if (!ObjectUtil.equal(dbChatSession.getEmail(), claudeSession.getEmail()) || !ObjectUtil.equal(dbChatSession.getPassword(), claudeSession.getPassword())) {
+            claudeSessionService.getSession(dbChatSession.getEmail(), dbChatSession.getPassword(), claudeSession.getOfficialSession(), claudeSession.getIsPlus());
+        }
+        Integer selectCount = claudeSessionService.getBaseMapper().selectCount(Wrappers.lambdaQuery(ClaudeSession.class)
+                .and(e -> e.eq(ClaudeSession::getEmail, claudeSession.getEmail())
+                        .or().eq(ClaudeSession::getCarID, claudeSession.getCarID()))
+                .ne(ClaudeSession::getId, claudeSession.getId()));
+        if (selectCount > 0) {
+            throw BusinessRuntimeException.getInstance("请检验车队ID或账号是否已存在");
+        }
+        claudeSessionService.updateById(claudeSession);
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
+
+    /**
+     * 删除镜像车队账号
+     */
+    @DeleteMapping("/delete/{id}")
+    public Result<String> deleteMirrorCarSession(@PathVariable Long id) {
+        Optional.ofNullable(claudeSessionService.getById(id))
+                .ifPresent(e -> {
+                    String carId = e.getCarID();
+                    if (StrUtil.isNotBlank(carId)) {
+                        claudeSessionService.removeById(e.getId());
+                        String highCarChatKey = RedisService.key.CLAUDE_CAR_CHAT.getName() + carId;
+                        redisService.del(highCarChatKey);
+                    }
+                });
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
+
+    /**
+     * 新增镜像车队账号
+     */
+    @PostMapping("/post/mirror/car/session")
+    public Result<String> postMirrorCarSession(@RequestBody ClaudeSession claudeSession) {
+        Integer selectCount = claudeSessionService.getBaseMapper().selectCount(Wrappers.lambdaQuery(ClaudeSession.class)
+                .eq(ClaudeSession::getCarID, claudeSession.getCarID()).or().eq(ClaudeSession::getEmail, claudeSession.getEmail()));
+        if (selectCount > 0) {
+            throw BusinessRuntimeException.getInstance("请检验车队ID或账号是否已存在");
+        }
+       claudeSessionService.getSession(claudeSession.getEmail(), claudeSession.getPassword(), claudeSession.getOfficialSession(),claudeSession.getIsPlus());
+
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
+
+}

+ 11 - 0
netflix-web/src/main/java/com/cyksj/web/controller/mirror/MirrorController.java

@@ -409,6 +409,17 @@ public class MirrorController {
 
     // ---------------------------------- claude ----------------------------------
 
+
+    /**
+     * 获取gpt车票信息
+     */
+    @GetMapping("/claude/userInfo")
+    public Result<ClaudeUserView> getClaudeUserInfo(Long relationId) {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        ClaudeUserView user = claudeService.getUserInfo(userId, relationId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(user);
+    }
+
     /**
      * Claude车队跳转登录
      *