chenbiao 1 tahun lalu
induk
melakukan
11b3b1af49

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

@@ -0,0 +1,11 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.GrokUser;
+
+/**
+ * @author chan
+ * @date 2025/3/20 18:32
+ */
+public interface GrokUserMapper extends BaseMapper<GrokUser> {
+}

+ 53 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/GrokUser.java

@@ -0,0 +1,53 @@
+package com.cyksj.model.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.ejlchina.searcher.bean.DbField;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @author chan
+ * @date 2025/3/20 18:04
+ */
+@Data
+public class GrokUser extends BaseEntity {
+
+    private String name;
+
+    @DbField("userToken")
+    @TableField("userToken")
+    private String userToken;
+
+    @TableField("expireTime")
+    private Date expireTime;
+
+    @TableField("isPlus")
+    private Boolean isPlus;
+
+    private String remark;
+
+    /**
+     * 车票id
+     */
+    @TableField("relationId")
+    private Long relationId;
+
+    /**
+     * 限制次数
+     */
+    private Integer limitNum;
+
+    /**
+     * 限制时间
+     */
+    private Long limitTime;
+
+
+    /**
+     * 是否封禁
+     */
+    private Boolean isBlock;
+
+}

+ 17 - 0
netflix-dao/src/main/java/com/cyksj/model/request/GrokOauthReq.java

@@ -0,0 +1,17 @@
+package com.cyksj.model.request;
+
+import lombok.Data;
+
+/**
+ * @author chan
+ * @date 2025/3/20 18:50
+ */
+@Data
+public class GrokOauthReq {
+
+    /**
+     * 用户token
+     */
+    private String userToken;
+
+}

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

@@ -0,0 +1,41 @@
+package com.cyksj.model.views;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @author chan
+ * @date 2025/3/20 18:22
+ */
+@Data
+@Builder
+public class GrokUserView {
+
+    /**
+     * 规格名称
+     */
+    private String skuName;
+
+    /**
+     * 过期时间
+     */
+    private Date expireTime;
+
+    /**
+     * 限制时间
+     */
+    private Long limitTime;
+
+    /**
+     * 限制次数
+     */
+    private Integer limitNum;
+
+    /**
+     * 使用次数
+     */
+    private Long use;
+
+}

+ 20 - 0
netflix-service/src/main/java/com/cyksj/service/grok/GrokService.java

@@ -0,0 +1,20 @@
+package com.cyksj.service.grok;
+
+import com.cyksj.model.entity.GrokUser;
+import com.cyksj.model.views.GrokUserView;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author chan
+ * @date 2025/3/20 18:20
+ */
+public interface GrokService {
+    GrokUserView getUserInfo(long userId, Long relationId);
+
+    GrokUser findByUserTokenAndExpireTimeAfter(String userToken, LocalDateTime now);
+
+    GrokUser checkCarAccount(Long userId, Long relationId);
+
+    Long getConversationCount(String userToken, Long limitTime);
+}

+ 177 - 0
netflix-service/src/main/java/com/cyksj/service/grok/impl/GrokServiceImpl.java

@@ -0,0 +1,177 @@
+package com.cyksj.service.grok.impl;
+
+import cn.hutool.core.lang.UUID;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+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.views.GrokUserView;
+import com.cyksj.service.grok.GrokService;
+import com.cyksj.service.user.UserBindRelationService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author chan
+ * @date 2025/3/20 18:20
+ */
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class GrokServiceImpl implements GrokService {
+
+    private final GoodsDonSkuMapper skuMapper;
+
+    private final GrokUserMapper grokUserMapper;
+
+    private final UserBindRelationService userBindRelationService;
+
+    private final GroupsRelationMapper groupsRelationMapper;
+
+    private final UserMapper userMapper;
+
+    private final GroupsMapper groupsMapper;
+
+    @Override
+    public GrokUserView getUserInfo(long userId, Long relationId) {
+        GrokUser grokUser = checkCarAccount(userId, relationId);
+        if (grokUser != null) {
+
+            GroupsRelation groupsRelation = getGroupsRelation(userId, relationId);
+            GroupsTrips groupsTrips = getGroupsTrips(groupsRelation);
+            GoodsDonSku goodsDonSku = skuMapper.selectById(groupsTrips.getSkuId());
+
+           GrokUserView view =GrokUserView.builder()
+                    .skuName(goodsDonSku.getSubTitle())
+                    .expireTime(grokUser.getExpireTime())
+                    .limitNum(grokUser.getLimitNum())
+                    .limitTime(grokUser.getLimitTime())
+
+                    //.use(Math.min(grokUser.getLimitNum(), getConversationCount(grokUser.getUserToken(),grokUser.getLimitTime())))
+                    .build();
+            return view;
+        } else {
+            throw BusinessRuntimeException.getInstance("您还未购买该车票");
+        }
+    }
+
+    @Override
+    public GrokUser findByUserTokenAndExpireTimeAfter(String userToken, LocalDateTime now) {
+        return grokUserMapper.selectOne(Wrappers.lambdaQuery(GrokUser.class).eq(GrokUser::getUserToken, userToken).gt(GrokUser::getExpireTime, now));
+    }
+
+    @Override
+    public GrokUser checkCarAccount(Long userId, Long relationId) {
+        GroupsRelation groupsRelation = getGroupsRelation(userId, relationId);
+        GroupsTrips groupsTrips = getGroupsTrips(groupsRelation);
+        GoodsDonSku goodsDonSku = skuMapper.selectById(groupsTrips.getSkuId());
+
+        if (goodsDonSku != null && goodsDonSku.getIsMirror() && goodsDonSku.getIsCar()) {
+            return getGrokUser(userId, relationId, groupsRelation, goodsDonSku);
+        } else {
+            return null;
+        }
+    }
+
+
+    @Override
+    public Long getConversationCount(String userToken, Long limitTime) {
+        JSONObject conversationCount = getConversationCount(userToken);
+        Long count = Optional.ofNullable(conversationCount.getLong("count")).orElse(0l);
+        return new BigDecimal(count).divide(BigDecimal.valueOf(4000),0, RoundingMode.HALF_UP).longValue();
+    }
+
+
+    /**
+     * 获取车位信息
+     *
+     * @param userId
+     * @param relationId
+     * @return
+     */
+    private GroupsRelation getGroupsRelation(Long userId, Long relationId) {
+        List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+        GroupsRelation groupsRelation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class).in(GroupsRelation::getUserId, userIdList).eq(GroupsRelation::getId, relationId));
+        if (groupsRelation == null) {
+            throw BusinessRuntimeException.getInstance("车票不存在");
+        }
+        return groupsRelation;
+    }
+
+    /**
+     * 获取车队信息
+     *
+     * @param groupsRelation
+     * @return
+     */
+    private GroupsTrips getGroupsTrips(GroupsRelation groupsRelation) {
+        GroupsTrips groupsTrips = groupsMapper.selectById(groupsRelation.getGroupsId());
+        if (groupsTrips == null) {
+            throw BusinessRuntimeException.getInstance("车队异常");
+        }
+        return groupsTrips;
+    }
+
+    private GrokUser getGrokUser(Long userId, Long relationId, GroupsRelation groupsRelation, GoodsDonSku goodsDonSku) {
+        GrokUser grokUser = grokUserMapper.selectOne(Wrappers.lambdaQuery(GrokUser.class).eq(GrokUser::getRelationId, relationId));
+        User user = userMapper.selectById(userId);
+        if (grokUser == null) {
+            grokUser = createGrokUser(groupsRelation, user, goodsDonSku);
+        } else {
+            updateGrokUser(groupsRelation, user, grokUser);
+        }
+        return grokUser;
+    }
+
+
+    /**
+     * 创建chatgptUser
+     */
+    private synchronized GrokUser createGrokUser(GroupsRelation groupsRelation, User user, GoodsDonSku goodsDonSku) {
+        GrokUser grokUser = new GrokUser();
+        if (goodsDonSku.getIsCar()) {
+            grokUser.setLimitNum(goodsDonSku.getGptLimitNum());
+            grokUser.setLimitTime(goodsDonSku.getGptLimitTime());
+        }
+        try {
+            grokUser.setExpireTime(groupsRelation.getExpiryTime());
+            grokUser.setIsPlus(true);
+            grokUser.setName(user.getNickname());
+            grokUser.setRelationId(groupsRelation.getId());
+            grokUser.setUserToken(UUID.randomUUID().toString());
+            grokUserMapper.insert(grokUser);
+
+        } catch (DuplicateKeyException e) {
+            log.error("重复插入Grok镜像用户:{}token,errmsg:{}", user.getNickname(), StringUtil.getErrorText(e));
+        }
+        return grokUser;
+    }
+
+
+    private void updateGrokUser(GroupsRelation groupsRelation, User user, GrokUser grokUser) {
+        grokUser.setName(user.getNickname());
+        grokUser.setExpireTime(groupsRelation.getExpiryTime());
+        grokUserMapper.updateById(grokUser);
+    }
+
+    public JSONObject getConversationCount(String userToken) {
+        try {
+            String res = HttpUtil.get("http://147.79.20.183:9611/grok/getConversationCount?userToken=" + userToken);
+            return new JSONObject(res);
+        }catch (Exception e){
+            return new JSONObject("{\"count\": 0}");
+        }
+    }
+
+}

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

@@ -1,6 +1,7 @@
 package com.cyksj.web.controller.mirror;
 
 import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.servlet.ServletUtil;
@@ -18,9 +19,11 @@ import com.cyksj.mapper.GroupsRelationMapper;
 import com.cyksj.mapper.renew.RenewUpgradePackageMapper;
 import com.cyksj.model.dto.ChatgptUserVerifyDto;
 import com.cyksj.model.entity.*;
+import com.cyksj.model.request.GrokOauthReq;
 import com.cyksj.model.views.*;
 import com.cyksj.service.chatgpt.ChatGptAccountService;
 import com.cyksj.service.claude.ClaudeService;
+import com.cyksj.service.grok.GrokService;
 import com.cyksj.service.luma.LumaService;
 import com.cyksj.service.midjourney.MidjourneyAccountService;
 import com.cyksj.service.sys.SysConfigService;
@@ -95,6 +98,8 @@ public class MirrorController {
 
     private final SysConfigService sysConfigService;
 
+    private final GrokService grokService;
+
 
     /**
      * GPT车票跳转登录
@@ -510,4 +515,50 @@ public class MirrorController {
             response.sendRedirect(DOMAIN + "/codetoken?logintoken=" + userToken);
         }
     }
+
+
+    //------------------------ grok -------------------------------
+
+
+    /**
+     * Grok车票跳转登录
+     *
+     */
+    @RequestMapping("/grok/oauth")
+    public String grokOauth(@RequestBody GrokOauthReq grokOauthReq) {
+        try {
+            log.info("用户通过userToken:{}访问grok镜像", grokOauthReq.getUserToken());
+            GrokUser user = grokService.findByUserTokenAndExpireTimeAfter(grokOauthReq.getUserToken(), LocalDateTime.now());
+            JSONObject result = new JSONObject();
+
+            if (user == null) {
+                result.putOpt("code",0);
+                result.putOpt("msg","用户不存在或已过期");
+                return result.toString();
+            }
+            result.putOpt("code",1);
+            result.putOpt("msg","登陆成功");
+            result.putOpt("isPro","登陆成功");
+            result.putOpt("expireTime", new DateTime(user.getExpireTime()).toString());
+            return result.toString();
+        } catch (Exception e) {
+            log.error("服务器错误", e);
+            JSONObject result = new JSONObject();
+            result.putOpt("code",0);
+            result.putOpt("msg","服务器错误");
+            return result.toString();
+        }
+    }
+
+    /**
+     * 获取grok车票信息
+     */
+    @GetMapping("/grok/userInfo")
+    public Result<GrokUserView> getGrokUserInfo(Long relationId) {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        GrokUserView user = grokService.getUserInfo(userId, relationId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(user);
+    }
+
+
 }