Parcourir la source

fix midjouney-alpha 版本

chenbiao il y a 2 ans
Parent
commit
ece6a90b79

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/MidjourneyUser.java

@@ -56,6 +56,8 @@ public class MidjourneyUser extends BaseEntity{
      */
     private Integer mode;
 
+    private Boolean isCar;
+
     /**
      * 车票类型 2试用
      */

+ 53 - 0
netflix-dao/src/main/java/com/cyksj/model/views/MidjouneyCarInfoView.java

@@ -0,0 +1,53 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Data;
+
+/**
+ * @author chan
+ * @date 2024/8/7 13:46
+ */
+@Data
+@SearchBean(
+        tables = "midjourney_session mj "
+        ,where = "mj.status is true"
+)
+public class MidjouneyCarInfoView {
+
+
+    private Long id;
+
+    /**
+     * 状态
+     */
+    private Boolean status;
+
+    /**
+     * 是否为快速号
+     */
+    @DbField("mj.isPlus")
+    private Boolean isPlus;
+
+    /**
+     * 车id
+     */
+    @DbField("mj.carID")
+    private String carId;
+
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 剩余快速时间
+     */
+    @DbField("mj.fastTime")
+    private Long fastTime;
+
+    /**
+     * 得分
+     */
+    private Double score;
+}

+ 25 - 5
netflix-dao/src/main/java/com/cyksj/model/views/MidjourneyUserView.java

@@ -1,9 +1,11 @@
 package com.cyksj.model.views;
 
 import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.DbIgnore;
 import com.ejlchina.searcher.bean.SearchBean;
 import lombok.Data;
 
+import java.math.BigDecimal;
 import java.util.Date;
 
 /**
@@ -11,7 +13,9 @@ import java.util.Date;
  * @date 2024/4/28 17:43
  */
 @Data
-@SearchBean(tables = "midjourney_user mu left join groups_relation gr on mu.relation_id = gr.id ")
+@SearchBean(tables = "midjourney_user mu left join groups_relation gr on mu.relation_id = gr.id " +
+        " left join groups_trips gt on gt.id = gr.groups_id" +
+        " left join goods_don_sku sku on sku.id = gt.sku_id")
 public class MidjourneyUserView {
 
 
@@ -25,16 +29,32 @@ public class MidjourneyUserView {
     private Long userId;
 
     @DbField("mu.mj_fast_num")
-    private Integer mjFastNum;
+    private Integer mjUserFastNum;
 
     @DbField("mu.mj_relax_num")
+    private Integer mjUserRelaxNum;
+
+    /**
+     * sku mj fast次数
+     */
+    @DbField("sku.mj_fast_num")
+    private Integer mjFastNum;
+
+    /**
+     * sku mj relax次数
+     */
+    @DbField("sku.mj_relax_num")
     private Integer mjRelaxNum;
 
     @DbField("mu.expire_time")
     private Date expireTime;
 
+    @DbField("gt.sku_id")
+    private Long skuId;
 
-
-
-
+    /**
+     * mj 套餐包最低单价
+     */
+    @DbIgnore
+    private BigDecimal mjPackagePrice;
 }

+ 2 - 13
netflix-service/src/main/java/com/cyksj/service/midjourney/MidjourneyService.java

@@ -11,19 +11,8 @@ import java.util.List;
  * @date 2024/4/23 15:44
  */
 public interface MidjourneyService {
-    MidjourneyUserConversation submitImagine(MidjourneyUser user, String prompt, List<String> base64Array) throws Exception;
+    MidjourneyUser getUser(long userId, Long relationId);
 
-    MidjourneyUserConversation submitDescribe(MidjourneyUser user, String base64) throws Exception;
+    String getCarLoginUrl(Long userId, Long relationId, String carId);
 
-    MidjourneyUserConversation submitBlend(MidjourneyUser user, BlendDimensions dimensions, List<String> base64Array) throws Exception;
-
-    MidjourneyUserConversation submitModal(MidjourneyUser user, Long taskId, String prompt, String maskBase64) throws Exception;
-
-    MidjourneyUserConversation submitShorten(MidjourneyUser user, String prompt) throws Exception;
-
-    List<MidjourneyUserConversation> listConversationByIds(Integer mode, List<Long> ids) throws Exception;
-
-    MidjourneyUserConversation submitAction(MidjourneyUser user, Long taskId, String customId) throws Exception;
-
-    MidjourneyUserConversation cancelConversation(MidjourneyUser user, Long id);
 }

+ 121 - 260
netflix-service/src/main/java/com/cyksj/service/midjourney/impl/MidjourneyServiceImpl.java

@@ -1,7 +1,12 @@
 package com.cyksj.service.midjourney.impl;
 
 import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.lang.UUID;
 import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.RandomUtil;
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpUtil;
 import cn.hutool.json.JSONArray;
@@ -11,17 +16,21 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
 import com.cyksj.common.util.Jsons;
-import com.cyksj.mapper.MidjourneyUserConversationMapper;
+import com.cyksj.common.util.StringUtil;
+import com.cyksj.mapper.*;
 import com.cyksj.model.dto.BlendDimensions;
 import com.cyksj.model.dto.MessageButton;
-import com.cyksj.model.entity.MidjourneyUser;
-import com.cyksj.model.entity.MidjourneyUserConversation;
+import com.cyksj.model.entity.*;
 import com.cyksj.model.response.SubmitResult;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.midjourney.MidjourneyService;
+import com.cyksj.service.sys.SysConfigService;
+import com.cyksj.service.user.UserBindRelationService;
+import com.ejlchina.searcher.BeanSearcher;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
+import org.springframework.dao.DuplicateKeyException;
 import org.springframework.stereotype.Service;
 
 import javax.imageio.stream.FileImageOutputStream;
@@ -40,295 +49,147 @@ import java.util.stream.Collectors;
 @Slf4j
 @RequiredArgsConstructor
 public class MidjourneyServiceImpl implements MidjourneyService {
-    private static final String RELAX_HOST = "http://43.154.230.104:8080";
-    private static final String FAST_HOST = "https://aigc.api4midjourney.com/api";
-    private static final String FAST_TOKEN = "14a6b469-7cb2-4b99-9238-676c7c5cffef";
 
-    private final MidjourneyUserConversationMapper conversationMapper;
+    private final MidjourneyUserMapper midjourneyUserMapper;
 
-    private static final List<String> progress = List.of("100%");
+    private final GroupsRelationMapper groupsRelationMapper;
 
-    private static final List<String> status = List.of("MODAL","CANCEL","FAILURE");
+    private final BeanSearcher beanSearcher;
 
-    private final RedisService redisService;
+    private final UserBindRelationService userBindRelationService;
 
-    private static final GlobalThreadPoolTaskExecutor TASK_EXECUTOR = GlobalThreadPoolTaskExecutor.getInstance();
+    private final GroupsMapper groupsMapper;
 
+    private final UserMapper userMapper;
 
-    @Override
-    public MidjourneyUserConversation submitImagine(MidjourneyUser user, String prompt, List<String> base64Array) throws Exception {
-        Map<String, Object> imagineParam = MapUtil.builder(new HashMap<String,Object>())
-                .put("prompt", prompt).put("state", user.getId()).build();
-        if (CollectionUtil.isNotEmpty(base64Array)) {
-            imagineParam.put("base64Array", base64Array);
-        }
-        SubmitResult result = submit(user.getMode(),"imagine", imagineParam);
-        return saveConversation(user.getId(), user.getMode(),Long.parseLong(result.getResult()),result.getProperties(),"IMAGINE", StringUtils.EMPTY);
-    }
+    private final RedisService redisService;
 
-    public MidjourneyUserConversation saveConversation(Long userId,Integer mode,Long taskId,Map<String,Object> properties, String action,String prompt) throws Exception {
-        MidjourneyUserConversation conversation = new MidjourneyUserConversation()
-                .setUserId(userId).setTaskId(taskId).setAction(action).setPrompt(prompt)
-                .setMode(mode).setStartTime(System.currentTimeMillis()).setProgress("0%")
-                .setStatus("IN_PROGRESS").setTaskId(taskId);
-        if (MapUtil.isNotEmpty(properties)) {
-            conversation.setProperties(Jsons.toJson(properties));
-            conversation.setChannelId(properties.get("discordChannelId") == null ? null : Long.parseLong(properties.get("discordChannelId").toString()))
-                    .setInstanceId(properties.get("discordInstanceId") == null ? null : Long.parseLong(properties.get("discordInstanceId").toString()));
-        }
-        conversationMapper.insert(conversation);
-        return conversation;
-    }
+    private final GoodsDonSkuMapper skuMapper;
 
+    private final SysConfigService sysConfigService;
 
     @Override
-    public MidjourneyUserConversation submitDescribe(MidjourneyUser user, String base64) throws Exception {
-        Map<String, Object> param = MapUtil.builder(new HashMap<String,Object>()).put("state", user.getId()).put("base64", base64).build();
-        SubmitResult result = submit(user.getMode(),"describe", param);
-        return saveConversation(user.getId(), user.getMode(),Long.parseLong(result.getResult()),result.getProperties(),"DESCRIBE", StringUtils.EMPTY);
-    }
+    public MidjourneyUser getUser(long userId, Long relationId) {
+        GroupsRelation groupsRelation = getGroupsRelation(userId, relationId);
+        GroupsTrips groupsTrips = getGroupsTrips(groupsRelation);
+        GoodsDonSku goodsDonSku = skuMapper.selectById(groupsTrips.getSkuId());
 
-    @Override
-    public MidjourneyUserConversation submitBlend(MidjourneyUser user, BlendDimensions dimensions, List<String> base64Array) throws Exception {
-        Map<String, Object> param = MapUtil.builder(new HashMap<String,Object>())
-                .put("base64Array", base64Array).put("state", user.getId()).build();
-        if (dimensions != null) {
-            param.put("dimensions", dimensions);
-        }
-        SubmitResult result = submit(user.getMode(),"blend", param);
-        Map<String, Object> properties = result.getProperties();
-        if (user.getMode() == 1) {
-            String finalPrompt = "%s --ar %s --style raw --s 250";
-            List<String> picList = uploadBase64Pic(base64Array);
-            String pics = picList.stream().map(pic -> "<" + pic + ">").collect(Collectors.joining(" "));
-            properties.put("finalPrompt", String.format(finalPrompt, pics,dimensions.getValue()));
-        }
-        return saveConversation(user.getId(), user.getMode(), Long.parseLong(result.getResult()),properties,"BLEND", StringUtils.EMPTY);
-    }
-
-    @Override
-    public MidjourneyUserConversation submitModal(MidjourneyUser user, Long taskId, String prompt, String maskBase64) throws Exception {
-        Map<String, Object> param = MapUtil.builder(new HashMap<String,Object>())
-                .put("taskId", taskId).put("state", user.getId()).build();
-        if (StringUtils.isNotBlank(prompt)) {
-            param.put("prompt", prompt);
-        }
-        if (StringUtils.isNotBlank(maskBase64)) {
-            param.put("maskBase64", maskBase64);
+        if (goodsDonSku != null && goodsDonSku.getGoodsId() == 26 && goodsDonSku.getIsMirror()) {
+            return getMidjourneyUser(userId, relationId, groupsRelation, goodsDonSku);
+        } else {
+            throw BusinessRuntimeException.getInstance("服务器出了点问题");
         }
-        SubmitResult result = submit(user.getMode(),"modal", param);
-        return saveConversation(user.getId(),  user.getMode(),Long.parseLong(result.getResult()),result.getProperties(),"MODAL", StringUtils.EMPTY);
     }
 
     @Override
-    public MidjourneyUserConversation submitShorten(MidjourneyUser user, String prompt) throws Exception {
-        Map<String, Object> param = MapUtil.builder(new HashMap<String,Object>())
-                .put("prompt", prompt).put("state", user.getId()).build();
-        SubmitResult result = submit(user.getMode(),"shorten", param);
-        return saveConversation(user.getId(), user.getMode(), Long.parseLong(result.getResult()),result.getProperties(),"SHORTEN", StringUtils.EMPTY);
-    }
-
-    /**
-     * 恢复次数
-     */
-    public void recoverUserLimit(Long id,Integer mode,Integer num){
-        if (mode == 1){
-            redisService.incr(RedisService.key.MIDJOURNEY_FAST_LIMIT.getName() + id, 1L);
-        }
-        if (mode == 2){
-            if (num != null) {
-                redisService.incr(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + id, 1L);
-            }
-        }
-    }
-    @Override
-    public MidjourneyUserConversation submitAction(MidjourneyUser user, Long taskId, String customId) throws Exception {
-        MidjourneyUserConversation conversation = conversationMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUserConversation.class).eq(MidjourneyUserConversation::getTaskId, taskId).last("limit 1"));
-        if (conversation == null) {
-            throw BusinessRuntimeException.getInstance("关联任务不存在或已失效");
-        }
-        if (!user.getMode().equals(conversation.getMode())) {
-            throw BusinessRuntimeException.getInstance("当前出图模式与关联任务出图模式不符");
-        }
-        AtomicBoolean flag = new AtomicBoolean(false);
-        if (StringUtils.isNotBlank(conversation.getButtons())){
-            List<MessageButton> messageButtons = Jsons.parseList(conversation.getButtons(), MessageButton.class);
-            messageButtons.forEach(button -> {
-                if (button.getCustomId().equals(customId)) {
-                    log.info("action customId:{}", customId);
-                    button.setStyle(3);
-                    if (button.getLabel().contains("Vary") || button.getCustomId().contains("::pan_")
-                            || button.getEmoji().equals("🔄") || button.getCustomId().contains("PromptAnalyzer:")
-                            || button.getCustomId().contains("PicReader::") || button.getCustomId().contains("::variation::")
-                            || button.getCustomId().contains("::CustomZoom::")) {
-                        flag.set(true);
+    public String getCarLoginUrl(Long userId, Long relationId, String carId) {
+
+        GroupsRelation groupsRelation = getGroupsRelation(userId, relationId);
+        GroupsTrips groupsTrips = getGroupsTrips(groupsRelation);
+        GoodsDonSku goodsDonSku = skuMapper.selectById(groupsTrips.getSkuId());
+        if (goodsDonSku != null && goodsDonSku.getIsMirror() && goodsDonSku.getIsCar()) {
+            MidjourneyUser midjourneyUser = getMidjourneyUser(userId, relationId, groupsRelation, goodsDonSku);
+
+            String DOMAIN = "https://mj.yinhedvd.com";
+            try {
+                SysConfig sysConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, "mirror_mj_domain"));
+                if (sysConfig != null) {
+                    String sysValue = sysConfig.getSysValue();
+                    if (JSONUtil.isJsonArray(sysValue)) {
+                        List<String> domainList = JSONUtil.parseArray(sysValue).toList(String.class);
+                        DOMAIN = domainList.get(RandomUtil.randomInt(domainList.size()));
                     }
                 }
-            });
-            conversation.setButtons(Jsons.toJson(messageButtons));
-        }
-        conversation.setBookmark(customId.contains("BOOKMARK"));
-        conversationMapper.updateById(conversation);
-        if (conversation.getBookmark()) {
-            return conversation;
-        }
-        Map<String, Object> param = MapUtil.builder(new HashMap<String,Object>())
-                .put("taskId", taskId).put("state", user.getId()).put("customId", customId).build();
-        SubmitResult result = submit(user.getMode(),"action", param);
-        if (flag.get()) {
-            // 以上操作有弹窗确认,恢复次数
-            recoverUserLimit(user.getId(), user.getMode(),user.getMjRelaxNum());
-        }
-        return saveConversation(user.getId(), user.getMode(), Long.parseLong(result.getResult()),result.getProperties(),"ACTION", StringUtils.EMPTY);
-    }
-
-
-    public SubmitResult submit(Integer mode,String action, Map<String, Object> param) throws Exception {
-        if (mode == 1) {
-            param.put("mode", "FAST");
-        }
-        String url = (mode == 1 ? FAST_HOST : RELAX_HOST) + getActionUrl(action);
-        String body = HttpRequest.post(url).body(Jsons.toJson(param)).header("Authorization", FAST_TOKEN).execute().body();
-        log.info("action body:{}", body);
-        SubmitResult submitResult = Jsons.parseObject(body, SubmitResult.class);
-        int code = submitResult.getCode();
-        if (code != 1 && code != 21 && code != 22) {
-            if (code == 3) {
-                throw BusinessRuntimeException.getInstance("账号不存在");
-            }
-            if (code == 4) {
-                throw BusinessRuntimeException.getInstance("图片重复");
+            } catch (Exception e) {
+                log.error("随机抽取域名错误. msg:{}", StringUtil.getErrorText(e));
             }
-            if (code == 24) {
-                throw BusinessRuntimeException.getInstance("prompt包含敏感词");
-            }
-            log.error("action:" + action + " error message:" + submitResult.getDescription());
-            throw BusinessRuntimeException.getInstance("队列已满,请稍后尝试");
-        }
-        return submitResult;
-    }
-    private String getActionUrl(String action) {
-         switch (action) {
-            case "imagine":
-                return "/mj/submit/imagine";
-            case "action":
-                return "/mj/submit/action";
-            case "describe":
-                return "/mj/submit/describe";
-            case "blend":
-                return"/mj/submit/blend";
-            case "modal":
-                return "/mj/submit/modal";
-            case "shorten":
-                return "/mj/submit/shorten";
-            default:  throw new IllegalArgumentException("Unknown action: " + action);
+            log.info("domain:{},用户:{},所在车次:{},座位id:{},在{}获取跳转Midjourney镜像的登录url", DOMAIN, userId, groupsTrips.getId(), relationId, DateTime.now());
+            return DOMAIN + "/auth/logintoken?carid=" + carId + "&usertoken=" + midjourneyUser.getUserToken();
+        } else {
+            throw BusinessRuntimeException.getInstance("服务器出了点问题");
         }
     }
-    @Override
-    public List<MidjourneyUserConversation> listConversationByIds(Integer mode, List<Long> ids) throws Exception {
-        List<MidjourneyUserConversation> list = new ArrayList<>();
-        listByIds(mode,ids).forEach(json -> {
-            JSONObject jsons = JSONUtil.parseObj(json);
-            MidjourneyUserConversation conversation = JSONUtil.toBean(jsons, MidjourneyUserConversation.class);
-            conversation.setUserId(jsons.getLong("state"));
-            conversation.setTaskId(jsons.getLong("id"));
-            list.add(conversation);
-            TASK_EXECUTOR.execute(() -> {
-                try {
-                    sync(conversation);
-                } catch (IOException e) {
-                    throw new RuntimeException(e);
-                }
-            });
-        });
-        return list;
-    }
 
 
-    public void sync(MidjourneyUserConversation conversation) throws IOException {
-        if ((StringUtils.isNotBlank(conversation.getProgress()) && progress.contains(conversation.getProgress())) || status.contains(conversation.getStatus())) {
-            log.info("同步任务:{},进度:{}",conversation.getTaskId(),conversation.getProgress());
-            MidjourneyUserConversation dbConversation = conversationMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUserConversation.class).eq(MidjourneyUserConversation::getTaskId, conversation.getTaskId())
-                    .eq(MidjourneyUserConversation::getUserId, conversation.getUserId()).last("limit 1"));
-            if (dbConversation != null) {
-                try {
-                    if (StringUtils.isNotBlank(conversation.getImageUrl())) {
-                        conversation.setImageUrl(uploadPic(conversation.getImageUrl(), "conversation"+dbConversation.getId()));
-                    }
-                } catch (IOException e) {
-                    log.error("上传图片失败",e);
-                }finally {
-                    conversation.setId(dbConversation.getId());
-                    conversationMapper.updateById(conversation);
-                }
-            }
-        }
-    }
-
-
-    private static String uploadPic(String url, String prefix) throws IOException {
-        byte[] body = HttpUtil.downloadBytes(url);
-        Path tempFile = Files.createTempFile(prefix, ".png");
-        try (FileImageOutputStream imageOutput = new FileImageOutputStream(tempFile.toFile())) {
-            imageOutput.write(body, 0, body.length);
+    /**
+     * 获取车位信息
+     *
+     * @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("车票不存在");
         }
-        Map<String, Object> paramMap = new HashMap<>();
-        paramMap.put("file", tempFile.toFile());
-        JSONObject result = JSONUtil.parseObj(HttpUtil.post("https://files.liuliangbang.vip/pic/ups", paramMap));
-        return result.getJSONObject("value").getJSONArray("saved").getJSONObject(0).getJSONObject("info").getStr("cdnUrl");
+        return groupsRelation;
     }
 
-    private static List<String> uploadBase64Pic(List<String> base64Array) throws IOException {
-        List<String> list = new ArrayList<>();
-        for (String base64 : base64Array) {
-            String fileExt = "jpeg";
-            if (base64.contains(";")){
-                fileExt = base64.split(";")[0].split("/")[1];
-                base64 = base64.split(",")[1];
-            }
-            byte[] body = Base64.getDecoder().decode(base64);
-            Path tempFile = Files.createTempFile(UUID.randomUUID().toString(), "." + fileExt);
-            try (FileImageOutputStream imageOutput = new FileImageOutputStream(tempFile.toFile())) {
-                imageOutput.write(body, 0, body.length);
-            }
-            Map<String, Object> paramMap = new HashMap<>();
-            paramMap.put("file", tempFile.toFile());
-            JSONObject result = JSONUtil.parseObj(HttpUtil.post("https://files.liuliangbang.vip/pic/ups", paramMap));
-            list.add(result.getJSONObject("value").getJSONArray("saved").getJSONObject(0).getJSONObject("info").getStr("cdnUrl"));
+    /**
+     * 获取车队信息
+     *
+     * @param groupsRelation
+     * @return
+     */
+    private GroupsTrips getGroupsTrips(GroupsRelation groupsRelation) {
+        GroupsTrips groupsTrips = groupsMapper.selectById(groupsRelation.getGroupsId());
+        if (groupsTrips == null) {
+            throw BusinessRuntimeException.getInstance("车队异常");
         }
-        return list;
-    }
-    public JSONArray listByIds(Integer mode,List<Long> ids) throws Exception {
-        Map<String, Object> param = MapUtil.builder(new HashMap<String, Object>()).put("ids", ids).build();
-        String body = HttpRequest.post((mode == 1 ? FAST_HOST : RELAX_HOST) + "/mj/task/list-by-condition").header("Authorization", FAST_TOKEN).body(Jsons.toJson(param)).execute().body();
-        log.info("listByIds body:{}", body);
-        return JSONUtil.parseArray(body);
+        return groupsTrips;
     }
 
-    @Override
-    public MidjourneyUserConversation cancelConversation(MidjourneyUser user, Long id) {
-        MidjourneyUserConversation conversation = conversationMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUserConversation.class).eq(MidjourneyUserConversation::getId, id));
-        if (conversation == null) {
-            throw BusinessRuntimeException.getInstance("会话不存在");
-        }
-        if (!Objects.equals(conversation.getUserId(), user.getId())) {
-            throw BusinessRuntimeException.getInstance("不是您的会话");
+    private MidjourneyUser getMidjourneyUser(Long userId, Long relationId, GroupsRelation groupsRelation, GoodsDonSku goodsDonSku) {
+        MidjourneyUser midjourneyUser = midjourneyUserMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUser.class).eq(MidjourneyUser::getRelationId, relationId));
+        User user = userMapper.selectById(userId);
+        if (midjourneyUser == null) {
+            midjourneyUser = createMidjourneyUser(groupsRelation, user, goodsDonSku);
+        } else {
+            updateMidjourneyUser(groupsRelation, user, midjourneyUser);
         }
-        conversation.setStatus("CANCEL");
-        conversationMapper.updateById(conversation);
-        TASK_EXECUTOR.execute(() -> {
-            cancel(user.getMode(),conversation.getTaskId());
-        });
-        return conversation;
+        return midjourneyUser;
     }
 
-    public void cancel(Integer mode,Long taskId) {
-        String body = HttpUtil.post(mode == 1 ? FAST_HOST : RELAX_HOST + "/mj/task/"+taskId+"/cancel",MapUtil.empty());
-        log.info("cancel body:{}", body);
-        JSONObject jsonObject = JSONUtil.parseObj(body);
-        if (jsonObject.getInt("code") != 1) {
-            throw BusinessRuntimeException.getInstance("cancel error message:" + jsonObject.getStr("description"));
-        }
+    /**
+     * 创建MidjourneyUser
+     */
+    private synchronized MidjourneyUser createMidjourneyUser(GroupsRelation groupsRelation, User user, GoodsDonSku goodsDonSku) {
+        MidjourneyUser midjourneyUser = new MidjourneyUser();
+        midjourneyUser.setExpireTime(groupsRelation.getExpiryTime());
+        midjourneyUser.setName(user.getNickname());
+        midjourneyUser.setImg("https://cdn.sxfoundation.com/picture/f6ee11101c4f5f0bc48d88aca7a5dbfd-1666945673391.png");
+        midjourneyUser.setRelationId(groupsRelation.getId());
+        midjourneyUser.setUserToken(UUID.randomUUID().toString());
+        if (groupsRelation.getAqType() == 2) {
+            //fast模式 5次
+            midjourneyUser.setMjFastNum(5);
+            midjourneyUser.setMjRelaxNum(0);
+        } else {
+            midjourneyUser.setMjFastNum(goodsDonSku.getMjFastNum());
+            midjourneyUser.setMjRelaxNum((goodsDonSku.getMjRelaxNum() == null || goodsDonSku.getMjRelaxNum() == 0) ? null : goodsDonSku.getMjRelaxNum());
+        }
+        midjourneyUser.setAqType(groupsRelation.getAqType());
+        try {
+            midjourneyUserMapper.insert(midjourneyUser);
+        } catch (DuplicateKeyException e) {
+        }
+        redisService.set(RedisService.key.MIDJOURNEY_FAST_LIMIT.getName() + midjourneyUser.getId(), midjourneyUser.getMjFastNum(), RedisService.key.MIDJOURNEY_FAST_LIMIT.getTimeout());
+        redisService.set(RedisService.key.MIDJOURNEY_USER.getName() + midjourneyUser.getUserToken(), midjourneyUser, RedisService.key.MIDJOURNEY_USER.getTimeout());
+        if (midjourneyUser.getMjRelaxNum() != null) {
+            redisService.set(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + midjourneyUser.getId(), midjourneyUser.getMjRelaxNum(), RedisService.key.MIDJOURNEY_RELAX_LIMIT.getTimeout());
+        }
+        return midjourneyUser;
+    }
+
+    private void updateMidjourneyUser(GroupsRelation groupsRelation, User user, MidjourneyUser midjourneyUser) {
+        midjourneyUser.setName(user.getNickname());
+        midjourneyUser.setImg("https://cdn.sxfoundation.com/picture/f6ee11101c4f5f0bc48d88aca7a5dbfd-1666945673391.png");
+        midjourneyUser.setExpireTime(groupsRelation.getExpiryTime());
+        midjourneyUserMapper.updateById(midjourneyUser);
+        midjourneyUser.setAqType(groupsRelation.getAqType());
+        redisService.set(RedisService.key.MIDJOURNEY_USER.getName() + midjourneyUser.getUserToken(), midjourneyUser, RedisService.key.MIDJOURNEY_USER.getTimeout());
     }
 
 }

+ 50 - 350
netflix-web/src/main/java/com/cyksj/web/controller/mirror/MidjourneyController.java

@@ -1,34 +1,29 @@
 package com.cyksj.web.controller.mirror;
 
-import cn.hutool.core.util.StrUtil;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import cn.hutool.core.collection.CollectionUtil;
 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.mapper.GroupsRelationMapper;
-import com.cyksj.mapper.MidjourneyPaintingPlazaMapper;
-import com.cyksj.mapper.MidjourneyUserMapper;
-import com.cyksj.model.dto.*;
-import com.cyksj.model.entity.GroupsRelation;
-import com.cyksj.model.entity.MidjourneyPaintingPlaza;
+import com.cyksj.mapper.UpgradePackageMapper;
 import com.cyksj.model.entity.MidjourneyUser;
-import com.cyksj.model.entity.MidjourneyUserConversation;
-import com.cyksj.model.views.MidjourneyPaintingUserView;
-import com.cyksj.model.views.MidjourneyUserPaintingDayRecordView;
-import com.cyksj.model.views.MidjourneyUserPaintingRecordView;
-import com.cyksj.redis.RedisService;
+import com.cyksj.model.entity.UpgradePackage;
+import com.cyksj.model.views.MidjouneyCarInfoView;
+import com.cyksj.model.views.MidjourneyUserView;
 import com.cyksj.service.midjourney.MidjourneyService;
+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.util.MapBuilder;
+import com.ejlchina.searcher.param.Operator;
 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.Date;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.List;
 
 /** server/镜像服务/mj绘画
@@ -41,369 +36,74 @@ import java.util.List;
 @RequestMapping("/applets/midjourney")
 public class MidjourneyController {
 
-    private final MidjourneyUserMapper midjourneyUserMapper;
 
     private final HttpServletRequest request;
 
     private final MidjourneyService midjourneyService;
 
     private final BeanSearcher beanSearcher;
-    
-    private final RedisService redisService;
 
-    private final GroupsRelationMapper groupsRelationMapper;
+    private final UpgradePackageMapper upgradePackageMapper;
 
-    private final MidjourneyPaintingPlazaMapper midjourneyPaintingPlazaMapper;
-    public MidjourneyUser getUser(){
-        String userToken = request.getHeader("user-token");
-        MidjourneyUser midjourneyUser = (MidjourneyUser) redisService.get(RedisService.key.MIDJOURNEY_USER.getName() + userToken);
-        if (midjourneyUser == null){
-            midjourneyUser = midjourneyUserMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUser.class)
-                    .eq(MidjourneyUser::getUserToken, userToken).last("limit 1"));
-            if (midjourneyUser == null){
-                throw new BusinessRuntimeException("账号不存在,请重新登录");
-            }
-            Long relationId = midjourneyUser.getRelationId();
-            GroupsRelation relation = groupsRelationMapper.selectById(relationId);
-            midjourneyUser.setAqType(relation.getAqType());
-            redisService.set(RedisService.key.MIDJOURNEY_USER.getName() + userToken, midjourneyUser, RedisService.key.MIDJOURNEY_USER.getTimeout());
-            Object fastNum = redisService.get(RedisService.key.MIDJOURNEY_FAST_LIMIT.getName() + midjourneyUser.getId());
-            if (fastNum == null){
-                redisService.set(RedisService.key.MIDJOURNEY_FAST_LIMIT.getName() + midjourneyUser.getId(), midjourneyUser.getMjFastNum(), RedisService.key.MIDJOURNEY_FAST_LIMIT.getTimeout());
-            }
-            Object relaxNum = redisService.get(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + midjourneyUser.getId());
-            if (relaxNum == null){
-                if (midjourneyUser.getMjRelaxNum() != null){
-                    redisService.set(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + midjourneyUser.getId(), midjourneyUser.getMjRelaxNum(), RedisService.key.MIDJOURNEY_RELAX_LIMIT.getTimeout());
-                }
-            }
-        }else {
-            Object fastNum = redisService.get(RedisService.key.MIDJOURNEY_FAST_LIMIT.getName() + midjourneyUser.getId());
-            if (fastNum == null){
-                redisService.set(RedisService.key.MIDJOURNEY_FAST_LIMIT.getName() + midjourneyUser.getId(), midjourneyUser.getMjFastNum(), RedisService.key.MIDJOURNEY_FAST_LIMIT.getTimeout());
-            }else {
-                midjourneyUser.setMjFastNum(Integer.parseInt(fastNum.toString()));
-            }
-            Object relaxNum = redisService.get(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + midjourneyUser.getId());
-            if (relaxNum == null){
-                if (midjourneyUser.getMjRelaxNum() != null){
-                    redisService.set(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + midjourneyUser.getId(), midjourneyUser.getMjRelaxNum(), RedisService.key.MIDJOURNEY_RELAX_LIMIT.getTimeout());
-                }
-            }else {
-                midjourneyUser.setMjRelaxNum(Integer.parseInt(relaxNum.toString()));
-            }
-        }
-        return midjourneyUser;
-    }
-
-
-    /**
-     * 检查用户次数
-     */
-    public Long checkUserLimit(MidjourneyUser user){
-        Long num = 0L;
-        if (user.getExpireTime().before(new Date())){
-            throw BusinessRuntimeException.getInstance("账号已过期");
-        }
-       if (user.getMode() == 1){
-           num = redisService.decr(RedisService.key.MIDJOURNEY_FAST_LIMIT.getName() + user.getId(), 1L);
-           if (num < 0) {
-               user.setMode(2);
-               redisService.incr(RedisService.key.MIDJOURNEY_FAST_LIMIT.getName() + user.getId(), 1L);
-           }
-       }
-       if (user.getMode() == 2){
-           Object relax = redisService.get(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + user.getId());
-           if (relax != null){
-               num = redisService.decr(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + user.getId(), 1L);
-               if (num < 0){
-                   redisService.incr(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + user.getId(), 1L);
-               }
-           }else {
-               num = null;
-           }
-       }
-       return num;
-    }
-
-    /**
-     * 恢复次数
-     */
-    public void recoverUserLimit(Long id,Integer mode,Long num){
-        if (mode == 1){
-            redisService.incr(RedisService.key.MIDJOURNEY_FAST_LIMIT.getName() + id, 1L);
-        }
-        if (mode == 2){
-            if (num != null){
-                redisService.incr(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + id, 1L);
-            }
-        }
-    }
+    private final UserBindRelationService userBindRelationService;
 
-    /**
-     * 同步数据库
-     */
-    public void syncUser(Long id,Integer mode,Long num){
-        log.info("同步次数 id:{},mode:{},num:{}",id,mode,num);
-        if (num == null){
-            return;
-        }
-        LambdaUpdateWrapper<MidjourneyUser> wrapper = Wrappers.lambdaUpdate(MidjourneyUser.class)
-                .eq(MidjourneyUser::getId, id);
-        if (mode == 1){
-            wrapper.set(MidjourneyUser::getMjFastNum, num);
-        }
-        if (mode == 2){
-            wrapper.set(MidjourneyUser::getMjRelaxNum, num);
-        }
-        midjourneyUserMapper.update(null, wrapper);
-    }
 
+    //-------------------------alpha -----------------------
 
     /**
-     * 查询用户信息
-     */
-    @GetMapping("/whoami")
-    public Result<MidjourneyUser> queryUser(){
-        MidjourneyUser user = getUser();
-        return GatewayResponse.SUCCESS.newBuilder().toResult(user);
-    }
-
-
-    /**
-     * 提交Imagine任务
-     */
-    @PostMapping("/submit/imagine")
-    public Result<MidjourneyUserConversation> submitImagine(@RequestBody SubmitImagineDTO submitImagineDTO) {
-        log.info("提交Imagine任务,提示:{},base64数组长度:{}",submitImagineDTO.getPrompt(),submitImagineDTO.getBase64Array());
-        MidjourneyUser user = getUser();
-        Long num = checkUserLimit(user);
-        if (num != null && num < 0){
-            throw BusinessRuntimeException.getInstance("次数已用完");
-        }
-        MidjourneyUserConversation conversation;
-        try {
-            conversation = midjourneyService.submitImagine(user, submitImagineDTO.getPrompt(), submitImagineDTO.getBase64Array());
-        } catch (Exception e) {
-            recoverUserLimit(user.getId(), user.getMode(),num);
-            throw BusinessRuntimeException.getInstance(e.getMessage());
-        }
-        syncUser(user.getId(), user.getMode(), num);
-        return GatewayResponse.SUCCESS.newBuilder().toResult(conversation);
-    }
-
-    /**
-     * 提交Describe任务
-     */
-    @PostMapping("/submit/describe")
-    public Result<MidjourneyUserConversation> submitDescribe(@RequestBody SubmitDescribeDTO submitDescribeDTO) {
-        log.info("提交Describe任务");
-        MidjourneyUser user = getUser();
-        Long num = checkUserLimit(user);
-        if (num != null && num < 0){
-            throw BusinessRuntimeException.getInstance("次数已用完");
-        }
-        MidjourneyUserConversation conversation;
-        try {
-            conversation = midjourneyService.submitDescribe(user, submitDescribeDTO.getBase64());
-        } catch (Exception e) {
-            recoverUserLimit(user.getId(), user.getMode(),num);
-            throw BusinessRuntimeException.getInstance(e.getMessage());
-        }
-        syncUser(user.getId(), user.getMode(), num);
-        return GatewayResponse.SUCCESS.newBuilder().toResult(conversation);
-    }
-
-    /**
-     * 提交Blend任务
-     */
-    @PostMapping("/submit/blend")
-    public Result<MidjourneyUserConversation> submitBlend(@RequestBody SubmitBlendDTO submitBlendDTO) {
-        log.info("提交Blend任务 dimensions:{},base64数组长度:{}", submitBlendDTO.getDimensions(), submitBlendDTO.getBase64Array().size());
-        MidjourneyUser user = getUser();
-        Long num = checkUserLimit(user);
-        if (num != null && num < 0){
-            throw BusinessRuntimeException.getInstance("次数已用完");
-        }
-        MidjourneyUserConversation conversation;
-        try {
-            conversation = midjourneyService.submitBlend(user, submitBlendDTO.getDimensions(), submitBlendDTO.getBase64Array());
-        } catch (Exception e) {
-            recoverUserLimit(user.getId(), user.getMode(),num);
-            throw BusinessRuntimeException.getInstance(e.getMessage());
-        }
-        syncUser(user.getId(), user.getMode(), num);
-        return GatewayResponse.SUCCESS.newBuilder().toResult(conversation);
-    }
-
-    /**
-     * 提交Modal任务
+     * 获取车队列表
+     *
+     * @param relationId
+     * @return
      */
-    @PostMapping("/submit/modal")
-    public Result<MidjourneyUserConversation> submitModal(@RequestBody SubmitModalDTO submitModalDTO) {
-        log.info("提交Modal任务,taskId:{},提示:{},base64数组长度:{}",submitModalDTO.getTaskId(),submitModalDTO.getPrompt(),submitModalDTO.getMaskBase64());
-        MidjourneyUser user = getUser();
-        Long num = checkUserLimit(user);
-        if (num != null && num < 0){
-            throw BusinessRuntimeException.getInstance("次数已用完");
-        }
-        MidjourneyUserConversation conversation;
-        try {
-            conversation = midjourneyService.submitModal(user, submitModalDTO.getTaskId(), submitModalDTO.getPrompt(), submitModalDTO.getMaskBase64());
-        } catch (Exception e) {
-            recoverUserLimit(user.getId(), user.getMode(),num);
-            throw BusinessRuntimeException.getInstance(e.getMessage());
+    @GetMapping("/mj/cars")
+    public Result<SearchResult<MidjouneyCarInfoView>> getCarInfoList(Long relationId, @RequestParam(defaultValue = "true") Boolean isPlus) {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        //查看用户是否存在车票
+        MidjourneyUser midjourneyUser = midjourneyService.getUser(userId, relationId);
+        if (midjourneyUser == null) {
+            throw BusinessRuntimeException.getInstance("您还未购买车票");
         }
-        syncUser(user.getId(), user.getMode(), num);
-        return GatewayResponse.SUCCESS.newBuilder().toResult(conversation);
-    }
+        SearchResult<MidjouneyCarInfoView> carInfoList = beanSearcher.search(MidjouneyCarInfoView.class,MapUtils.flatBuilder(request.getParameterMap()).build());
 
-    /**
-     * 提交Shorten任务
-     */
-    @PostMapping("/submit/shorten")
-    public Result<MidjourneyUserConversation> submitShorten(@RequestBody SubmitShortenDTO submitShortenDTO) {
-        log.info("提交Shorten任务 提示词:{}",submitShortenDTO.getPrompt());
-        MidjourneyUser user = getUser();
-        Long num = checkUserLimit(user);
-        if (num != null && num < 0){
-            throw BusinessRuntimeException.getInstance("次数已用完");
-        }
-        MidjourneyUserConversation conversation;
-        try {
-            conversation = midjourneyService.submitShorten(user, submitShortenDTO.getPrompt());
-        } catch (Exception e) {
-            recoverUserLimit(user.getId(), user.getMode(),num);
-            throw BusinessRuntimeException.getInstance(e.getMessage());
-        }
-        syncUser(user.getId(), user.getMode(), num);
-        return GatewayResponse.SUCCESS.newBuilder().toResult(conversation);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(carInfoList);
     }
 
     /**
-     * 执行动作
+     * 获取mj车票信息
      */
-    @PostMapping("/submit/action")
-    public Result<MidjourneyUserConversation> action(@RequestBody SubmitActionDTO actionDTO) {
-        log.info("任务id:{},执行动作:{}",actionDTO.getTaskId(),actionDTO.getCustomId());
-        MidjourneyUser user = getUser();
-        Long num = checkUserLimit(user);
-        if (num != null && num < 0){
-            throw BusinessRuntimeException.getInstance("次数已用完");
+    @GetMapping("/mj/userInfo")
+    public Result<MidjourneyUserView> getUserInfo(Long relationId) {
+        long userId = StpUserUtil.getLoginIdAsLong();
+        List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+        MidjourneyUserView search = beanSearcher.searchFirst(MidjourneyUserView.class, MapUtils.flatBuilder(request.getParameterMap())
+                .field(MidjourneyUserView::getUserId, userIdList).op(Operator.InList)
+                .field(MidjourneyUserView::getRelationId, relationId)
+                .build());
+        if (search == null) {
+            throw BusinessRuntimeException.getInstance("您还未购买车票");
         }
-        MidjourneyUserConversation conversation;
-        try {
-            conversation = midjourneyService.submitAction(user, actionDTO.getTaskId(), actionDTO.getCustomId());
-        } catch (Exception e) {
-            recoverUserLimit(user.getId(), user.getMode(),num);
-            throw BusinessRuntimeException.getInstance(e.getMessage());
+        List<UpgradePackage> upgradePackages = upgradePackageMapper.selectList(Wrappers.lambdaQuery(UpgradePackage.class).apply("JSON_CONTAINS(sku_ids,'\"" + search.getSkuId() + "\"')").eq(UpgradePackage::getStatus, Boolean.TRUE).eq(UpgradePackage::getDeleted, Boolean.TRUE));
+        if (CollectionUtil.isNotEmpty(upgradePackages)){
+            upgradePackages.stream().map(e -> e.getPrice().divide(BigDecimal.valueOf(e.getNum()), 2, RoundingMode.HALF_UP)).min(BigDecimal::compareTo).ifPresent(search::setMjPackagePrice);
         }
-        syncUser(user.getId(), user.getMode(), num);
-        return GatewayResponse.SUCCESS.newBuilder().toResult(conversation);
-    }
-
-
-    /**
-     * 查询会话列表
-     */
-    @GetMapping("/conversation/list")
-    public Result<SearchResult<MidjourneyUserConversation>> conversationList(){
-        MidjourneyUser user = getUser();
-        log.info("查询会话列表 userId:{}",user.getId());
-        MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
-        return GatewayResponse.SUCCESS.newBuilder().toResult(beanSearcher.search(MidjourneyUserConversation.class,
-                builder.field(MidjourneyUserConversation::getUserId, user.getId())
-                        .orderBy(MidjourneyUserConversation::getId).desc().build()));
-    }
-
-    /**
-     * 根据ids查询会话
-     */
-    @GetMapping("/conversation/listByIds")
-    public Result<List<MidjourneyUserConversation>> conversationListByIds(Integer mode,@RequestParam(value = "ids" ) List<Long> ids) throws Exception {
-        MidjourneyUser user = getUser();
-        log.info("根据ids查询会话 userId:{}",user.getId());
-        return GatewayResponse.SUCCESS.newBuilder().toResult(midjourneyService.listConversationByIds(mode,ids));
-    }
-
-    /**
-     * 取消任务
-     */
-    @PostMapping("/conversation/{id}/cancel")
-    public Result<MidjourneyUserConversation> conversationCancel(@PathVariable("id") Long id){
-        MidjourneyUser user = getUser();
-        log.info("取消任务 id:{}",id);
-        return GatewayResponse.SUCCESS.newBuilder().toResult(midjourneyService.cancelConversation(user,id));
+        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
     }
 
 
-    /**
-     * 修改midjourney账号模式
-     */
-    @PutMapping("/put/midjourney/user/{mode}")
-    public Result<String> putMidjourneyUserMode(@PathVariable Integer mode, Long userId) {
-        log.info("修改midjourney账号模式 userId:{},mode:{}", userId, mode);
-        MidjourneyUser midjourneyUser = midjourneyUserMapper.selectById(userId);
-        if (midjourneyUser == null) {
-            throw BusinessRuntimeException.getInstance("参数错误");
-        }
-        midjourneyUser.setMode(mode);
-        midjourneyUserMapper.updateById(midjourneyUser);
-        redisService.del(RedisService.key.MIDJOURNEY_USER.getName() + midjourneyUser.getUserToken());
-        return GatewayResponse.SUCCESS.newBuilder().toResult();
-    }
 
 
     /**
-     * mj绘画广场
+     * 根据userToken mj车队跳转登录
+     *
+     * @param carId 车队id
      */
-    @GetMapping("/get/painting")
-    public Result<SearchResult<MidjourneyPaintingUserView>> getPaintingCollect() {
-        SearchResult<MidjourneyPaintingUserView> search = beanSearcher.search(MidjourneyPaintingUserView.class, MapUtils.flatBuilder(request.getParameterMap())
-                .build());
-        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+    @GetMapping("/mirrorLogin/{relationId}/{carId}")
+    public Result<String> chatGPtCarLoginWithToken(@PathVariable Long relationId, @PathVariable String carId) {
+        Long userId = StpUserUtil.getLoginIdAsLong();
+        midjourneyService.getUser(userId, relationId);
+        String url = midjourneyService.getCarLoginUrl(userId, relationId, carId);
+        return GatewayResponse.SUCCESS.newBuilder().toResult(url);
     }
 
-    /**
-     * 复制mj绘画广场 提示词
-     */
-    @PostMapping("/painting/copy/{id}")
-    public Result<String> resetPaintingCopyNum(@PathVariable Long id) {
-        MidjourneyPaintingPlaza midjourneyPaintingPlaza = midjourneyPaintingPlazaMapper.selectById(id);
-        if (midjourneyPaintingPlaza != null) {
-            midjourneyPaintingPlazaMapper.updatePaintingCopyNum(id);
-        }
-        return GatewayResponse.SUCCESS.newBuilder().toResult();
-    }
-
-    /**
-     * 用户绘画记录
-     */
-    @GetMapping("/get/painting/record")
-    public Result<SearchResult<MidjourneyUserPaintingDayRecordView>> getPaintingRecord(String prompt, Boolean bookmark) {
-        MidjourneyUser user = getUser();
-        String condition = String.format(" and mc.user_id = %s", user.getId());
-        if (StrUtil.isNotBlank(prompt)) {
-            condition += String.format(" and mc.prompt = '%s'", prompt);
-        }
-        if (bookmark != null) {
-            condition += String.format(" and mc.bookmark is %s", bookmark);
-        }
-        SearchResult<MidjourneyUserPaintingDayRecordView> search = beanSearcher.search(MidjourneyUserPaintingDayRecordView.class, MapUtils.flatBuilder(request.getParameterMap())
-                .put("condition", condition)
-                .orderBy(MidjourneyUserPaintingRecordView::getCreatedTime).desc()
-                .build());
-        String dateSql;
-        for (MidjourneyUserPaintingDayRecordView e : search.getDataList()) {
-            String date = e.getDate();
-            dateSql = String.format(" and DATE_FORMAT(mc.created_time,'%%Y-%%m-%%d') = '%s'", date);
-            List<MidjourneyUserPaintingRecordView> list = beanSearcher.searchAll(MidjourneyUserPaintingRecordView.class, MapUtils.builder()
-                    .put("condition", condition)
-                    .put("date", dateSql)
-                    .orderBy(MidjourneyUserPaintingRecordView::getCreatedTime).desc()
-                    .build());
-            e.setList(list);
-        }
-        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
-    }
 }