liujc 1 år sedan
förälder
incheckning
efe7b8606a
100 ändrade filer med 4308 tillägg och 566 borttagningar
  1. 2 2
      audio-analysis/src/main/java/com/yonge/netty/dto/UserChannelContext.java
  2. 1 1
      audio-analysis/src/main/resources/logback-spring.xml
  3. 7 0
      cooleshow-api/pom.xml
  4. 17 0
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/AdminFeignService.java
  5. 16 0
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/TenantFeignService.java
  6. 115 0
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/dto/TenantWrapper.java
  7. 23 0
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/fallback/AdminFeignServiceFallback.java
  8. 16 0
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/fallback/TenantFeignServiceFallback.java
  9. 18 0
      cooleshow-auth/auth-api/pom.xml
  10. 10 0
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/LoginEntity.java
  11. 4 203
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/SysUser.java
  12. 95 0
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/WxConfigInfo.java
  13. 55 0
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/WxTemplateConfig.java
  14. 63 0
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/WxTemplateMessage.java
  15. 4 1
      cooleshow-auth/auth-server/pom.xml
  16. 14 10
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/config/WebSecurityConfig.java
  17. 3 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/filter/PhoneLoginAuthenticationFilter.java
  18. 15 8
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/handler/BaseAuthenticationFailureEvenHandler.java
  19. 147 82
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/provider/PhoneAuthenticationProvider.java
  20. 16 13
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/provider/service/DefaultUserDetailsService.java
  21. 9 8
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/SysUserDao.java
  22. 27 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/WxConfigInfoMapper.java
  23. 27 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/WxTemplateConfigMapper.java
  24. 27 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/WxTemplateMessageMapper.java
  25. 63 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/wrapper/WxConfigInfoWrapper.java
  26. 63 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/wrapper/WxTemplateConfigWrapper.java
  27. 63 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/wrapper/WxTemplateMessageWrapper.java
  28. 1 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/enums/EClientType.java
  29. 76 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/enums/ELoginType.java
  30. 50 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/MWxMpService.java
  31. 43 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/WxCacheService.java
  32. 113 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/domain/WxConfigStorageWrapper.java
  33. 25 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/domain/WxContentWrapper.java
  34. 51 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/handler/WxMessageRouteEvent.java
  35. 292 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/impl/MWxMpServiceImpl.java
  36. 115 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/impl/WxCacheServiceImpl.java
  37. 13 4
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/SysUserService.java
  38. 67 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/WxConfigInfoService.java
  39. 43 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/WxTemplateConfigService.java
  40. 43 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/WxTemplateMessageService.java
  41. 21 14
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/SysUserServiceImpl.java
  42. 145 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/WxConfigInfoServiceImpl.java
  43. 65 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/WxTemplateConfigServiceImpl.java
  44. 65 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/WxTemplateMessageServiceImpl.java
  45. 11 17
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/web/controller/TokenController.java
  46. 1 1
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/web/controller/UserController.java
  47. 38 0
      cooleshow-auth/auth-server/src/main/resources/config/mybatis/SysUserMapper.xml
  48. 35 0
      cooleshow-auth/auth-server/src/main/resources/config/mybatis/WxConfigInfoMapper.xml
  49. 25 0
      cooleshow-auth/auth-server/src/main/resources/config/mybatis/WxTemplateConfigMapper.xml
  50. 27 0
      cooleshow-auth/auth-server/src/main/resources/config/mybatis/WxTemplateMessageMapper.xml
  51. 1 1
      cooleshow-auth/auth-server/src/main/resources/logback-spring.xml
  52. 1 1
      cooleshow-bbs/src/main/resources/logback-spring.xml
  53. 1 1
      cooleshow-cms/src/main/resources/logback-spring.xml
  54. 4 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/AppConstant.java
  55. 10 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/SysConfigConstant.java
  56. 21 15
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/controller/BaseController.java
  57. 3 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/entity/BaseEntity.java
  58. 30 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/EActivationCode.java
  59. 35 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/EPaymentVersion.java
  60. 29 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/ESettlementFrom.java
  61. 32 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/ETenantUnBindAuditStatus.java
  62. 6 2
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/SysUserType.java
  63. 29 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/payment/EGoodsSource.java
  64. 56 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/payment/EGoodsType.java
  65. 25 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/payment/EOrderType.java
  66. 47 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/payment/EPaymentChannel.java
  67. 51 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/payment/EPaymentStatus.java
  68. 34 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/payment/EPaymentType.java
  69. 1 1
      cooleshow-gateway/gateway-web/src/main/resources/logback-spring.xml
  70. 1 1
      cooleshow-mall/mall-admin/src/main/resources/logback-spring.xml
  71. 1 1
      cooleshow-mall/mall-portal/src/main/resources/logback-spring.xml
  72. 19 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/jobs/TenantPersonStatTask.java
  73. 1 1
      cooleshow-task/src/main/resources/logback-spring.xml
  74. 1 0
      cooleshow-user/pom.xml
  75. 116 97
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/StudentController.java
  76. 124 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/SysAreaController.java
  77. 71 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/SysGoodsPriceController.java
  78. 5 4
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TeacherController.java
  79. 58 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantAccountRecordController.java
  80. 188 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantAlbumController.java
  81. 105 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantEntryRecordController.java
  82. 96 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantInfoController.java
  83. 72 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantUnbindRecordController.java
  84. 51 3
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/open/AdminClient.java
  85. 124 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/open/OpenSysAreaController.java
  86. 99 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/open/UserPaymentClient.java
  87. 168 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/SysAreaVo.java
  88. 126 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/TenantAlbumVo.java
  89. 69 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/TenantInfoVo.java
  90. 6 19
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/task/TaskController.java
  91. 1 1
      cooleshow-user/user-admin/src/main/resources/logback-spring.xml
  92. 4 0
      cooleshow-user/user-biz/pom.xml
  93. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/ImUserFriendDao.java
  94. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/StudentDao.java
  95. 33 46
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysMusicCompareRecordDao.java
  96. 20 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysMusicCompareWeekDataDao.java
  97. 13 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/TeacherDao.java
  98. 12 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/UserOrderDao.java
  99. 12 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/req/TeacherSubmitReq.java
  100. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/MusicSheetSearch.java

+ 2 - 2
audio-analysis/src/main/java/com/yonge/netty/dto/UserChannelContext.java

@@ -838,10 +838,10 @@ public class UserChannelContext {
 			totalTimes = chunkList.size();
 		}
 		
-		/*if (maxTimes * 100 / totalTimes < hardLevel.getIntegrityRange()) {
+		if (maxTimes * 100 / totalTimes < hardLevel.getIntegrityRange()) {
 			tempo = 1;
 			LOGGER.debug("节奏错误原因:信号分堆后的最大数量不足指定的完成比例");
-		}*/
+		}
 		
 		/**
 		for (int i = 0; i < chunkList.size(); i++) {

+ 1 - 1
audio-analysis/src/main/resources/logback-spring.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration scan="true" scanPeriod="10 seconds">
 
-	<property name="LOG_HOME" value="/mdata/logs/audio-analysis-%d{yyyy-MM-dd_HH}-%i.log" />
+	<property name="LOG_HOME" value="/mnt/datadisk/logs/audio-analysis-%d{yyyy-MM-dd_HH}-%i.log" />
 	<property name="CONSOLE_LOG_PATTERN"
 		value="[%X{username} %X{ip} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}] : %msg%n" />
 

+ 7 - 0
cooleshow-api/pom.xml

@@ -26,5 +26,12 @@
             <groupId>com.yonge.cooleshow</groupId>
             <artifactId>cooleshow-common</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-annotations</artifactId>
+            <version>1.5.20</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 </project>

+ 17 - 0
cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/AdminFeignService.java

@@ -5,6 +5,7 @@ import com.yonge.cooleshow.api.feign.dto.EmployeeApi;
 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.fallback.AdminFeignServiceFallback;
 import com.yonge.cooleshow.common.constant.AppConstant;
@@ -118,6 +119,22 @@ public interface AdminFeignService {
     @GetMapping(value = "/open/adminClient/getEmployee")
     HttpResponseResult<EmployeeApi> getEmployee(@RequestParam("userId") Long userId);
 
+    /**
+     * 机构信息
+     * @param tenantId 机构ID
+     * @return TenantWrapper.Tenant
+     */
+    @GetMapping(value = "/open/adminClient/getTenant")
+    HttpResponseResult<TenantWrapper.Tenant> getTenantInfo(@RequestParam("tenantId") Long tenantId);
+
+    /**
+     * 机构员工信息
+     * @param userId 用户ID
+     * @return TenantWrapper.Staff
+     */
+    @GetMapping(value = "/open/adminClient/getTenantStaff")
+    HttpResponseResult<TenantWrapper.Staff> getTenantStaff(@RequestParam("userId") Long userId);
+
 
     @PostMapping(value = "/open/adminClient/orderUpdate", consumes="application/json", produces="application/json")
     HttpResponseResult<Boolean> updateCouponOrderInfo(@RequestParam("couponIssueId") String couponIssueId,

+ 16 - 0
cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/TenantFeignService.java

@@ -0,0 +1,16 @@
+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)
+public interface TenantFeignService {
+
+    //机构人员汇总
+    @GetMapping(value = "/task/tenantPersonStat")
+    void tenantPersonStat();
+}

+ 115 - 0
cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/dto/TenantWrapper.java

@@ -0,0 +1,115 @@
+package com.yonge.cooleshow.api.feign.dto;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+
+/**
+ * 机构员工表
+ * 2023-07-21 17:32:49
+ */
+public class TenantWrapper implements Serializable {
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel("tenant - 机构表")
+    public static class Tenant implements Serializable {
+
+        @ApiModelProperty("主键ID")
+        private Long id;
+
+        @ApiModelProperty("名称")
+        private String name;
+
+        @ApiModelProperty("logo")
+        private String logo;
+
+        @ApiModelProperty("省份编码")
+        private Integer provinceCode;
+
+        @ApiModelProperty("城市编码")
+        private Integer cityCode;
+
+        @ApiModelProperty("地区/街道")
+        private Integer regionCode;
+
+        @ApiModelProperty("联系人")
+        private String username;
+
+        @ApiModelProperty("管理员ID,用户ID")
+        private Long userId;
+
+        @ApiModelProperty("手机号")
+        private String phone;
+
+        @ApiModelProperty("启用/冻结")
+        private Boolean enableFlag;
+
+        @ApiModelProperty("简介")
+        @TableField(value = "brief_introduction_")
+        private String briefIntroduction;
+
+        public static Tenant from(String json) {
+            return JSON.parseObject(json, Tenant.class);
+        }
+    }
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" TenantStaff-机构员工表")
+    public static class Staff implements Serializable {
+
+        @ApiModelProperty("主键ID")
+        private Long id;
+
+        @ApiModelProperty("机构ID")
+        private Long tenantId;
+
+        @ApiModelProperty("用户ID")
+        private Long userId;
+
+        @ApiModelProperty("头像")
+        private String avatar;
+
+        @ApiModelProperty("昵称")
+        private String nickname;
+
+        @ApiModelProperty("IM授权签名")
+        private String imToken;
+
+        @ApiModelProperty("微信ID")
+        private String wechatId;
+
+        @ApiModelProperty("微信OpenID")
+        private String wxOpenid;
+
+        @ApiModelProperty("公众号关注标识")
+        private Boolean subscribeFlag;
+
+        @ApiModelProperty("管理员标识")
+        private Boolean manageAdmin;
+
+        @ApiModelProperty("介绍")
+        private String introduction;
+
+        @ApiModelProperty("帐号状态(注销,冻结,激活)")
+        private String status;
+
+        public static Staff from(String json) {
+            return JSON.parseObject(json, Staff.class);
+        }
+    }
+
+}

+ 23 - 0
cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/fallback/AdminFeignServiceFallback.java

@@ -6,6 +6,7 @@ import com.yonge.cooleshow.api.feign.dto.EmployeeApi;
 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.common.entity.ContractDto;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
@@ -99,6 +100,28 @@ public class AdminFeignServiceFallback implements AdminFeignService {
         return null;
     }
 
+    /**
+     * 机构信息
+     *
+     * @param tenantId 机构ID
+     * @return TenantWrapper.Tenant
+     */
+    @Override
+    public HttpResponseResult<TenantWrapper.Tenant> getTenantInfo(Long tenantId) {
+        return null;
+    }
+
+    /**
+     * 机构员工信息
+     *
+     * @param userId 用户ID
+     * @return TenantWrapper.Staff
+     */
+    @Override
+    public HttpResponseResult<TenantWrapper.Staff> getTenantStaff(Long userId) {
+        return null;
+    }
+
     @Override
     public HttpResponseResult<Boolean> updateCouponOrderInfo(String couponIssueId, Boolean returnCoupon, String orderNo) {
         return null;

+ 16 - 0
cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/fallback/TenantFeignServiceFallback.java

@@ -0,0 +1,16 @@
+package com.yonge.cooleshow.api.feign.fallback;
+
+import com.yonge.cooleshow.api.feign.TenantFeignService;
+
+/**
+ * Description
+ *
+ * @author liujunchi
+ * @date 2022-05-06
+ */
+public class TenantFeignServiceFallback implements TenantFeignService {
+
+    @Override
+    public void tenantPersonStat() {
+    }
+}

+ 18 - 0
cooleshow-auth/auth-api/pom.xml

@@ -33,5 +33,23 @@
 			<groupId>com.yonge.cooleshow</groupId>
 			<artifactId>cooleshow-common</artifactId>
 		</dependency>
+		<dependency>
+			<groupId>com.yonge.cooleshow</groupId>
+			<artifactId>cooleshow-common</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-openfeign-core</artifactId>
+			<version>2.1.1.RELEASE</version>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>com.yonge.toolset</groupId>
+			<artifactId>utils</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.yonge.toolset</groupId>
+			<artifactId>utils</artifactId>
+		</dependency>
 	</dependencies>
 </project>

+ 10 - 0
cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/LoginEntity.java

@@ -20,6 +20,8 @@ public class LoginEntity {
     private String qrCode;
     //关联帐号授权码
     private String authToken;
+    // 登录类型
+    private String loginType;
     
     public Boolean getIsSurportRegister() {
 		return isSurportRegister;
@@ -92,4 +94,12 @@ public class LoginEntity {
     public void setAuthToken(String authToken) {
         this.authToken = authToken;
     }
+
+    public String getLoginType() {
+        return loginType;
+    }
+
+    public void setLoginType(String loginType) {
+        this.loginType = loginType;
+    }
 }

+ 4 - 203
cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/SysUser.java

@@ -6,12 +6,14 @@ import java.io.Serializable;
 import java.util.Date;
 import java.util.List;
 
+import lombok.Data;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 
 /**
  * 对应数据库表(sys_user):
  */
+@Data
 public class SysUser implements Serializable{
 
 	/**
@@ -103,137 +105,8 @@ public class SysUser implements Serializable{
 
 	private String certificateType = "IDENTITY";
 
-	public String getCertificateType() {
-		return certificateType;
-	}
-
-	public void setCertificateType(String certificateType) {
-		this.certificateType = certificateType;
-	}
-
-	public String getRealName() {
-		return realName;
-	}
-
-	public void setRealName(String realName) {
-		this.realName = realName;
-	}
-
-	public String getImToken() {
-		return imToken;
-	}
-
-	public void setImToken(String imToken) {
-		this.imToken = imToken;
-	}
-
-	public Long getId() {
-		return id;
-	}
-
-	public void setId(Long id) {
-		this.id = id;
-	}
-
-	public void setUsername(String username) {
-		this.username = username;
-	}
-
-	public String getUsername() {
-		return this.username;
-	}
-
-	public void setPassword(String password) {
-		this.password = password;
-	}
-
-	public String getPassword() {
-		return this.password;
-	}
-
-	public void setSalt(String salt) {
-		this.salt = salt;
-	}
-
-	public String getSalt() {
-		return this.salt;
-	}
-
-	public void setPhone(String phone) {
-		this.phone = phone;
-	}
-
-	public String getPhone() {
-		return this.phone;
-	}
-
-	public void setAvatar(String avatar) {
-		this.avatar = avatar;
-	}
-
-	public String getAvatar() {
-		return this.avatar;
-	}
-
-	public void setCreateTime(java.util.Date createTime) {
-		this.createTime = createTime;
-	}
-
-	public java.util.Date getCreateTime() {
-		return this.createTime;
-	}
-
-	public void setUpdateTime(java.util.Date updateTime) {
-		this.updateTime = updateTime;
-	}
-
-	public java.util.Date getUpdateTime() {
-		return this.updateTime;
-	}
-
-	public Integer getLockFlag() {
-		return lockFlag;
-	}
-
-	public void setLockFlag(Integer lockFlag) {
-		this.lockFlag = lockFlag;
-	}
-
-	public Boolean getSuperAdmin() {
-		return isSuperAdmin;
-	}
-
-	public void setSuperAdmin(Boolean superAdmin) {
-		isSuperAdmin = superAdmin;
-	}
-
-	public Boolean getDelFlag() {
-		return delFlag;
-	}
-
-	public void setDelFlag(Boolean delFlag) {
-		this.delFlag = delFlag;
-	}
-
-	public void setWxOpenid(String wxOpenid) {
-		this.wxOpenid = wxOpenid;
-	}
-
-	public String getWxOpenid() {
-		return this.wxOpenid;
-	}
-
-	public void setQqOpenid(String qqOpenid) {
-		this.qqOpenid = qqOpenid;
-	}
-
-	public String getQqOpenid() {
-		return this.qqOpenid;
-	}
-
-	public String getUserType() {
-		return userType;
-	}
+	@ApiModelProperty(value = "机构编号")
+	private Long tenantId;
 
 	public void setUserType(String userType) {
 		if(StringUtils.isNotEmpty(userType) && userType.startsWith(",")){
@@ -242,78 +115,6 @@ public class SysUser implements Serializable{
 		this.userType = userType;
 	}
 
-	public Integer getGender() {
-		return gender;
-	}
-
-	public void setGender(Integer gender) {
-		this.gender = gender;
-	}
-
-	public String getNation() {
-		return nation;
-	}
-
-	public void setNation(String nation) {
-		this.nation = nation;
-	}
-
-	public Date getBirthdate() {
-		return birthdate;
-	}
-
-	public void setBirthdate(Date birthdate) {
-		this.birthdate = birthdate;
-	}
-
-	public String getEmail() {
-		return email;
-	}
-
-	public void setEmail(String email) {
-		this.email = email;
-	}
-
-	public String getIdCardNo() {
-		return idCardNo;
-	}
-
-	public void setIdCardNo(String idCardNo) {
-		this.idCardNo = idCardNo;
-	}
-
-	public String getWechatId() {
-		return wechatId;
-	}
-
-	public void setWechatId(String wechatId) {
-		this.wechatId = wechatId;
-	}
-
-	public Boolean getIsSuperAdmin() {
-		return isSuperAdmin;
-	}
-
-	public void setIsSuperAdmin(Boolean isSuperAdmin) {
-		this.isSuperAdmin = isSuperAdmin;
-	}
-
-	public List<Long> getRoles() {
-		return roles;
-	}
-
-	public void setRoles(List<Long> roles) {
-		this.roles = roles;
-	}
-
-	public Date getLastUsernameTime() {
-		return lastUsernameTime;
-	}
-
-	public void setLastUsernameTime(Date lastUsernameTime) {
-		this.lastUsernameTime = lastUsernameTime;
-	}
-
 	@Override
 	public String toString() {
 		return ToStringBuilder.reflectionToString(this);

+ 95 - 0
cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/WxConfigInfo.java

@@ -0,0 +1,95 @@
+package com.yonge.cooleshow.auth.api.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 微信配置信息
+ * 2023-02-01 14:21:57
+ */
+@Data
+@ApiModel(" WxConfigInfo-微信配置信息")
+@TableName("wx_config_info")
+public class WxConfigInfo implements Serializable {
+
+    @ApiModelProperty("主键标识")
+    @TableId(value = "id")
+    private Long id;
+
+    @ApiModelProperty("公众号名称")
+	@TableField(value = "mp_name")
+    private String mpName;
+
+    @ApiModelProperty("公众号ID")
+	@TableField(value = "appid")
+    private String appid;
+
+    @ApiModelProperty("接入密钥")
+	@TableField(value = "secret")
+    private String secret;
+
+    @ApiModelProperty("消息密钥")
+	@TableField(value = "token")
+    private String token;
+
+    @ApiModelProperty("加密模式密钥")
+	@TableField(value = "aeskey")
+    private String aeskey;
+
+    @ApiModelProperty("关注公众号提示信息")
+	@TableField(value = "content")
+    private String content;
+
+    @ApiModelProperty("商户ID")
+	@TableField(value = "merchant_id")
+    private String merchantId;
+
+    @ApiModelProperty("商户密钥")
+	@TableField(value = "merchant_key")
+    private String merchantKey;
+
+    @ApiModelProperty("微信帐单回调")
+	@TableField(value = "notify_url")
+    private String notifyUrl;
+
+    @ApiModelProperty("交易类型")
+	@TableField(value = "trade_type")
+    private String tradeType;
+
+    @ApiModelProperty("签名类型")
+	@TableField(value = "sign_type")
+    private String signType;
+
+    @ApiModelProperty("关注跳转地址")
+	@TableField(value = "subscribe_url")
+    private String subscribeUrl;
+
+    @ApiModelProperty("关联公众号")
+	@TableField(value = "mp_app_id")
+    private String mpAppId;
+
+    @ApiModelProperty("公众号类型")
+	@TableField(value = "mp_type")
+    private Integer mpType;
+
+    @ApiModelProperty("全局标识")
+	@TableField(value = "is_global")
+    private Boolean isGlobal;
+
+    @ApiModelProperty("状态")
+	@TableField(value = "status")
+    private Boolean status;
+
+    @ApiModelProperty("创建时间")
+	@TableField(value = "create_time")
+    private Date createTime;
+
+}

+ 55 - 0
cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/WxTemplateConfig.java

@@ -0,0 +1,55 @@
+package com.yonge.cooleshow.auth.api.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 微信模板配置
+ * 2023-02-01 14:21:57
+ */
+@Data
+@ApiModel(" WxTemplateConfig-微信模板配置")
+@TableName("wx_template_config")
+public class WxTemplateConfig implements Serializable {
+
+    @ApiModelProperty("主键")
+    @TableId(value = "id")
+    private Long id;
+
+    @ApiModelProperty("微信公众号")
+	@TableField(value = "appid")
+    private String appid;
+
+    @ApiModelProperty("消息指令")
+	@TableField(value = "command")
+    private String command;
+
+    @ApiModelProperty("微信模板id")
+	@TableField(value = "wx_template_id")
+    private String wxTemplateId;
+
+    @ApiModelProperty("模板消息地址")
+	@TableField(value = "url")
+    private String url;
+
+    @ApiModelProperty("描述")
+	@TableField(value = "description")
+    private String description;
+
+    @ApiModelProperty("状态")
+	@TableField(value = "status")
+    private Boolean status;
+
+    @ApiModelProperty("创建时间")
+	@TableField(value = "create_time")
+    private Date createTime;
+
+}

+ 63 - 0
cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/WxTemplateMessage.java

@@ -0,0 +1,63 @@
+package com.yonge.cooleshow.auth.api.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 微信模板消息内容
+ * 2023-02-01 14:21:57
+ */
+@Data
+@ApiModel(" WxTemplateMessage-微信模板消息内容")
+@TableName("wx_template_message")
+public class WxTemplateMessage implements Serializable {
+
+    @ApiModelProperty("主键列")
+    @TableId(value = "id")
+    private Long id;
+
+    @ApiModelProperty("应用标识")
+	@TableField(value = "appid")
+    private String appid;
+
+    @ApiModelProperty("指令")
+	@TableField(value = "command")
+    private String command;
+
+    @ApiModelProperty("内容")
+	@TableField(value = "content")
+    private String content;
+
+    @ApiModelProperty("标题")
+	@TableField(value = "title")
+    private String title;
+
+    @ApiModelProperty("版本")
+	@TableField(value = "version")
+    private Integer version;
+
+    @ApiModelProperty("类型WECHAT;APP")
+	@TableField(value = "type")
+    private String type;
+
+    @ApiModelProperty("描述")
+	@TableField(value = "description")
+    private String description;
+
+    @ApiModelProperty("状态")
+	@TableField(value = "status")
+    private Boolean status;
+
+    @ApiModelProperty("创建时间")
+	@TableField(value = "create_time")
+    private Date createTime;
+
+}

+ 4 - 1
cooleshow-auth/auth-server/pom.xml

@@ -8,7 +8,6 @@
         <artifactId>cooleshow-auth</artifactId>
         <version>1.0</version>
     </parent>
-    <groupId>com.yonge.cooleshow</groupId>
     <artifactId>auth-server</artifactId>
     <version>1.0</version>
     <name>auth-server</name>
@@ -23,6 +22,10 @@
             <artifactId>microsvc-config-jwt</artifactId>
         </dependency>
         <dependency>
+            <groupId>com.microsvc.toolkit.middleware</groupId>
+            <artifactId>microsvc-middleware-wechat</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.springframework.security</groupId>
             <artifactId>spring-security-jwt</artifactId>
             <version>1.0.9.RELEASE</version>

+ 14 - 10
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/config/WebSecurityConfig.java

@@ -1,5 +1,15 @@
 package com.yonge.cooleshow.auth.config;
 
+import com.yonge.cooleshow.auth.core.filter.PhoneLoginAuthenticationFilter;
+import com.yonge.cooleshow.auth.core.filter.UsernameAuthenticationFilter;
+import com.yonge.cooleshow.auth.core.handler.BaseAuthenticationFailureEvenHandler;
+import com.yonge.cooleshow.auth.core.handler.BaseAuthenticationSuccessEventHandler;
+import com.yonge.cooleshow.auth.core.provider.PhoneAuthenticationProvider;
+import com.yonge.cooleshow.auth.core.provider.service.DefaultUserDetailsService;
+import com.yonge.cooleshow.auth.middleware.wechat.WxCacheService;
+import com.yonge.cooleshow.auth.service.SysUserDeviceService;
+import com.yonge.cooleshow.auth.service.SysUserService;
+import com.yonge.cooleshow.common.service.IdGeneratorService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -15,16 +25,6 @@ import org.springframework.security.crypto.factory.PasswordEncoderFactories;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
 
-import com.yonge.cooleshow.auth.core.filter.PhoneLoginAuthenticationFilter;
-import com.yonge.cooleshow.auth.core.filter.UsernameAuthenticationFilter;
-import com.yonge.cooleshow.auth.core.handler.BaseAuthenticationFailureEvenHandler;
-import com.yonge.cooleshow.auth.core.handler.BaseAuthenticationSuccessEventHandler;
-import com.yonge.cooleshow.auth.core.provider.PhoneAuthenticationProvider;
-import com.yonge.cooleshow.auth.core.provider.service.DefaultUserDetailsService;
-import com.yonge.cooleshow.auth.service.SysUserDeviceService;
-import com.yonge.cooleshow.auth.service.SysUserService;
-import com.yonge.cooleshow.common.service.IdGeneratorService;
-
 @Configuration
 @EnableWebSecurity
 @EnableGlobalMethodSecurity(prePostEnabled = true)//会拦截注解了@PreAuthrize注解的配置.
@@ -48,6 +48,9 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 	@Autowired
 	private SysUserDeviceService sysUserDeviceService;
 
+	@Autowired
+	private WxCacheService wxCacheService;
+
 	@Override
 	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 		auth.authenticationProvider(daoAuthenticationProvider());
@@ -110,6 +113,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
         provider.setSmsCodeService(smsCodeService);
         provider.setSysUserService(sysUserService);
         provider.setSysUserDeviceService(sysUserDeviceService);
+		provider.setWxCacheService(wxCacheService);
 		// 禁止隐藏用户未找到异常
 		provider.setHideUserNotFoundExceptions(false);
         return provider;

+ 3 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/filter/PhoneLoginAuthenticationFilter.java

@@ -26,6 +26,7 @@ public class PhoneLoginAuthenticationFilter extends AbstractAuthenticationProces
 	private static final String LOGIN_USER_TYPE = "loginUserType";
 	private static final String QR_CODE = "qrCode";
 	private static final String AUTH_TOKEN = "token";
+	private static final String LOGIN_TYPE = "loginType";
 
 	private static final String DEVICE_NUM = "deviceNum";
 
@@ -51,6 +52,7 @@ public class PhoneLoginAuthenticationFilter extends AbstractAuthenticationProces
 		String loginUserType = obtainParameter(request, LOGIN_USER_TYPE);
 		String qrCode = obtainParameter(request, QR_CODE);
 		String authToken = obtainParameter(request, AUTH_TOKEN);
+		String loginType = obtainParameter(request, LOGIN_TYPE);
 
 		String clientId = request.getParameter(clientIdParameter).toUpperCase();
 
@@ -71,6 +73,7 @@ public class PhoneLoginAuthenticationFilter extends AbstractAuthenticationProces
 		loginEntity.setDeviceNum(deviceNum);
 		loginEntity.setQrCode(qrCode);
 		loginEntity.setAuthToken(authToken);
+		loginEntity.setLoginType(loginType);
 
 		authRequest = new PhoneAuthenticationToken(SecurityConstants.PHONE_PRINCIPAL_PREFIX + principal, loginEntity);
 

+ 15 - 8
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/handler/BaseAuthenticationFailureEvenHandler.java

@@ -1,10 +1,7 @@
 package com.yonge.cooleshow.auth.core.handler;
 
-import java.io.IOException;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import org.apache.http.HttpStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -13,8 +10,9 @@ import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler;
 import org.springframework.stereotype.Component;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
 
 @Component
 public class BaseAuthenticationFailureEvenHandler extends ExceptionMappingAuthenticationFailureHandler {
@@ -30,6 +28,8 @@ public class BaseAuthenticationFailureEvenHandler extends ExceptionMappingAuthen
     	int resultCode = HttpStatus.SC_CONFLICT;
     	
         String message = exception.getLocalizedMessage();
+
+        String data = null;
         if (message.equals("Bad credentials")) {
             message = "用户名或密码错误";
         }else if(message.equals("User is disabled")){
@@ -37,9 +37,16 @@ public class BaseAuthenticationFailureEvenHandler extends ExceptionMappingAuthen
         }else if(message.equals("404.9")){
         	message = "用户名或密码错误";
         	resultCode = 99;
+        } else if (message.startsWith("MA:404:")) {
+            // 返回用户绑定openId
+            data = message.split(":")[2];
+            // 用户未绑定openId错误码
+            resultCode = 5001;
+            // 用户未绑定openId错误信息
+            message = "用户未绑定小程序账号";
         }
         logger.info("登录失败,异常:{}", message);
-        HttpResponseResult result = new HttpResponseResult(false, resultCode, null, message);
+        HttpResponseResult result = new HttpResponseResult(false, resultCode, data, message);
         response.setContentType("application/json; charset=utf-8");
         response.getWriter().write(objectMapper.writeValueAsString(result));
     }

+ 147 - 82
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/provider/PhoneAuthenticationProvider.java

@@ -1,14 +1,20 @@
 package com.yonge.cooleshow.auth.core.provider;
 
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
+import com.alibaba.fastjson.JSON;
 import com.microsvc.toolkit.config.jwt.utils.RsaKeyHelper;
+import com.microsvc.toolkit.middleware.wechat.WxServiceManager;
 import com.yonge.cooleshow.auth.api.dto.SysUserInfo;
 import com.yonge.cooleshow.auth.api.entity.LoginEntity;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.config.token.PhoneAuthenticationToken;
+import com.yonge.cooleshow.auth.enums.ELoginType;
+import com.yonge.cooleshow.auth.middleware.wechat.WxCacheService;
 import com.yonge.cooleshow.auth.service.SysUserDeviceService;
 import com.yonge.cooleshow.auth.service.SysUserService;
+import com.yonge.cooleshow.common.security.SecurityConstants;
 import com.yonge.cooleshow.common.service.IdGeneratorService;
-import com.yonge.toolset.base.exception.BizException;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.security.authentication.BadCredentialsException;
@@ -27,6 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
 import java.security.interfaces.RSAPublicKey;
 import java.util.Date;
 import java.util.Objects;
+
 @Slf4j
 public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider {
 
@@ -38,6 +45,8 @@ public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider
 
     private SysUserDeviceService sysUserDeviceService;
 
+    private WxCacheService wxCacheService;
+
     @Override
     protected void additionalAuthenticationChecks(UserDetails userDetails, Authentication authentication) throws AuthenticationException {
         if (authentication.getCredentials() == null) {
@@ -59,111 +68,163 @@ public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider
         String qrCode = loginEntity.getQrCode();
         // 授权Token登录
         String authToken = loginEntity.getAuthToken();
-        if (StringUtils.isNotEmpty(qrCode)) {
-            // 二维码验证
-            boolean b = sysUserService.verifyQrCode(phone, qrCode);
-            if (!b) {
-                throw new BadCredentialsException("二维码校验失败");
+        // 用户登陆方式
+        ELoginType loginType = ELoginType.get(loginEntity.getLoginType());
+
+        if (ELoginType.WECHAT_MA == loginType) {
+            // 小程序登陆
+            // 根据小程序code获取openId;查询用户是否存在
+            // 查询配置信息, keyword =>小程序apppid
+            WxMaService wxMaService = WxServiceManager.getInstance().getWxMaService(phone, wxCacheService);
+            if (wxMaService == null) {
+                log.warn("genRequestAuthorityTokenInfo WX_APPID, appid={}, jscode={}", phone, smsCode);
+                throw new BadCredentialsException("小程序授权失败,请联系管理员");
             }
-        } else if (StringUtils.isNotEmpty(authToken)) {
-            // 授权authToken登录
+
+            String openid;
             try {
-                RSAPublicKey rsaPublicKey = RsaKeyHelper.getRSAPublicKey("jmedu", "dayaedu", "jmedu.jks", "dayaedu");
-                Jwt jwt = JwtHelper.decodeAndVerify(authToken, new RsaVerifier(rsaPublicKey));
+                // 校验请求jscode的合法
+                WxMaJscode2SessionResult sessionret = wxMaService.getUserService().getSessionInfo(smsCode);
 
-                //获取jwt原始内容
-                String claims = jwt.getClaims();
-                if (StringUtils.isEmpty(claims)) {
-                    throw new BizException("三方授权校验失败");
+                if (StringUtils.isAnyBlank(sessionret.getOpenid(), sessionret.getSessionKey())) {
+                    log.warn("genRequestAuthorityTokenInfo JSCODE, ret={}", JSON.toJSONString(sessionret));
+                    throw new BadCredentialsException("小程序授权失败,请重新授权");
                 }
-                log.info("retrieveUser claims={}", claims);
+                // 用户openid
+                openid = sessionret.getOpenid();
+
             } catch (Exception e) {
-                log.error("retrieveUser authToken={}", authToken, e);
+                log.error("genRequestAuthorityTokenInfo WX_OAUTH2, appid={}, jscode={}", phone, smsCode, e);
+                throw new BadCredentialsException("小程序授权已失效,请重新登陆");
             }
 
-        } else {
-            // 验证码验证
-            boolean b = smsCodeService.verifyValidCode(phone, smsCode, "SMS_VERIFY_CODE_LOGIN");
-            if (!b) {
-                throw new BadCredentialsException("验证码校验失败");
+            String clientId = loginEntity.getClientId();
+            String deviceNum = loginEntity.getDeviceNum();
+            // 根据用户授权openid,查询机构员工绑定信息
+            SysUser sysUser = sysUserService.getSysUserByOpenId(openid, clientId);
+            if (Objects.isNull(sysUser)) {
+                throw new UsernameNotFoundException("MA:404:" + openid);
             }
-        }
-
-        String clientId = loginEntity.getClientId();
-        Boolean isRegister = loginEntity.getIsSurportRegister();
-        String loginUserType = loginEntity.getLoginUserType();
-        String deviceNum = loginEntity.getDeviceNum();
 
-        SysUserInfo userInfo = sysUserService.queryUserInfoByPhone(phone);
+            // 重置登陆账号信息
+            username = SecurityConstants.PHONE_PRINCIPAL_PREFIX + sysUser.getPhone();
 
-        if (userInfo == null) {
-            if (isRegister == false || StringUtils.equals("SYSTEM", clientId)) {
-                throw new LockedException("用户不存在");
+            // 绑定设备
+            if (StringUtils.isNotBlank(deviceNum)) {
+                sysUserDeviceService.bindDevice(clientId, sysUser.getId(), deviceNum);
             }
 
-            userInfo = sysUserService.registerUser(loginEntity.getPhone(), clientId, loginUserType);
+        } else {
 
-            if (Objects.nonNull(userInfo.getSysUser())) {
-                // 自动添加系统默认IM帐号为好友,并自动发送通知消息
-                sysUserService.sendSysCustomerServiceFriendMessage(userInfo.getSysUser(), clientId.toUpperCase());
-            }
+            // 其他登陆方式
+            if (StringUtils.isNotEmpty(qrCode)) {
+                // 二维码验证
+                boolean b = sysUserService.verifyQrCode(phone, qrCode);
+                if (!b) {
+                    throw new BadCredentialsException("二维码校验失败");
+                }
+            } else if (StringUtils.isNotEmpty(authToken)) {
+                // 授权authToken登录
+                try {
+                    RSAPublicKey rsaPublicKey = RsaKeyHelper.getRSAPublicKey("jmedu", "dayaedu", "jmedu.jks", "dayaedu");
+                    Jwt jwt = JwtHelper.decodeAndVerify(authToken, new RsaVerifier(rsaPublicKey));
 
-            if (StringUtils.isNotBlank(deviceNum)) {
-                sysUserDeviceService.bindDevice(clientId, userInfo.getSysUser().getId(), deviceNum);
-            }
-        } else {
-            SysUser user = userInfo.getSysUser();
-            if (user == null) {
-                throw new LockedException("用户不存在");
-            }
-            if (user.getLockFlag() == 1) {
-                throw new LockedException("用户已锁定");
-            }
+                    //获取jwt原始内容
+                    String claims = jwt.getClaims();
+                    if (StringUtils.isEmpty(claims)) {
+                        throw new BadCredentialsException("三方授权校验失败");
+                    }
+                    log.info("retrieveUser claims={}", claims);
+                } catch (Exception e) {
+                    log.error("retrieveUser authToken={}", authToken, e);
+                }
 
-            if (StringUtils.isNotBlank(deviceNum)) {
-                sysUserDeviceService.bindDevice(clientId, user.getId(), deviceNum);
-            }
-            //登录
-            if (userInfo.getSysUser().getUserType().contains(clientId)){
-                return login(username);
-            }
-            //官网登录
-            if(StringUtils.isNotEmpty(loginUserType) && userInfo.getSysUser().getUserType().contains(loginUserType)){
-                return login(username);
+            } else {
+                // 验证码验证
+                boolean b = smsCodeService.verifyValidCode(phone, smsCode, "SMS_VERIFY_CODE_LOGIN");
+                if (!b) {
+                    throw new BadCredentialsException("验证码校验失败");
+                }
             }
 
-            /**********************************注册*********************************************/
-            //不能注册的
-            if(isRegister == false || StringUtils.equals("SYSTEM", clientId)){
-                throw new LockedException("用户不存在");
-            }
+            String clientId = loginEntity.getClientId();
+            Boolean isRegister = loginEntity.getIsSurportRegister();
+            String loginUserType = loginEntity.getLoginUserType();
+            String deviceNum = loginEntity.getDeviceNum();
+
+            SysUserInfo userInfo = sysUserService.queryUserInfoByPhone(phone);
+
+            if (userInfo == null) {
+                if (isRegister == false || StringUtils.equals("SYSTEM", clientId)) {
+                    throw new LockedException("用户不存在");
+                }
+
+                userInfo = sysUserService.registerUser(loginEntity.getPhone(), clientId, loginUserType);
+
+                if (Objects.nonNull(userInfo.getSysUser())) {
+                    // 自动添加系统默认IM帐号为好友,并自动发送通知消息
+                    sysUserService.sendSysCustomerServiceFriendMessage(userInfo.getSysUser(), clientId.toUpperCase());
+                }
+
+                if (StringUtils.isNotBlank(deviceNum)) {
+                    sysUserDeviceService.bindDevice(clientId, userInfo.getSysUser().getId(), deviceNum);
+                }
+            } else {
+                SysUser user = userInfo.getSysUser();
+                if (user == null) {
+                    throw new LockedException("用户不存在");
+                }
+                if (user.getLockFlag() == 1) {
+                    throw new LockedException("用户已锁定");
+                }
+
+                if (StringUtils.isNotBlank(deviceNum)) {
+                    sysUserDeviceService.bindDevice(clientId, user.getId(), deviceNum);
+                }
+                //登录
+                if (userInfo.getSysUser().getUserType().contains(clientId)){
+                    return login(username);
+                }
+                //官网登录
+                if(StringUtils.isNotEmpty(loginUserType) && userInfo.getSysUser().getUserType().contains(loginUserType)){
+                    return login(username);
+                }
 
-            user.setUpdateTime(new Date());
-            if(StringUtils.isNotEmpty(loginUserType)){
-                if (StringUtils.equalsIgnoreCase(loginUserType, "TEACHER")) {
-                    user.setUserType(user.getUserType() + "," + loginUserType);
-                    sysUserService.saveTeacher(user);
-                } else if (StringUtils.equalsIgnoreCase(loginUserType, "STUDENT")) {
-                    user.setUserType(user.getUserType() + "," + loginUserType);
-                    sysUserService.saveStudent(user);
-                }else {
+                /**********************************注册*********************************************/
+                //不能注册的
+                if(isRegister == false || StringUtils.equals("SYSTEM", clientId)){
                     throw new LockedException("用户不存在");
                 }
-            }else if(StringUtils.isNotEmpty(clientId)){
-                if (StringUtils.equalsIgnoreCase(clientId, "TEACHER")) {
-                    user.setUserType(user.getUserType() + "," + clientId);
-                    sysUserService.saveTeacher(user);
-                } else if (StringUtils.equalsIgnoreCase(clientId, "STUDENT")) {
-                    user.setUserType(user.getUserType() + "," + clientId);
-                    sysUserService.saveStudent(user);
-                } else {
+
+                user.setUpdateTime(new Date());
+                if(StringUtils.isNotEmpty(loginUserType)){
+                    if (StringUtils.equalsIgnoreCase(loginUserType, "TEACHER")) {
+                        user.setUserType(user.getUserType() + "," + loginUserType);
+                        sysUserService.saveTeacher(user);
+                    } else if (StringUtils.equalsIgnoreCase(loginUserType, "STUDENT")) {
+                        user.setUserType(user.getUserType() + "," + loginUserType);
+                        sysUserService.saveStudent(user);
+                    }else {
+                        throw new LockedException("用户不存在");
+                    }
+                }else if(StringUtils.isNotEmpty(clientId)){
+                    if (StringUtils.equalsIgnoreCase(clientId, "TEACHER")) {
+                        user.setUserType(user.getUserType() + "," + clientId);
+                        sysUserService.saveTeacher(user);
+                    } else if (StringUtils.equalsIgnoreCase(clientId, "STUDENT")) {
+                        user.setUserType(user.getUserType() + "," + clientId);
+                        sysUserService.saveStudent(user);
+                    } else {
+                        throw new LockedException("用户不存在");
+                    }
+                }else{
                     throw new LockedException("用户不存在");
                 }
-            }else{
-                throw new LockedException("用户不存在");
+                sysUserService.update(user);
             }
-            sysUserService.update(user);
+
         }
+
         return login(username);
     }
 
@@ -211,4 +272,8 @@ public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider
     public void setSysUserDeviceService(SysUserDeviceService sysUserDeviceService) {
         this.sysUserDeviceService = sysUserDeviceService;
     }
+
+    public void setWxCacheService(WxCacheService wxCacheService) {
+        this.wxCacheService = wxCacheService;
+    }
 }

+ 16 - 13
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/provider/service/DefaultUserDetailsService.java

@@ -1,14 +1,17 @@
 package com.yonge.cooleshow.auth.core.provider.service;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import com.yonge.cooleshow.api.feign.AdminFeignService;
 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.auth.api.dto.SysUserInfo;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.auth.service.SysUserService;
 import com.yonge.cooleshow.common.enums.SysUserType;
 import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.cooleshow.common.security.AuthUser;
+import com.yonge.cooleshow.common.security.SecurityConstants;
 import com.yonge.cooleshow.common.util.WebUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -19,24 +22,16 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
 
-import com.yonge.cooleshow.auth.api.dto.SysUserInfo;
-import com.yonge.cooleshow.auth.api.entity.SysUser;
-import com.yonge.cooleshow.auth.service.SysUserService;
-import com.yonge.cooleshow.common.security.AuthUser;
-import com.yonge.cooleshow.common.security.SecurityConstants;
-
 import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
 
 @Service
 public class DefaultUserDetailsService implements UserDetailsService {
 
     @Autowired
-    private PasswordEncoder passwordEncoder;
-
-    @Autowired
     private SysUserService sysUserService;
 
     @Resource
@@ -93,6 +88,14 @@ public class DefaultUserDetailsService implements UserDetailsService {
             if (UserLockFlag.LOCKED.equals(data.getLockFlag())) {
                 throw new LockedException("账户被锁定");
             }
+        } else if (SysUserType.ORGANIZATION.getCode().equals(clientId)) {
+            TenantWrapper.Staff tenantStaff = adminFeignService.getTenantStaff(sysUser.getId()).getData();
+            if (tenantStaff == null) {
+                throw new UsernameNotFoundException("账户不存在");
+            }
+            if (UserLockFlag.LOCKED.name().equals(tenantStaff.getStatus())) {
+                throw new LockedException("账户被锁定");
+            }
         }
 
         List<GrantedAuthority> authorities = null;

+ 9 - 8
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/SysUserDao.java

@@ -1,19 +1,16 @@
 package com.yonge.cooleshow.auth.dal.dao;
 
-import java.util.List;
-
-import com.yonge.cooleshow.common.enums.SysUserType;
-import io.swagger.models.auth.In;
-import org.apache.ibatis.annotations.Param;
-
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
 import com.yonge.cooleshow.auth.api.dto.UserSetReq;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
-import com.yonge.cooleshow.common.enums.UserLockFlag;
 import com.yonge.cooleshow.auth.api.vo.UserSetVo;
-import com.yonge.toolset.mybatis.dal.BaseDAO;
 import com.yonge.cooleshow.common.entity.ImUserModel;
+import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.toolset.mybatis.dal.BaseDAO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 public interface SysUserDao extends BaseDAO<Long, SysUser> {
 
@@ -174,4 +171,8 @@ public interface SysUserDao extends BaseDAO<Long, SysUser> {
     Integer getUnCompCourseNum(@Param("userId") Long userId);
 
     void updateLockStatus(@Param("userId")Long userId, @Param("lockFlag") Integer lockFlag, @Param("sysUserType")  String sysUserType);
+
+    Long getTenantByClient(@Param("userId") Long userId, @Param("clientId") String clientId);
+
+    SysUser getSysUserByOpenId(@Param("openId") String openId, @Param("clientId") String clientId);
 }

+ 27 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/WxConfigInfoMapper.java

@@ -0,0 +1,27 @@
+package com.yonge.cooleshow.auth.dal.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.entity.WxConfigInfo;
+import com.yonge.cooleshow.auth.dal.wrapper.WxConfigInfoWrapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * 微信配置信息
+ * 2023-02-01 14:21:57
+ */
+@Repository
+public interface WxConfigInfoMapper extends BaseMapper<WxConfigInfo> {
+
+	/**
+	 * 分页查询
+	 * @param page IPage<WxConfigInfoWrapper.WxConfigInfo>
+	 * @param param WxConfigInfoWrapper.WxConfigInfoQuery
+	 * @return List<WxConfigInfoWrapper.WxConfigInfo>
+	 */
+	List<WxConfigInfo> selectPage(@Param("page") IPage<WxConfigInfo> page, @Param("param") WxConfigInfoWrapper.WxConfigInfoQuery param);
+
+}

+ 27 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/WxTemplateConfigMapper.java

@@ -0,0 +1,27 @@
+package com.yonge.cooleshow.auth.dal.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.entity.WxTemplateConfig;
+import com.yonge.cooleshow.auth.dal.wrapper.WxTemplateConfigWrapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * 微信模板配置
+ * 2023-02-01 14:21:57
+ */
+@Repository
+public interface WxTemplateConfigMapper extends BaseMapper<WxTemplateConfig> {
+
+	/**
+	 * 分页查询
+	 * @param page IPage<WxTemplateConfigWrapper.WxTemplateConfig>
+	 * @param param WxTemplateConfigWrapper.WxTemplateConfigQuery
+	 * @return List<WxTemplateConfigWrapper.WxTemplateConfig>
+	 */
+	List<WxTemplateConfig> selectPage(@Param("page") IPage<WxTemplateConfig> page, @Param("param") WxTemplateConfigWrapper.WxTemplateConfigQuery param);
+
+}

+ 27 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/WxTemplateMessageMapper.java

@@ -0,0 +1,27 @@
+package com.yonge.cooleshow.auth.dal.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.entity.WxTemplateMessage;
+import com.yonge.cooleshow.auth.dal.wrapper.WxTemplateMessageWrapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * 微信模板消息内容
+ * 2023-02-01 14:21:57
+ */
+@Repository
+public interface WxTemplateMessageMapper extends BaseMapper<WxTemplateMessage> {
+
+	/**
+	 * 分页查询
+	 * @param page IPage<WxTemplateMessageWrapper.WxTemplateMessage>
+	 * @param param WxTemplateMessageWrapper.WxTemplateMessageQuery
+	 * @return List<WxTemplateMessageWrapper.WxTemplateMessage>
+	 */
+	List<WxTemplateMessage> selectPage(@Param("page") IPage<WxTemplateMessage> page, @Param("param") WxTemplateMessageWrapper.WxTemplateMessageQuery param);
+
+}

+ 63 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/wrapper/WxConfigInfoWrapper.java

@@ -0,0 +1,63 @@
+package com.yonge.cooleshow.auth.dal.wrapper;
+
+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.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Optional;
+
+/**
+ * 微信配置信息
+ * 2023-02-01 14:21:57
+ */
+@ApiModel(value = "WxConfigInfoWrapper对象", description = "微信配置信息查询对象")
+public class WxConfigInfoWrapper {
+
+    @Data
+	@Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" WxConfigInfoQuery-微信配置信息")
+    public static class WxConfigInfoQuery implements QueryInfo {
+
+    	@ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+        @ApiModelProperty("关键字匹配")
+		private String keyword;
+
+        public String getKeyword() {
+            return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
+        }
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static WxConfigInfoQuery from(String json) {
+            return JSON.parseObject(json, WxConfigInfoQuery.class);
+        }
+    }
+
+	@ApiModel(" WxConfigInfo-微信配置信息")
+    public static class WxConfigInfo {
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static WxConfigInfo from(String json) {
+            return JSON.parseObject(json, WxConfigInfo.class);
+        }
+	}
+
+}

+ 63 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/wrapper/WxTemplateConfigWrapper.java

@@ -0,0 +1,63 @@
+package com.yonge.cooleshow.auth.dal.wrapper;
+
+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.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Optional;
+
+/**
+ * 微信模板配置
+ * 2023-02-01 14:21:57
+ */
+@ApiModel(value = "WxTemplateConfigWrapper对象", description = "微信模板配置查询对象")
+public class WxTemplateConfigWrapper {
+
+    @Data
+	@Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" WxTemplateConfigQuery-微信模板配置")
+    public static class WxTemplateConfigQuery implements QueryInfo {
+
+    	@ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+        @ApiModelProperty("关键字匹配")
+		private String keyword;
+
+        public String getKeyword() {
+            return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
+        }
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static WxTemplateConfigQuery from(String json) {
+            return JSON.parseObject(json, WxTemplateConfigQuery.class);
+        }
+    }
+
+	@ApiModel(" WxTemplateConfig-微信模板配置")
+    public static class WxTemplateConfig {
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static WxTemplateConfig from(String json) {
+            return JSON.parseObject(json, WxTemplateConfig.class);
+        }
+	}
+
+}

+ 63 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/wrapper/WxTemplateMessageWrapper.java

@@ -0,0 +1,63 @@
+package com.yonge.cooleshow.auth.dal.wrapper;
+
+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.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Optional;
+
+/**
+ * 微信模板消息内容
+ * 2023-02-01 14:21:57
+ */
+@ApiModel(value = "WxTemplateMessageWrapper对象", description = "微信模板消息内容查询对象")
+public class WxTemplateMessageWrapper {
+
+    @Data
+	@Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" WxTemplateMessageQuery-微信模板消息内容")
+    public static class WxTemplateMessageQuery implements QueryInfo {
+
+    	@ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+        @ApiModelProperty("关键字匹配")
+		private String keyword;
+
+        public String getKeyword() {
+            return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
+        }
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static WxTemplateMessageQuery from(String json) {
+            return JSON.parseObject(json, WxTemplateMessageQuery.class);
+        }
+    }
+
+	@ApiModel(" WxTemplateMessage-微信模板消息内容")
+    public static class WxTemplateMessage {
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static WxTemplateMessage from(String json) {
+            return JSON.parseObject(json, WxTemplateMessage.class);
+        }
+	}
+
+}

+ 1 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/enums/EClientType.java

@@ -11,6 +11,7 @@ import com.yonge.toolset.base.enums.BaseEnum;
 public enum EClientType implements BaseEnum<String, EClientType> {
     TEACHER("老师端"),
     STUDENT("学生端"),
+    TENANT_STUDENT("机构-学生端"),
     SYSTEM("平台端"),
     WEBSITE("官网"),
     ;

+ 76 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/enums/ELoginType.java

@@ -0,0 +1,76 @@
+package com.yonge.cooleshow.auth.enums;
+
+import com.yonge.toolset.base.enums.BaseEnum;
+import lombok.Getter;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * 登录方式
+ * Created by Eric.Shang on 2022/11/8.
+ */
+@Getter
+public enum ELoginType implements BaseEnum<String, ELoginType> {
+
+    PASSWORD("用户密码"),
+    CAPTCHA("图形验证码"),
+    SMS("短信验证码"),
+    WECHAT_OPENID("微信公众号"),
+    WECHAT_MA("微信小程序"),
+    ;
+
+    private final String message;
+
+    ELoginType(String message) {
+        this.message = message;
+    }
+
+    /**
+     * 获取枚举类的code值
+     *
+     * @return T
+     */
+    @Override
+    public String getCode() {
+        return this.name();
+    }
+
+    /**
+     * 用户登录方式有效性校验
+     * @param name 登录方式
+     * @return boolean
+     */
+    public static boolean invalid(String name) {
+        if (StringUtils.isNotEmpty(name)) {
+
+            ELoginType[] values = ELoginType.values();
+            for (ELoginType item : values) {
+
+                if (item.name().equals(name.toUpperCase())) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 获取登录方式
+     * @param dataType 登录类型
+     * @return ELoginType
+     */
+    public static ELoginType get(String dataType) {
+
+        if (StringUtils.isNoneBlank(dataType)) {
+
+            for (ELoginType item : ELoginType.values()) {
+
+                if (item.getCode().equals(dataType.toUpperCase())) {
+                    return item;
+                }
+            }
+
+        }
+
+        return PASSWORD;
+    }
+}

+ 50 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/MWxMpService.java

@@ -0,0 +1,50 @@
+package com.yonge.cooleshow.auth.middleware.wechat;
+
+import com.microsvc.toolkit.middleware.wechat.WxMpBaseService;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * Created by Eric.Shang on 2/3/17.
+ */
+public interface MWxMpService extends WxMpBaseService {
+
+    /**
+     * 校验公众号签名
+     * @param appid 公众号标识
+     * @param timestamp 时间戳
+     * @param nonce 随机数
+     * @param signature 签名
+     * @return boolean
+     */
+    boolean checkWxMpSignature(String appid, String timestamp, String nonce, String signature);
+
+    /**
+     * 校验小程序签名
+     * @param appid 公众号标识
+     * @param timestamp 时间戳
+     * @param nonce 随机数
+     * @param signature 签名
+     * @return boolean
+     */
+    boolean checkWxMaSignature(String appid, String timestamp, String nonce, String signature);
+
+    /**
+     * 构造oauth2授权的url连接, 网页授权获取用户基本信息
+     * @param appid 公众号标识
+     * @param scope 授权类型
+     * @param state 状态
+     * @param redirectURI 用户授权完成后的重定向链接,无需urlencode, 方法内会进行encode
+     * @return String
+     */
+    String oauth2buildAuthorizationUrl(String appid, String redirectURI, String scope, String state);
+
+    /**
+     * 用code网页授权获取用户基本信息
+     * @param appid 公众号标识
+     * @param code 授权code
+     * @return String
+     * @throws WxErrorException WxErrorException
+     */
+    String getOAuth2OpenId(String appid, String code) throws WxErrorException;
+
+}

+ 43 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/WxCacheService.java

@@ -0,0 +1,43 @@
+package com.yonge.cooleshow.auth.middleware.wechat;
+
+import com.microsvc.toolkit.middleware.wechat.MWxCacheService;
+import com.yonge.cooleshow.auth.api.entity.WxConfigInfo;
+import com.yonge.cooleshow.auth.api.entity.WxTemplateConfig;
+import com.yonge.cooleshow.auth.api.entity.WxTemplateMessage;
+
+/**
+ * Created by Eric.Shang on 4/1/18.
+ */
+public interface WxCacheService extends MWxCacheService {
+
+    /**
+     * 模板消息内容
+     * @param appId 公众号标识
+     * @param cmd 消息类型
+     * @return WxTemplateMessage
+     */
+    WxTemplateMessage findWxTemplateMessageBaseInfo(String appId, String cmd);
+
+    /**
+     * 模板消息配置
+     * @param appId 公众号标识
+     * @param cmd 消息类型
+     * @return WxTemplateConfig
+     */
+    WxTemplateConfig findWxTemplateConfigBaseInfo(String appId, String cmd);
+
+    /**
+     * 查询公众号通知消息内容
+     * @param appId 公众号Id
+     * @return WxConfigInfo
+     */
+    WxConfigInfo findMPSubscribeNotifyMessageBaseInfo(String appId);
+
+    /**
+     * 更新公众号关注状态
+     * @param appId 应用ID
+     * @param openId 来源用户
+     * @param subscribe 订阅状态
+     */
+    void updateMpSubscribeStatusInfo(String appId, String openId, Boolean subscribe);
+}

+ 113 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/domain/WxConfigStorageWrapper.java

@@ -0,0 +1,113 @@
+package com.yonge.cooleshow.auth.middleware.wechat.domain;
+
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
+import cn.binarywang.wx.miniapp.config.WxMaConfig;
+import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
+import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
+import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.auth.api.entity.WxConfigInfo;
+import com.yonge.cooleshow.auth.middleware.wechat.handler.WxMessageRouteEvent;
+import lombok.Data;
+import me.chanjar.weixin.mp.api.WxMpMessageRouter;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
+import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
+
+import java.io.Serializable;
+
+/**
+ * Created by Eric.Shang on 4/3/17.
+ */
+@Data
+public class WxConfigStorageWrapper implements Serializable {
+
+    // 公众号
+    private WxMpService wxMpService;
+    private WxMpConfigStorage storage;
+    private WxConfigInfo config;
+    private WxMpMessageRouter router;
+
+    public static WxConfigStorageWrapper build() {
+        return new WxConfigStorageWrapper();
+    }
+
+    /*
+    公共号配置
+     */
+    private WxMpConfigStorage wxMpConfigStorage() {
+        // 默认实现方式,基于内存存储
+        WxMpDefaultConfigImpl info = new WxMpDefaultConfigImpl();
+        info.setAppId(getConfig().getAppid());
+        info.setSecret(getConfig().getSecret());
+        info.setAesKey(getConfig().getAeskey());
+        info.setToken(getConfig().getToken());
+
+        return info;
+    }
+
+    public WxConfigStorageWrapper config(String config) {
+
+        this.config(JSON.parseObject(config, WxConfigInfo.class)).setStorage(wxMpConfigStorage());
+
+        WxMpService wxService = new WxMpServiceImpl();
+        wxService.setWxMpConfigStorage(getStorage());
+
+        return this.wxMpService(wxService).router(WxMessageRouteEvent.router(wxService));
+    }
+
+    public WxConfigStorageWrapper config(WxConfigInfo config) {
+        this.config = config;
+        return this;
+    }
+
+    public WxConfigStorageWrapper wxMpService(WxMpService wxMpService) {
+        this.wxMpService = wxMpService;
+        return this;
+    }
+
+    public WxConfigStorageWrapper router(WxMpMessageRouter router) {
+        this.router = router;
+        return this;
+    }
+
+    /*
+    小程序配置
+     */
+    private WxMaService wxMaService;
+    private WxMaConfig maConfig;
+    private WxMaMessageRouter maMessageRouter;
+
+    private WxMaConfig wxMaConfigStorage() {
+        // 小程序默认配置实现, 基于内存存储
+        WxMaDefaultConfigImpl info = new WxMaDefaultConfigImpl();
+        info.setAppid(getConfig().getAppid());
+        info.setSecret(getConfig().getSecret());
+        info.setAesKey(getConfig().getAeskey());
+        info.setToken(getConfig().getToken());
+
+        return info;
+    }
+
+    public WxConfigStorageWrapper maConfig(String config) {
+
+        this.config(JSON.parseObject(config, WxConfigInfo.class)).setMaConfig(wxMaConfigStorage());
+
+        WxMaService maService = new WxMaServiceImpl();
+        maService.setWxMaConfig(getMaConfig());
+
+        return this.wxMaService(maService).maMessageRouter(WxMessageRouteEvent.maRouter(maService));
+    }
+
+
+    public WxConfigStorageWrapper wxMaService(WxMaService wxMaService) {
+        this.wxMaService = wxMaService;
+        return this;
+    }
+
+    public WxConfigStorageWrapper maMessageRouter(WxMaMessageRouter maMessageRouter) {
+        this.maMessageRouter = maMessageRouter;
+        return this;
+    }
+}

+ 25 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/domain/WxContentWrapper.java

@@ -0,0 +1,25 @@
+package com.yonge.cooleshow.auth.middleware.wechat.domain;
+
+import com.alibaba.fastjson.JSONArray;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ *
+ * 微信消息(图文消息,文本消息等)
+ * Created by Eric.Shang on 9/1/18.
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WxContentWrapper implements Serializable {
+
+    private JSONArray welcome;
+    private String contact;
+
+}

+ 51 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/handler/WxMessageRouteEvent.java

@@ -0,0 +1,51 @@
+package com.yonge.cooleshow.auth.middleware.wechat.handler;
+
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
+import com.microsvc.toolkit.middleware.wechat.handler.ContactUSHandler;
+import com.microsvc.toolkit.middleware.wechat.handler.LocationHandler;
+import com.microsvc.toolkit.middleware.wechat.handler.NullHandler;
+import com.microsvc.toolkit.middleware.wechat.handler.ScanHandler;
+import com.microsvc.toolkit.middleware.wechat.handler.SubscribeHandler;
+import com.microsvc.toolkit.middleware.wechat.handler.UnsubscribeHandler;
+import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.mp.api.WxMpMessageRouter;
+import me.chanjar.weixin.mp.api.WxMpService;
+
+/**
+ * 微信消息路由配置
+ * Created by Eric.Shang on 6/3/17.
+ */
+public final class WxMessageRouteEvent {
+
+    // 联系我们事件配置
+    private static final String EVENT_KEY_CONTACT_US = "WX_CONTACT_US";
+
+    private WxMessageRouteEvent() {
+    }
+
+    /**
+     * 微信消息路由处理中心
+     * @param wxMpService 公众号实例
+     * @return WxMpMessageRouter
+     */
+    public static WxMpMessageRouter router(WxMpService wxMpService) {
+        return new WxMpMessageRouter(wxMpService)
+                .rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.SCAN).handler(new ScanHandler()).end()
+                .rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.SUBSCRIBE).handler(new SubscribeHandler()).end()
+                .rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.UNSUBSCRIBE).handler(new UnsubscribeHandler()).end()
+                .rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.LOCATION).handler(new LocationHandler()).end()
+                .rule().async(false).msgType(WxConsts.XmlMsgType.LOCATION).handler(new LocationHandler()).end()
+                .rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.CLICK).eventKey(EVENT_KEY_CONTACT_US).handler(new ContactUSHandler()).end()
+                .rule().async(false).handler(new NullHandler()).end();
+    }
+
+    /**
+     * 小程序消息路由处理中心
+     * @param wxMaService wxMaService
+     * @return WxMaMessageRouter
+     */
+    public static WxMaMessageRouter maRouter(WxMaService wxMaService) {
+        return new WxMaMessageRouter(wxMaService).rule().end();
+    }
+}

+ 292 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/impl/MWxMpServiceImpl.java

@@ -0,0 +1,292 @@
+package com.yonge.cooleshow.auth.middleware.wechat.impl;
+
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.WxMaMessage;
+import cn.binarywang.wx.miniapp.config.WxMaConfig;
+import com.alibaba.fastjson.JSON;
+import com.google.common.collect.Maps;
+import com.microsvc.toolkit.common.tools.ThreadPool;
+import com.microsvc.toolkit.middleware.wechat.WxServiceManager;
+import com.yonge.cooleshow.auth.api.entity.WxConfigInfo;
+import com.yonge.cooleshow.auth.middleware.wechat.MWxMpService;
+import com.yonge.cooleshow.auth.middleware.wechat.WxCacheService;
+import com.yonge.cooleshow.auth.middleware.wechat.domain.WxConfigStorageWrapper;
+import com.yonge.cooleshow.auth.middleware.wechat.domain.WxContentWrapper;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
+import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
+import me.chanjar.weixin.mp.bean.message.WxMpXmlOutNewsMessage;
+import me.chanjar.weixin.mp.bean.result.WxMpUser;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Objects;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * 公众号事件消息通知
+ * Created by Eric.Shang on 2/3/17.
+ */
+@Slf4j
+@Service
+public class MWxMpServiceImpl implements MWxMpService {
+
+    private final ConcurrentMap<String, WxConfigStorageWrapper> wxMap = Maps.newConcurrentMap();
+
+    @Autowired
+    private WxCacheService wxCacheService;
+
+    /**
+     * 校验公众号签名
+     *
+     * @param appid 公众号标识
+     * @param timestamp 时间戳
+     * @param nonce     随机数
+     * @param signature 签名
+     * @return boolean
+     */
+    @Override
+    public boolean checkWxMpSignature(String appid, String timestamp, String nonce, String signature) {
+        WxMpService wxMpService = WxServiceManager.getInstance().getWxMpService(appid, wxCacheService);
+        if (wxMpService == null) {
+            log.warn("checkWxMpSignature invalid, appid={}, nonce={} signature={}", appid, nonce, signature);
+            return false;
+        }
+        return wxMpService.checkSignature(timestamp, nonce, signature);
+
+    }
+
+    /**
+     * 校验小程序签名
+     *
+     * @param appid 公众号标识
+     * @param timestamp 时间戳
+     * @param nonce     随机数
+     * @param signature 签名
+     * @return boolean
+     */
+    @Override
+    public boolean checkWxMaSignature(String appid, String timestamp, String nonce, String signature) {
+        WxMaService wxMaService = WxServiceManager.getInstance().getWxMaService(appid, wxCacheService);
+        if (wxMaService == null) {
+            log.warn("checkWxMaSignature invalid, appid={}, nonce={} signature={}", appid, nonce, signature);
+            return false;
+        }
+        return wxMaService.checkSignature(timestamp, nonce, signature);
+
+    }
+
+    /**
+     * 构造oauth2授权的url连接, 网页授权获取用户基本信息
+     * @param appid 公众号标识
+     * @param scope 授权类型
+     * @param state 状态
+     * @param redirectURI 用户授权完成后的重定向链接,无需urlencode, 方法内会进行encode
+     * @return String
+     */
+    @Override
+    public String oauth2buildAuthorizationUrl(String appid, String redirectURI, String scope, String state) {
+        WxMpService wxMpService = WxServiceManager.getInstance().getWxMpService(appid, wxCacheService);
+        if (wxMpService == null) {
+            log.warn("oauth2buildAuthorizationUrl invalid, appid={}, url={}, scope={}, state={}", appid, redirectURI,
+                    scope, state);
+            return "";
+        }
+        return wxMpService.getOAuth2Service().buildAuthorizationUrl(redirectURI, scope, state);
+
+    }
+
+    /**
+     * 用code网页授权获取用户基本信息
+     *
+     * @param appid 公众号标识
+     * @param code 授权code
+     * @return String
+     * @throws WxErrorException WxErrorException
+     */
+    @Override
+    public String getOAuth2OpenId(String appid, String code) throws WxErrorException {
+        WxMpService wxMpService = WxServiceManager.getInstance().getWxMpService(appid, wxCacheService);
+        if (wxMpService == null) {
+            log.warn("getOAuth2OpenId invalid, appid={}, code={}", appid, code);
+            return "";
+        }
+
+        return wxMpService.getOAuth2Service().getAccessToken(code).getOpenId();
+    }
+
+    /**
+     * 根据appid返回配置实例对象
+     *
+     * @param appid 公众号ID
+     * @return WxMpConfigStorage
+     */
+    @Override
+    public WxMpConfigStorage getWxMpConfigStorage(String appid) {
+
+        // 公众号配置信息
+        return wxMap.get(appid).getStorage();
+    }
+
+    /**
+     * 微信路由事件消息
+     *
+     * @param appId     公众号ID
+     * @param inMessage WxMpXmlMessage
+     * @return WxMpXmlOutMessage
+     */
+    @Override
+    public WxMpXmlOutMessage route(String appId, WxMpXmlMessage inMessage) {
+        if (StringUtils.isEmpty(appId)) {
+            log.warn("route invalid appid={}", appId);
+            return null;
+        }
+        if (!wxMap.containsKey(appId)) {
+            String wxConfig = wxCacheService.findWxConfigBaseInfo(appId);
+            if (StringUtils.isNotEmpty(wxConfig)) {
+                wxMap.put(appId, WxConfigStorageWrapper.build().config(wxConfig));
+            }
+        }
+        return wxMap.get(appId).getRouter().route(inMessage);
+    }
+
+    /**
+     * 关注微信公众号提示信息
+     *
+     * @param wxMpService WxMpService
+     * @param wxMessage WxMpXmlMessage
+     * @return WxMpXmlOutMessage
+     */
+    @Override
+    public WxMpXmlOutMessage wxMpSubscribePromptInfo(final WxMpService wxMpService, final WxMpXmlMessage wxMessage) {
+
+        // 查询关注公众号通知消息
+        String appId = wxMpService.getWxMpConfigStorage().getAppId();
+
+        // 获取用户信息
+        try {
+            final WxMpUser wxMpUser = wxMpService.getUserService().userInfo(wxMessage.getFromUser());
+            ThreadPool.getExecutor().submit(() -> {
+
+                // 更新公众号关注状态
+                wxCacheService.updateMpSubscribeStatusInfo(appId, wxMessage.getFromUser(), wxMpUser.getSubscribe());
+            });
+        } catch (WxErrorException e) {
+            log.error("wxMpSubscribePromptInfo openid={}", wxMessage.getFromUser(), e);
+        }
+
+        WxConfigInfo configInfo = wxCacheService.findMPSubscribeNotifyMessageBaseInfo(appId);
+        if (Objects.isNull(configInfo) || StringUtils.isBlank(configInfo.getContent())) {
+            log.warn("wxMpSubscribePromptInfo invalid req, appid={}", appId);
+            return null;
+        }
+        log.debug("wxMpSubscribePromptInfo appid={}, info={}", appId, JSON.toJSONString(configInfo));
+        // 回复图文消息
+        WxContentWrapper wrapper = JSON.parseObject(configInfo.getContent(), WxContentWrapper.class);
+
+        return WxMpXmlOutMessage.NEWS().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())
+                .articles(JSON.parseArray(wrapper.getWelcome().toString(), WxMpXmlOutNewsMessage.Item.class)).build();
+    }
+
+    /**
+     * 修正用户当前位置信息
+     *
+     * @param wxMessage WxMpXmlMessage
+     * @return WxMpXmlOutMessage
+     */
+    @Override
+    public WxMpXmlOutMessage updateUserLocationInfo(WxMpXmlMessage wxMessage) {
+
+        return null;
+    }
+
+    /**
+     * 用户取消关注事件处理
+     *
+     * @param wxMessage WxMpXmlMessage
+     * @return WxMpXmlOutMessage
+     */
+    @Override
+    public WxMpXmlOutMessage wxMpUnsubscribeInfo(WxMpXmlMessage wxMessage) {
+
+        // 公众号取消关注通知
+        wxCacheService.updateMpSubscribeStatusInfo("", wxMessage.getFromUser(), false);
+
+        return null;
+    }
+
+    /**
+     * 微信扫码消息通知
+     *
+     * @param wxMessage WxMpXmlMessage
+     * @return WxMpXmlOutMessage
+     */
+    @Override
+    public WxMpXmlOutMessage wxScanNotifyInfo(WxMpXmlMessage wxMessage) {
+        /*
+        * 扫描带参数二维码事件
+        *
+        * 消息事件类型:
+        * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140454
+        * */
+
+        return null;
+    }
+
+    /**
+     * 微信点击联系我们
+     *
+     * @param wxMpService WxMpService
+     * @param wxMessage WxMpXmlMessage
+     * @return WxMpXmlOutMessage
+     */
+    @Override
+    public WxMpXmlOutMessage wxClickEventContactUSInfo(WxMpService wxMpService, WxMpXmlMessage wxMessage) {
+        // 查询关注公众号通知消息
+        String appid = wxMpService.getWxMpConfigStorage().getAppId();
+        WxConfigInfo configInfo = wxCacheService.findMPSubscribeNotifyMessageBaseInfo(appid);
+        if (Objects.isNull(configInfo)) {
+            log.warn("wxMpSubscribePromptInfo invalid req, appid={}", appid);
+            return null;
+        }
+        WxContentWrapper wrapper = JSON.parseObject(JSON.toJSONString(configInfo), WxContentWrapper.class);
+        return WxMpXmlOutMessage.TEXT().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser())
+                .content(wrapper.getContact()).build();
+    }
+
+    /**
+     * 根据appid返回配置实例对象
+     * @param appid 公众号ID
+     * @return WxMpConfigStorage
+     */
+    @Override
+    public WxMaConfig getWxMaConfigStorage(String appid) {
+        // 公众号配置
+        return wxMap.get(appid).getMaConfig();
+    }
+
+    /**
+     * 小程序路由事件消息
+     * @param appid 公众号ID
+     * @param inMessage WxMpXmlMessage
+     */
+    @Override
+    public void maRoute(String appid, WxMaMessage inMessage) {
+        if (StringUtils.isNotEmpty(appid)) {
+            if (!wxMap.containsKey(appid)) {
+                String wxConfig = wxCacheService.findWxConfigBaseInfo(appid);
+                if (StringUtils.isNotEmpty(wxConfig)) {
+                    wxMap.put(appid, WxConfigStorageWrapper.build().config(wxConfig));
+                }
+            }
+            wxMap.get(appid).getMaMessageRouter().route(inMessage);
+        } else {
+            log.warn("route invalid appid={}", appid);
+        }
+    }
+
+}

+ 115 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/impl/WxCacheServiceImpl.java

@@ -0,0 +1,115 @@
+package com.yonge.cooleshow.auth.middleware.wechat.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.auth.api.entity.WxConfigInfo;
+import com.yonge.cooleshow.auth.api.entity.WxTemplateConfig;
+import com.yonge.cooleshow.auth.api.entity.WxTemplateMessage;
+import com.yonge.cooleshow.auth.middleware.wechat.WxCacheService;
+import com.yonge.cooleshow.auth.service.WxConfigInfoService;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RBucket;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.text.MessageFormat;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 微信配置信息
+ * Created by Eric.Shang on 4/1/18.
+ */
+@Slf4j
+@Service
+public class WxCacheServiceImpl implements WxCacheService {
+
+    @Autowired
+    private RedissonClient redissonClient;
+    @Autowired
+    private WxConfigInfoService wxConfigInfoService;
+
+    // 微信相关缓存信息
+    private static final String WX_CONFIG_KEY = "wxcfg:{0}"; // wxcfg:[#appid#]
+
+    /**
+     * 模板消息内容
+     *
+     * @param appId 公众号标识
+     * @param cmd 消息类型
+     * @return WxTemplateMessage
+     */
+    @Override
+    public WxTemplateMessage findWxTemplateMessageBaseInfo(String appId, String cmd) {
+
+        // 公众号模板信息内容
+        return wxConfigInfoService.findWxTemplateMessageByCommand(appId, cmd);
+    }
+
+    /**
+     * 模板消息配置
+     *
+     * @param appId 公众号标识
+     * @param cmd   消息类型
+     * @return WxTemplateConfig
+     */
+    @Override
+    public WxTemplateConfig findWxTemplateConfigBaseInfo(String appId, String cmd) {
+
+        return wxConfigInfoService.findWxTemplateConfigWhen(appId, cmd);
+    }
+
+    /**
+     * 查询公众号配置信息
+     *
+     * @param appId 公众号ID
+     * @return String
+     */
+    @Override
+    public String findWxConfigBaseInfo(String appId) {
+
+        // 缓存微信配置信息
+        String hash = MessageFormat.format(WX_CONFIG_KEY, appId);
+        RBucket<Object> bucket = redissonClient.getBucket(hash);
+        // 缓存数据已失效,重新生成缓存数据
+        if (!bucket.isExists()) {
+            WxConfigInfo config = wxConfigInfoService.findWxConfigInfoByAppId(appId);
+            if (config == null) {
+                log.warn("findWxConfigBaseInfo 公众号配置不存在, appId={}", appId);
+                return "";
+            }
+
+            // 缓存数据, 默认缓存7天
+            bucket.set(JSON.toJSONString(config), 7, TimeUnit.DAYS);
+
+            // 直接返回
+            return JSON.toJSONString(config);
+        }
+
+        return (String) bucket.get();
+    }
+
+    /**
+     * 查询公众号通知消息内容
+     *
+     * @param appId 公众号Id
+     * @return WxConfigInfo
+     */
+    @Override
+    public WxConfigInfo findMPSubscribeNotifyMessageBaseInfo(String appId) {
+
+        // 查询微信公众号配置信息
+        return wxConfigInfoService.findWxConfigInfoByAppId(appId);
+    }
+
+    /**
+     * 更新公众号关注状态
+     *
+     * @param appId     应用ID
+     * @param openId  来源用户
+     * @param subscribe 订阅状态
+     */
+    @Override
+    public void updateMpSubscribeStatusInfo(String appId, String openId, Boolean subscribe) {
+
+    }
+}

+ 13 - 4
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/SysUserService.java

@@ -1,7 +1,5 @@
 package com.yonge.cooleshow.auth.service;
 
-import java.util.List;
-
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.dto.SysUserInfo;
 import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
@@ -10,10 +8,10 @@ import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.api.vo.UserSetVo;
 import com.yonge.cooleshow.auth.enums.EClientType;
 import com.yonge.cooleshow.common.entity.ImUserModel;
-import com.yonge.cooleshow.common.enums.SysUserType;
-import com.yonge.cooleshow.common.enums.UserLockFlag;
 import com.yonge.toolset.mybatis.service.BaseService;
 
+import java.util.List;
+
 public interface SysUserService extends BaseService<Long, SysUser> {
 
     /**
@@ -211,4 +209,15 @@ public interface SysUserService extends BaseService<Long, SysUser> {
      * @return SysUser
      */
     SysUser queryUserInfoWithIMToken(Long userId, EClientType clientType);
+
+    //根据用户类型获取机构编号
+    Long getTenantByClient(Long userId, String clientId);
+
+    /**
+     * 根据openId获取用户信息
+     * @param openId 用户openId
+     * @param clientId 客户端ID
+     * @return SysUser
+     */
+    SysUser getSysUserByOpenId(String openId, String clientId);
 }

+ 67 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/WxConfigInfoService.java

@@ -0,0 +1,67 @@
+package com.yonge.cooleshow.auth.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.yonge.cooleshow.auth.api.entity.WxConfigInfo;
+import com.yonge.cooleshow.auth.api.entity.WxTemplateConfig;
+import com.yonge.cooleshow.auth.api.entity.WxTemplateMessage;
+import com.yonge.cooleshow.auth.dal.wrapper.WxConfigInfoWrapper;
+
+/**
+ * 微信配置信息
+ * 2023-02-01 14:21:57
+ */
+public interface WxConfigInfoService extends IService<WxConfigInfo>  {
+
+	/**
+     * 查询详情
+     * @param id 详情ID
+     * @return WxConfigInfo
+     */
+	WxConfigInfo detail(Long id);
+
+    /**
+     * 分页查询
+     * @param page IPage<WxConfigInfo>
+     * @param query WxConfigInfoWrapper.WxConfigInfoQuery
+     * @return IPage<WxConfigInfo>
+     */
+    IPage<WxConfigInfo> selectPage(IPage<WxConfigInfo> page, WxConfigInfoWrapper.WxConfigInfoQuery query);
+
+    /**
+     * 添加
+     * @param wxConfigInfo WxConfigInfoWrapper.WxConfigInfo
+     * @return Boolean
+     */
+     Boolean add(WxConfigInfoWrapper.WxConfigInfo wxConfigInfo);
+
+    /**
+     * 更新
+     * @param wxConfigInfo WxConfigInfoWrapper.WxConfigInfo
+     * @return Boolean
+     */
+     Boolean update(WxConfigInfoWrapper.WxConfigInfo wxConfigInfo);
+
+    /**
+     * 公众号模板信息内容
+     * @param appId 公众号Id
+     * @param cmd 消息指令
+     * @return WxTemplateMessage
+     */
+    WxTemplateMessage findWxTemplateMessageByCommand(String appId, String cmd);
+
+    /**
+     * 公众号模板消息配置
+     * @param appId 公众号Id
+     * @param cmd 指令
+     * @return WxTemplateConfig
+     */
+    WxTemplateConfig findWxTemplateConfigWhen(String appId, String cmd);
+
+    /**
+     * 公众号配置
+     * @param appId 公众号Id
+     * @return WxConfigInfo
+     */
+    WxConfigInfo findWxConfigInfoByAppId(String appId);
+}

+ 43 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/WxTemplateConfigService.java

@@ -0,0 +1,43 @@
+package com.yonge.cooleshow.auth.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.yonge.cooleshow.auth.api.entity.WxTemplateConfig;
+import com.yonge.cooleshow.auth.dal.wrapper.WxTemplateConfigWrapper;
+
+/**
+ * 微信模板配置
+ * 2023-02-01 14:21:57
+ */
+public interface WxTemplateConfigService extends IService<WxTemplateConfig>  {
+
+	/**
+     * 查询详情
+     * @param id 详情ID
+     * @return WxTemplateConfig
+     */
+	WxTemplateConfig detail(Long id);
+
+    /**
+     * 分页查询
+     * @param page IPage<WxTemplateConfig>
+     * @param query WxTemplateConfigWrapper.WxTemplateConfigQuery
+     * @return IPage<WxTemplateConfig>
+     */
+    IPage<WxTemplateConfig> selectPage(IPage<WxTemplateConfig> page, WxTemplateConfigWrapper.WxTemplateConfigQuery query);
+
+    /**
+     * 添加
+     * @param wxTemplateConfig WxTemplateConfigWrapper.WxTemplateConfig
+     * @return Boolean
+     */
+     Boolean add(WxTemplateConfigWrapper.WxTemplateConfig wxTemplateConfig);
+
+    /**
+     * 更新
+     * @param wxTemplateConfig WxTemplateConfigWrapper.WxTemplateConfig
+     * @return Boolean
+     */
+     Boolean update(WxTemplateConfigWrapper.WxTemplateConfig wxTemplateConfig);
+
+}

+ 43 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/WxTemplateMessageService.java

@@ -0,0 +1,43 @@
+package com.yonge.cooleshow.auth.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.yonge.cooleshow.auth.api.entity.WxTemplateMessage;
+import com.yonge.cooleshow.auth.dal.wrapper.WxTemplateMessageWrapper;
+
+/**
+ * 微信模板消息内容
+ * 2023-02-01 14:21:57
+ */
+public interface WxTemplateMessageService extends IService<WxTemplateMessage>  {
+
+	/**
+     * 查询详情
+     * @param id 详情ID
+     * @return WxTemplateMessage
+     */
+	WxTemplateMessage detail(Long id);
+
+    /**
+     * 分页查询
+     * @param page IPage<WxTemplateMessage>
+     * @param query WxTemplateMessageWrapper.WxTemplateMessageQuery
+     * @return IPage<WxTemplateMessage>
+     */
+    IPage<WxTemplateMessage> selectPage(IPage<WxTemplateMessage> page, WxTemplateMessageWrapper.WxTemplateMessageQuery query);
+
+    /**
+     * 添加
+     * @param wxTemplateMessage WxTemplateMessageWrapper.WxTemplateMessage
+     * @return Boolean
+     */
+     Boolean add(WxTemplateMessageWrapper.WxTemplateMessage wxTemplateMessage);
+
+    /**
+     * 更新
+     * @param wxTemplateMessage WxTemplateMessageWrapper.WxTemplateMessage
+     * @return Boolean
+     */
+     Boolean update(WxTemplateMessageWrapper.WxTemplateMessage wxTemplateMessage);
+
+}

+ 21 - 14
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/SysUserServiceImpl.java

@@ -3,7 +3,6 @@ package com.yonge.cooleshow.auth.service.impl;
 import com.alibaba.fastjson.JSON;
 import com.google.common.collect.Lists;
 import com.yonge.cooleshow.api.feign.AdminFeignService;
-import com.yonge.cooleshow.api.feign.TeacherFeignService;
 import com.yonge.cooleshow.api.feign.dto.UserFriendInfoVO;
 import com.yonge.cooleshow.auth.api.dto.QRLoginDto;
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
@@ -46,6 +45,7 @@ import java.text.MessageFormat;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Random;
 import java.util.stream.Collectors;
 
@@ -68,8 +68,6 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
     private AdminFeignService adminFeignService;
     @Autowired
     private CustomerServiceConfig customerServiceConfig;
-    @Autowired
-    private TeacherFeignService teacherFeignService;
 
     @Override
     public BaseDAO<Long, SysUser> getDAO() {
@@ -119,12 +117,12 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
         userInfo.setSysUser(sysUser);
 
         List<String> roleCodeList = sysUserRoleService.queryRoleCodeListByUserId(sysUser.getId());
-        userInfo.setRoles(roleCodeList.toArray(new String[roleCodeList.size()]));
+        userInfo.setRoles(roleCodeList.toArray(new String[0]));
 
         List<Long> roleIdList = sysUserRoleService.queryRoleIdListByUserId(sysUser.getId());
         List<String> permissionList = sysRoleMenuService.queryPermissionsByRoleIdList(roleIdList);
 
-        userInfo.setPermissions(permissionList.toArray(new String[permissionList.size()]));
+        userInfo.setPermissions(permissionList.toArray(new String[0]));
 
         return userInfo;
     }
@@ -378,17 +376,8 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
         SysUser sysUser = sysUserDao.get(userId);
 
         if (EClientType.STUDENT == clientType && Objects.nonNull(sysUser)) {
-
             // 重新请求生成IM会话TOKEN
             try {
-
-                /*HttpResponseResult<Boolean> recv = teacherFeignService.userTeacherIdentityInfo(userId);
-
-                if (Objects.nonNull(recv) && recv.getData()) {
-                    // 同时一个手机号,拥手老师、学生身份时,为学生创建新的IMToken
-
-                }*/
-
                 String name = sysUser.getUsername();
                 if(StringUtils.isEmpty(name)){
                     name = sysUser.getRealName();
@@ -412,4 +401,22 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
 
         return sysUser;
     }
+
+    @Override
+    public Long getTenantByClient(Long userId, String clientId) {
+        // 查询用户机构信息,若没有则返回-1
+        return Optional.ofNullable(sysUserDao.getTenantByClient(userId, clientId)).orElse(-1L);
+    }
+
+    /**
+     * 根据openId获取用户信息
+     *
+     * @param openId 用户openId
+     * @param clientId 客户端ID
+     * @return SysUser
+     */
+    @Override
+    public SysUser getSysUserByOpenId(String openId, String clientId) {
+        return sysUserDao.getSysUserByOpenId(openId, clientId);
+    }
 }

+ 145 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/WxConfigInfoServiceImpl.java

@@ -0,0 +1,145 @@
+package com.yonge.cooleshow.auth.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yonge.cooleshow.auth.api.entity.WxConfigInfo;
+import com.yonge.cooleshow.auth.api.entity.WxTemplateConfig;
+import com.yonge.cooleshow.auth.api.entity.WxTemplateMessage;
+import com.yonge.cooleshow.auth.dal.dao.WxConfigInfoMapper;
+import com.yonge.cooleshow.auth.dal.wrapper.WxConfigInfoWrapper;
+import com.yonge.cooleshow.auth.service.WxConfigInfoService;
+import com.yonge.cooleshow.auth.service.WxTemplateConfigService;
+import com.yonge.cooleshow.auth.service.WxTemplateMessageService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 微信配置信息
+ * 2023-02-01 14:21:57
+ */
+@Slf4j
+@Service
+public class WxConfigInfoServiceImpl extends ServiceImpl<WxConfigInfoMapper, WxConfigInfo> implements WxConfigInfoService {
+
+    @Autowired
+    private WxTemplateConfigService wxTemplateConfigService;
+    @Autowired
+    private WxTemplateMessageService wxTemplateMessageService;
+
+	/**
+     * 查询详情
+     * @param id 详情ID
+     * @return WxConfigInfo
+     */
+	@Override
+    public WxConfigInfo detail(Long id) {
+
+        return baseMapper.selectById(id);
+    }
+
+    /**
+     * 分页查询
+     * @param page IPage<WxConfigInfo>
+     * @param query WxConfigInfoWrapper.WxConfigInfoQuery
+     * @return IPage<WxConfigInfo>
+     */
+    @Override
+    public IPage<WxConfigInfo> selectPage(IPage<WxConfigInfo> page, WxConfigInfoWrapper.WxConfigInfoQuery query) {
+
+        return page.setRecords(baseMapper.selectPage(page, query));
+    }
+
+    /**
+     * 添加
+     * @param wxConfigInfo WxConfigInfoWrapper.WxConfigInfo
+     * @return Boolean
+     */
+    @Override
+    public Boolean add(WxConfigInfoWrapper.WxConfigInfo wxConfigInfo) {
+
+        return this.save(JSON.parseObject(wxConfigInfo.jsonString(), WxConfigInfo.class));
+    }
+
+    /**
+     * 更新
+     * @param wxConfigInfo WxConfigInfoWrapper.WxConfigInfo
+     * @return Boolean
+     */
+    @Override
+    public Boolean update(WxConfigInfoWrapper.WxConfigInfo wxConfigInfo){
+
+        return this.updateById(JSON.parseObject(wxConfigInfo.jsonString(), WxConfigInfo.class));
+    }
+
+    /**
+     * 公众号模板信息内容
+     *
+     * @param appId 公众号Id
+     * @param cmd   消息指令
+     * @return WxTemplateMessage
+     */
+    @Override
+    public WxTemplateMessage findWxTemplateMessageByCommand(String appId, String cmd) {
+
+        List<WxTemplateMessage> records = wxTemplateMessageService.lambdaQuery()
+            .eq(WxTemplateMessage::getAppid, appId)
+            .eq(WxTemplateMessage::getCommand, cmd)
+            .eq(WxTemplateMessage::getStatus, true)
+            .list();
+
+        if (CollectionUtils.isEmpty(records)) {
+            return null;
+        }
+
+        return records.get(0);
+    }
+
+    /**
+     * 公众号模板消息配置
+     *
+     * @param appId 公众号Id
+     * @param cmd   指令
+     * @return WxTemplateConfig
+     */
+    @Override
+    public WxTemplateConfig findWxTemplateConfigWhen(String appId, String cmd) {
+
+        List<WxTemplateConfig> records = wxTemplateConfigService.lambdaQuery()
+            .eq(WxTemplateConfig::getAppid, appId)
+            .eq(WxTemplateConfig::getCommand, cmd)
+            .eq(WxTemplateConfig::getStatus, true)
+            .list();
+
+        if (CollectionUtils.isEmpty(records)) {
+            return null;
+        }
+
+        return records.get(0);
+    }
+
+    /**
+     * 公众号配置
+     *
+     * @param appId 公众号Id
+     * @return WxConfigInfo
+     */
+    @Override
+    public WxConfigInfo findWxConfigInfoByAppId(String appId) {
+
+        List<WxConfigInfo> records = lambdaQuery()
+            .eq(WxConfigInfo::getAppid, appId)
+            .eq(WxConfigInfo::getStatus, true)
+            .list();
+
+        if (CollectionUtils.isEmpty(records)) {
+            return null;
+        }
+
+        return records.get(0);
+    }
+}

+ 65 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/WxTemplateConfigServiceImpl.java

@@ -0,0 +1,65 @@
+package com.yonge.cooleshow.auth.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yonge.cooleshow.auth.api.entity.WxTemplateConfig;
+import com.yonge.cooleshow.auth.dal.dao.WxTemplateConfigMapper;
+import com.yonge.cooleshow.auth.dal.wrapper.WxTemplateConfigWrapper;
+import com.yonge.cooleshow.auth.service.WxTemplateConfigService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * 微信模板配置
+ * 2023-02-01 14:21:57
+ */
+@Slf4j
+@Service
+public class WxTemplateConfigServiceImpl extends ServiceImpl<WxTemplateConfigMapper, WxTemplateConfig> implements WxTemplateConfigService {
+
+	/**
+     * 查询详情
+     * @param id 详情ID
+     * @return WxTemplateConfig
+     */
+	@Override
+    public WxTemplateConfig detail(Long id) {
+
+        return baseMapper.selectById(id);
+    }
+
+    /**
+     * 分页查询
+     * @param page IPage<WxTemplateConfig>
+     * @param query WxTemplateConfigWrapper.WxTemplateConfigQuery
+     * @return IPage<WxTemplateConfig>
+     */
+    @Override
+    public IPage<WxTemplateConfig> selectPage(IPage<WxTemplateConfig> page, WxTemplateConfigWrapper.WxTemplateConfigQuery query) {
+
+        return page.setRecords(baseMapper.selectPage(page, query));
+    }
+
+    /**
+     * 添加
+     * @param wxTemplateConfig WxTemplateConfigWrapper.WxTemplateConfig
+     * @return Boolean
+     */
+    @Override
+    public Boolean add(WxTemplateConfigWrapper.WxTemplateConfig wxTemplateConfig) {
+
+        return this.save(JSON.parseObject(wxTemplateConfig.jsonString(), WxTemplateConfig.class));
+    }
+
+    /**
+     * 更新
+     * @param wxTemplateConfig WxTemplateConfigWrapper.WxTemplateConfig
+     * @return Boolean
+     */
+    @Override
+    public Boolean update(WxTemplateConfigWrapper.WxTemplateConfig wxTemplateConfig){
+
+        return this.updateById(JSON.parseObject(wxTemplateConfig.jsonString(), WxTemplateConfig.class));
+    }
+}

+ 65 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/WxTemplateMessageServiceImpl.java

@@ -0,0 +1,65 @@
+package com.yonge.cooleshow.auth.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yonge.cooleshow.auth.api.entity.WxTemplateMessage;
+import com.yonge.cooleshow.auth.dal.dao.WxTemplateMessageMapper;
+import com.yonge.cooleshow.auth.dal.wrapper.WxTemplateMessageWrapper;
+import com.yonge.cooleshow.auth.service.WxTemplateMessageService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * 微信模板消息内容
+ * 2023-02-01 14:21:57
+ */
+@Slf4j
+@Service
+public class WxTemplateMessageServiceImpl extends ServiceImpl<WxTemplateMessageMapper, WxTemplateMessage> implements WxTemplateMessageService {
+
+	/**
+     * 查询详情
+     * @param id 详情ID
+     * @return WxTemplateMessage
+     */
+	@Override
+    public WxTemplateMessage detail(Long id) {
+
+        return baseMapper.selectById(id);
+    }
+
+    /**
+     * 分页查询
+     * @param page IPage<WxTemplateMessage>
+     * @param query WxTemplateMessageWrapper.WxTemplateMessageQuery
+     * @return IPage<WxTemplateMessage>
+     */
+    @Override
+    public IPage<WxTemplateMessage> selectPage(IPage<WxTemplateMessage> page, WxTemplateMessageWrapper.WxTemplateMessageQuery query) {
+
+        return page.setRecords(baseMapper.selectPage(page, query));
+    }
+
+    /**
+     * 添加
+     * @param wxTemplateMessage WxTemplateMessageWrapper.WxTemplateMessage
+     * @return Boolean
+     */
+    @Override
+    public Boolean add(WxTemplateMessageWrapper.WxTemplateMessage wxTemplateMessage) {
+
+        return this.save(JSON.parseObject(wxTemplateMessage.jsonString(), WxTemplateMessage.class));
+    }
+
+    /**
+     * 更新
+     * @param wxTemplateMessage WxTemplateMessageWrapper.WxTemplateMessage
+     * @return Boolean
+     */
+    @Override
+    public Boolean update(WxTemplateMessageWrapper.WxTemplateMessage wxTemplateMessage){
+
+        return this.updateById(JSON.parseObject(wxTemplateMessage.jsonString(), WxTemplateMessage.class));
+    }
+}

+ 11 - 17
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/web/controller/TokenController.java

@@ -31,7 +31,6 @@ import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.oauth2.common.OAuth2AccessToken;
 import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
-import org.springframework.security.oauth2.provider.token.TokenStore;
 import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.MultiValueMap;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -61,9 +60,6 @@ public class TokenController extends BaseController {
     private ResourceServerTokenServices resourceServerTokenServices;
 
     @Autowired
-    private TokenStore tokenStore;
-
-    @Autowired
     private RestTemplate restTemplate;
 
     @Autowired
@@ -83,6 +79,7 @@ public class TokenController extends BaseController {
             @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
             @ApiImplicitParam(name = "smsCode", value = "验证码", required = true, dataType = "String"),
             @ApiImplicitParam(name = "isSurportRegister", value = "是否在登录时注册", dataType = "Boolean"),
+            @ApiImplicitParam(name = "loginType", value = "登陆类型", dataType = "String", defaultValue = "PASSWORD"),
             @ApiImplicitParam(name = "loginUserType", value = "登录用户类型 STUDENT TEACHER(官网登录)", dataType = "String")
     })
     public Object smsLogin() {
@@ -93,29 +90,26 @@ public class TokenController extends BaseController {
     public SysUser queryUserInfo() {
         AuthUser authUser = SecurityUtils.getUser();
         if (authUser != null) {
-            return userService.get(authUser.getUserId());
+            // 获取用户信息
+            SysUser sysUser = userService.get(authUser.getUserId());
+            // 获取用户机构信息
+            sysUser.setTenantId(userService.getTenantByClient(authUser.getUserId(),authUser.getClientId()));
+            return sysUser;
         }
         return null;
     }
 
     @ApiOperation(value = "获取用户信息")
     @GetMapping("/api/queryUserInfo")
-    public Object apiQueryUserInfo(@RequestParam(value = "clientType", required = false, defaultValue = "TEACHER") String clientType) {
-
-        // 校验客户端类型
-        if (EClientType.invalid(clientType)) {
-            return failed("无效的客户端类型");
-        }
-
+    public Object apiQueryUserInfo() {
         AuthUser authUser = SecurityUtils.getUser();
         if (authUser != null) {
-            SysUser sysUser = userService.queryUserInfoWithIMToken(authUser.getUserId(), EClientType.valueOf(clientType));
-
+            SysUser sysUser = userService.queryUserInfoWithIMToken(authUser.getUserId(), EClientType.valueOf(authUser.getClientId()));
+            sysUser.setTenantId(userService.getTenantByClient(authUser.getUserId(),authUser.getClientId()));
             String imUserId = String.valueOf(sysUser.getId());
-            if (EClientType.STUDENT.match(clientType)) {
-                imUserId = MessageFormat.format("{0}:{1}",imUserId, clientType);
+            if (EClientType.STUDENT.match(authUser.getClientId())) {
+                imUserId = MessageFormat.format("{0}:{1}",imUserId, authUser.getClientId());
             }
-
             // 封装返回参数
             return succeed(JSON.parseObject(JSON.toJSONString(sysUser), SysUserVo.class).imUserId(imUserId));
         }

+ 1 - 1
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/web/controller/UserController.java

@@ -390,7 +390,7 @@ public class UserController extends BaseController {
         }
 
         // 新密码规则:clx+手机号后四位
-        String newPassword = MessageFormat.format("klx{0}", sysUser.getPhone().substring(7));
+        String newPassword = MessageFormat.format("klxjg{0}", sysUser.getPhone().substring(7));
 
         // 生成重置默认密码
         String password = new BCryptPasswordEncoder().encode(newPassword);

+ 38 - 0
cooleshow-auth/auth-server/src/main/resources/config/mybatis/SysUserMapper.xml

@@ -304,6 +304,24 @@
         where cs.teacher_id_ = #{userId}
           and status_ in ('NOT_START','ING')
     </select>
+    <select id="getTenantByClient" resultType="java.lang.Long">
+        select tenant_id_ from
+        <choose>
+            <when test="clientId == 'STUDENT'">
+                student
+            </when>
+            <when test="clientId == 'TEACHER'">
+                teacher
+            </when>
+            <when test="clientId == 'ORGANIZATION'">
+                tenant_staff
+            </when>
+            <otherwise>
+                employee
+            </otherwise>
+        </choose>
+        where user_id_ = #{userId}
+    </select>
 
     <update id="updateLockStatus">
         <if test="sysUserType == 'STUDENT'">
@@ -317,4 +335,24 @@
         </if>
     </update>
 
+    <select id="getSysUserByOpenId" resultType="com.yonge.cooleshow.auth.api.entity.SysUser">
+        SELECT t1.*
+        FROM sys_user t1 LEFT JOIN
+        <choose>
+            <when test="clientId == 'STUDENT'">
+                student
+            </when>
+            <when test="clientId == 'TEACHER'">
+                teacher
+            </when>
+            <when test="clientId == 'ORGANIZATION'">
+                tenant_staff
+            </when>
+            <otherwise>
+                employee
+            </otherwise>
+        </choose> t2 ON (t1.id_ = t2.user_id_)
+        WHERE t1.del_flag_ = 0 and t2.wx_openid_ = #{openId} LIMIT 1
+    </select>
+
 </mapper>

+ 35 - 0
cooleshow-auth/auth-server/src/main/resources/config/mybatis/WxConfigInfoMapper.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE  mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.yonge.cooleshow.auth.dal.dao.WxConfigInfoMapper">
+
+
+
+    <!-- 表字段 -->
+    <sql id="baseColumns">
+         t.id AS id
+        , t.mp_name AS mpName
+        , t.appid AS appid
+        , t.secret AS secret
+        , t.token AS token
+        , t.aeskey AS aeskey
+        , t.content AS content
+        , t.merchant_id AS merchantId
+        , t.merchant_key AS merchantKey
+        , t.notify_url AS notifyUrl
+        , t.trade_type AS tradeType
+        , t.sign_type AS signType
+        , t.subscribe_url AS subscribeUrl
+        , t.mp_app_id AS mpAppId
+        , t.mp_type AS mpType
+        , t.is_global AS isGlobal
+        , t.status AS status
+        , t.create_time AS createTime
+        </sql>
+
+    <select id="selectPage" resultType="com.yonge.cooleshow.auth.api.entity.WxConfigInfo">
+		SELECT
+        	<include refid="baseColumns" />
+		FROM wx_config_info t
+	</select>
+
+</mapper>

+ 25 - 0
cooleshow-auth/auth-server/src/main/resources/config/mybatis/WxTemplateConfigMapper.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE  mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.yonge.cooleshow.auth.dal.dao.WxTemplateConfigMapper">
+
+
+
+    <!-- 表字段 -->
+    <sql id="baseColumns">
+         t.id AS id
+        , t.appid AS appid
+        , t.command AS command
+        , t.wx_template_id AS wxTemplateId
+        , t.url AS url
+        , t.description AS description
+        , t.status AS status
+        , t.create_time AS createTime
+        </sql>
+
+    <select id="selectPage" resultType="com.yonge.cooleshow.auth.api.entity.WxTemplateConfig">
+		SELECT
+        	<include refid="baseColumns" />
+		FROM wx_template_config t
+	</select>
+
+</mapper>

+ 27 - 0
cooleshow-auth/auth-server/src/main/resources/config/mybatis/WxTemplateMessageMapper.xml

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE  mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.yonge.cooleshow.auth.dal.dao.WxTemplateMessageMapper">
+
+
+
+    <!-- 表字段 -->
+    <sql id="baseColumns">
+         t.id AS id
+        , t.appid AS appid
+        , t.command AS command
+        , t.content AS content
+        , t.title AS title
+        , t.version AS version
+        , t.type AS type
+        , t.description AS description
+        , t.status AS status
+        , t.create_time AS createTime
+        </sql>
+
+    <select id="selectPage" resultType="com.yonge.cooleshow.auth.api.entity.WxTemplateMessage">
+		SELECT
+        	<include refid="baseColumns" />
+		FROM wx_template_message t
+	</select>
+
+</mapper>

+ 1 - 1
cooleshow-auth/auth-server/src/main/resources/logback-spring.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration scan="true" scanPeriod="10 seconds">
 
-	<property name="LOG_HOME" value="/mdata/logs/auth-%d{yyyy-MM-dd_HH}-%i.log" />
+	<property name="LOG_HOME" value="/mnt/datadisk/logs/auth-%d{yyyy-MM-dd_HH}-%i.log" />
 	<property name="CONSOLE_LOG_PATTERN"
 		value="[%X{username} %X{ip} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}] : %msg%n" />
 

+ 1 - 1
cooleshow-bbs/src/main/resources/logback-spring.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration scan="true" scanPeriod="10 seconds">
 
-	<property name="LOG_HOME" value="/mdata/logs/bbs-%d{yyyy-MM-dd_HH}-%i.log" />
+	<property name="LOG_HOME" value="/mnt/datadisk/logs/bbs-%d{yyyy-MM-dd_HH}-%i.log" />
 	<property name="CONSOLE_LOG_PATTERN"
 		value="[%X{username} %X{ip} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}] : %msg%n" />
 

+ 1 - 1
cooleshow-cms/src/main/resources/logback-spring.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration scan="true" scanPeriod="10 seconds">
 
-	<property name="LOG_HOME" value="/mdata/logs/cms-%d{yyyy-MM-dd_HH}-%i.log" />
+	<property name="LOG_HOME" value="/mnt/datadisk/logs/cms-%d{yyyy-MM-dd_HH}-%i.log" />
 	<property name="CONSOLE_LOG_PATTERN"
 		value="[%X{username} %X{ip} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}] : %msg%n" />
 

+ 4 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/AppConstant.java

@@ -23,6 +23,10 @@ public interface AppConstant {
      */
     String APPLICATION_ADMIN = "admin";
     /**
+     * 管理端
+     */
+    String APPLICATION_TENANT = "tenant";
+    /**
      * 老师端
      */
     String APPLICATION_TEACHER = "teacher";

+ 10 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/SysConfigConstant.java

@@ -358,4 +358,14 @@ public interface SysConfigConstant {
      * 个人风采虚拟人数增长最大值
      */
     String STYLE_VIDEO_VIRTUAL_NUMBER = "style_video_virtual_number";
+
+    /**
+     * 客服电话
+     */
+    String CUSTOMER_SERVICE_PHONE = "customer_service_phone";
+
+    /**
+     * 机构人员解绑申请超时时间,分钟
+     */
+    String TENANT_USER_UNBIND_EXPIRE_TIME = "tenant_user_unbind_expire_time";
 }

+ 21 - 15
cooleshow-common/src/main/java/com/yonge/cooleshow/common/controller/BaseController.java

@@ -1,14 +1,11 @@
 package com.yonge.cooleshow.common.controller;
 
-import java.net.URLEncoder;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-import javax.servlet.http.HttpServletRequest;
-
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.exception.ThirdpartyException;
+import com.yonge.toolset.utils.http.HttpUtil;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
@@ -23,12 +20,13 @@ import org.springframework.web.bind.MethodArgumentNotValidException;
 import org.springframework.web.bind.annotation.ControllerAdvice;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.yonge.cooleshow.common.entity.HttpResponseResult;
-import com.yonge.toolset.base.exception.BizException;
-import com.yonge.toolset.base.exception.ThirdpartyException;
-import com.yonge.toolset.utils.http.HttpUtil;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import javax.servlet.http.HttpServletRequest;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 @ControllerAdvice
 public class BaseController {
@@ -111,6 +109,14 @@ public class BaseController {
             if (e.getMessage().equals("205")) {
                 return failed(HttpStatus.RESET_CONTENT, e.getMessage());
             }
+
+            // 自定义错误码
+            if (e instanceof BizException) {
+                BizException bizException = (BizException) e;
+                return getResponseData(false, bizException.getCode(), null, bizException.getMessage());
+            }
+
+            // 默认返回错误码
             return failed(e.getMessage());
         } else if (e instanceof AccessDeniedException) {
             return failed("禁止访问");

+ 3 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/entity/BaseEntity.java

@@ -1,7 +1,10 @@
 package com.yonge.cooleshow.common.entity;
 
+import lombok.Data;
+
 import java.io.Serializable;
 
+@Data
 public class BaseEntity implements Serializable {
 
 }

+ 30 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/EActivationCode.java

@@ -0,0 +1,30 @@
+package com.yonge.cooleshow.common.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+public enum EActivationCode implements BaseEnum<String, EActivationCode> {
+
+    SEND("已发"),
+    WAIT("未发"),
+    ;
+
+    @EnumValue
+    private String code;
+
+    private String desc;
+
+    EActivationCode(String desc) {
+        this.code = this.name();
+        this.desc = desc;
+    }
+
+    @Override
+    public String getCode() {
+        return name();
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+}

+ 35 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/EPaymentVersion.java

@@ -0,0 +1,35 @@
+package com.yonge.cooleshow.common.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+/**
+ * 活动资源类型
+ *
+ * @Author: liweifan
+ * @Data: 2022/4/7 15:48
+ */
+public enum EPaymentVersion implements BaseEnum<String, EPaymentVersion> {
+
+    V1("20230726前 原生支付"),
+    V2("20230726后,机构"),
+    ;
+
+    @EnumValue
+    private String code;
+    private String msg;
+
+    EPaymentVersion(String msg) {
+        this.code = this.name();
+        this.msg = msg;
+    }
+
+    @Override
+    public String getCode() {
+        return this.code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+}

+ 29 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/ESettlementFrom.java

@@ -0,0 +1,29 @@
+package com.yonge.cooleshow.common.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+public enum ESettlementFrom implements BaseEnum<String, ESettlementFrom> {
+
+    TEACHER("结算给老师"),
+    TENANT("结算给机构"),
+    ;
+
+    @EnumValue
+    private String code;
+    private String msg;
+
+    ESettlementFrom(String msg) {
+        this.code = this.name();
+        this.msg = msg;
+    }
+
+    @Override
+    public String getCode() {
+        return this.code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+}

+ 32 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/ETenantUnBindAuditStatus.java

@@ -0,0 +1,32 @@
+package com.yonge.cooleshow.common.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+/**
+ * 机构用户解绑审核状态
+ */
+public enum ETenantUnBindAuditStatus implements BaseEnum<String, ETenantUnBindAuditStatus> {
+
+    DOING("审核中"),
+    PASS("审核通过"),
+    UNPASS("审核不通过");
+
+    @EnumValue
+    private final String code;
+    private final String msg;
+
+    ETenantUnBindAuditStatus(String msg) {
+        this.code = this.name();
+        this.msg = msg;
+    }
+
+    @Override
+    public String getCode() {
+        return this.code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+}

+ 6 - 2
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/SysUserType.java

@@ -2,11 +2,15 @@ package com.yonge.cooleshow.common.enums;
 
 import com.baomidou.mybatisplus.annotation.EnumValue;
 import com.yonge.toolset.base.enums.BaseEnum;
-import org.apache.commons.lang3.StringUtils;
 
 public enum SysUserType implements BaseEnum<String, SysUserType> {
 
-    STUDENT("学生"), TEACHER("指导老师"), SYSTEM("系统內置");
+    STUDENT("学生"),
+    TEACHER("指导老师"),
+    SYSTEM("系统內置"),
+    ORGANIZATION("机构"),
+    ;
+
     @EnumValue
     private String code;
 

+ 29 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/payment/EGoodsSource.java

@@ -0,0 +1,29 @@
+package com.yonge.cooleshow.common.enums.payment;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.cooleshow.common.enums.ActivityShareEnum;
+import com.yonge.toolset.base.enums.BaseEnum;
+import lombok.Getter;
+
+/**
+ * 商品来源
+ */
+@Getter
+public enum EGoodsSource implements BaseEnum<String, EGoodsSource> {
+
+    MALL("商城"),
+    VIP("数字化器乐学练工具"),
+    ;
+
+    private final String msg;
+
+    @EnumValue
+    private final String code;
+
+    EGoodsSource(String msg) {
+        this.msg = msg;
+
+        this.code = this.name();
+    }
+
+}

+ 56 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/payment/EGoodsType.java

@@ -0,0 +1,56 @@
+package com.yonge.cooleshow.common.enums.payment;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.google.common.collect.Lists;
+import com.yonge.toolset.base.enums.BaseEnum;
+import lombok.Getter;
+
+import java.util.List;
+
+/**
+ * 商品类型类型
+ */
+@Getter
+public enum EGoodsType implements BaseEnum<String, EGoodsType> {
+
+    VIP("数字化器乐学练工具", "VIP"),
+    INSTRUMENTS("乐器购买", "MALL"),
+    TEXTBOOK("教材", "MALL"),
+    ;
+
+    private final String msg;
+    private final String source;
+
+    @EnumValue
+    private final String code;
+
+    EGoodsType(String msg, String source) {
+        this.msg = msg;
+        this.source = source;
+
+        this.code = this.name();
+    }
+
+    /**
+     * 商城商品类型
+     * @return List<EGoodsType>
+     */
+    public static List<EGoodsType> mallGoodsTypes() {
+
+        return Lists.newArrayList(INSTRUMENTS);
+    }
+
+    /**
+     * 商品类型匹配
+     * @param code 商品编码
+     * @return boolean
+     */
+    public static boolean match(String code) {
+        for (EGoodsType eGoodsType : EGoodsType.values()) {
+            if (eGoodsType.getCode().equals(code)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}

+ 25 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/payment/EOrderType.java

@@ -0,0 +1,25 @@
+package com.yonge.cooleshow.common.enums.payment;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+import lombok.Getter;
+
+@Getter
+public enum EOrderType implements BaseEnum<String, EOrderType> {
+
+    VIP("数字化器乐学练工具"),
+    SCHOOL_REGISTER("学生报名"),
+    ;
+
+
+    private final String name;
+
+    @EnumValue
+    private final String code;
+
+    EOrderType(String name) {
+        this.name = name;
+
+        this.code = this.name();
+    }
+}

+ 47 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/payment/EPaymentChannel.java

@@ -0,0 +1,47 @@
+package com.yonge.cooleshow.common.enums.payment;
+
+import lombok.Getter;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * 三方支付渠道
+ */
+@Getter
+public enum EPaymentChannel {
+
+    ALIPAY_QR("alipay_qr", "支付宝正扫", 1),
+    ALIPAY_WAP("alipay_wap", "支付宝H5支付", 1),
+    WX_PUB("wx_pub", "微信公众号支付", 2),
+    ;
+
+    private final String msg;
+    private final int payType;
+
+    private final String code;
+
+    EPaymentChannel(String code, String msg, int payType) {
+        this.code = code;
+        this.msg = msg;
+        this.payType = payType;
+    }
+
+    /**
+     * 支付渠道
+     * @param code 渠道商
+     * @return EPaymentChannel
+     */
+    public static EPaymentChannel get(String code) {
+
+        EPaymentChannel[] values = EPaymentChannel.values();
+        if (StringUtils.isNotBlank(code)) {
+
+            for (EPaymentChannel item : values) {
+                if (item.getCode().equals(code)) {
+                    return item;
+                }
+            }
+        }
+        return WX_PUB;
+    }
+
+}

+ 51 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/payment/EPaymentStatus.java

@@ -0,0 +1,51 @@
+package com.yonge.cooleshow.common.enums.payment;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.google.common.collect.Lists;
+import lombok.Getter;
+
+import java.util.List;
+
+/**
+ * 订单支付状态
+ */
+@Getter
+public enum EPaymentStatus  {
+
+    WAIT_PAY("待支付"),
+    PAYING("支付中"),
+    PAID("已付款"),
+    TIMEOUT("订单超时"),
+    FAIL("支付失败"),
+    CLOSED("订单关闭"),
+    REFUNDED("已退款"),
+    ;
+
+    private final String msg;
+
+    @EnumValue
+    private final String code;
+
+    EPaymentStatus(String msg) {
+        this.msg = msg;
+
+        this.code = this.name();
+    }
+
+    /**
+     * 乐团报名状态
+     * @return List<EPaymentStatus>
+     */
+    public static List<EPaymentStatus> registerStatus() {
+        return Lists.newArrayList(PAID);
+    }
+
+    /**
+     * 乐团报名订单
+     * WAIT_PAY, PAYING, 只能是已支付和退款中的订单
+     * @return List<EPaymentStatus>
+     */
+    public static List<EPaymentStatus> registerOrder() {
+        return Lists.newArrayList(PAID);
+    }
+}

+ 34 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/payment/EPaymentType.java

@@ -0,0 +1,34 @@
+package com.yonge.cooleshow.common.enums.payment;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import lombok.Getter;
+
+/**
+ * 订单支付类型
+ */
+@Getter
+public enum EPaymentType {
+
+    VIP("开通会员"),
+    PRACTICE("陪练课购买"),
+    LIVE("直播课购买"),
+    VIDEO("视频课购买"),
+    MUSIC("单曲点播"),
+    PIANO_ROOM("琴房时长"),
+    ACTI_REGIST("活动报名"),
+    ALBUM("专辑购买"),
+    TENANT_ALBUM("平台专辑"),
+    ;
+
+    private final String msg;
+
+    @EnumValue
+    private final String code;
+
+    EPaymentType(String msg) {
+        this.msg = msg;
+
+        this.code = this.name();
+    }
+
+}

+ 1 - 1
cooleshow-gateway/gateway-web/src/main/resources/logback-spring.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration scan="true" scanPeriod="10 seconds">
 
-	<property name="LOG_HOME" value="/mdata/logs/gateway-%d{yyyy-MM-dd_HH}-%i.log" />
+	<property name="LOG_HOME" value="/mnt/datadisk/logs/gateway-%d{yyyy-MM-dd_HH}-%i.log" />
 	<property name="CONSOLE_LOG_PATTERN"
 		value="[%X{username} %X{ip} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}] : %msg%n" />
 

+ 1 - 1
cooleshow-mall/mall-admin/src/main/resources/logback-spring.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration scan="true" scanPeriod="10 seconds">
 
-	<property name="LOG_HOME" value="/mdata/logs/mall-admin-%d{yyyy-MM-dd_HH}-%i.log" />
+	<property name="LOG_HOME" value="/mnt/datadisk/logs/mall-admin-%d{yyyy-MM-dd_HH}-%i.log" />
 	<property name="CONSOLE_LOG_PATTERN"
 			  value="[%X{username} %X{ip} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}] : %msg%n" />
 

+ 1 - 1
cooleshow-mall/mall-portal/src/main/resources/logback-spring.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration scan="true" scanPeriod="10 seconds">
 
-	<property name="LOG_HOME" value="/mdata/logs/mall-portal-%d{yyyy-MM-dd_HH}-%i.log" />
+	<property name="LOG_HOME" value="/mnt/datadisk/logs/mall-portal-%d{yyyy-MM-dd_HH}-%i.log" />
 	<property name="CONSOLE_LOG_PATTERN"
 			  value="[%X{username} %X{ip} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}] : %msg%n" />
 

+ 19 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/jobs/TenantPersonStatTask.java

@@ -0,0 +1,19 @@
+package com.yonge.cooleshow.task.jobs;
+
+import com.yonge.cooleshow.api.feign.TenantFeignService;
+import com.yonge.cooleshow.task.core.BaseTask;
+import com.yonge.cooleshow.task.core.TaskException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class TenantPersonStatTask extends BaseTask {
+
+    @Autowired
+    private TenantFeignService tenantFeignService;
+
+    @Override
+    public void execute() throws TaskException {
+        tenantFeignService.tenantPersonStat();
+    }
+}

+ 1 - 1
cooleshow-task/src/main/resources/logback-spring.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration scan="true" scanPeriod="10 seconds">
 
-	<property name="LOG_HOME" value="/mdata/logs/task-%d{yyyy-MM-dd_HH}-%i.log" />
+	<property name="LOG_HOME" value="/mnt/datadisk/logs/task-%d{yyyy-MM-dd_HH}-%i.log" />
 	<property name="CONSOLE_LOG_PATTERN"
 			  value="[%X{username} %X{ip} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}] : %msg%n" />
 

+ 1 - 0
cooleshow-user/pom.xml

@@ -41,5 +41,6 @@
 		<module>user-admin</module>
 		<module>user-biz</module>
         <module>user-website</module>
+        <module>user-tenant</module>
     </modules>
 </project>

+ 116 - 97
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/StudentController.java

@@ -1,41 +1,19 @@
 package com.yonge.cooleshow.admin.controller;
 
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiImplicitParams;
-import io.swagger.annotations.ApiOperation;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Date;
-import java.util.List;
-
-import javax.servlet.http.HttpServletResponse;
-import javax.validation.Valid;
-
-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.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 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;
@@ -46,6 +24,29 @@ 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.annotation.Resource;
+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("/student")
@@ -54,8 +55,7 @@ public class StudentController extends BaseController {
     @Autowired
     private StudentService studentService;
 
-
-    @Autowired
+    @Resource
     private SysUserFeignService sysUserFeignService;
 
     @Autowired
@@ -64,56 +64,55 @@ public class StudentController extends BaseController {
     @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);
-	}
+    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);
-				}
-			}
-		}
+
+        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")
@@ -121,45 +120,45 @@ public class StudentController extends BaseController {
     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;
-			}
-    	}
+
+        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);
-				}
-			}
-		}
+
+        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"}, rows);
+                    "年龄", "专业", "手机号码", "是否是会员", "注册时间", "用户状态", "学生来源"}, 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");
@@ -185,7 +184,7 @@ public class StudentController extends BaseController {
     @PreAuthorize("@pcs.hasPermissions('student/addVip')")
     public HttpResponseResult<Boolean> addVip(@Valid @RequestBody VipSubmitReq vipSubmitReq) {
         SysUser sysUser = sysUserFeignService.queryUserInfo();
-        if (sysUser == null  || sysUser.getId() == null) {
+        if (sysUser == null || sysUser.getId() == null) {
             return failed("用户信息获取失败");
         }
         return succeed(memberPriceSettingsService.addVip(vipSubmitReq, ClientEnum.STUDENT, sysUser));
@@ -200,4 +199,24 @@ public class StudentController extends BaseController {
         recordSearch.setClient(ClientEnum.STUDENT);
         return succeed(vipCardRecordService.vipRecord(recordSearch));
     }
+
+    @PostMapping("/updateTenant")
+    @ApiOperation(value = "修改机构")
+    public HttpResponseResult<Boolean> updateTenant(@RequestBody StudentWrapper.StudentUpdateTenant updateTenant) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        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();
+    }
 }

+ 124 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/SysAreaController.java

@@ -0,0 +1,124 @@
+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.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Validated
+@RestController
+@RequestMapping("/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);
+    }
+}

+ 71 - 0
cooleshow-user/user-admin/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("/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));
+    }
+
+
+}

+ 5 - 4
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TeacherController.java

@@ -26,6 +26,7 @@ import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
+import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 
@@ -78,7 +79,7 @@ import static com.yonge.cooleshow.common.entity.HttpResponseResult.succeed;
 @Api(value = "教师表", tags = "教师表")
 public class TeacherController extends BaseController {
 
-    @Autowired
+    @Resource
     private SysUserFeignService sysUserFeignService;
     @Autowired
     private TeacherService teacherService;
@@ -215,9 +216,9 @@ public class TeacherController extends BaseController {
         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"}, rows);
+                    "注册时间", "认证时间", "状态", "是否是会员", "徽章", "机构"}, 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");

+ 58 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantAccountRecordController.java

@@ -0,0 +1,58 @@
+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.TenantAccountRecordService;
+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.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 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.*;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@RequestMapping("/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);
+    }
+
+}

+ 188 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantAlbumController.java

@@ -0,0 +1,188 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.admin.io.request.TenantAlbumVo;
+import com.yonge.cooleshow.api.feign.dto.TenantWrapper;
+import com.yonge.cooleshow.biz.dal.dto.search.StudentMusicSheetSearch;
+import com.yonge.cooleshow.biz.dal.entity.*;
+import com.yonge.cooleshow.biz.dal.enums.SubjectTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.*;
+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.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.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("/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;
+
+    /**
+     * 查询分页
+     *
+     * @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());
+        //查询曲目表
+
+        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(value, tenantAlbumSheet);
+                Long musicSheetId = tenantAlbumSheet.getMusicSheetId();
+                MusicSheetVo musicSheet = idMsMap.getOrDefault(musicSheetId, new MusicSheetVo());
+                tenantAlbumSheet.setMusicSheetName(musicSheet.getMusicSheetName());
+                tenantAlbumSheet.setMusicTag(musicSheet.getMusicTag());
+                return tenantAlbumSheet;
+            }).collect(Collectors.toList());
+
+
+            sheetData.setTenantAlbumSheetList(tenantAlbumSheets);
+            musicSheetData.add(sheetData);
+        });
+
+        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 ->
+                        JSON.parseObject(JSON.toJSONString(next), TenantAlbumWrapper.MusicSheetData.class))
+                .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(@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 ->
+                        JSON.parseObject(JSON.toJSONString(next), TenantAlbumWrapper.MusicSheetData.class))
+                .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();
+    }
+
+}

+ 105 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantEntryRecordController.java

@@ -0,0 +1,105 @@
+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.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.service.TenantApplyRecordService;
+import com.yonge.cooleshow.biz.dal.service.TenantEntryRecordService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantApplyRecordWrapper;
+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.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.poi.ss.formula.functions.T;
+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("/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-user/user-admin/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.microsvc.toolkit.common.response.paging.QueryInfo;
+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.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * @Author:haonan
+ * @Date:2023/7/24 9:57
+ * @Filename:TenantInfoController
+ */
+@RestController
+@RequestMapping("/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(@Validated @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(@Valid @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);
+    }
+
+}

+ 72 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantUnbindRecordController.java

@@ -0,0 +1,72 @@
+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;
+
+import javax.annotation.Resource;
+
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("/tenantUnbindRecord")
+@Api(tags = "机构解绑申请记录")
+public class TenantUnbindRecordController extends BaseController {
+
+    @Autowired
+    private TenantUnbindRecordService tenantUnbindRecordService;
+
+    @Resource
+    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();
+    }
+}

+ 51 - 3
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/open/AdminClient.java

@@ -1,14 +1,18 @@
 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;
@@ -17,6 +21,8 @@ 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;
@@ -24,12 +30,13 @@ 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.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.jwt.Jwt;
@@ -46,12 +53,13 @@ import java.math.BigDecimal;
 import java.security.interfaces.RSAPublicKey;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
+@Slf4j
 @RestController
 @RequestMapping("/open/adminClient")
 public class AdminClient extends BaseController {
-    private final static Logger log = LoggerFactory.getLogger(UserOrderClient.class);
 
     @Autowired
     private UserFirstTimeService userFirstTimeService;
@@ -68,6 +76,12 @@ public class AdminClient extends BaseController {
     @Autowired
     private CouponInfoService couponInfoService;
 
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
     @GetMapping("/recordTime")
     public HttpResponseResult<Boolean> recordTime(
             @RequestParam("userId") Long userId,
@@ -132,6 +146,40 @@ public class AdminClient extends BaseController {
         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));
+        }
+        return succeed(ret);
+    }
+
     /**
      * 订单优惠券信息
      * @return HttpResponseResult<CouponOrderVO.CouponPageInfo>

+ 124 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/open/OpenSysAreaController.java

@@ -0,0 +1,124 @@
+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.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Validated
+@RestController
+@RequestMapping("/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);
+    }
+}

+ 99 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/open/UserPaymentClient.java

@@ -0,0 +1,99 @@
+package com.yonge.cooleshow.admin.controller.open;
+
+import com.alibaba.fastjson.JSON;
+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.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 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.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Objects;
+
+@Slf4j
+@RestController
+@RequestMapping("/open/userOrder")
+@Api(tags = "开放权限接口-支付回调")
+public class UserPaymentClient {
+
+    @Autowired
+    private PaymentServiceContext paymentServiceContext;
+    @Autowired
+    private UserPaymentCoreService userPaymentCoreService;
+    @Autowired
+    private UserPaymentOrderService userPaymentOrderService;
+
+    @Autowired
+    private UserOrderService userOrderService;
+
+    /**
+     * 支付消息回调
+     * @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.getTransNo(), paymentResp.getMerOrderNo());
+        if (Objects.isNull(paymentOrder)) {
+            return paymentResp.getMsg();
+        }
+
+        // 执行支付回调流程
+        userPaymentCoreService.executePaymentCallback(paymentResp);
+
+        return paymentServiceContext.getPaymentService(vendor).returnNotifyResult(request);
+    }
+
+    @ApiOperation(value = "用户付款", notes = "用户付款")
+    @PostMapping("/executePayment")
+    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);
+    }
+
+}

+ 168 - 0
cooleshow-user/user-admin/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;
+    }
+}

+ 126 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/TenantAlbumVo.java

@@ -0,0 +1,126 @@
+package com.yonge.cooleshow.admin.io.request;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.entity.TenantAlbumMusic;
+import com.yonge.cooleshow.biz.dal.enums.SubjectTypeEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.math.BigDecimal;
+import java.util.List;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 机构专辑
+ * 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 String type;
+
+        @ApiModelProperty("级别")
+        private String level;
+
+        @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("声部id列表")
+        private List<Long> musicSheetIdList = new ArrayList<>();
+    }
+
+    @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;
+    }
+
+}

+ 69 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/TenantInfoVo.java

@@ -0,0 +1,69 @@
+package com.yonge.cooleshow.admin.io.request;
+
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Date;
+
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotNull;
+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("名称")
+        @NotNull
+        private String name;
+
+        @ApiModelProperty("logo")
+        private String logo;
+
+        @ApiModelProperty("简介")
+        private String briefIntroduction;
+
+        @ApiModelProperty("省份编码")
+        @NotNull
+        private Integer provinceCode;
+
+        @ApiModelProperty("城市编码")
+        @NotNull
+        private Integer cityCode;
+
+        @ApiModelProperty("地区/街道")
+        @NotNull
+        private Integer regionCode;
+
+        @ApiModelProperty("联系人")
+        @Length(min = 1, max = 8, message = "联系人字符最大8位")
+        private String username;
+
+        @ApiModelProperty("手机号")
+        @NotNull
+        @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);
+        }
+    }
+
+}

+ 6 - 19
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/task/TaskController.java

@@ -1,17 +1,6 @@
 package com.yonge.cooleshow.admin.task;
 
-import com.yonge.cooleshow.biz.dal.service.ActivityPlanEvaluationService;
-import com.yonge.cooleshow.biz.dal.service.ActivityPlanService;
-import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
-import com.yonge.cooleshow.biz.dal.service.CustomerServiceBatchSendingService;
-import com.yonge.cooleshow.biz.dal.service.MusicAlbumService;
-import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
-import com.yonge.cooleshow.biz.dal.service.PlatformCashAccountRecordService;
-import com.yonge.cooleshow.biz.dal.service.TeacherStyleVideoService;
-import com.yonge.cooleshow.biz.dal.service.UserAccountRecordService;
-import com.yonge.cooleshow.biz.dal.service.UserBindingTeacherService;
-import com.yonge.cooleshow.biz.dal.service.UserOrderService;
-import com.yonge.cooleshow.biz.dal.service.VideoLessonGroupService;
+import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
@@ -20,11 +9,7 @@ import org.redisson.api.RBucket;
 import org.redisson.api.RedissonClient;
 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.PostMapping;
-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.bind.annotation.*;
 import springfox.documentation.annotations.ApiIgnore;
 
 import java.io.File;
@@ -67,10 +52,11 @@ public class TaskController extends BaseController {
     private TeacherStyleVideoService teacherStyleVideoService;
 
     @Autowired
-    private VideoLessonGroupService videoLessonGroupService;
-    @Autowired
     private CustomerServiceBatchSendingService customerServiceBatchSendingService;
 
+    @Autowired
+    private UserPaymentCoreService userPaymentCoreService;
+
     /***
      * 轮询用户订单
      * @author liweifan
@@ -80,6 +66,7 @@ public class TaskController extends BaseController {
     @GetMapping("/pollingOrder")
     public HttpResponseResult pollingOrder() {
         userOrderService.pollingOrder();
+        userPaymentCoreService.scanPaymentTimeoutOrderRecord();
         return succeed();
     }
 

+ 1 - 1
cooleshow-user/user-admin/src/main/resources/logback-spring.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration scan="true" scanPeriod="10 seconds">
 
-	<property name="LOG_HOME" value="/mdata/logs/admin-%d{yyyy-MM-dd_HH}-%i.log" />
+	<property name="LOG_HOME" value="/mnt/datadisk/logs/admin-%d{yyyy-MM-dd_HH}-%i.log" />
 	<property name="CONSOLE_LOG_PATTERN"
 		value="[%X{username} %X{ip} %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}] : %msg%n" />
 

+ 4 - 0
cooleshow-user/user-biz/pom.xml

@@ -104,6 +104,10 @@
             <artifactId>toolset-payment</artifactId>
             <version>${project.toolset.version}</version>
         </dependency>
+        <dependency>
+            <groupId>com.microsvc.toolkit.middleware</groupId>
+            <artifactId>microsvc-middleware-payment</artifactId>
+        </dependency>
     </dependencies>
 
     <build>

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/ImUserFriendDao.java

@@ -17,5 +17,7 @@ public interface ImUserFriendDao extends BaseMapper<ImUserFriend> {
     int insertBatch(@Param("entities") List<ImUserFriend> entities);
 
     ImUserFriend findByUserIdAndFriendId(@Param("userId") Long userId, @Param("friendId") Long friendId);
+
+    void delFriendByTenantId(@Param("tenantId") Long tenantId,@Param("userId") Long userId);
 }
 

+ 8 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/StudentDao.java

@@ -11,6 +11,7 @@ import com.yonge.cooleshow.biz.dal.entity.Student;
 import com.yonge.cooleshow.biz.dal.entity.Subject;
 import com.yonge.cooleshow.biz.dal.vo.MyFollow;
 import com.yonge.cooleshow.biz.dal.vo.StudentVo;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper;
 import org.apache.ibatis.annotations.Param;
 
 public interface StudentDao extends BaseMapper<Student> {
@@ -71,4 +72,11 @@ public interface StudentDao extends BaseMapper<Student> {
      */
     List<MyFollow> queryMyFollow(@Param("page") IPage page, @Param("param") QueryMyFollowSearch query);
 
+    List<Map<Integer, String>> getStudentSubjectMapList(List<Long> studentIds);
+
+    int countStudentsWithTenant(Map<String, Object> params);
+
+    List<TenantInfoWrapper.UserCount> countTeacherByTenantIds(@Param("tenantIdList") List<Long> tenantIdList);
+
+    Integer queryStudentCounts(@Param("id") Long id);
 }

+ 33 - 46
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysMusicCompareRecordDao.java

@@ -3,6 +3,8 @@ package com.yonge.cooleshow.biz.dal.dao;
 import java.util.List;
 import java.util.Map;
 
+import com.yonge.cooleshow.biz.dal.entity.SysMusicCompareWeekData;
+import com.yonge.cooleshow.biz.dal.queryInfo.SysMusicCompareRecordQueryInfo;
 import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.music.MusicCompareWrapper;
 import org.apache.ibatis.annotations.Param;
@@ -15,68 +17,53 @@ import com.yonge.toolset.mybatis.dal.BaseDAO;
 
 public interface SysMusicCompareRecordDao extends BaseDAO<Long, SysMusicCompareRecord> {
 
-	/**
-	 * @describe 获取用户最后一次评测数据
-	 * @author Joburgess
-	 * @date 2021/8/23 0023
-	 * @param userId:
-	 * @return com.ym.mec.biz.dal.entity.SysMusicCompareRecord
-	 */
+	//获取用户最后一次评测数据
 	SysMusicCompareRecord getUserLastEvaluationData(@Param("userId") Long userId);
 
-	/**
-	 * @param userId   :
-	 * @param clientId
-	 * @return com.ym.mec.biz.dal.dto.StudentTrainOverviewDto
-	 * @describe 获取用户训练总览
-	 * @author Joburgess
-	 * @date 2021/8/11 0011
-	 */
+	//获取用户训练总览
 	StudentTrainOverviewDto getUserTrainOverView(@Param("userId") Long userId, @Param("clientId") String clientId);
 
-	/**
-	 * @param userId    :
-	 * @param startTime :
-	 * @param endTime   :
-	 * @param clientId
-	 * @return java.util.List<com.ym.mec.biz.dal.dto.StudentTrainChartDto>
-	 * @describe 获取用户训练图表数据
-	 * @author Joburgess
-	 * @date 2021/8/12 0012
-	 */
+	//获取用户训练图表数据
 	List<StudentTrainChartDto> getUserTrainChartData(@Param("userId") Long userId, @Param(
 			"startTime") String startTime, @Param("endTime") String endTime, @Param("clientId") String clientId);
 
 	int countMusicGroupStudentTrainData(Map<String, Object> params);
 
-	/**
-	 * @describe 统计分部小酷Ai新增人数
-	 * @author Joburgess
-	 * @date 2021/8/18 0018
-	 * @param organId:
-	 * @return int
-	 */
+
+	//统计分部小酷Ai新增人数
 	int getOrganNewCloudStudyNum(@Param("organId") Integer organId);
 
 	int getOrgansTotalNewCloudStudyNum(@Param("organIds") List<Integer> organIds);
 
 	List<Map<Integer, Integer>> getOrgansNewCloudStudyNum(@Param("organIds") List<Integer> organIds);
 
-	/**
-	 * @describe 获取用户本周最高分对应曲目编号
-	 * @author Joburgess
-	 * @date 2021/8/30 0030
-	 * @param userId:
-	 * @param monday:
-	 * @param heardLevel:
-	 * @return java.lang.Integer
-	 */
+	//获取用户本周最高分对应曲目编号
 	Integer getUserWeekMaxMusicScoreId(@Param("userId") Long userId, @Param("monday") String monday, @Param("heardLevel") HeardLevelEnum heardLevel);
 
-	/**
-	 * 曲目练习记录统计
-	 * @param queryInfo MusicCompareWrapper.RecordQueryInfo
-	 * @return List<StatGroupWrapper>
-	 */
+	//曲目练习记录统计
 	List<StatGroupWrapper> selectMusicCompareRecordStatInfo(@Param("record") MusicCompareWrapper.RecordQueryInfo queryInfo);
+
+	//小程序学员训练统计列表
+    int countWeChatStudentTrainData(Map<String, Object> params);
+
+	//小程序学员训练统计列表
+	List<SysMusicCompareRecordQueryInfo.WechatCompareRecordPageDto> queryWeChatStudentTrainData(Map<String, Object> params);
+
+	//小程序学员训练统计
+	SysMusicCompareRecordQueryInfo.WechatCompareRecordSumDto wechatCompareRecordSum(@Param("queryInfo") SysMusicCompareRecordQueryInfo.WechatCompareRecordQueryInfo queryInfo);
+
+	//小程序学员评测列表
+    List<SysMusicCompareRecordQueryInfo.StudentMusicCompareRecord> queryStudentTrain(Map<String, Object> params);
+
+	//小程序学员评测列表
+	int countStudentTrain(Map<String, Object> params);
+
+	SysMusicCompareRecordQueryInfo.StudentMusicCompareRecordStat studentMusicCompareRecordStat(@Param("query") SysMusicCompareRecordQueryInfo.StudentMusicCompareRecordQuery query);
+
+	//学生端训练统计
+	SysMusicCompareRecordQueryInfo.StudentMusicCompareRecordDto studentTrainStat(@Param("query") SysMusicCompareRecordQueryInfo.StudentMusicCompareRecordQuery query);
+
+	//统计用户指定周训练数据
+	SysMusicCompareWeekData getUserWeekCompareData(@Param("userId") Long userId,
+												   @Param("monday") String monday);
 }

+ 20 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysMusicCompareWeekDataDao.java

@@ -0,0 +1,20 @@
+package com.yonge.cooleshow.biz.dal.dao;
+
+import com.yonge.cooleshow.biz.dal.entity.SysMusicCompareWeekData;
+import com.yonge.cooleshow.biz.dal.queryInfo.SysMusicCompareRecordQueryInfo;
+import com.yonge.toolset.mybatis.dal.BaseDAO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface SysMusicCompareWeekDataDao extends BaseDAO<Integer, SysMusicCompareWeekData> {
+
+    SysMusicCompareWeekData getWithUserAndMonday(@Param("userId") Long userId,
+                                                 @Param("monday") String monday);
+
+    List<SysMusicCompareRecordQueryInfo.MusicCompareRankingDto> getUserTrainStat(@Param("monday") String monday,
+                                                                                 @Param("orderType") Integer orderType,
+                                                                                 @Param("heardLevel") String heardLevel,
+                                                                                 @Param("tenantId") Long tenantId);
+	
+}

+ 13 - 5
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/TeacherDao.java

@@ -15,6 +15,7 @@ import com.yonge.cooleshow.biz.dal.vo.MyFens;
 import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
 
 import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper;
 import org.apache.ibatis.annotations.Param;
 
 public interface TeacherDao extends BaseMapper<Teacher> {
@@ -33,18 +34,18 @@ public interface TeacherDao extends BaseMapper<Teacher> {
     List<TeacherVo> selectPage(@Param("page") IPage page, @Param("param") TeacherSearch teacher);
 
     /**
-     * @description: 获取用户基本信息
      * @param userId
      * @return com.yonge.cooleshow.biz.dal.dto.BasicUserInfo
+     * @description: 获取用户基本信息
      * @author zx
      * @date 2022/3/22 13:52
      */
     BasicUserInfo getBasicUserInfo(@Param("userId") Long userId);
 
     /**
-     * @description: 获取用户基本信息
      * @param studentIds
      * @return com.yonge.cooleshow.biz.dal.dto.BasicUserInfo
+     * @description: 获取用户基本信息
      * @author zx
      * @date 2022/3/22 13:52
      */
@@ -85,26 +86,33 @@ public interface TeacherDao extends BaseMapper<Teacher> {
      * @updateTime 2022/5/9 10:17
      * @return: java.util.List<com.yonge.cooleshow.biz.dal.entity.Subject>
      */
-    List<Subject> querySubjectItem(@Param("userId") Long userId, @Param("type")String type);
+    List<Subject> querySubjectItem(@Param("userId") Long userId, @Param("type") String type);
 
     /**
      * 查询我的粉丝
-     * @param page IPage<MyFens>
+     *
+     * @param page  IPage<MyFens>
      * @param query TeacherQueryInfo.FansQuery
      * @return List<MyFens>
      */
     List<MyFens> queryMyFans(@Param("page") IPage<MyFens> page, @Param("record") TeacherQueryInfo.FansQuery query);
-    
+
     /**
      * 查询热门老师
+     *
      * @return
      */
     List<HotTeacherVo> queryHotTeacherList(Long subjectId);
 
     /**
      * 老师学生人数统计
+     *
      * @param teacherIds 老师ID
      * @return List<StatGroupWrapper>
      */
     List<StatGroupWrapper> selectTeacherStudentNumberStatInfo(@Param("teacherIds") List<Long> teacherIds);
+
+    List<TenantInfoWrapper.UserCount> countTeacherByTenantIds(@Param("tenantIdList") List<Long> tenantIdList);
+
+    Integer queryTeacherCounts(@Param("id") Long id);
 }

+ 12 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/UserOrderDao.java

@@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.yonge.cooleshow.biz.dal.entity.UserOrder;
 import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
+import com.yonge.cooleshow.biz.dal.wrapper.PaymentDivMemberRecordWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import org.apache.ibatis.annotations.Param;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderVo;
 import com.yonge.cooleshow.biz.dal.dto.search.OrderSearch;
@@ -89,4 +91,14 @@ public interface UserOrderDao extends BaseMapper<UserOrder>{
 	 */
     UserOrderVo getUserOrderByPaymentNoOrTransNo(@Param("paymentNo") String paymentNo,
 												 @Param("transNo") String transNo);
+
+    List<UserOrder> selectPaymentOrderPage(@Param("page") IPage<UserPaymentOrderWrapper.UserPaymentOrder> page,
+                                           @Param("query") UserPaymentOrderWrapper.UserPaymentOrderQuery query);
+
+	//首页支出明细列表
+    List<PaymentDivMemberRecordWrapper.IndexIncomeQueryDto> queryExpend(@Param("page") IPage<PaymentDivMemberRecordWrapper.IndexIncomeQueryDto> page,
+																		@Param("param") PaymentDivMemberRecordWrapper.IndexIncomeQuery param);
+
+	//小程序首页订单详情
+	PaymentDivMemberRecordWrapper.OrderDetailDto getExpendOrderDetail(@Param("orderNo") String orderNo);
 }

+ 12 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/req/TeacherSubmitReq.java

@@ -1,16 +1,18 @@
 package com.yonge.cooleshow.biz.dal.dto.req;
 
+import com.yonge.cooleshow.common.enums.ESettlementFrom;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
-
-import java.io.Serializable;
+import lombok.Data;
 
 import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
 
 /**
  * @Author: liweifan
  * @Data: 2022/3/18 14:56
  */
+@Data
 @ApiModel(value = "TeacherSubmitReq对象", description = "新增/修改老师对象")
 public class TeacherSubmitReq implements Serializable {
 
@@ -45,6 +47,14 @@ public class TeacherSubmitReq implements Serializable {
     @ApiModelProperty("是否测试用户")
 	private Boolean isTestUser;
 
+    @ApiModelProperty("所属机构,平台为-1")
+    private Long tenantId;
+
+    @ApiModelProperty("结算方式")
+    private ESettlementFrom settlementFrom;
+
+    @ApiModelProperty("是否解绑")
+    private Boolean bindTenant;
 
     public Long getUserId() {
         return userId;

+ 1 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/MusicSheetSearch.java

@@ -45,7 +45,7 @@ public class MusicSheetSearch  extends QueryInfo{
     @ApiModelProperty(hidden = true)
     private List<Long> subjectIdList;
 
-    @ApiModelProperty(value = "曲目来源类型 TEACHER 老师 PLATFORM 平台")
+    @ApiModelProperty(value = "曲目来源类型 TEACHER 老师 PLATFORM 平台 TENANT 机构")
     private SourceTypeEnum sourceType;
 
     @ApiModelProperty("曲目状态(0:停用,1:启用))")

Vissa filer visades inte eftersom för många filer har ändrats