Bladeren bron

Merge branch 'gpt_qk_link'

zoujiajian 9 maanden geleden
bovenliggende
commit
adda9c4bf4

+ 5 - 0
netflix-common/src/main/java/com/cyksj/common/constant/Constant.java

@@ -740,4 +740,9 @@ public interface Constant {
 	 * 实物支付商户id
 	 */
 	String REAL_GOODS_PAY_SHOP_ID = "real_goods_pay_shop_id";
+
+	/**
+	 * gpt车队id
+	 */
+	String GPT_CARD_ID = "P288";
 }

+ 9 - 0
netflix-dao/src/main/java/com/cyksj/mapper/GptQuickLinkRecordMapper.java

@@ -0,0 +1,9 @@
+package com.cyksj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.GptQuickLinkRecord;
+
+
+public interface GptQuickLinkRecordMapper extends BaseMapper<GptQuickLinkRecord> {
+
+}

+ 32 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/GptQuickLinkRecord.java

@@ -0,0 +1,32 @@
+package com.cyksj.model.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.cyksj.model.BaseEntity;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * gpt快捷链接
+ */
+@Data
+@TableName("gpt_quick_link_record")
+@SearchBean(tables = "gpt_quick_link_record")
+public class GptQuickLinkRecord extends BaseEntity {
+
+    /**
+     * 用户ID
+     */
+    private Long userId;
+
+    /**
+     * 标识
+     */
+    private String code;
+
+    /**
+     * 有效期
+     */
+    private Date expiryTime;
+}

+ 34 - 0
netflix-dao/src/main/java/com/cyksj/model/response/GptQuickLinkResp.java

@@ -0,0 +1,34 @@
+package com.cyksj.model.response;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/**
+ * 项目名: yhlxj11111111
+ * 文件名: GptQuickLinkResp
+ * 创建者: JavaZou
+ * 创建时间:2025/11/20 15:51
+ */
+@Getter
+@Setter
+public class GptQuickLinkResp {
+
+	/**
+	 * 1.成功 2.链接到期 3.车票过期 4.多张车票
+	 */
+	private Integer state;
+
+	private String url;
+
+	private String code;
+
+	private Date expiryTime;
+
+	@JsonIgnore
+	private Long userId;
+
+	private String token;
+}

+ 25 - 0
netflix-service/src/main/java/com/cyksj/service/gpt/GptQuickLinkService.java

@@ -0,0 +1,25 @@
+package com.cyksj.service.gpt;
+
+import com.cyksj.model.entity.GptQuickLinkRecord;
+import com.cyksj.model.response.GptQuickLinkResp;
+
+/**
+ * GPT快捷链接服务接口
+ */
+public interface GptQuickLinkService {
+    
+    /**
+     * 创建快捷链接
+     */
+    GptQuickLinkRecord createQuickLink(Long userId);
+    
+    /**
+     * 获取用户最新的快捷链接
+     */
+    GptQuickLinkRecord getLatestQuickLink(Long userId);
+    
+    /**
+     * 根据code获取快捷链接
+     */
+    GptQuickLinkResp getQuickUrlByCode(String code);
+}

+ 163 - 0
netflix-service/src/main/java/com/cyksj/service/gpt/impl/GptQuickLinkServiceImpl.java

@@ -0,0 +1,163 @@
+package com.cyksj.service.gpt.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+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.GptQuickLinkRecordMapper;
+import com.cyksj.mapper.GroupsRelationMapper;
+import com.cyksj.model.entity.GptQuickLinkRecord;
+import com.cyksj.model.entity.SysConfig;
+import com.cyksj.model.manage.views.GroupsRelationView;
+import com.cyksj.model.response.GptQuickLinkResp;
+import com.cyksj.service.chatgpt.ChatGptAccountService;
+import com.cyksj.service.gpt.GptQuickLinkService;
+import com.cyksj.service.sys.SysConfigService;
+import com.cyksj.service.user.UserBindRelationService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.param.Operator;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * GPT快捷链接服务实现类
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class GptQuickLinkServiceImpl implements GptQuickLinkService {
+
+    private final GptQuickLinkRecordMapper gptQuickLinkRecordMapper;
+
+    private final GroupsRelationMapper groupsRelationMapper;
+
+    private final UserBindRelationService userBindRelationService;
+
+    private final BeanSearcher beanSearcher;
+
+    private final ChatGptAccountService chatGptAccountService;
+
+    private final SysConfigService sysConfigService;
+
+    @Override
+    public GptQuickLinkRecord createQuickLink(Long userId) {
+        // 检查用户是否有GPT镜像车票
+        List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+        if (getValidGptTicket(userIdList).isEmpty()) {
+            throw new BusinessRuntimeException("您没有有效的GPT镜像车票");
+        }
+        //生成标识
+        String code = StringUtil.randomString(6);;
+        GptQuickLinkRecord quickLink = new GptQuickLinkRecord();
+        quickLink.setUserId(userId);
+        quickLink.setCode(code);
+        // 创建新的快捷链接,有效期30天
+        quickLink.setExpiryTime(DateUtil.offsetDay(DateTime.now(), 30));
+        try {
+            gptQuickLinkRecordMapper.insert(quickLink);
+            //将之前的链接变成失效
+            gptQuickLinkRecordMapper.update(null, Wrappers.lambdaUpdate(GptQuickLinkRecord.class)
+                    .set(GptQuickLinkRecord::getExpiryTime, DateTime.now())
+                    .in(GptQuickLinkRecord::getUserId, userIdList)
+                    .ne(GptQuickLinkRecord::getCode, code)
+                    .gt(GptQuickLinkRecord::getExpiryTime, DateTime.now()));
+        } catch (DuplicateKeyException e) {
+            throw BusinessRuntimeException.getInstance("系统繁忙,请重新生成!");
+        }
+        return quickLink;
+    }
+    
+    @Override
+    public GptQuickLinkRecord getLatestQuickLink(Long userId) {
+        Date now = DateTime.now();
+        List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+        LambdaQueryWrapper<GptQuickLinkRecord> wrapper = Wrappers.lambdaQuery(GptQuickLinkRecord.class)
+                .in(GptQuickLinkRecord::getUserId, userIdList)
+                .gt(GptQuickLinkRecord::getExpiryTime, now)
+                .orderByDesc(GptQuickLinkRecord::getId)
+                .last("limit 1");
+        return gptQuickLinkRecordMapper.selectOne(wrapper);
+    }
+
+    @Override
+    public GptQuickLinkResp getQuickUrlByCode(String code) {
+        Date now = DateTime.now();
+        LambdaQueryWrapper<GptQuickLinkRecord> wrapper = Wrappers.lambdaQuery(GptQuickLinkRecord.class)
+                .eq(GptQuickLinkRecord::getCode, code)
+                .last("limit 1");
+        GptQuickLinkRecord gptQuickLinkRecord = gptQuickLinkRecordMapper.selectOne(wrapper);
+        if (gptQuickLinkRecord == null) {
+            throw BusinessRuntimeException.getInstance("快捷链接不存在");
+        }
+        GptQuickLinkResp resp = new GptQuickLinkResp();
+        resp.setUserId(gptQuickLinkRecord.getUserId());
+        //成功
+        Integer state = 1;
+        if (gptQuickLinkRecord != null) {
+            if (gptQuickLinkRecord.getExpiryTime().before(now)) {
+                //链接失效
+                state = 2;
+            } else {
+                Long userId = gptQuickLinkRecord.getUserId();
+                List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+                List<GroupsRelationView> validGptTicket = getValidGptTicket(userIdList);
+                if (validGptTicket.isEmpty()) {
+                    //车票过期
+                    state = 3;
+                } else {
+                    if (validGptTicket.size() > 1) {
+                        //多张车票
+                        state = 4;
+                    } else {
+                        GroupsRelationView groupsRelationView = validGptTicket.get(0);
+                        Long relationId = groupsRelationView.getId();
+                        //获取gpt镜像访问url
+                        String url = chatGptAccountService.getCarLoginUrl(getGptDomain(), userId, relationId, Constant.GPT_CARD_ID);
+                        resp.setUrl(url);
+                    }
+                }
+            }
+        }
+        resp.setState(state);
+        return resp;
+    }
+    public List<GroupsRelationView> getValidGptTicket(List<Long> userIdList) {
+        List<GroupsRelationView> relationViews = beanSearcher.searchAll(GroupsRelationView.class, MapUtils.builder()
+                .field(GroupsRelationView::getGoodsId, Constant.GPT_PLUS_GID)
+                .field(GroupsRelationView::getUserId, userIdList).op(Operator.InList)
+                .field(GroupsRelationView::getIsMirror, Boolean.TRUE)
+                .field(GroupsRelationView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan)
+                .onlySelect(GroupsRelationView::getId)
+                .build());
+        return relationViews;
+    }
+
+    public String getGptDomain() {
+        SysConfig gptNewDomain = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
+                .eq(SysConfig::getSysKey, "mirror_gpt_new_domain")
+                .last("limit 1"));
+        if (gptNewDomain != null) {
+            String sysValue = gptNewDomain.getSysValue();
+            if (JSONUtil.isJsonArray(sysValue)) {
+                List<String> domainList = JSONUtil.parseArray(sysValue).toList(String.class);
+                if (CollUtil.isNotEmpty(domainList)) {
+                    int randomInt = RandomUtil.randomInt(domainList.size());
+                    return domainList.get(randomInt);
+                }
+            }
+        }
+        return null;
+    }
+}

+ 75 - 0
netflix-web/src/main/java/com/cyksj/web/controller/api/GptQuickLinkController.java

@@ -0,0 +1,75 @@
+package com.cyksj.web.controller.api;
+
+import cn.hutool.core.util.StrUtil;
+import com.cyksj.common.annotation.NoSubmit;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.model.entity.GptQuickLinkRecord;
+import com.cyksj.model.response.GptQuickLinkResp;
+import com.cyksj.service.gpt.GptQuickLinkService;
+import com.cyksj.web.util.StpUserUtil;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * GPT快捷链接API控制器
+ */
+@RestController
+@RequestMapping("/applets/gpt/quickLink")
+@RequiredArgsConstructor
+public class GptQuickLinkController {
+    
+    private final GptQuickLinkService gptQuickLinkService;
+    
+    /**
+     * 创建或获取快捷链接
+     */
+    @NoSubmit
+    @PostMapping("/create")
+    public Result<GptQuickLinkResp> createQuickLink() {
+        // 获取当前登录用户ID
+        Long userId = StpUserUtil.getLoginIdAsLong();
+        // 创建或获取快捷链接
+        GptQuickLinkRecord quickLink = gptQuickLinkService.createQuickLink(userId);
+        GptQuickLinkResp resp = new GptQuickLinkResp();
+        resp.setCode(quickLink.getCode());
+        resp.setExpiryTime(quickLink.getExpiryTime());
+        return GatewayResponse.SUCCESS.newBuilder().toResult(resp);
+    }
+    
+    /**
+     * 获取最新的快捷链接
+     */
+    @GetMapping("/get")
+    public Result<GptQuickLinkResp> getLatestQuickLink() {
+        // 获取当前登录用户ID
+        Long userId = StpUserUtil.getLoginIdAsLong();
+        // 获取最新的快捷链接
+        GptQuickLinkRecord quickLink = gptQuickLinkService.getLatestQuickLink(userId);
+        if (quickLink == null) {
+            return GatewayResponse.SUCCESS.newBuilder().toResult();
+        }
+        GptQuickLinkResp resp = new GptQuickLinkResp();
+        resp.setCode(quickLink.getCode());
+        resp.setExpiryTime(quickLink.getExpiryTime());
+        return GatewayResponse.SUCCESS.newBuilder().toResult(resp);
+    }
+
+    /**
+     * 通过快捷链接登录gpt镜像对话页
+     */
+    @GetMapping("/get/chatGpt/page/{code}")
+    public Result<GptQuickLinkResp> getCharGptPageByCode(@PathVariable String code) {
+        GptQuickLinkResp resp = gptQuickLinkService.getQuickUrlByCode(code.trim());
+        if (resp.getState() == 4) {
+            Long userId = resp.getUserId();
+            String token = StpUserUtil.getTokenValueByLoginId(userId);
+            if (StrUtil.isEmpty(token)) {
+                StpUserUtil.login(resp.getUserId());
+                token = StpUserUtil.getTokenValue();
+            }
+            resp.setToken(token);
+        }
+        return GatewayResponse.SUCCESS.newBuilder().toResult(resp);
+    }
+}