From e2f8fb082c83c8257e5c0f20108bb004f1fe9cb2 Mon Sep 17 00:00:00 2001 From: xupei Date: Fri, 13 Sep 2024 10:43:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B9=BF=E5=9C=BA=E7=94=A8=E6=88=B7=E6=B3=A8?= =?UTF-8?q?=E5=86=8C=E4=BF=AE=E6=94=B9=20=E6=B7=BB=E5=8A=A0=E8=B4=A6?= =?UTF-8?q?=E6=88=B7=E5=BC=80=E5=A7=8B=E6=97=B6=E9=97=B4=E5=B9=B6=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E7=A7=AF=E5=88=86=E4=B8=BA0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../da/service/impl/AccountServiceImpl.java | 3178 +++++++++-------- 1 file changed, 1590 insertions(+), 1588 deletions(-) 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 d135060b..74f2dc33 100644 --- a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java @@ -1,1588 +1,1590 @@ -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.constant.CommonConstant; -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.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.*; -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.*; -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.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.Assert; -import org.springframework.web.multipart.MultipartFile; - -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.text.SimpleDateFormat; -import java.time.*; -import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoUnit; -import java.util.*; -import java.util.stream.Collectors; - -/** - * 服务实现类 - * - * @author easy-generator - * @since 2022-07-06 - */ -@Slf4j -@Service -public class AccountServiceImpl extends ServiceImpl implements AccountService { - @Resource - private AccountMapper accountMapper; - - @Resource - private JWTTokenHelper jwtTokenHelper; - - @Resource - private AccountLoginLogService accountLoginLogService; - - @Resource - private LibraryService libraryService; - - @Resource - private UserLikeGroupService userLikeGroupService; - - @Resource - private TrialOrderMapper trialOrderMapper; - - @Resource - private QuestionnaireMapper questionnaireMapper; - - @Resource - private CreditsService creditsService; - - @Resource - private MinioUtil minioUtil; - - @Value("${minio.bucketName.users}") - private String userBucket; - - @Resource - private RedisUtil redisUtil; - - @Override - @Transactional(rollbackFor = Exception.class) - public AccountPreLoginVO preLogin(AccountPreLoginDTO accountDTO) { - log.info("aida预先登入accountDTO###{}", JSON.toJSONString(accountDTO)); - Account account = getOneByEmail(accountDTO.getEmail()); - //用户有效期校验 - validateUserValidaExpire(account); - if ("Third-000000".equals(account.getUserPassword())) { - account.setUserPassword(accountDTO.getPassword()); - accountMapper.updateById(account); - } else { - if (!account.getUserPassword().equals(accountDTO.getPassword())) { - throw new BusinessException("password.error", ResultEnum.PROMPT.getCode()); - } - } - /*发送邮件*/ - AuthenticationOperationTypeEnum authenticationOperationTypeEnum = AuthenticationOperationTypeEnum.of(accountDTO.getOperationType()); - log.info(account.getUserEmail()); - log.info(accountDTO.getEmail()); - if (!account.getUserEmail().equals(accountDTO.getEmail())) { - throw new BusinessException("email.error", ResultEnum.PROMPT.getCode()); - } - if (Objects.isNull(authenticationOperationTypeEnum)) { - throw new BusinessException("unknown.authentication.operation.type"); - } - String randomVerifyCode = RandomsUtil.generateVerifyCode(100000L, 999999L); - LocalCacheUtils.setVerifyCodeCache( - accountDTO.getOperationType() + "_" + accountDTO.getEmail(), randomVerifyCode); - Boolean result = Boolean.FALSE; - switch (authenticationOperationTypeEnum) { - case LOGIN: - result = SendEmailUtil.send(accountDTO.getEmail(), null, - SendEmailUtil.LOGIN_TEMPLATE_ID, randomVerifyCode); - break; - case FORGET_PWD: - result = SendEmailUtil.send(accountDTO.getEmail(), null, - SendEmailUtil.UPDATE_PWD_TEMPLATE_ID, randomVerifyCode); - break; - case EXCEPTION_IP: - result = SendEmailUtil.send(accountDTO.getEmail(), accountDTO.getIp(), - SendEmailUtil.EXCEPTION_ID_TEMPLATE_ID, randomVerifyCode); - break; - case BIND_MAILBOX: - result = SendEmailUtil.send(accountDTO.getEmail(), null, - SendEmailUtil.BIND_MAILBOX_TEMPLATE_ID, randomVerifyCode); - break; - default: - } - if (!result) { - throw new BusinessException("failed.to.send.mail"); - } - return new AccountPreLoginVO(account.getId()); - } - - @Resource - private PortfolioService portfolioService; - - @Transactional(rollbackFor = Exception.class) - @Override - public AccountLoginVO login(AccountLoginDTO accountLoginDTO, HttpServletRequest request) { -// Assert.isTrue(StringUtils.isNotBlank(accountLoginDTO.getEmail()), "Please input a email !"); -// Assert.isTrue(StringUtils.isNotBlank(accountLoginDTO.getEmailVerifyCode()), "Please input the email verification code !"); - log.info("aida确认登入###accountLoginDTO###{}", JSON.toJSONString(accountLoginDTO)); - Account accountExist = getOneByEmail(accountLoginDTO.getEmail().trim()); - LoginTypeEnum accountType = LoginTypeEnum.of(accountLoginDTO.getLoginType()); - if (Objects.isNull(accountType)) { - throw new BusinessException("unknown.login.type"); - } - if (!accountType.equals(LoginTypeEnum.EMAIL)) { - throw new BusinessException("error.login.type"); - } - //用户有效期校验 - validateUserValidaExpire(accountExist); - - Account account = null; - switch (accountType) { - case PASSWORD: -// Assert.isTrue(StringUtils.isNotBlank(accountLoginDTO.getPassword()), "Please input a password !"); -// account = getOneByUserName(accountLoginDTO.getUserName()); -// Assert.isTrue(Objects.nonNull(account), "User does not exist!"); -// Assert.isTrue(account.getUserPassword().equals(accountLoginDTO.getPassword()), "Password error !"); - // 走不到这边 - break; - case EMAIL: - account = getOneByEmail(accountLoginDTO.getEmail().trim()); - //校验邮箱验证码 - String verifyCode = LocalCacheUtils.getVerifyCodeCache(AuthenticationOperationTypeEnum.LOGIN.name() + "_" + accountLoginDTO.getEmail()); - if (StringUtils.isBlank(verifyCode)) { - throw new BusinessException("the.verification.code.has.expired", ResultEnum.PROMPT.getCode()); - } - if (!"921314".equals(accountLoginDTO.getEmailVerifyCode())) { - if (!verifyCode.equals(accountLoginDTO.getEmailVerifyCode())) { - throw new BusinessException("verification.code.error", ResultEnum.PROMPT.getCode()); - } - } - break; - default: - } - 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; - } - - private void validateUserValidaExpire(Account account) { - Long currentTime = new Date().getTime(); - if (Objects.nonNull(account.getValidStartTime())) { - if (currentTime < account.getValidStartTime()) { - throw new BusinessException("user.expired"); - } - } - if (Objects.nonNull(account.getValidEndTime())) { - if (currentTime > account.getValidEndTime()) { - throw new BusinessException("user.expired"); - } - } - } - - private void calculateExceptionIp(String ip, Account account) { - //必须先绑定邮箱才可以发有异常ip邮件提醒 - if (StringUtils.isNotBlank(account.getUserEmail())) { - List accountLoginLogs = accountLoginLogService.getByUserId(account.getId()); - if (CollectionUtil.isNotEmpty(accountLoginLogs)) { - List existIps = accountLoginLogs.stream().map(AccountLoginLog::getIp).collect(Collectors.toList()); - if (!existIps.contains(ip)) { - //非常用ip,没有出现过 - EmailSendDTO emailSendDTO = new EmailSendDTO(); - emailSendDTO.setEmail(account.getUserEmail()); - emailSendDTO.setOperationType(AuthenticationOperationTypeEnum.EXCEPTION_IP.name()); - emailSendDTO.setIp(ip); - sendEmail(emailSendDTO); - } - } - } - //保存登入日志 - accountLoginLogService.saveLoginLog(ip, account.getId()); - } - - private String createAccountToken(Account account) { - AuthPrincipalVo principal = new AuthPrincipalVo(); - principal.setId(account.getId()); - principal.setUsername(account.getUserName()); - principal.setLanguage(account.getLanguage()); - principal.setCountry(account.getCountry()); - String token2 = jwtTokenHelper.createToken(principal); - LocalCacheUtils.setTokenCache(String.valueOf(account.getId()), token2); - return token2; - } - - @Override - public Boolean bindEmail(AccountBindEmailDTO accountBindEmailDTO) { - Account account = baseMapper.selectById(accountBindEmailDTO.getUserId()); - if (Objects.isNull(account)) { - throw new BusinessException("userName.does.not.exist", ResultEnum.PROMPT.getCode()); - } - if (StringUtils.isNotBlank(account.getUserEmail())) { - throw new BusinessException("user.has.bound.mailbox"); - } - //校验邮箱验证码 - String verifyCode = LocalCacheUtils.getVerifyCodeCache(AuthenticationOperationTypeEnum.BIND_MAILBOX.name() + "_" + accountBindEmailDTO.getUserEmail()); - if (StringUtils.isBlank(verifyCode)) { - throw new BusinessException("the.verification.code.has.expired", ResultEnum.PROMPT.getCode()); - } - if (!verifyCode.equals(accountBindEmailDTO.getEmailVerifyCode())) { - throw new BusinessException("verification.code.error", ResultEnum.PROMPT.getCode()); - } - //绑定 - updatePwdByUserId(accountBindEmailDTO.getUserEmail(), accountBindEmailDTO.getUserId()); - return Boolean.TRUE; - } - - @Transactional(rollbackFor = Exception.class) - @Override - public Boolean forgetPwd(AccountRegisterDTO accountDTO) { -// Account emailAccount = getOneByEmail(accountDTO.getEmail()); - //校验邮箱验证码 - if (accountDTO.getVerifyEmail()) { - String verifyCode = LocalCacheUtils.getVerifyCodeCache(AuthenticationOperationTypeEnum.FORGET_PWD.name() + "_" + accountDTO.getEmail()); - if (StringUtils.isBlank(verifyCode)) { - throw new BusinessException("the.verification.code.has.expired", ResultEnum.PROMPT.getCode()); - } - if (!verifyCode.equals(accountDTO.getEmailVerifyCode())) { - throw new BusinessException("verification.code.error", ResultEnum.PROMPT.getCode()); - } - } else { - updatePwdByEmail(accountDTO.getPassword(), accountDTO.getEmail()); - } - return Boolean.TRUE; - } - - private void updatePwdByEmail(String pwd, String email) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.lambda().eq(Account::getUserEmail, email); - Account accountNew = new Account(); - accountNew.setUserPassword(pwd); - accountMapper.update(accountNew, queryWrapper); - } - - private void updatePwdByUserId(String email, Long userId) { - Account accountNew = new Account(); - accountNew.setUserEmail(email); - accountNew.setId(userId); - accountMapper.updateById(accountNew); - } - - - private Account getOneByEmail(String email) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("BINARY user_email", email); - List accountList = accountMapper.selectList(queryWrapper); - log.info(accountList.toString()); - if (CollectionUtil.isEmpty(accountList)) { - throw new BusinessException("email.does.not.exist", ResultEnum.PROMPT.getCode()); - } - return accountList.get(0); - } - - // 忽略大小写 - private Account getAccountByEmail(String email) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("user_email", email); - List accountList = accountMapper.selectList(queryWrapper); - log.info(accountList.toString()); - if (CollectionUtil.isEmpty(accountList)) { - throw new BusinessException("email.does.not.exist", ResultEnum.PROMPT.getCode()); - } - return accountList.get(0); - } - - private Account getOneByUserName(String userName) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.lambda().eq(Account::getUserName, userName); - queryWrapper.lambda().last("limit 1"); - List accountList = accountMapper.selectList(queryWrapper); - if (CollectionUtil.isEmpty(accountList)) { - throw new BusinessException("userName.does.not.exist", ResultEnum.PROMPT.getCode()); - } - return accountList.get(0); - } - - private Account getOneByUserId(Long userId) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("id", userId); - return accountMapper.selectOne(queryWrapper); - } - - - @Override - public Boolean sendEmail(EmailSendDTO emailSendDTO) { - AuthenticationOperationTypeEnum authenticationOperationTypeEnum = AuthenticationOperationTypeEnum.of(emailSendDTO.getOperationType()); - if (Objects.isNull(authenticationOperationTypeEnum)) { - throw new BusinessException("unknown.authentication.operation.type"); - } - Account emailAccount = getOneByEmail(emailSendDTO.getEmail()); - String randomVerifyCode = RandomsUtil.generateVerifyCode(100000L, 999999L); - LocalCacheUtils.setVerifyCodeCache( - emailSendDTO.getOperationType() + "_" + emailSendDTO.getEmail(), randomVerifyCode); - Boolean result = Boolean.FALSE; - switch (authenticationOperationTypeEnum) { - case LOGIN: - result = SendEmailUtil.send(emailSendDTO.getEmail(), null, - SendEmailUtil.LOGIN_TEMPLATE_ID, randomVerifyCode); - break; - case FORGET_PWD: - result = SendEmailUtil.send(emailSendDTO.getEmail(), null, - SendEmailUtil.UPDATE_PWD_TEMPLATE_ID, randomVerifyCode); - break; - case EXCEPTION_IP: - result = SendEmailUtil.send(emailSendDTO.getEmail(), emailSendDTO.getIp(), - SendEmailUtil.EXCEPTION_ID_TEMPLATE_ID, randomVerifyCode); - break; - case BIND_MAILBOX: - result = SendEmailUtil.send(emailSendDTO.getEmail(), null, - SendEmailUtil.BIND_MAILBOX_TEMPLATE_ID, randomVerifyCode); - break; - default: - } - if (!result) { - throw new BusinessException("failed.to.send.mail"); - } - return Boolean.TRUE; - } - - @Override - public Boolean logout(AccountLogoutDTO accountLogoutDTO) { - //jwt本身失效比较难做 统一用缓存实现 删除缓存就失效 - String token = LocalCacheUtils.getTokenCache(String.valueOf(accountLogoutDTO.getUserId())); - if (StringUtils.isNotBlank(token)) { - LocalCacheUtils.delTokenCache(String.valueOf(accountLogoutDTO.getUserId())); - } - return Boolean.TRUE; - } - - @Override - public Boolean isLogin(AccountLogoutDTO accountLogoutDTO) { - String token = LocalCacheUtils.getTokenCache(String.valueOf(accountLogoutDTO.getUserId())); - if (StringUtils.isNotBlank(token)) { - return Boolean.TRUE; - } - return Boolean.FALSE; - } - - @Override - public Boolean addUser(AccountAddDTO accountAddDTO) { - 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(toDayEnd(Long.parseLong(accountAddDTO.getValidEndTime()))); - account.setUserPassword("Third-000000"); - account.setLanguage(Language.ENGLISH.name()); - account.setCreateDate(new Date()); - account.setIsTrial(0); - account.setIsBeginner(1); - return accountMapper.insert(account) > 0; - } - - @Override - public Boolean editUser(AccountEditDTO accountEditDTO) { - if (Objects.isNull(accountEditDTO) || ObjectUtils.isAllFieldNull(accountEditDTO)) { - throw new BusinessException("The edited account information cannot be blank!"); - } - QueryWrapper queryTotal = new QueryWrapper<>(); - Account account = new Account(); - //校验 - if (StringUtils.isNotBlank(accountEditDTO.getNewEmail())) { - Assert.isTrue(StringUtils.isNotBlank(accountEditDTO.getOldEmail()), "oldEmail cannot be empty!"); - queryTotal.eq("user_email", accountEditDTO.getOldEmail()); - Account accountSelect = accountMapper.selectOne(queryTotal); - Assert.notNull(accountSelect, "oldEmail does not exist!"); - - account.setUserEmail(accountEditDTO.getNewEmail()); - } - if (StringUtils.isNotBlank(accountEditDTO.getNewUserName())) { - Assert.isTrue(StringUtils.isNotBlank(accountEditDTO.getOldUserName()), "oldUserName cannot be empty!"); - queryTotal.eq("user_name", accountEditDTO.getOldUserName()); - Account accountSelect = accountMapper.selectOne(queryTotal); - Assert.notNull(accountSelect, "oldUserName does not exist!"); - - account.setUserName(accountEditDTO.getNewUserName()); - } - if (StringUtils.isNotBlank(accountEditDTO.getNewValidStartTime())) { - Assert.isTrue(StringUtils.isNotBlank(accountEditDTO.getOldUserName()), "oldUserName cannot be empty!"); - queryTotal.eq("user_name", accountEditDTO.getOldUserName()); - Account accountSelect = accountMapper.selectOne(queryTotal); - Assert.notNull(accountSelect, "oldUserName does not exist!"); - - account.setValidStartTime(Long.valueOf(accountEditDTO.getNewValidStartTime())); - } - if (StringUtils.isNotBlank(accountEditDTO.getNewValidEndTime())) { - Assert.isTrue(StringUtils.isNotBlank(accountEditDTO.getOldUserName()), "oldUserName cannot be empty!"); - queryTotal.eq("user_name", accountEditDTO.getOldUserName()); - Account accountSelect = accountMapper.selectOne(queryTotal); - Assert.notNull(accountSelect, "oldUserName does not exist!"); - - account.setValidEndTime(toDayEnd(Long.parseLong(accountEditDTO.getNewValidEndTime()))); - } - Account accountSelect = accountMapper.selectOne(queryTotal); - Assert.notNull(accountSelect, "oldAccount does not exist!"); - accountMapper.update(account, queryTotal); - return null; - } - - @Override - public String getUserLanguage() { - AuthPrincipalVo userInfo = UserContext.getUserHolder(); - return Language.valueOf(userInfo.getLanguage()).name(); - } - - @Override - public String changeUserLanguage(String language) { - AuthPrincipalVo userInfo = UserContext.getUserHolder(); - Account account = accountMapper.selectById(userInfo.getId()); - account.setLanguage(language); - accountMapper.updateById(account); - String accountToken = createAccountToken(account); - return accountToken; - } - - @Override - public Boolean trialUserLogout() { - AuthPrincipalVo userInfo = UserContext.getUserHolder(); - Account account = accountMapper.selectById(userInfo.getId()); - if (account.getIsTrial() != 1) { - throw new BusinessException("用户为正式用户"); - } - libraryService.deleteTrialData(userInfo.getId()); - userLikeGroupService.deleteTrialData(userInfo.getId()); - return Boolean.TRUE; - } - - @Override - public Boolean completeGuidance() { - AuthPrincipalVo userInfo = UserContext.getUserHolder(); - Account account = accountMapper.selectById(userInfo.getId()); - account.setIsBeginner(0); - accountMapper.updateById(account); - return Boolean.TRUE; - } - - @Override - public Boolean addTrialUser(AccountTrialDTO accountTrialDTO, HttpServletRequest request) { - // 获取用户申请试用IP - String ipAddress = RequestInfoUtil.getIpAddress(request); - boolean link = false; - if (StringUtils.isNotBlank(accountTrialDTO.getRef())) { - link = true; - } - // 先检测试用订单 - QueryWrapper trialOrderQueryWrapper = new QueryWrapper<>(); - trialOrderQueryWrapper.eq("BINARY email", accountTrialDTO.getEmail()); -// trialOrderQueryWrapper.lambda().eq(TrialOrder::getIp, ipAddress); -// trialOrderQueryWrapper.lambda().and(wrapper -> -// wrapper.eq(TrialOrder::getEmail, accountTrialDTO.getEmail()) -// .or() // OR -// .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."); - } - // 先检测用户名和邮箱 - QueryWrapper qw = new QueryWrapper<>(); - qw.eq("BINARY user_email", accountTrialDTO.getEmail()); - List accountList = accountMapper.selectList(qw); - if (CollectionUtil.isNotEmpty(accountList) && !accountList.get(0).getSystemUser().equals(0)) { - if (accountList.get(0).getIsTrial() == 1) { - throw new BusinessException("The email has already been registered", ResultEnum.PROMPT.getCode()); - } 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()); - } - } - } - // 接收到数据后要形成一条使用订单信息 - TrialOrder trialOrder = CopyUtil.copyObject(accountTrialDTO, TrialOrder.class); - trialOrder.setCreateTime(LocalDateTime.now()); - trialOrder.setStatus(0); - trialOrder.setIp(ipAddress); - trialOrderMapper.insert(trialOrder); -// SendEmailUtil.sendCustomEmail("1023316923@qq.com", null, trialOrder,1); -// SendEmailUtil.sendCustomEmail("calvinwong@aidlab.hk", null, trialOrder,1); -// SendEmailUtil.sendCustomEmail("kaicpang.pang@connect.polyu.hk", null, trialOrder,1); - // 判断当前的试用订单是否自动批准 - if (AutoApproved.getStatus()) { - // 改变试用订单状态,新增试用用户 - trialOrder.setStatus(1); - trialOrder.setUpdateTime(LocalDateTime.now()); - trialOrderMapper.updateById(trialOrder); - Account account = new Account(); - if (CollectionUtil.isNotEmpty(accountList)) { - account = CopyUtil.copyObject(accountList.get(0), Account.class); - account.setIsTrial(1); - account.setIsBeginner(1); - account.setSystemUser(3); - account.setValidStartTime(System.currentTimeMillis()); - if (link) { - account.setValidEndTime(toDayEnd(Instant.now().plus(14, ChronoUnit.DAYS).toEpochMilli())); - } else { - account.setValidEndTime(toDayEnd(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli())); - } - accountMapper.updateById(account); - } else { - account.setUserName(trialOrder.getUserName()); - account.setUserPassword("Third-000000"); - account.setUserEmail(trialOrder.getEmail()); - account.setLanguage(Language.ENGLISH.name()); - account.setValidStartTime(System.currentTimeMillis()); - if (link) { - account.setValidEndTime(toDayEnd(Instant.now().plus(14, ChronoUnit.DAYS).toEpochMilli())); - } else { - account.setValidEndTime(toDayEnd(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli())); - } - account.setCreateDate(new Date()); - account.setIsTrial(1); - account.setIsBeginner(1); - account.setSystemUser(3); - account.setCredits(BigDecimal.valueOf(100)); - accountMapper.insert(account); - } - // 发送邮件提醒用户试用用户已创建 -// SendEmailUtil.sendCustomEmail("1023316923@qq.com", null, trialOrder,2); -// SendEmailUtil.sendCustomEmail("calvinwong@aidlab.hk", null, trialOrder,2); -// 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 { - SendEmailUtil.sendCustomEmail(account.getUserEmail(), null, trialOrder, 3, trialOrder.getCountry(), link); - } - } - return Boolean.TRUE; - } - - @Override - public IPage trialOrderList(TrialOrderDTO trialOrderDTO) { - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(trialOrderDTO.getStatus() != null, TrialOrder::getStatus, trialOrderDTO.getStatus()); - return trialOrderMapper.selectPage(new Page<>(trialOrderDTO.getPage(), trialOrderDTO.getSize()), qw); - } - - @Override - public Boolean trialOrderApproval(List ids) { - for (Long id : ids) { - TrialOrder trialOrder = trialOrderMapper.selectById(id); - trialOrder.setStatus(1); - trialOrder.setUpdateTime(LocalDateTime.now()); - trialOrderMapper.updateById(trialOrder); - - QueryWrapper qw = new QueryWrapper<>(); - qw.eq("BINARY user_email", trialOrder.getEmail()); - List accountList = accountMapper.selectList(qw); - - Account account = new Account(); - if (CollectionUtil.isNotEmpty(accountList)) { - account = CopyUtil.copyObject(accountList.get(0), Account.class); - account.setIsTrial(1); - account.setIsBeginner(1); - account.setValidStartTime(System.currentTimeMillis()); - account.setValidEndTime(toDayEnd(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli())); - accountMapper.updateById(account); - } else { - account.setUserName(trialOrder.getUserName()); - account.setUserPassword("Third-000000"); - account.setUserEmail(trialOrder.getEmail()); - account.setLanguage(Language.ENGLISH.name()); - account.setValidStartTime(System.currentTimeMillis()); - account.setValidEndTime(toDayEnd(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli())); - account.setCreateDate(new Date()); - account.setIsTrial(1); - account.setIsBeginner(1); - account.setSystemUser(1); - accountMapper.insert(account); - } - // 发送邮件提醒用户试用用户已创建 -// SendEmailUtil.sendCustomEmail("1023316923@qq.com", null, trialOrder,2, trialOrder.getCountry()); -// SendEmailUtil.sendCustomEmail("calvinwong@aidlab.hk", null, trialOrder,2, trialOrder.getCountry()); -// 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 { - SendEmailUtil.sendCustomEmail(account.getUserEmail(), null, trialOrder, 3, trialOrder.getCountry(), false); - } - } - return Boolean.TRUE; - } - - @Override - public Boolean getIsAutoApproval() { - return AutoApproved.getStatus(); - } - - @Override - public Boolean switchIsAutoApproval() { - AutoApproved.setStatus(!AutoApproved.getStatus()); - return Boolean.TRUE; - } - - @Override - public Boolean trialOrderRefuse(List ids) { - for (Long id : ids) { - TrialOrder trialOrder = trialOrderMapper.selectById(id); - trialOrder.setStatus(2); - trialOrder.setUpdateTime(LocalDateTime.now()); - trialOrderMapper.updateById(trialOrder); - } - return Boolean.TRUE; - } - - @Override - public Long getExpiredTime() { - AuthPrincipalVo userInfo = UserContext.getUserHolder(); - return accountMapper.selectById(userInfo.getId()).getValidEndTime(); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public Boolean addNoLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO) { - // 构建查询条件,查找已注册的账户数量 - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.lambda().isNotNull(Account::getBrowserIdentifiers); - queryWrapper.lambda().like(Account::getUserName, "PolyU-SFT-"); - List existingAccounts = accountMapper.selectList(queryWrapper); - - // 检查注册账户数量是否超过限制 - if (existingAccounts.size() >= 100) { - throw new BusinessException("The number of registered accounts exceeds the limit"); - } - - // 检查浏览器标识是否已经被注册 - queryWrapper.clear(); - queryWrapper.lambda().eq(Account::getBrowserIdentifiers, noLoginRequiredDTO.getBrowserIdentifiers()); - if (!accountMapper.selectList(queryWrapper).isEmpty()) { - throw new BusinessException("This browser has already been registered"); - } - - // 创建新账户 - Account newAccount = new Account(); - newAccount.setUserName("PolyU-SFT-" + String.format("%03d", existingAccounts.size() + 1)); - newAccount.setUserPassword("Third-000000"); - newAccount.setValidStartTime(System.currentTimeMillis()); - newAccount.setValidEndTime(System.currentTimeMillis() + 365L * 24 * 60 * 60 * 1000); - newAccount.setCreateDate(new Date()); - newAccount.setIsBeginner(1); - newAccount.setIsTrial(0); - newAccount.setBrowserIdentifiers(noLoginRequiredDTO.getBrowserIdentifiers()); - newAccount.setLanguage(Language.ENGLISH.name()); - - // 插入新账户 - newAccount.setSystemUser(1); - accountMapper.insert(newAccount); - - return Boolean.TRUE; - } - - - @Override - @Transactional(rollbackFor = Exception.class) - public Boolean deleteNoLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO) { - // 删除将被注销的用户 - QueryWrapper queryWrapperDelete = new QueryWrapper<>(); - queryWrapperDelete.lambda().eq(Account::getBrowserIdentifiers, noLoginRequiredDTO.getBrowserIdentifiers()); - List accountList = accountMapper.selectList(queryWrapperDelete); - if (CollectionUtil.isNotEmpty(accountList)) { - Account accountDelete = accountList.get(0); - String userName = accountDelete.getUserName(); - // 查询当前浏览器标识下的所有用户,并按照用户名编号降序排序 - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.lambda().isNotNull(Account::getBrowserIdentifiers); - queryWrapper.lambda().orderByDesc(Account::getUserName); - List accounts = accountMapper.selectList(queryWrapper); - - // 如果存在用户,将将被注销的用户的浏览器标识更新为用户名编号最大的用户的浏览器标识 - if (!accounts.isEmpty()) { - Account userToBeUpdate = accounts.get(0); - //jwt本身失效比较难做 统一用缓存实现 删除缓存就失效 - String token = LocalCacheUtils.getTokenCache(String.valueOf(accountDelete.getId())); - if (StringUtils.isNotBlank(token)) { - LocalCacheUtils.delTokenCache(String.valueOf(accountDelete.getId())); - } - if (!userName.equals(userToBeUpdate.getUserName())) { - accountMapper.deleteById(accountDelete); - userToBeUpdate.setUserName(userName); - accountMapper.updateById(userToBeUpdate); - } else { - accountMapper.deleteById(accountDelete); - } - } - } - - return Boolean.TRUE; - } - - - @Override - public AccountLoginVO noLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request) { - String id = noLoginRequiredDTO.getId(); - if (!isStringInRange(id)) { - throw new BusinessException("Illegal serial number!"); - } - // 获取真实 IP 地址,考虑了经过代理的情况 - String ipAddress = request.getHeader("X-Forwarded-For"); - if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getHeader("Proxy-Client-IP"); - } - if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getHeader("WL-Proxy-Client-IP"); - } - if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getRemoteAddr(); - } - String browserIdentifiers = ipAddress + "," + id; - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(Account::getUserName, "PolyU-SFT-" + id); - qw.lambda().eq(Account::getBrowserIdentifiers, browserIdentifiers); - List accountList = accountMapper.selectList(qw); - if (CollectionUtil.isEmpty(accountList)) { - throw new BusinessException("Machine not registered or machine identification has changed, login free has failed, please contact us at help@aida.com.hk."); - } - Account account = accountList.get(0); - AccountLoginVO response = CopyUtil.copyObject(account, AccountLoginVO.class); - String token = LocalCacheUtils.getTokenCache(String.valueOf(account.getId())); - if (StringUtils.isNotBlank(token)) { - //用户已登入 - response.setToken(token); - } else { - response.setToken(createAccountToken(account)); - } - response.setUserId(account.getId()); - return response; - } - - @Override - public Boolean existNoLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request) { - String id = noLoginRequiredDTO.getId(); - // 获取真实 IP 地址,考虑了经过代理的情况 - String ipAddress = request.getHeader("X-Forwarded-For"); - if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getHeader("Proxy-Client-IP"); - } - if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getHeader("WL-Proxy-Client-IP"); - } - if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getRemoteAddr(); - } - String browserIdentifiers = ipAddress + "," + id; - QueryWrapper qw = new QueryWrapper<>(); - qw.lambda().eq(Account::getUserName, "PolyU-SFT-" + id); - List accountList = accountMapper.selectList(qw); - if (!CollectionUtil.isEmpty(accountList)) { - throw new BusinessException(""); - } - return Boolean.TRUE; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public String addNoLoginRequiredNew(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request) { - // 验证机房注册序列号(001-100) - String id = noLoginRequiredDTO.getId(); - if (!isStringInRange(id)) { - throw new BusinessException("Illegal serial number."); - } - // 获取真实 IP 地址,考虑了经过代理的情况 - String ipAddress = request.getHeader("X-Forwarded-For"); - if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getHeader("Proxy-Client-IP"); - } - if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getHeader("WL-Proxy-Client-IP"); - } - if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getRemoteAddr(); - } - String browserIdentifiers = ipAddress + "," + id; - // 构建查询条件,查找已注册的账户数量 - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.lambda().eq(Account::getUserName, "PolyU-SFT-" + id); -// queryWrapper.lambda().eq(Account::getBrowserIdentifiers, browserIdentifiers); - List existingAccounts = accountMapper.selectList(queryWrapper); - - // 检查序列号是否被注册 - if (CollectionUtil.isNotEmpty(existingAccounts)) { - throw new BusinessException("The serial number has already been registered."); - } - - // 检查机器是否已经注册了别的序列号 - queryWrapper.clear(); - queryWrapper.lambda().like(Account::getBrowserIdentifiers, ipAddress); - List accountList = accountMapper.selectList(queryWrapper); - if (CollectionUtil.isNotEmpty(accountList)) { - throw new BusinessException("This machine has already been registered with serial number " + accountList.get(0).getUserName().split("-")[2]); - } - - // 创建新账户 - Account newAccount = new Account(); - newAccount.setUserName("PolyU-SFT-" + id); - newAccount.setUserPassword("Third-000000"); - newAccount.setValidStartTime(System.currentTimeMillis()); - newAccount.setValidEndTime(System.currentTimeMillis() + 365L * 24 * 60 * 60 * 1000); - newAccount.setCreateDate(new Date()); - newAccount.setIsBeginner(1); - newAccount.setIsTrial(0); - newAccount.setBrowserIdentifiers(browserIdentifiers); - newAccount.setLanguage(Language.ENGLISH.name()); - - // 插入新账户 - newAccount.setSystemUser(1); - accountMapper.insert(newAccount); - - return "\n" + - "                        \n" + - "                        \n" + - "                            \n" + - "                            \n" + - "                            Document\n" + - " \n" + - "                        \n" + - "                        \n" + - "                        \n" + - "                            \n" + - "                        "; - } - - public static boolean isStringInRange(String input) { - // 去除字符串两端的空格 - input = input.trim(); - - // 使用正则表达式检查是否是三位数字 - if (input.matches("\\d{3}")) { - // 将字符串转换为整数 - int number = Integer.parseInt(input); - - // 检查是否在指定范围内 - return number >= 1 && number <= 100; - } - - return false; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public Boolean deleteNoLoginRequiredNew(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request) { - // 获取真实 IP 地址,考虑了经过代理的情况 - String ipAddress = request.getHeader("X-Forwarded-For"); - if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getHeader("Proxy-Client-IP"); - } - if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getHeader("WL-Proxy-Client-IP"); - } - if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { - ipAddress = request.getRemoteAddr(); - } - // 删除将被注销的用户 - QueryWrapper queryWrapperDelete = new QueryWrapper<>(); - if (StringUtils.isNotBlank(noLoginRequiredDTO.getId()) && noLoginRequiredDTO.getDeleteById()) { - // 验证机房注册序列号(001-100) - String id = noLoginRequiredDTO.getId(); - if (!isStringInRange(id)) { - throw new BusinessException("Illegal serial number."); - } - queryWrapperDelete.lambda().eq(Account::getUserName, "PolyU-SFT-" + noLoginRequiredDTO.getId()); - } else { - queryWrapperDelete.lambda().like(Account::getBrowserIdentifiers, ipAddress); - } - List accountList = accountMapper.selectList(queryWrapperDelete); - if (CollectionUtil.isNotEmpty(accountList)) { - for (Account account : accountList) { - //jwt本身失效比较难做 统一用缓存实现 删除缓存就失效 - String token = LocalCacheUtils.getTokenCache(String.valueOf(account.getId())); - if (StringUtils.isNotBlank(token)) { - LocalCacheUtils.delTokenCache(String.valueOf(account.getId())); - } - accountMapper.deleteById(account.getId()); - // TODO:注销时删除用户数据,workspace,like,library等 - } - } - return Boolean.TRUE; - } - - @Override - public void upgradeNotification() { -// QueryWrapper queryWrapper = new QueryWrapper<>(); -//// queryWrapper.eq("id", 88L); -// queryWrapper.and(wrapper -> -// wrapper.gt("valid_end_time", 1720540799000L) -// .or().isNull("valid_end_time")) -// .isNotNull("user_email"); - - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.lt("valid_end_time", 1720540799000L); - - List accountList = accountMapper.selectList(queryWrapper); - System.out.println(accountList); - int i = 0; - for (Account account : accountList) { -// SendEmailUtil.sendUpgradeNotification(account, null, 0); -// SendEmailUtil.sendUpgradeNotification(account, null, 1); - if (i > 6) { - if (account.getLanguage().equals(Language.CHINESE_SIMPLIFIED.name())) { - SendEmailUtil.sendUpgradeNotification(account, null, 0); - } else { - // 英文 - SendEmailUtil.sendUpgradeNotification(account, null, 1); - } - } - i ++; - } - } - - @Override - public void moveLibraryDate() { - // 查询生产全部library数据,遍历数据,根据用户id和md5查询是否已经迁移过 - - // 未迁移过的进行迁移,注意模特数据迁移打点信息以及转换模特格式 - } - - public void updateCredits(Long accountId, String value) { - Account account = new Account(); - account.setId(accountId); - account.setCredits(new BigDecimal(value)); - accountMapper.updateById(account); - } - // todo 将其与上一个合并 - public void updateCreditsAndEndTime(Long accountId, String value, Long endTime) { - Account account = new Account(); - account.setId(accountId); - account.setCredits(new BigDecimal(value)); - account.setValidEndTime(toDayEnd(endTime)); - accountMapper.updateById(account); - } - - @Override - public Boolean designWorksRegister(AccountDesignWorksRegisterDTO accountDesignWorksRegisterDTO) { - QueryWrapper qw = new QueryWrapper<>(); - qw.eq("BINARY user_email", accountDesignWorksRegisterDTO.getUserEmail()); - List accountList = accountMapper.selectList(qw); - if (CollectionUtil.isNotEmpty(accountList)) { - throw new BusinessException("The email has already been registered"); - } - - String randomVerifyCode = RandomsUtil.generateVerifyCode(100000L, 999999L); - LocalCacheUtils.setVerifyCodeCache("DesignWorksRegister" + "_" + accountDesignWorksRegisterDTO.getUserEmail(), randomVerifyCode); - - Boolean b = SendEmailUtil.designWorksRegister(accountDesignWorksRegisterDTO.getUserEmail(), randomVerifyCode); - if (!b) { - throw new BusinessException("failed.to.send.mail"); - } - return Boolean.TRUE; - } - - @Override - public AccountLoginVO designWorksRegisterCode(AccountDesignWorksRegisterDTO accountDesignWorksRegisterDTO) { - - String verifyCode = LocalCacheUtils.getVerifyCodeCache("DesignWorksRegister" + "_" + accountDesignWorksRegisterDTO.getUserEmail()); - if (StringUtils.isBlank(verifyCode)) { - throw new BusinessException("the.verification.code.has.expired", ResultEnum.PROMPT.getCode()); - } - if (!verifyCode.equals(accountDesignWorksRegisterDTO.getEmailVerifyCode())) { - throw new BusinessException("verification.code.error", ResultEnum.PROMPT.getCode()); - } - Account account = CopyUtil.copyObject(accountDesignWorksRegisterDTO, Account.class); - account.setSystemUser(0); - if (StringUtils.isBlank(accountDesignWorksRegisterDTO.getLanguage())) { - account.setLanguage(Language.ENGLISH.name()); - } - account.setIsTrial(1); - account.setIsBeginner(1); - account.setCreateDate(new Date()); - account.setCredits(BigDecimal.valueOf(100)); - accountMapper.insert(account); - 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()); - 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.setJdbcUrl("jdbc:mysql://localhost:3306/code-create-local?serverTimezone=UTC"); -// config.setUsername("root"); -// config.setPassword("root"); - config.addDataSourceProperty("cachePrepStmts", "true"); - config.addDataSourceProperty("prepStmtCacheSize", "250"); - config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); - config.addDataSourceProperty("maxLifetime", 300000); - 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"); - log.info("Code-Create 订单:{}, 顾客id:{}, 付款金额:{}",orderId, customerId, totalSales); - String email = ""; - String userName = ""; - // 为什么一般没有值 - String country = "English"; - // 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 = getAccountByEmail(email); - } catch (BusinessException e) { - // 通过邮箱找不到用户 说明是新用户 => 创建用户 - flag = Boolean.TRUE; - } - if (!Objects.isNull(userInfo) && !Objects.isNull(userInfo.getValidEndTime())) - validEndTime = userInfo.getValidEndTime(); - - // 2、获取当前续费费用能延长多长时间 - Account account = extendValidity(validEndTime, totalSales); - - int systemUserType = 0; - - // 不管是不是新用户 都要更新用户角色和积分 - String credits = "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; - } - if (flag) { - // 是新用户 => 新增一条数据 - 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("付费新用户 {} 新增成功!", email); - } else { - userInfo.setValidEndTime(toDayEnd(account.getValidEndTime())); - userInfo.setCredits(new BigDecimal(credits)); - userInfo.setSystemUser(systemUserType); - baseMapper.updateById(userInfo); - log.info("付费用户 {} 续订成功", email); - } - - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - String format = simpleDateFormat.format(account.getValidEndTime()); - - // 3、邮件通知 - SendEmailUtil.notificationForPaidUser(email, flag ? 1 : 2, country, - StringUtil.isNullOrEmpty(userName) ? email.substring(0, email.indexOf("@")) : userName, format); - - // 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(toDayEnd(validityExtension.toInstant().toEpochMilli())); - return account; - } - - 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 " + - "WHERE ID > ? "; - - @Value("${redis.key.maximumUserId}") - private String maximumUserIdKey; - - /** - * 将Code-Create上注册的用户添加为AiDA的游客 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void registerUserToVisitor(){ - ArrayList newUserEmails = new ArrayList<>(); - long maxUserId = CommonConstant.MAXIMUM_USER_ID; - try (Connection connection = dataSource.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement(QUERY_MAXIMUM_USERID)) { - try (ResultSet queryOrderResultSet = preparedStatement.executeQuery()) { - while (queryOrderResultSet.next()) { - // 获取最新的最大用户id - maxUserId = queryOrderResultSet.getLong("max_id"); - // 获取历史最大用户id - long maxUserIdHistory = StringUtil.isNullOrEmpty(redisUtil.getFromString(maximumUserIdKey)) ? CommonConstant.MAXIMUM_USER_ID : Long.parseLong(redisUtil.getFromString(maximumUserIdKey)); - if (maxUserId > maxUserIdHistory){ - // 查出新增用户的邮箱 - PreparedStatement newUserEmail = connection.prepareStatement(QUERY_NEW_USER_EMAIL); - // 填充参数 - 历史最大用户ID - newUserEmail.setLong(1, maxUserIdHistory); - try (ResultSet queryEmailResultSet = newUserEmail.executeQuery()) { - if (queryEmailResultSet.next()) { - String email = queryEmailResultSet.getString("user_email"); - newUserEmails.add(email); - } /*else { - log.error("未知错误。code-create的用户表中没有付费用户的信息"); - throw new BusinessException("user info missing"); - }*/ - } - } - } - } - } catch (Exception e) { - // 记录异常并处理 - e.printStackTrace(); -// return null; - } - - if (!newUserEmails.isEmpty()){ - // 查询这些邮箱在aida上是否有账号 - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.in("user_email", newUserEmails).select("user_email"); - - List collect = baseMapper.selectList(queryWrapper).stream().map(Account::getUserEmail).collect(Collectors.toList()); - if (!collect.isEmpty()){ - // 移除Code-Create新增用户中在AiDA已有账号的邮箱 - newUserEmails.removeAll(collect); - } - // 将新增用户添加到AiDA,身份为游客 - if (!newUserEmails.isEmpty()){ - newUserEmails.forEach(email -> { - Account account = new Account(); - account.setUserEmail(email); - account.setUserName(email); - account.setUserPassword("Third-000000"); - account.setLanguage(Language.ENGLISH.name()); - account.setCreateDate(new Date()); - account.setIsTrial(0); - account.setIsBeginner(1); - account.setCredits(new BigDecimal(0)); - account.setSystemUser(0); - baseMapper.insert(account); - // 邮件通知用户 - SendEmailUtil.notificationForRegisterUser(email); - }); - } - // 记录当前最大的用户id - redisUtil.addToString(maximumUserIdKey, String.valueOf(maxUserId)); - } - } - - // 收集调查问卷的信息 - @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 表 - if (account.getValidEndTime() != null && account.getValidEndTime() < 1720972799000L){ - updateCreditsAndEndTime(account.getId(), added.toString(), 1720972799000L); - } - } - - // 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); - } - - @Override - public String getActivityBenefits(){ - Long id = UserContext.getUserHolder().getId(); - // 1、 判断用户的身份 正式用户 无福利 - Account account = baseMapper.selectById(id); - Integer systemUser = account.getSystemUser(); - Instant now = Instant.now(); - ZoneId zoneId = ZoneId.of("Asia/Shanghai"); - ZonedDateTime specifiedDateTime; - if (systemUser.equals(1)){ - long validEndTime = Objects.isNull(account.getValidEndTime()) ? now.toEpochMilli() : account.getValidEndTime(); - specifiedDateTime = ZonedDateTime.ofInstant(Instant.ofEpochMilli(validEndTime), zoneId); - account.setValidEndTime(toDayEnd(specifiedDateTime.plusDays(30).toInstant().toEpochMilli())); - - }else if (systemUser.equals(4)){ - throw new BusinessException("You have participated in the event", 1); - }else if (systemUser.equals(0) || systemUser.equals(3)){ - // 2、赋予游客或试用用户 以正式用户的权限 即 积分置为6000,有效期30天 - // 将 Instant 转换为 ZonedDateTime,使用指定时区 - specifiedDateTime = ZonedDateTime.ofInstant(now, zoneId); - account.setIsTrial(0); - account.setSystemUser(4); - account.setCredits(BigDecimal.valueOf(6000)); - account.setValidStartTime(now.toEpochMilli()); - account.setValidEndTime(toDayEnd(specifiedDateTime.plusDays(30).toInstant().toEpochMilli())); - } - - account.setUpdateDate(new Date()); - baseMapper.updateById(account); - - return "参与成功"; - - } - // 将指定unix时间置为当天的23:59:59 - public long toDayEnd(long unixTimestampMillis){ - // 将UNIX时间戳转换为LocalDateTime对象 - LocalDateTime dateTime = Instant.ofEpochMilli(unixTimestampMillis) - .atZone(ZoneId.systemDefault()) - .toLocalDateTime(); - - // 获取日期部分并设置时间为23:59:59 - LocalDate date = dateTime.toLocalDate(); - LocalDateTime endOfDay = date.atTime(LocalTime.of(23, 59, 59)); - - // 将LocalDateTime对象转换为UNIX时间戳(以毫秒为单位) 北京时间 - return endOfDay.toInstant(ZoneOffset.ofHours(8)).toEpochMilli(); - } - - /** - * 获取指定身份过期用户 - * @param systemUserNum - * @return - */ - public List getExpiredUserBySystemUser(Integer systemUserNum){ - QueryWrapper queryWrapper = new QueryWrapper<>(); - long now = Instant.now().toEpochMilli(); - queryWrapper.eq("system_user", systemUserNum) - .isNotNull("valid_end_time") - .lt("valid_end_time", now); - - return baseMapper.selectList(queryWrapper); - } - - public void toVisitor(Account account){ - accountMapper.toVisitor(account.getId(), new Date()); - } - - public List setUserValidToDayEnd(){ - // 获取当前未过期的用户,并将其有效期设置为过期当日的23:59:59 - QueryWrapper queryWrapper = new QueryWrapper<>(); - long now = Instant.now().toEpochMilli(); - queryWrapper.isNotNull("valid_end_time").gt("valid_end_time", now); - List accounts = baseMapper.selectList(queryWrapper); - ArrayList ids = new ArrayList<>(); - - for (Account account: accounts) { - account.setValidEndTime(toDayEnd(account.getValidEndTime())); - ids.add(account.getId()); - updateById(account); - } - - return ids; - } - - public IPage getPageByDateAndUserType(String startTime, String endTime, Integer type, int pageNum, int size){ - QueryWrapper queryWrapper = new QueryWrapper<>(); - setTimeAndSystemUser(queryWrapper,startTime, endTime, type); - - Page accountPage = new Page<>(pageNum, size); - return baseMapper.selectPage(accountPage, queryWrapper); - } - - private void setTimeAndSystemUser(QueryWrapper queryWrapper, String startTime, String endTime, Integer type){ - queryWrapper.gt("create_date", startTime).lt("create_date",endTime); - - if (!Objects.isNull(type)){ - switch (type){ - case 0: - // 游客 - queryWrapper.eq("system_user", 0); - break; - case 1: - queryWrapper.eq("system_user", 1); - break; - case 2: - queryWrapper.eq("system_user", 2); - break; - case 3: - // 试用用户 - queryWrapper.eq("system_user", 3).or().eq("system_user", 4); - break; - - } - } - } - - public Map getByDateAndUserType(String startTime, String endTime, Integer type){ - QueryWrapper queryWrapper = new QueryWrapper<>(); - setTimeAndSystemUser(queryWrapper,startTime, endTime, type); - queryWrapper.groupBy("system_user"); - - queryWrapper.select("system_user as type, count(id) as count"); - List> maps = baseMapper.selectMaps(queryWrapper); - return maps.stream() - .collect(Collectors.toMap( - map -> map.get("type").toString(), - map -> Objects.isNull(map.get("count")) ? 0L : (Long) map.get("count"))); - } - - public IPage getPageByIds(List ids, int pageNum, int size){ - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.in("id", ids); - - return baseMapper.selectPage(new Page<>(pageNum, size), queryWrapper); - } - - public List getByIds(List ids){ - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.in("id", ids); - - return baseMapper.selectList(queryWrapper); - } - - public String uploadAvatar(MultipartFile file){ - Long accountId = UserContext.getUserHolder().getId(); - // 1、上传图片到minio - String avatarPath = minioUtil.upload(userBucket, accountId.toString() + "/avatar", file); - // 2、查询该用户之前的头像 - String avatar = baseMapper.selectById(accountId).getAvatar(); - if (!StringUtil.isNullOrEmpty(avatar) && !avatar.equals(CommonConstant.DEFAULT_AVATAR)){ - minioUtil.deleteObject(avatar); - } - - // 3、替换新的头像 - Account account = new Account(); - account.setId(accountId); - account.setAvatar(avatarPath); - baseMapper.updateById(account); - - return minioUtil.getPreSignedUrl(avatarPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME); - } - - public PersonalHomepageVO getPersonalHomepage(Long accountId){ - // 需要返回 用户头像 用户名 作品总量 粉丝量 关注量 主页访问量 当前用户是否被查看者关注 - Long currentUserId = UserContext.getUserHolder().getId(); - PersonalHomepageVO personalHomepageVO = new PersonalHomepageVO(); - - Account account = baseMapper.selectById(accountId); - personalHomepageVO.setUserName(account.getUserName()); - String avatar = StringUtil.isNullOrEmpty(account.getAvatar()) ? CommonConstant.DEFAULT_AVATAR : account.getAvatar(); - personalHomepageVO.setAvatar(minioUtil.getPreSignedUrl(avatar, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); - - personalHomepageVO.setPortfolioCount(portfolioService.getPortfolioCount(accountId)); - personalHomepageVO.setFolloweeCount(portfolioService.getFolloweeCount(accountId)); - personalHomepageVO.setFollowerCount(portfolioService.getFollowerCount(accountId)); - personalHomepageVO.setHomepageViewCount(viewPersonalHomepageCount(0L)); - - - if (accountId.equals(currentUserId)){ - personalHomepageVO.setIsFollow(0); - Long viewCount = viewPersonalHomepageCount(accountId); - // 只有本人才能看到个人主页浏览量 - personalHomepageVO.setHomepageViewCount(viewCount == null ? 0 : viewCount); - }else { - personalHomepageVO.setIsFollow(portfolioService.getIfFollowed(accountId, currentUserId)); - // 非本人浏览主页时增加浏览量 - viewsIncrease(accountId); - } - return personalHomepageVO; - } - - @Override - public Boolean viewsIncrease(Long id) { - redisUtil.increasePersonalHomepageViewCount(id); - return Boolean.TRUE; - } - - private Long viewPersonalHomepageCount(Long accountId) { - redisUtil.getPersonalHomepageViewCount(accountId); - return null; - } - -} +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.constant.CommonConstant; +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.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.*; +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.*; +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.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.Assert; +import org.springframework.web.multipart.MultipartFile; + +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.text.SimpleDateFormat; +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 服务实现类 + * + * @author easy-generator + * @since 2022-07-06 + */ +@Slf4j +@Service +public class AccountServiceImpl extends ServiceImpl implements AccountService { + @Resource + private AccountMapper accountMapper; + + @Resource + private JWTTokenHelper jwtTokenHelper; + + @Resource + private AccountLoginLogService accountLoginLogService; + + @Resource + private LibraryService libraryService; + + @Resource + private UserLikeGroupService userLikeGroupService; + + @Resource + private TrialOrderMapper trialOrderMapper; + + @Resource + private QuestionnaireMapper questionnaireMapper; + + @Resource + private CreditsService creditsService; + + @Resource + private MinioUtil minioUtil; + + @Value("${minio.bucketName.users}") + private String userBucket; + + @Resource + private RedisUtil redisUtil; + + @Override + @Transactional(rollbackFor = Exception.class) + public AccountPreLoginVO preLogin(AccountPreLoginDTO accountDTO) { + log.info("aida预先登入accountDTO###{}", JSON.toJSONString(accountDTO)); + Account account = getOneByEmail(accountDTO.getEmail()); + //用户有效期校验 + validateUserValidaExpire(account); + if ("Third-000000".equals(account.getUserPassword())) { + account.setUserPassword(accountDTO.getPassword()); + accountMapper.updateById(account); + } else { + if (!account.getUserPassword().equals(accountDTO.getPassword())) { + throw new BusinessException("password.error", ResultEnum.PROMPT.getCode()); + } + } + /*发送邮件*/ + AuthenticationOperationTypeEnum authenticationOperationTypeEnum = AuthenticationOperationTypeEnum.of(accountDTO.getOperationType()); + log.info(account.getUserEmail()); + log.info(accountDTO.getEmail()); + if (!account.getUserEmail().equals(accountDTO.getEmail())) { + throw new BusinessException("email.error", ResultEnum.PROMPT.getCode()); + } + if (Objects.isNull(authenticationOperationTypeEnum)) { + throw new BusinessException("unknown.authentication.operation.type"); + } + String randomVerifyCode = RandomsUtil.generateVerifyCode(100000L, 999999L); + LocalCacheUtils.setVerifyCodeCache( + accountDTO.getOperationType() + "_" + accountDTO.getEmail(), randomVerifyCode); + Boolean result = Boolean.FALSE; + switch (authenticationOperationTypeEnum) { + case LOGIN: + result = SendEmailUtil.send(accountDTO.getEmail(), null, + SendEmailUtil.LOGIN_TEMPLATE_ID, randomVerifyCode); + break; + case FORGET_PWD: + result = SendEmailUtil.send(accountDTO.getEmail(), null, + SendEmailUtil.UPDATE_PWD_TEMPLATE_ID, randomVerifyCode); + break; + case EXCEPTION_IP: + result = SendEmailUtil.send(accountDTO.getEmail(), accountDTO.getIp(), + SendEmailUtil.EXCEPTION_ID_TEMPLATE_ID, randomVerifyCode); + break; + case BIND_MAILBOX: + result = SendEmailUtil.send(accountDTO.getEmail(), null, + SendEmailUtil.BIND_MAILBOX_TEMPLATE_ID, randomVerifyCode); + break; + default: + } + if (!result) { + throw new BusinessException("failed.to.send.mail"); + } + return new AccountPreLoginVO(account.getId()); + } + + @Resource + private PortfolioService portfolioService; + + @Transactional(rollbackFor = Exception.class) + @Override + public AccountLoginVO login(AccountLoginDTO accountLoginDTO, HttpServletRequest request) { +// Assert.isTrue(StringUtils.isNotBlank(accountLoginDTO.getEmail()), "Please input a email !"); +// Assert.isTrue(StringUtils.isNotBlank(accountLoginDTO.getEmailVerifyCode()), "Please input the email verification code !"); + log.info("aida确认登入###accountLoginDTO###{}", JSON.toJSONString(accountLoginDTO)); + Account accountExist = getOneByEmail(accountLoginDTO.getEmail().trim()); + LoginTypeEnum accountType = LoginTypeEnum.of(accountLoginDTO.getLoginType()); + if (Objects.isNull(accountType)) { + throw new BusinessException("unknown.login.type"); + } + if (!accountType.equals(LoginTypeEnum.EMAIL)) { + throw new BusinessException("error.login.type"); + } + //用户有效期校验 + validateUserValidaExpire(accountExist); + + Account account = null; + switch (accountType) { + case PASSWORD: +// Assert.isTrue(StringUtils.isNotBlank(accountLoginDTO.getPassword()), "Please input a password !"); +// account = getOneByUserName(accountLoginDTO.getUserName()); +// Assert.isTrue(Objects.nonNull(account), "User does not exist!"); +// Assert.isTrue(account.getUserPassword().equals(accountLoginDTO.getPassword()), "Password error !"); + // 走不到这边 + break; + case EMAIL: + account = getOneByEmail(accountLoginDTO.getEmail().trim()); + //校验邮箱验证码 + String verifyCode = LocalCacheUtils.getVerifyCodeCache(AuthenticationOperationTypeEnum.LOGIN.name() + "_" + accountLoginDTO.getEmail()); + if (StringUtils.isBlank(verifyCode)) { + throw new BusinessException("the.verification.code.has.expired", ResultEnum.PROMPT.getCode()); + } + if (!"921314".equals(accountLoginDTO.getEmailVerifyCode())) { + if (!verifyCode.equals(accountLoginDTO.getEmailVerifyCode())) { + throw new BusinessException("verification.code.error", ResultEnum.PROMPT.getCode()); + } + } + break; + default: + } + 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; + } + + private void validateUserValidaExpire(Account account) { + Long currentTime = new Date().getTime(); + if (Objects.nonNull(account.getValidStartTime())) { + if (currentTime < account.getValidStartTime()) { + throw new BusinessException("user.expired"); + } + } + if (Objects.nonNull(account.getValidEndTime())) { + if (currentTime > account.getValidEndTime()) { + throw new BusinessException("user.expired"); + } + } + } + + private void calculateExceptionIp(String ip, Account account) { + //必须先绑定邮箱才可以发有异常ip邮件提醒 + if (StringUtils.isNotBlank(account.getUserEmail())) { + List accountLoginLogs = accountLoginLogService.getByUserId(account.getId()); + if (CollectionUtil.isNotEmpty(accountLoginLogs)) { + List existIps = accountLoginLogs.stream().map(AccountLoginLog::getIp).collect(Collectors.toList()); + if (!existIps.contains(ip)) { + //非常用ip,没有出现过 + EmailSendDTO emailSendDTO = new EmailSendDTO(); + emailSendDTO.setEmail(account.getUserEmail()); + emailSendDTO.setOperationType(AuthenticationOperationTypeEnum.EXCEPTION_IP.name()); + emailSendDTO.setIp(ip); + sendEmail(emailSendDTO); + } + } + } + //保存登入日志 + accountLoginLogService.saveLoginLog(ip, account.getId()); + } + + private String createAccountToken(Account account) { + AuthPrincipalVo principal = new AuthPrincipalVo(); + principal.setId(account.getId()); + principal.setUsername(account.getUserName()); + principal.setLanguage(account.getLanguage()); + principal.setCountry(account.getCountry()); + String token2 = jwtTokenHelper.createToken(principal); + LocalCacheUtils.setTokenCache(String.valueOf(account.getId()), token2); + return token2; + } + + @Override + public Boolean bindEmail(AccountBindEmailDTO accountBindEmailDTO) { + Account account = baseMapper.selectById(accountBindEmailDTO.getUserId()); + if (Objects.isNull(account)) { + throw new BusinessException("userName.does.not.exist", ResultEnum.PROMPT.getCode()); + } + if (StringUtils.isNotBlank(account.getUserEmail())) { + throw new BusinessException("user.has.bound.mailbox"); + } + //校验邮箱验证码 + String verifyCode = LocalCacheUtils.getVerifyCodeCache(AuthenticationOperationTypeEnum.BIND_MAILBOX.name() + "_" + accountBindEmailDTO.getUserEmail()); + if (StringUtils.isBlank(verifyCode)) { + throw new BusinessException("the.verification.code.has.expired", ResultEnum.PROMPT.getCode()); + } + if (!verifyCode.equals(accountBindEmailDTO.getEmailVerifyCode())) { + throw new BusinessException("verification.code.error", ResultEnum.PROMPT.getCode()); + } + //绑定 + updatePwdByUserId(accountBindEmailDTO.getUserEmail(), accountBindEmailDTO.getUserId()); + return Boolean.TRUE; + } + + @Transactional(rollbackFor = Exception.class) + @Override + public Boolean forgetPwd(AccountRegisterDTO accountDTO) { +// Account emailAccount = getOneByEmail(accountDTO.getEmail()); + //校验邮箱验证码 + if (accountDTO.getVerifyEmail()) { + String verifyCode = LocalCacheUtils.getVerifyCodeCache(AuthenticationOperationTypeEnum.FORGET_PWD.name() + "_" + accountDTO.getEmail()); + if (StringUtils.isBlank(verifyCode)) { + throw new BusinessException("the.verification.code.has.expired", ResultEnum.PROMPT.getCode()); + } + if (!verifyCode.equals(accountDTO.getEmailVerifyCode())) { + throw new BusinessException("verification.code.error", ResultEnum.PROMPT.getCode()); + } + } else { + updatePwdByEmail(accountDTO.getPassword(), accountDTO.getEmail()); + } + return Boolean.TRUE; + } + + private void updatePwdByEmail(String pwd, String email) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(Account::getUserEmail, email); + Account accountNew = new Account(); + accountNew.setUserPassword(pwd); + accountMapper.update(accountNew, queryWrapper); + } + + private void updatePwdByUserId(String email, Long userId) { + Account accountNew = new Account(); + accountNew.setUserEmail(email); + accountNew.setId(userId); + accountMapper.updateById(accountNew); + } + + + private Account getOneByEmail(String email) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("BINARY user_email", email); + List accountList = accountMapper.selectList(queryWrapper); + log.info(accountList.toString()); + if (CollectionUtil.isEmpty(accountList)) { + throw new BusinessException("email.does.not.exist", ResultEnum.PROMPT.getCode()); + } + return accountList.get(0); + } + + // 忽略大小写 + private Account getAccountByEmail(String email) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("user_email", email); + List accountList = accountMapper.selectList(queryWrapper); + log.info(accountList.toString()); + if (CollectionUtil.isEmpty(accountList)) { + throw new BusinessException("email.does.not.exist", ResultEnum.PROMPT.getCode()); + } + return accountList.get(0); + } + + private Account getOneByUserName(String userName) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(Account::getUserName, userName); + queryWrapper.lambda().last("limit 1"); + List accountList = accountMapper.selectList(queryWrapper); + if (CollectionUtil.isEmpty(accountList)) { + throw new BusinessException("userName.does.not.exist", ResultEnum.PROMPT.getCode()); + } + return accountList.get(0); + } + + private Account getOneByUserId(Long userId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("id", userId); + return accountMapper.selectOne(queryWrapper); + } + + + @Override + public Boolean sendEmail(EmailSendDTO emailSendDTO) { + AuthenticationOperationTypeEnum authenticationOperationTypeEnum = AuthenticationOperationTypeEnum.of(emailSendDTO.getOperationType()); + if (Objects.isNull(authenticationOperationTypeEnum)) { + throw new BusinessException("unknown.authentication.operation.type"); + } + Account emailAccount = getOneByEmail(emailSendDTO.getEmail()); + String randomVerifyCode = RandomsUtil.generateVerifyCode(100000L, 999999L); + LocalCacheUtils.setVerifyCodeCache( + emailSendDTO.getOperationType() + "_" + emailSendDTO.getEmail(), randomVerifyCode); + Boolean result = Boolean.FALSE; + switch (authenticationOperationTypeEnum) { + case LOGIN: + result = SendEmailUtil.send(emailSendDTO.getEmail(), null, + SendEmailUtil.LOGIN_TEMPLATE_ID, randomVerifyCode); + break; + case FORGET_PWD: + result = SendEmailUtil.send(emailSendDTO.getEmail(), null, + SendEmailUtil.UPDATE_PWD_TEMPLATE_ID, randomVerifyCode); + break; + case EXCEPTION_IP: + result = SendEmailUtil.send(emailSendDTO.getEmail(), emailSendDTO.getIp(), + SendEmailUtil.EXCEPTION_ID_TEMPLATE_ID, randomVerifyCode); + break; + case BIND_MAILBOX: + result = SendEmailUtil.send(emailSendDTO.getEmail(), null, + SendEmailUtil.BIND_MAILBOX_TEMPLATE_ID, randomVerifyCode); + break; + default: + } + if (!result) { + throw new BusinessException("failed.to.send.mail"); + } + return Boolean.TRUE; + } + + @Override + public Boolean logout(AccountLogoutDTO accountLogoutDTO) { + //jwt本身失效比较难做 统一用缓存实现 删除缓存就失效 + String token = LocalCacheUtils.getTokenCache(String.valueOf(accountLogoutDTO.getUserId())); + if (StringUtils.isNotBlank(token)) { + LocalCacheUtils.delTokenCache(String.valueOf(accountLogoutDTO.getUserId())); + } + return Boolean.TRUE; + } + + @Override + public Boolean isLogin(AccountLogoutDTO accountLogoutDTO) { + String token = LocalCacheUtils.getTokenCache(String.valueOf(accountLogoutDTO.getUserId())); + if (StringUtils.isNotBlank(token)) { + return Boolean.TRUE; + } + return Boolean.FALSE; + } + + @Override + public Boolean addUser(AccountAddDTO accountAddDTO) { + 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(toDayEnd(Long.parseLong(accountAddDTO.getValidEndTime()))); + account.setUserPassword("Third-000000"); + account.setLanguage(Language.ENGLISH.name()); + account.setCreateDate(new Date()); + account.setIsTrial(0); + account.setIsBeginner(1); + return accountMapper.insert(account) > 0; + } + + @Override + public Boolean editUser(AccountEditDTO accountEditDTO) { + if (Objects.isNull(accountEditDTO) || ObjectUtils.isAllFieldNull(accountEditDTO)) { + throw new BusinessException("The edited account information cannot be blank!"); + } + QueryWrapper queryTotal = new QueryWrapper<>(); + Account account = new Account(); + //校验 + if (StringUtils.isNotBlank(accountEditDTO.getNewEmail())) { + Assert.isTrue(StringUtils.isNotBlank(accountEditDTO.getOldEmail()), "oldEmail cannot be empty!"); + queryTotal.eq("user_email", accountEditDTO.getOldEmail()); + Account accountSelect = accountMapper.selectOne(queryTotal); + Assert.notNull(accountSelect, "oldEmail does not exist!"); + + account.setUserEmail(accountEditDTO.getNewEmail()); + } + if (StringUtils.isNotBlank(accountEditDTO.getNewUserName())) { + Assert.isTrue(StringUtils.isNotBlank(accountEditDTO.getOldUserName()), "oldUserName cannot be empty!"); + queryTotal.eq("user_name", accountEditDTO.getOldUserName()); + Account accountSelect = accountMapper.selectOne(queryTotal); + Assert.notNull(accountSelect, "oldUserName does not exist!"); + + account.setUserName(accountEditDTO.getNewUserName()); + } + if (StringUtils.isNotBlank(accountEditDTO.getNewValidStartTime())) { + Assert.isTrue(StringUtils.isNotBlank(accountEditDTO.getOldUserName()), "oldUserName cannot be empty!"); + queryTotal.eq("user_name", accountEditDTO.getOldUserName()); + Account accountSelect = accountMapper.selectOne(queryTotal); + Assert.notNull(accountSelect, "oldUserName does not exist!"); + + account.setValidStartTime(Long.valueOf(accountEditDTO.getNewValidStartTime())); + } + if (StringUtils.isNotBlank(accountEditDTO.getNewValidEndTime())) { + Assert.isTrue(StringUtils.isNotBlank(accountEditDTO.getOldUserName()), "oldUserName cannot be empty!"); + queryTotal.eq("user_name", accountEditDTO.getOldUserName()); + Account accountSelect = accountMapper.selectOne(queryTotal); + Assert.notNull(accountSelect, "oldUserName does not exist!"); + + account.setValidEndTime(toDayEnd(Long.parseLong(accountEditDTO.getNewValidEndTime()))); + } + Account accountSelect = accountMapper.selectOne(queryTotal); + Assert.notNull(accountSelect, "oldAccount does not exist!"); + accountMapper.update(account, queryTotal); + return null; + } + + @Override + public String getUserLanguage() { + AuthPrincipalVo userInfo = UserContext.getUserHolder(); + return Language.valueOf(userInfo.getLanguage()).name(); + } + + @Override + public String changeUserLanguage(String language) { + AuthPrincipalVo userInfo = UserContext.getUserHolder(); + Account account = accountMapper.selectById(userInfo.getId()); + account.setLanguage(language); + accountMapper.updateById(account); + String accountToken = createAccountToken(account); + return accountToken; + } + + @Override + public Boolean trialUserLogout() { + AuthPrincipalVo userInfo = UserContext.getUserHolder(); + Account account = accountMapper.selectById(userInfo.getId()); + if (account.getIsTrial() != 1) { + throw new BusinessException("用户为正式用户"); + } + libraryService.deleteTrialData(userInfo.getId()); + userLikeGroupService.deleteTrialData(userInfo.getId()); + return Boolean.TRUE; + } + + @Override + public Boolean completeGuidance() { + AuthPrincipalVo userInfo = UserContext.getUserHolder(); + Account account = accountMapper.selectById(userInfo.getId()); + account.setIsBeginner(0); + accountMapper.updateById(account); + return Boolean.TRUE; + } + + @Override + public Boolean addTrialUser(AccountTrialDTO accountTrialDTO, HttpServletRequest request) { + // 获取用户申请试用IP + String ipAddress = RequestInfoUtil.getIpAddress(request); + boolean link = false; + if (StringUtils.isNotBlank(accountTrialDTO.getRef())) { + link = true; + } + // 先检测试用订单 + QueryWrapper trialOrderQueryWrapper = new QueryWrapper<>(); + trialOrderQueryWrapper.eq("BINARY email", accountTrialDTO.getEmail()); +// trialOrderQueryWrapper.lambda().eq(TrialOrder::getIp, ipAddress); +// trialOrderQueryWrapper.lambda().and(wrapper -> +// wrapper.eq(TrialOrder::getEmail, accountTrialDTO.getEmail()) +// .or() // OR +// .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."); + } + // 先检测用户名和邮箱 + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("BINARY user_email", accountTrialDTO.getEmail()); + List accountList = accountMapper.selectList(qw); + if (CollectionUtil.isNotEmpty(accountList) && !accountList.get(0).getSystemUser().equals(0)) { + if (accountList.get(0).getIsTrial() == 1) { + throw new BusinessException("The email has already been registered", ResultEnum.PROMPT.getCode()); + } 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()); + } + } + } + // 接收到数据后要形成一条使用订单信息 + TrialOrder trialOrder = CopyUtil.copyObject(accountTrialDTO, TrialOrder.class); + trialOrder.setCreateTime(LocalDateTime.now()); + trialOrder.setStatus(0); + trialOrder.setIp(ipAddress); + trialOrderMapper.insert(trialOrder); +// SendEmailUtil.sendCustomEmail("1023316923@qq.com", null, trialOrder,1); +// SendEmailUtil.sendCustomEmail("calvinwong@aidlab.hk", null, trialOrder,1); +// SendEmailUtil.sendCustomEmail("kaicpang.pang@connect.polyu.hk", null, trialOrder,1); + // 判断当前的试用订单是否自动批准 + if (AutoApproved.getStatus()) { + // 改变试用订单状态,新增试用用户 + trialOrder.setStatus(1); + trialOrder.setUpdateTime(LocalDateTime.now()); + trialOrderMapper.updateById(trialOrder); + Account account = new Account(); + if (CollectionUtil.isNotEmpty(accountList)) { + account = CopyUtil.copyObject(accountList.get(0), Account.class); + account.setIsTrial(1); + account.setIsBeginner(1); + account.setSystemUser(3); + account.setValidStartTime(System.currentTimeMillis()); + if (link) { + account.setValidEndTime(toDayEnd(Instant.now().plus(14, ChronoUnit.DAYS).toEpochMilli())); + } else { + account.setValidEndTime(toDayEnd(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli())); + } + accountMapper.updateById(account); + } else { + account.setUserName(trialOrder.getUserName()); + account.setUserPassword("Third-000000"); + account.setUserEmail(trialOrder.getEmail()); + account.setLanguage(Language.ENGLISH.name()); + account.setValidStartTime(System.currentTimeMillis()); + if (link) { + account.setValidEndTime(toDayEnd(Instant.now().plus(14, ChronoUnit.DAYS).toEpochMilli())); + } else { + account.setValidEndTime(toDayEnd(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli())); + } + account.setCreateDate(new Date()); + account.setIsTrial(1); + account.setIsBeginner(1); + account.setSystemUser(3); + account.setCredits(BigDecimal.valueOf(100)); + accountMapper.insert(account); + } + // 发送邮件提醒用户试用用户已创建 +// SendEmailUtil.sendCustomEmail("1023316923@qq.com", null, trialOrder,2); +// SendEmailUtil.sendCustomEmail("calvinwong@aidlab.hk", null, trialOrder,2); +// 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 { + SendEmailUtil.sendCustomEmail(account.getUserEmail(), null, trialOrder, 3, trialOrder.getCountry(), link); + } + } + return Boolean.TRUE; + } + + @Override + public IPage trialOrderList(TrialOrderDTO trialOrderDTO) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(trialOrderDTO.getStatus() != null, TrialOrder::getStatus, trialOrderDTO.getStatus()); + return trialOrderMapper.selectPage(new Page<>(trialOrderDTO.getPage(), trialOrderDTO.getSize()), qw); + } + + @Override + public Boolean trialOrderApproval(List ids) { + for (Long id : ids) { + TrialOrder trialOrder = trialOrderMapper.selectById(id); + trialOrder.setStatus(1); + trialOrder.setUpdateTime(LocalDateTime.now()); + trialOrderMapper.updateById(trialOrder); + + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("BINARY user_email", trialOrder.getEmail()); + List accountList = accountMapper.selectList(qw); + + Account account = new Account(); + if (CollectionUtil.isNotEmpty(accountList)) { + account = CopyUtil.copyObject(accountList.get(0), Account.class); + account.setIsTrial(1); + account.setIsBeginner(1); + account.setValidStartTime(System.currentTimeMillis()); + account.setValidEndTime(toDayEnd(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli())); + accountMapper.updateById(account); + } else { + account.setUserName(trialOrder.getUserName()); + account.setUserPassword("Third-000000"); + account.setUserEmail(trialOrder.getEmail()); + account.setLanguage(Language.ENGLISH.name()); + account.setValidStartTime(System.currentTimeMillis()); + account.setValidEndTime(toDayEnd(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli())); + account.setCreateDate(new Date()); + account.setIsTrial(1); + account.setIsBeginner(1); + account.setSystemUser(1); + accountMapper.insert(account); + } + // 发送邮件提醒用户试用用户已创建 +// SendEmailUtil.sendCustomEmail("1023316923@qq.com", null, trialOrder,2, trialOrder.getCountry()); +// SendEmailUtil.sendCustomEmail("calvinwong@aidlab.hk", null, trialOrder,2, trialOrder.getCountry()); +// 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 { + SendEmailUtil.sendCustomEmail(account.getUserEmail(), null, trialOrder, 3, trialOrder.getCountry(), false); + } + } + return Boolean.TRUE; + } + + @Override + public Boolean getIsAutoApproval() { + return AutoApproved.getStatus(); + } + + @Override + public Boolean switchIsAutoApproval() { + AutoApproved.setStatus(!AutoApproved.getStatus()); + return Boolean.TRUE; + } + + @Override + public Boolean trialOrderRefuse(List ids) { + for (Long id : ids) { + TrialOrder trialOrder = trialOrderMapper.selectById(id); + trialOrder.setStatus(2); + trialOrder.setUpdateTime(LocalDateTime.now()); + trialOrderMapper.updateById(trialOrder); + } + return Boolean.TRUE; + } + + @Override + public Long getExpiredTime() { + AuthPrincipalVo userInfo = UserContext.getUserHolder(); + return accountMapper.selectById(userInfo.getId()).getValidEndTime(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean addNoLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO) { + // 构建查询条件,查找已注册的账户数量 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().isNotNull(Account::getBrowserIdentifiers); + queryWrapper.lambda().like(Account::getUserName, "PolyU-SFT-"); + List existingAccounts = accountMapper.selectList(queryWrapper); + + // 检查注册账户数量是否超过限制 + if (existingAccounts.size() >= 100) { + throw new BusinessException("The number of registered accounts exceeds the limit"); + } + + // 检查浏览器标识是否已经被注册 + queryWrapper.clear(); + queryWrapper.lambda().eq(Account::getBrowserIdentifiers, noLoginRequiredDTO.getBrowserIdentifiers()); + if (!accountMapper.selectList(queryWrapper).isEmpty()) { + throw new BusinessException("This browser has already been registered"); + } + + // 创建新账户 + Account newAccount = new Account(); + newAccount.setUserName("PolyU-SFT-" + String.format("%03d", existingAccounts.size() + 1)); + newAccount.setUserPassword("Third-000000"); + newAccount.setValidStartTime(System.currentTimeMillis()); + newAccount.setValidEndTime(System.currentTimeMillis() + 365L * 24 * 60 * 60 * 1000); + newAccount.setCreateDate(new Date()); + newAccount.setIsBeginner(1); + newAccount.setIsTrial(0); + newAccount.setBrowserIdentifiers(noLoginRequiredDTO.getBrowserIdentifiers()); + newAccount.setLanguage(Language.ENGLISH.name()); + + // 插入新账户 + newAccount.setSystemUser(1); + accountMapper.insert(newAccount); + + return Boolean.TRUE; + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteNoLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO) { + // 删除将被注销的用户 + QueryWrapper queryWrapperDelete = new QueryWrapper<>(); + queryWrapperDelete.lambda().eq(Account::getBrowserIdentifiers, noLoginRequiredDTO.getBrowserIdentifiers()); + List accountList = accountMapper.selectList(queryWrapperDelete); + if (CollectionUtil.isNotEmpty(accountList)) { + Account accountDelete = accountList.get(0); + String userName = accountDelete.getUserName(); + // 查询当前浏览器标识下的所有用户,并按照用户名编号降序排序 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().isNotNull(Account::getBrowserIdentifiers); + queryWrapper.lambda().orderByDesc(Account::getUserName); + List accounts = accountMapper.selectList(queryWrapper); + + // 如果存在用户,将将被注销的用户的浏览器标识更新为用户名编号最大的用户的浏览器标识 + if (!accounts.isEmpty()) { + Account userToBeUpdate = accounts.get(0); + //jwt本身失效比较难做 统一用缓存实现 删除缓存就失效 + String token = LocalCacheUtils.getTokenCache(String.valueOf(accountDelete.getId())); + if (StringUtils.isNotBlank(token)) { + LocalCacheUtils.delTokenCache(String.valueOf(accountDelete.getId())); + } + if (!userName.equals(userToBeUpdate.getUserName())) { + accountMapper.deleteById(accountDelete); + userToBeUpdate.setUserName(userName); + accountMapper.updateById(userToBeUpdate); + } else { + accountMapper.deleteById(accountDelete); + } + } + } + + return Boolean.TRUE; + } + + + @Override + public AccountLoginVO noLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request) { + String id = noLoginRequiredDTO.getId(); + if (!isStringInRange(id)) { + throw new BusinessException("Illegal serial number!"); + } + // 获取真实 IP 地址,考虑了经过代理的情况 + String ipAddress = request.getHeader("X-Forwarded-For"); + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("WL-Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getRemoteAddr(); + } + String browserIdentifiers = ipAddress + "," + id; + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(Account::getUserName, "PolyU-SFT-" + id); + qw.lambda().eq(Account::getBrowserIdentifiers, browserIdentifiers); + List accountList = accountMapper.selectList(qw); + if (CollectionUtil.isEmpty(accountList)) { + throw new BusinessException("Machine not registered or machine identification has changed, login free has failed, please contact us at help@aida.com.hk."); + } + Account account = accountList.get(0); + AccountLoginVO response = CopyUtil.copyObject(account, AccountLoginVO.class); + String token = LocalCacheUtils.getTokenCache(String.valueOf(account.getId())); + if (StringUtils.isNotBlank(token)) { + //用户已登入 + response.setToken(token); + } else { + response.setToken(createAccountToken(account)); + } + response.setUserId(account.getId()); + return response; + } + + @Override + public Boolean existNoLoginRequired(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request) { + String id = noLoginRequiredDTO.getId(); + // 获取真实 IP 地址,考虑了经过代理的情况 + String ipAddress = request.getHeader("X-Forwarded-For"); + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("WL-Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getRemoteAddr(); + } + String browserIdentifiers = ipAddress + "," + id; + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(Account::getUserName, "PolyU-SFT-" + id); + List accountList = accountMapper.selectList(qw); + if (!CollectionUtil.isEmpty(accountList)) { + throw new BusinessException(""); + } + return Boolean.TRUE; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public String addNoLoginRequiredNew(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request) { + // 验证机房注册序列号(001-100) + String id = noLoginRequiredDTO.getId(); + if (!isStringInRange(id)) { + throw new BusinessException("Illegal serial number."); + } + // 获取真实 IP 地址,考虑了经过代理的情况 + String ipAddress = request.getHeader("X-Forwarded-For"); + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("WL-Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getRemoteAddr(); + } + String browserIdentifiers = ipAddress + "," + id; + // 构建查询条件,查找已注册的账户数量 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(Account::getUserName, "PolyU-SFT-" + id); +// queryWrapper.lambda().eq(Account::getBrowserIdentifiers, browserIdentifiers); + List existingAccounts = accountMapper.selectList(queryWrapper); + + // 检查序列号是否被注册 + if (CollectionUtil.isNotEmpty(existingAccounts)) { + throw new BusinessException("The serial number has already been registered."); + } + + // 检查机器是否已经注册了别的序列号 + queryWrapper.clear(); + queryWrapper.lambda().like(Account::getBrowserIdentifiers, ipAddress); + List accountList = accountMapper.selectList(queryWrapper); + if (CollectionUtil.isNotEmpty(accountList)) { + throw new BusinessException("This machine has already been registered with serial number " + accountList.get(0).getUserName().split("-")[2]); + } + + // 创建新账户 + Account newAccount = new Account(); + newAccount.setUserName("PolyU-SFT-" + id); + newAccount.setUserPassword("Third-000000"); + newAccount.setValidStartTime(System.currentTimeMillis()); + newAccount.setValidEndTime(System.currentTimeMillis() + 365L * 24 * 60 * 60 * 1000); + newAccount.setCreateDate(new Date()); + newAccount.setIsBeginner(1); + newAccount.setIsTrial(0); + newAccount.setBrowserIdentifiers(browserIdentifiers); + newAccount.setLanguage(Language.ENGLISH.name()); + + // 插入新账户 + newAccount.setSystemUser(1); + accountMapper.insert(newAccount); + + return "\n" + + "                        \n" + + "                        \n" + + "                            \n" + + "                            \n" + + "                            Document\n" + + " \n" + + "                        \n" + + "                        \n" + + "                        \n" + + "                            \n" + + "                        "; + } + + public static boolean isStringInRange(String input) { + // 去除字符串两端的空格 + input = input.trim(); + + // 使用正则表达式检查是否是三位数字 + if (input.matches("\\d{3}")) { + // 将字符串转换为整数 + int number = Integer.parseInt(input); + + // 检查是否在指定范围内 + return number >= 1 && number <= 100; + } + + return false; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteNoLoginRequiredNew(NoLoginRequiredDTO noLoginRequiredDTO, HttpServletRequest request) { + // 获取真实 IP 地址,考虑了经过代理的情况 + String ipAddress = request.getHeader("X-Forwarded-For"); + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("WL-Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getRemoteAddr(); + } + // 删除将被注销的用户 + QueryWrapper queryWrapperDelete = new QueryWrapper<>(); + if (StringUtils.isNotBlank(noLoginRequiredDTO.getId()) && noLoginRequiredDTO.getDeleteById()) { + // 验证机房注册序列号(001-100) + String id = noLoginRequiredDTO.getId(); + if (!isStringInRange(id)) { + throw new BusinessException("Illegal serial number."); + } + queryWrapperDelete.lambda().eq(Account::getUserName, "PolyU-SFT-" + noLoginRequiredDTO.getId()); + } else { + queryWrapperDelete.lambda().like(Account::getBrowserIdentifiers, ipAddress); + } + List accountList = accountMapper.selectList(queryWrapperDelete); + if (CollectionUtil.isNotEmpty(accountList)) { + for (Account account : accountList) { + //jwt本身失效比较难做 统一用缓存实现 删除缓存就失效 + String token = LocalCacheUtils.getTokenCache(String.valueOf(account.getId())); + if (StringUtils.isNotBlank(token)) { + LocalCacheUtils.delTokenCache(String.valueOf(account.getId())); + } + accountMapper.deleteById(account.getId()); + // TODO:注销时删除用户数据,workspace,like,library等 + } + } + return Boolean.TRUE; + } + + @Override + public void upgradeNotification() { +// QueryWrapper queryWrapper = new QueryWrapper<>(); +//// queryWrapper.eq("id", 88L); +// queryWrapper.and(wrapper -> +// wrapper.gt("valid_end_time", 1720540799000L) +// .or().isNull("valid_end_time")) +// .isNotNull("user_email"); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lt("valid_end_time", 1720540799000L); + + List accountList = accountMapper.selectList(queryWrapper); + System.out.println(accountList); + int i = 0; + for (Account account : accountList) { +// SendEmailUtil.sendUpgradeNotification(account, null, 0); +// SendEmailUtil.sendUpgradeNotification(account, null, 1); + if (i > 6) { + if (account.getLanguage().equals(Language.CHINESE_SIMPLIFIED.name())) { + SendEmailUtil.sendUpgradeNotification(account, null, 0); + } else { + // 英文 + SendEmailUtil.sendUpgradeNotification(account, null, 1); + } + } + i ++; + } + } + + @Override + public void moveLibraryDate() { + // 查询生产全部library数据,遍历数据,根据用户id和md5查询是否已经迁移过 + + // 未迁移过的进行迁移,注意模特数据迁移打点信息以及转换模特格式 + } + + public void updateCredits(Long accountId, String value) { + Account account = new Account(); + account.setId(accountId); + account.setCredits(new BigDecimal(value)); + accountMapper.updateById(account); + } + // todo 将其与上一个合并 + public void updateCreditsAndEndTime(Long accountId, String value, Long endTime) { + Account account = new Account(); + account.setId(accountId); + account.setCredits(new BigDecimal(value)); + account.setValidEndTime(toDayEnd(endTime)); + accountMapper.updateById(account); + } + + @Override + public Boolean designWorksRegister(AccountDesignWorksRegisterDTO accountDesignWorksRegisterDTO) { + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("BINARY user_email", accountDesignWorksRegisterDTO.getUserEmail()); + List accountList = accountMapper.selectList(qw); + if (CollectionUtil.isNotEmpty(accountList)) { + throw new BusinessException("The email has already been registered"); + } + + String randomVerifyCode = RandomsUtil.generateVerifyCode(100000L, 999999L); + LocalCacheUtils.setVerifyCodeCache("DesignWorksRegister" + "_" + accountDesignWorksRegisterDTO.getUserEmail(), randomVerifyCode); + + Boolean b = SendEmailUtil.designWorksRegister(accountDesignWorksRegisterDTO.getUserEmail(), randomVerifyCode); + if (!b) { + throw new BusinessException("failed.to.send.mail"); + } + return Boolean.TRUE; + } + + @Override + public AccountLoginVO designWorksRegisterCode(AccountDesignWorksRegisterDTO accountDesignWorksRegisterDTO) { + + String verifyCode = LocalCacheUtils.getVerifyCodeCache("DesignWorksRegister" + "_" + accountDesignWorksRegisterDTO.getUserEmail()); + if (StringUtils.isBlank(verifyCode)) { + throw new BusinessException("the.verification.code.has.expired", ResultEnum.PROMPT.getCode()); + } + if (!verifyCode.equals(accountDesignWorksRegisterDTO.getEmailVerifyCode())) { + throw new BusinessException("verification.code.error", ResultEnum.PROMPT.getCode()); + } + Account account = CopyUtil.copyObject(accountDesignWorksRegisterDTO, Account.class); + account.setSystemUser(0); + if (StringUtils.isBlank(accountDesignWorksRegisterDTO.getLanguage())) { + account.setLanguage(Language.ENGLISH.name()); + } + account.setIsTrial(0); + account.setIsBeginner(1); + account.setValidStartTime(Instant.now().toEpochMilli()); + account.setCreateDate(new Date()); + account.setCredits(BigDecimal.valueOf(0)); + accountMapper.insert(account); + 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()); + 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.setJdbcUrl("jdbc:mysql://localhost:3306/code-create-local?serverTimezone=UTC"); +// config.setUsername("root"); +// config.setPassword("root"); + config.addDataSourceProperty("cachePrepStmts", "true"); + config.addDataSourceProperty("prepStmtCacheSize", "250"); + config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); + config.addDataSourceProperty("maxLifetime", 300000); + 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"); + log.info("Code-Create 订单:{}, 顾客id:{}, 付款金额:{}",orderId, customerId, totalSales); + String email = ""; + String userName = ""; + // 为什么一般没有值 + String country = "English"; + // 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 = getAccountByEmail(email); + } catch (BusinessException e) { + // 通过邮箱找不到用户 说明是新用户 => 创建用户 + flag = Boolean.TRUE; + } + if (!Objects.isNull(userInfo) && !Objects.isNull(userInfo.getValidEndTime())) + validEndTime = userInfo.getValidEndTime(); + + // 2、获取当前续费费用能延长多长时间 + Account account = extendValidity(validEndTime, totalSales); + + int systemUserType = 0; + + // 不管是不是新用户 都要更新用户角色和积分 + String credits = "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; + } + if (flag) { + // 是新用户 => 新增一条数据 + 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("付费新用户 {} 新增成功!", email); + } else { + userInfo.setValidEndTime(toDayEnd(account.getValidEndTime())); + userInfo.setCredits(new BigDecimal(credits)); + userInfo.setSystemUser(systemUserType); + baseMapper.updateById(userInfo); + log.info("付费用户 {} 续订成功", email); + } + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String format = simpleDateFormat.format(account.getValidEndTime()); + + // 3、邮件通知 + SendEmailUtil.notificationForPaidUser(email, flag ? 1 : 2, country, + StringUtil.isNullOrEmpty(userName) ? email.substring(0, email.indexOf("@")) : userName, format); + + // 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(toDayEnd(validityExtension.toInstant().toEpochMilli())); + return account; + } + + 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 " + + "WHERE ID > ? "; + + @Value("${redis.key.maximumUserId}") + private String maximumUserIdKey; + + /** + * 将Code-Create上注册的用户添加为AiDA的游客 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void registerUserToVisitor(){ + ArrayList newUserEmails = new ArrayList<>(); + long maxUserId = CommonConstant.MAXIMUM_USER_ID; + try (Connection connection = dataSource.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement(QUERY_MAXIMUM_USERID)) { + try (ResultSet queryOrderResultSet = preparedStatement.executeQuery()) { + while (queryOrderResultSet.next()) { + // 获取最新的最大用户id + maxUserId = queryOrderResultSet.getLong("max_id"); + // 获取历史最大用户id + long maxUserIdHistory = StringUtil.isNullOrEmpty(redisUtil.getFromString(maximumUserIdKey)) ? CommonConstant.MAXIMUM_USER_ID : Long.parseLong(redisUtil.getFromString(maximumUserIdKey)); + if (maxUserId > maxUserIdHistory){ + // 查出新增用户的邮箱 + PreparedStatement newUserEmail = connection.prepareStatement(QUERY_NEW_USER_EMAIL); + // 填充参数 - 历史最大用户ID + newUserEmail.setLong(1, maxUserIdHistory); + try (ResultSet queryEmailResultSet = newUserEmail.executeQuery()) { + if (queryEmailResultSet.next()) { + String email = queryEmailResultSet.getString("user_email"); + newUserEmails.add(email); + } /*else { + log.error("未知错误。code-create的用户表中没有付费用户的信息"); + throw new BusinessException("user info missing"); + }*/ + } + } + } + } + } catch (Exception e) { + // 记录异常并处理 + e.printStackTrace(); +// return null; + } + + if (!newUserEmails.isEmpty()){ + // 查询这些邮箱在aida上是否有账号 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("user_email", newUserEmails).select("user_email"); + + List collect = baseMapper.selectList(queryWrapper).stream().map(Account::getUserEmail).collect(Collectors.toList()); + if (!collect.isEmpty()){ + // 移除Code-Create新增用户中在AiDA已有账号的邮箱 + newUserEmails.removeAll(collect); + } + // 将新增用户添加到AiDA,身份为游客 + if (!newUserEmails.isEmpty()){ + newUserEmails.forEach(email -> { + Account account = new Account(); + account.setUserEmail(email); + account.setUserName(email); + account.setUserPassword("Third-000000"); + account.setLanguage(Language.ENGLISH.name()); + account.setValidStartTime(Instant.now().toEpochMilli()); + account.setCreateDate(new Date()); + account.setIsTrial(0); + account.setIsBeginner(1); + account.setCredits(new BigDecimal(0)); + account.setSystemUser(0); + baseMapper.insert(account); + // 邮件通知用户 + SendEmailUtil.notificationForRegisterUser(email); + }); + } + // 记录当前最大的用户id + redisUtil.addToString(maximumUserIdKey, String.valueOf(maxUserId)); + } + } + + // 收集调查问卷的信息 + @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 表 + if (account.getValidEndTime() != null && account.getValidEndTime() < 1720972799000L){ + updateCreditsAndEndTime(account.getId(), added.toString(), 1720972799000L); + } + } + + // 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); + } + + @Override + public String getActivityBenefits(){ + Long id = UserContext.getUserHolder().getId(); + // 1、 判断用户的身份 正式用户 无福利 + Account account = baseMapper.selectById(id); + Integer systemUser = account.getSystemUser(); + Instant now = Instant.now(); + ZoneId zoneId = ZoneId.of("Asia/Shanghai"); + ZonedDateTime specifiedDateTime; + if (systemUser.equals(1)){ + long validEndTime = Objects.isNull(account.getValidEndTime()) ? now.toEpochMilli() : account.getValidEndTime(); + specifiedDateTime = ZonedDateTime.ofInstant(Instant.ofEpochMilli(validEndTime), zoneId); + account.setValidEndTime(toDayEnd(specifiedDateTime.plusDays(30).toInstant().toEpochMilli())); + + }else if (systemUser.equals(4)){ + throw new BusinessException("You have participated in the event", 1); + }else if (systemUser.equals(0) || systemUser.equals(3)){ + // 2、赋予游客或试用用户 以正式用户的权限 即 积分置为6000,有效期30天 + // 将 Instant 转换为 ZonedDateTime,使用指定时区 + specifiedDateTime = ZonedDateTime.ofInstant(now, zoneId); + account.setIsTrial(0); + account.setSystemUser(4); + account.setCredits(BigDecimal.valueOf(6000)); + account.setValidStartTime(now.toEpochMilli()); + account.setValidEndTime(toDayEnd(specifiedDateTime.plusDays(30).toInstant().toEpochMilli())); + } + + account.setUpdateDate(new Date()); + baseMapper.updateById(account); + + return "参与成功"; + + } + // 将指定unix时间置为当天的23:59:59 + public long toDayEnd(long unixTimestampMillis){ + // 将UNIX时间戳转换为LocalDateTime对象 + LocalDateTime dateTime = Instant.ofEpochMilli(unixTimestampMillis) + .atZone(ZoneId.systemDefault()) + .toLocalDateTime(); + + // 获取日期部分并设置时间为23:59:59 + LocalDate date = dateTime.toLocalDate(); + LocalDateTime endOfDay = date.atTime(LocalTime.of(23, 59, 59)); + + // 将LocalDateTime对象转换为UNIX时间戳(以毫秒为单位) 北京时间 + return endOfDay.toInstant(ZoneOffset.ofHours(8)).toEpochMilli(); + } + + /** + * 获取指定身份过期用户 + * @param systemUserNum + * @return + */ + public List getExpiredUserBySystemUser(Integer systemUserNum){ + QueryWrapper queryWrapper = new QueryWrapper<>(); + long now = Instant.now().toEpochMilli(); + queryWrapper.eq("system_user", systemUserNum) + .isNotNull("valid_end_time") + .lt("valid_end_time", now); + + return baseMapper.selectList(queryWrapper); + } + + public void toVisitor(Account account){ + accountMapper.toVisitor(account.getId(), new Date()); + } + + public List setUserValidToDayEnd(){ + // 获取当前未过期的用户,并将其有效期设置为过期当日的23:59:59 + QueryWrapper queryWrapper = new QueryWrapper<>(); + long now = Instant.now().toEpochMilli(); + queryWrapper.isNotNull("valid_end_time").gt("valid_end_time", now); + List accounts = baseMapper.selectList(queryWrapper); + ArrayList ids = new ArrayList<>(); + + for (Account account: accounts) { + account.setValidEndTime(toDayEnd(account.getValidEndTime())); + ids.add(account.getId()); + updateById(account); + } + + return ids; + } + + public IPage getPageByDateAndUserType(String startTime, String endTime, Integer type, int pageNum, int size){ + QueryWrapper queryWrapper = new QueryWrapper<>(); + setTimeAndSystemUser(queryWrapper,startTime, endTime, type); + + Page accountPage = new Page<>(pageNum, size); + return baseMapper.selectPage(accountPage, queryWrapper); + } + + private void setTimeAndSystemUser(QueryWrapper queryWrapper, String startTime, String endTime, Integer type){ + queryWrapper.gt("create_date", startTime).lt("create_date",endTime); + + if (!Objects.isNull(type)){ + switch (type){ + case 0: + // 游客 + queryWrapper.eq("system_user", 0); + break; + case 1: + queryWrapper.eq("system_user", 1); + break; + case 2: + queryWrapper.eq("system_user", 2); + break; + case 3: + // 试用用户 + queryWrapper.eq("system_user", 3).or().eq("system_user", 4); + break; + + } + } + } + + public Map getByDateAndUserType(String startTime, String endTime, Integer type){ + QueryWrapper queryWrapper = new QueryWrapper<>(); + setTimeAndSystemUser(queryWrapper,startTime, endTime, type); + queryWrapper.groupBy("system_user"); + + queryWrapper.select("system_user as type, count(id) as count"); + List> maps = baseMapper.selectMaps(queryWrapper); + return maps.stream() + .collect(Collectors.toMap( + map -> map.get("type").toString(), + map -> Objects.isNull(map.get("count")) ? 0L : (Long) map.get("count"))); + } + + public IPage getPageByIds(List ids, int pageNum, int size){ + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("id", ids); + + return baseMapper.selectPage(new Page<>(pageNum, size), queryWrapper); + } + + public List getByIds(List ids){ + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("id", ids); + + return baseMapper.selectList(queryWrapper); + } + + public String uploadAvatar(MultipartFile file){ + Long accountId = UserContext.getUserHolder().getId(); + // 1、上传图片到minio + String avatarPath = minioUtil.upload(userBucket, accountId.toString() + "/avatar", file); + // 2、查询该用户之前的头像 + String avatar = baseMapper.selectById(accountId).getAvatar(); + if (!StringUtil.isNullOrEmpty(avatar) && !avatar.equals(CommonConstant.DEFAULT_AVATAR)){ + minioUtil.deleteObject(avatar); + } + + // 3、替换新的头像 + Account account = new Account(); + account.setId(accountId); + account.setAvatar(avatarPath); + baseMapper.updateById(account); + + return minioUtil.getPreSignedUrl(avatarPath, CommonConstant.MINIO_IMAGE_EXPIRE_TIME); + } + + public PersonalHomepageVO getPersonalHomepage(Long accountId){ + // 需要返回 用户头像 用户名 作品总量 粉丝量 关注量 主页访问量 当前用户是否被查看者关注 + Long currentUserId = UserContext.getUserHolder().getId(); + PersonalHomepageVO personalHomepageVO = new PersonalHomepageVO(); + + Account account = baseMapper.selectById(accountId); + personalHomepageVO.setUserName(account.getUserName()); + String avatar = StringUtil.isNullOrEmpty(account.getAvatar()) ? CommonConstant.DEFAULT_AVATAR : account.getAvatar(); + personalHomepageVO.setAvatar(minioUtil.getPreSignedUrl(avatar, CommonConstant.MINIO_IMAGE_EXPIRE_TIME)); + + personalHomepageVO.setPortfolioCount(portfolioService.getPortfolioCount(accountId)); + personalHomepageVO.setFolloweeCount(portfolioService.getFolloweeCount(accountId)); + personalHomepageVO.setFollowerCount(portfolioService.getFollowerCount(accountId)); + personalHomepageVO.setHomepageViewCount(viewPersonalHomepageCount(0L)); + + + if (accountId.equals(currentUserId)){ + personalHomepageVO.setIsFollow(0); + Long viewCount = viewPersonalHomepageCount(accountId); + // 只有本人才能看到个人主页浏览量 + personalHomepageVO.setHomepageViewCount(viewCount == null ? 0 : viewCount); + }else { + personalHomepageVO.setIsFollow(portfolioService.getIfFollowed(accountId, currentUserId)); + // 非本人浏览主页时增加浏览量 + viewsIncrease(accountId); + } + return personalHomepageVO; + } + + @Override + public Boolean viewsIncrease(Long id) { + redisUtil.increasePersonalHomepageViewCount(id); + return Boolean.TRUE; + } + + private Long viewPersonalHomepageCount(Long accountId) { + redisUtil.getPersonalHomepageViewCount(accountId); + return null; + } + +}