TASK:LLM;
This commit is contained in:
@@ -53,7 +53,8 @@ public class AuthenticationFilter extends OncePerRequestFilter {
|
|||||||
"/api/portfolio/page", "/api/portfolio/detail", "/api/portfolio/commentPage", "/api/portfolio/viewsIncrease",
|
"/api/portfolio/page", "/api/portfolio/detail", "/api/portfolio/commentPage", "/api/portfolio/viewsIncrease",
|
||||||
"/api/account/designWorksRegister","/api/account/questionnaire","/api/stripe/trade/notify",
|
"/api/account/designWorksRegister","/api/account/questionnaire","/api/stripe/trade/notify",
|
||||||
"/notification","/api/account/activateNewEmail","/api/third/party/auth/google_callback","/api/third/party/parseGoogleCredential","/api/third/party/receiveDesignResults","/api/third/party/parseWeChatCode","/api/third/party/receiveDesignParams"
|
"/notification","/api/account/activateNewEmail","/api/third/party/auth/google_callback","/api/third/party/parseGoogleCredential","/api/third/party/receiveDesignResults","/api/third/party/parseWeChatCode","/api/third/party/receiveDesignParams"
|
||||||
, "api/account/schoolLogin", "api/account/enterpriseLogin", "api/account/organizationNameSearch"
|
, "api/account/schoolLogin", "api/account/enterpriseLogin", "api/account/organizationNameSearch",
|
||||||
|
"/api/llm/stream"
|
||||||
);
|
);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
81
src/main/java/com/ai/da/controller/LLMController.java
Normal file
81
src/main/java/com/ai/da/controller/LLMController.java
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
package com.ai.da.controller;
|
||||||
|
|
||||||
|
import com.ai.da.common.config.exception.BusinessException;
|
||||||
|
import com.ai.da.common.response.PageBaseResponse;
|
||||||
|
import com.ai.da.common.response.Response;
|
||||||
|
import com.ai.da.mapper.primary.entity.Account;
|
||||||
|
import com.ai.da.mapper.primary.entity.AccountExtend;
|
||||||
|
import com.ai.da.mapper.primary.entity.ChatMessage;
|
||||||
|
import com.ai.da.mapper.primary.entity.TrialOrder;
|
||||||
|
import com.ai.da.model.dto.*;
|
||||||
|
import com.ai.da.model.vo.AccountLoginVO;
|
||||||
|
import com.ai.da.model.vo.AccountPreLoginVO;
|
||||||
|
import com.ai.da.model.vo.BindEmailVO;
|
||||||
|
import com.ai.da.model.vo.PersonalHomepageVO;
|
||||||
|
import com.ai.da.service.AccountService;
|
||||||
|
import com.ai.da.service.LLMService;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
|
||||||
|
@Api(tags = "llm模块")
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/llm")
|
||||||
|
public class LLMController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private LLMService llmService;
|
||||||
|
|
||||||
|
@ApiOperation(value = "对话")
|
||||||
|
@CrossOrigin
|
||||||
|
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||||
|
public SseEmitter streamPrompt(@RequestParam String prompt,
|
||||||
|
@RequestParam Long projectId,
|
||||||
|
@RequestParam(required = false) String fileUrl,
|
||||||
|
@RequestParam String token) {
|
||||||
|
return llmService.stream(prompt, projectId, fileUrl, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "对话创建项目")
|
||||||
|
@GetMapping(value = "/chatCreateProject")
|
||||||
|
public Response<Long> chatCreateProject(@RequestParam String prompt) {
|
||||||
|
return Response.success(llmService.chatCreateProject(prompt));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "上传文件")
|
||||||
|
@GetMapping(value = "/uploadFile")
|
||||||
|
public Response<List<String>> uploadFile(@RequestParam MultipartFile file) {
|
||||||
|
return Response.success(llmService.uploadFile(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取历史聊天记录")
|
||||||
|
@GetMapping(value = "/getChatHistory")
|
||||||
|
public Response<List<ChatMessage>> getChatHistory(@RequestParam Long projectId) {
|
||||||
|
return Response.success(llmService.getChatHistory(projectId));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.ai.da.mapper.primary;
|
||||||
|
|
||||||
|
import com.ai.da.common.config.mybatis.plus.CommonMapper;
|
||||||
|
import com.ai.da.mapper.primary.entity.ChatMessage;
|
||||||
|
|
||||||
|
public interface ChatMessageMapper extends CommonMapper<ChatMessage> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.ai.da.mapper.primary.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@TableName("chat_message")
|
||||||
|
public class ChatMessage implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private Long projectId;
|
||||||
|
|
||||||
|
private String role;
|
||||||
|
|
||||||
|
private Integer seq;
|
||||||
|
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
private Long accountId;
|
||||||
|
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
}
|
||||||
@@ -101,5 +101,9 @@ public class Workspace implements Serializable {
|
|||||||
|
|
||||||
private Long projectId;
|
private Long projectId;
|
||||||
|
|
||||||
|
private Integer userBrandDna;
|
||||||
|
|
||||||
|
private Integer brandPercentage;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,4 +69,8 @@ public class DesignCollectionDTO {
|
|||||||
|
|
||||||
private Integer designNum;
|
private Integer designNum;
|
||||||
|
|
||||||
|
private Long brandId;
|
||||||
|
|
||||||
|
private Double brandScale;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,4 +14,6 @@ public class ToProductImageDTO {
|
|||||||
private BigDecimal imageStrength;
|
private BigDecimal imageStrength;
|
||||||
private String direction;
|
private String direction;
|
||||||
private Double brightenValue;
|
private Double brightenValue;
|
||||||
|
private BigDecimal imageStrengthMin;
|
||||||
|
private BigDecimal imageStrengthMax;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,4 +28,13 @@ public enum AgeGroup implements IEnumDisplay {
|
|||||||
}
|
}
|
||||||
throw new IllegalArgumentException("No matching constant for [" + value + "]");
|
throw new IllegalArgumentException("No matching constant for [" + value + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isValidName(String name) {
|
||||||
|
for (AgeGroup ageGroup : AgeGroup.values()) {
|
||||||
|
if (ageGroup.name().equalsIgnoreCase(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,4 +31,13 @@ public enum DesignProcess implements IEnumDisplay {
|
|||||||
}
|
}
|
||||||
throw new IllegalArgumentException("No matching constant for [" + value + "]");
|
throw new IllegalArgumentException("No matching constant for [" + value + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isValidName(String name) {
|
||||||
|
for (DesignProcess process : DesignProcess.values()) {
|
||||||
|
if (process.name().equalsIgnoreCase(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,15 @@ public enum Position implements IEnumDisplay {
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isValidName(String name) {
|
||||||
|
for (Position position : Position.values()) {
|
||||||
|
if (position.name().equalsIgnoreCase(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@JsonValue
|
@JsonValue
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
|
|||||||
@@ -22,6 +22,15 @@ public enum Sex implements IEnumDisplay {
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isValidName(String name) {
|
||||||
|
for (Sex sex : Sex.values()) {
|
||||||
|
if (sex.name().equalsIgnoreCase(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@JsonValue
|
@JsonValue
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
|
|||||||
@@ -31,6 +31,15 @@ public enum StyleEnum {
|
|||||||
this.english = english;
|
this.english = english;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isValidName(String name) {
|
||||||
|
for (StyleEnum styleEnum : StyleEnum.values()) {
|
||||||
|
if (styleEnum.name().equalsIgnoreCase(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// 获取中文描述
|
// 获取中文描述
|
||||||
public String getChinese() {
|
public String getChinese() {
|
||||||
return chinese;
|
return chinese;
|
||||||
|
|||||||
@@ -55,4 +55,8 @@ public class ValidateElementVO {
|
|||||||
private Long collectionId;
|
private Long collectionId;
|
||||||
|
|
||||||
private Long accountId;
|
private Long accountId;
|
||||||
|
|
||||||
|
private Long brandId;
|
||||||
|
|
||||||
|
private Double brandScale;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4382,4 +4382,46 @@ public class PythonService {
|
|||||||
log.error("PythonService##poseTransferBatch接口调用失败###{}", response);
|
log.error("PythonService##poseTransferBatch接口调用失败###{}", response);
|
||||||
throw new BusinessException("poseTransferBatch.interface.exception");
|
throw new BusinessException("poseTransferBatch.interface.exception");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JSONObject getProjectParam(String prompt) {
|
||||||
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
||||||
|
.connectTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.pingInterval(5, TimeUnit.SECONDS)//websocket轮训间隔(单位:秒)
|
||||||
|
.readTimeout(60, TimeUnit.SECONDS)//读取超时(单位:秒)
|
||||||
|
.writeTimeout(60, TimeUnit.SECONDS)//写入超时(单位:秒)
|
||||||
|
.build();
|
||||||
|
MediaType mediaType = MediaType.parse("application/json");
|
||||||
|
Map<String, Object> content = Maps.newHashMap();
|
||||||
|
content.put("prompt", prompt);
|
||||||
|
RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(content));
|
||||||
|
|
||||||
|
log.info("getProjectParam 请求地址: {}", accessPythonIp + ":" + accessPythonPort + "/api/extraction_project_info");
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(accessPythonIp + ":" + accessPythonPort + "/api/extraction_project_info")
|
||||||
|
.method("POST", body)
|
||||||
|
.addHeader("Content-Type", "application/json")
|
||||||
|
.build();
|
||||||
|
Response response = null;
|
||||||
|
try {
|
||||||
|
response = client.newCall(request).execute();
|
||||||
|
} catch (IOException ioException) {
|
||||||
|
log.error("PythonService##getProjectParam异常###{}", ExceptionUtil.getThrowableList(ioException));
|
||||||
|
throw new BusinessException("getProjectParam.interface.exception");
|
||||||
|
}
|
||||||
|
String responseBody;
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
try {
|
||||||
|
responseBody = response.body().string();
|
||||||
|
JSONObject responseObject = JSON.parseObject(responseBody);
|
||||||
|
log.info("PythonService##responseObject###{}", responseObject);
|
||||||
|
return responseObject;
|
||||||
|
} catch (IOException | JSONException e) {
|
||||||
|
log.error("PythonService##getProjectParam异常###{}", e.getMessage());
|
||||||
|
throw new BusinessException("getProjectParam.interface.exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.error("PythonService##getProjectParam接口调用失败###{}", response);
|
||||||
|
throw new BusinessException("getProjectParam.interface.exception");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
40
src/main/java/com/ai/da/service/LLMService.java
Normal file
40
src/main/java/com/ai/da/service/LLMService.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package com.ai.da.service;
|
||||||
|
|
||||||
|
import com.ai.da.common.response.PageBaseResponse;
|
||||||
|
import com.ai.da.mapper.primary.entity.Account;
|
||||||
|
import com.ai.da.mapper.primary.entity.AccountExtend;
|
||||||
|
import com.ai.da.mapper.primary.entity.ChatMessage;
|
||||||
|
import com.ai.da.mapper.primary.entity.TrialOrder;
|
||||||
|
import com.ai.da.model.dto.*;
|
||||||
|
import com.ai.da.model.vo.AccountLoginVO;
|
||||||
|
import com.ai.da.model.vo.AccountPreLoginVO;
|
||||||
|
import com.ai.da.model.vo.BindEmailVO;
|
||||||
|
import com.ai.da.model.vo.PersonalHomepageVO;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务类
|
||||||
|
*
|
||||||
|
* @author easy-generator
|
||||||
|
* @since 2022-08-11
|
||||||
|
*/
|
||||||
|
public interface LLMService {
|
||||||
|
|
||||||
|
SseEmitter stream(String prompt, Long projectId, String fileUrl, String token);
|
||||||
|
|
||||||
|
Long chatCreateProject(String prompt);
|
||||||
|
|
||||||
|
List<String> uploadFile(MultipartFile file);
|
||||||
|
|
||||||
|
List<ChatMessage> getChatHistory(Long projectId);
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package com.ai.da.service;
|
package com.ai.da.service;
|
||||||
|
|
||||||
import com.ai.da.model.dto.ProgressDTO;
|
import com.ai.da.model.dto.ProgressDTO;
|
||||||
|
import com.ai.da.model.vo.AuthPrincipalVo;
|
||||||
|
|
||||||
public interface ProductImageService {
|
public interface ProductImageService {
|
||||||
void asyncInitialize(Long brandId);
|
void asyncInitialize(Long brandId, AuthPrincipalVo userHolder);
|
||||||
// double getInitializeProgress(Long brandId);
|
// double getInitializeProgress(Long brandId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,4 +62,6 @@ public interface SysFileService extends IService<SysFile> {
|
|||||||
List<SysFile> getByIds(List<Long> ids);
|
List<SysFile> getByIds(List<Long> ids);
|
||||||
|
|
||||||
SysFile getOneBySex(Long styleId, String sex, String ageGroup);
|
SysFile getOneBySex(Long styleId, String sex, String ageGroup);
|
||||||
|
|
||||||
|
SysFile getOneBySex(String styleName, String sex, String ageGroup);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -622,6 +622,10 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
}else {
|
}else {
|
||||||
elementVO.setDesignNum(8);
|
elementVO.setDesignNum(8);
|
||||||
}
|
}
|
||||||
|
if (null != designDTO.getBrandId()) {
|
||||||
|
elementVO.setBrandId(designDTO.getBrandId());
|
||||||
|
elementVO.setBrandScale(designDTO.getBrandScale());
|
||||||
|
}
|
||||||
return elementVO;
|
return elementVO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
288
src/main/java/com/ai/da/service/impl/LLMServiceImpl.java
Normal file
288
src/main/java/com/ai/da/service/impl/LLMServiceImpl.java
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
package com.ai.da.service.impl;
|
||||||
|
|
||||||
|
import com.ai.da.common.constant.CommonConstant;
|
||||||
|
import com.ai.da.common.context.UserContext;
|
||||||
|
import com.ai.da.common.security.jwt.JWTTokenHelper;
|
||||||
|
import com.ai.da.common.utils.MinioUtil;
|
||||||
|
import com.ai.da.mapper.primary.*;
|
||||||
|
import com.ai.da.mapper.primary.entity.*;
|
||||||
|
import com.ai.da.model.dto.ReceiveDesignParam;
|
||||||
|
import com.ai.da.model.enums.*;
|
||||||
|
import com.ai.da.model.vo.AuthPrincipalVo;
|
||||||
|
import com.ai.da.python.PythonService;
|
||||||
|
import com.ai.da.service.DesignService;
|
||||||
|
import com.ai.da.service.LLMService;
|
||||||
|
import com.ai.da.service.SysFileService;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class LLMServiceImpl implements LLMService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ChatMessageMapper chatMessageMapper;
|
||||||
|
@Resource
|
||||||
|
private ProjectMapper projectMapper;
|
||||||
|
@Resource
|
||||||
|
private PythonService pythonService;
|
||||||
|
@Resource
|
||||||
|
private WorkspaceMapper workspaceMapper;
|
||||||
|
@Resource
|
||||||
|
private SysFileService sysFileService;
|
||||||
|
@Resource
|
||||||
|
private MinioUtil minioUtil;
|
||||||
|
@Resource
|
||||||
|
private StyleMapper styleMapper;
|
||||||
|
@Resource
|
||||||
|
private WorkspaceRelStyleMapper workspaceRelStyleMapper;
|
||||||
|
@Resource
|
||||||
|
private JWTTokenHelper jwtTokenHelper;
|
||||||
|
@Resource
|
||||||
|
private DesignService designService;
|
||||||
|
private final ExecutorService executor = Executors.newCachedThreadPool();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SseEmitter stream(String prompt, Long projectId, String fileUrl, String token) {
|
||||||
|
SseEmitter emitter = new SseEmitter(0L); // 永不超时
|
||||||
|
|
||||||
|
executor.submit(() -> {
|
||||||
|
try {
|
||||||
|
boolean validate = jwtTokenHelper.validateToken(token);
|
||||||
|
if (validate) {
|
||||||
|
AuthPrincipalVo principal = jwtTokenHelper.parserToUser(token);
|
||||||
|
Long accountId = principal.getId();
|
||||||
|
int userSeq = getNextSeq(projectId); // 获取当前session下一条消息序号
|
||||||
|
String url = "http://18.167.251.121:10002/chat-stream";
|
||||||
|
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
||||||
|
conn.setRequestMethod("POST");
|
||||||
|
conn.setDoOutput(true);
|
||||||
|
conn.setRequestProperty("Content-Type", "application/json");
|
||||||
|
|
||||||
|
JSONObject jsonBodyObject = new JSONObject();
|
||||||
|
jsonBodyObject.put("session_id", projectId.toString());
|
||||||
|
jsonBodyObject.put("role", "user");
|
||||||
|
jsonBodyObject.put("image", ""); // 可扩展
|
||||||
|
jsonBodyObject.put("file", fileUrl != null ? fileUrl : "");
|
||||||
|
jsonBodyObject.put("message", prompt);
|
||||||
|
jsonBodyObject.put("enable_thinking", false);
|
||||||
|
|
||||||
|
// 1. 存储用户输入
|
||||||
|
ChatMessage userMessage = new ChatMessage();
|
||||||
|
userMessage.setRole("user");
|
||||||
|
userMessage.setProjectId(projectId);
|
||||||
|
userMessage.setSeq(userSeq);
|
||||||
|
userMessage.setCreateTime(LocalDateTime.now());
|
||||||
|
userMessage.setContent(jsonBodyObject.toJSONString());
|
||||||
|
userMessage.setAccountId(accountId);
|
||||||
|
chatMessageMapper.insert(userMessage);
|
||||||
|
|
||||||
|
try (OutputStream os = conn.getOutputStream()) {
|
||||||
|
byte[] input = jsonBodyObject.toJSONString().getBytes(StandardCharsets.UTF_8);
|
||||||
|
os.write(input, 0, input.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 流式接收并累积内容
|
||||||
|
StringBuilder responseBuilder = new StringBuilder();
|
||||||
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
line = line.trim();
|
||||||
|
if (!line.isEmpty() && line.startsWith("data: ")) {
|
||||||
|
String jsonStr = line.substring(6);
|
||||||
|
System.out.println(jsonStr);
|
||||||
|
JSONObject json = JSON.parseObject(jsonStr);
|
||||||
|
String status = json.getString("status");
|
||||||
|
|
||||||
|
if ("[DONE]".equals(status)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(status)) {
|
||||||
|
String content = json.getString("content");
|
||||||
|
if (!status.equals("[RUNNING]") && !status.equals("[DESIGN_SIGNAL]")) {
|
||||||
|
JSONObject toolsData = json.getJSONObject("tools_data");
|
||||||
|
ReceiveDesignParam receiveDesignParam = JSONObject.parseObject(JSONObject.toJSONString(toolsData), ReceiveDesignParam.class);
|
||||||
|
receiveDesignParam.setProjectId(projectId);
|
||||||
|
designService.receiveDesignParams(receiveDesignParam);
|
||||||
|
}
|
||||||
|
if (content != null) {
|
||||||
|
responseBuilder.append(content);
|
||||||
|
emitter.send(json.toJSONString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 存储系统回复
|
||||||
|
int systemSeq = getNextSeq(projectId);
|
||||||
|
ChatMessage systemMessage = new ChatMessage();
|
||||||
|
systemMessage.setRole("user");
|
||||||
|
systemMessage.setProjectId(projectId);
|
||||||
|
systemMessage.setSeq(systemSeq);
|
||||||
|
systemMessage.setCreateTime(LocalDateTime.now());
|
||||||
|
systemMessage.setContent(responseBuilder.toString());
|
||||||
|
systemMessage.setAccountId(accountId);
|
||||||
|
chatMessageMapper.insert(systemMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitter.complete();
|
||||||
|
} catch (Exception e) {
|
||||||
|
emitter.completeWithError(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return emitter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long chatCreateProject(String prompt) {
|
||||||
|
AuthPrincipalVo userHolder = UserContext.getUserHolder();
|
||||||
|
JSONObject jsonObject = pythonService.getProjectParam(prompt);
|
||||||
|
JSONObject data = jsonObject.getJSONObject("data");
|
||||||
|
Project project = new Project();
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
project.setUpdateTime(now);
|
||||||
|
project.setCreateTime(now);
|
||||||
|
project.setAccountId(userHolder.getId());
|
||||||
|
project.setName(data.getString("project_name"));
|
||||||
|
project.setOriginal(1);
|
||||||
|
String process = data.getString("process");
|
||||||
|
if (StringUtils.isEmpty(process)) {
|
||||||
|
project.setProcess(DesignProcess.SERIES_DESIGN.name());
|
||||||
|
}else {
|
||||||
|
if (DesignProcess.isValidName(process)) {
|
||||||
|
project.setProcess(process);
|
||||||
|
}else {
|
||||||
|
project.setProcess(DesignProcess.SERIES_DESIGN.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
projectMapper.insert(project);
|
||||||
|
|
||||||
|
Workspace workspace = new Workspace();
|
||||||
|
workspace.setAccountId(userHolder.getId());
|
||||||
|
workspace.setCreateTime(now);
|
||||||
|
String ageGroup = data.getString("ageGroup");
|
||||||
|
if (StringUtils.isEmpty(ageGroup)) {
|
||||||
|
workspace.setAgeGroup("Adult");
|
||||||
|
}else {
|
||||||
|
if (AgeGroup.isValidName(process)) {
|
||||||
|
workspace.setAgeGroup(ageGroup);
|
||||||
|
}else {
|
||||||
|
workspace.setAgeGroup("Adult");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String gender = data.getString("gender");
|
||||||
|
if (StringUtils.isEmpty(gender)) {
|
||||||
|
workspace.setSex("Female");
|
||||||
|
}else {
|
||||||
|
if (Sex.isValidName(gender)) {
|
||||||
|
workspace.setSex(gender);
|
||||||
|
}else {
|
||||||
|
workspace.setSex("Female");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String position = data.getString("position");
|
||||||
|
if (StringUtils.isEmpty(position)) {
|
||||||
|
workspace.setPosition("Overall");
|
||||||
|
}else {
|
||||||
|
if (Position.isValidName(position)) {
|
||||||
|
workspace.setPosition(position);
|
||||||
|
}else {
|
||||||
|
workspace.setPosition("Overall");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
workspace.setSystemDesignerPercentage(30);
|
||||||
|
workspace.setProjectId(project.getId());
|
||||||
|
|
||||||
|
String style = data.getString("style");
|
||||||
|
String styleName = null;
|
||||||
|
if (StringUtils.isEmpty(style)) {
|
||||||
|
styleName = StyleEnum.NEW_CHINESE.name();
|
||||||
|
}else {
|
||||||
|
if (StyleEnum.isValidName(style)) {
|
||||||
|
styleName = style;
|
||||||
|
}else {
|
||||||
|
styleName = StyleEnum.NEW_CHINESE.name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SysFile sysFile = sysFileService.getOneBySex(styleName, workspace.getSex(), workspace.getAgeGroup());
|
||||||
|
|
||||||
|
if (workspace.getSex().equals(Sex.FEMALE.getValue())) {
|
||||||
|
workspace.setMannequinFemaleId(sysFile.getId());
|
||||||
|
workspace.setMannequinFemaleType("System");
|
||||||
|
}else {
|
||||||
|
workspace.setMannequinMaleId(sysFile.getId());
|
||||||
|
workspace.setMannequinMaleType("System");
|
||||||
|
}
|
||||||
|
|
||||||
|
workspaceMapper.insert(workspace);
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(styleName)) {
|
||||||
|
QueryWrapper<Style> qw = new QueryWrapper<>();
|
||||||
|
qw.lambda().eq(Style::getName, styleName);
|
||||||
|
Style style1 = styleMapper.selectOne(qw);
|
||||||
|
if (Objects.nonNull(style1)) {
|
||||||
|
WorkspaceRelStyle rel = new WorkspaceRelStyle();
|
||||||
|
rel.setWorkspaceId(workspace.getId());
|
||||||
|
rel.setStyleId(style1.getId());
|
||||||
|
workspaceRelStyleMapper.insert(rel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return project.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> uploadFile(MultipartFile file) {
|
||||||
|
AuthPrincipalVo userHolder = UserContext.getUserHolder();
|
||||||
|
String minioUrl = minioUtil.upload("chat-message", userHolder.getId() + "", file);
|
||||||
|
String preSignedUrl = minioUtil.getPreSignedUrl(minioUrl, CommonConstant.MINIO_IMAGE_EXPIRE_TIME);
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
result.add(minioUrl);
|
||||||
|
result.add(preSignedUrl);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ChatMessage> getChatHistory(Long projectId) {
|
||||||
|
QueryWrapper<ChatMessage> qw = new QueryWrapper<>();
|
||||||
|
qw.lambda().eq(ChatMessage::getProjectId, projectId);
|
||||||
|
qw.lambda().orderByAsc(ChatMessage::getSeq);
|
||||||
|
List<ChatMessage> chatMessages = chatMessageMapper.selectList(qw);
|
||||||
|
return chatMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getNextSeq(Long projectId) {
|
||||||
|
QueryWrapper<ChatMessage> qw = new QueryWrapper<>();
|
||||||
|
qw.lambda().eq(ChatMessage::getProjectId, projectId);
|
||||||
|
qw.lambda().orderByDesc(ChatMessage::getSeq);
|
||||||
|
qw.last("limit 1");
|
||||||
|
ChatMessage chatMessage = chatMessageMapper.selectOne(qw);
|
||||||
|
if (Objects.nonNull(chatMessage)) {
|
||||||
|
return chatMessage.getSeq() + 1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.ai.da.service.impl;
|
package com.ai.da.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import com.ai.da.common.context.UserContext;
|
||||||
import com.ai.da.common.utils.RedisUtil;
|
import com.ai.da.common.utils.RedisUtil;
|
||||||
import com.ai.da.mapper.primary.BrandRelLibraryMapper;
|
import com.ai.da.mapper.primary.BrandRelLibraryMapper;
|
||||||
import com.ai.da.mapper.primary.LibraryMapper;
|
import com.ai.da.mapper.primary.LibraryMapper;
|
||||||
@@ -10,12 +11,14 @@ import com.ai.da.mapper.primary.entity.Library;
|
|||||||
import com.ai.da.mapper.primary.entity.ProductImageAttribute;
|
import com.ai.da.mapper.primary.entity.ProductImageAttribute;
|
||||||
import com.ai.da.mapper.secondary.entity.AttributeRecognitionJSON;
|
import com.ai.da.mapper.secondary.entity.AttributeRecognitionJSON;
|
||||||
import com.ai.da.model.dto.ProgressDTO;
|
import com.ai.da.model.dto.ProgressDTO;
|
||||||
|
import com.ai.da.model.vo.AuthPrincipalVo;
|
||||||
import com.ai.da.python.PythonService;
|
import com.ai.da.python.PythonService;
|
||||||
import com.ai.da.service.ProductImageService;
|
import com.ai.da.service.ProductImageService;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -23,6 +26,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -42,10 +46,11 @@ public class ProductImageServiceImpl implements ProductImageService {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private RedisUtil redisUtil;
|
private RedisUtil redisUtil;
|
||||||
|
@Value("${minio.bucketName.users}")
|
||||||
|
private String userBucket;
|
||||||
@Async
|
@Async
|
||||||
@Override
|
@Override
|
||||||
public void asyncInitialize(Long brandId) {
|
public void asyncInitialize(Long brandId, AuthPrincipalVo userHolder) {
|
||||||
System.out.println(">>> [asyncInitialize] 当前线程:" + Thread.currentThread().getName());
|
System.out.println(">>> [asyncInitialize] 当前线程:" + Thread.currentThread().getName());
|
||||||
|
|
||||||
String progressKey = String.valueOf(brandId);
|
String progressKey = String.valueOf(brandId);
|
||||||
@@ -73,7 +78,7 @@ public class ProductImageServiceImpl implements ProductImageService {
|
|||||||
JSONArray data = result.getJSONArray("data");
|
JSONArray data = result.getJSONArray("data");
|
||||||
for (int i = 0; i < data.size(); i++) {
|
for (int i = 0; i < data.size(); i++) {
|
||||||
JSONObject obj = data.getJSONObject(i);
|
JSONObject obj = data.getJSONObject(i);
|
||||||
String gender = library.getLevel2Type();
|
String gender = library.getLevel3Type();
|
||||||
String category = null;
|
String category = null;
|
||||||
if (gender.equals("Female")) {
|
if (gender.equals("Female")) {
|
||||||
category = obj.getString("category_female");
|
category = obj.getString("category_female");
|
||||||
@@ -89,6 +94,10 @@ public class ProductImageServiceImpl implements ProductImageService {
|
|||||||
attr.setCategory(category);
|
attr.setCategory(category);
|
||||||
attr.setImgUrl(imgUrl);
|
attr.setImgUrl(imgUrl);
|
||||||
attr.setLibraryId(libraryId);
|
attr.setLibraryId(libraryId);
|
||||||
|
String imageName = UUID.randomUUID().toString();
|
||||||
|
String objectName = userHolder.getId() + "/imageToSketch/" + imageName;
|
||||||
|
String sketchPath = pythonService.imageToSketch(imgUrl, userBucket, objectName, "2", "");
|
||||||
|
attr.setImgUrl(sketchPath);
|
||||||
productImageAttributeMapper.insert(attr);
|
productImageAttributeMapper.insert(attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -303,6 +303,29 @@ public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> impl
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SysFile getOneBySex(String styleName, String sex, String ageGroup) {
|
||||||
|
QueryWrapper<SysFile> qw = new QueryWrapper<>();
|
||||||
|
qw.lambda().eq(SysFile::getLevel1Type, "Models");
|
||||||
|
qw.lambda().eq(SysFile::getLevel2Type, sex);
|
||||||
|
|
||||||
|
QueryWrapper<SysFileExtra> sysFileExtraQW = new QueryWrapper<>();
|
||||||
|
sysFileExtraQW.lambda().eq(SysFileExtra::getAgeGroup, ageGroup);
|
||||||
|
Set<Long> collect = sysFileExtraMapper.selectList(sysFileExtraQW).stream().map(SysFileExtra::getSysId).collect(Collectors.toSet());
|
||||||
|
if (!CollectionUtils.isEmpty(collect)) {
|
||||||
|
qw.lambda().in(SysFile::getId, collect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(styleName)) {
|
||||||
|
qw.lambda().eq(SysFile::getLevel3Type, styleName);
|
||||||
|
}
|
||||||
|
List<SysFile> sysFileList = sysFileMapper.selectList(qw);
|
||||||
|
if (!CollectionUtils.isEmpty(sysFileList)) {
|
||||||
|
return sysFileList.get(0);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Style style = new Style();
|
Style style = new Style();
|
||||||
if (Objects.nonNull(style)) {
|
if (Objects.nonNull(style)) {
|
||||||
|
|||||||
@@ -1170,8 +1170,8 @@ public class UserLikeGroupServiceImpl extends ServiceImpl<UserLikeGroupMapper, U
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public Boolean productImageInitialize(ProductImageInitializeDTO productImageInitializeDTO) {
|
public Boolean productImageInitialize(ProductImageInitializeDTO productImageInitializeDTO) {
|
||||||
|
AuthPrincipalVo userHolder = UserContext.getUserHolder();
|
||||||
productImageService.asyncInitialize(productImageInitializeDTO.getBrandId());
|
productImageService.asyncInitialize(productImageInitializeDTO.getBrandId(), userHolder);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ spring.security.jwtExpiration=8640000000
|
|||||||
spring.security.ignorePaths=/,/favicon.ico,/doc.html,/webjars/**,/swagger-resources,/v2/api-docs,\
|
spring.security.ignorePaths=/,/favicon.ico,/doc.html,/webjars/**,/swagger-resources,/v2/api-docs,\
|
||||||
/api/account/**,/api/element/**,/api/python/**,/api/design/**,/api/history/**,/api/library/**,/api/third/party/**,/api/generate/**,/api/workspace/**,/api/classification/**,\
|
/api/account/**,/api/element/**,/api/python/**,/api/design/**,/api/history/**,/api/library/**,/api/third/party/**,/api/generate/**,/api/workspace/**,/api/classification/**,\
|
||||||
/api/product/**,/api/ali-pay/**,/api/order-info/**,/api/paypal/**,/api/credits/**,/api/inquiry/**,/api/tasks/**,/api/python/prepareForSR,/api/alipay-hk/**,/api/portfolio/**,\
|
/api/product/**,/api/ali-pay/**,/api/order-info/**,/api/paypal/**,/api/credits/**,/api/inquiry/**,/api/tasks/**,/api/python/prepareForSR,/api/alipay-hk/**,/api/portfolio/**,\
|
||||||
/api/stripe/**,/api/message/**,/api/tags/**,/notification/**,/api/affiliate/**,/api/project/**
|
/api/stripe/**,/api/message/**,/api/tags/**,/notification/**,/api/affiliate/**,/api/project/**,/api/llm/**
|
||||||
spring.security.authApi=/auth/login
|
spring.security.authApi=/auth/login
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user