diff --git a/pom.xml b/pom.xml index e20e83e1..ff9df865 100644 --- a/pom.xml +++ b/pom.xml @@ -288,6 +288,28 @@ spring-boot-starter-websocket + + com.google.auth + google-auth-library-oauth2-http + 1.8.0 + + + + com.google.api-client + google-api-client + 1.32.1 + + + com.google.oauth-client + google-oauth-client + 1.32.1 + + + com.google.http-client + google-http-client-jackson2 + 1.41.5 + + diff --git a/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java b/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java index a70bc51b..54dbf3a6 100644 --- a/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java +++ b/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java @@ -51,7 +51,7 @@ public class AuthenticationFilter extends OncePerRequestFilter { "/api/python/flush","/api/account/healthy","/api/ali-pay/trade/notify","/api/paypal/ipn/back","/api/alipay-hk/trade/notify", "/api/portfolio/page", "/api/portfolio/detail", "/api/portfolio/commentPage", "/api/portfolio/viewsIncrease", "/api/account/designWorksRegister","/api/account/questionnaire","/api/stripe/trade/notify", - "/notification","/api/account/activateNewEmail","/api/third/party/auth/google_callback" + "/notification","/api/account/activateNewEmail","/api/third/party/auth/google_callback","/api/third/party/parseGoogleCredential","/api/third/party/receiveDesignResults","/api/third/party/parseWeChatCode" ); @Override diff --git a/src/main/java/com/ai/da/common/utils/MinioUtil.java b/src/main/java/com/ai/da/common/utils/MinioUtil.java index bf5bea69..f8b86a51 100644 --- a/src/main/java/com/ai/da/common/utils/MinioUtil.java +++ b/src/main/java/com/ai/da/common/utils/MinioUtil.java @@ -484,6 +484,57 @@ public class MinioUtil { return null; // or throw an exception } } + + /** + * 从 MinIO 下载对象到本地路径 + * + * @param bucketName 存储桶名称 + * @param objectName MinIO 上对象的名称 + * @param localFilePath 本地文件路径 + */ + public void downloadMinioObjectToLocal(String bucketName, String objectName, String localFilePath) { + File localFile = new File(localFilePath); + File parentDir = localFile.getParentFile(); + if (parentDir != null) { + parentDir.mkdirs(); // 创建文件夹,确保路径结构与 MinIO 一致 + } + + try (InputStream stream = minioClient.getObject( + GetObjectArgs.builder().bucket(bucketName).object(objectName).build()); + FileOutputStream out = new FileOutputStream(localFile)) { + + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = stream.read(buffer)) != -1) { + out.write(buffer, 0, bytesRead); + } + log.info("Downloaded object {} to {}", objectName, localFilePath); + } catch (Exception e) { + log.error("Error while downloading object {}: {}", objectName, e.getMessage()); + } + } + + /** + * 从路径中提取存储桶名称 + * + * @param path MinIO 路径 + * @return 存储桶名称 + */ + public String getBucketNameFromPath(String path) { + int index = path.indexOf("/"); + return path.substring(0, index); // 获取第一级路径作为 bucket 名称 + } + + /** + * 从路径中提取对象名称 + * + * @param path MinIO 路径 + * @return 对象名称 + */ + public String getObjectNameFromPath(String path) { + int index = path.indexOf("/"); + return path.substring(index + 1); // 获取路径的其余部分作为对象名称 + } } diff --git a/src/main/java/com/ai/da/common/utils/SendEmailUtil.java b/src/main/java/com/ai/da/common/utils/SendEmailUtil.java index 490b598f..9dd76934 100644 --- a/src/main/java/com/ai/da/common/utils/SendEmailUtil.java +++ b/src/main/java/com/ai/da/common/utils/SendEmailUtil.java @@ -395,20 +395,20 @@ public class SendEmailUtil { // 根据邮件类型设置不同的主题和模板 String subject = ""; Template template = new Template(); - if (type == 1) { - subject = "Upcoming System Upgrade for AiDA 3.0"; - template.setTemplateID(UPGRADE_NOTIFICATION_ID); - } else { - subject = "即将到来的AiDA 3.0系统升级"; - template.setTemplateID(UPGRADE_NOTIFICATION_ID_CHINESE); - } // if (type == 1) { -// subject = "Successful System Upgrade and New Features in AiDA 3.1"; -// template.setTemplateID(UPGRADE_SUCCESS_NOTIFICATION_ID); +// subject = "Upcoming System Upgrade for AiDA 3.0"; +// template.setTemplateID(UPGRADE_NOTIFICATION_ID); // }else { -// subject = "系统升级成功和AiDA 3.1新功能"; -// template.setTemplateID(UPGRADE_SUCCESS_NOTIFICATION_ID_CHINESE); +// subject = "即将到来的AiDA 3.0系统升级"; +// template.setTemplateID(UPGRADE_NOTIFICATION_ID_CHINESE); // } + if (type == 1) { + subject = "Successful System Upgrade and New Features in AiDA 3.1"; + template.setTemplateID(UPGRADE_SUCCESS_NOTIFICATION_ID); + }else { + subject = "系统升级成功和AiDA 3.1新功能"; + template.setTemplateID(UPGRADE_SUCCESS_NOTIFICATION_ID_CHINESE); + } template.setTemplateData(buildAccountData(account)); req.setSubject(subject); @@ -776,6 +776,47 @@ public class SendEmailUtil { throw new BusinessException("failed.to.send.mail"); } } + private final static Long SYSTEM_UPGRADE_CN_ID = 131743L; + private final static Long SYSTEM_UPGRADE_EN_ID = 131744L; + public static void temporaryUpgrade(Account account, String senderAddress, int type) { + try { + // 实例化一个认证对象 + Credential cred = new Credential(SECRET_ID, SECRET_KEy); + HttpProfile httpProfile = new HttpProfile(); + httpProfile.setEndpoint("ses.tencentcloudapi.com"); + ClientProfile clientProfile = new ClientProfile(); + clientProfile.setHttpProfile(httpProfile); + SesClient client = new SesClient(cred, "ap-hongkong", clientProfile); + SendEmailRequest req = new SendEmailRequest(); + if (StringUtils.isEmpty(senderAddress)) { + senderAddress = CODE_CREATE_SEND_ADDRESS; + } + req.setFromEmailAddress(senderAddress); + req.setDestination(new String[]{account.getUserEmail()}); + + // 根据邮件类型设置不同的主题和模板 + String subject = ""; + Template template = new Template(); + if (type == 1) { + subject = "AiDA system upgrade completed"; + template.setTemplateID(SYSTEM_UPGRADE_EN_ID); + }else { + subject = "AiDA系统升级完成"; + template.setTemplateID(SYSTEM_UPGRADE_CN_ID); + } + template.setTemplateData(buildAccountData(account)); + + req.setSubject(subject); + req.setTemplate(template); + + // 发送邮件 + SendEmailResponse resp = client.SendEmail(req); + log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp)); + } catch (TencentCloudSDKException e) { + log.info("邮件发送失败###{}", e.toString()); + throw new BusinessException("failed.to.send.mail"); + } + } private final static Long CANCEL_MERCHANT_EN = 130720L; private final static Long NEW_MERCHANT_EN = 130721L; diff --git a/src/main/java/com/ai/da/controller/AccountController.java b/src/main/java/com/ai/da/controller/AccountController.java index c73fcdaa..5ec9754a 100644 --- a/src/main/java/com/ai/da/controller/AccountController.java +++ b/src/main/java/com/ai/da/controller/AccountController.java @@ -3,6 +3,7 @@ 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.TrialOrder; import com.ai.da.model.dto.*; import com.ai.da.model.vo.AccountLoginVO; @@ -261,5 +262,66 @@ public class AccountController { return Response.success(true); } + @PostMapping("temporaryUpgrade") + @ApiOperation(value = "临时升级") + public Response temporaryUpgrade() { + accountService.temporaryUpgrade(); + return Response.success(true); + } + @PostMapping("enterpriseLogin") + @ApiOperation(value = "企业登录") + public Response enterpriseLogin(@Valid @RequestBody AccountLoginDTO accountDTO) { + return Response.success(accountService.enterpriseLogin(accountDTO)); + } + + @PostMapping("schoolLogin") + @ApiOperation(value = "学校登录") + public Response schoolLogin(@Valid @RequestBody AccountLoginDTO accountDTO) { + return Response.success(accountService.schoolLogin(accountDTO)); + } + + @PostMapping("addOrUpdateSubAccount") + @ApiOperation(value = "子账号新增") + public Response addSubAccount(@Valid @RequestBody AddSubAccountDTO addSubAccountDTO) { + return Response.success(accountService.addSubAccount(addSubAccountDTO)); + } + + @PostMapping("deleteSubAccount") + @ApiOperation(value = "子账号删除") + public Response deleteSubAccount(@Valid @RequestBody AddSubAccountDTO addSubAccountDTO) { + return Response.success(accountService.deleteSubAccount(addSubAccountDTO)); + } + + @PostMapping("subAccountList") + @ApiOperation(value = "子账号查询") + public Response> subAccountList(@Valid @RequestBody SubAccountPageDTO subAccountPageDTO) { + return Response.success(accountService.subAccountList(subAccountPageDTO)); + } + + @GetMapping("accountDetail") + @ApiOperation(value = "账号详情") + public Response accountDetail(@RequestParam("id") Long id) { + return Response.success(accountService.accountDetail(id)); + } + + @PostMapping("getAccountDetail") + @ApiOperation(value = "获取账户信息") + public Response getAccountDetail() { + return Response.success(accountService.getAccountDetail()); + } + + @CrossOrigin + @GetMapping("/bindGoogle") + @ApiOperation(value = "绑定谷歌") + public Response bindGoogle(@RequestParam("credential") String credential) { + return Response.success(accountService.bindGoogle(credential)); + } + + @CrossOrigin + @GetMapping("/bindWeChat") + @ApiOperation(value = "绑定微信") + public Response bindWeChat(@RequestParam("code") String code) { + return Response.success(accountService.bindWeChat(code)); + } } diff --git a/src/main/java/com/ai/da/controller/DesignController.java b/src/main/java/com/ai/da/controller/DesignController.java index 2ea463c1..934bcecb 100644 --- a/src/main/java/com/ai/da/controller/DesignController.java +++ b/src/main/java/com/ai/da/controller/DesignController.java @@ -31,7 +31,7 @@ public class DesignController { @ApiOperation(value = "设计 Conllection") @PostMapping("/designCollection") @CrossOrigin - public Response designCollection(@Valid @RequestBody DesignCollectionDTO designDTO) { + public Response designCollection(@Valid @RequestBody DesignCollectionDTO designDTO) { return Response.success(designService.designCollection(designDTO)); } @@ -43,7 +43,7 @@ public class DesignController { @ApiOperation(value = "重新设计 Collection") @PostMapping("/reDesignCollection") - public Response reDesignCollection(@Valid @RequestBody ReDesignCollectionDTO reDesignDTO) { + public Response reDesignCollection(@Valid @RequestBody ReDesignCollectionDTO reDesignDTO) { return Response.success(designService.reDesignCollection(reDesignDTO)); } @@ -83,4 +83,16 @@ public class DesignController { return Response.success(designService.getModel(designItemIdList)); } + @ApiOperation(value = "获取design结果") + @GetMapping("/getDesignResult") + public Response getDesignResult(@RequestParam("requestId") String requestId, @RequestParam("objectSignList") List objectSignList){ + return Response.success(designService.getDesignResult(requestId, objectSignList)); + } + + @ApiOperation(value = "云生成") + @PostMapping("/designCloud") + @CrossOrigin + public Response designCloud(@Valid @RequestBody DesignCollectionDTO designDTO) { + return Response.success(designService.designCloud(designDTO)); + } } diff --git a/src/main/java/com/ai/da/controller/SavedCollectionController.java b/src/main/java/com/ai/da/controller/SavedCollectionController.java index 29cbabac..bcd07da1 100644 --- a/src/main/java/com/ai/da/controller/SavedCollectionController.java +++ b/src/main/java/com/ai/da/controller/SavedCollectionController.java @@ -245,4 +245,16 @@ public class SavedCollectionController { public Response likeHistoryRelSketch() { return Response.success(userLikeGroupService.likeHistoryRelSketch()); } + + @ApiOperation(value = "download") + @PostMapping("/download") + public Response download() { + return Response.success(userLikeGroupService.download()); + } + + @ApiOperation(value = "productImageInitialize") + @PostMapping("/productImageInitialize") + public Response productImageUpload(@Valid @RequestBody ProductImageInitializeDTO productImageInitializeDTO) { + return Response.success(userLikeGroupService.productImageInitialize(productImageInitializeDTO)); + } } diff --git a/src/main/java/com/ai/da/controller/ThirdPartyController.java b/src/main/java/com/ai/da/controller/ThirdPartyController.java index e077fa8c..c0ff893f 100644 --- a/src/main/java/com/ai/da/controller/ThirdPartyController.java +++ b/src/main/java/com/ai/da/controller/ThirdPartyController.java @@ -1,9 +1,13 @@ package com.ai.da.controller; import com.ai.da.common.response.Response; +import com.ai.da.mapper.primary.entity.GoogleUser; import com.ai.da.model.dto.*; import com.ai.da.model.vo.AccountLoginVO; +import com.ai.da.model.vo.DesignCollectionVO; import com.ai.da.service.AccountService; +import com.ai.da.service.DesignService; +import com.alibaba.fastjson.JSONObject; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -28,6 +32,9 @@ public class ThirdPartyController { @Resource private AccountService accountService; + @Resource + private DesignService designService; + /*@ApiOperation(value = "Add user information") @PostMapping("/addUser") public Response addUser(@Valid @RequestBody AccountAddDTO accountAddDTO) { @@ -121,4 +128,22 @@ public class ThirdPartyController { public Response googleCallback(@RequestParam("code") String code, HttpSession session) { return Response.success(accountService.googleCallback(code, session)); } + @CrossOrigin + @GetMapping("/parseGoogleCredential") + public Response parseGoogleCredential(@RequestParam("credential") String credential) { + return Response.success(accountService.parseGoogleCredential(credential)); + } + + @CrossOrigin + @GetMapping("/parseWeChatCode") + public Response parseWeChatCode(@RequestParam("code") String code) { + return Response.success(accountService.parseWeChatCode(code)); + } + + @ApiOperation(value = "接收Design结果") + @PostMapping("/receiveDesignResults") + @CrossOrigin + public Response receiveDesignResults(@Valid @RequestBody JSONObject responseObject) { + return Response.success(designService.receiveDesignResults(responseObject)); + } } diff --git a/src/main/java/com/ai/da/mapper/primary/entity/AccountExtendMapper.java b/src/main/java/com/ai/da/mapper/primary/AccountExtendMapper.java similarity index 74% rename from src/main/java/com/ai/da/mapper/primary/entity/AccountExtendMapper.java rename to src/main/java/com/ai/da/mapper/primary/AccountExtendMapper.java index 312fa810..687790e3 100644 --- a/src/main/java/com/ai/da/mapper/primary/entity/AccountExtendMapper.java +++ b/src/main/java/com/ai/da/mapper/primary/AccountExtendMapper.java @@ -1,6 +1,7 @@ -package com.ai.da.mapper.primary.entity; +package com.ai.da.mapper.primary; import com.ai.da.common.config.mybatis.plus.CommonMapper; +import com.ai.da.mapper.primary.entity.AccountExtend; import java.util.Date; import java.util.List; diff --git a/src/main/java/com/ai/da/mapper/primary/ProductImageAttributeMapper.java b/src/main/java/com/ai/da/mapper/primary/ProductImageAttributeMapper.java new file mode 100644 index 00000000..65d0551a --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/ProductImageAttributeMapper.java @@ -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.ProductImageAttribute; + +public interface ProductImageAttributeMapper extends CommonMapper { +} diff --git a/src/main/java/com/ai/da/mapper/primary/entity/Account.java b/src/main/java/com/ai/da/mapper/primary/entity/Account.java index 60fcc9f0..dc4a93ae 100644 --- a/src/main/java/com/ai/da/mapper/primary/entity/Account.java +++ b/src/main/java/com/ai/da/mapper/primary/entity/Account.java @@ -97,6 +97,10 @@ public class Account implements Serializable { * 2 : 月付用户 * 3 : 试用用户 * 4 : 参加活动获取30天有效期和6000个积分的用户 + * 5 : 企业管理员账号 + * 6 : 企业子账号 + * 7 : 学校管理员 + * 8 : 学校子账号 */ private Integer systemUser; @@ -105,6 +109,15 @@ public class Account implements Serializable { */ private String avatar; - private Long invitationCode; + private String organizationName; + private Long parentId; + + private Integer isAdmin; + + private BigDecimal shareCredits; + + private Integer subAccountNum; + + private String invitationCode; } diff --git a/src/main/java/com/ai/da/mapper/primary/entity/AccountExtend.java b/src/main/java/com/ai/da/mapper/primary/entity/AccountExtend.java index 5742f0ec..c5b612b1 100644 --- a/src/main/java/com/ai/da/mapper/primary/entity/AccountExtend.java +++ b/src/main/java/com/ai/da/mapper/primary/entity/AccountExtend.java @@ -1,5 +1,6 @@ package com.ai.da.mapper.primary.entity; +import com.ai.da.common.response.PageResponse; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -26,5 +27,9 @@ public class AccountExtend implements Serializable { private String authType; + private String headImgUrl; + + private String name; + private String auth; } diff --git a/src/main/java/com/ai/da/mapper/primary/entity/GoogleUser.java b/src/main/java/com/ai/da/mapper/primary/entity/GoogleUser.java index b15410e8..ba2e5139 100644 --- a/src/main/java/com/ai/da/mapper/primary/entity/GoogleUser.java +++ b/src/main/java/com/ai/da/mapper/primary/entity/GoogleUser.java @@ -4,7 +4,11 @@ import lombok.Data; @Data public class GoogleUser { - private String id; + private String sub; // 用户唯一标识 private String email; private String name; + private String picture; + private boolean emailVerified; + private String givenName; + private String familyName; } diff --git a/src/main/java/com/ai/da/mapper/primary/entity/ProductImageAttribute.java b/src/main/java/com/ai/da/mapper/primary/entity/ProductImageAttribute.java new file mode 100644 index 00000000..129eb32b --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/entity/ProductImageAttribute.java @@ -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; + +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("product_image_attribute") +public class ProductImageAttribute implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + private String imgName; + private String length; + private String sleeveLength; + private String sleeveShape; + private String sleeveShoulder; + private String neckline; + private String collar; + private String design; + private String silhouette; + private String type; + private String openingType; + private String subtype; + + private String style; +} diff --git a/src/main/java/com/ai/da/mapper/secondary/entity/AttributeRetrieval.java b/src/main/java/com/ai/da/mapper/secondary/entity/AttributeRetrieval.java index 84cc1b91..12ef2329 100644 --- a/src/main/java/com/ai/da/mapper/secondary/entity/AttributeRetrieval.java +++ b/src/main/java/com/ai/da/mapper/secondary/entity/AttributeRetrieval.java @@ -19,6 +19,4 @@ public class AttributeRetrieval { private String subtype; private String style; - - private Integer deprecated; } diff --git a/src/main/java/com/ai/da/model/dto/AccountLoginDTO.java b/src/main/java/com/ai/da/model/dto/AccountLoginDTO.java index 2c1483c9..2f536ffb 100644 --- a/src/main/java/com/ai/da/model/dto/AccountLoginDTO.java +++ b/src/main/java/com/ai/da/model/dto/AccountLoginDTO.java @@ -32,4 +32,6 @@ public class AccountLoginDTO { @ApiModelProperty("邮箱验证码") private String emailVerifyCode; + private String organizationName; + } diff --git a/src/main/java/com/ai/da/model/dto/AddSubAccountDTO.java b/src/main/java/com/ai/da/model/dto/AddSubAccountDTO.java new file mode 100644 index 00000000..2f894789 --- /dev/null +++ b/src/main/java/com/ai/da/model/dto/AddSubAccountDTO.java @@ -0,0 +1,12 @@ +package com.ai.da.model.dto; + +import com.ai.da.mapper.primary.entity.Account; +import lombok.Data; + +import java.util.List; + +@Data +public class AddSubAccountDTO extends Account { + + private List deleteIdList; +} diff --git a/src/main/java/com/ai/da/model/dto/DesignCollectionDTO.java b/src/main/java/com/ai/da/model/dto/DesignCollectionDTO.java index 478483c4..91120a0b 100644 --- a/src/main/java/com/ai/da/model/dto/DesignCollectionDTO.java +++ b/src/main/java/com/ai/da/model/dto/DesignCollectionDTO.java @@ -63,4 +63,8 @@ public class DesignCollectionDTO { private String moodboardPostion; + private List requestIdList; + + private Integer designNum; + } diff --git a/src/main/java/com/ai/da/model/dto/GenerateToPythonDTO.java b/src/main/java/com/ai/da/model/dto/GenerateToPythonDTO.java index 16fa7988..64c31bb7 100644 --- a/src/main/java/com/ai/da/model/dto/GenerateToPythonDTO.java +++ b/src/main/java/com/ai/da/model/dto/GenerateToPythonDTO.java @@ -29,12 +29,15 @@ public class GenerateToPythonDTO { private String svg; - public GenerateToPythonDTO(String tasks_id, String prompt, String image_url, String mode, String category, String gender) { + private String version; + + public GenerateToPythonDTO(String tasks_id, String prompt, String image_url, String mode, String category, String gender, String version) { this.image_url = image_url; this.category = category; this.prompt = prompt; this.mode = mode; this.tasks_id = tasks_id; this.gender = gender; + this.version = version; } } diff --git a/src/main/java/com/ai/da/model/dto/ProductImageInitializeDTO.java b/src/main/java/com/ai/da/model/dto/ProductImageInitializeDTO.java new file mode 100644 index 00000000..a3aace06 --- /dev/null +++ b/src/main/java/com/ai/da/model/dto/ProductImageInitializeDTO.java @@ -0,0 +1,10 @@ +package com.ai.da.model.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class ProductImageInitializeDTO { + private List libraryIds; +} diff --git a/src/main/java/com/ai/da/model/dto/ReDesignCollectionDTO.java b/src/main/java/com/ai/da/model/dto/ReDesignCollectionDTO.java index b72a690a..8c8bbe48 100644 --- a/src/main/java/com/ai/da/model/dto/ReDesignCollectionDTO.java +++ b/src/main/java/com/ai/da/model/dto/ReDesignCollectionDTO.java @@ -33,7 +33,7 @@ public class ReDesignCollectionDTO { @ApiModelProperty("市场手稿板图片id 数组") private List marketingSketchs; - @NotNull(message = "colorBoards.cannot.be.empty") + @NotNull(message = "systemScale.cannot.be.empty") @ApiModelProperty("系统取图比列") private BigDecimal systemScale; @@ -67,4 +67,8 @@ public class ReDesignCollectionDTO { private String moodboardPosition; private String moodTemplateId; + + private List requestIdList; + + private Integer designNum; } diff --git a/src/main/java/com/ai/da/model/dto/SubAccountPageDTO.java b/src/main/java/com/ai/da/model/dto/SubAccountPageDTO.java new file mode 100644 index 00000000..f5dcc995 --- /dev/null +++ b/src/main/java/com/ai/da/model/dto/SubAccountPageDTO.java @@ -0,0 +1,9 @@ +package com.ai.da.model.dto; + +import com.ai.da.model.vo.PageQueryBaseVo; +import lombok.Data; + +@Data +public class SubAccountPageDTO extends PageQueryBaseVo { + private String userName; +} diff --git a/src/main/java/com/ai/da/model/vo/AccountLoginVO.java b/src/main/java/com/ai/da/model/vo/AccountLoginVO.java index ab23b872..9a1f9b85 100644 --- a/src/main/java/com/ai/da/model/vo/AccountLoginVO.java +++ b/src/main/java/com/ai/da/model/vo/AccountLoginVO.java @@ -1,5 +1,6 @@ package com.ai.da.model.vo; +import com.ai.da.mapper.primary.entity.AccountExtend; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import io.swagger.models.auth.In; @@ -8,6 +9,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import javax.validation.constraints.NotBlank; +import java.util.List; @AllArgsConstructor @NoArgsConstructor @@ -40,4 +42,6 @@ public class AccountLoginVO { private Long followerCount; + private List accountExtendList; + } diff --git a/src/main/java/com/ai/da/model/vo/DesignCollectionItemVO.java b/src/main/java/com/ai/da/model/vo/DesignCollectionItemVO.java index dc15cd14..1c98e059 100644 --- a/src/main/java/com/ai/da/model/vo/DesignCollectionItemVO.java +++ b/src/main/java/com/ai/da/model/vo/DesignCollectionItemVO.java @@ -22,6 +22,8 @@ public class DesignCollectionItemVO { @ApiModelProperty("t_design_python_outfit id") private String designOutfitUrl; + private String objectSign; + public DesignCollectionItemVO() { } diff --git a/src/main/java/com/ai/da/model/vo/DesignCollectionVO.java b/src/main/java/com/ai/da/model/vo/DesignCollectionVO.java index 8ad6e7a4..807f364c 100644 --- a/src/main/java/com/ai/da/model/vo/DesignCollectionVO.java +++ b/src/main/java/com/ai/da/model/vo/DesignCollectionVO.java @@ -23,6 +23,8 @@ public class DesignCollectionVO { private String processId; + private List UnfinishedList; + public DesignCollectionVO() { } } diff --git a/src/main/java/com/ai/da/model/vo/GoogleTokenResponse.java b/src/main/java/com/ai/da/model/vo/GoogleTokenResponse.java index f742d3c0..71676761 100644 --- a/src/main/java/com/ai/da/model/vo/GoogleTokenResponse.java +++ b/src/main/java/com/ai/da/model/vo/GoogleTokenResponse.java @@ -6,5 +6,8 @@ import lombok.Data; public class GoogleTokenResponse { private String accessToken; private String idToken; + private long expiresIn; + private String tokenType; + private String scope; } diff --git a/src/main/java/com/ai/da/model/vo/ValidateElementVO.java b/src/main/java/com/ai/da/model/vo/ValidateElementVO.java index f2cb87a1..73912616 100644 --- a/src/main/java/com/ai/da/model/vo/ValidateElementVO.java +++ b/src/main/java/com/ai/da/model/vo/ValidateElementVO.java @@ -47,4 +47,8 @@ public class ValidateElementVO { private String modelSex; private String style; + + private List requestIdList; + + private Integer designNum; } diff --git a/src/main/java/com/ai/da/python/PythonService.java b/src/main/java/com/ai/da/python/PythonService.java index 08113d91..3032a498 100644 --- a/src/main/java/com/ai/da/python/PythonService.java +++ b/src/main/java/com/ai/da/python/PythonService.java @@ -230,13 +230,14 @@ public class PythonService { designPythonObjects.setProcess_id(processId); long pinPrintNum = calculateDesignPinPrintNum(elementVO.getPrintBoardElements()); - long noPinPrintNum = calculateDesignNoPinPrintNum(elementVO.getPrintBoardElements()); - long noPrintNum = 8 - pinPrintNum - noPinPrintNum; + long noPinPrintNum = calculateDesignNoPinPrintNum(elementVO.getPrintBoardElements(), elementVO.getDesignNum()); + long noPrintNum = elementVO.getDesignNum() - pinPrintNum - noPinPrintNum; elementVO.setNoPinPrintNum(noPinPrintNum); int[] sketchNumbers = new int[3]; - for (int i = 0; i < 8; i++) { + int designNum = elementVO.getDesignNum(); + for (int i = 0; i < designNum; i++) { CurrentDesignPictureTypeEnum designPictureType = calculateCurrentDesignPictureTypeNew(elementVO, sketchNumbers, systemScale); if (designPictureType == null) break; @@ -261,7 +262,7 @@ public class PythonService { elementVO.setDesignPythonItemPrint(designPythonItemPrint); elementVO.setDesignPrintPictureTypeLayoutList(calculateCurrentDesignPintPictureTypeLayout(elementVO.getModelSex())); - DesignPythonObject pythonObject = createDesignPythonObject(elementVO, designPictureType, systemScale, singleOverall, switchCategory); + DesignPythonObject pythonObject = createDesignPythonObject(elementVO, designPictureType, systemScale, singleOverall, switchCategory, i); objects.add(pythonObject); redisUtil.addProcessId(processId, i + 1); } @@ -296,22 +297,24 @@ public class PythonService { } } - private DesignPythonObject createDesignPythonObject(ValidateElementVO elementVO, CurrentDesignPictureTypeEnum designPictureType, BigDecimal systemScale, String singleOverall, String switchCategory) { + private DesignPythonObject createDesignPythonObject(ValidateElementVO elementVO, CurrentDesignPictureTypeEnum designPictureType, BigDecimal systemScale, String singleOverall, String switchCategory, int i) { DesignPythonObject pythonObject = new DesignPythonObject(); pythonObject.setItems(coverToDesignPythonItemNew(elementVO, designPictureType, systemScale)); pythonObject.setBasic(coverToBasic(pythonObject.getItems().get(0), singleOverall, switchCategory, elementVO.getDesignLibraryModelPoint())); + pythonObject.setObjectSign(elementVO.getRequestIdList().get(i)); return pythonObject; } private CurrentDesignPictureTypeEnum calculateCurrentDesignPictureTypeNew(ValidateElementVO elementVO, int[] sketchNumbers, BigDecimal systemScale) { List pinData = getPinData(elementVO); + Integer designNum = elementVO.getDesignNum(); if (CollectionUtil.isNotEmpty(pinData)) { return CurrentDesignPictureTypeEnum.PIN; } else { if (sketchNumbers[1] == 0 && sketchNumbers[2] == 0) { - sketchNumbers[1] = systemScale.multiply(BigDecimal.valueOf(8 - sketchNumbers[0])).setScale(0, BigDecimal.ROUND_HALF_UP).intValue(); - sketchNumbers[2] = 8 - sketchNumbers[0] - sketchNumbers[1]; + sketchNumbers[1] = systemScale.multiply(BigDecimal.valueOf(designNum - sketchNumbers[0])).setScale(0, BigDecimal.ROUND_HALF_UP).intValue(); + sketchNumbers[2] = designNum - sketchNumbers[0] - sketchNumbers[1]; } if (sketchNumbers[2] > 0 && sketchNumbers[1] > 0) { Long l = RandomsUtil.randomSysFile(0l, 2l); @@ -491,7 +494,7 @@ public class PythonService { } //计算print 非Pin图片剩余张数 - private long calculateDesignNoPinPrintNum(List printBoardElements) { + private long calculateDesignNoPinPrintNum(List printBoardElements, Integer designNum) { if (CollectionUtils.isEmpty(printBoardElements)) { return 0; } @@ -500,10 +503,10 @@ public class PythonService { return 0; } else { long pinNum = printBoardElements.stream().filter(f -> f.getHasPin() == 1).count(); - if (8 - pinNum < 4) { - return RandomsUtil.randomSysFile(0L, 8 - pinNum + 1); + if (designNum - pinNum < designNum/2) { + return RandomsUtil.randomSysFile(0L, designNum - pinNum + 1); } else { - return RandomsUtil.randomSysFile(0L, 4L + 1); + return RandomsUtil.randomSysFile(0L, (long) (designNum/2 + 1)); } } } @@ -553,7 +556,7 @@ public class PythonService { if (elementVO.getSingleOverall().equals(SingleOverallEnum.OVERALL.getRealName())) { List otherSketchCategoryList = getOtherSketchCategoryList(elementVO.getModelSex(), designPythonItem); if (!otherSketchCategoryList.isEmpty()) { - JSONObject attributeRecognition = getAttributeRecognition(designPythonItem, designPythonItem.getType(), elementVO.getModelSex()); + JSONObject attributeRecognition = getAttributeRecognition(designPythonItem.getPath(), designPythonItem.getType(), elementVO.getModelSex()); for (String styleCategory : otherSketchCategoryList) { DesignPythonItem otherSketch = processAttributeRecognition(attributeRecognition, elementVO, designPictureType, styleCategory, systemScale); itemList.add(otherSketch); @@ -790,7 +793,7 @@ public class PythonService { return attributeRetrieval; } - public JSONObject getAttributeRecognition(DesignPythonItem designPythonItem, String styleCategory, String modelSex) { + public JSONObject getAttributeRecognition(String sketchImgUrl, String styleCategory, String modelSex) { OkHttpClient client = new OkHttpClient().newBuilder() .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS) @@ -801,7 +804,7 @@ public class PythonService { JSONObject paramJSONObject = new JSONObject(); paramJSONObject.put("category", styleCategory); paramJSONObject.put("colony", modelSex); - paramJSONObject.put("sketch_img_url", designPythonItem.getPath()); + paramJSONObject.put("sketch_img_url", sketchImgUrl); JSONArray paramArray = new JSONArray(); paramArray.add(paramJSONObject); String param = JSON.toJSONString(paramArray, SerializerFeature.DisableCircularReferenceDetect); @@ -3003,6 +3006,58 @@ public class PythonService { throw new BusinessException("design.interface.exception"); } + public JSONObject designStream(DesignPythonObjects designPythonObjects) { + // todo 限流校验 +// AccessLimitUtils.validate("design",5); + 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"); + //关闭FastJson的引用检测 防止出现$ref 现象 + String param = JSON.toJSONString(designPythonObjects, SerializerFeature.DisableCircularReferenceDetect); + log.info("design请求python 参数:####{}", param); + RequestBody body = RequestBody.create(mediaType, param); + Request request = new Request.Builder() + .url(accessPythonIp + ":" + accessPythonPort + "/api/design_v2") +// .url(fastApiPythonAddress + "/api/design") +// .url(accessPythonIp + ":10200/aifda/api/v1.0/generate") + .method("POST", body) + .addHeader("Authorization", "Basic YWlkbGFiOjEyMw==") + .addHeader("Content-Type", "application/json") + .build(); + Response response; + String responseBody; + try { + response = client.newCall(request).execute(); + } catch (IOException ioException) { + AccessLimitUtils.validateOut("design"); + log.error("PythonService##design异常###{}", ExceptionUtil.getThrowableList(ioException)); + throw new BusinessException("design.interface.exception"); + } + //去除限流 +// AccessLimitUtils.validateOut("design"); + if (response.isSuccessful()) { + try { + if (Objects.nonNull(response.body())) { + responseBody = response.body().string(); + JSONObject responseObject = JSON.parseObject(responseBody); + log.info("PythonService##responseObject###{}", responseObject); + return responseObject; + } + throw new BusinessException("design.interface.exception"); + } catch (IOException | JSONException e) { + log.error("PythonService##design异常###{}", e.getMessage()); + throw new BusinessException("design.interface.exception"); + } + } + log.error("PythonService##design异常response###{}", response); + //生成失败 + throw new BusinessException("design.interface.exception"); + } + /** * 暂时未用 */ @@ -3566,4 +3621,54 @@ public class PythonService { //生成失败 throw new BusinessException("bright.interface.exception"); } + + public JSONObject attributeRecognition(List pictureUrls,List ids, List category) { + //限流校验 + AccessLimitUtils.validate("attributeRecognition", 20); + OkHttpClient client = new OkHttpClient().newBuilder() + .connectTimeout(30, TimeUnit.SECONDS) + .pingInterval(5, TimeUnit.SECONDS)//websocket轮训间隔(单位:秒) + .readTimeout(300, TimeUnit.SECONDS)//读取超时(单位:秒) + .writeTimeout(300, TimeUnit.SECONDS)//写入超时(单位:秒) + .build(); + MediaType mediaType = MediaType.parse("application/json"); + Map> content = Maps.newHashMap(); + //识别图片路径数组 + content.put("upload_img_path", pictureUrls); + //识别图片id数组 + content.put("upload_img_id", ids); + content.put("upload_img_category", category); + RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(content)); + Request request = new Request.Builder() + .url(accessPythonIp + ":9993/api/attribute") + .method("POST", body) + .addHeader("Authorization", "Basic YWlkbGFiOjEyMw==") + .addHeader("Content-Type", "application/json") + .build(); + Response response = null; + String bodyStr = null; + try { + log.info("识别python对应的属性标签值请求入参content###{}", JSON.toJSONString(content)); + response = client.newCall(request).execute(); + bodyStr = response.body().string(); + } catch (IOException ioException) { + log.error("PythonService###attributeRecognition异常##{}", ExceptionUtil.getThrowableList(ioException)); + } + log.info("识别python对应的属性标签值结果###{}",bodyStr.trim()); + //去除限流 + AccessLimitUtils.validateOut("attributeRecognition"); + if (Objects.isNull(response)) { + log.error("PythonService##attributeRecognition异常###{}", "response or body is empty!"); + throw new BusinessException("attribute recognition exception!"); + } + JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(response)); + Boolean result = jsonObject.getBoolean("successful"); + if (result) { + JSONObject attributeJSONObject = JSON.parseObject(bodyStr.trim()); + return attributeJSONObject; + } + log.info("识别python对应的属性标签值异常###{}", jsonObject); + //生成失败 + throw new BusinessException("Atribute recognition exception!"); + } } diff --git a/src/main/java/com/ai/da/python/vo/DesignPythonObject.java b/src/main/java/com/ai/da/python/vo/DesignPythonObject.java index aa6a11e2..12946423 100644 --- a/src/main/java/com/ai/da/python/vo/DesignPythonObject.java +++ b/src/main/java/com/ai/da/python/vo/DesignPythonObject.java @@ -15,4 +15,6 @@ public class DesignPythonObject { * basic 选项 */ DesignPythonBasic basic; + + private String objectSign; } diff --git a/src/main/java/com/ai/da/python/vo/DesignPythonObjects.java b/src/main/java/com/ai/da/python/vo/DesignPythonObjects.java index af5fa3be..1f61ee07 100644 --- a/src/main/java/com/ai/da/python/vo/DesignPythonObjects.java +++ b/src/main/java/com/ai/da/python/vo/DesignPythonObjects.java @@ -16,4 +16,6 @@ public class DesignPythonObjects { * design新增的library */ List addLibrary; + + private String requestId; } diff --git a/src/main/java/com/ai/da/service/AccountService.java b/src/main/java/com/ai/da/service/AccountService.java index bd9c99b4..2f2f6ff3 100644 --- a/src/main/java/com/ai/da/service/AccountService.java +++ b/src/main/java/com/ai/da/service/AccountService.java @@ -1,6 +1,8 @@ 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.GoogleUser; import com.ai.da.mapper.primary.entity.TrialOrder; import com.ai.da.model.dto.*; import com.ai.da.model.vo.AccountLoginVO; @@ -186,4 +188,28 @@ public interface AccountService extends IService { String googleCallback(String code, HttpSession session); List getPaidCustomerEmail(); + + void temporaryUpgrade(); + + AccountLoginVO enterpriseLogin(AccountLoginDTO accountDTO); + + AccountLoginVO schoolLogin(AccountLoginDTO accountDTO); + + Boolean addSubAccount(AddSubAccountDTO addSubAccountDTO); + + Boolean deleteSubAccount(AddSubAccountDTO addSubAccountDTO); + + PageBaseResponse subAccountList(SubAccountPageDTO subAccountPageDTO); + + Account accountDetail(Long id); + + AccountLoginVO parseGoogleCredential(String credential); + + AccountLoginVO parseWeChatCode(String code); + + AccountLoginVO getAccountDetail(); + + Boolean bindGoogle(String credential); + + Boolean bindWeChat(String code); } diff --git a/src/main/java/com/ai/da/service/DesignService.java b/src/main/java/com/ai/da/service/DesignService.java index b346c8bf..d362d27b 100644 --- a/src/main/java/com/ai/da/service/DesignService.java +++ b/src/main/java/com/ai/da/service/DesignService.java @@ -7,6 +7,7 @@ import com.ai.da.model.vo.DesignCollectionVO; import com.ai.da.model.vo.DesignItemDetailVO; import com.ai.da.model.vo.DesignLikeVO; import com.ai.da.python.vo.DesignPythonObjects; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.extension.service.IService; import java.math.BigDecimal; @@ -25,7 +26,7 @@ public interface DesignService extends IService { * @param designDTO * @return */ - DesignCollectionVO designCollection(DesignCollectionDTO designDTO); + String designCollection(DesignCollectionDTO designDTO); /** * redesign @@ -33,7 +34,7 @@ public interface DesignService extends IService { * @param reDesignDTO * @return */ - DesignCollectionVO reDesignCollection(ReDesignCollectionDTO reDesignDTO); + String reDesignCollection(ReDesignCollectionDTO reDesignDTO); /** * redesign @@ -99,4 +100,10 @@ public interface DesignService extends IService { List getModel(List designItemIdList); Long getCountByUserAndTime(String startTime, String endTime, List accountIds); + + Boolean receiveDesignResults(JSONObject responseObject); + + DesignCollectionVO getDesignResult(String requestId, List objectSignList); + + String designCloud(DesignCollectionDTO designDTO); } diff --git a/src/main/java/com/ai/da/service/UserLikeGroupService.java b/src/main/java/com/ai/da/service/UserLikeGroupService.java index 71edbc50..552e9fe3 100644 --- a/src/main/java/com/ai/da/service/UserLikeGroupService.java +++ b/src/main/java/com/ai/da/service/UserLikeGroupService.java @@ -4,6 +4,7 @@ import com.ai.da.mapper.primary.entity.CanvasElementUpload; import com.ai.da.mapper.primary.entity.ToProductImageResult; import com.ai.da.mapper.primary.entity.UserLikeGroup; import com.ai.da.model.dto.ExportSaveDTO; +import com.ai.da.model.dto.ProductImageInitializeDTO; import com.ai.da.model.dto.ProductImageLikeDTO; import com.ai.da.model.dto.ToProductImageDTO; import com.ai.da.model.vo.*; @@ -62,4 +63,8 @@ public interface UserLikeGroupService extends IService { List getRelightResult(List taskIdList); String likeHistoryRelSketch(); + + String download(); + + Boolean productImageInitialize(ProductImageInitializeDTO productImageInitializeDTO); } diff --git a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java index 2d826c03..7fff9732 100644 --- a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java @@ -7,9 +7,11 @@ import com.ai.da.common.context.UserContext; import com.ai.da.common.enums.AuthenticationOperationTypeEnum; import com.ai.da.common.enums.CreditsEventsEnum; import com.ai.da.common.enums.LoginTypeEnum; +import com.ai.da.common.response.PageBaseResponse; import com.ai.da.common.response.ResultEnum; import com.ai.da.common.security.jwt.JWTTokenHelper; import com.ai.da.common.utils.*; +import com.ai.da.mapper.primary.AccountExtendMapper; import com.ai.da.mapper.primary.AccountMapper; import com.ai.da.mapper.primary.QuestionnaireMapper; import com.ai.da.mapper.primary.TrialOrderMapper; @@ -20,11 +22,16 @@ import com.ai.da.model.enums.Language; import com.ai.da.model.vo.*; import com.ai.da.service.*; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; +import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.client.json.jackson2.JacksonFactory; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import io.netty.util.internal.StringUtil; @@ -538,7 +545,12 @@ public class AccountServiceImpl extends ServiceImpl impl // .like(TrialOrder::getUserName, accountTrialDTO.getUserName())); List trialOrders = trialOrderMapper.selectList(trialOrderQueryWrapper); if (CollectionUtil.isNotEmpty(trialOrders)) { - throw new BusinessException("You have submitted a trial application, please wait for approval."); + TrialOrder trialOrder = trialOrders.get(0); + if (trialOrder.getStatus() == 1) { + throw new BusinessException("You have submitted a trial application, please wait for approval."); + }else { + throw new BusinessException("You have already been approved for a trial, please do not apply for the trial again"); + } } // 先检测用户名和邮箱 QueryWrapper qw = new QueryWrapper<>(); @@ -1392,7 +1404,7 @@ public class AccountServiceImpl extends ServiceImpl impl private static final String QUERY_MAXIMUM_USERID = "SELECT MAX(ID) AS max_id FROM pmr_users;"; - private static final String QUERY_NEW_USER_EMAIL = "SELECT user_email FROM pmr_users " + + private static final String QUERY_NEW_USER_EMAIL = "SELECT user_email, user_nicename FROM pmr_users " + "WHERE ID > ? "; @Value("${redis.key.maximumUserId}") @@ -1404,7 +1416,8 @@ public class AccountServiceImpl extends ServiceImpl impl @Override @Transactional(rollbackFor = Exception.class) public void registerUserToVisitor(){ - ArrayList newUserEmails = new ArrayList<>(); + ArrayList> newUsersInfo = new ArrayList<>(); + ArrayList allEmail = new ArrayList<>(); long maxUserId = CommonConstant.MAXIMUM_USER_ID; try (Connection connection = dataSource.getConnection(); PreparedStatement preparedStatement = connection.prepareStatement(QUERY_MAXIMUM_USERID)) { @@ -1420,9 +1433,14 @@ public class AccountServiceImpl extends ServiceImpl impl // 填充参数 - 历史最大用户ID newUserEmail.setLong(1, maxUserIdHistory); try (ResultSet queryEmailResultSet = newUserEmail.executeQuery()) { - if (queryEmailResultSet.next()) { + while (queryEmailResultSet.next()) { String email = queryEmailResultSet.getString("user_email"); - newUserEmails.add(email); + String username = queryEmailResultSet.getString("user_nicename"); + HashMap info = new HashMap<>(); + info.put("email", email); + info.put("username", username); + newUsersInfo.add(info); + allEmail.add(email); } /*else { log.error("未知错误。code-create的用户表中没有付费用户的信息"); throw new BusinessException("user info missing"); @@ -1437,22 +1455,36 @@ public class AccountServiceImpl extends ServiceImpl impl // return null; } - if (!newUserEmails.isEmpty()){ + if (!newUsersInfo.isEmpty()){ // 查询这些邮箱在aida上是否有账号 QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.in("user_email", newUserEmails).select("user_email"); + queryWrapper.in("user_email", allEmail).select("user_email"); - List collect = baseMapper.selectList(queryWrapper).stream().map(Account::getUserEmail).collect(Collectors.toList()); - if (!collect.isEmpty()){ - // 移除Code-Create新增用户中在AiDA已有账号的邮箱 - newUserEmails.removeAll(collect); + // 重复的邮箱 + List duplicateEmails = baseMapper.selectList(queryWrapper).stream().map(Account::getUserEmail).collect(Collectors.toList()); + if (!duplicateEmails.isEmpty()){ + // 移除Code-Create新增用户中在AiDA已有账号的邮箱,allEmail中剩余邮箱均为新用户邮箱 + allEmail.removeIf(item -> duplicateEmails.stream() + .anyMatch(removeItem -> removeItem.equalsIgnoreCase(item))); + if (!allEmail.isEmpty()){ + Iterator> iterator = newUsersInfo.iterator(); + while (iterator.hasNext()) { + Map userInfo = iterator.next(); + String email = userInfo.get("email"); + if (!allEmail.contains(email)) { + iterator.remove(); // 使用迭代器安全地移除元素 + } + } + }else { + newUsersInfo.clear(); + } } // 将新增用户添加到AiDA,身份为游客 - if (!newUserEmails.isEmpty()){ - newUserEmails.forEach(email -> { + if (!newUsersInfo.isEmpty()){ + newUsersInfo.forEach(userInfo -> { Account account = new Account(); - account.setUserEmail(email); - account.setUserName(email); + account.setUserEmail(userInfo.get("email")); + account.setUserName(userInfo.get("username")); account.setUserPassword("Third-000000"); account.setLanguage(Language.ENGLISH.name()); account.setValidStartTime(Instant.now().toEpochMilli()); @@ -1463,7 +1495,7 @@ public class AccountServiceImpl extends ServiceImpl impl account.setSystemUser(0); baseMapper.insert(account); // 邮件通知用户 - SendEmailUtil.notificationForRegisterUser(email); + SendEmailUtil.notificationForRegisterUser(userInfo.get("email")); }); } // 记录当前最大的用户id @@ -1471,6 +1503,16 @@ public class AccountServiceImpl extends ServiceImpl impl } } + public static void main(String[] args) { + List a = new ArrayList<>(); + a.add("1023316923@qq.com"); + a.add("Malinyuquan@gmail.com"); + + if (a.contains("malinyuquan@gmail.com")) { + log.info("aaaaaaaaaaaaaaaaaaaaa"); + } + } + private static final String QUERY_PAID_CUSTOMER_EMAIL = "SELECT distinct c.email " + "FROM `pmr_wc_order_stats` o " + "inner join `pmr_wc_customer_lookup` c " + @@ -1857,27 +1899,39 @@ public class AccountServiceImpl extends ServiceImpl impl @Override public String googleCallback(String code, HttpSession session) { try { - log.info("code:" + code); + log.info("code: " + code); // 使用 code 获取 Google 用户信息 GoogleUser googleUser = getGoogleUserFromCode(code); - log.info("googleUser:" + JSON.toJSONString(googleUser)); + log.info("googleUser: " + JSON.toJSONString(googleUser)); // 检查数据库中是否已有该用户 -// QueryWrapper qw = new QueryWrapper<>(); -// qw.lambda().eq(AccountExtend::getAuth, googleUser.getId()); -// List accountExtends = accountExtendMapper.selectList(qw); -// Account existingUser = findUserByGoogleId(googleUser.getId()); - return "Login successful"; -// if (CollectionUtil.isNotEmpty(accountExtends)) { -// // 用户已存在,直接登录 -//// session.setAttribute("user", existingUser); -// return "Login successful"; -// } else { -// // 用户不存在,创建新用户(自动注册) -//// User newUser = googleAuthService.registerNewUser(googleUser); -//// session.setAttribute("user", newUser); -// return "Registration and login successful"; -// } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(Account::getUserEmail, googleUser.getEmail()); // 根据邮箱查询用户 + List accounts = accountMapper.selectList(queryWrapper); + + if (CollectionUtil.isNotEmpty(accounts)) { + // 用户已存在,直接登录 + session.setAttribute("user", accounts.get(0)); + return "Login successful"; + } else { + // 用户不存在,创建新用户(自动注册) + Account newUser = new Account(); + newUser.setUserEmail(googleUser.getEmail()); + newUser.setUserName(googleUser.getName()); + newUser.setUserPassword("Third-000000"); + newUser.setLanguage(Language.ENGLISH.name()); + newUser.setValidStartTime(System.currentTimeMillis()); + newUser.setValidEndTime(toDayEnd(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli())); + newUser.setCreateDate(new Date()); + newUser.setIsTrial(1); + newUser.setIsBeginner(1); + newUser.setCredits(BigDecimal.valueOf(100)); + newUser.setSystemUser(3); + accountMapper.insert(newUser); + session.setAttribute("user", newUser); + + return "Registration and login successful"; + } } catch (Exception e) { return "Error processing Google login: " + e.getMessage(); } @@ -1887,6 +1941,7 @@ public class AccountServiceImpl extends ServiceImpl impl private static final String USER_INFO_URL = "https://www.googleapis.com/oauth2/v3/userinfo"; private static final String CLIENT_ID = "194770296147-njd68pm7tnapgonkj2h48mhf63n15n3f.apps.googleusercontent.com"; private static final String CLIENT_SECRET = "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"; +// private static final String REDIRECT_URI = "https://0551-117-143-125-51.ngrok-free.app/api/third/party/auth/google_callback"; private static final String REDIRECT_URI = "https://develop.api.aida.com.hk/api/third/party/auth/google_callback"; public GoogleUser getGoogleUserFromCode(String code) { @@ -1932,4 +1987,516 @@ public class AccountServiceImpl extends ServiceImpl impl // return userRepository.save(newUser); // } + @Override + public void temporaryUpgrade() { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().ne(Account::getSystemUser, 0); + queryWrapper.lambda().isNotNull(Account::getUserEmail); +// queryWrapper.lambda().eq(Account::getId, 6); + List accountList = accountMapper.selectList(queryWrapper); + int i = 0; + for (Account account : accountList) { + if (i >= 0) { + try { + // 判断用户语言,调用相应邮件发送方法 + if (Language.CHINESE_SIMPLIFIED.name().equals(account.getLanguage())) { +// SendEmailUtil.temporaryUpgrade(account, null, 0); + } else { +// SendEmailUtil.temporaryUpgrade(account, null, 1); + } + } catch (Exception e) { + // 捕获单个用户的发送失败异常,记录日志但不中断流程 + log.error("邮件发送失败,用户邮箱:{},原因:{}", account.getUserEmail(), e.getMessage(), e); + } + } + i ++; + } + } + + + @Override + public AccountLoginVO enterpriseLogin(AccountLoginDTO accountDTO) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(Account::getUserName, accountDTO.getUserName()); + qw.lambda().eq(Account::getOrganizationName, accountDTO.getOrganizationName()); + List accounts = accountMapper.selectList(qw); + if (CollectionUtil.isEmpty(accounts)) { + throw new BusinessException("Username or enterprise name incorrect."); + } + qw.lambda().eq(Account::getUserPassword, accountDTO.getPassword()); + accounts = accountMapper.selectList(qw); + if (CollectionUtil.isEmpty(accounts)) { + throw new BusinessException("Password error."); + } + Account account = accounts.get(0); + AccountLoginVO response = CopyUtil.copyObject(account, AccountLoginVO.class); + response.setEmail(account.getUserEmail()); + String token = LocalCacheUtils.getTokenCache(String.valueOf(account.getId())); + if (StringUtils.isNotBlank(token)) { + //用户已登入 + response.setToken(token); + } else { + response.setToken(createAccountToken(account)); + } + response.setUserId(account.getId()); + response.setSystemUser(account.getSystemUser()); + // 设置头像 + String avatar; + if (StringUtil.isNullOrEmpty(account.getAvatar())){ + avatar = CommonConstant.DEFAULT_AVATAR; + }else { + avatar = account.getAvatar(); + } + response.setAvatar(minioUtil.getPreSignedUrl(avatar, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + response.setFolloweeCount(portfolioService.getFolloweeCount(account.getId())); + response.setFollowerCount(portfolioService.getFollowerCount(account.getId())); + //判断是否常用ip 不是则发邮件提示 +// calculateExceptionIp(RequestInfoUtil.getIpAddress(request), account); + return response; + } + + @Override + public AccountLoginVO schoolLogin(AccountLoginDTO accountDTO) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(Account::getUserName, accountDTO.getUserName()); + qw.lambda().eq(Account::getOrganizationName, accountDTO.getOrganizationName()); + List accounts = accountMapper.selectList(qw); + if (CollectionUtil.isEmpty(accounts)) { + throw new BusinessException("Username or school name incorrect."); + } + qw.lambda().eq(Account::getUserPassword, accountDTO.getPassword()); + accounts = accountMapper.selectList(qw); + if (CollectionUtil.isEmpty(accounts)) { + throw new BusinessException("Password error."); + } + Account account = accounts.get(0); + AccountLoginVO response = CopyUtil.copyObject(account, AccountLoginVO.class); + response.setEmail(account.getUserEmail()); + String token = LocalCacheUtils.getTokenCache(String.valueOf(account.getId())); + if (StringUtils.isNotBlank(token)) { + //用户已登入 + response.setToken(token); + } else { + response.setToken(createAccountToken(account)); + } + response.setUserId(account.getId()); + response.setSystemUser(account.getSystemUser()); + // 设置头像 + String avatar; + if (StringUtil.isNullOrEmpty(account.getAvatar())){ + avatar = CommonConstant.DEFAULT_AVATAR; + }else { + avatar = account.getAvatar(); + } + response.setAvatar(minioUtil.getPreSignedUrl(avatar, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + response.setFolloweeCount(portfolioService.getFolloweeCount(account.getId())); + response.setFollowerCount(portfolioService.getFollowerCount(account.getId())); + //判断是否常用ip 不是则发邮件提示 +// calculateExceptionIp(RequestInfoUtil.getIpAddress(request), account); + return response; + } + + @Override + public Boolean addSubAccount(AddSubAccountDTO addSubAccountDTO) { + if (null == addSubAccountDTO.getId()) { + AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder(); + Account account = accountMapper.selectById(authPrincipalVo.getId()); + + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(Account::getOrganizationName, account.getOrganizationName()); + List accounts = accountMapper.selectList(qw); + if (accounts.size() >= account.getSubAccountNum()) { + throw new BusinessException("The maximum number of sub accounts that can be created has been reached."); + } + + qw.lambda().eq(Account::getUserName, addSubAccountDTO.getUserName()); + accounts = accountMapper.selectList(qw); + if (CollectionUtil.isNotEmpty(accounts)) { + throw new BusinessException("The enterprise already has an account with the same username."); + } + + Account subAccount = CopyUtil.copyObject(addSubAccountDTO, Account.class); + subAccount.setSystemUser(6); + subAccount.setValidStartTime(account.getValidStartTime()); + subAccount.setValidEndTime(account.getValidEndTime()); + subAccount.setLanguage(Language.ENGLISH.name()); + subAccount.setCreateDate(new Date()); + subAccount.setIsTrial(0); + subAccount.setIsBeginner(1); + subAccount.setParentId(account.getParentId()); + accountMapper.insert(subAccount); + }else { + Account subAccount = CopyUtil.copyObject(addSubAccountDTO, Account.class); + accountMapper.updateById(subAccount); + } + + + return Boolean.TRUE; + } + + @Override + public Boolean deleteSubAccount(AddSubAccountDTO addSubAccountDTO) { + accountMapper.deleteBatchIds(addSubAccountDTO.getDeleteIdList()); + return Boolean.TRUE; + } + + @Override + public PageBaseResponse subAccountList(SubAccountPageDTO subAccountPageDTO) { + AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder(); + Account account = accountMapper.selectById(authPrincipalVo); + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().ne(Account::getId, account.getId()); + qw.lambda().eq(Account::getOrganizationName, account.getOrganizationName()); + // 执行分页查询 + IPage page = accountMapper.selectPage(new Page<>(subAccountPageDTO.getPage(), subAccountPageDTO.getSize()), qw); + + return PageBaseResponse.success(page); + } + + @Override + public Account accountDetail(Long id) { + return accountMapper.selectById(id); + } + + @Override + public AccountLoginVO parseGoogleCredential(String credential) { + try { + // 配置 Google ID Token 验证器 + GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder( + new NetHttpTransport(), + JacksonFactory.getDefaultInstance()) + .setAudience(Collections.singletonList(CLIENT_ID)) + .build(); + + // 验证并解析 ID Token + GoogleIdToken idToken = verifier.verify(credential); + + + if (idToken != null) { + GoogleIdToken.Payload payload = idToken.getPayload(); + + // 提取用户信息 + String userId = payload.getSubject(); + String email = payload.getEmail(); + String name = (String) payload.get("name"); + String pictureUrl = (String) payload.get("picture"); + log.info(userId); + log.info(email); + log.info(name); + + // 检查数据库中是否已有该用户 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(Account::getUserEmail, email); // 根据邮箱查询用户 + List accounts = accountMapper.selectList(queryWrapper); + Account account = new Account(); + if (CollectionUtil.isNotEmpty(accounts)) { + account = accounts.get(0); + } else { + + AccountExtend accountExtendInsert = new AccountExtend(); + accountExtendInsert.setAuth(userId); + accountExtendInsert.setAuthType("Google"); + accountExtendInsert.setHeadImgUrl(pictureUrl); + accountExtendInsert.setName(name); + + // 用户不存在,创建新用户(自动注册) + Account newUser = new Account(); + newUser.setUserEmail(email); + newUser.setUserName(name); + newUser.setUserPassword("Third-000000"); + newUser.setLanguage(Language.ENGLISH.name()); + newUser.setValidStartTime(System.currentTimeMillis()); + newUser.setValidEndTime(toDayEnd(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli())); + newUser.setCreateDate(new Date()); + newUser.setIsTrial(1); + newUser.setIsBeginner(1); + newUser.setCredits(BigDecimal.valueOf(100)); + newUser.setSystemUser(3); + accountMapper.insert(newUser); + + accountExtendInsert.setAccountId(newUser.getId()); + accountExtendMapper.insert(accountExtendInsert); + + account = newUser; + } + + AccountLoginVO response = CopyUtil.copyObject(account, AccountLoginVO.class); + response.setEmail(account.getUserEmail()); + String token = LocalCacheUtils.getTokenCache(String.valueOf(account.getId())); + if (StringUtils.isNotBlank(token)) { + //用户已登入 + response.setToken(token); + } else { + response.setToken(createAccountToken(account)); + } + response.setUserId(account.getId()); + response.setSystemUser(account.getSystemUser()); + // 设置头像 + String avatar; + if (StringUtil.isNullOrEmpty(account.getAvatar())){ + avatar = CommonConstant.DEFAULT_AVATAR; + }else { + avatar = account.getAvatar(); + } + response.setAvatar(minioUtil.getPreSignedUrl(avatar, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + response.setFolloweeCount(portfolioService.getFolloweeCount(account.getId())); + response.setFollowerCount(portfolioService.getFollowerCount(account.getId())); + return response; + } else { + throw new IllegalArgumentException("Invalid ID token."); + } + + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("Failed to verify ID token: " + e.getMessage()); + } + } + + private static final String WECHAT_ACCESS_TOKEN_URL = + "https://api.weixin.qq.com/sns/oauth2/access_token"; + + private static final String APP_ID = "wxcfb92eb28d6385f5"; + private static final String APP_SECRET = "e5592c691756455b2d03ebfd21fc3131"; + + @Override + public AccountLoginVO parseWeChatCode(String code) { + // 1. 获取 access_token 和 openid + JSONObject accessTokenResponse = getAccessTokenFromWeChat(code); + String accessToken = accessTokenResponse.getString("access_token"); + String openId = accessTokenResponse.getString("openid"); + + if (StringUtils.isEmpty(accessToken) || StringUtils.isEmpty(openId)) { + throw new RuntimeException("微信接口返回数据缺失: " + accessTokenResponse.toJSONString()); + } + + // 2. 获取用户信息 + JSONObject userInfoResponse = getUserInfoFromWeChat(accessToken, openId); + + // 提取 unionid 和 nickname + String unionId = userInfoResponse.getString("unionid"); + String userName = userInfoResponse.getString("nickname"); + String headimgurl = userInfoResponse.getString("headimgurl"); + if (unionId == null) { + throw new IllegalArgumentException("无法获取 unionid,请检查微信开发平台配置"); + } + + // 检查数据库中是否已有该unionid + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(AccountExtend::getAuthType, "WeChat"); + queryWrapper.lambda().eq(AccountExtend::getAuth, unionId); + List accountExtends = accountExtendMapper.selectList(queryWrapper); + Account account = new Account(); + if (CollectionUtil.isEmpty(accountExtends)) { + AccountExtend accountExtendInsert = new AccountExtend(); + accountExtendInsert.setAuth(unionId); + accountExtendInsert.setAuthType("WeChat"); + accountExtendInsert.setHeadImgUrl(headimgurl); + accountExtendInsert.setName(userName); + + // 用户不存在,创建新用户(自动注册) + Account newUser = new Account(); +// newUser.setUserEmail(email); + newUser.setUserName(userName); + newUser.setUserPassword("Third-000000"); + newUser.setLanguage(Language.ENGLISH.name()); + newUser.setValidStartTime(System.currentTimeMillis()); + newUser.setValidEndTime(toDayEnd(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli())); + newUser.setCreateDate(new Date()); + newUser.setIsTrial(1); + newUser.setIsBeginner(1); + newUser.setCredits(BigDecimal.valueOf(100)); + newUser.setSystemUser(3); + accountMapper.insert(newUser); + + accountExtendInsert.setAccountId(newUser.getId()); + accountExtendMapper.insert(accountExtendInsert); + + account = newUser; + }else { + AccountExtend accountExtend = accountExtends.get(0); + account = accountMapper.selectById(accountExtend.getAccountId()); + } + + AccountLoginVO response = CopyUtil.copyObject(account, AccountLoginVO.class); + response.setEmail(account.getUserEmail()); + String token = LocalCacheUtils.getTokenCache(String.valueOf(account.getId())); + if (StringUtils.isNotBlank(token)) { + //用户已登入 + response.setToken(token); + } else { + response.setToken(createAccountToken(account)); + } + response.setUserId(account.getId()); + response.setSystemUser(account.getSystemUser()); + // 设置头像 + String avatar; + if (StringUtil.isNullOrEmpty(account.getAvatar())){ + avatar = CommonConstant.DEFAULT_AVATAR; + }else { + avatar = account.getAvatar(); + } + response.setAvatar(minioUtil.getPreSignedUrl(avatar, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + response.setFolloweeCount(portfolioService.getFolloweeCount(account.getId())); + response.setFollowerCount(portfolioService.getFollowerCount(account.getId())); + return response; + } + + private static final String WECHAT_USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo"; + private JSONObject getUserInfoFromWeChat(String accessToken, String openId) { + // 构造微信用户信息接口的 URL + String url = String.format( + "%s?access_token=%s&openid=%s&lang=zh_CN", + WECHAT_USER_INFO_URL, accessToken, openId + ); + + // 调用微信接口 + RestTemplate restTemplate = new RestTemplate(); + String response = restTemplate.getForObject(url, String.class); + + // 转换为 JSON 对象 + JSONObject jsonResponse = JSONObject.parseObject(response); + if (jsonResponse.containsKey("errcode")) { + throw new RuntimeException("微信用户信息接口调用失败: " + jsonResponse.getString("errmsg")); + } + + return jsonResponse; + } + + private JSONObject getAccessTokenFromWeChat(String code) { + // 构造微信接口请求 URL + String url = String.format( + "%s?appid=%s&secret=%s&code=%s&grant_type=authorization_code", + WECHAT_ACCESS_TOKEN_URL, APP_ID, APP_SECRET, code + ); + + // 调用微信接口 + RestTemplate restTemplate = new RestTemplate(); + String response = restTemplate.getForObject(url, String.class); + + // 转换为 JSON 对象 + JSONObject jsonResponse = JSONObject.parseObject(response); + if (jsonResponse.containsKey("errcode")) { + throw new RuntimeException("微信接口调用失败: " + jsonResponse.getString("errmsg")); + } + + return jsonResponse; + } + + @Override + public AccountLoginVO getAccountDetail() { + AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder(); + Long accountId = authPrincipalVo.getId(); + Account account = accountMapper.selectById(accountId); + + AccountLoginVO response = CopyUtil.copyObject(account, AccountLoginVO.class); + response.setEmail(account.getUserEmail()); + String token = LocalCacheUtils.getTokenCache(String.valueOf(account.getId())); + if (StringUtils.isNotBlank(token)) { + //用户已登入 + response.setToken(token); + } else { + response.setToken(createAccountToken(account)); + } + response.setUserId(account.getId()); + response.setSystemUser(account.getSystemUser()); + // 设置头像 + String avatar; + if (StringUtil.isNullOrEmpty(account.getAvatar())){ + avatar = CommonConstant.DEFAULT_AVATAR; + }else { + avatar = account.getAvatar(); + } + response.setAvatar(minioUtil.getPreSignedUrl(avatar, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + response.setFolloweeCount(portfolioService.getFolloweeCount(account.getId())); + response.setFollowerCount(portfolioService.getFollowerCount(account.getId())); + + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(AccountExtend::getAccountId, response.getUserId()); + List accountExtends = accountExtendMapper.selectList(qw); + if (CollectionUtil.isNotEmpty(accountExtends)) { + response.setAccountExtendList(accountExtends); + } + + return response; + } + + @Override + public Boolean bindGoogle(String credential) { + try { + // 配置 Google ID Token 验证器 + GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder( + new NetHttpTransport(), + JacksonFactory.getDefaultInstance()) + .setAudience(Collections.singletonList(CLIENT_ID)) + .build(); + + // 验证并解析 ID Token + GoogleIdToken idToken = verifier.verify(credential); + + + if (idToken != null) { + GoogleIdToken.Payload payload = idToken.getPayload(); + + // 提取用户信息 + String userId = payload.getSubject(); + String email = payload.getEmail(); + String name = (String) payload.get("name"); + String pictureUrl = (String) payload.get("picture"); + + + AccountExtend accountExtendInsert = new AccountExtend(); + accountExtendInsert.setAuth(userId); + accountExtendInsert.setAuthType("Google"); + accountExtendInsert.setHeadImgUrl(pictureUrl); + accountExtendInsert.setName(name); + + + AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder(); + accountExtendInsert.setAccountId(authPrincipalVo.getId()); + accountExtendMapper.insert(accountExtendInsert); + + return Boolean.TRUE; + } else { + throw new IllegalArgumentException("Invalid ID token."); + } + + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("Failed to verify ID token: " + e.getMessage()); + } + } + + @Override + public Boolean bindWeChat(String code) { + // 1. 获取 access_token 和 openid + JSONObject accessTokenResponse = getAccessTokenFromWeChat(code); + String accessToken = accessTokenResponse.getString("access_token"); + String openId = accessTokenResponse.getString("openid"); + + if (StringUtils.isEmpty(accessToken) || StringUtils.isEmpty(openId)) { + throw new RuntimeException("微信接口返回数据缺失: " + accessTokenResponse.toJSONString()); + } + + // 2. 获取用户信息 + JSONObject userInfoResponse = getUserInfoFromWeChat(accessToken, openId); + + // 提取 unionid 和 nickname + String unionId = userInfoResponse.getString("unionid"); + String userName = userInfoResponse.getString("nickname"); + String headimgurl = userInfoResponse.getString("headimgurl"); + if (unionId == null) { + throw new IllegalArgumentException("无法获取 unionid,请检查微信开发平台配置"); + } + AccountExtend accountExtendInsert = new AccountExtend(); + accountExtendInsert.setAuth(unionId); + accountExtendInsert.setAuthType("WeChat"); + accountExtendInsert.setHeadImgUrl(headimgurl); + accountExtendInsert.setName(userName); + + AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder(); + accountExtendInsert.setAccountId(authPrincipalVo.getId()); + accountExtendMapper.insert(accountExtendInsert); + + return Boolean.TRUE; + } } diff --git a/src/main/java/com/ai/da/service/impl/CollectionElementServiceImpl.java b/src/main/java/com/ai/da/service/impl/CollectionElementServiceImpl.java index e0f86569..73f0ec99 100644 --- a/src/main/java/com/ai/da/service/impl/CollectionElementServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/CollectionElementServiceImpl.java @@ -609,6 +609,12 @@ public class CollectionElementServiceImpl extends ServiceImpl impleme @Resource private RedisUtil redisUtil; + private final ConcurrentHashMap> designContext = new ConcurrentHashMap<>(); + + @Override - public DesignCollectionVO designCollection(DesignCollectionDTO designDTO) { + public String designCollection(DesignCollectionDTO designDTO) { AuthPrincipalVo userInfo = UserContext.getUserHolder(); //校验collection element ValidateElementVO elementVO = collectionElementService.validateElement(designDTO); @@ -283,7 +287,7 @@ public class DesignServiceImpl extends ServiceImpl impleme // return saveDesignItemAndDetail(pythonObjects, designId, collectionId, userInfo, designDTO.getTimeZone()); // } - private DesignCollectionVO designOrRedesignOperateNew(DesignCollectionDTO designDTO, AuthPrincipalVo userInfo, + private String designOrRedesignOperateNew(DesignCollectionDTO designDTO, AuthPrincipalVo userInfo, Long collectionIdParam, ValidateElementVO elementVO) { if (CollectionUtil.isNotEmpty(designDTO.getSketchBoards())) { //编辑sketchBoard @@ -336,7 +340,9 @@ public class DesignServiceImpl extends ServiceImpl impleme log.info("增加image_id关联运行时间:" + totalTimeInSeconds + " 秒"); //design startTime = System.currentTimeMillis(); - JSONObject responseJSONObject = pythonService.designNew(pythonObjects); + String requestId = UUID.randomUUID().toString(); + pythonObjects.setRequestId(requestId); + JSONObject responseJSONObject = pythonService.designStream(pythonObjects); endTime = System.currentTimeMillis(); totalTimeInSeconds = (endTime - startTime) / 1000; log.info("design python端运行时间:" + totalTimeInSeconds + " 秒"); @@ -350,10 +356,26 @@ public class DesignServiceImpl extends ServiceImpl impleme endTime = System.currentTimeMillis(); totalTimeInSeconds = (endTime - startTime) / 1000; log.info("处理关联关系运行时间:" + totalTimeInSeconds + " 秒"); + + + Map context = new HashMap<>(); + context.put("pythonObjects", pythonObjects); // 转换后的 Python 请求参数 + context.put("designId", designId); // 设计 ID + context.put("collectionId", collectionId); // 集合 ID + context.put("userInfo", userInfo); // 用户信息 + context.put("timeZone", designDTO.getTimeZone()); // 时区 + context.put("singleOverall", designDTO.getSingleOverall()); // 其他设计参数 + context.put("requestIdList", elementVO.getRequestIdList()); + + // 将上下文存入全局设计上下文中 + designContext.put(requestId, context); + //保存python返回信息;保存designItem和detail - return savePythonDesignItemAndDetail(pythonObjects, designId, collectionId, userInfo, designDTO.getTimeZone(), responseJSONObject, designDTO.getSingleOverall()); +// return savePythonDesignItemAndDetail(pythonObjects, designId, collectionId, userInfo, designDTO.getTimeZone(), responseJSONObject, designDTO.getSingleOverall()); + return requestId; } + @Override public void relationImageId(DesignPythonObjects pythonObjects) { if (Objects.isNull(pythonObjects)) { @@ -601,6 +623,152 @@ public class DesignServiceImpl extends ServiceImpl impleme @Resource private MinioUtil minioUtil; + private DesignCollectionVO savePythonDesignItemAndDetailSingle(DesignPythonObjects pythonObjects, Long designId, Long collectionId, AuthPrincipalVo userInfo, String timeZone, JSONObject outfit, String singleOverall, Map context) { + Object designCollectionVO = context.get("DesignCollectionVO"); + DesignCollectionVO response; + List designCollectionItems = Lists.newArrayList(); + if (null == designCollectionVO) { + response = new DesignCollectionVO(); + response.setDesignId(designId); + response.setCollectionId(collectionId); + response.setProcessId(pythonObjects.getProcess_id()); + }else { + response = (DesignCollectionVO) designCollectionVO; + designCollectionItems = response.getDesignCollectionItems(); + } + + response.setDesignCollectionItems(designCollectionItems); + + + DesignPythonObject item = new DesignPythonObject(); + String objectSign = outfit.getString("objectSign"); + log.info(objectSign); + for (DesignPythonObject object : pythonObjects.getObjects()) { + if (object.getObjectSign().equals(objectSign)) { + item = object; + continue; + } + } + + + DesignItem designItem = new DesignItem(); + designItem.setAccountId(userInfo.getId()); + designItem.setCollectionId(collectionId); + designItem.setDesignId(designId); + designItem.setCreateDate(DateUtil.getByTimeZone(timeZone)); + //生成的八张图片 + designItem.setDesignUrl(item.getBasic().getSave_name()); + designItem.setHasLike((byte) 0); + //生成designItem + Long designItemId = designItemService.saveOne(designItem); + // python design返回入库及封装 +// JSONObject outfit = data.getJSONObject(i + ""); +// if (null == outfit) { +// continue; +// } + TDesignPythonOutfit designPythonOutfit = new TDesignPythonOutfit(); + designPythonOutfit.setDesignItemId(designItemId); + designPythonOutfit.setUserId(userInfo.getId()); + designPythonOutfit.setDesignId(designId); + designPythonOutfit.setCollectionId(collectionId); + String synthesisUrl = outfit.getString("synthesis_url"); + if (!StringUtils.isEmpty(synthesisUrl)) { + designPythonOutfit.setDesignUrl(synthesisUrl); + } else { + throw new BusinessException("design.interface.exception"); + } + designPythonOutfitService.save(designPythonOutfit); + + JSONArray layers = outfit.getJSONArray("layers"); + List list = new ArrayList<>(); + DesignCollectionItemVO designCollectionItemVO = new DesignCollectionItemVO(); + designCollectionItemVO.setObjectSign(objectSign); + for (int i1 = 0; i1 < layers.size(); i1++) { + JSONObject jsonObject = layers.getJSONObject(i1); + TDesignPythonOutfitDetail designPythonOutfitDetail = new TDesignPythonOutfitDetail(); + designPythonOutfitDetail.setDesignId(designId); + designPythonOutfitDetail.setDesignPythonOutfitId(designPythonOutfit.getId()); + designPythonOutfitDetail.setPosition(jsonObject.getString("position")); + designPythonOutfitDetail.setImageSize(jsonObject.getString("image_size")); + designPythonOutfitDetail.setImageUrl(jsonObject.getString("image_url")); + if (singleOverall.equals(SingleOverallEnum.SINGLE.getRealName())) { + designCollectionItemVO.setDesignItemUrl(designItem.getDesignUrl()); + } + designPythonOutfitDetail.setImageCategory(jsonObject.getString("image_category")); + designPythonOutfitDetail.setMaskUrl(jsonObject.getString("mask_url")); + designPythonOutfitDetail.setUserId(userInfo.getId()); + designPythonOutfitDetail.setPriority(Integer.parseInt(jsonObject.getString("priority"))); + designPythonOutfitDetail.setCreateDate(LocalDateTime.now()); + list.add(designPythonOutfitDetail); + } + designPythonOutfitDetailService.saveBatch(list); + designCollectionItemVO.setDesignItemId(designItemId); + designCollectionItemVO.setDesignItemUrl(designItem.getDesignUrl()); + designCollectionItemVO.setDesignOutfitId(designPythonOutfit.getId()); + String designUrl = designPythonOutfit.getDesignUrl(); + if (!StringUtils.isEmpty(designUrl) && designUrl.contains("/")) { + int firstIndex = designUrl.indexOf("/"); + designCollectionItemVO.setDesignOutfitUrl(minioUtil.getPreSignedUrl(designUrl.substring(0, firstIndex) + "/" + designUrl.substring(firstIndex + 1), 24 * 60)); + } + //response + designCollectionItems.add(designCollectionItemVO); + + List designItemDetails = Lists.newArrayList(); + Map typePriority = list.stream().collect(Collectors.toMap(d -> d.getImageCategory().split("_")[0], + d -> Math.abs(d.getPriority()), + (existing, replacement) -> replacement)); + Map typeAndUndividedLayer = designItemService.setTypeAndUndividedLayer(layers); + for (DesignPythonItem detail : item.getItems()) { + if (null == detail) { + continue; + } + DesignItemDetail designItemDetail = CopyUtil.copyObject(detail, DesignItemDetail.class); + designItemDetail.setAccountId(userInfo.getId()); + designItemDetail.setDesignId(designId); + designItemDetail.setDesignItemId(designItemId); + designItemDetail.setCollectionElementId(detail.getElementId()); + designItemDetail.setCreateDate(DateUtil.getByTimeZone(timeZone)); + designItemDetail.setUndividedLayer(typeAndUndividedLayer.get(designItemDetail.getType().toLowerCase())); + if (SysFileLevel2TypeEnum.BODY.getRealName().equals(detail.getType())) { + designItemDetail.setPath(detail.getBody_path()); + //BODY不关联businessId + designItemDetail.setBusinessId(0L); + } + designItemDetail.setIconPath(detail.getIcon()); + designItemDetail.setPriority(typePriority.get(detail.getType().toLowerCase())); + if (!detail.getType().equals("Body")){ + DesignPythonItemPrint printObject = detail.getPrint().getOverall(); +// designItemDetail.setPrintPath(Objects.isNull(printObject) ? "" : printObject.getPath()); + designItemDetail.setPrintPath(CollectionUtils.isEmpty(printObject.getPrint_path_list()) ? "" : printObject.getPrint_path_list().get(0)); + } + designItemDetailService.save(designItemDetail); + if (!SysFileLevel2TypeEnum.BODY.getRealName().equals(detail.getType()) && !StringUtil.isNullOrEmpty(designItemDetail.getPrintPath())) { + DesignItemDetailPrint print = new DesignItemDetailPrint(); + print.setDesignItemDetailId(designItemDetail.getId()); + print.setPrintType("print"); + print.setPath(designItemDetail.getPrintPath()); + print.setSingleOrOverall("overall"); + print.setPosition("[0.0,0.0]"); +// print.setScale(1d); + // todo mark 将print默认scale置为0.3 + print.setScale(0.3d); + print.setAngle(0.0); + print.setPriority(1); + QueryWrapper getPrintboardLevel2TypeQw = new QueryWrapper<>(); + getPrintboardLevel2TypeQw.lambda().eq(CollectionElement::getUrl, print.getPath()); + getPrintboardLevel2TypeQw.lambda().orderByDesc(CollectionElement::getCreateDate); + getPrintboardLevel2TypeQw.last("limit 1"); + CollectionElement one = collectionElementService.getOne(getPrintboardLevel2TypeQw); + print.setLevel2Type(one.getLevel2Type()); + print.setCreateDate(LocalDateTime.now()); + designItemDetailPrintService.save(print); + } + } + synchronized (context) { + context.put("DesignCollectionVO", response); + } + return response; + } private DesignCollectionVO savePythonDesignItemAndDetail(DesignPythonObjects pythonObjects , Long designId, Long collectionId, AuthPrincipalVo userInfo, String timeZone, JSONObject responseJSONObject, String singleOverall) { DesignCollectionVO response = new DesignCollectionVO(); @@ -612,6 +780,7 @@ public class DesignServiceImpl extends ServiceImpl impleme if (data == null) { throw new BusinessException("design.interface.exception"); } + for (int i = 0; i < pythonObjects.getObjects().size(); i++) { DesignPythonObject item = pythonObjects.getObjects().get(i); DesignItem designItem = new DesignItem(); @@ -641,6 +810,7 @@ public class DesignServiceImpl extends ServiceImpl impleme throw new BusinessException("design.interface.exception"); } designPythonOutfitService.save(designPythonOutfit); + JSONArray layers = outfit.getJSONArray("layers"); List list = new ArrayList<>(); DesignCollectionItemVO designCollectionItemVO = new DesignCollectionItemVO(); @@ -750,7 +920,7 @@ public class DesignServiceImpl extends ServiceImpl impleme //生成designItem Long designItemId = designItemService.saveOne(designItem); //response - designCollectionItems.add(new DesignCollectionItemVO(designItemId, designItem.getDesignUrl(), null, null)); + designCollectionItems.add(new DesignCollectionItemVO(designItemId, designItem.getDesignUrl(), null, null, null)); List designItemDetails = Lists.newArrayList(); item.getItems().forEach(detail -> { @@ -797,7 +967,7 @@ public class DesignServiceImpl extends ServiceImpl impleme } @Override - public DesignCollectionVO reDesignCollection(ReDesignCollectionDTO reDesignDTO) { + public String reDesignCollection(ReDesignCollectionDTO reDesignDTO) { //校验collection Collection collection = collectionService.getById(reDesignDTO.getCollectionId()); if (Objects.isNull(collection)) { @@ -849,15 +1019,15 @@ public class DesignServiceImpl extends ServiceImpl impleme } List designItems = designItemService.getByDesignId(designId); if (CollectionUtils.isEmpty(designItems)) { - return new DesignCollectionVO(designId, design.getCollectionId(), null, null); + return new DesignCollectionVO(designId, design.getCollectionId(), null, null, null); } - return new DesignCollectionVO(designId, design.getCollectionId(), coverDesignItemToVO(designItems), null); + return new DesignCollectionVO(designId, design.getCollectionId(), coverDesignItemToVO(designItems), null, null); } private List coverDesignItemToVO(List designItems) { List response = Lists.newArrayList(); designItems.forEach(designItem -> { - response.add(new DesignCollectionItemVO(designItem.getId(), designItem.getDesignUrl(), null, null)); + response.add(new DesignCollectionItemVO(designItem.getId(), designItem.getDesignUrl(), null, null, null)); }); return response; } @@ -1389,4 +1559,62 @@ public class DesignServiceImpl extends ServiceImpl impleme } } + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean receiveDesignResults(JSONObject responseJSONObject) { +// String requestId = "UUID.randomUUID().toString()"; + String requestId = responseJSONObject.getString("requestId"); + Map context; + synchronized (designContext) { + log.info(designContext.toString()); + context = designContext.get(requestId); + if (context == null) { + log.error("上下文数据缺失,无法完成操作"); + return false; + } + + DesignPythonObjects pythonObjects = (DesignPythonObjects) context.get("pythonObjects"); + Long designId = (Long) context.get("designId"); + Long collectionId = (Long) context.get("collectionId"); + AuthPrincipalVo userInfo = (AuthPrincipalVo) context.get("userInfo"); + String timeZone = (String) context.get("timeZone"); + String singleOverall = (String) context.get("singleOverall"); + + DesignCollectionVO designCollectionVO = savePythonDesignItemAndDetailSingle(pythonObjects, designId, collectionId, userInfo, timeZone, responseJSONObject, singleOverall, context); + + log.info(designContext.toString()); + designContext.put(requestId, context); + } + + return Boolean.TRUE; + } + + @Override + public DesignCollectionVO getDesignResult(String requestId, List objectSignList) { +// Map stringObjectMap = designContext.get("UUID.randomUUID().toString()"); + Map stringObjectMap = designContext.get(requestId); + log.info(stringObjectMap.toString()); + DesignCollectionVO result = (DesignCollectionVO) stringObjectMap.get("DesignCollectionVO"); + if (Objects.isNull(result)) { + DesignCollectionVO noneResult = new DesignCollectionVO(); + noneResult.setUnfinishedList(objectSignList); + return noneResult; + } + for (DesignCollectionItemVO designCollectionItem : result.getDesignCollectionItems()) { + String objectSign = designCollectionItem.getObjectSign(); + objectSignList.remove(objectSign); + } + result.setUnfinishedList(objectSignList); + return result; + } + + @Override + public String designCloud(DesignCollectionDTO designDTO) { + AuthPrincipalVo userInfo = UserContext.getUserHolder(); + //校验collection element + ValidateElementVO elementVO = collectionElementService.validateElement(designDTO); + //design + return designOrRedesignOperateNew(designDTO, userInfo, null, elementVO); + } + } diff --git a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java index 0e2e196f..8f769d36 100644 --- a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java @@ -150,6 +150,14 @@ public class GenerateServiceImpl extends ServiceImpl i String port = generateServicePort; String jsonString = ""; HashMap params = new HashMap<>(); + String version = null; + if (!StringUtil.isNullOrEmpty(generateThroughImageTextDTO.getVersion()) && generateThroughImageTextDTO.getVersion().equals("high")){ + version = "high"; + params.put("version","high"); + }else if (!StringUtil.isNullOrEmpty(generateThroughImageTextDTO.getVersion()) && generateThroughImageTextDTO.getVersion().equals("fast")){ + version = "fast"; + params.put("version","fast"); + } // 3.1 确定不同类型的印花分别调哪个接口 if (generateThroughImageTextDTO.getLevel1Type().equals(PRINT_BOARD.getRealName())) { switch (generateThroughImageTextDTO.getLevel2Type()) { @@ -171,15 +179,16 @@ public class GenerateServiceImpl extends ServiceImpl i break; case "Pattern": GenerateToPythonDTO generateToPythonDTO = new GenerateToPythonDTO(generateThroughImageTextDTO.getUniqueId(), text, Objects.isNull(collectionElement) ? "" : collectionElement.getUrl(), - mode, category, generateThroughImageTextDTO.getGender()); + mode, category, generateThroughImageTextDTO.getGender(), version); jsonString = JSON.toJSONString(generateToPythonDTO, SerializerFeature.WriteMapNullValue); } } else { GenerateToPythonDTO generateToPythonDTO = new GenerateToPythonDTO(generateThroughImageTextDTO.getUniqueId(), text, Objects.isNull(collectionElement) ? "" : collectionElement.getUrl(), - mode, category, generateThroughImageTextDTO.getGender()); + mode, category, generateThroughImageTextDTO.getGender(), version); jsonString = JSON.toJSONString(generateToPythonDTO, SerializerFeature.WriteMapNullValue); } + Boolean requestResult = pythonService.generateSketchOrPrint(jsonString, port, path); // 4、将请求信息落库,将本次generate的请求信息添加到t_generate表中 @@ -325,7 +334,8 @@ public class GenerateServiceImpl extends ServiceImpl i // generate.setText(text); break; case "Sketchboard": - text = "clear lines, simple outlines monochrome white vector image of " + translated + ", no background, sketch flat, front view display, best quality, ultra-high resolution 8k"; +// text = "clear lines, simple outlines monochrome white vector image of " + translated + ", no background, sketch flat, front view display, best quality, ultra-high resolution 8k"; + text = "a single item of sketch of " + translated + ", 4k, white background"; // generate.setText(text); default: } @@ -498,6 +508,13 @@ public class GenerateServiceImpl extends ServiceImpl i // 校验后获取 generateThroughImageTextDTO.setGenerateType(generate.getGenerateType()); creditsEventsEnum = CreditsEventsEnum.PATTERN; + + // 模型迁移SD1.? -> flux,从而产生了不同模型的选择, + // high -> 生成图片质量高,但生成速度慢,每次生成只返回一张图片 + // fast -> 生成图片质量低,但生成速度快,每次生成返回四张图片 + if (!StringUtil.isNullOrEmpty(generateThroughImageTextDTO.getVersion()) && generateThroughImageTextDTO.getVersion().equals("high")){ + times = 1; + } } // Slogan 参数校验 if (generateThroughImageTextDTO.getLevel2Type().equals(CollectionLevel2TypeEnum.SLOGAN.getRealName())) { @@ -554,8 +571,14 @@ public class GenerateServiceImpl extends ServiceImpl i } } else if (generateThroughImageTextDTO.getLevel1Type().equals(MOOD_BOARD.getRealName())) { creditsEventsEnum = CreditsEventsEnum.MOOD_BOARD; + if (!StringUtil.isNullOrEmpty(generateThroughImageTextDTO.getVersion()) && generateThroughImageTextDTO.getVersion().equals("high")){ + times = 1; + } } else if (generateThroughImageTextDTO.getLevel1Type().equals(SKETCH_BOARD.getRealName())) { creditsEventsEnum = CreditsEventsEnum.SKETCH_BOARD; + if (!StringUtil.isNullOrEmpty(generateThroughImageTextDTO.getVersion()) && generateThroughImageTextDTO.getVersion().equals("high")){ + times = 1; + } } // 2、判断用户当前积分是否够本次生成消耗 @@ -567,6 +590,11 @@ public class GenerateServiceImpl extends ServiceImpl i // 3、生成唯一id 使用uuid,由于uuid重复的几率很小,故取消对uuid重复性的校验 String uuid = UUID.randomUUID().toString(); + // 除了 Moodboard || Printboard->Pattern(可以区分三种风格) || Sketchboard(Generate Sketch)这三个地方需要区分high || fast之外,其他地方保持原样 + if (generateThroughImageTextDTO.getLevel1Type().equals("Printboard") && !generateThroughImageTextDTO.getLevel2Type().equals("Pattern")){ + generateThroughImageTextDTO.setVersion(null); + } + ArrayList taskIdList = new ArrayList<>(); for (int i = 1; i <= times; i++) { String temp = uuid; diff --git a/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java b/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java index 2c51cfa6..eb9fefb0 100644 --- a/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/UserLikeGroupServiceImpl.java @@ -9,14 +9,18 @@ import com.ai.da.common.utils.*; import com.ai.da.mapper.primary.*; import com.ai.da.mapper.primary.entity.*; import com.ai.da.mapper.secondary.AttributeRetrievalMapper; +import com.ai.da.mapper.secondary.entity.AttributeRecognitionJSON; import com.ai.da.model.dto.PortfolioDTO; +import com.ai.da.model.dto.ProductImageInitializeDTO; import com.ai.da.model.dto.ProductImageLikeDTO; import com.ai.da.model.dto.ToProductImageDTO; import com.ai.da.model.vo.*; import com.ai.da.python.PythonService; import com.ai.da.service.*; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -30,13 +34,14 @@ import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.io.*; +import java.nio.file.Paths; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; +import static cn.hutool.poi.excel.sax.AttributeName.s; + /** * 服务实现类 * @@ -79,6 +84,8 @@ public class UserLikeGroupServiceImpl extends ServiceImpl designItemDetailQueryWrapper = new QueryWrapper<>(); + designItemDetailQueryWrapper.lambda().eq(DesignItemDetail::getDesignItemId, designItemId); + designItemDetailQueryWrapper.lambda().ne(DesignItemDetail::getType, "Body"); + List designItemDetails = designItemDetailMapper.selectList(designItemDetailQueryWrapper); + String collect = designItemDetails.stream().map(DesignItemDetail::getType).collect(Collectors.joining(",")); + Long designId = tDesignPythonOutfit.getDesignId(); Design design = designMapper.selectById(designId); String productType = "overall"; if (design.getSingleOverall().equals("single")) { productType = "single"; + sb.append(collect); + }else { + if (collect.contains("Tops")) { + sb.append("a handsome man,"); + }else { + sb.append("a beautiful women,"); + } + sb.append("wearing ").append(collect); + } + if (StringUtils.isEmpty(prompt)) { + sb.append(",8K realistic,HDR"); + }else { + sb.append(",").append(prompt).append(",8K realistic,HDR"); } // 走模型 - pythonService.toProductImage(tDesignPythonOutfit.getDesignUrl(), taskId, s, toProductImageDTO.getImageStrength(), productType); + pythonService.toProductImage(tDesignPythonOutfit.getDesignUrl(), taskId, sb.toString(), toProductImageDTO.getImageStrength(), productType); ToProductImageResult toProductImageResult = new ToProductImageResult(); toProductImageResult.setElementId(tDesignPythonOutfit.getId()); toProductImageResult.setElementType("DesignOutfit"); @@ -290,10 +319,16 @@ public class UserLikeGroupServiceImpl extends ServiceImpl qw = new QueryWrapper<>(); List userLikeGroups = userLikeGroupMapper.selectList(qw); - Map>>> result = new HashMap<>(); + List>> result = new ArrayList<>(); + for (UserLikeGroup userLikeGroup : userLikeGroups) { Long accountId = userLikeGroup.getAccountId(); Long collectionId = userLikeGroup.getCollectionId(); - QueryWrapper collectionElementQueryWrapper = new QueryWrapper<>(); - collectionElementQueryWrapper.lambda().eq(CollectionElement::getCollectionId, collectionId); - collectionElementQueryWrapper.lambda().eq(CollectionElement::getLevel1Type, "Sketchboard"); - List collectionElements = collectionElementMapper.selectList(collectionElementQueryWrapper); - List urlList = collectionElements.stream().map(CollectionElement::getUrl).collect(Collectors.toList()); + // 提前转换为Set以提高contains的效率 + List collectionElements = getCollectionElementsByCollectionId(collectionId); + Set urlSet = collectionElements.stream() + .map(CollectionElement::getUrl) + .collect(Collectors.toSet()); - QueryWrapper userLikeQueryWrapper = new QueryWrapper<>(); - userLikeQueryWrapper.lambda().eq(UserLike::getUserLikeGroupId, userLikeGroup.getId()); - List userLikes = userLikeMapper.selectList(userLikeQueryWrapper); - - List> list = new ArrayList<>(); + List userLikes = getUserLikesByGroupId(userLikeGroup.getId()); for (UserLike userLike : userLikes) { - QueryWrapper designItemDetailQueryWrapper = new QueryWrapper<>(); - designItemDetailQueryWrapper.lambda().eq(DesignItemDetail::getDesignItemId, userLike.getDesignItemId()); - designItemDetailQueryWrapper.lambda().ne(DesignItemDetail::getType, "Body"); - List designItemDetails = designItemDetailMapper.selectList(designItemDetailQueryWrapper); - Map sketch = new HashMap<>(); + List> userLikeSketchList = new ArrayList<>(); + List designItemDetails = getDesignItemDetails(userLike.getDesignItemId()); + for (DesignItemDetail designItemDetail : designItemDetails) { + Map sketch = new HashMap<>(); String path = designItemDetail.getPath(); + + // 下载路径到本地 +// if (!StringUtils.isEmpty(path)) { +// String bucketName = minioUtil.getBucketNameFromPath(path); +// String objectName = minioUtil.getObjectNameFromPath(path); +// String localBasePath = "C:\\workspace\\fileData\\minio"; +// String localFilePath = Paths.get(localBasePath, path).toString(); +// +// // 检查文件是否已经存在,避免重复下载 +// File localFile = new File(localFilePath); +// if (!localFile.exists()) { +// minioUtil.downloadMinioObjectToLocal(bucketName, objectName, localFilePath); +// } else { +// log.info("File already exists, skipping download: {}", localFilePath); +// } +// } + + Long designId = designItemDetail.getDesignId(); + Design design = designMapper.selectById(designId); + if (null == design) { + continue; + } + if (design.getSingleOverall().equals("single")) { + continue; + } + if (design.getModelType().equals("System")) { + SysFile sysFile = sysFileMapper.selectById(design.getTemplateId()); + if (null == sysFile) { + continue; + } + sketch.put("sex", sysFile.getLevel2Type().equals("Male") ? "Male" : "Female"); + } else { + Library library = libraryMapper.selectById(design.getTemplateId()); + if (null == library) { + continue; + } + sketch.put("sex", library.getLevel2Type().equals("Female") ? "Female" : "Male"); + } + sketch.put("type", designItemDetail.getType()); sketch.put("path", path); - if (urlList.contains(path)) { - sketch.put("beSelected", true); - }else { - sketch.put("beSelected", false); - } + sketch.put("beSelected", urlSet.contains(path)); + sketch.put("accountId", accountId); + if (path.contains("aida-sys-image/images/")) { - String searchPath = new String(path); - String replace = searchPath.replace("aida-sys-image/images/", ""); + String replace = path.replace("aida-sys-image/images/", ""); String style = getStyleByUrl(replace); if (!StringUtils.isEmpty(style)) { sketch.put("style", style); } } + userLikeSketchList.add(sketch); + } + if (CollectionUtil.isNotEmpty(userLikeSketchList)) { + result.add(userLikeSketchList); } - list.add(sketch); - } - if (result.containsKey(accountId)) { - result.get(accountId).add(list); - }else { - List>> lists = new ArrayList<>(); - lists.add(list); - result.put(accountId, lists); } } - System.out.println(JSONObject.toJSONString(result)); + + // 将结果以美观的JSON形式保存到文件中 + saveResultAsPrettyJson(result, "C:\\Users\\10233\\Desktop\\result.json"); + return null; } + @Override + public String download() { + // 下载 aida-collection-element bucket 下所有 Sketchboard 文件夹内容 +// String sketchboardLocalPath = "C:\\workspace\\fileData\\minio"; +// minioUtil.downloadSketchboardDirectories(sketchboardLocalPath); +// +// // 下载整个 aida-users bucket +// String aidaUsersLocalPath = "C:\\workspace\\fileData\\minio"; +// minioUtil.downloadEntireBucket("aida-users", aidaUsersLocalPath); + return null; + } + + // 提取公共方法 + private List getCollectionElementsByCollectionId(Long collectionId) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(CollectionElement::getCollectionId, collectionId) + .eq(CollectionElement::getLevel1Type, "Sketchboard"); + return collectionElementMapper.selectList(qw); + } + + private List getUserLikesByGroupId(Long groupId) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(UserLike::getUserLikeGroupId, groupId); + return userLikeMapper.selectList(qw); + } + + private List getDesignItemDetails(Long designItemId) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(DesignItemDetail::getDesignItemId, designItemId) + .ne(DesignItemDetail::getType, "Body"); + return designItemDetailMapper.selectList(qw); + } + + private void saveResultAsPrettyJson(List>> result, String filePath) { + // 使用一个 Map 将结果存储为字符串键 + Map resultMap = new HashMap<>(); + resultMap.put("data", result); + + try (FileWriter file = new FileWriter(filePath)) { + // 使用 JSONObject 将转换后的 Map 转为 JSON + JSONObject jsonObject = new JSONObject(resultMap); + // 格式化输出为美观的 JSON + file.write(JSON.toJSONString(jsonObject, SerializerFeature.PrettyFormat)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + + private String getStyleByUrl(String replace) { String[] split = replace.split("/"); String tableName = getTableName(split); if (StringUtils.isEmpty(tableName)) { return null; }else { + replace = split[1] + "/" + split[2]; return attributeRetrievalMapper.getStyleByUrl(replace, tableName); } } @@ -721,4 +839,53 @@ public class UserLikeGroupServiceImpl extends ServiceImpl