浏览代码

fix机构版0918合并

Eric 1 年之前
父节点
当前提交
bdbc855a15
共有 100 个文件被更改,包括 11645 次插入37 次删除
  1. 2 6
      audio-analysis/src/main/java/com/yonge/audio/config/LocalFastJsonHttpMessageConverter.java
  2. 57 7
      audio-analysis/src/main/java/com/yonge/audio/config/WebMvcConfig.java
  3. 3 4
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/AdminFeignService.java
  4. 3 3
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/CmsFeignService.java
  5. 2 4
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/MallAdminFeignService.java
  6. 2 3
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/MallPortalFeignService.java
  7. 2 5
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/StudentFeignService.java
  8. 2 2
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/TeacherFeignService.java
  9. 2 3
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/TenantFeignService.java
  10. 60 0
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/properties/OpenFeignConfigProperties.java
  11. 90 0
      cooleshow-app/pom.xml
  12. 22 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/AppServerApplication.java
  13. 167 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ActivityEvaluationController.java
  14. 51 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ActivityEvaluationRecordController.java
  15. 150 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ActivityPlanController.java
  16. 53 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ActivityRegistrationController.java
  17. 162 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ActivityRewardController.java
  18. 53 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ActivityUserRewardController.java
  19. 164 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/AdminCourseGroupController.java
  20. 112 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/AlbumFavoriteController.java
  21. 112 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/AlbumMusicRelateController.java
  22. 72 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/AppVersionInfoController.java
  23. 99 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/AuditReasonController.java
  24. 105 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ContractTemplateController.java
  25. 83 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/CourseCoursewareController.java
  26. 228 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/CourseGroupController.java
  27. 74 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/CourseHomeworkController.java
  28. 92 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/CourseScheduleRepliedController.java
  29. 175 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/CustomerServiceBatchSendingController.java
  30. 91 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/CustomerServiceReceiveController.java
  31. 138 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/EmployeeController.java
  32. 94 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/HolidaysFestivalsController.java
  33. 89 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/HomeController.java
  34. 123 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/HotSearchController.java
  35. 113 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ImGroupController.java
  36. 74 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MemberPriceSettingsController.java
  37. 257 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MusicAlbumController.java
  38. 112 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MusicFavoriteController.java
  39. 112 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MusicSheetAccompanimentController.java
  40. 427 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MusicSheetController.java
  41. 112 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MusicSheetPurchaseRecordController.java
  42. 134 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MusicTagController.java
  43. 70 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/PianoRoomChangeRecordController.java
  44. 121 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/PianoRoomSettingsController.java
  45. 68 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/PlatformCashAccountRecordController.java
  46. 40 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/PracticeController.java
  47. 98 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ReturnVisitController.java
  48. 88 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SmsCodeController.java
  49. 92 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/StudentAttendanceController.java
  50. 221 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/StudentController.java
  51. 92 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/StudentCourseHomeworkController.java
  52. 82 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SubjectController.java
  53. 129 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysAreaController.java
  54. 114 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysConfigController.java
  55. 71 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysGoodsPriceController.java
  56. 49 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysImComplaintController.java
  57. 103 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysManualController.java
  58. 59 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysSuggestionController.java
  59. 47 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysUserContractRecordController.java
  60. 76 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TeacherAuthEntryRecordController.java
  61. 70 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TeacherAuthMusicianRecordController.java
  62. 353 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TeacherController.java
  63. 67 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TeacherStyleVideoController.java
  64. 49 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantAccountRecordController.java
  65. 67 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantActivationCodeController.java
  66. 256 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantAlbumController.java
  67. 100 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantEntryRecordController.java
  68. 96 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantInfoController.java
  69. 136 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantMemberController.java
  70. 70 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantUnbindHistoryController.java
  71. 70 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantUnbindRecordController.java
  72. 81 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/UnbindAuthUserController.java
  73. 80 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/UploadFileController.java
  74. 36 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/UserAccountController.java
  75. 95 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/UserAccountRecordController.java
  76. 78 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/UserOrderController.java
  77. 93 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/UserOrderRefundController.java
  78. 132 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/UserWithdrawalController.java
  79. 351 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/VideoLessonController.java
  80. 109 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/VideoLessonEvaluateController.java
  81. 108 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/VideoLessonPurchaseRecordController.java
  82. 108 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/VideoLessonStudyRecordController.java
  83. 47 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/VipCardRecordController.java
  84. 236 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/coupon/CouponInfoController.java
  85. 143 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/coupon/CouponIssueController.java
  86. 130 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/music/MusicCompareRecordStatController.java
  87. 244 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/AdminClient.java
  88. 316 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/ImController.java
  89. 129 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/OpenSysAreaController.java
  90. 47 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/OpenSysConfigController.java
  91. 73 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/OpenUserAccountController.java
  92. 206 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/UserOrderClient.java
  93. 275 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/UserPaymentClient.java
  94. 135 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/ActivityTeacherVO.java
  95. 168 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/SysAreaVo.java
  96. 326 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/TeacherBindingUserVo.java
  97. 134 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/TenantAlbumVo.java
  98. 60 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/TenantInfoVo.java
  99. 433 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/coupon/CouponInfoVO.java
  100. 243 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/coupon/CouponInventoryVO.java

+ 2 - 6
audio-analysis/src/main/java/com/yonge/audio/config/LocalFastJsonHttpMessageConverter.java

@@ -2,12 +2,10 @@ package com.yonge.audio.config;
 
 import com.alibaba.fastjson.serializer.JSONSerializer;
 import com.alibaba.fastjson.serializer.ObjectSerializer;
-import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
 import com.alibaba.fastjson.serializer.ValueFilter;
 import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
 import com.vdurmont.emoji.EmojiParser;
 import com.yonge.toolset.base.enums.BaseEnum;
-import com.yonge.toolset.utils.json.JsonUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.http.HttpInputMessage;
 import org.springframework.http.HttpOutputMessage;
@@ -15,10 +13,8 @@ import org.springframework.http.converter.HttpMessageNotReadableException;
 import org.springframework.http.converter.HttpMessageNotWritableException;
 
 import java.io.IOException;
-import java.io.OutputStream;
 import java.lang.reflect.Type;
 import java.math.BigDecimal;
-import java.util.Date;
 
 public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConverter {
 
@@ -32,12 +28,12 @@ public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConver
 	@Override
 	protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
 
-		OutputStream out = outputMessage.getBody();
+		/*OutputStream out = outputMessage.getBody();
 		JsonUtil.getConfig().put(Date.class, new SimpleDateFormatSerializer(FORMAT));
 		//JsonUtil.getConfig().put(String.class, new EmojiSerializer());
 		String text = JsonUtil.toJSONString(obj, EnumFilter.instance, getFeatures());
 		byte[] bytes = text.getBytes(getCharset());
-		out.write(bytes);
+		out.write(bytes);*/
 	}
 }
 

+ 57 - 7
audio-analysis/src/main/java/com/yonge/audio/config/WebMvcConfig.java

@@ -1,16 +1,22 @@
 package com.yonge.audio.config;
 
-import java.util.ArrayList;
-import java.util.List;
-
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+import com.google.common.collect.Lists;
+import com.yonge.cooleshow.biz.dal.config.jackson.JacksonConfig;
+import com.yonge.cooleshow.biz.dal.config.jackson.MappingJSONHttpMessageConverter;
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
 import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
-import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
 import org.springframework.format.FormatterRegistry;
 import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
-import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
 
 @Configuration
 public class WebMvcConfig implements WebMvcConfigurer {
@@ -20,10 +26,54 @@ public class WebMvcConfig implements WebMvcConfigurer {
 	 */
 	@Override
 	public void addFormatters(FormatterRegistry registry) {
+		// 枚举转换器
 		registry.addConverterFactory(new EnumConverterFactory());
+		// 字符串时间转换器
+		registry.addConverter(new JacksonConfig.CustomStringDateConverter());
 	}
-	
-	@Bean
+
+	/**
+	 * @param converters List<HttpMessageConverter<?>>
+	 */
+	@Override
+	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+		//WebMvcConfigurer.super.configureMessageConverters(converters);
+
+		// 如果存在fastJson的转换器,将其移除
+		converters.removeIf(httpMessageConverter -> httpMessageConverter instanceof FastJsonHttpMessageConverter);
+
+		// 需要重新加入jackson的转换器,该处的objectMapper已经在配置中注册了
+		MappingJSONHttpMessageConverter converter = new MappingJSONHttpMessageConverter(new JacksonConfig.JacksonObjectMapper());
+		converter.setDefaultCharset(StandardCharsets.UTF_8); // 字符编号
+		converters.add(0, converter);
+
+		// 添加String转换器
+		converters.add(utf8StringHttpMessageConverter());
+	}
+
+	/**
+	 * 自定义String转换器
+	 * @return HttpMessageConverters
+	 */
+	//@Bean
+	@Primary
+	public StringHttpMessageConverter utf8StringHttpMessageConverter() {
+
+		StringHttpMessageConverter converter = new StringHttpMessageConverter();
+
+		List<MediaType> mediaTypes = Lists.newArrayList();
+		mediaTypes.add(MediaType.TEXT_HTML);
+		mediaTypes.add(MediaType.TEXT_PLAIN);
+		mediaTypes.add(MediaType.TEXT_XML);
+		mediaTypes.add(MediaType.APPLICATION_XML);
+
+		converter.setSupportedMediaTypes(mediaTypes);
+		converter.setDefaultCharset(StandardCharsets.UTF_8);
+
+		return converter;
+	}
+
+	//@Bean
     public HttpMessageConverters fastJsonHttpMessageConverters(){
 		LocalFastJsonHttpMessageConverter converter = new LocalFastJsonHttpMessageConverter();
         List<MediaType> fastMediaTypes =  new ArrayList<MediaType>();

+ 3 - 4
cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/AdminFeignService.java

@@ -2,14 +2,13 @@ package com.yonge.cooleshow.api.feign;
 
 import com.yonge.cooleshow.api.feign.dto.CouponInfoApi;
 import com.yonge.cooleshow.api.feign.dto.EmployeeApi;
+import com.yonge.cooleshow.api.feign.dto.ImUserInfo;
 import com.yonge.cooleshow.api.feign.dto.StudentApi;
 import com.yonge.cooleshow.api.feign.dto.StudentWrapper;
 import com.yonge.cooleshow.api.feign.dto.TeacherApi;
 import com.yonge.cooleshow.api.feign.dto.TenantWrapper;
 import com.yonge.cooleshow.api.feign.dto.UserFriendInfoVO;
-import com.yonge.cooleshow.api.feign.dto.*;
 import com.yonge.cooleshow.api.feign.fallback.AdminFeignServiceFallback;
-import com.yonge.cooleshow.common.constant.AppConstant;
 import com.yonge.cooleshow.common.entity.ContractDto;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.MallOrderItemDto;
@@ -30,8 +29,8 @@ import java.util.List;
  * @author liujunchi
  * @date 2022-05-06
  */
-@FeignClient(name = AppConstant.APPLICATION_ADMIN + AppConstant.SERVER, configuration = FeignConfiguration.class,
-        fallback = AdminFeignServiceFallback.class)
+@FeignClient(name = "${app-config.open-feign.admin-server.name:admin-server}", url = "${app-config.open-feign.admin-server.url:}",
+        configuration = FeignConfiguration.class, fallback = AdminFeignServiceFallback.class)
 public interface AdminFeignService {
     /***
      * 轮询用户订单

+ 3 - 3
cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/CmsFeignService.java

@@ -1,8 +1,7 @@
 package com.yonge.cooleshow.api.feign;
 
-import com.yonge.cooleshow.common.constant.AppConstant;
-import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.api.feign.fallback.CmsFeignServiceFallback;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.feign.config.FeignConfiguration;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -14,7 +13,8 @@ import org.springframework.web.bind.annotation.GetMapping;
  * @date 2022-04-29
  */
 
-@FeignClient(name = AppConstant.APPLICATION_CMS + AppConstant.SERVER, configuration = FeignConfiguration.class, fallback = CmsFeignServiceFallback.class)
+@FeignClient(name = "${app-config.open-feign.cms-server.name:cms-server}", url = "${app-config.open-feign.cms-server.url:}",
+        configuration = FeignConfiguration.class, fallback = CmsFeignServiceFallback.class)
 public interface CmsFeignService {
 
     /**

+ 2 - 4
cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/MallAdminFeignService.java

@@ -1,19 +1,17 @@
 package com.yonge.cooleshow.api.feign;
 
 import com.yonge.cooleshow.api.feign.fallback.MallAdminFeignServiceFallback;
-import com.yonge.cooleshow.common.constant.AppConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.feign.config.FeignConfiguration;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.ResponseBody;
 
 import java.util.List;
 import java.util.Map;
 
-@FeignClient(name = AppConstant.APPLICATION_MALL_ADMIN + AppConstant.SERVER, configuration = FeignConfiguration.class,
-        fallback = MallAdminFeignServiceFallback.class)
+@FeignClient(name = "${app-config.open-feign.mall-admin-server.name:mall-admin-server}", url = "${app-config.open-feign.mall-admin-server.url:}",
+        configuration = FeignConfiguration.class, fallback = MallAdminFeignServiceFallback.class)
 public interface MallAdminFeignService {
 
 

+ 2 - 3
cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/MallPortalFeignService.java

@@ -1,14 +1,13 @@
 package com.yonge.cooleshow.api.feign;
 
 import com.yonge.cooleshow.api.feign.fallback.MallPortalFeignServiceFallback;
-import com.yonge.cooleshow.common.constant.AppConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.feign.config.FeignConfiguration;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 
-@FeignClient(name = AppConstant.APPLICATION_MALL_PORTAL + AppConstant.SERVER, configuration = FeignConfiguration.class,
-        fallback = MallPortalFeignServiceFallback.class)
+@FeignClient(name = "${app-config.open-feign.mall-portal-server.name:mall-portal-server}", url = "${app-config.open-feign.mall-portal-server.url:}",
+        configuration = FeignConfiguration.class, fallback = MallPortalFeignServiceFallback.class)
 public interface MallPortalFeignService {
 
     /**

+ 2 - 5
cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/StudentFeignService.java

@@ -1,16 +1,13 @@
 package com.yonge.cooleshow.api.feign;
 
-import com.yonge.cooleshow.api.feign.dto.StudentWrapper;
 import com.yonge.cooleshow.api.feign.fallback.StudentFeignServiceFallback;
-import com.yonge.cooleshow.common.constant.AppConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.feign.config.FeignConfiguration;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
 
-@FeignClient(name = AppConstant.APPLICATION_STUDENT + AppConstant.SERVER, configuration = FeignConfiguration.class, fallback = StudentFeignServiceFallback.class)
+@FeignClient(name = "${app-config.open-feign.student-server.name:student-server}", url = "${app-config.open-feign.student-server.url:}",
+        configuration = FeignConfiguration.class, fallback = StudentFeignServiceFallback.class)
 public interface StudentFeignService {
 
     /***

+ 2 - 2
cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/TeacherFeignService.java

@@ -1,14 +1,14 @@
 package com.yonge.cooleshow.api.feign;
 
 import com.yonge.cooleshow.api.feign.fallback.TeacherFeignServiceFallback;
-import com.yonge.cooleshow.common.constant.AppConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.feign.config.FeignConfiguration;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 
-@FeignClient(name = AppConstant.APPLICATION_TEACHER + AppConstant.SERVER, configuration = FeignConfiguration.class, fallback = TeacherFeignServiceFallback.class)
+@FeignClient(name = "${app-config.open-feign.teacher-server.name:teacher-server}", url = "${app-config.open-feign.teacher-server.url:}",
+        configuration = FeignConfiguration.class, fallback = TeacherFeignServiceFallback.class)
 public interface TeacherFeignService {
 
     /***

+ 2 - 3
cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/TenantFeignService.java

@@ -1,13 +1,12 @@
 package com.yonge.cooleshow.api.feign;
 
 import com.yonge.cooleshow.api.feign.fallback.AdminFeignServiceFallback;
-import com.yonge.cooleshow.common.constant.AppConstant;
 import com.yonge.toolset.feign.config.FeignConfiguration;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 
-@FeignClient(name = AppConstant.APPLICATION_TENANT + AppConstant.SERVER, configuration = FeignConfiguration.class,
-        fallback = AdminFeignServiceFallback.class)
+@FeignClient(name = "${app-config.open-feign.tenant-server.name:tenant-server}", url="${app-config.open-feign.tenant-server.url:}",
+        configuration = FeignConfiguration.class, fallback = AdminFeignServiceFallback.class)
 public interface TenantFeignService {
 
     //机构人员汇总

+ 60 - 0
cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/properties/OpenFeignConfigProperties.java

@@ -0,0 +1,60 @@
+package com.yonge.cooleshow.api.feign.properties;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
+import org.springframework.context.annotation.Configuration;
+
+import java.io.Serializable;
+
+/**
+ * OpenFeign配置
+ * Created by Eric.Shang on 2023/2/8.
+ */
+@ConfigurationProperties(prefix = "app-config.open-feign")
+@Configuration
+@Data
+public class OpenFeignConfigProperties {
+
+    @ApiModelProperty("授权服务")
+    @NestedConfigurationProperty
+    private ServerConfig authServer;
+
+    @ApiModelProperty("内容管理服务")
+    @NestedConfigurationProperty
+    private ServerConfig cmsServer;
+
+    @ApiModelProperty("后台管理服务")
+    @NestedConfigurationProperty
+    private ServerConfig adminServer;
+
+    @ApiModelProperty("商城后台服务")
+    @NestedConfigurationProperty
+    private ServerConfig mallAdminServer;
+
+    @ApiModelProperty("商城服务")
+    @NestedConfigurationProperty
+    private ServerConfig mallPortalServer;
+
+    @ApiModelProperty("学生服务")
+    @NestedConfigurationProperty
+    private ServerConfig studentServer;
+
+    @ApiModelProperty("老师服务")
+    @NestedConfigurationProperty
+    private ServerConfig teacherServer;
+
+    @ApiModelProperty("机构服务")
+    @NestedConfigurationProperty
+    private ServerConfig tenantServer;
+
+    @Data
+    @ApiModel("OpenFeign服务配置")
+    public static class ServerConfig implements Serializable {
+
+        private String name;
+        private String url;
+    }
+}

+ 90 - 0
cooleshow-app/pom.xml

@@ -0,0 +1,90 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.yonge.cooleshow</groupId>
+        <artifactId>cooleshow</artifactId>
+        <version>1.0</version>
+    </parent>
+    <artifactId>cooleshow-app</artifactId>
+    <packaging>jar</packaging>
+    <name>${project.artifactId}</name>
+    <url>http://maven.apache.org</url>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-security</artifactId>
+        </dependency>
+
+        <!-- swagger-spring-boot -->
+        <dependency>
+            <groupId>com.spring4all</groupId>
+            <artifactId>swagger-spring-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.yonge.toolset</groupId>
+            <artifactId>audit-log</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.yonge.toolset</groupId>
+            <artifactId>thirdparty-component</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.yonge.cooleshow</groupId>
+            <artifactId>user-biz</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.whvcse</groupId>
+            <artifactId>easy-captcha</artifactId>
+            <version>1.6.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security.oauth</groupId>
+            <artifactId>spring-security-oauth2</artifactId>
+            <version>2.3.3.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>com.yonge.toolset</groupId>
+            <artifactId>utils</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.1.6.RELEASE</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 22 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/AppServerApplication.java

@@ -0,0 +1,22 @@
+package com.yonge.cooleshow;
+
+import com.yonge.cooleshow.config.AppBeanNameGenerator;
+import com.yonge.toolset.base.BaseApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * 后端服务
+ * Created by Eric.Shang on 2022/11/2.
+ */
+@SpringBootApplication
+public class AppServerApplication {
+
+    public static void main(String[] args) {
+        //SpringApplication.run(AppServerApplication.class, args);
+        //BaseApplication.run(AppConstant.APPLICATION_ADMIN, AppServerApplication.class, args);
+
+         BaseApplication.createSpringApplicationBuilder("cooleshow-app", AppServerApplication.class, args)
+                 .beanNameGenerator(new AppBeanNameGenerator())
+                 .run(args);
+    }
+}

+ 167 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ActivityEvaluationController.java

@@ -0,0 +1,167 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.admin.io.request.ActivityTeacherVO;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.ActivityEvaluationDto;
+import com.yonge.cooleshow.biz.dal.dto.activity.ActivityTeacherQuery;
+import com.yonge.cooleshow.biz.dal.dto.search.ActivityEvaluationSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.MusicSheetSearch;
+import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
+import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationService;
+import com.yonge.cooleshow.biz.dal.vo.ActivityEvaluationVo;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
+import com.yonge.cooleshow.biz.dal.vo.activity.ActivityTeacherWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.commons.collections.CollectionUtils;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Objects;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/activityEvaluation")
+@Api(value = "评测活动表", tags = "评测活动表")
+public class ActivityEvaluationController extends BaseController {
+
+    @Autowired
+    private ActivityEvaluationService activityEvaluationService;
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入activityEvaluationSearch")
+	@PreAuthorize("@pcs.hasPermissions('activityEvaluation/page')")
+	public HttpResponseResult<PageInfo<ActivityEvaluationVo>> page(@RequestBody ActivityEvaluationSearch query) {
+		IPage<ActivityEvaluationVo> pages = activityEvaluationService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+
+	@PostMapping("/list")
+	@ApiOperation(value = "查询列表", notes = "传入activityEvaluationSearch")
+	@PreAuthorize("@pcs.hasPermissions('activityEvaluation/list')")
+	public HttpResponseResult<List<ActivityEvaluationVo>> selectAll(@RequestBody ActivityEvaluationSearch query) {
+		List<ActivityEvaluationVo> list = activityEvaluationService.selectAll(query);
+		return succeed(list);
+	}
+    
+    /**
+	 * 批量增加曲目
+	 */
+	@PostMapping("/addBatch")
+	@ApiOperation(value = "批量增加曲目")
+	@PreAuthorize("@pcs.hasPermissions('activityEvaluation/addBatch')")
+	public HttpResponseResult addBatch(@Valid @RequestBody ActivityEvaluationDto param) {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null || null == user.getId()) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+    	return status(activityEvaluationService.addBatch(param,user));
+	}
+
+	@ApiOperation(value = "批量更新曲目信息")
+	@PostMapping("/batchUpdate")
+	public HttpResponseResult<Boolean> batchUpdateEvaluationInfo(@Valid @RequestBody ActivityEvaluationDto info) {
+
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null || null == user.getId()) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+
+		if (CollectionUtils.isEmpty(info.getEvaluationInfos())) {
+			return failed("评测曲目信息为空");
+		}
+
+		for (ActivityEvaluationDto.EvaluationInfo item : info.getEvaluationInfos()) {
+
+			if (Objects.isNull(item.getId())
+					|| Objects.isNull(item.getEvaluationDifficulty())) {
+				return failed("无效的请求参数");
+			}
+
+			item.updateBy(user.getId()).updateTime(DateTime.now().toDate());
+		}
+
+		// 批量更新曲目信息
+		int ret = activityEvaluationService.batchUpdateEvaluationInfo(user, info);
+
+		return status(ret > 0);
+	}
+
+ 	/**
+	 * 删除
+	 */
+	@PostMapping("/remove")
+	@ApiOperation(value = "删除", notes = "传入ids")
+	@PreAuthorize("@pcs.hasPermissions('activityEvaluation/remove')")
+	public HttpResponseResult remove(
+			@ApiParam(value = "主键集合", required = true)
+			@RequestParam(value = "ids") String ids) {
+        if (StringUtil.isEmpty(ids)) {
+			return failed("参数不能为空");
+		}
+		return status(activityEvaluationService.removeByIds(StringUtil.toLongList(ids)));
+	}
+
+
+	@ApiOperation(value = "分页查询曲目", httpMethod="POST", consumes="application/json", produces="application/json")
+	@PostMapping(value="/musicPage", consumes="application/json", produces="application/json")
+	@PreAuthorize("@pcs.hasPermissions('activityEvaluation/musicPage')")
+	public HttpResponseResult<PageInfo<MusicSheetVo>> musicPage(@RequestBody MusicSheetSearch query) {
+		if(null == query.getActivityId()){
+			return failed("活动id不能为空");
+		}
+		query.setAuditStatus(AuthStatusEnum.PASS);
+		query.setState(YesOrNoEnum.YES);
+		query.setAuditVersion(YesOrNoEnum.NO);
+		IPage<MusicSheetVo> musicSheetVoIPage = activityEvaluationService.musicPage(PageUtil.getPage(query), query);
+		return succeed(PageUtil.pageInfo(musicSheetVoIPage));
+	}
+
+	/**
+	 * 分享活动老师信息
+	 * @param request ActivityTeacherInfoRequest
+	 * @return HttpResponseResult<PageInfo<ActivityTeacherResponse>>
+	 */
+	@ApiOperation(value = "分页查询活动老师信息", httpMethod="POST", consumes="application/json", produces="application/json")
+	@PostMapping(value="/teachers", consumes="application/json", produces="application/json")
+	public HttpResponseResult<PageInfo<ActivityTeacherVO.ResponseInfo>> activityTeacherPageInfo(@RequestBody ActivityTeacherVO.RequestInfo request) {
+
+		if(Objects.isNull(request.getActivityId())){
+			return failed("活动id不能为空");
+		}
+
+		// 老师信息
+		IPage<ActivityTeacherWrapper> wrapper = activityEvaluationService.activityTeacherPageInfo(PageUtil.getPage(request),
+				ActivityTeacherQuery.from(request.jsonString()));
+
+		// 数据转换
+		List<ActivityTeacherVO.ResponseInfo> responses = JSON.parseArray(JSON.toJSONString(wrapper.getRecords()),
+				ActivityTeacherVO.ResponseInfo.class);
+
+		// 分页数据信息
+		return succeed(PageUtil.getPageInfo(wrapper, responses));
+	}
+}

+ 51 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ActivityEvaluationRecordController.java

@@ -0,0 +1,51 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.search.ActivityEvaluationRecordSearch;
+import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationRecordService;
+import com.yonge.cooleshow.biz.dal.vo.ActivityEvaluationRecordVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/activityEvaluationRecord")
+@Api(value = "评测活动参与记录表", tags = "评测活动参与记录表")
+public class ActivityEvaluationRecordController extends BaseController {
+
+    @Autowired
+    private ActivityEvaluationRecordService activityEvaluationRecordService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    @PreAuthorize("@pcs.hasPermissions('activityEvaluationRecord/detail')")
+    public HttpResponseResult<ActivityEvaluationRecordVo> detail(@PathVariable("id") Long id) {
+    	return succeed(activityEvaluationRecordService.detail(id));
+	}
+    
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入activityEvaluationRecordSearch")
+    @PreAuthorize("@pcs.hasPermissions('activityEvaluationRecord/page')")
+    public HttpResponseResult<PageInfo<ActivityEvaluationRecordVo>> page(@RequestBody ActivityEvaluationRecordSearch query) {
+		IPage<ActivityEvaluationRecordVo> pages = activityEvaluationRecordService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+
+}

+ 150 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ActivityPlanController.java

@@ -0,0 +1,150 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.ActivityPlanDto;
+import com.yonge.cooleshow.biz.dal.dto.SaveOrUpdateRewardDto;
+import com.yonge.cooleshow.biz.dal.dto.search.ActivityPlanSearch;
+import com.yonge.cooleshow.biz.dal.entity.ActivityPlan;
+import com.yonge.cooleshow.biz.dal.service.ActivityPlanService;
+import com.yonge.cooleshow.biz.dal.vo.ActivityPlanVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.ActivityTypeEnum;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.util.CollectionUtils;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/activityPlan")
+@Api(value = "活动计划表", tags = "活动计划表")
+public class ActivityPlanController extends BaseController {
+
+    @Autowired
+    private ActivityPlanService activityPlanService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    @PreAuthorize("@pcs.hasPermissions('activityPlan/detail')")
+    public HttpResponseResult<ActivityPlanVo> detail(@PathVariable("id") Long id) {
+        return succeed(activityPlanService.detail(id));
+    }
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入activityPlanSearch")
+    @PreAuthorize("@pcs.hasPermissions('activityPlan/page')")
+    public HttpResponseResult<PageInfo<ActivityPlanVo>> page(@RequestBody ActivityPlanSearch query) {
+        IPage<ActivityPlanVo> pages = activityPlanService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    /**
+     * 新增或修改
+     */
+    @PostMapping("/submit")
+    @ApiOperation(value = "新增或修改", notes = "传入activityPlan")
+    @PreAuthorize("@pcs.hasPermissions('activityPlan/submit')")
+    public HttpResponseResult<ActivityPlan> submit(@Valid @RequestBody ActivityPlanDto activityPlan) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        activityPlan.setUserId(user.getId());
+
+        // 分享活动奖品校验
+        if (ActivityTypeEnum.SHARE == activityPlan.getActivityType()
+                && CollectionUtils.isEmpty(activityPlan.getRewardItems())) {
+            return failed("分享活动奖品信息为空");
+        }
+
+        try {
+            return HttpResponseResult.succeed(activityPlanService.submit(activityPlan));
+        } catch (BizException e) {
+            return HttpResponseResult.failed(e.getMessage());
+        } catch (Exception e) {
+            e.printStackTrace();
+            return HttpResponseResult.failed("变更失败");
+        }
+    }
+
+    /**
+     * 启用/停用
+     */
+    @GetMapping("/updateActivityState")
+    @ApiOperation(value = "启用/停用")
+    @PreAuthorize("@pcs.hasPermissions('activityPlan/updateActivityState')")
+    public HttpResponseResult updateActivityState(
+            @ApiParam(value = "活动id", required = true) @RequestParam("activityId") Long activityId,
+            @ApiParam(value = "活动状态 0 停用 1 启用", required = true) @RequestParam("activityState") Integer activityState) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return status(activityPlanService.updateActivityState(activityId, activityState, user.getId()));
+    }
+
+    /**
+     * 草稿/正式
+     */
+    @GetMapping("/updateDraftFlag")
+    @ApiOperation(value = "草稿/正式")
+    @PreAuthorize("@pcs.hasPermissions('activityPlan/updateDraftFlag')")
+    public HttpResponseResult updateDraftFlag(
+            @ApiParam(value = "活动id", required = true) @RequestParam("activityId") Long activityId,
+            @ApiParam(value = "创建状态 0 正式 1 草稿 ", required = true) @RequestParam("draftFlag") Integer draftFlag) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return status(activityPlanService.updateDraftFlag(activityId, draftFlag, user.getId()));
+    }
+
+    /**
+     * 修改奖品
+     */
+    @PostMapping("/saveOrUpdateReward")
+    @ApiOperation(value = "修改奖品")
+    @PreAuthorize("@pcs.hasPermissions('activityPlan/saveOrUpdateReward')")
+    public HttpResponseResult saveOrUpdateReward(@Validated @RequestBody SaveOrUpdateRewardDto saveOrUpdateRewardDto) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        try {
+            return HttpResponseResult.succeed(activityPlanService.saveOrUpdateReward(saveOrUpdateRewardDto));
+        } catch (BizException e) {
+            return HttpResponseResult.failed(e.getMessage());
+        } catch (Exception e) {
+            e.printStackTrace();
+            return HttpResponseResult.failed("变更失败");
+        }
+    }
+}

+ 53 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ActivityRegistrationController.java

@@ -0,0 +1,53 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.search.ActivityRegistrationSearch;
+import com.yonge.cooleshow.biz.dal.service.ActivityRegistrationService;
+import com.yonge.cooleshow.biz.dal.vo.ActivityRegistrationVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/activityRegistration")
+@Api(value = "活动报名表", tags = "活动报名表")
+public class ActivityRegistrationController extends BaseController {
+
+    @Autowired
+    private ActivityRegistrationService activityRegistrationService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    @PreAuthorize("@pcs.hasPermissions('activityRegistration/detail')")
+    public HttpResponseResult<ActivityRegistrationVo> detail(@PathVariable("id") Long id) {
+    	return succeed(activityRegistrationService.detail(id));
+	}
+    
+    /**
+     * 参与名单
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入activityRegistrationSearch")
+    @PreAuthorize("@pcs.hasPermissions('activityRegistration/page')")
+    public HttpResponseResult<PageInfo<ActivityRegistrationVo>> page(@Valid @RequestBody ActivityRegistrationSearch query) {
+		IPage<ActivityRegistrationVo> pages = activityRegistrationService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+
+}

+ 162 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ActivityRewardController.java

@@ -0,0 +1,162 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.ActivityRewardDto;
+import com.yonge.cooleshow.biz.dal.dto.search.ActivityRewardChangeStockSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.ActivityRewardSearch;
+import com.yonge.cooleshow.biz.dal.entity.ActivityRewardChangeStock;
+import com.yonge.cooleshow.biz.dal.service.ActivityRewardService;
+import com.yonge.cooleshow.biz.dal.vo.ActivityRewardChangeStockVo;
+import com.yonge.cooleshow.biz.dal.vo.ActivityRewardVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.RewardTypeEnum;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Optional;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/activityReward")
+@Api(value = "活动奖品表", tags = "活动奖品表")
+public class ActivityRewardController extends BaseController {
+
+    @Autowired
+    private ActivityRewardService activityRewardService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    /**
+     * 通过奖品id查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "通过奖品id查询单条", notes = "传入id")
+    @PreAuthorize("@pcs.hasPermissions('activityReward/detail')")
+    public HttpResponseResult<ActivityRewardVo> detail(@PathVariable("id") Long id) {
+        return succeed(activityRewardService.detail(id));
+    }
+
+    /**
+     * 通过活动id查询单条(弃用)
+     */
+    @GetMapping("/detailByActivityId/{id}")
+    @ApiOperation(value = "通过活动id查询单条(弃用)", notes = "传入id")
+    @PreAuthorize("@pcs.hasPermissions('activityReward/detailByActivityId')")
+    public HttpResponseResult<ActivityRewardVo> detailByActivityId(@PathVariable("id") Long id) {
+        return succeed(activityRewardService.detailByActivityId(id));
+    }
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入activityRewardSearch")
+    @PreAuthorize("@pcs.hasPermissions('activityReward/page')")
+    public HttpResponseResult<PageInfo<ActivityRewardVo>> page(@RequestBody ActivityRewardSearch query) {
+        IPage<ActivityRewardVo> pages = activityRewardService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    /**
+     * 查询列表
+     */
+    @PostMapping("/list")
+    @ApiOperation(value = "查询列表", notes = "传入activityRewardSearch")
+    @PreAuthorize("@pcs.hasPermissions('activityReward/list')")
+    public HttpResponseResult<List<ActivityRewardVo>> list(@RequestBody ActivityRewardSearch query) {
+        List<ActivityRewardVo> list = activityRewardService.selectAll(query);
+        return succeed(list);
+    }
+
+    /**
+     * 新增或修改
+     */
+    @PostMapping("/submit")
+    @ApiOperation(value = "新增或修改", notes = "传入activityReward")
+    @PreAuthorize("@pcs.hasPermissions('activityReward/submit')")
+    public HttpResponseResult submit(@Valid @RequestBody ActivityRewardDto activityReward) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        // 校验请求参数
+        if (RewardTypeEnum.COUPON == activityReward.getRewardType()
+                && Optional.ofNullable(activityReward.getCouponId()).orElse(0L) <= 0) {
+            return failed("无效的优惠券ID");
+        }
+
+        return status(activityRewardService.submit(activityReward, user));
+    }
+
+    /**
+     * 启用/停用
+     */
+    @GetMapping("/updateStatus")
+    @ApiOperation(value = "启用/停用")
+    @PreAuthorize("@pcs.hasPermissions('activityReward/updateStatus')")
+    public HttpResponseResult updateStatus(
+            @ApiParam(value = "活动id", required = true) @RequestParam("id") Long id,
+            @ApiParam(value = "活动状态 0 停用 1 启用", required = true) @RequestParam("status") Integer status) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return status(activityRewardService.updateStatus(id, status, user.getId()));
+    }
+
+    /**
+     * 调整库存
+     */
+    @PostMapping("/updateStock")
+    @ApiOperation(value = "调整库存")
+    @PreAuthorize("@pcs.hasPermissions('activityReward/updateStock')")
+    public HttpResponseResult updateStock(@RequestBody ActivityRewardChangeStock activityRewardChangeStock) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        activityRewardChangeStock.setCreateBy(user.getId());
+        activityRewardChangeStock.setSource("ADMIN");
+        try {
+            activityRewardService.updateStock(activityRewardChangeStock);
+            return HttpResponseResult.succeed();
+        } catch (BizException e) {
+            return HttpResponseResult.failed(e.getMessage());
+        } catch (Exception e) {
+            e.printStackTrace();
+            return HttpResponseResult.failed("变更失败");
+        }
+    }
+
+    /**
+     * 库存变更记录查询分页
+     */
+    @PostMapping("/selectChangeStockPage")
+    @ApiOperation(value = "库存变更记录查询分页", notes = "传入activityRewardChangeStockSearch")
+    @PreAuthorize("@pcs.hasPermissions('activityReward/selectChangeStockPage')")
+    public HttpResponseResult<PageInfo<ActivityRewardChangeStockVo>> selectChangeStockPage(@RequestBody ActivityRewardChangeStockSearch query) {
+        query.setSource("ADMIN");
+        IPage<ActivityRewardChangeStockVo> pages = activityRewardService.selectChangeStockPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+}

+ 53 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ActivityUserRewardController.java

@@ -0,0 +1,53 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.search.ActivityUserRewardSearch;
+import com.yonge.cooleshow.biz.dal.service.ActivityUserRewardService;
+import com.yonge.cooleshow.biz.dal.vo.ActivityUserRewardVo;
+import com.yonge.cooleshow.biz.dal.vo.UserRewardVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/activityUserReward")
+@Api(value = "活动用户获奖表", tags = "活动用户获奖表")
+public class ActivityUserRewardController extends BaseController {
+
+    @Autowired
+    private ActivityUserRewardService activityUserRewardService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    @PreAuthorize("@pcs.hasPermissions('activityUserReward/detail')")
+    public HttpResponseResult<ActivityUserRewardVo> detail(@PathVariable("id") Long id) {
+    	return succeed(activityUserRewardService.detail(id));
+	}
+    
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入activityUserRewardSearch")
+    @PreAuthorize("@pcs.hasPermissions('activityUserReward/page')")
+    public HttpResponseResult<PageInfo<UserRewardVo>> page(@RequestBody @Valid ActivityUserRewardSearch query) {
+		IPage<UserRewardVo> pages = activityUserRewardService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+}

+ 164 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/AdminCourseGroupController.java

@@ -0,0 +1,164 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.LiveSaleOutDto;
+import com.yonge.cooleshow.biz.dal.dto.search.LiveCourseGroupSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.LiveCourseGroupStudentCourseSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.LiveCourseGroupStudentSearch;
+import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
+import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
+import com.yonge.cooleshow.biz.dal.vo.LiveCourseGroupPlanVo;
+import com.yonge.cooleshow.biz.dal.vo.LiveCourseGroupStudentCourseVo;
+import com.yonge.cooleshow.biz.dal.vo.LiveCourseGroupStudentVo;
+import com.yonge.cooleshow.biz.dal.vo.LiveCourseGroupVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 课程组表(CourseGroup)表控制层
+ *
+ * @author hgw
+ * @since 2022-03-18 15:29:10
+ */
+@Api(tags = "课程组表")
+@RestController
+@RequestMapping("${app-config.url.admin:}/courseGroup")
+public class AdminCourseGroupController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private CourseGroupService courseGroupService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation(value = "老师直播课列表", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/live/list", consumes="application/json", produces="application/json")
+    public HttpResponseResult<PageInfo<LiveCourseGroupVo>> teacherList(@Validated(value = LiveCourseGroupSearch.TeacherGroup.class)
+                                                                           @RequestBody LiveCourseGroupSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        query.setCourseType(CourseScheduleEnum.LIVE);
+
+        IPage<LiveCourseGroupVo> liveCourseGroupVoIPage = courseGroupService
+                .selectAdminLivePage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(liveCourseGroupVoIPage));
+    }
+
+
+    @ApiOperation(value = "学生直播课列表", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/live/list/student", consumes="application/json", produces="application/json")
+    public HttpResponseResult<PageInfo<LiveCourseGroupVo>> studentList(@Validated(value = LiveCourseGroupSearch.StudentGroup.class)
+                                                                           @RequestBody LiveCourseGroupSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        query.setCourseType(CourseScheduleEnum.LIVE);
+
+        IPage<LiveCourseGroupVo> liveCourseGroupVoIPage = courseGroupService
+                .selectAdminLivePage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(liveCourseGroupVoIPage));
+    }
+
+    @ApiOperation(value = "直播课详情")
+    @PostMapping(value="/detail/{courseGroupId}")
+    public HttpResponseResult<LiveCourseGroupVo> detail(@ApiParam(value = "课程组编号ID", required = true)
+                                                                   @PathVariable("courseGroupId") Long courseGroupId) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        if (courseGroupId == null) {
+            return failed("课程组id不能为空");
+        }
+
+        LiveCourseGroupVo liveCourseGroupVo = courseGroupService.detail(courseGroupId);
+        if (liveCourseGroupVo == null) {
+            return failed("没找到课程组信息");
+        }
+        return succeed(liveCourseGroupVo);
+    }
+
+
+    @ApiOperation(value = "直播课下架")
+    @PostMapping(value="/live/saleOut")
+    public HttpResponseResult<Boolean> liveSaleOut(@RequestBody @Valid LiveSaleOutDto dto) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        if (dto.getCourseGroupId() == null) {
+            return failed("课程组id不能为空");
+        }
+
+        return succeed(courseGroupService.liveSaleOut(dto));
+    }
+
+
+
+    @ApiOperation(value = "老师详情-直播课购买学员信息", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/live/student", consumes="application/json", produces="application/json")
+    public HttpResponseResult<PageInfo<LiveCourseGroupStudentVo>> student(@Valid @RequestBody LiveCourseGroupStudentSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        IPage<LiveCourseGroupStudentVo> liveCourseGroupVoIPage = courseGroupService
+                .selectAdminLiveStudentPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(liveCourseGroupVoIPage));
+    }
+
+
+    @ApiOperation(value = "老师详情-教学计划")
+    @PostMapping(value="/live/{courseGroupId}")
+    public HttpResponseResult<List<LiveCourseGroupPlanVo>> student(@ApiParam(value = "课程组编号ID", required = true)
+                                                                              @PathVariable("courseGroupId") Long courseGroupId) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        if (courseGroupId == null) {
+            return failed("课程组id不能为空");
+        }
+
+        return succeed(courseGroupService.selectAdminLivePlan(courseGroupId));
+    }
+
+
+    @ApiOperation(value = "学生详情-直播课详情-学生上课状态", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/live/student/course", consumes="application/json", produces="application/json")
+    public HttpResponseResult<PageInfo<LiveCourseGroupStudentCourseVo>> studentCourse(@Valid @RequestBody LiveCourseGroupStudentCourseSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        IPage<LiveCourseGroupStudentCourseVo> liveCourseGroupStudentCourseVoIPage = courseGroupService
+                .selectAdminLiveStudentCoursePage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(liveCourseGroupStudentCourseVoIPage));
+    }
+
+}
+

+ 112 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/AlbumFavoriteController.java

@@ -0,0 +1,112 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.AlbumFavoriteDto;
+import com.yonge.cooleshow.biz.dal.entity.AlbumFavorite;
+import com.yonge.cooleshow.biz.dal.service.AlbumFavoriteService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+/**
+ * 专辑收藏表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:45
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.admin:}/album/favorite")
+@Api(tags = "专辑收藏表 API接口")
+public class AlbumFavoriteController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+	@Autowired
+	private AlbumFavoriteService albumFavoriteService;
+
+	@ApiOperation(value = "新增", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/create", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> create(@Valid @RequestBody AlbumFavorite albumFavorite) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        //albumFavorite.setCreateBy(sysUser.getId());
+        //albumFavorite.setCreateTime(new Date());
+        albumFavoriteService.save(albumFavorite);
+        return succeed();
+    }
+
+    @ApiOperation(value = "删除", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping("/delete/{id}")
+    public Object delete(@PathVariable Long id) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        albumFavoriteService.removeById(id);
+        return succeed();
+    }
+
+    @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/update", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> update(@Valid @RequestBody AlbumFavorite albumFavorite) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        if (albumFavorite.getId()==null){
+            return failed("缺少ID");
+        }
+
+        //albumFavorite.setUpdateBy(sysUser.getId());
+        //albumFavorite.setUpdateTime(new Date());
+        albumFavoriteService.updateById(albumFavorite);
+        return succeed();
+    }
+
+    @ApiOperation(value = "分页查询", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/list", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> list(@RequestBody AlbumFavoriteDto albumFavoriteDto) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        int pageNo = albumFavoriteDto.getPageNo();
+        int pageSize = albumFavoriteDto.getPageSize();
+
+        try {
+            if (pageNo==0) {
+                pageNo = 1;
+            }
+            if (pageSize==0) {
+                pageSize = 10;
+            }
+
+            LambdaQueryWrapper<AlbumFavorite> lambdaQueryWrapper = Wrappers.lambdaQuery();
+            //lambdaQueryWrapper.like(AlbumFavorite::getName , "k");
+
+            Page<AlbumFavorite> page = new Page<>(pageNo,pageSize);
+            return succeed(albumFavoriteService.page(page, lambdaQueryWrapper));
+        } catch (Exception e) {
+            e.printStackTrace();
+            return HttpResponseResult.failed(e.getMessage());
+        }
+    }
+}

+ 112 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/AlbumMusicRelateController.java

@@ -0,0 +1,112 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.AlbumMusicRelateDto;
+import com.yonge.cooleshow.biz.dal.entity.AlbumMusicRelate;
+import com.yonge.cooleshow.biz.dal.service.AlbumMusicRelateService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+/**
+ * 专辑曲谱关联表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.admin:}/album/music/relate")
+@Api(tags = "专辑曲谱关联表 API接口")
+public class AlbumMusicRelateController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+	@Autowired
+	private AlbumMusicRelateService albumMusicRelateService;
+
+	@ApiOperation(value = "新增", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/create", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> create(@Valid @RequestBody AlbumMusicRelate albumMusicRelate) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        //albumMusicRelate.setCreateBy(sysUser.getId());
+        //albumMusicRelate.setCreateTime(new Date());
+        albumMusicRelateService.save(albumMusicRelate);
+        return succeed();
+    }
+
+    @ApiOperation(value = "删除", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping("/delete/{id}")
+    public Object delete(@PathVariable Long id) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        albumMusicRelateService.removeById(id);
+        return succeed();
+    }
+
+    @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/update", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> update(@Valid @RequestBody AlbumMusicRelate albumMusicRelate) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        if (albumMusicRelate.getId()==null){
+            return failed("缺少ID");
+        }
+
+        //albumMusicRelate.setUpdateBy(sysUser.getId());
+        //albumMusicRelate.setUpdateTime(new Date());
+        albumMusicRelateService.updateById(albumMusicRelate);
+        return succeed();
+    }
+
+    @ApiOperation(value = "分页查询", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/list", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> list(@RequestBody AlbumMusicRelateDto albumMusicRelateDto) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        int pageNo = albumMusicRelateDto.getPageNo();
+        int pageSize = albumMusicRelateDto.getPageSize();
+
+        try {
+            if (pageNo==0) {
+                pageNo = 1;
+            }
+            if (pageSize==0) {
+                pageSize = 10;
+            }
+
+            LambdaQueryWrapper<AlbumMusicRelate> lambdaQueryWrapper = Wrappers.lambdaQuery();
+            //lambdaQueryWrapper.like(AlbumMusicRelate::getName , "k");
+
+            Page<AlbumMusicRelate> page = new Page<>(pageNo,pageSize);
+            return succeed(albumMusicRelateService.page(page, lambdaQueryWrapper));
+        } catch (Exception e) {
+            e.printStackTrace();
+            return HttpResponseResult.failed(e.getMessage());
+        }
+    }
+}

+ 72 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/AppVersionInfoController.java

@@ -0,0 +1,72 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.yonge.cooleshow.biz.dal.entity.AppVersionInfo;
+import com.yonge.cooleshow.biz.dal.queryInfo.AppVersionInfoQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RequestMapping("${app-config.url.admin:}/appVersionInfo")
+@Api(tags = "APP版本信息服务")
+@RestController
+public class AppVersionInfoController extends BaseController {
+
+	@Autowired
+	private AppVersionInfoService appVersionInfoService;
+
+	@ApiOperation("分页查询")
+	@GetMapping(value = "/list")
+	@PreAuthorize("@pcs.hasPermissions('appVersionInfo/list')")
+	public HttpResponseResult<PageInfo<AppVersionInfo>> getList(AppVersionInfoQueryInfo queryInfo) {
+		return succeed(appVersionInfoService.queryPage(queryInfo));
+	}
+
+	@ApiOperation("根据app客户端查询对象")
+	@ApiImplicitParam(name = "platform", value = "平台名称", required = true, dataType = "String", paramType = "path")
+	@GetMapping(value = "/queryByPlatform")
+	public HttpResponseResult<AppVersionInfo> queryByPlatform(String platform) {
+		List<AppVersionInfo> list = appVersionInfoService.queryNewestByPlatform(platform);
+		if (list.size() > 0) {
+			return succeed(list.get(0));
+		}
+		return failed();
+	}
+
+	@ApiOperation("单查询")
+	@ApiImplicitParam(name = "id", value = "ID编号", required = true, dataType = "Integer", paramType = "path")
+	@GetMapping(value = "/query")
+	@PreAuthorize("@pcs.hasPermissions('appVersionInfo/query')")
+	public HttpResponseResult<AppVersionInfo> query(Long id) {
+		return succeed(appVersionInfoService.get(id));
+	}
+
+	@ApiOperation("新增")
+	@PostMapping(value = "/add", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	@PreAuthorize("@pcs.hasPermissions('appVersionInfo/add')")
+	public Object add(AppVersionInfo appVersionInfo) {
+		appVersionInfoService.add(appVersionInfo);
+		return succeed();
+	}
+
+	@ApiOperation("更新")
+	@PostMapping(value = "/update", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	@PreAuthorize("@pcs.hasPermissions('appVersionInfo/update')")
+	public Object update(AppVersionInfo appVersionInfo) {
+		appVersionInfoService.updateVersion(appVersionInfo);
+		return succeed();
+	}
+
+}

+ 99 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/AuditReasonController.java

@@ -0,0 +1,99 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.AuditReasonSearch;
+import com.yonge.cooleshow.biz.dal.entity.AuditReason;
+import com.yonge.cooleshow.biz.dal.service.AuditReasonService;
+import com.yonge.cooleshow.biz.dal.vo.AuditReasonVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.Date;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/auditReason")
+@Api(value = "审核原因表", tags = "审核原因表")
+public class AuditReasonController extends BaseController {
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private AuditReasonService auditReasonService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<AuditReasonVo> detail(@PathVariable("id") Long id) {
+    	return succeed(auditReasonService.detail(id));
+	}
+    
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入auditReasonSearch")
+    public HttpResponseResult<PageInfo<AuditReasonVo>> page(@RequestBody AuditReasonSearch query) {
+		IPage<AuditReasonVo> pages = auditReasonService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+    
+    /**
+	 * 新增
+	 */
+	@PostMapping("/save")
+	@ApiOperation(value = "新增", notes = "传入auditReason")
+	public HttpResponseResult save(@Valid @RequestBody AuditReason auditReason) {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser == null  || sysUser.getId() == null) {
+			return failed("用户信息获取失败");
+		}
+		auditReason.setCreateBy(sysUser.getId());
+		auditReason.setCreateTime(new Date());
+		auditReason.setUpdateBy(sysUser.getId());
+		auditReason.setUpdateTime(new Date());
+    	return status(auditReasonService.save(auditReason));
+	}
+    
+    /**
+	 * 修改
+	 */
+	@PostMapping("/update")
+	@ApiOperation(value = "修改", notes = "传入auditReason")
+	public HttpResponseResult update(@Valid @RequestBody AuditReason auditReason) {
+
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser == null  || sysUser.getId() == null) {
+			return failed("用户信息获取失败");
+		}
+		auditReason.setUpdateBy(sysUser.getId());
+		auditReason.setUpdateTime(new Date());
+        return status(auditReasonService.updateById(auditReason));
+	}
+
+
+ 	/**
+	 * 删除
+	 */
+	@PostMapping("/remove/{id}")
+	@ApiOperation(value = "删除", notes = "传入ids")
+	public HttpResponseResult remove(@PathVariable Long id) {
+
+		return status(auditReasonService.del(id));
+	}
+}

+ 105 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ContractTemplateController.java

@@ -0,0 +1,105 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.ContractTemplateDto;
+import com.yonge.cooleshow.biz.dal.entity.ContractTemplate;
+import com.yonge.cooleshow.biz.dal.queryInfo.ContractTemplateQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.ContractTemplateService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.ContractTemplateSourceEnum;
+import com.yonge.cooleshow.common.enums.ContractTemplateTypeEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RequestMapping("${app-config.url.admin:}/contractTemplate")
+@Api(tags = "协议模板")
+@RestController
+public class ContractTemplateController extends BaseController {
+
+	@Autowired
+	private ContractTemplateService contractTemplateService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+	@ApiOperation("分页查询")
+	@GetMapping(value = "/list")
+	@PreAuthorize("@pcs.hasPermissions('contractTemplate/list')")
+	public HttpResponseResult<PageInfo<ContractTemplateDto>> getList(ContractTemplateQueryInfo queryInfo) {
+		queryInfo.setSource(ContractTemplateSourceEnum.PLATFORM.getCode());
+		return succeed(contractTemplateService.queryPageList(queryInfo));
+	}
+
+	@ApiOperation("单查询")
+	@ApiImplicitParam(name = "id", value = "ID编号", required = true, dataType = "Integer", paramType = "path")
+	@GetMapping(value = "/query")
+	@PreAuthorize("@pcs.hasPermissions('contractTemplate/query')")
+	public HttpResponseResult<ContractTemplate> query(Integer id) {
+		return succeed(contractTemplateService.get(id));
+	}
+
+	@ApiOperation("查询最新启用的协议模板")
+	@GetMapping(value = "/queryLatestContractTemplate")
+	@PreAuthorize("@pcs.hasPermissions('contractTemplate/queryLatestContractTemplate')")
+	public HttpResponseResult<ContractTemplate> queryLatestContractTemplate(@ApiParam(value = "业务类型 REGISTER 注册 COURSES 课程购买 PRODUCT 产品 WITHDRAW 结算", required = true) @RequestParam("contractType") ContractTemplateTypeEnum contractType) {
+		return succeed(contractTemplateService.queryLatestContractTemplate(contractType));
+	}
+
+	@ApiOperation("新增")
+	@PostMapping(value = "/add", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	@PreAuthorize("@pcs.hasPermissions('contractTemplate/add')")
+	public HttpResponseResult<Object> add(@RequestBody ContractTemplate contractTemplate) {
+		contractTemplate.setSource(ContractTemplateSourceEnum.PLATFORM.getCode());
+		if(StringUtil.isEmpty(contractTemplate.getType())){
+			contractTemplate.setType(ContractTemplateTypeEnum.BUY_ORDER.getCode());
+		}
+
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if(sysUser == null || sysUser.getId() == null){
+        	return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+		contractTemplate.setStatus(false);
+		contractTemplate.setModifyBy(sysUser.getId());
+		contractTemplateService.createContractTemplate(contractTemplate);
+		return succeed();
+	}
+
+	@ApiOperation("更新")
+	@PostMapping(value = "/update", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	@PreAuthorize("@pcs.hasPermissions('contractTemplate/update')")
+	public HttpResponseResult<Object> update(@RequestBody ContractTemplate contractTemplate) {
+		if(StringUtil.isEmpty(contractTemplate.getType())){
+			contractTemplate.setType(ContractTemplateTypeEnum.BUY_ORDER.getCode());
+		}
+		contractTemplateService.update(contractTemplate);
+		return succeed();
+	}
+
+	@ApiOperation("启用协议")
+	@PostMapping(value = "/updateStatus", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	@PreAuthorize("@pcs.hasPermissions('contractTemplate/updateStatus')")
+	public HttpResponseResult<Object> enableContract(int id) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        
+		contractTemplateService.enableContract(id, sysUser.getId());
+		return succeed();
+	}
+
+}

+ 83 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/CourseCoursewareController.java

@@ -0,0 +1,83 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.search.CourseCoursewareSearch;
+import com.yonge.cooleshow.biz.dal.entity.CourseCourseware;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.CourseCoursewareService;
+import com.yonge.cooleshow.biz.dal.vo.CourseCoursewareVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.Date;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/courseCourseware")
+@Api(value = "课件表", tags = "课件表")
+public class CourseCoursewareController extends BaseController {
+
+    @Autowired
+    private CourseCoursewareService courseCoursewareService;
+    
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入courseCoursewareSearch")
+    public HttpResponseResult<PageInfo<CourseCoursewareVo>> page(@RequestBody CourseCoursewareSearch query) {
+		IPage<CourseCoursewareVo> pages = courseCoursewareService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+    
+    /**
+	 * 新增或修改
+	 */
+    @PostMapping("/submit")
+    @ApiOperation(value = "新增或修改", notes = "传入courseCourseware")
+	public HttpResponseResult<CourseCourseware> submit(@Valid @RequestBody CourseCourseware courseCourseware) {
+		if (courseCourseware.getId() != null) {
+			courseCourseware.setUpdateTime(new Date());
+		} else {
+			courseCourseware.setUpdateTime(new Date());
+			courseCourseware.setCreateTime(new Date());
+		}
+		if (courseCourseware.getUserId() == null) {
+			throw new BizException("用户id不能为空");
+		}
+		courseCourseware.setClientType(ClientEnum.TEACHER);
+        return succeed(courseCoursewareService.submit(courseCourseware));
+    }
+
+ 	/**
+	 * 删除
+	 */
+	@PostMapping("/remove/{id}")
+	@ApiOperation(value = "删除", notes = "传入id")
+	public HttpResponseResult remove(@PathVariable Long id ) {
+		return status(courseCoursewareService.removeById(id));
+	}
+
+
+	/**
+	 * 删除
+	 */
+	@PostMapping("/remove")
+	@ApiOperation(value = "批量删除", notes = "传入id")
+	public HttpResponseResult remove(@RequestParam String ids ) {
+		return status(courseCoursewareService.removeByIds(StringUtil.toLongList(ids)));
+	}
+}

+ 228 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/CourseGroupController.java

@@ -0,0 +1,228 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.yonge.cooleshow.biz.dal.dto.search.CourseGroupDetailSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.CourseGroupSearch;
+import com.yonge.cooleshow.biz.dal.entity.VideoLessonGroupDetail;
+import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
+import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
+import com.yonge.cooleshow.biz.dal.vo.CourseGroupInfoVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseGroupLiveVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseGroupPianoDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseGroupPianoVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseGroupPracticeDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseGroupPracticeVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseGroupStudentVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseGroupVideoVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseSchedulePaymentVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseSchedulePlanVo;
+import com.yonge.cooleshow.biz.dal.vo.PianoRoomTimeVo;
+import com.yonge.cooleshow.biz.dal.vo.StudentSignVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @Author: cy
+ * @Date: 2022/5/19
+ */
+@RestController
+@RequestMapping("${app-config.url.admin:}/courseGroup")
+@Api(tags = "课程组")
+@Validated
+public class CourseGroupController extends BaseController {
+    @Autowired
+    private CourseGroupService courseGroupService;
+    @Autowired
+    private CourseScheduleService courseScheduleService;
+
+    @ApiOperation(value = "课程组管理-陪练课", notes = "{\n" +
+            "    \"subjectId\":20,\n" +
+            "    \"search\":\"师\",\n" +
+            "    \"status\":\"ING\"\n" +
+            "}")
+    @PostMapping(value = "/practice")
+    public HttpResponseResult<PageInfo<CourseGroupPracticeVo>> selectPracticeGroup(@RequestBody CourseGroupSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectPracticeGroup(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "课程组管理-陪练课-详情", notes = "{\n" +
+            "    \"courseGroupId\": 140,\n" +
+            "    \"teacherSign\": 0,\n" +
+            "    \"studentSign\": 0,\n" +
+            "    \"search\": \"游\",\n" +
+            "    \"status\": \"COMPLETE\",\n" +
+            "    \"salaryStatus\": \"NOT_START\",\n" +
+            "    \"startTime\": \"2022-05-21 08:00:00\",\n" +
+            "    \"endTime\": \"\"\n" +
+            "}")
+    @PostMapping(value = "/practice/detail")
+    public HttpResponseResult<PageInfo<CourseGroupPracticeDetailVo>> selectPracticeGroupDetail(@Validated @RequestBody CourseGroupDetailSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectPracticeGroupDetail(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "课程组管理-直播课", notes = "{\n" +
+            "    \"subjectId\":73,\n" +
+            "    \"search\":\"夏\",\n" +
+            "    \"status\":\"ING\"\n" +
+            "}")
+    @PostMapping(value = "/live")
+    public HttpResponseResult<PageInfo<CourseGroupLiveVo>> selectLiveGroup(@RequestBody CourseGroupSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectLiveGroup(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "课程组管理-直播课-购买学员", notes = "{\n" +
+            "    \"groupId\":140,\n" +
+            "    \"search\":\"游\",\n" +
+            "    \"orderNo\":\"22051615250800001\"\n" +
+            "}")
+    @PostMapping(value = "/live/studentPayment")
+    public HttpResponseResult<PageInfo<CourseSchedulePaymentVo>> selectLiveGroupStudent(@RequestBody CourseGroupSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectLiveGroupStudent(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "课程组管理-直播课-教学计划", notes = "{\n" +
+            "    \"groupId\":140,\n" +
+            "    \"courseId\":\"391\",\n" +
+            "    \"salaryStatus\":\"NOT_START\",\n" +
+            "    \"startTime\":\"2022-05-20 08:00:00\",\n" +
+            "    \"endTime\":null\n" +
+            "}")
+    @PostMapping(value = "/live/plan")
+    public HttpResponseResult<PageInfo<CourseSchedulePlanVo>> selectLiveGroupPlan(@RequestBody CourseGroupSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectLiveGroupPlan(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "课程组管理-视频课", notes = "{\n" +
+            "    \"subjectId\":21,\n" +
+            "    \"search\":\"老\"\n" +
+            "}")
+    @PostMapping(value = "/video")
+    public HttpResponseResult<PageInfo<CourseGroupVideoVo>> selectVideoGroup(@RequestBody CourseGroupSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectVideoGroup(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "课程组管理-视频课-购买学员", notes = "{\n" +
+            "    \"groupId\":51,\n" +
+            "    \"orderNo\":\"22050720002900001\",\n" +
+            "    \"search\":\"1\",\n" +
+            "    \"startTime\":\"2022-05-07 20:00:29\",\n" +
+            "    \"endTime\":null\n" +
+            "}")
+    @PostMapping(value = "/video/studentPayment")
+    public HttpResponseResult<PageInfo<CourseGroupStudentVo>> selectVideoGroupStudent(@RequestBody CourseGroupSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectVideoGroupStudent(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "课程组管理-视频课-教学计划", notes = "{\n" +
+            "    \"groupId\":18\n" +
+            "}")
+    @PostMapping(value = "/video/plan")
+    public HttpResponseResult<PageInfo<VideoLessonGroupDetail>> selectVideoGroupPlan(@RequestBody CourseGroupSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectVideoGroupPlan(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "课程组管理-直播课-课程信息")
+    @GetMapping(value = "/live/info")
+    public HttpResponseResult<CourseGroupInfoVo> selectLiveGroupInfo(@NotNull Long groupId) {
+        return succeed(courseGroupService.selectLiveGroupInfo(groupId));
+    }
+
+    @ApiOperation(value = "课程组管理-琴房课", notes = "{\n" +
+            "    \"subjectId\":20,\n" +
+            "    \"search\":\"师\",\n" +
+            "    \"status\":\"ING\"\n" +
+            "}")
+    @PostMapping(value = "/piano")
+    public HttpResponseResult<PageInfo<CourseGroupPianoVo>> selectPianoGroup(@RequestBody CourseGroupSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectPianoGroup(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "课程组管理-琴房课-详情", notes = "{\n" +
+            "    \"courseGroupId\":334,\n" +
+            "    \"search\":\"\",\n" +
+            "    \"status\":\"\",\n" +
+            "    \"startTime\":null,\n" +
+            "    \"endTime\":null,\n" +
+            "    \"teacherSign\":null,\n" +
+            "    \"studentSign\":null\n" +
+            "}")
+    @PostMapping(value = "/piano/detail")
+    public HttpResponseResult<PageInfo<CourseGroupPianoDetailVo>> selectPianoGroupDetail(@Validated @RequestBody CourseGroupDetailSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectPianoGroupDetail(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "课程组管理-琴房课-详情-学员名单")
+    @GetMapping(value = "/piano/student")
+    public HttpResponseResult<List<StudentSignVo>> studentSign(@NotNull Long courseId) {
+        return succeed(courseGroupService.studentSign(courseId, null));
+    }
+
+    @ApiOperation(value = "学员管理-琴房课", notes = "{\n" +
+            "    \"studentId\":20,\n" +
+            "    \"search\":\"师\",\n" +
+            "    \"status\":\"ING\"\n" +
+            "}")
+    @PostMapping(value = "/piano/student")
+    public HttpResponseResult<PageInfo<CourseGroupPianoVo>> selectPianoGroupStudent(@RequestBody CourseGroupSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectPianoGroupStudent(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "学员管理-琴房课-详情", notes = "{\n" +
+            "    \"studentId\":20,\n" +
+            "    \"courseGroupId\":334,\n" +
+            "    \"search\":\"\",\n" +
+            "    \"status\":\"\",\n" +
+            "    \"startTime\":null,\n" +
+            "    \"endTime\":null,\n" +
+            "    \"teacherSign\":0,\n" +
+            "    \"studentSign\":0\n" +
+            "}")
+    @PostMapping(value = "/piano/student/detail")
+    public HttpResponseResult<PageInfo<CourseGroupPianoDetailVo>> selectPianoGroupStudentDetail(@Validated @RequestBody CourseGroupDetailSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectPianoGroupStudentDetail(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation("查询琴房剩余时长、冻结时长、统计学员人数")
+    @GetMapping("/selectRemainTime")
+    public HttpResponseResult<PianoRoomTimeVo> selectRemainTime(Long teacherId) {
+        return succeed(courseScheduleService.selectRemainTime(teacherId));
+    }
+
+    @ApiOperation(value = "老师管理-琴房课", notes = "{\n" +
+            "    \"teacherId\":20,\n" +
+            "    \"search\":\"师\",\n" +
+            "    \"status\":\"ING\"\n" +
+            "}")
+    @PostMapping(value = "/piano/teacher")
+    public HttpResponseResult<PageInfo<CourseGroupPianoVo>> selectPianoGroupTeacher(@RequestBody CourseGroupSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectPianoGroupTeacher(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "老师管理-琴房课-详情", notes = "{\n" +
+            "    \"teacherId\":20,\n" +
+            "    \"courseGroupId\":334,\n" +
+            "    \"search\":\"\",\n" +
+            "    \"status\":\"\",\n" +
+            "    \"startTime\":null,\n" +
+            "    \"endTime\":null,\n" +
+            "    \"teacherSign\":0,\n" +
+            "    \"studentSign\":0\n" +
+            "}")
+    @PostMapping(value = "/piano/teacher/detail")
+    public HttpResponseResult<PageInfo<CourseGroupPianoDetailVo>> selectPianoGroupTeacherDetail(@Validated @RequestBody CourseGroupDetailSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectPianoGroupTeacherDetail(PageUtil.getPage(search), search)));
+    }
+}

+ 74 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/CourseHomeworkController.java

@@ -0,0 +1,74 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.yonge.cooleshow.biz.dal.dto.search.HomeworkAdminSearch;
+import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
+import com.yonge.cooleshow.biz.dal.service.CourseHomeworkService;
+import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
+import com.yonge.cooleshow.biz.dal.vo.CourseHomeworkDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseHomeworkVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/homework")
+@Api(value = "课程作业表", tags = "课程作业表")
+public class CourseHomeworkController extends BaseController {
+
+    @Autowired
+    private CourseHomeworkService courseHomeworkService;
+
+	@Autowired
+	private CourseScheduleService courseScheduleService;
+
+	@ApiOperation(value = "课后作业-列表", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+	@PostMapping(value = "/list", consumes = "application/json", produces = "application/json")
+	@PreAuthorize("@pcs.hasPermissions('homework/list')")
+	public HttpResponseResult<PageInfo<CourseHomeworkVo>> list(@Valid @RequestBody HomeworkAdminSearch query) {
+		query.setDecorate(YesOrNoEnum.YES);
+		query.setCourseStatus(CourseScheduleEnum.COMPLETE);
+
+		List<CourseScheduleEnum> list = new ArrayList<>();
+		list.add(CourseScheduleEnum.PIANO_ROOM_CLASS);
+		list.add(CourseScheduleEnum.PRACTICE);
+		query.setCourseType(list);
+		return succeed(PageUtil.pageInfo(courseHomeworkService.selectAdminPage(PageUtil.getPage(query),query)));
+	}
+
+
+	@ApiOperation(value = "课后作业-详情",notes = "传入课程编号ID")
+	@GetMapping(value = "/detail/{courseId}/{studentId}")
+	@PreAuthorize("@pcs.hasPermissions('homework/detail')")
+	public HttpResponseResult<CourseHomeworkDetailVo> detail(@ApiParam(value = "课程编号ID", required = true)
+															 @PathVariable("courseId") Long courseId,
+															 @PathVariable("studentId") Long studentId) {
+		return succeed(courseHomeworkService.getCourseHomeworkDetailByCourseId(courseId,studentId));
+	}
+
+
+
+	@PostMapping(value = "/teacherSend")
+	@ApiOperation(value = "发送老师未评价和未布置作业消息")
+	@PreAuthorize("@pcs.hasPermissions('homework/teacherSend')")
+	public HttpResponseResult<Object> sendTodayNotRepliedAndNotDecorateHomework() {
+		courseScheduleService.sendTodayNotRepliedAndNotDecorateHomework();
+		return HttpResponseResult.succeed();
+	}
+}

+ 92 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/CourseScheduleRepliedController.java

@@ -0,0 +1,92 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.search.CourseScheduleRepliedSearch;
+import com.yonge.cooleshow.biz.dal.entity.CourseScheduleReplied;
+import com.yonge.cooleshow.biz.dal.service.CourseScheduleRepliedService;
+import com.yonge.cooleshow.biz.dal.vo.CourseScheduleRepliedVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+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.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/courseScheduleReplied")
+@Api(value = "课程点评", tags = "课程点评")
+public class CourseScheduleRepliedController extends BaseController {
+
+    @Autowired
+    private CourseScheduleRepliedService courseScheduleRepliedService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<CourseScheduleRepliedVo> detail(@PathVariable("id") Long id) {
+    	return succeed(courseScheduleRepliedService.detail(id));
+	}
+    
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入courseScheduleRepliedSearch")
+    public HttpResponseResult<PageInfo<CourseScheduleRepliedVo>> page(@RequestBody CourseScheduleRepliedSearch query) {
+		IPage<CourseScheduleRepliedVo> pages = courseScheduleRepliedService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+    
+    /**
+	 * 新增
+	 */
+	@PostMapping("/save")
+	@ApiOperation(value = "新增", notes = "传入courseScheduleReplied")
+	public HttpResponseResult save(@Valid @RequestBody CourseScheduleReplied courseScheduleReplied) {
+    	return status(courseScheduleRepliedService.save(courseScheduleReplied));
+	}
+    
+    /**
+	 * 修改
+	 */
+	@PostMapping("/update")
+	@ApiOperation(value = "修改", notes = "传入courseScheduleReplied")
+	public HttpResponseResult update(@Valid @RequestBody CourseScheduleReplied courseScheduleReplied) {
+        return status(courseScheduleRepliedService.updateById(courseScheduleReplied));
+	}
+    
+    /**
+	 * 新增或修改
+	 */
+    @PostMapping("/submit")
+    @ApiOperation(value = "新增或修改", notes = "传入courseScheduleReplied")
+	public HttpResponseResult submit(@Valid @RequestBody CourseScheduleReplied courseScheduleReplied) {
+        return status(courseScheduleRepliedService.saveOrUpdate(courseScheduleReplied));
+    }
+
+ 	/**
+	 * 删除
+	 */
+	@PostMapping("/remove")
+	@ApiOperation(value = "删除", notes = "传入ids")
+	public HttpResponseResult remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+        if (StringUtil.isEmpty(ids)) {
+			return failed("参数不能为空");
+		}
+		return status(courseScheduleRepliedService.removeByIds(StringUtil.toLongList(ids)));
+	}
+}

+ 175 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/CustomerServiceBatchSendingController.java

@@ -0,0 +1,175 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.admin.io.request.im.CustomerServiceBatchSendingVo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.enums.im.EImReceiveType;
+import com.yonge.cooleshow.biz.dal.enums.im.EImSendStatus;
+import com.yonge.cooleshow.biz.dal.service.CustomerServiceBatchSendingService;
+import com.yonge.cooleshow.biz.dal.wrapper.im.CustomerServiceBatchSendingWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Objects;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.admin:}/batchSending")
+@Api(tags = "客服群发")
+public class CustomerServiceBatchSendingController extends BaseController {
+
+    @Autowired
+    private CustomerServiceBatchSendingService customerServiceBatchSendingService;
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+
+	/**
+	 * 查询单条
+	 * @param id 详情ID
+	 * @return R<CustomerServiceBatchSendingVo.CustomerServiceBatchSending>
+	 */
+	@ApiOperation(value = "详情", notes = "客服群发-根据详情ID查询单条, 传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @GetMapping("/detail/{id}")
+    public HttpResponseResult<CustomerServiceBatchSendingWrapper.CustomerServiceBatchSending> detail(@PathVariable("id") Long id) {
+
+		CustomerServiceBatchSendingWrapper.CustomerServiceBatchSending wrapper = customerServiceBatchSendingService.detail(id);
+        
+        return HttpResponseResult.succeed(wrapper);
+	}
+    
+    /**
+	 * 查询分页
+	 * @param query CustomerServiceBatchSendingVo.CustomerServiceBatchSendingQuery
+	 * @return R<PageInfo<CustomerServiceBatchSendingVo.CustomerServiceBatchSending>>
+	 */
+    @ApiOperation(value = "查询分页", notes = "客服群发- 传入 CustomerServiceBatchSendingVo.CustomerServiceBatchSendingQuery") 
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<CustomerServiceBatchSendingWrapper.CustomerServiceBatchSending>> page(@RequestBody CustomerServiceBatchSendingWrapper.CustomerServiceBatchSendingQuery query) {
+    
+        // 查询数据
+        IPage<CustomerServiceBatchSendingWrapper.CustomerServiceBatchSending> pages = customerServiceBatchSendingService.selectPage(PageUtil.getPage(query), query);
+
+        return HttpResponseResult.succeed(PageUtil.pageInfo(pages));
+	}
+    
+    /**
+	 * 新增
+	 * @param info CustomerServiceBatchSendingVo.CustomerServiceBatchSending
+	 * @return R<Boolean>
+	 */
+    @ApiOperation(value = "新增", notes = "客服群发- 传入 CustomerServiceBatchSendingVo.CustomerServiceBatchSending")
+	@PostMapping("/save")
+	public HttpResponseResult<Boolean> add(@RequestBody CustomerServiceBatchSendingVo.CustomerServiceBatchSending info) {
+
+		// 获取当前用户ID
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null || null == user.getId()) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+		info.setCreateBy(user.getId());
+
+		if (EImReceiveType.PORTION == info.getReceiveType()
+				&& CollectionUtils.isEmpty(info.getReceives())) {
+			throw new BizException("接收用户不能为空");
+		}
+		// 设置默认参数
+		info.setSendStatus(EImSendStatus.WAIT);
+
+        // 新增数据
+        customerServiceBatchSendingService.add(JSON.parseObject(info.jsonString(),
+				CustomerServiceBatchSendingWrapper.CustomerServiceBatchSending.class));
+        
+        return HttpResponseResult.succeed();
+	}
+    
+    /**
+	 * 修改
+	 * @param info CustomerServiceBatchSendingVo.CustomerServiceBatchSending
+	 * @return R<Boolean>
+	 */
+    @ApiOperation(value = "修改", notes = "客服群发- 传入 CustomerServiceBatchSendingVo.CustomerServiceBatchSending")
+	@PostMapping("/update")
+	public HttpResponseResult<Boolean> update(@Validated @RequestBody CustomerServiceBatchSendingVo.CustomerServiceBatchSending info) {
+
+		if (Objects.isNull(info.getId())) {
+			throw new BizException("请求参数异常");
+		}
+
+        // 更新数据
+        customerServiceBatchSendingService.update(JSON.parseObject(info.jsonString(),
+				CustomerServiceBatchSendingWrapper.CustomerServiceBatchSending.class));
+        
+        return HttpResponseResult.succeed();
+	}
+
+ 	/**
+	 * 删除
+	 * @param id 详情ID
+	 * @return R<Boolean>
+	 */
+	@ApiOperation(value = "删除", notes = "客服群发- 传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+	@PostMapping("/remove")
+	public HttpResponseResult<Boolean> remove(@RequestParam Long id) {
+    
+		return HttpResponseResult.succeed(customerServiceBatchSendingService.removeById(id));
+	}
+
+	@ApiOperation(value = "更新消息状态", notes = "客服群发- 传入id")
+	@ApiImplicitParams({
+			@ApiImplicitParam(name = "id", value = "主键Id", dataType = "long"),
+			@ApiImplicitParam(name = "sendStatus", value = "发送状态", dataType = "String")
+	})
+	@PostMapping("/status/{id}")
+	public HttpResponseResult<Boolean> status(@PathVariable("id") Long id, EImSendStatus sendStatus) {
+
+		if (Objects.isNull(sendStatus)) {
+			throw new BizException("发送状态不能为空");
+		}
+
+		// 更新群发消息状态
+		customerServiceBatchSendingService.status(id, sendStatus);
+
+		return HttpResponseResult.succeed(true);
+	}
+
+	@ApiOperation(value = "立即发送", notes = "客服群发- 传入id")
+	@ApiImplicitParams({
+			@ApiImplicitParam(name = "id", value = "主键Id", dataType = "long")
+	})
+	@PostMapping("/send/{id}")
+	public HttpResponseResult<Boolean> send(@PathVariable("id") Long id) {
+
+		// 更新群发消息状态
+		customerServiceBatchSendingService.sendMessage(id);
+
+		return HttpResponseResult.succeed(true);
+	}
+}

+ 91 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/CustomerServiceReceiveController.java

@@ -0,0 +1,91 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.admin.io.request.im.CustomerServiceReceiveVo;
+import com.yonge.cooleshow.biz.dal.entity.CustomerServiceReceive;
+import com.yonge.cooleshow.biz.dal.service.CustomerServiceReceiveService;
+import com.yonge.cooleshow.biz.dal.wrapper.im.CustomerServiceReceiveWrapper;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Objects;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.admin:}/batchReceive")
+@Api(tags = "客服群发接收")
+public class CustomerServiceReceiveController {
+
+    @Autowired
+    private CustomerServiceReceiveService customerServiceReceiveService;
+
+    
+    /**
+	 * 查询分页
+	 * @param query CustomerServiceReceiveVo.CustomerServiceReceiveQuery
+	 * @return R<PageInfo<CustomerServiceReceiveVo.CustomerServiceReceive>>
+	 */
+    @ApiOperation(value = "查询分页", notes = "客服群发接收- 传入 CustomerServiceReceiveVo.CustomerServiceReceiveQuery") 
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<CustomerServiceReceiveWrapper.CustomerServiceReceive>> page(@RequestBody CustomerServiceReceiveWrapper.CustomerServiceReceiveQuery query) {
+    
+        // 查询数据
+        IPage<CustomerServiceReceiveWrapper.CustomerServiceReceive> pages = customerServiceReceiveService.selectPage(PageUtil.getPage(query), query);
+
+        return HttpResponseResult.succeed(PageUtil.pageInfo(pages));
+	}
+    
+    /**
+	 * 新增
+	 * @param info CustomerServiceReceiveVo.CustomerServiceReceive
+	 * @return R<Boolean>
+	 */
+    @ApiOperation(value = "新增", notes = "客服群发接收- 传入 CustomerServiceReceiveVo.CustomerServiceReceive")
+	@PostMapping("/save")
+	public HttpResponseResult<Boolean> add(@Validated @RequestBody List<CustomerServiceReceiveVo.CustomerServiceReceive> info) {
+
+		if (CollectionUtils.isEmpty(info)
+				|| info.stream().anyMatch(x -> Objects.isNull(x.getBatchSendingId()))) {
+			throw new BizException("无效的请求参数");
+		}
+
+		List<CustomerServiceReceive> receives = JSON.parseArray(JSON.toJSONString(info), CustomerServiceReceive.class);
+		// 新增数据
+        customerServiceReceiveService.saveBatch(receives);
+        
+        return HttpResponseResult.succeed();
+	}
+    
+ 	/**
+	 * 删除
+	 * @param id 详情ID
+	 * @return R<Boolean>
+	 */
+	@ApiOperation(value = "删除", notes = "客服群发接收- 传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+	@PostMapping("/remove")
+	public HttpResponseResult<Boolean> remove(@RequestParam Long id) {
+    
+		return HttpResponseResult.succeed(customerServiceReceiveService.removeById(id));
+	}
+}

+ 138 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/EmployeeController.java

@@ -0,0 +1,138 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dao.EmployeeDao;
+import com.yonge.cooleshow.biz.dal.dto.EmployeeDto;
+import com.yonge.cooleshow.biz.dal.dto.search.EmployeeSearch;
+import com.yonge.cooleshow.biz.dal.entity.Employee;
+import com.yonge.cooleshow.biz.dal.enums.GenderEnum;
+import com.yonge.cooleshow.biz.dal.service.EmployeeService;
+import com.yonge.cooleshow.biz.dal.vo.EmployeeVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.cooleshow.common.enums.UserStatusEnum;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.Date;
+import java.util.List;
+
+@RequestMapping("${app-config.url.admin:}/employee")
+@Api(tags = "员工管理")
+@RestController
+public class EmployeeController extends BaseController {
+    @Autowired
+    private EmployeeService employeeService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private EmployeeDao employeeDao;
+
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入student")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", paramType = "path", dataType = "long", required = true),
+    })
+    @PreAuthorize("@pcs.hasPermissions('employee/detail')")
+    public HttpResponseResult<EmployeeVo> detail(@PathVariable("id") Long id) {
+        EmployeeVo detail = employeeService.detail(id);
+        return succeed(detail);
+    }
+
+    /**
+     * 查询分页
+     */
+    @ApiOperation(value = "查询分页", notes = "传入student")
+    @PostMapping("/page")
+    @PreAuthorize("@pcs.hasPermissions('employee/page')")
+    public HttpResponseResult<PageInfo<EmployeeVo>> page(@RequestBody EmployeeSearch query) {
+        query.setSort("id_");
+    	
+    	if(StringUtils.isNotBlank(query.getUserStatus())){
+    		switch (query.getUserStatus()) {
+			case "LOCKED":
+				query.setDelFlag(YesOrNoEnum.NO);
+				query.setLockFlag(UserLockFlag.LOCKED);
+				break;
+			case "CLOSED":
+				query.setDelFlag(YesOrNoEnum.YES);
+				break;
+
+			default:
+				query.setDelFlag(YesOrNoEnum.NO);
+				query.setLockFlag(UserLockFlag.NORMAL);
+				break;
+			}
+    	}
+        IPage<EmployeeVo> pages = employeeService.selectPage(PageUtil.getPage(query), query);
+		List<EmployeeVo> rows = pages.getRecords();
+		
+		for(EmployeeVo vo : rows){
+			if(vo.getDelFlag() == YesOrNoEnum.YES){
+				vo.setUserStatus(UserStatusEnum.CLOSED);
+			}else{
+				if(vo.getLockFlag() == UserLockFlag.LOCKED){
+					vo.setUserStatus(UserStatusEnum.LOCKED);
+				}else{
+					vo.setUserStatus(UserStatusEnum.NORMAL);
+				}
+			}
+		}
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "新增员工")
+    @PostMapping("/add")
+    @PreAuthorize("@pcs.hasPermissions('employee/add')")
+    public HttpResponseResult<EmployeeDto> add(@Valid @RequestBody EmployeeDto employee) throws Exception {
+        employee.setCreateTime(new Date());
+        employee.setUpdateTime(new Date());
+        return employeeService.addEmployee(employee);
+    }
+
+    @ApiOperation(value = "修改员工")
+    @PostMapping("/update")
+    @PreAuthorize("@pcs.hasPermissions('employee/update')")
+    public HttpResponseResult<EmployeeDto> update(@Valid @RequestBody EmployeeDto employee) throws Exception {
+        employee.setUpdateTime(new Date());
+        return employeeService.updateEmployee(employee);
+    }
+
+    @ApiOperation(value = "获取用户信息")
+    @GetMapping("/queryUserInfo")
+    public HttpResponseResult<EmployeeVo> apiQueryUserInfo() {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser != null && sysUser.getId() != null) {
+            Employee employee = employeeService.get(sysUser.getId());
+            EmployeeVo employeeVo = new EmployeeVo().buildVo(employee);
+            employeeVo.setUserId(sysUser.getId());
+            employeeVo.setRoleIds(employeeDao.queryUserRole(sysUser.getId()));
+            employeeVo.setSysUser(sysUser);
+
+            BeanUtils.copyProperties(sysUser, employeeVo, "gender");
+            employeeVo.setGender(GenderEnum.valueOf(sysUser.getGender()));
+            return succeed(employeeVo);
+        }
+        return failed("获取用户信息失败");
+    }
+
+}

+ 94 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/HolidaysFestivalsController.java

@@ -0,0 +1,94 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.HolidaysFestivals;
+import com.yonge.cooleshow.biz.dal.service.HolidaysFestivalsService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.log.model.AuditLogAnnotation;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Date;
+
+@RequestMapping("${app-config.url.admin:}/holidaysFestivals")
+@Api(tags = "节假日")
+@RestController
+public class HolidaysFestivalsController extends BaseController {
+
+	@Autowired
+	private HolidaysFestivalsService holidaysFestivalsService;
+
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+
+	@ApiOperation("按年查询节假日")
+	@ApiImplicitParam(name = "year", value = "年份", required = false, dataType = "Integer", paramType = "path")
+	@GetMapping(value = "/query/{year}", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	public HttpResponseResult<HolidaysFestivals> query(@PathVariable("year") Integer year) {
+		
+		HolidaysFestivals originHolidaysFestivals = holidaysFestivalsService.queryByYear(year);
+
+		return succeed(originHolidaysFestivals);
+	}
+
+	@ApiOperation("新增节假日")
+	@ApiImplicitParam(name = "HolidaysFestivals", value = "节假日对象", required = false, dataType = "HolidaysFestivals", paramType = "body")
+	@PostMapping(value = "/add", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	@AuditLogAnnotation(operateName = "新增节假日", interfaceURL = "holidaysFestivals/add")
+	@PreAuthorize("@pcs.hasPermissions('holidaysFestivals/add')")
+	public Object add(@RequestBody HolidaysFestivals holidaysFestivals) {
+		SysUser user = sysUserFeignService.queryUserInfo();
+
+		if (user == null || user.getId() == null) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+
+		if (holidaysFestivals.getYear() == null || holidaysFestivals.getYear() <= 2020) {
+			return failed("参数错误");
+		}
+
+		// 检查是否已经新增
+		HolidaysFestivals originHolidaysFestivals = holidaysFestivalsService.queryByYear(holidaysFestivals.getYear());
+
+		if (originHolidaysFestivals != null) {
+			return failed("该年份已提交,请勿重复提交");
+		}
+
+		Date date = new Date();
+		holidaysFestivals.setCreateTime(date).setCreateBy(user.getId()).setUpdateTime(date).setUpdateBy(user.getId());
+		holidaysFestivalsService.insert(holidaysFestivals);
+		return succeed();
+	}
+
+	@ApiOperation("更新节假日")
+	@ApiImplicitParam(name = "HolidaysFestivals", value = "节假日对象", required = false, dataType = "HolidaysFestivals", paramType = "body")
+	@PostMapping(value = "/update", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	@AuditLogAnnotation(operateName = "更新节假日", interfaceURL = "holidaysFestivals/update")
+	@PreAuthorize("@pcs.hasPermissions('holidaysFestivals/update')")
+	public Object update(@RequestBody HolidaysFestivals holidaysFestivals) {
+		SysUser user = sysUserFeignService.queryUserInfo();
+
+		if (user == null || user.getId() == null) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+
+		Date date = new Date();
+		holidaysFestivals.setUpdateTime(date).setUpdateBy(user.getId());
+
+		holidaysFestivalsService.update(holidaysFestivals);
+		return succeed();
+	}
+}

+ 89 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/HomeController.java

@@ -0,0 +1,89 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.yonge.cooleshow.biz.dal.dto.SubjectHomeSearch;
+import com.yonge.cooleshow.biz.dal.dto.req.TotalReq;
+import com.yonge.cooleshow.biz.dal.service.HomeService;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
+import com.yonge.cooleshow.biz.dal.vo.CourseHomeVo;
+import com.yonge.cooleshow.biz.dal.vo.HomeMusicSheetVo;
+import com.yonge.cooleshow.biz.dal.vo.SubjectHomeVo;
+import com.yonge.cooleshow.biz.dal.vo.res.HomeTotalStudent;
+import com.yonge.cooleshow.biz.dal.vo.res.HomeTotalTeacher;
+import com.yonge.cooleshow.biz.dal.vo.res.HomeUserToDoNum;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.Map;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/home")
+@Api(value = "首页", tags = "首页")
+public class HomeController extends BaseController {
+    @Autowired
+    private HomeService homeService;
+
+    @Autowired
+    private MusicSheetService musicSheetService;
+
+    @ApiOperation(value = "查询用户待办事项数")
+    @PostMapping("/getUserToDoNum")
+    @PreAuthorize("@pcs.hasPermissions('home/getUserToDoNum')")
+    public HttpResponseResult<HomeUserToDoNum> getUserToDoNum() {
+        return succeed(homeService.getUserToDoNum());
+    }
+
+    @ApiOperation(value = "老师数据统计")
+    @PostMapping("/totalTeacher")
+    @PreAuthorize("@pcs.hasPermissions('home/totalTeacher')")
+    public HttpResponseResult<HomeTotalTeacher> totalTeacher(@Valid @RequestBody TotalReq totalReq) {
+        return homeService.totalTeacher(totalReq);
+    }
+
+    @ApiOperation(value = "学员数据统计")
+    @PostMapping("/totalStudent")
+    @PreAuthorize("@pcs.hasPermissions('home/totalStudent')")
+    public HttpResponseResult<HomeTotalStudent> totalStudent(@Valid @RequestBody TotalReq totalReq) {
+        return homeService.totalStudent(totalReq);
+    }
+
+    @ApiOperation(value = "首页曲目点播数据")
+    @PostMapping("/musicSheet")
+    @PreAuthorize("@pcs.hasPermissions('home/musicSheet')")
+    public HttpResponseResult<HomeMusicSheetVo> musicSheet() {
+        return succeed(musicSheetService.getMusicSheetHome());
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "dateTime", dataType = "String", value = "如果查询年数据 yyyy   如果查询月数据 yyyy-mm"),
+            @ApiImplicitParam(name = "timeType", dataType = "String", value = " 时间类型 MONTH月度  YEAR年度"),
+            @ApiImplicitParam(name = "type", dataType = "String", value = "类型  PRACTICE陪练课  LIVE直播课"),
+    })
+    @ApiOperation(value = "获取首页课程数据")
+    @PostMapping("/courseHome")
+    @PreAuthorize("@pcs.hasPermissions('home/courseHome')")
+    public HttpResponseResult<CourseHomeVo> queryCourseHomeData(@RequestBody Map<String,Object> param) {
+        return succeed(homeService.queryCourseHomeData(param));
+    }
+
+
+
+    @ApiOperation(value = "获取首页- 内容数据-声部数据")
+    @PostMapping("/subjectHome")
+    // @PreAuthorize("@pcs.hasPermissions('home/courseHome')")
+    public HttpResponseResult<PageInfo<SubjectHomeVo>> subjectHome(@RequestBody SubjectHomeSearch query) {
+        return succeed(homeService.subjectHome(PageUtil.getPage(query),query));
+    }
+}

+ 123 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/HotSearchController.java

@@ -0,0 +1,123 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.HotSearchSearch;
+import com.yonge.cooleshow.biz.dal.entity.HotSearch;
+import com.yonge.cooleshow.biz.dal.service.HotSearchService;
+import com.yonge.cooleshow.biz.dal.vo.HotSearchVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.Date;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/hotSearch")
+@Api(value = "热门搜索表", tags = "热门搜索表")
+public class HotSearchController extends BaseController {
+
+    @Autowired
+    private HotSearchService hotSearchService;
+
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<HotSearch> detail(@PathVariable("id") Long id) {
+		HotSearch hotSearch = hotSearchService.getById(id);
+		if (hotSearch == null) {
+			return failed("未找到对应信息");
+		}
+		return succeed(hotSearch);
+	}
+    
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入hotSearchSearch")
+    public HttpResponseResult<PageInfo<HotSearchVo>> page(@RequestBody HotSearchSearch query) {
+		IPage<HotSearchVo> pages = hotSearchService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+    
+    /**
+	 * 新增
+	 */
+	@PostMapping("/save")
+	@ApiOperation(value = "新增", notes = "传入hotSearch")
+	public HttpResponseResult save(@Valid @RequestBody HotSearch hotSearch) {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null || user.getId() == null) {
+			return failed("用户信息不存在");
+		}
+
+		hotSearch.setCreateOn(new Date());
+		hotSearch.setModifyOn(new Date());
+		hotSearch.setCreateBy(user.getId());
+		hotSearch.setUpdateBy(user.getId());
+		hotSearch.setStatus(YesOrNoEnum.NO);
+
+		return status(hotSearchService.save(hotSearch));
+	}
+    
+    /**
+	 * 修改
+	 */
+	@PostMapping("/update")
+	@ApiOperation(value = "修改", notes = "传入hotSearch")
+	public HttpResponseResult update(@Valid @RequestBody HotSearch hotSearch) {
+		if (hotSearch.getId() == null) {
+			return failed("热门搜索id不能为空");
+		}
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null || user.getId() == null) {
+			return failed("用户信息不存在");
+		}
+		hotSearch.setModifyOn(new Date());
+		hotSearch.setUpdateBy(user.getId());
+
+		return status(hotSearchService.update(hotSearch));
+	}
+
+ 	/**
+	 * 删除
+	 */
+	@PostMapping("/remove/{id}")
+	@ApiOperation(value = "删除", notes = "传入ids")
+	public HttpResponseResult remove(@PathVariable Long id) {
+
+		if (id == null) {
+			return failed("参数错误");
+		}
+		return status(hotSearchService.removeById(id));
+	}
+
+
+	@PostMapping("/status/{id}")
+	@ApiOperation(value = "修改状态", notes = "传入ids")
+	public HttpResponseResult status(@PathVariable Long id) {
+
+		if (id == null) {
+			return failed("参数错误");
+		}
+		return status(hotSearchService.status(id));
+	}
+}

+ 113 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ImGroupController.java

@@ -0,0 +1,113 @@
+package com.yonge.cooleshow.admin.controller;
+
+
+import com.yonge.cooleshow.biz.dal.dto.ImGroupSearchDto;
+import com.yonge.cooleshow.biz.dal.entity.ImGroup;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.ImGroupService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.utils.date.DateUtil;
+import com.yonge.toolset.utils.validator.ValidationKit;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 即时通讯群组(ImGroup)表控制层
+ *
+ * @author zx
+ * @since 2022-03-22 10:45:56
+ */
+@Api(tags = "即时通讯群组")
+@RestController
+@RequestMapping("${app-config.url.admin:}/imGroup")
+public class ImGroupController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private ImGroupService imGroupService;
+    @Autowired
+    private SysUserService sysUserService;
+
+    @ApiOperation("获取群详情")
+    @PostMapping(value = "/getDetail/{groupId}")
+    @PreAuthorize("@pcs.hasPermissions('imGroup/detail')")
+    public HttpResponseResult<ImGroup> getDetail(@ApiParam(value = "群编号", required = true) @PathVariable("groupId") String groupId) throws Exception {
+        ImGroup group = imGroupService.getById(groupId);
+        if (group == null) {
+            return failed(HttpStatus.NO_CONTENT, "群组不存在");
+        }
+        return succeed(group);
+    }
+
+    @ApiOperation("群列表")
+    @PostMapping(value = "/queryAll")
+    @PreAuthorize("@pcs.hasPermissions('imGroup/queryAll')")
+    public HttpResponseResult<List<ImGroup>> queryAll(@Valid @RequestBody ImGroupSearchDto imGroupSearchDto, BindingResult bindingResult) throws Exception {
+        ValidationKit.ignoreFields(bindingResult,"createUserId");
+        imGroupSearchDto.setUserId(sysUserService.getUserId());
+        return succeed(imGroupService.queryAll(imGroupSearchDto));
+    }
+
+    @ApiOperation("退出群聊")
+    @PostMapping(value = "/quit/{groupId}")
+    public HttpResponseResult quit(@ApiParam(value = "群编号", required = true) @PathVariable("groupId") String groupId) throws Exception {
+        imGroupService.quit(groupId,sysUserService.getUserId(), ClientEnum.STUDENT);
+        return succeed();
+    }
+
+
+
+    @GetMapping(value = "/syncImHistoryMessageTask")
+    // 融云同步即时通讯聊天记录
+    public void syncImHistoryMessageTask(String date) throws Exception {
+        if (date == null) {
+            date = DateUtil.format(DateUtil.addHours(new Date(), -2), DateUtil.YEAR_MONTH_DAY_HOUR);
+        }
+        // 获取输入日期
+        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHH");
+        Date currentDate = format.parse(date);
+
+        // 创建Calendar对象 设置为输入时间
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(currentDate);
+
+        // 将日期减少三天
+        calendar.add(Calendar.DATE, -3);
+
+        // 获取减少三天后的日期
+        Date targetTime = calendar.getTime();
+
+        calendar.setTime(currentDate);
+
+        //按照小时递减
+        while (currentDate.after(targetTime)) {
+            imGroupService.getAndSaveImHistoryMessage(DateUtil.format(currentDate, DateUtil.YEAR_MONTH_DAY_HOUR));
+            calendar.add(Calendar.HOUR, -1);
+            currentDate = calendar.getTime();
+        }
+
+    }
+
+
+}
+

+ 74 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MemberPriceSettingsController.java

@@ -0,0 +1,74 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.MemberPriceSettingsSearch;
+import com.yonge.cooleshow.biz.dal.entity.MemberPriceSettings;
+import com.yonge.cooleshow.biz.dal.service.MemberPriceSettingsService;
+import com.yonge.cooleshow.biz.dal.vo.MemberPriceSettingsVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.Date;
+
+@RequestMapping("${app-config.url.admin:}/memberPriceSettings")
+@Api(tags = "会员价格设置")
+@RestController
+public class MemberPriceSettingsController extends BaseController {
+	@Autowired
+	private MemberPriceSettingsService memberPriceSettingsService;
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+
+	/**
+	 * 查询单条
+	 */
+	@GetMapping("/detail/{id}")
+	@ApiOperation(value = "详情", notes = "传入id")
+	public HttpResponseResult<MemberPriceSettingsVo> detail(@PathVariable("id") Long id) {
+		return succeed(memberPriceSettingsService.detail(id));
+	}
+
+	/**
+	 * 查询分页
+	 */
+	@GetMapping("/list")
+	@ApiOperation(value = "查询分页", notes = "传入memberPriceSettingsSearch")
+	@PreAuthorize("@pcs.hasPermissions('memberPriceSettings/list')")
+	public HttpResponseResult<PageInfo<MemberPriceSettingsVo>> page(MemberPriceSettingsSearch query) {
+		IPage<MemberPriceSettingsVo> pages = memberPriceSettingsService.selectPage(PageUtil.getPage(query), query);
+		return succeed(PageUtil.pageInfo(pages));
+	}
+
+	/**
+	 * 修改
+	 */
+	@PostMapping(value = "/update", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+	@ApiOperation(value = "修改", notes = "传入memberPriceSettings")
+	@PreAuthorize("@pcs.hasPermissions('memberPriceSettings/update')")
+	public HttpResponseResult<Boolean> update(@Valid @RequestBody MemberPriceSettings memberPriceSettings) {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null || user.getId() == null) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+		memberPriceSettings.setUpdateBy(user.getId());
+		memberPriceSettings.setUpdateTime(new Date());
+		return status(memberPriceSettingsService.updateById(memberPriceSettings));
+	}
+}

+ 257 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MusicAlbumController.java

@@ -0,0 +1,257 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.AdjustModel;
+import com.yonge.cooleshow.biz.dal.dto.MusicAlbumSheetDto;
+import com.yonge.cooleshow.biz.dal.dto.MusicAlbumSheetSortDto;
+import com.yonge.cooleshow.biz.dal.dto.search.MusicAlbumDetailSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.MusicAlbumSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.StudentMusicSheetOrderSearch;
+import com.yonge.cooleshow.biz.dal.entity.MusicAlbum;
+import com.yonge.cooleshow.biz.dal.service.MusicAlbumService;
+import com.yonge.cooleshow.biz.dal.vo.AlbumDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.MusicAlbumVo;
+import com.yonge.cooleshow.biz.dal.vo.StudentMusicAlbumOrderVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.Date;
+
+/**
+ * 专辑表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.admin:}/music/album")
+@Api(tags = "专辑表 API接口")
+public class MusicAlbumController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+	@Autowired
+	private MusicAlbumService musicAlbumService;
+
+	@ApiOperation(value = "新增", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/create", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/album/create')")
+    public HttpResponseResult<Object> create(@Valid @RequestBody MusicAlbum musicAlbum) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+
+        String[] split = musicAlbum.getAlbumTag().split(",");
+        if (split.length >3) {
+            throw new BizException("专辑标签数不能超过3个");
+        }
+
+        musicAlbum.setCreateBy(sysUser.getId());
+        musicAlbum.setCreateTime(new Date());
+        musicAlbum.setUpdateBy(sysUser.getId());
+        musicAlbum.setUpdateTime(new Date());
+        musicAlbum.setAlbumStatus(YesOrNoEnum.NO);
+        return succeed(musicAlbumService.createMusicAlbum(musicAlbum));
+    }
+
+    @ApiOperation(value = "删除", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping("/delete/{id}")
+    @PreAuthorize("@pcs.hasPermissions('music/album/delete')")
+    public Object delete(@PathVariable Long id) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        return succeed(musicAlbumService.del(id));
+    }
+
+    @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/update", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/album/update')")
+    public HttpResponseResult<Object> update(@Valid @RequestBody MusicAlbum musicAlbum) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        if (musicAlbum.getId()==null){
+            return failed("缺少ID");
+        }
+        /*MusicAlbum service = musicAlbumService.getById(musicAlbum.getId());
+        if (YesOrNoEnum.YES.getCode().equals(service.getAlbumStatus().getCode())) {
+            return failed("启用状态不许修改");
+        }*/
+
+        String[] split = musicAlbum.getAlbumTag().split(",");
+        if (split.length >3) {
+            throw new BizException("专辑标签数不能超过3个");
+        }
+
+        musicAlbum.setUpdateBy(sysUser.getId());
+        musicAlbum.setUpdateTime(new Date());
+        return succeed(musicAlbumService.updateMusicAlbum(musicAlbum));
+    }
+
+    @ApiOperation(value = "分页查询", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/list", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/album/list')")
+    public HttpResponseResult<PageInfo<MusicAlbumVo>> list(@RequestBody MusicAlbumSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        query.setUserId(sysUser.getId());
+        IPage<MusicAlbumVo> iPage = musicAlbumService.selectPage(PageUtil.getPage(query),query);
+        return succeed(PageUtil.pageInfo(iPage));
+    }
+
+    /**
+     * 启用/停用
+     */
+    @PostMapping("/state/{id}")
+    @ApiOperation(value = "启用/停用", notes = "传入id")
+    @PreAuthorize("@pcs.hasPermissions('music/album/state')")
+    public HttpResponseResult<Boolean> state(@ApiParam(value = "专辑编号", required = true)  @PathVariable Long id) {
+        if (StringUtil.isEmpty(id)) {
+            return failed("参数不能为空");
+        }
+        return status(musicAlbumService.state(id));
+    }
+
+
+    /**
+     * 专辑详情
+     */
+    @PostMapping(value = "/detail", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "专辑详情",  httpMethod="POST", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/album/detail')")
+    public HttpResponseResult<AlbumDetailVo> detail(@Valid @RequestBody MusicAlbumDetailSearch query) {
+
+        query.setType(2);
+        AlbumDetailVo albumDetailVo = musicAlbumService.detail(PageUtil.getPage(query), query, null, null);
+        return succeed(albumDetailVo);
+    }
+
+
+    /**
+     * 专辑详情能新增的曲目列表
+     */
+    @PostMapping(value = "/detail/canAddMusicSheet", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "专辑详情能新增的曲目列表",  httpMethod="POST", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/album/detail/canAddMusicSheet')")
+    public HttpResponseResult<AlbumDetailVo> detailAddMusicSheet(@Valid @RequestBody MusicAlbumDetailSearch query) {
+
+        query.setType(1);
+        query.setState(YesOrNoEnum.YES);
+        AlbumDetailVo albumDetailVo = musicAlbumService.detail(PageUtil.getPage(query), query, null, null);
+        return succeed(albumDetailVo);
+    }
+
+
+    /**
+     * 专辑详情删除曲目列表
+     */
+    @PostMapping(value = "/detail/delMusicSheet" ,consumes="application/json", produces="application/json")
+    @ApiOperation(value = "专辑详情删除曲目列表",  httpMethod="POST", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/album/detail/delMusicSheet')")
+    public HttpResponseResult<Boolean> detailDelMusicSheet(@Valid @RequestBody MusicAlbumSheetDto query) {
+        if (StringUtil.isEmpty(query.getAlbumId())) {
+            return failed("专辑编号ID不能为空");
+        }
+        if (StringUtil.isEmpty(query.getMusicSheetIds())) {
+            return failed("曲目编号不能为空");
+        }
+        return status(musicAlbumService.delMusicSheet(query.getAlbumId(),query.getMusicSheetIds()));
+    }
+
+
+    /**
+     * 修改曲目的排序值
+     */
+    @PostMapping(value = "/detail/updateMusicSheet" ,consumes="application/json", produces="application/json")
+    @ApiOperation(value = "专辑详情修改曲目排序",  httpMethod="POST", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/album/detail/updateMusicSheet')")
+    public HttpResponseResult<Boolean> updateMusicSheet(@Valid @RequestBody MusicAlbumSheetSortDto query) {
+        if (StringUtil.isEmpty(query.getAlbumId())) {
+            return failed("专辑编号ID不能为空");
+        }
+        if (StringUtil.isEmpty(query.getMusicSheetId())) {
+            return failed("曲目编号不能为空");
+        }
+        return succeed(musicAlbumService.updateMusicSheet(query));
+    }
+
+
+
+    /**
+     * 专辑详情添加曲目列表
+     */
+    @PostMapping(value = "/detail/addMusicSheet",consumes="application/json", produces="application/json")
+    @ApiOperation(value = "专辑详情添加曲目列表",  httpMethod="POST", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/album/detail/addMusicSheet')")
+    public HttpResponseResult<Boolean> detailAddMusicSheet(@Valid @RequestBody MusicAlbumSheetDto query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        if (StringUtil.isEmpty(query.getAlbumId())) {
+            return failed("专辑编号ID不能为空");
+        }
+        if (CollectionUtils.isEmpty(query.getAlbumMusicList())) {
+            return failed("曲目不能为空");
+        }
+        return status(musicAlbumService.addMusicSheet(query.getAlbumId(),query.getAlbumMusicList(),sysUser.getId()));
+    }
+
+
+
+    /**
+     * 设置排序值 和加精
+     */
+    @PostMapping("/adjust")
+    @ApiOperation(value = "专辑调整设置")
+    public HttpResponseResult<Boolean> adjust(@RequestBody @Valid AdjustModel model) {
+
+
+
+        MusicAlbum musicAlbum = new MusicAlbum();
+        musicAlbum.setId(model.getId());
+        musicAlbum.setSortNumber(model.getSort());
+
+        musicAlbumService.updateById(musicAlbum);
+
+        return succeed();
+    }
+
+    /**
+     * 学生详情-乐谱
+     */
+    @PostMapping(value = "/student", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "学生详情-专辑", httpMethod="POST", consumes="application/json", produces="application/json")
+    public HttpResponseResult<PageInfo<StudentMusicAlbumOrderVo>> student(@Valid @RequestBody StudentMusicSheetOrderSearch query) {
+        return succeed(PageUtil.pageInfo(musicAlbumService.selectStudentOrderPage(PageUtil.getPage(query),query)));
+    }
+
+
+}

+ 112 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MusicFavoriteController.java

@@ -0,0 +1,112 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.MusicFavoriteDto;
+import com.yonge.cooleshow.biz.dal.entity.MusicFavorite;
+import com.yonge.cooleshow.biz.dal.service.MusicFavoriteService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+/**
+ * 乐谱收藏表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.admin:}/music/favorite")
+@Api(tags = "乐谱收藏表 API接口")
+public class MusicFavoriteController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+	@Autowired
+	private MusicFavoriteService musicFavoriteService;
+
+	@ApiOperation(value = "新增", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/create", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> create(@Valid @RequestBody MusicFavorite musicFavorite) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        //musicFavorite.setCreateBy(sysUser.getId());
+        //musicFavorite.setCreateTime(new Date());
+        musicFavoriteService.save(musicFavorite);
+        return succeed();
+    }
+
+    @ApiOperation(value = "删除", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping("/delete/{id}")
+    public Object delete(@PathVariable Long id) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        musicFavoriteService.removeById(id);
+        return succeed();
+    }
+
+    @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/update", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> update(@Valid @RequestBody MusicFavorite musicFavorite) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        if (musicFavorite.getId()==null){
+            return failed("缺少ID");
+        }
+
+        //musicFavorite.setUpdateBy(sysUser.getId());
+        //musicFavorite.setUpdateTime(new Date());
+        musicFavoriteService.updateById(musicFavorite);
+        return succeed();
+    }
+
+    @ApiOperation(value = "分页查询", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/list", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> list(@RequestBody MusicFavoriteDto musicFavoriteDto) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        int pageNo = musicFavoriteDto.getPageNo();
+        int pageSize = musicFavoriteDto.getPageSize();
+
+        try {
+            if (pageNo==0) {
+                pageNo = 1;
+            }
+            if (pageSize==0) {
+                pageSize = 10;
+            }
+
+            LambdaQueryWrapper<MusicFavorite> lambdaQueryWrapper = Wrappers.lambdaQuery();
+            //lambdaQueryWrapper.like(MusicFavorite::getName , "k");
+
+            Page<MusicFavorite> page = new Page<>(pageNo,pageSize);
+            return succeed(musicFavoriteService.page(page, lambdaQueryWrapper));
+        } catch (Exception e) {
+            e.printStackTrace();
+            return HttpResponseResult.failed(e.getMessage());
+        }
+    }
+}

+ 112 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MusicSheetAccompanimentController.java

@@ -0,0 +1,112 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.MusicSheetAccompanimentDto;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheetAccompaniment;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetAccompanimentService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+/**
+ * 曲谱伴奏表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.admin:}/music/sheet/accompaniment")
+@Api(tags = "曲谱伴奏表 API接口")
+public class MusicSheetAccompanimentController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+	@Autowired
+	private MusicSheetAccompanimentService musicSheetAccompanimentService;
+
+	@ApiOperation(value = "新增", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/create", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> create(@Valid @RequestBody MusicSheetAccompaniment musicSheetAccompaniment) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        //musicSheetAccompaniment.setCreateBy(sysUser.getId());
+        //musicSheetAccompaniment.setCreateTime(new Date());
+        musicSheetAccompanimentService.save(musicSheetAccompaniment);
+        return succeed();
+    }
+
+    @ApiOperation(value = "删除", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping("/delete/{id}")
+    public Object delete(@PathVariable Long id) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        musicSheetAccompanimentService.removeById(id);
+        return succeed();
+    }
+
+    @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/update", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> update(@Valid @RequestBody MusicSheetAccompaniment musicSheetAccompaniment) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        if (musicSheetAccompaniment.getId()==null){
+            return failed("缺少ID");
+        }
+
+        //musicSheetAccompaniment.setUpdateBy(sysUser.getId());
+        //musicSheetAccompaniment.setUpdateTime(new Date());
+        musicSheetAccompanimentService.updateById(musicSheetAccompaniment);
+        return succeed();
+    }
+
+    @ApiOperation(value = "分页查询", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/list", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> list(@RequestBody MusicSheetAccompanimentDto musicSheetAccompanimentDto) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        int pageNo = musicSheetAccompanimentDto.getPageNo();
+        int pageSize = musicSheetAccompanimentDto.getPageSize();
+
+        try {
+            if (pageNo==0) {
+                pageNo = 1;
+            }
+            if (pageSize==0) {
+                pageSize = 10;
+            }
+
+            LambdaQueryWrapper<MusicSheetAccompaniment> lambdaQueryWrapper = Wrappers.lambdaQuery();
+            //lambdaQueryWrapper.like(MusicSheetAccompaniment::getName , "k");
+
+            Page<MusicSheetAccompaniment> page = new Page<>(pageNo,pageSize);
+            return succeed(musicSheetAccompanimentService.page(page, lambdaQueryWrapper));
+        } catch (Exception e) {
+            e.printStackTrace();
+            return HttpResponseResult.failed(e.getMessage());
+        }
+    }
+}

+ 427 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MusicSheetController.java

@@ -0,0 +1,427 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.AdjustModel;
+import com.yonge.cooleshow.biz.dal.dto.MusicSheetDto;
+import com.yonge.cooleshow.biz.dal.dto.MusicSheetExport;
+import com.yonge.cooleshow.biz.dal.dto.MusicSheetRenderDto;
+import com.yonge.cooleshow.biz.dal.dto.ReasonDto;
+import com.yonge.cooleshow.biz.dal.dto.req.TeacherMusicSheetAuditReq;
+import com.yonge.cooleshow.biz.dal.dto.search.MusicSheetSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.StudentMusicSheetOrderSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.TeacherMusicSheetAuditSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.TeacherMusicSheetSearch;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
+import com.yonge.cooleshow.biz.dal.enums.ChargeTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.MusicSheetTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.OrderTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
+import com.yonge.cooleshow.biz.dal.service.MusicTagService;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetStudentByMessage;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
+import com.yonge.cooleshow.biz.dal.vo.StudentMusicSheetOrderVo;
+import com.yonge.cooleshow.biz.dal.vo.TeacherMusicSheetVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.BizHttpStatus;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.utils.easyexcel.ErrMsg;
+import com.yonge.toolset.utils.easyexcel.ExcelDataReader;
+import com.yonge.toolset.utils.easyexcel.ExcelException;
+import com.yonge.toolset.utils.easyexcel.ExcelUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.Valid;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 曲谱表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.admin:}/music/sheet")
+@Api(tags = "曲谱表 API接口")
+public class MusicSheetController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+	@Autowired
+	private MusicSheetService musicSheetService;
+
+    @Autowired
+    private MusicTagService musicTagService;
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    @PreAuthorize("@pcs.hasPermissions('music/sheet/detail')")
+    public HttpResponseResult<MusicSheetDetailVo> detail(@ApiParam(value = "曲谱编号", required = true) @PathVariable("id") Long id) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        return succeed(musicSheetService.detail(id, sysUser, ClientEnum.SYSTEM));
+    }
+
+	@ApiOperation(value = "新增", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/create", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/sheet/create')")
+    public HttpResponseResult<Object> create(@Valid @RequestBody MusicSheetDto musicSheetDto) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        if (ChargeTypeEnum.CHARGE.getCode().equals(musicSheetDto.getChargeType().getCode())
+                && musicSheetDto.getMusicPrice()==null){
+            return failed("此曲谱为收费曲谱,需要提供价格");
+        }
+
+        // 单曲时声部必填,合奏非必填,默认单曲
+        if (musicSheetDto.getMusicSheetType() == null || StringUtil.isEmpty(musicSheetDto.getMusicSheetType())) {
+            musicSheetDto.setMusicSheetType(MusicSheetTypeEnum.SINGLE);
+        }
+        if (MusicSheetTypeEnum.SINGLE.equals(musicSheetDto.getMusicSheetType())
+                && StringUtil.isEmpty(musicSheetDto.getMusicSubject())) {
+            return failed("曲目声部不能为空");
+        }
+
+        if (musicSheetDto.getNotation() == null) {
+            musicSheetDto.setNotation(YesOrNoEnum.NO);
+        }
+        String musicTag = musicSheetDto.getMusicTag();
+        List<Long> musicTagList = StringUtil.toLongList(musicTag);
+
+        //  一级曲谱标签只能选一个二级
+        if (!musicTagService.checkParentDifferent(musicTagList)) {
+            return failed("每个一级标签只能选一个二级标签");
+        }
+
+        // 合奏图片不做限制
+        if (MusicSheetTypeEnum.SINGLE.equals(musicSheetDto.getMusicSheetType()) &&
+                StringUtil.isEmpty(musicSheetDto.getMusicImg())) {
+            throw new BizException("曲目渲染失败");
+        }
+
+        musicSheetDto.setUserId(sysUser.getId());
+        musicSheetDto.setAuditStatus(AuthStatusEnum.PASS);
+        musicSheetDto.setFirstPassAuditTime(new Date());
+        musicSheetDto.setDelFlag(false);
+        musicSheetDto.setSourceType(SourceTypeEnum.PLATFORM);
+
+        musicSheetDto.setFavoriteCount(0);
+        musicSheetDto.setCreateBy(sysUser.getId());
+        musicSheetDto.setCreateTime(new Date());
+        musicSheetService.saveMusicSheet(musicSheetDto,sysUser.getId());
+
+        return succeed("新增曲谱成功");
+
+    }
+
+    @ApiOperation(value = "删除", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping("/delete/{id}")
+    @PreAuthorize("@pcs.hasPermissions('music/sheet/delete')")
+    public Object delete(@PathVariable Long id) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        boolean result = musicSheetService.del(id);
+        if (result){
+            return succeed("删除成功");
+        } else {
+            return failed("删除失败");
+        }
+    }
+
+    @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/update", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/sheet/update')")
+    public HttpResponseResult<Object> update(@Valid @RequestBody MusicSheetDto musicSheet) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        if (musicSheet.getId()==null){
+            return failed("缺少ID");
+        }
+        /*MusicSheet service = musicSheetService.getById(musicSheet.getId());
+        if (YesOrNoEnum.YES.getCode().equals(service.getState().getCode())) {
+            return failed("启用状态不许修改");
+        }*/
+
+        if (musicSheet.getNotation() == null) {
+            musicSheet.setNotation(YesOrNoEnum.NO);
+        }
+
+        // 合奏时图片不做限制
+        if (MusicSheetTypeEnum.SINGLE.equals(musicSheet.getMusicSheetType())
+                && StringUtil.isEmpty(musicSheet.getMusicImg())) {
+            throw new BizException("曲目渲染失败");
+        }
+
+        musicSheet.setUpdateBy(sysUser.getId());
+        musicSheet.setAuditStatus(AuthStatusEnum.PASS);
+        musicSheet.setUpdateTime(new Date());
+        if ( musicSheetService.saveMusicSheet(musicSheet,sysUser.getId())){
+            return succeed("修改成功");
+        } else {
+            return failed("修改失败");
+        }
+    }
+
+    @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/updateRenderFile", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/sheet/updateRenderFile')")
+    public HttpResponseResult<Object> updateRenderFile(@Valid @RequestBody MusicSheetRenderDto musicSheetRenderDto) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        if (musicSheetRenderDto.getMusicSheetId()==null){
+            return failed("缺少ID");
+        }
+        MusicSheet musicSheet = musicSheetService.getById(musicSheetRenderDto.getMusicSheetId());
+        
+        if(musicSheet == null){
+        	return failed("参数异常");
+        }
+        musicSheet.setMusicFirstSvg(musicSheetRenderDto.getMusicFirstSvg());
+        musicSheet.setMusicJianSvg(musicSheetRenderDto.getMusicJianSvg());
+        musicSheet.setMusicJSON(musicSheetRenderDto.getMusicJSON());
+        musicSheet.setMusicSvg(musicSheetRenderDto.getMusicSvg());
+
+        musicSheet.setUpdateBy(sysUser.getId());
+        musicSheet.setUpdateTime(new Date());
+        if ( musicSheetService.updateById(musicSheet)){
+            return succeed("修改成功");
+        } else {
+            return failed("修改失败");
+        }
+    }
+
+    @ApiOperation(value = "分页查询", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/list", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/sheet/list')")
+    public HttpResponseResult<PageInfo<MusicSheetVo>> list(@RequestBody MusicSheetSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        query.setAuditStatus(AuthStatusEnum.PASS);
+        IPage<MusicSheetVo> musicSheetVoIPage = musicSheetService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(musicSheetVoIPage));
+    }
+
+
+    /**
+     * 启用/停用
+     */
+    @PostMapping("/state/{id}")
+    @ApiOperation(value = "启用/停用", notes = "传入id")
+    @PreAuthorize("@pcs.hasPermissions('music/sheet/state')")
+    public HttpResponseResult<Boolean> state(@ApiParam(value = "曲目编号", required = true)  @PathVariable Long id, @RequestBody ReasonDto reasonDto) {
+        if (StringUtil.isEmpty(id)) {
+            return failed("参数不能为空");
+        }
+        MusicSheet musicSheet = musicSheetService.getById(id);
+        if (musicSheet == null) {
+            return failed("未找到曲目");
+        }
+        if (YesOrNoEnum.YES.equals(musicSheet.getState()) &&
+                musicSheet.getSourceType().equals(SourceTypeEnum.TEACHER) && StringUtil.isEmpty(reasonDto.getReason())) {
+            return failed("请填写下架原因");
+        }
+        return status(musicSheetService.state(id,reasonDto.getReason(),ClientEnum.SYSTEM));
+    }
+
+
+    /**
+     * 批量启用/停用
+     */
+    @PostMapping("/stateList")
+    @ApiOperation(value = "批量启用/停用")
+    @PreAuthorize("@pcs.hasPermissions('music/sheet/stateList')")
+    public HttpResponseResult<Boolean> stateList(@RequestBody ReasonDto reasonDto) {
+        if (StringUtil.isEmpty(reasonDto.getMusicSheetIds())) {
+            return failed("参数不能为空");
+        }
+        if (reasonDto.getState() == null) {
+            return failed("启用/禁用状态不能为空");
+        }
+        if (reasonDto.getState().equals(YesOrNoEnum.NO) && StringUtil.isEmpty(reasonDto.getReason())) {
+            return failed("停用原因不能为空");
+        }
+
+        return status(musicSheetService.stateList(reasonDto));
+    }
+
+    /**
+     * 学生详情-乐谱
+     */
+    @PostMapping(value = "/student", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "学生详情-乐谱", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/sheet/student')")
+    public HttpResponseResult<PageInfo<StudentMusicSheetOrderVo>> student(@Valid @RequestBody StudentMusicSheetOrderSearch query) {
+        return succeed(PageUtil.pageInfo(musicSheetService.selectStudentOrderPage(PageUtil.getPage(query),query)));
+    }
+
+
+    /**
+     * 老师详情-乐谱
+     */
+    @PostMapping(value = "/teacher", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "老师详情-乐谱", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/sheet/teacher')")
+    public HttpResponseResult<PageInfo<TeacherMusicSheetVo>> teacher(@Valid @RequestBody TeacherMusicSheetSearch query) {
+        return succeed(PageUtil.pageInfo(musicSheetService.selectTeacherPage(PageUtil.getPage(query),query)));
+    }
+
+    /**
+     * 审核中心-乐谱审核列表
+     */
+    @PostMapping(value = "/audit/list", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "审核中心-乐谱审核列表", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/sheet/audit/list')")
+    public HttpResponseResult<PageInfo<TeacherMusicSheetVo>> audit(@RequestBody TeacherMusicSheetAuditSearch query) {
+        return succeed(PageUtil.pageInfo(musicSheetService.selectAuditPage(PageUtil.getPage(query),query)));
+    }
+
+    /**
+     * 审核中心-乐谱审核
+     */
+    @PostMapping(value = "/audit", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "审核中心-乐谱审核", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PreAuthorize("@pcs.hasPermissions('music/sheet/audit')")
+    public HttpResponseResult<Boolean> audit(@Valid @RequestBody TeacherMusicSheetAuditReq param) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        return status(musicSheetService.audit(param,sysUser.getId()));
+    }
+
+
+    /**
+     * 审核中心-乐谱审核
+     */
+    @GetMapping(value = "/auditDetail/{authMusicSheetId}")
+    @ApiOperation(value = "审核中心-乐谱审核详情",  notes = "传入曲目审核id")
+    public HttpResponseResult<MusicSheetDetailVo> auditDetail(@PathVariable Long authMusicSheetId) {
+
+        return succeed(musicSheetService.auditDetail(authMusicSheetId));
+    }
+
+
+
+    /**
+     * 审核中心-乐谱审核记录列表
+     */
+    @GetMapping(value = "/auditDetailList/{authMusicSheetId}")
+    @ApiOperation(value = "审核中心-乐谱审核详情历史记录",  notes = "传入曲目审核id")
+    public HttpResponseResult<List<MusicSheetDetailVo>> auditDetailList(@PathVariable Long authMusicSheetId) {
+
+        return succeed(musicSheetService.auditDetailList(authMusicSheetId));
+    }
+
+
+
+
+
+    @PostMapping(value = "/buySendMessage", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "发送学生购买老师曲目信息", httpMethod="POST", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Boolean> buySendMessage(@Valid @RequestBody MusicSheetStudentByMessage param) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        return status(musicSheetService.sendBuyMessage(param.getTeacherId(), param.getStudentId(), param.getMusicSheetId(),
+                                                       ClientEnum.STUDENT, OrderTypeEnum.MUSIC));
+    }
+    /**
+     * 导入
+     */
+    @PostMapping("/importExcel")
+    @ApiOperation(value = "导入", notes = "传入file")
+    public HttpResponseResult<List<ErrMsg>> importExcel(@RequestParam("file") MultipartFile file) {
+        if (null == file) {
+            return HttpResponseResult.failed("请上传文件");
+        }
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        try {
+            ExcelDataReader<MusicSheetExport> reader = ExcelUtils.getReader(MusicSheetExport.class, file);
+            musicSheetService.importExcel(reader.getDataList(), user.getId());
+            return HttpResponseResult.succeed();
+        } catch (ExcelException e) {
+            return HttpResponseResult.failed(BizHttpStatus.IMPORT.getCode(), e.getErrMsgList(), BizHttpStatus.IMPORT.getMsg());
+        }
+    }
+
+
+    /**
+     * 置顶
+     */
+    @PostMapping("/top/{id}")
+    @ApiOperation(value = "置顶曲目", notes = "传入id")
+    @PreAuthorize("@pcs.hasPermissions('music/sheet/top')")
+    public HttpResponseResult<Boolean> top(@ApiParam(value = "曲目编号", required = true)  @PathVariable Long id) {
+        if (StringUtil.isEmpty(id)) {
+            return failed("参数不能为空");
+        }
+        return status(musicSheetService.top(id));
+    }
+
+
+    /**
+     * 设置排序值 和加精
+     */
+    @PostMapping("/adjust")
+    @ApiOperation(value = "曲目调整设置")
+    public HttpResponseResult<Boolean> adjust(@RequestBody @Valid AdjustModel model) {
+
+        MusicSheet musicSheet = new MusicSheet();
+        musicSheet.setId(model.getId());
+        musicSheet.setSortNumber(model.getSort());
+        musicSheet.setExquisiteFlag(model.getExquisiteFlag());
+
+        musicSheetService.updateById(musicSheet);
+
+        return succeed();
+    }
+
+
+
+
+}

+ 112 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MusicSheetPurchaseRecordController.java

@@ -0,0 +1,112 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.MusicSheetPurchaseRecordDto;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheetPurchaseRecord;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetPurchaseRecordService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+/**
+ * 曲谱购买记录表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.admin:}/music/sheet/purchase/record")
+@Api(tags = "曲谱购买记录表 API接口")
+public class MusicSheetPurchaseRecordController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+	@Autowired
+	private MusicSheetPurchaseRecordService musicSheetPurchaseRecordService;
+
+	@ApiOperation(value = "新增", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/create", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> create(@Valid @RequestBody MusicSheetPurchaseRecord musicSheetPurchaseRecord) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        //musicSheetPurchaseRecord.setCreateBy(sysUser.getId());
+        //musicSheetPurchaseRecord.setCreateTime(new Date());
+        musicSheetPurchaseRecordService.save(musicSheetPurchaseRecord);
+        return succeed();
+    }
+
+    @ApiOperation(value = "删除", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping("/delete/{id}")
+    public Object delete(@PathVariable Long id) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        musicSheetPurchaseRecordService.removeById(id);
+        return succeed();
+    }
+
+    @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/update", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> update(@Valid @RequestBody MusicSheetPurchaseRecord musicSheetPurchaseRecord) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        if (musicSheetPurchaseRecord.getId()==null){
+            return failed("缺少ID");
+        }
+
+        //musicSheetPurchaseRecord.setUpdateBy(sysUser.getId());
+        //musicSheetPurchaseRecord.setUpdateTime(new Date());
+        musicSheetPurchaseRecordService.updateById(musicSheetPurchaseRecord);
+        return succeed();
+    }
+
+    @ApiOperation(value = "分页查询", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/list", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> list(@RequestBody MusicSheetPurchaseRecordDto musicSheetPurchaseRecordDto) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        int pageNo = musicSheetPurchaseRecordDto.getPageNo();
+        int pageSize = musicSheetPurchaseRecordDto.getPageSize();
+
+        try {
+            if (pageNo==0) {
+                pageNo = 1;
+            }
+            if (pageSize==0) {
+                pageSize = 10;
+            }
+
+            LambdaQueryWrapper<MusicSheetPurchaseRecord> lambdaQueryWrapper = Wrappers.lambdaQuery();
+            //lambdaQueryWrapper.like(MusicSheetPurchaseRecord::getName , "k");
+
+            Page<MusicSheetPurchaseRecord> page = new Page<>(pageNo,pageSize);
+            return succeed(musicSheetPurchaseRecordService.page(page, lambdaQueryWrapper));
+        } catch (Exception e) {
+            e.printStackTrace();
+            return HttpResponseResult.failed(e.getMessage());
+        }
+    }
+}

+ 134 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MusicTagController.java

@@ -0,0 +1,134 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.AdjustModel;
+import com.yonge.cooleshow.biz.dal.dto.MusicTagSaveDto;
+import com.yonge.cooleshow.biz.dal.dto.search.MusicTagSearch;
+import com.yonge.cooleshow.biz.dal.entity.MusicTag;
+import com.yonge.cooleshow.biz.dal.service.MusicTagService;
+import com.yonge.cooleshow.biz.dal.vo.MusicTagVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/MusicTag")
+@Api(value = "音乐标签表", tags = "音乐标签表")
+public class MusicTagController extends BaseController {
+
+    @Autowired
+    private MusicTagService musicTagService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+	@ApiOperation(value = "详情", notes = "传入id")
+	@PreAuthorize("@pcs.hasPermissions('MusicTag/detail')")
+    public HttpResponseResult<MusicTagVo> detail(@ApiParam(value = "标签编号", required = true) @PathVariable("id") Long id) {
+    	return succeed(musicTagService.detail(id));
+	}
+
+    /**
+     * 查询分页tree
+     */
+    @PostMapping(value = "/page", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "查询分页", httpMethod="POST", consumes="application/json", produces="application/json")
+	@PreAuthorize("@pcs.hasPermissions('MusicTag/page')")
+    public HttpResponseResult<PageInfo<MusicTagVo>> page(@Valid @RequestBody MusicTagSearch query) {
+		IPage<MusicTagVo> pages = musicTagService.selectPage(PageUtil.getPage(query), query);
+		return succeed(PageUtil.pageInfo(pages));
+	}
+
+
+	/**
+	 * 查询分页tree
+	 */
+	@GetMapping("/tree")
+	@ApiOperation(value = "查询标签树列表")
+	public HttpResponseResult<List<MusicTagVo>> tree(String type) {
+		List<MusicTagVo> treeList = musicTagService.selectMusicTagTree(type);
+		return succeed(treeList);
+	}
+
+    /**
+	 * 新增
+	 */
+	@PostMapping(value = "/save",  consumes="application/json", produces="application/json")
+	@ApiOperation(value = "新增", httpMethod="POST", consumes="application/json", produces="application/json")
+	@PreAuthorize("@pcs.hasPermissions('MusicTag/save')")
+	public HttpResponseResult<Boolean> save(@Validated(MusicTagSaveDto.Create.class) @RequestBody MusicTagSaveDto musicTagSaveDto) {
+
+		return succeed(musicTagService.createMusicTag(musicTagSaveDto));
+	}
+
+    /**
+	 * 修改
+	 */
+	@PostMapping(value =  "/update",  consumes="application/json", produces="application/json")
+	@ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
+	@PreAuthorize("@pcs.hasPermissions('MusicTag/update')")
+	public HttpResponseResult<Boolean> update(@Validated(MusicTagSaveDto.Update.class) @RequestBody MusicTagSaveDto musicTagSaveDto) {
+		return succeed(musicTagService.updateMusicTag(musicTagSaveDto));
+	}
+
+ 	/**
+	 * 删除
+	 */
+	@PostMapping("/remove/{id}")
+	@ApiOperation(value = "删除", notes = "传入id")
+	@PreAuthorize("@pcs.hasPermissions('MusicTag/remove')")
+	public HttpResponseResult<Boolean> remove(@ApiParam(value = "标签编号", required = true) @PathVariable Long id) {
+        if (StringUtil.isEmpty(id)) {
+			return failed("参数不能为空");
+		}
+		return status(musicTagService.del(id));
+	}
+
+	/**
+	 * 启用/停用
+	 */
+	@PostMapping("/state/{id}")
+	@ApiOperation(value = "启用/停用", notes = "传入id")
+	@PreAuthorize("@pcs.hasPermissions('MusicTag/state')")
+	public HttpResponseResult<Boolean> state(@ApiParam(value = "标签编号", required = true)  @PathVariable Long id) {
+		if (StringUtil.isEmpty(id)) {
+			return failed("参数不能为空");
+		}
+		return status(musicTagService.state(id));
+	}
+
+
+	/**
+	 * 设置排序值 和加精
+	 */
+	@PostMapping("/adjust")
+	@ApiOperation(value = "标签调整设置")
+	public HttpResponseResult<Boolean> adjust(@RequestBody @Valid AdjustModel model) {
+
+		MusicTag musicTag = new MusicTag();
+		musicTag.setId(model.getId());
+		musicTag.setSortNumber(model.getSort());
+
+		musicTagService.updateById(musicTag);
+
+		return succeed();
+	}
+}

+ 70 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/PianoRoomChangeRecordController.java

@@ -0,0 +1,70 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.PianoRoomChangeRecordSearch;
+import com.yonge.cooleshow.biz.dal.entity.PianoRoomChangeRecord;
+import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.PianoRoomChangeRecordService;
+import com.yonge.cooleshow.biz.dal.vo.PianoRoomChangeRecordVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/pianoRoomChangeRecord")
+@Api(value = "琴房时长变更记录表", tags = "琴房时长变更记录表")
+public class PianoRoomChangeRecordController extends BaseController {
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private PianoRoomChangeRecordService pianoRoomChangeRecordService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<PianoRoomChangeRecordVo> detail(@PathVariable("id") Long id) {
+    	return succeed(pianoRoomChangeRecordService.detail(id));
+	}
+    
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入pianoRoomChangeRecordSearch")
+    public HttpResponseResult<PageInfo<PianoRoomChangeRecordVo>> page(@RequestBody PianoRoomChangeRecordSearch query) {
+		IPage<PianoRoomChangeRecordVo> pages = pianoRoomChangeRecordService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+    
+    /**
+	 * 新增
+	 */
+	@PostMapping("/add")
+	@ApiOperation(value = "新增", notes = "传入pianoRoomChangeRecord")
+	public HttpResponseResult add(@Valid @RequestBody PianoRoomChangeRecord pianoRoomChangeRecord) {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null || null == user.getId()) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+		pianoRoomChangeRecord.setCreateBy(user.getId());
+		pianoRoomChangeRecord.setSourceType(SourceTypeEnum.PLATFORM);
+    	return status(pianoRoomChangeRecordService.add(pianoRoomChangeRecord));
+	}
+}

+ 121 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/PianoRoomSettingsController.java

@@ -0,0 +1,121 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.PianoRoomSettingsSearch;
+import com.yonge.cooleshow.biz.dal.entity.PianoRoomSettings;
+import com.yonge.cooleshow.biz.dal.service.PianoRoomSettingsService;
+import com.yonge.cooleshow.biz.dal.vo.PianoRoomSettingsVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.Date;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/pianoRoomSettings")
+@Api(value = "琴房时长价格配置", tags = "")
+public class PianoRoomSettingsController extends BaseController {
+
+    @Autowired
+    private PianoRoomSettingsService pianoRoomSettingsService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<PianoRoomSettingsVo> detail(@PathVariable("id") Long id) {
+        return succeed(pianoRoomSettingsService.detail(id));
+    }
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入pianoRoomSettingsSearch")
+    public HttpResponseResult<PageInfo<PianoRoomSettingsVo>> page(@RequestBody PianoRoomSettingsSearch query) {
+        IPage<PianoRoomSettingsVo> pages = pianoRoomSettingsService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+    /**
+     * 新增
+     */
+    @PostMapping("/save")
+    @ApiOperation(value = "新增", notes = "传入pianoRoomSettings")
+    public HttpResponseResult save(@Valid @RequestBody PianoRoomSettings pianoRoomSettings) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || user.getId() == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        pianoRoomSettings.setCreateBy(user.getId());
+        pianoRoomSettings.setUpdateBy(user.getId());
+        return status(pianoRoomSettingsService.save(pianoRoomSettings));
+    }
+    /**
+     * 修改
+     */
+    @PostMapping("/update")
+    @ApiOperation(value = "修改", notes = "传入pianoRoomSettings")
+    public HttpResponseResult update(@Valid @RequestBody PianoRoomSettings pianoRoomSettings) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || user.getId() == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        pianoRoomSettings.setUpdateBy(user.getId());
+        pianoRoomSettings.setUpdateTime(new Date());
+        return status(pianoRoomSettingsService.updateById(pianoRoomSettings));
+    }
+
+
+    /**
+     * 启用/冻结
+     */
+    @GetMapping(value = "/changeStatus/{id}/{status}")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", paramType = "path", dataType = "long", required = true),
+            @ApiImplicitParam(name = "status", value = "状态 0-正常,1-冻结", paramType = "path", dataType = "int", required = true)
+    })
+    @ApiOperation(value = "启用/冻结")
+    public HttpResponseResult<Boolean> changeStatus(@PathVariable("id") Long id, @PathVariable("status") Integer status) {
+        if (null == id || (status != 0 && status != 1)) {
+            return HttpResponseResult.failed("参数异常");
+        }
+        return HttpResponseResult.status(pianoRoomSettingsService.changeStatus(id,status) > 0);
+    }
+
+
+    /**
+     * 删除
+     */
+    @PostMapping("/remove")
+    @ApiOperation(value = "删除", notes = "传入ids")
+    public HttpResponseResult remove(@ApiParam(value = "主键集合(多个id,分割)", required = true) @RequestParam String ids) {
+        if (StringUtil.isEmpty(ids)) {
+            return failed("参数不能为空");
+        }
+        return status(pianoRoomSettingsService.removeByIds(StringUtil.toLongList(ids)));
+    }
+
+}

+ 68 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/PlatformCashAccountRecordController.java

@@ -0,0 +1,68 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.yonge.cooleshow.biz.dal.dto.excel.PlatformCashAccountRecordExport;
+import com.yonge.cooleshow.biz.dal.dto.search.PlatformCashAccountRecordSearch;
+import com.yonge.cooleshow.biz.dal.entity.PlatformCashAccountRecord;
+import com.yonge.cooleshow.biz.dal.service.PlatformCashAccountRecordService;
+import com.yonge.cooleshow.biz.dal.vo.PlatformCashAccountPageVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.utils.easyexcel.ExcelUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/platformCashAccountRecord")
+@Api(value = "平台账户记录", tags = "平台账户记录")
+public class PlatformCashAccountRecordController extends BaseController {
+
+    @Autowired
+    private PlatformCashAccountRecordService platformCashAccountRecordService;
+
+	@ApiOperation(value = "平台账户记录-列表", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+	@PostMapping(value = "/list", consumes = "application/json", produces = "application/json")
+	@PreAuthorize("@pcs.hasPermissions('platformCashAccountRecord/list')")
+	public HttpResponseResult<PlatformCashAccountPageVo> list(@RequestBody PlatformCashAccountRecordSearch query) {
+		PlatformCashAccountPageVo model = new PlatformCashAccountPageVo();
+		PageInfo<PlatformCashAccountRecord> pageInfo = PageUtil.pageInfo(platformCashAccountRecordService.queryPage(PageUtil.getPage(query),query));
+		model.setPageInfo(pageInfo);
+		model.setSummary(platformCashAccountRecordService.querySummary(query));
+		return succeed(model);
+	}
+
+	/**
+	 * 查询导出
+	 */
+	@PostMapping("/export")
+	@ApiOperation(value = "查询导出", notes = "传入orderSearch")
+	@PreAuthorize("@pcs.hasPermissions('platformCashAccountRecord/export')")
+	public void export(@RequestBody PlatformCashAccountRecordSearch query) {
+		List<PlatformCashAccountRecord> platformCashAccountRecords = platformCashAccountRecordService.queryAll(query);
+
+		List<PlatformCashAccountRecordExport> list = new ArrayList<>();
+		platformCashAccountRecords.forEach(o -> {
+			PlatformCashAccountRecordExport export = new PlatformCashAccountRecordExport();
+			BeanUtils.copyProperties(o, export);
+			if (null == export.getTransAmount()) {
+				export.setTransAmount(BigDecimal.ZERO);
+			}
+			list.add(export);
+		});
+		ExcelUtils.exportExcel(list, "平台收支列表数据" + System.currentTimeMillis(),
+				"平台收支列表数据");
+	}
+
+}

+ 40 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/PracticeController.java

@@ -0,0 +1,40 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.search.PracticeSearch;
+import com.yonge.cooleshow.biz.dal.service.PracticeService;
+import com.yonge.cooleshow.biz.dal.vo.PracticeVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/pactice")
+@Api(value = "陪练课")
+public class PracticeController extends BaseController {
+
+    @Autowired
+    private PracticeService pacticeService;
+
+    @ApiOperation(value = "陪练课-老师详情")
+    @PostMapping("/teacherPactice")
+    public HttpResponseResult<PageInfo<PracticeVo>> teacherPactice(@RequestBody PracticeSearch search) {
+        IPage<PracticeVo> pages = pacticeService.selectTeacherPactice(PageUtil.getPage(search), search);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "陪练课-学生详情")
+    @PostMapping("/studentPactice")
+    public HttpResponseResult<PageInfo<PracticeVo>> studentPactice(@RequestBody PracticeSearch search) {
+        IPage<PracticeVo> pages = pacticeService.selectStudentPactice(PageUtil.getPage(search), search);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+}

+ 98 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ReturnVisitController.java

@@ -0,0 +1,98 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.ReturnVisitSearch;
+import com.yonge.cooleshow.biz.dal.entity.ReturnVisit;
+import com.yonge.cooleshow.biz.dal.service.ReturnVisitService;
+import com.yonge.cooleshow.biz.dal.vo.ReturnVisitVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.Date;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/returnVisit")
+@Api(value = "回访表", tags = "回访表")
+public class ReturnVisitController extends BaseController {
+
+    @Autowired
+    private ReturnVisitService returnVisitService;
+
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<ReturnVisitVo> detail(@PathVariable("id") Long id) {
+    	return succeed(returnVisitService.detail(id));
+	}
+    
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入returnVisitSearch")
+    public HttpResponseResult<PageInfo<ReturnVisitVo>> page(@RequestBody ReturnVisitSearch query) {
+		IPage<ReturnVisitVo> pages = returnVisitService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+    
+    /**
+	 * 新增
+	 */
+	@PostMapping("/save")
+	@ApiOperation(value = "新增", notes = "传入returnVisit")
+	public HttpResponseResult save(@Valid @RequestBody ReturnVisit returnVisit) {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null || null == user.getId()) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+		returnVisit.setCreateBy(user.getId());
+		returnVisit.setCreateTime(new Date());
+
+    	return status(returnVisitService.save(returnVisit));
+	}
+    
+    /**
+	 * 修改
+	 */
+	// @PostMapping("/update")
+	@ApiOperation(value = "修改", notes = "传入returnVisit")
+	public HttpResponseResult update(@Valid @RequestBody ReturnVisit returnVisit) {
+        return status(returnVisitService.updateById(returnVisit));
+	}
+
+
+ 	/**
+	 * 删除
+	 */
+	@PostMapping("/remove")
+	@ApiOperation(value = "删除", notes = "传入ids")
+	public HttpResponseResult remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+        if (StringUtil.isEmpty(ids)) {
+			return failed("参数不能为空");
+		}
+		return status(returnVisitService.removeByIds(StringUtil.toLongList(ids)));
+	}
+}

+ 88 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SmsCodeController.java

@@ -0,0 +1,88 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.wf.captcha.SpecCaptcha;
+import com.wf.captcha.utils.CaptchaUtil;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.security.SecurityConstants;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.concurrent.TimeUnit;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/code")
+@Api(tags = "验证码服务")
+public class SmsCodeController extends BaseController {
+
+    @Autowired
+    private SmsCodeService smsCodeService;
+    @Autowired
+    private RedisTemplate<String,String> redisTemplate;
+
+    @ApiOperation(value = "发送登录短信验证码")
+    @ApiImplicitParams({  @ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataType = "String"),
+                          @ApiImplicitParam(name = "type", value = "类型(PASSWD:修改密码,LOGIN:登录或注册,BANK:绑定银行卡,PHONE:修改手机号)", required = true, dataType = "String") })
+    @PostMapping(value = "/sendSmsCode")
+    public Object sendLoginVerifyCode(String mobile,String type) throws Exception {
+        smsCodeService.sendValidCode(mobile, type, ClientEnum.SYSTEM);
+        return succeed();
+    }
+
+    @ApiOperation(value = "校验短信验证码")
+    @ApiImplicitParams({ @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "code", value = "短信验证码", required = true, dataType = "String"),
+                         @ApiImplicitParam(name = "type", value = "类型(PASSWD:修改密码,LOGIN:登录或注册,BANK:绑定银行卡,PHONE:修改手机号)", required = true, dataType = "String") })
+    @PostMapping(value = "/verifySmsCode")
+    public Object verifySmsCode(String phone,String code,String type) {
+        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
+            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
+        }
+        if(smsCodeService.verifyValidCode(phone,code,type)){
+            return succeed();
+        }
+        return failed("验证码校验失败");
+    }
+
+    @PostMapping(value = "/verifyImageCode")
+    @ApiOperation("校验登录图形验证码")
+    @ApiImplicitParams({ @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "code", value = "验证码", required = true, dataType = "String") })
+    public Object verifyImageCode(String phone,String code){
+        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
+            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
+        }
+        String redisKey = MessageTypeEnum.KAPTCHA_SESSION_KEY + phone;
+        if(redisTemplate.hasKey(redisKey)){
+            if(StringUtils.equalsIgnoreCase(redisTemplate.opsForValue().get(redisKey),code)){
+                return succeed();
+            }
+        }
+        return failed(SecurityConstants.VERIFY_FAILURE);
+    }
+
+    @RequestMapping("/getImageCode")
+    @ApiOperation("获取登录图片验证码")
+    @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String")
+    public void getLoginImage(HttpServletRequest request, HttpServletResponse response,String phone) throws Exception {
+        if(StringUtils.isEmpty(phone)){
+            throw new BizException("请输入手机号");
+        }
+        SpecCaptcha specCaptcha = new SpecCaptcha(125, 45, 4);
+        redisTemplate.opsForValue().set(MessageTypeEnum.KAPTCHA_SESSION_KEY + phone,specCaptcha.text(),3, TimeUnit.MINUTES);
+        CaptchaUtil.out(specCaptcha, request, response);
+    }
+}

+ 92 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/StudentAttendanceController.java

@@ -0,0 +1,92 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.search.StudentAttendanceSearch;
+import com.yonge.cooleshow.biz.dal.entity.StudentAttendance;
+import com.yonge.cooleshow.biz.dal.service.StudentAttendanceService;
+import com.yonge.cooleshow.biz.dal.vo.StudentAttendanceVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+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.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/studentAttendance")
+@Api(value = "学生考勤表", tags = "学生考勤表")
+public class StudentAttendanceController extends BaseController {
+
+    @Autowired
+    private StudentAttendanceService studentAttendanceService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<StudentAttendanceVo> detail(@PathVariable("id") Long id) {
+    	return succeed(studentAttendanceService.detail(id));
+	}
+    
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入studentAttendanceSearch")
+    public HttpResponseResult<PageInfo<StudentAttendanceVo>> page(@RequestBody StudentAttendanceSearch query) {
+		IPage<StudentAttendanceVo> pages = studentAttendanceService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+    
+    /**
+	 * 新增
+	 */
+	@PostMapping("/save")
+	@ApiOperation(value = "新增", notes = "传入studentAttendance")
+	public HttpResponseResult save(@Valid @RequestBody StudentAttendance studentAttendance) {
+    	return status(studentAttendanceService.save(studentAttendance));
+	}
+    
+    /**
+	 * 修改
+	 */
+	@PostMapping("/update")
+	@ApiOperation(value = "修改", notes = "传入studentAttendance")
+	public HttpResponseResult update(@Valid @RequestBody StudentAttendance studentAttendance) {
+        return status(studentAttendanceService.updateById(studentAttendance));
+	}
+    
+    /**
+	 * 新增或修改
+	 */
+    @PostMapping("/submit")
+    @ApiOperation(value = "新增或修改", notes = "传入studentAttendance")
+	public HttpResponseResult submit(@Valid @RequestBody StudentAttendance studentAttendance) {
+        return status(studentAttendanceService.saveOrUpdate(studentAttendance));
+    }
+
+ 	/**
+	 * 删除
+	 */
+	@PostMapping("/remove")
+	@ApiOperation(value = "删除", notes = "传入ids")
+	public HttpResponseResult remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+        if (StringUtil.isEmpty(ids)) {
+			return failed("参数不能为空");
+		}
+		return status(studentAttendanceService.removeByIds(StringUtil.toLongList(ids)));
+	}
+}

+ 221 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/StudentController.java

@@ -0,0 +1,221 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.VipSubmitReq;
+import com.yonge.cooleshow.biz.dal.dto.search.StudentSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.VipRecordSearch;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.MemberPriceSettingsService;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.VipCardRecordService;
+import com.yonge.cooleshow.biz.dal.vo.StudentVo;
+import com.yonge.cooleshow.biz.dal.vo.VipRecordVo;
+import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.cooleshow.common.enums.UserStatusEnum;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.utils.date.DateUtil;
+import com.yonge.toolset.utils.excel.POIUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.List;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/student")
+@Api(value = "学生表", tags = "学生表")
+public class StudentController extends BaseController {
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private MemberPriceSettingsService memberPriceSettingsService;
+
+    @Autowired
+    private VipCardRecordService vipCardRecordService;
+
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", paramType = "path", dataType = "long", required = true),
+    })
+    @PreAuthorize("@pcs.hasPermissions('student/detail')")
+    public HttpResponseResult<StudentVo> detail(@PathVariable("id") Long id) {
+        StudentVo detail = studentService.detail(id);
+        return succeed(detail);
+    }
+
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入StudentSearch")
+    @PreAuthorize("@pcs.hasPermissions('student/page')")
+    public HttpResponseResult<PageInfo<StudentVo>> page(@RequestBody StudentSearch query) {
+
+        if (StringUtils.isNotBlank(query.getUserStatus())) {
+            switch (query.getUserStatus()) {
+                case "LOCKED":
+                    query.setDelFlag(YesOrNoEnum.NO);
+                    query.setLockFlag(UserLockFlag.LOCKED);
+                    break;
+                case "CLOSED":
+                    query.setDelFlag(YesOrNoEnum.YES);
+                    break;
+
+                default:
+                    query.setDelFlag(YesOrNoEnum.NO);
+                    query.setLockFlag(UserLockFlag.NORMAL);
+                    break;
+            }
+        }
+
+        IPage<StudentVo> pages = studentService.selectPage(PageUtil.getPage(query), query);
+        List<StudentVo> rows = pages.getRecords();
+
+        for (StudentVo vo : rows) {
+            if (vo.getDelFlag() == YesOrNoEnum.YES) {
+                vo.setUserStatus(UserStatusEnum.CLOSED);
+            } else {
+                if (vo.getLockFlag() == UserLockFlag.LOCKED) {
+                    vo.setUserStatus(UserStatusEnum.LOCKED);
+                } else {
+                    vo.setUserStatus(UserStatusEnum.NORMAL);
+                }
+            }
+        }
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "学生列表导出")
+    @PostMapping("export")
+    @PreAuthorize("@pcs.hasPermissions('student/export')")
+    public void export(HttpServletResponse response, @RequestBody StudentSearch queryInfo) throws IOException {
+        queryInfo.setPage(1);
+        queryInfo.setRows(49999);
+
+        if (StringUtils.isNotBlank(queryInfo.getUserStatus())) {
+            switch (queryInfo.getUserStatus()) {
+                case "LOCKED":
+                    queryInfo.setDelFlag(YesOrNoEnum.NO);
+                    queryInfo.setLockFlag(UserLockFlag.LOCKED);
+                    break;
+                case "CLOSED":
+                    queryInfo.setDelFlag(YesOrNoEnum.YES);
+                    break;
+
+                default:
+                    queryInfo.setDelFlag(YesOrNoEnum.NO);
+                    queryInfo.setLockFlag(UserLockFlag.NORMAL);
+                    break;
+            }
+        }
+        List<StudentVo> rows = studentService.selectPage(PageUtil.getPage(queryInfo), queryInfo).getRecords();
+        if (rows.size() < 1) {
+            throw new BizException("没有可导出数据");
+        }
+
+        for (StudentVo vo : rows) {
+            if (vo.getDelFlag() == YesOrNoEnum.YES) {
+                vo.setUserStatus(UserStatusEnum.CLOSED);
+            } else {
+                if (vo.getLockFlag() == UserLockFlag.LOCKED) {
+                    vo.setUserStatus(UserStatusEnum.LOCKED);
+                } else {
+                    vo.setUserStatus(UserStatusEnum.NORMAL);
+                }
+            }
+        }
+        OutputStream outputStream = response.getOutputStream();
+        try {
+            HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"学生编号", "学生姓名", "真实姓名", "性别", "出生日期",
+                    "年龄", "专业", "手机号码", "是否是会员", "注册时间", "用户状态", "学生来源"}, new String[]{
+                    "userId", "username", "realName", "gender.msg", "birthdate", "age", "subjectName", "phone",
+                    "isVip.msg", "createTime", "userStatus.msg", "tenantName"}, rows);
+            response.setContentType("application/octet-stream");
+            response.setHeader("Content-Disposition", "attac:wq" +
+                    "hment;filename=学生列表-" + DateUtil.getDate(new Date()) + ".xls");
+
+            outputStream = response.getOutputStream();
+            workbook.write(outputStream);
+            outputStream.flush();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (outputStream != null) {
+                try {
+                    outputStream.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    @PostMapping("/addVip")
+    @ApiOperation(value = "添加会员")
+    @PreAuthorize("@pcs.hasPermissions('student/addVip')")
+    public HttpResponseResult<Boolean> addVip(@Valid @RequestBody VipSubmitReq vipSubmitReq) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        return succeed(memberPriceSettingsService.addVip(vipSubmitReq, ClientEnum.STUDENT, sysUser));
+    }
+
+
+    @PostMapping("/vipRecord")
+    @ApiOperation(value = "会员记录")
+    @PreAuthorize("@pcs.hasPermissions('student/vipRecord')")
+    public HttpResponseResult<PageInfo<VipRecordVo>> vipRecord(@Valid @RequestBody VipRecordSearch recordSearch) {
+
+        recordSearch.setClient(ClientEnum.STUDENT);
+        return succeed(vipCardRecordService.vipRecord(recordSearch));
+    }
+
+    @PostMapping("/updateTenant")
+    @ApiOperation(value = "修改机构")
+    public HttpResponseResult<Boolean> updateTenant(@RequestBody StudentWrapper.StudentUpdateTenant updateTenant) {
+        SysUser user = sysUserFeignService.queryUserById(updateTenant.getStudentId());
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if (user.getTenantId() == null || user.getTenantId() == -1L) {
+            return failed("非机构用户不允许更换机构");
+        }
+
+        Student student = studentService.getById(user.getId());
+        if (student == null) {
+            return failed("未查询到学生的信息");
+        }
+
+        studentService.updateTenant(student, updateTenant.getTenantId());
+        return succeed();
+    }
+}

+ 92 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/StudentCourseHomeworkController.java

@@ -0,0 +1,92 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.search.StudentCourseHomeworkSearch;
+import com.yonge.cooleshow.biz.dal.entity.StudentCourseHomework;
+import com.yonge.cooleshow.biz.dal.service.StudentCourseHomeworkService;
+import com.yonge.cooleshow.biz.dal.vo.StudentCourseHomeworkVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+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.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/studentCourseHomework")
+@Api(value = "学生课程作业", tags = "学生课程作业")
+public class StudentCourseHomeworkController extends BaseController {
+
+    @Autowired
+    private StudentCourseHomeworkService studentCourseHomeworkService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<StudentCourseHomeworkVo> detail(@PathVariable("id") Long id) {
+    	return succeed(studentCourseHomeworkService.detail(id));
+	}
+    
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入studentCourseHomeworkSearch")
+    public HttpResponseResult<PageInfo<StudentCourseHomeworkVo>> page(@RequestBody StudentCourseHomeworkSearch query) {
+		IPage<StudentCourseHomeworkVo> pages = studentCourseHomeworkService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+    
+    /**
+	 * 新增
+	 */
+	@PostMapping("/save")
+	@ApiOperation(value = "新增", notes = "传入studentCourseHomework")
+	public HttpResponseResult save(@Valid @RequestBody StudentCourseHomework studentCourseHomework) {
+    	return status(studentCourseHomeworkService.save(studentCourseHomework));
+	}
+    
+    /**
+	 * 修改
+	 */
+	@PostMapping("/update")
+	@ApiOperation(value = "修改", notes = "传入studentCourseHomework")
+	public HttpResponseResult update(@Valid @RequestBody StudentCourseHomework studentCourseHomework) {
+        return status(studentCourseHomeworkService.updateById(studentCourseHomework));
+	}
+    
+    /**
+	 * 新增或修改
+	 */
+    @PostMapping("/submit")
+    @ApiOperation(value = "新增或修改", notes = "传入studentCourseHomework")
+	public HttpResponseResult submit(@Valid @RequestBody StudentCourseHomework studentCourseHomework) {
+        return status(studentCourseHomeworkService.saveOrUpdate(studentCourseHomework));
+    }
+
+ 	/**
+	 * 删除
+	 */
+	@PostMapping("/remove")
+	@ApiOperation(value = "删除", notes = "传入ids")
+	public HttpResponseResult remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+        if (StringUtil.isEmpty(ids)) {
+			return failed("参数不能为空");
+		}
+		return status(studentCourseHomeworkService.removeByIds(StringUtil.toLongList(ids)));
+	}
+}

+ 82 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SubjectController.java

@@ -0,0 +1,82 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.queryInfo.SubjectQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.SubjectService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@RequestMapping("${app-config.url.admin:}/subject")
+@Api(tags = "声部服务")
+@RestController
+public class SubjectController extends BaseController {
+
+	@Autowired
+	private SubjectService subjectService;
+
+	@ApiOperation(value = "根据声部编号查询声部")
+	@GetMapping("/get/{id}")
+	@PreAuthorize("@pcs.hasPermissions('subject/get')")
+	public HttpResponseResult<Subject> get(@ApiParam(value = "声部编号", required = true) @PathVariable("id") Long id) {
+		return succeed(subjectService.get(id));
+	}
+
+	@ApiOperation(value = "分页查询声部列表")
+	@GetMapping("/queryPage")
+	@PreAuthorize("@pcs.hasPermissions('subject/queryPage')")
+	public HttpResponseResult<PageInfo<Subject>> queryPage(SubjectQueryInfo queryInfo) {
+		PageInfo<Subject> pageInfo = subjectService.queryPage(queryInfo);
+		
+		if(pageInfo.getRows().size() == 0){
+			return succeed(pageInfo);
+		}
+
+		Map<Long, Subject> map = subjectService.findBySubjectByIdList(pageInfo.getRows().stream().map(t -> t.getParentSubjectId()).collect(Collectors.toList())).stream()
+				.collect(Collectors.toMap(Subject::getId, t -> t));
+
+		pageInfo.getRows().forEach(row -> {
+			if(row.getParentSubjectId() != null && row.getParentSubjectId() > 0) {
+				row.setParentSubjectName(map.get(row.getParentSubjectId()).getName());
+			}
+		});
+		return succeed(pageInfo);
+	}
+
+	@ApiOperation(value = "分页查询声部树状列表")
+	@GetMapping("/queryPageTree")
+	@PreAuthorize("@pcs.hasPermissions('subject/queryPageTree')")
+	public HttpResponseResult<PageInfo<Subject>> queryPageTree(SubjectQueryInfo queryInfo) {
+		return succeed(subjectService.queryPageTree(queryInfo));
+	}
+
+	@ApiOperation(value = "修改、新增声部")
+	@PostMapping("/upset")
+	@PreAuthorize("@pcs.hasPermissions('subject/upset')")
+	public Object update(@RequestBody Subject subject) {
+		subjectService.upSetSubject(subject);
+		return succeed();
+	}
+
+	/*@ApiOperation(value = "删除指定声部")
+	@PostMapping("/delete/{id}")
+	@PreAuthorize("@pcs.hasPermissions('subject/delete')")
+	public HttpResponseResult<Subject> delete(@ApiParam(value = "声部编号", required = true) @PathVariable("id") Long id) {
+		subjectService.deleteById(id);
+		return succeed();
+	}*/
+}

+ 129 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysAreaController.java

@@ -0,0 +1,129 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.google.common.collect.Lists;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.yonge.cooleshow.admin.io.request.SysAreaVo;
+import com.yonge.cooleshow.biz.dal.entity.SysArea;
+import com.yonge.cooleshow.biz.dal.service.SysAreaService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysAreaWrapper;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Validated
+@RestController
+@RequestMapping("${app-config.url.admin:}/sysArea")
+@Api(tags = "区域表")
+public class SysAreaController {
+
+    @Autowired
+    private SysAreaService sysAreaService;
+
+	/**
+	 * 查询单条
+	 * @param id 详情ID
+	 * @return R<SysAreaVo.SysArea>
+	 */
+	@ApiOperation(value = "详情", notes = "传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @GetMapping("/detail/{id}")
+    public HttpResponseResult<SysAreaWrapper.SysArea> detail(@PathVariable("id") Long id) {
+
+        return HttpResponseResult.succeed(sysAreaService.detail(id));
+	}
+
+	/**
+	 * 根据code查询
+	 * @param code 详情ID
+	 * @return R<SysAreaVo.SysArea>
+	 */
+	@ApiOperation(value = "根据code查询", notes = "传入code")
+    @GetMapping("/queryByCode/{code}")
+    public HttpResponseResult<SysArea> queryByCode(@PathVariable("code") Integer code) {
+
+		List<Integer> codeList = new ArrayList<Integer>();
+		codeList.add(code);
+		List<SysArea> list = sysAreaService.queryByCodes(codeList);
+
+		if(list == null || list.size() == 0){
+			throw BizException.from("根据code查询区域表失败");
+		}
+
+        return HttpResponseResult.succeed(list.get(0));
+	}
+
+    /**
+	 * 查询分页
+	 * @param query SysAreaVo.SysAreaQuery
+	 * @return R<PageInfo<SysAreaVo.SysAreaList>>
+	 */
+    @ApiOperation(value = "查询分页", notes = "传入sysAreaSearch")
+    @PreAuthorize("@auditsvc.hasPermissions('sysArea/page', {'BACKEND'})")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<SysAreaWrapper.SysArea>> page(@RequestBody SysAreaWrapper.SysAreaQuery query) {
+
+        IPage<SysAreaWrapper.SysArea> pages = sysAreaService.selectPage(QueryInfo.getPage(query), query);
+
+        return HttpResponseResult.succeed(QueryInfo.pageInfo(pages));
+	}
+
+    /**
+     * 查询全部区域
+     * @return R<List<SysAreaVo.Province>>
+     */
+    @ApiOperation(value = "查询全部区域", notes = "查询全部区域")
+    @GetMapping("/queryAllProvince")
+    public HttpResponseResult<List<SysAreaVo.Province>> queryAllProvince() {
+
+        List<SysAreaVo.Province> provinces = Lists.newArrayList();
+
+        // 全部城市信息
+        Map<Integer, List<SysArea>> areaMap = sysAreaService.lambdaQuery().list().stream()
+            .filter(x -> x.getDelFlag().equals("0"))
+            .collect(Collectors.groupingBy(SysArea::getParentOrganId));
+
+        SysAreaVo.Province provinceVo;
+        SysAreaVo.City cityVo;
+        for (SysArea province : areaMap.get(0)) {
+
+            provinceVo = JSON.parseObject(JSON.toJSONString(province), SysAreaVo.Province.class)
+                .cities(Lists.newArrayList());
+            provinces.add(provinceVo);
+
+            // 城市信息
+            for (SysArea city : areaMap.get(province.getId())) {
+
+                cityVo = JSON.parseObject(JSON.toJSONString(city), SysAreaVo.City.class);
+                provinceVo.getAreas().add(cityVo);
+
+                if (areaMap.containsKey(city.getId())) {
+                    cityVo.setAreas(JSON.parseArray(JSON.toJSONString(areaMap.get(city.getId())), SysAreaVo.District.class));
+                }
+            }
+        }
+
+        return HttpResponseResult.succeed(provinces);
+    }
+}

+ 114 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysConfigController.java

@@ -0,0 +1,114 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.log.model.AuditLogAnnotation;
+import com.yonge.toolset.utils.http.HttpUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** 
+ * 系统配置控制层
+ */
+@RestController
+@Api(tags = "系统参数设置")
+@RequestMapping(value = "${app-config.url.admin:}/sysConfig")
+public class SysConfigController extends BaseController {
+
+	@Autowired
+	private SysConfigService sysConfigService;
+
+	@ApiOperation(value = "参数列表")
+	@GetMapping(value = "list")
+    @PreAuthorize("@pcs.hasPermissions('sysConfig/list')")
+	public Object configList(String group) {
+		Map<String,Object> params = new HashMap<String, Object>();
+		params.put("group", group);
+		List<SysConfig> configs = sysConfigService.findAll(params);
+		return succeed(configs);
+	}
+
+	@ApiOperation(value = "修改参数")
+	@PostMapping(value = "update")
+    @PreAuthorize("@pcs.hasPermissions('sysConfig/update')")
+	@AuditLogAnnotation(operateName = "修改参数")
+	public Object update(SysConfig config) {
+		config.setModifyOn(new Date());
+		sysConfigService.updateConfig(config);
+		return succeed();
+	}
+
+	@ApiOperation(value = "修改参数")
+	@PostMapping(value = "batchUpdate")
+    @PreAuthorize("@pcs.hasPermissions('sysConfig/batchUpdate')")
+	@AuditLogAnnotation(operateName = "修改参数")
+	public Object batchUpdate(@RequestBody List<SysConfig> configList) {
+		sysConfigService.batchUpdate(configList);
+		return succeed();
+	}
+
+	@ApiOperation(value = "新增参数")
+	@PostMapping(value = "add")
+    @PreAuthorize("@pcs.hasPermissions('sysConfig/add')")
+	public Object addConfig(SysConfig config) {
+		if (config == null)
+			return failed("参数无效");
+		if (StringUtils.isBlank(config.getParamName())) {
+			return failed("参数名称不能为空");
+		}
+		if (StringUtils.isBlank(config.getParamValue())) {
+			return failed("参数值不能为空");
+		}
+		config.setCreateOn(new Date());
+		config.setModifyOn(new Date());
+		return sysConfigService.insert(config) > 0 ? succeed() : failed("添加失败");
+	}
+
+	@ApiOperation(value = "查询参数")
+	@GetMapping(value = "get")
+    @PreAuthorize("@pcs.hasPermissions('sysConfig/get')")
+	public Object getConfig(Long id) {
+		if (id == null || id <= 0)
+			return failed("请检查输入的ID");
+		return succeed(sysConfigService.get(id));
+	}
+
+	@ApiOperation(value = "查询参数")
+	@GetMapping(value = "queryByParamName")
+    @PreAuthorize("@pcs.hasPermissions('sysConfig/queryByParamName')")
+	public Object queryByParamName(String paramName) {
+		if(StringUtils.isBlank(paramName)){
+			return failed("参数不能为空");
+		}
+		return succeed(sysConfigService.findByParamName(paramName));
+	}
+
+	@GetMapping(value = "findConfigValue")
+	public HttpResponseResult<String> findConfigValue(String paramName) {
+		if(StringUtils.isBlank(paramName)){
+			return failed("参数不能为空");
+		}
+		return succeed(sysConfigService.findConfigValue(paramName));
+	}
+
+	@ApiOperation(value = "url短链接")
+	@PostMapping("shortURL")
+	public HttpResponseResult<String> shortURL(String orginURL) {
+		return succeed(HttpUtil.getSortUrl(orginURL));
+	}
+}

+ 71 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysGoodsPriceController.java

@@ -0,0 +1,71 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.biz.dal.entity.SysGoodsPrice;
+import com.yonge.cooleshow.biz.dal.service.SysGoodsPriceService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysGoodsPriceWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 商品价格设置
+ * 2023-07-21 17:32:49
+ */
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/sysGoodsPrice")
+@Api(value = "商品价格", tags = "商品价格")
+public class SysGoodsPriceController extends BaseController {
+
+    @Autowired
+    SysGoodsPriceService sysGoodsPriceService;
+
+    /**
+     * 查询分页
+     * @param query
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "sysGoodsPrice")
+    @PreAuthorize("@pcs.hasPermissions('sysGoodsPrice/page')")
+    public HttpResponseResult<PageInfo<SysGoodsPrice>> page(@RequestBody SysGoodsPriceWrapper.SysGoodsPriceQuery query) {
+        IPage<SysGoodsPrice> pages = sysGoodsPriceService.selectPage(QueryInfo.getPage(query), query);
+        return HttpResponseResult.succeed(PageUtil.pageInfo(pages));
+    }
+
+
+    /**
+     * 修改
+     * @param sysGoodsPrice
+     */
+    @PostMapping("/update")
+    @ApiOperation(value = "修改", notes = "sysGoodsPrice")
+    @PreAuthorize("@pcs.hasPermissions('sysGoodsPrice/update')")
+    public HttpResponseResult<Boolean> update(@RequestBody SysGoodsPriceWrapper.SysGoodsPrice sysGoodsPrice) {
+
+        return HttpResponseResult.succeed(sysGoodsPriceService.update(sysGoodsPrice));
+    }
+
+    /**
+     * 新增
+     * @param sysGoodsPrice
+     */
+    @PostMapping("/add")
+    @ApiOperation(value = "新增", notes = "sysGoodsPrice")
+    @PreAuthorize("@pcs.hasPermissions('sysGoodsPrice/add')")
+    public HttpResponseResult<Boolean> add(@RequestBody SysGoodsPriceWrapper.SysGoodsPrice sysGoodsPrice) {
+        return HttpResponseResult.succeed(sysGoodsPriceService.add(sysGoodsPrice));
+    }
+
+
+}

+ 49 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysImComplaintController.java

@@ -0,0 +1,49 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.yonge.cooleshow.biz.dal.entity.SysImComplaint;
+import com.yonge.cooleshow.biz.dal.service.SysImComplaintService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Date;
+
+/**
+ * (SysImComplaint)表控制层
+ *
+ * @author zx
+ * @since 2022-06-13 16:37:00
+ */
+@RestController
+@Api(tags = "消息(群组)投诉")
+@RequestMapping("${app-config.url.admin:}/sysImComplaint")
+public class SysImComplaintController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private SysImComplaintService sysImComplaintService;
+    @Autowired
+    private SysUserService sysUserService;
+
+    @ApiOperation(value = "新增")
+    @PostMapping("/add")
+    @PreAuthorize("@pcs.hasPermissions('sysImComplaint/add')")
+    public HttpResponseResult<Boolean> add(@RequestBody SysImComplaint sysImComplaint) {
+        sysImComplaint.setUserId(sysUserService.getUserId());
+        Date now = new Date();
+        sysImComplaint.setUpdateTime(now);
+        sysImComplaint.setCreateTime(now);
+        return succeed(sysImComplaintService.save(sysImComplaint));
+    }
+
+}
+

+ 103 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysManualController.java

@@ -0,0 +1,103 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.SysManual;
+import com.yonge.cooleshow.biz.dal.queryInfo.SysManualQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.SysManualService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * (SysManual)表控制层
+ *
+ * @author makejava
+ * @since 2021-12-20 14:23:36
+ */
+@RestController
+@Api(tags = "帮助手册")
+@RequestMapping("${app-config.url.admin:}/sysManual")
+public class SysManualController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private SysManualService sysManualService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation(value = "查询操作手册")
+    @RequestMapping("/listMenuIds")
+    public Object listMenuIds() {
+        return succeed(sysManualService.listMenuIds());
+    }
+
+    @ApiOperation(value = "查询操作手册")
+    @RequestMapping("/list")
+    public Object list(SysManualQueryInfo queryInfo) {
+        return succeed(sysManualService.query(queryInfo));
+    }
+
+    @ApiOperation(value = "新增帮助手册")
+    @PostMapping("/add")
+    public Object add(@RequestBody SysManual sysManual) throws Exception {
+        this.check(sysManual);
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        return succeed(sysManualService.add(sysManual, sysUser.getId()));
+    }
+
+    @ApiOperation(value = "修改帮助手册")
+    @PostMapping("/update")
+    public Object update(@RequestBody SysManual sysManual) throws Exception {
+        this.check(sysManual);
+        if (sysManual.getId() == null) {
+            throw new Exception("更新必须有id");
+        }
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        return succeed(sysManualService.update(sysManual, sysUser.getId()));
+    }
+
+    private void check(SysManual sysManual) throws Exception {
+        if (sysManual.getMenuId() == null) {
+            throw new Exception("菜单Id是必须");
+        }
+        if (sysManual.getName() == null) {
+            throw new Exception("菜单名是必填");
+        }
+        if (sysManual.getName().length() > 256) {
+            throw new Exception("菜单名不能超过256");
+        }
+        if (sysManual.getOpFlow() == null) {
+            throw new Exception("操作流程必填");
+        }
+        if (sysManual.getOpFlow().length() > 8000) {
+            throw new Exception("操作流程不能超过8000字节");
+        }
+        if (sysManual.getFunRule() == null) {
+            throw new Exception("功能规则必填");
+        }
+        if (sysManual.getFunRule().length() > 8000) {
+            throw new Exception("功能规则不能超过8000字节");
+        }
+    }
+
+    @ApiOperation(value = "删除帮助手册")
+    @PostMapping("/remove")
+    public Object remove(@RequestBody SysManual sysManual) throws Exception {
+        sysManualService.removeById(sysManual.getId());
+        return succeed();
+    }
+
+}

+ 59 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysSuggestionController.java

@@ -0,0 +1,59 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestion;
+import com.yonge.cooleshow.biz.dal.queryInfo.SysSuggestionQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Api(tags = "意见反馈")
+@RestController
+@RequestMapping("${app-config.url.admin:}/")
+public class SysSuggestionController extends BaseController {
+
+    @Autowired
+    private SysSuggestionService sysSuggestionService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation(value = "新增")
+    @RequestMapping("sysSuggestion/add")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestion/add')")
+    public Object add(SysSuggestion sysSuggestion) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        sysSuggestion.setUserId(sysUser.getId().longValue());
+        sysSuggestion.setClientType("TEACHER");
+        if(StringUtils.isEmpty(sysSuggestion.getMobileNo())){
+            sysSuggestion.setMobileNo(sysUser.getPhone());
+        }
+        sysSuggestionService.insert(sysSuggestion);
+        return succeed();
+    }
+
+    @ApiOperation(value = "删除")
+    @RequestMapping("sysSuggestion/del")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestion/del')")
+    public Object del(Long id) {
+        sysSuggestionService.delete(id);
+        return succeed();
+    }
+
+    @ApiOperation(value = "分页查询")
+    @RequestMapping("sysSuggestion/queryPage")
+    @PreAuthorize("@pcs.hasPermissions('sysSuggestion/queryPage')")
+    public Object queryPage(SysSuggestionQueryInfo queryInfo) {
+        return succeed(sysSuggestionService.queryPage(queryInfo));
+    }
+
+}

+ 47 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/SysUserContractRecordController.java

@@ -0,0 +1,47 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.search.SysUserContractRecordSearch;
+import com.yonge.cooleshow.biz.dal.service.SysUserContractRecordService;
+import com.yonge.cooleshow.biz.dal.vo.SysUserContractRecordVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 用户协议记录表-一个用户一种协议一个版本一条记录(SysUserContractRecord)表控制层
+ *
+ * @author hgw
+ * @since 2022-05-07 15:04:05
+ */
+@Api(tags = "用户协议记录表-一个用户一种协议一个版本一条记录")
+@RestController
+@RequestMapping("${app-config.url.admin:}/sysUserContractRecord")
+public class SysUserContractRecordController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private SysUserContractRecordService sysUserContractRecordService;
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入sysUserContractRecordSearch")
+    @PreAuthorize("@pcs.hasPermissions('sysUserContractRecord/page')")
+    public HttpResponseResult<PageInfo<SysUserContractRecordVo>> page(@RequestBody SysUserContractRecordSearch query) {
+        IPage<SysUserContractRecordVo> pages = sysUserContractRecordService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+}
+

+ 76 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TeacherAuthEntryRecordController.java

@@ -0,0 +1,76 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.req.AuthOperaReq;
+import com.yonge.cooleshow.biz.dal.dto.search.AuthEntryRecordSearch;
+import com.yonge.cooleshow.biz.dal.service.TeacherAuthEntryRecordService;
+import com.yonge.cooleshow.biz.dal.vo.TeacherAuthEntryRecordVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/teacherAuthEntryRecord")
+@Api(value = "老师入驻审核表", tags = "老师入驻审核表")
+public class TeacherAuthEntryRecordController extends BaseController {
+    @Autowired
+    private TeacherAuthEntryRecordService teacherAuthEntryRecordService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", paramType = "path", dataType = "long", required = true),
+    })
+    @PreAuthorize("@pcs.hasPermissions('teacherAuthEntryRecord/detail')")
+    public HttpResponseResult<TeacherAuthEntryRecordVo> detail(@PathVariable("id") Long id) {
+        TeacherAuthEntryRecordVo detail = teacherAuthEntryRecordService.detail(id);
+        return succeed(detail);
+    }
+
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入AuthEntryRecordSearch")
+    @PreAuthorize("@pcs.hasPermissions('teacherAuthEntryRecord/page')")
+    public HttpResponseResult<PageInfo<TeacherAuthEntryRecordVo>> page(@RequestBody AuthEntryRecordSearch search) {
+        IPage<TeacherAuthEntryRecordVo> pages = teacherAuthEntryRecordService.selectPage(PageUtil.getPage(search), search);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @PostMapping("/historyPage")
+    @ApiOperation(value = "查询分页", notes = "传入AuthEntryRecordSearch")
+    @PreAuthorize("@pcs.hasPermissions('teacherAuthEntryRecord/page')")
+    public HttpResponseResult<PageInfo<TeacherAuthEntryRecordVo>> historyPage(@RequestBody AuthEntryRecordSearch search) {
+        IPage<TeacherAuthEntryRecordVo> pages = teacherAuthEntryRecordService.historyPage(PageUtil.getPage(search), search);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @PostMapping("/doAuth")
+    @ApiOperation(value = "审核", notes = "传入authOperaDto")
+    @PreAuthorize("@pcs.hasPermissions('teacherAuthEntryRecord/doAuth')")
+    public HttpResponseResult<Boolean> doAuth(@Valid @RequestBody AuthOperaReq authOperaReq) throws Exception {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return teacherAuthEntryRecordService.doAuth(authOperaReq, user);
+    }
+}

+ 70 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TeacherAuthMusicianRecordController.java

@@ -0,0 +1,70 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.req.AuthOperaReq;
+import com.yonge.cooleshow.biz.dal.dto.search.AuthEntryRecordSearch;
+import com.yonge.cooleshow.biz.dal.service.TeacherAuthMusicianRecordService;
+import com.yonge.cooleshow.biz.dal.vo.MusicianAuthEntryRecordVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/teacherAuthMusicianRecord")
+@Api(value = "老师音乐人审核表", tags = "老师音乐人审核表")
+public class TeacherAuthMusicianRecordController extends BaseController {
+    @Autowired
+    private TeacherAuthMusicianRecordService teacherAuthMusicianRecordService;
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+
+	/**
+	 * 查询单条详情
+	 */
+	@GetMapping("/detail/{id}")
+	@ApiOperation(value = "详情", notes = "传入id")
+	@ApiImplicitParams({
+			@ApiImplicitParam(name = "id", value = "id", paramType = "path", dataType = "long", required = true),
+	})
+	@PreAuthorize("@pcs.hasPermissions('teacherAuthMusicianRecord/detail')")
+	public HttpResponseResult<MusicianAuthEntryRecordVo> detail(@PathVariable("id") Long id) {
+		MusicianAuthEntryRecordVo detail = teacherAuthMusicianRecordService.detail(id);
+		return succeed(detail);
+	}
+
+	/**
+	 * 查询分页
+	 */
+	@PostMapping("/page")
+	@ApiOperation(value = "查询分页", notes = "传入AuthEntryRecordSearch")
+	@PreAuthorize("@pcs.hasPermissions('teacherAuthMusicianRecord/page')")
+	public HttpResponseResult<PageInfo<MusicianAuthEntryRecordVo>> page(@RequestBody AuthEntryRecordSearch query) {
+		IPage<MusicianAuthEntryRecordVo> pages = teacherAuthMusicianRecordService.selectPage(PageUtil.getPage(query), query);
+		return succeed(PageUtil.pageInfo(pages));
+	}
+
+	@PostMapping("/doAuth")
+	@ApiOperation(value = "审核", notes = "传入authOperaDto")
+	@PreAuthorize("@pcs.hasPermissions('teacherAuthMusicianRecord/doAuth')")
+	public HttpResponseResult<Boolean> doAuth(@Valid @RequestBody AuthOperaReq authOperaReq) throws Exception {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		return teacherAuthMusicianRecordService.doAuth(authOperaReq, sysUser);
+	}
+}

+ 353 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TeacherController.java

@@ -0,0 +1,353 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.admin.io.request.TeacherBindingUserVo;
+import com.yonge.cooleshow.admin.io.request.teacher.TeacherVO;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.TeacherDto;
+import com.yonge.cooleshow.biz.dal.dto.VipSubmitReq;
+import com.yonge.cooleshow.biz.dal.dto.req.TeacherSubmitReq;
+import com.yonge.cooleshow.biz.dal.dto.search.TeacherSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.VipRecordSearch;
+import com.yonge.cooleshow.biz.dal.entity.TeacherStyleVideo;
+import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.queryInfo.TeacherBindingUserQueryInfo;
+import com.yonge.cooleshow.biz.dal.queryInfo.TeacherQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.ImGroupService;
+import com.yonge.cooleshow.biz.dal.service.MemberPriceSettingsService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.service.UserBindingTeacherService;
+import com.yonge.cooleshow.biz.dal.service.VipCardRecordService;
+import com.yonge.cooleshow.biz.dal.vo.MyFens;
+import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
+import com.yonge.cooleshow.biz.dal.vo.VipRecordVo;
+import com.yonge.cooleshow.biz.dal.vo.userBindingTeacher.UserBindingCourseWrapper;
+import com.yonge.cooleshow.biz.dal.vo.userBindingTeacher.UserBindingTeacherWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.cooleshow.common.enums.UserStatusEnum;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.utils.date.DateUtil;
+import com.yonge.toolset.utils.excel.POIUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/teacher")
+@Api(value = "教师表", tags = "教师表")
+public class TeacherController extends BaseController {
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private TeacherService teacherService;
+
+    @Autowired
+    private MemberPriceSettingsService memberPriceSettingsService;
+
+
+    @Autowired
+    private VipCardRecordService vipCardRecordService;
+
+    @Autowired
+    private UserBindingTeacherService userBindingTeacherService;
+
+    @Autowired
+    private ImGroupService imGroupService;
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", paramType = "path", dataType = "long", required = true),
+    })
+    @PreAuthorize("@pcs.hasPermissions('teacher/detail')")
+    public HttpResponseResult<TeacherVo> detail(@PathVariable("id") Long userId) {
+        //TeacherVo detail = teacherService.detail(userId);
+
+        TeacherVo detail = teacherService.findTeacherDetailInfo(userId);
+        if (null != detail && !CollectionUtils.isEmpty(detail.getStyleVideo())) {
+            List<TeacherStyleVideo> styleVideo = detail.getStyleVideo();
+            List<TeacherStyleVideo> collect = styleVideo.stream().filter(o -> AuthStatusEnum.PASS.equals(o.getAuthStatus())).collect(Collectors.toList());
+            detail.setStyleVideo(collect);
+        }
+        return succeed(detail);
+    }
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入teacher")
+    @PreAuthorize("@pcs.hasPermissions('teacher/page')")
+    public HttpResponseResult<PageInfo<TeacherVo>> page(@RequestBody TeacherSearch query) {
+    	
+    	if(StringUtils.isNotBlank(query.getUserStatus())){
+    		switch (query.getUserStatus()) {
+			case "LOCKED":
+				query.setDelFlag(YesOrNoEnum.NO);
+				query.setLockFlag(UserLockFlag.LOCKED);
+				break;
+			case "CLOSED":
+				query.setDelFlag(YesOrNoEnum.YES);
+				break;
+
+			default:
+				query.setDelFlag(YesOrNoEnum.NO);
+				query.setLockFlag(UserLockFlag.NORMAL);
+				break;
+			}
+    	}
+        IPage<TeacherVo> pages = teacherService.selectPage(PageUtil.getPage(query), query);
+		List<TeacherVo> rows = pages.getRecords();
+		
+		for(TeacherVo vo : rows){
+			if(vo.getDelFlag() == YesOrNoEnum.YES){
+				vo.setUserStatus(UserStatusEnum.CLOSED);
+			}else{
+				if(vo.getLockFlag() == UserLockFlag.LOCKED){
+					vo.setUserStatus(UserStatusEnum.LOCKED);
+				}else{
+					vo.setUserStatus(UserStatusEnum.NORMAL);
+				}
+			}
+		}
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    /**
+     * 新增或修改
+     */
+    @PostMapping("/submit")
+    @ApiOperation(value = "新增或修改", notes = "传入teacher")
+    @PreAuthorize("@pcs.hasPermissions('teacher/submit')")
+    public HttpResponseResult<Boolean> submit(@Valid @RequestBody TeacherSubmitReq teacherSubmitReq) {
+        return teacherService.submit(teacherSubmitReq);
+    }
+
+    @PostMapping("/updateTenant")
+    @ApiOperation(value = "新增或修改", notes = "传入teacher")
+    @PreAuthorize("@pcs.hasPermissions('teacher/updateTenant')")
+    public HttpResponseResult<Boolean> updateTenant(@Valid @RequestBody TeacherWrapper.UpdateTenant updateTenant) {
+        teacherService.updateTenant(updateTenant);
+        return succeed();
+    }
+
+    @ApiOperation(value = "老师列表导出")
+    @PostMapping("export")
+    @PreAuthorize("@pcs.hasPermissions('teacher/export')")
+    public void export(HttpServletResponse response, @RequestBody TeacherSearch queryInfo) throws IOException {
+        queryInfo.setPage(1);
+        queryInfo.setRows(49999);
+    	
+    	if(StringUtils.isNotBlank(queryInfo.getUserStatus())){
+    		switch (queryInfo.getUserStatus()) {
+			case "LOCKED":
+				queryInfo.setDelFlag(YesOrNoEnum.NO);
+				queryInfo.setLockFlag(UserLockFlag.LOCKED);
+				break;
+			case "CLOSED":
+				queryInfo.setDelFlag(YesOrNoEnum.YES);
+				break;
+
+			default:
+				queryInfo.setDelFlag(YesOrNoEnum.NO);
+				queryInfo.setLockFlag(UserLockFlag.NORMAL);
+				break;
+			}
+    	}
+        List<TeacherVo> rows = teacherService.selectPage(PageUtil.getPage(queryInfo), queryInfo).getRecords();
+        if (rows.size() < 1) {
+            throw new BizException("没有可导出数据");
+        }
+		
+		for(TeacherVo vo : rows){
+			if(vo.getDelFlag() == YesOrNoEnum.YES){
+				vo.setUserStatus(UserStatusEnum.CLOSED);
+			}else{
+				if(vo.getLockFlag() == UserLockFlag.LOCKED){
+					vo.setUserStatus(UserStatusEnum.LOCKED);
+				}else{
+					vo.setUserStatus(UserStatusEnum.NORMAL);
+				}
+			}
+		}
+        for(TeacherVo vo : rows){
+        	if(StringUtils.isNotBlank(vo.getTag())){
+        		vo.setTag(vo.getTag().replace("STYLE", "个人风采").replace("LIVE", "直播课").replace("VIDEO", "视频课").replace("MUSIC", "乐谱").replace("DEGREE", "学历").replace("TEACHER", "教资"));
+        	}
+        }
+        OutputStream outputStream = response.getOutputStream();
+        try {
+            HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"老师编号", "昵称", "姓名", "手机号", "老师类型",
+                    "注册时间", "认证时间", "状态", "是否是会员", "徽章", "机构"}, new String[]{
+                    "userId", "username", "realName", "phone", "entryFlag.code == 1 ? '达人' : '游客'", "createTime",
+                    "entryAuthDate","userStatus.msg", "isVip.code == 1 ? '是' : '否'", "tag", "tenantName"}, rows);
+            response.setContentType("application/octet-stream");
+            response.setHeader("Content-Disposition", "attac:wq" +
+                    "hment;filename=老师列表-" + DateUtil.getDate(new Date()) + ".xls");
+
+            outputStream = response.getOutputStream();
+            workbook.write(outputStream);
+            outputStream.flush();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (outputStream != null) {
+                try {
+                    outputStream.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    @PostMapping("/addVip")
+    @ApiOperation(value = "添加会员")
+    @PreAuthorize("@pcs.hasPermissions('teacher/addVip')")
+    public HttpResponseResult<Boolean> addVip(@Valid @RequestBody VipSubmitReq vipSubmitReq) {
+
+
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        return succeed(memberPriceSettingsService.addVip(vipSubmitReq, ClientEnum.TEACHER,sysUser));
+    }
+
+
+    @PostMapping("/vipRecord")
+    @ApiOperation(value = "会员记录")
+    @PreAuthorize("@pcs.hasPermissions('teacher/vipRecord')")
+    public HttpResponseResult<PageInfo<VipRecordVo>> vipRecord(@Valid @RequestBody VipRecordSearch recordSearch) {
+
+        recordSearch.setClient(ClientEnum.TEACHER);
+        return succeed(vipCardRecordService.vipRecord(recordSearch));
+    }
+
+    @ApiOperation(value = "个人风采保存")
+    @PostMapping("/updateStyleVideo")
+    @PreAuthorize("@pcs.hasPermissions('teacher/updateStyleVideo')")
+    public HttpResponseResult<Boolean> updateStyleVideo(@RequestBody TeacherDto teacherDto) {
+        if (StringUtil.isEmpty(teacherDto.getSubjectId())) {
+            return failed("参数异常");
+        }
+        teacherService.updateStyleVideo(teacherDto.getUserId(), teacherDto.getStyleVideo(), teacherDto.getMessage());
+        return succeed();
+    }
+
+
+    @ApiOperation(value = "老师琴房课绑定学员列表")
+    @PostMapping("/bindingUserList")
+    // @PreAuthorize("@pcs.hasPermissions('teacher/bindingUserList')")
+    public HttpResponseResult<PageInfo<TeacherBindingUserVo.BindingUserList>> bindingUserList(@RequestBody  @Valid  TeacherBindingUserVo.BindingUserQuery query) {
+        IPage<UserBindingTeacherWrapper> wrapperIPage = userBindingTeacherService.selectBindingUserPage(PageUtil.getPage(query),
+                                                        TeacherBindingUserQueryInfo.BindingUserQuery.from(query.jsonString()));
+        // 数据转换
+        List<TeacherBindingUserVo.BindingUserList> pageInfos = JSON.parseArray(JSON.toJSONString(wrapperIPage.getRecords()),
+                                                                               TeacherBindingUserVo.BindingUserList.class);
+
+        return succeed(PageUtil.getPageInfo(wrapperIPage,pageInfos));
+    }
+
+
+    @ApiOperation(value = "查看课表")
+    @PostMapping("/selectBindingUserCourse")
+    // @PreAuthorize("@pcs.hasPermissions('teacher/selectBindingUserCourse')")
+    public HttpResponseResult<PageInfo<TeacherBindingUserVo.BindingStudentCourseList>> selectBindingUserCourse(@RequestBody @Valid TeacherBindingUserVo.BindingStudentCourseQuery query) {
+        IPage<UserBindingCourseWrapper> wrapperIPage = userBindingTeacherService.selectBindingUserCoursePage(PageUtil.getPage(query),
+                                                                                                             TeacherBindingUserQueryInfo.BindingStudentCourseQuery.from(query.jsonString()));
+        // 数据转换
+        List<TeacherBindingUserVo.BindingStudentCourseList> pageInfos = JSON.parseArray(JSON.toJSONString(wrapperIPage.getRecords()),
+                                                                                        TeacherBindingUserVo.BindingStudentCourseList.class);
+
+        return succeed(PageUtil.getPageInfo(wrapperIPage, pageInfos));
+    }
+    /**
+     * 查询老师统计指标
+     * @param userId 老师ID
+     * @return HttpResponseResult<TeacherVO.TeacherStat>
+     */
+    @ApiOperation(value = "老师统计指标", notes = "传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", paramType = "path", dataType = "long", required = true),
+    })
+    @GetMapping("/stat/{id}")
+    public HttpResponseResult<TeacherVO.TeacherStat> teacherStatInfo(@PathVariable("id") Long userId) {
+
+        // 老师统计指标
+        TeacherWrapper.TeacherStatInfo statInfo = teacherService.findTeacherStatInfoById(userId);
+
+        return succeed(TeacherVO.TeacherStat.from(statInfo.jsonString()));
+    }
+
+    /**
+     * 老师粉丝信息查询
+     * @param query TeacherVO.TeacherFansQuery
+     * @return HttpResponseResult<PageInfo<MyFens>>
+     */
+    @ApiOperation(value = "我的粉丝")
+    @PostMapping(value = "/myFans")
+    public HttpResponseResult<PageInfo<TeacherVO.TeacherFans>> queryMyFans(@RequestBody TeacherVO.TeacherFansQuery query) {
+
+        if (Optional.ofNullable(query.getTeacherId()).orElse(0L) <= 0) {
+            return failed("无效的请求参数");
+        }
+
+        IPage<MyFens> pages = teacherService.queryMyFans(PageUtil.getPage(query), TeacherQueryInfo.FansQuery.from(query.jsonString()));
+
+        // 数据转换
+        List<TeacherVO.TeacherFans> responses = JSON.parseArray(JSON.toJSONString(pages.getRecords()),
+                TeacherVO.TeacherFans.class);
+
+        return succeed(PageUtil.getPageInfo(pages, responses));
+    }
+
+
+    /**
+     * 老师粉丝信息查询
+     * @return HttpResponseResult<PageInfo<MyFens>>
+     */
+    @ApiOperation(value = "旧数据创建粉丝群接口")
+    @PutMapping(value = "/createFansImGroup")
+    public HttpResponseResult createFansImGroup() throws Exception {
+
+        imGroupService.setTeacherFansGroup();
+        return succeed();
+    }
+}

+ 67 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TeacherStyleVideoController.java

@@ -0,0 +1,67 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.req.AuthOperaReq;
+import com.yonge.cooleshow.biz.dal.dto.search.TeacherStyleVideoSearch;
+import com.yonge.cooleshow.biz.dal.service.TeacherStyleVideoService;
+import com.yonge.cooleshow.biz.dal.vo.TeacherStyleVideoVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/teacherStyleVideo")
+@Api(value = "教师风采视频表", tags = "教师风采视频表")
+public class TeacherStyleVideoController extends BaseController {
+    @Autowired
+    private TeacherStyleVideoService teacherStyleVideoService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<TeacherStyleVideoVo> detail(@PathVariable("id") Long id) {
+        return succeed(teacherStyleVideoService.detail(id));
+    }
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入teacherStyleVideoSearch")
+    public HttpResponseResult<PageInfo<TeacherStyleVideoVo>> page(@RequestBody TeacherStyleVideoSearch query) {
+        //后端审核只查询非入驻审核视频
+        query.setEntryFlag(YesOrNoEnum.NO);
+
+        IPage<TeacherStyleVideoVo> pages = teacherStyleVideoService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+
+    @PostMapping("/doAuth")
+    @ApiOperation(value = "审核", notes = "传入authOperaDto")
+    @PreAuthorize("@pcs.hasPermissions('teacherStyleVideo/doAuth')")
+    public HttpResponseResult<Boolean> doAuth(@Valid @RequestBody AuthOperaReq authOperaReq) throws Exception {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        return succeed(teacherStyleVideoService.doAuth(authOperaReq, sysUser));
+    }
+}

+ 49 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantAccountRecordController.java

@@ -0,0 +1,49 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.service.TenantAccountRecordService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantAccountRecordWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/tenantAccountRecord")
+@Api(value = "机构账户流水表", tags = "机构账户流水表")
+public class TenantAccountRecordController extends BaseController {
+
+    @Autowired
+    private TenantAccountRecordService tenantAccountRecordService;
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "机构流水", notes = "TenantAccountRecordQuery")
+    @PreAuthorize("@pcs.hasPermissions('tenantAccountRecord/page')")
+    public HttpResponseResult<PageInfo<TenantAccountRecordWrapper.TenantAccountRecord>> page(@RequestBody TenantAccountRecordWrapper.TenantAccountRecordQuery query) {
+
+
+        IPage<TenantAccountRecordWrapper.TenantAccountRecord> pages = tenantAccountRecordService.selectPage(PageUtil.getPage(query), query);
+
+        // 统计数据
+        TenantAccountRecordWrapper.TenantAccountRecordStat statistics = tenantAccountRecordService.getStatistics(query);
+        if (statistics == null) {
+            statistics = new TenantAccountRecordWrapper.TenantAccountRecordStat();
+        }
+
+        PageInfo<TenantAccountRecordWrapper.TenantAccountRecord> tenantAccountRecordPageInfo = PageUtil.pageInfo(pages);
+        tenantAccountRecordPageInfo.setStatInfo(statistics);
+        return succeed(tenantAccountRecordPageInfo);
+    }
+
+}

+ 67 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantActivationCodeController.java

@@ -0,0 +1,67 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.biz.dal.entity.TenantAlbumPurchase;
+import com.yonge.cooleshow.biz.dal.service.TenantActivationCodeService;
+import com.yonge.cooleshow.biz.dal.service.TenantAlbumPurchaseService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantActivationCodeWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.admin:}/tenantActivationCode")
+@Api(tags = "机构激活码")
+public class TenantActivationCodeController extends BaseController {
+
+    @Autowired
+    private TenantActivationCodeService tenantActivationCodeService;
+
+    @Autowired
+    private TenantAlbumPurchaseService tenantAlbumPurchaseService;
+
+
+    @ApiOperation(value = "查询分页", notes = "机构激活码- 传入 TenantActivationCodeVo.TenantActivationCodeQuery")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<TenantActivationCodeWrapper.TenantActivationCode>> page(
+            @RequestBody TenantActivationCodeWrapper.TenantActivationCodeQuery query) {
+
+        if (StringUtils.isBlank(query.getOrderNo())) {
+            throw new BizException("订单号不能为空");
+        }
+        // 查询订单购买的专辑
+        TenantAlbumPurchase albumPurchase = tenantAlbumPurchaseService.getByOrderNo(query.getOrderNo());
+        if (albumPurchase == null) {
+            return succeed(new PageInfo<>());
+        }
+        query.setActivationStatus(true);
+        query.setTenantAlbumPurchaseId(albumPurchase.getId());
+        // 查询数据
+        IPage<TenantActivationCodeWrapper.TenantActivationCode> pages =
+                tenantActivationCodeService.selectPage(QueryInfo.getPage(query), query);
+        PageInfo<TenantActivationCodeWrapper.TenantActivationCode> pageInfo = PageUtil.pageInfo(pages);
+
+        if (query.getTenantAlbumPurchaseId() != null) {
+            pageInfo.setStatInfo(albumPurchase);
+        }
+
+        return succeed(pageInfo);
+    }
+
+}

+ 256 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantAlbumController.java

@@ -0,0 +1,256 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.admin.io.request.TenantAlbumVo;
+import com.yonge.cooleshow.biz.dal.dto.search.StudentMusicSheetSearch;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.entity.TenantAlbum;
+import com.yonge.cooleshow.biz.dal.entity.TenantAlbumMusic;
+import com.yonge.cooleshow.biz.dal.entity.TenantAlbumRef;
+import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.enums.SubjectTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
+import com.yonge.cooleshow.biz.dal.service.MusicTagService;
+import com.yonge.cooleshow.biz.dal.service.SubjectService;
+import com.yonge.cooleshow.biz.dal.service.TenantAlbumMusicService;
+import com.yonge.cooleshow.biz.dal.service.TenantAlbumRefService;
+import com.yonge.cooleshow.biz.dal.service.TenantAlbumService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * @Author:haonan
+ * @Date:2023/7/27 18:26
+ * @Filename:TenantAlbumController
+ */
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/tenantAlbum")
+@Api(value = "机构专辑管理", tags = "机构专辑管理")
+public class TenantAlbumController {
+    @Autowired
+    TenantAlbumService tenantAlbumService;
+
+    @Autowired
+    private TenantAlbumMusicService tenantAlbumMusicService;
+
+    @Autowired
+    private TenantAlbumRefService tenantAlbumRefService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    @Autowired
+    private MusicSheetService musicSheetService;
+
+    @Autowired
+    private SubjectService subjectService;
+
+    @Autowired
+    private MusicTagService musicTagService;
+
+    /**
+     * 查询分页
+     *
+     * @param query
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "tenantAlbum")
+    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/page')")
+    public HttpResponseResult<PageInfo<TenantAlbumWrapper.TenantAlbum>> page(@RequestBody TenantAlbumWrapper.TenantAlbumQuery query) {
+        IPage<TenantAlbumWrapper.TenantAlbum> pages = tenantAlbumService.selectPage(QueryInfo.getPage(query), query);
+        return HttpResponseResult.succeed(PageUtil.pageInfo(pages));
+    }
+
+
+    /**
+     * 查询详情
+     *
+     * @param id 详情ID
+     * @return TenantAlbum
+     */
+    @PostMapping("/detail")
+    @ApiOperation(value = "查询详情", notes = "detail")
+    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/detail')")
+    public HttpResponseResult<TenantAlbumWrapper.TenantAlbum> detail(@RequestParam("id") Long id) {
+        TenantAlbum tenantAlbum = tenantAlbumService.detail(id);
+        if (tenantAlbum == null) {
+            throw new BizException("专辑信息不存在");
+        }
+
+        TenantAlbumWrapper.TenantAlbum vo = JSON.parseObject(JSON.toJSONString(tenantAlbum),
+                TenantAlbumWrapper.TenantAlbum.class);
+
+        //查关联表
+        TenantAlbumRef one = tenantAlbumRefService.lambdaQuery().eq(TenantAlbumRef::getTenantAlbumId, id)
+                .last("limit 1").one();
+        vo.setTenantId(one.getTenantId().toString());
+        //查询曲目表
+
+        TenantInfo tenantInfo = tenantInfoService.getById(one.getTenantId());
+        vo.setTenantName(tenantInfo.getName());
+        List<TenantAlbumMusic> tenantAlbumMusics = tenantAlbumMusicService.lambdaQuery()
+                .eq(TenantAlbumMusic::getTenantAlbumId, id)
+                .eq(TenantAlbumMusic::getDelFlag, false)
+                .list();
+
+        Map<SubjectTypeEnum, List<TenantAlbumMusic>> groupByType =
+                tenantAlbumMusics.stream().collect(Collectors.groupingBy(TenantAlbumMusic::getSubjectType));
+
+
+        List<Long> musicSheetIdlist = tenantAlbumMusics.stream().map(next -> next.getMusicSheetId()).distinct().collect(Collectors.toList());
+
+
+        StudentMusicSheetSearch search = new StudentMusicSheetSearch();
+        search.setMusicSheetIdlist(musicSheetIdlist);
+        search.setPage(1);
+        search.setRows(9999);
+        IPage<MusicSheetVo> records = musicSheetService.selectStudentPage(PageUtil.getPage(search), search, null);
+        Map<Long, MusicSheetVo> idMsMap = records.getRecords().stream()
+                .collect(Collectors.toMap(MusicSheet::getId, Function.identity()));
+        List<TenantAlbumWrapper.MusicSheetData> musicSheetData = vo.getMusicSheetData();
+        groupByType.forEach((key, value) -> {
+            value.sort(Comparator.comparing(TenantAlbumMusic::getSortNumber));
+            TenantAlbumWrapper.MusicSheetData sheetData = new TenantAlbumWrapper.MusicSheetData();
+            sheetData.setSubjectType(key);
+            List<TenantAlbumWrapper.TenantAlbumSheet> tenantAlbumSheets = value.stream().map(next -> {
+
+                TenantAlbumWrapper.TenantAlbumSheet tenantAlbumSheet = new TenantAlbumWrapper.TenantAlbumSheet();
+                BeanUtils.copyProperties(next, tenantAlbumSheet);
+                Long musicSheetId = tenantAlbumSheet.getMusicSheetId();
+                MusicSheetVo musicSheet = idMsMap.getOrDefault(musicSheetId, new MusicSheetVo());
+                tenantAlbumSheet.setMusicSheetName(musicSheet.getMusicSheetName());
+                tenantAlbumSheet.setMusicTag(musicSheet.getMusicTag());
+                tenantAlbumSheet.setComposer(musicSheet.getComposer());
+                tenantAlbumSheet.setMusicSubject(musicSheet.getMusicSubject());
+                return tenantAlbumSheet;
+            }).collect(Collectors.toList());
+            tenantAlbumSheets.stream().forEach(t->{
+                String musicSubject = t.getMusicSubject();
+
+                if (StringUtils.isNotBlank(musicSubject)){
+                    //设置对应声部名称
+                    List<Subject> subject = subjectService.findBySubjectByIdList(musicSubject);
+                    t.setMusicSubjectName(subject.get(0).getName());
+                }
+
+
+                //设置对应标签名称
+                String musicTag = t.getMusicTag();
+                if (StringUtils.isNotBlank(musicTag)){
+                    String[] split = musicTag.split(",");
+                    for (String s : split) {
+                        List<Long> list = new ArrayList<>();
+                        list.add(Long.parseLong(s));
+                        String tagName = musicTagService.getMusicTagNames(list);
+                        t.setMusicTagName(tagName);
+                    }
+                }
+
+            });
+
+
+            sheetData.setTenantAlbumSheetList(tenantAlbumSheets);
+            musicSheetData.add(sheetData);
+            vo.setMusicSheetData(musicSheetData);
+        });
+
+        return HttpResponseResult.succeed(vo);
+    }
+
+
+    /**
+     * 新增专辑
+     */
+    @PostMapping("/save")
+    @ApiOperation(value = "新增专辑", notes = "新增专辑")
+    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/save')")
+    public HttpResponseResult<Boolean> save(@Validated @RequestBody TenantAlbumVo.TenantAlbum album) {
+        TenantAlbum tenantAlbum = JSON.parseObject(album.jsonString(), TenantAlbum.class);
+        List<TenantAlbumVo.MusicSheetData> musicSheetData = album.getMusicSheetData();
+
+        List<TenantAlbumWrapper.MusicSheetData> musicSheetDataList = musicSheetData.stream().map(next ->{
+                    //TenantAlbumWrapper.MusicSheetData sheetData =new TenantAlbumWrapper.MusicSheetData();
+                    TenantAlbumWrapper.MusicSheetData sheetData =new TenantAlbumWrapper.MusicSheetData();
+
+                    List<TenantAlbumVo.MusicObject> musicSheetList = next.getMusicSheetList();
+                    sheetData.getTenantAlbumSheetList().addAll( musicSheetList.stream().map(m->{
+                        TenantAlbumWrapper.TenantAlbumSheet tenantAlbumSheet = new TenantAlbumWrapper.TenantAlbumSheet();
+                        tenantAlbumSheet.setLevel(m.getLevel());
+                        tenantAlbumSheet.setType(m.getType());
+                        tenantAlbumSheet.setId(m.getId().toString());
+                        return tenantAlbumSheet;
+                    }).collect(Collectors.toList()));
+                    sheetData.setSubjectType(next.getSubjectType());
+                    return sheetData;
+                }
+        ).collect(Collectors.toList());
+        tenantAlbumService.insertTenantAlbum(album.getTenantId(), tenantAlbum, musicSheetDataList);
+        return HttpResponseResult.succeed();
+    }
+
+    @PostMapping("/update")
+    @ApiOperation(value = "修改专辑", notes = "修改专辑")
+    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/update')")
+    public HttpResponseResult<Boolean> update( @RequestBody TenantAlbumVo.TenantAlbum album) {
+        TenantAlbum tenantAlbum = JSON.parseObject(album.jsonString(), TenantAlbum.class);
+        List<TenantAlbumVo.MusicSheetData> musicSheetData = album.getMusicSheetData();
+
+        List<TenantAlbumWrapper.MusicSheetData> musicSheetDataList = musicSheetData.stream().map(next ->{
+            //TenantAlbumWrapper.MusicSheetData sheetData =new TenantAlbumWrapper.MusicSheetData();
+            TenantAlbumWrapper.MusicSheetData sheetData =new TenantAlbumWrapper.MusicSheetData();
+
+            List<TenantAlbumVo.MusicObject> musicSheetList = next.getMusicSheetList();
+            sheetData.getTenantAlbumSheetList().addAll( musicSheetList.stream().map(m->{
+                TenantAlbumWrapper.TenantAlbumSheet tenantAlbumSheet = new TenantAlbumWrapper.TenantAlbumSheet();
+                tenantAlbumSheet.setLevel(m.getLevel());
+                tenantAlbumSheet.setType(m.getType());
+                tenantAlbumSheet.setId(m.getId().toString());
+                return tenantAlbumSheet;
+            }).collect(Collectors.toList()));
+            sheetData.setSubjectType(next.getSubjectType());
+            return sheetData;
+        }).collect(Collectors.toList());
+        tenantAlbumService.updateAlbum(album.getTenantId(), tenantAlbum, musicSheetDataList);
+        return HttpResponseResult.succeed();
+    }
+
+    @PostMapping("/updateStatus")
+    @ApiOperation(value = "启用/冻结", notes = "启用/冻结")
+    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/updateStatus')")
+    public HttpResponseResult<Boolean> updateStatus(@Validated @RequestBody TenantAlbumVo.UpdateStatus status) {
+        tenantAlbumService.lambdaUpdate()
+                .set(TenantAlbum::getStatus, status.getStatus())
+                .eq(TenantAlbum::getId, status.getId())
+                .update();
+        return HttpResponseResult.succeed();
+    }
+
+}

+ 100 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantEntryRecordController.java

@@ -0,0 +1,100 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.service.TenantApplyRecordService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantApplyRecordWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @Author:haonan
+ * @Date:2023/8/1 19:02
+ * @Filename:TenantEntryRecordController
+ */
+@RestController
+@RequestMapping("${app-config.url.admin:}/tenantApply")
+@Api(value = "机构审核", tags = "机构审核")
+public class TenantEntryRecordController extends BaseController {
+
+    @Autowired
+    TenantApplyRecordService tenantApplyRecordService;
+
+    @Autowired
+    SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    TenantInfoService tenantInfoService;
+
+    /**
+     * 机构入驻审核分页查询
+     */
+    @PostMapping("/applyPage")
+    @ApiOperation(value = "机构申请查询", notes = "机构申请查询")
+    @PreAuthorize("@pcs.hasPermissions('tenantApply/applyPage')")
+    public HttpResponseResult<PageInfo<TenantApplyRecordWrapper.TenantApplyRecord>> applyPage(@RequestBody TenantApplyRecordWrapper.TenantApplyRecordQuery query) {
+
+        IPage<TenantApplyRecordWrapper.TenantApplyRecord> pages = tenantApplyRecordService.selectPage(QueryInfo.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+
+    /**
+     * 机构入驻审核历史记录查询
+     */
+
+    @PostMapping("/historyPage")
+    @ApiOperation(value = "机构审核历史记录", notes = "机构审核历史记录")
+    @PreAuthorize("@pcs.hasPermissions('tenantApply/historyPage')")
+    public HttpResponseResult<PageInfo<TenantApplyRecordWrapper.TenantApply>> historyPage(@RequestBody TenantApplyRecordWrapper.TenantApplyRecordQuery query) {
+
+       IPage<TenantApplyRecordWrapper.TenantApply> pages = tenantApplyRecordService.historyPage(QueryInfo.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+
+    /**
+     * 机构入驻审核本次提交查询
+     */
+    @PostMapping("/queryNow")
+    @ApiOperation(value = "机构审核本次提交", notes = "机构审核本次提交")
+    @PreAuthorize("@pcs.hasPermissions('tenantApply/queryNow')")
+    public HttpResponseResult<TenantApplyRecordWrapper.TenantApplyRecord> queryNow(@RequestBody TenantApplyRecordWrapper.TenantApplyRecordQuery query) {
+
+        TenantApplyRecordWrapper.TenantApplyRecord tenantApplyRecord = tenantApplyRecordService.queryNow(query);
+        return succeed(tenantApplyRecord);
+    }
+
+    /**
+     * 机构入驻审核功能
+     */
+    @PostMapping("/entry")
+    @ApiOperation(value = "机构审核功能", notes = "机构审核功能")
+    @PreAuthorize("@pcs.hasPermissions('tenantApply/entry')")
+    public HttpResponseResult<Boolean> entry(@RequestBody TenantApplyRecordWrapper.TenantEntry entry) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        /*TenantInfo tenantInfo = tenantInfoService.lambdaQuery().eq(TenantInfo::getUserId, sysUser.getId())
+                .last("limit 1").one();
+        if (tenantInfo == null) {
+            throw new BizException("非法请求");
+        }*/
+        Long verifyUserId = sysUser.getId();
+
+        return succeed(tenantApplyRecordService.entry(entry,verifyUserId));
+    }
+
+
+}

+ 96 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantInfoController.java

@@ -0,0 +1,96 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.admin.io.request.TenantInfoVo;
+import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @Author:haonan
+ * @Date:2023/7/24 9:57
+ * @Filename:TenantInfoController
+ */
+@RestController
+@RequestMapping("${app-config.url.admin:}/tenantInfo")
+@Api(value = "机构管理", tags = "机构管理")
+public class TenantInfoController extends BaseController {
+
+    @Autowired
+    TenantInfoService tenantInfoService;
+
+    /**
+     * 查询分页
+     *
+     * @param query
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "TenantInfo")
+    @PreAuthorize("@pcs.hasPermissions('tenantInfo/page')")
+    public HttpResponseResult<PageInfo<TenantInfoWrapper.TenantInfo>> page(@RequestBody TenantInfoWrapper.TenantInfoQuery query) {
+
+        IPage<TenantInfoWrapper.TenantInfo> pages = tenantInfoService.selectPage(query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+
+    /**
+     * 插入数据
+     */
+    @PostMapping("/add")
+    @ApiOperation(value = "更新", notes = "传入TenantInfo")
+    @PreAuthorize("@pcs.hasPermissions('tenantInfo/add')")
+    public HttpResponseResult<Boolean> add( @RequestBody TenantInfoVo.TenantInfo info) {
+        return succeed(tenantInfoService.add(JSON.parseObject(info.jsonString(), TenantInfo.class)));
+    }
+
+    /**
+     * 修改数据
+     */
+    @PostMapping("/update")
+    @ApiOperation(value = "修改", notes = "传入TenantInfo")
+    @PreAuthorize("@pcs.hasPermissions('tenantInfo/update')")
+    public HttpResponseResult<Boolean> update( @RequestBody TenantInfoVo.TenantInfo info) {
+        return succeed(tenantInfoService.update(JSON.parseObject(info.jsonString(), TenantInfo.class)));
+    }
+
+    /**
+     * 冻结
+     */
+    @PostMapping("/updateStatus")
+    @ApiOperation(value = "冻结", notes = "传入id和布尔类型")
+    @PreAuthorize("@pcs.hasPermissions('tenantInfo/updateStatus')")
+    public HttpResponseResult<Boolean> updateStatus(@RequestBody TenantInfoWrapper.UpdateStatus updateStatus) {
+        tenantInfoService.updateStatus(updateStatus);
+        return succeed();
+    }
+
+    /**
+     * 查询详情
+     *
+     * @param id
+     */
+    @PostMapping("/detail")
+    @ApiOperation(value = "查询详情", notes = "查询详情")
+    @PreAuthorize("@pcs.hasPermissions('tenantInfo/detail')")
+    public HttpResponseResult<TenantInfoWrapper.TenantInfo> detail(@RequestParam("id")Long id) {
+
+        TenantInfoWrapper.TenantInfo info = tenantInfoService.detailTenantInfo(id);
+        return succeed(info);
+    }
+
+}

+ 136 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantMemberController.java

@@ -0,0 +1,136 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.biz.dal.entity.TenantMember;
+import com.yonge.cooleshow.biz.dal.service.TenantMemberService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantMemberWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+
+/**
+ * @Author:haonan
+ * @Date:2023/8/10 13:40
+ * @Filename:TenantMemberController
+ */
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.admin:}/tenantMember")
+@Api(tags = "机构子账户表")
+public class TenantMemberController extends BaseController {
+
+    @Autowired
+    private TenantMemberService tenantMemberService;
+
+    @ApiOperation(value = "详情", notes = "机构子账户表-根据详情ID查询单条, 传入id")
+    @PreAuthorize("@pcs.hasPermissions('tenantMember/detail', {'BACKEND'})")
+    @PostMapping("/detail/{id}")
+    public R<TenantMember> detail(@PathVariable("id") Long id) {
+
+        TenantMember wrapper = tenantMemberService.detail(id);
+
+        return R.from(wrapper);
+    }
+
+    @ApiOperation(value = "查询分页", notes = "机构子账户表- 传入 TenantMemberWrapper.TenantMemberQuery")
+    @PreAuthorize("@pcs.hasPermissions('tenantMember/page', {'BACKEND'})")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<TenantMemberWrapper.TenantMember>> page(@RequestBody TenantMemberWrapper.TenantMemberQuery query) {
+
+        IPage<TenantMemberWrapper.TenantMember> pages = tenantMemberService.selectPage(QueryInfo.getPage(query), query);
+
+        return succeed(QueryInfo.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "新增", notes = "机构子账户表- 传入 TenantMemberWrapper.InsertTenantMember")
+    @PreAuthorize("@pcs.hasPermissions('tenantMember/add', {'BACKEND'})")
+    @PostMapping("/add")
+    public HttpResponseResult add(@Valid @RequestBody TenantMemberWrapper.InsertOrUpdateTenantMember tenantMember) throws IOException {
+
+        File file = new File("/var/tmp/" + tenantMember.getMultipartFile().getOriginalFilename());
+        tenantMember.setFile(file);
+        InputStream inputStream = tenantMember.getMultipartFile().getInputStream();
+
+        try {
+            if (!file.getParentFile().exists()) {
+                file.getParentFile().mkdirs();
+            }
+            FileOutputStream fos = new FileOutputStream(file);
+            IOUtils.copy(inputStream, fos);
+            // 新增数据
+            return HttpResponseResult.succeed(tenantMemberService.add(tenantMember));
+        } catch (Exception e) {
+            return failed(e.getMessage());
+        } finally {
+            IOUtils.closeQuietly(inputStream);
+            FileUtils.deleteQuietly(file);
+        }
+    }
+
+    @ApiOperation(value = "修改", notes = "机构子账户表- 传入 TenantMemberWrapper.InsertTenantMember")
+    @PreAuthorize("@pcs.hasPermissions('tenantMember/update', {'BACKEND'})")
+    @PostMapping("/update")
+    public HttpResponseResult update(@RequestBody TenantMemberWrapper.InsertOrUpdateTenantMember tenantMember) throws IOException {
+        File file = new File("/var/tmp/" + tenantMember.getMultipartFile().getOriginalFilename());
+        tenantMember.setFile(file);
+        InputStream inputStream = tenantMember.getMultipartFile().getInputStream();
+
+        try {
+            if (!file.getParentFile().exists()) {
+                file.getParentFile().mkdirs();
+            }
+            FileOutputStream fos = new FileOutputStream(file);
+            IOUtils.copy(inputStream, fos);
+            // 新增数据
+            return HttpResponseResult.succeed(tenantMemberService.update(tenantMember));
+        } catch (Exception e) {
+            return failed(e.getMessage());
+        } finally {
+            IOUtils.closeQuietly(inputStream);
+            FileUtils.deleteQuietly(file);
+        }
+    }
+
+
+    @ApiOperation(value = "修改结算账户", notes = "机构子账户表- 传入 TenantMemberWrapper.UpdateCount")
+    @PreAuthorize("@pcs.hasPermissions('tenantMember/updateCount', {'BACKEND'})")
+    @PostMapping("/updateCount")
+    public HttpResponseResult updateCount(@RequestBody TenantMemberWrapper.UpdateCount tenantMember) {
+
+        // 更新数据
+        return HttpResponseResult.succeed(tenantMemberService.updateCount(tenantMember));
+    }
+
+
+    @ApiOperation(value = "删除", notes = "机构子账户表- 传入id")
+    @PreAuthorize("@pcs.hasPermissions('tenantMember/remove', {'BACKEND'})")
+    @PostMapping("/remove")
+    public R<Boolean> remove(@RequestParam Long id) {
+
+        return R.from(tenantMemberService.removeById(id));
+    }
+}

+ 70 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantUnbindHistoryController.java

@@ -0,0 +1,70 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.service.EmployeeService;
+import com.yonge.cooleshow.biz.dal.service.TenantUnbindRecordService;
+import com.yonge.cooleshow.biz.dal.vo.EmployeeVo;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantUnbindRecordWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.admin:}/tenantUnbindHistory")
+@Api(tags = "机构解绑历史表")
+public class TenantUnbindHistoryController extends BaseController{
+
+    @Autowired
+    private TenantUnbindRecordService tenantUnbindRecordService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private EmployeeService employeeService;
+
+    @ApiOperation(value = "查询分页", notes = "机构解绑申请记录- 传入 TenantUnbindRecordVo.TenantUnbindRecordQuery")
+    @PreAuthorize("@pcs.hasPermissions('tenantUnbindRecord/page')")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<TenantUnbindRecordWrapper.TenantUnbindRecord>>
+    page(@RequestBody TenantUnbindRecordWrapper.TenantUnbindRecordQuery query) {
+        // 查询数据
+        IPage<TenantUnbindRecordWrapper.TenantUnbindRecord> pages =
+                tenantUnbindRecordService.selectPage(QueryInfo.getPage(query), query);
+        return succeed(QueryInfo.pageInfo(pages, pages.getRecords()));
+    }
+
+    @ApiOperation(value = "审核")
+    @PostMapping("/audit")
+    @PreAuthorize("@pcs.hasPermissions('tenantUnbindRecord/audit')")
+    public HttpResponseResult<Boolean> audit(@RequestBody TenantUnbindRecordWrapper.Audio audio) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            throw new BizException("请登录");
+        }
+        EmployeeVo employeeVo = employeeService.detail(sysUserFeignService.queryUserInfo().getId());
+        if (employeeVo == null || UserLockFlag.LOCKED.equals(employeeVo.getLockFlag())) {
+            throw new BizException("权限不足");
+        }
+        tenantUnbindRecordService.tenantUserUnbindAudit(audio, sysUser.getId(),true);
+        return succeed();
+    }
+}

+ 70 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TenantUnbindRecordController.java

@@ -0,0 +1,70 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.service.EmployeeService;
+import com.yonge.cooleshow.biz.dal.service.TenantUnbindRecordService;
+import com.yonge.cooleshow.biz.dal.vo.EmployeeVo;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantUnbindRecordWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.admin:}/tenantUnbindRecord")
+@Api(tags = "机构解绑申请记录")
+public class TenantUnbindRecordController extends BaseController {
+
+    @Autowired
+    private TenantUnbindRecordService tenantUnbindRecordService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private EmployeeService employeeService;
+
+    @ApiOperation(value = "查询分页", notes = "机构解绑申请记录- 传入 TenantUnbindRecordVo.TenantUnbindRecordQuery")
+    @PreAuthorize("@pcs.hasPermissions('tenantUnbindRecord/page')")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<TenantUnbindRecordWrapper.TenantUnbindRecord>>
+    page(@RequestBody TenantUnbindRecordWrapper.TenantUnbindRecordQuery query) {
+        // 查询数据
+        IPage<TenantUnbindRecordWrapper.TenantUnbindRecord> pages =
+                tenantUnbindRecordService.selectPage(QueryInfo.getPage(query), query);
+        return succeed(QueryInfo.pageInfo(pages, pages.getRecords()));
+    }
+
+    @ApiOperation(value = "审核")
+    @PostMapping("/audit")
+    @PreAuthorize("@pcs.hasPermissions('tenantUnbindRecord/audit')")
+    public HttpResponseResult<Boolean> audit(@RequestBody TenantUnbindRecordWrapper.Audio audio) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            throw new BizException("请登录");
+        }
+        EmployeeVo employeeVo = employeeService.detail(sysUserFeignService.queryUserInfo().getId());
+        if (employeeVo == null || UserLockFlag.LOCKED.equals(employeeVo.getLockFlag())) {
+            throw new BizException("权限不足");
+        }
+        tenantUnbindRecordService.tenantUserUnbindAudit(audio, sysUser.getId(),true);
+        return succeed();
+    }
+}

+ 81 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/UnbindAuthUserController.java

@@ -0,0 +1,81 @@
+package com.yonge.cooleshow.admin.controller;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.biz.dal.entity.UnbindAuthUser;
+import com.yonge.cooleshow.biz.dal.service.UnbindAuthUserService;
+import com.yonge.cooleshow.biz.dal.wrapper.UnbindAuthUserWrapper;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.admin:}/unbindAuthUser")
+@Api(tags = "解绑审核人员设置")
+public class UnbindAuthUserController {
+
+    @Autowired
+    private UnbindAuthUserService unbindAuthUserService;
+
+    
+    @ApiOperation(value = "查询分页", notes = "解绑审核人员设置- 传入 UnbindAuthUserWrapper.UnbindAuthUserQuery") 
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<UnbindAuthUserWrapper.UnbindAuthUser>> page(@RequestBody UnbindAuthUserWrapper.UnbindAuthUserQuery query) {
+        
+        IPage<UnbindAuthUserWrapper.UnbindAuthUser> pages = unbindAuthUserService.selectPage(QueryInfo.getPage(query), query);
+        
+        return HttpResponseResult.succeed(PageUtil.pageInfo(pages));
+	}
+    
+    @ApiOperation(value = "新增", notes = "解绑审核人员设置- 传入 UnbindAuthUserWrapper.UnbindAuthUser")
+	@PostMapping("/save")
+	public HttpResponseResult<JSONObject> add(@Validated @RequestBody UnbindAuthUser unbindAuthUser) {
+
+        if (unbindAuthUser.getUserId() == null) {
+            throw new BizException("用户ID不能为空");
+        }
+        // 新增数据
+        unbindAuthUserService.save(unbindAuthUser);
+        
+        return HttpResponseResult.succeed();
+	}
+    
+    @ApiOperation(value = "修改", notes = "解绑审核人员设置- 传入 UnbindAuthUserWrapper.UnbindAuthUser")
+	@PostMapping("/update")
+	public HttpResponseResult<JSONObject> update(@Validated @RequestBody UnbindAuthUser unbindAuthUser) {
+
+        if (unbindAuthUser.getId() == null) {
+            throw new BizException("ID不能为空");
+        }
+
+        if (unbindAuthUser.getUserId() == null) {
+            throw new BizException("用户ID不能为空");
+        }
+        // 更新数据
+        unbindAuthUserService.updateById(unbindAuthUser);
+
+        return HttpResponseResult.succeed();
+	}
+
+	@ApiOperation(value = "删除", notes = "解绑审核人员设置- 传入id")
+	@PostMapping("/remove")
+	public HttpResponseResult<Boolean> remove(@RequestParam Long id) {
+    
+		return HttpResponseResult.succeed(unbindAuthUserService.removeById(id));
+	}
+}

+ 80 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/UploadFileController.java

@@ -0,0 +1,80 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.microsvc.toolkit.middleware.oss.wrapper.OssWrapper;
+import com.yonge.cooleshow.biz.dal.service.UploadFileService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.entity.UploadReturnBean;
+import com.yonge.toolset.thirdparty.entity.UploadSign;
+import com.yonge.toolset.utils.upload.UploadUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 上传控制层
+ */
+@RestController
+@RequestMapping("${app-config.url.admin:}/")
+@Api(tags = "文件上传服务")
+public class UploadFileController extends BaseController {
+
+    private final static Logger LOGGER = LoggerFactory.getLogger(UploadFileController.class);
+
+    @Autowired
+    private UploadFileService uploadFileService;
+
+    @PostMapping("/uploadFile")
+    public Object uploadFile(@ApiParam(value = "上传的文件", required = true) @RequestParam("file") MultipartFile file) {
+        try {
+            if (file != null && StringUtils.isNotBlank(file.getOriginalFilename())) {
+                UploadReturnBean bean = uploadFileService.uploadFile(file.getInputStream(), UploadUtil.getExtension(file.getOriginalFilename()));
+                bean.setName(file.getOriginalFilename());
+                if (bean.isStatus()) {
+                    return succeed(bean);
+                }
+                return failed(bean.getMessage());
+            }
+        } catch (Exception e) {
+            LOGGER.error("上传失败", e);
+        }
+        return failed("上传失败");
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "bucketName", dataType = "String", value = "为空时默认使用daya"),
+            @ApiImplicitParam(name = "fileName", dataType = "String", value = "要上传的文件名称,不包含路径信息"),
+            @ApiImplicitParam(name = "postData", dataType = "Map", value = "1.如果使用js sdk上传的时候设置了ACL请设置,例\"acl\":\"public-read\"值要与SDK中一致,没有则删除该项</br>" +
+                    "2.提供js sdk中的key值,例\"key\":\"20150115/中文/${filename}\""),
+            @ApiImplicitParam(name = "unknowValueField", dataType = "List", value = "对于用户无法确定表单值的放在unknownValueField中(比如有的上传控件会添加一些表单项,但表单项的值可能是随机的)"),
+            @ApiImplicitParam(name = "pluginName", dataType = "String", value = "插件名称,默认ks3,可选值:ks3,aliyun,tencent"),
+    })
+    @ApiOperation(value = "获取上传文件签名", notes = "{\n" +
+            "    \"bucketName\":\"\",\n" +
+            "    \"filename\":\"test.png\",\n" +
+            "    \"postData\":{\n" +
+            "        \"acl\":\"public-read\",\n" +
+            "        \"key\":\"20150115/中文/${filename}\"\n" +
+            "    },\n" +
+            "    \"unknowValueField\":[\"test\"]\n" +
+            "}")
+    @PostMapping("/getUploadSign")
+    public HttpResponseResult<OssWrapper.ResponseSign> getUploadSign(@RequestParam(defaultValue = "ks3") String pluginName,
+                                                                     @RequestBody UploadSign uploadSign) {
+        // 设置默认文件存储服务方
+        uploadSign.setPluginName(pluginName);
+        return succeed(uploadFileService.getUploadSign(uploadSign));
+    }
+}

+ 36 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/UserAccountController.java

@@ -0,0 +1,36 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.yonge.cooleshow.biz.dal.service.UserAccountService;
+import com.yonge.cooleshow.biz.dal.vo.UserAccountVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+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;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/userAccount")
+@Api(value = "用户账户表", tags = "用户账户表")
+public class UserAccountController extends BaseController {
+
+    @Autowired
+    private UserAccountService userAccountService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    @PreAuthorize("@pcs.hasPermissions('userAccount/detail')")
+    public HttpResponseResult<UserAccountVo> detail(@PathVariable("id") Long id) {
+    	return succeed(userAccountService.detail(id));
+	}
+
+
+
+}

+ 95 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/UserAccountRecordController.java

@@ -0,0 +1,95 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.excel.UserAccountRecordExport;
+import com.yonge.cooleshow.biz.dal.dto.search.UserAccountRecordSearch;
+import com.yonge.cooleshow.biz.dal.enums.InOrOutEnum;
+import com.yonge.cooleshow.biz.dal.service.UserAccountRecordService;
+import com.yonge.cooleshow.biz.dal.vo.UserAccountRecordVo;
+import com.yonge.cooleshow.biz.dal.vo.UserAccountVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.utils.easyexcel.ExcelUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/userAccountRecord")
+@Api(value = "用户账户流水表", tags = "用户账户流水表")
+public class UserAccountRecordController extends BaseController {
+
+    @Autowired
+    private UserAccountRecordService userAccountRecordService;
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    @PreAuthorize("@pcs.hasPermissions('userAccountRecord/detail')")
+    public HttpResponseResult<UserAccountRecordVo> detail(@PathVariable("id") Long id) {
+        return succeed(userAccountRecordService.detail(id));
+    }
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入userAccountRecordSearch")
+    @PreAuthorize("@pcs.hasPermissions('userAccountRecord/page')")
+    public HttpResponseResult<PageInfo<UserAccountRecordVo>> page(@RequestBody UserAccountRecordSearch query) {
+        if (query.getInOrOut() == null) {
+            query.setInOrOut(InOrOutEnum.IN);
+        }
+        IPage<UserAccountRecordVo> pages = userAccountRecordService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    /**
+     * 查询导出
+     */
+    @PostMapping("/export")
+    @ApiOperation(value = "查询导出", notes = "传入orderSearch")
+    @PreAuthorize("@pcs.hasPermissions('userAccountRecord/export')")
+    public void export(@RequestBody UserAccountRecordSearch query) {
+        query.setInOrOut(InOrOutEnum.IN);
+        List<UserAccountRecordVo> userAccountRecordVos = userAccountRecordService.selectAll(query);
+
+        List<UserAccountRecordExport> list = new ArrayList<>();
+        userAccountRecordVos.forEach(o -> {
+            UserAccountRecordExport export = new UserAccountRecordExport();
+            BeanUtils.copyProperties(o, export);
+            if (null == export.getTransAmount()) {
+                export.setTransAmount(BigDecimal.ZERO);
+            }
+            list.add(export);
+        });
+        ExcelUtils.exportExcel(list, "老师收入列表数据" + System.currentTimeMillis(),
+                "老师收入列表数据");
+    }
+
+    @ApiOperation(value = "收入数据统计")
+    @PostMapping("/accountTotal")
+    @PreAuthorize("@pcs.hasPermissions('userAccountRecord/accountTotal')")
+    public HttpResponseResult<UserAccountVo> accountTotal(@RequestBody UserAccountRecordSearch query) {
+        query.setInOrOut(InOrOutEnum.IN);
+        return userAccountRecordService.accountTotal(query);
+    }
+
+
+}

+ 78 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/UserOrderController.java

@@ -0,0 +1,78 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.excel.UserOrderExport;
+import com.yonge.cooleshow.biz.dal.dto.search.OrderSearch;
+import com.yonge.cooleshow.biz.dal.service.UserOrderService;
+import com.yonge.cooleshow.biz.dal.vo.UserOrderVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.utils.easyexcel.ExcelUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/userOrder")
+@Api(value = "订单管理", tags = "订单管理")
+public class UserOrderController extends BaseController {
+
+    @Autowired
+    private UserOrderService userOrderService;
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    @PreAuthorize("@pcs.hasPermissions('userOrder/detail')")
+    public HttpResponseResult<UserOrderVo> detail(@PathVariable("id") Long id) {
+        return succeed(userOrderService.detail(id));
+    }
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入orderSearch")
+    @PreAuthorize("@pcs.hasPermissions('userOrder/page')")
+    public HttpResponseResult<PageInfo<UserOrderVo>> page(@RequestBody OrderSearch query) {
+        IPage<UserOrderVo> pages = userOrderService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    /**
+     * 查询导出
+     */
+    @PostMapping("/export")
+    @ApiOperation(value = "查询导出", notes = "传入orderSearch")
+    @PreAuthorize("@pcs.hasPermissions('userOrder/export')")
+    public void export(@RequestBody OrderSearch query) {
+        List<UserOrderVo> userOrderVos = userOrderService.selectAllList(query);
+        List<UserOrderExport> list = new ArrayList<>();
+        userOrderVos.forEach(o -> {
+            UserOrderExport export = new UserOrderExport();
+            BeanUtils.copyProperties(o, export);
+            if (null == export.getFeeAmt()) {
+                export.setFeeAmt(BigDecimal.ZERO);
+            }
+            list.add(export);
+        });
+        ExcelUtils.exportExcel(list, "订单列表数据" + System.currentTimeMillis(),
+                "订单列表数据");
+    }
+}

+ 93 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/UserOrderRefundController.java

@@ -0,0 +1,93 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.req.AuthOperaReq;
+import com.yonge.cooleshow.biz.dal.dto.search.UserOrderRefundSearch;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderRefundBill;
+import com.yonge.cooleshow.biz.dal.service.UserOrderRefundService;
+import com.yonge.cooleshow.biz.dal.vo.UserOrderRefundVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/userOrderRefunds")
+@Api(value = "用户退款表", tags = "用户退款表")
+public class UserOrderRefundController extends BaseController {
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private UserOrderRefundService userOrderRefundService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+	@PreAuthorize("@pcs.hasPermissions('userOrderRefunds/detail')")
+	public HttpResponseResult<UserOrderRefundVo> detail(@PathVariable("id") Long id) {
+    	return succeed(userOrderRefundService.detail(id));
+	}
+    
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入orderRefundsSearch")
+	@PreAuthorize("@pcs.hasPermissions('userOrderRefunds/page')")
+	public HttpResponseResult<PageInfo<UserOrderRefundVo>> page(@RequestBody UserOrderRefundSearch query) {
+		IPage<UserOrderRefundVo> pages = userOrderRefundService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+
+	@PostMapping("/doAuth")
+	@ApiOperation(value = "审核", notes = "传入authOperaReq")
+	@PreAuthorize("@pcs.hasPermissions('userOrderRefunds/doAuth')")
+	public HttpResponseResult<Boolean> doAuth(@Valid @RequestBody AuthOperaReq authOperaReq) throws Exception {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null || null == user.getId()) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+		return userOrderRefundService.doAuth(authOperaReq, user);
+	}
+
+	@PostMapping("/orderRefund")
+	@ApiOperation(value = "直接退款", notes = "传入authOperaReq")
+	@PreAuthorize("@pcs.hasPermissions('userOrderRefunds/orderRefund')")
+	public HttpResponseResult<UserOrderRefundBill> orderRefund(String orderNo, String reason) throws Exception {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null || null == user.getId()) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+		return userOrderRefundService.orderRefund(orderNo, reason);
+	}
+
+	@PostMapping("/orderRefundSuccessBizHandle")
+	@ApiOperation(value = "调用退款后处理业务逻辑", notes = "传入authOperaReq")
+	@PreAuthorize("@pcs.hasPermissions('userOrderRefunds/orderRefundSuccessBizHandle')")
+	public HttpResponseResult<UserOrderRefundBill> orderRefundSuccessBizHandle(Long refundId) throws Exception {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null || null == user.getId()) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+		userOrderRefundService.orderRefundSuccessBizHandle(refundId);
+		return HttpResponseResult.succeed();
+	}
+
+}

+ 132 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/UserWithdrawalController.java

@@ -0,0 +1,132 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.excel.UserWithdrawalExport;
+import com.yonge.cooleshow.biz.dal.dto.req.AuthOperaReq;
+import com.yonge.cooleshow.biz.dal.dto.search.TeacherWithdrawalSearch;
+import com.yonge.cooleshow.biz.dal.service.UserWithdrawalService;
+import com.yonge.cooleshow.biz.dal.vo.UserWithdrawalVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.utils.easyexcel.ExcelUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/userWithdrawal")
+@Api(value = "用户结算", tags = "用户结算")
+public class UserWithdrawalController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private UserWithdrawalService userWithdrawalService;
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    @PreAuthorize("@pcs.hasPermissions('userWithdrawal/detail')")
+    public HttpResponseResult<UserWithdrawalVo> detail(@PathVariable("id") Long id) {
+        return succeed(userWithdrawalService.detail(id));
+    }
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入teacherWithdrawalSearch")
+    @PreAuthorize("@pcs.hasPermissions('userWithdrawal/page')")
+    public HttpResponseResult<PageInfo<UserWithdrawalVo>> page(@RequestBody TeacherWithdrawalSearch query) {
+        IPage<UserWithdrawalVo> pages = userWithdrawalService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    /**
+     * 查询导出
+     */
+    @PostMapping("/exportExcel")
+    @ApiOperation(value = "查询导出", notes = "传入TeacherWithdrawalSearch")
+    @PreAuthorize("@pcs.hasPermissions('userWithdrawal/exportExcel')")
+    public void exportExcel(@RequestBody TeacherWithdrawalSearch query) {
+        List<UserWithdrawalVo> withdrawalVoList = userWithdrawalService.selectList(query);
+        List<UserWithdrawalExport> list = new ArrayList<>();
+        withdrawalVoList.forEach(o -> {
+            UserWithdrawalExport export = new UserWithdrawalExport();
+            BeanUtils.copyProperties(o, export);
+            list.add(export);
+
+        });
+        ExcelUtils.exportExcel(list, "结算列表数据" + System.currentTimeMillis(),
+                "列表数据");
+    }
+
+    @GetMapping("/totalAmount")
+    @ApiOperation(value = "统计金额")
+    @PreAuthorize("@pcs.hasPermissions('userWithdrawal/totalAmount')")
+    public HttpResponseResult<UserWithdrawalVo> totalAmount() {
+        return succeed(userWithdrawalService.totalAmount());
+    }
+
+    @PostMapping("/doAuth")
+    @ApiOperation(value = "审核", notes = "传入authOperaReq")
+    @PreAuthorize("@pcs.hasPermissions('userWithdrawal/doAuth')")
+    public HttpResponseResult<Boolean> doAuth(@Valid @RequestBody AuthOperaReq authOperaReq) throws Exception {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return userWithdrawalService.batchAuth(authOperaReq, user);
+    }
+
+    /*@ApiImplicitParams({
+            @ApiImplicitParam(
+                    name = "id",
+                    value = "审核单id",
+                    paramType = "query", dataType = "Long"
+            )
+    })
+    @PostMapping("/transferAccount")
+    @ApiOperation(value = "继续转账", notes = "传入authOperaReq")
+    @PreAuthorize("@pcs.hasPermissions('userWithdrawal/transferAccount')")
+    public HttpResponseResult<Boolean> transferAccount(@ApiIgnore @RequestBody AuthOperaReq authOperaReq) throws Exception {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        try {
+            HttpResponseResult<Boolean> res = DistributedLock.of(redissonClient)
+                    .runIfLockCanGet(CacheNameEnum.LOCK_WITHDRAWAL.getRedisKey(authOperaReq.getId())
+                            , () -> userWithdrawalService.transferAccount(authOperaReq, user), 60L, TimeUnit.SECONDS);
+            if(null != res){
+                return res;
+            }else{
+                return HttpResponseResult.failed("转账失败");
+            }
+        } catch (BizException e) {
+            return HttpResponseResult.failed(e.getMessage());
+        }  catch (Exception e) {
+            e.printStackTrace();
+            return HttpResponseResult.failed("转账失败");
+        }
+    }*/
+}

+ 351 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/VideoLessonController.java

@@ -0,0 +1,351 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.admin.io.request.course.CourseRelationVo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.AdjustModel;
+import com.yonge.cooleshow.biz.dal.dto.search.VideoGroupSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.VideoLessonSearch;
+import com.yonge.cooleshow.biz.dal.entity.VideoLessonGroup;
+import com.yonge.cooleshow.biz.dal.entity.VideoLessonGroupDetail;
+import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.course.CourseTypeEnum;
+import com.yonge.cooleshow.biz.dal.queryInfo.CourseRelationQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.VideoLessonGroupDetailService;
+import com.yonge.cooleshow.biz.dal.service.VideoLessonGroupService;
+import com.yonge.cooleshow.biz.dal.valid.AddGroup;
+import com.yonge.cooleshow.biz.dal.valid.SelectGroup;
+import com.yonge.cooleshow.biz.dal.vo.CountVideoGroupVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonAuthGroup;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonExamineVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonGroupDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonPurchaseVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonShelvesVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonStudentDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonStudentVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonTeacherVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonVo;
+import com.yonge.cooleshow.biz.dal.wrapper.course.CourseRelationWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @Author: cy
+ * @Date: 2022/4/2
+ */
+@RestController
+@RequestMapping("${app-config.url.admin:}/videoLesson")
+@Api(tags = "视频课")
+@Validated
+public class VideoLessonController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private VideoLessonGroupService lessonGroupService;
+    @Autowired
+    private VideoLessonGroupDetailService videoLessonGroupDetailService;
+
+    @ApiOperation(value = "根据视频课组id查详情")
+    @GetMapping(value = "/selectGroupById")
+    public HttpResponseResult<VideoLessonGroup> selectGroupById(@NotNull Long groupId) {
+        return succeed(lessonGroupService.selectGroup(groupId));
+    }
+
+    /**
+     * @Description: 学员详情-查询视频课列表
+     * @Author: cy
+     * @Date: 2022/4/2
+     */
+    @ApiOperation(value = "学员详情-查询视频课列表")
+    @PostMapping(value = "/student")
+    public HttpResponseResult<PageInfo<VideoLessonStudentDetailVo>> selectStudentPage(@Validated(AddGroup.class) @RequestBody VideoLessonSearch search) {
+        return succeed(PageUtil.pageInfo(lessonGroupService.selectStudentPage(PageUtil.getPage(search), search)));
+    }
+
+    /**
+     * @Description: 老师详情-查询视频课列表
+     * @Author: cy
+     * @Date: 2022/4/6
+     */
+    @ApiOperation(value = "老师详情-查询视频课列表")
+    @PostMapping(value = "/teacher")
+    public HttpResponseResult<PageInfo<VideoLessonTeacherVo>> selectTeacherPage(@Validated(AddGroup.class) @RequestBody VideoLessonSearch search) {
+        return succeed(PageUtil.pageInfo(lessonGroupService.selectTeacherPage(PageUtil.getPage(search), search)));
+    }
+
+    /**
+     * @Description: 老师详情-视频课详情-查询购买学员列表
+     * @Author: cy
+     * @Date: 2022/4/6
+     */
+    @ApiOperation(value = "老师详情-视频课详情-查询购买学员列表", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/teacher/purchaseStudent", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<PageInfo<VideoLessonPurchaseVo>> selectPurchaseStudent(@Validated(SelectGroup.class) @RequestBody VideoLessonSearch search) {
+        return succeed(PageUtil.pageInfo(lessonGroupService.selectPurchaseStudent(PageUtil.getPage(search), search)));
+    }
+
+    /**
+     * @Description: 老师详情-视频课详情-教学计划
+     * @Author: cy
+     * @Date: 2022/4/6
+     */
+    @ApiOperation(value = "老师详情-视频课详情-教学计划", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/teacher/plan", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<PageInfo<VideoLessonGroupDetailVo>> page(@Validated(SelectGroup.class) @RequestBody VideoLessonSearch search) {
+        return succeed(PageUtil.pageInfo(videoLessonGroupDetailService.selectPage(PageUtil.getPage(search), search)));
+    }
+
+    /**
+     * @Description: 审核-视频课组列表
+     * @Author: cy
+     * @Date: 2022/4/20
+     */
+    @ApiOperation(value = "审核-视频课组列表", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/queryGroupList", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<PageInfo<VideoLessonAuthGroup>> queryGroupList(@RequestBody VideoGroupSearch search) {
+        return succeed(PageUtil.pageInfo(lessonGroupService.queryGroupList(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "审核-视频课组历史记录列表", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/queryGroupHistoryList", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<PageInfo<VideoLessonAuthGroup>> queryGroupHistoryList(@RequestBody VideoGroupSearch search) {
+        return succeed(PageUtil.pageInfo(lessonGroupService.queryGroupHistoryList(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "老师详情-视频课详情-推荐/赠送内容", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/queryRelationMusicAlbum", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<PageInfo<CourseRelationWrapper.MusicAlbumInfo>> queryRelationMusicAlbum(@RequestBody CourseRelationVo.CourseRelationQuery query) {
+
+        query.setCourseType(CourseTypeEnum.VIDEO);
+        IPage<CourseRelationWrapper.MusicAlbumInfo> iPage = lessonGroupService
+                .queryRelationMusicAlbum(PageUtil.getPage(query), CourseRelationQueryInfo.from(query.jsonString()));
+        return succeed(PageUtil.pageInfo(iPage));
+
+    }
+
+
+    /**
+     * @Description: 审核-根据视频课组id查视频课详情
+     * @Author: cy
+     * @Date: 2022/4/20
+     */
+    @ApiOperation(value = "审核-根据视频课组id查视频课详情")
+    @GetMapping("/authGroupDetil")
+    public HttpResponseResult<VideoLessonAuthGroup> authGroupDetil(
+            @ApiParam(value = "当前视频组id", required = true) @RequestParam(value = "videoGroupId") Long videoGroupId) {
+        return succeed(lessonGroupService.authGroupDetil(videoGroupId));
+    }
+
+    /**
+     * @Description: 审核-根据视频课组id查视频课详情
+     * @Author: cy
+     * @Date: 2022/4/20
+     */
+    @ApiOperation(value = "审核-根据视频课组id查视频课详情")
+    @GetMapping("/queryLessonInfo")
+    public HttpResponseResult<List<VideoLessonGroupDetail>> queryLessonInfo(Integer groupId) {
+        QueryWrapper<VideoLessonGroupDetail> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("video_lesson_group_id_", groupId);
+        return succeed(videoLessonGroupDetailService.list(queryWrapper));
+    }
+
+
+
+    /**
+     * @Description: 审核-修改视频课组审核状态
+     * @Author: cy
+     * @Date: 2022/4/25
+     */
+    @ApiOperation(value = "审核-修改视频课组审核状态", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/updateGroup", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> update(@Validated @RequestBody VideoLessonExamineVo examineVo) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        examineVo.setAuditId(user.getId());
+        examineVo.setAuditName(user.getUsername());
+        lessonGroupService.updateGroup(examineVo);
+        return succeed();
+    }
+
+    /**
+     * @Description: 更新上架状态
+     * @Author: cy
+     * @Date: 2022/4/25
+     */
+    @ApiOperation(value = "更新上架状态", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/updateShelves", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> updateShelves(@Validated @RequestBody VideoLessonShelvesVo shelvesVo) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if (shelvesVo.getShelvesFlag() == 0 && StringUtil.isEmpty(shelvesVo.getShelvesReason())) {
+            return failed( "下架必须要有下架原因");
+        }
+        VideoLessonGroup videoLessonGroup = lessonGroupService.getById(shelvesVo.getId());
+        if (videoLessonGroup.getAuditStatus() ==null || !videoLessonGroup.getAuditStatus().equals(AuthStatusEnum.PASS)) {
+            return failed("审核通过才能上架");
+        }
+
+        shelvesVo.setShelvesId(user.getId());
+        if (shelvesVo.getShelvesFlag() == 1) {
+            shelvesVo.setShelvesTime(new Date());
+        }
+        shelvesVo.setClientType(ClientEnum.SYSTEM);
+        lessonGroupService.updateShelves(shelvesVo);
+        return succeed();
+    }
+
+    @ApiOperation(value = "首页-视频课统计")
+    @GetMapping("/countVideoGroup")
+    public HttpResponseResult<CountVideoGroupVo> countVideoGroup() {
+        return succeed(lessonGroupService.countVideoGroup());
+    }
+
+
+    /**
+     * @Description: 新增视频课组&视频课
+     * @Author: cy
+     * @Date: 2022/4/1
+     */
+    @ApiOperation(value = "新增视频课组&视频课", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/add", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> add( @RequestBody VideoLessonVo lessonVo) {
+
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        lessonVo.setUserBy(user.getId());
+        if (lessonVo.getLessonGroup().getTeacherId() == null) {
+            return failed("请设置所属老师");
+        }
+        SysUser sysUser = sysUserFeignService.queryUserById(lessonVo.getLessonGroup().getTeacherId());
+
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        if (lessonVo.getLessonGroup().getDraftFlag().equals(YesOrNoEnum.NO) && CollectionUtils.isEmpty(lessonVo.getLessonList())) {
+            return failed("课程不能为空");
+        }
+        Long add = lessonGroupService.add(lessonVo, sysUser);
+        return succeed(add);
+    }
+
+    /**
+     * @Description: 修改视频课组&视频课
+     * @Author: cy
+     * @Date: 2022/4/7
+     */
+    @ApiOperation(value = "修改视频课组&视频课", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/update", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> update(@RequestBody VideoLessonVo lessonVo) {
+
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        lessonVo.setUserBy(user.getId());
+
+        if (lessonVo.getLessonGroup().getTeacherId() == null) {
+            return failed("请设置所属老师");
+        }
+        SysUser sysUser = sysUserFeignService.queryUserById(lessonVo.getLessonGroup().getTeacherId());
+
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        if (lessonVo.getLessonGroup().getDraftFlag().equals(YesOrNoEnum.NO) && CollectionUtils.isEmpty(lessonVo.getLessonList())) {
+            return failed("课程不能为空");
+        }
+        return succeed(lessonGroupService.update(lessonVo, sysUser));
+    }
+
+
+
+    /**
+     * 置顶
+     */
+    @PostMapping("/top/{id}")
+    @ApiOperation(value = "置顶", notes = "传入id")
+    public HttpResponseResult<Boolean> top(@ApiParam(value = "视频课编号", required = true)  @PathVariable Long id) {
+        if (StringUtil.isEmpty(id)) {
+            return failed("参数不能为空");
+        }
+        return status(lessonGroupService.top(id));
+    }
+
+
+
+    /**
+     * @Description: 根据组id查询视频课&视频课组
+     * @Author: cy
+     * @Date: 2022/4/2
+     */
+    @ApiOperation(value = "根据组id查询视频课&视频课组")
+    @GetMapping(value = "/selectVideoLesson")
+    public HttpResponseResult<VideoLessonStudentVo> selectVideoLesson(@NotNull(message = "视频组id不能为空") Long groupId) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        VideoLessonStudentVo videoLessonStudentVo = lessonGroupService.selectVideoLesson(groupId);
+        if (videoLessonStudentVo.getLessonGroup().getTeacherId().equals(sysUser.getId())) {
+            videoLessonStudentVo.setMyself(true);
+        } else {
+            videoLessonStudentVo.setMyself(false);
+        }
+        if (videoLessonStudentVo.getLessonGroup() != null && sysUser.getId().equals(videoLessonStudentVo.getLessonGroup().getId())) {
+            videoLessonStudentVo.setAlreadyBuy(true);
+        } else {
+            videoLessonStudentVo.setAlreadyBuy(false);
+        }
+        return succeed(videoLessonStudentVo);
+    }
+
+    /**
+     * 设置排序值 和加精
+     */
+    @PostMapping("/adjust")
+    @ApiOperation(value = "视频课调整排序")
+    public HttpResponseResult<Boolean> adjust(@RequestBody @Valid AdjustModel model) {
+
+        VideoLessonGroup videoLessonGroup = new VideoLessonGroup();
+        videoLessonGroup.setId(model.getId());
+        videoLessonGroup.setSortNumber(model.getSort());
+
+        lessonGroupService.updateById(videoLessonGroup);
+
+        return succeed();
+    }
+
+}

+ 109 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/VideoLessonEvaluateController.java

@@ -0,0 +1,109 @@
+package com.yonge.cooleshow.admin.controller;//package com.yonge.cooleshow.admin.controller;
+//
+//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+//import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+//import javax.validation.Valid;
+//
+//import com.yonge.cooleshow.biz.dal.dto.VideoLessonEvaluateDto;
+//import io.swagger.annotations.Api;
+//import io.swagger.annotations.ApiOperation;
+//import org.springframework.web.bind.annotation.*;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.web.bind.annotation.RequestMapping;
+//import com.yonge.cooleshow.common.controller.BaseController;
+//import com.yonge.cooleshow.common.entity.HttpResponseResult;
+//import com.yonge.cooleshow.biz.dal.entity.VideoLessonEvaluate;
+//import com.yonge.cooleshow.biz.dal.service.VideoLessonEvaluateService;
+//import com.yonge.cooleshow.auth.api.entity.SysUser;
+//import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+//
+///**
+// * 视频课学员评价 web 控制层
+// * @author yzp
+// * @date 2022-03-26 00:21:46
+// * @version v1.0
+// **/
+//@RestController
+//@RequestMapping("/video/lesson/evaluate")
+//@Api(tags = "视频课学员评价 API接口")
+//public class VideoLessonEvaluateController extends BaseController {
+//    @Autowired
+//    private SysUserFeignService sysUserFeignService;
+//
+//	@Autowired
+//	private VideoLessonEvaluateService videoLessonEvaluateService;
+//
+//	@ApiOperation(value = "新增", httpMethod="POST", consumes="application/json", produces="application/json")
+//    @PostMapping(value="/create", consumes="application/json", produces="application/json")
+//    public HttpResponseResult<Object> create(@Valid @RequestBody VideoLessonEvaluate videoLessonEvaluate) {
+//        SysUser sysUser = sysUserFeignService.queryUserInfo();
+//        if (sysUser == null) {
+//            return failed("用户信息获取失败");
+//        }
+//
+//        //videoLessonEvaluate.setCreateBy(sysUser.getId());
+//        //videoLessonEvaluate.setCreateTime(new Date());
+//        videoLessonEvaluateService.save(videoLessonEvaluate);
+//        return succeed();
+//    }
+//
+//    @ApiOperation(value = "删除", httpMethod="POST", consumes="application/json", produces="application/json")
+//    @PostMapping("/delete/{id}")
+//    public Object delete(@PathVariable Long id) {
+//        SysUser sysUser = sysUserFeignService.queryUserInfo();
+//        if (sysUser == null) {
+//            return failed("用户信息获取失败");
+//        }
+//
+//        videoLessonEvaluateService.removeById(id);
+//        return succeed();
+//    }
+//
+//    @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
+//    @PostMapping(value="/update", consumes="application/json", produces="application/json")
+//    public HttpResponseResult<Object> update(@Valid @RequestBody VideoLessonEvaluate videoLessonEvaluate) {
+//        SysUser sysUser = sysUserFeignService.queryUserInfo();
+//        if (sysUser == null) {
+//            return failed("用户信息获取失败");
+//        }
+//        if (videoLessonEvaluate.getId()==null){
+//            return failed("缺少ID");
+//        }
+//
+//        //videoLessonEvaluate.setUpdateBy(sysUser.getId());
+//        //videoLessonEvaluate.setUpdateTime(new Date());
+//        videoLessonEvaluateService.updateById(videoLessonEvaluate);
+//        return succeed();
+//    }
+//
+//    @ApiOperation(value = "分页查询", httpMethod="POST", consumes="application/json", produces="application/json")
+//    @PostMapping(value="/list", consumes="application/json", produces="application/json")
+//    public HttpResponseResult<Object> list(@RequestBody VideoLessonEvaluateDto videoLessonEvaluateDto) {
+//        SysUser sysUser = sysUserFeignService.queryUserInfo();
+//        if (sysUser == null) {
+//            return failed("用户信息获取失败");
+//        }
+//
+//        int pageNo = videoLessonEvaluateDto.getPageNo();
+//        int pageSize = videoLessonEvaluateDto.getPageSize();
+//
+//        try {
+//            if (pageNo==0) {
+//                pageNo = 1;
+//            }
+//            if (pageSize==0) {
+//                pageSize = 10;
+//            }
+//
+//            LambdaQueryWrapper<VideoLessonEvaluate> lambdaQueryWrapper = Wrappers.lambdaQuery();
+//            //lambdaQueryWrapper.like(VideoLessonEvaluate::getName , "k");
+//
+//            Page<VideoLessonEvaluate> page = new Page<>(pageNo,pageSize);
+//            return succeed(videoLessonEvaluateService.page(page, lambdaQueryWrapper));
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            return HttpResponseResult.failed(e.getMessage());
+//        }
+//    }
+//}

+ 108 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/VideoLessonPurchaseRecordController.java

@@ -0,0 +1,108 @@
+package com.yonge.cooleshow.admin.controller;//package com.yonge.cooleshow.admin.controller;
+//
+//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+//import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+//import javax.validation.Valid;
+//import com.yonge.cooleshow.biz.dal.dto.VideoLessonPurchaseRecordDto;
+//import io.swagger.annotations.Api;
+//import io.swagger.annotations.ApiOperation;
+//import org.springframework.web.bind.annotation.*;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.web.bind.annotation.RequestMapping;
+//import com.yonge.cooleshow.common.controller.BaseController;
+//import com.yonge.cooleshow.common.entity.HttpResponseResult;
+//import com.yonge.cooleshow.biz.dal.entity.VideoLessonPurchaseRecord;
+//import com.yonge.cooleshow.biz.dal.service.VideoLessonPurchaseRecordService;
+//import com.yonge.cooleshow.auth.api.entity.SysUser;
+//import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+//
+///**
+// * 视频课购买记录表 web 控制层
+// * @author yzp
+// * @date 2022-03-26 00:21:46
+// * @version v1.0
+// **/
+//@RestController
+//@RequestMapping("/video/lesson/purchase/record")
+//@Api(tags = "视频课购买记录表 API接口")
+//public class VideoLessonPurchaseRecordController extends BaseController {
+//    @Autowired
+//    private SysUserFeignService sysUserFeignService;
+//
+//	@Autowired
+//	private VideoLessonPurchaseRecordService videoLessonPurchaseRecordService;
+//
+//	@ApiOperation(value = "新增", httpMethod="POST", consumes="application/json", produces="application/json")
+//    @PostMapping(value="/create", consumes="application/json", produces="application/json")
+//    public HttpResponseResult<Object> create(@Valid @RequestBody VideoLessonPurchaseRecord videoLessonPurchaseRecord) {
+//        SysUser sysUser = sysUserFeignService.queryUserInfo();
+//        if (sysUser == null) {
+//            return failed("用户信息获取失败");
+//        }
+//
+//        //videoLessonPurchaseRecord.setCreateBy(sysUser.getId());
+//        //videoLessonPurchaseRecord.setCreateTime(new Date());
+//        videoLessonPurchaseRecordService.save(videoLessonPurchaseRecord);
+//        return succeed();
+//    }
+//
+//    @ApiOperation(value = "删除", httpMethod="POST", consumes="application/json", produces="application/json")
+//    @PostMapping("/delete/{id}")
+//    public Object delete(@PathVariable Long id) {
+//        SysUser sysUser = sysUserFeignService.queryUserInfo();
+//        if (sysUser == null) {
+//            return failed("用户信息获取失败");
+//        }
+//
+//        videoLessonPurchaseRecordService.removeById(id);
+//        return succeed();
+//    }
+//
+//    @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
+//    @PostMapping(value="/update", consumes="application/json", produces="application/json")
+//    public HttpResponseResult<Object> update(@Valid @RequestBody VideoLessonPurchaseRecord videoLessonPurchaseRecord) {
+//        SysUser sysUser = sysUserFeignService.queryUserInfo();
+//        if (sysUser == null) {
+//            return failed("用户信息获取失败");
+//        }
+//        if (videoLessonPurchaseRecord.getId()==null){
+//            return failed("缺少ID");
+//        }
+//
+//        //videoLessonPurchaseRecord.setUpdateBy(sysUser.getId());
+//        //videoLessonPurchaseRecord.setUpdateTime(new Date());
+//        videoLessonPurchaseRecordService.updateById(videoLessonPurchaseRecord);
+//        return succeed();
+//    }
+//
+//    @ApiOperation(value = "分页查询", httpMethod="POST", consumes="application/json", produces="application/json")
+//    @PostMapping(value="/list", consumes="application/json", produces="application/json")
+//    public HttpResponseResult<Object> list(@RequestBody VideoLessonPurchaseRecordDto videoLessonPurchaseRecordDto) {
+//        SysUser sysUser = sysUserFeignService.queryUserInfo();
+//        if (sysUser == null) {
+//            return failed("用户信息获取失败");
+//        }
+//
+//        int pageNo = videoLessonPurchaseRecordDto.getPageNo();
+//        int pageSize = videoLessonPurchaseRecordDto.getPageSize();
+//
+//        try {
+//            if (pageNo==0) {
+//                pageNo = 1;
+//            }
+//            if (pageSize==0) {
+//                pageSize = 10;
+//            }
+//
+//            LambdaQueryWrapper<VideoLessonPurchaseRecord> lambdaQueryWrapper = Wrappers.lambdaQuery();
+//            //lambdaQueryWrapper.like(VideoLessonPurchaseRecord::getName , "k");
+//
+//            Page<VideoLessonPurchaseRecord> page = new Page<>(pageNo,pageSize);
+//            return succeed(videoLessonPurchaseRecordService.page(page, lambdaQueryWrapper));
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            return HttpResponseResult.failed(e.getMessage());
+//        }
+//    }
+//}

+ 108 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/VideoLessonStudyRecordController.java

@@ -0,0 +1,108 @@
+package com.yonge.cooleshow.admin.controller;//package com.yonge.cooleshow.admin.controller;
+//
+//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+//import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+//import javax.validation.Valid;
+//import com.yonge.cooleshow.biz.dal.dto.VideoLessonStudyRecordDto;
+//import io.swagger.annotations.Api;
+//import io.swagger.annotations.ApiOperation;
+//import org.springframework.web.bind.annotation.*;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.web.bind.annotation.RequestMapping;
+//import com.yonge.cooleshow.common.controller.BaseController;
+//import com.yonge.cooleshow.common.entity.HttpResponseResult;
+//import com.yonge.cooleshow.biz.dal.entity.VideoLessonStudyRecord;
+//import com.yonge.cooleshow.biz.dal.service.VideoLessonStudyRecordService;
+//import com.yonge.cooleshow.auth.api.entity.SysUser;
+//import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+//
+///**
+// * 视频课学习记录表 web 控制层
+// * @author yzp
+// * @date 2022-03-26 00:21:46
+// * @version v1.0
+// **/
+//@RestController
+//@RequestMapping("/video/lesson/study/record")
+//@Api(tags = "视频课学习记录表 API接口")
+//public class VideoLessonStudyRecordController extends BaseController {
+//    @Autowired
+//    private SysUserFeignService sysUserFeignService;
+//
+//	@Autowired
+//	private VideoLessonStudyRecordService videoLessonStudyRecordService;
+//
+//	@ApiOperation(value = "新增", httpMethod="POST", consumes="application/json", produces="application/json")
+//    @PostMapping(value="/create", consumes="application/json", produces="application/json")
+//    public HttpResponseResult<Object> create(@Valid @RequestBody VideoLessonStudyRecord videoLessonStudyRecord) {
+//        SysUser sysUser = sysUserFeignService.queryUserInfo();
+//        if (sysUser == null) {
+//            return failed("用户信息获取失败");
+//        }
+//
+//        //videoLessonStudyRecord.setCreateBy(sysUser.getId());
+//        //videoLessonStudyRecord.setCreateTime(new Date());
+//        videoLessonStudyRecordService.save(videoLessonStudyRecord);
+//        return succeed();
+//    }
+//
+//    @ApiOperation(value = "删除", httpMethod="POST", consumes="application/json", produces="application/json")
+//    @PostMapping("/delete/{id}")
+//    public Object delete(@PathVariable Long id) {
+//        SysUser sysUser = sysUserFeignService.queryUserInfo();
+//        if (sysUser == null) {
+//            return failed("用户信息获取失败");
+//        }
+//
+//        videoLessonStudyRecordService.removeById(id);
+//        return succeed();
+//    }
+//
+//    @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
+//    @PostMapping(value="/update", consumes="application/json", produces="application/json")
+//    public HttpResponseResult<Object> update(@Valid @RequestBody VideoLessonStudyRecord videoLessonStudyRecord) {
+//        SysUser sysUser = sysUserFeignService.queryUserInfo();
+//        if (sysUser == null) {
+//            return failed("用户信息获取失败");
+//        }
+//        if (videoLessonStudyRecord.getId()==null){
+//            return failed("缺少ID");
+//        }
+//
+//        //videoLessonStudyRecord.setUpdateBy(sysUser.getId());
+//        //videoLessonStudyRecord.setUpdateTime(new Date());
+//        videoLessonStudyRecordService.updateById(videoLessonStudyRecord);
+//        return succeed();
+//    }
+//
+//    @ApiOperation(value = "分页查询", httpMethod="POST", consumes="application/json", produces="application/json")
+//    @PostMapping(value="/list", consumes="application/json", produces="application/json")
+//    public HttpResponseResult<Object> list(@RequestBody VideoLessonStudyRecordDto videoLessonStudyRecordDto) {
+//        SysUser sysUser = sysUserFeignService.queryUserInfo();
+//        if (sysUser == null) {
+//            return failed("用户信息获取失败");
+//        }
+//
+//        int pageNo = videoLessonStudyRecordDto.getPageNo();
+//        int pageSize = videoLessonStudyRecordDto.getPageSize();
+//
+//        try {
+//            if (pageNo==0) {
+//                pageNo = 1;
+//            }
+//            if (pageSize==0) {
+//                pageSize = 10;
+//            }
+//
+//            LambdaQueryWrapper<VideoLessonStudyRecord> lambdaQueryWrapper = Wrappers.lambdaQuery();
+//            //lambdaQueryWrapper.like(VideoLessonStudyRecord::getName , "k");
+//
+//            Page<VideoLessonStudyRecord> page = new Page<>(pageNo,pageSize);
+//            return succeed(videoLessonStudyRecordService.page(page, lambdaQueryWrapper));
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            return HttpResponseResult.failed(e.getMessage());
+//        }
+//    }
+//}

+ 47 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/VipCardRecordController.java

@@ -0,0 +1,47 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.search.VipCardRecordSearch;
+import com.yonge.cooleshow.biz.dal.service.VipCardRecordService;
+import com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/vipCardRecord")
+@Api(value = "购买会员卡记录表", tags = "购买会员卡记录表")
+public class VipCardRecordController extends BaseController {
+
+    @Autowired
+    private VipCardRecordService vipCardRecordService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{orderDetilId}")
+    @ApiOperation(value = "详情", notes = "传入订单详情id")
+    public HttpResponseResult<VipCardRecordVo> detail(@PathVariable("orderDetilId") Long orderDetilId) {
+    	return succeed(vipCardRecordService.detail(orderDetilId));
+	}
+    
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入vipCardRecordSearch")
+    public HttpResponseResult<PageInfo<VipCardRecordVo>> page(@RequestBody VipCardRecordSearch query) {
+		IPage<VipCardRecordVo> pages = vipCardRecordService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+}

+ 236 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/coupon/CouponInfoController.java

@@ -0,0 +1,236 @@
+package com.yonge.cooleshow.admin.controller.coupon;
+
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.admin.io.request.coupon.CouponInfoVO;
+import com.yonge.cooleshow.admin.io.request.coupon.CouponInventoryVO;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.CouponInfo;
+import com.yonge.cooleshow.biz.dal.entity.CouponInventory;
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponInfoQuery;
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponInventoryQuery;
+import com.yonge.cooleshow.biz.dal.service.CouponInfoService;
+import com.yonge.cooleshow.biz.dal.vo.coupon.CouponInfoWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.coupon.CouponInventoryWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.EStatus;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * <p>
+ * 优惠券信息 前端控制器
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-09-02
+ */
+@RestController
+@RequestMapping("${app-config.url.admin:}/couponInfo")
+@Api(value = "优惠券信息", tags = "优惠券信息")
+public class CouponInfoController extends BaseController {
+
+    @Autowired
+    private CouponInfoService couponInfoService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    /**
+     * 优惠券信息
+     * @param request CouponInfoVO.RequestInfo
+     * @return HttpResponseResult<PageInfo<CouponInfoVO.ResponseInfo>>
+     */
+    @PostMapping(value = "/page", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "查询优惠券分页", notes = "CouponInfoVO.PageRequest")
+    public HttpResponseResult<PageInfo<CouponInfoVO.CouponPageInfo>> queryCouponPageInfo(@RequestBody CouponInfoVO.PageRequest request) {
+
+        // 优惠券信息
+        IPage<CouponInfoWrapper> wrapper = couponInfoService.queryCouponPageInfo(PageUtil.getPage(request),
+                CouponInfoQuery.from(request.jsonString()));
+
+        // 数据转换
+        List<CouponInfoVO.CouponPageInfo> pageInfos = JSON.parseArray(JSON.toJSONString(wrapper.getRecords()),
+                CouponInfoVO.CouponPageInfo.class);
+
+        // 分页数据信息
+        return succeed(PageUtil.getPageInfo(wrapper, pageInfos));
+    }
+
+    /**
+     * 优惠券详情信息
+     * @param id 优惠券ID
+     * @return HttpResponseResult<CouponInfoVO.CouponQueryInfo>
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "优惠券详情", notes = "传入优惠券ID")
+    public HttpResponseResult<CouponInfoVO.CouponQueryInfo> findCouponById(@PathVariable("id") Long id) {
+
+        if (Objects.isNull(id)) {
+            return failed("无效的优惠券ID");
+        }
+
+        // 优惠券信息
+        CouponInfo couponInfo = couponInfoService.queryCouponInfoById(id);
+
+        return succeed(CouponInfoVO.CouponQueryInfo.from(JSON.toJSONString(couponInfo)));
+    }
+
+    /**
+     * 新增或者更新优惠券信息
+     * - ID为空新增;否则进行更新
+     * @param info CouponInfoVO.CouponInfo
+     * @return HttpResponseResult<CouponInfoVO.CouponInfo>
+     */
+    @PostMapping(value = "/save", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "新增或修改", notes = "CouponInfoVO.CouponInfo")
+    public HttpResponseResult<CouponInfoVO.CouponQueryInfo> saveOrUpdate(@Valid @RequestBody CouponInfoVO.CouponInfo info) {
+
+        // 获取当前登录用户信息
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(user) || Objects.isNull(user.getId())) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        // 校验参数合法性
+        if (info.invalidRequestParam(user.getId())) {
+            throw new BizException("无效的请求参数");
+        }
+
+        // 新增或更新信息
+        CouponInfo couponInfo = couponInfoService.saveOrUpdateCouponInfo(JSON.parseObject(info.jsonString(), CouponInfo.class), false);
+
+        return succeed(CouponInfoVO.CouponQueryInfo.from(JSON.toJSONString(couponInfo)));
+    }
+
+    /**
+     * 启用/停用 优惠券
+     */
+    @PostMapping("/updateState")
+    @ApiOperation(value = "优惠券状态启/停用")
+    public HttpResponseResult<Boolean> updateCouponStateInfo(@RequestBody CouponInfoVO.CouponInfo request) {
+
+        // 获取当前登录用户信息
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(user) || Objects.isNull(user.getId())) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        if (Objects.isNull(request)
+                || Objects.isNull(request.getId())
+                || EStatus.invalid(request.getStatus())) {
+            throw new BizException("无效请求参数");
+        }
+
+        // 更新数据信息
+        CouponInfoVO.CouponInfo info = CouponInfoVO.CouponInfo.builder()
+                .id(request.getId())
+                .status(request.getStatus())
+                .updatedBy(user.getId())
+                .updateTime(DateTime.now().getMillis())
+                .build();
+
+        CouponInfo couponInfo = couponInfoService.saveOrUpdateCouponInfo(JSON.parseObject(info.jsonString(), CouponInfo.class), true);
+
+        // 校验状态更新结果
+        return status(couponInfo.getStatus().intValue() == request.getStatus());
+    }
+
+    /**
+     * 优惠券库存量信息
+     * @param request CouponInventoryVO.PageRequest
+     * @return HttpResponseResult<PageInfo<CouponInventoryVO.PageInfo>>
+     */
+    @PostMapping(value = "/inventory/page", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "查询库存量调整分页信息", notes = "CouponInventoryVO.PageRequest")
+    public HttpResponseResult<PageInfo<CouponInventoryVO.PageInfo>> queryCouponInventoryPageInfo(@RequestBody CouponInventoryVO.PageRequest request) {
+
+        // 校验请求参数
+        if (request.invalidRequestParam()) {
+            throw new BizException("无效的优惠券ID");
+        }
+
+        // 优惠券信息
+        IPage<CouponInventoryWrapper> wrapper = couponInfoService.queryCouponInventoryPageInfo(PageUtil.getPage(request),
+                CouponInventoryQuery.from(request.jsonString()));
+
+        // 数据转换
+        List<CouponInventoryVO.PageInfo> pageInfos = JSON.parseArray(JSON.toJSONString(wrapper.getRecords()),
+                CouponInventoryVO.PageInfo.class);
+
+        // 分页数据信息
+        return succeed(PageUtil.getPageInfo(wrapper, pageInfos));
+    }
+
+    /**
+     * 调整新优惠券库存量信息
+     * @param info CouponInfoVO.CouponInfo
+     * @return HttpResponseResult<CouponInfoVO.CouponInfo>
+     */
+    @PostMapping(value = "/inventory/update", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "优惠券库存量更新", notes = "CouponInventoryVO.InventoryInfo")
+    public HttpResponseResult<Boolean> saveOrUpdate(@Valid @RequestBody CouponInventoryVO.InventoryInfo info) {
+
+        // 获取当前登录用户信息
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(user) || Objects.isNull(user.getId())) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        // 校验参数合法性
+        if (info.invalidRequestParam(user.getId())) {
+            throw new BizException("无效的请求参数");
+        }
+
+        // 新增或更新信息
+        int rows = couponInfoService.saveOrUpdateCouponInventoryInfo(JSON.parseObject(info.jsonString(),
+                CouponInventory.class));
+
+        return status(rows > 0);
+    }
+
+    /**
+     * 库存调整用户信息
+     * @param request CouponInventoryVO.PageRequest
+     * @return HttpResponseResult<PageInfo<CouponInventoryVO.PageInfo>>
+     */
+    @PostMapping(value = "/inventory/user", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "查询库存调整用户信息分页", notes = "CouponInventoryVO.PageRequest")
+    public HttpResponseResult<PageInfo<CouponInventoryVO.PageUserInfo>> queryInventoryUserPageInfo(@RequestBody CouponInventoryVO.PageRequest request) {
+
+        // 校验请求参数
+        if (Objects.isNull(request) || Objects.isNull(request.getCouponId())) {
+            throw new BizException("无效的优惠券ID");
+        }
+
+        // 优惠券信息
+        IPage<CouponInventoryWrapper> wrapper = couponInfoService.queryCouponInventoryPageInfo(PageUtil.getPage(request),
+                CouponInventoryQuery.from(request.jsonString()).groupByUser(true));
+
+        // 数据转换
+        List<CouponInventoryVO.PageUserInfo> pageInfos = JSON.parseArray(JSON.toJSONString(wrapper.getRecords()),
+                CouponInventoryVO.PageUserInfo.class);
+
+        // 分页数据信息
+        return succeed(PageUtil.getPageInfo(wrapper, pageInfos));
+    }
+
+}

+ 143 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/coupon/CouponIssueController.java

@@ -0,0 +1,143 @@
+package com.yonge.cooleshow.admin.controller.coupon;
+
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.admin.io.request.coupon.CouponIssueVo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.CouponIssue;
+import com.yonge.cooleshow.biz.dal.enums.SendTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponIssueQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.CouponIssueService;
+import com.yonge.cooleshow.biz.dal.vo.CouponIssueUserVo;
+import com.yonge.cooleshow.biz.dal.vo.coupon.CouponIssueWrapper;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.Date;
+import java.util.List;
+
+import static com.yonge.cooleshow.common.entity.HttpResponseResult.failed;
+import static com.yonge.cooleshow.common.entity.HttpResponseResult.succeed;
+
+/**
+ * <p>
+ * 优惠券发放 前端控制器
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-09-02
+ */
+@RestController
+@RequestMapping("${app-config.url.admin:}/couponIssue")
+@Api(value = "优惠券发放信息", tags = "优惠券发放信息")
+@Validated
+public class CouponIssueController {
+
+    @Autowired
+    private CouponIssueService couponIssueService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    /**
+     * 优惠券发放分页信息
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询优惠券发放分页")
+    public HttpResponseResult<PageInfo<CouponIssueVo.CouponIssuePageInfo>> queryCouponIssuePageInfo(@RequestBody @Valid CouponIssueVo.PageRequest request) {
+
+        if (request.getCouponId() == null) {
+            return failed("优惠券id不能为空");
+        }
+        IPage<CouponIssueWrapper> couponIssueWrapperIPage = couponIssueService.queryCouponIssueInfo(
+                PageUtil.getPage(request), CouponIssueQueryInfo.from(request.jsonString()));
+
+
+        // 数据转换
+        List<CouponIssueVo.CouponIssuePageInfo> pageInfos = JSON.parseArray(JSON.toJSONString(couponIssueWrapperIPage.getRecords()),
+                                                                    CouponIssueVo.CouponIssuePageInfo.class);
+
+        return succeed(PageUtil.getPageInfo(couponIssueWrapperIPage,pageInfos));
+    }
+
+
+    /**
+     * 优惠券课发放用户分页信息
+     */
+    @PostMapping("/userPage")
+    @ApiOperation(value = "优惠券发放用户分页信息")
+    public HttpResponseResult<PageInfo<CouponIssueUserVo>> queryCouponIssueUserPageInfo(@RequestBody @Valid CouponIssueVo.CouponIssueUserRequest request) {
+
+        IPage<CouponIssueUserVo> couponIssueUserVoIPage = couponIssueService.queryUser(PageUtil.getPage(request),
+                                                                                       request.getCouponId(),
+                                                                                       request.getClient(),
+                                                                                       request.getKeyword());
+
+
+        return succeed(PageUtil.pageInfo(couponIssueUserVoIPage));
+    }
+
+
+    @PostMapping("/issueUser")
+    @ApiOperation(value = "发送优惠券")
+    public HttpResponseResult<Boolean> issueCoupon(@RequestBody @Valid CouponIssueVo.CouponIssueUserParam param) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        couponIssueService.issueCoupon(param.getCouponId(), param.getUserParam(), sysUser.getId(), param.getRemark(),
+                                       SendTypeEnum.PLATFORM, new Date());
+
+        return succeed();
+    }
+
+    @PostMapping("/withdraw/{couponIssueId}")
+    @ApiOperation(value = "撤回优惠券")
+    public HttpResponseResult<Boolean> withdrawCoupon(@PathVariable Long couponIssueId) {
+        CouponIssue couponIssue = couponIssueService.getById(couponIssueId);
+        if (couponIssue == null) {
+            return failed("未找到数据");
+        }
+        if (couponIssue.getUseState().equals(CouponUseStateEnum.USED)) {
+            return failed("优惠券已被使用");
+        }  else if(couponIssue.getEndTime().compareTo(DateTime.now().getMillis()) <0) {
+            return failed("优惠券已过期");
+        }
+        return HttpResponseResult.status(couponIssueService.withdrawCoupon(couponIssueId));
+    }
+
+
+    /**
+     * 优惠券发放分页信息
+     */
+    @PostMapping("/user/page")
+    @ApiOperation(value = "查询用户(老师/学生)优惠券发放分页")
+    public HttpResponseResult<PageInfo<CouponIssueVo.UserCouponIssuePageInfo>> queryCouponIssuePageInfo(@RequestBody @Valid CouponIssueVo.UserCouponIssuePageRequest request) {
+
+        IPage<CouponIssueWrapper> couponIssueWrapperIPage = couponIssueService.queryCouponIssueInfo(
+                PageUtil.getPage(request), CouponIssueQueryInfo.from(request.jsonString()));
+
+
+        // 数据转换
+        List<CouponIssueVo.UserCouponIssuePageInfo> pageInfos = JSON.parseArray(JSON.toJSONString(couponIssueWrapperIPage.getRecords()),
+                                                                            CouponIssueVo.UserCouponIssuePageInfo.class);
+
+        return succeed(PageUtil.getPageInfo(couponIssueWrapperIPage,pageInfos));
+    }
+
+}

+ 130 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/music/MusicCompareRecordStatController.java

@@ -0,0 +1,130 @@
+package com.yonge.cooleshow.admin.controller.music;
+
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.admin.io.request.music.MusicCompareVo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.service.MusicCompareRecordStatService;
+import com.yonge.cooleshow.biz.dal.service.SysMusicCompareRecordService;
+import com.yonge.cooleshow.biz.dal.wrapper.music.MusicCompareWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 曲目练习统计表 前端控制器
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-10-17
+ */
+@RestController
+@RequestMapping("${app-config.url.admin:}/music/compare")
+@Api(tags = "曲目练习统计 ")
+public class MusicCompareRecordStatController extends BaseController {
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private MusicCompareRecordStatService musicCompareRecordStatService;
+    @Autowired
+    private SysMusicCompareRecordService sysMusicCompareRecordService;
+
+    /**
+     * 查询曲目统计汇总信息
+     */
+    @ApiOperation(value = "曲目统计汇总信息", notes = "")
+    @PostMapping(value = "/record/stat", consumes="application/json", produces="application/json")
+    public HttpResponseResult<MusicCompareVo.RecordStat> musicCompareRecordStatInfo(@RequestBody MusicCompareVo.StatQueryRequest request) {
+
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        if (request.invalidParam()) {
+            return failed("无效的请求参数");
+        }
+
+        MusicCompareWrapper.RecordStat records = musicCompareRecordStatService.findMusicCompareRecordStatInfo(sysUser.getId(),
+                MusicCompareWrapper.StatQueryInfo.from(request.jsonString()));
+
+        return succeed(MusicCompareVo.RecordStat.from(records.jsonString()));
+    }
+
+    /**
+     * 查询曲目统计汇总信息
+     */
+    @ApiOperation(value = "曲目统计信息查询", notes = "")
+    @PostMapping(value = "/record/page", consumes="application/json", produces="application/json")
+    public HttpResponseResult<PageInfo<MusicCompareVo.RecordInfo>> musicCompareRecordPageInfo(@RequestBody MusicCompareVo.StatQueryRequest request) {
+
+        if (request.invalidParam()) {
+            return failed("无效的请求参数");
+        }
+
+        // 曲目统计信息
+        IPage<MusicCompareWrapper.RecordInfo> wrapper = musicCompareRecordStatService.findMusicCompareRecordPage(PageUtil.getPage(request),
+                MusicCompareWrapper.StatQueryInfo.from(request.jsonString()));
+
+        // 数据转换
+        List<MusicCompareVo.RecordInfo> pageInfos = JSON.parseArray(JSON.toJSONString(wrapper.getRecords()),
+                MusicCompareVo.RecordInfo.class);
+
+        return succeed(PageUtil.getPageInfo(wrapper, pageInfos));
+    }
+
+    /**
+     * 查询曲目统计汇总信息
+     */
+    @ApiOperation(value = "曲目评测信息查询")
+    @PostMapping(value = "/evaluate/page", consumes="application/json", produces="application/json")
+    public HttpResponseResult<PageInfo<MusicCompareWrapper.RecordEvaluate>> musicCompareEvaluatePageInfo(@RequestBody MusicCompareVo.EvaluateQueryInfo request) {
+
+        if (request.invalidParam()) {
+            return failed("无效的请求参数");
+        }
+
+        // 曲目统计信息
+        IPage<MusicCompareWrapper.RecordEvaluate> wrapper = musicCompareRecordStatService.findMusicCompareRecordEvaluatePage(PageUtil.getPage(request),
+                MusicCompareWrapper.EvaluteQueryInfo.from(request.jsonString()));
+
+        return succeed(PageUtil.pageInfo(wrapper));
+    }
+
+    /**
+     * 用户最近一次评测报告
+     * @param recordId 评测记录ID
+     * @return HttpResponseResult<Object>
+     */
+    @ApiOperation(value = "用户最后一次评测数据")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "recordId", value = "评测记录ID", required = true, dataType = "Integer")
+    })
+    @GetMapping("evaluate/report")
+    public HttpResponseResult<Object> getLastEvaluationMusicalNotesPlayStats(@RequestParam("recordId") Long recordId){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if(sysUser == null){
+            throw new BizException("请登录");
+        }
+        return succeed(sysMusicCompareRecordService.getLastEvaluationMusicalNotesPlayStats(sysUser.getId(), recordId));
+    }
+}

+ 244 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/AdminClient.java

@@ -0,0 +1,244 @@
+package com.yonge.cooleshow.admin.controller.open;
+
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.config.jwt.utils.RsaKeyHelper;
+import com.yonge.cooleshow.admin.io.request.coupon.CouponOrderVO;
+import com.yonge.cooleshow.api.feign.dto.CouponInfoApi;
+import com.yonge.cooleshow.api.feign.dto.EmployeeApi;
+import com.yonge.cooleshow.api.feign.dto.StudentApi;
+import com.yonge.cooleshow.api.feign.dto.TeacherApi;
+import com.yonge.cooleshow.api.feign.dto.TenantWrapper;
+import com.yonge.cooleshow.biz.dal.entity.Employee;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.Teacher;
+import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponCategoryEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponInfoQuery;
+import com.yonge.cooleshow.biz.dal.service.CouponInfoService;
+import com.yonge.cooleshow.biz.dal.service.EmployeeService;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
+import com.yonge.cooleshow.biz.dal.service.UserFirstTimeService;
+import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.coupon.CouponOrderWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.UserFirstTimeTypeEnum;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.jwt.Jwt;
+import org.springframework.security.jwt.JwtHelper;
+import org.springframework.security.jwt.crypto.sign.RsaVerifier;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+@Slf4j
+@RestController
+@RequestMapping("${app-config.url.admin:}/open/adminClient")
+public class AdminClient extends BaseController {
+
+    @Autowired
+    private UserFirstTimeService userFirstTimeService;
+
+    @Autowired
+    private TeacherService teacherService;
+
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private EmployeeService employeeService;
+
+    @Autowired
+    private CouponInfoService couponInfoService;
+
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    @GetMapping("/recordTime")
+    public HttpResponseResult<Boolean> recordTime(
+            @RequestParam("userId") Long userId,
+            @RequestParam("userType") String userType,
+            @RequestParam("firstTimeType") UserFirstTimeTypeEnum firstTimeType
+    ) {
+        ClientEnum clientEnum = ClientEnum.valueOf(userType);
+        userFirstTimeService.recordTime(userId, clientEnum, firstTimeType);
+        return succeed(true);
+    }
+
+    @GetMapping("/getTeacher")
+    public HttpResponseResult<TeacherApi> getTeacher(@RequestParam("userId") Long userId) {
+        Teacher teacher = teacherService.getById(userId);
+
+        TeacherApi teacherApi = new TeacherApi();
+        BeanUtils.copyProperties(teacher, teacherApi);
+        return succeed(teacherApi);
+    }
+
+    @GetMapping("/getStudent")
+    public HttpResponseResult<StudentApi> getStudent(@RequestParam("userId") Long userId) {
+        Student student = studentService.getById(userId);
+
+        StudentApi studentApi = new StudentApi();
+        BeanUtils.copyProperties(student, studentApi);
+        return succeed(studentApi);
+    }
+
+    @ApiOperation(value = "学生帐号关联Id", notes = "CouponOrderVO.PageRequest")
+    @PostMapping("/unionStudent")
+    public HttpResponseResult<StudentWrapper.UnionStudentResp> unionStudent(@RequestBody StudentWrapper.UnionStudent info) {
+
+        if (info.getTokenCheck() == null || info.getTokenCheck()) {
+            if (StringUtils.isAnyBlank(info.getToken(), info.getMobile())) {
+                throw new BizException("请求参数错误");
+            }
+
+            // 校验三方帐号关联请求合法性
+            RSAPublicKey rsaPublicKey = RsaKeyHelper.getRSAPublicKey("jmedu", "dayaedu", "jmedu.jks", "dayaedu");
+            Jwt jwt = JwtHelper.decodeAndVerify(info.getToken(), new RsaVerifier(rsaPublicKey));
+
+            //获取jwt原始内容
+            String claims = jwt.getClaims();
+            if (StringUtils.isEmpty(claims)) {
+                throw new BizException("三方授权校验失败");
+            }
+
+        }
+        // 学生帐号关联
+        StudentWrapper.UnionStudentResp studentResp = studentService.unionStudent(info);
+
+        return succeed(studentResp);
+    }
+
+    @GetMapping("/getEmployee")
+    public HttpResponseResult<EmployeeApi> getEmployee(@RequestParam("userId") Long userId) {
+        Employee employee = employeeService.get(userId);
+
+        EmployeeApi employeeApi = new EmployeeApi();
+        BeanUtils.copyProperties(employee, employeeApi);
+        return succeed(employeeApi);
+    }
+
+    @ApiOperation(value = "机构信息查询", notes = "tenantId -> 机构ID")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "tenantId", value = "机构ID", required = true, dataType = "Long", paramType = "query")
+    })
+    @GetMapping("/getTenant")
+    public HttpResponseResult<TenantWrapper.Tenant> getTenant(@RequestParam("tenantId") Long tenantId) {
+
+        TenantWrapper.Tenant build = TenantWrapper.Tenant.builder().build();
+
+        TenantInfo tenantInfo = tenantInfoService.getById(tenantId);
+        if (Objects.nonNull(tenantInfo)) {
+            build = TenantWrapper.Tenant.from(JSON.toJSONString(tenantInfo));
+        }
+
+        return succeed(build);
+    }
+
+    @ApiOperation(value = "机构员工信息查询", notes = "userId -> 机构用户ID")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "userId", value = "机构用户ID", required = true, dataType = "Long", paramType = "query")
+    })
+    @GetMapping("/getTenantStaff")
+    public HttpResponseResult<TenantWrapper.Staff> getTenantStaff(@RequestParam("userId") Long userId) {
+
+        // 默认返回值
+        TenantWrapper.Staff ret = TenantWrapper.Staff.builder().build();
+
+        TenantStaff staff = tenantStaffService.getByUserId(userId);
+        if (Objects.nonNull(staff)) {
+            ret = TenantWrapper.Staff.from(JSON.toJSONString(staff));
+            ret.setStatus(staff.getStatus().name());
+            Long tenantId = staff.getTenantId();
+            TenantInfo tenantInfo = tenantInfoService.getById(Optional.ofNullable(tenantId).orElse(-1L));
+            ret.setTenantEnableFlag(Optional.ofNullable(tenantInfo).map(TenantInfo::getEnableFlag).orElse(false));
+        }
+        return succeed(ret);
+    }
+
+    /**
+     * 订单优惠券信息
+     * @return HttpResponseResult<CouponOrderVO.CouponPageInfo>
+     */
+    @PostMapping(value = "/orderInfo", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "查询订单优惠券信息", notes = "CouponOrderVO.PageRequest")
+    public HttpResponseResult<CouponInfoApi> queryCouponOrderPageInfo(@RequestParam Long userId, @RequestParam String issueIds, @RequestParam BigDecimal orderAmount, @RequestParam ClientEnum client) {
+
+        List<Long> collect = Arrays.stream(issueIds.split(","))
+                .map(Long::valueOf)
+                .collect(Collectors.toList());
+
+        CouponOrderVO.PageRequest request = new CouponOrderVO.PageRequest();
+        request.setClientType(client);
+        request.setCouponTypes(CouponCategoryEnum.getCategory("MALL"));
+        request.setIssueIds(collect);
+        request.setUseState(CouponUseStateEnum.USABLE);
+        request.setTimestamp(DateTime.now().getMillis());
+        request.setAmount(orderAmount.doubleValue());
+
+        CouponInfoApi couponInfoApi = new CouponInfoApi();
+        couponInfoApi.setDiscountedPrices(BigDecimal.ZERO);
+
+        if (CollectionUtils.isNotEmpty(collect)) {
+
+            // 订单优惠券信息
+            CouponOrderWrapper wrapper = couponInfoService.queryUserOrderCouponInfo(request.getUserId(),
+                    CouponInfoQuery.CouponOrderQuery.from(request.jsonString()));
+
+            couponInfoApi.setDiscountedPrices(BigDecimal.valueOf(wrapper.getDiscountedPrices()));
+        }
+
+        return succeed(couponInfoApi);
+    }
+
+    /**
+     * 更新订单优惠券信息
+     * @return HttpResponseResult<Boolean>
+     */
+    @PostMapping(value = "/orderUpdate", consumes="application/json", produces="application/json")
+    @ApiOperation(value = "更新订单优惠券信息")
+    public HttpResponseResult<Boolean> updateCouponOrderInfo(@RequestParam String couponIssueId,@RequestParam Boolean returnCoupon,@RequestParam String orderNo) {
+
+        CouponOrderVO.CouponUpdateRequest  request = new CouponOrderVO.CouponUpdateRequest();
+        request.setOrderNo(orderNo);
+        request.setReset(returnCoupon);
+        request.setUseType(CouponCategoryEnum.MALL);
+        List<Long> collect = Arrays.stream(couponIssueId.split(","))
+                .map(Long::valueOf)
+                .collect(Collectors.toList());
+        request.setIssueIds(collect);
+        // 更新受影响优惠券数据
+        int ret = couponInfoService.updateUserOrderCouponInfo(CouponOrderWrapper.from(request.jsonString()));
+
+        return succeed(ret > 0);
+    }
+}

+ 316 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/ImController.java

@@ -0,0 +1,316 @@
+package com.yonge.cooleshow.admin.controller.open;
+
+import com.alibaba.fastjson.JSON;
+import com.google.common.collect.Lists;
+import com.microsvc.toolkit.middleware.im.properties.ImConfigProperties;
+import com.microsvc.toolkit.middleware.live.LivePluginContext;
+import com.microsvc.toolkit.middleware.live.LivePluginService;
+import com.microsvc.toolkit.middleware.live.impl.TencentCloudLivePlugin;
+import com.yonge.cooleshow.admin.io.request.course.CourseRelationVo;
+import com.yonge.cooleshow.admin.io.request.im.IMNotifyMessageVO;
+import com.yonge.cooleshow.admin.io.request.im.UserFriendInfoVO;
+import com.yonge.cooleshow.api.feign.dto.ImUserInfo;
+import com.yonge.cooleshow.biz.dal.dto.TencentData;
+import com.yonge.cooleshow.biz.dal.dto.TencentImCallbackResult;
+import com.yonge.cooleshow.biz.dal.entity.ImUserStateSync;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.im.ETencentImCallbackCommand;
+import com.yonge.cooleshow.biz.dal.service.CourseRelationMusicAlbumService;
+import com.yonge.cooleshow.biz.dal.service.ImGroupService;
+import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
+import com.yonge.cooleshow.biz.dal.service.LiveRoomService;
+import com.yonge.cooleshow.biz.dal.wrapper.im.CustomerService;
+import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 用户通讯录表(ImUserFriend)表控制层
+ *
+ * @author zx
+ * @since 2022-03-22 10:45:59
+ */
+@Api(tags = "用户通讯录表")
+@RestController
+@RequestMapping("${app-config.url.admin:}/open")
+@Slf4j
+public class ImController extends BaseController {
+
+    /**
+     * 服务对象
+     */
+    @Resource
+    private ImUserFriendService imUserFriendService;
+    @Autowired
+    private CourseRelationMusicAlbumService courseRelationMusicAlbumService;
+
+    @Autowired
+    private LivePluginContext livePluginContext;
+
+    @Autowired
+    private LiveRoomService liveRoomService;
+
+    @Autowired
+    private ImGroupService imGroupService;
+
+    @Autowired
+    private ImConfigProperties imConfig;
+
+
+    @ApiOperation("新用户添加客服")
+    @PostMapping(value = "/im/customerService")
+    public HttpResponseResult<Boolean> customerService(@RequestBody UserFriendInfoVO info) {
+
+        if (info.invalidRequestParam()) {
+            return failed("无效的请求参数");
+        }
+
+        // 新用户自动绑定系统客服
+        int ret = imUserFriendService.registerUserBindCustomerService(info.getUserId(),
+                info.getFriendIds(), ClientEnum.valueOf(info.getClientType()));
+
+        return succeed(ret > 0);
+    }
+
+    /**
+     * 发送系统客服消息
+     * @param info IMNotifyMessageVO
+     * @return HttpResponseResult<Boolean>
+     */
+    @PostMapping(value = "/im/message")
+    public HttpResponseResult<Boolean> sendSysCustomerServiceMessage(@RequestBody IMNotifyMessageVO info) {
+
+        if (info.invalidRequestParam()) {
+            return failed("无效的请求参数");
+        }
+
+        // 发送客服通知消息
+        imUserFriendService.sendCustomerServiceNotifyMessage(info.getSender(),
+                CustomerService.NotifyMessage.from(info.jsonString()));
+
+        return succeed();
+    }
+
+    /**
+     * 同步用户购买课程赠送数据
+     * @param query CourseRelationVo.CourseRelationQuery
+     * @return HttpResponseResult<Boolean>
+     */
+    @ApiOperation("已购买课程赠送同步")
+    @PostMapping(value = "/course/sync")
+    public HttpResponseResult<Boolean> syncUserPurchaseRelationMusicAlbum(@RequestBody CourseRelationVo.CourseRelationQuery query) {
+
+        if (Objects.isNull(query.getCourseGroupId()) || Objects.isNull(query.getCourseType())) {
+            return failed("无效的请求参数");
+        }
+
+        // 同步数据
+        courseRelationMusicAlbumService.asyncUpdateCourseRelationMusicAlbumInfo(query.getCourseGroupId(), query.getCourseType());
+
+        return succeed();
+    }
+
+
+    @ApiOperation("腾讯im 回调接口")
+    @PostMapping(value = "/tencentImCallback")
+    public TencentImCallbackResult tencentImCallback(@RequestBody String body, HttpServletRequest request) {
+        log.info("tencentImCallback body:{}", body);
+
+        LivePluginService pluginService = livePluginContext.getPluginService(TencentCloudLivePlugin.PLUGIN_NAME);
+        String appKey = pluginService.getLiveRoomConfig().getAppKey();
+
+        log.info("tencentImCallback request param:{}", JSON.toJSONString(request.getParameterMap()));
+
+        List<String> sdkList = Arrays.asList(request.getParameterValues("SdkAppid"));
+        if (sdkList == null || sdkList.size() == 0) {
+            log.error("tencentImCallback sdkAppid is null");
+            return new TencentImCallbackResult();
+        }
+        if (!sdkList.contains(appKey)) {
+            log.error("tencentImCallback sdkAppid is not match");
+            return new TencentImCallbackResult();
+        }
+
+        String clientIP = request.getParameter("ClientIP");
+        String optPlatform = request.getParameter("OptPlatform");
+
+
+        if(request.getParameter("CallbackCommand").equals(ETencentImCallbackCommand.GROUP_CALLBACKONMEMBERSTATECHANGE.getCommand())) {
+            // 直播群成员在线状态回调
+            TencentData.CallbackOnMemberStateChange callbackOnMemberStateChange = TencentData.CallbackOnMemberStateChange.toObject(
+                    body);
+
+            log.debug("callbackOnMemberStateChange: {}", callbackOnMemberStateChange);
+            callbackOnMemberStateChange.setClientIP(clientIP);
+            callbackOnMemberStateChange.setOptPlatform(optPlatform);
+            for (TencentData.MemberListDTO memberListDTO : callbackOnMemberStateChange.getMemberList()) {
+                if (!imGroupService.checkImUserId(memberListDTO.getMemberAccount())) {
+                    return new TencentImCallbackResult();
+                }
+                memberListDTO.setMemberAccount(imGroupService.analysisImUserId(memberListDTO.getMemberAccount()));
+            }
+            // 直播间成员状态变更
+            liveRoomService.callbackOnMemberStateChange(callbackOnMemberStateChange);
+        } else if(request.getParameter("CallbackCommand").equals(ETencentImCallbackCommand.GROUP_CALLBACKAFTERMEMBEREXIT.getCommand())) {
+            // 群成员离开之后回调
+            TencentData.CallbackAfterMemberExit callbackAfterMemberExit = TencentData.CallbackAfterMemberExit.toObject(
+                    body);
+
+            log.debug("callbackAfterMemberExit: {}", callbackAfterMemberExit);
+            callbackAfterMemberExit.setClientIP(clientIP);
+            callbackAfterMemberExit.setOptPlatform(optPlatform);
+            for (TencentData.MemberListDTO memberListDTO : callbackAfterMemberExit.getExitMemberList()) {
+                if (!imGroupService.checkImUserId(memberListDTO.getMemberAccount())) {
+                    return new TencentImCallbackResult();
+                }
+                memberListDTO.setMemberAccount(imGroupService.analysisImUserId(memberListDTO.getMemberAccount()));
+            }
+            // 直播间成员状态变更
+            liveRoomService.callbackAfterMemberExit(callbackAfterMemberExit);
+        } else if(request.getParameter("CallbackCommand").equals(ETencentImCallbackCommand.GROUP_CALLBACKAFTERNEWMEMBERJOIN.getCommand())) {
+            // 新成员入群之后回调
+            TencentData.CallbackAfterNewMemberJoin callbackAfterNewMemberJoin = TencentData.CallbackAfterNewMemberJoin.toObject(
+                    body);
+
+            log.debug("CallbackAfterNewMemberJoin: {}", callbackAfterNewMemberJoin);
+            callbackAfterNewMemberJoin.setClientIP(clientIP);
+            callbackAfterNewMemberJoin.setOptPlatform(optPlatform);
+            for (TencentData.MemberListDTO memberListDTO : callbackAfterNewMemberJoin.getNewMemberList()) {
+                if (!imGroupService.checkImUserId(memberListDTO.getMemberAccount())) {
+                    return new TencentImCallbackResult();
+                }
+                memberListDTO.setMemberAccount(imGroupService.analysisImUserId(memberListDTO.getMemberAccount()));
+            }
+            // 直播间成员状态变更
+            liveRoomService.callbackAfterNewMemberJoin(callbackAfterNewMemberJoin);
+        }
+
+
+        return new TencentImCallbackResult();
+    }
+
+
+    @ApiOperation("腾讯云直播-推流 回调接口")
+    @PostMapping(value = "/tencentStreamEventCallback")
+    public TencentData.StreamEventCallbackResult tencentStreamEventCallback(@RequestBody String body) {
+
+        log.info("tencentStreamEventCallback body:{}", body);
+
+        TencentData.CallbackStreamStateEvent event = TencentData.CallbackStreamStateEvent.from(body);
+
+        boolean b = checkStream(event.getStreamId());
+        if (!b) {
+            return TencentData.StreamEventCallbackResult.builder().code(0).build();
+        }
+
+        ImUserStateSync imUserState = new ImUserStateSync();
+        imUserState.setUserid(getSpeakerId(event.getStreamId()).toString());
+        // 断流事件通知
+        if (event.getEventType() == 0) {
+            imUserState.setStatus("3");
+
+            // 更新推流时长
+            if (StringUtils.isNotBlank(event.getPushDuration()) && event.getPushDuration().matches("\\d+")) {
+                // 更新直播推流时长
+                liveRoomService.updateLiveRoomPushStreamTime(event);
+            }
+
+            // 自动关闭录制
+            liveRoomService.closeLive(getRoomUid(event.getStreamId()), getSpeakerId(event.getStreamId()).longValue(),event.getSequence());
+            // 同步点赞数
+            liveRoomService.syncLikeCount(getRoomUid(event.getStreamId()));
+        }
+
+        // 推流事件通知
+        if (event.getEventType() == 1) {
+            // 自动开启录制
+            liveRoomService.startLive(getRoomUid(event.getStreamId()), getSpeakerId(event.getStreamId()),event.getSequence());
+
+            imUserState.setStatus("0");
+        }
+        liveRoomService.opsRoom(Lists.newArrayList(imUserState));
+
+        return TencentData.StreamEventCallbackResult.builder().code(0).build();
+    }
+
+
+    private boolean checkStream(String streamId) {
+        return imGroupService.checkImUserId(streamId.split("_",2)[1]);
+    }
+
+
+    private Integer getSpeakerId(String streamId) {
+        return Integer.parseInt(imGroupService.analysisImUserId(streamId.split("_",2)[1]));
+    }
+
+    private String getRoomUid(String streamId) {
+        return streamId.split("_")[0];
+    }
+
+    @ApiOperation("腾讯云直播-录制 回调接口")
+    @PostMapping(value = "/tencentStreamRecordCallback")
+    public TencentData.StreamEventCallbackResult tencentStreamRecordCallback(@RequestBody String body) {
+
+        log.info("tencentStreamRecordCallback body:{}", body);
+
+        TencentData.CallbackSteamRecordEvent event = TencentData.CallbackSteamRecordEvent.from(body);
+
+
+        boolean b = checkStream(event.getStreamId());
+        if (!b) {
+            return TencentData.StreamEventCallbackResult.builder().code(0).build();
+        }
+
+        // 直播录制事件通知
+        if (event.getStreamId().startsWith("LIVE")) {
+            log.info("taskId={}, url={}", event.getTaskId(), event.getVideoUrl());
+
+            // 生成直播录制信息
+            liveRoomService.createLiveRoomVideoRecord(event);
+        }
+
+        return TencentData.StreamEventCallbackResult.builder().code(0).build();
+    }
+
+    @ApiOperation("腾讯云直播-推流异常 回调接口")
+    @PostMapping(value = "/tencentStreamExceptionCallback")
+    public TencentData.StreamEventCallbackResult tencentStreamExceptionCallback(@RequestBody String body) {
+
+        log.info("tencentStreamExceptionCallback body:{}", body);
+
+        return TencentData.StreamEventCallbackResult.builder().code(0).build();
+    }
+
+    @ApiOperation("注册im用户")
+    @PostMapping(value = "/im/register")
+    public ImUserInfo register(String userId, ClientEnum clientType, String username, String avatar) {
+
+        log.info("注册im用户");
+
+        try {
+            ImGroupWrapper.ImUserInfo register = imGroupService.register(userId, clientType, username, avatar);
+            return JSON.parseObject(JSON.toJSONString(register), ImUserInfo.class);
+        } catch (Exception e) {
+            log.error("注册im用户失败", e);
+            throw new BizException(e.getMessage());
+        }
+    }
+
+}
+

+ 129 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/OpenSysAreaController.java

@@ -0,0 +1,129 @@
+package com.yonge.cooleshow.admin.controller.open;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.google.common.collect.Lists;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.yonge.cooleshow.admin.io.request.SysAreaVo;
+import com.yonge.cooleshow.biz.dal.entity.SysArea;
+import com.yonge.cooleshow.biz.dal.service.SysAreaService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysAreaWrapper;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Validated
+@RestController
+@RequestMapping("${app-config.url.admin:}/open/sysArea")
+@Api(tags = "区域表")
+public class OpenSysAreaController {
+
+    @Autowired
+    private SysAreaService sysAreaService;
+
+    /**
+     * 查询单条
+     * @param id 详情ID
+     * @return R<SysAreaVo.SysArea>
+     */
+    @ApiOperation(value = "详情", notes = "传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @GetMapping("/detail/{id}")
+    public HttpResponseResult<SysAreaWrapper.SysArea> detail(@PathVariable("id") Long id) {
+
+        return HttpResponseResult.succeed(sysAreaService.detail(id));
+    }
+
+    /**
+     * 根据code查询
+     * @param code 详情ID
+     * @return R<SysAreaVo.SysArea>
+     */
+    @ApiOperation(value = "根据code查询", notes = "传入code")
+    @GetMapping("/queryByCode/{code}")
+    public HttpResponseResult<SysArea> queryByCode(@PathVariable("code") Integer code) {
+
+        List<Integer> codeList = new ArrayList<Integer>();
+        codeList.add(code);
+        List<SysArea> list = sysAreaService.queryByCodes(codeList);
+
+        if(list == null || list.size() == 0){
+            throw BizException.from("根据code查询区域表失败");
+        }
+
+        return HttpResponseResult.succeed(list.get(0));
+    }
+
+    /**
+     * 查询分页
+     * @param query SysAreaVo.SysAreaQuery
+     * @return R<PageInfo<SysAreaVo.SysAreaList>>
+     */
+    @ApiOperation(value = "查询分页", notes = "传入sysAreaSearch")
+    @PreAuthorize("@auditsvc.hasPermissions('sysArea/page', {'BACKEND'})")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<SysAreaWrapper.SysArea>> page(@RequestBody SysAreaWrapper.SysAreaQuery query) {
+
+        IPage<SysAreaWrapper.SysArea> pages = sysAreaService.selectPage(QueryInfo.getPage(query), query);
+
+        return HttpResponseResult.succeed(QueryInfo.pageInfo(pages));
+    }
+
+    /**
+     * 查询全部区域
+     * @return R<List<SysAreaVo.Province>>
+     */
+    @ApiOperation(value = "查询全部区域", notes = "查询全部区域")
+    @GetMapping("/queryAllProvince")
+    public HttpResponseResult<List<SysAreaVo.Province>> queryAllProvince() {
+
+        List<SysAreaVo.Province> provinces = Lists.newArrayList();
+
+        // 全部城市信息
+        Map<Integer, List<SysArea>> areaMap = sysAreaService.lambdaQuery().list().stream()
+                .filter(x -> x.getDelFlag().equals("0"))
+                .collect(Collectors.groupingBy(SysArea::getParentOrganId));
+
+        SysAreaVo.Province provinceVo;
+        SysAreaVo.City cityVo;
+        for (SysArea province : areaMap.get(0)) {
+
+            provinceVo = JSON.parseObject(JSON.toJSONString(province), SysAreaVo.Province.class)
+                    .cities(Lists.newArrayList());
+            provinces.add(provinceVo);
+
+            // 城市信息
+            for (SysArea city : areaMap.get(province.getId())) {
+
+                cityVo = JSON.parseObject(JSON.toJSONString(city), SysAreaVo.City.class);
+                provinceVo.getAreas().add(cityVo);
+
+                if (areaMap.containsKey(city.getId())) {
+                    cityVo.setAreas(JSON.parseArray(JSON.toJSONString(areaMap.get(city.getId())), SysAreaVo.District.class));
+                }
+            }
+        }
+
+        return HttpResponseResult.succeed(provinces);
+    }
+}

+ 47 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/OpenSysConfigController.java

@@ -0,0 +1,47 @@
+package com.yonge.cooleshow.admin.controller.open;
+
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.common.constant.SysConfigConstant;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 系统配置控制层
+ */
+@RestController
+@Api(tags = "系统参数设置")
+@RequestMapping(value = "${app-config.url.admin:}/open/sysConfig")
+public class OpenSysConfigController extends BaseController {
+
+    @Autowired
+    private SysConfigService sysConfigService;
+
+    @ApiOperation(value = "查询客服手机号")
+    @GetMapping(value = "/queryCustomerServicePhone")
+    public HttpResponseResult<String> queryCustomerServicePhone() {
+        SysConfig sysConfig = sysConfigService.findByParamName(SysConfigConstant.CUSTOMER_SERVICE_PHONE);
+        return succeed(sysConfig.getParamValue());
+    }
+
+    @ApiOperation(value = "查询客服联系方式,电话和邮箱")
+    @GetMapping(value = "/queryCustomerService")
+    public HttpResponseResult<Map<String, String>> queryCustomerService() {
+        SysConfig email = sysConfigService.findByParamName(SysConfigConstant.CUSTOMER_SERVICE_EMAIL);
+        SysConfig phone = sysConfigService.findByParamName(SysConfigConstant.CUSTOMER_SERVICE_PHONE);
+        Map<String, String> result = new HashMap<>();
+        result.put("email", email == null ? "" : email.getParamValue());
+        result.put("phone", phone == null ? "" : phone.getParamValue());
+        return succeed(result);
+    }
+
+}

+ 73 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/OpenUserAccountController.java

@@ -0,0 +1,73 @@
+package com.yonge.cooleshow.admin.controller.open;
+
+import com.yonge.cooleshow.biz.dal.dto.MusicImgDto;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
+import com.yonge.cooleshow.biz.dal.service.UserAccountService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.entity.MallOrderItemDto;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Objects;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/open")
+@Api(value = "开放权限接口", tags = "开放权限接口")
+public class OpenUserAccountController extends BaseController {
+    private final static Logger log = LoggerFactory.getLogger(OpenUserAccountController.class);
+
+
+
+    @Autowired
+    private UserAccountService userAccountService;
+
+    @Autowired
+    private MusicSheetService musicSheetService;
+
+    /**
+     * 设置商城收入分润
+     */
+    @PostMapping("/mallRecord")
+    public HttpResponseResult<Boolean> mallRecord(@RequestBody List<MallOrderItemDto> shareDto ) {
+        return succeed(userAccountService.saveMallAccountRecord(shareDto));
+    }
+
+
+
+    /**
+     * 设置商城收入状态
+     */
+    @PostMapping("/mallRecordState")
+    public HttpResponseResult<Boolean> mallRecordState(@RequestBody List<MallOrderItemDto> shareDto ) {
+        userAccountService.mallTeacherRecordState(shareDto);
+        return succeed();
+    }
+
+
+
+    @ApiOperation(value = "新增曲谱渲染图")
+    @PostMapping(value="/music/sheet/img")
+    public HttpResponseResult<Boolean> img(@RequestBody @Valid MusicImgDto musicImgDto) {
+        return succeed(musicSheetService.updateMusicImg(musicImgDto, musicImgDto.getMusicSheetId()));
+    }
+
+    @ApiOperation(value = "曲目数据修复")
+    @PostMapping(value="/music/sheet/musicCorrect")
+    public HttpResponseResult<Boolean> musicCorrect(@RequestBody MusicImgDto musicImgDto) {
+        if (Objects.isNull(musicImgDto.getMusicSheetId())) {
+            failed("曲目Id参数错误");
+        }
+        return succeed(musicSheetService.updateMusicCorrect(musicImgDto, musicImgDto.getMusicSheetId()));
+    }
+
+}

+ 206 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/UserOrderClient.java

@@ -0,0 +1,206 @@
+package com.yonge.cooleshow.admin.controller.open;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.yonge.cooleshow.biz.dal.entity.UserOrder;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderPayment;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderRefundBill;
+import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
+import com.yonge.cooleshow.biz.dal.service.UserOrderPaymentService;
+import com.yonge.cooleshow.biz.dal.service.UserOrderRefundService;
+import com.yonge.cooleshow.biz.dal.service.UserOrderService;
+import com.yonge.cooleshow.biz.dal.vo.UserOrderVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.ContractDto;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.CacheNameEnum;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.result.BaseResult;
+import com.yonge.toolset.payment.base.enums.MethodNameEnum;
+import com.yonge.toolset.payment.base.enums.OpenEnum;
+import com.yonge.toolset.payment.base.enums.PayChannelEnum;
+import com.yonge.toolset.payment.base.enums.PaymentClientEnum;
+import com.yonge.toolset.payment.base.model.Payment;
+import com.yonge.toolset.payment.base.model.callback.PaymentCallBack;
+import com.yonge.toolset.payment.core.service.PaymentClient;
+import com.yonge.toolset.payment.util.DistributedLock;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.redisson.api.RedissonClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.concurrent.TimeUnit;
+
+@RestController
+@RequestMapping("${app-config.url.admin:}/open/userOrder")
+@Api(value = "开放权限接口", tags = "开放权限接口")
+public class UserOrderClient extends BaseController {
+    private final static Logger log = LoggerFactory.getLogger(UserOrderClient.class);
+
+    @Autowired
+    private UserOrderPaymentService paymentService;
+    @Autowired
+    private UserOrderRefundService userOrderRefundService;
+    @Autowired
+    private UserOrderService userOrderService;
+    @Autowired
+    private PaymentClient paymentClient;
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Value("${message.debugMode}")
+    private boolean debugMode;
+
+    @ApiOperation(value = "查询付款单")
+    @GetMapping("/queryPayment")
+    public HttpResponseResult<Payment> queryPayment(String paymentNo) {
+        UserOrderPayment userOrderPayment = paymentService.getOne(Wrappers.<UserOrderPayment>lambdaQuery()
+                .eq(UserOrderPayment::getPaymentNo, paymentNo)
+        );
+        if (null == userOrderPayment) {
+            return HttpResponseResult.succeed();
+        }
+        Payment param = new Payment(userOrderPayment.getOpenType(),
+                PaymentClientEnum.valueOf(userOrderPayment.getPaymentClient()), userOrderPayment.getPayChannel());
+        param.setId(userOrderPayment.getTransNo());
+        param.setPaymentNo(userOrderPayment.getPaymentNo());
+        BaseResult<Payment> paymentBaseResult = paymentClient.queryPayment(param);
+        return HttpResponseResult.status(paymentBaseResult);
+    }
+
+    /***
+     * 支付回调
+     * @author liweifan
+     * @param: request
+     * @updateTime 2022/3/11 18:35
+     */
+    @RequestMapping("/callback/{openType}/{client}/{payChannel}/{payMethod}")
+    public Object callback(
+            @PathVariable("openType") String openType,
+            @PathVariable("client") String client,
+            @PathVariable("payChannel") String payChannel,
+            @PathVariable("payMethod") String payMethod,
+            HttpServletRequest request
+    ) {
+        //支付回调:openType is ORIGINAL ,paymentClient is STUDENT,payChannel is ali_app,payMethod is executePayment
+        log.info("支付回调:openType is {} ,paymentClient is {},payChannel is {},payMethod is {}", openType, client, payChannel, payMethod);
+        BaseResult<PaymentCallBack> res = paymentClient.analysisNotice(
+                OpenEnum.valueOf(openType), PaymentClientEnum.valueOf(client),
+                PayChannelEnum.valueOf(payChannel), MethodNameEnum.valueOf(payMethod), request);
+        log.info("统一解析结果:{}", JSONObject.toJSONString(res));
+
+        if (res.getStatus()) {
+            PaymentCallBack data = res.getData();
+            //查询到订单
+            UserOrderVo userOrderVo = userOrderService.getUserOrderByPaymentNoOrTransNo(data.getPaymentNo(), data.getId());
+            if (null == userOrderVo) {
+                return res.getData().getResMsg();
+            }
+            try {
+                DistributedLock.of(redissonClient)
+                        .runIfLockCanGet(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(userOrderVo.getOrderNo())
+                                , () -> {
+                                    if (MethodNameEnum.executePayment.equals(data.getMethodName())) {
+                                        //支付交易
+                                        paymentService.executePaymentCallBack(data);
+                                    } else if (MethodNameEnum.closePayment.equals(data.getMethodName())) {
+                                        //关闭订单
+                                        paymentService.closePaymentCallBack(data);
+                                    } else if (MethodNameEnum.refundPayment.equals(data.getMethodName())) {
+                                        //退款
+                                        userOrderRefundService.refundPaymentCallBack(data);
+                                    }
+                                }, 60L, TimeUnit.SECONDS);
+                return res.getData().getResMsg();
+            } catch (BizException e) {
+                log.error("回调业务异常,data is {}, msg is {}", JSONObject.toJSONString(data), e.getMessage());
+            } catch (Exception e) {
+                log.error("回调业务异常,data is {} , msg is {}", JSONObject.toJSONString(data),e.getMessage());
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    /***
+     * 支付回调
+     * @author liweifan
+     * @param: request
+     * @updateTime 2022/3/11 18:35
+     */
+    @PostMapping("/testCallback")
+    public void testCallback(@RequestBody PaymentCallBack data) {
+        if (!debugMode) {
+            return;
+        }
+        if (MethodNameEnum.executePayment.equals(data.getMethodName())) {
+            //支付交易
+            paymentService.executePaymentCallBack(data);
+        } else if (MethodNameEnum.closePayment.equals(data.getMethodName())) {
+            //关闭订单
+            paymentService.closePaymentCallBack(data);
+        } else if (MethodNameEnum.refundPayment.equals(data.getMethodName())) {
+            //退款
+            userOrderRefundService.refundPaymentCallBack(data);
+        }
+    }
+
+    @GetMapping("/setSuccessStatus")
+    @ApiOperation(value = "完成所有订单(测试用)")
+    public HttpResponseResult<Boolean> setSuccessStatus() {
+        if (!debugMode) {
+            return HttpResponseResult.failed("当前环境不允许调用");
+        }
+        userOrderService.setSuccessStatus();
+        return succeed(true);
+    }
+
+    @GetMapping("/setOrderStatus")
+    @ApiOperation(value = "设置订单状态(测试用)")
+    public HttpResponseResult<Boolean> setOrderStatus(
+            @RequestParam("orderNo") String orderNo,
+            @RequestParam("orderStatus") OrderStatusEnum orderStatus) {
+        if (!debugMode) {
+            return HttpResponseResult.failed("当前环境不允许调用");
+        }
+
+        UserOrder param = new UserOrder();
+        param.setOrderNo(orderNo);
+        param.setStatus(orderStatus);
+        Boolean aBoolean = DistributedLock.of(redissonClient)
+                .runIfLockToFunction(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(orderNo)
+                        , userOrderService::setOrderStatus, param, 10L);
+        return succeed(aBoolean);
+    }
+
+    @GetMapping("/orderRefound")
+    @ApiOperation(value = "退款(测试用)")
+    public HttpResponseResult<UserOrderRefundBill> orderRefound(
+            @RequestParam("orderNo") String orderNo) {
+        if (!debugMode) {
+            return HttpResponseResult.failed("当前环境不允许调用");
+        }
+        return userOrderRefundService.orderRefound(orderNo);
+    }
+
+    /**
+     * 签协议 商城调用
+     */
+    @PostMapping("/contractRecord")
+    @ApiOperation(value = "签协议 商城调用", notes = "签协议 商城调用")
+    public HttpResponseResult<Boolean> contractRecord(@RequestBody ContractDto contract) {
+        paymentService.setContractRecord(contract.getType(), contract.getUserId());
+        return succeed(true);
+    }
+}

+ 275 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/open/UserPaymentClient.java

@@ -0,0 +1,275 @@
+package com.yonge.cooleshow.admin.controller.open;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.huifu.adapay.core.AdapayCore;
+import com.huifu.adapay.core.util.AdapaySign;
+import com.microsvc.toolkit.common.response.template.R;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
+import com.microsvc.toolkit.middleware.payment.common.api.PaymentServiceContext;
+import com.microsvc.toolkit.middleware.payment.common.api.entity.PaymentResp;
+import com.microsvc.toolkit.middleware.payment.common.api.entity.RefundResp;
+import com.yeepay.g3.sdk.yop.encrypt.DigitalEnvelopeDTO;
+import com.yeepay.g3.sdk.yop.utils.DigitalEnvelopeUtils;
+import com.yeepay.g3.sdk.yop.utils.RSAKeyUtils;
+import com.yonge.cooleshow.biz.dal.entity.PaymentMerchantConfig;
+import com.yonge.cooleshow.biz.dal.entity.TenantMember;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderRefundBill;
+import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
+import com.yonge.cooleshow.biz.dal.service.PaymentMerchantConfigService;
+import com.yonge.cooleshow.biz.dal.service.TenantMemberService;
+import com.yonge.cooleshow.biz.dal.service.UserOrderRefundBillService;
+import com.yonge.cooleshow.biz.dal.service.UserOrderService;
+import com.yonge.cooleshow.biz.dal.service.UserPaymentCoreService;
+import com.yonge.cooleshow.biz.dal.service.UserPaymentOrderService;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import com.yonge.cooleshow.common.enums.EPayerType;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.Date;
+import java.util.Objects;
+
+@Slf4j
+@RestController
+@RequestMapping("${app-config.url.admin:}/open/userOrder")
+@Api(tags = "开放权限接口-支付回调")
+public class UserPaymentClient {
+
+    @Autowired
+    private PaymentServiceContext paymentServiceContext;
+    @Autowired
+    private UserPaymentCoreService userPaymentCoreService;
+    @Autowired
+    private UserPaymentOrderService userPaymentOrderService;
+
+    @Autowired
+    private UserOrderService userOrderService;
+
+    @Autowired
+    private TenantMemberService tenantMemberService;
+
+    @Autowired
+    private PaymentMerchantConfigService paymentMerchantConfigService;
+
+    @Autowired
+    private UserOrderRefundBillService userOrderRefundBillService;
+    /**
+     * 支付消息回调
+     * @param request HttpServletRequest
+     * @return String
+     */
+    @ApiOperation(value = "支付消息回调", notes = "三方支付平台支付消息通知")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "vendor", value = "服务提供方", dataType = "String")
+    })
+    @RequestMapping(value = "/payment/callback/{vendor}", method = {RequestMethod.GET, RequestMethod.POST})
+    public String payment(@PathVariable("vendor") String vendor, HttpServletRequest request) {
+
+        // 支付回调消息
+        PaymentResp paymentResp = paymentServiceContext.getPaymentService(vendor).callbackNotifyForPay(request);
+        if (Objects.isNull(paymentResp)) {
+            return null;
+        }
+        log.info("payment vendor={}, paymentResp={}", vendor, JSON.toJSONString(paymentResp));
+        // 支付订单确认
+        UserPaymentOrderWrapper.UserPaymentOrder paymentOrder = userPaymentOrderService
+                .getUserPaymentOrderByOrderNo( paymentResp.getMerOrderNo());
+        if (Objects.isNull(paymentOrder)) {
+            return paymentResp.getMsg();
+        }
+
+        // 执行支付回调流程
+        userPaymentCoreService.executePaymentCallback(paymentResp);
+
+        return paymentServiceContext.getPaymentService(vendor).returnNotifyResult(request);
+    }
+
+    @ApiOperation(value = "用户付款", notes = "用户付款")
+    @PostMapping("/executePayment/v2")
+    public R<UserPaymentOrderWrapper.PaymentReq> executePayment(@Validated @RequestBody UserPaymentOrderWrapper.PaymentOrderReqConfig config) {
+
+        // 用户登录状态校验
+        if (StringUtils.isBlank(config.getUserId())) {
+            throw BizException.from("用户未登录");
+        }
+
+        // 用户下单请求
+        UserPaymentOrderWrapper.PaymentOrderReqConfig reqConfig = UserPaymentOrderWrapper.PaymentOrderReqConfig.from(config.jsonString());
+
+        JwtUserInfo<Object> userInfo = JwtUserInfo.builder()
+            .userId(config.getUserId())
+            .clientType(config.getUserType().getCode())
+            .build();
+        // 创建用户支付数据
+        UserPaymentOrderWrapper.PaymentReq paymentConfig = userPaymentCoreService.executePayment(userInfo, reqConfig);
+        if (Objects.isNull(paymentConfig)) {
+            throw BizException.from("用户支付请求错误");
+        }
+
+        return R.from(paymentConfig);
+    }
+
+
+    /**
+     * 退款消息回调
+     * @param request HttpServletRequest
+     * @return String
+     */
+    @ApiOperation(value = "退款消息回调", notes = "三方支付平台退款消息通知")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "vendor", value = "服务提供方", dataType = "String")
+    })
+    @RequestMapping(value = "/refund/callback/{vendor}", method = {RequestMethod.GET, RequestMethod.POST})
+    public String refund(@PathVariable("vendor") String vendor, HttpServletRequest request) {
+
+        RefundResp refundResp = paymentServiceContext.getPaymentService(vendor).callbackNotifyForRefund(request);
+        if (Objects.isNull(refundResp)) {
+            log.info("refund REFUND_FAILED, vendor={}", vendor);
+            return null;
+        }
+        log.info("refund vendor={}, refundResp={}", vendor, JSON.toJSONString(refundResp));
+
+        // 退款订单确认
+        UserOrderRefundBill refundBill = userOrderRefundBillService.getByTransNoOrOrderNo(refundResp.getTransNo(), refundResp.getMerOrderNo());
+        if (Objects.isNull(refundBill)) {
+            log.warn("refund REFUND_FAILED, vendor={}, refundResp={}", vendor, JSON.toJSONString(refundResp));
+            return refundResp.getMsg();
+        }
+
+        // 执行退款回调流程
+        userPaymentCoreService.refundPaymentCallback(refundResp);
+
+        return paymentServiceContext.getPaymentService(vendor).returnNotifyResult(request);
+    }
+
+    @PostMapping("/callback/adapay")
+    public String callback(HttpServletRequest request) {
+        try {
+            // 验签请参data
+            String data = request.getParameter("data");
+            // 验签请参sign
+            String sign = request.getParameter("sign");
+
+            // 验签
+            if (!AdapaySign.verifySign(data, sign, AdapayCore.PUBLIC_KEY)) {
+                return "验签失败";
+            }
+
+            JSONObject dataObj = JSON.parseObject(data);
+
+            String memberId = dataObj.getString("member_id");
+
+            TenantMember tenantMember = tenantMemberService.getByMemberId(memberId, EPayerType.YEEPAY);
+            if(tenantMember == null){
+                return "账户["+ memberId +"]在系统中不存在";
+            }
+            tenantMember.setUpdateTime(new Date());
+
+            String transType = request.getParameter("type");
+
+            switch (transType) {
+
+                case "corp_member.succeeded":// 企业子账户开户成功
+                    String settleAccountId = dataObj.getString("settle_account_id");
+                    tenantMember.setSettleAccountId(settleAccountId);
+                    tenantMember.setStatus(AuthStatusEnum.PASS);
+
+                    break;
+
+                case "corp_member.failed":// 企业子账户开户失败
+                    tenantMember.setStatus(AuthStatusEnum.UNPASS);
+                    tenantMember.setMemo(dataObj.getString("audit_desc"));
+
+                    break;
+
+                case "corp_member_update.succeeded":// 更新企业用户对象成功
+                    tenantMember.setStatus(AuthStatusEnum.PASS);
+
+                    break;
+
+                case "corp_member_update.failed":// 更新企业用户对象失败
+                    tenantMember.setStatus(AuthStatusEnum.UNPASS);
+                    tenantMember.setMemo(dataObj.getString("audit_desc"));
+
+                    break;
+
+                default:
+                    break;
+            }
+
+            tenantMemberService.updateById(tenantMember);
+
+        } catch (Exception e) {
+            return e.getMessage();
+        }
+
+        return "succeeded";
+    }
+
+
+    @PostMapping("/callback/yeepay/{requestNo}")
+    public String callback(@PathVariable("requestNo") String requestNo, HttpServletRequest request) {
+
+        TenantMember tenantMember = tenantMemberService.getByRequestNo(requestNo);
+        if(tenantMember == null){
+            return "请求编号["+ requestNo +"]在系统中不存在";
+        }
+        tenantMember.setUpdateTime(new Date());
+
+        PaymentMerchantConfig paymentMerchantConfig = paymentMerchantConfigService.getByPaymentVendor(tenantMember.getPayerName());
+        if(paymentMerchantConfig == null){
+            throw new BizException("机构[{}][{}]商户信息找不到", tenantMember.getTenantId(), EPayerType.YEEPAY.getCode());
+        }
+
+        try {
+
+            String content = request.getParameter("response");
+
+            // 构造结果通知请求对象
+            DigitalEnvelopeDTO dto = new DigitalEnvelopeDTO();
+            dto.setCipherText(content);
+            PrivateKey privateKey = RSAKeyUtils.string2PrivateKey(paymentMerchantConfig.getRsaPrivateKey());
+            PublicKey publicKey = RSAKeyUtils.string2PublicKey(paymentMerchantConfig.getRsaPublicKey());
+
+            dto = DigitalEnvelopeUtils.decrypt(dto, privateKey, publicKey);
+
+            log.info("易宝支付回调信息:response:{} plaintText:{}", content, dto.getPlainText());
+
+            JSONObject dataObj = JSON.parseObject(dto.getPlainText());
+
+            if("COMPLETED".equals(dataObj.getString("applicationStatus"))) {
+                //审核成功
+                tenantMember.setStatus(AuthStatusEnum.PASS);
+                tenantMemberService.updateById(tenantMember);
+            }else if("REVIEW_BACK".equals(dataObj.getString("applicationStatus"))) {
+                //审核驳回
+                tenantMember.setStatus(AuthStatusEnum.UNPASS);
+                tenantMember.setMemo(dataObj.getString("auditOpinion"));
+                tenantMemberService.updateById(tenantMember);
+            }
+
+            return "SUCCESS";
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        return null;
+    }
+}

+ 135 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/ActivityTeacherVO.java

@@ -0,0 +1,135 @@
+package com.yonge.cooleshow.admin.io.request;
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.biz.dal.enums.MK;
+import com.yonge.toolset.base.page.QueryInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * 活动老师信息
+ * Created by Eric.Shang on 2022/8/29.
+ */
+public class ActivityTeacherVO {
+
+    /**
+     * 活动老师请求信息
+     */
+    @Data
+    @EqualsAndHashCode(callSuper = false)
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(value = "分享活动老师请求", description = "分享活动老师信息")
+    public static class RequestInfo extends QueryInfo {
+
+        @ApiModelProperty("活动ID")
+        private Long activityId;
+        @ApiModelProperty("老师编号/真实姓名/昵称/手机号")
+        private String keyword;
+        @ApiModelProperty("声部id(多个逗号隔开)")
+        private String subjectIds;
+        @ApiModelProperty("新增老师搜索, 1: 新增搜索; 0:已添加老师")
+        private Integer addType;
+
+        @ApiModelProperty(hidden = true)
+        private List<Long> subjectIdList;
+        @ApiModelProperty(hidden = true)
+        private Long id;
+        @ApiModelProperty(hidden = true)
+        private String mobile;
+        @ApiModelProperty(hidden = true)
+        private String name;
+
+        public String jsonString() {
+
+            return JSON.toJSONString(this);
+        }
+
+        public Integer getAddType() {
+            return Optional.ofNullable(addType).orElse(0);
+        }
+
+        public List<Long> getSubjectIdList() {
+
+            if (StringUtils.isNotEmpty(getSubjectIds())) {
+                this.subjectIdList = StringUtil.toLongList(subjectIds);
+            }
+
+            return subjectIdList;
+        }
+
+        public Long getId() {
+
+            if (StringUtils.isNotEmpty(getKeyword())
+                    && !getKeyword().matches(MK.EXP_MOBILE_NUMBER)
+                    && getKeyword().matches(MK.EXP_INT)) {
+
+                return Long.parseLong(getKeyword());
+            }
+            return id;
+        }
+
+        public String getMobile() {
+            if (StringUtils.isNotEmpty(getKeyword())
+                    && getKeyword().matches(MK.EXP_MOBILE_NUMBER)) {
+                return getKeyword();
+            }
+            return mobile;
+        }
+
+        public String getName() {
+
+            if (StringUtils.isNotEmpty(getKeyword())
+                    && !getKeyword().matches(MK.EXP_MOBILE_NUMBER)
+                    && !getKeyword().matches(MK.EXP_INT)) {
+
+                return getKeyword();
+            }
+
+            return name;
+        }
+
+        public Long getActivityId() {
+
+            if (Optional.ofNullable(this.activityId).orElse(0L) > 0) {
+                return this.activityId;
+            }
+            return null;
+        }
+    }
+
+    /**
+     * 活动老师响应信息
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(value = "分享活动老师响应", description = "分享活动老师信息")
+    public static class ResponseInfo implements Serializable {
+
+        @ApiModelProperty(value = "数据编号")
+        private Long id;
+        @ApiModelProperty("昵称")
+        private String username;
+        @ApiModelProperty("真实姓名")
+        private String realName;
+        @ApiModelProperty("手机号")
+        private String phone;
+        @ApiModelProperty("声部ID")
+        private String subjectId;
+        @ApiModelProperty("声部")
+        private String subjectName;
+        @ApiModelProperty(value = "老师编号")
+        private Long teacherId;
+    }
+}

+ 168 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/SysAreaVo.java

@@ -0,0 +1,168 @@
+package com.yonge.cooleshow.admin.io.request;
+
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 区域表
+ * 2022-11-23 18:28:58
+ */
+@ApiModel(value = "SysAreaVo对象", description = "区域表查询视图对象")
+public class SysAreaVo {
+
+    @Data
+    @ApiModel(" SysAreaList-区域表")
+    public static class SysAreaQuery implements QueryInfo {
+
+    	@ApiModelProperty("父节点")
+    	private Integer parentId;
+
+        @ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+    }
+
+    @Data
+    @ApiModel(" SysArea-区域表")
+    public static class SysArea {
+
+
+		@ApiModelProperty("")
+        private Integer id;
+
+
+		@ApiModelProperty("名称")
+        private String name;
+
+
+		@ApiModelProperty("编码")
+        private Integer code;
+
+
+		@ApiModelProperty("创建时间")
+        private Date createTime;
+
+
+		@ApiModelProperty("修改时间")
+        private Date updateTime;
+
+
+		@ApiModelProperty("是否删除  -1:已删除  0:正常")
+        private String delFlag;
+
+
+		@ApiModelProperty("父节点编号")
+        private Integer parentOrganId;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+    }
+
+    @Data
+    @ApiModel(" SysAreaList-区域表")
+    public static class SysAreaList {
+
+
+		@ApiModelProperty("")
+        private Integer id;
+
+
+		@ApiModelProperty("名称")
+        private String name;
+
+
+		@ApiModelProperty("编码")
+        private Integer code;
+
+
+		@ApiModelProperty("创建时间")
+        private Date createTime;
+
+
+		@ApiModelProperty("修改时间")
+        private Date updateTime;
+
+
+		@ApiModelProperty("是否删除  -1:已删除  0:正常")
+        private String delFlag;
+
+
+		@ApiModelProperty("父节点编号")
+        private Integer parentOrganId;
+
+        @ApiModelProperty("区域数")
+        private Integer number;
+    }
+
+    @Data
+    @ApiModel("省份")
+    public static class Province implements Serializable {
+
+        @ApiModelProperty("主键Id")
+        private Integer id;
+
+        @ApiModelProperty("名称")
+        private String name;
+
+        @ApiModelProperty("编码")
+        private Integer code;
+
+        @ApiModelProperty("父节点编号")
+        private Integer parentOrganId;
+
+        @ApiModelProperty("城市")
+        private List<City> areas;
+
+
+        public Province cities(List<City> cities) {
+            this.areas = cities;
+            return this;
+        }
+    }
+
+    @Data
+    @ApiModel("城市")
+    public static class City implements Serializable {
+
+        @ApiModelProperty("主键Id")
+        private Integer id;
+
+        @ApiModelProperty("名称")
+        private String name;
+
+        @ApiModelProperty("编码")
+        private Integer code;
+
+        @ApiModelProperty("父节点编号")
+        private Integer parentOrganId;
+
+        @ApiModelProperty("地区/街道")
+        private List<District> areas;
+
+    }
+
+    @Data
+    @ApiModel("地区/街道")
+    public static class District implements Serializable {
+
+        @ApiModelProperty("主键Id")
+        private Integer id;
+
+        @ApiModelProperty("名称")
+        private String name;
+
+        @ApiModelProperty("编码")
+        private Integer code;
+    }
+}

+ 326 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/TeacherBindingUserVo.java

@@ -0,0 +1,326 @@
+package com.yonge.cooleshow.admin.io.request;
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * Description
+ *
+ * @author liujunchi
+ * @date 2022-10-08
+ */
+public class TeacherBindingUserVo {
+
+    @ApiModel("BindingUserQuery-老师绑定的学生列表查询")
+    public static class BindingUserQuery extends QueryInfo {
+
+        @ApiModelProperty(value = "老师id",required = true)
+        @NotNull(message = "老师id不能为空")
+        private Long teacherId;
+
+        @ApiModelProperty("查询条件 昵称、编号、手机号")
+        private String search;
+
+        @ApiModelProperty("绑定开始时间")
+        private Date startTime;
+
+        @ApiModelProperty("绑定结束时间")
+        private Date endTime;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public Long getTeacherId() {
+            return teacherId;
+        }
+
+        public void setTeacherId(Long teacherId) {
+            this.teacherId = teacherId;
+        }
+
+        @Override
+        public String getSearch() {
+            return search;
+        }
+
+        @Override
+        public void setSearch(String search) {
+            this.search = search;
+        }
+
+        public Date getStartTime() {
+            return startTime;
+        }
+
+        public void setStartTime(Date startTime) {
+            this.startTime = startTime;
+        }
+
+        public Date getEndTime() {
+            return endTime;
+        }
+
+        public void setEndTime(Date endTime) {
+            this.endTime = endTime;
+        }
+    }
+
+
+    @ApiModel("BindingUserList-老师绑定的学生列表")
+    public static class BindingUserList  {
+
+        @ApiModelProperty("学生编号")
+        private Long userId;
+
+        @ApiModelProperty("昵称")
+        private String username;
+
+
+        @ApiModelProperty(value = "性别0女1男")
+        private Integer gender;
+
+        @ApiModelProperty(value = "年龄")
+        private Integer age;
+
+
+        // 声部
+        @ApiModelProperty(value = "声部")
+        private String subjectName;
+
+        @ApiModelProperty(value = "手机号")
+        private String phone;
+
+        @ApiModelProperty(value = "是否会员 0否 1是")
+        private YesOrNoEnum isVip;
+
+
+        @ApiModelProperty("课程数")
+        private Long courseNum;
+
+        @ApiModelProperty("已结束课时数")
+        private Integer endCourseNum;
+
+        @ApiModelProperty("未开始课程数")
+        private Integer noStartCourseNum;
+
+        @ApiModelProperty("绑定时间")
+        private Date bindingTime;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public String getSubjectName() {
+            return subjectName;
+        }
+
+        public void setSubjectName(String subjectName) {
+            this.subjectName = subjectName;
+        }
+
+        public Long getUserId() {
+            return userId;
+        }
+
+        public void setUserId(Long userId) {
+            this.userId = userId;
+        }
+
+        public String getUsername() {
+            return username;
+        }
+
+        public void setUsername(String username) {
+            this.username = username;
+        }
+
+        public Integer getGender() {
+            return gender;
+        }
+
+        public void setGender(Integer gender) {
+            this.gender = gender;
+        }
+
+        public Integer getAge() {
+            return age;
+        }
+
+        public void setAge(Integer age) {
+            this.age = age;
+        }
+
+        public String getPhone() {
+            return phone;
+        }
+
+        public void setPhone(String phone) {
+            this.phone = phone;
+        }
+
+        public YesOrNoEnum getIsVip() {
+            return isVip;
+        }
+
+        public void setIsVip(YesOrNoEnum isVip) {
+            this.isVip = isVip;
+        }
+
+        public Long getCourseNum() {
+            return courseNum;
+        }
+
+        public void setCourseNum(Long courseNum) {
+            this.courseNum = courseNum;
+        }
+
+        public Integer getEndCourseNum() {
+            return endCourseNum;
+        }
+
+        public void setEndCourseNum(Integer endCourseNum) {
+            this.endCourseNum = endCourseNum;
+        }
+
+        public Integer getNoStartCourseNum() {
+            return noStartCourseNum;
+        }
+
+        public void setNoStartCourseNum(Integer noStartCourseNum) {
+            this.noStartCourseNum = noStartCourseNum;
+        }
+
+        public Date getBindingTime() {
+            return bindingTime;
+        }
+
+        public void setBindingTime(Date bindingTime) {
+            this.bindingTime = bindingTime;
+        }
+    }
+
+    @ApiModel("BindingStudentCourseQuery-绑定学生课程列表查询")
+    public static class BindingStudentCourseQuery extends QueryInfo{
+
+        @ApiModelProperty(value = "老师id",required = true)
+        @NotNull(message = "老师id不能为空")
+        private Long teacherId;
+
+        @NotNull(message = "学员id不能为空")
+        @ApiModelProperty(value = "学员id",required = true)
+        private Long studentId;
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+        public Long getTeacherId() {
+            return teacherId;
+        }
+
+        public void setTeacherId(Long teacherId) {
+            this.teacherId = teacherId;
+        }
+
+        public Long getStudentId() {
+            return studentId;
+        }
+
+        public void setStudentId(Long studentId) {
+            this.studentId = studentId;
+        }
+    }
+
+
+
+    @ApiModel("BindingStudentCourseList-绑定学生课程列表")
+    public static class BindingStudentCourseList{
+
+        @ApiModelProperty("课程编号")
+        private Long courseId;
+
+        @ApiModelProperty("课程声部")
+        private String subjectName;
+
+        @ApiModelProperty("学员考勤 TRUANT:旷课 ATTENDCLASS:到课 NOTSTART:未开始")
+        private String status;
+
+        @ApiModelProperty(value = "课程状态 NOT_START未开始 ING进行中 COMPLETE已完成 CANCEL已取消  CourseScheduleEnum")
+        private String courseStatus;
+
+        @ApiModelProperty("上课时间")
+        private Date classDate;
+
+        // 课程开始时间
+        @ApiModelProperty("课程开始时间")
+        private Date startTime;
+
+        //课程结束时间
+        @ApiModelProperty("课程结束时间")
+        private Date endTime;
+
+        public Date getStartTime() {
+            return startTime;
+        }
+
+        public void setStartTime(Date startTime) {
+            this.startTime = startTime;
+        }
+
+        public Date getEndTime() {
+            return endTime;
+        }
+
+        public void setEndTime(Date endTime) {
+            this.endTime = endTime;
+        }
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+        public Long getCourseId() {
+            return courseId;
+        }
+
+        public void setCourseId(Long courseId) {
+            this.courseId = courseId;
+        }
+
+        public String getSubjectName() {
+            return subjectName;
+        }
+
+        public void setSubjectName(String subjectName) {
+            this.subjectName = subjectName;
+        }
+
+        public String getStatus() {
+            return status;
+        }
+
+        public void setStatus(String status) {
+            this.status = status;
+        }
+
+        public String getCourseStatus() {
+            return courseStatus;
+        }
+
+        public void setCourseStatus(String courseStatus) {
+            this.courseStatus = courseStatus;
+        }
+
+        public Date getClassDate() {
+            return classDate;
+        }
+
+        public void setClassDate(Date classDate) {
+            this.classDate = classDate;
+        }
+    }
+}

+ 134 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/TenantAlbumVo.java

@@ -0,0 +1,134 @@
+package com.yonge.cooleshow.admin.io.request;
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.biz.dal.enums.SubjectTypeEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 机构专辑
+ * 2023-07-28 10:17:46
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@ApiModel(value = "TenantAlbumVo对象", description = "机构专辑查询视图对象")
+public class TenantAlbumVo {
+
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" TenantAlbum-机构专辑")
+    public static class TenantAlbum {
+
+        @ApiModelProperty("主键ID")
+        private Long id;
+
+        @ApiModelProperty("机构ID")
+        private Long tenantId;
+
+        @ApiModelProperty("专辑名称")
+        private String name;
+
+        @ApiModelProperty("专辑介绍")
+        private String describe;
+
+        @ApiModelProperty("专辑封面")
+        private String coverImg;
+
+        @ApiModelProperty("平台价格")
+        private BigDecimal originalPrice;
+
+        @ApiModelProperty("机构价格")
+        private BigDecimal salePrice;
+
+        @ApiModelProperty("购买周期")
+        private Integer purchaseCycle;
+
+        @ApiModelProperty("原价")
+        private BigDecimal costPrice;
+
+        @ApiModelProperty("曲目相关信息")
+        private List<MusicSheetData> musicSheetData = new ArrayList<>();
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static TenantAlbum from(String json) {
+            return JSON.parseObject(json, TenantAlbum.class);
+        }
+    }
+
+    @ApiModel("声部模型")
+    @Data
+    public static class MusicSheetData {
+
+        @ApiModelProperty("声部类型")
+        @NotNull
+        private SubjectTypeEnum subjectType;
+
+        @ApiModelProperty("曲目列表")
+        private List<MusicObject> musicSheetList = new ArrayList<>();
+
+    }
+
+    @ApiModel("曲目对象")
+    @Data
+    public static class MusicObject {
+
+        @ApiModelProperty("曲目id")
+        private Long id;
+
+        @ApiModelProperty("类型")
+        private String type;
+
+        @ApiModelProperty("级别")
+        private String level;
+
+
+    }
+
+
+
+
+    @Data
+    public static class tenantAlbumMusics {
+        private Long id;
+        private Long tenantId;
+        private SubjectTypeEnum subjectType;
+        private Long tenantAlbumId;
+        private Long musicSheetId;
+        private Integer sortNumber;
+        private Boolean delFlag;
+        private Date updateTime;
+        private Date createTime;
+    }
+
+
+    @Data
+    @ApiModel("专辑启用/停用")
+    public static class UpdateStatus {
+
+        @ApiModelProperty("专辑ID")
+        @NotNull
+        private Long id;
+
+        @ApiModelProperty("启用/停用")
+        @NotNull
+        private Boolean status;
+    }
+
+}

+ 60 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/TenantInfoVo.java

@@ -0,0 +1,60 @@
+package com.yonge.cooleshow.admin.io.request;
+
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.Pattern;
+
+/**
+ * 机构表
+ * 2023-08-01 11:19:12
+ */
+@ApiModel(value = "TenantInfoVo对象", description = "机构表查询视图对象")
+public class TenantInfoVo {
+
+    @Data
+    @ApiModel(" TenantInfo-机构表")
+    public static class TenantInfo {
+
+        @ApiModelProperty("主键ID")
+        private Long id;
+
+        @ApiModelProperty("名称")
+        private String name;
+
+        @ApiModelProperty("logo")
+        private String logo;
+
+        @ApiModelProperty("简介")
+        private String briefIntroduction;
+
+        @ApiModelProperty("省份编码")
+        private Integer provinceCode;
+
+        @ApiModelProperty("城市编码")
+        private Integer cityCode;
+
+        @ApiModelProperty("地区/街道")
+        private Integer regionCode;
+
+        @ApiModelProperty("联系人")
+        @Length(min = 1, max = 8, message = "联系人字符最大8位")
+        private String username;
+
+        @ApiModelProperty("手机号")
+        @Pattern(regexp = "^1\\d{10}$", message = "手机号码格式错误")
+        private String phone;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static TenantInfo from(String json) {
+            return JSON.parseObject(json, TenantInfo.class);
+        }
+    }
+
+}

+ 433 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/coupon/CouponInfoVO.java

@@ -0,0 +1,433 @@
+package com.yonge.cooleshow.admin.io.request.coupon;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.MK;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponCategoryEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponValidTypeEnum;
+import com.yonge.cooleshow.common.enums.EStatus;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * 优惠券信息
+ * Created by Eric.Shang on 2022/9/2.
+ */
+public class CouponInfoVO {
+
+    /**
+     * 优惠券分页请求信息
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel("优惠券信息分页请求信息")
+    public static class PageRequest extends QueryInfo {
+
+        @ApiModelProperty(value = "优惠券ID", hidden = true)
+        private Long couponId;
+
+        @ApiModelProperty("优惠券名称")
+        private String name;
+
+        @ApiModelProperty("客户类型")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("优惠券类型 FULL_DISCOUNT(满减券) VOUCHER(代金券)")
+        private CouponTypeEnum couponType;
+
+        @ApiModelProperty("可用品类 UNIVERSAL(全场通用) VIP(小酷Ai) PIANO(云酷琴房) MALL(商场购物券) MUSIC(单曲点播券) ALBUM(专辑优惠券) SPARRING(陪练课购买券) LIVE(直播课购买券) ")
+        private CouponCategoryEnum category;
+
+        @ApiModelProperty("优惠券状态")
+        private Integer status;
+
+        @ApiModelProperty(value = "当前时间", hidden = true)
+        private Long timestamp;
+
+        @ApiModelProperty(value = "优惠券时间类型", hidden = true)
+        private CouponValidTypeEnum validType;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public String getName() {
+
+            return Optional.ofNullable(this.name)
+                    .filter(x -> StringUtils.isNotEmpty(x) && !x.matches(MK.EXP_INT)).orElse(null);
+        }
+
+        public Long getCouponId() {
+            if (StringUtils.isNotEmpty(this.name) && this.name.matches(MK.EXP_INT)) {
+                return Long.parseLong(this.name);
+            }
+            return couponId;
+        }
+
+        public void setStatus(Integer status) {
+
+            if (EStatus.ENABLE.match(status)) {
+                this.timestamp(DateTime.now().getMillis()).setValidType(CouponValidTypeEnum.DAY);
+            }
+            this.status = status;
+        }
+
+        public PageRequest timestamp(Long timestamp) {
+            this.timestamp = timestamp;
+            return this;
+        }
+    }
+
+    /**
+     * 优惠券分页响应数据
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel("优惠券信息分页响应信息")
+    public static class CouponPageInfo implements Serializable {
+
+        @ApiModelProperty("优惠券ID")
+        private Long id;
+
+        @ApiModelProperty("优惠券名称")
+        private String name;
+
+        @ApiModelProperty("描述")
+        private String describe;
+
+        @ApiModelProperty("客户端类型: TEACHER(老师端), STUDENT(学生端)")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("可用品类: UNIVERSAL(全场通用) VIP(小酷Ai) PIANO(云酷琴房) MALL(商场购物券) MUSIC(单曲点播券) SPARRING(陪练课购买券) LIVE(直播课购买券) VIDEO(视频课购买券) ")
+        private CouponCategoryEnum category;
+
+        @ApiModelProperty("优惠券类型: FULL_DISCOUNT(满减券) VOUCHER(代金券) ")
+        private CouponTypeEnum couponType;
+
+        @ApiModelProperty("当前库存量")
+        private Integer inventory;
+
+        @ApiModelProperty("领取次数限制")
+        private Integer quantityLimit;
+
+        @ApiModelProperty("状态")
+        private Integer status;
+
+        @ApiModelProperty("发放领取数")
+        private Integer issueNum;
+
+        @ApiModelProperty("关联奖品数")
+        private Integer rewardNum;
+
+        @ApiModelProperty("最后更新人")
+        private String updatedUser;
+
+        @ApiModelProperty(value = "最后更新时间", hidden = true)
+        private Long updateTime;
+
+        @ApiModelProperty("最后更新时间")
+        @JsonFormat(pattern = MK.TIME_PATTERN, timezone = MK.TIME_ZONE)
+        private Date updatedTime;
+
+        @ApiModelProperty("创建时间")
+        @JsonFormat(pattern = MK.TIME_PATTERN, timezone = MK.TIME_ZONE)
+        private Date createdTime;
+
+        public Date getUpdatedTime() {
+
+            if (Optional.ofNullable(getUpdateTime()).orElse(0L) > 0) {
+                return new DateTime(getUpdateTime()).toDate();
+            }
+            return updatedTime;
+        }
+    }
+
+    /**
+     * 优惠券详情信息
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class CouponQueryInfo implements Serializable {
+
+        @ApiModelProperty("优惠券ID")
+        private Long id;
+
+        @ApiModelProperty("优惠券名称")
+        private String name;
+
+        @ApiModelProperty("描述")
+        private String describe;
+
+        @ApiModelProperty("客户端类型: TEACHER(老师端), STUDENT(学生端)")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("可用品类: UNIVERSAL(全场通用) VIP(小酷Ai) " +
+                "PIANO(云酷琴房) MALL(商场购物券) MUSIC(单曲点播券) " +
+                "SPARRING(陪练课购买券) LIVE(直播课购买券) VIDEO(视频课购买券) " +
+                "VIDEO(视频课购买券)")
+        private CouponCategoryEnum category;
+
+        @ApiModelProperty("使用门槛")
+        private BigDecimal useLimit;
+
+        @ApiModelProperty("优惠金额")
+        private BigDecimal discountPrice;
+
+        @ApiModelProperty("优惠券类型")
+        private CouponTypeEnum couponType;
+
+        @ApiModelProperty("有效期类型: DAY(固定有效天数) TIME_PERIOD(固定时间段)")
+        private CouponValidTypeEnum validType;
+
+        @ApiModelProperty("有效天数")
+        private Integer validDay;
+
+        @ApiModelProperty("生效时间")
+        private Long startTime;
+
+        @ApiModelProperty("失效时间")
+        private Long endTime;
+
+        @ApiModelProperty("库存量")
+        private Integer inventory;
+
+        @ApiModelProperty("领取次数限制")
+        private Integer quantityLimit;
+
+        @ApiModelProperty("启禁状态")
+        private Integer status;
+
+        @ApiModelProperty("更新用户")
+        private Long updatedBy;
+
+        @ApiModelProperty("更新时间")
+        private Long updateTime;
+
+        @ApiModelProperty("创建用户")
+        private Long createdBy;
+
+        @ApiModelProperty("创建时间")
+        @JsonFormat(pattern = MK.TIME_PATTERN, timezone = MK.TIME_ZONE)
+        private Date createdTime;
+
+        public static CouponQueryInfo from(String recv) {
+            return JSON.parseObject(recv, CouponQueryInfo.class);
+        }
+    }
+
+    /**
+     * 新增或更新优惠券信息
+     */
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class CouponInfo implements Serializable {
+
+        @ApiModelProperty("优惠券ID")
+        private Long id;
+
+        @ApiModelProperty("优惠券名称")
+        private String name;
+
+        @ApiModelProperty("描述")
+        private String describe;
+
+        @ApiModelProperty("客户端类型: TEACHER(老师端), STUDENT(学生端)")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("可用品类: UNIVERSAL(全场通用) VIP(小酷Ai) PIANO(云酷琴房) MALL(商场购物券) MUSIC(单曲点播券) SPARRING(陪练课购买券) LIVE(直播课购买券) VIDEO(视频课购买券) ")
+        private CouponCategoryEnum category;
+
+        @ApiModelProperty("使用门槛")
+        private BigDecimal useLimit;
+
+        @ApiModelProperty("优惠金额")
+        private BigDecimal discountPrice;
+
+        @ApiModelProperty("优惠券类型: FULL_DISCOUNT(满减券) VOUCHER(代金券) ")
+        private CouponTypeEnum couponType;
+
+        @ApiModelProperty("有效期类型: DAY(固定有效天数) TIME_PERIOD(固定时间段)")
+        private CouponValidTypeEnum validType;
+
+        @ApiModelProperty("有效天数")
+        private Integer validDay;
+
+        @ApiModelProperty("生效时间")
+        private Long startTime;
+
+        @ApiModelProperty("失效时间")
+        private Long endTime;
+
+        @ApiModelProperty("库存量")
+        private Integer inventory;
+
+        @ApiModelProperty("领取次数限制")
+        private Integer quantityLimit;
+
+        @ApiModelProperty(value = "启禁状态, 0 停用 1 启用")
+        private Integer status;
+
+        @ApiModelProperty(value = "更新用户", hidden = true)
+        private Long updatedBy;
+
+        @ApiModelProperty(value = "更新时间", hidden = true)
+        private Long updateTime;
+
+        @ApiModelProperty(value = "创建用户", hidden = true)
+        private Long createdBy;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public boolean invalidRequestParam(Long userId) {
+
+            if (Objects.isNull(getId())) {
+
+                // 新增参数
+                if (StringUtils.isEmpty(getName())) {
+                    throw new BizException("优惠券名称不能为空");
+                }
+
+                if (Objects.isNull(getClientType())) {
+                    throw new BizException("客户端不能为空");
+                }
+
+                if (Objects.isNull(getCategory())) {
+                    throw new BizException("可用品类不能为空");
+                }
+
+                if (Objects.isNull(getCouponType())) {
+                    throw new BizException("优惠券类型不能为空");
+                }
+
+                /*if (CouponTypeEnum.FULL_DISCOUNT == getCouponType()
+                        && Optional.ofNullable(getUseLimit()).map(BigDecimal::intValue).orElse(0) <= 0) {
+                    throw new BizException("满减金额未设置");
+                }*/
+
+                if (Objects.isNull(getValidType())) {
+                    throw new BizException("有效期类型不能为空");
+                }
+
+                if (Optional.ofNullable(getValidDay()).orElse(0) <= 0
+                        && (Optional.ofNullable(getStartTime()).orElse(0L) == 0
+                            || Optional.ofNullable(getEndTime()).orElse(0L) == 0)) {
+                    throw new BizException("优惠券时间有效期不合法");
+                }
+
+                this.createdBy(userId).initSaveParam();
+            }
+            // 更新用户参数
+            this.updatedBy(userId).setUpdateTime(DateTime.now().getMillis());
+
+            return false;
+        }
+
+        public CouponInfo initSaveParam() {
+
+            return this.describe("")
+                    .useLimit(BigDecimal.ZERO)
+                    .discountPrice(BigDecimal.ZERO)
+                    .validDay(0)
+                    .startTime(0L)
+                    .endTime(0L)
+                    .inventory(0)
+                    .quantityLimit(0)
+                    .status(EStatus.DISABLE.getValue());
+        }
+
+        public CouponInfo describe(String describe) {
+            if (StringUtils.isEmpty(this.describe)) {
+                this.describe = describe;
+            }
+            return this;
+        }
+
+        public CouponInfo useLimit(BigDecimal useLimit) {
+            if (Objects.isNull(this.useLimit)) {
+                this.useLimit = useLimit;
+            }
+            return this;
+        }
+
+        public CouponInfo discountPrice(BigDecimal discountPrice) {
+            if (Objects.isNull(this.discountPrice)) {
+                this.discountPrice = discountPrice;
+            }
+            return this;
+        }
+
+        public CouponInfo validDay(Integer validDay) {
+            if (Objects.isNull(this.validDay)) {
+                this.validDay = validDay;
+            }
+            return this;
+        }
+
+        public CouponInfo startTime(Long startTime) {
+            if (Objects.isNull(this.startTime)) {
+                this.startTime = startTime;
+            }
+            return this;
+        }
+
+        public CouponInfo endTime(Long endTime) {
+            if (Objects.isNull(this.endTime)) {
+                this.endTime = endTime;
+            }
+            return this;
+        }
+
+        public CouponInfo inventory(Integer inventory) {
+            if (Objects.isNull(this.inventory)) {
+                this.inventory = inventory;
+            }
+            return this;
+        }
+
+        public CouponInfo quantityLimit(Integer quantityLimit) {
+            if (Objects.isNull(this.quantityLimit)) {
+                this.quantityLimit = quantityLimit;
+            }
+            return this;
+        }
+
+        public CouponInfo status(Integer status) {
+            this.status = status;
+            return this;
+        }
+
+        public CouponInfo createdBy(Long createdBy) {
+            this.createdBy = createdBy;
+            return this;
+        }
+
+        public CouponInfo updatedBy(Long updatedBy) {
+            this.updatedBy = updatedBy;
+            return this;
+        }
+
+    }
+}

+ 243 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/coupon/CouponInventoryVO.java

@@ -0,0 +1,243 @@
+package com.yonge.cooleshow.admin.io.request.coupon;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yonge.cooleshow.biz.dal.enums.MK;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponInventoryEnum;
+import com.yonge.cooleshow.common.enums.EStatus;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * 优惠券库存量
+ * Created by Eric.Shang on 2022/9/5.
+ */
+public class CouponInventoryVO {
+
+
+    /**
+     * 优惠券库存调整分页请求信息
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(value = "优惠券库存调整分页请求", description = "优惠券库存调整分页")
+    public static class PageRequest extends QueryInfo {
+
+        @ApiModelProperty("优惠券ID")
+        private Long couponId;
+
+        @ApiModelProperty("操作人")
+        private Long userId;
+
+        @ApiModelProperty("用户昵称或名称匹配")
+        private String keyword;
+
+        @ApiModelProperty("数据类型: ADDITION(添加) REDUCE(减少)")
+        private CouponInventoryEnum dataType;
+
+        @ApiModelProperty("开始时间, yyyy-MM-dd HH:mm:ss")
+        @DateTimeFormat(pattern = MK.TIME_PATTERN)
+        @JsonFormat(pattern = MK.TIME_PATTERN, timezone = MK.TIME_ZONE)
+        private Date startQueryTime;
+
+        @ApiModelProperty("结束时间, yyyy-MM-dd HH:mm:ss")
+        @DateTimeFormat(pattern = MK.TIME_PATTERN)
+        @JsonFormat(pattern = MK.TIME_PATTERN, timezone = MK.TIME_ZONE)
+        private Date endQueryTime;
+
+        @ApiModelProperty(value = "结束时间", hidden = true)
+        private Long startTime;
+        @ApiModelProperty(value = "结束时间", hidden = true)
+        private Long endTime;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public boolean invalidRequestParam() {
+
+            // 优惠券ID不能为空
+            return Optional.ofNullable(getCouponId()).orElse(0L) <= 0;
+        }
+
+        public Long getUserId() {
+
+            if (Optional.ofNullable(this.userId).orElse(0L) > 0) {
+                return this.userId;
+            }
+
+            return null;
+        }
+
+        public Long getStartTime() {
+            if (Objects.nonNull(getStartQueryTime())) {
+                return new DateTime(getStartQueryTime()).getMillis() / 1000;
+            }
+            return startTime;
+        }
+
+        public Long getEndTime() {
+            if (Objects.nonNull(getEndQueryTime())) {
+                return new DateTime(getEndQueryTime()).getMillis() / 1000;
+            }
+            return endTime;
+        }
+
+        public String getKeyword() {
+            if (StringUtils.isNotEmpty(this.keyword)) {
+                return keyword;
+            }
+            return null;
+        }
+    }
+
+    /**
+     * 库存量调整分页数据
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class PageInfo implements Serializable {
+
+        @ApiModelProperty("发放ID")
+        private Long id;
+
+        @ApiModelProperty("用户ID")
+        private Long userId;
+
+        @ApiModelProperty("操作人")
+        private String username;
+
+        @ApiModelProperty("优惠券ID")
+        private Long couponId;
+
+        @ApiModelProperty("数据类型: ADDITION(添加) REDUCE(减少)")
+        private CouponInventoryEnum dataType;
+
+        @ApiModelProperty("变化量")
+        private Integer number;
+
+        @ApiModelProperty("备注")
+        private String remark;
+
+        @ApiModelProperty("创建时间")
+        @JsonFormat(pattern = MK.TIME_PATTERN, timezone = MK.TIME_ZONE)
+        private Date createdTime;
+
+    }
+
+    /**
+     * 库存量调整记录
+     */
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class InventoryInfo implements Serializable {
+
+        @ApiModelProperty(value = "发放ID", hidden = true)
+        private Long id;
+
+        @ApiModelProperty(value = "用户ID", hidden = true)
+        private Long userId;
+
+        @ApiModelProperty("优惠券ID")
+        private Long couponId;
+
+        @ApiModelProperty("数据类型: ADDITION(添加) REDUCE(减少)")
+        private CouponInventoryEnum dataType;
+
+        @ApiModelProperty("变化量")
+        private Integer number;
+
+        @ApiModelProperty(value = "备注", hidden = true)
+        private String remark;
+
+        @ApiModelProperty(value = "启/禁状态", hidden = true)
+        private Integer status;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public boolean invalidRequestParam(Long userId) {
+
+            if (Optional.ofNullable(getCouponId()).orElse(0L) <= 0) {
+                throw new BizException("优惠券ID不能为空");
+            }
+
+            if (Objects.isNull(getDataType())) {
+                throw new BizException("类型不能为空");
+            }
+
+            if (Optional.ofNullable(getNumber()).orElse(0) <= 0) {
+                throw new BizException("变化量不能为空");
+            }
+
+            // 设置保存参数
+            this.userId(userId).initSaveParam();
+
+            return false;
+        }
+
+        public InventoryInfo initSaveParam() {
+
+            return this.remark("").status(EStatus.ENABLE.getValue());
+        }
+
+
+        public InventoryInfo id(Long id) {
+            this.id = id;
+            return this;
+        }
+
+        public InventoryInfo userId(Long userId) {
+            this.userId = userId;
+            return this;
+        }
+
+        public InventoryInfo remark(String remark) {
+            this.remark = remark;
+            return this;
+        }
+
+        public InventoryInfo status(Integer status) {
+            this.status = status;
+            return this;
+        }
+    }
+
+    /**
+     * 库存量调整用户分页数据
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class PageUserInfo implements Serializable {
+
+        @ApiModelProperty("用户ID")
+        private Long userId;
+
+        @ApiModelProperty("操作人")
+        private String username;
+
+        @ApiModelProperty("优惠券ID")
+        private Long couponId;
+
+    }
+}

部分文件因为文件数量过多而无法显示