diff --git a/src/main/java/com/ai/da/common/RabbitMQ/GenerateConsumer.java b/src/main/java/com/ai/da/common/RabbitMQ/GenerateConsumer.java index 7ba3f36b..0c5ea013 100644 --- a/src/main/java/com/ai/da/common/RabbitMQ/GenerateConsumer.java +++ b/src/main/java/com/ai/da/common/RabbitMQ/GenerateConsumer.java @@ -67,27 +67,14 @@ public class GenerateConsumer { } catch (IOException ex) { log.error("手动确认,不返回队列重新消费"); } - // 2.2 将该消息从取消列表中删除 -// redisUtil.removeFromSet(cancelSetKey, uniqueId); } else { -// GenerateCollectionVO generateCollectionVO = generateService.generateThroughImageText(generateThroughImageTextDTO); - try { - generateService.generateThroughImageText(generateThroughImageTextDTO); - }catch (Exception e){ - log.error("error message : {}", e.getMessage()); - } + generateService.generateThroughImageText(generateThroughImageTextDTO); // 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除 redisUtil.removeFromZSet(consumptionOrderKey, uniqueId); - /*if (!Objects.isNull(generateCollectionVO)) { - HashMap generateResult = new HashMap<>(); - generateResult.put(uniqueId, JSONObject.toJSONString(generateCollectionVO)); - // 将结果存在redis中 ,为空时不要存 - redisUtil.addToMap(resultMapKey, generateResult); - }*/ } - } catch (BusinessException e) { - log.error(e.getMsg()); + } catch (Exception e) { + log.error(e.getMessage()); // channel.basicNack() 为不确认deliveryTag对应的消息,第二个参数是否应用于多消息,第三个参数是否requeue try { // 第二个参数,是否批量确认消息,当传false时,只确认当前 deliveryTag对应的消息;当传true时,会确认当前及之前所有未确认的消息。 @@ -102,7 +89,7 @@ public class GenerateConsumer { } // 将入参和错误信息存入数据库 String exceptionMessage = JSONObject.toJSONString(generateThroughImageTextDTO) + - " Exception message : " + e.getMsg(); + " Exception message : " + e.getMessage(); HashMap exceptionInfo = new HashMap<>(); exceptionInfo.put(String.valueOf(uniqueId), exceptionMessage); // 存redis diff --git a/src/main/java/com/ai/da/common/constant/CommonConstant.java b/src/main/java/com/ai/da/common/constant/CommonConstant.java index eb325fe6..09496110 100644 --- a/src/main/java/com/ai/da/common/constant/CommonConstant.java +++ b/src/main/java/com/ai/da/common/constant/CommonConstant.java @@ -23,6 +23,10 @@ public class CommonConstant { public static final String GENERATE_SLOGAN = "/api/slogan"; + public static final String GENERATE_CANCEL = "/api/generate_cancel/"; + + public static final String GENERATE_LOGO_SINGLE_CANCEL = "/api/generate_single_logo_cancel/"; + public static final String PYTHON_PORT_9996 = "9996"; public static final String PYTHON_PORT_9997 = "9997"; diff --git a/src/main/java/com/ai/da/common/enums/CreditsEventsEnum.java b/src/main/java/com/ai/da/common/enums/CreditsEventsEnum.java index 0b00fa84..7978920c 100644 --- a/src/main/java/com/ai/da/common/enums/CreditsEventsEnum.java +++ b/src/main/java/com/ai/da/common/enums/CreditsEventsEnum.java @@ -7,22 +7,29 @@ import lombok.Getter; @Getter public enum CreditsEventsEnum { -// PRICE("price","6"), - PRICE("price","0.1"), + PRICE("price","6"), +// PRICE("price","0.1"), -// BUY_CREDITS("Buy Credits","600"), - BUY_CREDITS("Buy Credits","10"), + BUY_CREDITS("Buy Credits","60"), +// BUY_CREDITS("Buy Credits","10"), - INIT("init", "500"), + // 每月更新 + INIT_YEARLY("init_yearly", "6000"), + INIT_MONTHLY("init_monthly", "5000"), + INIT_TRIAL("init_trial", "100"), + INIT_WEEKLY("init_weekly","10000"), - DAILY_CHECKIN("Daily Check-In", "20"), +// SUPER_RESOLUTION("Super Resolution","30"), + SUPER_RESOLUTION("Super Resolution","10"), + SLOGAN("Slogan","10"), + LOGO("Logo","5"), + PATTERN("Pattern","5"), + MOOD_BOARD("MoodBoard","5"), + SKETCH_BOARD("SketchBoard","5"), + TO_PRODUCT_IMAGE("ToProductImage","5"), + QUESTIONNAIRE("Questionnaire","100"), - SOCIAL_MEDIA_SHARING("Social Media Sharing","20"), - -// SUPER_RESOLUTION("Super Resolution","300"), - SUPER_RESOLUTION("Super Resolution","5"), - - OTHER("Other","10"); + OTHER("Other","5"); private String name; 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 4060b9a4..0d1bed1a 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 @@ -50,7 +50,7 @@ public class AuthenticationFilter extends OncePerRequestFilter { "/api/third/party/existNoLoginRequired","/api/third/party/getRedirectUrl", "/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/designWorksRegister","/api/account/questionnaire" ); @Override diff --git a/src/main/java/com/ai/da/common/task/AccountTask.java b/src/main/java/com/ai/da/common/task/AccountTask.java new file mode 100644 index 00000000..fa866e9d --- /dev/null +++ b/src/main/java/com/ai/da/common/task/AccountTask.java @@ -0,0 +1,26 @@ +package com.ai.da.common.task; + +import com.ai.da.service.AccountService; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +@Component +public class AccountTask { + + @Resource + private AccountService accountService; + + /** 每周日晚上刷新 年付用户、月付用户的积分 */ +// @Scheduled(cron = "59 59 23 ? * SUN") + public void refreshCreditsMonthly(){ + accountService.refreshCreditsWeekly(); + } + + // todo 多久执行一次? + public void getPaidUser(){ + // 获取code-create 表中 指定日期之后 订单状态为wc-processing的订单 + accountService.extendValidityForCC(); + } +} 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 1e7b4a1d..2b8a832b 100644 --- a/src/main/java/com/ai/da/common/utils/SendEmailUtil.java +++ b/src/main/java/com/ai/da/common/utils/SendEmailUtil.java @@ -450,6 +450,106 @@ public class SendEmailUtil { } } + private final static Long QUESTIONNAIRE_FEEDBACK_EN_ID = 124151L; + private final static Long QUESTIONNAIRE_FEEDBACK_CN_ID = 124156L; + public static void questionnaireRelatedNotify(String userName, String email, String language){ + 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(); + req.setFromEmailAddress(CODE_CREATE_SEND_ADDRESS); + req.setDestination(new String[]{email}); + + // 根据邮件类型设置不同的主题和模板 + Template template = new Template(); + String subject = "Thank You for Completing the AiDA System Survey"; + template.setTemplateID(QUESTIONNAIRE_FEEDBACK_EN_ID); + if (language.equals("CN")) { + subject = "感谢您完成AiDA系统问卷调查"; + template.setTemplateID(QUESTIONNAIRE_FEEDBACK_CN_ID); + } + + JSONObject parameter = new JSONObject(); + parameter.put("userName", userName); + + template.setTemplateData(parameter.toJSONString()); + + 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 NEW_USER_PAYMENT_NOTIFICATION_EN = 0L; + private final static Long NEW_USER_PAYMENT_NOTIFICATION_CN = 0L; + private final static Long RENEWAL_NOTIFICATION_FOR_OLD_USER_EN = 0L; + private final static Long RENEWAL_NOTIFICATION_FOR_OLD_USER_CN = 0L; + + public static void notificationForPaidUser(String receiverAddress, int emailType, String country){ + 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(); + req.setFromEmailAddress(SEND_ADDRESS); + req.setDestination(new String[]{receiverAddress}); + + // 根据邮件类型设置不同的主题和模板 + String subject = ""; + Template template = new Template(); + switch (emailType) { + // 新用户 + case 1: + subject = "Welcome to AiDA!"; + if (country.equals("China")) { + template.setTemplateID(NEW_USER_PAYMENT_NOTIFICATION_CN); + }else { + template.setTemplateID(NEW_USER_PAYMENT_NOTIFICATION_EN); + } + break; + // 续费用户 + case 2: + subject = "Account renewal notification"; + if (country.equals("China")) { + template.setTemplateID(RENEWAL_NOTIFICATION_FOR_OLD_USER_CN); + }else { + template.setTemplateID(RENEWAL_NOTIFICATION_FOR_OLD_USER_EN); + } + break; + default: + break; + +// template.setTemplateData(buildNotificationData(trialOrder, link)); + } + + 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"); + } + } + public static Boolean designWorksRegister(String userEmail, String randomVerifyCode) { try { diff --git a/src/main/java/com/ai/da/controller/AccountController.java b/src/main/java/com/ai/da/controller/AccountController.java index 48769e5c..4b9087e3 100644 --- a/src/main/java/com/ai/da/controller/AccountController.java +++ b/src/main/java/com/ai/da/controller/AccountController.java @@ -167,4 +167,14 @@ public class AccountController { public Response designWorksRegisterCode(@Valid @RequestBody AccountDesignWorksRegisterDTO accountDesignWorksRegisterDTO) { return Response.success(accountService.designWorksRegisterCode(accountDesignWorksRegisterDTO)); } + + /** + * 填写调查问卷 + * @return + */ + @ApiOperation(value = "填写调查问卷") + @PostMapping("/questionnaire") + public Response questionnaire(@Valid @RequestBody String questionnaireInfo){ + return Response.success(accountService.collectQuestionnaires(questionnaireInfo)); + } } diff --git a/src/main/java/com/ai/da/controller/GenerateController.java b/src/main/java/com/ai/da/controller/GenerateController.java index 74743856..caa80dcc 100644 --- a/src/main/java/com/ai/da/controller/GenerateController.java +++ b/src/main/java/com/ai/da/controller/GenerateController.java @@ -63,8 +63,9 @@ public class GenerateController { @GetMapping("/stopWaiting") public Response stopWaiting(@RequestParam("userId") Long userId, @RequestParam("uniqueId") List uniqueId, - @RequestParam("timeZone") String timeZone) { - generateService.cancelGenerate(userId, uniqueId, timeZone); + @RequestParam("timeZone") String timeZone, + @RequestParam("type") String type) { + generateService.cancelGenerate(userId, uniqueId, timeZone, type); return Response.success("stop waiting successfully"); } diff --git a/src/main/java/com/ai/da/controller/ThirdPartyController.java b/src/main/java/com/ai/da/controller/ThirdPartyController.java index 7132d9b2..1f4f64c3 100644 --- a/src/main/java/com/ai/da/controller/ThirdPartyController.java +++ b/src/main/java/com/ai/da/controller/ThirdPartyController.java @@ -27,11 +27,11 @@ public class ThirdPartyController { @Resource private AccountService accountService; - @ApiOperation(value = "Add user information") + /*@ApiOperation(value = "Add user information") @PostMapping("/addUser") public Response addUser(@Valid @RequestBody AccountAddDTO accountAddDTO) { return Response.success(accountService.addUser(accountAddDTO)); - } + }*/ @ApiOperation(value = "Edit user information") @PostMapping("/editUser") diff --git a/src/main/java/com/ai/da/mapper/primary/QuestionnaireMapper.java b/src/main/java/com/ai/da/mapper/primary/QuestionnaireMapper.java new file mode 100644 index 00000000..844b3bd4 --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/QuestionnaireMapper.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.Questionnaire; + +public interface QuestionnaireMapper 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 025f49ef..f9f37fd9 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 @@ -87,5 +87,12 @@ public class Account implements Serializable { */ private BigDecimal credits; - private Integer SystemUser; + /** + * 用于区分游客与系统用户 + * 0 : 游客 + * 1 : 年付用户 + * 2 : 月付用户 + * 3 : 试用用户 + */ + private Integer systemUser; } diff --git a/src/main/java/com/ai/da/mapper/primary/entity/CreditsDetail.java b/src/main/java/com/ai/da/mapper/primary/entity/CreditsDetail.java index 1422ba4c..8a0aa02a 100644 --- a/src/main/java/com/ai/da/mapper/primary/entity/CreditsDetail.java +++ b/src/main/java/com/ai/da/mapper/primary/entity/CreditsDetail.java @@ -12,6 +12,8 @@ import java.math.BigDecimal; public class CreditsDetail extends BaseEntity { /** 用户id */ private Long accountId; + /** 任务id或uuid */ + private String taskId; /** 积分变更事件 */ private String changeEvent; /** 变更积分 ( + 表示加,- 表示减) */ diff --git a/src/main/java/com/ai/da/mapper/primary/entity/Questionnaire.java b/src/main/java/com/ai/da/mapper/primary/entity/Questionnaire.java new file mode 100644 index 00000000..d6daff5b --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/entity/Questionnaire.java @@ -0,0 +1,18 @@ +package com.ai.da.mapper.primary.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("t_questionnaire") +public class Questionnaire extends BaseEntity{ + + /** + * 用户所填调查问卷结果 + */ + private String questionnaireInfo; + /** + * 调查问卷标题 + */ + private String title; +} diff --git a/src/main/java/com/ai/da/model/dto/AccountAddDTO.java b/src/main/java/com/ai/da/model/dto/AccountAddDTO.java index 22de2a4f..5f054973 100644 --- a/src/main/java/com/ai/da/model/dto/AccountAddDTO.java +++ b/src/main/java/com/ai/da/model/dto/AccountAddDTO.java @@ -2,23 +2,27 @@ package com.ai.da.model.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; import lombok.Data; import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import java.math.BigDecimal; @Data @ApiModel("AccountAdd") +@AllArgsConstructor public class AccountAddDTO { @NotBlank(message = "email.cannot.be.empty") - @ApiModelProperty("email") - private String email; + @ApiModelProperty("userEmail") + private String userEmail; @NotBlank(message = "userName.cannot.be.empty") @ApiModelProperty("userName") private String userName; + private String country; + @NotBlank(message = "validStartTime.cannot.be.empty") @ApiModelProperty("Start time of account validity ") private String validStartTime; @@ -29,4 +33,8 @@ public class AccountAddDTO { private Integer isTrial; + private BigDecimal credits; + + private Integer systemUser; + } diff --git a/src/main/java/com/ai/da/model/dto/GenerateThroughImageTextDTO.java b/src/main/java/com/ai/da/model/dto/GenerateThroughImageTextDTO.java index 398fa9ec..6320dd5d 100644 --- a/src/main/java/com/ai/da/model/dto/GenerateThroughImageTextDTO.java +++ b/src/main/java/com/ai/da/model/dto/GenerateThroughImageTextDTO.java @@ -55,6 +55,6 @@ public class GenerateThroughImageTextDTO { @ApiModelProperty("页面上用户设计的slogan所截的图片") String sloganBase64; - @ApiModelProperty("种子 取值范围 0~99999") + @ApiModelProperty("种子 取值范围 0~500") String seed; } diff --git a/src/main/java/com/ai/da/model/vo/QuestionnaireVO.java b/src/main/java/com/ai/da/model/vo/QuestionnaireVO.java new file mode 100644 index 00000000..c1aeff6a --- /dev/null +++ b/src/main/java/com/ai/da/model/vo/QuestionnaireVO.java @@ -0,0 +1,57 @@ +package com.ai.da.model.vo; + +import lombok.Data; +import java.util.List; + +@Data +public class QuestionnaireVO { + /** + * 用户名 + */ + private String userName; + /** + * 用户性别 + */ + private String gender; + /** + * 职业 + */ + private String occupation; + /** + * 国家 + */ + private String country; + /** + * 电子邮件 + */ + private String email; + /** + * 年龄区间 + */ + private String age; + /** + * How has AiDA been helpful to you? + */ + private List helpful; + /** + * What do you think AiDA should improve? + */ + private List improve; + /** + * Will you subscribe to AiDA 3.0 + */ + private String isSubscribe; + /** + * If NO, please share why: + */ + private List reasonForNotSubscribe; + /** + * Are you currently using any design tools? + */ + private String designTools; + /** + * 用户所选语言 + */ + private String language; + +} diff --git a/src/main/java/com/ai/da/python/PythonService.java b/src/main/java/com/ai/da/python/PythonService.java index 11210996..da8def64 100644 --- a/src/main/java/com/ai/da/python/PythonService.java +++ b/src/main/java/com/ai/da/python/PythonService.java @@ -3175,15 +3175,15 @@ public class PythonService { throw new BusinessException("cloth-classification.interface.exception"); } - public Boolean cancelGenerateTask(String taskId) { + public Boolean cancelGenerateTask(String taskId, String path) { OkHttpClient client = new OkHttpClient().newBuilder() .connectTimeout(30, TimeUnit.SECONDS) .pingInterval(5, TimeUnit.SECONDS)//websocket轮训间隔(单位:秒) .readTimeout(60, TimeUnit.SECONDS)//读取超时(单位:秒) .writeTimeout(60, TimeUnit.SECONDS)//写入超时(单位:秒) .build(); -// String url = accessPythonIp + ":" + accessPythonPort + "/api/generate_cancel/" + taskId; - String url = fastApiPythonAddress + "/api/generate_cancel/" + taskId; + String url = accessPythonIp + ":" + accessPythonPort + path + taskId; +// String url = fastApiPythonAddress + "/api/generate_cancel/" + taskId; Request request = new Request.Builder() .url(url) // .addHeader("Authorization", "Basic YWlkbGFiOjEyMw==") @@ -3194,14 +3194,14 @@ public class PythonService { log.info("cancelGenerateTask请求入参content###{}", taskId); response = client.newCall(request).execute(); } catch (IOException ioException) { - log.error("PythonService##cancelGenerateTask异常###{}", ExceptionUtil.getThrowableList(ioException)); + log.error("PythonService##cancelGenerateTask异常###{}", response); return null; } int responseCode = response.code(); response.close(); if (responseCode != HttpURLConnection.HTTP_OK) { - log.info("generate-python 取消请求失败"); + log.info("generate-python 取消请求失败. {}", response); return Boolean.FALSE; } log.info("generate-python 取消请求成功"); diff --git a/src/main/java/com/ai/da/service/AccountService.java b/src/main/java/com/ai/da/service/AccountService.java index 496275ce..193ccff7 100644 --- a/src/main/java/com/ai/da/service/AccountService.java +++ b/src/main/java/com/ai/da/service/AccountService.java @@ -134,4 +134,10 @@ public interface AccountService extends IService { Boolean designWorksRegister(AccountDesignWorksRegisterDTO accountDesignWorksRegisterDTO); AccountLoginVO designWorksRegisterCode(AccountDesignWorksRegisterDTO accountDesignWorksRegisterDTO); + + Boolean extendValidityForCC(); + + Boolean collectQuestionnaires(String questionnaireInfo); + + void refreshCreditsWeekly(); } diff --git a/src/main/java/com/ai/da/service/CreditsService.java b/src/main/java/com/ai/da/service/CreditsService.java index e6179e22..faf19ce7 100644 --- a/src/main/java/com/ai/da/service/CreditsService.java +++ b/src/main/java/com/ai/da/service/CreditsService.java @@ -9,8 +9,6 @@ import com.baomidou.mybatisplus.extension.service.IService; public interface CreditsService extends IService { - void initCredits(); - Boolean buyCredits(Long accountId, Float quantity); void creditsIncrease(Long accountId, String event); @@ -29,5 +27,13 @@ public interface CreditsService extends IService { Boolean creditsPreDeduction(CreditsEventsEnum event, Integer num); - void taskCreditsDeduction(Long accountId, String taskId); + void addRecordToCreditsDeduction(Long accountId, String taskId, CreditsEventsEnum creditsEventsEnum); + + Boolean taskCreditsDeduction(Long accountId, String taskId); + + CreditsDetail getByAccountIdAndChangeEvent(Long accountId, String changeEvent, String changedCredits); + + void preInsert(Long accountId, String changeEventName, String taskId); + + void updateChangedCredits(String accountId, String taskId); } diff --git a/src/main/java/com/ai/da/service/GenerateService.java b/src/main/java/com/ai/da/service/GenerateService.java index 81b772db..7dca1588 100644 --- a/src/main/java/com/ai/da/service/GenerateService.java +++ b/src/main/java/com/ai/da/service/GenerateService.java @@ -35,7 +35,7 @@ public interface GenerateService extends IService { Long getRankPosition(String uniqueId); - void cancelGenerate(Long userId, List uniqueId, String timeZone); + void cancelGenerate(Long userId, List uniqueId, String timeZone, String type); void processRelightResult(String taskId, String url, String category); } 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 6a6fb2f0..ed70f616 100644 --- a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java @@ -3,31 +3,33 @@ package com.ai.da.service.impl; import cn.hutool.core.collection.CollectionUtil; import com.ai.da.common.config.exception.BusinessException; import com.ai.da.common.context.UserContext; -import com.ai.da.common.enums.LoginTypeEnum; 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.ResultEnum; import com.ai.da.common.security.jwt.JWTTokenHelper; import com.ai.da.common.utils.*; import com.ai.da.mapper.primary.AccountMapper; +import com.ai.da.mapper.primary.QuestionnaireMapper; import com.ai.da.mapper.primary.TrialOrderMapper; -import com.ai.da.mapper.primary.entity.Account; -import com.ai.da.mapper.primary.entity.AccountLoginLog; -import com.ai.da.mapper.primary.entity.TrialOrder; +import com.ai.da.mapper.primary.entity.*; import com.ai.da.model.dto.*; import com.ai.da.model.enums.AutoApproved; import com.ai.da.model.enums.Language; import com.ai.da.model.vo.AccountLoginVO; import com.ai.da.model.vo.AccountPreLoginVO; import com.ai.da.model.vo.AuthPrincipalVo; -import com.ai.da.service.AccountLoginLogService; -import com.ai.da.service.AccountService; -import com.ai.da.service.LibraryService; -import com.ai.da.service.UserLikeGroupService; +import com.ai.da.model.vo.QuestionnaireVO; +import com.ai.da.service.*; import com.alibaba.fastjson.JSON; 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.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import io.netty.util.internal.StringUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; @@ -36,9 +38,16 @@ import org.springframework.util.Assert; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; +import javax.sql.DataSource; import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.time.Instant; import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.Date; import java.util.List; @@ -72,6 +81,11 @@ public class AccountServiceImpl extends ServiceImpl impl @Resource private TrialOrderMapper trialOrderMapper; + @Resource + private QuestionnaireMapper questionnaireMapper; + + @Resource + private CreditsService creditsService; @Override @Transactional(rollbackFor = Exception.class) @@ -264,7 +278,7 @@ public class AccountServiceImpl extends ServiceImpl impl if (!verifyCode.equals(accountDTO.getEmailVerifyCode())) { throw new BusinessException("verification.code.error", ResultEnum.PROMPT.getCode()); } - }else { + } else { updatePwdByEmail(accountDTO.getPassword(), accountDTO.getEmail()); } return Boolean.TRUE; @@ -371,15 +385,18 @@ public class AccountServiceImpl extends ServiceImpl impl @Override public Boolean addUser(AccountAddDTO accountAddDTO) { - Account account = new Account(); - account.setUserEmail(accountAddDTO.getEmail()); - account.setUserPassword("Third-000000"); - account.setUserName(accountAddDTO.getUserName()); + Account account; + account = CopyUtil.copyObject(accountAddDTO,Account.class); +// account.setUserEmail(accountAddDTO.getUserEmail()); +// account.setUserName(accountAddDTO.getUserName()); +// account.setIsTrial(accountAddDTO.getIsTrial()); account.setValidStartTime(Long.valueOf(accountAddDTO.getValidStartTime())); account.setValidEndTime(Long.valueOf(accountAddDTO.getValidEndTime())); + account.setUserPassword("Third-000000"); + account.setLanguage(Language.ENGLISH.name()); account.setCreateDate(new Date()); - account.setIsTrial(accountAddDTO.getIsTrial()); - account.setSystemUser(1); + account.setIsTrial(0); + account.setIsBeginner(1); return accountMapper.insert(account) > 0; } @@ -493,7 +510,7 @@ public class AccountServiceImpl extends ServiceImpl impl if (CollectionUtil.isNotEmpty(accountList)) { if (accountList.get(0).getIsTrial() == 1) { throw new BusinessException("The email has already been registered", ResultEnum.PROMPT.getCode()); - }else { + } else { Account account = accountList.get(0); if (null == account.getValidEndTime() || account.getValidEndTime() > System.currentTimeMillis()) { throw new BusinessException("The email has already been registered", ResultEnum.PROMPT.getCode()); @@ -523,11 +540,11 @@ public class AccountServiceImpl extends ServiceImpl impl account.setValidStartTime(System.currentTimeMillis()); if (link) { account.setValidEndTime(Instant.now().plus(14, ChronoUnit.DAYS).toEpochMilli()); - }else { + } else { account.setValidEndTime(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli()); } accountMapper.updateById(account); - }else { + } else { account.setUserName(trialOrder.getUserName()); account.setUserPassword("Third-000000"); account.setUserEmail(trialOrder.getEmail()); @@ -535,7 +552,7 @@ public class AccountServiceImpl extends ServiceImpl impl account.setValidStartTime(System.currentTimeMillis()); if (link) { account.setValidEndTime(Instant.now().plus(14, ChronoUnit.DAYS).toEpochMilli()); - }else { + } else { account.setValidEndTime(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli()); } account.setCreateDate(new Date()); @@ -550,7 +567,7 @@ public class AccountServiceImpl extends ServiceImpl impl // SendEmailUtil.sendCustomEmail("kaicpang.pang@connect.polyu.hk", null, trialOrder,2); if (trialOrder.getCountry().equals("China")) { SendEmailUtil.sendCustomEmail(account.getUserEmail(), null, trialOrder, 3, trialOrder.getCountry(), link); - }else { + } else { SendEmailUtil.sendCustomEmail(account.getUserEmail(), null, trialOrder, 3, trialOrder.getCountry(), link); } } @@ -584,7 +601,7 @@ public class AccountServiceImpl extends ServiceImpl impl account.setValidStartTime(System.currentTimeMillis()); account.setValidEndTime(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli()); accountMapper.updateById(account); - }else { + } else { account.setUserName(trialOrder.getUserName()); account.setUserPassword("Third-000000"); account.setUserEmail(trialOrder.getEmail()); @@ -603,7 +620,7 @@ public class AccountServiceImpl extends ServiceImpl impl // SendEmailUtil.sendCustomEmail("kaicpang.pang@connect.polyu.hk", null, trialOrder,2, trialOrder.getCountry()); if (trialOrder.getCountry().equals("China")) { SendEmailUtil.sendCustomEmail(account.getUserEmail(), null, trialOrder, 3, trialOrder.getCountry(), false); - }else { + } else { SendEmailUtil.sendCustomEmail(account.getUserEmail(), null, trialOrder, 3, trialOrder.getCountry(), false); } } @@ -707,7 +724,7 @@ public class AccountServiceImpl extends ServiceImpl impl accountMapper.deleteById(accountDelete); userToBeUpdate.setUserName(userName); accountMapper.updateById(userToBeUpdate); - }else { + } else { accountMapper.deleteById(accountDelete); } } @@ -845,7 +862,7 @@ public class AccountServiceImpl extends ServiceImpl impl "                        \n" + "                        \n" + "                            \n" + "                        "; } @@ -889,7 +906,7 @@ public class AccountServiceImpl extends ServiceImpl impl throw new BusinessException("Illegal serial number."); } queryWrapperDelete.lambda().eq(Account::getUserName, "PolyU-SFT-" + noLoginRequiredDTO.getId()); - }else { + } else { queryWrapperDelete.lambda().like(Account::getBrowserIdentifiers, ipAddress); } List accountList = accountMapper.selectList(queryWrapperDelete); @@ -923,7 +940,7 @@ public class AccountServiceImpl extends ServiceImpl impl // SendEmailUtil.sendUpgradeNotification(account, null, 1); if (account.getLanguage().equals(Language.CHINESE_SIMPLIFIED.name())) { SendEmailUtil.sendUpgradeNotification(account, null, 0); - }else { + } else { // 英文 SendEmailUtil.sendUpgradeNotification(account, null, 1); } @@ -937,7 +954,7 @@ public class AccountServiceImpl extends ServiceImpl impl // 未迁移过的进行迁移,注意模特数据迁移打点信息以及转换模特格式 } - public void updateCredits(Long accountId, String value){ + public void updateCredits(Long accountId, String value) { Account account = new Account(); account.setId(accountId); account.setCredits(new BigDecimal(value)); @@ -954,7 +971,7 @@ public class AccountServiceImpl extends ServiceImpl impl } String randomVerifyCode = RandomsUtil.generateVerifyCode(100000L, 999999L); - LocalCacheUtils.setVerifyCodeCache("DesignWorksRegister"+ "_" + accountDesignWorksRegisterDTO.getUserEmail(), randomVerifyCode); + LocalCacheUtils.setVerifyCodeCache("DesignWorksRegister" + "_" + accountDesignWorksRegisterDTO.getUserEmail(), randomVerifyCode); Boolean b = SendEmailUtil.designWorksRegister(accountDesignWorksRegisterDTO.getUserEmail(), randomVerifyCode); if (!b) { @@ -966,7 +983,7 @@ public class AccountServiceImpl extends ServiceImpl impl @Override public AccountLoginVO designWorksRegisterCode(AccountDesignWorksRegisterDTO accountDesignWorksRegisterDTO) { - String verifyCode = LocalCacheUtils.getVerifyCodeCache("DesignWorksRegister"+ "_" + accountDesignWorksRegisterDTO.getUserEmail()); + String verifyCode = LocalCacheUtils.getVerifyCodeCache("DesignWorksRegister" + "_" + accountDesignWorksRegisterDTO.getUserEmail()); if (StringUtils.isBlank(verifyCode)) { throw new BusinessException("the.verification.code.has.expired", ResultEnum.PROMPT.getCode()); } @@ -996,4 +1013,234 @@ public class AccountServiceImpl extends ServiceImpl impl response.setSystemUser(account.getSystemUser()); return response; } + + private static final String QUERY_ORDER = "SELECT * FROM pmr_wc_order_stats " + + "WHERE status = 'wc-processing' AND date_paid > '2024-06-20 00:00:00'" + + " ORDER BY order_id DESC "; + + private static final String QUERY_CUSTOMER_EMAIL = "SELECT username, email, country FROM pmr_wc_customer_lookup " + + "WHERE customer_id = ? "; + private static final String UPDATE_ORDER_STATUS = "UPDATE pmr_wc_order_stats " + + "SET status = 'wc-complete' , date_completed = ? " + + "WHERE order_id = ?"; + + private static final DataSource dataSource; + + static { + HikariConfig config = new HikariConfig(); + config.setJdbcUrl("jdbc:mysql://code-create.com.hk:3306/db1nfvsgmjp3b8"); + config.setUsername("uafqtz4gsvfrw"); + config.setPassword("aida123456."); + config.addDataSourceProperty("cachePrepStmts", "true"); + config.addDataSourceProperty("prepStmtCacheSize", "250"); + config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); + dataSource = new HikariDataSource(config); + } + + /** + * 为Code-Create的用户延长有效期 + * + * @return null + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean extendValidityForCC() { + try (Connection connection = dataSource.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement(QUERY_ORDER)) { +// preparedStatement.setString(1, "someCondition"); + try (ResultSet queryOrderResultSet = preparedStatement.executeQuery()) { + while (queryOrderResultSet.next()) { + /* 处理结果集 */ + int orderId = queryOrderResultSet.getInt("order_id"); + int customerId = queryOrderResultSet.getInt("customer_id"); + double totalSales = queryOrderResultSet.getDouble("total_sales"); + String email = ""; + String userName = ""; + // 为什么一般没有值 + String country = ""; + // 1、查pmr_wc_customer_lookup表;确认当前订单对应的用户邮箱 + PreparedStatement preparedQueryEmail = connection.prepareStatement(QUERY_CUSTOMER_EMAIL); + preparedQueryEmail.setInt(1, customerId); + try (ResultSet queryEmailResultSet = preparedQueryEmail.executeQuery()) { + if (queryEmailResultSet.next()) { + email = queryEmailResultSet.getString("email"); + userName = queryEmailResultSet.getString("username"); + country = queryEmailResultSet.getString("country"); + } else { + log.error("未知错误。code-create的用户表中没有付费用户的信息"); + throw new BusinessException("user info missing"); + } + } + + // 2、查t_account表中是否有该用户 + // 2.1 没有 新建用户 + Account userInfo = null; + Long validEndTime = null; + // 标志当前用户是不是新用户 + Boolean flag = Boolean.FALSE; + try { + // 不是新用户 直接延长使用期限 + userInfo = getOneByEmail(email); + } catch (BusinessException e) { + // 通过邮箱找不到用户 说明是新用户 => 创建用户 + flag = Boolean.TRUE; + } + if (!Objects.isNull(userInfo) && !Objects.isNull(userInfo.getValidEndTime())) + validEndTime = userInfo.getValidEndTime(); + + // 2、获取当前续费费用能延长多长时间 + Account account = extendValidity(validEndTime, totalSales); + + if (flag) { + // 是新用户 => 新增一条数据 + String credits = "0"; + int systemUserType = 0; + if (totalSales == 5000.0){ + log.info("年付用户,初始积分6000"); + credits = CreditsEventsEnum.INIT_MONTHLY.getValue(); + systemUserType = 1; + }else if (totalSales == 500.0){ + log.info("月付用户,初始积分5000"); + credits = CreditsEventsEnum.INIT_MONTHLY.getValue(); + systemUserType = 2; + }else if (totalSales == 0.0){ + log.info("测试用户,初始积分10"); + credits = "10"; + systemUserType = 3; + } + + Boolean b = addUser(new AccountAddDTO(email, + StringUtil.isNullOrEmpty(userName) ? email.substring(0, email.indexOf("@")) : userName, + country, + account.getValidStartTime().toString(), + account.getValidEndTime().toString(), 0,new BigDecimal(credits),systemUserType)); + if (b) log.info("付费新用户新增成功!"); + } else { + userInfo.setValidEndTime(account.getValidEndTime()); + baseMapper.updateById(account); + log.info("付费用户续订成功"); + } + + // 3、todo 邮件通知 + // 3.1 判断用户语言 + + // 3.2 将用户信息填到邮件中 + + // 4、更新订单状态和日期 + PreparedStatement preparedUpdateOrder = connection.prepareStatement(UPDATE_ORDER_STATUS); + LocalDateTime localDateTime = LocalDateTime.now(); + String currentTime = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + + preparedUpdateOrder.setString(1, currentTime); + preparedUpdateOrder.setInt(2, orderId); + int row = preparedUpdateOrder.executeUpdate(); + if (row == 1) log.info("表 pmr_wc_order_stats 订单状态更新成功"); + + + } + } + } catch (Exception e) { + // 记录异常并处理 + e.printStackTrace(); + return Boolean.FALSE; + } + + return Boolean.TRUE; + } + + private Account extendValidity(Long validEndTime, double totalSales) { + Instant specifiedInstant; + Account account = new Account(); + long epochMilli = Instant.now().toEpochMilli(); + if (!Objects.isNull(validEndTime) && validEndTime > epochMilli) { + // 将 Unix 毫秒级时间戳转换为 Instant + specifiedInstant = Instant.ofEpochMilli(validEndTime); + } else { + specifiedInstant = Instant.now(); + account.setValidStartTime(specifiedInstant.toEpochMilli()); + } + + // 指定时区 + ZoneId zoneId = ZoneId.of("Asia/Shanghai"); + // 将 Instant 转换为 ZonedDateTime,使用指定时区 + ZonedDateTime specifiedDateTime = ZonedDateTime.ofInstant(specifiedInstant, zoneId); + ZonedDateTime validityExtension; + if (totalSales == 500) { + // 一个月 + validityExtension = specifiedDateTime.plusMonths(1); + } else if (totalSales == 5000) { + // 一年 + validityExtension = specifiedDateTime.plusYears(1); + } else { + // 测试 一天 + validityExtension = specifiedDateTime.plusDays(1); + } + // 获取一个月之后的时间的 Unix 毫秒级时间戳 + account.setValidEndTime(validityExtension.toInstant().toEpochMilli()); + return account; + } + + // 收集调查问卷的信息 + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean collectQuestionnaires(String questionnaireInfo) { + log.info("调查问卷详细信息:{}", questionnaireInfo); + QuestionnaireVO questionnaireVO = JSON.parseObject(questionnaireInfo, QuestionnaireVO.class); + String email = questionnaireVO.getEmail(); + // 1、通过邮箱判断当前用户有无系统账号 + Account account; + try { + account = getOneByEmail(email); + } catch (BusinessException e) { + log.info(e.getMessage()); + log.warn("当前用户 {} 在AiDA中没有账号", email); + throw new BusinessException("user.has.no.account",ResultEnum.PROMPT.getCode()); + } + // 2、先判断当前用户是否已经填写过问卷 + CreditsDetail record = creditsService.getByAccountIdAndChangeEvent(account.getId(), "Fill out the questionnaire", "+100"); + if (!Objects.isNull(record)) { + log.info("当前用户 {} 已经填写过问卷", email); + throw new BusinessException("questionnaire.filled.out", ResultEnum.PROMPT.getCode()); + } + + // 3.1、将问卷信息存储到数据库 + Questionnaire questionnaire = new Questionnaire(); + questionnaire.setQuestionnaireInfo(questionnaireInfo); + questionnaire.setTitle("AiDA_3.0 Feedback Survey--06/2024"); + questionnaire.setCreateTime(LocalDateTime.now()); + int insert = questionnaireMapper.insert(questionnaire); + + if (insert == 1) { + // 3.2、更新 t_credits_detail表 + CreditsDetail creditsDetail = new CreditsDetail(); + creditsDetail.setAccountId(account.getId()); + creditsDetail.setChangeEvent("Fill out the questionnaire"); + creditsDetail.setChangedCredits("+100"); + BigDecimal added = account.getCredits().add(new BigDecimal("100")); + creditsDetail.setCredits(added); + creditsDetail.setCreateTime(LocalDateTime.now()); + creditsService.save(creditsDetail); + + // 3.3、更新 t_account 表 + updateCredits(account.getId(), added.toString()); + } + + // 4、发邮件 区分中英文 + SendEmailUtil.questionnaireRelatedNotify(questionnaireVO.getUserName(), email, questionnaireVO.getLanguage()); + return Boolean.TRUE; + } + + /** + * 为年费用户每月更新积分 + */ + public void refreshCreditsWeekly(){ + UpdateWrapper accountUpdateWrapper = new UpdateWrapper<>(); + // 刷新账号有效期截止之前的年付用户的积分 + long epochMilli = Instant.now().toEpochMilli(); + accountUpdateWrapper.lambda().set(Account::getCredits, CreditsEventsEnum.INIT_WEEKLY.getValue()) + .eq(Account::getSystemUser,1).or().eq(Account::getSystemUser,2) + .gt(Account::getValidEndTime, epochMilli); + baseMapper.update(null,accountUpdateWrapper); + } + } diff --git a/src/main/java/com/ai/da/service/impl/AliPayServiceImpl.java b/src/main/java/com/ai/da/service/impl/AliPayServiceImpl.java index 75c93eb6..61f8b1d2 100644 --- a/src/main/java/com/ai/da/service/impl/AliPayServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/AliPayServiceImpl.java @@ -210,13 +210,13 @@ public class AliPayServiceImpl implements AliPayService { orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.SUCCESS); //记录支付日志 paymentInfoService.createPaymentInfoForAliPay(params); + // 更新积分 + creditsService.buyCredits(orderByOrderNo.getAccountId(),Float.parseFloat(totalAmount) / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())); // 添加积分变更记录 creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(), CreditsEventsEnum.BUY_CREDITS.getName() + "--Alipay", CreditsEventsEnum.BUY_CREDITS.getValue(), "positive"); - // 更新积分 - creditsService.buyCredits(orderByOrderNo.getAccountId(),Float.parseFloat(totalAmount) / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())); } finally { //要主动释放锁 lock.unlock(); @@ -312,13 +312,13 @@ public class AliPayServiceImpl implements AliPayService { orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.SUCCESS); //并记录支付日志 paymentInfoService.createPaymentInfoForAliPay(alipayTradeQueryResponse); + // 更新积分 + creditsService.buyCredits(orderByOrderNo.getAccountId(),orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())); // 添加积分变更记录 creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(), CreditsEventsEnum.BUY_CREDITS.getName() + "--Alipay", CreditsEventsEnum.BUY_CREDITS.getValue(), "positive"); - // 更新积分 - creditsService.buyCredits(orderByOrderNo.getAccountId(),orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())); } } diff --git a/src/main/java/com/ai/da/service/impl/AlipayHKServiceImpl.java b/src/main/java/com/ai/da/service/impl/AlipayHKServiceImpl.java index 14515580..208f82d8 100644 --- a/src/main/java/com/ai/da/service/impl/AlipayHKServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/AlipayHKServiceImpl.java @@ -241,13 +241,13 @@ public class AlipayHKServiceImpl implements AlipayHKService { //记录支付日志 paymentInfoService.createPaymentInfoForAliPayHK(alipayHKCallbackDTO); log.info("Alipay-HK 订单:{} 支付信息状态更新成功",orderNo); + // 更新积分 + creditsService.buyCredits(orderByOrderNo.getAccountId(),Float.parseFloat(totalAmount) / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())); // 添加积分变更记录 creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(), CreditsEventsEnum.BUY_CREDITS.getName() + "--AlipayHK", CreditsEventsEnum.BUY_CREDITS.getValue(), "positive"); - // 更新积分 - creditsService.buyCredits(orderByOrderNo.getAccountId(),Float.parseFloat(totalAmount) / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())); log.info("用户:{} 积分信息更新成功",orderByOrderNo.getAccountId()); } finally { //要主动释放锁 diff --git a/src/main/java/com/ai/da/service/impl/CreditsServiceImpl.java b/src/main/java/com/ai/da/service/impl/CreditsServiceImpl.java index 13f380ce..bb7adbaf 100644 --- a/src/main/java/com/ai/da/service/impl/CreditsServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/CreditsServiceImpl.java @@ -1,6 +1,7 @@ package com.ai.da.service.impl; import com.ai.da.common.config.exception.BusinessException; +import com.ai.da.common.constant.CommonConstant; import com.ai.da.common.context.UserContext; import com.ai.da.common.enums.CreditsEventsEnum; import com.ai.da.common.response.PageBaseResponse; @@ -13,9 +14,11 @@ import com.ai.da.model.dto.QueryIncomeOrExpenditureDTO; import com.ai.da.service.AccountService; import com.ai.da.service.CreditsService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import io.netty.util.internal.StringUtil; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -30,6 +33,7 @@ import java.util.Objects; import java.util.Set; @Service +@Slf4j public class CreditsServiceImpl extends ServiceImpl implements CreditsService { @Value("${redis.key.credits.pre-deduction}") @@ -42,11 +46,6 @@ public class CreditsServiceImpl extends ServiceImpl keys = redisUtil.getKeysFromString(creditsDeduction + ":" + accountId + ":*"); List multiValue = redisUtil.getMultiValue(keys); + // 1.1 预扣除区 积分总和 int sum = multiValue.stream().mapToInt(Integer::parseInt).sum(); + // 1.2 加上本次操作需要扣除的积分 sum += Integer.parseInt(event.getValue()) * num; // 2、获取当前积分 @@ -213,7 +211,7 @@ public class CreditsServiceImpl extends ServiceImpl qw = new QueryWrapper<>(); + qw.eq("account_id", accountId); + qw.eq("change_event", changeEvent); + qw.eq("changed_credits", changedCredits); + + return baseMapper.selectOne(qw); + } + + @Override + public void preInsert(Long accountId, String changeEventName, String taskId) { + CreditsDetail creditsDetail = new CreditsDetail(); + Account account = accountMapper.selectById(accountId); + creditsDetail.setAccountId(accountId); + creditsDetail.setTaskId(taskId); + creditsDetail.setChangeEvent(changeEventName); + creditsDetail.setChangedCredits("-0"); + creditsDetail.setCredits(account.getCredits()); + creditsDetail.setCreateTime(LocalDateTime.now()); + + baseMapper.insert(creditsDetail); + } + + @Override + public void updateChangedCredits(String accountId, String taskId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("account_id", accountId) + .eq("task_id", taskId); + + CreditsDetail creditsDetail = baseMapper.selectOne(queryWrapper); + String changeEvent = creditsDetail.getChangeEvent(); + BigDecimal currentCredits = accountMapper.selectById(accountId).getCredits(); + String credits = "0"; + if (changeEvent.equals("Logo") || + changeEvent.equals("Pattern") || + changeEvent.equals("MoodBoard") || + changeEvent.equals("SketchBoard")) { + credits = CreditsEventsEnum.LOGO.getValue(); + }else if (changeEvent.equals("Slogan")){ + credits = CreditsEventsEnum.SLOGAN.getValue(); + } + +// BigDecimal finalCredits = currentCredits.subtract(new BigDecimal(credits)); + String changeCredits = "-" + credits; + + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.lambda() + .eq(CreditsDetail::getTaskId, taskId) + .set(CreditsDetail::getChangedCredits, changeCredits) + .set(CreditsDetail::getCredits, currentCredits); + + baseMapper.update(null, updateWrapper); + } } 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 12af4462..c6c07158 100644 --- a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java @@ -4,6 +4,7 @@ import com.ai.da.common.config.exception.BusinessException; import com.ai.da.common.constant.CommonConstant; import com.ai.da.common.context.UserContext; import com.ai.da.common.enums.CollectionLevel2TypeEnum; +import com.ai.da.common.enums.CreditsEventsEnum; import com.ai.da.common.enums.GenerateModeEnum; import com.ai.da.common.enums.ModelNameEnum; import com.ai.da.common.utils.*; @@ -14,10 +15,7 @@ import com.ai.da.model.dto.GenerateThroughImageTextDTO; import com.ai.da.model.dto.GenerateToPythonDTO; import com.ai.da.model.vo.*; import com.ai.da.python.PythonService; -import com.ai.da.service.CollectionElementService; -import com.ai.da.service.GenerateService; -import com.ai.da.service.LibraryService; -import com.ai.da.service.RabbitMQService; +import com.ai.da.service.*; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -45,28 +43,22 @@ public class GenerateServiceImpl extends ServiceImpl i @Resource private CollectionElementMapper collectionElementMapper; - @Resource private GenerateDetailMapper generateDetailMapper; - @Resource private LibraryService libraryService; - @Resource private PythonService pythonService; - @Resource private CollectionElementService collectionElementService; - + @Resource + private CreditsService creditsService; @Resource private MinioUtil minioUtil; - @Resource private RabbitMQService rabbitMQService; - @Resource private RedisUtil redisUtil; - @Resource private GenerateCancelMapper generateCancelMapper; @@ -94,6 +86,8 @@ public class GenerateServiceImpl extends ServiceImpl i @Value("${access.python.generate_sr_port}") private String generateServicePort; + // 创建 Random 对象 + Random random = new Random(); @Override public GenerateCaptionVO generateCaption(Long sketchElementId) { @@ -154,11 +148,11 @@ public class GenerateServiceImpl extends ServiceImpl i String jsonString = ""; HashMap params = new HashMap<>(); // 3.1 确定不同类型的印花分别调哪个接口 - if (generateThroughImageTextDTO.getLevel1Type().equals(PRINT_BOARD.getRealName())){ - switch(generateThroughImageTextDTO.getLevel2Type()){ + if (generateThroughImageTextDTO.getLevel1Type().equals(PRINT_BOARD.getRealName())) { + switch (generateThroughImageTextDTO.getLevel2Type()) { case "Logo": path = CommonConstant.GENERATE_SINGLE_LOGO; - params.put("tasks_id",generateThroughImageTextDTO.getUniqueId()); + params.put("tasks_id", generateThroughImageTextDTO.getUniqueId()); params.put("prompt", text); params.put("seed", generateThroughImageTextDTO.getSeed()); jsonString = JSON.toJSONString(params, SerializerFeature.WriteMapNullValue); @@ -166,8 +160,8 @@ public class GenerateServiceImpl extends ServiceImpl i case "Slogan": path = CommonConstant.GENERATE_SLOGAN; port = CommonConstant.PYTHON_PORT_9997; - params.put("num_point","16"); - params.put("tasks_id",generateThroughImageTextDTO.getUniqueId()); + params.put("num_point", "16"); + params.put("tasks_id", generateThroughImageTextDTO.getUniqueId()); params.put("prompt", text); params.put("image_url", collectionElement.getUrl()); jsonString = JSON.toJSONString(params, SerializerFeature.WriteMapNullValue); @@ -177,7 +171,7 @@ public class GenerateServiceImpl extends ServiceImpl i mode, category, generateThroughImageTextDTO.getGender()); jsonString = JSON.toJSONString(generateToPythonDTO, SerializerFeature.WriteMapNullValue); } - }else { + } else { GenerateToPythonDTO generateToPythonDTO = new GenerateToPythonDTO(generateThroughImageTextDTO.getUniqueId(), text, Objects.isNull(collectionElement) ? "" : collectionElement.getUrl(), mode, category, generateThroughImageTextDTO.getGender()); jsonString = JSON.toJSONString(generateToPythonDTO, SerializerFeature.WriteMapNullValue); @@ -199,41 +193,12 @@ public class GenerateServiceImpl extends ServiceImpl i GenerateResultVO generateResultVO = new GenerateResultVO(generateThroughImageTextDTO.getUniqueId(), null, null, status); redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); - // 5、处理模型返回的数据 - // 5.1 将相应的url保存到数据库 - /*List generatedCollectionItems = new ArrayList<>(); - generatedSketchUrl.forEach(item -> { - GenerateDetail generateDetail = new GenerateDetail(); - GenerateCollectionItemVO generateCollectionItemVO = new GenerateCollectionItemVO(); - String md5 = MD5Utils.encryptFile(minioUtil.getPresignedUrl(item, 24 * 60), Boolean.FALSE); - // 通过MD5值和level1Type,判断不同level1Type下相同的图片是否被like过 - List> libraryIdList = generateDetailMapper.getLibraryIdThroughMD5(md5, generateThroughImageTextDTO.getLevel1Type()); - if (!libraryIdList.isEmpty()) { - generateDetail.setIsLike((byte) 1); - generateDetail.setLibraryId(libraryIdList.get(0).get("library_id")); - generateCollectionItemVO.setIsLiked(Boolean.TRUE); - } - generateDetail.setUrl(item); - generateDetail.setGenerateId(generate.getId()); - generateDetail.setCreateDate(DateUtil.getByTimeZone(generateThroughImageTextDTO.getTimeZone())); - generateDetail.setMd5(md5); - generateDetailMapper.insert(generateDetail); - - generateCollectionItemVO.setGenerateItemId(generateDetail.getId()); - generateCollectionItemVO.setGenerateItemUrl(minioUtil.getPresignedUrl(item, 24 * 60)); - generatedCollectionItems.add(generateCollectionItemVO); - }); - - // 6、将模型返回的图片地址返回给前端 - Long collectionId = Objects.isNull(collectionElement) ? null : collectionElement.getCollectionId(); - return new GenerateCollectionVO(generate.getId(), collectionId, generatedCollectionItems);*/ } @Override @Transactional(rollbackFor = Exception.class) public void processGenerateResult(String taskId, String url, String category) { - // 5、处理模型返回的数据 - // 5.1 将相应的url保存到数据库 + // 1、处理模型返回的数据 GenerateDetail generateDetail = new GenerateDetail(); GenerateCollectionItemVO generateCollectionItemVO = new GenerateCollectionItemVO(); Generate generate; @@ -246,7 +211,6 @@ public class GenerateServiceImpl extends ServiceImpl i } else { throw new BusinessException("There are some problems with database query, please try again."); } - } // Generate generate = selectByUniqueId(taskId); String md5 = MD5Utils.encryptFile(minioUtil.getPresignedUrl(url, 24 * 60), Boolean.FALSE); @@ -261,13 +225,24 @@ public class GenerateServiceImpl extends ServiceImpl i generateDetail.setGenerateId(generate.getId()); generateDetail.setCreateDate(LocalDateTime.now()); generateDetail.setMd5(md5); + // 将相应的url保存到数据库 generateDetailMapper.insert(generateDetail); String key = generateResultKey + ":" + taskId; String imageName = url.substring(url.lastIndexOf("/") + 1); String status = imageName.equals("white_image.jpg") ? "Invalid" : "Success"; GenerateResultVO generateResultVO = new GenerateResultVO(taskId, generateDetail.getId(), url, status, category); + // 更新redis redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); + + // 执行积分扣除 + // ** 注:如果生成的图片都是空白 则不扣积分 + if (!status.equals("Invalid")){ + String accountId = taskId.substring(taskId.lastIndexOf("-") + 1); + String uuid = taskId.substring(0, taskId.substring(0, taskId.lastIndexOf("-")).lastIndexOf("-")); + Boolean flag = creditsService.taskCreditsDeduction(Long.parseLong(accountId), uuid); + if (flag) creditsService.updateChangedCredits(accountId, uuid); + } } @Resource @@ -293,6 +268,17 @@ public class GenerateServiceImpl extends ServiceImpl i String status = imageName.equals("white_image.jpg") ? "Invalid" : "Success"; GenerateResultVO generateResultVO = new GenerateResultVO(taskId, toProductImageResult.getId(), url, status, category); redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); + + Long accountId = Long.parseLong(taskId.substring(taskId.lastIndexOf("-") + 1)); + if (!status.equals("Invalid")){ + // 4、扣除积分 + Boolean b = creditsService.taskCreditsDeduction(accountId, taskId); + // 3、记录积分变更 + if (b) creditsService.insertToCreditsDetail(accountId, + CreditsEventsEnum.TO_PRODUCT_IMAGE.getName(), + CreditsEventsEnum.TO_PRODUCT_IMAGE.getValue(), + "negative"); + } } private void validateGeneraType(Generate generate, String text, Long elementId) { @@ -350,7 +336,7 @@ public class GenerateServiceImpl extends ServiceImpl i text = "Flat coating,romantic,soft,pencil strokes,accentuating and widening the depth of pencil strokes,paper patterns,block colors,crayons,reducing image contrast,and hand drawn painting marks," + translated + ", fabric print, high quality"; } else if (userInput.contains("Real Style")) { text = "Still life photography,hyper realism,3d,deepened projection,increased permutation value,increased concavity and convexity value," + translated + ", fabric print, high quality"; - }else { + } else { text = translated; } // text = userInput + ", fabric print, high quality"; @@ -503,40 +489,42 @@ public class GenerateServiceImpl extends ServiceImpl i }*/ // 判断试用用户是否还有剩余试用机会 - int trialsCount = 0; + // ** 不再通过生成次数限制试用用户,统一使用积分限制 + /*int trialsCount = 0; if (generateThroughImageTextDTO.getIsTestUser()) { trialsCount = getTrialsCount(generateThroughImageTextDTO.getUserId(), generateThroughImageTextDTO.getLevel1Type()); if (trialsCount >= 2) { return new PrepareForGenerateVO(0); } - } - + }*/ + CreditsEventsEnum creditsEventsEnum = CreditsEventsEnum.OTHER; int times = 4; // 当level1Type为Print_board时,level2Type为pattern时需要确定generateType - if (generateThroughImageTextDTO.getLevel1Type().equals(PRINT_BOARD.getRealName())){ - if (StringUtil.isNullOrEmpty(generateThroughImageTextDTO.getLevel2Type())){ + if (generateThroughImageTextDTO.getLevel1Type().equals(PRINT_BOARD.getRealName())) { + if (StringUtil.isNullOrEmpty(generateThroughImageTextDTO.getLevel2Type())) { throw new BusinessException("level2Type.cannot.be.empty"); - }else if (!CollectionLevel2TypeEnum.printType().contains(generateThroughImageTextDTO.getLevel2Type())){ + } else if (!CollectionLevel2TypeEnum.printType().contains(generateThroughImageTextDTO.getLevel2Type())) { throw new BusinessException("unknown.parameter.level2Type"); } // Pattern 参数校验 - if (generateThroughImageTextDTO.getLevel2Type().equals(CollectionLevel2TypeEnum.Pattern.getRealName())){ + if (generateThroughImageTextDTO.getLevel2Type().equals(CollectionLevel2TypeEnum.Pattern.getRealName())) { String text = generateThroughImageTextDTO.getText(); Long elementId = generateThroughImageTextDTO.getCollectionElementId(); Generate generate = new Generate(); validateGeneraType(generate, text, elementId); // 校验后获取 generateThroughImageTextDTO.setGenerateType(generate.getGenerateType()); + creditsEventsEnum = CreditsEventsEnum.PATTERN; } // Slogan 参数校验 - if (generateThroughImageTextDTO.getLevel2Type().equals(CollectionLevel2TypeEnum.SLOGAN.getRealName())){ - if (StringUtil.isNullOrEmpty(generateThroughImageTextDTO.getSloganBase64())){ + if (generateThroughImageTextDTO.getLevel2Type().equals(CollectionLevel2TypeEnum.SLOGAN.getRealName())) { + if (StringUtil.isNullOrEmpty(generateThroughImageTextDTO.getSloganBase64())) { log.error("Printboard-Slogan模式下,slogan image为空"); throw new BusinessException("slogan.image.cannot.be.empty"); } - if (StringUtil.isNullOrEmpty(generateThroughImageTextDTO.getText())){ + if (StringUtil.isNullOrEmpty(generateThroughImageTextDTO.getText())) { log.error("Printboard-Slogan模式下,slogan text为空"); throw new BusinessException("slogan.style.cannot.be.empty"); } @@ -563,26 +551,38 @@ public class GenerateServiceImpl extends ServiceImpl i generateThroughImageTextDTO.setCollectionElementId(collectionElement.getId()); generateThroughImageTextDTO.setSloganBase64(null); generateThroughImageTextDTO.setDesignType("collection"); + creditsEventsEnum = CreditsEventsEnum.SLOGAN; } // Logo参数校验 - if (generateThroughImageTextDTO.getLevel2Type().equals(CollectionLevel2TypeEnum.LOGO.getRealName())){ + if (generateThroughImageTextDTO.getLevel2Type().equals(CollectionLevel2TypeEnum.LOGO.getRealName())) { // logo模式下一次只生成一张 times = 1; // 校验是否输入内容 - if (StringUtil.isNullOrEmpty(generateThroughImageTextDTO.getText().trim())){ + if (StringUtil.isNullOrEmpty(generateThroughImageTextDTO.getText().trim())) { throw new BusinessException("please.input.the.prompt"); } // 校验seed的取值范围 - int seed = Integer.parseInt(generateThroughImageTextDTO.getSeed()); - if (seed < 0 || seed > 99999){ - throw new BusinessException("the.value.range.of.seed"); - } + int seed = random.nextInt(501); + log.info("随机种子:{}", seed); + generateThroughImageTextDTO.setSeed(String.valueOf(seed)); + + creditsEventsEnum = CreditsEventsEnum.LOGO; } + } else if (generateThroughImageTextDTO.getLevel1Type().equals(MOOD_BOARD.getRealName())) { + creditsEventsEnum = CreditsEventsEnum.MOOD_BOARD; + } else if (generateThroughImageTextDTO.getLevel1Type().equals(SKETCH_BOARD.getRealName())) { + creditsEventsEnum = CreditsEventsEnum.SKETCH_BOARD; } - // 2、生成唯一id 使用uuid,由于uuid重复的几率很小,故取消对uuid重复性的校验 + // 2、判断用户当前积分是否够本次生成消耗 + Boolean preDeduction = creditsService.creditsPreDeduction(creditsEventsEnum, 1); + if (!preDeduction) { + throw new BusinessException("Not enough Credits"); + } + + // 3、生成唯一id 使用uuid,由于uuid重复的几率很小,故取消对uuid重复性的校验 String uuid = UUID.randomUUID().toString(); ArrayList taskIdList = new ArrayList<>(); @@ -593,7 +593,7 @@ public class GenerateServiceImpl extends ServiceImpl i generateThroughImageTextDTO.setUniqueId(temp); String jsonString = JSON.toJSONString(generateThroughImageTextDTO); - // 3、加入redis排队,便于获取实时排队信息 + // 4、加入redis排队,便于获取实时排队信息 Double maxScore = redisUtil.getMaxScore(consumptionOrderKey); redisUtil.addToZSet(consumptionOrderKey, temp, maxScore); @@ -602,12 +602,17 @@ public class GenerateServiceImpl extends ServiceImpl i GenerateResultVO generateResultVO = new GenerateResultVO(generateThroughImageTextDTO.getUniqueId(), null, null, "Waiting"); redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); - // 4、将消息发布到MQ消息队列 + // 5、将消息发布到MQ消息队列 rabbitMQService.publishMessageToGenerate(jsonString); } - // 5、返回唯一id - return new PrepareForGenerateVO(taskIdList, 2 - trialsCount); + // 6、添加预扣除积分到redis + creditsService.addRecordToCreditsDeduction(generateThroughImageTextDTO.getUserId(), uuid, creditsEventsEnum); + // 6.1 添加积分扣除记录到db + creditsService.preInsert(generateThroughImageTextDTO.getUserId(), creditsEventsEnum.getName(), uuid); + + // 7、返回唯一id + return new PrepareForGenerateVO(taskIdList, 2); } @Override @@ -616,57 +621,6 @@ public class GenerateServiceImpl extends ServiceImpl i return redisUtil.getRank(consumptionOrderKey, uniqueId); } - /*@Override - public GenerateCollectionVO getGenerateResult(String uniqueId) { - // 1、判断该请求是否已经异常 - Boolean isMember = redisUtil.isElementExistsInMap(exceptionMapKey, uniqueId); - if (isMember) { - throw new BusinessException("generate.interface.error"); - } - - // 2、判断该请求是否还在排队 - Boolean existsInZSet = redisUtil.isElementExistsInZSet(consumptionOrderKey, uniqueId); - if (existsInZSet) { - // 排队中,给出当前排序位置,rank从0开始 - Long rankPosition = getRankPosition(uniqueId); - // 有9个消费者,所以当rank>8即当前请求至少排在第九位时,其实际排队位置为9-8+1,当rank <=8,请求均在处理中 - return new GenerateCollectionVO(rankPosition > 8L ? rankPosition - 8 + 1 : 1L); - } - - // 3、判断redis中有没有 - boolean hasHashKey = redisUtil.isElementExistsInMap(resultMapKey, uniqueId); - if (hasHashKey) { - // 3.1 有直接从redis中拿 - String resultString = redisUtil.getMapValue(resultMapKey, uniqueId); - return JSONObject.parseObject(resultString, GenerateCollectionVO.class); - } - - // 3.2 判断数据库中有没有 - Generate generate = selectByUniqueId(uniqueId); - if (Objects.isNull(generate)) { - // 3.3 还没执行完,给出当前位置 - return new GenerateCollectionVO(1L); - } - Long generateId = generate.getId(); - QueryWrapper qw = new QueryWrapper<>(); - qw.eq("generate_id", generateId); - List generateDetails = generateDetailMapper.selectList(qw); - if (CollectionUtils.isEmpty(generateDetails)) { - // 会有这种情况吗?存到generate中,但是还没存到generateDetail中 - return new GenerateCollectionVO(1L); - } - - List generatedCollectionItems = new ArrayList<>(); - generateDetails.forEach(item -> { - GenerateCollectionItemVO generateCollectionItemVO = new GenerateCollectionItemVO(); - generateCollectionItemVO.setGenerateItemId(item.getId()); - generateCollectionItemVO.setGenerateItemUrl(minioUtil.getPresignedUrl(item.getUrl(), 24 * 60)); - generatedCollectionItems.add(generateCollectionItemVO); - }); - - return new GenerateCollectionVO(generateId, null, generatedCollectionItems); - }*/ - @Override public List getGenerateResultList(List taskIdList) { List results = new ArrayList<>(); @@ -712,7 +666,7 @@ public class GenerateServiceImpl extends ServiceImpl i @Override @Transactional(rollbackFor = Exception.class) - public void cancelGenerate(Long userId, List uniqueIdList, String timeZone) { + public void cancelGenerate(Long userId, List uniqueIdList, String timeZone, String type) { // todo 取消待优化 uniqueIdList.forEach(uniqueId -> { // 1、将需要取消的唯一id加入redis,以便及时取消生成 @@ -740,13 +694,23 @@ public class GenerateServiceImpl extends ServiceImpl i pythonService.cancelGenerateTask(uniqueId); } }*/ + String path; + if (type.equals("Logo")) { + path = CommonConstant.GENERATE_LOGO_SINGLE_CANCEL; + } else { + path = CommonConstant.GENERATE_CANCEL; + } String key = generateResultKey + ":" + uniqueId; GenerateResultVO generateResultVO = new Gson().fromJson(redisUtil.getFromString(key), GenerateResultVO.class); + if (Objects.isNull(generateResultVO)) { + log.warn("任务不存在,无法取消"); + return; + } // 判断当前task的状态是不是Fail if (!generateResultVO.getStatus().equals("Fail")) { // 2、不是,直接发送取消请求到python端 - pythonService.cancelGenerateTask(uniqueId); + pythonService.cancelGenerateTask(uniqueId, path); // 3、更改result中当前taskId的状态 redisUtil.addToString(key, new Gson().toJson(new GenerateResultVO(uniqueId, null, null, "Cancelled")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME); } diff --git a/src/main/java/com/ai/da/service/impl/PayPalCheckoutServiceImpl.java b/src/main/java/com/ai/da/service/impl/PayPalCheckoutServiceImpl.java index 62326aed..f4fd04b4 100644 --- a/src/main/java/com/ai/da/service/impl/PayPalCheckoutServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/PayPalCheckoutServiceImpl.java @@ -586,13 +586,13 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.SUCCESS); //记录支付日志 paymentInfoService.createPaymentInfoForPayPal(capturedOrder); + // 更新积分 + creditsService.buyCredits(orderInfo.getAccountId(), orderInfo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())); // 添加积分变更记录 creditsService.insertToCreditsDetail(orderInfo.getAccountId(), CreditsEventsEnum.BUY_CREDITS.getName() + "--PayPal", CreditsEventsEnum.BUY_CREDITS.getValue(), "positive"); - // 更新积分 - creditsService.buyCredits(orderInfo.getAccountId(), orderInfo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())); } } @@ -628,14 +628,14 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService { orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.SUCCESS); //并记录支付日志 paymentInfoService.createPaymentInfoForPayPal(result); + // 更新积分 +// creditsService.buyCredits(orderByOrderNo.getAccountId(),orderByOrderNo.getTotalFee() / Integer.parseInt(CreditsEventsEnum.PRICE.getValue())); + creditsService.buyCredits(orderByOrderNo.getAccountId(),orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())); // 添加积分变更记录 creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(), CreditsEventsEnum.BUY_CREDITS.getName() + "--Paypal", CreditsEventsEnum.BUY_CREDITS.getValue(), "positive"); - // 更新积分 -// creditsService.buyCredits(orderByOrderNo.getAccountId(),orderByOrderNo.getTotalFee() / Integer.parseInt(CreditsEventsEnum.PRICE.getValue())); - creditsService.buyCredits(orderByOrderNo.getAccountId(),orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())); } } diff --git a/src/main/java/com/ai/da/service/impl/SuperResolutionServiceImpl.java b/src/main/java/com/ai/da/service/impl/SuperResolutionServiceImpl.java index ee1fb6ff..63585f19 100644 --- a/src/main/java/com/ai/da/service/impl/SuperResolutionServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/SuperResolutionServiceImpl.java @@ -109,7 +109,8 @@ public class SuperResolutionServiceImpl extends ServiceImpl toProduct(ToProductImageDTO toProductImageDTO) { + // 判断用户当前积分是否够本次生成消耗 + Boolean preDeduction = creditsService.creditsPreDeduction(CreditsEventsEnum.TO_PRODUCT_IMAGE, toProductImageDTO.getToProductImageVOList().size()); + if (!preDeduction) { + throw new BusinessException("Not enough Credits"); + } + AuthPrincipalVo userHolder = UserContext.getUserHolder(); Long userLikeGroupId = toProductImageDTO.getUserLikeGroupId(); ToProductImageRecord toProductImageRecord = new ToProductImageRecord(); @@ -240,11 +246,12 @@ public class UserLikeGroupServiceImpl extends ServiceImpl