diff --git a/src/main/java/com/ai/da/common/constant/CommonConstant.java b/src/main/java/com/ai/da/common/constant/CommonConstant.java index cb84ef3c..71f6c86b 100644 --- a/src/main/java/com/ai/da/common/constant/CommonConstant.java +++ b/src/main/java/com/ai/da/common/constant/CommonConstant.java @@ -71,4 +71,9 @@ public class CommonConstant { public static final String RCA_WORKSHOP_TAG = "#RCAworkshop_2024"; + public static final String PORTFOLIO_DELETED_EN = "Portfolio has been deleted"; + + public static final String PORTFOLIO_DELETED_CN = "作品已删除"; + + } diff --git a/src/main/java/com/ai/da/common/task/AccountTask.java b/src/main/java/com/ai/da/common/task/AccountTask.java index 8b57b0f0..cfc65fd4 100644 --- a/src/main/java/com/ai/da/common/task/AccountTask.java +++ b/src/main/java/com/ai/da/common/task/AccountTask.java @@ -19,7 +19,7 @@ public class AccountTask { /** * 每周日晚上刷新 年付用户、月付用户的积分 */ - @Scheduled(cron = "59 59 23 ? * SUN") +// @Scheduled(cron = "59 59 23 ? * SUN") // @Scheduled(cron = "59 59 23 * * ?") public void refreshCreditsMonthly() { log.info("每周日晚11:59:59刷新付费用户积分为 6000"); @@ -33,7 +33,7 @@ public class AccountTask { } // 每天凌晨0点执行一次 - @Scheduled(cron = "0 0 0 * * ?") +// @Scheduled(cron = "0 0 0 * * ?") public void cancelActivityBenefits() { // 1、查询当前所有参与了活动且过期的用户 List accountList = accountService.getExpiredUserBySystemUser(4); @@ -46,7 +46,7 @@ public class AccountTask { } // 每天检测正式用户到期情况,每天凌晨0点执行 - @Scheduled(cron = "0 0 0 * * ?") +// @Scheduled(cron = "0 0 0 * * ?") public void paidUserToVisitor() { // 1、查询当前已过期正式用户或试用用户 List accountList = accountService.getExpiredUserBySystemUser(1); diff --git a/src/main/java/com/ai/da/common/websocket/NotificationConnection.java b/src/main/java/com/ai/da/common/websocket/NotificationConnection.java index 7dc7c7da..916f0713 100644 --- a/src/main/java/com/ai/da/common/websocket/NotificationConnection.java +++ b/src/main/java/com/ai/da/common/websocket/NotificationConnection.java @@ -16,11 +16,14 @@ import java.util.concurrent.ConcurrentHashMap; @Slf4j public class NotificationConnection { + //连接超时 + public static final long MAX_TIME_OUT = 2 * 60 * 1000; + static Map sessionMap = new ConcurrentHashMap<>(); private Session session; // 这里用ConcurrentHashMap 因为他是一个线程安全的Map - private static ConcurrentHashMap websockets = new ConcurrentHashMap<>(); + private static ConcurrentHashMap websockets = new ConcurrentHashMap<>(); //连接建立时执行的操作 /*@OnOpen public void onOpen(Session session){ @@ -31,24 +34,43 @@ public class NotificationConnection { @OnOpen public void onOpen(Session session, @PathParam("id") String id) { // 接收到前端传来的用户ID this.session = session; - websockets.put(Long.parseLong(id), this); //将ID作为key,当前的对象作为Value +// this.session.setMaxIdleTimeout(MAX_TIME_OUT); + websockets.put(this, Long.parseLong(id)); //将ID作为key,当前的对象作为Value log.info("【建立连接】 用户为:{}", this.session); log.info("【建立连接】 用户Id为:{}", id); log.info("【建立连接】 总数为:{}", websockets.size()); } @OnClose - public void onClose() { - websockets.remove(this); // 将当前的对象从集合中删除 - log.info("【连接断开】 用户为:{}", this.session); + public void onClose(CloseReason reason) { + if (websockets.containsKey(this)) { + websockets.remove(this); // 将当前的对象从集合中删除 + log.info("【连接断开】 用户为:{}, sessionId: {}, 原因为{}", websockets.get(this), this.session.getId(), reason); + } + // log.info("【连接断开】 总数为:{}", websockets.size()); } + /** + * 错误时调用 + * @param throwable 异常 + */ + @OnError + public void onError(Throwable throwable) { + log.info("【连接异常】 用户为:{} , sessionId: {}", websockets.get(this), this.session.getId(), throwable); + websockets.remove(this); // 将当前的对象从集合中删除 + } + //收到了客户端消息执行的操作 @OnMessage - public void onMessage(String text){ + public void onMessage(Session session, String text){ log.info("收到了一条消息:"+text); // return "已收到你的消息"; + if (text.equals("PING")){ + sendMsg("PONG", websockets.get(this)); + session.setMaxIdleTimeout(MAX_TIME_OUT); + } + } /*//连接关闭的时候执行的操作 @OnClose @@ -63,27 +85,31 @@ public class NotificationConnection { } }*/ - public void sendMsg(String message, Long userId) throws IOException { + public void sendMsg(String message, Long userId) { if (userId == null) { // 如果等于null则证明是群发 // 获取当前Map的一个迭代器,遍历Map的方式有很多种,看着来 // 这个就是遍历这个集合的过程.... - for (Map.Entry entry : websockets.entrySet()) { + for (Map.Entry entry : websockets.entrySet()) { // 获取每一个Entry实例 // 获取每一个Value,而这个Value就是WebSocket的实例 - NotificationConnection webSocket = entry.getValue(); + NotificationConnection webSocket = entry.getKey(); // 接下来就是遍历群发 log.info("广播消息 【给用户】 :{}发送消息【{}】", webSocket, message); - webSocket.session.getBasicRemote().sendText(message); // 发送!!!!!!!!! + try { + webSocket.session.getBasicRemote().sendText(message); // 发送!!!!!!!!! + } catch (IOException e) { + log.error("Failed to send message to session {}: {}", webSocket.session.getId(), e.getMessage()); + } } } else { // 如果不是群发,则判断ID,其余步骤一致 // 获取当前Map的一个迭代器,遍历Map的方式有很多种,看着来 // 这个就是遍历这个集合的过程.... - for (Map.Entry entry : websockets.entrySet()) { + for (Map.Entry entry : websockets.entrySet()) { // 获取每一个Entry实例 // 获取每一个Value,而这个Value就是WebSocket的实例 - NotificationConnection webSocket = entry.getValue(); + NotificationConnection webSocket = entry.getKey(); // 获取每一个Key,这个Key就是用户ID - Long key = entry.getKey(); + Long key = entry.getValue(); // 判断用户ID与当前的Key相等 if (userId.equals(key)) { log.info("私发消息 【给用户】 :{}发送消息【{}】", key, message); // 打印 diff --git a/src/main/java/com/ai/da/common/websocket/config/WebSocketConfig.java b/src/main/java/com/ai/da/common/websocket/config/WebSocketConfig.java index df5b252b..9feb56a1 100644 --- a/src/main/java/com/ai/da/common/websocket/config/WebSocketConfig.java +++ b/src/main/java/com/ai/da/common/websocket/config/WebSocketConfig.java @@ -6,8 +6,6 @@ import org.springframework.web.socket.server.standard.ServerEndpointExporter; /** * Configuration of WebSocket - * - * @author db1995 */ @Configuration public class WebSocketConfig { diff --git a/src/main/java/com/ai/da/controller/ConvenientInquiryController.java b/src/main/java/com/ai/da/controller/ConvenientInquiryController.java index 7953b74a..ecc8fdd1 100644 --- a/src/main/java/com/ai/da/controller/ConvenientInquiryController.java +++ b/src/main/java/com/ai/da/controller/ConvenientInquiryController.java @@ -122,14 +122,16 @@ public class ConvenientInquiryController { @ApiOperation("试用用户到正式用户的转化率") @GetMapping("/conversionRate") - public Response> conversionRate() { - return Response.success(convenientInquiryService.conversionRate()); + public Response> conversionRate(@ApiParam(value = "startTime") @RequestParam(required = false) @Nullable String startTime, + @ApiParam(value = "endTime") @RequestParam(required = false) @Nullable String endTime) { + return Response.success(convenientInquiryService.conversionRate(startTime, endTime)); } @ApiOperation("试用用户国家/城市分布") @GetMapping("/trialUserCountry") - public Response>> trialUserCountry() { - return Response.success(convenientInquiryService.trialUserCountry()); + public Response>> trialUserCountry(@ApiParam(value = "startTime") @RequestParam(required = false) @Nullable String startTime, + @ApiParam(value = "endTime") @RequestParam(required = false) @Nullable String endTime) { + return Response.success(convenientInquiryService.trialUserCountry(startTime, endTime)); } @ApiOperation("添加用户") diff --git a/src/main/java/com/ai/da/mapper/primary/TrialOrderMapper.java b/src/main/java/com/ai/da/mapper/primary/TrialOrderMapper.java index 65709299..d1de236e 100644 --- a/src/main/java/com/ai/da/mapper/primary/TrialOrderMapper.java +++ b/src/main/java/com/ai/da/mapper/primary/TrialOrderMapper.java @@ -3,6 +3,7 @@ package com.ai.da.mapper.primary; import com.ai.da.common.config.mybatis.plus.CommonMapper; import com.ai.da.mapper.primary.entity.TrialOrder; +import java.util.List; import java.util.Map; /** @@ -15,6 +16,4 @@ public interface TrialOrderMapper extends CommonMapper { Map countOfficialUser(); - - } diff --git a/src/main/java/com/ai/da/model/dto/UserDesignStatisticDTO.java b/src/main/java/com/ai/da/model/dto/UserDesignStatisticDTO.java index b0713077..0b087213 100644 --- a/src/main/java/com/ai/da/model/dto/UserDesignStatisticDTO.java +++ b/src/main/java/com/ai/da/model/dto/UserDesignStatisticDTO.java @@ -15,6 +15,8 @@ public class UserDesignStatisticDTO { private String isTrial; + private String credits; + private String trialOrderId; private String title; diff --git a/src/main/java/com/ai/da/service/AccountService.java b/src/main/java/com/ai/da/service/AccountService.java index 6e5c5b5f..bd9c99b4 100644 --- a/src/main/java/com/ai/da/service/AccountService.java +++ b/src/main/java/com/ai/da/service/AccountService.java @@ -184,4 +184,6 @@ public interface AccountService extends IService { void halfPricePromotion(); String googleCallback(String code, HttpSession session); + + List getPaidCustomerEmail(); } diff --git a/src/main/java/com/ai/da/service/ConvenientInquiryService.java b/src/main/java/com/ai/da/service/ConvenientInquiryService.java index 49424df6..fa4210f4 100644 --- a/src/main/java/com/ai/da/service/ConvenientInquiryService.java +++ b/src/main/java/com/ai/da/service/ConvenientInquiryService.java @@ -32,9 +32,9 @@ public interface ConvenientInquiryService extends IService { Map> getActiveUserFunc(String startTime, String endTime, List ids); - Map conversionRate(); + Map conversionRate(String startTime, String endTime); - Map> trialUserCountry(); + Map> trialUserCountry(String startTime, String endTime); Boolean addUser(AccountAddDTO accountAddDTO); 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 81bfd846..34efb6f2 100644 --- a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java @@ -576,6 +576,7 @@ public class AccountServiceImpl extends ServiceImpl impl account.setIsBeginner(1); account.setSystemUser(3); account.setValidStartTime(System.currentTimeMillis()); + account.setCountry(accountTrialDTO.getCountry()); if (link) { account.setValidEndTime(toDayEnd(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli())); } else { @@ -588,6 +589,7 @@ public class AccountServiceImpl extends ServiceImpl impl account.setUserPassword("Third-000000"); account.setUserEmail(trialOrder.getEmail()); account.setLanguage(Language.ENGLISH.name()); + account.setCountry(accountTrialDTO.getCountry()); account.setValidStartTime(System.currentTimeMillis()); if (link) { account.setValidEndTime(toDayEnd(Instant.now().plus(5, ChronoUnit.DAYS).toEpochMilli())); @@ -1469,6 +1471,31 @@ public class AccountServiceImpl extends ServiceImpl impl } } + private static final String QUERY_PAID_CUSTOMER_EMAIL = "SELECT distinct c.email " + + "FROM `pmr_wc_order_stats` o " + + "inner join `pmr_wc_customer_lookup` c " + + "on o.customer_id = c.customer_id " + + "and o.net_total in (5000, 500, 250) " + + "and o.`status` != 'wc-failed' " + + "and c.email not in ('1779019091@qq.com', 'xupei3360@163.com', '1627315083@qq.com', 'gigiwu33@hotmail.com')"; + + public List getPaidCustomerEmail(){ + List paidCustomerEmail = new ArrayList<>(); + try (Connection connection = dataSource.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement(QUERY_PAID_CUSTOMER_EMAIL)) { + try (ResultSet queryOrderResultSet = preparedStatement.executeQuery()) { + while (queryOrderResultSet.next()) { + paidCustomerEmail.add(queryOrderResultSet.getString("email")); + } + } + } catch (Exception e) { + // 记录异常并处理 + e.printStackTrace(); +// return null; + } + return paidCustomerEmail; + } + // 收集调查问卷的信息 @Override @Transactional(rollbackFor = Exception.class) diff --git a/src/main/java/com/ai/da/service/impl/ConvenientInquiryServiceImpl.java b/src/main/java/com/ai/da/service/impl/ConvenientInquiryServiceImpl.java index 2bad5969..819dc95d 100644 --- a/src/main/java/com/ai/da/service/impl/ConvenientInquiryServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/ConvenientInquiryServiceImpl.java @@ -392,9 +392,15 @@ public class ConvenientInquiryServiceImpl extends ServiceImpl conversionRate() { + public Map conversionRate(String startTime, String endTime) { QueryWrapper queryWrapper = new QueryWrapper<>(); + if (!StringUtils.isNullOrEmpty(startTime)){ + queryWrapper.gt("create_time", startTime); + } + if (!StringUtils.isNullOrEmpty(endTime)){ + queryWrapper.lt("create_time", endTime); + } // 获取试用用户总数 queryWrapper.select("count(distinct email) as count"); @@ -402,22 +408,40 @@ public class ConvenientInquiryServiceImpl extends ServiceImpl officialMaps = trialOrderMapper.countOfficialUser(); - Long trialToOfficial = officialMaps.get("count"); + List paidCustomerEmail = accountService.getPaidCustomerEmail(); + QueryWrapper qw = new QueryWrapper<>(); + if (!StringUtils.isNullOrEmpty(startTime)){ + qw.gt("create_time", startTime); + } + if (!StringUtils.isNullOrEmpty(endTime)){ + qw.lt("create_time", endTime); + } + qw.in("email", paidCustomerEmail); + List paidTrialUsers = trialOrderMapper.selectList(qw); + +// Map officialMaps = trialOrderMapper.countOfficialUser(); +// Long trialToOfficial = officialMaps.get("count"); // 计算转化率 - HashMap resp = new HashMap<>(); + HashMap resp = new HashMap<>(); resp.put("trialUserCount", totalTrials.floatValue()); - resp.put("trialToOfficialCount", trialToOfficial.floatValue()); - resp.put("conversionRate", new BigDecimal(trialToOfficial).divide(new BigDecimal(totalTrials), 2, RoundingMode.HALF_UP).floatValue()); - + resp.put("trialToOfficialCount", (float) paidTrialUsers.size()); + resp.put("conversionRate", new BigDecimal(paidTrialUsers.size()).divide(new BigDecimal(totalTrials), 6, RoundingMode.HALF_UP).floatValue()); + resp.put("paidTrialUser", paidTrialUsers); return resp; } // 试用用户地区统计 - public Map> trialUserCountry() { + public Map> trialUserCountry(String startTime, String endTime) { QueryWrapper queryWrapper = new QueryWrapper<>(); + if (!StringUtils.isNullOrEmpty(startTime)){ + queryWrapper.gt("create_time", startTime); + } + if (!StringUtils.isNullOrEmpty(endTime)){ + queryWrapper.lt("create_time", endTime); + } + queryWrapper.select("country, count(id) as count") .groupBy("country"); List> countryCount = trialOrderMapper.selectMaps(queryWrapper); diff --git a/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java b/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java index c2062a52..74a19386 100644 --- a/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/MessageCenterServiceImpl.java @@ -112,10 +112,15 @@ public class MessageCenterServiceImpl extends ServiceImpl select d.*,c.id trialOrderId, c.title,c.surname,c.given_name,c.country,c.occupation,c.create_time from ( - select b.account_id,count(b.account_id) design_times,a.user_name,a.user_email,a.is_trial + select b.account_id,count(b.account_id) design_times,a.user_name,a.user_email,a.is_trial,a.credits from t_account a left join t_design b on a.id = b.account_id