he2802 2 سال پیش
والد
کامیت
d97b1a6290
100فایلهای تغییر یافته به همراه3677 افزوده شده و 148 حذف شده
  1. 81 0
      run-prod.sh
  2. 115 0
      zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/financial/TopCostInstTpController.java
  3. 51 8
      zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/financial/TopDivideLogController.java
  4. 7 1
      zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/financial/TopOrderRecNoteController.java
  5. 13 0
      zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/order/TopOldOrderCheckLogController.java
  6. 6 3
      zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/order/TopOldOrderController.java
  7. 7 0
      zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/schedule/ScheduleController.java
  8. 246 0
      zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/settle/TopInstSettleController.java
  9. 99 0
      zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/top/TopCostCategoryController.java
  10. 100 0
      zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/top/TopInstCategoryController.java
  11. 28 0
      zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/top/TopInstitutionController.java
  12. 9 0
      zhongzheng-admin-saas/src/main/resources/application-dev.yml
  13. 11 0
      zhongzheng-admin-saas/src/main/resources/application-pre.yml
  14. 9 0
      zhongzheng-admin-saas/src/main/resources/application-prod.yml
  15. 6 12
      zhongzheng-admin/src/main/java/com/zhongzheng/controller/alioss/OssController.java
  16. 77 3
      zhongzheng-admin/src/main/java/com/zhongzheng/controller/common/CommonController.java
  17. 14 0
      zhongzheng-admin/src/main/java/com/zhongzheng/controller/exam/ExamApplyController.java
  18. 20 0
      zhongzheng-admin/src/main/java/com/zhongzheng/controller/grade/ClassGradeController.java
  19. 48 5
      zhongzheng-admin/src/main/java/com/zhongzheng/controller/order/OrderController.java
  20. 9 0
      zhongzheng-admin/src/main/resources/application-dev.yml
  21. 18 6
      zhongzheng-admin/src/main/resources/application-pre.yml
  22. 9 0
      zhongzheng-admin/src/main/resources/application-prod.yml
  23. 1 1
      zhongzheng-admin/src/main/resources/templates/wordPhone.ftl
  24. 12 2
      zhongzheng-api/src/main/java/com/zhongzheng/controller/base/ProfileTpController.java
  25. 40 5
      zhongzheng-api/src/main/java/com/zhongzheng/controller/course/CourseController.java
  26. 1 1
      zhongzheng-api/src/main/java/com/zhongzheng/controller/exam/ExamApplyController.java
  27. 64 0
      zhongzheng-api/src/main/java/com/zhongzheng/controller/goods/GoodsQuestionRelExamController.java
  28. 14 0
      zhongzheng-api/src/main/java/com/zhongzheng/controller/inform/InformUserController.java
  29. 13 0
      zhongzheng-api/src/main/java/com/zhongzheng/controller/user/UserController.java
  30. 5 2
      zhongzheng-api/src/main/java/com/zhongzheng/controller/user/UserStudyRecordController.java
  31. 24 5
      zhongzheng-api/src/main/java/com/zhongzheng/controller/wx/WxLoginController.java
  32. 9 0
      zhongzheng-api/src/main/resources/application-dev.yml
  33. 14 3
      zhongzheng-api/src/main/resources/application-pre.yml
  34. 9 0
      zhongzheng-api/src/main/resources/application-prod.yml
  35. 1 1
      zhongzheng-common/src/main/java/com/zhongzheng/common/core/domain/entity/SysDictData.java
  36. 22 0
      zhongzheng-common/src/main/java/com/zhongzheng/common/utils/DateUtils.java
  37. 30 0
      zhongzheng-common/src/main/java/com/zhongzheng/common/utils/ToolsUtils.java
  38. 122 0
      zhongzheng-common/src/main/java/com/zhongzheng/common/utils/file/FileUtils.java
  39. 60 0
      zhongzheng-common/src/main/java/com/zhongzheng/common/utils/poi/ExcelUtil.java
  40. 5 0
      zhongzheng-framework/src/main/java/com/zhongzheng/framework/config/SecurityConfig.java
  41. 2 1
      zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/SysTenantServiceImpl.java
  42. 1 1
      zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/TokenService.java
  43. 126 0
      zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/WxLoginService.java
  44. 4 1
      zhongzheng-system/src/main/java/com/zhongzheng/modules/alioss/bo/OssRequest.java
  45. 4 3
      zhongzheng-system/src/main/java/com/zhongzheng/modules/alioss/service/OssService.java
  46. 6 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/alisms/service/impl/AliSmsServiceImpl.java
  47. 3 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/bo/ExamAddBo.java
  48. 3 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/bo/ExamEditBo.java
  49. 6 2
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/bo/QuestionAddBo.java
  50. 7 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/bo/QuestionEditBo.java
  51. 46 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/bo/QuestionOtherAddBo.java
  52. 52 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/bo/QuestionOtherEditBo.java
  53. 54 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/bo/QuestionOtherQueryBo.java
  54. 3 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/domain/Exam.java
  55. 4 1
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/domain/Question.java
  56. 41 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/domain/QuestionOld.java
  57. 36 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/domain/QuestionOldChild.java
  58. 28 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/domain/QuestionOldOptions.java
  59. 48 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/domain/QuestionOther.java
  60. 14 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/mapper/QuestionOtherMapper.java
  61. 2 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/service/IExamService.java
  62. 55 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/service/IQuestionOtherService.java
  63. 4 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/service/IQuestionService.java
  64. 70 8
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/service/impl/ExamServiceImpl.java
  65. 305 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/service/impl/QuestionOtherServiceImpl.java
  66. 29 2
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/service/impl/QuestionServiceImpl.java
  67. 4 1
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/vo/ExamVo.java
  68. 51 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/vo/QuestionOtherVo.java
  69. 5 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/vo/QuestionVo.java
  70. 9 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/base/bo/UserProfileQueryBo.java
  71. 4 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/base/service/IProfileTpService.java
  72. 52 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/base/service/impl/ProfileTpServiceImpl.java
  73. 16 2
      zhongzheng-system/src/main/java/com/zhongzheng/modules/base/service/impl/UserProfileServiceImpl.java
  74. 6 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/base/vo/UserProfileVo.java
  75. 2 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/collect/mapper/CollectQuestionMapper.java
  76. 5 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/collect/service/impl/CollectQuestionServiceImpl.java
  77. 5 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/course/bo/CourseQueryBo.java
  78. 26 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/course/bo/ExternalQuestionBo.java
  79. 22 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/course/bo/QuestionOpenBo.java
  80. 2 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/course/mapper/CourseFileMapper.java
  81. 4 1
      zhongzheng-system/src/main/java/com/zhongzheng/modules/course/mapper/CourseHandoutsBusinessMapper.java
  82. 9 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/course/mapper/CourseMapper.java
  83. 10 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/course/service/ICourseService.java
  84. 0 1
      zhongzheng-system/src/main/java/com/zhongzheng/modules/course/service/impl/CourseFileServiceImpl.java
  85. 391 18
      zhongzheng-system/src/main/java/com/zhongzheng/modules/course/service/impl/CourseServiceImpl.java
  86. 38 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/course/vo/ExternalQuestionVo.java
  87. 47 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/bo/CdExamRoomBo.java
  88. 45 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/bo/CdExamRoomUpdateBo.java
  89. 66 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/bo/CdUserSubscribeBo.java
  90. 2 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/bo/ExamApplySiteAddBo.java
  91. 1 1
      zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/bo/ExamApplySubscribeBo.java
  92. 2 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/domain/ExamApply.java
  93. 8 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/mapper/ExamApplyMapper.java
  94. 4 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/mapper/ExamSiteMapper.java
  95. 7 1
      zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/service/IExamApplyService.java
  96. 2 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/service/IExamSiteService.java
  97. 363 29
      zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/service/impl/ExamApplyServiceImpl.java
  98. 78 17
      zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/service/impl/ExamApplySiteServiceImpl.java
  99. 5 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/service/impl/ExamSiteServiceImpl.java
  100. 4 0
      zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/vo/ExamApplyGoodsVo.java

+ 81 - 0
run-prod.sh

@@ -1,3 +1,41 @@
+#!/usr/bin/env bash
+# 定义应用组名
+group_name='zhongzheng'
+# 定义应用名称
+app_name='zhongzheng-saas-api'
+# 定义应用版本
+app_version='1.0-SNAPSHOT'
+# 定义应用环境
+profile_active='prod'
+echo '----copy jar----'
+docker stop ${app_name}
+echo '----stop container----'
+docker rm ${app_name}
+echo '----rm container----'
+docker rmi ${group_name}/${app_name}:${app_version}
+echo '----rm image----'
+# 打包编译docker镜像
+docker build -f /mydata/maven/build/Dockerfile -t ${group_name}/${app_name}:${app_version} .
+echo '----build image----'
+docker run -p 5055:5055 --name ${app_name} \
+--restart=always \
+-e 'spring.profiles.active'=${profile_active} \
+-e TZ="Asia/Shanghai" \
+-m 10240m \
+--cpus=3 \
+--log-opt max-size=50m \
+--log-opt max-file=3 \
+-v /etc/localtime:/etc/localtime \
+-v /usr/share/fonts:/usr/share/fonts \
+-v /data/logs/prod_api:/logs \
+-v /mydata/app/${app_name}/logs:/var/logs \
+-d ${group_name}/${app_name}:${app_version}
+echo '----start container----'
+
+echo "开始等待20秒..."
+# 1-10秒内随机
+sleep 5
+echo "等待后继续"
 
 #!/usr/bin/env bash
 # 定义应用组名
@@ -33,3 +71,46 @@ docker run \
 -v /data/nginx/conf.d:/data/nginx/conf.d \
 -d ${group_admin_name}/${app_admin_name}:${app_admin_version}
 echo '----start container admin----'
+
+echo "开始等待20秒..."
+# 1-10秒内随机
+sleep 5
+echo "等待后继续"
+
+#!/usr/bin/env bash
+# 定义应用组名
+group_admin_name='zhongzheng'
+# 定义应用名称
+app_admin_name='zhongzheng-saas-admin-top'
+# 定义应用版本
+app_admin_version='1.0-SNAPSHOT'
+# 定义应用环境
+profile_active='prod'
+echo '----copy jar admin top----'
+docker stop ${app_admin_name}
+echo '----stop container admin top----'
+docker rm ${app_admin_name}
+echo '----rm container admin top----'
+docker rmi ${group_admin_name}/${app_admin_name}:${app_admin_version}
+echo '----rm image admin top----'
+# 打包编译docker镜像
+docker build -f /mydata/maven/build/Dockerfile-saas -t ${group_admin_name}/${app_admin_name}:${app_admin_version} .
+echo '----build image admin top----'
+docker run \
+-p 7077:7077 \
+--name ${app_admin_name} \
+--restart=always \
+--log-opt max-size=50m \
+--log-opt max-file=3 \
+-e 'spring.profiles.active'=${profile_active} \
+-e TZ="Asia/Shanghai" \
+-v /etc/localtime:/etc/localtime \
+-v /usr/share/fonts:/usr/share/fonts \
+-v /data/logs/prod_admin_top:/logs \
+-v /mydata/app/${app_admin_name}/logs:/var/logs \
+-v /data/nginx/conf.d:/data/nginx/conf.d \
+-d ${group_admin_name}/${app_admin_name}:${app_admin_version}
+echo '----start container admin top----'
+
+
+

+ 115 - 0
zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/financial/TopCostInstTpController.java

@@ -0,0 +1,115 @@
+package com.zhongzheng.controller.financial;
+
+import java.util.List;
+import java.util.Arrays;
+
+import com.zhongzheng.modules.top.financial.bo.*;
+import com.zhongzheng.modules.top.financial.service.ITopCostInstTpItemService;
+import com.zhongzheng.modules.top.financial.service.ITopCostInstTpService;
+import com.zhongzheng.modules.top.financial.vo.TopCostInstTpVo;
+import com.zhongzheng.modules.top.goods.vo.TopCourseEducationTypeVo;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zhongzheng.common.annotation.Log;
+import com.zhongzheng.common.core.controller.BaseController;
+import com.zhongzheng.common.core.domain.AjaxResult;
+import com.zhongzheng.common.enums.BusinessType;
+import com.zhongzheng.common.utils.poi.ExcelUtil;
+import com.zhongzheng.common.core.page.TableDataInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * 供应商成本模板Controller
+ *
+ * @author hjl
+ * @date 2023-07-21
+ */
+@Api(value = "供应商成本模板控制器", tags = {"供应商成本模板管理"})
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@RestController
+@RequestMapping("/top/cost/inst/tp")
+public class TopCostInstTpController extends BaseController {
+
+    private final ITopCostInstTpService iTopCostInstTpService;
+
+    private final ITopCostInstTpItemService iTopCostInstTpItemService;
+
+    /**
+     * 查询供应商成本模板列表
+     */
+    @ApiOperation("查询供应商成本模板列表")
+    @PreAuthorize("@ss.hasPermi('system:tp:list')")
+    @GetMapping("/list")
+    public TableDataInfo<TopCostInstTpVo> list(TopCostInstTpQueryBo bo) {
+        startPage();
+        List<TopCostInstTpVo> list = iTopCostInstTpService.selectList(bo);
+        return getDataTable(list);
+    }
+
+    @ApiOperation("查询供应商成本模板所有业务层次列表")
+    @PreAuthorize("@ss.hasPermi('system:tp:list')")
+    @GetMapping("/businessList")
+    public AjaxResult<List<TopCourseEducationTypeVo>> businessList(TopCostInstTpItemQueryBo bo) {
+        List<TopCourseEducationTypeVo> list = iTopCostInstTpItemService.queryEduList(bo);
+        return AjaxResult.success(list);
+    }
+
+
+    /**
+     * 获取供应商成本模板详细信息
+     */
+    @ApiOperation("获取供应商成本模板详细信息")
+    @PreAuthorize("@ss.hasPermi('system:tp:query')")
+    @GetMapping("/{tpId}")
+    public AjaxResult<TopCostInstTpVo> getInfo(@PathVariable("tpId" ) Long tpId) {
+        return AjaxResult.success(iTopCostInstTpService.queryById(tpId));
+    }
+
+    /**
+     * 新增供应商成本模板
+     */
+    @ApiOperation("新增供应商成本模板")
+    @PreAuthorize("@ss.hasPermi('system:tp:add')")
+    @Log(title = "供应商成本模板", businessType = BusinessType.INSERT)
+    @PostMapping()
+    public AjaxResult<Void> add(@RequestBody TopCostInstTpAddBo bo) {
+        return toAjax(iTopCostInstTpService.insertByAddBo(bo) ? 1 : 0);
+    }
+
+    /**
+     * 修改供应商成本模板
+     */
+    @ApiOperation("修改供应商成本模板")
+    @PreAuthorize("@ss.hasPermi('system:tp:edit')")
+    @Log(title = "供应商成本模板", businessType = BusinessType.UPDATE)
+    @PostMapping("/edit")
+    public AjaxResult<Void> edit(@RequestBody TopCostInstTpEditBo bo) {
+        return toAjax(iTopCostInstTpService.updateByEditBo(bo) ? 1 : 0);
+    }
+
+    @ApiOperation("供应商成本模板批量删除")
+    @PreAuthorize("@ss.hasPermi('system:tp:edit')")
+    @Log(title = "供应商成本模板批量删除", businessType = BusinessType.UPDATE)
+    @PostMapping("/deleteBatch")
+    public AjaxResult<Void> deleteBatch(@RequestBody TopCostInstTpQueryBo bo) {
+        return toAjax(iTopCostInstTpService.deleteBatch(bo) ? 1 : 0);
+    }
+
+    @ApiOperation("修改供应商成本模板默认状态")
+    @PreAuthorize("@ss.hasPermi('system:tp:edit')")
+    @Log(title = "修改供应商成本模板默认状态", businessType = BusinessType.UPDATE)
+    @PostMapping("/editDefaultStatus")
+    public AjaxResult<Void> editDefaultStatus(@RequestBody TopCostInstTpEditBo bo) {
+        return toAjax(iTopCostInstTpService.updateDefaultStatus(bo) ? 1 : 0);
+    }
+}

+ 51 - 8
zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/financial/TopDivideLogController.java

@@ -2,6 +2,7 @@ package com.zhongzheng.controller.financial;
 
 import java.util.List;
 import java.util.Arrays;
+import java.util.Map;
 
 import com.zhongzheng.common.constant.UserConstants;
 import com.zhongzheng.common.utils.SecurityUtils;
@@ -57,8 +58,8 @@ public class TopDivideLogController extends BaseController {
      */
     @ApiOperation("查询机构分成记录列表")
     @PreAuthorize("@ss.hasPermi('system:log:list')")
-    @GetMapping("/companyList")
-    public TableDataInfo<TopDivideLogVo> getCompanyList(TopDivideLogQueryBo bo) {
+    @PostMapping("/companyList")
+    public TableDataInfo<TopDivideLogVo> getCompanyList(@RequestBody TopDivideLogQueryBo bo) {
         startPage();
         List<TopDivideLogVo> list = iTopDivideLogService.getCompanyList(bo);
         return getDataTable(list);
@@ -77,8 +78,8 @@ public class TopDivideLogController extends BaseController {
 
     @ApiOperation("查询业务员提成列表")
     @PreAuthorize("@ss.hasPermi('system:log:list')")
-    @GetMapping("/sellerList")
-    public TableDataInfo<TopDivideLogVo> getSellerList(TopDivideLogQueryBo bo) {
+    @PostMapping("/sellerList")
+    public TableDataInfo<TopDivideLogVo> getSellerList(@RequestBody TopDivideLogQueryBo bo) {
         startPage();
         List<TopDivideLogVo> list = iTopDivideLogService.getSellerList(bo);
         return getDataTable(list);
@@ -86,13 +87,29 @@ public class TopDivideLogController extends BaseController {
 
     @ApiOperation("查询佣金列表")
     @PreAuthorize("@ss.hasPermi('system:log:list')")
-    @GetMapping("/commissionList")
-    public TableDataInfo<TopDivideLogVo> getCommissionList(TopDivideLogQueryBo bo) {
+    @PostMapping("/commissionList")
+    public TableDataInfo<TopDivideOrderVo> getCommissionList(@RequestBody TopDivideOrderQueryBo bo) {
         startPage();
-        List<TopDivideLogVo> list = iTopDivideLogService.getCommissionList(bo);
+        List<TopDivideOrderVo> list = iTopDivideLogService.getCommissionList(bo);
         return getDataTable(list);
     }
 
+    @ApiOperation("查询佣金打印")
+    @PreAuthorize("@ss.hasPermi('system:log:list')")
+    @PostMapping("/commissionPrint")
+    public AjaxResult<TopDivideOrderVo> getCommissionPrint(@RequestBody TopDivideOrderQueryBo bo) {
+        TopDivideOrderVo vo = iTopDivideLogService.getCommissionDetail(bo);
+        return AjaxResult.success(vo);
+    }
+
+    @ApiOperation("查询佣金结算列表统计")
+    @PreAuthorize("@ss.hasPermi('system:log:list')")
+    @GetMapping("/commissionOrderCount")
+    public AjaxResult<Map<String,Object>> commissionOrderCount(TopDivideOrderQueryBo bo) {
+        Map<String,Object> map = iTopDivideLogService.getCommissionOrderCount(bo);
+        return AjaxResult.success(map);
+    }
+
     @ApiOperation("通过坏账配置详情")
     @GetMapping(value = "/configKey/badBill")
     public AjaxResult getBadBill()
@@ -110,11 +127,30 @@ public class TopDivideLogController extends BaseController {
     @ApiOperation("查询月份订单列表")
     @PreAuthorize("@ss.hasPermi('system:log:list')")
     @GetMapping("/monthOrderList")
-    public AjaxResult<List<TopDivideOrderVo>> getMonthOrderList(TopDivideOrderQueryBo bo) {
+    public TableDataInfo<TopDivideOrderVo> getMonthOrderList(TopDivideOrderQueryBo bo) {
+        startPage();
         List<TopDivideOrderVo> list = iTopDivideOrderService.getMonthOrderList(bo);
+        return getDataTable(list);
+    }
+
+    @ApiOperation("查询月份订单统计")
+    @PreAuthorize("@ss.hasPermi('system:log:list')")
+    @GetMapping("/monthOrderCount")
+    public AjaxResult<Map<String,Object>> getMonthOrderCount(TopDivideOrderQueryBo bo) {
+        Map<String,Object> map = iTopDivideOrderService.getMonthOrderCount(bo);
+        return AjaxResult.success(map);
+    }
+
+    @ApiOperation("查询打印月份订单列表")
+    @PreAuthorize("@ss.hasPermi('system:log:list')")
+    @GetMapping("/monthOrderListWithPrint")
+    public AjaxResult<List<TopDivideOrderVo>> getMonthOrderListWithPrint(TopDivideOrderQueryBo bo) {
+        List<TopDivideOrderVo> list = iTopDivideOrderService.getMonthOrderListWithPrint(bo);
         return AjaxResult.success(list);
     }
 
+
+
     /**
      * 获取分成记录详细信息
      */
@@ -124,4 +160,11 @@ public class TopDivideLogController extends BaseController {
     public AjaxResult<TopDivideLogVo> getInfo(@PathVariable("id" ) Long id) {
         return AjaxResult.success(iTopDivideLogService.queryById(id));
     }
+
+    @ApiOperation("获取分成记录单据打印详细信息")
+    @PreAuthorize("@ss.hasPermi('system:log:query')")
+    @GetMapping("/withPrint/{id}")
+    public AjaxResult<TopDivideLogVo> getInfoWithPrint(@PathVariable("id" ) Long id) {
+        return AjaxResult.success(iTopDivideLogService.queryByIdWithPrint(id));
+    }
 }

+ 7 - 1
zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/financial/TopOrderRecNoteController.java

@@ -76,5 +76,11 @@ public class TopOrderRecNoteController extends BaseController {
         return toAjax(iTopOrderRecNoteService.updateByEditBo(bo) ? 1 : 0);
     }
 
-
+    @ApiOperation("批量修改订单收款提醒")
+    @PreAuthorize("@ss.hasPermi('system:note:edit')")
+    @Log(title = "批量修改订单收款提醒", businessType = BusinessType.UPDATE)
+    @PostMapping("/editBatch")
+    public AjaxResult<Void> editBatch(@RequestBody List<TopOrderRecNoteEditBo> bo) {
+        return toAjax(iTopOrderRecNoteService.updateByBatchEditBo(bo) ? 1 : 0);
+    }
 }

+ 13 - 0
zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/order/TopOldOrderCheckLogController.java

@@ -109,4 +109,17 @@ public class TopOldOrderCheckLogController extends BaseController {
         }
         return toAjax(iTopOldOrderCheckLogService.updateBatchDivideByEditBo(bo) ? 1 : 0);
     }
+
+    @ApiOperation("批量修改月份分成审核记录")
+    @PreAuthorize("@ss.hasPermi('system:log:edit')")
+    @Log(title = "批量修改月份分成审核记录", businessType = BusinessType.UPDATE)
+    @PostMapping("/updateBatchDivideByMonthEditBo")
+    public AjaxResult<Void> updateBatchDivideByMonthEditBo(@RequestBody List<TopOldOrderCheckLogEditBo> bo) {
+        TopLoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        for(TopOldOrderCheckLogEditBo editBo : bo){
+            editBo.setLoginId(loginUser.getUser().getUserId());
+            editBo.setLoginName(loginUser.getUser().getUserName());
+        }
+        return toAjax(iTopOldOrderCheckLogService.updateBatchDivideByMonthEditBo(bo) ? 1 : 0);
+    }
 }

+ 6 - 3
zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/order/TopOldOrderController.java

@@ -9,6 +9,7 @@ import com.zhongzheng.common.utils.poi.ExcelUtil;
 import com.zhongzheng.framework.web.service.TopTokenService;
 import com.zhongzheng.modules.top.financial.bo.OrderRefundPayBo;
 import com.zhongzheng.modules.top.financial.bo.TopDivideLogQueryBo;
+import com.zhongzheng.modules.top.financial.bo.TopDivideOrderQueryBo;
 import com.zhongzheng.modules.top.financial.vo.OrderRefundPayDetailVo;
 import com.zhongzheng.modules.top.financial.vo.TopCostTpVo;
 import com.zhongzheng.modules.top.financial.vo.TopOrderLogVo;
@@ -166,12 +167,14 @@ public class TopOldOrderController extends BaseController {
     @ApiOperation("佣金结算列表导出")
     @PreAuthorize("@ss.hasPermi('system:tp:list')")
     @GetMapping("/commissionListExport")
-    public AjaxResult<List<TopOldOrderSellerExportVo>> commissionListExport(TopDivideLogQueryBo bo) {
+    public AjaxResult<List<TopOldOrderSellerExportVo>> commissionListExport(TopDivideOrderQueryBo bo) {
         List<TopOldOrderCommissionExportVo> list = iTopOldOrderService.commissionListExport(bo);
         ExcelUtil<TopOldOrderCommissionExportVo> util = new ExcelUtil<TopOldOrderCommissionExportVo>(TopOldOrderCommissionExportVo.class);
         return util.exportExcel(list, "佣金结算列表");
     }
 
+
+
     @ApiOperation("机构分成列表")
     @PreAuthorize("@ss.hasPermi('system:tp:list')")
     @GetMapping("/queryTenantList")
@@ -252,8 +255,8 @@ public class TopOldOrderController extends BaseController {
     }
 
     @ApiOperation("订单应收应付统计")
-    @GetMapping("/countOrderNum")
-    public AjaxResult<Map<String, Object>> countOrderNum(TopOldOrderQueryBo bo) {
+    @PostMapping("/countOrderNum")
+    public AjaxResult<Map<String, Object>> countOrderNum(@RequestBody TopOldOrderQueryBo bo) {
         return AjaxResult.success(iTopOldOrderService.countOrderNum(bo));
     }
 

+ 7 - 0
zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/schedule/ScheduleController.java

@@ -84,4 +84,11 @@ public class ScheduleController extends BaseController {
         iScheduleService.makeDivideSellerMonthBill();
         return AjaxResult.success();
     }
+
+    @ApiOperation("更新机构分成,业务提成应付时间")
+    @GetMapping("/updateCompanyPredictPayTime")
+    public AjaxResult updateCompanyPredictPayTime(){
+        iScheduleService.updatePredictPayTime();
+        return AjaxResult.success();
+    }
 }

+ 246 - 0
zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/settle/TopInstSettleController.java

@@ -0,0 +1,246 @@
+package com.zhongzheng.controller.settle;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.zhongzheng.common.core.controller.BaseController;
+import com.zhongzheng.common.core.domain.AjaxResult;
+import com.zhongzheng.common.core.domain.model.TopLoginUser;
+import com.zhongzheng.common.core.page.TableDataInfo;
+import com.zhongzheng.common.exception.CustomException;
+import com.zhongzheng.common.utils.ServletUtils;
+import com.zhongzheng.common.utils.poi.ExcelUtil;
+import com.zhongzheng.framework.web.service.TopTokenService;
+import com.zhongzheng.modules.top.settle.bo.*;
+import com.zhongzheng.modules.top.settle.service.ITopInstSettleService;
+import com.zhongzheng.modules.top.settle.vo.*;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author yangdamao
+ * @date 2023年07月24日 11:19
+ */
+@Api(value = "供应商结算", tags = {"供应商结算管理"})
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@RestController
+@RequestMapping("/settle")
+public class TopInstSettleController extends BaseController {
+
+    private final ITopInstSettleService ITopInstSettleService;
+    private final TopTokenService tokenService;
+
+    /**
+     * 获取订单详情信息
+     */
+    @ApiOperation("获取订单详细信息")
+    @GetMapping("/order/info")
+    public AjaxResult<TopOrderInfoVo> getOrderInfo(SettleOrderInfoBo bo) {
+        return AjaxResult.success(ITopInstSettleService.getOrderInfo(bo));
+    }
+
+    /**
+     * 结算金额计算
+     */
+    @ApiOperation("结算金额计算")
+    @GetMapping("/money")
+    public AjaxResult<BigDecimal> getSettleMoney(SettleMoneyBo bo) {
+        return AjaxResult.success(ITopInstSettleService.getSettleMoney(bo));
+    }
+
+    /**
+     * 订单批量导入
+     */
+    @ApiOperation("订单批量导入")
+    @PostMapping("/order/import")
+    public AjaxResult<List<SettleOrderImportVo>> batchOrderImport(MultipartFile file,String param) {
+        if (StringUtils.isBlank(param)){
+            throw new CustomException("参数不能未空");
+        }
+        ExcelUtil<SettleOrderImportBo> util = new ExcelUtil<SettleOrderImportBo>(SettleOrderImportBo.class);
+        List<SettleOrderImportBo> orderImportBo = null;
+        try{
+            orderImportBo = util.importExcel(file.getInputStream());
+        }catch (Exception e){
+            e.printStackTrace();
+            throw new IllegalArgumentException("模板格式不正确,请重新下载模板");
+        }
+        Collections.reverse(orderImportBo);
+        if (orderImportBo.stream().allMatch(item -> ObjectUtils.isNull(item))){
+            throw new IllegalArgumentException("模板格式不正确,请重新下载模板");
+        }
+        SettleOrderImportParamBo paramBo = JSON.parseObject(param, SettleOrderImportParamBo.class);
+        return AjaxResult.success(ITopInstSettleService.batchOrderImport(orderImportBo,paramBo));
+    }
+
+    /**
+     * 按数量保存结算订单
+     */
+    @ApiOperation("按数量保存结算订单")
+    @PostMapping("/num/save")
+    public AjaxResult<Void> numSettleOrderSave(@RequestBody NumSettleBo bo) {
+        TopLoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        bo.setLoginId(loginUser.getUser().getUserId());
+        bo.setLoginName(loginUser.getUser().getUserName());
+        return toAjax(ITopInstSettleService.numSettleOrderSave(bo) ? 1 : 0);
+    }
+
+    /**
+     * 按时间保存结算订单
+     */
+    @ApiOperation("按时间保存结算订单")
+    @PostMapping("/time/save")
+    public AjaxResult<Void> timeSettleOrderSave(@RequestBody TimeSettleBo bo) {
+        TopLoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        bo.setLoginId(loginUser.getUser().getUserId());
+        bo.setLoginName(loginUser.getUser().getUserName());
+        return toAjax(ITopInstSettleService.timeSettleOrderSave(bo) ? 1 : 0);
+    }
+
+    /**
+     * 结算订单列表
+     */
+    @ApiOperation("结算订单列表")
+    @GetMapping("/list")
+    public TableDataInfo<SettleVo> list(SettleQueryBo bo) {
+        TopLoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        bo.setLoginId(loginUser.getUser().getUserId());
+        bo.setLoginName(loginUser.getUser().getUserName());
+        startPage();
+        List<SettleVo> list = ITopInstSettleService.getSettleList(bo);
+        return getDataTable(list);
+    }
+
+    /**
+     * 获取时间结算单详情信息
+     */
+    @ApiOperation("获取时间结算单详情信息")
+    @GetMapping("/time/detail/{settleId}")
+    public AjaxResult<TimeSettleDetailVo> getTimeSettleDetail(@PathVariable("settleId") Long settleId) {
+        return AjaxResult.success(ITopInstSettleService.getTimeSettleDetail(settleId));
+    }
+
+    /**
+     * 获取数量结算单详情信息
+     */
+    @ApiOperation("获取数量结算单详情信息")
+    @GetMapping("/num/detail/{settleId}")
+    public AjaxResult<NumSettleDetailVo> getNumSettleDetail(@PathVariable("settleId") Long settleId) {
+        return AjaxResult.success(ITopInstSettleService.getNumSettleDetail(settleId));
+    }
+
+    /**
+     * 时间结算单修改
+     */
+    @ApiOperation("时间结算单修改")
+    @PostMapping("/time/update")
+    public AjaxResult<Void> updateTimeSettle(@RequestBody TimeSettleBo bo) {
+        TopLoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        bo.setLoginId(loginUser.getUser().getUserId());
+        bo.setLoginName(loginUser.getUser().getUserName());
+        return toAjax(ITopInstSettleService.updateTimeSettle(bo) ? 1 : 0);
+    }
+
+    /**
+     * 数量结算单修改
+     */
+    @ApiOperation("数量结算单修改")
+    @PostMapping("/num/update")
+    public AjaxResult<Void> updateNumSettle(@RequestBody NumSettleBo bo) {
+        TopLoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        bo.setLoginId(loginUser.getUser().getUserId());
+        bo.setLoginName(loginUser.getUser().getUserName());
+        return toAjax(ITopInstSettleService.updateNumSettle(bo) ? 1 : 0);
+    }
+
+    /**
+     * 结算单批量提交审核
+     */
+    @ApiOperation("结算单批量提交审核")
+    @PostMapping("/batch/submit/check")
+    public AjaxResult<Void> batchSubmitCheck(@RequestBody List<Long> settleIds) {
+        TopLoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        return toAjax(ITopInstSettleService.batchSubmitCheck(settleIds,loginUser.getUser().getUserId(),loginUser.getUser().getUserName()) ? 1 : 0);
+    }
+
+    /**
+     * 结算单批量删除
+     */
+    @ApiOperation("结算单批量删除")
+    @PostMapping("/batch/delete")
+    public AjaxResult<Void> batchDeleteSettle(@RequestBody List<Long> settleIds) {
+        return toAjax(ITopInstSettleService.batchDeleteSettle(settleIds) ? 1 : 0);
+    }
+
+    /**
+     * 结算单审核
+     */
+    @ApiOperation("结算单审核")
+    @PostMapping("/check")
+    public AjaxResult<Void> checkSettle(@RequestBody CheckSettleBo bo) {
+        TopLoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        bo.setLoginId(loginUser.getUser().getUserId());
+        bo.setLoginName(loginUser.getUser().getUserName());
+        return toAjax(ITopInstSettleService.checkSettle(bo) ? 1 : 0);
+    }
+
+    /**
+     * 结算单总金额
+     */
+    @ApiOperation("结算单总金额")
+    @PostMapping("/total/money")
+    public AjaxResult<BigDecimal> getSettleTotalMoney(SettleQueryBo bo) {
+        TopLoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        bo.setLoginId(loginUser.getUser().getUserId());
+        bo.setLoginName(loginUser.getUser().getUserName());
+        return AjaxResult.success(ITopInstSettleService.getSettleTotalMoney(bo));
+    }
+
+    /**
+     * 结算单支付信息
+     */
+    @ApiOperation("结算单支付信息")
+    @GetMapping("/pay/info/{settleId}")
+    public AjaxResult<SettleVo> getSettlePayInfo(@PathVariable("settleId") Long settleId) {
+        return AjaxResult.success(ITopInstSettleService.getSettlePayInfo(settleId));
+    }
+
+    /**
+     * 结算单支付
+     */
+    @ApiOperation("结算单支付")
+    @PostMapping("/pay")
+    public AjaxResult<Void> settlePay(@RequestBody SettlePayBo bo) {
+        TopLoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        bo.setLoginId(loginUser.getUser().getUserId());
+        bo.setLoginName(loginUser.getUser().getUserName());
+        return toAjax(ITopInstSettleService.settlePay(bo) ? 1 : 0);
+    }
+
+    /**
+     * 结算单据打印信息
+     */
+    @ApiOperation("结算单据打印信息")
+    @GetMapping("/receipts/{settleId}")
+    public AjaxResult<SettleReceiptsVo> getSettleReceipts(@PathVariable("settleId") Long settleId) {
+        return AjaxResult.success(ITopInstSettleService.getSettleReceipts(settleId));
+    }
+
+    /**
+     * 结算单据打印明细信息
+     */
+    @ApiOperation("结算单据打印明细信息")
+    @GetMapping("/receipts/detail/{settleId}")
+    public AjaxResult<List<NumSettleOrderVo>> getSettleReceiptsDetail(@PathVariable("settleId") Long settleId) {
+        return AjaxResult.success(ITopInstSettleService.getSettleReceiptsDetail(settleId));
+    }
+
+}

+ 99 - 0
zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/top/TopCostCategoryController.java

@@ -0,0 +1,99 @@
+package com.zhongzheng.controller.top;
+
+import java.util.List;
+import java.util.Arrays;
+
+import com.zhongzheng.modules.top.system.bo.TopCostCategoryAddBo;
+import com.zhongzheng.modules.top.system.bo.TopCostCategoryEditBo;
+import com.zhongzheng.modules.top.system.bo.TopCostCategoryQueryBo;
+import com.zhongzheng.modules.top.system.service.ITopCostCategoryService;
+import com.zhongzheng.modules.top.system.vo.TopCostCategoryVo;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zhongzheng.common.annotation.Log;
+import com.zhongzheng.common.core.controller.BaseController;
+import com.zhongzheng.common.core.domain.AjaxResult;
+import com.zhongzheng.common.enums.BusinessType;
+import com.zhongzheng.common.utils.poi.ExcelUtil;
+import com.zhongzheng.common.core.page.TableDataInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * 机构成本类别Controller
+ *
+ * @author ruoyi
+ * @date 2023-07-27
+ */
+@Api(value = "机构成本类别控制器", tags = {"机构成本类别管理"})
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@RestController
+@RequestMapping("/top/category")
+public class TopCostCategoryController extends BaseController {
+
+    private final ITopCostCategoryService iTopCostCategoryService;
+
+    /**
+     * 查询机构成本类别列表
+     */
+    @ApiOperation("查询机构成本类别列表")
+    @PreAuthorize("@ss.hasPermi('system:category:list')")
+    @GetMapping("/list")
+    public TableDataInfo<TopCostCategoryVo> list(TopCostCategoryQueryBo bo) {
+        startPage();
+        List<TopCostCategoryVo> list = iTopCostCategoryService.queryList(bo);
+        return getDataTable(list);
+    }
+
+
+
+    /**
+     * 获取机构成本类别详细信息
+     */
+    @ApiOperation("获取机构成本类别详细信息")
+    @PreAuthorize("@ss.hasPermi('system:category:query')")
+    @GetMapping("/{categoryId}")
+    public AjaxResult<TopCostCategoryVo> getInfo(@PathVariable("categoryId" ) Long categoryId) {
+        return AjaxResult.success(iTopCostCategoryService.queryById(categoryId));
+    }
+
+    /**
+     * 新增机构成本类别
+     */
+    @ApiOperation("新增机构成本类别")
+    @PreAuthorize("@ss.hasPermi('system:category:add')")
+    @Log(title = "机构成本类别", businessType = BusinessType.INSERT)
+    @PostMapping()
+    public AjaxResult<Void> add(@RequestBody TopCostCategoryAddBo bo) {
+        return toAjax(iTopCostCategoryService.insertByAddBo(bo) ? 1 : 0);
+    }
+
+    /**
+     * 修改机构成本类别
+     */
+    @ApiOperation("修改机构成本类别")
+    @PreAuthorize("@ss.hasPermi('system:category:edit')")
+    @Log(title = "机构成本类别", businessType = BusinessType.UPDATE)
+    @PostMapping("/edit")
+    public AjaxResult<Void> edit(@RequestBody TopCostCategoryEditBo bo) {
+        return toAjax(iTopCostCategoryService.updateByEditBo(bo) ? 1 : 0);
+    }
+
+    @ApiOperation("机构成本类别批量删除")
+    @PreAuthorize("@ss.hasPermi('system:tp:edit')")
+    @Log(title = "机构成本类别批量删除", businessType = BusinessType.UPDATE)
+    @PostMapping("/deleteBatch")
+    public AjaxResult<Void> deleteBatch(@RequestBody TopCostCategoryEditBo bo) {
+        return toAjax(iTopCostCategoryService.deleteBatch(bo) ? 1 : 0);
+    }
+
+}

+ 100 - 0
zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/top/TopInstCategoryController.java

@@ -0,0 +1,100 @@
+package com.zhongzheng.controller.top;
+
+import java.util.List;
+import java.util.Arrays;
+
+import com.zhongzheng.modules.top.financial.bo.TopCostInstTpQueryBo;
+import com.zhongzheng.modules.top.system.bo.TopInstCategoryAddBo;
+import com.zhongzheng.modules.top.system.bo.TopInstCategoryEditBo;
+import com.zhongzheng.modules.top.system.bo.TopInstCategoryQueryBo;
+import com.zhongzheng.modules.top.system.service.ITopInstCategoryService;
+import com.zhongzheng.modules.top.system.vo.TopInstCategoryVo;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zhongzheng.common.annotation.Log;
+import com.zhongzheng.common.core.controller.BaseController;
+import com.zhongzheng.common.core.domain.AjaxResult;
+import com.zhongzheng.common.enums.BusinessType;
+
+import com.zhongzheng.common.utils.poi.ExcelUtil;
+import com.zhongzheng.common.core.page.TableDataInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * 供应商成本分类Controller
+ *
+ * @author ruoyi
+ * @date 2023-07-20
+ */
+@Api(value = "供应商成本分类控制器", tags = {"供应商成本分类管理"})
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@RestController
+@RequestMapping("/top/inst/category")
+public class TopInstCategoryController extends BaseController {
+
+    private final ITopInstCategoryService iTopInstCategoryService;
+
+    /**
+     * 查询供应商成本分类列表
+     */
+    @ApiOperation("查询供应商成本分类列表")
+    @PreAuthorize("@ss.hasPermi('system:category:list')")
+    @GetMapping("/list")
+    public TableDataInfo<TopInstCategoryVo> list(TopInstCategoryQueryBo bo) {
+        startPage();
+        List<TopInstCategoryVo> list = iTopInstCategoryService.queryList(bo);
+        return getDataTable(list);
+    }
+
+
+
+    /**
+     * 获取供应商成本分类详细信息
+     */
+    @ApiOperation("获取供应商成本分类详细信息")
+    @PreAuthorize("@ss.hasPermi('system:category:query')")
+    @GetMapping("/{costCatId}")
+    public AjaxResult<TopInstCategoryVo> getInfo(@PathVariable("costCatId" ) Long costCatId) {
+        return AjaxResult.success(iTopInstCategoryService.queryById(costCatId));
+    }
+
+    /**
+     * 新增供应商成本分类
+     */
+    @ApiOperation("新增供应商成本分类")
+    @PreAuthorize("@ss.hasPermi('system:category:add')")
+    @Log(title = "供应商成本分类", businessType = BusinessType.INSERT)
+    @PostMapping()
+    public AjaxResult<Void> add(@RequestBody TopInstCategoryAddBo bo) {
+        return toAjax(iTopInstCategoryService.insertByAddBo(bo) ? 1 : 0);
+    }
+
+    /**
+     * 修改供应商成本分类
+     */
+    @ApiOperation("修改供应商成本分类")
+    @PreAuthorize("@ss.hasPermi('system:category:edit')")
+    @Log(title = "供应商成本分类", businessType = BusinessType.UPDATE)
+    @PostMapping("/edit")
+    public AjaxResult<Void> edit(@RequestBody TopInstCategoryEditBo bo) {
+        return toAjax(iTopInstCategoryService.updateByEditBo(bo) ? 1 : 0);
+    }
+
+    @ApiOperation("供应商成本分类批量删除")
+    @PreAuthorize("@ss.hasPermi('system:tp:edit')")
+    @Log(title = "供应商成本分类批量删除", businessType = BusinessType.UPDATE)
+    @PostMapping("/deleteBatch")
+    public AjaxResult<Void> deleteBatch(@RequestBody TopInstCategoryEditBo bo) {
+        return toAjax(iTopInstCategoryService.deleteBatch(bo) ? 1 : 0);
+    }
+}

+ 28 - 0
zhongzheng-admin-saas/src/main/java/com/zhongzheng/controller/top/TopInstitutionController.java

@@ -3,11 +3,14 @@ package com.zhongzheng.controller.top;
 import java.util.List;
 import java.util.Arrays;
 
+import com.zhongzheng.modules.top.financial.bo.TopCostInstTpQueryBo;
 import com.zhongzheng.modules.top.system.bo.TopInstitutionAddBo;
 import com.zhongzheng.modules.top.system.bo.TopInstitutionEditBo;
 import com.zhongzheng.modules.top.system.bo.TopInstitutionQueryBo;
 import com.zhongzheng.modules.top.system.service.ITopInstitutionService;
 import com.zhongzheng.modules.top.system.vo.TopInstitutionVo;
+import com.zhongzheng.modules.user.bo.UserQueryBo;
+import com.zhongzheng.modules.user.vo.UserExportVo;
 import lombok.RequiredArgsConstructor;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -54,6 +57,24 @@ public class TopInstitutionController extends BaseController {
         return getDataTable(list);
     }
 
+    @ApiOperation("导出职能机构列表")
+    @PreAuthorize("@ss.hasPermi('app:user:list')")
+    @GetMapping("/listExport")
+    public AjaxResult<TopInstitutionVo> listExport(TopInstitutionQueryBo bo) {
+        List<TopInstitutionVo> list = iTopInstitutionService.queryList(bo);
+        ExcelUtil<TopInstitutionVo> util = new ExcelUtil<>(TopInstitutionVo.class);
+        return util.exportExcel(list,"导出职能机构列表");
+    }
+
+    @ApiOperation("成本分类查询职能机构列表")
+    @PreAuthorize("@ss.hasPermi('system:institution:list')")
+    @GetMapping("/listByCat")
+    public TableDataInfo<TopInstitutionVo> listByCat(TopInstitutionQueryBo bo) {
+        startPage();
+        List<TopInstitutionVo> list = iTopInstitutionService.listByCat(bo);
+        return getDataTable(list);
+    }
+
 
 
     /**
@@ -88,5 +109,12 @@ public class TopInstitutionController extends BaseController {
         return toAjax(iTopInstitutionService.updateByEditBo(bo) ? 1 : 0);
     }
 
+    @ApiOperation("职能机构批量删除")
+    @PreAuthorize("@ss.hasPermi('system:tp:edit')")
+    @Log(title = "职能机构批量删除", businessType = BusinessType.UPDATE)
+    @PostMapping("/deleteBatch")
+    public AjaxResult<Void> deleteBatch(@RequestBody TopInstitutionQueryBo bo) {
+        return toAjax(iTopInstitutionService.deleteBatch(bo) ? 1 : 0);
+    }
 
 }

+ 9 - 0
zhongzheng-admin-saas/src/main/resources/application-dev.yml

@@ -174,3 +174,12 @@ invoice:
     host: http://192.168.1.222:7077/sys/common/openMplatform/log
 
 liveHost: http://192.168.1.222:6009
+
+exam:
+    applySave: http://192.168.1.7:9099/cd/exam/save
+    applyUpdate: http://192.168.1.7:9099/cd/exam/update
+    applyDelete: http://192.168.1.7:9099/cd/exam/delete
+    subscribeSave: http://192.168.1.7:9099/cd/subscribe/save
+    subscribeSaveExam: http://192.168.1.7:9099/cd/subscribe/save/exam
+    subscribeUpdateExam: http://192.168.1.7:9099/cd/subscribe/update/exam
+    subscribeAddExamNum: http://192.168.1.7:9099/cd/subscribe/add/num

+ 11 - 0
zhongzheng-admin-saas/src/main/resources/application-pre.yml

@@ -172,3 +172,14 @@ oldSys:
 
 invoice:
     host: http://192.168.1.222:8077/sys/common/openMplatform/log
+
+liveHost: http://192.168.1.222:6009
+
+exam:
+    applySave: http://192.168.1.7:9099/cd/exam/save
+    applyUpdate: http://192.168.1.7:9099/cd/exam/update
+    applyDelete: http://192.168.1.7:9099/cd/exam/delete
+    subscribeSave: http://192.168.1.7:9099/cd/subscribe/save
+    subscribeSaveExam: http://192.168.1.7:9099/cd/subscribe/save/exam
+    subscribeUpdateExam: http://192.168.1.7:9099/cd/subscribe/update/exam
+    subscribeAddExamNum: http://192.168.1.7:9099/cd/subscribe/add/num

+ 9 - 0
zhongzheng-admin-saas/src/main/resources/application-prod.yml

@@ -174,3 +174,12 @@ invoice:
     host: https://ptapi.gdzzkj.net/sys/common/openMplatform/log
 
 liveHost: https://sso.xyyxt.net
+
+exam:
+    applySave: http://39.108.7.155:9099/cd/exam/save
+    applyUpdate: http://39.108.7.155:9099/cd/exam/update
+    applyDelete: http://39.108.7.155:9099/cd/exam/delete
+    subscribeSave: http://39.108.7.155:9099/cd/subscribe/save
+    subscribeSaveExam: http://39.108.7.155:9099/cd/subscribe/save/exam
+    subscribeUpdateExam: http://39.108.7.155:9099/cd/subscribe/update/exam
+    subscribeAddExamNum: http://39.108.7.155:9099/cd/subscribe/add/num

+ 6 - 12
zhongzheng-admin/src/main/java/com/zhongzheng/controller/alioss/OssController.java

@@ -72,18 +72,12 @@ public class OssController extends BaseController {
         return AjaxResult.success("返回图片路径",result);
     }
 
-    @ApiOperation("上传file图片")
-    @PostMapping("/uploadTest")
-    public AjaxResult<String> uploadTest() throws Exception {
-        InputStream in = ossService.getStreamByObject("oss/images/avatar/114/1315/1686203595404_1371903125");
-        FileOutputStream fos = new FileOutputStream("D:\\testfile\\b.jpg");
-        byte[] b = new byte[1024];
-        while ((in.read(b)) != -1) {
-            fos.write(b);// 写入数据
-        }
-        in.close();
-        fos.close();// 保存数据
-        return AjaxResult.success("返回图片路径","");
+    @ApiOperation("上传file图片带路径")
+    @PostMapping("/uploadPath")
+    public AjaxResult<String> uploadPath(OssRequest file) throws Exception {
+        String result = ossService.uploadWithPath(file,file.getPath());
+        log.info("服务端生成签名:{}",result);
+        return AjaxResult.success("返回图片路径",result);
     }
 
 }

+ 77 - 3
zhongzheng-admin/src/main/java/com/zhongzheng/controller/common/CommonController.java

@@ -24,7 +24,13 @@ import com.zhongzheng.common.utils.poi.ExcelUtil;
 import com.zhongzheng.framework.config.ServerConfig;
 import com.zhongzheng.framework.web.service.WxLoginService;
 import com.zhongzheng.modules.activity.vo.ActivityGoodsPriceVo;
+import com.zhongzheng.modules.alioss.bo.OssRequest;
+import com.zhongzheng.modules.alioss.service.OssService;
+import com.zhongzheng.modules.bank.service.IExamService;
+import com.zhongzheng.modules.bank.service.IQuestionOtherService;
 import com.zhongzheng.modules.base.bo.ConfigQueryBo;
+import com.zhongzheng.modules.course.bo.ExternalQuestionBo;
+import com.zhongzheng.modules.course.vo.ExternalQuestionVo;
 import com.zhongzheng.modules.distribution.bo.DistributionActivityGoodsQueryBo;
 import com.zhongzheng.modules.distribution.bo.DistributionCashWithdrawalPayBo;
 import com.zhongzheng.modules.distribution.service.IDistributionActivityGoodsService;
@@ -45,6 +51,7 @@ import com.zhongzheng.modules.goods.service.IGoodsService;
 import com.zhongzheng.modules.goods.vo.GoodsJzsVo;
 import com.zhongzheng.modules.goods.vo.GoodsVo;
 import com.zhongzheng.modules.goods.vo.UserGoodsListVo;
+import com.zhongzheng.modules.goods.vo.UserOrderGoodsListVo;
 import com.zhongzheng.modules.grade.bo.*;
 import com.zhongzheng.modules.grade.service.IClassGradeService;
 import com.zhongzheng.modules.grade.service.IClassGradeUserService;
@@ -146,6 +153,14 @@ public class CommonController extends BaseController {
     @Autowired
     private IClassGradeUserService iClassGradeUserService;
 
+    @Autowired
+    private IExamService iExamService;
+
+    @Autowired
+    private IQuestionOtherService iQuestionOtherService;
+    @Autowired
+    private OssService ossService;
+
     /**
      * 通用下载请求
      *
@@ -264,6 +279,34 @@ public class CommonController extends BaseController {
         return AjaxResult.success(voList);
     }
 
+    @ApiOperation("旧系统获取用户订单商品信息")
+    @PostMapping("common/get/orderGoods")
+    public AjaxResult getUserOrderGoods(@RequestBody UserGoodsListBo bo) {
+        if (!ToolsUtils.checkSignFromOldSys(bo.getStamp().toString(), bo.getSign())) {
+            return AjaxResult.error("签名错误");
+        }
+        List<UserOrderGoodsListVo> voList = iGoodsService.getUserOrderGoods(bo);
+
+        return AjaxResult.success(voList);
+    }
+
+    @ApiOperation("校验用户是否有账号")
+    @PostMapping("common/check/account")
+    public AjaxResult checkUserAccount(@RequestBody UserGoodsListBo bo) {
+        if (!ToolsUtils.checkSignFromOldSys(bo.getStamp().toString(), bo.getSign())) {
+            return AjaxResult.error("签名错误");
+        }
+        Map<String,String> url = iGoodsService.checkUserAccount(bo);
+        return AjaxResult.success(url);
+    }
+
+    @ApiOperation("七大员学员资料批量变更")
+    @PostMapping("common/apply/user/profile")
+    public AjaxResult updateExamUserProfile(MultipartFile file) {
+        iExamApplyService.updateExamUserProfile(file);
+        return AjaxResult.success();
+    }
+
     @ApiOperation("七大员新考结果")
     @PostMapping("common/apply/result")
     public AjaxResult examApplyResult(@RequestBody ExamApplyResultBo bo) {
@@ -285,22 +328,43 @@ public class CommonController extends BaseController {
         return AjaxResult.success();
     }
 
+    @ApiOperation("七大员考试预约取消")
+    @PostMapping("common/apply/subscribe/cancel")
+    public AjaxResult examApplySubscribeCancel(@RequestBody ExamApplySubscribeBo bo) {
+        if (!ToolsUtils.checkSignFromOldSys(bo.getStamp().toString(), bo.getSign())) {
+            return AjaxResult.error("签名错误");
+        }
+        ServletUtils.getResponse().setHeader("TenantId",bo.getTenantId().toString());
+        iUserSubscribeService.examApplySubscribeCancel(bo);
+        return AjaxResult.success();
+    }
+
 
     @ApiOperation("学员学时图片修改")
     @PostMapping("common/student/image/update")
     public AjaxResult updateStudentImage(@RequestBody UpdateStudentImageBo bo) {
+        if (!ToolsUtils.checkSignFromOldSys(bo.getStamp().toString(), bo.getSign())) {
+            return AjaxResult.error("签名错误");
+        }
+        String base = iUserSubscribeService.updateStudentImage(bo);
+        return AjaxResult.success(base);
+    }
+
+    @ApiOperation("获取外部题库商品(山东题库)")
+    @PostMapping("common/external/question")
+    public AjaxResult getExternalQuestion(@RequestBody ExternalQuestionBo bo) {
 //        if (!ToolsUtils.checkSignFromOldSys(bo.getStamp().toString(), bo.getSign())) {
 //            return AjaxResult.error("签名错误");
 //        }
-        String base = iUserSubscribeService.updateStudentImage(bo);
-        return AjaxResult.success(base);
+        List<ExternalQuestionVo> questionVos = iGoodsService.getExternalQuestion(bo);
+        return AjaxResult.success(questionVos);
     }
 
 
     @ApiOperation("获取某场考试信息")
     @PostMapping("common/apply/detail")
     public AjaxResult examApplyDetail(@RequestBody ExamApplyDetailBo bo) {
-        List<ExamApplyDetailVo> voList = iExamApplyService.examApplyDetail(bo);
+        ExamApplyDetailVo voList = iExamApplyService.examApplyDetail(bo);
         return AjaxResult.success(voList);
     }
 
@@ -665,6 +729,16 @@ public class CommonController extends BaseController {
         return AjaxResult.success(iClassGradeUserService.pushOfficialPeriodMore(list));
     }
 
+    @ApiOperation("测试获取山东题库")
+    @PreAuthorize("@ss.hasPermi('system:withdrawal:add')")
+    @Log(title = "测试获取山东题库", businessType = BusinessType.INSERT)
+    @GetMapping("/common/free/getShanDongExam")
+    public AjaxResult getShanDongExam(GoodsQueryBo bo) {
+        iQuestionOtherService.queryById(3L);
+        return AjaxResult.success();
+    }
+
+
     @ApiOperation("旧系统post请求")
     @PostMapping("/common/free/clientPost")
     public AjaxResult<Void> clientPost(@RequestBody ClientPostAddBo bo) {

+ 14 - 0
zhongzheng-admin/src/main/java/com/zhongzheng/controller/exam/ExamApplyController.java

@@ -10,6 +10,7 @@ import com.zhongzheng.common.core.page.TableDataInfo;
 import com.zhongzheng.common.enums.BusinessType;
 import com.zhongzheng.common.exception.CustomException;
 import com.zhongzheng.common.utils.poi.EasyPoiUtil;
+import com.zhongzheng.modules.base.bo.UserProfileQueryBo;
 import com.zhongzheng.modules.exam.bo.*;
 import com.zhongzheng.modules.exam.service.IExamApplyGoodsService;
 import com.zhongzheng.modules.exam.service.IExamApplyService;
@@ -266,4 +267,17 @@ public class ExamApplyController extends BaseController {
         return AjaxResult.success(vo);
     }
 
+    @ApiOperation("七大员学员资料批量变更")
+    @PostMapping("/user/profile")
+    public AjaxResult updateExamUserProfile(MultipartFile file) {
+        iExamApplyService.updateExamUserProfile(file);
+        return AjaxResult.success();
+    }
+
+    @ApiOperation("七大员学员资料导出")
+    @PostMapping("/user/profile/export")
+    public AjaxResult examUserProfileExport(@RequestBody UserProfileQueryBo bo) {
+        return AjaxResult.success(iExamApplyService.examUserProfileExport(bo));
+    }
+
 }

+ 20 - 0
zhongzheng-admin/src/main/java/com/zhongzheng/controller/grade/ClassGradeController.java

@@ -12,6 +12,8 @@ import cn.afterturn.easypoi.excel.entity.ExportParams;
 import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.lang.Validator;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.github.pagehelper.PageInfo;
 import com.zhongzheng.common.core.domain.entity.SysRole;
 import com.zhongzheng.common.core.redis.RedisCache;
@@ -23,6 +25,7 @@ import com.zhongzheng.modules.base.vo.UserProfileExportGaiVo;
 import com.zhongzheng.modules.goods.service.IGoodsService;
 import com.zhongzheng.modules.goods.vo.GoodsVo;
 import com.zhongzheng.modules.grade.bo.*;
+import com.zhongzheng.modules.grade.domain.ClassGrade;
 import com.zhongzheng.modules.grade.service.*;
 import com.zhongzheng.modules.grade.vo.*;
 import com.zhongzheng.modules.user.entity.ClientLoginUser;
@@ -120,6 +123,17 @@ public class ClassGradeController extends BaseController {
         return getDataTable(list);
     }
 
+    /**
+     * 查询班级列表(新)
+     */
+    @ApiOperation("查询班级列表(新)")
+    @GetMapping("/search/list")
+    public TableDataInfo<ClassGradeVo> searchGradeList(ClassGradeQueryBo bo) {
+        startPage();
+        List<ClassGradeVo> list = iClassGradeService.searchGradeList(bo);
+        return getDataTable(list);
+    }
+
     /**
      * 查询其他平台班级详情
      */
@@ -182,6 +196,12 @@ public class ClassGradeController extends BaseController {
     @PreAuthorize("@ss.hasPermi('grade:grade:list')")
     @GetMapping("/listGrade")
     public TableDataInfo<ClassGradeStudentVo> listGrade(ClassGradeUserQueryBo bo) {
+        if (ObjectUtils.isNotNull(bo.getGradeId())){
+            ClassGrade gradeGrade = iClassGradeService.getById(bo.getGradeId());
+            if (StringUtils.isNotBlank(gradeGrade.getSevenCode())){
+                bo.setSevenCode(gradeGrade.getSevenCode());
+            }
+        }
         startPage();
         List<ClassGradeStudentVo> list = iClassGradeService.listGrade(bo);
         return getDataTable(list);

+ 48 - 5
zhongzheng-admin/src/main/java/com/zhongzheng/controller/order/OrderController.java

@@ -5,26 +5,28 @@ import java.time.format.DateTimeFormatter;
 import java.util.*;
 
 import cn.hutool.core.lang.Validator;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.zhongzheng.common.core.domain.model.LoginUser;
-import com.zhongzheng.common.utils.DateUtils;
 import com.zhongzheng.common.utils.SecurityUtils;
 import com.zhongzheng.common.utils.ServletUtils;
 import com.zhongzheng.framework.web.service.TokenService;
-import com.zhongzheng.modules.grade.vo.ClassPeriodStudentExportAllVo;
+import com.zhongzheng.modules.course.bo.QuestionOpenBo;
+import com.zhongzheng.modules.goods.bo.QuestionOpenImportBo;
+import com.zhongzheng.modules.goods.vo.QuestionOpenImportVo;
 import com.zhongzheng.modules.order.bo.*;
 import com.zhongzheng.modules.order.service.IOrderGoodsService;
 import com.zhongzheng.modules.order.service.IOrderService;
 import com.zhongzheng.modules.order.vo.OrderGoodsVo;
 import com.zhongzheng.modules.order.vo.OrderListVo;
 import com.zhongzheng.modules.order.vo.OrderVo;
-import com.zhongzheng.modules.user.bo.UserSubscribeExportBo;
+import com.zhongzheng.modules.user.domain.UserSubscribe;
+import com.zhongzheng.modules.user.service.IUserSubscribeService;
 import lombok.RequiredArgsConstructor;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -37,6 +39,7 @@ import com.zhongzheng.common.utils.poi.ExcelUtil;
 import com.zhongzheng.common.core.page.TableDataInfo;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * 订单Controller
@@ -54,6 +57,8 @@ public class OrderController extends BaseController {
 
     private final IOrderGoodsService iOrderGoodsService;
 
+    private final IUserSubscribeService iUserSubscribeService;
+
     private final TokenService tokenService;
 
     /**
@@ -146,6 +151,19 @@ public class OrderController extends BaseController {
     @PostMapping("/inputOrder")
     public AjaxResult addInputOrder(@RequestBody OrderAddBo bo) {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        if (ObjectUtils.isNotNull(bo.getOpenQuestionSign()) && bo.getOpenQuestionSign() == 1){
+            //新B端外部题库开通
+            QuestionOpenBo questionOpenBo = new QuestionOpenBo();
+            questionOpenBo.setCreateSysUserId(loginUser.getUser().getUserId());
+            questionOpenBo.setCreateBy(SecurityUtils.getUsername());
+            questionOpenBo.setGoodsId(bo.getGoodsList().get(0).getGoodsId());
+            UserSubscribe userSubscribe = iUserSubscribeService.getOne(new LambdaQueryWrapper<UserSubscribe>()
+                    .eq(UserSubscribe::getUserId, bo.getUserId())
+                    .eq(UserSubscribe::getOrderGoodsId, bo.getSubOrderGoodsId())
+                    .last("limit 1"));
+            questionOpenBo.setUserSubscribeIds(Arrays.asList(userSubscribe.getSubscribeId()));
+            return AjaxResult.success(iOrderService.questionGoodsOpen(questionOpenBo));
+        }
         if(Validator.isEmpty(bo.getCreateUsername())){
             bo.setCreateSysUserId(loginUser.getUser().getUserId());
             bo.setCreateBy(SecurityUtils.getUsername());
@@ -170,4 +188,29 @@ public class OrderController extends BaseController {
         return AjaxResult.success(map);
     }
 
+    /**
+     * 七大员题库商品开通
+     */
+    @ApiOperation("七大员题库商品开通")
+    @PostMapping("/question/open")
+    public AjaxResult<Void> questionGoodsOpen(@RequestBody QuestionOpenBo bo) {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        bo.setCreateSysUserId(loginUser.getUser().getUserId());
+        bo.setCreateBy(SecurityUtils.getUsername());
+        return toAjax(iOrderService.questionGoodsOpen(bo) ? 1 : 0);
+    }
+
+    /**
+     * 七大员题库商品导入开通
+     */
+    @ApiOperation("七大员题库商品导入开通")
+    @PostMapping("/question/open/import")
+    public AjaxResult<QuestionOpenImportVo> questionGoodsOpenImport(MultipartFile file)throws Exception {
+        ExcelUtil<QuestionOpenImportBo> util = new ExcelUtil<>(QuestionOpenImportBo.class);
+        List<QuestionOpenImportBo> importBoList = util.importExcel(file.getInputStream());
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        return AjaxResult.success(iOrderService.questionGoodsOpenImport(importBoList,loginUser.getUser().getUserId(),SecurityUtils.getUsername()));
+    }
+
+
 }

+ 9 - 0
zhongzheng-admin/src/main/resources/application-dev.yml

@@ -175,3 +175,12 @@ invoice:
     host: http://192.168.1.222:7077/sys/common/openMplatform/log
 
 liveHost: http://192.168.1.222:6009
+
+exam:
+    applySave: http://192.168.1.7:9099/cd/exam/save
+    applyUpdate: http://192.168.1.7:9099/cd/exam/update
+    applyDelete: http://192.168.1.7:9099/cd/exam/delete
+    subscribeSave: http://192.168.1.7:9099/cd/subscribe/save
+    subscribeSaveExam: http://192.168.1.7:9099/cd/subscribe/save/exam
+    subscribeUpdateExam: http://192.168.1.7:9099/cd/subscribe/update/exam
+    subscribeAddExamNum: http://192.168.1.7:9099/cd/subscribe/add/num

+ 18 - 6
zhongzheng-admin/src/main/resources/application-pre.yml

@@ -70,16 +70,16 @@ spring:
                 max-wait: -1ms
 aliyun:
     oss:
-        endpoint: https://file-dev.xyyxt.net # oss对外服务的访问域名
+        endpoint: https://file.xyyxt.net # oss对外服务的访问域名
         accessKeyId: LTAIgC8O2WUXvXuR  # 访问身份验证中用到用户标识
         accessKeySecret: 1yyCazuT1M6MruBXzgFjP0p9gdMlwX # 用户用于加密签名字符串和oss用来验证签名字符串的密钥
-        bucketName: zhongzheng-test # oss的存储空间
+        bucketName: zhongzheng-prod # oss的存储空间
         policy:
             expire: 30 # 签名有效期(S)
         maxSize: 100 # 上传文件大小(M)
-        callback: http://120.79.166.78:19004/aliyun/oss/callback # 文件上传成功后的回调地址
+        callback: https://cloud.xyyxt.net/aliyun/oss/callback # 文件上传成功后的回调地址
         dir:
-            prefix: oss/images/ # 上传文件夹路径前缀 `
+            prefix: oss/images/ # 上传文件夹路径前缀 ` `
 
 poliv:
     token:
@@ -140,8 +140,8 @@ officialPush:
     periodPath: https://jypt-dev.gdcic.net/organjxjy/XueshiShenqing
     infoAccount: peixunjigou
     token: 0ca175b9c0f726a831d895e26933246
-    sevenInfoPath: http://sgry-dev.gdcic.net/organjxjy/ShangBaoMingdan
-    sevenPeriodPath: http://sgry-dev.gdcic.net/organjxjy/XueshiShenqing
+    sevenInfoPath: http://sgry.gdcic.net/organjxjy/ShangBaoMingdan
+    sevenPeriodPath: http://sgry.gdcic.net/organjxjy/XueshiShenqing
 
 distributionOldPay:
     host: http://test.jqbao.net/System/BussinessApi/AddRedPackData
@@ -172,3 +172,15 @@ oldSys:
 
 invoice:
     host: http://192.168.1.222:8077/sys/common/openMplatform/log
+
+liveHost: http://192.168.1.222:6009
+
+exam:
+    applySave: http://192.168.1.7:9099/cd/exam/save
+    applyUpdate: http://192.168.1.7:9099/cd/exam/update
+    applyDelete: http://192.168.1.7:9099/cd/exam/delete
+    subscribeSave: http://192.168.1.7:9099/cd/subscribe/save
+    subscribeSaveExam: http://192.168.1.7:9099/cd/subscribe/save/exam
+    subscribeUpdateExam: http://192.168.1.7:9099/cd/subscribe/update/exam
+    subscribeAddExamNum: http://192.168.1.7:9099/cd/subscribe/add/num
+

+ 9 - 0
zhongzheng-admin/src/main/resources/application-prod.yml

@@ -174,3 +174,12 @@ invoice:
     host: https://ptapi.gdzzkj.net/sys/common/openMplatform/log
 
 liveHost: https://sso.xyyxt.net
+
+exam:
+    applySave: http://39.108.7.155:9099/cd/exam/save
+    applyUpdate: http://39.108.7.155:9099/cd/exam/update
+    applyDelete: http://39.108.7.155:9099/cd/exam/delete
+    subscribeSave: http://39.108.7.155:9099/cd/subscribe/save
+    subscribeSaveExam: http://39.108.7.155:9099/cd/subscribe/save/exam
+    subscribeUpdateExam: http://39.108.7.155:9099/cd/subscribe/update/exam
+    subscribeAddExamNum: http://39.108.7.155:9099/cd/subscribe/add/num

+ 1 - 1
zhongzheng-admin/src/main/resources/templates/wordPhone.ftl

@@ -49,7 +49,7 @@
 		<table border="1" class="tabsty">
 			<tr>
 				<td class="strong">姓 名</td>
-				<td>${name}</td>
+				<td>${username}</td>
 				<td class="strong">性别</td>
 				<td>${s}</td>
 				<td class="strong">培训岗位</td>

+ 12 - 2
zhongzheng-api/src/main/java/com/zhongzheng/controller/base/ProfileTpController.java

@@ -12,6 +12,7 @@ import com.zhongzheng.modules.base.service.IProfileTpService;
 import com.zhongzheng.modules.base.service.IUserProfileService;
 import com.zhongzheng.modules.base.vo.ProfileTpVo;
 import com.zhongzheng.modules.base.vo.UserProfileVo;
+import com.zhongzheng.modules.user.bo.CommitmentSealBo;
 import com.zhongzheng.modules.user.entity.ClientLoginUser;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -20,6 +21,7 @@ import net.polyv.common.v1.util.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.Arrays;
 import java.util.List;
@@ -63,8 +65,16 @@ public class ProfileTpController extends BaseController {
         return getDataTable(list);
     }
 
-
-
+    /**
+     * 学员上传承诺书
+     */
+    @ApiOperation("学员上传承诺书")
+    @PostMapping("/commitment/upload")
+    public AjaxResult<Void> commitmentSealUpload(@RequestBody CommitmentSealBo bo) {
+        ClientLoginUser loginUser = wxTokenService.getLoginUser(ServletUtils.getRequest());
+        bo.setUserId(loginUser.getUser().getUserId());
+        return toAjax(iProfileTpService.commitmentSealUpload(bo) ? 1:0 );
+    }
 
 
     /**

+ 40 - 5
zhongzheng-api/src/main/java/com/zhongzheng/controller/course/CourseController.java

@@ -9,15 +9,14 @@ import com.zhongzheng.modules.course.bo.*;
 import com.zhongzheng.modules.course.service.*;
 import com.zhongzheng.modules.course.vo.*;
 import com.zhongzheng.modules.goods.vo.GoodsUserVo;
+import com.zhongzheng.modules.order.bo.SpecialQuestionBo;
+import com.zhongzheng.modules.order.vo.SpecialQuestionVo;
 import com.zhongzheng.modules.user.entity.ClientLoginUser;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 
@@ -70,11 +69,47 @@ public class CourseController extends BaseController {
     public TableDataInfo<GoodsUserVo> goodsList(CourseQueryBo bo) {
         ClientLoginUser loginUser = wxTokenService.getLoginUser(ServletUtils.getRequest());
         bo.setUserId(loginUser.getUser().getUserId());
+//        startPage();
+//        List<GoodsUserVo> list = iCourseService.goodsList(bo);
+//        return getDataTable(list);
+        return iCourseService.goodsListPage(bo);
+    }
+
+    /**
+     * 查询课程列表
+     */
+    @ApiOperation("查询用户拥有的题库列表(山东题库)")
+    @GetMapping("/special/question/list")
+    public TableDataInfo<SpecialQuestionVo> getSpecialQuestionList(SpecialQuestionBo bo) {
+        ClientLoginUser loginUser = wxTokenService.getLoginUser(ServletUtils.getRequest());
+        bo.setUserId(loginUser.getUser().getUserId());
         startPage();
-        List<GoodsUserVo> list = iCourseService.goodsList(bo);
+        List<SpecialQuestionVo> list = iCourseService.getSpecialQuestionList(bo);
         return getDataTable(list);
     }
 
+    /**
+     * 获取题库H5跳转码
+     */
+    @ApiOperation("获取题库H5跳转码")
+    @GetMapping("/special/question/skip/code")
+    public AjaxResult getSpecialQuestionSkipCode() {
+        ClientLoginUser loginUser = wxTokenService.getLoginUser(ServletUtils.getRequest());
+        return AjaxResult.success(iCourseService.getSpecialQuestionSkipCode(loginUser.getUser().getUserId()));
+    }
+
+    /**
+     * 查询用户是否拥有(山东题库)
+     */
+    @ApiOperation("查询用户是否拥有(山东题库)")
+    @GetMapping("/special/question/count")
+    public AjaxResult<Long> getSpecialQuestionCount(SpecialQuestionBo bo) {
+        ClientLoginUser loginUser = wxTokenService.getLoginUser(ServletUtils.getRequest());
+        bo.setUserId(loginUser.getUser().getUserId());
+        Long num = iCourseService.getSpecialQuestionCount(bo);
+        return AjaxResult.success(num);
+    }
+
     @ApiOperation("查询用户拥有的讲义商品")
     @GetMapping("/goodsHandoutsList")
     public TableDataInfo<GoodsUserVo> goodsHandoutsList(CourseQueryBo bo) {

+ 1 - 1
zhongzheng-api/src/main/java/com/zhongzheng/controller/exam/ExamApplyController.java

@@ -122,7 +122,7 @@ public class ExamApplyController extends BaseController {
      */
     @ApiOperation("新增用户预约考试")
     @Log(title = "用户预约考试", businessType = BusinessType.INSERT)
-    @PostMapping("save")
+    @PostMapping("/save")
     public AjaxResult<Long> saveApply(@RequestBody UserSubscribeAddBo bo) throws ParseException {
         ClientLoginUser loginUser = wxTokenService.getLoginUser(ServletUtils.getRequest());
         bo.setUserId(loginUser.getUser().getUserId());

+ 64 - 0
zhongzheng-api/src/main/java/com/zhongzheng/controller/goods/GoodsQuestionRelExamController.java

@@ -0,0 +1,64 @@
+package com.zhongzheng.controller.goods;
+
+import java.util.List;
+import java.util.Arrays;
+
+import com.zhongzheng.common.core.page.TableDataInfo;
+import com.zhongzheng.common.utils.ServletUtils;
+import com.zhongzheng.framework.web.service.WxTokenService;
+import com.zhongzheng.modules.goods.bo.GoodsQuestionRelExamAddBo;
+import com.zhongzheng.modules.goods.bo.GoodsQuestionRelExamEditBo;
+import com.zhongzheng.modules.goods.bo.GoodsQuestionRelExamQueryBo;
+import com.zhongzheng.modules.goods.service.IGoodsQuestionRelExamService;
+import com.zhongzheng.modules.goods.vo.GoodsQuestionRelExamVo;
+import com.zhongzheng.modules.user.entity.ClientLoginUser;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zhongzheng.common.annotation.Log;
+import com.zhongzheng.common.core.controller.BaseController;
+import com.zhongzheng.common.core.domain.AjaxResult;
+import com.zhongzheng.common.enums.BusinessType;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * 三方题库试卷记录Controller
+ *
+ * @author ruoyi
+ * @date 2023-08-14
+ */
+@Api(value = "三方题库试卷记录控制器", tags = {"三方题库试卷记录管理"})
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@RestController
+@RequestMapping("/goods/rel/exam")
+public class GoodsQuestionRelExamController extends BaseController {
+
+    private final IGoodsQuestionRelExamService iGoodsQuestionRelExamService;
+
+    private final WxTokenService wxTokenService;
+
+
+    /**
+     * 新增三方题库试卷记录
+     */
+    @ApiOperation("获取三方题库试卷ID")
+    @PreAuthorize("@ss.hasPermi('system:exam:add')")
+    @Log(title = "获取三方题库试卷ID", businessType = BusinessType.INSERT)
+    @PostMapping()
+    public AjaxResult<GoodsQuestionRelExamVo> add(@RequestBody GoodsQuestionRelExamAddBo bo) {
+        ClientLoginUser loginUser = wxTokenService.getLoginUser(ServletUtils.getRequest());
+        bo.setUserId(loginUser.getUser().getUserId());
+        return AjaxResult.success(iGoodsQuestionRelExamService.makeExam(bo));
+    }
+
+
+}

+ 14 - 0
zhongzheng-api/src/main/java/com/zhongzheng/controller/inform/InformUserController.java

@@ -61,6 +61,20 @@ public class InformUserController extends BaseController {
         return getDataTable(list);
     }
 
+    /**
+     * 查询通知绑定学员列表
+     */
+    @ApiOperation("学员通知消息数量")
+    @GetMapping("/count")
+    public AjaxResult<Integer> getInformUserCount(InformUserQueryBo bo) {
+        ClientLoginUser loginUser = wxTokenService.getLoginUser(ServletUtils.getRequest());
+        bo.setUserId(loginUser.getUser().getUserId());
+        startPage();
+        bo.setStatus(1);
+        Integer count = iInformUserService.getInformUserCount(bo);
+        return AjaxResult.success(count);
+    }
+
 
     /**
      * 获取通知绑定学员详细信息

+ 13 - 0
zhongzheng-api/src/main/java/com/zhongzheng/controller/user/UserController.java

@@ -20,6 +20,7 @@ import com.zhongzheng.modules.user.service.IUserService;
 import com.zhongzheng.modules.user.service.IUserVisitLogService;
 import com.zhongzheng.modules.user.service.IUserWxFollowService;
 import com.zhongzheng.modules.user.vo.UserVo;
+import com.zhongzheng.modules.wx.bo.WxIdBody;
 import com.zhongzheng.modules.wx.bo.WxLoginBody;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -185,6 +186,8 @@ public class UserController extends BaseController {
         return AjaxResult.success();
     }
 
+
+
     @ApiOperation("检查是否绑定公众号")
     @PreAuthorize("@ss.hasPermi('system:user:list')")
     @GetMapping("/checkBindGzh")
@@ -195,6 +198,16 @@ public class UserController extends BaseController {
         return AjaxResult.success("成功",userVo.getGzhOpenId());
     }
 
+    @ApiOperation("检查账号是否绑定该openid")
+    @PreAuthorize("@ss.hasPermi('system:user:list')")
+    @PostMapping("/checkBindOpenId")
+    public AjaxResult<Boolean> checkBindOpenId(@RequestBody WxIdBody loginBody)
+    {
+        ClientLoginUser loginUser = wxTokenService.getLoginUser(ServletUtils.getRequest());
+        loginBody.setUserId(loginUser.getUser().getUserId());
+        return AjaxResult.success("成功",wxLoginService.checkBindOpenId(loginBody));
+    }
+
     @ApiOperation("把其他用户踢下线")
     @Log(title = "把其他用户踢下线", businessType = BusinessType.UPDATE)
     @PostMapping("/offline")

+ 5 - 2
zhongzheng-api/src/main/java/com/zhongzheng/controller/user/UserStudyRecordController.java

@@ -3,6 +3,7 @@ package com.zhongzheng.controller.user;
 import java.util.List;
 import java.util.Arrays;
 
+import cn.hutool.core.lang.Validator;
 import com.zhongzheng.common.utils.ServletUtils;
 import com.zhongzheng.framework.web.service.WxTokenService;
 import com.zhongzheng.modules.course.bo.CourseMenuQueryBo;
@@ -97,8 +98,10 @@ public class UserStudyRecordController extends BaseController {
     @Log(title = "用户学习记录", businessType = BusinessType.INSERT)
     @PostMapping()
     public AjaxResult<Integer> add(@RequestBody UserStudyRecordAddBo bo) {
-        ClientLoginUser loginUser = wxTokenService.getLoginUser(ServletUtils.getRequest());
-        bo.setUserId(loginUser.getUser().getUserId());
+        if(Validator.isEmpty(bo.getUserId())){
+            ClientLoginUser loginUser = wxTokenService.getLoginUser(ServletUtils.getRequest());
+            bo.setUserId(loginUser.getUser().getUserId());
+        }
         return AjaxResult.success(iUserStudyRecordService.insertByAddBo(bo));
     }
 

+ 24 - 5
zhongzheng-api/src/main/java/com/zhongzheng/controller/wx/WxLoginController.java

@@ -86,7 +86,7 @@ public class WxLoginController
      * @param loginBody 登录信息
      * @return 结果
      */
-    @ApiOperation("小程序微信登录")
+    @ApiOperation("小程序通过手机授权微信登录")
     @PostMapping("/app/common/bindLogin")
     public AjaxResult bindLogin(@RequestBody WxLoginBody loginBody)
     {
@@ -94,6 +94,14 @@ public class WxLoginController
         return AjaxResult.success(map);
     }
 
+    @ApiOperation("小程序通过openid微信登录")
+    @PostMapping("/app/common/openIdLogin")
+    public AjaxResult openIdLogin(@RequestBody WxLoginBody loginBody)
+    {
+        Map<String,Object> map = wxLoginService.openIdLogin(loginBody);
+        return AjaxResult.success(map);
+    }
+
     @ApiOperation("获取用户小程序openid")
     @PostMapping("/wx/getOpenid")
     public AjaxResult<Void> getOpenid(@RequestBody WxLoginBody loginBody)
@@ -103,18 +111,29 @@ public class WxLoginController
         return AjaxResult.success(openId);
     }
 
+    @ApiOperation("考前获取用户小程序openid")
+    @PostMapping("/app/common/wx/exam/getOpenid")
+    public AjaxResult<Map<String,String>> getExamOpenid(@RequestBody WxLoginBody loginBody)
+    {
+        Map<String,String> map = wxLoginService.getExamWxOpenId(loginBody);
+        return AjaxResult.success(map);
+    }
+
+    @ApiOperation("考前获取公众号openid")
+    @PostMapping("/app/common/wx/gzh_bind")
+    public AjaxResult wx_gzh_bind(@RequestBody WxLoginBody loginBody)
+    {
+        return AjaxResult.success(wxLoginService.bindGzhUnionIdUser(loginBody));
+    }
+
     @ApiOperation("小程序校验PC登录二维码")
     @PostMapping("/scan_login_check")
     public AjaxResult scanLoginCheck(@RequestBody WxLoginBody loginBody)
     {
-        log.info("loginBody:"+ JSON.toJSONString(loginBody));
         ClientLoginUser loginUser = wxTokenService.getLoginUser(ServletUtils.getRequest());
-        log.info("loginUser:"+ JSON.toJSONString(loginUser));
         String scanCode = loginBody.getScanCode();
         String key = "SCAN_LOGIN_"+scanCode;
-        log.info("key:"+ key);
         String keyStatus = "SCAN_LOGIN_STATUS_"+scanCode; //0未扫码 1已扫码 2已登录
-        log.info("keyStatus:"+ keyStatus);
         Long status = redisCache.getCacheObject(keyStatus);
         if(Validator.isNotEmpty(status)&&status.equals(1L)){
             redisCache.setCacheObject(key, loginUser.getUser().getUserId(),60, TimeUnit.SECONDS);//60秒锁定

+ 9 - 0
zhongzheng-api/src/main/resources/application-dev.yml

@@ -177,3 +177,12 @@ invoice:
     host: http://192.168.1.222:7077/sys/common/openMplatform/log
 
 liveHost: http://192.168.1.222:6009
+
+exam:
+    applySave: http://192.168.1.7:9099/cd/exam/save
+    applyUpdate: http://192.168.1.7:9099/cd/exam/update
+    applyDelete: http://192.168.1.7:9099/cd/exam/delete
+    subscribeSave: http://192.168.1.7:9099/cd/subscribe/save
+    subscribeSaveExam: http://192.168.1.7:9099/cd/subscribe/save/exam
+    subscribeUpdateExam: http://192.168.1.7:9099/cd/subscribe/update/exam
+    subscribeAddExamNum: http://192.168.1.7:9099/cd/subscribe/add/num

+ 14 - 3
zhongzheng-api/src/main/resources/application-pre.yml

@@ -70,14 +70,14 @@ spring:
                 max-wait: -1ms
 aliyun:
     oss:
-        endpoint: https://file-dev.xyyxt.net # oss对外服务的访问域名
+        endpoint: https://file.xyyxt.net # oss对外服务的访问域名
         accessKeyId: LTAIgC8O2WUXvXuR  # 访问身份验证中用到用户标识
         accessKeySecret: 1yyCazuT1M6MruBXzgFjP0p9gdMlwX # 用户用于加密签名字符串和oss用来验证签名字符串的密钥
-        bucketName: zhongzheng-test # oss的存储空间
+        bucketName: zhongzheng-prod # oss的存储空间
         policy:
             expire: 30 # 签名有效期(S)
         maxSize: 100 # 上传文件大小(M)
-        callback: http://120.79.166.78:19004/aliyun/oss/callback # 文件上传成功后的回调地址
+        callback: https://cloud.xyyxt.net/aliyun/oss/callback # 文件上传成功后的回调地址
         dir:
             prefix: oss/images/ # 上传文件夹路径前缀 `
 poliv:
@@ -172,3 +172,14 @@ oldSys:
 
 invoice:
     host: http://192.168.1.222:8077/sys/common/openMplatform/log
+
+liveHost: http://192.168.1.222:6009
+
+exam:
+    applySave: http://192.168.1.7:9099/cd/exam/save
+    applyUpdate: http://192.168.1.7:9099/cd/exam/update
+    applyDelete: http://192.168.1.7:9099/cd/exam/delete
+    subscribeSave: http://192.168.1.7:9099/cd/subscribe/save
+    subscribeSaveExam: http://192.168.1.7:9099/cd/subscribe/save/exam
+    subscribeUpdateExam: http://192.168.1.7:9099/cd/subscribe/update/exam
+    subscribeAddExamNum: http://192.168.1.7:9099/cd/subscribe/add/num

+ 9 - 0
zhongzheng-api/src/main/resources/application-prod.yml

@@ -186,3 +186,12 @@ invoice:
     host: https://ptapi.gdzzkj.net/sys/common/openMplatform/log
 
 liveHost: https://sso.xyyxt.net
+
+exam:
+    applySave: http://39.108.7.155:9099/cd/exam/save
+    applyUpdate: http://39.108.7.155:9099/cd/exam/update
+    applyDelete: http://39.108.7.155:9099/cd/exam/delete
+    subscribeSave: http://39.108.7.155:9099/cd/subscribe/save
+    subscribeSaveExam: http://39.108.7.155:9099/cd/subscribe/save/exam
+    subscribeUpdateExam: http://39.108.7.155:9099/cd/subscribe/update/exam
+    subscribeAddExamNum: http://39.108.7.155:9099/cd/subscribe/add/num

+ 1 - 1
zhongzheng-common/src/main/java/com/zhongzheng/common/core/domain/entity/SysDictData.java

@@ -71,7 +71,7 @@ public class SysDictData implements Serializable
     private String listClass;
 
     @TableField(value = "tenant_id")
-    private Long tenantId;
+    private String tenantId;
 
     /** 是否默认(Y是 N否) */
     @Excel(name = "是否默认", readConverterExp = "Y=是,N=否")

+ 22 - 0
zhongzheng-common/src/main/java/com/zhongzheng/common/utils/DateUtils.java

@@ -542,6 +542,28 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
     }
 
 
+    public static Long getAppointTime(Long millisecond, Integer day) {
+        for (Integer i = 0; i < day; i++) {
+            Long dayAfter = getDayBefore(millisecond, 1);
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(timeToDate(dayAfter));
+            int index = calendar.get(Calendar.DAY_OF_WEEK) - 1;
+            String[] weeks = new String[]{"星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
+
+            if (weeks[index].equals("星期六") || weeks[index].equals("星期天")) {
+                day += 1;
+
+            }
+            //判断当前是否为工作日
+            if (!isWorkingDay(dayAfter)) {
+                day += 1;
+            }
+            millisecond = dayAfter;
+        }
+
+        return millisecond;
+    }
+
     /**
      * 指定时间往前或往后推n天
      *

+ 30 - 0
zhongzheng-common/src/main/java/com/zhongzheng/common/utils/ToolsUtils.java

@@ -338,6 +338,36 @@ public class ToolsUtils {
         return true;
     }
 
+    public static String EncoderByMd5WithUtf(String str) {
+        String result = "";
+        MessageDigest md5 = null;
+        try {
+            md5 = MessageDigest.getInstance("MD5");
+            // 这句是关键
+            md5.update(str.getBytes("UTF-8"));
+        } catch (NoSuchAlgorithmException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (UnsupportedEncodingException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        byte b[] = md5.digest();
+        int i;
+        StringBuffer buf = new StringBuffer("");
+        for (int offset = 0; offset < b.length; offset++) {
+            i = b[offset];
+            if (i < 0)
+                i += 256;
+            if (i < 16)
+                buf.append("0");
+            buf.append(Integer.toHexString(i));
+        }
+        result = buf.toString();
+
+        return result;
+    }
+
     public static String EncoderByMd5(String str) {
         String result = "";
         MessageDigest md5 = null;

+ 122 - 0
zhongzheng-common/src/main/java/com/zhongzheng/common/utils/file/FileUtils.java

@@ -17,6 +17,7 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.*;
 import java.math.BigInteger;
 import java.net.URLEncoder;
+import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -27,6 +28,7 @@ import java.util.List;
 import java.util.UUID;
 import java.util.stream.Stream;
 import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
 import java.util.zip.ZipOutputStream;
 
 /**
@@ -444,4 +446,124 @@ public class FileUtils extends org.apache.commons.io.FileUtils
         }
     }
 
+
+    /**
+     * 解压
+     *
+     * @param inputStream zip压缩文件
+     * @param descDir 指定的解压目录
+     */
+    public static void unzipWithStream(InputStream inputStream, String descDir) {
+        if (!descDir.endsWith(File.separator)) {
+            descDir = descDir + File.separator;
+        }
+        try (ZipInputStream zipInputStream = new ZipInputStream(inputStream, Charset.forName("GBK"))) {
+            ZipEntry zipEntry;
+            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
+                String zipEntryNameStr = zipEntry.getName();
+                String zipEntryName = zipEntryNameStr;
+                if (zipEntryNameStr.contains("/")) {
+                    String str1 = zipEntryNameStr.substring(0, zipEntryNameStr.indexOf("/"));
+                    zipEntryName = zipEntryNameStr.substring(str1.length() + 1);
+                }
+                String outPath = (descDir + zipEntryName).replace("\\\\", "/");
+                File outFile = new File(outPath.substring(0, outPath.lastIndexOf('/')));
+                if (!outFile.exists()) {
+                    outFile.mkdirs();
+                }
+                if (new File(outPath).isDirectory()) {
+                    continue;
+                }
+                writeFile(outPath, zipInputStream);
+                zipInputStream.closeEntry();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new CustomException("压缩包处理异常,异常信息{}"+ e);
+        }
+    }
+
+    //将流写到文件中
+    public static void writeFile(String filePath, ZipInputStream zipInputStream) {
+        File file = new File(filePath);
+        File directory = file.getParentFile();
+        if (!directory.exists()){
+            directory.mkdirs();
+        }
+        try (OutputStream outputStream = new FileOutputStream(filePath)) {
+            byte[] bytes = new byte[4096];
+            int len;
+            while ((len = zipInputStream.read(bytes)) != -1) {
+                outputStream.write(bytes, 0, len);
+            }
+        } catch (IOException ex) {
+            ex.printStackTrace();
+            throw new CustomException("解压文件时,写出到文件出错!");
+        }
+    }
+
+
+    /**
+     * 打包压缩文件夹
+     *
+     * @param folderPath 文件夹路径
+     * @param zipFilePath 压缩后的文件路径
+     * @throws IOException IO异常
+     */
+    public static void zipFolder(String folderPath, String zipFilePath) throws IOException {
+        FileOutputStream fos = null;
+        ZipOutputStream zos = null;
+        try {
+            fos = new FileOutputStream(zipFilePath);
+            zos = new ZipOutputStream(fos);
+
+            // 递归遍历整个文件夹并添加到压缩包
+            addFolderToZip("", new File(folderPath), zos);
+        } finally {
+            if (zos != null) {
+                zos.close();
+            }
+            if (fos != null) {
+                fos.close();
+            }
+        }
+    }
+
+    /**
+     * 将文件夹及其中的文件递归添加到压缩流中
+     *
+     * @param parentPath 父级路径
+     * @param folder 文件夹
+     * @param zos Zip输出流
+     * @throws FileNotFoundException 文件未找到异常
+     * @throws IOException IO异常
+     */
+    private static void addFolderToZip(String parentPath, File folder, ZipOutputStream zos) throws FileNotFoundException, IOException {
+        for (File file : folder.listFiles()) {
+            if (file.isDirectory()) {
+                // 递归添加子文件夹中的文件
+                addFolderToZip(parentPath + folder.getName() + "/", file, zos);
+            } else {
+                FileInputStream fis = null;
+                try {
+                    fis = new FileInputStream(file);
+
+                    // 新建Zip条目并将输入流加入到Zip包中
+                    ZipEntry zipEntry = new ZipEntry( folder.getName() + "/" + file.getName());
+                    zos.putNextEntry(zipEntry);
+
+                    byte[] bytes = new byte[1024];
+                    int length;
+                    while ((length = fis.read(bytes)) >= 0) {
+                        zos.write(bytes, 0, length);
+                    }
+                } finally {
+                    if (fis != null) {
+                        fis.close();
+                    }
+                }
+            }
+        }
+    }
+
 }

+ 60 - 0
zhongzheng-common/src/main/java/com/zhongzheng/common/utils/poi/ExcelUtil.java

@@ -342,6 +342,55 @@ public class ExcelUtil<T>
         return sheetsList;
     }
 
+    public String userProfileExport(String filePath, String sheetName)
+    {
+        OutputStream out = null;
+        try
+        {
+            FileInputStream inputStream = new FileInputStream(filePath);
+            String filename = encodingName(sheetName);
+            out = new FileOutputStream(getAbsoluteFile(filename));
+            byte[] buffer = new byte[1024];
+            int len = 0;
+            while ((len = inputStream.read(buffer)) != -1) {
+                out.write(buffer, 0, len);
+            }
+            return filename;
+        }
+        catch (Exception e)
+        {
+            log.error("导出学员资料异常{}", e.getMessage());
+            throw new CustomException("导出学员资料异常,请联系网站管理员!");
+        }
+        finally
+        {
+
+            if (wb != null)
+            {
+                try
+                {
+                    wb.close();
+                }
+                catch (IOException e1)
+                {
+                    e1.printStackTrace();
+                }
+            }
+            if (out != null)
+            {
+                try
+                {
+                    out.close();
+                }
+                catch (IOException e1)
+                {
+                    e1.printStackTrace();
+                }
+            }
+        }
+    }
+
+
     public AjaxResult exportEasyExcel(List<Map<String, Object>> sheetsList, String sheetName)
     {
         OutputStream out = null;
@@ -387,6 +436,8 @@ public class ExcelUtil<T>
         }
     }
 
+
+
     public void exportEasyExcelStudy(List<Map<String, Object>> sheetsList,String path)
     {
         OutputStream out = null;
@@ -984,6 +1035,15 @@ public class ExcelUtil<T>
         return filename;
     }
 
+    /**
+     * 编码文件名
+     */
+    public String encodingName(String filename)
+    {
+        filename = UUID.randomUUID().toString() + "_" + filename;
+        return filename;
+    }
+
     public String encodingFilename(String filename)
     {
         filename = UUID.randomUUID().toString() + "_" + filename + ".xlsx";

+ 5 - 0
zhongzheng-framework/src/main/java/com/zhongzheng/framework/config/SecurityConfig.java

@@ -135,11 +135,16 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 .antMatchers("/profile/**").anonymous()
                 .antMatchers("/common/jzs/**").anonymous()
                 .antMatchers("/common/rollback/period").anonymous()
+                .antMatchers("/common/apply/user/profile").anonymous()
                 .antMatchers("/common/decompression").anonymous()
                 .antMatchers("/common/merge/file").anonymous()
                 .antMatchers("/common/get/goods").anonymous()
+                .antMatchers("/common/get/orderGoods").anonymous()
+                .antMatchers("/common/check/account").anonymous()
+                .antMatchers("/common/apply/user/profile").anonymous()
                 .antMatchers("/common/get/goods/studyUrl").anonymous()
                 .antMatchers("/common/apply/detail").anonymous()
+                .antMatchers("/common/external/question").anonymous()
                 .antMatchers("/common/student/image/update").anonymous()
                 .antMatchers("/common/platform/pay").anonymous()
                 .antMatchers("/common/platform/pay/handle").anonymous()

+ 2 - 1
zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/SysTenantServiceImpl.java

@@ -96,6 +96,7 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
         lqw.ne(SysTenant::getStatus, -1);
         lqw.like(StrUtil.isNotBlank(bo.getTenantName()), SysTenant::getTenantName, bo.getTenantName());
         lqw.eq(ObjectUtils.isNotNull(bo.getTenantid()),SysTenant::getTenantId, bo.getTenantid());
+        lqw.orderByDesc(SysTenant::getSort);
         return entity2Vo(this.list(lqw));
     }
 
@@ -402,7 +403,7 @@ public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant
             }
             dictData.setDictCode(null);
             dictData.setDictTypeId(dictType1.getDictId());
-            dictData.setTenantId(newTenantId);
+            dictData.setTenantId(newTenantId.toString());
         }
         iSysDictDataService.saveBatch(dictDatas);
     }

+ 1 - 1
zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/TokenService.java

@@ -98,7 +98,7 @@ public class TokenService
         {
             // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
             authentication = authenticationManager
-                    .authenticate(new UsernamePasswordAuthenticationToken("admin", "admin123"));
+                    .authenticate(new UsernamePasswordAuthenticationToken("admin", "admin159"));
         }
         catch (Exception e)
         {

+ 126 - 0
zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/WxLoginService.java

@@ -6,6 +6,7 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
@@ -29,6 +30,7 @@ import com.zhongzheng.modules.distribution.vo.SellerWxVo;
 import com.zhongzheng.modules.goods.domain.Goods;
 import com.zhongzheng.modules.goods.service.IGoodsService;
 import com.zhongzheng.modules.goods.vo.GoodsVo;
+import com.zhongzheng.modules.grade.domain.ClassGradeUser;
 import com.zhongzheng.modules.system.service.ISysConfigService;
 import com.zhongzheng.modules.user.bo.UserWxFollowAddBo;
 import com.zhongzheng.modules.user.domain.User;
@@ -270,6 +272,41 @@ public class WxLoginService implements IWxLoginService {
         return map;
     }
 
+    @Transactional(rollbackFor = Exception.class)
+    public Map<String, Object> openIdLogin(WxLoginBody loginBody) {
+        if(Validator.isEmpty(loginBody.getOpenId())){
+            throw new CustomException("openid缺失");
+        }
+        User user = iUserService.getOne(new LambdaQueryWrapper<User>().eq(User::getOpenId, loginBody.getOpenId()).last("limit 1"));
+        if (ObjectUtils.isNull(user)&&Validator.isEmpty(loginBody.getUserId())) {
+            throw new CustomException("该openid暂无绑定!",666);
+        }
+        if (Validator.isNotEmpty(loginBody.getUserId())) {
+            user = iUserService.getOne(new LambdaQueryWrapper<User>().eq(User::getUserId, loginBody.getUserId()).last("limit 1"));
+            if(Validator.isNotEmpty(user.getOpenId())){
+                throw new CustomException("该用户已绑定过openid!",667);
+            }
+            user.setOpenId(loginBody.getOpenId());
+            if(Validator.isNotEmpty(loginBody.getUnionId())){
+                user.setUnionId(loginBody.getUnionId());
+            }
+            iUserService.updateById(user);
+        }
+
+        //如果活动分销码变动
+        if (StringUtils.isNotBlank(loginBody.getShareActivityCode())){
+            user.setShareActivityCode(loginBody.getShareActivityCode());
+            iUserService.updateById(user);
+        }
+        ClientLoginUser loginUser = new ClientLoginUser();
+        loginUser.setUser(user);
+        Map<String, Object> map = new HashMap<>();
+        map.put(Constants.TOKEN, wxTokenService.createToken(loginUser));
+        map.put("user_account", loginUser.getUser().getUserAccount());
+        map.put("full_info", Validator.isEmpty(user.getIdCard()) ? false : true); //是否完善身份信息
+        return map;
+    }
+
 
     public Map<String, String> smallTel(WxLoginBody loginBody) {
         initData();
@@ -384,6 +421,30 @@ public class WxLoginService implements IWxLoginService {
         return openId;
     }
 
+    public Map<String,String> getExamWxOpenId(WxLoginBody loginBody) {
+        if(Validator.isEmpty(loginBody.getCode())){
+            throw new CustomException("code缺失");
+        }
+        initData();
+        String openId;
+
+        //每次更新最新openid
+        String param = String.format(wxAuthParam, appid, appsrcret, loginBody.getCode());
+        String resultString = HttpUtils.sendGet(wxAuthUrl, param);
+        //解析json
+        JSONObject jsonObject = (JSONObject) JSONObject.parse(resultString);
+        String session_key = String.valueOf(jsonObject.get("session_key"));
+        openId = String.valueOf(jsonObject.get("openid"));
+        String unionId = null;
+        if (jsonObject.containsKey("unionid")) { //当没绑定开放平台
+            unionId = String.valueOf(jsonObject.get("unionid"));
+        }
+        Map<String,String> map = new HashMap();
+        map.put("openId",openId);
+        map.put("unionId",unionId);
+        return map;
+    }
+
 
     //小程序获取用户信息
     public User getWxUnionIdUser(WxLoginBody loginBody) {
@@ -1271,6 +1332,71 @@ public class WxLoginService implements IWxLoginService {
         }
         return user;
     }
+
+    //获取公众号openid
+    public String bindGzhUnionIdUser(WxLoginBody loginBody) {
+        if(Validator.isEmpty(loginBody.getCode())){
+            throw new CustomException("code不能为空");
+        }
+        initData();
+        String param = String.format(gzh_wxAuthParam, gzh_appid, gzh_appsrcret, loginBody.getCode());
+        String resultString = HttpUtils.sendGet(gzh_wxAuthUrl, param);
+        //解析json
+        JSONObject jsonObject = (JSONObject) JSONObject.parse(resultString);
+        String access_token = String.valueOf(jsonObject.get("access_token"));
+        if(access_token.equals("null")){
+            throw new CustomException( String.valueOf(jsonObject.get("errmsg")));
+        }
+        String openId = String.valueOf(jsonObject.get("openid"));
+
+        String userInfoParam = String.format(gzh_wxUserInfoParam, access_token, openId);
+        String userInfoResultString = HttpUtils.sendGet(gzh_wxUserInfoUrl, userInfoParam);
+
+        //解析json
+        JSONObject jsonObject1 = (JSONObject) JSONObject.parse(userInfoResultString);
+        return openId;
+    }
+
+    public Boolean checkBindOpenId(WxIdBody loginBody) {
+        if(Validator.isEmpty(loginBody.getOpenid())||Validator.isEmpty(loginBody.getFromPlat())){
+            throw new CustomException("参数缺失");
+        }
+        User user = iUserService.getOne(new LambdaQueryWrapper<User>().eq(User::getUserId,loginBody.getUserId()));
+        if(loginBody.getFromPlat()==1){
+            if(Validator.isEmpty(user.getGzhOpenId())){
+                LambdaUpdateWrapper<User> objectLambdaUpdateWrapper = Wrappers.lambdaUpdate();
+                objectLambdaUpdateWrapper.eq(User::getUserId, loginBody.getUserId());
+                objectLambdaUpdateWrapper.set(User::getGzhOpenId, loginBody.getOpenid());
+                objectLambdaUpdateWrapper.set(User::getUpdateTime, DateUtils.getNowTime());
+                iUserService.update(null, objectLambdaUpdateWrapper);
+                return true;
+            }else{
+                if(user.getGzhOpenId().equals(loginBody.getOpenid())){
+                    return true;
+                }else{
+                    return false;
+                }
+            }
+        }
+        else if(loginBody.getFromPlat()==2){
+            if(Validator.isEmpty(user.getOpenId())){
+                LambdaUpdateWrapper<User> objectLambdaUpdateWrapper = Wrappers.lambdaUpdate();
+                objectLambdaUpdateWrapper.eq(User::getUserId, loginBody.getUserId());
+                objectLambdaUpdateWrapper.set(User::getOpenId, loginBody.getOpenid());
+                objectLambdaUpdateWrapper.set(User::getUpdateTime, DateUtils.getNowTime());
+                iUserService.update(null, objectLambdaUpdateWrapper);
+                return true;
+            }else{
+                if(user.getOpenId().equals(loginBody.getOpenid())){
+                    return true;
+                }else{
+                    return false;
+                }
+            }
+        }
+        return false;
+    }
+
     public DistributionSeller bindWxGzhOpenIdSeller(WxLoginBody loginBody) {
         DistributionSeller seller = iDistributionSellerService.getOne(new LambdaQueryWrapper<DistributionSeller>().eq(DistributionSeller::getSellerId,loginBody.getSellerId()));
         if (seller == null) {

+ 4 - 1
zhongzheng-system/src/main/java/com/zhongzheng/modules/alioss/bo/OssRequest.java

@@ -20,7 +20,7 @@ import javax.validation.constraints.NotNull;
 public class OssRequest{
 
     /** 上传图片标识 */
-    @ApiModelProperty(value = "上传图片标识 0头像 1身份证 2题库 3指南指引图片 4广告图片 5身份证或学信网图片 6文件excel,word,zip等",required = true)
+    @ApiModelProperty(value = "上传图片标识 0头像 1身份证 2题库 3指南指引图片 4广告图片 5身份证或学信网图片 6文件excel,word,zip等 10文件zip",required = true)
     @NotNull(message = "上传图片标识不能为空")
     private Integer ImageStatus;
 
@@ -33,4 +33,7 @@ public class OssRequest{
 
     @ApiModelProperty("班级ID")
     private Long gradeId;
+
+    @ApiModelProperty("图片路径")
+    private String path;
 }

+ 4 - 3
zhongzheng-system/src/main/java/com/zhongzheng/modules/alioss/service/OssService.java

@@ -23,12 +23,14 @@ public interface OssService {
 
     String upload(OssRequest base) throws Exception;
 
+    String uploadWithPath(OssRequest base,String path) throws Exception;
+
+    String uploadWithUrl(OssRequest base,String urlString);
+
     String uploadInputStream(InputStream inputStream,Integer imageStatus) throws Exception;
 
     String uploadBase64(String fileStr,OssRequest ossRequest);
 
-    String uploadWithPath(OssRequest base, String path) throws Exception;
-
     void closeClient();
 
     void zipPeopleDownload(ClassPeriodStudentExportVo vo, ZipOutputStream outStream);
@@ -43,5 +45,4 @@ public interface OssService {
 
     void processObject(String targetImage ,String sourceImage,String styleType) ;
 
-    String uploadWithUrl(OssRequest base, String pdfUrl);
 }

+ 6 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/alisms/service/impl/AliSmsServiceImpl.java

@@ -92,6 +92,12 @@ public class AliSmsServiceImpl implements IAliSmsService {
         try{
             SendSmsResponse response = SmsUtils.sendSms(tel,SIGNNAME,code,param,ACCESSKEYID,ACCESSKEYSECRET);
             if(response.getBody().getMessage().equals("OK")){
+                SmsAddBo smsAddBo = new SmsAddBo();
+                smsAddBo.setCode(param);
+                smsAddBo.setTel(tel);
+                smsAddBo.setType(9L);
+                smsAddBo.setIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
+                iSmsService.insertByAddBo(smsAddBo);
                 return new ResultBean(response);
             }
             return null;

+ 3 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/bo/ExamAddBo.java

@@ -79,4 +79,7 @@ public class ExamAddBo {
     private ExamSimulateConfigBo simulateConfigJson;
     /** 开启模拟考 1启动(考试类型才能启动) 0关闭 */
     private Integer simulateStatus;
+
+    @ApiModelProperty("商品试卷限制终端学习,多个,拼接  1公众号 2小程序")
+    private String examLimitClient;
 }

+ 3 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/bo/ExamEditBo.java

@@ -99,4 +99,7 @@ public class ExamEditBo {
     private ExamSimulateConfigBo simulateConfigJson;
     /** 开启模拟考 1启动(考试类型才能启动) 0关闭 */
     private Integer simulateStatus;
+
+    @ApiModelProperty("商品试卷限制终端学习,多个,拼接  1公众号 2小程序")
+    private String examLimitClient;
 }

+ 6 - 2
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/bo/QuestionAddBo.java

@@ -73,6 +73,10 @@ public class QuestionAddBo {
     /** 导入顺序 */
     @ApiModelProperty("导入顺序")
     private Long importSort;
-
-
+    /** 山东题库ID */
+    @ApiModelProperty("山东题库ID")
+    private Long sdQid;
+    /** 来源平台 1自有 2山东 */
+    @ApiModelProperty("来源平台 1自有 2山东")
+    private Integer fromPlat;
 }

+ 7 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/bo/QuestionEditBo.java

@@ -83,4 +83,11 @@ public class QuestionEditBo {
 
     @ApiModelProperty("题目ID")
     private List<Long> questionIds;
+
+    /** 山东题库ID */
+    @ApiModelProperty("山东题库ID")
+    private Long sdQid;
+    /** 来源平台 1自有 2山东 */
+    @ApiModelProperty("来源平台 1自有 2山东")
+    private Integer fromPlat;
 }

+ 46 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/bo/QuestionOtherAddBo.java

@@ -0,0 +1,46 @@
+package com.zhongzheng.modules.bank.bo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import java.util.Date;
+
+
+
+/**
+ * 第三方题库添加对象 question_other
+ *
+ * @author ruoyi
+ * @date 2023-08-03
+ */
+@Data
+@ApiModel("第三方题库添加对象")
+public class QuestionOtherAddBo {
+
+    /** 用户ID */
+    @ApiModelProperty("用户ID")
+    private Long userId;
+    /** 专业 */
+    @ApiModelProperty("专业")
+    private String majorname;
+    /**  状态 1正常 0关闭 */
+    @ApiModelProperty(" 状态 1正常 0关闭")
+    private Integer status;
+    /** 创建时间 */
+    @ApiModelProperty("创建时间")
+    private Long createTime;
+    /** 更新时间 */
+    @ApiModelProperty("更新时间")
+    private Long updateTime;
+    /** $column.columnComment */
+    @ApiModelProperty("$column.columnComment")
+    private String jsonStr;
+    /** 1 山东题库 */
+    @ApiModelProperty("1 山东题库")
+    private Integer fromPlat;
+    /** 试卷ID */
+    @ApiModelProperty("试卷ID")
+    private Long examId;
+    private Long relExamId;
+}

+ 52 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/bo/QuestionOtherEditBo.java

@@ -0,0 +1,52 @@
+package com.zhongzheng.modules.bank.bo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import java.util.Date;
+
+
+/**
+ * 第三方题库编辑对象 question_other
+ *
+ * @author ruoyi
+ * @date 2023-08-03
+ */
+@Data
+@ApiModel("第三方题库编辑对象")
+public class QuestionOtherEditBo {
+
+    /** $column.columnComment */
+    @ApiModelProperty("$column.columnComment")
+    private Long id;
+
+    /** 用户ID */
+    @ApiModelProperty("用户ID")
+    private Long userId;
+
+    /** 专业 */
+    @ApiModelProperty("专业")
+    private String majorname;
+
+    /**  状态 1正常 0关闭 */
+    @ApiModelProperty(" 状态 1正常 0关闭")
+    private Integer status;
+
+    /** 更新时间 */
+    @ApiModelProperty("更新时间")
+    private Long updateTime;
+
+
+    /** $column.columnComment */
+    @ApiModelProperty("$column.columnComment")
+    private String jsonStr;
+
+    /** 1 山东题库 */
+    @ApiModelProperty("1 山东题库")
+    private Integer fromPlat;
+
+    /** 试卷ID */
+    @ApiModelProperty("试卷ID")
+    private Long examId;
+}

+ 54 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/bo/QuestionOtherQueryBo.java

@@ -0,0 +1,54 @@
+package com.zhongzheng.modules.bank.bo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.HashMap;
+
+import com.zhongzheng.common.core.domain.BaseEntity;
+
+/**
+ * 第三方题库分页查询对象 question_other
+ *
+ * @author ruoyi
+ * @date 2023-08-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel("第三方题库分页查询对象")
+public class QuestionOtherQueryBo extends BaseEntity {
+
+	/** 分页大小 */
+	@ApiModelProperty("分页大小")
+	private Integer pageSize;
+	/** 当前页数 */
+	@ApiModelProperty("当前页数")
+	private Integer pageNum;
+	/** 排序列 */
+	@ApiModelProperty("排序列")
+	private String orderByColumn;
+	/** 排序的方向desc或者asc */
+	@ApiModelProperty(value = "排序的方向", example = "asc,desc")
+	private String isAsc;
+
+
+	/** 用户ID */
+	@ApiModelProperty("用户ID")
+	private Long userId;
+	/** 专业 */
+	@ApiModelProperty("专业")
+	private String majorname;
+	/**  状态 1正常 0关闭 */
+	@ApiModelProperty(" 状态 1正常 0关闭")
+	private Integer status;
+	/** $column.columnComment */
+	@ApiModelProperty("$column.columnComment")
+	private String jsonStr;
+	/** 1 山东题库 */
+	@ApiModelProperty("1 山东题库")
+	private Integer fromPlat;
+}

+ 3 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/domain/Exam.java

@@ -76,4 +76,7 @@ private static final long serialVersionUID=1L;
     private ExamSimulateConfigBo simulateConfig;
     @TableField(exist = false)
     private Long oId;
+    /** 商品试卷限制终端学习,多个,拼接  1公众号 2小程序 */
+    @TableField(updateStrategy=FieldStrategy.IGNORED)
+    private String examLimitClient;
 }

+ 4 - 1
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/domain/Question.java

@@ -64,5 +64,8 @@ private static final long serialVersionUID=1L;
     private Long tenantId;
     @TableField(exist = false)
     private Long oId;
-
+    /** 山东题库ID */
+    private Long sdQid;
+    /** 来源平台 1自有 2山东 */
+    private Integer fromPlat;
 }

+ 41 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/domain/QuestionOld.java

@@ -0,0 +1,41 @@
+package com.zhongzheng.modules.bank.domain;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 题库题目对象 question
+ *
+ * @author hjl
+ * @date 2021-10-22
+ */
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class QuestionOld implements Serializable {
+
+private static final long serialVersionUID=1L;
+
+    private String title;
+
+    private Integer scenetype;
+
+    private Integer quiztype;
+
+    private Long SdQid;
+
+    private String analysis;
+
+    private List<QuestionOldOptions> options;
+
+    private List<QuestionOldChild> childlist;
+
+}

+ 36 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/domain/QuestionOldChild.java

@@ -0,0 +1,36 @@
+package com.zhongzheng.modules.bank.domain;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 题库题目对象 question
+ *
+ * @author hjl
+ * @date 2021-10-22
+ */
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class QuestionOldChild implements Serializable {
+
+private static final long serialVersionUID=1L;
+
+    private String title;
+
+    private Integer scenetype;
+
+    private Integer quiztype;
+
+    private Long SdQid;
+
+    private String analysis;
+
+    private List<QuestionOldOptions> options;
+
+
+}

+ 28 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/domain/QuestionOldOptions.java

@@ -0,0 +1,28 @@
+package com.zhongzheng.modules.bank.domain;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * 题库题目对象 question
+ *
+ * @author hjl
+ * @date 2021-10-22
+ */
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class QuestionOldOptions implements Serializable {
+
+private static final long serialVersionUID=1L;
+
+    private String serialnum;
+
+    private Boolean isanswer;
+
+    private String optiontitle;
+
+}

+ 48 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/domain/QuestionOther.java

@@ -0,0 +1,48 @@
+package com.zhongzheng.modules.bank.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import java.io.Serializable;
+import java.util.Date;
+import java.math.BigDecimal;
+import com.zhongzheng.common.annotation.Excel;
+
+/**
+ * 第三方题库对象 question_other
+ *
+ * @author ruoyi
+ * @date 2023-08-03
+ */
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+@TableName("question_other")
+public class QuestionOther implements Serializable {
+
+private static final long serialVersionUID=1L;
+
+    /** $column.columnComment */
+    @TableId(value = "id")
+    private Long id;
+    /** 用户ID */
+    private Long userId;
+    /** 专业 */
+    private String majorname;
+    /**  状态 1正常 0关闭 */
+    private Integer status;
+    /** 创建时间 */
+    @TableField(fill = FieldFill.INSERT)
+    private Long createTime;
+    /** 更新时间 */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Long updateTime;
+    /** $column.columnComment */
+    private String jsonStr;
+    /** 1 山东题库 */
+    private Integer fromPlat;
+    /** 试卷ID */
+    private Long examId;
+    private Long relExamId;
+}

+ 14 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/mapper/QuestionOtherMapper.java

@@ -0,0 +1,14 @@
+package com.zhongzheng.modules.bank.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.modules.bank.domain.QuestionOther;
+
+/**
+ * 第三方题库Mapper接口
+ *
+ * @author ruoyi
+ * @date 2023-08-03
+ */
+public interface QuestionOtherMapper extends BaseMapper<QuestionOther> {
+
+}

+ 2 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/service/IExamService.java

@@ -59,4 +59,6 @@ public interface IExamService extends IService<Exam> {
     boolean batchDelExam(QuestionBatchDelBo bo);
 
     Exam getExamByTenant(String code, Long newTenantId);
+
+	boolean getShanDongExam(Long userId,String majorname,Long relExamId);
 }

+ 55 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/service/IQuestionOtherService.java

@@ -0,0 +1,55 @@
+package com.zhongzheng.modules.bank.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.modules.bank.bo.QuestionOtherAddBo;
+import com.zhongzheng.modules.bank.bo.QuestionOtherEditBo;
+import com.zhongzheng.modules.bank.bo.QuestionOtherQueryBo;
+import com.zhongzheng.modules.bank.domain.QuestionOther;
+import com.zhongzheng.modules.bank.vo.QuestionOtherVo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 第三方题库Service接口
+ *
+ * @author ruoyi
+ * @date 2023-08-03
+ */
+public interface IQuestionOtherService extends IService<QuestionOther> {
+	/**
+	 * 查询单个
+	 * @return
+	 */
+	QuestionOtherVo queryById(Long id);
+
+	Long queryByUserMajor(Long userId,String majorname,Long relExamId);
+
+	/**
+	 * 查询列表
+	 */
+	List<QuestionOtherVo> queryList(QuestionOtherQueryBo bo);
+
+	/**
+	 * 根据新增业务对象插入第三方题库
+	 * @param bo 第三方题库新增业务对象
+	 * @return
+	 */
+	Long insertByAddBo(QuestionOtherAddBo bo);
+
+	/**
+	 * 根据编辑业务对象修改第三方题库
+	 * @param bo 第三方题库编辑业务对象
+	 * @return
+	 */
+	Boolean updateByEditBo(QuestionOtherEditBo bo);
+
+	/**
+	 * 校验并删除数据
+	 * @param ids 主键集合
+	 * @param isValid 是否校验,true-删除前校验,false-不校验
+	 * @return
+	 */
+	Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 4 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/service/IQuestionService.java

@@ -104,4 +104,8 @@ public interface IQuestionService extends IService<Question> {
 
 
     Question getQuestionByTenant(String code, Long newTenantId);
+
+	String insertByAddBoImport(QuestionAddBo bo, Integer no);
+
+	Long insertByAddBoImportBackId(QuestionAddBo bo, Integer no);
 }

+ 70 - 8
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/service/impl/ExamServiceImpl.java

@@ -5,6 +5,7 @@ import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@@ -14,20 +15,18 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.pagehelper.Page;
 import com.zhongzheng.common.exception.CustomException;
+import com.zhongzheng.common.type.EncryptHandler;
 import com.zhongzheng.common.utils.DateUtils;
 import com.zhongzheng.common.utils.ServletUtils;
+import com.zhongzheng.common.utils.ToolsUtils;
+import com.zhongzheng.common.utils.http.HttpUtils;
 import com.zhongzheng.modules.bank.bo.*;
-import com.zhongzheng.modules.bank.domain.Exam;
-import com.zhongzheng.modules.bank.domain.ExamQuestion;
-import com.zhongzheng.modules.bank.domain.QuestionBusiness;
-import com.zhongzheng.modules.bank.domain.QuestionChapterExam;
+import com.zhongzheng.modules.bank.domain.*;
 import com.zhongzheng.modules.bank.mapper.ExamMapper;
-import com.zhongzheng.modules.bank.service.IExamQuestionService;
-import com.zhongzheng.modules.bank.service.IExamService;
-import com.zhongzheng.modules.bank.service.IQuestionBusinessService;
-import com.zhongzheng.modules.bank.service.IQuestionChapterExamService;
+import com.zhongzheng.modules.bank.service.*;
 import com.zhongzheng.modules.bank.vo.ExamVo;
 import com.zhongzheng.modules.bank.vo.QuestionChapterExamVo;
+import com.zhongzheng.modules.course.domain.CourseBusiness;
 import com.zhongzheng.modules.course.domain.CourseMenuExam;
 import com.zhongzheng.modules.course.service.ICourseMenuExamService;
 import com.zhongzheng.modules.exam.bo.ExamPaperQueryBo;
@@ -36,8 +35,11 @@ import com.zhongzheng.modules.goods.domain.GoodsAttached;
 import com.zhongzheng.modules.goods.service.IGoodsAttachedService;
 import com.zhongzheng.modules.goods.vo.GoodsAttachedVo;
 import com.zhongzheng.modules.user.bo.CheckUserExamRecordBo;
+import com.zhongzheng.modules.user.domain.User;
 import com.zhongzheng.modules.user.service.IUserExamRecordService;
+import com.zhongzheng.modules.user.service.IUserService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -72,6 +74,13 @@ public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements IE
     private ExamMapper examMapper;
     @Autowired
     private IUserExamRecordService iUserExamRecordService;
+    @Autowired
+    private IQuestionOtherService iQuestionOtherService;
+    @Autowired
+    private IUserService iUserService;
+
+    @Value("${oldSys.host}")
+    private String OLD_SYS_HOST;
 
     @Override
     public ExamVo queryById(Long examId){
@@ -339,4 +348,57 @@ public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements IE
     public Exam getExamByTenant(String code, Long newTenantId) {
         return baseMapper.getExamByTenant(code, newTenantId);
     }
+
+    @Override
+    public boolean getShanDongExam(Long userId,String majorname,Long relExamId) {
+        Boolean getNew = false;
+        User user = iUserService.getOne(new LambdaQueryWrapper<User>()
+                .eq(User::getUserId, userId).last("limit 1"));
+        String idnum = user.getIdCard();
+        String username = user.getRealname();
+        Long nowTime = DateUtils.getNowTime();
+        String sign = ToolsUtils.EncoderByMd5WithUtf(idnum+majorname+nowTime.toString() + "pubilc2022");
+        Map<String,String> map = new HashMap<>();
+        map.put("idnum",idnum);//152301198304206010
+        map.put("tenantId","867735392558919680");
+        map.put("username",username);//袁红军
+        map.put("majorname",majorname);//土建质量员
+        map.put("stamp",nowTime.toString());
+        map.put("sign",sign);
+    //    JSONObject param = JSONObject.parseObject(JSONObject.toJSONString(map));
+        String respone = "";
+        if(getNew){
+            String url = OLD_SYS_HOST+"/system/BussinessApi/InitQdyQuiz";
+            try {
+                respone = HttpUtils.postFormBody(url, map);
+                if (!respone.contains("\"msg\":\"获取成功\"")) {
+                    throw new CustomException("同步请求错误" + respone);
+                }
+                QuestionOtherAddBo addBo = new QuestionOtherAddBo();
+                addBo.setJsonStr(respone);
+                addBo.setFromPlat(1);
+                addBo.setUserId(userId);
+                addBo.setMajorname(majorname);
+                addBo.setRelExamId(relExamId);
+                Long id = iQuestionOtherService.insertByAddBo(addBo);
+                iQuestionOtherService.queryById(id);
+        //        System.out.println(respone);
+            } catch (Exception e) {
+                throw new CustomException("同步请求错误" + e.getMessage());
+            }
+        }else{
+            QuestionOther add = iQuestionOtherService.getOne(new LambdaQueryWrapper<QuestionOther>()
+                    .eq(QuestionOther::getId, 3L).last("limit 1"));
+            if(Validator.isEmpty(add)){
+                throw new CustomException("模拟数据不存在");
+            }
+            add.setUserId(userId);
+            add.setMajorname(majorname);
+            add.setRelExamId(relExamId);
+            add.setId(null);
+            iQuestionOtherService.save(add);
+        }
+
+        return false;
+    }
 }

+ 305 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/service/impl/QuestionOtherServiceImpl.java

@@ -0,0 +1,305 @@
+package com.zhongzheng.modules.bank.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.lang.Validator;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.zhongzheng.common.exception.CustomException;
+import com.zhongzheng.common.utils.DateUtils;
+import com.zhongzheng.common.utils.ServletUtils;
+import com.zhongzheng.modules.bank.bo.*;
+import com.zhongzheng.modules.bank.domain.QuestionOld;
+import com.zhongzheng.modules.bank.domain.QuestionOldChild;
+import com.zhongzheng.modules.bank.domain.QuestionOldOptions;
+import com.zhongzheng.modules.bank.domain.QuestionOther;
+import com.zhongzheng.modules.bank.mapper.QuestionOtherMapper;
+import com.zhongzheng.modules.bank.service.IExamService;
+import com.zhongzheng.modules.bank.service.IQuestionOtherService;
+import com.zhongzheng.modules.bank.service.IQuestionService;
+import com.zhongzheng.modules.bank.vo.ExamVo;
+import com.zhongzheng.modules.bank.vo.QuestionOtherVo;
+import com.zhongzheng.modules.course.service.ICourseMenuExamService;
+import com.zhongzheng.modules.order.domain.OrderGoods;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.github.pagehelper.Page;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 第三方题库Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2023-08-03
+ */
+@Service
+public class QuestionOtherServiceImpl extends ServiceImpl<QuestionOtherMapper, QuestionOther> implements IQuestionOtherService {
+
+    @Autowired
+    private IQuestionService iQuestionService;
+
+    @Autowired
+    private IExamService iExamService;
+
+    @Override
+    public QuestionOtherVo queryById(Long id){
+        QuestionOther db = this.baseMapper.selectById(id);
+        JSONObject jsonObject = (JSONObject) JSONObject.parse(db.getJsonStr());
+        List<QuestionOld> qList = JSONArray.parseArray(String.valueOf(jsonObject.get("data")),QuestionOld.class);
+        if (!db.getJsonStr().contains("\"msg\":\"获取成功\"")) {
+            throw new CustomException("同步请求错误");
+        }
+        int i = 1;
+        List<ExamQuestionAddBo> qIdList = new ArrayList<>();
+        for(QuestionOld old : qList){
+            QuestionAddBo childAddBo = new QuestionAddBo();
+            String importNo = ServletUtils.getEncoded("IMPORT");
+            childAddBo.setStatus(1);
+            childAddBo.setContent(old.getTitle());
+            childAddBo.setSdQid(old.getSdQid());
+            childAddBo.setImportNo(importNo);
+            childAddBo.setCreateTime(DateUtils.getNowTime());
+            childAddBo.setCreateBy("admin");
+            childAddBo.setPublishStatus(1);
+            if(old.getQuiztype()==1){
+                childAddBo.setType(1);
+            }
+            else if(old.getQuiztype()==2){
+                childAddBo.setType(2);
+            }
+            else if(old.getQuiztype()==4){
+                childAddBo.setType(3);
+            }
+            else if(old.getQuiztype()==5){
+                childAddBo.setType(4);
+            }
+
+            if(old.getQuiztype()<3){
+                childAddBo.setAnalysisContent(old.getAnalysis());
+                String answerQuestion="";
+                List<QuestionChildAddBo> optionsList = new ArrayList<>();
+                for(QuestionOldOptions options : old.getOptions()){
+                    QuestionChildAddBo addBo = new QuestionChildAddBo();
+                    addBo.setContent(options.getOptiontitle());
+                    addBo.setOptionsId(dealOptions(options.getSerialnum()));
+                    if(options.getIsanswer()){
+                        answerQuestion+=options.getSerialnum();
+                    }
+                    optionsList.add(addBo);
+                }
+                childAddBo.setOptionsList(optionsList);
+                childAddBo.setAnswerQuestion(dealImportAnswer(answerQuestion));
+            }
+            else if(old.getQuiztype()==4){
+                childAddBo.setAnalysisContent(old.getAnalysis());
+                String answerQuestion="";
+                for(QuestionOldOptions options : old.getOptions()){
+                    if(options.getIsanswer()){
+                        if(options.getSerialnum().equals("A")){
+                            answerQuestion = "1";
+                        }else{
+                            answerQuestion = "0";
+                        }
+                    }
+                }
+                childAddBo.setAnswerQuestion(answerQuestion);
+            }
+            else if(old.getQuiztype()==5){
+                List<QuestionChildAddBo> optionsList = new ArrayList<>();
+                for(QuestionOldChild oldChild :old.getChildlist()){
+                    QuestionChildAddBo addBo = new QuestionChildAddBo();
+                    addBo.setContent(oldChild.getTitle());
+                    if(oldChild.getQuiztype()==1){
+                        addBo.setType(1);
+                    }
+                    else if(oldChild.getQuiztype()==2){
+                        addBo.setType(2);
+                    }
+                    else if(oldChild.getQuiztype()==4){
+                        addBo.setType(3);
+                    }
+                    addBo.setAnalysisContent(oldChild.getAnalysis());
+                    if(oldChild.getQuiztype()<3){
+                        String answerQuestion="";
+                        List<QuestionOptionsAddBo> optionsItemList = new ArrayList<>();
+                        for(QuestionOldOptions options : oldChild.getOptions()){
+                            QuestionOptionsAddBo addChildBo = new QuestionOptionsAddBo();
+                            addChildBo.setContent(options.getOptiontitle());
+                            addChildBo.setOptionsId(dealOptions(options.getSerialnum()));
+                            if(options.getIsanswer()){
+                                answerQuestion+=options.getSerialnum();
+                            }
+                            optionsItemList.add(addChildBo);
+                        }
+                        addBo.setOptionsList(optionsItemList);
+                        addBo.setAnswerQuestion(dealImportAnswer(answerQuestion));
+                    }
+                    else if(oldChild.getQuiztype()==4){
+                        String answerQuestion="";
+                        for(QuestionOldOptions options : oldChild.getOptions()){
+                            if(options.getIsanswer()){
+                                if(options.getSerialnum().equals("A")){
+                                    answerQuestion = "1";
+                                }else{
+                                    answerQuestion = "0";
+                                }
+                            }
+                        }
+                        addBo.setAnswerQuestion(answerQuestion);
+                    }
+                    optionsList.add(addBo);
+                }
+                childAddBo.setOptionsList(optionsList);
+            }
+            childAddBo.setFromPlat(2);
+            Long qId = iQuestionService.insertByAddBoImportBackId(childAddBo,i);
+            ExamQuestionAddBo questionAddBo = new ExamQuestionAddBo();
+            questionAddBo.setQuestionId(qId);
+            questionAddBo.setSort(i);
+            qIdList.add(questionAddBo);
+            i++;
+        }
+        ExamAddBo examAddBo = new ExamAddBo();
+        examAddBo.setExamName("七大员新考试卷");
+        examAddBo.setDoType(1);
+        examAddBo.setStatus(1);
+        examAddBo.setPublishStatus(1L);
+        examAddBo.setQuestionList(qIdList);
+        ExamVo examVo = iExamService.insertByAddBo(examAddBo);
+        QuestionOtherEditBo editBo = new QuestionOtherEditBo();
+        editBo.setId(id);
+        editBo.setExamId(examVo.getExamId());
+        updateByEditBo(editBo);
+        return BeanUtil.toBean(db, QuestionOtherVo.class);
+    }
+
+    @Override
+    public Long queryByUserMajor(Long userId, String majorname,Long relExamId) {
+        QuestionOther questionOther = getOne(new LambdaQueryWrapper<QuestionOther>()
+                .eq(QuestionOther::getUserId, userId).eq(QuestionOther::getMajorname, majorname).eq(QuestionOther::getRelExamId, relExamId)
+                .eq(QuestionOther::getStatus, 1));
+        if(Validator.isNotEmpty(questionOther)){
+            return questionOther.getExamId();
+        }
+        iExamService.getShanDongExam(userId,majorname, relExamId);
+        questionOther = getOne(new LambdaQueryWrapper<QuestionOther>()
+                .eq(QuestionOther::getUserId, userId).eq(QuestionOther::getMajorname, majorname).eq(QuestionOther::getRelExamId, relExamId)
+                .eq(QuestionOther::getStatus, 1));
+        if(Validator.isNotEmpty(questionOther)){
+            return questionOther.getExamId();
+        }
+        return null;
+    }
+
+    private Long dealOptions(String v) {
+        if ("A".equals(v)) {
+           return 1L;
+        } else if ("B".equals(v)) {
+            return 2L;
+        } else if ("C".equals(v)) {
+            return 3L;
+        } else if ("D".equals(v)) {
+            return 4L;
+        } else if ("E".equals(v)) {
+            return 5L;
+        } else if ("F".equals(v)) {
+            return 6L;
+        }
+        return 99L;
+    }
+
+    private String dealImportAnswer(String Answer) {
+        String[] itemArray = Answer.split("");
+        List<String> list = new ArrayList<>();
+        for (String v : itemArray) {
+            if ("A".equals(v)) {
+                list.add("1");
+            } else if ("B".equals(v)) {
+                list.add("2");
+            } else if ("C".equals(v)) {
+                list.add("3");
+            } else if ("D".equals(v)) {
+                list.add("4");
+            } else if ("E".equals(v)) {
+                list.add("5");
+            } else if ("F".equals(v)) {
+                list.add("6");
+            }
+        }
+        return String.join(",", list);
+    }
+
+    @Override
+    public List<QuestionOtherVo> queryList(QuestionOtherQueryBo bo) {
+        LambdaQueryWrapper<QuestionOther> lqw = Wrappers.lambdaQuery();
+        lqw.eq(bo.getUserId() != null, QuestionOther::getUserId, bo.getUserId());
+        lqw.like(StrUtil.isNotBlank(bo.getMajorname()), QuestionOther::getMajorname, bo.getMajorname());
+        lqw.eq(bo.getStatus() != null, QuestionOther::getStatus, bo.getStatus());
+        lqw.eq(StrUtil.isNotBlank(bo.getJsonStr()), QuestionOther::getJsonStr, bo.getJsonStr());
+        lqw.eq(bo.getFromPlat() != null, QuestionOther::getFromPlat, bo.getFromPlat());
+        return entity2Vo(this.list(lqw));
+    }
+
+    /**
+    * 实体类转化成视图对象
+    *
+    * @param collection 实体类集合
+    * @return
+    */
+    private List<QuestionOtherVo> entity2Vo(Collection<QuestionOther> collection) {
+        List<QuestionOtherVo> voList = collection.stream()
+                .map(any -> BeanUtil.toBean(any, QuestionOtherVo.class))
+                .collect(Collectors.toList());
+        if (collection instanceof Page) {
+            Page<QuestionOther> page = (Page<QuestionOther>)collection;
+            Page<QuestionOtherVo> pageVo = new Page<>();
+            BeanUtil.copyProperties(page,pageVo);
+            pageVo.addAll(voList);
+            voList = pageVo;
+        }
+        return voList;
+    }
+
+    @Override
+    public Long insertByAddBo(QuestionOtherAddBo bo) {
+        QuestionOther add = BeanUtil.toBean(bo, QuestionOther.class);
+        validEntityBeforeSave(add);
+        add.setCreateTime(DateUtils.getNowTime());
+        add.setUpdateTime(DateUtils.getNowTime());
+        this.save(add);
+        return add.getId();
+    }
+
+    @Override
+    public Boolean updateByEditBo(QuestionOtherEditBo bo) {
+        QuestionOther update = BeanUtil.toBean(bo, QuestionOther.class);
+        validEntityBeforeSave(update);
+        update.setUpdateTime(DateUtils.getNowTime());
+        return this.updateById(update);
+    }
+
+    /**
+     * 保存前的数据校验
+     *
+     * @param entity 实体类数据
+     */
+    private void validEntityBeforeSave(QuestionOther entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return this.removeByIds(ids);
+    }
+}

+ 29 - 2
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/service/impl/QuestionServiceImpl.java

@@ -3032,8 +3032,7 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i
         return false;
     }
 
-
-    @Transactional(rollbackFor = Exception.class)
+    @Override
     public String insertByAddBoImport(QuestionAddBo bo, Integer no) {
         String errorLog = null;
         Question add = BeanUtil.toBean(bo, Question.class);
@@ -3062,6 +3061,34 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i
         return errorLog;
     }
 
+    @Override
+    public Long insertByAddBoImportBackId(QuestionAddBo bo, Integer no) {
+        Question add = BeanUtil.toBean(bo, Question.class);
+        add.setCode(ServletUtils.getImportEncoded("TM") + no);
+        if (bo.getOptionsList() != null && bo.getOptionsList().size() > 0) {
+            add.setJsonStr(JSON.toJSONString(bo.getOptionsList()));
+        }
+        /*if(checkNameUnique(add)){
+            errorLog+=bo.getContent()+"-名称重复\n";
+           return errorLog;
+        }*/
+        //    add.setCreateTime(DateUtils.getNowTime());
+        add.setUpdateTime(DateUtils.getNowTime());
+        boolean result = this.save(add);
+        if (bo.getBusinessList() != null) {
+            Collection<QuestionBusiness> coll = new HashSet<>();
+            for (int i = 0; i < bo.getBusinessList().size(); i++) {
+                QuestionBusinessAddBo item = bo.getBusinessList().get(i);
+                QuestionBusiness addItem = BeanUtil.toBean(item, QuestionBusiness.class);
+                addItem.setMajorId(add.getQuestionId());
+                addItem.setType(QuestionBusiness.TYPE_QUESTION);
+                coll.add(addItem);
+            }
+            boolean result1 = iQuestionBusinessService.saveBatch(coll);
+        }
+        return add.getQuestionId();
+    }
+
     private boolean checkNameUnique(Question entity) {
         Question info = getOne(new LambdaQueryWrapper<Question>()
                 .eq(Question::getPrefixName, entity.getPrefixName()).eq(Question::getContent, entity.getContent()).ne(Question::getStatus, -1).last("limit 1"));

+ 4 - 1
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/vo/ExamVo.java

@@ -154,5 +154,8 @@ public class ExamVo {
 	@Excel(name = "开启模拟考 1启动(考试类型才能启动) 0关闭")
 	@ApiModelProperty("开启模拟考 1启动(考试类型才能启动) 0关闭")
 	private Integer simulateStatus;
-
+	/** 商品试卷限制终端学习,多个,拼接  1公众号 2小程序 */
+	@Excel(name = "商品试卷限制终端学习,多个,拼接  1公众号 2小程序")
+	@ApiModelProperty("商品试卷限制终端学习,多个,拼接  1公众号 2小程序")
+	private String examLimitClient;
 }

+ 51 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/vo/QuestionOtherVo.java

@@ -0,0 +1,51 @@
+package com.zhongzheng.modules.bank.vo;
+
+import com.zhongzheng.common.annotation.Excel;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.util.Date;
+
+
+
+/**
+ * 第三方题库视图对象 mall_package
+ *
+ * @author ruoyi
+ * @date 2023-08-03
+ */
+@Data
+@ApiModel("第三方题库视图对象")
+public class QuestionOtherVo {
+	private static final long serialVersionUID = 1L;
+
+	/** $pkColumn.columnComment */
+	@ApiModelProperty("$pkColumn.columnComment")
+	private Long id;
+
+	/** 用户ID */
+	@Excel(name = "用户ID")
+	@ApiModelProperty("用户ID")
+	private Long userId;
+	/** 专业 */
+	@Excel(name = "专业")
+	@ApiModelProperty("专业")
+	private String majorname;
+	/**  状态 1正常 0关闭 */
+	@Excel(name = " 状态 1正常 0关闭")
+	@ApiModelProperty(" 状态 1正常 0关闭")
+	private Integer status;
+	/** $column.columnComment */
+	@Excel(name = " 状态 1正常 0关闭")
+	@ApiModelProperty("$column.columnComment")
+	private String jsonStr;
+	/** 1 山东题库 */
+	@Excel(name = "1 山东题库")
+	@ApiModelProperty("1 山东题库")
+	private Integer fromPlat;
+	/** 试卷ID */
+	@Excel(name = "试卷ID")
+	@ApiModelProperty("试卷ID")
+	private Long examId;
+}

+ 5 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/bank/vo/QuestionVo.java

@@ -130,4 +130,9 @@ public class QuestionVo {
 	@Excel(name = "多选 每项部分分,默认0分则不开启")
 	@ApiModelProperty("多选 每项部分分,默认0分则不开启")
 	private BigDecimal partScore;
+	private Long sdQid;
+	/** 来源平台 1自有 2山东 */
+	@Excel(name = "来源平台 1自有 2山东")
+	@ApiModelProperty("来源平台 1自有 2山东")
+	private Integer fromPlat;
 }

+ 9 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/base/bo/UserProfileQueryBo.java

@@ -118,4 +118,13 @@ public class UserProfileQueryBo extends BaseEntity implements Serializable {
 	/** 订单商品ID */
 	@ApiModelProperty("订单商品ID")
 	private Long orderGoodsId;
+
+	@ApiModelProperty("报名开始时间")
+	private Long applyStartTime;
+
+	@ApiModelProperty("报名结束时间")
+	private Long applyEndTime;
+
+	@ApiModelProperty("公司名称")
+	private String companyName;
 }

+ 4 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/base/service/IProfileTpService.java

@@ -6,6 +6,8 @@ import com.zhongzheng.modules.base.bo.ProfileTpEditBo;
 import com.zhongzheng.modules.base.bo.ProfileTpQueryBo;
 import com.zhongzheng.modules.base.domain.ProfileTp;
 import com.zhongzheng.modules.base.vo.ProfileTpVo;
+import com.zhongzheng.modules.user.bo.CommitmentSealBo;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.Collection;
 import java.util.List;
@@ -56,4 +58,6 @@ public interface IProfileTpService extends IService<ProfileTp> {
 	Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
 
 	ProfileTpVo queryByGoodsId(Long goodsId);
+
+    boolean commitmentSealUpload(CommitmentSealBo bo);
 }

+ 52 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/base/service/impl/ProfileTpServiceImpl.java

@@ -4,10 +4,13 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.pagehelper.Page;
+import com.zhongzheng.common.exception.CustomException;
 import com.zhongzheng.common.utils.DateUtils;
 import com.zhongzheng.common.utils.ServletUtils;
 import com.zhongzheng.modules.base.bo.ProfileTpAddBo;
@@ -15,14 +18,18 @@ import com.zhongzheng.modules.base.bo.ProfileTpEditBo;
 import com.zhongzheng.modules.base.bo.ProfileTpQueryBo;
 import com.zhongzheng.modules.base.domain.ProfileTp;
 import com.zhongzheng.modules.base.domain.ProfileTpBusiness;
+import com.zhongzheng.modules.base.domain.UserProfile;
 import com.zhongzheng.modules.base.mapper.ProfileTpMapper;
 import com.zhongzheng.modules.base.service.IProfileTpBusinessService;
 import com.zhongzheng.modules.base.service.IProfileTpService;
+import com.zhongzheng.modules.base.service.IUserProfileService;
 import com.zhongzheng.modules.base.vo.ProfileTpVo;
+import com.zhongzheng.modules.user.bo.CommitmentSealBo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.*;
 import java.util.stream.Collectors;
@@ -39,6 +46,9 @@ public class ProfileTpServiceImpl extends ServiceImpl<ProfileTpMapper, ProfileTp
     @Autowired
     private IProfileTpBusinessService iProfileTpBusinessService;
 
+    @Autowired
+    private IUserProfileService iUserProfileService;
+
 
     @Override
     public ProfileTpVo queryById(Long profileTpId){
@@ -166,5 +176,47 @@ public class ProfileTpServiceImpl extends ServiceImpl<ProfileTpMapper, ProfileTp
         }
     }
 
+    @Override
+    public boolean commitmentSealUpload(CommitmentSealBo bo) {
+        // 承诺书校验
+        checkCommitentSeal(bo);
+        UserProfile userProfile = iUserProfileService.getById(bo.getId());
+        if (ObjectUtils.isNull(userProfile)){
+            throw new CustomException("学员资料不存在");
+        }
+        if (!userProfile.getUserId().equals(bo.getUserId())){
+            throw new CustomException("当前学员和资料不匹配");
+        }
+        //替换学员承诺书
+        String keyValue = userProfile.getKeyValue();
+        JSONObject jsonObject = JSONObject.parseObject(keyValue);
+        Map<String, Object> userMap = new HashMap<>();
+        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
+            userMap.put(entry.getKey(), entry.getValue());
+        }
+        String key = "commitment_seal";
+        JSONObject recentJson = JSONObject.parseObject(userMap.get(key).toString());
+        Map<String, Object> recentMap = new HashMap<>();
+        for (Map.Entry<String, Object> entry : recentJson.entrySet()) {
+            recentMap.put(entry.getKey(), entry.getValue());
+        }
+        if (ObjectUtils.isNotNull(recentMap)){
+            recentMap.put("value",bo.getImageUrl());
+        }else {
+            recentMap.put("fieldKey",key);
+            recentMap.put("value",bo.getImageUrl());
+            recentMap.put("fieldName","承诺书盖章");
+            recentMap.put("status",0);
+        }
+        userMap.put(key,recentMap);
+        String content = JSONObject.toJSONString(userMap);
+        userProfile.setKeyValue(content);
+        return iUserProfileService.updateById(userProfile);
+    }
+
+    private void checkCommitentSeal(CommitmentSealBo bo) {
+
+    }
+
 
 }

+ 16 - 2
zhongzheng-system/src/main/java/com/zhongzheng/modules/base/service/impl/UserProfileServiceImpl.java

@@ -33,6 +33,7 @@ import com.zhongzheng.modules.base.vo.UserProfileExportVo;
 import com.zhongzheng.modules.course.domain.CourseBusiness;
 import com.zhongzheng.modules.goods.service.IGoodsService;
 import com.zhongzheng.modules.goods.vo.GoodsVo;
+import com.zhongzheng.modules.grade.domain.ClassGradeUser;
 import com.zhongzheng.modules.inform.bo.InformUserAddBo;
 import com.zhongzheng.modules.inform.service.IInformRemindService;
 import com.zhongzheng.modules.inform.service.IInformUserService;
@@ -175,7 +176,14 @@ public class UserProfileServiceImpl extends ServiceImpl<UserProfileMapper, UserP
         if(Validator.isEmpty(bo.getOrderGoodsId())||bo.getOrderGoodsId()==0L){
             throw new CustomException("参数错误");
         }
-
+        UserProfile old = getOne(new LambdaQueryWrapper<UserProfile>().eq(UserProfile::getOrderGoodsId, bo.getOrderGoodsId())
+                .eq(UserProfile::getCurrentStatus, 1L)
+                .eq(UserProfile::getChangeStatus, 1L)
+                .eq(UserProfile::getTypeStatus, bo.getTypeStatus())
+                .last("limit 1"));
+        if(Validator.isNotEmpty(old)){
+            throw new CustomException("存在未处理的数据,无法操作");
+        }
         UserProfile add = BeanUtil.toBean(bo, UserProfile.class);
         validEntityBeforeSave(add);
         add.setCreateTime(DateUtils.getNowTime());
@@ -493,7 +501,7 @@ public class UserProfileServiceImpl extends ServiceImpl<UserProfileMapper, UserP
         String keyValue = bo.getKeyValue();
         if (Validator.isNotEmpty(keyValue)) {
             Map<String, String> maps = JSONObject.parseObject(keyValue, Map.class);
-            String recent_photos, idcard_face_photo, idcard_national_photo,work_unit,idcard,name,education,apply_post,telphone;
+            String recent_photos, idcard_face_photo, idcard_national_photo,work_unit,idcard,name,education,apply_post,telphone,sex;
             LambdaUpdateWrapper<User> objectLambdaUpdateWrapper = Wrappers.lambdaUpdate();
             objectLambdaUpdateWrapper.eq(User::getUserId, bo.getUserId());
             UserVo user = iUserService.queryById(bo.getUserId());
@@ -568,6 +576,12 @@ public class UserProfileServiceImpl extends ServiceImpl<UserProfileMapper, UserP
                     objectLambdaUpdateWrapper.set(User::getJob, apply_post);
                 }
             }
+            if (maps.containsKey("sex")) {
+                sex = JSONObject.parseObject(String.valueOf(maps.get("sex")), UserProfileFit.class).getValue();
+                if(Validator.isNotEmpty(sex)){
+                    objectLambdaUpdateWrapper.set(User::getSex, sex.equals("男")?1:2);
+                }
+            }
             objectLambdaUpdateWrapper.set(User::getUpdateTime, DateUtils.getNowTime());
             iUserService.update(null, objectLambdaUpdateWrapper);
         }

+ 6 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/base/vo/UserProfileVo.java

@@ -112,4 +112,10 @@ public class UserProfileVo {
 	private Integer typeStatus;
 	/** 订单商品ID */
 	private Long orderGoodsId;
+
+	@ApiModelProperty("报名时间")
+	private Long applyTime;
+
+	@ApiModelProperty("公司名称")
+	private String companyName;
 }

+ 2 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/collect/mapper/CollectQuestionMapper.java

@@ -23,4 +23,6 @@ public interface CollectQuestionMapper extends BaseMapper<CollectQuestion> {
     List<QuestionVo> selectExamQuestionList(CollectQuestionQueryBo bo);
 
     List<CollectQuestionVo> selectTypeNum(CollectQuestionQueryBo bo);
+
+    List<CollectQuestionVo> selectSpecialExam(CollectQuestionQueryBo bo);
 }

+ 5 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/collect/service/impl/CollectQuestionServiceImpl.java

@@ -3,6 +3,7 @@ package com.zhongzheng.modules.collect.service.impl;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.zhongzheng.common.exception.CustomException;
 import com.zhongzheng.common.utils.DateUtils;
 import com.zhongzheng.modules.bank.vo.QuestionVo;
@@ -75,6 +76,10 @@ public class CollectQuestionServiceImpl extends ServiceImpl<CollectQuestionMappe
 
     @Override
     public List<CollectQuestionVo> selectExamList(CollectQuestionQueryBo bo) {
+        if (ObjectUtils.isNotNull(bo.getDoMode()) && bo.getDoMode() == 4){
+            //山东题库
+            return collectQuestionMapper.selectSpecialExam(bo);
+        }
         return collectQuestionMapper.selectExamList(bo);
     }
 

+ 5 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/course/bo/CourseQueryBo.java

@@ -136,4 +136,9 @@ public class CourseQueryBo extends BaseEntity {
 	/** 真实姓名 */
 	@ApiModelProperty("真实姓名")
 	private String realname;
+
+	@ApiModelProperty("查询标识:1 PC学习列表")
+	private Integer querySign;
+
+	private List<Long> orderGoodsIds;
 }

+ 26 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/course/bo/ExternalQuestionBo.java

@@ -0,0 +1,26 @@
+package com.zhongzheng.modules.course.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+/**
+ * @author yangdamao
+ * @date 2023年09月12日 8:52
+ */
+@Data
+public class ExternalQuestionBo implements Serializable {
+
+    @ApiModelProperty("当前时间戳")
+    @NotBlank(message = "当前时间戳不能为空")
+    private Long stamp;
+
+    @ApiModelProperty("签名")
+    @NotBlank(message = "签名不能为空")
+    private String sign;
+
+    private Long tenantId;
+
+}

+ 22 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/course/bo/QuestionOpenBo.java

@@ -0,0 +1,22 @@
+package com.zhongzheng.modules.course.bo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author yangdamao
+ * @date 2023年09月13日 17:45
+ */
+@Data
+public class QuestionOpenBo implements Serializable {
+
+    private Long goodsId;
+
+    private List<Long> userSubscribeIds;
+
+    private Long createSysUserId;
+
+    private String createBy;
+}

+ 2 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/course/mapper/CourseFileMapper.java

@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.zhongzheng.modules.course.domain.CourseFile;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 /**
  * 文件Mapper接口
  *

+ 4 - 1
zhongzheng-system/src/main/java/com/zhongzheng/modules/course/mapper/CourseHandoutsBusinessMapper.java

@@ -1,7 +1,11 @@
 package com.zhongzheng.modules.course.mapper;
 
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
 import com.zhongzheng.modules.course.domain.CourseHandoutsBusiness;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * 讲义关联业务Mapper接口
@@ -10,5 +14,4 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  * @date 2021-11-02
  */
 public interface CourseHandoutsBusinessMapper extends BaseMapper<CourseHandoutsBusiness> {
-
 }

+ 9 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/course/mapper/CourseMapper.java

@@ -3,6 +3,7 @@ package com.zhongzheng.modules.course.mapper;
 
 import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.github.pagehelper.Page;
 import com.zhongzheng.modules.course.bo.CourseQueryBo;
 import com.zhongzheng.modules.course.domain.Course;
 import com.zhongzheng.modules.course.vo.CourseUserVo;
@@ -12,6 +13,8 @@ import com.zhongzheng.modules.goods.vo.GoodsPeriodVo;
 import com.zhongzheng.modules.goods.vo.GoodsUserVo;
 import com.zhongzheng.modules.grade.bo.ClassGradeUserQueryBo;
 import com.zhongzheng.modules.grade.vo.ClassGradeVo;
+import com.zhongzheng.modules.order.bo.SpecialQuestionBo;
+import com.zhongzheng.modules.order.vo.SpecialQuestionVo;
 import com.zhongzheng.modules.user.bo.UserPlanQueryBo;
 import org.apache.ibatis.annotations.Param;
 
@@ -66,4 +69,10 @@ public interface CourseMapper extends BaseMapper<Course> {
 
     @InterceptorIgnore(tenantLine = "true")
     Long getCourseByTenantTwo(@Param("courseName") String courseName,@Param("code") String code,@Param("tenantId") Long tenantId);
+
+    List<SpecialQuestionVo> getSpecialQuestionList(SpecialQuestionBo bo);
+
+    Long getSpecialQuestionCount(SpecialQuestionBo bo);
+
+    List<Long> getOrderGoodsIds(CourseQueryBo bo);
 }

+ 10 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/course/service/ICourseService.java

@@ -14,11 +14,14 @@ import com.zhongzheng.modules.goods.vo.GoodsUserVo;
 import com.zhongzheng.modules.goods.vo.GoodsVo;
 import com.zhongzheng.modules.grade.bo.ClassGradeUserQueryBo;
 import com.zhongzheng.modules.grade.vo.ClassGradeVo;
+import com.zhongzheng.modules.order.bo.SpecialQuestionBo;
+import com.zhongzheng.modules.order.vo.SpecialQuestionVo;
 import com.zhongzheng.modules.user.bo.UserPlanQueryBo;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 课程Service接口
@@ -74,6 +77,8 @@ public interface ICourseService extends IService<Course> {
 
     List<GoodsUserVo> goodsList(CourseQueryBo bo);
 
+	TableDataInfo<GoodsUserVo> goodsListPage(CourseQueryBo bo);
+
 	List<GoodsUserVo> goodsStudyProgressList(CourseQueryBo bo);
 
 	List<GoodsUserVo> goodsHandoutsList(CourseQueryBo bo);
@@ -100,4 +105,9 @@ public interface ICourseService extends IService<Course> {
 
 	Long getLiveTime();
 
+    List<SpecialQuestionVo> getSpecialQuestionList(SpecialQuestionBo bo);
+
+    Long getSpecialQuestionCount(SpecialQuestionBo bo);
+
+	Map<String,String> getSpecialQuestionSkipCode(Long userId);
 }

+ 0 - 1
zhongzheng-system/src/main/java/com/zhongzheng/modules/course/service/impl/CourseFileServiceImpl.java

@@ -167,5 +167,4 @@ public class CourseFileServiceImpl extends ServiceImpl<CourseFileMapper, CourseF
     public void deleteByTenant(Long handoutsId, Long newTenantId) {
         baseMapper.deleteByTenant(handoutsId, newTenantId);
     }
-
 }

+ 391 - 18
zhongzheng-system/src/main/java/com/zhongzheng/modules/course/service/impl/CourseServiceImpl.java

@@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@@ -11,10 +12,20 @@ import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.client.j2se.MatrixToImageWriter;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.QRCodeWriter;
+import com.zhongzheng.common.core.page.TableDataInfo;
 import com.zhongzheng.common.core.redis.RedisCache;
 import com.zhongzheng.common.exception.CustomException;
+import com.zhongzheng.common.type.EncryptHandler;
 import com.zhongzheng.common.utils.DateUtils;
 import com.zhongzheng.common.utils.ServletUtils;
+import com.zhongzheng.modules.base.domain.UserProfile;
+import com.zhongzheng.modules.base.service.IUserProfileService;
 import com.zhongzheng.modules.course.bo.CourseAddBo;
 import com.zhongzheng.modules.course.bo.CourseEditBo;
 import com.zhongzheng.modules.course.bo.CourseQueryBo;
@@ -30,44 +41,50 @@ import com.zhongzheng.modules.exam.domain.*;
 import com.zhongzheng.modules.exam.service.*;
 import com.zhongzheng.modules.exam.vo.ExamApplyGoodsVo;
 import com.zhongzheng.modules.goods.bo.GoodsBatchDelBo;
+import com.zhongzheng.modules.goods.domain.Goods;
 import com.zhongzheng.modules.goods.domain.GoodsCourse;
+import com.zhongzheng.modules.goods.domain.GoodsQuestionRel;
+import com.zhongzheng.modules.goods.domain.QuestionMerchant;
 import com.zhongzheng.modules.goods.service.IGoodsCourseService;
+import com.zhongzheng.modules.goods.service.IGoodsQuestionRelService;
+import com.zhongzheng.modules.goods.service.IGoodsService;
+import com.zhongzheng.modules.goods.service.IQuestionMerchantService;
 import com.zhongzheng.modules.goods.vo.GoodsPeriodStatusVo;
 import com.zhongzheng.modules.goods.vo.GoodsPeriodVo;
+import com.zhongzheng.modules.goods.vo.GoodsSectionNumVo;
 import com.zhongzheng.modules.goods.vo.GoodsUserVo;
 import com.zhongzheng.modules.grade.bo.ClassGradeUserQueryBo;
 import com.zhongzheng.modules.grade.bo.UserPeriodQueryBo;
 import com.zhongzheng.modules.grade.bo.UserPeriodStatusAddBo;
+import com.zhongzheng.modules.grade.domain.UserPeriod;
 import com.zhongzheng.modules.grade.domain.UserPeriodStatus;
 import com.zhongzheng.modules.grade.service.IClassGradeUserService;
 import com.zhongzheng.modules.grade.service.IUserPeriodService;
 import com.zhongzheng.modules.grade.service.IUserPeriodStatusService;
 import com.zhongzheng.modules.grade.vo.ClassGradeVo;
 import com.zhongzheng.modules.grade.vo.UserPeriodVo;
+import com.zhongzheng.modules.order.bo.SpecialQuestionBo;
+import com.zhongzheng.modules.order.vo.SpecialQuestionVo;
 import com.zhongzheng.modules.order.service.IOrderGoodsService;
+import com.zhongzheng.modules.system.domain.SysTenant;
+import com.zhongzheng.modules.system.service.ISysTenantService;
 import com.zhongzheng.modules.user.bo.SubjectStudyRecordQueryBo;
+import com.zhongzheng.modules.user.bo.UserPhoneBo;
 import com.zhongzheng.modules.user.bo.UserPlanQueryBo;
-import com.zhongzheng.modules.user.domain.UserBankRecord;
-import com.zhongzheng.modules.user.domain.UserStudyRecord;
-import com.zhongzheng.modules.user.domain.UserStudyRecordPhoto;
-import com.zhongzheng.modules.user.domain.UserSubscribe;
-import com.zhongzheng.modules.user.service.IUserBankRecordService;
-import com.zhongzheng.modules.user.service.IUserStudyRecordPhotoService;
-import com.zhongzheng.modules.user.service.IUserStudyRecordService;
-import com.zhongzheng.modules.user.service.IUserSubscribeService;
+import com.zhongzheng.modules.user.domain.*;
+import com.zhongzheng.modules.user.service.*;
 import com.zhongzheng.modules.user.vo.SubjectStudyRecordVo;
 import com.zhongzheng.modules.user.vo.UserStudyRecordPhotoVo;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.io.ByteArrayOutputStream;
 import java.math.BigDecimal;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
@@ -128,8 +145,24 @@ public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> impleme
     @Autowired
     private IUserSubscribeService iUserSubscribeService;
 
+    @Autowired
+    private IUserProfileService iUserProfileService;
+    @Autowired
+    private IGoodsService iGoodsService;
+    @Autowired
+    private IGoodsQuestionRelService iGoodsQuestionRelService;
+    @Autowired
+    private IQuestionMerchantService iQuestionMerchantService;
+    @Autowired
+    private ISysTenantService iSysTenantService;
+    @Autowired
+    private IUserService iUserService;
     @Autowired
     private RedisCache redisCache;
+    @Value("${liveGotoURL}")
+    private String URL_PREFIX;
+
+
 
     @Override
     public CourseVo queryById(Long courseId){
@@ -469,9 +502,21 @@ public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> impleme
             }
             String fullName = goodsUserVo.getEducationName()+goodsUserVo.getBusinessName()+goodsUserVo.getProjectName();
             goodsUserVo.setErJianErZao(false);
+            goodsUserVo.setUserProfile(0);
             if(Validator.isNotEmpty(fullName)){
                 if(fullName.equals("继续教育二级建造师")||fullName.equals("继续教育二级造价师")){
                     goodsUserVo.setErJianErZao(true);
+                }else if (goodsUserVo.getEducationName().equals("考前培训") && goodsUserVo.getProjectName().equals("施工现场专业人员")){
+                    //七大员新考 判断是否提交学员资料
+                    int count = iUserProfileService.count(new LambdaQueryWrapper<UserProfile>()
+                            .notIn(UserProfile::getStatus, Arrays.asList(3, -1))
+                            .eq(UserProfile::getUserId, goodsUserVo.getUserId())
+                            .eq(UserProfile::getGoodsId, goodsUserVo.getGoodsId())
+//                            .eq(UserProfile::getCurrentStatus, 1)
+                    );
+                    if (count > 0){
+                        goodsUserVo.setUserProfile(1);
+                    }
                 }
             }
 
@@ -493,6 +538,7 @@ public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> impleme
             goodsUserVo.setPeriodPlush(classGradeVo.getPeriodPlush());
             goodsUserVo.setOfficialName(classGradeVo.getOfficialName());
             goodsUserVo.setPeriodWaitTime(classGradeVo.getPeriodWaitTime());
+            goodsUserVo.setOpenQuestion(0);
             Long secLong = 0L;
             Long studyLong = 0L;
             SubjectStudyRecordQueryBo subjectStudyRecordQueryBo = new SubjectStudyRecordQueryBo();
@@ -500,10 +546,15 @@ public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> impleme
             subjectStudyRecordQueryBo.setUserId(bo.getUserId());
             subjectStudyRecordQueryBo.setGradeId(goodsUserVo.getGradeId());
             subjectStudyRecordQueryBo.setOrderGoodsId(goodsUserVo.getOrderGoodsId());
-            List<SubjectStudyRecordVo> subjectStudyRecordVos = iUserStudyRecordService.listSubject(subjectStudyRecordQueryBo);
-            for (SubjectStudyRecordVo subjectStudyRecordVo : subjectStudyRecordVos) {
-                secLong = new BigDecimal(secLong.toString()).add(new BigDecimal(subjectStudyRecordVo.getSectionNum().toString())).longValue();
-                studyLong = new BigDecimal(studyLong.toString()).add(new BigDecimal(subjectStudyRecordVo.getRecordNum().toString())).longValue();
+//            List<SubjectStudyRecordVo> subjectStudyRecordVos = iUserStudyRecordService.listSubject(subjectStudyRecordQueryBo);
+//            for (SubjectStudyRecordVo subjectStudyRecordVo : subjectStudyRecordVos) {
+//                secLong = new BigDecimal(secLong.toString()).add(new BigDecimal(subjectStudyRecordVo.getSectionNum().toString())).longValue();
+//                studyLong = new BigDecimal(studyLong.toString()).add(new BigDecimal(subjectStudyRecordVo.getRecordNum().toString())).longValue();
+//            }
+            GoodsSectionNumVo vo = iUserStudyRecordService.getGoodsSectionNum(subjectStudyRecordQueryBo);
+            if (ObjectUtils.isNotNull(vo)){
+                secLong = vo.getSectionNum();
+                studyLong = vo.getRecordNum();
             }
             goodsUserVo.setSecAllNum(secLong);
             goodsUserVo.setStuAllNum(studyLong);
@@ -519,13 +570,15 @@ public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> impleme
                         && (DateUtils.getNowTime() >= goodsUserVo.getServiceStartTime() && DateUtils.getNowTime() <= goodsUserVo.getServiceEndTime())){
                     UserSubscribe userSubscribe = iUserSubscribeService.getOne(new LambdaQueryWrapper<UserSubscribe>()
                             .eq(UserSubscribe::getUserId, bo.getUserId())
-                            .eq(UserSubscribe::getGoodsId, goodsUserVo.getGoodsId())
+                            .eq(UserSubscribe::getOrderGoodsId, goodsUserVo.getOrderGoodsId())
                             .eq(UserSubscribe::getSubscribeStatus, 1)
                             .orderByDesc(UserSubscribe::getCreateTime)
                             .last("limit 1"));
                     if (ObjectUtils.isNull(userSubscribe)){
                         goodsUserVo.setSubscribeSign(1);
-                    }else if (ObjectUtils.isNotNull(userSubscribe.getResult()) && userSubscribe.getResult() == 0){
+                    }else if (userSubscribe.getSubscribeStatus() == 1 && userSubscribe.getExamStatus() == 0){
+                        goodsUserVo.setSubscribeSign(4);
+                    } else if (ObjectUtils.isNotNull(userSubscribe.getResult()) && userSubscribe.getResult() == 0){
                         goodsUserVo.setSubscribeSign(3);
                     }
                 }
@@ -545,6 +598,13 @@ public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> impleme
                            String format = String.format("%s-%s", twoAddBo.getStartTime(), twoAddBo.getEndTime());
                             examApplyGoodsVo.setApplyTime(time);
                             examApplyGoodsVo.setApplyMoment(format);
+                            examApplyGoodsVo.setApplyNum(twoAddBo.getNum().intValue());
+                            //预约人数
+                            int count = iUserSubscribeService.count(new LambdaQueryWrapper<UserSubscribe>()
+                                    .eq(UserSubscribe::getSubscribeStatus, 1)
+                                    .eq(UserSubscribe::getExamStatus, 0)
+                                    .eq(UserSubscribe::getApplyId, examApplyGoodsVo.getApplyId()));
+                            examApplyGoodsVo.setSubscribeNum(count);
                         }
                     }
                     switch (examApply.getApplyNature()){
@@ -599,10 +659,261 @@ public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> impleme
                     }
                 }
             }
+
+            //预约考试是否可以购买题库(该商品没有关联题库且预约考试的时间提前8天)
+            UserSubscribe userSubscribeTwo = iUserSubscribeService.getOne(new LambdaQueryWrapper<UserSubscribe>()
+            .eq(UserSubscribe::getOrderGoodsId,goodsUserVo.getOrderGoodsId())
+            .eq(UserSubscribe::getSubscribeStatus,1)
+            .eq(UserSubscribe::getExamStatus,0)
+            .last("limit 1"));
+            if (ObjectUtils.isNotNull(userSubscribeTwo)){
+                Goods goods = iGoodsService.getById(goodsUserVo.getGoodsId());
+                if (ObjectUtils.isNull(goods.getQuestionGoodsId())){
+                    //没有关联题库 是否购买过题库
+                    int count = iGoodsQuestionRelService.count(new LambdaQueryWrapper<GoodsQuestionRel>()
+                            .eq(GoodsQuestionRel::getOrderGoodsId, userSubscribeTwo.getOrderGoodsId())
+                            .gt(GoodsQuestionRel::getQuestionDoNum, 0));
+                    if (count <= 0){
+                        //考试时间往前推8天
+                        Long appointTime = DateUtils.getDayBefore(userSubscribeTwo.getApplySiteExamTime(), 8);
+                        if (DateUtils.getNowTime() < appointTime){
+                            goodsUserVo.setOpenQuestion(1);
+                            //获取默认题库商家商品
+                            QuestionMerchant one = iQuestionMerchantService.getOne(new LambdaQueryWrapper<QuestionMerchant>()
+                                    .eq(QuestionMerchant::getSign, 1)
+                                    .eq(QuestionMerchant::getStatus, 1)
+                                    .last("limit 1"));
+                            if (ObjectUtils.isNotNull(one)){
+                                Goods goodsOne = iGoodsService.getOne(new LambdaQueryWrapper<Goods>()
+                                        .eq(Goods::getQuestionMerchantId, one.getMerchantId())
+                                        .eq(Goods::getStatus, 1)
+                                        .last("limit 1"));
+                                if (ObjectUtils.isNotNull(goodsOne)){
+                                    goodsUserVo.setQuestionGoodsId(goodsOne.getGoodsId());
+                                }
+                            }
+                        }
+                    }
+                }
+            }
         }
         return goodsUserVos;
     }
 
+    @Override
+    public TableDataInfo<GoodsUserVo> goodsListPage(CourseQueryBo bo) {
+        TableDataInfo tableDataInfo = new TableDataInfo();
+        PageHelper.startPage(bo.getPageNum(), bo.getPageSize());
+        List<Long> page = baseMapper.getOrderGoodsIds(bo);
+        PageInfo<Long> pageInfo = new PageInfo<Long>(page);
+        if (CollectionUtils.isEmpty(pageInfo.getList())){
+            tableDataInfo.setTotal(0L);
+            tableDataInfo.setRows(new ArrayList());
+            return tableDataInfo;
+        }
+        tableDataInfo.setTotal(pageInfo.getTotal());
+        bo.setOrderGoodsIds(pageInfo.getList());
+        List<GoodsUserVo> goodsUserVos = baseMapper.goodsList(bo);
+        //用户课程得详细信息
+        for (GoodsUserVo goodsUserVo : goodsUserVos) {
+            //获得当前所在班级
+            ClassGradeVo classGradeVo = baseMapper.gradeIdSelect(goodsUserVo.getUserId(),goodsUserVo.getGoodsId(),goodsUserVo.getGradeId(),goodsUserVo.getOrderGoodsId());
+            if(Validator.isEmpty(classGradeVo)){
+                continue;
+            }
+            String fullName = goodsUserVo.getEducationName()+goodsUserVo.getBusinessName()+goodsUserVo.getProjectName();
+            goodsUserVo.setErJianErZao(false);
+            goodsUserVo.setUserProfile(0);
+            if(Validator.isNotEmpty(fullName)){
+                if(fullName.equals("继续教育二级建造师")||fullName.equals("继续教育二级造价师")){
+                    goodsUserVo.setErJianErZao(true);
+                }else if (goodsUserVo.getEducationName().equals("考前培训") && goodsUserVo.getProjectName().equals("施工现场专业人员")){
+                    int count = iUserProfileService.count(new LambdaQueryWrapper<UserProfile>()
+                            .ne(UserProfile::getStatus,-1)
+                            .eq(UserProfile::getUserId, goodsUserVo.getUserId())
+                            .eq(UserProfile::getOrderGoodsId, goodsUserVo.getOrderGoodsId())
+                            .eq(UserProfile::getCurrentStatus, 1)
+                    );
+                    if (count > 0){
+                        goodsUserVo.setUserProfile(1);
+                    }
+                }
+            }
+
+            goodsUserVo.setGradeId(classGradeVo.getGradeId());
+            goodsUserVo.setLearningStatus(classGradeVo.getLearningStatus());
+            goodsUserVo.setLearningTimeStart(classGradeVo.getLearningTimeStart());
+            goodsUserVo.setGradeStatus(classGradeVo.getStatus());
+            goodsUserVo.setClassStartTime(classGradeVo.getClassStartTime());
+            goodsUserVo.setClassEndTime(classGradeVo.getClassEndTime());
+            goodsUserVo.setPeriodStatus(classGradeVo.getPeriodStatus());
+            goodsUserVo.setClassStatus(classGradeVo.getClassStatus());
+            goodsUserVo.setRecordNum(classGradeVo.getRecordNum());
+            goodsUserVo.setExamNum(classGradeVo.getExamNum());
+            goodsUserVo.setInterfaceAccountId(classGradeVo.getInterfaceAccountId());
+            goodsUserVo.setInterfacePushId(classGradeVo.getInterfacePushId());
+            goodsUserVo.setOfficialLearningUrl(classGradeVo.getOfficialLearningUrl());
+            goodsUserVo.setOfficialStatus(classGradeVo.getOfficialStatus());
+            goodsUserVo.setLearnStatus(classGradeVo.getLearnStatus());
+            goodsUserVo.setPeriodPlush(classGradeVo.getPeriodPlush());
+            goodsUserVo.setOfficialName(classGradeVo.getOfficialName());
+            goodsUserVo.setPeriodWaitTime(classGradeVo.getPeriodWaitTime());
+            goodsUserVo.setOpenQuestion(0);
+            Long secLong = 0L;
+            Long studyLong = 0L;
+            SubjectStudyRecordQueryBo subjectStudyRecordQueryBo = new SubjectStudyRecordQueryBo();
+            subjectStudyRecordQueryBo.setGoodsId(goodsUserVo.getGoodsId());
+            subjectStudyRecordQueryBo.setUserId(bo.getUserId());
+            subjectStudyRecordQueryBo.setGradeId(goodsUserVo.getGradeId());
+            subjectStudyRecordQueryBo.setOrderGoodsId(goodsUserVo.getOrderGoodsId());
+//            List<SubjectStudyRecordVo> subjectStudyRecordVos = iUserStudyRecordService.listSubject(subjectStudyRecordQueryBo);
+//            for (SubjectStudyRecordVo subjectStudyRecordVo : subjectStudyRecordVos) {
+//                secLong = new BigDecimal(secLong.toString()).add(new BigDecimal(subjectStudyRecordVo.getSectionNum().toString())).longValue();
+//                studyLong = new BigDecimal(studyLong.toString()).add(new BigDecimal(subjectStudyRecordVo.getRecordNum().toString())).longValue();
+//            }
+            GoodsSectionNumVo vo = iUserStudyRecordService.getGoodsSectionNum(subjectStudyRecordQueryBo);
+            if (ObjectUtils.isNotNull(vo)){
+                secLong = vo.getSectionNum();
+                studyLong = vo.getRecordNum();
+            }
+            goodsUserVo.setSecAllNum(secLong);
+            goodsUserVo.setStuAllNum(studyLong);
+            goodsUserVo.setSubscribeSign(2);
+
+
+            //查询对应考试安排
+            List<ExamApplyGoodsVo> examApplyGoodsVoList = iExamApplyGoodsService.listByGoodsId(goodsUserVo.getGoodsId());
+            if (examApplyGoodsVoList != null && examApplyGoodsVoList.size() > 0) {
+                //是否满足预约考试条件
+                if (ObjectUtils.isNotNull(classGradeVo.getPeriodStatus())
+                        && classGradeVo.getPeriodStatus() == 1
+                        && (DateUtils.getNowTime() >= goodsUserVo.getServiceStartTime() && DateUtils.getNowTime() <= goodsUserVo.getServiceEndTime())){
+                    UserSubscribe userSubscribe = iUserSubscribeService.getOne(new LambdaQueryWrapper<UserSubscribe>()
+                            .eq(UserSubscribe::getUserId, bo.getUserId())
+                            .eq(UserSubscribe::getGoodsId, goodsUserVo.getGoodsId())
+                            .eq(UserSubscribe::getSubscribeStatus, 1)
+                            .orderByDesc(UserSubscribe::getCreateTime)
+                            .last("limit 1"));
+                    if (ObjectUtils.isNull(userSubscribe)){
+                        goodsUserVo.setSubscribeSign(1);
+                    }else if (ObjectUtils.isNotNull(userSubscribe.getResult()) && userSubscribe.getResult() == 0){
+                        goodsUserVo.setSubscribeSign(3);
+                    }
+                }
+
+                List<ExamApplyGoodsVo> examApplyGoodsVos = new ArrayList<>();
+                List<ExamApplyGoodsVo> examApplyGoodsVos2 = new ArrayList<>();
+                examApplyGoodsVoList.forEach(examApplyGoodsVo -> {
+                    ExamApply examApply = iExamApplyService.getById(examApplyGoodsVo.getApplyId());
+                    List<ExamApplySiteTime> siteTimes = iExamApplySiteTimeService.list(new LambdaQueryWrapper<ExamApplySiteTime>()
+                            .eq(ExamApplySiteTime::getApplyId, examApplyGoodsVo.getApplyId()));
+                    if (CollectionUtils.isNotEmpty(siteTimes)){
+                        ExamApplySiteTime timeTime = siteTimes.get(0);
+                        List<ExamApplySiteTimeTwoAddBo> siteTimeTwoAddBos = JSONArray.parseArray(timeTime.getSiteTime(), ExamApplySiteTimeTwoAddBo.class);
+                        ExamApplySiteTimeTwoAddBo twoAddBo = siteTimeTwoAddBos.get(0);
+                        if (ObjectUtils.isNotNull(twoAddBo)){
+                            Long time = timeTime.getExamTime()+28800L;
+                            String format = String.format("%s-%s", twoAddBo.getStartTime(), twoAddBo.getEndTime());
+                            examApplyGoodsVo.setApplyTime(time);
+                            examApplyGoodsVo.setApplyMoment(format);
+                        }
+                    }
+                    switch (examApply.getApplyNature()){
+                        case 1: //普通场
+                            LambdaQueryWrapper<ExamApplyUser> lqw = Wrappers.lambdaQuery();
+                            lqw.eq(ExamApplyUser::getApplyId, examApplyGoodsVo.getApplyId());
+                            List<ExamApplyUser> examApplyUserList = iExamApplyUserService.list(lqw);
+                            if (examApplyUserList != null && examApplyUserList.size() > 0) {
+                                ArrayList<Long> userIds = new ArrayList<>();
+                                examApplyUserList.forEach(examApplyUser -> {
+                                    userIds.add(examApplyUser.getUserId());
+                                });
+                                if (userIds.contains(bo.getUserId())) {
+                                    examApplyGoodsVos.add(examApplyGoodsVo);
+                                }
+                            }else {
+                                examApplyGoodsVos2.add(examApplyGoodsVo);
+                            }
+                            break;
+                        case 2://专场
+                            List<ExamApplyUser> applyUsers = iExamApplyUserService
+                                    .list(new LambdaQueryWrapper<ExamApplyUser>().eq(ExamApplyUser::getApplyId, examApply.getApplyId()));
+                            if (CollectionUtils.isNotEmpty(applyUsers) &&
+                                    applyUsers.stream().anyMatch(x -> x.getUserId().equals(bo.getUserId()))){
+                                examApplyGoodsVos.add(examApplyGoodsVo);
+                            }
+                            break;
+                        default:
+                            break;
+                    }
+                });
+                examApplyGoodsVos.addAll(examApplyGoodsVos2);
+                goodsUserVo.setExamApplyGoodsList(examApplyGoodsVos);
+            }
+            LambdaQueryWrapper<UserSubscribe> lq = Wrappers.lambdaQuery();
+            lq.eq(UserSubscribe::getOrderGoodsId, goodsUserVo.getOrderGoodsId());
+            lq.eq(UserSubscribe::getSubscribeStatus, 1);
+            lq.eq(UserSubscribe::getBeforeStatus, 1);
+            lq.last("limit 1");
+            UserSubscribe userSubscribe = iUserSubscribeService.getOne(lq);
+            if (userSubscribe != null) {
+                LambdaQueryWrapper<ExamBefore> lqw1 = Wrappers.lambdaQuery();
+                lqw1.eq(ExamBefore::getBeforeId, userSubscribe.getBeforeId());
+                lqw1.eq(ExamBefore::getStatus, 1);
+                ExamBefore examBefore = iExamBeforeService.getOne(lqw1);
+                if (examBefore != null) {
+                    if ((System.currentTimeMillis()/1000) > examBefore.getBeforeStartTime().longValue() && (System.currentTimeMillis()/1000) < examBefore.getBeforeEndTime().longValue()) {
+                        goodsUserVo.setBeforeStatus(1L);
+                        goodsUserVo.setBeforeName(examBefore.getBeforeName());
+                        goodsUserVo.setBeforeStartTime(examBefore.getBeforeStartTime());
+                        goodsUserVo.setBeforeEndTime(examBefore.getBeforeEndTime());
+                    }
+                }
+            }
+
+            //预约考试是否可以购买题库(该商品没有关联题库且预约考试的时间提前8天)
+            UserSubscribe userSubscribeTwo = iUserSubscribeService.getOne(new LambdaQueryWrapper<UserSubscribe>()
+                    .eq(UserSubscribe::getOrderGoodsId,goodsUserVo.getOrderGoodsId())
+                    .eq(UserSubscribe::getSubscribeStatus,1)
+                    .eq(UserSubscribe::getExamStatus,0)
+                    .last("limit 1"));
+            if (ObjectUtils.isNotNull(userSubscribeTwo)){
+                Goods goods = iGoodsService.getById(goodsUserVo.getGoodsId());
+                if (ObjectUtils.isNull(goods.getQuestionGoodsId())){
+                    //没有关联题库 是否购买过题库
+                    int count = iGoodsQuestionRelService.count(new LambdaQueryWrapper<GoodsQuestionRel>()
+                            .eq(GoodsQuestionRel::getOrderGoodsId, userSubscribeTwo.getOrderGoodsId())
+                            .gt(GoodsQuestionRel::getQuestionDoNum, 0));
+                    if (count <= 0){
+                        //考试时间往前推8天
+                        Long appointTime = DateUtils.getDayBefore(userSubscribeTwo.getApplySiteExamTime(), 8);
+                        if (DateUtils.getNowTime() < appointTime){
+                            goodsUserVo.setOpenQuestion(1);
+                            //获取默认题库商家商品
+                            QuestionMerchant one = iQuestionMerchantService.getOne(new LambdaQueryWrapper<QuestionMerchant>()
+                                    .eq(QuestionMerchant::getSign, 1)
+                                    .eq(QuestionMerchant::getStatus, 1)
+                                    .last("limit 1"));
+                            if (ObjectUtils.isNotNull(one)){
+                                Goods goodsOne = iGoodsService.getOne(new LambdaQueryWrapper<Goods>()
+                                        .eq(Goods::getQuestionMerchantId, one.getMerchantId())
+                                        .eq(Goods::getStatus, 1)
+                                        .last("limit 1"));
+                                if (ObjectUtils.isNotNull(goodsOne)){
+                                    goodsUserVo.setQuestionGoodsId(goodsOne.getGoodsId());
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        tableDataInfo.setRows(goodsUserVos.stream().sorted(Comparator.comparing(GoodsUserVo::getOgCreateTime).reversed()).collect(Collectors.toList()));
+        return tableDataInfo;
+    }
+
+
     @Override
     public List<GoodsUserVo> goodsStudyProgressList(CourseQueryBo bo) {
         List<GoodsUserVo> goodsUserVos = baseMapper.goodsStudyProgressList(bo);
@@ -719,6 +1030,68 @@ public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> impleme
         return aLong;
     }
 
+    @Override
+    public List<SpecialQuestionVo> getSpecialQuestionList(SpecialQuestionBo bo) {
+        List<SpecialQuestionVo> specialQuestionList = baseMapper.getSpecialQuestionList(bo);
+        if (CollectionUtils.isEmpty(specialQuestionList)){
+            return new ArrayList<>();
+        }
+        specialQuestionList.forEach(item -> {
+            GoodsQuestionRel questionRel = iGoodsQuestionRelService
+                    .getOne(new LambdaQueryWrapper<GoodsQuestionRel>()
+                    .eq(GoodsQuestionRel::getQuestionGoodsId, item.getGoodsId())
+                    .eq(GoodsQuestionRel::getQsOrderGoodsId, item.getOrderGoodsId())
+                    .gt(GoodsQuestionRel::getQuestionDoNum, 0)
+                    .last("limit 1"));
+            if (ObjectUtils.isNotNull(questionRel)){
+                item.setSubscribeStatus(questionRel.getStatus());
+            }
+        });
+        return specialQuestionList;
+    }
+
+    @Override
+    public Long getSpecialQuestionCount(SpecialQuestionBo bo) {
+        return baseMapper.getSpecialQuestionCount(bo);
+    }
+
+    @Override
+    public Map<String, String> getSpecialQuestionSkipCode(Long userId) {
+        Map<String, String> map = new HashMap<>();
+        //缓存用户信息key
+        String key = String.format("KQTZ%s",userId);
+        User user = iUserService.getById(userId);
+        Long tenantId = user.getTenantId();
+        SysTenant sysTenant = iSysTenantService.getById(tenantId);
+        //课程
+        String h5Url = String.format("%s%s/pages/questionBank/index?skipPort=%s&sign=1", URL_PREFIX, sysTenant.getHostH5(),key);
+
+        //跳转H5码
+        try {
+            QRCodeWriter qrCodeWriter = new QRCodeWriter();
+            BitMatrix bitMatrix = qrCodeWriter.encode(h5Url, BarcodeFormat.QR_CODE, 120, 120);
+            // 写到输出流
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            MatrixToImageWriter.writeToStream(bitMatrix, "jpg", outputStream);
+            //转换为base64
+            Base64.Encoder encoder1 = Base64.getEncoder();
+            String urlBase64 = "data:image/jpeg;base64,"
+                    + encoder1.encodeToString(outputStream.toByteArray());
+            map.put("h5Base64",urlBase64);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        UserPhoneBo phoneBo = new UserPhoneBo();
+        phoneBo.setTelphone(EncryptHandler.decrypt(user.getTelphone()));
+        phoneBo.setTenantId(tenantId);
+        phoneBo.setIdNum(EncryptHandler.decrypt(user.getIdCard()));
+
+        //缓存用户信息
+        redisCache.setCacheObjectTenant(tenantId+":"+key, JSONObject.toJSONString(phoneBo), 12, TimeUnit.HOURS);
+
+        return map;
+    }
+
     private Long liveTime(Long nowTime, Integer day) {
         for (Integer i = 0; i < day; i++) {
             Long dayAfter = DateUtils.getDayAfter(nowTime, 1);

+ 38 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/course/vo/ExternalQuestionVo.java

@@ -0,0 +1,38 @@
+package com.zhongzheng.modules.course.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * @author yangdamao
+ * @date 2023年09月12日 8:52
+ */
+@Data
+public class ExternalQuestionVo implements Serializable {
+
+    @ApiModelProperty("商品ID")
+    private Long goodsId;
+
+    @ApiModelProperty("商家ID")
+    private Long merchantId;
+
+    @ApiModelProperty("商品名称")
+    private String goodsName;
+
+    @ApiModelProperty("商家名称")
+    private String merchantName;
+
+    @ApiModelProperty("做题次数")
+    private Integer doNum;
+
+    @ApiModelProperty("商品价格")
+    private BigDecimal goodsPrice;
+
+    @ApiModelProperty("封面地址")
+    private String coverUrl;
+
+}

+ 47 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/bo/CdExamRoomBo.java

@@ -0,0 +1,47 @@
+package com.zhongzheng.modules.exam.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author yangdamao
+ * @date 2023年07月11日 16:53
+ */
+@Data
+public class CdExamRoomBo implements Serializable {
+
+    @ApiModelProperty("标识ID")
+    private Long signId;
+
+    @ApiModelProperty("考场类型:1普通场 2专场")
+    private Integer examType;
+
+    @ApiModelProperty("考试日期")
+    private Long examTime;
+
+    @ApiModelProperty("考试开始时间段")
+    private String examStartTime;
+
+    @ApiModelProperty("考试结束时间段")
+    private String examEndTime;
+
+    @ApiModelProperty("考试地点名称")
+    private String examSite;
+
+    @ApiModelProperty("考场人数")
+    private Integer examNum;
+
+    @ApiModelProperty("已约人数")
+    private Integer scheduledNum;
+
+    @ApiModelProperty("数据来源:1新系统 2旧系统 ")
+    private Integer dataFrom;
+
+    @ApiModelProperty("机构ID")
+    private Long tenantId;
+    @ApiModelProperty("类型:1七大员新考")
+    private Integer type;
+
+}

+ 45 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/bo/CdExamRoomUpdateBo.java

@@ -0,0 +1,45 @@
+package com.zhongzheng.modules.exam.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author yangdamao
+ * @date 2023年07月11日 16:53
+ */
+@Data
+public class CdExamRoomUpdateBo implements Serializable {
+
+    @ApiModelProperty("标识ID")
+    private Long signId;
+
+    @ApiModelProperty("考场类型:1普通场 2专场")
+    private Integer examType;
+
+    @ApiModelProperty("机构ID")
+    private Long tenantId;
+
+    @ApiModelProperty("考试日期")
+    private Long examTime;
+
+    @ApiModelProperty("考试开始时间段")
+    private String examStartTime;
+
+    @ApiModelProperty("考试结束时间段")
+    private String examEndTime;
+
+    @ApiModelProperty("考场人数")
+    private Integer examNum;
+
+    @ApiModelProperty("已约人数")
+    private Integer scheduledNum;
+
+    @ApiModelProperty("数据来源:1新系统 2旧系统 ")
+    private Integer dataFrom;
+
+    @ApiModelProperty("考试地点名称")
+    private String examSite;
+
+}

+ 66 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/bo/CdUserSubscribeBo.java

@@ -0,0 +1,66 @@
+package com.zhongzheng.modules.exam.bo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author yangdamao
+ * @date 2023年07月17日 8:59
+ */
+@Data
+public class CdUserSubscribeBo implements Serializable {
+
+    /** 用户ID */
+    @ApiModelProperty("用户ID")
+    private Long userId;
+    /** 用户姓名 */
+    @ApiModelProperty("用户姓名")
+    private String userName;
+    /** 用户身份证 */
+    @ApiModelProperty("用户身份证")
+    private String userCard;
+    /** 用户手机号码 */
+    @ApiModelProperty("用户手机号码")
+    private String userPhone;
+    /** 商品名称 */
+    @ApiModelProperty("商品名称")
+    private String goodsName;
+    /** 订单商品ID */
+    @ApiModelProperty("订单商品ID")
+    private Long orderGoodsId;
+    /** 业务层次名称 */
+    @ApiModelProperty("业务层次名称")
+    private String businessName;
+    @ApiModelProperty("专业")
+    private String major;
+    /** 考试次数 */
+    @ApiModelProperty("考试次数")
+    private Integer examNum;
+    /** 补考次数 */
+    @ApiModelProperty("补考次数")
+    private Integer replenishExamNum;
+    /** 刷题次数 */
+    @ApiModelProperty("刷题次数")
+    private Integer doQuestionNum;
+    /** 题库商家名称 */
+    @ApiModelProperty("题库商家名称")
+    private String questionMerchant;
+    /** 机构Id */
+    @ApiModelProperty("机构Id")
+    private Long tenantId;
+    @ApiModelProperty("数据来源:1新系统 2旧系统")
+    private Integer dataFrom;
+    @ApiModelProperty("类型:1七大员新考")
+    private Integer type;
+    /** 公司名称 */
+    @ApiModelProperty("公司名称")
+    private String companyName;
+    @ApiModelProperty("旧企业ID")
+    private String oldCompanyId;
+    @ApiModelProperty("旧机构ID")
+    private String oldInstitutionId;
+    @ApiModelProperty("旧客户ID")
+    private String oldCustomerId;
+}

+ 2 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/bo/ExamApplySiteAddBo.java

@@ -21,6 +21,8 @@ public class ExamApplySiteAddBo {
     /** 考试地点 */
     @ApiModelProperty("考试地点")
     private Long siteId;
+    @ApiModelProperty("考试地点")
+    private String siteAddress;
     /** 考试安排ID */
     @ApiModelProperty("考试安排ID")
     private Long applyId;

+ 1 - 1
zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/bo/ExamApplySubscribeBo.java

@@ -20,7 +20,7 @@ public class ExamApplySubscribeBo implements Serializable {
     private String telphone;
 
     @ApiModelProperty("标识ID")
-    private Integer signId;
+    private Long signId;
 
     @ApiModelProperty("学员类型:1非补考 2补考")
     private Integer studentType;

+ 2 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/domain/ExamApply.java

@@ -63,4 +63,6 @@ private static final long serialVersionUID=1L;
     private Integer applyNature;
     /** 专场学员资料地址 */
     private String natureUrl;
+
+    private Long tenantId;
 }

+ 8 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/mapper/ExamApplyMapper.java

@@ -2,6 +2,7 @@ package com.zhongzheng.modules.exam.mapper;
 
 import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhongzheng.modules.base.domain.UserProfile;
 import com.zhongzheng.modules.exam.bo.ExamApplyDetailBo;
 import com.zhongzheng.modules.exam.bo.ExamApplyQueryBo;
 import com.zhongzheng.modules.exam.bo.ExamApplyRoomQueryBo;
@@ -89,4 +90,11 @@ public interface ExamApplyMapper extends BaseMapper<ExamApply> {
     List<ExamApplyUserDetailVo> getExamUserInfo(ExamApplyDetailVo bo);
 
     List<Long> getApplyGoodsId(@Param("applyId") Long applyId,@Param("majorName")  String majorName);
+
+    UserSubscribe getHaveSubscribe(ExamApplyQueryBo queryBo);
+
+    List<UserProfile> getUserProfileList(@Param("idCard") String idCard,@Param("businessName") String businessName,@Param("post") String post);
+
+    @InterceptorIgnore(tenantLine = "true")
+    ExamApply getEntityById(Long applyId);
 }

+ 4 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/mapper/ExamSiteMapper.java

@@ -1,5 +1,6 @@
 package com.zhongzheng.modules.exam.mapper;
 
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
 import com.zhongzheng.modules.exam.domain.ExamSite;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 
@@ -12,4 +13,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 public interface ExamSiteMapper extends BaseMapper<ExamSite> {
 
     Integer selectCountSite(Long siteId);
+
+    @InterceptorIgnore(tenantLine = "true")
+    ExamSite getEntityById(Long siteId);
 }

+ 7 - 1
zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/service/IExamApplyService.java

@@ -1,12 +1,14 @@
 package com.zhongzheng.modules.exam.service;
 
 import com.zhongzheng.common.core.page.TableDataInfo;
+import com.zhongzheng.modules.base.bo.UserProfileQueryBo;
 import com.zhongzheng.modules.exam.bo.*;
 import com.zhongzheng.modules.exam.domain.ExamApply;
 import com.zhongzheng.modules.exam.vo.*;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.zhongzheng.modules.goods.domain.Goods;
 import com.zhongzheng.modules.goods.vo.GoodsVo;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.Collection;
 import java.util.List;
@@ -88,11 +90,15 @@ public interface IExamApplyService extends IService<ExamApply> {
 
 	void examApplyResult(ExamApplyResultBo bo);
 
-    List<ExamApplyDetailVo> examApplyDetail(ExamApplyDetailBo bo);
+    ExamApplyDetailVo examApplyDetail(ExamApplyDetailBo bo);
 
 	ExamBeforeKnowVo getBeforeKnow();
 
 	boolean saveOrUpBeforeKnow(ExamBeforeKnowBo bo);
 
     List<Long> getApplyGoodsId(Long applyId, String majorName);
+
+    void updateExamUserProfile(MultipartFile file);
+
+	String examUserProfileExport(UserProfileQueryBo bo);
 }

+ 2 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/service/IExamSiteService.java

@@ -52,4 +52,6 @@ public interface IExamSiteService extends IService<ExamSite> {
 	 * @return
 	 */
 	Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    ExamSite getEntityById(Long siteId);
 }

+ 363 - 29
zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/service/impl/ExamApplyServiceImpl.java

@@ -1,7 +1,10 @@
 package com.zhongzheng.modules.exam.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.lang.Validator;
+import cn.hutool.extra.template.TemplateException;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -11,13 +14,17 @@ import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.pagehelper.Page;
+import com.openhtmltopdf.swing.Java2DRenderer;
+import com.openhtmltopdf.util.FSImageWriter;
 import com.zhongzheng.common.core.page.TableDataInfo;
 import com.zhongzheng.common.exception.CustomException;
 import com.zhongzheng.common.type.EncryptHandler;
 import com.zhongzheng.common.utils.DateUtils;
 import com.zhongzheng.common.utils.JavaMailUtils;
 import com.zhongzheng.common.utils.ServletUtils;
+import com.zhongzheng.common.utils.file.FileUploadUtils;
 import com.zhongzheng.common.utils.file.FileUtils;
+import com.zhongzheng.common.utils.http.HttpUtils;
 import com.zhongzheng.common.utils.poi.EasyPoiUtil;
 import com.zhongzheng.common.utils.poi.ExcelUtil;
 import com.zhongzheng.modules.activity.domain.ActivityRecommend;
@@ -29,6 +36,13 @@ import com.zhongzheng.modules.bank.domain.Exam;
 import com.zhongzheng.modules.bank.domain.QuestionBusiness;
 import com.zhongzheng.modules.bank.service.IExamService;
 import com.zhongzheng.modules.bank.service.IQuestionBusinessService;
+import com.zhongzheng.modules.base.bo.UserProfileFit;
+import com.zhongzheng.modules.base.bo.UserProfileQueryBo;
+import com.zhongzheng.modules.base.domain.UserProfile;
+import com.zhongzheng.modules.base.service.IUserProfileService;
+import com.zhongzheng.modules.base.vo.UserProfileVo;
+import com.zhongzheng.modules.course.domain.Major;
+import com.zhongzheng.modules.course.service.IMajorService;
 import com.zhongzheng.modules.exam.bo.*;
 import com.zhongzheng.modules.exam.domain.*;
 import com.zhongzheng.modules.exam.mapper.ExamApplyMapper;
@@ -46,9 +60,13 @@ import com.zhongzheng.modules.user.domain.UserSubscribe;
 import com.zhongzheng.modules.user.service.IUserService;
 import com.zhongzheng.modules.user.service.IUserSubscribeService;
 import com.zhongzheng.modules.user.vo.UserStudyRecordExport;
+import com.zhongzheng.modules.user.vo.UserVo;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
 import org.apache.commons.io.IOUtils;
 import org.apache.http.entity.ContentType;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.mock.web.MockMultipartFile;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -58,6 +76,7 @@ import javax.activation.DataHandler;
 import javax.mail.*;
 import javax.mail.internet.*;
 import javax.mail.util.ByteArrayDataSource;
+import java.awt.image.BufferedImage;
 import java.io.*;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -88,6 +107,8 @@ public class ExamApplyServiceImpl extends ServiceImpl<ExamApplyMapper, ExamApply
     @Autowired
     private IGoodsService iGoodsService;
     @Autowired
+    private IMajorService iMajorService;
+    @Autowired
     private IUserService iUserService;
     @Autowired
     private ISysTenantService sysTenantService;
@@ -103,6 +124,15 @@ public class ExamApplyServiceImpl extends ServiceImpl<ExamApplyMapper, ExamApply
     private OssService ossService;
     @Autowired
     private ISysConfigService iSysConfigService;
+    @Autowired
+    private IUserProfileService iUserProfileService;
+    @Value("${exam.applyDelete}")
+    private String EXAM_APPLY_DELETE;
+    @Value("${aliyun.oss.endpoint}")
+    private String ALIYUN_OSS_ENDPOINT;
+
+    @Value("${zhongzheng.profile}")
+    private String ZHONGZHENG_PROFILE;
 
     @Override
     public ExamApplyVo queryById(Long applyId) {
@@ -271,6 +301,17 @@ public class ExamApplyServiceImpl extends ServiceImpl<ExamApplyMapper, ExamApply
             if (countApplySubscribe(queryBo) > 0) {
                 throw new RuntimeException("该考试计划存在预约数据,无法删除");
             }
+
+            //通知B端
+            //删除考场同步B端
+            CdExamRoomUpdateBo roomBo = new CdExamRoomUpdateBo();
+            roomBo.setSignId(bo.getApplyId());
+            roomBo.setDataFrom(1);
+            roomBo.setTenantId(Long.valueOf(ServletUtils.getRequest().getHeader("TenantId")));
+            String param = JSONObject.toJSONString(roomBo);
+            Map<String, String> headersMap = new HashMap<>();
+            HttpUtils.sendPostJsonHeaderAsync(EXAM_APPLY_DELETE, param, headersMap);
+
         }
         validEntityBeforeSave(update);
         update.setUpdateTime(DateUtils.getNowTime());
@@ -380,6 +421,26 @@ public class ExamApplyServiceImpl extends ServiceImpl<ExamApplyMapper, ExamApply
 
     @Override
     public ExamUserApplyVo subscribe(ExamApplyQueryBo bo) {
+        //校验预约学员资料信息
+        UserProfile userProfile = iUserProfileService.getOne(new LambdaQueryWrapper<UserProfile>()
+                .eq(UserProfile::getUserId, bo.getUserId())
+                .eq(UserProfile::getOrderGoodsId, bo.getOrderGoodsId())
+                .eq(UserProfile::getGoodsId, bo.getGoodsId())
+                .in(UserProfile::getStatus, Arrays.asList(1,2))
+                .eq(UserProfile::getChangeStatus, 1)
+                .last("limit 1"));
+        if (ObjectUtils.isNull(userProfile) || ObjectUtils.isNull(userProfile.getKeyValue())){
+            throw new CustomException("学员资料不完善,请先完善学员资料");
+        }
+        JSONObject jsonObject = JSONObject.parseObject(userProfile.getKeyValue());
+        if (ObjectUtils.isNull(jsonObject.get("commitment_seal"))){
+            throw new CustomException("缺少带有公司印章的承诺书,请先上传!");
+        }
+        JSONObject commitmentSeal = JSONObject.parseObject(JSONObject.toJSONString(jsonObject.get("commitment_seal")));
+        if (ObjectUtils.isNull(commitmentSeal.get("value"))){
+            throw new CustomException("缺少带有公司印章的承诺书,请先上传!");
+        }
+
         //查询学时通过情况
         Integer countGradePeriod = baseMapper.countGradePeriod(bo);
         if (countGradePeriod < 1) {
@@ -407,13 +468,13 @@ public class ExamApplyServiceImpl extends ServiceImpl<ExamApplyMapper, ExamApply
                 .eq(UserSubscribe::getGoodsId, bo.getGoodsId())
                 .eq(UserSubscribe::getSubscribeStatus, 1)
                 .eq(UserSubscribe::getOrderGoodsId, bo.getOrderGoodsId())
-                .eq(UserSubscribe::getResult, 2)
+                .ne(UserSubscribe::getExamStatus, 1)
                 .orderByDesc(UserSubscribe::getCreateTime)
                 .last("limit 1"));
         if (ObjectUtils.isNotNull(subscribe)) {
             Long examTime = subscribe.getApplySiteExamTime();
             //向后推15个工作日
-            Long applyEndTime = getApplyEndTime(examTime * 1000, 15);
+            Long applyEndTime = getApplyEndTime(examTime, 15);
             if (DateUtils.getNowTime() < applyEndTime){
                 throw new CustomException("成绩审核中,请等待15个工作日后再预约!");
             }
@@ -433,12 +494,11 @@ public class ExamApplyServiceImpl extends ServiceImpl<ExamApplyMapper, ExamApply
 
     private Long getApplyEndTime(Long millisecond, Integer day) {
         for (Integer i = 0; i < day; i++) {
-            Long dayAfter = DateUtils.getDayBefore(millisecond, 1);
+            Long dayAfter = DateUtils.getDayAfter(millisecond, 1);
             Calendar calendar = Calendar.getInstance();
             calendar.setTime(DateUtils.timeToDate(dayAfter));
             int index = calendar.get(Calendar.DAY_OF_WEEK) - 1;
             String[] weeks = new String[]{"星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
-
             if (weeks[index].equals("星期六") || weeks[index].equals("星期天")) {
                 day += 1;
 
@@ -783,7 +843,7 @@ public class ExamApplyServiceImpl extends ServiceImpl<ExamApplyMapper, ExamApply
                 OssRequest ossRequest = new OssRequest();
                 ossRequest.setGradeId(0L);
                 ossRequest.setUserId(0L);
-                ossRequest.setImageStatus(6);
+                ossRequest.setImageStatus(7);
                 File file1 = new File(zipPath);
                 ossRequest.setFile(FileUtils.getMultipartFile(file1));
                 String upload = ossService.upload(ossRequest);
@@ -909,34 +969,32 @@ public class ExamApplyServiceImpl extends ServiceImpl<ExamApplyMapper, ExamApply
     }
 
     @Override
-    public List<ExamApplyDetailVo> examApplyDetail(ExamApplyDetailBo bo) {
+    public ExamApplyDetailVo examApplyDetail(ExamApplyDetailBo bo) {
         List<ExamApplyDetailVo> vo = baseMapper.getExamInfo(bo);
         if (CollectionUtils.isEmpty(vo)){
-            return new ArrayList<>();
+            return new ExamApplyDetailVo();
         }
+        ExamApplyDetailVo detailVo = vo.stream().findFirst().get();
         //获取考试学员
-        vo.forEach(item -> {
-            //考场名称和考试名称
-            ExamSite site = iExamSiteService.getById(item.getSiteId());
-            if (ObjectUtils.isNotNull(site)){
-                item.setSiteName(site.getSiteAddress());
-            }
-            ExamApply examApply = getById(item.getApplyId());
-            if (ObjectUtils.isNotNull(examApply)){
-                item.setApplyName(examApply.getApplyName());
-            }
-            List<ExamApplyUserDetailVo> examUserInfo = baseMapper.getExamUserInfo(item);
-            if (CollectionUtils.isNotEmpty(examUserInfo)){
-                examUserInfo.forEach(user -> {
-                    //身份证隐藏
-                    String decrypt = EncryptHandler.decrypt(user.getIdCard());
-                    String content = decrypt.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2");
-                    user.setIdCard(content);
-                });
-                item.setUserDetailVos(examUserInfo);
-            }
-        });
-        return vo;
+        //考场名称和考试名称
+        ExamSite site = iExamSiteService.getEntityById(detailVo.getSiteId());
+        if (ObjectUtils.isNotNull(site)){
+            detailVo.setSiteName(site.getSiteAddress());
+        }
+        ExamApply examApply = baseMapper.getEntityById(detailVo.getApplyId());
+        if (ObjectUtils.isNotNull(examApply)){
+            detailVo.setApplyName(examApply.getApplyName());
+        }
+        List<ExamApplyUserDetailVo> examUserInfo = baseMapper.getExamUserInfo(detailVo);
+        if (CollectionUtils.isNotEmpty(examUserInfo)){
+            examUserInfo.forEach(user -> {
+                //身份证隐藏
+                String decrypt = EncryptHandler.decrypt(user.getIdCard());
+                user.setIdCard(decrypt);
+            });
+            detailVo.setUserDetailVos(examUserInfo);
+        }
+        return detailVo;
     }
 
     @Override
@@ -983,6 +1041,282 @@ public class ExamApplyServiceImpl extends ServiceImpl<ExamApplyMapper, ExamApply
         return baseMapper.getApplyGoodsId(applyId, majorName);
     }
 
+    @Override
+    public void updateExamUserProfile(MultipartFile file) {
+        String zhiyuan = System.getProperty("user.dir");
+        String path = zhiyuan+"/zhongzheng-admin/src/main/resources/kaoshi";
+        try {
+            FileUtils.unzipWithStream(file.getInputStream(),path);
+        }catch (Exception e){
+            e.printStackTrace();
+            throw new CustomException("文件解压错误");
+        }
+        // 路径
+        try (Stream<Path> paths = Files.walk(Paths.get(path))){
+            List<Path> fileNames = paths
+                    .filter(Files::isRegularFile)
+                    .collect(Collectors.toList());
+            if (CollectionUtils.isEmpty(fileNames)){
+                return;
+            }
+            Map<String, List<Path>> map = fileNames.stream().collect(Collectors.groupingBy(item -> {
+                Path name = item.getFileName();
+                List<String> sign = Arrays.stream(name.toString().split("\\$")).collect(Collectors.toList());
+                //身份证号
+                String idCard = sign.get(0);
+                return idCard;
+            }));
+            map.forEach((k,v) ->{
+                //身份证号
+                String idCard = k;
+                User user = iUserService.getOne(new LambdaQueryWrapper<User>()
+                        .eq(User::getIdCard, EncryptHandler.encrypt(idCard)));
+                if (ObjectUtils.isNull(user)){
+                    return;
+                }
+                for (Path item : v) {
+                    List<String> sign = Arrays.stream(item.getFileName().toString().split("\\$")).collect(Collectors.toList());
+                    String promise = sign.get(1);
+                    String post = Arrays.stream(sign.get(sign.size() - 1).split("\\.")).findFirst().orElse("");
+                    String content1 = item.toString();
+                    File userFile = new File(content1);
+                    MultipartFile multipartFile = FileUtils.getMultipartFile(userFile);
+                    if (!promise.contains("承诺书")){
+                        continue;
+                    }
+                    //查询学员资料填写情况
+                    List<UserProfile> profiles = baseMapper.getUserProfileList(idCard,"考前培训施工现场专业人员",post);
+                    profiles.forEach(userItem -> {
+                        JSONObject jsonObject = JSONObject.parseObject(userItem.getKeyValue());
+                        Map<String, Object> userMap = new HashMap<>();
+                        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
+                            userMap.put(entry.getKey(), entry.getValue());
+                        }
+                        String key = "commitment_seal";
+                        String fieldName = "承诺书盖章";
+                        OssRequest ossRequest = new OssRequest();
+                        ossRequest.setUserId(user.getUserId());
+                        ossRequest.setFile(multipartFile);
+                        ossRequest.setImageStatus(0);
+                        try {
+                            String upload = ossService.upload(ossRequest);
+                            JSONObject recentJson = JSONObject.parseObject(userMap.get(key).toString());
+                            Map<String, Object> recentMap = new HashMap<>();
+                            for (Map.Entry<String, Object> entry : recentJson.entrySet()) {
+                                recentMap.put(entry.getKey(), entry.getValue());
+                            }
+                            if (ObjectUtils.isNotNull(recentMap)){
+                                recentMap.put("value",upload);
+                            }else {
+                                recentMap.put("fieldKey",key);
+                                recentMap.put("value",upload);
+                                recentMap.put("fieldName",fieldName);
+                                recentMap.put("status",0);
+                            }
+                            userMap.put(key,recentMap);
+                        }catch (Exception e) {
+                            throw new CustomException(fieldName+"上传oss失败");
+                        }
+                        String content = JSONObject.toJSONString(userMap);
+                        userItem.setKeyValue(content);
+                    });
+                    iUserProfileService.updateBatchById(profiles);
+                }
+            });
+            //删除本地文件
+            FileUtils.deleteFilePackage(path);
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new CustomException("学员资料有误");
+        }
+
+    }
+
+    @Override
+    public String examUserProfileExport(UserProfileQueryBo bo) {
+        List<UserProfileVo> userProfileVos = iUserProfileService.queryList(bo);
+        if (CollectionUtils.isEmpty(userProfileVos)){
+            throw new CustomException("请勿导出空数据");
+        }
+        //根据公司分组
+        Map< String, List<UserProfileVo>> map = userProfileVos.stream().collect(Collectors.groupingBy(x -> {
+            User user = iUserService.getById(x.getUserId());
+            return StringUtils.isNotBlank(user.getCompanyName())?user.getCompanyName():"没有填写公司名称的学员";
+        }));
+        //写入文件
+        String path = System.getProperty("user.dir") + "/zhongzheng-admin/src/main/resources/profile";
+
+        map.forEach((k,v) -> {
+            String toPath = path+"/"+k;
+            File file = new File(toPath);
+            if (!file.exists()){
+                file.mkdirs();
+            }
+            //学员分组
+            Map<Long, List<UserProfileVo>> userMap = v.stream().collect(Collectors.groupingBy(UserProfileVo::getUserId));
+            userMap.forEach((m,j) -> {
+                User user = iUserService.getById(m);
+                if (ObjectUtils.isNull(user)){
+                    return;
+                }
+                String idCard = EncryptHandler.decrypt(user.getIdCard());
+                //学员资料
+                String keyValue = j.get(0).getKeyValue();
+                JSONObject jsonObject = JSONObject.parseObject(keyValue);
+                //头像
+                JSONObject recentPhotos = JSONObject.parseObject(JSONObject.toJSONString(jsonObject.get("recent_photos")));
+                if (ObjectUtils.isNotNull(recentPhotos)){
+                    handleFile(recentPhotos,idCard,toPath,"recent_photos","");
+                }
+                //身份证正面
+                JSONObject facePhoto = JSONObject.parseObject(JSONObject.toJSONString(jsonObject.get("idcard_face_photo")));
+                if (ObjectUtils.isNotNull(facePhoto)){
+                    handleFile(facePhoto,idCard,toPath,"idcard_face_photo","");
+                }
+                //身份证反面
+                JSONObject nationalPhotos = JSONObject.parseObject(JSONObject.toJSONString(jsonObject.get("idcard_national_photo")));
+                if (ObjectUtils.isNotNull(nationalPhotos)){
+                    handleFile(nationalPhotos,idCard,toPath,"idcard_national_photo","");
+                }
+
+                //承诺书
+                for (UserProfileVo userProfile : j) {
+                    Goods goods = iGoodsService.getById(userProfile.getGoodsId());
+                    Major major = iMajorService.getById(goods.getMajorId());
+                    if (ObjectUtils.isNotNull(major)){
+                        try {
+                            generateCommitment(userProfile.getKeyValue(),toPath,idCard,major.getCategoryName());
+                        } catch (IOException e) {
+                            e.printStackTrace();
+                            throw new CustomException("承诺书生成失败");
+                        }
+                    }
+                }
+            });
+        });
+
+        //打成压缩包
+        String zipPath = System.getProperty("user.dir") + "/zhongzheng-admin/src/main/resources/profile-zip/七大员资料.zip";
+        try {
+            File file = new File(zipPath);
+            if (!file.exists()){
+                //先得到文件的上级目录,并创建上级目录,在创建文件
+                file.getParentFile().mkdir();
+                file.createNewFile();
+            }
+            FileUtils.zipFolder(path,zipPath);
+            //删除本地资源
+            FileUtils.deleteFilePackage(path);
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new CustomException("文件压缩zip包失败!");
+        }
+        ExcelUtil<UserProfile> util = new ExcelUtil<>(UserProfile.class);
+        String content = util.userProfileExport(zipPath, "七大员资料.zip");
+
+        //删除本地资源
+        FileUtils.deleteFilePackage(System.getProperty("user.dir") + "/zhongzheng-admin/src/main/resources/profile-zip");
+        return content;
+    }
+
+    //生成承诺书
+    private void generateCommitment(String keyValue,String toPath,String idCard,String major)throws IOException {
+        int imgIndex=(int)(Math.random() * 10 );
+        //第一种方式
+        Map<String, String> maps = JSONObject.parseObject(keyValue, Map.class);
+
+        //给模板绑定数据
+        Calendar rightNow = Calendar.getInstance();
+        Map<String, Object> bindingMap = new HashMap<>();
+        bindingMap.put("username", JSONObject.parseObject(String.valueOf(maps.get("name")), UserProfileFit.class).getValue());
+        bindingMap.put("s", JSONObject.parseObject(String.valueOf(maps.get("sex")), UserProfileFit.class).getValue());
+        bindingMap.put("post", JSONObject.parseObject(String.valueOf(maps.get("apply_post")), UserProfileFit.class).getValue());
+        bindingMap.put("idcard", JSONObject.parseObject(String.valueOf(maps.get("idcard")), UserProfileFit.class).getValue());
+        bindingMap.put("phone", JSONObject.parseObject(String.valueOf(maps.get("telphone")), UserProfileFit.class).getValue());
+        bindingMap.put("school", JSONObject.parseObject(String.valueOf(maps.get("school")), UserProfileFit.class).getValue());
+        bindingMap.put("edu", JSONObject.parseObject(String.valueOf(maps.get("education")), UserProfileFit.class).getValue());
+        bindingMap.put("major", JSONObject.parseObject(String.valueOf(maps.get("major")), UserProfileFit.class).getValue());
+        bindingMap.put("cname", JSONObject.parseObject(String.valueOf(maps.get("unit_contact")), UserProfileFit.class).getValue());
+        bindingMap.put("cphone", JSONObject.parseObject(String.valueOf(maps.get("unit_tel")), UserProfileFit.class).getValue());
+        bindingMap.put("image", ALIYUN_OSS_ENDPOINT + "/" + JSONObject.parseObject(String.valueOf(maps.get("commitment_electr_signature")), UserProfileFit.class).getValue());
+        bindingMap.put("y", Convert.toStr(rightNow.get(Calendar.YEAR)));
+        bindingMap.put("m", rightNow.get(Calendar.MONTH) + 1);
+        bindingMap.put("d", rightNow.get(Calendar.DAY_OF_MONTH));
+        bindingMap.put("time", JSONObject.parseObject(String.valueOf(maps.get("graduation_time")), UserProfileFit.class).getValue());
+        bindingMap.put("year", JSONObject.parseObject(String.valueOf(maps.get("working_years")), UserProfileFit.class).getValue());
+        File touch = FileUtil.touch(ZHONGZHENG_PROFILE + imgIndex+"word.html");
+        //默认freemake配置
+        Configuration configuration = new Configuration();
+        configuration.setDefaultEncoding("UTF-8");
+        configuration.setClassForTemplateLoading(this.getClass(), "/templates");
+        Template template = configuration.getTemplate("wordPhone.ftl");
+        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(touch), "UTF-8"));
+        try {
+            //写入数据
+            template.process(bindingMap, out);
+            out.flush();
+            out.close();
+        } catch (TemplateException | freemarker.template.TemplateException e) {
+            e.printStackTrace();
+        }
+        //将模板输出为图片
+        final Java2DRenderer renderer = new Java2DRenderer(touch, 1000, 1000);
+        final BufferedImage img = renderer.getImage();
+        final FSImageWriter imageWriter = new FSImageWriter();
+        imageWriter.setWriteCompressionQuality(1.0f);
+        String fileName = idCard+"$承诺书$"+major+".jpg";
+        String filePath = toPath+"/"+fileName;
+        imageWriter.write(img, filePath);//输出路径
+
+    }
+
+    private void handleFile(JSONObject recentPhotos,String idCard,String toPath,String key,String major){
+        try {
+            if (ObjectUtils.isNotNull(recentPhotos.get("value"))){
+                String content = recentPhotos.get("value").toString();
+                InputStream photos = ossService.getStreamByObject(content);
+                //文件名称
+                String keyName = "";
+                if ("recent_photos".equals(key)){
+                    keyName = "头像";
+                }else if ("idcard_face_photo".equals(key)){
+                    keyName = "身份证正面";
+                }else if ("idcard_national_photo".equals(key)){
+                    keyName = "身份证反面";
+                }else if ("commitment_electr_signature".equals(key)){
+                    keyName = "承诺书";
+                }
+
+                if (StringUtils.isBlank(keyName)){
+                    return;
+                }
+                String fileName = idCard+"$"+keyName;
+                if (StringUtils.isNotBlank(major)){
+                    fileName = fileName+"$"+major;
+                }
+                if (content.contains(".")){
+                    List<String> names = Arrays.stream(content.split("\\.")).collect(Collectors.toList());
+                    fileName = fileName + "." + names.get(names.size() -1);
+                }else {
+                    fileName = fileName +".jpg";
+                }
+                String filePath = toPath+"/"+fileName;
+                //写入本地文件
+                FileOutputStream fileOutputStream = new FileOutputStream(filePath);
+                byte[] buffer = new byte[1024];
+                int len = 0;
+                while ((len = photos.read(buffer)) != -1) {
+                    fileOutputStream.write(buffer, 0, len);
+                }
+                photos.close();
+                fileOutputStream.close();
+            }
+        }catch (Exception e) {
+            e.printStackTrace();
+            throw new CustomException("获取学员资料文件失败");
+        }
+    }
+
 
     private void userStudyRecord(String userPath, List<UserSubscribe> list) {
         Map<Long, List<UserSubscribe>> map = list.stream().collect(Collectors.groupingBy(UserSubscribe::getUserId));

+ 78 - 17
zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/service/impl/ExamApplySiteServiceImpl.java

@@ -2,25 +2,31 @@ package com.zhongzheng.modules.exam.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.pagehelper.Page;
 import com.zhongzheng.common.utils.DateUtils;
+import com.zhongzheng.common.utils.http.HttpUtils;
 import com.zhongzheng.modules.exam.bo.*;
+import com.zhongzheng.modules.exam.domain.ExamApply;
 import com.zhongzheng.modules.exam.domain.ExamApplySite;
 import com.zhongzheng.modules.exam.domain.ExamApplySiteTime;
+import com.zhongzheng.modules.exam.domain.ExamSite;
 import com.zhongzheng.modules.exam.mapper.ExamApplySiteMapper;
+import com.zhongzheng.modules.exam.service.IExamApplyService;
 import com.zhongzheng.modules.exam.service.IExamApplySiteService;
 import com.zhongzheng.modules.exam.service.IExamApplySiteTimeService;
+import com.zhongzheng.modules.exam.service.IExamSiteService;
 import com.zhongzheng.modules.exam.vo.ExamApplySiteVo;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -34,9 +40,15 @@ public class ExamApplySiteServiceImpl extends ServiceImpl<ExamApplySiteMapper, E
 
     @Autowired
     private IExamApplySiteTimeService examApplySiteTimeService;
+    @Autowired
+    private IExamApplyService iExamApplyService;
+    @Autowired
+    private IExamSiteService iExamSiteService;
+    @Value("${exam.applySave}")
+    private String EXAM_APPLY_SAVE;
 
     @Override
-    public ExamApplySiteVo queryById(Long id){
+    public ExamApplySiteVo queryById(Long id) {
         ExamApplySite db = this.baseMapper.selectById(id);
         return BeanUtil.toBean(db, ExamApplySiteVo.class);
     }
@@ -51,19 +63,19 @@ public class ExamApplySiteServiceImpl extends ServiceImpl<ExamApplySiteMapper, E
     }
 
     /**
-    * 实体类转化成视图对象
-    *
-    * @param collection 实体类集合
-    * @return
-    */
+     * 实体类转化成视图对象
+     *
+     * @param collection 实体类集合
+     * @return
+     */
     private List<ExamApplySiteVo> entity2Vo(Collection<ExamApplySite> collection) {
         List<ExamApplySiteVo> voList = collection.stream()
                 .map(any -> BeanUtil.toBean(any, ExamApplySiteVo.class))
                 .collect(Collectors.toList());
         if (collection instanceof Page) {
-            Page<ExamApplySite> page = (Page<ExamApplySite>)collection;
+            Page<ExamApplySite> page = (Page<ExamApplySite>) collection;
             Page<ExamApplySiteVo> pageVo = new Page<>();
-            BeanUtil.copyProperties(page,pageVo);
+            BeanUtil.copyProperties(page, pageVo);
             pageVo.addAll(voList);
             voList = pageVo;
         }
@@ -92,13 +104,13 @@ public class ExamApplySiteServiceImpl extends ServiceImpl<ExamApplySiteMapper, E
      *
      * @param entity 实体类数据
      */
-    private void validEntityBeforeSave(ExamApplySite entity){
+    private void validEntityBeforeSave(ExamApplySite entity) {
         //TODO 做一些数据校验,如唯一约束
     }
 
     @Override
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if(isValid){
+        if (isValid) {
             //TODO 做一些业务上的校验,判断是否需要校验
         }
         return this.removeByIds(ids);
@@ -106,12 +118,13 @@ public class ExamApplySiteServiceImpl extends ServiceImpl<ExamApplySiteMapper, E
 
     @Override
     public boolean addSite(List<ExamApplySiteAddBo> bo) {
+        Long applyId = bo.get(0).getApplyId();
         //删除之前的地点
         LambdaQueryWrapper<ExamApplySite> lqw = Wrappers.lambdaQuery();
-        lqw.eq( ExamApplySite::getApplyId,bo.get(0).getApplyId());
-        lqw.eq( ExamApplySite::getStatus,bo.get(0).getStatus());
+        lqw.eq(ExamApplySite::getApplyId, applyId);
+        lqw.eq(ExamApplySite::getStatus, bo.get(0).getStatus());
         this.remove(lqw);
-        examApplySiteTimeService.remove(new LambdaQueryWrapper<ExamApplySiteTime>().eq(ExamApplySiteTime::getApplyId,bo.get(0).getApplyId()));
+        boolean remove = examApplySiteTimeService.remove(new LambdaQueryWrapper<ExamApplySiteTime>().eq(ExamApplySiteTime::getApplyId, bo.get(0).getApplyId()));
         //增加地点
         for (ExamApplySiteAddBo examApplySiteAddBo : bo) {
             ExamApplySite add = BeanUtil.toBean(examApplySiteAddBo, ExamApplySite.class);
@@ -120,7 +133,7 @@ public class ExamApplySiteServiceImpl extends ServiceImpl<ExamApplySiteMapper, E
             add.setUpdateTime(DateUtils.getNowTime());
             this.save(add);
             for (ExamApplySiteTimeAddBo examApplySiteTimeAddBo : examApplySiteAddBo.getExamApplySiteTime()) {
-                if (CollectionUtils.isNotEmpty(examApplySiteTimeAddBo.getExamApplySiteTimeTwo())){
+                if (CollectionUtils.isNotEmpty(examApplySiteTimeAddBo.getExamApplySiteTimeTwo())) {
                     for (ExamApplySiteTimeTwoAddBo examApplySiteTimeTwoAddBo : examApplySiteTimeAddBo.getExamApplySiteTimeTwo()) {
                         ExamApplySiteTime examApplySiteTime = BeanUtil.toBean(examApplySiteTimeAddBo, ExamApplySiteTime.class);
                         examApplySiteTime.setApplySiteId(add.getId());
@@ -133,6 +146,54 @@ public class ExamApplySiteServiceImpl extends ServiceImpl<ExamApplySiteMapper, E
                 }
             }
         }
+
+        List<ExamApplySiteTimeAddBo> examApplySiteTime = bo.get(0).getExamApplySiteTime();
+        ExamSite site = iExamSiteService.getById(bo.get(0).getSiteId());
+        ExamApplySiteTimeAddBo timeAddBo = examApplySiteTime.stream().findFirst().orElse(null);
+        if (ObjectUtils.isNotNull(timeAddBo)) {
+            if (remove) {
+                //修改
+                //修改考场同步B端
+                ExamApply apply = iExamApplyService.getById(applyId);
+                CdExamRoomUpdateBo roomBo = new CdExamRoomUpdateBo();
+                roomBo.setSignId(apply.getApplyId());
+                roomBo.setDataFrom(1);
+                roomBo.setTenantId(apply.getTenantId());
+                roomBo.setExamType(apply.getApplyNature());
+                roomBo.setExamTime(timeAddBo.getExamTime());
+                ExamApplySiteTimeTwoAddBo twoAddBo = timeAddBo.getExamApplySiteTimeTwo().stream().findFirst().orElse(null);
+                roomBo.setExamStartTime(twoAddBo.getStartTime());
+                roomBo.setExamEndTime(twoAddBo.getEndTime());
+                roomBo.setExamSite(site.getSiteAddress());
+                roomBo.setExamNum(twoAddBo.getNum().intValue());
+                roomBo.setScheduledNum(0);
+                String param = JSONObject.toJSONString(roomBo);
+                Map<String, String> headersMap = new HashMap<>();
+                HttpUtils.sendPostJsonHeaderAsync(EXAM_APPLY_SAVE, param, headersMap);
+
+            } else {
+                //新增
+                //考场创建同步B端
+                ExamApply apply = iExamApplyService.getById(applyId);
+                CdExamRoomBo roomBo = new CdExamRoomBo();
+                roomBo.setSignId(apply.getApplyId());
+                roomBo.setDataFrom(1);
+                roomBo.setTenantId(apply.getTenantId());
+                roomBo.setType(1);//七大员预约
+                roomBo.setExamType(apply.getApplyNature());
+                roomBo.setExamTime(timeAddBo.getExamTime());
+                ExamApplySiteTimeTwoAddBo twoAddBo = timeAddBo.getExamApplySiteTimeTwo().stream().findFirst().orElse(null);
+                roomBo.setExamStartTime(twoAddBo.getStartTime());
+                roomBo.setExamEndTime(twoAddBo.getEndTime());
+                roomBo.setExamSite(site.getSiteAddress());
+                roomBo.setExamNum(twoAddBo.getNum().intValue());
+                roomBo.setScheduledNum(0);
+                String param = JSONObject.toJSONString(roomBo);
+                Map<String, String> headersMap = new HashMap<>();
+                HttpUtils.sendPostJsonHeaderAsync(EXAM_APPLY_SAVE, param, headersMap);
+            }
+
+        }
         return true;
     }
 }

+ 5 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/service/impl/ExamSiteServiceImpl.java

@@ -156,4 +156,9 @@ public class ExamSiteServiceImpl extends ServiceImpl<ExamSiteMapper, ExamSite> i
         }
         return this.removeByIds(ids);
     }
+
+    @Override
+    public ExamSite getEntityById(Long siteId) {
+        return baseMapper.getEntityById(siteId);
+    }
 }

+ 4 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/exam/vo/ExamApplyGoodsVo.java

@@ -43,4 +43,8 @@ public class ExamApplyGoodsVo {
 	private String applyMoment;
 	@ApiModelProperty("考试时间")
 	private Long applyTime;
+	@ApiModelProperty("考场人数")
+	private Integer applyNum;
+	@ApiModelProperty("预约人数")
+	private Integer subscribeNum;
 }

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است