Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/master' into develop_zqc

DESKTOP-VAEGFGM\zqc 7 mēneši atpakaļ
vecāks
revīzija
a7ce7acd32
100 mainītis faili ar 1635 papildinājumiem un 380 dzēšanām
  1. 10 6
      citu-framework/citu-spring-boot-starter-web/src/main/java/com/citu/framework/apilog/core/interceptor/ApiAccessLogInterceptor.java
  2. 0 1
      citu-framework/citu-spring-boot-starter-web/src/main/java/com/citu/framework/i18n/config/CituI18nAutoConfiguration.java
  3. 7 3
      citu-framework/citu-spring-boot-starter-web/src/main/java/com/citu/framework/i18n/config/LocaleInterceptor.java
  4. 1 1
      citu-framework/citu-spring-boot-starter-web/src/main/java/com/citu/framework/xss/config/CituXssAutoConfiguration.java
  5. 0 1
      citu-framework/citu-spring-boot-starter-web/src/main/java/com/citu/framework/xss/core/clean/JsoupXssCleaner.java
  6. 2 0
      citu-framework/citu-spring-boot-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  7. 2 5
      citu-module-infra/citu-module-infra-biz/Dockerfile
  8. 13 12
      citu-module-member/citu-module-member-biz/src/main/java/com/citu/module/member/controller/app/invoice/AppInvoiceListController.java
  9. 24 23
      citu-module-member/citu-module-member-biz/src/main/java/com/citu/module/member/controller/app/invoice/InvoiceTitleController.java
  10. 8 0
      citu-module-pay/citu-module-pay-biz/src/main/java/com/citu/module/pay/controller/admin/channel/PayChannelController.java
  11. 3 0
      citu-module-pay/citu-module-pay-biz/src/main/java/com/citu/module/pay/controller/app/wallet/vo/transaction/AppPayWalletTransactionRespVO.java
  12. 6 0
      citu-module-pay/citu-module-pay-biz/src/main/java/com/citu/module/pay/dal/mysql/channel/PayChannelMapper.java
  13. 8 0
      citu-module-pay/citu-module-pay-biz/src/main/java/com/citu/module/pay/service/channel/PayChannelService.java
  14. 5 0
      citu-module-pay/citu-module-pay-biz/src/main/java/com/citu/module/pay/service/channel/PayChannelServiceImpl.java
  15. 5 3
      citu-module-pay/citu-module-pay-biz/src/main/java/com/citu/module/pay/service/currency/PayCurrencyRechargeServiceImpl.java
  16. 24 0
      menduner/menduner-common/src/main/java/com/citu/module/menduner/common/dto/TimeRange.java
  17. 2 7
      menduner/menduner-common/src/main/java/com/citu/module/menduner/common/dto/TimeRangeBasePageReqVO.java
  18. 2 7
      menduner/menduner-common/src/main/java/com/citu/module/menduner/common/dto/TimeRangeBaseReqVO.java
  19. 28 35
      menduner/menduner-common/src/main/java/com/citu/module/menduner/common/util/TimeUtils.java
  20. 5 0
      menduner/menduner-im-biz/pom.xml
  21. 2 0
      menduner/menduner-im-biz/src/main/java/com/citu/module/menduner/im/controller/app/WuKongSessionController.java
  22. 6 6
      menduner/menduner-reward-biz/src/main/java/com/citu/module/menduner/reward/controller/app/sigin/AppSignInConfigController.java
  23. 22 22
      menduner/menduner-reward-biz/src/main/java/com/citu/module/menduner/reward/controller/app/sigin/AppSignInRecordController.java
  24. 3 2
      menduner/menduner-reward-biz/src/main/java/com/citu/module/menduner/reward/service/event/EventTrackServiceImpl.java
  25. 2 0
      menduner/menduner-system-api/src/main/java/com/citu/module/menduner/system/enums/ErrorCodeConstants.java
  26. 2 2
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/aop/VipEntitlementCheck.java
  27. 51 90
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/aop/VipEntitlementCheckAspect.java
  28. 72 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/analysis/HomeController.java
  29. 9 8
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/enterprise/EnterpriseUserBindController.java
  30. 11 2
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/job/JobAdvertisedController.java
  31. 17 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/user/MdeUserController.java
  32. 2 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/common/auth/AppMdeAuthController.java
  33. 53 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/common/captcha/AppCaptchaController.java
  34. 17 2
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/order/AppTradeOrderController.java
  35. 3 4
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/person/AppPersonController.java
  36. 10 4
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/person/AppPersonResumeController.java
  37. 5 5
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/person/job/AppJobInterestedSaveReqVO.java
  38. 16 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/person/resume/AppPersonInfoSaveSimpleReqVO.java
  39. 1 1
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/person/workexp/AppWorkExpSaveReqVO.java
  40. 2 1
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/user/AppMdeUserController.java
  41. 1 2
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/recruit/order/AppRecruitTradeOrderController.java
  42. 8 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/recruit/person/AppRecruitPersonCvController.java
  43. 3 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/enterprise/vo/EnterpriseSaveReqVO.java
  44. 4 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/job/JobAdvertisedRespVO.java
  45. 2 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/job/JobAdvertisedDO.java
  46. 22 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/enterprise/EnterpriseMapper.java
  47. 21 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/enterprise/EnterpriseUserBindMapper.java
  48. 5 4
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/job/JobAdvertisedMapper.java
  49. 1 2
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/job/JobCvRelMapper.java
  50. 21 1
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/person/PersonInfoMapper.java
  51. 22 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/user/MdeUserMapper.java
  52. 21 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/redis/RedisKeyConstants.java
  53. 30 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/framework/captcha/config/CituCaptchaConfiguration.java
  54. 49 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/framework/captcha/core/RedisCaptchaServiceImpl.java
  55. 8 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/framework/captcha/package-info.java
  56. 42 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/mq/consumer/PublishJobConsumer.java
  57. 3 3
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/mq/consumer/PublishJobHireConsumer.java
  58. 2 1
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/mq/consumer/UserMemberConsumer.java
  59. 45 24
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/auth/MdeAuthServiceImpl.java
  60. 29 10
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/auth/MdeEnterpriseAuthServiceImpl.java
  61. 9 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/enterprise/EnterpriseService.java
  62. 16 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/enterprise/EnterpriseServiceImpl.java
  63. 23 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/enterprise/bind/EnterpriseUserBindService.java
  64. 52 16
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/enterprise/bind/EnterpriseUserBindServiceImpl.java
  65. 1 7
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/industry/IndustryServiceImpl.java
  66. 16 3
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/interview/InterviewInviteServiceImpl.java
  67. 6 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/job/JobAdvertisedService.java
  68. 49 42
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/job/JobAdvertisedServiceImpl.java
  69. 1 1
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/job/JobCvRelServiceImpl.java
  70. 9 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/job/JobIntegrationServiceImpl.java
  71. 3 2
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/order/TradeOrderServiceImpl.java
  72. 29 4
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/person/PersonIntegrationServiceImpl.java
  73. 10 1
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/person/info/PersonInfoService.java
  74. 24 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/person/info/PersonInfoServiceImpl.java
  75. 7 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/user/MdeUserService.java
  76. 27 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/user/MdeUserServiceImpl.java
  77. 47 2
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/util/RecruitAnalysisUtils.java
  78. 63 0
      menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/util/RedisUtils.java
  79. 1 0
      menduner/menduner-system-biz/src/main/resources/META-INF/services/com.xingyuv.captcha.service.CaptchaCacheService
  80. 24 2
      menduner/menduner-system-biz/src/main/resources/application.yaml
  81. 416 0
      menduner/menduner-system-biz/src/main/resources/i18n/messages_en_GB.properties
  82. 1 0
      menduner/menduner-system-biz/src/main/resources/i18n/messages_en_US.properties
  83. 1 0
      menduner/menduner-system-biz/src/main/resources/i18n/messages_zh_CN.properties
  84. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg1.png
  85. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg2.png
  86. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg3.png
  87. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg4.png
  88. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg5.png
  89. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg6.png
  90. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg7.png
  91. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg8.png
  92. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg9.png
  93. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/1.png
  94. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/11/10.png
  95. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/11/11.png
  96. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/11/12.png
  97. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/11/13.png
  98. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/11/14.png
  99. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/11/15.png
  100. BIN
      menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/11/16.png

+ 10 - 6
citu-framework/citu-spring-boot-starter-web/src/main/java/com/citu/framework/apilog/core/interceptor/ApiAccessLogInterceptor.java

@@ -15,7 +15,7 @@ import java.util.Map;
 
 /**
  * API 访问日志 Interceptor
- *
+ * <p>
  * 目的:在非 prod 环境时,打印 request 和 response 两条日志到日志文件(控制台)中。
  *
  * @author Rayson
@@ -36,13 +36,13 @@ public class ApiAccessLogInterceptor implements HandlerInterceptor {
         }
 
         // 打印 request 日志
-        if (!SpringUtils.isProd()) {
+        if (!SpringUtils.isProd() && !isVersionUrl(request)) {
             Map<String, String> queryString = ServletUtils.getParamMap(request);
             String requestBody = ServletUtils.isJsonRequest(request) ? ServletUtils.getBody(request) : null;
             if (CollUtil.isEmpty(queryString) && StrUtil.isEmpty(requestBody)) {
-                log.info("[preHandle][开始请求 方式({}) URL({}) 无参数]",request.getMethod(),request.getRequestURI());
+                log.info("[preHandle][开始请求 方式({}) URL({}) 无参数]", request.getMethod(), request.getRequestURI());
             } else {
-                log.info("[preHandle][开始请求 方式({})  URL({}) 参数({})]",request.getMethod(), request.getRequestURI(),
+                log.info("[preHandle][开始请求 方式({})  URL({}) 参数({})]", request.getMethod(), request.getRequestURI(),
                         StrUtil.blankToDefault(requestBody, queryString.toString()));
             }
             // 计时
@@ -56,12 +56,16 @@ public class ApiAccessLogInterceptor implements HandlerInterceptor {
     @Override
     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
         // 打印 response 日志
-        if (!SpringUtils.isProd()) {
+        if (!SpringUtils.isProd() && !isVersionUrl(request)) {
             StopWatch stopWatch = (StopWatch) request.getAttribute(ATTRIBUTE_STOP_WATCH);
             stopWatch.stop();
             log.info("[afterCompletion][完成请求 方式({}) URL({}) 耗时({} ms)]",
-                    request.getMethod(),request.getRequestURI(), stopWatch.getTotalTimeMillis());
+                    request.getMethod(), request.getRequestURI(), stopWatch.getTotalTimeMillis());
         }
     }
 
+    private boolean isVersionUrl(HttpServletRequest request) {
+        return request.getRequestURL().toString().contains("/version");
+    }
+
 }

+ 0 - 1
citu-framework/citu-spring-boot-starter-web/src/main/java/com/citu/framework/i18n/config/CituI18nAutoConfiguration.java

@@ -1,6 +1,5 @@
 package com.citu.framework.i18n.config;
 
-import com.citu.framework.xss.config.XssProperties;
 import org.springframework.boot.autoconfigure.AutoConfiguration;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;

+ 7 - 3
citu-framework/citu-spring-boot-starter-web/src/main/java/com/citu/framework/i18n/config/LocaleInterceptor.java

@@ -31,16 +31,20 @@ public class LocaleInterceptor implements HandlerInterceptor {
 
         String language = request.getHeader(HttpHeaders.ACCEPT_LANGUAGE);
         Locale locale = null;
-
+        boolean isNotPrint = !request.getRequestURL().toString().contains("/version");
         if (StringUtils.hasText(language)) {
             locale = parseAcceptLanguageHeader(language.replace("-", "_"));
-            log.warn("解析请求国际化语言[{}]", locale);
+            if (isNotPrint) {
+                log.warn("解析请求国际化语言[{}]", locale);
+            }
         }
 
         if (null == locale) {
             // 如果无法解析语言头或者解析失败,则使用默认语言
             locale = Locale.getDefault();
-            log.warn("获取默认国际化语言[{}]", locale);
+            if (isNotPrint) {
+                log.warn("获取默认国际化语言[{}]", locale);
+            }
 
         }
         LocaleContextHolder.setLocale(locale, true);

+ 1 - 1
citu-framework/citu-spring-boot-starter-web/src/main/java/com/citu/framework/xss/config/CituXssAutoConfiguration.java

@@ -42,7 +42,7 @@ public class CituXssAutoConfiguration implements WebMvcConfigurer {
      */
     @Bean
     @ConditionalOnMissingBean(name = "xssJacksonCustomizer")
-    @ConditionalOnBean(ObjectMapper.class)
+//    @ConditionalOnBean(ObjectMapper.class)
     @ConditionalOnProperty(value = "citu.xss.enable", havingValue = "true")
     public Jackson2ObjectMapperBuilderCustomizer xssJacksonCustomizer(XssProperties properties,
                                                                       PathMatcher pathMatcher,

+ 0 - 1
citu-framework/citu-spring-boot-starter-web/src/main/java/com/citu/framework/xss/core/clean/JsoupXssCleaner.java

@@ -59,6 +59,5 @@ public class JsoupXssCleaner implements XssCleaner {
     public String clean(String html) {
         return Jsoup.clean(html, baseUri, safelist, new Document.OutputSettings().prettyPrint(false));
     }
-
 }
 

+ 2 - 0
citu-framework/citu-spring-boot-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -1,7 +1,9 @@
 com.citu.framework.apilog.config.CituApiLogAutoConfiguration
 com.citu.framework.jackson.config.CituJacksonAutoConfiguration
+com.citu.framework.xss.config.CituXssAutoConfiguration
 com.citu.framework.swagger.config.CituSwaggerAutoConfiguration
 com.citu.framework.web.config.CituWebAutoConfiguration
 com.citu.framework.apilog.config.CituApiLogRpcAutoConfiguration
 com.citu.framework.banner.config.CituBannerAutoConfiguration
 com.citu.framework.i18n.config.CituI18nAutoConfiguration
+

+ 2 - 5
citu-module-infra/citu-module-infra-biz/Dockerfile

@@ -2,17 +2,14 @@
 ## 感谢复旦核博士的建议!灰子哥,牛皮!
 FROM adoptopenjdk/openjdk11
 
-## 创建目录,并使用它作为工作目录
-RUN mkdir -p /citu-module-infra-biz
-WORKDIR /citu-module-infra-biz
 ## 将后端项目的 Jar 文件,复制到镜像中
-COPY ./target/citu-module-infra-biz.jar app.jar
+ADD target/citu-module-infra-biz.jar app.jar
 
 ## 设置 TZ 时区
 ## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
 ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx512m"
 
-## 暴露后端项目的 48080 端口
+## 暴露后端项目的 48082 端口
 EXPOSE 48082
 
 ## 启动后端项目

+ 13 - 12
citu-module-member/citu-module-member-biz/src/main/java/com/citu/module/member/controller/app/invoice/AppInvoiceListController.java

@@ -1,23 +1,23 @@
 package com.citu.module.member.controller.app.invoice;
 
+import com.citu.framework.common.pojo.CommonResult;
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.common.util.object.BeanUtils;
+import com.citu.framework.security.core.annotations.PreAuthenticated;
 import com.citu.module.member.controller.app.invoice.vo.InvoiceListPageReqVO;
 import com.citu.module.member.controller.app.invoice.vo.InvoiceListRespVO;
 import com.citu.module.member.controller.app.invoice.vo.InvoiceListSaveReqVO;
 import com.citu.module.member.dal.dataobject.invoice.InvoiceListDO;
 import com.citu.module.member.service.invoice.InvoiceListService;
-import org.springframework.web.bind.annotation.*;
-import javax.annotation.Resource;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.security.access.prepost.PreAuthorize;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
 
-import javax.validation.*;
+import javax.annotation.Resource;
+import javax.validation.Valid;
 
-import com.citu.framework.common.pojo.PageResult;
-import com.citu.framework.common.pojo.CommonResult;
-import com.citu.framework.common.util.object.BeanUtils;
 import static com.citu.framework.common.pojo.CommonResult.success;
 
 
@@ -30,6 +30,7 @@ public class AppInvoiceListController {
     @Resource
     private InvoiceListService invoiceListService;
 
+    @PreAuthenticated
     @PostMapping("/create")
     @Operation(summary = "创建发票")
     public CommonResult<Long> createInvoiceList(@Valid @RequestBody InvoiceListSaveReqVO createReqVO) {
@@ -54,8 +55,8 @@ public class AppInvoiceListController {
 
     @GetMapping("/get")
     @Operation(summary = "获得发票清单")
+    @PreAuthenticated
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('member:invoice-list:query')")
     public CommonResult<InvoiceListRespVO> getInvoiceList(@RequestParam("id") Long id) {
         InvoiceListDO invoiceList = invoiceListService.getInvoiceList(id);
         return success(BeanUtils.toBean(invoiceList, InvoiceListRespVO.class));
@@ -63,7 +64,7 @@ public class AppInvoiceListController {
 
     @GetMapping("/page")
     @Operation(summary = "获得发票清单分页")
-//    @PreAuthorize("@ss.hasPermission('member:invoice-list:query')")
+    @PreAuthenticated
     public CommonResult<PageResult<InvoiceListRespVO>> getInvoiceListPage(@Valid InvoiceListPageReqVO pageReqVO) {
         PageResult<InvoiceListDO> pageResult = invoiceListService.getInvoiceListPage(pageReqVO);
         return success(BeanUtils.toBean(pageResult, InvoiceListRespVO.class));

+ 24 - 23
citu-module-member/citu-module-member-biz/src/main/java/com/citu/module/member/controller/app/invoice/InvoiceTitleController.java

@@ -1,36 +1,32 @@
 package com.citu.module.member.controller.app.invoice;
 
+import com.citu.framework.apilog.core.annotation.ApiAccessLog;
+import com.citu.framework.common.pojo.CommonResult;
+import com.citu.framework.common.pojo.PageParam;
+import com.citu.framework.common.pojo.PageResult;
+import com.citu.framework.common.util.object.BeanUtils;
+import com.citu.framework.excel.core.util.ExcelUtils;
+import com.citu.framework.security.core.annotations.PreAuthenticated;
 import com.citu.module.member.controller.app.invoice.vo.InvoiceTitlePageReqVO;
 import com.citu.module.member.controller.app.invoice.vo.InvoiceTitleRespVO;
 import com.citu.module.member.controller.app.invoice.vo.InvoiceTitleSaveReqVO;
 import com.citu.module.member.dal.dataobject.invoice.InvoiceTitleDO;
 import com.citu.module.member.service.invoice.InvoiceTitleService;
-import org.springframework.web.bind.annotation.*;
-import javax.annotation.Resource;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.security.access.prepost.PreAuthorize;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
 
-import javax.validation.constraints.*;
-import javax.validation.*;
-import javax.servlet.http.*;
-import java.util.*;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
 import java.io.IOException;
+import java.util.List;
 
-import com.citu.framework.common.pojo.PageParam;
-import com.citu.framework.common.pojo.PageResult;
-import com.citu.framework.common.pojo.CommonResult;
-import com.citu.framework.common.util.object.BeanUtils;
+import static com.citu.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static com.citu.framework.common.pojo.CommonResult.success;
 
-import com.citu.framework.excel.core.util.ExcelUtils;
-
-import com.citu.framework.apilog.core.annotation.ApiAccessLog;
-import static com.citu.framework.apilog.core.enums.OperateTypeEnum.*;
-
-
 
 @Tag(name = "管理发票抬头")
 @RestController
@@ -42,12 +38,14 @@ public class InvoiceTitleController {
     private InvoiceTitleService invoiceTitleService;
 
     @PostMapping("/create")
+    @PreAuthenticated
     @Operation(summary = "创建发票抬头")
     public CommonResult<Long> createInvoiceTitle(@Valid @RequestBody InvoiceTitleSaveReqVO createReqVO) {
         return success(invoiceTitleService.createInvoiceTitle(createReqVO));
     }
 
     @PutMapping("/update")
+    @PreAuthenticated
     @Operation(summary = "更新发票抬头")
     public CommonResult<Boolean> updateInvoiceTitle(@Valid @RequestBody InvoiceTitleSaveReqVO updateReqVO) {
         invoiceTitleService.updateInvoiceTitle(updateReqVO);
@@ -56,8 +54,8 @@ public class InvoiceTitleController {
 
     @DeleteMapping("/delete")
     @Operation(summary = "删除发票抬头")
+    @PreAuthenticated
     @Parameter(name = "id", description = "编号", required = true)
-//    @PreAuthorize("@ss.hasPermission('member:invoice-title:delete')")
     public CommonResult<Boolean> deleteInvoiceTitle(@RequestParam("id") Long id) {
         invoiceTitleService.deleteInvoiceTitle(id);
         return success(true);
@@ -65,6 +63,7 @@ public class InvoiceTitleController {
 
     @GetMapping("/get")
     @Operation(summary = "获得发票抬头")
+    @PreAuthenticated
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
     public CommonResult<InvoiceTitleRespVO> getInvoiceTitle(@RequestParam("id") Long id) {
         InvoiceTitleDO invoiceTitle = invoiceTitleService.getInvoiceTitle(id);
@@ -72,22 +71,24 @@ public class InvoiceTitleController {
     }
 
     @GetMapping("/page")
+    @PreAuthenticated
     @Operation(summary = "获得发票抬头分页")
     public CommonResult<PageResult<InvoiceTitleRespVO>> getInvoiceTitlePage(@Valid InvoiceTitlePageReqVO pageReqVO) {
         PageResult<InvoiceTitleDO> pageResult = invoiceTitleService.getInvoiceTitlePage(pageReqVO);
         return success(BeanUtils.toBean(pageResult, InvoiceTitleRespVO.class));
     }
 
+    @PreAuthenticated
     @GetMapping("/export-excel")
     @Operation(summary = "导出发票抬头 Excel")
     @ApiAccessLog(operateType = EXPORT)
     public void exportInvoiceTitleExcel(@Valid InvoiceTitlePageReqVO pageReqVO,
-              HttpServletResponse response) throws IOException {
+                                        HttpServletResponse response) throws IOException {
         pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
         List<InvoiceTitleDO> list = invoiceTitleService.getInvoiceTitlePage(pageReqVO).getList();
         // 导出 Excel
         ExcelUtils.write(response, "发票抬头.xls", "数据", InvoiceTitleRespVO.class,
-                        BeanUtils.toBean(list, InvoiceTitleRespVO.class));
+                BeanUtils.toBean(list, InvoiceTitleRespVO.class));
     }
 
 }

+ 8 - 0
citu-module-pay/citu-module-pay-biz/src/main/java/com/citu/module/pay/controller/admin/channel/PayChannelController.java

@@ -79,4 +79,12 @@ public class PayChannelController {
         return success(convertSet(channels, PayChannelDO::getCode));
     }
 
+    @GetMapping("/get-enable-code-list2")
+    @Operation(summary = "获得指定应用的开启的支付渠道编码列表")
+    @Parameter(name = "appId", description = "应用编号", required = true, example = "1")
+    public CommonResult<Set<String>> getEnableChannelCodeList(@RequestParam("code") String code) {
+        List<PayChannelDO> channels = channelService.getEnableChannelList(code);
+        return success(convertSet(channels, PayChannelDO::getCode));
+    }
+
 }

+ 3 - 0
citu-module-pay/citu-module-pay-biz/src/main/java/com/citu/module/pay/controller/app/wallet/vo/transaction/AppPayWalletTransactionRespVO.java

@@ -15,6 +15,9 @@ public class AppPayWalletTransactionRespVO {
     @Schema(description = "交易金额,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
     private Long price;
 
+    @Schema(description = "交易后余额,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
+    private Integer balance;
+
     @Schema(description = "流水标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "土豆土豆")
     private String title;
 

+ 6 - 0
citu-module-pay/citu-module-pay-biz/src/main/java/com/citu/module/pay/dal/mysql/channel/PayChannelMapper.java

@@ -25,4 +25,10 @@ public interface PayChannelMapper extends BaseMapperX<PayChannelDO> {
                 .eq(PayChannelDO::getStatus, status));
     }
 
+    default List<PayChannelDO> selectListByCode(String code, Integer status) {
+        return selectList(new LambdaQueryWrapperX<PayChannelDO>()
+                .eq(PayChannelDO::getCode, code)
+                .eq(PayChannelDO::getStatus, status));
+    }
+
 }

+ 8 - 0
citu-module-pay/citu-module-pay-biz/src/main/java/com/citu/module/pay/service/channel/PayChannelService.java

@@ -93,6 +93,14 @@ public interface PayChannelService {
      */
     List<PayChannelDO> getEnableChannelList(Long appId);
 
+    /**
+     * 获得指定应用的开启的渠道列表
+     *
+     * @param code 应用编码
+     * @return 渠道列表
+     */
+    List<PayChannelDO> getEnableChannelList(String code);
+
     /**
      * 获得指定编号的支付客户端
      *

+ 5 - 0
citu-module-pay/citu-module-pay-biz/src/main/java/com/citu/module/pay/service/channel/PayChannelServiceImpl.java

@@ -163,6 +163,11 @@ public class PayChannelServiceImpl implements PayChannelService {
         return payChannelMapper.selectListByAppId(appId, CommonStatusEnum.ENABLE.getStatus());
     }
 
+    @Override
+    public List<PayChannelDO> getEnableChannelList(String code) {
+        return payChannelMapper.selectListByCode(code, CommonStatusEnum.ENABLE.getStatus());
+    }
+
     @Override
     public PayClient getPayClient(Long id) {
         PayChannelDO channel = validPayChannel(id);

+ 5 - 3
citu-module-pay/citu-module-pay-biz/src/main/java/com/citu/module/pay/service/currency/PayCurrencyRechargeServiceImpl.java

@@ -60,7 +60,7 @@ public class PayCurrencyRechargeServiceImpl implements PayCurrencyRechargeServic
     /**
      * 比例倍数 1:10
      **/
-    private static final Integer RATIO_MULTIPLE = 10;
+//    private static final Integer RATIO_MULTIPLE = 10;
     @Resource
     public SocialClientApi socialClientApi;
     @Resource
@@ -80,7 +80,8 @@ public class PayCurrencyRechargeServiceImpl implements PayCurrencyRechargeServic
      * @return Long
      **/
     public static Long convertPriceRatio(Long price) {
-        return (price / 100) * RATIO_MULTIPLE;
+//        return (price / 100) * RATIO_MULTIPLE;
+        return price ;
     }
 
     /**
@@ -90,7 +91,8 @@ public class PayCurrencyRechargeServiceImpl implements PayCurrencyRechargeServic
      * @return Long 原始金额
      */
     public static Long revertConvertPriceRatio(Long convertedPrice) {
-        return (convertedPrice / RATIO_MULTIPLE) * 100;
+//        return (convertedPrice / RATIO_MULTIPLE) * 100;
+        return convertedPrice;
     }
 
     @Override

+ 24 - 0
menduner/menduner-common/src/main/java/com/citu/module/menduner/common/dto/TimeRange.java

@@ -0,0 +1,24 @@
+package com.citu.module.menduner.common.dto;
+
+/**
+ * 时间范围常量
+ **/
+public interface TimeRange {
+
+    /** 全部 **/
+    String ALL = "-1";
+    /** 最近7天 **/
+    String TYPE_RECENT_7_DAYS = "0";
+    /** 上个月 **/
+    String TYPE_LAST_MONTH = "1";
+    /** 上个季度 **/
+    String TYPE_LAST_QUARTER = "2";
+    /** 最近24小时 **/
+    String TYPE_24_HOURS = "3";
+    /** 最近30天 **/
+    String TYPE_MONTH = "4";
+    /** 最近一年 **/
+    String TYPE_YEAR = "5";
+    /** 自定义 **/
+    String TYPE_CUSTOM = "99";
+}

+ 2 - 7
menduner/menduner-common/src/main/java/com/citu/module/menduner/common/dto/TimeRangeBasePageReqVO.java

@@ -13,13 +13,8 @@ import static com.citu.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DA
 @Data
 public class TimeRangeBasePageReqVO extends PageParam {
 
-    public static final String ALL = "-1";
-    public static final String TYPE_RECENT_7_DAYS = "0";
-    public static final String TYPE_LAST_MONTH = "1";
-    public static final String TYPE_LAST_QUARTER = "2";
-    public static final String TYPE_CUSTOM = "99";
-
-    @Schema(description = "统计类型 -1全部|0最近7天|1上个月|2上季度|99自定义", required = true)
+    /** {@link com.citu.module.menduner.common.dto.TimeRange} **/
+    @Schema(description = "统计类型 -1全部|0最近7天|1上个月|2上季度|3 24小时|4每月|5每年|99自定义", required = true)
     private String type;
 
     @Schema(description = "自定义时间范围")

+ 2 - 7
menduner/menduner-common/src/main/java/com/citu/module/menduner/common/dto/TimeRangeBaseReqVO.java

@@ -18,13 +18,8 @@ import static com.citu.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DA
 @Data
 public class TimeRangeBaseReqVO {
 
-    public static final String ALL = "-1";
-    public static final String TYPE_RECENT_7_DAYS = "0";
-    public static final String TYPE_LAST_MONTH = "1";
-    public static final String TYPE_LAST_QUARTER = "2";
-    public static final String TYPE_CUSTOM = "99";
-
-    @Schema(description = "统计类型 -1全部|0最近7天|1上个月|2上季度|99自定义", required = true)
+    /** {@link com.citu.module.menduner.common.dto.TimeRange} **/
+    @Schema(description = "统计类型 -1全部|0最近7天|1上个月|2上季度|3 24小时|4每月|5每年|99自定义", required = true)
     private String type;
 
     @Schema(description = "自定义时间范围")

+ 28 - 35
menduner/menduner-common/src/main/java/com/citu/module/menduner/common/util/TimeUtils.java

@@ -1,5 +1,6 @@
 package com.citu.module.menduner.common.util;
 
+import com.citu.module.menduner.common.dto.TimeRange;
 import com.citu.module.menduner.common.dto.TimeRangeBasePageReqVO;
 import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
 
@@ -14,64 +15,41 @@ public class TimeUtils {
      * 生成时间范围
      **/
     public static LocalDateTime[] generateDateTimeRange(TimeRangeBasePageReqVO reqVO) {
-        if (TimeRangeBasePageReqVO.TYPE_CUSTOM.equals(reqVO.getType())) {
+        if (TimeRange.TYPE_CUSTOM.equals(reqVO.getType())) {
             return reqVO.getTime();
         }
-        LocalDateTime[] dateTimeRange = new LocalDateTime[2];
-        LocalDateTime now = LocalDateTime.now();
-        switch (reqVO.getType()) {
-            case TimeRangeBasePageReqVO.ALL:
-                dateTimeRange[0] = null;
-                dateTimeRange[1] = null;
-                break;
-            case TimeRangeBasePageReqVO.TYPE_RECENT_7_DAYS:
-                // 最新7天内
-                dateTimeRange[0] = now.minusDays(7);
-                dateTimeRange[1] = now;
-                break;
-            case TimeRangeBasePageReqVO.TYPE_LAST_MONTH:
-                // 上个月
-                dateTimeRange[0] = now.minusMonths(1).withDayOfMonth(1);
-                dateTimeRange[1] = now.withDayOfMonth(1).minusNanos(1);
-                break;
-            case TimeRangeBasePageReqVO.TYPE_LAST_QUARTER:
-                // 上季度
-                int currentMonth = now.getMonthValue();
-                // 计算上一季度的起始月份
-                int quarterStartMonth = ((currentMonth - 1) / 3) * 3 + 1;
-                int lastQuarterStartMonth = quarterStartMonth - 3;
-                dateTimeRange[0] = now.withMonth(lastQuarterStartMonth).withDayOfMonth(1);
-                dateTimeRange[1] = now.withMonth(quarterStartMonth).withDayOfMonth(1).minusNanos(1);
-                break;
-        }
-        return dateTimeRange;
+        return generateDateTimeRange(reqVO.getType());
     }
 
     /**
      * 生成时间范围
      **/
     public static LocalDateTime[] generateDateTimeRange(TimeRangeBaseReqVO reqVO) {
-        if (TimeRangeBasePageReqVO.TYPE_CUSTOM.equals(reqVO.getType())) {
+        if (TimeRange.TYPE_CUSTOM.equals(reqVO.getType())) {
             return reqVO.getTime();
         }
+        return generateDateTimeRange(reqVO.getType());
+    }
+
+    private static LocalDateTime[] generateDateTimeRange(String type) {
         LocalDateTime[] dateTimeRange = new LocalDateTime[2];
         LocalDateTime now = LocalDateTime.now();
-        switch (reqVO.getType()) {
-            case TimeRangeBasePageReqVO.ALL:
+        switch (type) {
+            case TimeRange.ALL:
                 dateTimeRange[0] = null;
                 dateTimeRange[1] = null;
                 break;
-            case TimeRangeBasePageReqVO.TYPE_RECENT_7_DAYS:
+            case TimeRange.TYPE_RECENT_7_DAYS:
                 // 最新7天内
                 dateTimeRange[0] = now.minusDays(7);
                 dateTimeRange[1] = now;
                 break;
-            case TimeRangeBasePageReqVO.TYPE_LAST_MONTH:
+            case TimeRange.TYPE_LAST_MONTH:
                 // 上个月
                 dateTimeRange[0] = now.minusMonths(1).withDayOfMonth(1);
                 dateTimeRange[1] = now.withDayOfMonth(1).minusNanos(1);
                 break;
-            case TimeRangeBasePageReqVO.TYPE_LAST_QUARTER:
+            case TimeRange.TYPE_LAST_QUARTER:
                 // 上季度
                 int currentMonth = now.getMonthValue();
                 // 计算上一季度的起始月份
@@ -80,6 +58,21 @@ public class TimeUtils {
                 dateTimeRange[0] = now.withMonth(lastQuarterStartMonth).withDayOfMonth(1);
                 dateTimeRange[1] = now.withMonth(quarterStartMonth).withDayOfMonth(1).minusNanos(1);
                 break;
+            case TimeRange.TYPE_24_HOURS:
+                // 最近24小时
+                dateTimeRange[0] = now.minusHours(24);
+                dateTimeRange[1] = now;
+                break;
+            case TimeRange.TYPE_MONTH:
+                // 最近一个月
+                dateTimeRange[0] = now.minusDays(30);
+                dateTimeRange[1] = now;
+                break;
+            case TimeRange.TYPE_YEAR:
+                // 最近一年
+                dateTimeRange[0] = now.minusMonths(12);
+                dateTimeRange[1] = now;
+                break;
         }
         return dateTimeRange;
     }

+ 5 - 0
menduner/menduner-im-biz/pom.xml

@@ -37,6 +37,11 @@
             <version>${revision}</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.citu</groupId>
+            <artifactId>citu-spring-boot-starter-protection</artifactId>
+        </dependency>
+
 
         <!-- Registry 注册中心相关 -->
         <dependency>

+ 2 - 0
menduner/menduner-im-biz/src/main/java/com/citu/module/menduner/im/controller/app/WuKongSessionController.java

@@ -2,6 +2,7 @@ package com.citu.module.menduner.im.controller.app;
 
 import com.citu.framework.common.pojo.CommonResult;
 import com.citu.framework.security.core.annotations.PreAuthenticated;
+import com.citu.framework.signature.core.annotation.ApiSignature;
 import com.citu.module.menduner.im.controller.app.base.wukong.ConversationSyncReqVo;
 import com.citu.module.menduner.im.controller.app.base.wukong.ConversationsDeleteReqVo;
 import com.citu.module.menduner.im.controller.app.base.wukong.ConversationsUnreadReqVo;
@@ -33,6 +34,7 @@ public class WuKongSessionController {
      * @return CommonResult
      */
     @PreAuthenticated
+    @ApiSignature(timeout = 30)
     @PostMapping("/conversation/sync")
     public CommonResult conversatioSync(@RequestBody ConversationSyncReqVo reqVo){
         return  service.conversatioSync(reqVo);

+ 6 - 6
menduner/menduner-reward-biz/src/main/java/com/citu/module/menduner/reward/controller/app/sigin/AppSignInConfigController.java

@@ -27,11 +27,11 @@ public class AppSignInConfigController {
     @Resource
     private SignInConfigService signInConfigService;
 
-    @GetMapping("/list")
-    @Operation(summary = "获得签到规则列表")
-    public CommonResult<List<AppSignInConfigRespVO>> getSignInConfigList() {
-        List<SignInConfigDO> pageResult = signInConfigService.getSignInConfigList(CommonStatusEnum.ENABLE.getStatus());
-        return success(SignInConfigConvert.INSTANCE.convertList2(pageResult));
-    }
+//    @GetMapping("/list")
+//    @Operation(summary = "获得签到规则列表")
+//    public CommonResult<List<AppSignInConfigRespVO>> getSignInConfigList() {
+//        List<SignInConfigDO> pageResult = signInConfigService.getSignInConfigList(CommonStatusEnum.ENABLE.getStatus());
+//        return success(SignInConfigConvert.INSTANCE.convertList2(pageResult));
+//    }
 
 }

+ 22 - 22
menduner/menduner-reward-biz/src/main/java/com/citu/module/menduner/reward/controller/app/sigin/AppSignInRecordController.java

@@ -31,27 +31,27 @@ public class AppSignInRecordController {
     @Resource
     private SignInRecordService signInRecordService;
 
-    @GetMapping("/get-summary")
-    @Operation(summary = "获得个人签到统计")
-    @PreAuthenticated
-    public CommonResult<AppSignInRecordSummaryRespVO> getSignInRecordSummary() {
-        return success(signInRecordService.getSignInRecordSummary(getLoginUserId()));
-    }
-
-    @PostMapping("/create")
-    @Operation(summary = "签到")
-    @PreAuthenticated
-    public CommonResult<AppSignInRecordRespVO> createSignInRecord() {
-        SignInRecordDO recordDO = signInRecordService.createSignRecord(getLoginUserId());
-        return success(SignInRecordConvert.INSTANCE.coverRecordToAppRecordVo(recordDO));
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "获得签到记录分页")
-    @PreAuthenticated
-    public CommonResult<PageResult<AppSignInRecordRespVO>> getSignRecordPage(PageParam pageParam) {
-        PageResult<SignInRecordDO> pageResult = signInRecordService.getSignRecordPage(getLoginUserId(), pageParam);
-        return success(SignInRecordConvert.INSTANCE.convertPage02(pageResult));
-    }
+//    @GetMapping("/get-summary")
+//    @Operation(summary = "获得个人签到统计")
+//    @PreAuthenticated
+//    public CommonResult<AppSignInRecordSummaryRespVO> getSignInRecordSummary() {
+//        return success(signInRecordService.getSignInRecordSummary(getLoginUserId()));
+//    }
+//
+//    @PostMapping("/create")
+//    @Operation(summary = "签到")
+//    @PreAuthenticated
+//    public CommonResult<AppSignInRecordRespVO> createSignInRecord() {
+//        SignInRecordDO recordDO = signInRecordService.createSignRecord(getLoginUserId());
+//        return success(SignInRecordConvert.INSTANCE.coverRecordToAppRecordVo(recordDO));
+//    }
+//
+//    @GetMapping("/page")
+//    @Operation(summary = "获得签到记录分页")
+//    @PreAuthenticated
+//    public CommonResult<PageResult<AppSignInRecordRespVO>> getSignRecordPage(PageParam pageParam) {
+//        PageResult<SignInRecordDO> pageResult = signInRecordService.getSignRecordPage(getLoginUserId(), pageParam);
+//        return success(SignInRecordConvert.INSTANCE.convertPage02(pageResult));
+//    }
 
 }

+ 3 - 2
menduner/menduner-reward-biz/src/main/java/com/citu/module/menduner/reward/service/event/EventTrackServiceImpl.java

@@ -3,6 +3,7 @@ package com.citu.module.menduner.reward.service.event;
 import cn.hutool.core.collection.CollectionUtil;
 import com.baomidou.dynamic.datasource.annotation.DSTransactional;
 import com.citu.framework.security.core.LoginUser;
+import com.citu.module.menduner.common.dto.TimeRange;
 import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
 import com.citu.module.menduner.common.enums.PointBizTypeEnum;
 import com.citu.module.menduner.common.util.LoginUserContext;
@@ -111,13 +112,13 @@ public class EventTrackServiceImpl implements EventTrackService {
     public List<TaskRespVO> getMarkTask(TaskReqVO reqVO) {
         LocalDateTime[] timeRange = null;
         if (TaskReqVO.TYPE_RECOMMEND.equals(reqVO.getType())) {
-            timeRange = generateDateTimeRange(TimeRangeBaseReqVO.builder().type(TimeRangeBaseReqVO.ALL).build());
+            timeRange = generateDateTimeRange(TimeRangeBaseReqVO.builder().type(TimeRange.ALL).build());
         } else {
             LocalDate today = LocalDate.now();
             LocalDateTime startOfDay = today.atStartOfDay();  // 当天的开始时间
             LocalDateTime endOfDay = today.atTime(23, 59, 59);  // 当天的结束时间
             timeRange = generateDateTimeRange(TimeRangeBaseReqVO.builder()
-                    .type(TimeRangeBaseReqVO.TYPE_CUSTOM)
+                    .type(TimeRange.TYPE_CUSTOM)
                     // time 是数组,第一个元素是开始时间,第二个元素是结束时间,改为当天的起始和结束
                     .time(new LocalDateTime[]{startOfDay, endOfDay})
                     .build());

+ 2 - 0
menduner/menduner-system-api/src/main/java/com/citu/module/menduner/system/enums/ErrorCodeConstants.java

@@ -182,6 +182,8 @@ public interface ErrorCodeConstants {
     ErrorCode MDE_USER_PHONE_INIT_PASSWORD=
             new ErrorCode(1_100_017_022, "密码不安全,请修改密码后登录");
 
+    ErrorCode MDE_USER_PHONE_NOT_EXISTS_ERROR = new ErrorCode(1_100_017_023, "手机号尝试多次,请8个小时后重试");
+
     // ========== 角色模块 1_100_018_000 ==========
     ErrorCode MDE_ROLE_NOT_EXISTS = new ErrorCode(1_100_018_001, "角色不存在");
     ErrorCode MDE_ROLE_NAME_DUPLICATE = new ErrorCode(1_100_018_002, "已经存在名为【{}】的角色");

+ 2 - 2
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/aop/VipEntitlementCheck.java

@@ -60,7 +60,7 @@ public @interface VipEntitlementCheck {
     /**
      * 操作
      **/
-    OperationType operate();
+    OperationType operate() default OperationType.DEDUCT;
 
     /**
      * 是否后台管理员操作
@@ -68,6 +68,6 @@ public @interface VipEntitlementCheck {
     boolean system() default false;
 
     enum OperationType {
-        ADD, DEDUCT
+        DEDUCT
     }
 }

+ 51 - 90
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/aop/VipEntitlementCheckAspect.java

@@ -1,5 +1,6 @@
 package com.citu.module.menduner.system.aop;
 
+import com.baomidou.dynamic.datasource.annotation.DSTransactional;
 import com.citu.module.menduner.common.util.LoginUserContext;
 import com.citu.module.menduner.system.controller.base.enterprise.vip.EnterpriseEntitlementRespVO;
 import com.citu.module.menduner.system.dal.dataobject.enterprise.EnterpriseEntitlementDO;
@@ -14,6 +15,9 @@ import org.springframework.util.StringUtils;
 
 import javax.annotation.Resource;
 
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
 import static com.citu.framework.common.exception.enums.GlobalErrorCodeConstants.FORBIDDEN;
 import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static com.citu.module.menduner.system.aop.VipEntitlementCheck.*;
@@ -34,18 +38,16 @@ public class VipEntitlementCheckAspect {
     @Lazy
     private EnterpriseEntitlementService enterpriseEntitlementService;
 
-
+    @DSTransactional
     @Around("@annotation(vipEntitlementCheck)")
     public Object around(ProceedingJoinPoint joinPoint, VipEntitlementCheck vipEntitlementCheck) {
 
         boolean isEnterprise = VipEntitlementCheck.ENTERPRISE.equals(vipEntitlementCheck.userType());
         Long userId = LoginUserContext.getUserId();
         Long enterpriseId = LoginUserContext.getEnterpriseId3();
-        validate(isEnterprise, enterpriseId, userId, vipEntitlementCheck.type(), vipEntitlementCheck.operate());
         try {
-            Object result = joinPoint.proceed();
-            process(isEnterprise, enterpriseId, userId, vipEntitlementCheck.type(), vipEntitlementCheck.operate());
-            return result;
+            deductQuota(isEnterprise, enterpriseId, userId, vipEntitlementCheck.type(), vipEntitlementCheck.operate());
+            return joinPoint.proceed();
         } catch (Throwable e) {
             e.getStackTrace();
             throw exception(FORBIDDEN);
@@ -55,46 +57,23 @@ public class VipEntitlementCheckAspect {
     /**
      * 验证权限
      */
-    public void validate(String type) {
+    public void deductQuota(String type) {
         Long enterpriseId = LoginUserContext.getEnterpriseId3();
-        validate(null != enterpriseId, enterpriseId, LoginUserContext.getUserId(), type, null);
+        deductQuota(null != enterpriseId, enterpriseId, LoginUserContext.getUserId(), type, OperationType.DEDUCT);
     }
 
-    public void validate(String type, VipEntitlementCheck.OperationType operator) {
-        Long enterpriseId = LoginUserContext.getEnterpriseId3();
-        validate(null != enterpriseId, enterpriseId, LoginUserContext.getUserId(), type, operator);
-    }
 
-    public void validate(String type, boolean isTrigger) {
+    public void deductQuota(String type, boolean isTrigger) {
         if (!isTrigger) {
             // 如果为false则不执行
             return;
         }
-        validate(type);
+        deductQuota(type);
     }
 
 
-    /**
-     * 权益处理
-     *
-     * @param type     权益类型
-     * @param operator 操作
-     */
-    public void process(String type, VipEntitlementCheck.OperationType operator) {
-        Long enterpriseId = LoginUserContext.getEnterpriseId3();
-        process(null != enterpriseId, enterpriseId, LoginUserContext.getUserId(), type, operator);
-    }
-
-    public void process(String type, VipEntitlementCheck.OperationType operator, boolean isTrigger) {
-        if (!isTrigger) {
-            // 如果为false则不执行
-            return;
-        }
-        process(type, operator);
-    }
-
 
-    private void validate(boolean isEnterprise, Long enterpriseId,
+    private void deductQuota(boolean isEnterprise, Long enterpriseId,
                           Long userId, String type,
                           VipEntitlementCheck.OperationType operator) {
 
@@ -111,75 +90,36 @@ public class VipEntitlementCheckAspect {
             // 没有权限
             throw exception(FORBIDDEN);
         }
-        if (null == operator || VipEntitlementCheck.OperationType.ADD.equals(operator)) {
-            // 新增不做效验
-            return;
-        }
-        switch (type) {
-            case OPERATE_PUBLISH_JOB:
-                if (entitlementRespVO.getPublishJobCount() <= 0) {
-                    throw exception(ENTERPRISE_ENTITLEMENT_QUOTA_OVERFLOW);
-                }
-                break;
-            case OPERATE_SEARCH:
-                if (entitlementRespVO.getSearchCount() <= 0) {
-                    throw exception(ENTERPRISE_ENTITLEMENT_QUOTA_OVERFLOW);
-                }
-            case OPERATE_LOOK_CV:
-                if (entitlementRespVO.getLookCvCount() <= 0) {
-                    throw exception(ENTERPRISE_ENTITLEMENT_QUOTA_OVERFLOW);
-                }
-                break;
-            default:
-                throw exception(FORBIDDEN);
-        }
+//        if (null == operator || VipEntitlementCheck.OperationType.ADD.equals(operator)) {
+//            // 新增不做效验
+//            return;
+//        }
+        deductQuota(type, entitlementRespVO,operator);
     }
 
-    private void process(boolean isEnterprise,
-                         Long enterpriseId, Long userId,
-                         String type, VipEntitlementCheck.OperationType operator) {
-        if (!isEnterprise || LoginUserContext.checkIsSystemUser()) {
-            // 用户
-            return;
-        }
-        // TODO 设计业务的应该通过业务查询计数,但是如果按照这种办法,旧数据那些发布了很多职位的怎么办?
-        // TODO 目前只单纯写个加减1,还未沟通具体逻辑
+    /**
+     * 扣减额度
+     */
+    private void deductQuota(String type, EnterpriseEntitlementRespVO entitlementRespVO, VipEntitlementCheck.OperationType operator) {
+        int amount =  -1;
 
-        // 企业
-        EnterpriseEntitlementRespVO entitlementRespVO =
-                enterpriseEntitlementService.getByEnterpriseIdAndUserId(enterpriseId, userId);
-        int amount = VipEntitlementCheck.OperationType.ADD.equals(operator) ? 1 : -1;
-        int num = 0;
         switch (type) {
             case OPERATE_PUBLISH_JOB:
-                num = entitlementRespVO.getPublishJobCount() + amount;
-                if (num > entitlementRespVO.getPackageInfo().getPublishJobCount()) {
-                    // 用户持有的额度大于套餐的额度
-                    // TODO 1、管理员给用户加的额度 ,要不要扣额度?
-                    // TODO 2、如果旧职位是开启状态的,现在操作关闭会计算累加
-                    // return;
-                }
-                entitlementRespVO.setPublishJobCount(num);
+                validateAndUpdateQuota(entitlementRespVO::getPublishJobCount, entitlementRespVO::setPublishJobCount,
+                        entitlementRespVO.getPackageInfo().getPublishJobCount(), amount, operator);
                 break;
             case OPERATE_SEARCH:
-                num = entitlementRespVO.getSearchCount() + amount;
-                if (num > entitlementRespVO.getPackageInfo().getPublishJobCount()) {
-                    // 用户持有的额度大于套餐的额度
-                    // return;
-                }
-                entitlementRespVO.setSearchCount(num);
+                validateAndUpdateQuota(entitlementRespVO::getSearchCount, entitlementRespVO::setSearchCount,
+                        entitlementRespVO.getPackageInfo().getSearchCount(), amount, operator);
                 break;
             case OPERATE_LOOK_CV:
-                num = entitlementRespVO.getLookCvCount() + amount;
-                if (num > entitlementRespVO.getPackageInfo().getLookCvCount()) {
-                    // 用户持有的额度大于套餐的额度
-                    // return;
-                }
-                entitlementRespVO.setLookCvCount(num);
+                validateAndUpdateQuota(entitlementRespVO::getLookCvCount, entitlementRespVO::setLookCvCount,
+                        entitlementRespVO.getPackageInfo().getLookCvCount(), amount, operator);
                 break;
             default:
-                return;
+                throw exception(FORBIDDEN);
         }
+
         enterpriseEntitlementService.update(EnterpriseEntitlementDO.builder()
                 .id(entitlementRespVO.getId())
                 .publishJobCount(entitlementRespVO.getPublishJobCount())
@@ -188,4 +128,25 @@ public class VipEntitlementCheckAspect {
                 .build());
     }
 
+    /**
+     * 校验并更新额度
+     */
+    private void validateAndUpdateQuota(Supplier<Integer> getCurrentCount, Consumer<Integer> setNewCount,
+                                        int maxCount, int amount, VipEntitlementCheck.OperationType operator) {
+        int currentCount = getCurrentCount.get();
+        int newCount = currentCount + amount;
+         if (VipEntitlementCheck.OperationType.DEDUCT.equals(operator) && currentCount <= 0) {
+            throw exception(ENTERPRISE_ENTITLEMENT_QUOTA_OVERFLOW);
+        }
+
+        if (newCount > maxCount) {
+            // 用户持有的额度大于套餐的额度
+            // TODO 1、管理员给用户加的额度 ,要不要扣额度?
+            // TODO 2、如果旧职位是开启状态的,现在操作关闭会计算累加
+            // return;
+        }
+
+        setNewCount.accept(newCount);
+    }
+
 }

+ 72 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/analysis/HomeController.java

@@ -0,0 +1,72 @@
+package com.citu.module.menduner.system.controller.admin.analysis;
+
+import com.citu.framework.common.pojo.CommonResult;
+import com.citu.framework.security.core.annotations.PreAuthenticated;
+import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
+import com.citu.module.menduner.system.service.enterprise.EnterpriseService;
+import com.citu.module.menduner.system.service.enterprise.bind.EnterpriseUserBindService;
+import com.citu.module.menduner.system.service.person.info.PersonInfoService;
+import com.citu.module.menduner.system.service.user.MdeUserService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.Map;
+
+import static com.citu.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "管理后台 - 首页统计")
+@RestController
+@RequestMapping("/menduner/system/home")
+@Validated
+@Slf4j
+public class HomeController {
+
+    @Resource
+    private PersonInfoService personInfoService;
+
+    @Resource
+    private MdeUserService mdeUserService;
+
+    @Resource
+    private EnterpriseService enterpriseService;
+
+    @Resource
+    private EnterpriseUserBindService enterpriseUserBindService;
+
+    @GetMapping("/get/person/count")
+    @Operation(summary = "统计新增加人才简历数量")
+    @PreAuthenticated
+    public CommonResult<Map<String, Object[]>> getPersonCount(@Valid TimeRangeBaseReqVO reqVO) {
+        return success(personInfoService.getPersonCount(reqVO));
+    }
+
+    @GetMapping("/get/user/count")
+    @Operation(summary = "统计新用户数量")
+    @PreAuthenticated
+    public CommonResult<Map<String, Object[]>> getUserCount(@Valid TimeRangeBaseReqVO reqVO) {
+        return success(mdeUserService.getUserCount(reqVO));
+    }
+
+    @GetMapping("/get/enterprise/count")
+    @Operation(summary = "统计新注册企业数量")
+    @PreAuthenticated
+    public CommonResult<Map<String, Object[]>> getEnterpriseCount(@Valid TimeRangeBaseReqVO reqVO) {
+        return success(enterpriseService.getEnterpriseCount(reqVO));
+    }
+
+    @GetMapping("/get/enterprise-user/count")
+    @Operation(summary = "统计新企业用户数量")
+    @PreAuthenticated
+    public CommonResult<Map<String, Object[]>> getEnterpriseUserCount(@Valid TimeRangeBaseReqVO reqVO) {
+        return success(enterpriseUserBindService.getEnterpriseUserCount(reqVO));
+    }
+
+
+}

+ 9 - 8
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/enterprise/EnterpriseUserBindController.java

@@ -118,19 +118,20 @@ public class EnterpriseUserBindController {
     }
 
 
-    @PostMapping("/disable")
-    @Operation(summary = "禁用账户")
+
+    @PostMapping("/enable")
+    @Operation(summary = "启用账户")
     @PreAuthorize("@ss.hasPermission('menduner:system:enterprise-user-bind:update')")
-    public CommonResult<Boolean> disable(@RequestParam("ids") String ids) {
-        return success(enterpriseUserBindService.disable(StrUtils.splitToLong(ids)));
+    public CommonResult<Boolean> enable(@RequestParam("ids") Long id) {
+        return success(enterpriseUserBindService.enable(id));
     }
 
 
-    @PostMapping("/enable")
-    @Operation(summary = "用账户")
+    @PostMapping("/disable")
+    @Operation(summary = "用账户")
     @PreAuthorize("@ss.hasPermission('menduner:system:enterprise-user-bind:update')")
-    public CommonResult<Boolean> enable(@RequestParam("ids") String ids) {
-        return success(enterpriseUserBindService.enable(StrUtils.splitToLong(ids)));
+    public CommonResult<Boolean> disable(@RequestParam("id") Long id) {
+        return success(enterpriseUserBindService.disable(id));
     }
 
 

+ 11 - 2
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/job/JobAdvertisedController.java

@@ -56,13 +56,22 @@ public class JobAdvertisedController {
     }
 
     @GetMapping("/page")
-    @Operation(summary = "获得全员猎聘职位分页")
+    @Operation(summary = "获得聘职位分页")
     @PreAuthorize("@ss.hasPermission('menduner:system:job-advertised:query')")
     public CommonResult<PageResult<JobAdvertisedRespVO>> getJobAdvertisedPage(@Valid JobAdvertisedPageReqVO pageReqVO) {
-        PageResult<JobAdvertisedDO> pageResult = jobAdvertisedService.getHireJobPage(pageReqVO);
+        PageResult<JobAdvertisedDO> pageResult = jobAdvertisedService.getJobAdvertisedPage(pageReqVO);
         return success(BeanUtils.toBean(pageResult, JobAdvertisedRespVO.class));
     }
 
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除招聘职位")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('menduner:system:job-advertised:delete')")
+    public CommonResult<Boolean> deleteJobAdvertised(@RequestParam("id") Long id) {
+        jobAdvertisedService.deleteJobAdvertised(id);
+        return success(true);
+    }
+
     @GetMapping("/list")
     @Operation(summary = "获得招聘职位列表")
     @PreAuthorize("@ss.hasPermission('menduner:system:job-advertised:query')")

+ 17 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/admin/user/MdeUserController.java

@@ -22,6 +22,7 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 import java.io.IOException;
+import java.util.Collections;
 import java.util.List;
 
 import static com.citu.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
@@ -108,5 +109,21 @@ public class MdeUserController {
         return success(true);
     }
 
+    @PostMapping("/enable")
+    @Operation(summary = "启用")
+    @PreAuthorize("@ss.hasPermission('menduner:system:mde-user:update')")
+    public CommonResult<Boolean> enable(@RequestParam("id") Long id) {
+        mdeUserService.enable(Collections.singletonList(id));
+        return success(true);
+    }
+
+    @PostMapping("/disable")
+    @Operation(summary = "禁用")
+    @PreAuthorize("@ss.hasPermission('menduner:system:mde-user:update')")
+    public CommonResult<Boolean> disable(@RequestParam("id") Long id) {
+        mdeUserService.disable(Collections.singletonList(id));
+        return success(true);
+    }
+
 
 }

+ 2 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/common/auth/AppMdeAuthController.java

@@ -4,6 +4,7 @@ import cn.hutool.core.util.StrUtil;
 import com.citu.framework.common.enums.UserTypeEnum;
 import com.citu.framework.common.pojo.CommonResult;
 import com.citu.framework.idempotent.core.annotation.Idempotent;
+import com.citu.framework.idempotent.core.keyresolver.impl.ExpressionIdempotentKeyResolver;
 import com.citu.framework.idempotent.core.keyresolver.impl.UserIdempotentKeyResolver;
 import com.citu.framework.security.config.SecurityProperties;
 import com.citu.framework.security.core.util.SecurityFrameworkUtils;
@@ -48,6 +49,7 @@ public class AppMdeAuthController {
 
     @PostMapping("/login")
     @Operation(summary = "使用手机/邮箱 + 密码登录")
+    @Idempotent(keyResolver = ExpressionIdempotentKeyResolver.class,keyArg = "#reqVO.account")
     public CommonResult<AppMdeAuthLoginRespVO> login(@RequestBody @Valid AppMdeAuthLoginReqVO reqVO) {
         return success(authService.login(reqVO));
     }

+ 53 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/common/captcha/AppCaptchaController.java

@@ -0,0 +1,53 @@
+package com.citu.module.menduner.system.controller.app.common.captcha;
+
+import cn.hutool.core.util.StrUtil;
+import com.citu.framework.common.util.servlet.ServletUtils;
+import com.xingyuv.captcha.model.common.ResponseModel;
+import com.xingyuv.captcha.model.vo.CaptchaVO;
+import com.xingyuv.captcha.service.CaptchaService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.annotation.security.PermitAll;
+import javax.servlet.http.HttpServletRequest;
+
+@Tag(name = "用户端 - 验证码")
+@RestController("appCaptchaController")
+@RequestMapping("/menduner/system/captcha")
+public class AppCaptchaController {
+
+    @Resource
+    private CaptchaService captchaService;
+
+    @PostMapping({"/get"})
+    @Operation(summary = "获得验证码")
+    @PermitAll
+    public ResponseModel get(@RequestBody CaptchaVO data, HttpServletRequest request) {
+        assert request.getRemoteHost() != null;
+        data.setBrowserInfo(getRemoteId(request));
+        return captchaService.get(data);
+    }
+
+    @PostMapping("/check")
+    @Operation(summary = "校验验证码")
+    @PermitAll
+    public ResponseModel check(@RequestBody CaptchaVO data, HttpServletRequest request) {
+        data.setBrowserInfo(getRemoteId(request));
+        return captchaService.check(data);
+    }
+
+    public static String getRemoteId(HttpServletRequest request) {
+        String ip = ServletUtils.getClientIP(request);
+        String ua = request.getHeader("user-agent");
+        if (StrUtil.isNotBlank(ip)) {
+            return ip + ua;
+        }
+        return request.getRemoteAddr() + ua;
+    }
+
+}

+ 17 - 2
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/order/AppTradeOrderController.java

@@ -7,12 +7,14 @@ import com.citu.framework.signature.core.annotation.ApiSignature;
 import com.citu.module.menduner.common.util.LoginUserContext;
 import com.citu.module.menduner.system.controller.app.jobhunt.order.vo.AppTradeOrderPageReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.order.vo.AppTradeOrderRespVO;
-import com.citu.module.menduner.system.controller.base.order.AppTradeOrderGetReqVO;
 import com.citu.module.menduner.system.controller.base.order.AppTradeOrderCreateReqVO;
+import com.citu.module.menduner.system.controller.base.order.AppTradeOrderGetReqVO;
 import com.citu.module.menduner.system.controller.base.order.AppTradeOrderGetRespVO;
 import com.citu.module.menduner.system.controller.base.order.TradeOrderCreateReqVO;
+import com.citu.module.menduner.system.dal.dataobject.user.UserPackageDO;
 import com.citu.module.menduner.system.enums.user.MdeUserTypeEnum;
 import com.citu.module.menduner.system.service.order.TradeOrderService;
+import com.citu.module.menduner.system.service.user.UserPackageService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.validation.annotation.Validated;
@@ -21,7 +23,10 @@ import org.springframework.web.bind.annotation.*;
 import javax.annotation.Resource;
 import javax.validation.Valid;
 
+import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static com.citu.framework.common.pojo.CommonResult.success;
+import static com.citu.module.menduner.system.enums.ErrorCodeConstants.ENTERPRISE_PACKAGE_NOT_EXISTS;
+import static com.citu.module.menduner.system.enums.ErrorCodeConstants.MDE_REQUEST_ILLEGAL;
 import static com.citu.module.menduner.system.enums.TradeOrderTypeMq.PAY_APP_USER_KEY;
 
 @Tag(name = "求职端 - 交易订单")
@@ -33,6 +38,9 @@ public class AppTradeOrderController {
     @Resource
     private TradeOrderService tradeOrderService;
 
+    @Resource
+    private UserPackageService userPackageService;
+
     @GetMapping("/page")
     @Operation(summary = "获得订单分页")
     @PreAuthenticated
@@ -52,7 +60,14 @@ public class AppTradeOrderController {
         dto.setSpuId(reqVO.getSpuId());
         dto.setSpuName(reqVO.getSpuName());
         dto.setPrice(reqVO.getPrice());
-        return success(tradeOrderService.createOrder(dto,PAY_APP_USER_KEY));
+        UserPackageDO packageDO = userPackageService.getUserPackage(reqVO.getSpuId());
+        if (null == packageDO) {
+            throw exception(ENTERPRISE_PACKAGE_NOT_EXISTS);
+        }
+        if (null == reqVO.getPrice() || !reqVO.getPrice().equals(packageDO.getPrice())) {
+            throw exception(MDE_REQUEST_ILLEGAL);
+        }
+        return success(tradeOrderService.createOrder(dto, PAY_APP_USER_KEY));
     }
 
     @GetMapping("/get/unpaid")

+ 3 - 4
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/person/AppPersonController.java

@@ -7,6 +7,7 @@ import com.citu.framework.idempotent.core.annotation.Idempotent;
 import com.citu.framework.idempotent.core.keyresolver.impl.UserIdempotentKeyResolver;
 import com.citu.framework.security.core.annotations.PreAuthenticated;
 import com.citu.framework.signature.core.annotation.ApiSignature;
+import com.citu.module.menduner.common.util.LoginUserContext;
 import com.citu.module.menduner.system.controller.app.jobhunt.job.vo.AppJobAdvertisedRespVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.person.enterprise.PersonEnterpriseSubscribeReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.person.job.AppPersonJobFavoriteReqVO;
@@ -14,7 +15,6 @@ import com.citu.module.menduner.system.controller.app.jobhunt.person.vo.AppInvit
 import com.citu.module.menduner.system.controller.app.jobhunt.person.vo.AppPersonInfoRespVO;
 import com.citu.module.menduner.system.controller.base.enterprise.vo.EnterpriseBaseSimpleRespVO;
 import com.citu.module.menduner.system.controller.base.person.block.PersonEnterpriseBlockSaveReqVO;
-import com.citu.module.menduner.system.controller.base.person.info.PersonSimpleRespVO;
 import com.citu.module.menduner.system.convert.PersonConvert;
 import com.citu.module.menduner.system.dal.dataobject.person.PersonInfoDO;
 import com.citu.module.menduner.system.service.job.JobIntegrationService;
@@ -60,9 +60,8 @@ public class AppPersonController {
     @GetMapping("/get")
     @ApiSignature(timeout = 30)
     @Operation(summary = "获得人才信息")
-    @Parameter(name = "userId", description = "用户id", required = true, example = "1024")
-    public CommonResult<AppPersonInfoRespVO> getUserInfo(@RequestParam("userId") Long userId) {
-        PersonInfoDO userInfo = personInfoService.getUserInfoByUserId(userId);
+    public CommonResult<AppPersonInfoRespVO> getUserInfo() {
+        PersonInfoDO userInfo = personInfoService.getUserInfoByUserId(LoginUserContext.getUserId());
         return success(PersonConvert.INSTANCE.convert(userInfo));
     }
 

+ 10 - 4
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/person/AppPersonResumeController.java

@@ -1,5 +1,6 @@
 package com.citu.module.menduner.system.controller.app.jobhunt.person;
 
+import cn.hutool.core.util.ObjectUtil;
 import com.citu.framework.common.pojo.CommonResult;
 import com.citu.framework.idempotent.core.annotation.Idempotent;
 import com.citu.framework.idempotent.core.keyresolver.impl.UserIdempotentKeyResolver;
@@ -17,13 +18,12 @@ import com.citu.module.menduner.system.controller.app.jobhunt.person.resume.AppP
 import com.citu.module.menduner.system.controller.app.jobhunt.person.resume.AppPersonInfoSaveReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.person.resume.AppPersonInfoSaveSimpleReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.person.resume.AppPersonInfoTagReqVO;
-import com.citu.module.menduner.system.controller.app.jobhunt.person.trainexp.AppTrainExpRespVO;
-import com.citu.module.menduner.system.controller.app.jobhunt.person.trainexp.AppTrainExpSaveReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.person.skill.AppPersonSkillRespVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.person.skill.AppPersonSkillSaveReqVO;
+import com.citu.module.menduner.system.controller.app.jobhunt.person.trainexp.AppTrainExpRespVO;
+import com.citu.module.menduner.system.controller.app.jobhunt.person.trainexp.AppTrainExpSaveReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.person.workexp.AppWorkExpRespVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.person.workexp.AppWorkExpSaveReqVO;
-import com.citu.module.menduner.system.controller.app.recruit.enterprise.vo.AppRecruitEnterpriseTagReqVO;
 import com.citu.module.menduner.system.convert.*;
 import com.citu.module.menduner.system.dal.dataobject.cvattachment.CvAttachmentDO;
 import com.citu.module.menduner.system.dal.dataobject.eduexp.EduExpDO;
@@ -103,7 +103,6 @@ public class AppPersonResumeController {
     }
 
 
-
     @PreAuthenticated
     @PostMapping("/avatar/update")
     @Operation(summary = "修改人才头像")
@@ -118,7 +117,14 @@ public class AppPersonResumeController {
     @Operation(summary = "保存简易基本信息")
     @Idempotent(keyResolver = UserIdempotentKeyResolver.class)
     public CommonResult<Boolean> saveSimple(@Valid @RequestBody AppPersonInfoSaveSimpleReqVO reqVO) {
+        if (ObjectUtil.isNotEmpty(reqVO.getInterestedList())) {
+            reqVO.getInterestedList().forEach(interested -> jobInterestedService.saveJobInterested(interested));
+        }
+        if (null != reqVO.getWorkExpList()) {
+            reqVO.getWorkExpList().forEach(workExp -> workExpService.saveWorkExp(workExp));
+        }
         return success(personInfoService.saveSimple(reqVO));
+
     }
 
     @PreAuthenticated

+ 5 - 5
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/person/job/AppJobInterestedSaveReqVO.java

@@ -19,23 +19,23 @@ public class AppJobInterestedSaveReqVO {
     @Schema(description = "期望职位", example = "20359")
     private Long positionId;
 
-    @NotNull(message = "{1_100_007_003}")
+//    @NotNull(message = "{1_100_007_003}")
     @Schema(description = "期望行业")
     private List<String> industryIdList;
 
-    @NotBlank(message = "{1_100_007_004}")
+//    @NotBlank(message = "{1_100_007_004}")
     @Schema(description = "求职类型(0全职 1兼职 2临时 3实习)", example = "2")
     private String jobType;
 
-    @NotNull(message = "{1_100_007_005}")
+//    @NotNull(message = "{1_100_007_005}")
     @Schema(description = "薪酬最低要求")
     private BigDecimal payFrom;
 
-    @NotNull(message = "{1_100_007_006}")
+//    @NotNull(message = "{1_100_007_006}")
     @Schema(description = "薪酬最高要求")
     private BigDecimal payTo;
 
-    @NotNull(message = "{1_100_007_007}")
+//    @NotNull(message = "{1_100_007_007}")
     @Schema(description = "工作城市", example = "15253")
     private Long workAreaId;
 

+ 16 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/person/resume/AppPersonInfoSaveSimpleReqVO.java

@@ -1,9 +1,13 @@
 package com.citu.module.menduner.system.controller.app.jobhunt.person.resume;
 
+import com.citu.module.menduner.system.controller.app.jobhunt.person.job.AppJobInterestedSaveReqVO;
+import com.citu.module.menduner.system.controller.app.jobhunt.person.workexp.AppWorkExpSaveReqVO;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import javax.validation.constraints.NotBlank;
+import java.time.LocalDateTime;
+import java.util.List;
 
 @Data
 @Schema(description = "menduner 人才简历-简易基本信息 Request VO")
@@ -28,8 +32,20 @@ public class AppPersonInfoSaveSimpleReqVO {
     @Schema(description = "工作经验", example = "1")
     private String expType;
 
+    @Schema(description = "出生日期")
+    private LocalDateTime birthday;
+
     @NotBlank(message = "{1_100_001_007}")
     @Schema(description = "学历", example = "2")
     private String eduType;
 
+    @Schema(description = "邮箱")
+    private String email;
+
+    @Schema(description = "求职意向")
+    private List<AppJobInterestedSaveReqVO> interestedList;
+
+    @Schema(description = "工作经历")
+    private List<AppWorkExpSaveReqVO> workExpList;
+
 }

+ 1 - 1
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/person/workexp/AppWorkExpSaveReqVO.java

@@ -35,7 +35,7 @@ public class AppWorkExpSaveReqVO {
     @Schema(description = "职位名称(没有选择系统职位时可自定义)", example = "赵六")
     private String positionName;
 
-    @NotNull(message = "{1_100_012_002}")
+//    @NotNull(message = "{1_100_012_002}")
     @Schema(description = "在职开始日期")
     private LocalDateTime startTime;
 

+ 2 - 1
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/jobhunt/user/AppMdeUserController.java

@@ -47,7 +47,8 @@ public class AppMdeUserController {
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
     @ApiSignature(timeout = 30)
     @PreAuthenticated
-    public CommonResult<AppMdeUserRespVO> getMdeUser(@RequestParam("id") Long id) {
+    public CommonResult<AppMdeUserRespVO> getMdeUser() {
+        Long id = LoginUserContext.getUserId();
         MdeUserDO mdeUser = mdeUserService.getMdeUser(id);
         AppMdeUserRespVO resp = BeanUtils.toBean(mdeUser, AppMdeUserRespVO.class);
         resp.setEntitlement(BeanUtils.toBean(userEntitlementService.getByUserId(id), UserEntitlementRespVO.class));

+ 1 - 2
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/recruit/order/AppRecruitTradeOrderController.java

@@ -45,15 +45,14 @@ public class AppRecruitTradeOrderController {
     @PreAuthenticated
     @ApiSignature(timeout = 30)
     public CommonResult<Long> create(@RequestBody @Valid AppTradeOrderCreateReqVO reqVO) {
-        TradeOrderTypeEnum type = TradeOrderTypeEnum.getByType(reqVO.getType());
         TradeOrderCreateReqVO dto = new TradeOrderCreateReqVO();
         dto.setUserType(String.valueOf(MdeUserTypeEnum.ENTERPRISE_USER.getType()));
         dto.setEnterpriseId(LoginUserContext.getEnterpriseId());
         dto.setUserId(LoginUserContext.getUserId());
         dto.setType(reqVO.getType());
         dto.setSpuId(reqVO.getSpuId());
-        dto.setSpuName(type.getName() + ": " + reqVO.getSpuName());
         dto.setPrice(reqVO.getPrice());
+        dto.setSpuName(reqVO.getSpuName());
         return success(tradeOrderService.createOrder(dto,PAY_APP_ENTERPRISE_KEY));
     }
 

+ 8 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/app/recruit/person/AppRecruitPersonCvController.java

@@ -15,6 +15,7 @@ import com.citu.module.menduner.system.service.job.JobCvRelService;
 import com.citu.module.menduner.system.service.job.JobIntegrationService;
 import com.citu.module.menduner.system.service.person.PersonIntegrationService;
 import com.citu.module.menduner.system.service.unfit.UnfitCandidateService;
+import com.citu.module.menduner.system.util.RedisUtils;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.validation.annotation.Validated;
@@ -23,7 +24,9 @@ import org.springframework.web.bind.annotation.*;
 import javax.annotation.Resource;
 import javax.validation.Valid;
 
+import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static com.citu.framework.common.pojo.CommonResult.success;
+import static com.citu.module.menduner.system.enums.ErrorCodeConstants.MDE_REQUEST_ILLEGAL;
 
 @Tag(name = "招聘端 - 人才简历")
 @RestController
@@ -46,6 +49,8 @@ public class AppRecruitPersonCvController {
     @Resource
     private InterviewInviteService interviewInviteService;
 
+    @Resource
+    private RedisUtils redisUtils;
 
     @PreAuthenticated
     @GetMapping("/page")
@@ -68,6 +73,9 @@ public class AppRecruitPersonCvController {
     @ApiSignature(timeout = 30)
     @Operation(summary = "获取人才在线简历详情")
     public CommonResult<AppRecruitPersonDetailRespVO> detail(@RequestParam("userId") Long userId) {
+        if (!redisUtils.checkEnterpriseUserLookPersonPermission(userId)) {
+            throw exception(MDE_REQUEST_ILLEGAL);
+        }
         return success(personIntegrationService.detail(userId));
     }
 

+ 3 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/enterprise/vo/EnterpriseSaveReqVO.java

@@ -70,6 +70,9 @@ public class EnterpriseSaveReqVO {
     @Schema(description = "是否筹备")
     private Boolean prepare;
 
+    @Schema(description = "营业执照照片")
+    private String businessUrl;
+
     @Schema(description = "允许企业发布哪些职位类型")
     private List<String> pubJobTypePerm;
 

+ 4 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/controller/base/job/JobAdvertisedRespVO.java

@@ -120,4 +120,8 @@ public class JobAdvertisedRespVO {
     @ExcelProperty("创建时间")
     private LocalDateTime createTime;
 
+    @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("更新时间")
+    private LocalDateTime updateTime;
+
 }

+ 2 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/dataobject/job/JobAdvertisedDO.java

@@ -67,10 +67,12 @@ public class JobAdvertisedDO extends TenantBaseDO {
     /**
      * 薪酬from
      */
+    @TableField(updateStrategy = FieldStrategy.ALWAYS)
     private BigDecimal payFrom;
     /**
      * 薪酬to
      */
+    @TableField(updateStrategy = FieldStrategy.ALWAYS)
     private BigDecimal payTo;
     /**
      * 薪酬单位

+ 22 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/enterprise/EnterpriseMapper.java

@@ -6,6 +6,7 @@ import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.mybatis.core.mapper.BaseMapperX;
 import com.citu.framework.mybatis.core.query.LambdaQueryWrapperX;
 import com.citu.framework.mybatis.core.query.MPJLambdaWrapperX;
+import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.enterprise.vo.AppEnterpriseSearchPageReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.job.vo.AppEnterpriseJobRespVO;
 import com.citu.module.menduner.system.controller.base.CommonRespVO;
@@ -18,10 +19,13 @@ import com.citu.module.menduner.system.dal.dataobject.enterprise.EnterpriseBusin
 import com.citu.module.menduner.system.dal.dataobject.enterprise.EnterpriseDO;
 import com.citu.module.menduner.system.dal.dataobject.industry.IndustryDO;
 import com.citu.module.menduner.system.dal.dataobject.person.PersonEnterpriseSubscribeDO;
+import com.citu.module.menduner.system.dal.dataobject.user.MdeUserDO;
 import com.citu.module.menduner.system.enums.MendunerStatusEnum;
+import com.citu.module.menduner.system.util.RecruitAnalysisUtils;
 import org.apache.ibatis.annotations.Mapper;
 import org.springframework.util.StringUtils;
 
+import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.List;
 
@@ -131,6 +135,7 @@ public interface EnterpriseMapper extends BaseMapperX<EnterpriseDO> {
         query.inIfPresent(EnterpriseDO::getIndustryId, reqVO.getIndustryIds());
         query.eqIfPresent(EnterpriseDO::getScale, reqVO.getScale());
         query.eqIfPresent(EnterpriseDO::getFinancingStatus, reqVO.getFinancingStatus());
+        query.eqIfPresent(EnterpriseDO::getStatus, MendunerStatusEnum.ENABLE.getStatus());
 
         query.orderByDesc(EnterpriseDO::getVipFlag, EnterpriseDO::getVipExpireDate);
 
@@ -178,5 +183,22 @@ public interface EnterpriseMapper extends BaseMapperX<EnterpriseDO> {
                 .orderByDesc(EnterpriseDO::getUpdateTime));
     }
 
+    /**
+     * 企业的统计
+     **/
+    default List<CommonRespVO> getEnterpriseCount(TimeRangeBaseReqVO reqVO,
+                                            LocalDateTime startTime, LocalDateTime endTime) {
+
+        MPJLambdaWrapperX<EnterpriseDO> wrapper = new MPJLambdaWrapperX<>();
+        wrapper.selectCount(EnterpriseDO::getId, CommonRespVO::getValue);
+
+        wrapper.betweenIfPresent(EnterpriseDO::getCreateTime, startTime, endTime);
+
+        RecruitAnalysisUtils.applyTimeGrouping(wrapper, EnterpriseDO::getCreateTime, reqVO.getType());
+        wrapper.orderByDesc("`key`");
+
+        return selectJoinList(CommonRespVO.class, wrapper);
+    }
+
 
 }

+ 21 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/enterprise/EnterpriseUserBindMapper.java

@@ -5,11 +5,13 @@ import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.mybatis.core.mapper.BaseMapperX;
 import com.citu.framework.mybatis.core.query.LambdaQueryWrapperX;
 import com.citu.framework.mybatis.core.query.MPJLambdaWrapperX;
+import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
 import com.citu.module.menduner.system.api.user.UserInfoRespDTO;
 import com.citu.module.menduner.system.controller.app.jobhunt.job.vo.AppJobCvLookRespVO;
 import com.citu.module.menduner.system.controller.app.recruit.user.vo.AppRecruitEnterpriseUserRespVO;
 import com.citu.module.menduner.system.controller.app.recruit.user.vo.AppRecruitUserPageReqVO;
 import com.citu.module.menduner.system.controller.app.recruit.user.vo.AppRecruitUserRespVO;
+import com.citu.module.menduner.system.controller.base.CommonRespVO;
 import com.citu.module.menduner.system.controller.base.contact.EnterpriseUserSummaryRespVO;
 import com.citu.module.menduner.system.controller.base.enterprise.bind.EnterpriseUserBindDetailRespVO;
 import com.citu.module.menduner.system.controller.base.enterprise.bind.EnterpriseUserBindPageReqVO;
@@ -18,8 +20,10 @@ import com.citu.module.menduner.system.dal.dataobject.enterprise.EnterpriseDO;
 import com.citu.module.menduner.system.dal.dataobject.enterprise.EnterpriseUserBindDO;
 import com.citu.module.menduner.system.enums.MendunerStatusEnum;
 import com.citu.module.menduner.system.enums.enterprise.EnterpriseUserTypeEnum;
+import com.citu.module.menduner.system.util.RecruitAnalysisUtils;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.time.LocalDateTime;
 import java.util.List;
 
 /**
@@ -212,7 +216,24 @@ public interface EnterpriseUserBindMapper extends BaseMapperX<EnterpriseUserBind
 
         return selectJoinOne(UserInfoRespDTO.class, wrapper);
 
+    }
+
+
+    /**
+     * 企业用户的统计
+     **/
+    default List<CommonRespVO> getEnterpriseUserCount(TimeRangeBaseReqVO reqVO,
+                                                  LocalDateTime startTime, LocalDateTime endTime) {
+
+        MPJLambdaWrapperX<EnterpriseUserBindDO> wrapper = new MPJLambdaWrapperX<>();
+        wrapper.selectCount(EnterpriseUserBindDO::getId, CommonRespVO::getValue);
+
+        wrapper.betweenIfPresent(EnterpriseUserBindDO::getCreateTime, startTime, endTime);
+
+        RecruitAnalysisUtils.applyTimeGrouping(wrapper, EnterpriseUserBindDO::getCreateTime, reqVO.getType());
+        wrapper.orderByDesc("`key`");
 
+        return selectJoinList(CommonRespVO.class, wrapper);
     }
 
 

+ 5 - 4
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/job/JobAdvertisedMapper.java

@@ -59,7 +59,7 @@ public interface JobAdvertisedMapper extends BaseMapperX<JobAdvertisedDO> {
                 .eqIfPresent(JobAdvertisedDO::getHire, reqVO.isHire())
                 .eqIfPresent(JobAdvertisedDO::getStatus, reqVO.getStatus())
                 .betweenIfPresent(JobAdvertisedDO::getCreateTime, reqVO.getCreateTime())
-                .orderByDesc(JobAdvertisedDO::getId));
+                .orderByDesc(JobAdvertisedDO::getUpdateTime));
     }
 
     default List<JobAdvertisedDO> selectListByIds( List<Long> ids) {
@@ -269,8 +269,8 @@ public interface JobAdvertisedMapper extends BaseMapperX<JobAdvertisedDO> {
                 .eqIfPresent(JobAdvertisedDO::getEduType, reqVO.getEduType())
                 .eqIfPresent(JobAdvertisedDO::getStatus, reqVO.getStatus())
                 .eqIfPresent(JobAdvertisedDO::getHire, reqVO.getHire())
-                .betweenIfPresent(JobAdvertisedDO::getCreateTime, reqVO.getCreateTime())
-                .orderByDesc(JobAdvertisedDO::getTop, JobAdvertisedDO::getUpdateTime);
+                .betweenIfPresent(JobAdvertisedDO::getCreateTime, reqVO.getCreateTime());
+
 
         query.eq(JobAdvertisedDO::getEnterpriseId, enterpriseId);
         query.eq(JobAdvertisedDO::getUserId, userId);
@@ -281,6 +281,7 @@ public interface JobAdvertisedMapper extends BaseMapperX<JobAdvertisedDO> {
         } else {
             notExpireTime(query);
         }
+        query.orderByDesc(JobAdvertisedDO::getTop, JobAdvertisedDO::getUpdateTime);
         return selectPage(reqVO, query);
     }
 
@@ -296,7 +297,7 @@ public interface JobAdvertisedMapper extends BaseMapperX<JobAdvertisedDO> {
         query.eq(JobAdvertisedDO::getEnterpriseId, enterpriseId);
         query.eq(JobAdvertisedDO::getUserId, userId);
         notExpireTime(query);
-        query.eq(JobAdvertisedDO::getStatus, JobStatusEnum.ENABLE.getStatus());
+//        query.eq(JobAdvertisedDO::getStatus, JobStatusEnum.ENABLE.getStatus());
         query.inIfPresent(JobAdvertisedDO::getId, ids);
         query.orderByDesc(JobAdvertisedDO::getUpdateTime);
         return selectJoinList(AppRecruitJobSimpleRespVO.class, query);

+ 1 - 2
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/job/JobCvRelMapper.java

@@ -71,7 +71,7 @@ public interface JobCvRelMapper extends BaseMapperX<JobCvRelDO> {
         wrapper.likeIfExists(JobCvRelDO::getPhone, reqVO.getPhone());
 
         // 投递的职位 inner 人才信息 (投递人)
-        wrapper.innerJoin(PersonInfoDO.class, "person", PersonInfoDO::getUserId, JobCvRelDO::getUserId);
+        wrapper.leftJoin(PersonInfoDO.class, "person", PersonInfoDO::getUserId, JobCvRelDO::getUserId);
         // 人才相关的条件
         wrapper.likeIfExists("person.name", reqVO.getName());
         wrapper.eqIfExists("person.job_status", reqVO.getJobStatus());
@@ -195,7 +195,6 @@ public interface JobCvRelMapper extends BaseMapperX<JobCvRelDO> {
     default List<JobCvRelDO> selectByJobIdList(List<Long> jobIdList) {
         return selectList(new LambdaQueryWrapperX<JobCvRelDO>()
                 .in(JobCvRelDO::getJobId, jobIdList)
-                .eq(JobCvRelDO::getStatus, MendunerStatusEnum.ENABLE.getStatus())
         );
     }
 

+ 21 - 1
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/person/PersonInfoMapper.java

@@ -6,20 +6,23 @@ import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.mybatis.core.mapper.BaseMapperX;
 import com.citu.framework.mybatis.core.query.LambdaQueryWrapperX;
 import com.citu.framework.mybatis.core.query.MPJLambdaWrapperX;
+import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.person.vo.AppInvitePersonRespVO;
+import com.citu.module.menduner.system.controller.base.CommonRespVO;
 import com.citu.module.menduner.system.controller.base.person.PersonMapQueryReqVO;
 import com.citu.module.menduner.system.controller.base.person.PersonQueryReqVO;
 import com.citu.module.menduner.system.controller.base.person.info.PersonInfoPageReqVO;
 import com.citu.module.menduner.system.controller.base.person.info.PersonInfoRespVO;
-import com.citu.module.menduner.system.controller.base.person.info.PersonSimpleRespVO;
 import com.citu.module.menduner.system.dal.dataobject.enterprise.EnterpriseTalentPoolDO;
 import com.citu.module.menduner.system.dal.dataobject.job.JobInterestedDO;
 import com.citu.module.menduner.system.dal.dataobject.person.PersonInfoDO;
 import com.citu.module.menduner.system.dal.dataobject.user.MdeUserDO;
 import com.citu.module.menduner.system.util.JoinHelper;
+import com.citu.module.menduner.system.util.RecruitAnalysisUtils;
 import org.apache.ibatis.annotations.Mapper;
 
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.List;
 
@@ -233,4 +236,21 @@ public interface PersonInfoMapper extends BaseMapperX<PersonInfoDO> {
         return selectJoinPage(pageParam, AppInvitePersonRespVO.class, query);
     }
 
+    /**
+     * 新创建的简历的统计
+     **/
+    default List<CommonRespVO> getNewPersonCount(TimeRangeBaseReqVO reqVO,
+                                                 LocalDateTime startTime, LocalDateTime endTime) {
+
+        MPJLambdaWrapperX<PersonInfoDO> wrapper = new MPJLambdaWrapperX<>();
+        wrapper.selectCount(PersonInfoDO::getId, CommonRespVO::getValue);
+
+        wrapper.betweenIfPresent(PersonInfoDO::getCreateTime, startTime, endTime);
+
+        RecruitAnalysisUtils.applyTimeGrouping(wrapper, PersonInfoDO::getCreateTime, reqVO.getType());
+        wrapper.orderByDesc("`key`");
+
+        return selectJoinList(CommonRespVO.class, wrapper);
+    }
+
 }

+ 22 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/mysql/user/MdeUserMapper.java

@@ -3,10 +3,15 @@ package com.citu.module.menduner.system.dal.mysql.user;
 import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.mybatis.core.mapper.BaseMapperX;
 import com.citu.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.citu.framework.mybatis.core.query.MPJLambdaWrapperX;
+import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
+import com.citu.module.menduner.system.controller.base.CommonRespVO;
 import com.citu.module.menduner.system.controller.base.user.MdeUserPageReqVO;
 import com.citu.module.menduner.system.dal.dataobject.user.MdeUserDO;
+import com.citu.module.menduner.system.util.RecruitAnalysisUtils;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.time.LocalDateTime;
 import java.util.List;
 
 /**
@@ -43,4 +48,21 @@ public interface MdeUserMapper extends BaseMapperX<MdeUserDO> {
     default List<MdeUserDO> selectListByStatus(String status) {
         return selectList(MdeUserDO::getStatus, status);
     }
+
+    /**
+     * 用户的统计
+     **/
+    default List<CommonRespVO> getUserCount(TimeRangeBaseReqVO reqVO,
+                                            LocalDateTime startTime, LocalDateTime endTime) {
+
+        MPJLambdaWrapperX<MdeUserDO> wrapper = new MPJLambdaWrapperX<>();
+        wrapper.selectCount(MdeUserDO::getId, CommonRespVO::getValue);
+
+        wrapper.betweenIfPresent(MdeUserDO::getCreateTime, startTime, endTime);
+
+        RecruitAnalysisUtils.applyTimeGrouping(wrapper, MdeUserDO::getCreateTime, reqVO.getType());
+        wrapper.orderByDesc("`key`");
+
+        return selectJoinList(CommonRespVO.class, wrapper);
+    }
 }

+ 21 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/dal/redis/RedisKeyConstants.java

@@ -153,4 +153,25 @@ public interface RedisKeyConstants {
      * VALUE 数据类型:String
      **/
     String MDE_AUTH_USER_PWD_LOCK = "mde_auth_user_pwd_lock:%s";
+
+    /**
+     * 手机号枚举(一个ip一个手机号)
+     * <p>
+     * KEY 格式:mde_auth_user_phone_enum:{phone}
+     * VALUE 数据类型:String
+     **/
+    String MDE_AUTH_USER_PHONE_ENUM = "mde_auth_user_phone_enum:%s";
+
+    /**
+     * 企业用户密码错误多次锁定
+     * <p>
+     * KEY 格式:mde_auth_enterprise_user_pwd_lock:{id}
+     * VALUE 数据类型:String
+     **/
+    String MDE_AUTH_ENTERPRISE_USER_PWD_LOCK = "mde_auth_enterprise_user_pwd_lock:%s";
+
+    /**
+     * 企业用户查看人才权限
+     **/
+    String MDE_AUTH_ENTERPRISE_USER_VIEW_PERMISSION = "mde_auth_enterprise_user_look_person_permission:%s-%s";
 }

+ 30 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/framework/captcha/config/CituCaptchaConfiguration.java

@@ -0,0 +1,30 @@
+package com.citu.module.menduner.system.framework.captcha.config;
+
+
+import com.citu.module.menduner.system.framework.captcha.core.RedisCaptchaServiceImpl;
+import com.xingyuv.captcha.properties.AjCaptchaProperties;
+import com.xingyuv.captcha.service.CaptchaCacheService;
+import com.xingyuv.captcha.service.impl.CaptchaServiceFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.core.StringRedisTemplate;
+
+/**
+ * 验证码的配置类
+ *
+ * @author Rayson
+ */
+@Configuration(proxyBeanMethods = false)
+public class CituCaptchaConfiguration {
+
+    @Bean
+    public CaptchaCacheService captchaCacheService(AjCaptchaProperties config,
+                                                   StringRedisTemplate stringRedisTemplate) {
+        CaptchaCacheService captchaCacheService = CaptchaServiceFactory.getCache(config.getCacheType().name());
+        if (captchaCacheService instanceof RedisCaptchaServiceImpl) {
+            ((RedisCaptchaServiceImpl) captchaCacheService).setStringRedisTemplate(stringRedisTemplate);
+        }
+        return captchaCacheService;
+    }
+
+}

+ 49 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/framework/captcha/core/RedisCaptchaServiceImpl.java

@@ -0,0 +1,49 @@
+package com.citu.module.menduner.system.framework.captcha.core;
+
+import com.xingyuv.captcha.service.CaptchaCacheService;
+import lombok.Setter;
+import org.springframework.data.redis.core.StringRedisTemplate;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 基于 Redis 实现验证码的存储
+ *
+ * @author 星语
+ */
+@Setter
+public class RedisCaptchaServiceImpl implements CaptchaCacheService {
+
+    private StringRedisTemplate stringRedisTemplate;
+
+    @Override
+    public String type() {
+        return "redis";
+    }
+
+    @Override
+    public void set(String key, String value, long expiresInSeconds) {
+        stringRedisTemplate.opsForValue().set(key, value, expiresInSeconds, TimeUnit.SECONDS);
+    }
+
+    @Override
+    public boolean exists(String key) {
+        return Boolean.TRUE.equals(stringRedisTemplate.hasKey(key));
+    }
+
+    @Override
+    public void delete(String key) {
+        stringRedisTemplate.delete(key);
+    }
+
+    @Override
+    public String get(String key) {
+        return stringRedisTemplate.opsForValue().get(key);
+    }
+
+    @Override
+    public Long increment(String key, long val) {
+        return stringRedisTemplate.opsForValue().increment(key,val);
+    }
+
+}

+ 8 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/framework/captcha/package-info.java

@@ -0,0 +1,8 @@
+/**
+ * 验证码拓展
+ *
+ * 基于 aj-captcha 实现滑块验证码,文档:https://ajcaptcha.beliefteam.cn/captcha-doc/
+ *
+ * @author 星语
+ */
+package com.citu.module.menduner.system.framework.captcha;

+ 42 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/mq/consumer/PublishJobConsumer.java

@@ -0,0 +1,42 @@
+package com.citu.module.menduner.system.mq.consumer;
+
+
+import com.citu.module.menduner.system.dal.dataobject.order.TradeOrderDO;
+import com.citu.module.menduner.system.enums.TradeOrderTypeMq;
+import com.citu.module.menduner.system.service.job.JobAdvertisedService;
+import com.citu.module.menduner.system.service.order.TradeOrderService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+import org.apache.rocketmq.spring.core.RocketMQListener;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+
+/**
+ * 职位完成支付 消费
+ **/
+@Slf4j
+@Component
+@RocketMQMessageListener(
+        topic = TradeOrderTypeMq.PUBLISH_JOB_ORDER_TOPIC,
+        consumerGroup = TradeOrderTypeMq.PUBLISH_JOB_ORDER_TOPIC + "_CONSUMER"
+)
+public class PublishJobConsumer implements RocketMQListener<Long> {
+
+    @Resource
+    private TradeOrderService tradeOrderService;
+
+    @Resource
+    private JobAdvertisedService service;
+
+    @Override
+    public void onMessage(Long orderId) {
+        log.info("接收到队列消息[{}]", orderId);
+        TradeOrderDO order = tradeOrderService.getOrder(orderId);
+        // 计算新的过期时间,支付时间+120天
+        LocalDateTime updateTime = order.getPayTime();
+        LocalDateTime newExpireTime = updateTime.plusDays(120);
+        service.enableAndUpdateExpireTime(order.getSpuId(), newExpireTime);
+    }
+}

+ 3 - 3
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/mq/consumer/PublishJobHireConsumer.java

@@ -11,10 +11,9 @@ import org.apache.rocketmq.spring.core.RocketMQListener;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
-import java.util.Collections;
 
 /**
- * 众聘职位完成支付 消费
+ * 职位完成支付 消费
  **/
 @Slf4j
 @Component
@@ -34,6 +33,7 @@ public class PublishJobHireConsumer implements RocketMQListener<Long> {
     public void onMessage(Long orderId) {
         log.info("接收到队列消息[{}]", orderId);
         TradeOrderDO order = tradeOrderService.getOrder(orderId);
-        service.enable(Collections.singletonList(order.getSpuId()));
+        // TODO 众聘职位过期时间不知道
+        service.enableAndUpdateExpireTime(order.getSpuId(),null);
     }
 }

+ 2 - 1
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/mq/consumer/UserMemberConsumer.java

@@ -3,7 +3,6 @@ package com.citu.module.menduner.system.mq.consumer;
 import com.baomidou.dynamic.datasource.annotation.DSTransactional;
 import com.citu.module.menduner.common.enums.EventAsyncUrlEnum;
 import com.citu.module.menduner.common.message.EventAsyncConfirmMessage;
-import com.citu.module.menduner.common.util.LoginUserContext;
 import com.citu.module.menduner.system.controller.base.user.vip.UserEntitlementSaveReqVO;
 import com.citu.module.menduner.system.dal.dataobject.order.TradeOrderDO;
 import com.citu.module.menduner.system.dal.dataobject.user.MdeUserDO;
@@ -122,7 +121,9 @@ public class UserMemberConsumer implements RocketMQListener<Long> {
                     .build()
             );
         } else {
+
             userEntitleService.updateUserEntitlement(UserEntitlementSaveReqVO.builder()
+                    .id(entitlement.getId())
                     .userId(user.getId())
                     .resumeRefreshCount(packageDO.getResumeRefreshCount() + packageDO.getResumeRefreshCount())
                     // 覆盖权限,以新套餐为准,不会出现,买大权益套餐还能买小权益套餐的情况

+ 45 - 24
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/auth/MdeAuthServiceImpl.java

@@ -41,7 +41,8 @@ import com.xingyuv.captcha.model.vo.CaptchaVO;
 import com.xingyuv.captcha.service.CaptchaService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -53,8 +54,7 @@ import java.util.concurrent.TimeUnit;
 import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static com.citu.framework.common.util.servlet.ServletUtils.getClientIP;
 import static com.citu.framework.web.core.util.WebFrameworkUtils.getTerminal;
-import static com.citu.module.menduner.system.dal.redis.RedisKeyConstants.MDE_AUTH_USER_PWD_LOCK;
-import static com.citu.module.menduner.system.dal.redis.RedisKeyConstants.MDE_AUTH_USER_SMS_CODE_LOCK;
+import static com.citu.module.menduner.system.dal.redis.RedisKeyConstants.*;
 import static com.citu.module.menduner.system.enums.ErrorCodeConstants.*;
 
 /**
@@ -92,7 +92,8 @@ public class MdeAuthServiceImpl implements MdeAuthService {
     @Resource
     protected CaptchaService captchaService;
     @Resource
-    private StringRedisTemplate redisTemplate;
+    @Lazy
+    private RedisTemplate<String, String> redisTemplate;
 
     @VisibleForTesting
     protected void validateCaptcha(AppMdeAuthLoginReqVO reqVO) {
@@ -116,7 +117,12 @@ public class MdeAuthServiceImpl implements MdeAuthService {
     @Override
     public AppMdeAuthLoginRespVO login(AppMdeAuthLoginReqVO reqVO) {
         // 校验验证码
-        validateCaptcha(reqVO);
+       String userAgent = ServletUtils.getUserAgent().toLowerCase();
+       if(!userAgent.contains("micromessenger")
+               && !userAgent.contains("wechatdevtools")
+               && !userAgent.contains("miniprogram")) {
+           validateCaptcha(reqVO);
+       }
         LoginLogTypeEnum logTypeEnum = LoginLogTypeEnum.LOGIN_MOBILE;
         // TODO 求职端用户 手机号+密码,招聘端用户 邮箱+密码
         if (ValidationUtils.isMobile(reqVO.getAccount())) {
@@ -143,9 +149,28 @@ public class MdeAuthServiceImpl implements MdeAuthService {
         // 校验账号是否存在
         MdeUserDO user = userService.getUserByPhone(account);
         if (null == user) {
+            String num =
+                    redisTemplate.opsForValue()
+                            .get(String.format(MDE_AUTH_USER_PHONE_ENUM, account));
+            Integer numInt = Integer.parseInt(null == num ? "0" : num) + 1;
+
+            redisTemplate.opsForValue()
+                    .set(String.format(MDE_AUTH_USER_PHONE_ENUM, account), String.valueOf(numInt), 8, TimeUnit.HOURS);
+
             createLoginLog(null, account, logTypeEnum, LoginResultEnum.BAD_CREDENTIALS);
-            throw exception(MDE_USER_MOBILE_NOT_EXISTS);
+            if (numInt >= 3) {
+                // 8个小时内输错3次 锁定
+                throw exception(MDE_USER_PHONE_NOT_EXISTS_ERROR);
+            } else {
+                throw exception(MDE_USER_MOBILE_NOT_EXISTS);
+            }
         }
+        // 校验是否禁用
+        if (ObjectUtil.notEqual(user.getStatus(), MendunerStatusEnum.ENABLE.getStatus())) {
+            createLoginLog(user.getId(), account, logTypeEnum, LoginResultEnum.USER_DISABLED);
+            throw exception(MDE_AUTH_LOGIN_USER_DISABLED);
+        }
+
         if (!userService.isPasswordMatch(password, user.getPassword())) {
             // 只有输错密码并且是首次才提示修改密码
             if (null == user.getLoginDate()) {
@@ -155,15 +180,15 @@ public class MdeAuthServiceImpl implements MdeAuthService {
                 // 获取错误次数
                 String num =
                         redisTemplate.opsForValue()
-                                .get(String.format(MDE_AUTH_USER_PWD_LOCK, user.getPhone()));
+                                .get(String.format(MDE_AUTH_USER_PWD_LOCK, user.getId()));
                 Integer numInt = Integer.parseInt(null == num ? "0" : num) + 1;
 
                 redisTemplate.opsForValue()
-                        .setIfAbsent(MDE_AUTH_USER_PWD_LOCK, String.valueOf(numInt), 8, TimeUnit.HOURS);
+                        .set(String.format(MDE_AUTH_USER_PWD_LOCK, user.getId()), String.valueOf(numInt), 8, TimeUnit.HOURS);
                 if (numInt >= 5) {
                     // 8个小时内输错5次 锁定
                     userService.disable(Collections.singletonList(user.getId()));
-                    createLoginLog(user.getId(),account,logTypeEnum, LoginResultEnum.USER_DISABLED);
+                    createLoginLog(user.getId(), account, logTypeEnum, LoginResultEnum.USER_DISABLED);
                     throw exception(MDE_AUTH_LOGIN_USER_DISABLED);
                 } else {
                     // 提示账户密码错误
@@ -173,11 +198,8 @@ public class MdeAuthServiceImpl implements MdeAuthService {
             }
         }
 
-        // 校验是否禁用
-        if (ObjectUtil.notEqual(user.getStatus(), MendunerStatusEnum.ENABLE.getStatus())) {
-            createLoginLog(user.getId(), account, logTypeEnum, LoginResultEnum.USER_DISABLED);
-            throw exception(MDE_AUTH_LOGIN_USER_DISABLED);
-        }
+        // 登录成功就清理
+        redisTemplate.delete(String.format(MDE_AUTH_USER_PWD_LOCK, user.getId()));
         return user;
 
     }
@@ -207,7 +229,6 @@ public class MdeAuthServiceImpl implements MdeAuthService {
     }
 
     @Override
-    @DSTransactional
     public AppMdeAuthLoginRespVO smsLogin(AppMdeAuthSmsLoginReqVO reqVO) {
         // 校验验证码
         String userIp = getClientIP();
@@ -228,15 +249,21 @@ public class MdeAuthServiceImpl implements MdeAuthService {
             Assert.notNull(user, "获取用户失败,结果为空");
         }
 
+        // 是否禁用
+        if (ObjectUtil.notEqual(user.getStatus(), MendunerStatusEnum.ENABLE.getStatus())) {
+            createLoginLog(user.getId(), user.getPhone(), LoginLogTypeEnum.LOGIN_SMS, LoginResultEnum.USER_DISABLED);
+            throw exception(MDE_AUTH_LOGIN_USER_DISABLED);
+        }
+
         if (result.isError()) {
             // 获取错误次数
             String num =
                     redisTemplate.opsForValue()
-                            .get(String.format(MDE_AUTH_USER_SMS_CODE_LOCK, reqVO.getPhone()));
+                            .get(String.format(MDE_AUTH_USER_SMS_CODE_LOCK, user.getId()));
             Integer numInt = Integer.parseInt(null == num ? "0" : num) + 1;
 
             redisTemplate.opsForValue()
-                    .setIfAbsent(MDE_AUTH_USER_SMS_CODE_LOCK, String.valueOf(numInt), 8, TimeUnit.HOURS);
+                    .set(String.format(MDE_AUTH_USER_SMS_CODE_LOCK, user.getId()), String.valueOf(numInt), 8, TimeUnit.HOURS);
 
             if (numInt >= 5) {
                 // 8个小时内输错5次 锁定
@@ -249,12 +276,6 @@ public class MdeAuthServiceImpl implements MdeAuthService {
             }
         }
 
-        // 是否禁用
-        if (ObjectUtil.notEqual(user.getStatus(), MendunerStatusEnum.ENABLE.getStatus())) {
-            createLoginLog(user.getId(), user.getPhone(), LoginLogTypeEnum.LOGIN_SMS, LoginResultEnum.USER_DISABLED);
-            throw exception(MDE_AUTH_LOGIN_USER_DISABLED);
-        }
-
         // 如果 socialType 非空,说明需要绑定社交用户
         String openid = null;
         if (reqVO.getSocialType() != null) {
@@ -262,7 +283,7 @@ public class MdeAuthServiceImpl implements MdeAuthService {
                     reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())).getCheckedData();
         }
         // 登录成功就清理
-        redisTemplate.delete(MDE_AUTH_USER_SMS_CODE_LOCK);
+        redisTemplate.delete(String.format(MDE_AUTH_USER_SMS_CODE_LOCK, user.getId()));
         // 创建 Token 令牌,记录登录日志
         return createTokenAfterLoginSuccess(user, reqVO.getPhone(), LoginLogTypeEnum.LOGIN_SMS, openid);
     }

+ 29 - 10
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/auth/MdeEnterpriseAuthServiceImpl.java

@@ -36,6 +36,7 @@ import com.xingyuv.captcha.model.common.ResponseModel;
 import com.xingyuv.captcha.model.vo.CaptchaVO;
 import com.xingyuv.captcha.service.CaptchaService;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
@@ -47,6 +48,7 @@ import java.util.concurrent.TimeUnit;
 
 import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static com.citu.framework.common.util.servlet.ServletUtils.getClientIP;
+import static com.citu.module.menduner.system.dal.redis.RedisKeyConstants.MDE_AUTH_ENTERPRISE_USER_PWD_LOCK;
 import static com.citu.module.menduner.system.enums.ErrorCodeConstants.*;
 
 /**
@@ -81,10 +83,10 @@ public class MdeEnterpriseAuthServiceImpl implements MdeEnterpriseAuthService {
     @Resource
     private MailSendApi mailSendApi;
     @Resource
+    @Lazy
     private RedisTemplate<String, Object> redisTemplate;
 
     @Override
-    @DSTransactional
     public AppMdeAuthLoginRespVO login(String email, String password) {
         // 使用邮箱 + 密码,进行登录。
         EnterpriseUserBindDO bindUser = check(email, password);
@@ -126,16 +128,22 @@ public class MdeEnterpriseAuthServiceImpl implements MdeEnterpriseAuthService {
         final LoginLogTypeEnum logTypeEnum = LoginLogTypeEnum.LOGIN_EMAIL;
         // 校验账号是否存在
         EnterpriseUserBindDO user = userBindService.getByEmail(email);
-        if (null == user) {
+        // 数据库表是utf8mb4_general_ci,不区分大小写都能查询出来的,所以要再次对比
+        if (null == user || !email.equals(user.getEmail())) {
             // 如果用户为空,则效验是否存在企业注册申请
             registerService.validateApplyByEmail(email);
             // 邮箱存在注册申请则直接抛出异常不走下面
             createLoginLog(null, email, logTypeEnum, LoginResultEnum.BAD_CREDENTIALS);
             throw exception(MDE_USER_EMAIL_NOT_REGISTERED);
         }
+        // 校验是否禁用
+        if (ObjectUtil.notEqual(user.getStatus(), MendunerStatusEnum.ENABLE.getStatus())) {
+            createLoginLog(user.getId(), email, logTypeEnum, LoginResultEnum.USER_DISABLED);
+            throw exception(MDE_ENTERPRISE_USER_BIND_IS_DISABLE);
+        }
         if (!userBindService.isPasswordMatch(password, user.getPassword())) {
             // 只有输错密码并且是首次and密码和邮箱一致(旧平台同步的数据才是邮箱和密码一致)才需要发邮箱告诉密码
-            if (null == user.getLoginDate()&&userBindService.isPasswordMatch(user.getEmail(), user.getPassword())) {
+            if (null == user.getLoginDate() && userBindService.isPasswordMatch(user.getEmail(), user.getPassword())) {
                 // 效验有没有更改过密码
                 // 没有则发送邮箱
                 MailSendSingleToUserReqDTO reqDTO = new MailSendSingleToUserReqDTO();
@@ -145,17 +153,28 @@ public class MdeEnterpriseAuthServiceImpl implements MdeEnterpriseAuthService {
                 mailSendApi.sendSingleMailToMember(reqDTO).getCheckedData();
                 throw exception(MDE_USER_EMAIL_INIT_PASSWORD);
             } else {
-                createLoginLog(user.getId(), email, logTypeEnum, LoginResultEnum.BAD_CREDENTIALS);
-                throw exception(MDE_AUTH_LOGIN_BAD_CREDENTIALS);
+                // 获取错误次数
+                String num = (String) redisTemplate.opsForValue()
+                        .get(String.format(MDE_AUTH_ENTERPRISE_USER_PWD_LOCK, user.getId()));
+                Integer numInt = Integer.parseInt(null == num ? "0" : num) + 1;
+
+                redisTemplate.opsForValue()
+                        .set(String.format(MDE_AUTH_ENTERPRISE_USER_PWD_LOCK, user.getId())
+                                , String.valueOf(numInt), 8, TimeUnit.HOURS);
+                if (numInt >= 5) {
+                    // 8个小时内输错5次 锁定
+                    userBindService.disable(user.getId());
+                    createLoginLog(user.getId(), email, logTypeEnum, LoginResultEnum.USER_DISABLED);
+                    throw exception(MDE_ENTERPRISE_USER_BIND_IS_DISABLE);
+                } else {
+                    createLoginLog(user.getId(), email, logTypeEnum, LoginResultEnum.BAD_CREDENTIALS);
+                    throw exception(MDE_AUTH_LOGIN_BAD_CREDENTIALS);
+                }
             }
         }
-        // 校验是否禁用
-        if (ObjectUtil.notEqual(user.getStatus(), MendunerStatusEnum.ENABLE.getStatus())) {
-            createLoginLog(user.getId(), email, logTypeEnum, LoginResultEnum.USER_DISABLED);
-            throw exception(MDE_AUTH_LOGIN_USER_DISABLED);
-        }
 
 
+        redisTemplate.delete(String.format(MDE_AUTH_ENTERPRISE_USER_PWD_LOCK, user.getId()));
         return user;
     }
 

+ 9 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/enterprise/EnterpriseService.java

@@ -2,6 +2,7 @@ package com.citu.module.menduner.system.service.enterprise;
 
 import com.citu.framework.common.pojo.PageParam;
 import com.citu.framework.common.pojo.PageResult;
+import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.enterprise.vo.AppEnterpriseClickReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.enterprise.vo.AppEnterpriseDetailRespVO;
 import com.citu.module.menduner.system.controller.app.recruit.enterprise.vo.*;
@@ -11,6 +12,7 @@ import com.citu.module.menduner.system.dal.dataobject.enterprise.EnterpriseDO;
 
 import javax.validation.Valid;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -135,6 +137,13 @@ public interface EnterpriseService {
      * @param reqVO
      **/
     void updatePubJobTypePerm(EnterprisePubJobTypePermUpdateReqVO reqVO);
+
+    /**
+     * 企业统计
+     *
+     * @param reqVO
+     **/
+    Map<String, Object[]> getEnterpriseCount(TimeRangeBaseReqVO reqVO);
     // ========== 求职端 ==========
 
     /**

+ 16 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/enterprise/EnterpriseServiceImpl.java

@@ -7,6 +7,7 @@ import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.common.util.object.BeanUtils;
 import com.citu.framework.datapermission.core.annotation.DataPermission;
 import com.citu.framework.dict.core.DictFrameworkUtils;
+import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
 import com.citu.module.menduner.common.util.LoginUserContext;
 import com.citu.module.menduner.system.api.python.GraphSendDTO;
 import com.citu.module.menduner.system.controller.app.jobhunt.enterprise.vo.AppEnterpriseClickReqVO;
@@ -37,13 +38,16 @@ import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
+import java.time.LocalDateTime;
 import java.util.*;
 import java.util.stream.Collectors;
 
 import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static com.citu.framework.common.util.collection.CollectionUtils.convertSet;
+import static com.citu.module.menduner.common.util.TimeUtils.generateDateTimeRange;
 import static com.citu.module.menduner.system.enums.DictTypeConstants.*;
 import static com.citu.module.menduner.system.enums.ErrorCodeConstants.MDE_ENTERPRISE_NOT_EXISTS;
+import static com.citu.module.menduner.system.util.RecruitAnalysisUtils.packBarCount;
 
 /**
  * 企业信息 Service 实现类
@@ -237,6 +241,18 @@ public class EnterpriseServiceImpl implements EnterpriseService {
         enterpriseMapper.updateById(enterprise);
     }
 
+    @Override
+    public Map<String, Object[]> getEnterpriseCount(TimeRangeBaseReqVO reqVO) {
+        LocalDateTime[] timeRange = generateDateTimeRange(reqVO);
+        List<CommonRespVO> result = enterpriseMapper.getEnterpriseCount(reqVO, timeRange[0], timeRange[1]);
+        List<CommonRespVO> sortedResult = result.stream()
+                .sorted(Comparator.comparing(CommonRespVO::getKey))
+                .collect(Collectors.toList());
+        return packBarCount(sortedResult.stream()
+                .filter(c -> null != c.getKey())
+                .collect(Collectors.toList())
+        );
+    }
 
     @Override
     public void click(AppEnterpriseClickReqVO reqVO) {

+ 23 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/enterprise/bind/EnterpriseUserBindService.java

@@ -1,6 +1,7 @@
 package com.citu.module.menduner.system.service.enterprise.bind;
 
 import com.citu.framework.common.pojo.PageResult;
+import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.enterprise.vo.AppEnterpriseUserBindRespVO;
 import com.citu.module.menduner.system.controller.app.recruit.user.vo.*;
 import com.citu.module.menduner.system.controller.base.contact.EnterpriseUserContactRespVO;
@@ -10,6 +11,7 @@ import com.citu.module.menduner.system.dal.dataobject.enterprise.EnterpriseUserB
 
 import javax.validation.Valid;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 企业登录用户 Service 接口
@@ -159,6 +161,13 @@ public interface EnterpriseUserBindService {
      **/
     void updateEmail(Long id,String email);
 
+    /**
+     * 企业用户统计
+     *
+     * @param reqVO 查询条件
+     **/
+    Map<String, Object[]> getEnterpriseUserCount(TimeRangeBaseReqVO reqVO);
+
     // ========== 求职端 ==========
 
     /**
@@ -223,6 +232,20 @@ public interface EnterpriseUserBindService {
      **/
     boolean enable(List<Long> ids);
 
+    /**
+     * 禁用账号
+     *
+     * @return id
+     **/
+    boolean disable(Long id);
+
+    /**
+     * 启用账户
+     *
+     * @return id
+     **/
+    boolean enable(Long ids);
+
     /**
      * 获取用户列表分页数据
      *

+ 52 - 16
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/enterprise/bind/EnterpriseUserBindServiceImpl.java

@@ -6,9 +6,14 @@ import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.common.util.object.BeanUtils;
 import com.citu.framework.common.util.validation.ValidationUtils;
 import com.citu.framework.security.core.LoginUser;
+import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
 import com.citu.module.menduner.common.util.LoginUserContext;
 import com.citu.module.menduner.system.controller.app.jobhunt.enterprise.vo.AppEnterpriseUserBindRespVO;
-import com.citu.module.menduner.system.controller.app.recruit.user.vo.*;
+import com.citu.module.menduner.system.controller.app.recruit.user.vo.AppRecruitEnterpriseUserRespVO;
+import com.citu.module.menduner.system.controller.app.recruit.user.vo.AppRecruitUserPageReqVO;
+import com.citu.module.menduner.system.controller.app.recruit.user.vo.AppRecruitUserRespVO;
+import com.citu.module.menduner.system.controller.app.recruit.user.vo.AppRecruitUserSaveReqVO;
+import com.citu.module.menduner.system.controller.base.CommonRespVO;
 import com.citu.module.menduner.system.controller.base.contact.EnterpriseUserContactRespVO;
 import com.citu.module.menduner.system.controller.base.contact.EnterpriseUserSummaryRespVO;
 import com.citu.module.menduner.system.controller.base.enterprise.bind.*;
@@ -21,8 +26,8 @@ import com.citu.module.menduner.system.enums.MendunerStatusEnum;
 import com.citu.module.menduner.system.enums.enterprise.EnterpriseUserTypeEnum;
 import com.citu.module.menduner.system.enums.permission.MdeDefaultRoleEnum;
 import com.citu.module.menduner.system.service.permission.MdePermissionService;
-import com.citu.module.menduner.system.service.user.MdeUserService;
 import org.springframework.context.annotation.Lazy;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
@@ -30,14 +35,16 @@ import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
 
 import static com.citu.framework.common.exception.enums.GlobalErrorCodeConstants.FORBIDDEN;
 import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static com.citu.module.menduner.common.util.LoginUserContext.checkIsEnterpriseUser;
+import static com.citu.module.menduner.common.util.TimeUtils.generateDateTimeRange;
+import static com.citu.module.menduner.system.dal.redis.RedisKeyConstants.MDE_AUTH_ENTERPRISE_USER_PWD_LOCK;
 import static com.citu.module.menduner.system.enums.ErrorCodeConstants.*;
+import static com.citu.module.menduner.system.util.RecruitAnalysisUtils.packBarCount;
 
 /**
  * 企业登录用户 Service 实现类
@@ -59,11 +66,11 @@ public class EnterpriseUserBindServiceImpl implements EnterpriseUserBindService
     private EnterpriseMapper enterpriseMapper;
 
     @Resource
-    @Lazy
-    private MdeUserService mdeUserService;
+    private PasswordEncoder passwordEncoder;
 
     @Resource
-    private PasswordEncoder passwordEncoder;
+    @Lazy
+    private RedisTemplate<String, String> redisTemplate;
 
     @Override
     public Long createEnterpriseUserBind(EnterpriseUserBindSaveReqVO createReqVO) {
@@ -180,19 +187,19 @@ public class EnterpriseUserBindServiceImpl implements EnterpriseUserBindService
     @DSTransactional
     public void createUser(EnterpriseUserBindDO userBindDO) {
         userBindDO.setEmail(userBindDO.getEmail().trim());
-        if(!StringUtils.hasText(userBindDO.getEmail())) {
+        if (!StringUtils.hasText(userBindDO.getEmail())) {
             throw exception(MDE_ENTERPRISE_USER_BIND_EMAIL_NOT_NULL);
         }
-        if(!ValidationUtils.isEmail(userBindDO.getEmail())) {
+        if (!ValidationUtils.isEmail(userBindDO.getEmail())) {
             throw exception(MDE_ENTERPRISE_USER_BIND_EMAIL_FORMAT_ERROR);
         }
-        if(null != getByEmail(userBindDO.getEmail())) {
+        if (null != getByEmail(userBindDO.getEmail())) {
             throw exception(MDE_ENTERPRISE_USER_BIND_EMAIL_DUPLICATE);
         }
         if (!StringUtils.hasText(userBindDO.getPassword())) {
             // 没有输入密码,则邮箱作为密码
             userBindDO.setPassword(encodePassword(userBindDO.getEmail()));
-        }else {
+        } else {
             userBindDO.setPassword(encodePassword(userBindDO.getPassword()));
         }
         mapper.insert(userBindDO);
@@ -207,6 +214,9 @@ public class EnterpriseUserBindServiceImpl implements EnterpriseUserBindService
 
     @Override
     public EnterpriseUserBindDO getByEmail(String email) {
+        if(!ValidationUtils.isEmail(email)) {
+            throw exception(MDE_ENTERPRISE_USER_BIND_EMAIL_FORMAT_ERROR);
+        }
         return mapper.selectByEmail(email);
     }
 
@@ -244,6 +254,19 @@ public class EnterpriseUserBindServiceImpl implements EnterpriseUserBindService
                 .email(email).build());
     }
 
+    @Override
+    public Map<String, Object[]> getEnterpriseUserCount(TimeRangeBaseReqVO reqVO) {
+        LocalDateTime[] timeRange = generateDateTimeRange(reqVO);
+        List<CommonRespVO> result = mapper.getEnterpriseUserCount(reqVO, timeRange[0], timeRange[1]);
+        List<CommonRespVO> sortedResult = result.stream()
+                .sorted(Comparator.comparing(CommonRespVO::getKey))
+                .collect(Collectors.toList());
+        return packBarCount(sortedResult.stream()
+                .filter(c -> null != c.getKey())
+                .collect(Collectors.toList())
+        );
+    }
+
     @Override
     public EnterpriseUserContactRespVO getContact(Long enterpriseId, Long userId) {
         EnterpriseUserBindDO userBindDO = mapper.selectByEnterpriseIdAndUserId(enterpriseId, userId);
@@ -378,8 +401,7 @@ public class EnterpriseUserBindServiceImpl implements EnterpriseUserBindService
             if (MendunerStatusEnum.DISABLE.getStatus().equals(userBindDO.getStatus())) {
                 throw exception(MDE_ENTERPRISE_USER_BIND_IS_DISABLE);
             }
-            userBindDO.setStatus(MendunerStatusEnum.DISABLE.getStatus());
-            mapper.updateById(userBindDO);
+            disable(id);
         }
         return true;
     }
@@ -392,12 +414,26 @@ public class EnterpriseUserBindServiceImpl implements EnterpriseUserBindService
             if (MendunerStatusEnum.ENABLE.getStatus().equals(userBindDO.getStatus())) {
                 return true;
             }
-            userBindDO.setStatus(MendunerStatusEnum.ENABLE.getStatus());
-            mapper.updateById(userBindDO);
+            enable(id);
         }
         return true;
     }
 
+    @Override
+    public boolean disable(Long id) {
+        mapper.updateById(EnterpriseUserBindDO.builder()
+                .id(id).status(MendunerStatusEnum.DISABLE.getStatus()).build());
+        return true;
+    }
+
+    @Override
+    public boolean enable(Long id) {
+        mapper.updateById(EnterpriseUserBindDO.builder()
+                .id(id).status(MendunerStatusEnum.ENABLE.getStatus()).build());
+        redisTemplate.delete(String.format(MDE_AUTH_ENTERPRISE_USER_PWD_LOCK, id));
+        return true;
+    }
+
     private EnterpriseUserBindDO valid(Long id) {
         LoginUser loginUser = checkIsEnterpriseUser();
 

+ 1 - 7
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/industry/IndustryServiceImpl.java

@@ -299,12 +299,6 @@ public class IndustryServiceImpl implements IndustryService {
         }
 
         List<IndustryDO> industryDOS = industryMapper.selectBatchIds(ids);
-//        List<IndustryDO> industryPaerntDOS = industryMapper.selectBatchIds(industryParentIds);
-//
-//        Map<Long, String> parentMap  = new HashMap<>();
-//        industryPaerntDOS.forEach(item->parentMap.put(item.getId(), item.getNameCn()));
-
-
         return industryDOS.stream().collect(Collectors.toMap(IndustryDO::getId, IndustryDO::getNameCn));
     }
-}//        Set<Long> industryParentIds = industryDOS.stream().map(IndustryDO::getParentId).collect(Collectors.toSet());
+}

+ 16 - 3
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/interview/InterviewInviteServiceImpl.java

@@ -1,6 +1,7 @@
 package com.citu.module.menduner.system.service.interview;
 
 
+import cn.hutool.core.collection.CollUtil;
 import com.baomidou.dynamic.datasource.annotation.DSTransactional;
 import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.common.util.object.BeanUtils;
@@ -9,6 +10,7 @@ import com.citu.module.menduner.common.util.LoginUserContext;
 import com.citu.module.menduner.system.controller.app.jobhunt.interview.vo.AppInterviewInvitePageReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.interview.vo.AppInterviewInviteRespVO;
 import com.citu.module.menduner.system.controller.app.recruit.interview.vo.*;
+import com.citu.module.menduner.system.controller.app.recruit.unfit.AppRecruitUnfitCandidateRespVO;
 import com.citu.module.menduner.system.controller.base.CommonRespVO;
 import com.citu.module.menduner.system.controller.base.analysis.RecruitAnalysisPageReqVO;
 import com.citu.module.menduner.system.controller.base.analysis.RecruitInterviewInviteAnalysisRespVO;
@@ -26,6 +28,7 @@ import com.citu.module.menduner.system.service.enterprise.bind.EnterpriseUserBin
 import com.citu.module.menduner.system.service.hire.HireCommissionRatioService;
 import com.citu.module.menduner.system.service.job.JobAdvertisedService;
 import com.citu.module.menduner.system.service.job.JobCvRelService;
+import com.citu.module.menduner.system.util.RedisUtils;
 import com.citu.module.pay.api.wallet.PayWalletApi;
 import com.citu.module.pay.api.wallet.dto.PayWalletAddBalanceDTO;
 import com.citu.module.pay.enums.wallet.PayWalletBizTypeEnum;
@@ -39,6 +42,7 @@ import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.util.Collections;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static com.citu.framework.common.util.validation.ValidationUtils.isMobile;
@@ -56,9 +60,9 @@ import static com.citu.module.menduner.common.util.TimeUtils.generateDateTimeRan
 public class InterviewInviteServiceImpl implements InterviewInviteService {
 
     /**
-     * 比例倍数 1:10 (点数转钱包的比例)
+     * 比例倍数 1:1 (点数转钱包的比例)
      **/
-    private static final Integer RATIO_MULTIPLE = 10;
+    private static final Integer RATIO_MULTIPLE = 1;
     @Resource
     private InterviewInviteMapper mapper;
     @Resource
@@ -71,6 +75,8 @@ public class InterviewInviteServiceImpl implements InterviewInviteService {
     private JobCvRelService jobCvRelService;
     @Resource
     private JobAdvertisedService jobAdvertisedService;
+    @Resource
+    private RedisUtils redisUtils;
 
     /**
      * 计算佣金
@@ -205,11 +211,18 @@ public class InterviewInviteServiceImpl implements InterviewInviteService {
     @Override
     public PageResult<AppRecruitInterviewInviteRespVO> page(AppRecruitInterviewInviteReqPageVO reqVO) {
         LoginUser loginUser = LoginUserContext.get();
-        return mapper.page(
+        PageResult<AppRecruitInterviewInviteRespVO> result= mapper.page(
                 reqVO,
                 LoginUserContext.getEnterpriseId(loginUser),
                 LoginUserContext.getUserId(loginUser)
         );
+        if (CollUtil.isEmpty(result.getList())) {
+            return PageResult.empty();
+        }
+        redisUtils.setEnterpriseUserLookPersonPermission(result.getList().stream()
+                .map(AppRecruitInterviewInviteRespVO::getUserId)
+                .collect(Collectors.toSet()));
+        return result;
     }
 
     @Override

+ 6 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/job/JobAdvertisedService.java

@@ -20,6 +20,7 @@ import com.citu.module.menduner.system.controller.base.job.JobAdvertisedSaveReqV
 import com.citu.module.menduner.system.dal.dataobject.job.JobAdvertisedDO;
 
 import javax.validation.Valid;
+import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Map;
 
@@ -155,6 +156,11 @@ public interface JobAdvertisedService {
      **/
     void enable(List<Long> ids);
 
+    /**
+     * 开启职位并修改过期时间
+     **/
+    void enableAndUpdateExpireTime(Long id, LocalDateTime expireTime);
+
     /**
      * 关闭职位
      **/

+ 49 - 42
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/job/JobAdvertisedServiceImpl.java

@@ -39,7 +39,6 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
-import org.springframework.util.StringUtils;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
@@ -116,9 +115,10 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
     @Override
     public void deleteJobAdvertised(Long id) {
         // 校验存在
-        validateJobAdvertisedExists(id);
+        JobAdvertisedDO jobAdvertised = validateJobAdvertisedExists(id);
         // 删除
         mapper.deleteById(id);
+        jobDataSync(jobAdvertised, SyncConstants.DELETE);
     }
 
     private JobAdvertisedDO validateJobAdvertisedExists(Long id) {
@@ -142,7 +142,7 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
     @Override
     public PageResult<JobAdvertisedDO> getHireJobPage(JobAdvertisedPageReqVO page) {
         page.setEnterpriseId(DEFAULT_ENTERPRISE_ID);
-        page.setEnterpriseId(DEFAULT_USER_ID);
+        page.setUserId(DEFAULT_USER_ID);
         return mapper.selectPage(page);
     }
 
@@ -389,21 +389,15 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
             throw exception(MDE_JOB_ADVERTISED_NAME_DUPLICATE, job.getName());
         }
 
-        if (job.getId() == null) {
+        if (null == job.getId()) {
             // 新增职位
             processNewJob(job, enterpriseId, userId);
+
         } else {
             // 修改职位
             processExistingJob(job, enterpriseId, userId);
         }
 
-        // 保存或更新职位信息
-        if (job.getId() == null) {
-            mapper.insert(job);
-        } else {
-            mapper.updateById(job);
-        }
-
         return job.getId();
     }
 
@@ -415,35 +409,27 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
      * @param userId       用户ID
      */
     private void processNewJob(JobAdvertisedDO job, Long enterpriseId, Long userId) {
-        // 验证权益
-        vipEntitlementCheckAspect.validate(VipEntitlementCheck.OPERATE_PUBLISH_JOB, !job.getHire());
+        // 不是众聘职位 和 不是待开启的职位才需要权益
+        boolean triggerVip = !job.getHire() && !JobStatusEnum.WAIT_ENABLE.getStatus().equals(job.getStatus());
+        // 扣除额度
+        vipEntitlementCheckAspect.deductQuota(VipEntitlementCheck.OPERATE_PUBLISH_JOB, triggerVip);
 
+        if (job.getHire() || JobStatusEnum.WAIT_ENABLE.getStatus().equals(job.getStatus())) {
+            // 众聘职位||待开启,还需要给钱才能开启
+            job.setStatus(JobStatusEnum.WAIT_ENABLE.getStatus());
+        } else {
+            //默认开启
+            job.setStatus(JobStatusEnum.ENABLE.getStatus());
+        }
 
         // 设置默认值
         job.setUserId(userId);
         job.setEnterpriseId(enterpriseId);
         job.setTop(false);
 
-        if (StringUtils.hasText(job.getStatus())) {
-            // 有保存状态则写入保存的状态
-            job.setStatus(job.getStatus());
-        } else {
-            if (!job.getHire()) {
-                // 不是众聘职位
-                job.setHirePrice(0L);
-                job.setStatus(JobStatusEnum.ENABLE.getStatus());
-            } else {
-                // 众聘职位新增后,还需要给钱才能开启
-                job.setStatus(JobStatusEnum.WAIT_ENABLE.getStatus());
-            }
-        }
-
         // 后置处理
         jobOperateAfter(job, SyncConstants.ADD);
 
-        // 处理权益
-        vipEntitlementCheckAspect
-                .process(VipEntitlementCheck.OPERATE_PUBLISH_JOB, VipEntitlementCheck.OperationType.DEDUCT, !job.getHire());
     }
 
     /**
@@ -495,17 +481,31 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
                 // 已经是开启状态
                 throw exception(MDE_JOB_ADVERTISED_STATUS_ENABLE_ERROR);
             }
-            vipEntitlementCheckAspect.validate(VipEntitlementCheck.OPERATE_PUBLISH_JOB, VipEntitlementCheck.OperationType.DEDUCT);
+            boolean exec = job.getCreateTime().isAfter(LocalDateTime.of(2024, 11, 1, 0, 0));
+            // 扣除额度 20241101之后的数据才做处理
+            vipEntitlementCheckAspect.deductQuota(VipEntitlementCheck.OPERATE_PUBLISH_JOB, exec);
             job.setStatus(JobStatusEnum.ENABLE.getStatus());
             mapper.updateById(job);
             jobDataSync(job, SyncConstants.UPDATE);
-            // 20241101之后的数据才做处理
-            boolean exec = job.getCreateTime().isAfter(LocalDateTime.of(2024, 11, 1, 0, 0));
-            vipEntitlementCheckAspect
-                    .process(VipEntitlementCheck.OPERATE_PUBLISH_JOB, VipEntitlementCheck.OperationType.DEDUCT, exec);
+
         }
     }
 
+    @Override
+    public void enableAndUpdateExpireTime(Long id, LocalDateTime expireTime) {
+        JobAdvertisedDO job = get(id);
+        if (JobStatusEnum.ENABLE.getStatus().equals(job.getStatus())) {
+            // 已经是开启状态
+            return;
+        }
+        job.setStatus(JobStatusEnum.ENABLE.getStatus());
+        if(null != expireTime) {
+            job.setExpireTime(expireTime);
+        }
+        mapper.updateById(job);
+        jobDataSync(job, SyncConstants.UPDATE);
+    }
+
     @Override
     @DSTransactional
     public void disable(List<Long> ids) {
@@ -515,15 +515,9 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
                 // 已经是关闭状态
                 throw exception(MDE_JOB_ADVERTISED_STATUS_CLOSE_ERROR);
             }
-            vipEntitlementCheckAspect.validate(VipEntitlementCheck.OPERATE_PUBLISH_JOB, VipEntitlementCheck.OperationType.ADD);
             job.setStatus(JobStatusEnum.DISABLE.getStatus());
             mapper.updateById(job);
             jobDataSync(job, SyncConstants.UPDATE);
-            // 20241101之后的数据才做处理
-            boolean exec = job.getCreateTime().isAfter(LocalDateTime.of(2024, 11, 1, 0, 0));
-            vipEntitlementCheckAspect
-                    .process(VipEntitlementCheck.OPERATE_PUBLISH_JOB, VipEntitlementCheck.OperationType.ADD,
-                            exec);
         }
     }
 
@@ -687,7 +681,7 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
                                     JobAdvertisedConvert.INSTANCE.convert(job)
                             )
             );
-        } else {
+        } else if (SyncConstants.UPDATE.equals(operate)){
             // es
             esProducer.send(SyncConstants.JOB, SyncConstants.UPDATE, job.getId());
             // 图数据库
@@ -699,6 +693,19 @@ public class JobAdvertisedServiceImpl implements JobAdvertisedService {
                                     JobAdvertisedConvert.INSTANCE.convert(job)
                             )
             );
+        }else {
+            // es
+            esProducer.send(SyncConstants.JOB, SyncConstants.DELETE, job.getId());
+            // 图数据库
+            producer.send(
+                    new GraphSendDTO
+                            (
+                                    SyncConstants.DELETE,
+                                    SyncConstants.JOB,
+                                    job.getId()
+                            )
+            );
+
         }
     }
 

+ 1 - 1
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/job/JobCvRelServiceImpl.java

@@ -193,7 +193,7 @@ public class JobCvRelServiceImpl implements JobCvRelService {
 
     @Override
     @DSTransactional
-    @VipEntitlementCheck(type = VipEntitlementCheck.OPERATE_LOOK_CV, operate = VipEntitlementCheck.OperationType.DEDUCT)
+    @VipEntitlementCheck(type = VipEntitlementCheck.OPERATE_LOOK_CV)
     public boolean look(Long id) {
         JobCvRelDO jobCvRel = validateJobCvRelExists(id);
         if (JobCvRelStatusEnum.LOOK.getStatus().equals(jobCvRel.getStatus())) {

+ 9 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/job/JobIntegrationServiceImpl.java

@@ -39,6 +39,7 @@ import com.citu.module.menduner.system.service.area.AreaService;
 import com.citu.module.menduner.system.service.enterprise.bind.EnterpriseUserBindService;
 import com.citu.module.menduner.system.service.interview.InterviewInviteService;
 import com.citu.module.menduner.system.util.ESQueryBuildUtils;
+import com.citu.module.menduner.system.util.RedisUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.elasticsearch.index.query.BoolQueryBuilder;
 import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
@@ -99,6 +100,8 @@ public class JobIntegrationServiceImpl implements JobIntegrationService {
 
     @Resource
     private ElasticsearchRestTemplate elasticsearchTemplate;
+    @Resource
+    private RedisUtils redisUtils;
 
 
     /**
@@ -327,6 +330,9 @@ public class JobIntegrationServiceImpl implements JobIntegrationService {
         if (CollUtil.isEmpty(pageResult.getList())) {
             return PageResult.empty();
         }
+        redisUtils.setEnterpriseUserLookPersonPermission(pageResult.getList().stream()
+                .map(AppRecruitJobCvRelRespVO::getUserId)
+                .collect(Collectors.toSet()));
         return pageResult;
 
     }
@@ -338,6 +344,9 @@ public class JobIntegrationServiceImpl implements JobIntegrationService {
         if (CollUtil.isEmpty(pageResult.getList())) {
             return PageResult.empty();
         }
+        redisUtils.setEnterpriseUserLookPersonPermission(pageResult.getList().stream()
+                .map(AppRecruitUnfitCandidateRespVO::getUserId)
+                .collect(Collectors.toSet()));
         return pageResult;
     }
 

+ 3 - 2
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/order/TradeOrderServiceImpl.java

@@ -80,12 +80,13 @@ public class TradeOrderServiceImpl implements TradeOrderService {
 
     @Override
     public Long createOrder(TradeOrderCreateReqVO createReqVO,String payKey) {
+        TradeOrderTypeEnum type = TradeOrderTypeEnum.getByType(createReqVO.getType());
         // 1.1 获得商品
         // 1.2 插入 订单
         TradeOrderDO tradeOrderDO = new TradeOrderDO().setUserId(createReqVO.getUserId())
                 .setUserType(createReqVO.getUserType()).setEnterpriseId(createReqVO.getEnterpriseId())
                 .setAppKey(payKey)
-                .setSpuId(createReqVO.getSpuId()).setSpuName(createReqVO.getSpuName())
+                .setSpuId(createReqVO.getSpuId()).setSpuName(type.getName() + "-" + createReqVO.getSpuName())
                 .setPrice(createReqVO.getPrice()).setPayStatus(false).setRefundPrice(0L);
         // 初始化默认
         buildDefaultOrder(tradeOrderDO, null == createReqVO.getType() ?
@@ -97,7 +98,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
         Long payOrderId = payOrderApi.createOrder(new PayOrderCreateReqDTO()
                 .setAppKey(payKey).setUserIp(getClientIP()) // 支付应用
                 .setMerchantOrderId(tradeOrderDO.getId().toString()) // 业务的订单编号
-                .setSubject(createReqVO.getSpuName()).setBody("")
+                .setSubject(type.getName()).setBody(type.getName() + "-" + createReqVO.getSpuName())
                 .setPrice(Math.toIntExact(createReqVO.getPrice())) // 价格信息
                 .setExpireTime(addTime(Duration.ofHours(2L)))).getCheckedData(); // 支付的过期时间
         // 2.2 更新支付单到 订单

+ 29 - 4
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/person/PersonIntegrationServiceImpl.java

@@ -35,6 +35,7 @@ import com.citu.module.menduner.system.dal.mysql.workexp.WorkExpMapper;
 import com.citu.module.menduner.system.enums.sync.SyncConstants;
 import com.citu.module.menduner.system.mq.producer.GraphProducer;
 import com.citu.module.menduner.system.service.area.AreaService;
+import com.citu.module.menduner.system.util.RedisUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 import org.springframework.validation.annotation.Validated;
@@ -44,6 +45,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static com.citu.module.menduner.system.enums.DictTypeConstants.*;
 
@@ -84,6 +86,9 @@ public class PersonIntegrationServiceImpl implements PersonIntegrationService {
     @Resource
     private AreaService areaService;
 
+    @Resource
+    private RedisUtils redisUtils;
+
 
     @Override
     public AppRecruitPersonDetailRespVO detail(Long userId) {
@@ -236,7 +241,13 @@ public class PersonIntegrationServiceImpl implements PersonIntegrationService {
 //            return PageResult.empty();
 //        }
 
-        return personInfoMapper.queryPage(reqVO, ids, LoginUserContext.getEnterpriseId());
+        PageResult<PersonInfoRespVO> result = personInfoMapper.queryPage(reqVO, ids, LoginUserContext.getEnterpriseId());
+
+        redisUtils.setEnterpriseUserLookPersonPermission(
+                result.getList().stream()
+                        .map(PersonInfoRespVO::getUserId)
+                        .collect(Collectors.toSet()));
+        return result;
     }
 
     @Override
@@ -253,7 +264,12 @@ public class PersonIntegrationServiceImpl implements PersonIntegrationService {
                 reqVO.setAreaIds(areaIdList);
             }
         }
-        return personInfoMapper.queryPage(reqVO, LoginUserContext.getEnterpriseId());
+        PageResult<PersonInfoRespVO> result = personInfoMapper.queryPage(reqVO, LoginUserContext.getEnterpriseId());
+        redisUtils.setEnterpriseUserLookPersonPermission(
+                result.getList().stream()
+                        .map(PersonInfoRespVO::getUserId)
+                        .collect(Collectors.toSet()));
+        return result;
     }
 
     @Override
@@ -270,14 +286,23 @@ public class PersonIntegrationServiceImpl implements PersonIntegrationService {
                 e.printStackTrace();
             }
         }
-        return personInfoMapper.queryPageById(null == ids ? null : Arrays.asList(ids),
+        PageResult<PersonInfoRespVO> result = personInfoMapper.queryPageById(null == ids ? null : Arrays.asList(ids),
                 LoginUserContext.getEnterpriseId(),
                 reqVO);
+        redisUtils.setEnterpriseUserLookPersonPermission(
+                result.getList().stream()
+                        .map(PersonInfoRespVO::getUserId)
+                        .collect(Collectors.toSet()));
+        return result;
     }
 
     @Override
     public PageResult<PersonInfoRespVO> selectEnterpriseTalentPoolPage(PersonInfoPageReqVO reqVO) {
-        return personInfoMapper.selectEnterpriseTalentPoolPage(LoginUserContext.getEnterpriseId(), reqVO);
+        PageResult<PersonInfoRespVO> result = personInfoMapper.selectEnterpriseTalentPoolPage(LoginUserContext.getEnterpriseId(), reqVO);
+        redisUtils.setEnterpriseUserLookPersonPermission(result.getList().stream()
+                .map(PersonInfoRespVO::getUserId)
+                .collect(Collectors.toSet()));
+        return result;
     }
 
     @Override

+ 10 - 1
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/person/info/PersonInfoService.java

@@ -2,6 +2,7 @@ package com.citu.module.menduner.system.service.person.info;
 
 import com.citu.framework.common.pojo.PageParam;
 import com.citu.framework.common.pojo.PageResult;
+import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.person.resume.AppPersonAdvantageSaveReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.person.resume.AppPersonInfoSaveReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.person.resume.AppPersonInfoSaveSimpleReqVO;
@@ -9,11 +10,11 @@ import com.citu.module.menduner.system.controller.app.jobhunt.person.resume.AppP
 import com.citu.module.menduner.system.controller.app.jobhunt.person.vo.AppInvitePersonRespVO;
 import com.citu.module.menduner.system.controller.base.person.info.PersonInfoPageReqVO;
 import com.citu.module.menduner.system.controller.base.person.info.PersonInfoSaveReqVO;
-import com.citu.module.menduner.system.controller.base.person.info.PersonSimpleRespVO;
 import com.citu.module.menduner.system.dal.dataobject.person.PersonInfoDO;
 import org.springframework.web.bind.annotation.RequestBody;
 
 import javax.validation.Valid;
+import java.util.Map;
 
 /**
  * 人才信息-人才档案 Service 接口
@@ -68,6 +69,14 @@ public interface PersonInfoService {
      */
     PersonInfoDO getUserInfoByUserId(Long userId);
 
+
+    /**
+     * 人才简历统计
+     */
+    Map<String, Object[]> getPersonCount(TimeRangeBaseReqVO reqVO);
+
+    // ========== 求职端 ==========
+
     /**
      * 保存简历基本信息
      *

+ 24 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/person/info/PersonInfoServiceImpl.java

@@ -5,6 +5,7 @@ import com.citu.framework.common.pojo.PageParam;
 import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.common.util.object.BeanUtils;
 import com.citu.framework.common.util.validation.ValidationUtils;
+import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
 import com.citu.module.menduner.common.util.LoginUserContext;
 import com.citu.module.menduner.system.api.python.GraphSendDTO;
 import com.citu.module.menduner.system.controller.app.jobhunt.person.resume.AppPersonAdvantageSaveReqVO;
@@ -12,10 +13,12 @@ import com.citu.module.menduner.system.controller.app.jobhunt.person.resume.AppP
 import com.citu.module.menduner.system.controller.app.jobhunt.person.resume.AppPersonInfoSaveSimpleReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.person.resume.AppPersonInfoTagReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.person.vo.AppInvitePersonRespVO;
+import com.citu.module.menduner.system.controller.base.CommonRespVO;
 import com.citu.module.menduner.system.controller.base.person.info.PersonInfoPageReqVO;
 import com.citu.module.menduner.system.controller.base.person.info.PersonInfoSaveReqVO;
 import com.citu.module.menduner.system.dal.dataobject.person.PersonInfoDO;
 import com.citu.module.menduner.system.dal.mysql.person.PersonInfoMapper;
+import com.citu.module.menduner.system.enums.eduexp.EducationTypeEnum;
 import com.citu.module.menduner.system.enums.sync.SyncConstants;
 import com.citu.module.menduner.system.mq.producer.GraphProducer;
 import org.springframework.stereotype.Service;
@@ -24,8 +27,16 @@ import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 
+import java.time.LocalDateTime;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
 import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.citu.module.menduner.common.util.TimeUtils.generateDateTimeRange;
 import static com.citu.module.menduner.system.enums.ErrorCodeConstants.*;
+import static com.citu.module.menduner.system.util.RecruitAnalysisUtils.packBarCount;
 
 /**
  * 人才信息-人才档案 Service 实现类
@@ -93,6 +104,19 @@ public class PersonInfoServiceImpl implements PersonInfoService {
         return personInfoMapper.getByUserId(userId);
     }
 
+    @Override
+    public Map<String, Object[]> getPersonCount(TimeRangeBaseReqVO reqVO) {
+        LocalDateTime[] timeRange = generateDateTimeRange(reqVO);
+        List<CommonRespVO> result = personInfoMapper.getNewPersonCount(reqVO, timeRange[0], timeRange[1]);
+        List<CommonRespVO> sortedResult = result.stream()
+                .sorted(Comparator.comparing(CommonRespVO::getKey))
+                .collect(Collectors.toList());
+        return packBarCount(sortedResult.stream()
+                .filter(c -> null != c.getKey())
+                .collect(Collectors.toList())
+        );
+    }
+
     @Override
     @DSTransactional // 单机+多数据源方案,使用 @DSTransactional 保证本地事务,以及数据源的切换
     public boolean saveInfo(AppPersonInfoSaveReqVO reqVO) {

+ 7 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/user/MdeUserService.java

@@ -4,6 +4,7 @@ package com.citu.module.menduner.system.service.user;
 import com.citu.framework.common.enums.TerminalEnum;
 import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.common.validation.Mobile;
+import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.user.vo.*;
 import com.citu.module.menduner.system.controller.base.user.MdeUserPageReqVO;
 import com.citu.module.menduner.system.controller.base.user.MdeUserSaveReqVO;
@@ -12,6 +13,7 @@ import com.citu.module.menduner.system.dal.dataobject.user.MdeUserDO;
 import javax.validation.Valid;
 import java.time.LocalDateTime;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 用户登录 Service 接口
@@ -189,4 +191,9 @@ public interface MdeUserService {
      * 禁用用户
      **/
     void disable(List<Long> ids);
+
+    /**
+     * 获取用户统计
+     **/
+    Map<String, Object[]> getUserCount(TimeRangeBaseReqVO reqVO);
 }

+ 27 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/service/user/MdeUserServiceImpl.java

@@ -10,7 +10,9 @@ import com.citu.framework.common.enums.UserTypeEnum;
 import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.common.util.object.BeanUtils;
 import com.citu.framework.datapermission.core.util.DataPermissionUtils;
+import com.citu.module.menduner.common.dto.TimeRangeBaseReqVO;
 import com.citu.module.menduner.system.controller.app.jobhunt.user.vo.*;
+import com.citu.module.menduner.system.controller.base.CommonRespVO;
 import com.citu.module.menduner.system.controller.base.user.MdeUserPageReqVO;
 import com.citu.module.menduner.system.controller.base.user.MdeUserSaveReqVO;
 import com.citu.module.menduner.system.dal.dataobject.user.MdeUserDO;
@@ -28,19 +30,26 @@ import com.mzt.logapi.context.LogRecordContext;
 import com.mzt.logapi.service.impl.DiffParseFunction;
 import com.mzt.logapi.starter.annotation.LogRecord;
 import org.springframework.context.annotation.Lazy;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
+import java.util.Comparator;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static com.citu.framework.common.util.servlet.ServletUtils.getClientIP;
 import static com.citu.framework.web.core.util.WebFrameworkUtils.getTerminal;
+import static com.citu.module.menduner.common.util.TimeUtils.generateDateTimeRange;
+import static com.citu.module.menduner.system.dal.redis.RedisKeyConstants.MDE_AUTH_USER_PWD_LOCK;
 import static com.citu.module.menduner.system.enums.ErrorCodeConstants.*;
 import static com.citu.module.menduner.system.enums.MdeLogRecordConstants.*;
+import static com.citu.module.menduner.system.util.RecruitAnalysisUtils.packBarCount;
 import static com.citu.module.system.enums.ErrorCodeConstants.USER_USERNAME_EXISTS;
 
 /**
@@ -68,6 +77,10 @@ public class MdeUserServiceImpl implements MdeUserService {
     @Resource
     private SocialClientApi socialClientApi;
 
+    @Resource
+    @Lazy
+    private RedisTemplate<String,String> redisTemplate;
+
 
     @Override
     @DSTransactional // 单机+多数据源方案,使用 @DSTransactional 保证本地事务,以及数据源的切换
@@ -411,6 +424,7 @@ public class MdeUserServiceImpl implements MdeUserService {
         for (Long id : ids) {
             mdeUserMapper
                     .updateById(MdeUserDO.builder().id(id).status(MendunerStatusEnum.ENABLE.getStatus()).build());
+            redisTemplate.delete(String.format(MDE_AUTH_USER_PWD_LOCK, id));
         }
     }
 
@@ -421,4 +435,17 @@ public class MdeUserServiceImpl implements MdeUserService {
                     .updateById(MdeUserDO.builder().id(id).status(MendunerStatusEnum.DISABLE.getStatus()).build());
         }
     }
+
+    @Override
+    public Map<String, Object[]> getUserCount(TimeRangeBaseReqVO reqVO) {
+        LocalDateTime[] timeRange = generateDateTimeRange(reqVO);
+        List<CommonRespVO> result = mdeUserMapper.getUserCount(reqVO, timeRange[0], timeRange[1]);
+        List<CommonRespVO> sortedResult = result.stream()
+                .sorted(Comparator.comparing(CommonRespVO::getKey))
+                .collect(Collectors.toList());
+        return packBarCount(sortedResult.stream()
+                .filter(c -> null != c.getKey())
+                .collect(Collectors.toList())
+        );
+    }
 }

+ 47 - 2
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/util/RecruitAnalysisUtils.java

@@ -1,12 +1,17 @@
 package com.citu.module.menduner.system.util;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ArrayUtil;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import com.citu.framework.mybatis.core.query.MPJLambdaWrapperX;
 import com.citu.module.menduner.system.controller.base.CommonRespVO;
 
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
+import static com.citu.module.menduner.common.dto.TimeRange.*;
+
 /**
  * 招聘分析工具类
  **/
@@ -16,11 +21,14 @@ public class RecruitAnalysisUtils {
      * 包装柱状图格式
      **/
     public static Map<String, Object[]> packBarCount(List<CommonRespVO> result) {
+        Map<String, Object[]> map = new LinkedHashMap<>();
         if (CollUtil.isEmpty(result)) {
-            return null;
+            map.put("x", ArrayUtil.newArray(String.class, 0));
+            map.put("y", ArrayUtil.newArray(String.class, 0));
+            return map;
         }
 
-        Map<String, Object[]> map = new LinkedHashMap<>();
+
         String[] keys = result.stream()
                 .map(CommonRespVO::getKey)
                 .toArray(String[]::new);
@@ -36,4 +44,41 @@ public class RecruitAnalysisUtils {
     }
 
 
+    /**
+     * 时间分组
+     *
+     * @param wrapper 条件构造器
+     * @param column  字段
+     * @param type    {@link com.citu.module.menduner.common.dto.TimeRange}
+     **/
+    public static <R> void applyTimeGrouping(MPJLambdaWrapperX<?> wrapper,
+                                             SFunction<R, ?> column,
+                                             String type) {
+        switch (type) {
+            case TYPE_24_HOURS:
+                wrapper.selectFunc("DATE_FORMAT(%s, '%%m-%%d %%H:00')", arg -> arg.accept(column), "`key`");
+                wrapper.groupBy("DATE_FORMAT(create_time, '%Y-%m-%d-%H')");
+                break;
+            case ALL:
+            case TYPE_RECENT_7_DAYS:
+            case TYPE_LAST_MONTH:
+            case TYPE_LAST_QUARTER:
+            case TYPE_MONTH:
+            case TYPE_CUSTOM:
+                wrapper.selectFunc("DATE_FORMAT(%s, '%%m-%%d')", arg -> arg.accept(column), "`key`");
+                wrapper.groupBy("DATE_FORMAT(create_time, '%Y-%m-%d')");
+                break;
+            case TYPE_YEAR:
+                wrapper.selectFunc("DATE_FORMAT(%s, '%%y年%%m月')", arg -> arg.accept(column), "`key`");
+                wrapper.groupBy("DATE_FORMAT(create_time, '%y-%m')");
+                break;
+            default:
+                // wrapper.selectFunc("DATE_FORMAT(%s, '%%Y年')", arg -> arg.accept(column), "`key`");
+                // wrapper.groupBy("DATE_FORMAT(create_time, '%')");
+                break;
+
+        }
+
+
+    }
 }

+ 63 - 0
menduner/menduner-system-biz/src/main/java/com/citu/module/menduner/system/util/RedisUtils.java

@@ -0,0 +1,63 @@
+package com.citu.module.menduner.system.util;
+
+import com.citu.module.menduner.common.util.LoginUserContext;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import static com.citu.module.menduner.system.dal.redis.RedisKeyConstants.MDE_AUTH_ENTERPRISE_USER_VIEW_PERMISSION;
+
+/**
+ * redis 公共操作
+ **/
+@Component
+public class RedisUtils {
+
+    @Resource
+    private RedisTemplate<String, Object> redisTemplate;
+
+
+    /**
+     * 设置人才在线简历查看权限
+     *
+     * @param userIds 人才id集合
+     */
+    public void setEnterpriseUserLookPersonPermission(Set<Long> userIds) {
+        if (null == userIds) {
+            return;
+        }
+        Set<Long> ids = (Set<Long>)
+                redisTemplate.opsForValue().get(
+                        String.format(MDE_AUTH_ENTERPRISE_USER_VIEW_PERMISSION, LoginUserContext.getEnterpriseId(),
+                                LoginUserContext.getUserId())
+                );
+        if (null == ids) {
+            ids = new HashSet<>();
+        }
+        // 将新的 Set<Long> 追加到已有的 Set<Long> 中
+        ids.addAll(userIds);
+        redisTemplate.opsForValue()
+                .set(
+                        String.format(MDE_AUTH_ENTERPRISE_USER_VIEW_PERMISSION, LoginUserContext.getEnterpriseId(), LoginUserContext.getUserId()),
+                        ids, 2, TimeUnit.HOURS);
+    }
+
+
+    /**
+     * 效验是否有权限查看该人才数据
+     *
+     * @param userId 人才id
+     */
+    public boolean checkEnterpriseUserLookPersonPermission(Long userId) {
+        Set<Long> ids = (Set<Long>) redisTemplate.opsForValue()
+                .get(
+                        String.format(MDE_AUTH_ENTERPRISE_USER_VIEW_PERMISSION,
+                                LoginUserContext.getEnterpriseId(), LoginUserContext.getUserId())
+                );
+        return null != ids && ids.contains(userId);
+    }
+}

+ 1 - 0
menduner/menduner-system-biz/src/main/resources/META-INF/services/com.xingyuv.captcha.service.CaptchaCacheService

@@ -0,0 +1 @@
+com.citu.module.menduner.system.framework.captcha.core.RedisCaptchaServiceImpl

+ 24 - 2
menduner/menduner-system-biz/src/main/resources/application.yaml

@@ -21,7 +21,7 @@ spring:
   servlet:
     # 文件上传相关配置项
     multipart:
-      max-file-size: 16MB # 单个文件大小
+      max-file-size: 25MB # 单个文件大小
       max-request-size: 32MB # 设置总上传的文件大小
   mvc:
     pathmatch:
@@ -116,6 +116,23 @@ baidu:
     apiKey: yREaxoyldHnwuq8hqAEe0JAQ
     secretKey: nYGuu9KJGWvi3RsWodCQ1OuFMDVXukBR
 
+--- #################### 验证码相关配置 ####################
+aj:
+  captcha:
+    jigsaw: classpath:images/jigsaw # 滑动验证,底图路径,不配置将使用默认图片;以 classpath: 开头,取 resource 目录下路径
+    pic-click: classpath:images/pic-click # 滑动验证,底图路径,不配置将使用默认图片;以 classpath: 开头,取 resource 目录下路径
+    cache-type: redis # 缓存 local/redis...
+    cache-number: 1000 # local 缓存的阈值,达到这个值,清除缓存
+    timing-clear: 180 # local定时清除过期缓存(单位秒),设置为0代表不执行
+    type: blockPuzzle # 验证码类型 default两种都实例化。 blockPuzzle 滑块拼图 clickWord 文字点选
+    water-mark: 门墩儿 # 右下角水印文字(我的水印),可使用 https://tool.chinaz.com/tools/unicode.aspx 中文转 Unicode,Linux 可能需要转 unicode
+    interference-options: 0 # 滑动干扰项(0/1/2)
+    req-frequency-limit-enable: false # 接口请求次数一分钟限制是否开启 true|false
+    req-get-lock-limit: 5 # 验证失败5次,get接口锁定
+    req-get-lock-seconds: 10 # 验证失败后,锁定时间间隔
+    req-get-minute-limit: 30 # get 接口一分钟内请求数限制
+    req-check-minute-limit: 60 # check 接口一分钟内请求数限制
+    req-verify-minute-limit: 60 # verify 接口一分钟内请求数限制
 
 --- #################### 芋道相关配置 ####################
 
@@ -134,6 +151,11 @@ citu:
     description: 提供管理员管理的所有功能
     version: ${citu.info.version}
     base-package: ${citu.info.base-package}
+  xss:
+    enable: true
+    exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
+      - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
+      - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
   # 是否开启国际化
   i18n:
     enable: true
@@ -143,7 +165,7 @@ citu:
     transform:
       enable: false
   captcha:
-    enable: false # 验证码的开关,默认为 true;
+    enable: true # 验证码的开关,默认为 true;
   tenant: # 多租户相关配置项
     enable: true
     ignore-urls:

+ 416 - 0
menduner/menduner-system-biz/src/main/resources/i18n/messages_en_GB.properties

@@ -0,0 +1,416 @@
+# ========== 系统 ==========
+0=Successful
+# ========== 客户端错误段 ==========
+400=incorrect request parameters
+401=account not logged in
+403=no permission for this operation
+404=request not found
+405=incorrect request method
+423=request failed, please try again later # concurrent request, not allowed
+429=request too frequent, please try again later
+
+# ========== 服务端错误段 ==========
+500=system abnormality
+501=function not implemented/not enabled
+502=incorrect configuration item
+# ========== 自定义错误段 ==========
+900=duplicate request, please try again later # duplicate request
+901=demonstration mode, write operation prohibited
+999=unknown error
+# ========== 公共 1_099_000_000 ==========
+1_099_000_001=Status cannot be empty
+1_099_000_002=The modification status must be {value}
+1_099_000_003=Display order cannot be empty
+1_099_000_004=Superior ID cannot be empty
+1_099_000_005=id cannot be empty
+1_099_000_006=User ID cannot be empty
+1_099_000_007=Enterprise ID cannot be empty
+1_099_000_008=User Type cannot be empty
+1_099_000_009=The file format is incorrect and only supports.
+1_099_000_010=File attachment cannot be empty
+1_099_000_011=Illegal request
+# ========== 人才信息-人才档案 1_100_001_000 ==========
+1_100_001_001=Personal Profile Does Not Exist
+1_100_001_002=Personal advantage cannot be empty
+1_100_001_003=Real name cannot be empty
+1_100_001_004=Contact phone number cannot be empty
+1_100_001_005=Birthdate cannot be empty
+1_100_001_006=Work experience cannot be empty
+1_100_001_007=Education cannot be empty
+1_100_001_008=Job search status cannot be empty
+1_100_001_009=City cannot be empty
+1_100_001_010=Frequently used email cannot be empty
+1_100_001_011=Please fill in your personal basic information first
+1_100_001_012=Email number is invalid, please enter the correct email address
+1_100_001_013=Invalid phone number, please enter the correct phone number
+# ========== 行业信息 1_100_002_000 ==========
+1_100_002_001=Industry information does not exist
+# ========== 职位信息 1_100_003_000 ==========
+1_100_003_001=Position information does not exist
+1_100_003_002=Position type cannot be empty
+1_100_003_003=Position name cannot be empty
+# ========== 地区 1_100_004_000 ==========
+1_100_004_001=Region does not exist
+1_100_004_002=Popular regions already exist, please do not add them again
+1_100_004_003=Work area cannot be empty
+# ========== 简历附件 1_100_005_000 ==========
+1_100_005_001=Resume attachment does not exist
+1_100_005_002=Upload a maximum of 5 resume attachments
+# ========== 教育经历 1_100_006_000 ==========
+1_100_006_001=Educational experience does not exist
+1_100_006_002=No education selected
+1_100_006_003=No educational system type selected
+1_100_006_004=No school start date selected
+1_100_006_005=No end date selected for school
+# ========== 求职意向 1_100_007_000 ==========
+1_100_007_001=Job search intention does not exist
+1_100_007_002=No expected position selected
+1_100_007_003=No expected industry selected
+1_100_007_004=No job search type selected
+1_100_007_005=No minimum salary requirement filled in
+1_100_007_006=No maximum salary requirement filled in
+1_100_007_007=No work city selected
+# ========== 专业 1_100_008_000 ==========
+1_100_008_001=Major does not exist
+# ========== 职位标签 1_100_009_000 ==========
+1_100_009_001=Position tag does not exist
+1_100_009_002=Position tag cannot be empty
+# ========== 学校 1_100_010_000 ==========
+1_100_010_001=School does not exist
+# ========== 人才证书 1_100_011_000 ==========
+1_100_011_001=Personnel certificate does not exist
+1_100_011_002=Certificate Chinese name cannot be empty
+1_100_011_003=Certificate English name cannot be empty
+# ========== 工作经历 1_100_012_000 ==========
+1_100_012_001=Work experience does not exist
+1_100_012_002=No start date selected for employment
+1_100_027_003=No end time selected for employment
+# ========== 人才技能 1_100_013_000 ==========
+1_100_013_001=Personnel skill does not exist
+1_100_013_002=The skill already exists
+# ========== 证书 1_100_014_000 ==========
+1_100_014_001=Certificate does not exist
+# ========== 访问量 1_100_015_000 ==========
+1_100_015_001=The traffic does not exist
+1_100_015_002=Business type does not exist
+1_100_015_003=Business ID does not exist
+1_100_015_004=Access date does not exist
+# ========== 用户登录 1_100_016_000 ==========
+1_100_016_001=User does not exist
+1_100_016_002=Unregistered with phone number
+1_100_016_003=Modifying phone failed, the phone number ({}) has already been used
+1_100_016_004=User account already exists
+1_100_016_005=Phone number already exists
+1_100_016_006=Email already exists
+1_100_016_007=Phone number cannot be empty
+1_100_016_008=Importing user data cannot be empty!
+1_100_016_009=User password verification failed
+1_100_016_010=The user named [{}] has been disabled
+1_100_016_011=User creation failed due to exceeding the maximum tenant quota ({}) for tenants!
+1_100_016_012=The new password cannot be empty
+1_100_016_013=Phone verification code cannot be empty
+1_100_016_014=The length of the mobile verification code is 4-6 digits
+1_100_016_015=The length of the phone number is 8-11 digits
+1_100_016_016=Phone verification codes must all be numbers
+1_100_016_017=Password length is 8-36 bits
+1_100_016_018=User ID cannot be empty
+1_100_016_019=Password cannot be empty
+1_100_016_020=User account cannot be empty
+1_100_016_021=This email has been used by another user
+1_100_016_022=Email format incorrect
+1_100_016_023=Email length cannot exceed 255 characters
+1_100_016_024=Email cannot be empty
+1_100_016_025=This phone number has already been used by another user
+# ========== AUTH 模块 1_100_017_000 ==========
+1_100_017_001=Login failed, incorrect account and password
+1_100_017_002=Login failed, account disabled
+1_100_017_003=Login failed, unable to resolve third-party login information
+1_100_017_004=The phone number has already been used
+1_100_017_005=Incorrect verification code, reason: {}
+1_100_017_006=Account not bound, needs to be bound
+1_100_017_007=Token has expired
+1_100_017_008=Phone number does not exist
+1_100_017_009=Sending scene cannot be empty
+1_100_017_010=Phone code cannot be empty
+1_100_017_011=Login code cannot be empty
+1_100_017_012=State cannot be empty
+1_100_017_013=Authorization code cannot be empty
+1_100_017_014=The type of social platform cannot be empty
+1_100_017_015=The verification code cannot be empty
+1_100_017_016=No enterprise selected
+1_100_017_017=Unregistered user, please register individual user first before applying for enterprise user
+1_100_017_018=Access token cannot be empty
+1_100_017_019=Email number not registered
+1_100_017_020=Email verification code incorrect
+1_100_017_021=This is your first login, and the initialization password has been sent to your email
+1_100_017_022=Password is not secure, please change your password and log in
+1_100_017_023=Phone number tried multiple times, please try again after 8 hours
+# ========== 角色模块 1_100_018_000 ==========
+1_100_018_001=Character does not exist
+1_100_018_002=A role named [{}] already exists
+1_100_018_003=A role with code [{}] already exists
+1_100_018_004=Cannot operate on roles with built-in system types
+1_100_018_005=The character named [{}] has been disabled
+1_100_018_006=Encoding [{}] cannot be used
+1_100_018_007=Role number cannot be empty
+1_100_018_008=Role name cannot be empty
+1_100_018_009=The length of the character name cannot exceed 30 characters
+1_100_018_010=Character flag cannot be empty
+1_100_018_011=The character flag cannot exceed 100 characters in length
+1_100_018_012=Data range cannot be empty
+1_100_018_013=The data range must be {value}
+# ========== 企业信息 1_100_019_000 ==========
+1_100_019_001=Enterprise information does not exist
+1_100_019_002=Enterprise code cannot be empty
+1_100_019_003=No company name filled in
+1_100_019_004=Enterprise alias not filled in
+1_100_019_005=Company profile not filled in
+1_100_019_006=No industry selected
+1_100_019_007=No financing stage selected
+1_100_019_008=No personnel size selected
+1_100_019_009=No work hours filled in
+# ========== 企业工商信息  1_100_020_001 ==========
+1_100_020_001=Enterprise business information does not exist
+1_100_020_002=No company name filled in
+1_100_020_003=Unified social credit code not filled in
+1_100_020_004=Business license image recognition failed, please upload clear and legal images again
+# ========== 企业注册申请 1_100_021_000 ==========
+1_100_021_001=The enterprise registration application does not exist
+1_100_021_002=Enterprise registration application has been approved
+1_100_021_003=The enterprise registration application has been approved and cannot be rejected
+1_100_021_004=Enterprise name cannot be empty
+1_100_021_005=Contact number cannot be empty
+1_100_021_006=Contact email cannot be empty
+1_100_021_007=Business license not uploaded
+1_100_021_008=Unified social credit code cannot be empty
+1_100_021_009=Enterprise registered
+1_100_021_010=The enterprise has applied for review, please do not resubmit
+1_100_021_011=Incorrect format of unified social credit code
+1_100_021_012=Unified Social Credit Code has been registered
+1_100_021_013=Contact name cannot be empty
+1_100_021_014=Password cannot be empty
+1_100_021_015=Password length is 8-36 digits
+1_100_021_016=Enterprise registration application in progress
+1_100_021_017=This email has been registered by another company
+# ========== 企业地址 1_100_022_001 ==========
+1_100_022_001=The company address does not exist
+# ========== 企业登录用户 1_100_023_000 ==========
+1_100_023_001=Enterprise login user does not exist
+1_100_023_002=Name cannot be empty
+1_100_023_003=The account has been disabled
+1_100_023_004=This account is an administrator account and cannot be operated
+1_100_023_005=New password cannot be empty
+1_100_023_006=The length of the new password is 8-36 digits
+1_100_023_007=This email has been registered by another company
+1_100_023_008=Enterprise user email cannot be empty
+1_100_023_009=Enterprise user login email format incorrect
+# ========== 企业岗位信息 1_100_024_000 ==========
+1_100_024_001=Enterprise position information does not exist
+1_100_024_002=The Chinese name of the position cannot be empty
+1_100_024_003=Position English cannot be empty
+# ========== 招聘职位 1_100_025_000 ==========
+1_100_025_001=Recruitment position does not exist
+1_100_025_002=Recruitment position ID cannot be empty
+1_100_025_003=Position name cannot be empty
+1_100_025_004=Recruitment type cannot be empty
+1_100_025_005=The publishing user ID cannot be empty
+1_100_025_006=Work experience cannot be empty
+1_100_025_007=Educational requirements cannot be empty
+1_100_025_008=Insufficient account balance
+1_100_025_009=Insufficient account points
+1_100_025_010=Unable to modify the reward balance for published positions
+1_100_025_011=Cannot modify reward points for published positions
+1_100_025_012=Position name ({}) already exists, please modify and save again
+1_100_025_013=The expiration time cannot be less than the current time
+1_100_025_014=Position has been opened, please do not repeat the operation
+1_100_025_015=Position closed, please do not repeat operation
+# ========== 企业招聘者浏览 1_100_026_000 ==========
+1_100_026_001=Enterprise recruiter browsing does not exist
+# ========== 人才-企业关注订阅 1_100_027_000 ==========
+1_100_027_001=Enterprise follow subscription does not exist
+1_100_027_002=Enterprise has followed and subscribed, please do not click again
+# ========== 人才-浏览记录 1_100_028_000 ==========
+1_100_028_001=Browsing history does not exist
+# ========== 人才-招聘职位收藏 1_100_029_000 ==========
+1_100_029_001=Recruitment position collection does not exist
+1_100_029_002=Position has been saved, please do not click again
+# ========== 培训经历 1_100_030_000 ==========
+1_100_030_001=Training experience does not exist
+1_100_030_002=Training start time cannot be empty
+1_100_030_003=Training end time cannot be empty
+1_100_030_004=Training institution name cannot be empty
+1_100_030_005=Training course cannot be empty
+# ========== 项目经历 1_100_031_000 ==========
+1_100_031_001=Project experience does not exist
+1_100_031_002=Project name not filled in
+1_100_031_003=Project start time cannot be empty
+1_100_031_004=Project end time cannot be empty
+# ========== 职业技能 1_100_032_000 ==========
+1_100_032_001=Vocational skill does not exist
+1_100_032_002=There are sub profession skills that cannot be deleted
+1_100_032_003=Parent level vocational skill does not exist
+1_100_032_004=Unable to set oneself as a parent vocational skill
+1_100_032_005=There is already a vocational skill with the Chinese name for this skill
+1_100_032_006=Cannot set one's own child Skill as the parent Skill
+# ========== 面试邀请 1_100_033_000 ==========
+1_100_033_001=Interview invitation does not exist
+1_100_033_002=Invited user ID cannot be empty
+1_100_033_003=Invited user ID cannot be empty
+1_100_033_004=No recruitment position selected
+1_100_033_005=Interview type cannot be empty
+1_100_033_006=Interview time cannot be empty
+1_100_033_007=The contact phone number of the invited party cannot be empty
+1_100_033_008=The contact phone number of the inviting party cannot be empty
+1_100_033_009=Interview address cannot be empty
+1_100_033_010=Interview status cannot be empty
+1_100_033_011=The current interview has not been completed
+1_100_033_012=The current employee has not yet joined and cannot be settled
+1_100_033_013=Settlement function maintenance in progress
+1_100_033_014=Other interviewees have already made appointments during this time period
+1_100_033_015=The interview time cannot be less than the current time
+1_100_033_016=Invitation party's contact phone number format is incorrect
+# ========== 企业用户申请 1_100_034_000 ==========
+1_100_034_001=Enterprise user application does not exist
+1_100_034_002=User application has been approved
+1_100_034_003=The user's application has been approved and cannot be rejected
+1_100_034_005=Applied for review, please do not resubmit
+# ========== 招聘职位简历投递 1_100_035_000 ==========
+1_100_035_001=Recruitment position resume submission does not exist
+1_100_035_002=The position has been submitted
+1_100_035_003=No resume attachment selected
+1_100_035_004=Recruitment position ID cannot be empty
+1_100_035_005=This position is currently not allowed for delivery
+1_100_035_006=Recruitment for this position has been suspended
+1_100_035_007=Resume attachment title cannot be empty
+1_100_035_008=Resume attachment address cannot be empty
+1_100_035_009=Resume status submitted cannot be empty
+1_100_035_010=Resume has been viewed and cannot be retracted
+# ========== 众聘-简历投递 1_100_036_000 ==========
+1_100_036_001=The submitted resume does not exist
+1_100_036_002=The posted position ID cannot be empty
+1_100_036_003=The user ID for posting positions cannot be empty
+1_100_036_004=Referee ID cannot be empty
+1_100_036_005=The delivery user ID cannot be empty
+1_100_036_006=The name of the sender cannot be empty
+1_100_036_007=The contact phone number of the deliveryman cannot be empty
+1_100_036_008=Resume attachment cannot be empty
+# ========== 众聘-佣金比例 1_100_037_000 ==========
+1_100_037_001=Commission ratio does not exist
+1_100_037_002=Commission ratio cannot be empty
+1_100_037_003=Commission ratio cannot be less than 0
+1_100_037_004=The total commission ratio cannot be less than or greater than 100%
+# ========== 用户账户 1_100_038_000 ==========
+1_100_038_001=User account does not exist
+# ========== 账户相关 1_100_039_000 ============
+1_100_039_001=User does not exist
+1_100_039_002=Insufficient user points balance
+1_100_039_003=Variable integral cannot be empty
+1_100_039_004=User balance insufficient
+1_100_039_005=Variable balance cannot be empty
+# ========== 企业邀请码 1_100_040_000 ==========
+1_100_040_001=Enterprise invitation code does not exist
+1_100_040_002=Enterprise ID cannot be empty
+1_100_040_003=User ID cannot be empty
+1_100_040_004=Type cannot be empty
+1_100_040_005=Invitation code cannot be empty
+1_100_040_006=Failure days cannot be empty
+# ========== 企业邀请记录 1_100_041_000 ==========
+1_100_041_001=Enterprise invitation record does not exist
+1_100_041_002=Invited enterprise ID cannot be empty
+1_100_041_003=Invited user ID cannot be empty
+1_100_041_004=Invitation enterprise ID cannot be empty
+1_100_041_005=Invited user ID cannot be empty
+1_100_041_006=Type cannot be empty
+1_100_041_007=Invitation code cannot be empty
+1_100_041_008=Not an enterprise administrator cannot operate to become a subsidiary
+1_100_041_009=The company already has a superior and cannot be operated as a subsidiary
+1_100_041_010=Already joined the enterprise and cannot be operated repeatedly
+1_100_041_011=Please complete personal basic information first
+1_100_041_012=Cannot join the same enterprise
+# ========== 企业实名认证 1_100_043_000 ==========
+1_100_043_001=Enterprise real name authentication does not exist
+1_100_043_002=Authentication user ID cannot be empty
+1_100_043_003=Name cannot be empty
+1_100_043_004=ID card number cannot be empty
+1_100_043_005=ID card front not uploaded
+1_100_043_006=ID card reverse not uploaded
+# ========== 标签管理 1_100_044_000 ==========
+1_100_044_001=Label management does not exist
+1_100_044_002=Chinese name cannot be empty
+1_100_044_003=English name cannot be empty
+1_100_044_004=Label type cannot be empty
+# ========== 猎寻服务 1_100_045_000 ==========
+1_100_045_001=Hunting service does not exist
+1_100_045_002=Name cannot be empty
+1_100_045_003=Enterprise name cannot be empty
+1_100_045_004=Contact information cannot be empty
+1_100_045_005=Data submission frequency has exceeded today's maximum submission count
+# ========== 订单 1_100_046_000 ==========
+1_100_046_001=Order does not exist
+1_100_046_002=Order update payment status failed, order is not in the 'Unpaid' status
+1_100_046_003=Order update payment status failed, payment order number does not match
+1_100_046_004=Order update payment status failed, payment status is not in the 'Payment Successful' state
+1_100_046_005=Order update payment status failed, payment amount does not match
+1_100_046_006=Refund initiated failed, order unpaid
+1_100_046_007=Failed to initiate refund, order has been refunded
+1_100_046_008=Failed to initiate refund, refund order does not exist
+1_100_046_009=Refund initiated failed, refund order not refunded successfully
+1_100_046_010=Failed to initiate refund, refund order number does not match
+1_100_046_011=Failed to initiate refund, refund amount does not match
+1_100_046_012=Product name cannot be empty
+1_100_046_013=Product amount cannot be empty
+1_100_046_014=Transaction order cancellation failed, order is not in the 'Pending Payment' status
+1_100_046_015=Order type cannot be empty
+# ========== 用户实名制 1_100_047_000 ==========
+1_100_047_001=User real name system does not exist
+# ========== 品牌 1_100_048_000 ==========
+1_100_048_001=Brand does not exist
+# ========== 兑换 1_100_049_000 ==========
+1_100_049_001=Exchange does not exist
+1_100_049_002=Product name cannot be empty
+1_100_049_003=Product image address cannot be empty
+1_100_049_004=Redemption points cannot be empty
+1_100_049_005=Contact name cannot be empty
+1_100_049_006=Contact phone number cannot be empty
+1_100_049_007=Product type cannot be empty
+# ========== 人才屏蔽企业关系 1_100_050_000 ==========
+1_100_050_001=Talent blocking enterprise relationship does not exist
+1_100_050_002=Enterprise blocked, please do not click again
+# ========== 用户套餐 1_100_051_000 ==========
+1_100_051_001=User package does not exist
+1_100_051_002=Package name cannot be empty
+1_100_051_003=Package price cannot be empty
+1_100_051_004=Days cannot be empty
+1_100_051_005=Recommended cannot be empty
+1_100_051_006=Instruction text cannot be empty
+1_100_051_007=Resume refresh count cannot be empty
+1_100_051_008=Whether to enable resume blocking cannot be empty
+1_100_051_009=Whether to enable priority recommendation cannot be empty
+1_100_051_010=Whether to enable resume template download cannot be empty
+1_100_051_011=Is it enabled? Who has seen it? I cannot leave it blank
+1_100_051_012=Whether to enable salary report cannot be empty
+# ========== 用户权益记录 1_100_052_000 ==========
+1_100_052_001=User rights record does not exist
+# ========== 企业套餐 1_100_053_000 ==========
+1_100_053_001=Enterprise package does not exist
+1_100_053_002=Package name cannot be empty
+1_100_053_003=Package price cannot be empty
+1_100_053_004=Days cannot be empty
+1_100_053_005=Does it default to not being empty
+1_100_053_006=Recommended cannot be empty
+1_100_053_007=Instruction text cannot be empty
+1_100_053_008=The number of positions allowed to be published cannot be empty
+1_100_053_009=The number of talents allowed to be searched cannot be empty
+# ========== 企业权益记录 1_100_054_000 ==========
+1_100_054_001=Enterprise equity record does not exist
+1_100_054_002=Enterprise credit limit has exceeded
+# ========== 早报资讯 1_100_055_000 ==========
+1_100_055_001=Morning News does not exist
+# ========== 招聘会 1_100_056_000 ==========
+1_100_056_001=The job fair does not exist
+1_100_056_002=Recruitment position ID cannot be empty
+1_100_056_003=The name of the job fair cannot be empty
+1_100_056_004=The job fair time has passed, recruitment is temporarily suspended
+1_100_056_005=You do not have permission to attend this job fair
+# ========== 招聘职位扩展 1_100_057_000 ==========
+1_100_057_001=Recruitment position ID cannot be empty

+ 1 - 0
menduner/menduner-system-biz/src/main/resources/i18n/messages_en_US.properties

@@ -144,6 +144,7 @@
 1_100_017_020=Email verification code incorrect
 1_100_017_021=This is your first login, and the initialization password has been sent to your email
 1_100_017_022=Password is not secure, please change your password and log in
+1_100_017_023=Phone number tried multiple times, please try again after 8 hours
 # ========== 角色模块 1_100_018_000 ==========
 1_100_018_001=Character does not exist
 1_100_018_002=A role named [{}] already exists

+ 1 - 0
menduner/menduner-system-biz/src/main/resources/i18n/messages_zh_CN.properties

@@ -144,6 +144,7 @@
 1_100_017_020=邮箱验证码不正确
 1_100_017_021=您是首次登录,初始化密码已发往您的邮箱
 1_100_017_022=密码不安全,请修改密码后登录
+1_100_017_023=手机号尝试多次,请8个小时后重试
 # ========== 角色模块 1_100_018_000 ==========
 1_100_018_001=角色不存在
 1_100_018_002=已经存在名为【{}】的角色

BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg1.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg2.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg3.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg4.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg5.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg6.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg7.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg8.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/original/bg9.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/1.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/11/10.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/11/11.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/11/12.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/11/13.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/11/14.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/11/15.png


BIN
menduner/menduner-system-biz/src/main/resources/images/jigsaw/slidingBlock/11/16.png


Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels