Browse Source

Merge remote-tracking branch 'origin/feature/0721-tenant' into feature/0721-tenant

zouxuan 2 years ago
parent
commit
f93dabd66b
75 changed files with 3324 additions and 300 deletions
  1. 18 0
      cooleshow-auth/auth-api/pom.xml
  2. 10 0
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/LoginEntity.java
  3. 95 0
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/WxConfigInfo.java
  4. 55 0
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/WxTemplateConfig.java
  5. 63 0
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/WxTemplateMessage.java
  6. 4 1
      cooleshow-auth/auth-server/pom.xml
  7. 14 10
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/config/WebSecurityConfig.java
  8. 3 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/filter/PhoneLoginAuthenticationFilter.java
  9. 15 8
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/handler/BaseAuthenticationFailureEvenHandler.java
  10. 147 82
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/provider/PhoneAuthenticationProvider.java
  11. 7 8
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/SysUserDao.java
  12. 27 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/WxConfigInfoMapper.java
  13. 27 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/WxTemplateConfigMapper.java
  14. 27 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/WxTemplateMessageMapper.java
  15. 63 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/wrapper/WxConfigInfoWrapper.java
  16. 63 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/wrapper/WxTemplateConfigWrapper.java
  17. 63 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/wrapper/WxTemplateMessageWrapper.java
  18. 76 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/enums/ELoginType.java
  19. 50 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/MWxMpService.java
  20. 43 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/WxCacheService.java
  21. 113 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/domain/WxConfigStorageWrapper.java
  22. 25 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/domain/WxContentWrapper.java
  23. 51 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/handler/WxMessageRouteEvent.java
  24. 292 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/impl/MWxMpServiceImpl.java
  25. 115 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/impl/WxCacheServiceImpl.java
  26. 10 4
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/SysUserService.java
  27. 67 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/WxConfigInfoService.java
  28. 43 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/WxTemplateConfigService.java
  29. 43 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/WxTemplateMessageService.java
  30. 14 5
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/SysUserServiceImpl.java
  31. 145 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/WxConfigInfoServiceImpl.java
  32. 65 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/WxTemplateConfigServiceImpl.java
  33. 65 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/WxTemplateMessageServiceImpl.java
  34. 1 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/web/controller/TokenController.java
  35. 20 0
      cooleshow-auth/auth-server/src/main/resources/config/mybatis/SysUserMapper.xml
  36. 35 0
      cooleshow-auth/auth-server/src/main/resources/config/mybatis/WxConfigInfoMapper.xml
  37. 25 0
      cooleshow-auth/auth-server/src/main/resources/config/mybatis/WxTemplateConfigMapper.xml
  38. 27 0
      cooleshow-auth/auth-server/src/main/resources/config/mybatis/WxTemplateMessageMapper.xml
  39. 21 15
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/controller/BaseController.java
  40. 70 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/SysGoodsPriceController.java
  41. 146 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantAlbumController.java
  42. 15 5
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantInfoController.java
  43. 1 23
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantUnbindRecordController.java
  44. 131 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/TenantAlbumVo.java
  45. 2 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/TenantAlbumMusic.java
  46. 36 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/SubjectTypeEnum.java
  47. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/TenantAlbumMapper.java
  48. 3 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/TenantAlbumRefMapper.java
  49. 6 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/TenantInfoMapper.java
  50. 26 10
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantActivationCodeService.java
  51. 3 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumRefService.java
  52. 20 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumService.java
  53. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantInfoService.java
  54. 6 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantUnbindRecordService.java
  55. 90 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantActivationCodeServiceImpl.java
  56. 8 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantAlbumRefServiceImpl.java
  57. 79 63
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantAlbumServiceImpl.java
  58. 17 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantInfoServiceImpl.java
  59. 144 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantUnbindRecordServiceImpl.java
  60. 43 6
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/SysGoodsPriceWrapper.java
  61. 32 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantActivationCodeWrapper.java
  62. 79 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantAlbumWrapper.java
  63. 13 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantUnbindRecordWrapper.java
  64. 11 1
      cooleshow-user/user-biz/src/main/resources/config/mybatis/TenantAlbumMapper.xml
  65. 6 1
      cooleshow-user/user-biz/src/main/resources/config/mybatis/TenantAlbumRefMapper.xml
  66. 30 6
      cooleshow-user/user-biz/src/main/resources/config/mybatis/TenantInfoMapper.xml
  67. 4 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/TenantUnbindRecordMapper.xml
  68. 3 2
      cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/StudentController.java
  69. 91 0
      cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/TenantActivationCodeController.java
  70. 1 1
      cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/TenantAlbumController.java
  71. 100 0
      cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/TenantUnbindRecordController.java
  72. 35 21
      cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/open/OpenTenantController.java
  73. 1 1
      cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/vo/TenantActivationCodeVo.java
  74. 12 2
      pom.xml
  75. 10 0
      toolset/toolset-base/src/main/java/com/yonge/toolset/base/exception/BizException.java

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

@@ -33,5 +33,23 @@
 			<groupId>com.yonge.cooleshow</groupId>
 			<groupId>com.yonge.cooleshow</groupId>
 			<artifactId>cooleshow-common</artifactId>
 			<artifactId>cooleshow-common</artifactId>
 		</dependency>
 		</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>
 	</dependencies>
 </project>
 </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 qrCode;
     //关联帐号授权码
     //关联帐号授权码
     private String authToken;
     private String authToken;
+    // 登录类型
+    private String loginType;
     
     
     public Boolean getIsSurportRegister() {
     public Boolean getIsSurportRegister() {
 		return isSurportRegister;
 		return isSurportRegister;
@@ -92,4 +94,12 @@ public class LoginEntity {
     public void setAuthToken(String authToken) {
     public void setAuthToken(String authToken) {
         this.authToken = authToken;
         this.authToken = authToken;
     }
     }
+
+    public String getLoginType() {
+        return loginType;
+    }
+
+    public void setLoginType(String loginType) {
+        this.loginType = loginType;
+    }
 }
 }

+ 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>
         <artifactId>cooleshow-auth</artifactId>
         <version>1.0</version>
         <version>1.0</version>
     </parent>
     </parent>
-    <groupId>com.yonge.cooleshow</groupId>
     <artifactId>auth-server</artifactId>
     <artifactId>auth-server</artifactId>
     <version>1.0</version>
     <version>1.0</version>
     <name>auth-server</name>
     <name>auth-server</name>
@@ -23,6 +22,10 @@
             <artifactId>microsvc-config-jwt</artifactId>
             <artifactId>microsvc-config-jwt</artifactId>
         </dependency>
         </dependency>
         <dependency>
         <dependency>
+            <groupId>com.microsvc.toolkit.middleware</groupId>
+            <artifactId>microsvc-middleware-wechat</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.springframework.security</groupId>
             <groupId>org.springframework.security</groupId>
             <artifactId>spring-security-jwt</artifactId>
             <artifactId>spring-security-jwt</artifactId>
             <version>1.0.9.RELEASE</version>
             <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;
 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.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 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.crypto.password.PasswordEncoder;
 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
 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
 @Configuration
 @EnableWebSecurity
 @EnableWebSecurity
 @EnableGlobalMethodSecurity(prePostEnabled = true)//会拦截注解了@PreAuthrize注解的配置.
 @EnableGlobalMethodSecurity(prePostEnabled = true)//会拦截注解了@PreAuthrize注解的配置.
@@ -48,6 +48,9 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 	@Autowired
 	@Autowired
 	private SysUserDeviceService sysUserDeviceService;
 	private SysUserDeviceService sysUserDeviceService;
 
 
+	@Autowired
+	private WxCacheService wxCacheService;
+
 	@Override
 	@Override
 	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 		auth.authenticationProvider(daoAuthenticationProvider());
 		auth.authenticationProvider(daoAuthenticationProvider());
@@ -110,6 +113,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
         provider.setSmsCodeService(smsCodeService);
         provider.setSmsCodeService(smsCodeService);
         provider.setSysUserService(sysUserService);
         provider.setSysUserService(sysUserService);
         provider.setSysUserDeviceService(sysUserDeviceService);
         provider.setSysUserDeviceService(sysUserDeviceService);
+		provider.setWxCacheService(wxCacheService);
 		// 禁止隐藏用户未找到异常
 		// 禁止隐藏用户未找到异常
 		provider.setHideUserNotFoundExceptions(false);
 		provider.setHideUserNotFoundExceptions(false);
         return provider;
         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 LOGIN_USER_TYPE = "loginUserType";
 	private static final String QR_CODE = "qrCode";
 	private static final String QR_CODE = "qrCode";
 	private static final String AUTH_TOKEN = "token";
 	private static final String AUTH_TOKEN = "token";
+	private static final String LOGIN_TYPE = "loginType";
 
 
 	private static final String DEVICE_NUM = "deviceNum";
 	private static final String DEVICE_NUM = "deviceNum";
 
 
@@ -51,6 +52,7 @@ public class PhoneLoginAuthenticationFilter extends AbstractAuthenticationProces
 		String loginUserType = obtainParameter(request, LOGIN_USER_TYPE);
 		String loginUserType = obtainParameter(request, LOGIN_USER_TYPE);
 		String qrCode = obtainParameter(request, QR_CODE);
 		String qrCode = obtainParameter(request, QR_CODE);
 		String authToken = obtainParameter(request, AUTH_TOKEN);
 		String authToken = obtainParameter(request, AUTH_TOKEN);
+		String loginType = obtainParameter(request, LOGIN_TYPE);
 
 
 		String clientId = request.getParameter(clientIdParameter).toUpperCase();
 		String clientId = request.getParameter(clientIdParameter).toUpperCase();
 
 
@@ -71,6 +73,7 @@ public class PhoneLoginAuthenticationFilter extends AbstractAuthenticationProces
 		loginEntity.setDeviceNum(deviceNum);
 		loginEntity.setDeviceNum(deviceNum);
 		loginEntity.setQrCode(qrCode);
 		loginEntity.setQrCode(qrCode);
 		loginEntity.setAuthToken(authToken);
 		loginEntity.setAuthToken(authToken);
+		loginEntity.setLoginType(loginType);
 
 
 		authRequest = new PhoneAuthenticationToken(SecurityConstants.PHONE_PRINCIPAL_PREFIX + principal, loginEntity);
 		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;
 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.apache.http.HttpStatus;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
@@ -13,8 +10,9 @@ import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler;
 import org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler;
 import org.springframework.stereotype.Component;
 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
 @Component
 public class BaseAuthenticationFailureEvenHandler extends ExceptionMappingAuthenticationFailureHandler {
 public class BaseAuthenticationFailureEvenHandler extends ExceptionMappingAuthenticationFailureHandler {
@@ -30,6 +28,8 @@ public class BaseAuthenticationFailureEvenHandler extends ExceptionMappingAuthen
     	int resultCode = HttpStatus.SC_CONFLICT;
     	int resultCode = HttpStatus.SC_CONFLICT;
     	
     	
         String message = exception.getLocalizedMessage();
         String message = exception.getLocalizedMessage();
+
+        String data = null;
         if (message.equals("Bad credentials")) {
         if (message.equals("Bad credentials")) {
             message = "用户名或密码错误";
             message = "用户名或密码错误";
         }else if(message.equals("User is disabled")){
         }else if(message.equals("User is disabled")){
@@ -37,9 +37,16 @@ public class BaseAuthenticationFailureEvenHandler extends ExceptionMappingAuthen
         }else if(message.equals("404.9")){
         }else if(message.equals("404.9")){
         	message = "用户名或密码错误";
         	message = "用户名或密码错误";
         	resultCode = 99;
         	resultCode = 99;
+        } else if (message.startsWith("MA:404:")) {
+            // 返回用户绑定openId
+            data = message.split(":")[2];
+            // 用户未绑定openId错误码
+            resultCode = 5001;
+            // 用户未绑定openId错误信息
+            message = "用户未绑定小程序账号";
         }
         }
         logger.info("登录失败,异常:{}", 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.setContentType("application/json; charset=utf-8");
         response.getWriter().write(objectMapper.writeValueAsString(result));
         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;
 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.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.dto.SysUserInfo;
 import com.yonge.cooleshow.auth.api.entity.LoginEntity;
 import com.yonge.cooleshow.auth.api.entity.LoginEntity;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.config.token.PhoneAuthenticationToken;
 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.SysUserDeviceService;
 import com.yonge.cooleshow.auth.service.SysUserService;
 import com.yonge.cooleshow.auth.service.SysUserService;
+import com.yonge.cooleshow.common.security.SecurityConstants;
 import com.yonge.cooleshow.common.service.IdGeneratorService;
 import com.yonge.cooleshow.common.service.IdGeneratorService;
-import com.yonge.toolset.base.exception.BizException;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.BadCredentialsException;
@@ -27,6 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
 import java.security.interfaces.RSAPublicKey;
 import java.security.interfaces.RSAPublicKey;
 import java.util.Date;
 import java.util.Date;
 import java.util.Objects;
 import java.util.Objects;
+
 @Slf4j
 @Slf4j
 public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider {
 public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider {
 
 
@@ -38,6 +45,8 @@ public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider
 
 
     private SysUserDeviceService sysUserDeviceService;
     private SysUserDeviceService sysUserDeviceService;
 
 
+    private WxCacheService wxCacheService;
+
     @Override
     @Override
     protected void additionalAuthenticationChecks(UserDetails userDetails, Authentication authentication) throws AuthenticationException {
     protected void additionalAuthenticationChecks(UserDetails userDetails, Authentication authentication) throws AuthenticationException {
         if (authentication.getCredentials() == null) {
         if (authentication.getCredentials() == null) {
@@ -59,111 +68,163 @@ public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider
         String qrCode = loginEntity.getQrCode();
         String qrCode = loginEntity.getQrCode();
         // 授权Token登录
         // 授权Token登录
         String authToken = loginEntity.getAuthToken();
         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 {
             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) {
             } 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("用户不存在");
                     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("用户不存在");
                     throw new LockedException("用户不存在");
                 }
                 }
-            }else{
-                throw new LockedException("用户不存在");
+                sysUserService.update(user);
             }
             }
-            sysUserService.update(user);
+
         }
         }
+
         return login(username);
         return login(username);
     }
     }
 
 
@@ -211,4 +272,8 @@ public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider
     public void setSysUserDeviceService(SysUserDeviceService sysUserDeviceService) {
     public void setSysUserDeviceService(SysUserDeviceService sysUserDeviceService) {
         this.sysUserDeviceService = sysUserDeviceService;
         this.sysUserDeviceService = sysUserDeviceService;
     }
     }
+
+    public void setWxCacheService(WxCacheService wxCacheService) {
+        this.wxCacheService = wxCacheService;
+    }
 }
 }

+ 7 - 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;
 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.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
 import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
 import com.yonge.cooleshow.auth.api.dto.UserSetReq;
 import com.yonge.cooleshow.auth.api.dto.UserSetReq;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 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.cooleshow.auth.api.vo.UserSetVo;
-import com.yonge.toolset.mybatis.dal.BaseDAO;
 import com.yonge.cooleshow.common.entity.ImUserModel;
 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> {
 public interface SysUserDao extends BaseDAO<Long, SysUser> {
 
 
@@ -176,4 +173,6 @@ public interface SysUserDao extends BaseDAO<Long, SysUser> {
     void updateLockStatus(@Param("userId")Long userId, @Param("lockFlag") Integer lockFlag, @Param("sysUserType")  String sysUserType);
     void updateLockStatus(@Param("userId")Long userId, @Param("lockFlag") Integer lockFlag, @Param("sysUserType")  String sysUserType);
 
 
     Long getTenantByClient(@Param("userId") Long userId, @Param("clientId") String clientId);
     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);
+        }
+	}
+
+}

+ 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) {
+
+    }
+}

+ 10 - 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;
 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.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.dto.SysUserInfo;
 import com.yonge.cooleshow.auth.api.dto.SysUserInfo;
 import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
 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.api.vo.UserSetVo;
 import com.yonge.cooleshow.auth.enums.EClientType;
 import com.yonge.cooleshow.auth.enums.EClientType;
 import com.yonge.cooleshow.common.entity.ImUserModel;
 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 com.yonge.toolset.mybatis.service.BaseService;
 
 
+import java.util.List;
+
 public interface SysUserService extends BaseService<Long, SysUser> {
 public interface SysUserService extends BaseService<Long, SysUser> {
 
 
     /**
     /**
@@ -214,4 +212,12 @@ public interface SysUserService extends BaseService<Long, SysUser> {
 
 
     //根据用户类型获取机构编号
     //根据用户类型获取机构编号
     Long getTenantByClient(Long userId, String clientId);
     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);
+
+}

+ 14 - 5
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.alibaba.fastjson.JSON;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
 import com.yonge.cooleshow.api.feign.AdminFeignService;
 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.api.feign.dto.UserFriendInfoVO;
 import com.yonge.cooleshow.auth.api.dto.QRLoginDto;
 import com.yonge.cooleshow.auth.api.dto.QRLoginDto;
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
@@ -69,8 +68,6 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
     private AdminFeignService adminFeignService;
     private AdminFeignService adminFeignService;
     @Autowired
     @Autowired
     private CustomerServiceConfig customerServiceConfig;
     private CustomerServiceConfig customerServiceConfig;
-    @Autowired
-    private TeacherFeignService teacherFeignService;
 
 
     @Override
     @Override
     public BaseDAO<Long, SysUser> getDAO() {
     public BaseDAO<Long, SysUser> getDAO() {
@@ -120,12 +117,12 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
         userInfo.setSysUser(sysUser);
         userInfo.setSysUser(sysUser);
 
 
         List<String> roleCodeList = sysUserRoleService.queryRoleCodeListByUserId(sysUser.getId());
         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<Long> roleIdList = sysUserRoleService.queryRoleIdListByUserId(sysUser.getId());
         List<String> permissionList = sysRoleMenuService.queryPermissionsByRoleIdList(roleIdList);
         List<String> permissionList = sysRoleMenuService.queryPermissionsByRoleIdList(roleIdList);
 
 
-        userInfo.setPermissions(permissionList.toArray(new String[permissionList.size()]));
+        userInfo.setPermissions(permissionList.toArray(new String[0]));
 
 
         return userInfo;
         return userInfo;
     }
     }
@@ -410,4 +407,16 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
         // 查询用户机构信息,若没有则返回-1
         // 查询用户机构信息,若没有则返回-1
         return Optional.ofNullable(sysUserDao.getTenantByClient(userId, clientId)).orElse(-1L);
         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));
+    }
+}

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

@@ -79,6 +79,7 @@ public class TokenController extends BaseController {
             @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
             @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
             @ApiImplicitParam(name = "smsCode", value = "验证码", required = true, dataType = "String"),
             @ApiImplicitParam(name = "smsCode", value = "验证码", required = true, dataType = "String"),
             @ApiImplicitParam(name = "isSurportRegister", value = "是否在登录时注册", dataType = "Boolean"),
             @ApiImplicitParam(name = "isSurportRegister", value = "是否在登录时注册", dataType = "Boolean"),
+            @ApiImplicitParam(name = "loginType", value = "登陆类型", dataType = "String", defaultValue = "PASSWORD"),
             @ApiImplicitParam(name = "loginUserType", value = "登录用户类型 STUDENT TEACHER(官网登录)", dataType = "String")
             @ApiImplicitParam(name = "loginUserType", value = "登录用户类型 STUDENT TEACHER(官网登录)", dataType = "String")
     })
     })
     public Object smsLogin() {
     public Object smsLogin() {

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

@@ -335,4 +335,24 @@
         </if>
         </if>
     </update>
     </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>
 </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>

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

@@ -1,14 +1,11 @@
 package com.yonge.cooleshow.common.controller;
 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.codec.binary.Base64;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 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.ControllerAdvice;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 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
 @ControllerAdvice
 public class BaseController {
 public class BaseController {
@@ -111,6 +109,14 @@ public class BaseController {
             if (e.getMessage().equals("205")) {
             if (e.getMessage().equals("205")) {
                 return failed(HttpStatus.RESET_CONTENT, e.getMessage());
                 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());
             return failed(e.getMessage());
         } else if (e instanceof AccessDeniedException) {
         } else if (e instanceof AccessDeniedException) {
             return failed("禁止访问");
             return failed("禁止访问");

+ 70 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/SysGoodsPriceController.java

@@ -0,0 +1,70 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+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(PageUtil.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));
+    }
+
+
+}

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

@@ -0,0 +1,146 @@
+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.admin.io.request.TenantAlbumVo;
+import com.yonge.cooleshow.api.feign.dto.TenantWrapper;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.*;
+import com.yonge.cooleshow.biz.dal.enums.SubjectTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.TenantAlbumMusicService;
+import com.yonge.cooleshow.biz.dal.service.TenantAlbumRefService;
+import com.yonge.cooleshow.biz.dal.service.TenantAlbumService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.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.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+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 SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    /**
+     * 查询分页
+     *
+     * @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 query 详情ID
+     * @return TenantAlbum
+     */
+    @PostMapping("/detail")
+    @ApiOperation(value = "查询详情", notes = "detail")
+    //@PreAuthorize("@pcs.hasPermissions('tenantAlbum/detail')")
+    public HttpResponseResult<TenantAlbumVo.TenantAlbum> detail(@RequestBody TenantAlbumVo.TenantAlbum query) {
+
+        TenantAlbumVo.TenantAlbum vo = new TenantAlbumVo.TenantAlbum();
+        Long id = query.getId();
+        TenantAlbum tenantAlbum= tenantAlbumService.detail(id);
+        //查关联表
+        TenantAlbumRef ref = tenantAlbumRefService.getBytenantAlbumId(id);
+        vo.setTenantId(ref.getTenantId());
+        //查询机构专辑表
+        vo.setName(tenantAlbum.getName());
+        vo.setDescribe(tenantAlbum.getDescribe());
+        vo.setCoverImg(tenantAlbum.getCoverImg());
+        vo.setPurchaseCycle(tenantAlbum.getPurchaseCycle());
+        vo.setSalePrice(tenantAlbum.getSalePrice());
+        //查询曲目表
+
+        List<TenantAlbumVo.MusicSheetData> data = query.getMusicSheetData();
+
+        List<TenantAlbumMusic> tenantAlbumMusics = query.getMusicSheetData().stream().map(next -> {
+
+            AtomicInteger sort = new AtomicInteger(0);
+            return next.getMusicSheetIdList().stream().map(tenantAlbumMusic -> {
+
+                TenantAlbumMusic tenantAlbumMusic1 = new TenantAlbumMusic();
+                //tenantAlbumMusic1.setId(tenantAlbumMusic);
+                tenantAlbumMusic1.setSubjectType(next.getSubjectType());
+                tenantAlbumMusic1.setTenantId(query.getTenantId());
+                tenantAlbumMusic1.setMusicSheetId(tenantAlbumMusic);
+                tenantAlbumMusic1.setDelFlag(true);
+                tenantAlbumMusic1.setTenantAlbumId(tenantAlbum.getId());
+                tenantAlbumMusic1.setSortNumber(sort.getAndIncrement());
+                return tenantAlbumMusic1;
+            }).collect(Collectors.toList());
+
+        }).flatMap(Collection::stream).collect(Collectors.toList());
+
+
+        vo.setTenantAlbumMusics(tenantAlbumMusics);
+
+/*        List<TenantAlbumVo.MusicSheetData> dataList = query.getMusicSheetData();
+        TenantAlbumVo.MusicSheetData data = dataList.get(0);
+        List<Long> list = data.getMusicSheetIdList();
+        data.getSubjectType();
+        Long musicId = list.get(0);
+
+        tenantAlbumMusicService.detail(musicId);*/
+        return HttpResponseResult.succeed(vo);
+    }
+
+
+    /**
+     * 新增专辑
+     */
+    @PostMapping("/insert")
+    @ApiOperation(value = "新增专辑", notes = "新增专辑")
+    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/insert')")
+    public HttpResponseResult<Boolean> insertTenantAlbum( @RequestBody TenantAlbumWrapper.TenantAlbum album) {
+
+
+        return HttpResponseResult.succeed(tenantAlbumService.insertTenantAlbum(album));
+    }
+
+
+}

+ 15 - 5
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantInfoController.java

@@ -39,13 +39,15 @@ public class TenantInfoController extends BaseController {
      */
      */
     @PostMapping("/page")
     @PostMapping("/page")
     @ApiOperation(value = "查询分页", notes = "TenantInfo")
     @ApiOperation(value = "查询分页", notes = "TenantInfo")
-    //@PreAuthorize("@pcs.hasPermissions('tenantInfo/page')")
+    @PreAuthorize("@pcs.hasPermissions('tenantInfo/page')")
     public HttpResponseResult<PageInfo<TenantInfoWrapper.TenantInfo>> page(@RequestBody TenantInfoWrapper.TenantInfoQuery query) {
     public HttpResponseResult<PageInfo<TenantInfoWrapper.TenantInfo>> page(@RequestBody TenantInfoWrapper.TenantInfoQuery query) {
 
 
         IPage<TenantInfoWrapper.TenantInfo> pages = tenantInfoService.selectPage(PageUtil.getPage(query), query);
         IPage<TenantInfoWrapper.TenantInfo> pages = tenantInfoService.selectPage(PageUtil.getPage(query), query);
         return succeed(PageUtil.pageInfo(pages));
         return succeed(PageUtil.pageInfo(pages));
     }
     }
 
 
+
+
     /**
     /**
      * 修改数据
      * 修改数据
      */
      */
@@ -57,6 +59,18 @@ public class TenantInfoController extends BaseController {
         return succeed(tenantInfoService.updateTenantInfo(info));
         return succeed(tenantInfoService.updateTenantInfo(info));
     }
     }
 
 
+    /**
+     * 查看详情
+     */
+    @PostMapping("/detail")
+    @ApiOperation(value = "查看详情", notes = "查看详情")
+    @PreAuthorize("@pcs.hasPermissions('tenantInfo/detail')")
+    public HttpResponseResult<TenantInfoWrapper.TenantInfo > detail(@Valid @RequestBody TenantInfo info) {
+        Long id = info.getId();
+        return succeed(tenantInfoService.Infodetail(id));
+    }
+
+
 
 
     /**
     /**
      * 插入数据
      * 插入数据
@@ -137,7 +151,3 @@ public class TenantInfoController extends BaseController {
 
 
 
 
 }
 }
-
-
-
-//sysUser     tenantStaff

+ 1 - 23
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantUnbindRecordController.java

@@ -108,30 +108,8 @@ public class TenantUnbindRecordController extends BaseController {
         if (audio.getId() == null || audio.getStatus() == null) {
         if (audio.getId() == null || audio.getStatus() == null) {
             throw new BizException("参数错误");
             throw new BizException("参数错误");
         }
         }
+        Boolean entry = tenantUnbindRecordService.entry(audio);
 
 
-        boolean update = tenantUnbindRecordService.lambdaUpdate()
-                .set(TenantUnbindRecord::getStatus, audio.getStatus() ? "PASS" : "UNPASS")
-                .set(TenantUnbindRecord::getReason, audio.getReason())
-                .set(TenantUnbindRecord::getVerifyUserId, sysUserFeignService.queryUserInfo().getId())
-                .eq(TenantUnbindRecord::getId, audio.getId())
-                .eq(TenantUnbindRecord::getStatus, "DOING").update();
-        if (!update) {
-            throw new BizException("审核失败,请刷新后重试");
-        }
-
-        if (audio.getStatus()) {
-            TenantUnbindRecord unbindRecord = tenantUnbindRecordService.getById(audio.getId());
-            String userType = unbindRecord.getUserType();
-            if ("STUDENT".equals(userType)) {
-                studentService.lambdaUpdate()
-                        .set(Student::getTenantId, -1L)
-                        .eq(Student::getUserId, unbindRecord.getUserId()).update();
-            } else if ("TEACHER".equals(userType)) {
-                teacherService.lambdaUpdate()
-                        .set(Teacher::getTenantId, -1L)
-                        .eq(Teacher::getUserId, unbindRecord.getUserId()).update();
-            }
-        }
         return succeed();
         return succeed();
     }
     }
 
 

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

@@ -0,0 +1,131 @@
+package com.yonge.cooleshow.admin.io.request;
+
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+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;
+
+/**
+ * 机构专辑
+ * 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 Integer musicNum;
+
+
+        @ApiModelProperty("平台价格")
+        private BigDecimal originalPrice;
+
+
+        @ApiModelProperty("机构价格")
+        private BigDecimal salePrice;
+
+
+        @ApiModelProperty("购买周期")
+        private Integer purchaseCycle;
+
+
+        @ApiModelProperty("曲目声部分类(多个,分隔)")
+        private String subjectTypes;
+
+
+        @ApiModelProperty("启用状态")
+        private Boolean status;
+
+
+        @ApiModelProperty("删除标识")
+        private Boolean delFlag;
+
+
+        @ApiModelProperty("更新时间")
+        private Date updateTime;
+
+
+        @ApiModelProperty("创建时间")
+        private Date createTime;
+
+        @ApiModelProperty("曲目相关信息")
+        private List<MusicSheetData> musicSheetData = new ArrayList<>();
+
+
+        private List<TenantAlbumMusic> tenantAlbumMusics = new ArrayList<>();
+
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static TenantAlbum from(String json) {
+            return JSON.parseObject(json, TenantAlbum.class);
+        }
+    }
+
+    @Data
+    public static class MusicSheetData{
+        private SubjectTypeEnum subjectType;
+
+        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;
+    }
+
+}

+ 2 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/TenantAlbumMusic.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.IdType;
+import com.yonge.cooleshow.biz.dal.enums.SubjectTypeEnum;
 import lombok.Data;
 import lombok.Data;
 
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModel;
@@ -32,7 +33,7 @@ public class TenantAlbumMusic implements Serializable {
 
 
     @ApiModelProperty("声部分类(ENSEMBLE, MUSIC, SUBJECT)") 
     @ApiModelProperty("声部分类(ENSEMBLE, MUSIC, SUBJECT)") 
 	@TableField(value = "subject_type_")
 	@TableField(value = "subject_type_")
-    private String subjectType;
+    private SubjectTypeEnum subjectType;
 
 
     @ApiModelProperty("机构专辑ID") 
     @ApiModelProperty("机构专辑ID") 
 	@TableField(value = "tenant_album_id_")
 	@TableField(value = "tenant_album_id_")

+ 36 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/SubjectTypeEnum.java

@@ -0,0 +1,36 @@
+package com.yonge.cooleshow.biz.dal.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+/**
+ * Description 审核状态(0:待审核;1:通过;2:未通过)
+ *
+ * @author: haonan
+ * @date: 2023-07-28
+ */
+public enum SubjectTypeEnum implements BaseEnum<String, SubjectTypeEnum> {
+
+
+    ENSEMBLE("合奏"),
+    MUSIC("小曲目"),
+    SUBJECT("声部");
+
+    @EnumValue
+    private String code;
+    private String msg;
+
+    SubjectTypeEnum(String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public String getMsg() {
+        return this.msg;
+    }
+
+    @Override
+    public String getCode() {
+        return this.code;
+    }
+}

+ 1 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/TenantAlbumMapper.java

@@ -22,6 +22,6 @@ public interface TenantAlbumMapper extends BaseMapper<TenantAlbum> {
 	 * @param param TenantAlbumWrapper.TenantAlbumQuery
 	 * @param param TenantAlbumWrapper.TenantAlbumQuery
 	 * @return List<TenantAlbumWrapper.TenantAlbum>
 	 * @return List<TenantAlbumWrapper.TenantAlbum>
 	 */
 	 */
-	List<TenantAlbum> selectPage(@Param("page") IPage<TenantAlbum> page, @Param("param") TenantAlbumWrapper.TenantAlbumQuery param);
+	List<TenantAlbumWrapper.TenantAlbum> selectPage(@Param("page") IPage<TenantAlbumWrapper.TenantAlbum> page, @Param("param") TenantAlbumWrapper.TenantAlbumQuery param);
 	
 	
 }
 }

+ 3 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/TenantAlbumRefMapper.java

@@ -23,5 +23,7 @@ public interface TenantAlbumRefMapper extends BaseMapper<TenantAlbumRef> {
 	 * @return List<TenantAlbumRefWrapper.TenantAlbumRef>
 	 * @return List<TenantAlbumRefWrapper.TenantAlbumRef>
 	 */
 	 */
 	List<TenantAlbumRef> selectPage(@Param("page") IPage<TenantAlbumRef> page, @Param("param") TenantAlbumRefWrapper.TenantAlbumRefQuery param);
 	List<TenantAlbumRef> selectPage(@Param("page") IPage<TenantAlbumRef> page, @Param("param") TenantAlbumRefWrapper.TenantAlbumRefQuery param);
-	
+
+
+    TenantAlbumRef selectByAlbumId(@Param("id") Long id);
 }
 }

+ 6 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/TenantInfoMapper.java

@@ -53,9 +53,14 @@ public interface TenantInfoMapper extends BaseMapper<TenantInfo> {
 
 
 	TenantInfoWrapper.TenantInfo queryNow(@Param("param") TenantInfoWrapper.TenantInfoQuery query);
 	TenantInfoWrapper.TenantInfo queryNow(@Param("param") TenantInfoWrapper.TenantInfoQuery query);
 
 
-	Boolean insertNow(@Param("info") TenantInfoWrapper.TenantInfo info);
 
 
 	Boolean updateStatusById(@Param("id") long id);
 	Boolean updateStatusById(@Param("id") long id);
 
 
 	Boolean updateUnpassStatusById(@Param("id") long id);
 	Boolean updateUnpassStatusById(@Param("id") long id);
+
+	TenantInfoWrapper.TenantInfo selectInfoById(@Param("id") Long id);
+
+	String queryStudentCount(@Param("id") Long id);
+
+	String queryTeacherCount(@Param("id") Long id);
 }
 }

+ 26 - 10
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantActivationCodeService.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantActivationCodeWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantActivationCodeWrapper;
 import com.yonge.cooleshow.biz.dal.entity.TenantActivationCode;
 import com.yonge.cooleshow.biz.dal.entity.TenantActivationCode;
+import com.yonge.toolset.utils.easyexcel.ExcelDataReaderProperty;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
 
 
 import java.util.List;
 import java.util.List;
@@ -13,49 +14,64 @@ import java.util.List;
  * 机构激活码
  * 机构激活码
  * 2023-07-21 17:32:49
  * 2023-07-21 17:32:49
  */
  */
-public interface TenantActivationCodeService extends IService<TenantActivationCode>  {
+public interface TenantActivationCodeService extends IService<TenantActivationCode> {
 
 
-	/**
+    /**
      * 查询详情
      * 查询详情
+     *
      * @param id 详情ID
      * @param id 详情ID
      * @return TenantActivationCode
      * @return TenantActivationCode
      */
      */
-	TenantActivationCode detail(Long id);
+    TenantActivationCode detail(Long id);
 
 
     /**
     /**
      * 分页查询
      * 分页查询
-     * @param page IPage<TenantActivationCode>
+     *
+     * @param page  IPage<TenantActivationCode>
      * @param query TenantActivationCodeWrapper.TenantActivationCodeQuery
      * @param query TenantActivationCodeWrapper.TenantActivationCodeQuery
      * @return IPage<TenantActivationCode>
      * @return IPage<TenantActivationCode>
      */
      */
     IPage<TenantActivationCodeWrapper.TenantActivationCode> selectPage(IPage<TenantActivationCodeWrapper.TenantActivationCode> page,
     IPage<TenantActivationCodeWrapper.TenantActivationCode> selectPage(IPage<TenantActivationCodeWrapper.TenantActivationCode> page,
                                                                        TenantActivationCodeWrapper.TenantActivationCodeQuery query);
                                                                        TenantActivationCodeWrapper.TenantActivationCodeQuery query);
-	
+
     /**
     /**
      * 添加
      * 添加
+     *
      * @param tenantActivationCode TenantActivationCodeWrapper.TenantActivationCode
      * @param tenantActivationCode TenantActivationCodeWrapper.TenantActivationCode
      * @return Boolean
      * @return Boolean
      */
      */
-     Boolean add(TenantActivationCodeWrapper.TenantActivationCode tenantActivationCode);   
+    Boolean add(TenantActivationCodeWrapper.TenantActivationCode tenantActivationCode);
 
 
     /**
     /**
      * 更新
      * 更新
+     *
      * @param tenantActivationCode TenantActivationCodeWrapper.TenantActivationCode
      * @param tenantActivationCode TenantActivationCodeWrapper.TenantActivationCode
      * @return Boolean
      * @return Boolean
      */
      */
-     Boolean update(TenantActivationCodeWrapper.TenantActivationCode tenantActivationCode);
+    Boolean update(TenantActivationCodeWrapper.TenantActivationCode tenantActivationCode);
 
 
-    void sendActivationCode(Long tenantId, Long tenantAlbumPurchaseId, List<String> activationCodeList, List<Long> studentIdList);
+    void sendActivationCode(Long tenantId, Long tenantAlbumPurchaseId, List<String> activationCodeList,
+                            List<Long> studentIdList);
 
 
     void active(String activationCode, Long studentId);
     void active(String activationCode, Long studentId);
 
 
 
 
-
     /**
     /**
      * 添加用户机构专辑激活记录
      * 添加用户机构专辑激活记录
      *
      *
-     * @param studentId 学生ID
+     * @param studentId         学生ID
      * @param userOrderDetailVo 订单详情
      * @param userOrderDetailVo 订单详情
      */
      */
     void addUserTenantAlbumRecord(Long studentId, UserOrderDetailVo userOrderDetailVo);
     void addUserTenantAlbumRecord(Long studentId, UserOrderDetailVo userOrderDetailVo);
+
+    /**
+     * 导入激活码
+     *
+     * @param dataList              数据列表
+     * @param tenantId              机构ID
+     * @param userId                机构管理员用户ID
+     * @param tenantAlbumPurchaseId 专辑购买的ID
+     */
+    void importActiveCode(List<ExcelDataReaderProperty<TenantActivationCodeWrapper.ImportTemplate>> dataList,
+                          Long tenantId, Long userId, Long tenantAlbumPurchaseId);
 }
 }

+ 3 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumRefService.java

@@ -33,7 +33,7 @@ public interface TenantAlbumRefService extends IService<TenantAlbumRef>  {
      * @param tenantAlbumRef TenantAlbumRefWrapper.TenantAlbumRef
      * @param tenantAlbumRef TenantAlbumRefWrapper.TenantAlbumRef
      * @return Boolean
      * @return Boolean
      */
      */
-     Boolean add(TenantAlbumRefWrapper.TenantAlbumRef tenantAlbumRef);   
+     Boolean add(TenantAlbumRef tenantAlbumRef);
 
 
     /**
     /**
      * 更新
      * 更新
@@ -49,4 +49,6 @@ public interface TenantAlbumRefService extends IService<TenantAlbumRef>  {
      * @return
      * @return
      */
      */
     List<TenantAlbumRef> getByAlbumId(Long tenantAlbumId);
     List<TenantAlbumRef> getByAlbumId(Long tenantAlbumId);
+
+    TenantAlbumRef getBytenantAlbumId(Long id);
 }
 }

+ 20 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumService.java

@@ -26,14 +26,14 @@ public interface TenantAlbumService extends IService<TenantAlbum>  {
      * @param query TenantAlbumWrapper.TenantAlbumQuery
      * @param query TenantAlbumWrapper.TenantAlbumQuery
      * @return IPage<TenantAlbum>
      * @return IPage<TenantAlbum>
      */
      */
-    IPage<TenantAlbum> selectPage(IPage<TenantAlbum> page, TenantAlbumWrapper.TenantAlbumQuery query);
+    IPage<TenantAlbumWrapper.TenantAlbum> selectPage(IPage<TenantAlbumWrapper.TenantAlbum> page, TenantAlbumWrapper.TenantAlbumQuery query);
 	
 	
     /**
     /**
      * 添加
      * 添加
      * @param tenantAlbum TenantAlbumWrapper.TenantAlbum
      * @param tenantAlbum TenantAlbumWrapper.TenantAlbum
      * @return Boolean
      * @return Boolean
      */
      */
-     Boolean add(TenantAlbumWrapper.TenantAlbum tenantAlbum);   
+     Boolean add(TenantAlbum tenantAlbum);
 
 
     /**
     /**
      * 更新
      * 更新
@@ -55,4 +55,22 @@ public interface TenantAlbumService extends IService<TenantAlbum>  {
      * @param userOrderDetailVo
      * @param userOrderDetailVo
      */
      */
     void orderSuccess(UserOrderDetailVo userOrderDetailVo);
     void orderSuccess(UserOrderDetailVo userOrderDetailVo);
+
+    Boolean insertTenantAlbum(TenantAlbumWrapper.TenantAlbum album);
+
+
+    /**
+     * 添加机构专辑数据
+     * @return
+     */
+    //Boolean addTenantAlbum(TenantAlbum album);
+
+    /**
+     * 添加机构Id
+     * @param tenantId
+     * @return
+     */
+    //Boolean addTenantId(Long tenantId);
+
+   // Boolean addMusicSheet(List<com.yonge.cooleshow.admin.io.request.TenantAlbumVo.MusicSheetData> data);
 }
 }

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantInfoService.java

@@ -89,4 +89,6 @@ public interface TenantInfoService extends IService<TenantInfo>  {
      * @return
      * @return
      */
      */
     Boolean entry(TenantInfoWrapper.TenantInfoQuery query);
     Boolean entry(TenantInfoWrapper.TenantInfoQuery query);
+
+    TenantInfoWrapper.TenantInfo Infodetail(Long id);
 }
 }

+ 6 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantUnbindRecordService.java

@@ -45,4 +45,10 @@ public interface TenantUnbindRecordService extends IService<TenantUnbindRecord>
      */
      */
     Boolean update(TenantUnbindRecordWrapper.TenantUnbindRecord tenantUnbindRecord);
     Boolean update(TenantUnbindRecordWrapper.TenantUnbindRecord tenantUnbindRecord);
 
 
+    /**
+     * 审核
+     * @param audio
+     * @return
+     */
+    Boolean entry(TenantUnbindRecordWrapper.Audio audio);
 }
 }

+ 90 - 5
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantActivationCodeServiceImpl.java

@@ -4,8 +4,13 @@ import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
 import com.yonge.cooleshow.biz.dal.dao.StudentDao;
 import com.yonge.cooleshow.biz.dal.dao.StudentDao;
-import com.yonge.cooleshow.biz.dal.entity.*;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.TenantActivationCode;
+import com.yonge.cooleshow.biz.dal.entity.TenantAlbumPurchase;
+import com.yonge.cooleshow.biz.dal.entity.UserTenantAlbumRecord;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
 import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
 import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
@@ -19,14 +24,18 @@ import com.yonge.cooleshow.biz.dal.wrapper.TenantActivationCodeWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 import com.yonge.cooleshow.common.enums.EActivationCode;
 import com.yonge.cooleshow.common.enums.EActivationCode;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.utils.easyexcel.ExcelDataReaderProperty;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
 
 
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Calendar;
+import java.util.Comparator;
 import java.util.Date;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
@@ -193,7 +202,7 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
         Integer purchaseCycle = purchase.getPurchaseCycle();
         Integer purchaseCycle = purchase.getPurchaseCycle();
 
 
 
 
-        addUserTenantAlbumRecord(student.getUserId(), purchase,null);
+        addUserTenantAlbumRecord(student.getUserId(), purchase, null);
 
 
         // 更新购买记录中激活码使用统计数量值
         // 更新购买记录中激活码使用统计数量值
         Integer activeCodeNumber = this.lambdaQuery()
         Integer activeCodeNumber = this.lambdaQuery()
@@ -211,7 +220,7 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
     /**
     /**
      * 添加用户机构专辑激活记录
      * 添加用户机构专辑激活记录
      *
      *
-     * @param studentId 学生ID
+     * @param studentId         学生ID
      * @param userOrderDetailVo 订单详情
      * @param userOrderDetailVo 订单详情
      */
      */
     @Override
     @Override
@@ -221,7 +230,84 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
 
 
     }
     }
 
 
-    private void addUserTenantAlbumRecord(Long studentId, TenantAlbumPurchase purchase, UserOrderDetailVo userOrderDetailVo) {
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void importActiveCode(List<ExcelDataReaderProperty<TenantActivationCodeWrapper.ImportTemplate>> dataList,
+                                 Long tenantId, Long userId, Long tenantAlbumPurchaseId) {
+        if (dataList.isEmpty()) {
+            return;
+        }
+        dataList.sort(Comparator.comparingInt(ExcelDataReaderProperty::getRowIndex));
+
+        List<String> errMsg = new ArrayList<>();
+        Map<String, Integer> codeRowMap = new HashMap<>();
+        Map<String, String> codePhoneMap = new HashMap<>();
+        // 校验数据格式是否错误
+        for (ExcelDataReaderProperty<TenantActivationCodeWrapper.ImportTemplate> next : dataList) {
+            Integer rowIndex = next.getRowIndex();
+            TenantActivationCodeWrapper.ImportTemplate code = next.getClazz();
+
+            int msgRowNo = rowIndex + 1;
+            code.checkIsIllegal().forEach(err -> errMsg.add(String.format("第%s行%s", msgRowNo, err)));
+            if (codeRowMap.containsKey(code.getCode())) {
+                errMsg.add(String.format("第%s行%s", msgRowNo, "激活码重复"));
+            }
+            codeRowMap.put(code.getCode().trim(), msgRowNo);
+            codePhoneMap.put(code.getCode().trim(), code.getPhone().trim());
+
+            if (errMsg.size() > 100) {
+                break;
+            }
+        }
+
+        if (!errMsg.isEmpty()) {
+            throw new BizException(String.join(",", errMsg));
+        }
+        // 校验激活码是否被使用
+        List<List<String>> codePartition = Lists.partition(new ArrayList<>(codeRowMap.keySet()), 50);
+
+        List<TenantActivationCode> tenantActivationCodes = new ArrayList<>();
+        for (List<String> codes : codePartition) {
+            List<TenantActivationCode> activationCodes = this.lambdaQuery()
+                    .eq(TenantActivationCode::getTenantId, tenantId)
+                    .eq(TenantActivationCode::getTenantAlbumPurchaseId, tenantAlbumPurchaseId)
+                    .in(TenantActivationCode::getActivationCode, codes).list();
+
+            // 存在无效码或者已经使用过的码
+            if (codes.size() != activationCodes.size() ||
+                    activationCodes.stream().anyMatch(TenantActivationCode::getActivationStatus)) {
+                Map<String, Boolean> codeStatusMap = activationCodes.stream()
+                        .collect(Collectors.toMap(TenantActivationCode::getActivationCode,
+                                TenantActivationCode::getActivationStatus));
+                for (String code : codes) {
+                    if (!codeStatusMap.containsKey(code)) {
+                        errMsg.add(String.format("第%s行%s", codeRowMap.get(code), "验证码无效"));
+                    } else if (Boolean.TRUE.equals(codeStatusMap.get(code))) {
+                        errMsg.add(String.format("第%s行%s", codeRowMap.get(code), "验证码已经激活"));
+                    }
+                }
+            }
+
+            List<TenantActivationCode> updateDataList = activationCodes.stream().map(next -> {
+                TenantActivationCode tenantActivationCode = new TenantActivationCode();
+                tenantActivationCode.setId(next.getId());
+                tenantActivationCode.setActivationPhone(codePhoneMap.get(next.getActivationCode()));
+                tenantActivationCode.setSendStatus(EActivationCode.SEND);
+                return tenantActivationCode;
+            }).collect(Collectors.toList());
+
+            tenantActivationCodes.addAll(updateDataList);
+        }
+        if (!errMsg.isEmpty()) {
+            throw new BizException(String.join(",", errMsg));
+        }
+        if (!tenantActivationCodes.isEmpty()) {
+            this.updateBatchById(tenantActivationCodes, 50);
+        }
+    }
+
+    private void addUserTenantAlbumRecord(Long studentId, TenantAlbumPurchase purchase,
+                                          UserOrderDetailVo userOrderDetailVo) {
 
 
 
 
         UserTenantAlbumRecord userTenantAlbumRecord = new UserTenantAlbumRecord();
         UserTenantAlbumRecord userTenantAlbumRecord = new UserTenantAlbumRecord();
@@ -253,7 +339,6 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
         }
         }
 
 
 
 
-
         QueryWrapper<UserTenantAlbumRecord> queryWrapper = new QueryWrapper<>();
         QueryWrapper<UserTenantAlbumRecord> queryWrapper = new QueryWrapper<>();
         queryWrapper.lambda()
         queryWrapper.lambda()
                 .eq(UserTenantAlbumRecord::getTenantId, userTenantAlbumRecord.getTenantId())
                 .eq(UserTenantAlbumRecord::getTenantId, userTenantAlbumRecord.getTenantId())

+ 8 - 3
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantAlbumRefServiceImpl.java

@@ -50,9 +50,9 @@ public class TenantAlbumRefServiceImpl extends ServiceImpl<TenantAlbumRefMapper,
      * @return Boolean
      * @return Boolean
      */
      */
     @Override
     @Override
-    public Boolean add(TenantAlbumRefWrapper.TenantAlbumRef tenantAlbumRef) {    	
-        
-        return this.save(JSON.parseObject(tenantAlbumRef.jsonString(), TenantAlbumRef.class));
+    public Boolean add(TenantAlbumRef tenantAlbumRef) {
+        return this.save(tenantAlbumRef);
+        //return this.save(JSON.parseObject(tenantAlbumRef.jsonString(), TenantAlbumRef.class));
     }
     }
 
 
     /**
     /**
@@ -78,4 +78,9 @@ public class TenantAlbumRefServiceImpl extends ServiceImpl<TenantAlbumRefMapper,
                 .eq(TenantAlbumRef::getTenantAlbumId, tenantAlbumId)
                 .eq(TenantAlbumRef::getTenantAlbumId, tenantAlbumId)
                 .list();
                 .list();
     }
     }
+
+    @Override
+    public TenantAlbumRef getBytenantAlbumId(Long id) {
+        return baseMapper.selectByAlbumId(id);
+    }
 }
 }

+ 79 - 63
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantAlbumServiceImpl.java

@@ -1,20 +1,15 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 package com.yonge.cooleshow.biz.dal.service.impl;
 
 
-import cn.hutool.core.lang.Snowflake;
-import cn.hutool.core.lang.UUID;
-import cn.hutool.core.lang.generator.SnowflakeGenerator;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.entity.*;
-import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
-import com.yonge.cooleshow.common.enums.EActivationCode;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.exception.BizException;
-import com.yonge.toolset.base.util.StringUtil;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
@@ -23,10 +18,13 @@ import lombok.extern.slf4j.Slf4j;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMapper;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
+import springfox.documentation.spring.web.json.Json;
 
 
 import java.math.BigDecimal;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
 /**
 /**
@@ -53,10 +51,10 @@ public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, Tenan
     private UserOrderService userOrderService;
     private UserOrderService userOrderService;
 
 
     @Autowired
     @Autowired
-    private TenantActivationCodeService tenantActivationCodeService;
+    private SysUserFeignService sysUserFeignService;
 
 
     @Autowired
     @Autowired
-    private TenantAlbumPurchaseService tenantAlbumPurchaseService;
+    private TenantAlbumMusicService tenantAlbumMusicService;
 
 
     /**
     /**
      * 查询详情
      * 查询详情
@@ -76,9 +74,9 @@ public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, Tenan
      * @return IPage<TenantAlbum>
      * @return IPage<TenantAlbum>
      */
      */
     @Override
     @Override
-    public IPage<TenantAlbum> selectPage(IPage<TenantAlbum> page, TenantAlbumWrapper.TenantAlbumQuery query) {
-        
-        return page.setRecords(baseMapper.selectPage(page, query));
+    public IPage<TenantAlbumWrapper.TenantAlbum> selectPage(IPage<TenantAlbumWrapper.TenantAlbum> page, TenantAlbumWrapper.TenantAlbumQuery query) {
+        List<TenantAlbumWrapper.TenantAlbum> albums = baseMapper.selectPage(page, query);
+        return page.setRecords(albums);
     }
     }
 
 
     /**
     /**
@@ -87,9 +85,10 @@ public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, Tenan
      * @return Boolean
      * @return Boolean
      */
      */
     @Override
     @Override
-    public Boolean add(TenantAlbumWrapper.TenantAlbum tenantAlbum) {
+    public Boolean add(TenantAlbum tenantAlbum) {
 
 
-        return this.save(JSON.parseObject(tenantAlbum.jsonString(), TenantAlbum.class));
+        //return this.save(JSON.parseObject(tenantAlbum.jsonString(), TenantAlbum.class));
+        return this.save(tenantAlbum);
     }
     }
 
 
     /**
     /**
@@ -116,10 +115,9 @@ public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, Tenan
             throw new BizException("订单商品信息为空");
             throw new BizException("订单商品信息为空");
         }
         }
 
 
-
-        TenantAlbumWrapper.TenantAlbumContent tenantAlbumContent = JSON
-                .parseObject(orderGoodsInfo.getBizContent(), TenantAlbumWrapper.TenantAlbumContent.class);
-        if (tenantAlbumContent == null) {
+        TenantAlbumWrapper.TenantAlbumBuy tenantAlbumBuy = JSON
+                .parseObject(JSON.toJSONString(orderGoodsInfo.getBizContent()), TenantAlbumWrapper.TenantAlbumBuy.class);
+        if (tenantAlbumBuy == null) {
             log.error("订单创建前检测,订单商品信息为空");
             log.error("订单创建前检测,订单商品信息为空");
             throw new BizException("订单商品信息为空");
             throw new BizException("订单商品信息为空");
         }
         }
@@ -131,7 +129,6 @@ public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, Tenan
             log.error("订单创建前检测,专辑不存在,bizId={}", orderGoodsInfo.getBizId());
             log.error("订单创建前检测,专辑不存在,bizId={}", orderGoodsInfo.getBizId());
             throw new BizException("订单商品信息为空");
             throw new BizException("订单商品信息为空");
         }
         }
-        tenantAlbumContent.setBuyCycle(tenantAlbum.getPurchaseCycle());
 
 
         // 查询专辑所在机构
         // 查询专辑所在机构
         List<TenantAlbumRef> refList =
         List<TenantAlbumRef> refList =
@@ -164,10 +161,8 @@ public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, Tenan
                 }
                 }
                 price = tenantAlbum.getSalePrice();
                 price = tenantAlbum.getSalePrice();
                 userOrderDetail.setMerchId(tenantInfo.getId());
                 userOrderDetail.setMerchId(tenantInfo.getId());
-                tenantAlbumContent.setBuyMultiple(1);
-                tenantAlbumContent.setBuyNumber(1);
-                tenantAlbumContent.setBuyCycle(tenantAlbumContent.getBuyCycle());
-                tenantAlbumContent.setTenantId(tenantInfo.getId());
+                tenantAlbumBuy.setBuyCycle(1);
+                tenantAlbumBuy.setBuyNumber(1);
                 break;
                 break;
             }
             }
 
 
@@ -184,8 +179,6 @@ public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, Tenan
                 }
                 }
                 price = tenantAlbum.getOriginalPrice();
                 price = tenantAlbum.getOriginalPrice();
                 userOrderDetail.setMerchId(0L);
                 userOrderDetail.setMerchId(0L);
-                tenantAlbumContent.setTenantId(tenantStaff.getTenantId());
-                tenantAlbumContent.setBuyCycle(tenantAlbumContent.getBuyCycle()*tenantAlbumContent.getBuyMultiple());
                 break;
                 break;
             }
             }
         }
         }
@@ -194,10 +187,9 @@ public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, Tenan
 
 
         userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
         userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
         userOrderDetail.setBizId(tenantAlbum.getId());
         userOrderDetail.setBizId(tenantAlbum.getId());
-        userOrderDetail.setBizContent(JSON.toJSONString(tenantAlbumContent));
         userOrderDetail.setGoodNum(orderGoodsInfo.getGoodNum());
         userOrderDetail.setGoodNum(orderGoodsInfo.getGoodNum());
         userOrderDetail.setOriginalPrice(price.multiply(new BigDecimal(orderGoodsInfo.getGoodNum()))
         userOrderDetail.setOriginalPrice(price.multiply(new BigDecimal(orderGoodsInfo.getGoodNum()))
-                .multiply(new BigDecimal(tenantAlbumContent.getBuyMultiple())));
+                .multiply(new BigDecimal(tenantAlbumBuy.getBuyCycle())));
         userOrderDetail.setCouponAmount(BigDecimal.ZERO);
         userOrderDetail.setCouponAmount(BigDecimal.ZERO);
         userOrderDetail.setExpectPrice(userOrderDetail.getOriginalPrice());
         userOrderDetail.setExpectPrice(userOrderDetail.getOriginalPrice());
         userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(userOrderDetail.getCouponAmount()));
         userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(userOrderDetail.getCouponAmount()));
@@ -216,45 +208,69 @@ public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, Tenan
     public void orderSuccess(UserOrderDetailVo userOrderDetailVo) {
     public void orderSuccess(UserOrderDetailVo userOrderDetailVo) {
 
 
         // 学生 插入机构专辑购买数据
         // 学生 插入机构专辑购买数据
-        // 学生购买机构专辑
-        switch (userOrderDetailVo.getOrderClient()) {
-            case STUDENT: {
-                tenantActivationCodeService.addUserTenantAlbumRecord(userOrderDetailVo.getUserId(),userOrderDetailVo);
 
 
-                break;
-            }
 
 
-            case TENANT: {
-                // 机构   插入机构专辑购买记录,生成机构专辑激活码
-
-                TenantAlbumWrapper.TenantAlbumContent tenantAlbumContent = JSON
-                        .parseObject(userOrderDetailVo.getBizContent(), TenantAlbumWrapper.TenantAlbumContent.class);
-                TenantAlbumPurchase tenantAlbumPurchase = new TenantAlbumPurchase();
-                tenantAlbumPurchase.setTenantId(tenantAlbumContent.getTenantId());
-                tenantAlbumPurchase.setTenantAlbumId(userOrderDetailVo.getBizId());
-                tenantAlbumPurchase.setPurchaseTime(userOrderDetailVo.getCreateTime());
-                tenantAlbumPurchase.setPurchaseQuantity(userOrderDetailVo.getGoodNum());
-                tenantAlbumPurchase.setPurchaseCycle(tenantAlbumContent.getBuyCycle());
-                tenantAlbumPurchase.setActiveQuantity(0);
-                tenantAlbumPurchase.setPurchasePrice(userOrderDetailVo.getActualPrice());
-                tenantAlbumPurchase.setPurchaseStatus(OrderStatusEnum.PAID.getCode());
-                tenantAlbumPurchaseService.save(tenantAlbumPurchase);
-
-                List<TenantActivationCode> tenantActivationCodes = new ArrayList<>();
-                for (int i = 0; i < userOrderDetailVo.getGoodNum(); i++) {
-                    TenantActivationCode tenantActivationCode = new TenantActivationCode();
-                    tenantActivationCode.setTenantId(tenantAlbumContent.getTenantId());
-                    tenantActivationCode.setTenantAlbumId(tenantAlbumContent.getTenantAlbumId());
-                    tenantActivationCode.setTenantAlbumPurchaseId(tenantAlbumPurchase.getId());
-//                    tenantActivationCode.setActivationCode(StringUtil.DeciamlToThirtySix(IdWorker.get32UUID()));
-                    tenantActivationCode.setActivationCode(IdWorker.get32UUID());
-                    tenantActivationCode.setSendStatus(EActivationCode.WAIT);
-                    tenantActivationCodes.add(tenantActivationCode);
-                }
-                tenantActivationCodeService.saveBatch(tenantActivationCodes);
-                break;
-            }
+        // 机构   插入机构专辑购买记录,生成机构专辑激活码
+
+    }
+
+    /**
+     * 新增机构专辑
+     * @param album
+     * @return
+     */
+    @Override
+    public Boolean insertTenantAlbum(TenantAlbumWrapper.TenantAlbum album) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        TenantInfo tenantInfo = tenantInfoService.lambdaQuery().eq(TenantInfo::getUserId, sysUser.getId())
+                .last("limit 1").one();
+        if (tenantInfo == null) {
+            throw new BizException("非法请求");
+        }
+
+        //给机构专辑赋值
+        TenantAlbum tenantAlbum = new TenantAlbum();
+        tenantAlbum.setName(album.getName());
+        tenantAlbum.setDescribe(album.getDescribe());
+        tenantAlbum.setCoverImg(album.getCoverImg());
+        tenantAlbum.setPurchaseCycle(album.getPurchaseCycle());
+        tenantAlbum.setSalePrice(album.getSalePrice());
+
+        //tenantAlbumService.addTenantAlbum(tenantAlbum);
+        add(tenantAlbum);
+        //关联表赋值
+        //tenantAlbumService.addTenantId(album.getTenantId());
+        TenantAlbumRef ref = new TenantAlbumRef();
+        ref.setTenantAlbumId(album.getId());
+        ref.setTenantId(album.getTenantId());
+        tenantAlbumRefService.add(ref);
+        //曲目表赋值
+        List<TenantAlbumWrapper.TenantAlbum.MusicSheetData> data = album.getMusicSheetData();
+
+        List<TenantAlbumMusic> tenantAlbumMusics = album.getMusicSheetData().stream().map(next -> {
+
+            AtomicInteger sort = new AtomicInteger(0);
+            return next.getMusicSheetIdList().stream().map(tenantAlbumMusic -> {
+
+                TenantAlbumMusic tenantAlbumMusic1 = new TenantAlbumMusic();
+                //tenantAlbumMusic1.setId(tenantAlbumMusic);
+                tenantAlbumMusic1.setSubjectType(next.getSubjectType());
+                tenantAlbumMusic1.setTenantId(album.getTenantId());
+                tenantAlbumMusic1.setMusicSheetId(tenantAlbumMusic);
+                tenantAlbumMusic1.setDelFlag(true);
+                tenantAlbumMusic1.setTenantAlbumId(tenantAlbum.getId());
+                tenantAlbumMusic1.setSortNumber(sort.getAndIncrement());
+                return tenantAlbumMusic1;
+            }).collect(Collectors.toList());
+
+        }).flatMap(Collection::stream).collect(Collectors.toList());
+
+        if(!tenantAlbumMusics.isEmpty()){
+            tenantAlbumMusicService.saveBatch(tenantAlbumMusics,100);
         }
         }
 
 
+        return true;
     }
     }
+
+
 }
 }

+ 17 - 3
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantInfoServiceImpl.java

@@ -1,5 +1,6 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 package com.yonge.cooleshow.biz.dal.service.impl;
 
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -17,6 +18,7 @@ import com.yonge.cooleshow.biz.dal.mapper.TenantStaffMapper;
 import com.yonge.cooleshow.biz.dal.service.SysAreaService;
 import com.yonge.cooleshow.biz.dal.service.SysAreaService;
 import com.yonge.cooleshow.biz.dal.service.SysConfigService;
 import com.yonge.cooleshow.biz.dal.service.SysConfigService;
 import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
 import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
@@ -83,8 +85,8 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
         if (id == null || id == -1) {
         if (id == null || id == -1) {
             return null;
             return null;
         }
         }
-
-        return baseMapper.selectById(id);
+        TenantInfo info = baseMapper.selectById(id);
+        return info;
     }
     }
 
 
     /**
     /**
@@ -105,7 +107,7 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
         for (int i = 0; i < tenantInfos.size(); i++) {
         for (int i = 0; i < tenantInfos.size(); i++) {
             TenantInfoWrapper.TenantInfo info = tenantInfos.get(i);
             TenantInfoWrapper.TenantInfo info = tenantInfos.get(i);
             long id = info.getId();
             long id = info.getId();
-            listId.add(i, (int) id);
+            listId.add(i,(int)id);
         }
         }
         //查询对应机构的老师数量
         //查询对应机构的老师数量
         List<Integer> listTeacher = new ArrayList<>();
         List<Integer> listTeacher = new ArrayList<>();
@@ -436,6 +438,18 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
         return  true;
         return  true;
     }
     }
 
 
+    @Override
+    public TenantInfoWrapper.TenantInfo Infodetail(Long id) {
+        if (id == null || id == -1) {
+            return null;
+        }
+        TenantInfoWrapper.TenantInfo info = tenantInfoMapper.selectInfoById(id);
+
+        info.setStudentCounts(tenantInfoMapper.queryStudentCount(id));
+        info.setTeacherCounts(tenantInfoMapper.queryTeacherCount(id));
+        return info;
+    }
+
 
 
     /**
     /**
      * 匹配地区码与省市区
      * 匹配地区码与省市区

+ 144 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantUnbindRecordServiceImpl.java

@@ -1,8 +1,21 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 package com.yonge.cooleshow.biz.dal.service.impl;
 
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.biz.dal.dao.StudentDao;
+import com.yonge.cooleshow.biz.dal.dao.SubjectDao;
+import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.entity.Teacher;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.toolset.base.exception.BizException;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.BeanUtils;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
@@ -11,6 +24,10 @@ import com.yonge.cooleshow.biz.dal.wrapper.TenantUnbindRecordWrapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantUnbindRecordMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantUnbindRecordMapper;
 import com.yonge.cooleshow.biz.dal.service.TenantUnbindRecordService;
 import com.yonge.cooleshow.biz.dal.service.TenantUnbindRecordService;
 
 
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
 /**
 /**
  * 机构解绑申请记录
  * 机构解绑申请记录
  * 2023-07-21 17:32:49
  * 2023-07-21 17:32:49
@@ -19,6 +36,28 @@ import com.yonge.cooleshow.biz.dal.service.TenantUnbindRecordService;
 @Service
 @Service
 public class TenantUnbindRecordServiceImpl extends ServiceImpl<TenantUnbindRecordMapper, TenantUnbindRecord> implements TenantUnbindRecordService {
 public class TenantUnbindRecordServiceImpl extends ServiceImpl<TenantUnbindRecordMapper, TenantUnbindRecord> implements TenantUnbindRecordService {
 
 
+
+    @Autowired
+    private TeacherDao teacherDao;
+
+    @Autowired
+    private StudentDao studentDao;
+
+    @Autowired
+    private SubjectDao subjectDao;
+
+    @Autowired
+    private TenantUnbindRecordService tenantUnbindRecordService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private TeacherService teacherService;
+
 	/**
 	/**
      * 查询详情
      * 查询详情
      * @param id 详情ID
      * @param id 详情ID
@@ -38,8 +77,83 @@ public class TenantUnbindRecordServiceImpl extends ServiceImpl<TenantUnbindRecor
      */
      */
     @Override
     @Override
     public IPage<TenantUnbindRecordWrapper.TenantUnbindRecord> selectPage(IPage<TenantUnbindRecordWrapper.TenantUnbindRecord> page, TenantUnbindRecordWrapper.TenantUnbindRecordQuery query) {
     public IPage<TenantUnbindRecordWrapper.TenantUnbindRecord> selectPage(IPage<TenantUnbindRecordWrapper.TenantUnbindRecord> page, TenantUnbindRecordWrapper.TenantUnbindRecordQuery query) {
-        
-        return page.setRecords(baseMapper.selectPage(page, query));
+
+        List<TenantUnbindRecordWrapper.TenantUnbindRecord> records = baseMapper.selectPage(page, query);
+        if(records.isEmpty()){
+            return page.setRecords(records);
+        }
+
+        Map<String, List<TenantUnbindRecordWrapper.TenantUnbindRecord>> gropuByUserType = records.stream().collect(Collectors.groupingBy(TenantUnbindRecordWrapper.TenantUnbindRecord::getUserType));
+
+        List<Long> teacherIds  = new ArrayList<>();
+        List<Long> studentIds  = new ArrayList<>();
+
+        for (Map.Entry<String, List<TenantUnbindRecordWrapper.TenantUnbindRecord>> entry : gropuByUserType.entrySet()) {
+            if("TEACHER".equals(entry.getKey())){
+                teacherIds.addAll(entry.getValue().stream().map(TenantUnbindRecordWrapper.TenantUnbindRecord::getUserId).collect(Collectors.toList()));
+            }else{
+                studentIds.addAll(entry.getValue().stream().map(TenantUnbindRecordWrapper.TenantUnbindRecord::getUserId).collect(Collectors.toList()));
+
+            }
+
+        }
+        List<Teacher> teachers = new ArrayList<>();
+        List<Teacher> students = new ArrayList<>();
+        List<Teacher> users = new ArrayList<>();
+        if(!teacherIds.isEmpty()){
+            QueryWrapper<Teacher>
+                    objectQueryWrapper = new QueryWrapper<>();
+            objectQueryWrapper.lambda()
+                    .in(Teacher::getUserId,teacherIds);
+            teachers = teacherDao.selectList(objectQueryWrapper);
+        }else {
+            QueryWrapper<Student>
+                    objectQueryWrapper = new QueryWrapper<>();
+            objectQueryWrapper.lambda()
+                    .in(Student::getUserId,studentIds);
+            List<Student> studentList = studentDao.selectList(objectQueryWrapper);
+            students =studentList.stream().map(next->{
+                Teacher teacher = new Teacher();
+                teacher.setUserId(next.getUserId());
+                teacher.setSubject(next.getSubjectId());
+                return teacher;
+            }).collect(Collectors.toList());
+        }
+        users.addAll(students);
+        users.addAll(teachers);
+
+        List<Long> subjectIdList = users.stream().map(next -> {
+            List<Long > list = new ArrayList<>();
+            String subjectId = next.getSubjectId();
+            if (StringUtils.isEmpty(subjectId)) {
+                return list;
+            }
+            return Arrays.stream(next.getSubjectId().split(",")).map(Long::valueOf).collect(Collectors.toList());
+        }).flatMap(Collection::stream).collect(Collectors.toList());
+
+        Map<Long,String> userIdSubjectNameMap = new HashMap<>();
+        if(!subjectIdList.isEmpty()){
+            List<Subject> subjectList = subjectDao.findBySubjectIds(subjectIdList);
+            Map<Long, String> idNameMap = subjectList.stream().collect(Collectors.toMap(Subject::getId, Subject::getName));
+
+            for (Teacher user : users) {
+                String subjectId = user.getSubjectId();
+                if(StringUtils.isEmpty(subjectId)){
+                    continue;
+                }
+                List<String> names = Arrays.stream(subjectId.split(",")).map(next ->
+                        idNameMap.getOrDefault(Long.valueOf(next), "")).collect(Collectors.toList());
+                userIdSubjectNameMap.put(user.getUserId(),String.join(",",names));
+            }
+        }
+
+        for (TenantUnbindRecordWrapper.TenantUnbindRecord record : records) {
+            record.setSubjectName(userIdSubjectNameMap.getOrDefault(record.getUserId(),""));
+
+        }
+
+
+        return page.setRecords(records);
     }
     }
 	
 	
     /**
     /**
@@ -63,4 +177,32 @@ public class TenantUnbindRecordServiceImpl extends ServiceImpl<TenantUnbindRecor
 
 
         return this.updateById(JSON.parseObject(tenantUnbindRecord.jsonString(), TenantUnbindRecord.class));       
         return this.updateById(JSON.parseObject(tenantUnbindRecord.jsonString(), TenantUnbindRecord.class));       
     }
     }
+
+    @Override
+    public Boolean entry(TenantUnbindRecordWrapper.Audio audio) {
+        boolean update = tenantUnbindRecordService.lambdaUpdate()
+                .set(TenantUnbindRecord::getStatus, audio.getStatus() ? "PASS" : "UNPASS")
+                .set(TenantUnbindRecord::getReason, audio.getReason())
+                .set(TenantUnbindRecord::getVerifyUserId, sysUserFeignService.queryUserInfo().getId())
+                .eq(TenantUnbindRecord::getId, audio.getId())
+                .eq(TenantUnbindRecord::getStatus, "DOING").update();
+        if (!update) {
+            throw new BizException("审核失败,请刷新后重试");
+        }
+
+        if (audio.getStatus()) {
+            TenantUnbindRecord unbindRecord = tenantUnbindRecordService.getById(audio.getId());
+            String userType = unbindRecord.getUserType();
+            if ("STUDENT".equals(userType)) {
+                studentService.lambdaUpdate()
+                        .set(Student::getTenantId, -1L)
+                        .eq(Student::getUserId, unbindRecord.getUserId()).update();
+            } else if ("TEACHER".equals(userType)) {
+                teacherService.lambdaUpdate()
+                        .set(Teacher::getTenantId, -1L)
+                        .eq(Teacher::getUserId, unbindRecord.getUserId()).update();
+            }
+        }
+        return null;
+    }
 }
 }

+ 43 - 6
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/SysGoodsPriceWrapper.java

@@ -1,9 +1,14 @@
 package com.yonge.cooleshow.biz.dal.wrapper;
 package com.yonge.cooleshow.biz.dal.wrapper;
 
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
-import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.yonge.toolset.base.page.QueryInfo;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiModelProperty;
+
+import java.math.BigDecimal;
+import java.util.Date;
 import java.util.Optional;
 import java.util.Optional;
 
 
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
@@ -24,13 +29,13 @@ public class SysGoodsPriceWrapper {
     @NoArgsConstructor
     @NoArgsConstructor
     @AllArgsConstructor
     @AllArgsConstructor
     @ApiModel(" SysGoodsPriceQuery-商品价格设置")
     @ApiModel(" SysGoodsPriceQuery-商品价格设置")
-    public static class SysGoodsPriceQuery implements QueryInfo {
+    public static class SysGoodsPriceQuery extends QueryInfo {
     
     
     	@ApiModelProperty("当前页")
     	@ApiModelProperty("当前页")
-        private Integer page;
+        private int page;
         
         
         @ApiModelProperty("分页行数")
         @ApiModelProperty("分页行数")
-        private Integer rows;
+        private int rows;
         
         
         @ApiModelProperty("关键字匹配")
         @ApiModelProperty("关键字匹配")
 		private String keyword;
 		private String keyword;
@@ -46,11 +51,43 @@ public class SysGoodsPriceWrapper {
         public static SysGoodsPriceQuery from(String json) {
         public static SysGoodsPriceQuery from(String json) {
             return JSON.parseObject(json, SysGoodsPriceQuery.class);
             return JSON.parseObject(json, SysGoodsPriceQuery.class);
         }
         }
-    }  
+    }
 
 
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
 	@ApiModel(" SysGoodsPrice-商品价格设置")
 	@ApiModel(" SysGoodsPrice-商品价格设置")
     public static class SysGoodsPrice {
     public static class SysGoodsPrice {
-        
+        @ApiModelProperty("主键ID")
+        private Long id;
+
+        @ApiModelProperty("商品类型")
+        private String goodsType;
+
+        @ApiModelProperty("销售价")
+        private BigDecimal salePrice;
+
+        @ApiModelProperty("原价")
+        private BigDecimal originalPrice;
+
+        @ApiModelProperty("描述")
+        private String describe;
+
+        @ApiModelProperty("购买周期")
+        private Integer duration;
+
+        @ApiModelProperty("图片")
+        private String goodsImg;
+
+        @ApiModelProperty("更新人")
+        private Long updateBy;
+
+        @ApiModelProperty("更新时间")
+        private Date updateTime;
+
+        @ApiModelProperty("创建时间")
+        private Date createTime;
         public String jsonString() {
         public String jsonString() {
             return JSON.toJSONString(this);
             return JSON.toJSONString(this);
         }
         }

+ 32 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantActivationCodeWrapper.java

@@ -1,12 +1,16 @@
 package com.yonge.cooleshow.biz.dal.wrapper;
 package com.yonge.cooleshow.biz.dal.wrapper;
 
 
+import com.alibaba.excel.annotation.ExcelProperty;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.microsvc.toolkit.common.response.paging.QueryInfo;
 import com.microsvc.toolkit.common.response.paging.QueryInfo;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiModelProperty;
 
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.Date;
+import java.util.List;
 import java.util.Optional;
 import java.util.Optional;
+import java.util.regex.Pattern;
 
 
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Builder;
@@ -126,4 +130,32 @@ public class TenantActivationCodeWrapper {
         }
         }
     }
     }
 
 
+    @Data
+    public static class ImportTemplate {
+
+        @ExcelProperty(value = "激活码")
+        private String code;
+
+        @ExcelProperty(value = "手机号")
+        private String phone;
+
+        private static final String PHONE_REG = "^(13\\d|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18\\d|19[0-35-9])" +
+                "\\d{8}$";
+
+        public List<String> checkIsIllegal() {
+            List<String> errMsg = new ArrayList<>();
+            if (StringUtils.isEmpty(code)) {
+                errMsg.add("激活码不能为空");
+            }
+            if (StringUtils.isEmpty(phone)) {
+                errMsg.add("手机号不能为空");
+            } else if (!Pattern.matches(PHONE_REG, phone)) {
+                errMsg.add("手机号格式错误");
+            }
+            return errMsg;
+        }
+
+
+    }
+
 }
 }

+ 79 - 5
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantAlbumWrapper.java

@@ -2,9 +2,14 @@ package com.yonge.cooleshow.biz.dal.wrapper;
 
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.microsvc.toolkit.common.response.paging.QueryInfo;
 import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.biz.dal.enums.SubjectTypeEnum;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiModelProperty;
 
 
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
 import java.util.Optional;
 import java.util.Optional;
 
 
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
@@ -27,6 +32,10 @@ public class TenantAlbumWrapper {
     @ApiModel(" TenantAlbumQuery-机构专辑")
     @ApiModel(" TenantAlbumQuery-机构专辑")
     public static class TenantAlbumQuery implements QueryInfo {
     public static class TenantAlbumQuery implements QueryInfo {
 
 
+
+        @ApiModelProperty("主键ID")
+        private Long id;
+
         @ApiModelProperty("当前页")
         @ApiModelProperty("当前页")
         private Integer page;
         private Integer page;
 
 
@@ -39,6 +48,12 @@ public class TenantAlbumWrapper {
         @ApiModelProperty("机构ID")
         @ApiModelProperty("机构ID")
         private Long tenantId;
         private Long tenantId;
 
 
+        @ApiModelProperty("专辑名称")
+        private String name;
+
+        @ApiModelProperty("机构名称")
+        private String tenantName;
+
         public String getKeyword() {
         public String getKeyword() {
             return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
             return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
         }
         }
@@ -52,9 +67,61 @@ public class TenantAlbumWrapper {
         }
         }
     }
     }
 
 
-    @ApiModel(" TenantAlbum-机构专辑")
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" TenantAlbum-机构专辑返回")
     public static class TenantAlbum {
     public static class TenantAlbum {
 
 
+        @ApiModelProperty("主键ID")
+        private Long id;
+
+        @ApiModelProperty("机构ID")
+        private Long tenantId;
+
+        @ApiModelProperty("专辑名称")
+        private String name;
+
+        @ApiModelProperty("机构名称")
+        private String tenantName;
+
+        @ApiModelProperty("专辑介绍")
+        private String describe;
+
+        @ApiModelProperty("专辑封面")
+        private String coverImg;
+
+        @ApiModelProperty("曲目数")
+        private Integer musicNum;
+
+        @ApiModelProperty("平台价格")
+        private BigDecimal originalPrice;
+
+        @ApiModelProperty("机构价格")
+        private BigDecimal salePrice;
+
+        @ApiModelProperty("购买周期")
+        private Integer purchaseCycle;
+
+        @ApiModelProperty("曲目声部分类(多个,分隔)")
+        private String subjectTypes;
+
+        @ApiModelProperty("启用状态")
+        private Boolean status;
+
+        @ApiModelProperty("删除标识")
+        private Boolean delFlag;
+
+        @ApiModelProperty("更新时间")
+        private Date updateTime;
+
+        @ApiModelProperty("创建时间")
+        private Date createTime;
+
+        @ApiModelProperty("曲目相关信息")
+        private List<MusicSheetData> musicSheetData = new ArrayList<>();
+
         public String jsonString() {
         public String jsonString() {
             return JSON.toJSONString(this);
             return JSON.toJSONString(this);
         }
         }
@@ -62,6 +129,14 @@ public class TenantAlbumWrapper {
         public static TenantAlbum from(String json) {
         public static TenantAlbum from(String json) {
             return JSON.parseObject(json, TenantAlbum.class);
             return JSON.parseObject(json, TenantAlbum.class);
         }
         }
+
+        @Data
+        public static class MusicSheetData {
+            private SubjectTypeEnum subjectType;
+
+            private List<Long> musicSheetIdList = new ArrayList<>();
+        }
+
     }
     }
 
 
     @Data
     @Data
@@ -108,11 +183,10 @@ public class TenantAlbumWrapper {
         @ApiModelProperty("采购倍数")
         @ApiModelProperty("采购倍数")
         private Integer buyMultiple;
         private Integer buyMultiple;
 
 
-        @ApiModelProperty(value = "采购周期",hidden = true)
+        @ApiModelProperty(value = "采购周期", hidden = true)
         private Integer buyCycle;
         private Integer buyCycle;
 
 
-        @ApiModelProperty(value = "采购机构",hidden = true)
+        @ApiModelProperty(value = "采购机构", hidden = true)
         private Long tenantId;
         private Long tenantId;
 
 
-    }
-}
+    }}

+ 13 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantUnbindRecordWrapper.java

@@ -1,6 +1,7 @@
 package com.yonge.cooleshow.biz.dal.wrapper;
 package com.yonge.cooleshow.biz.dal.wrapper;
 
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.microsvc.toolkit.common.response.paging.QueryInfo;
 import com.microsvc.toolkit.common.response.paging.QueryInfo;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiModelProperty;
@@ -48,6 +49,9 @@ public class TenantUnbindRecordWrapper {
         @ApiModelProperty("用户类型,TEACHER/STUDENT")
         @ApiModelProperty("用户类型,TEACHER/STUDENT")
         private String userType;
         private String userType;
 
 
+        @ApiModelProperty("审核状态 DOING、审核中 PASS、通过 UNPASS、不通过")
+        private String status;
+
         public String getKeyword() {
         public String getKeyword() {
             return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
             return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
         }
         }
@@ -134,6 +138,15 @@ public class TenantUnbindRecordWrapper {
         @ApiModelProperty("创建时间")
         @ApiModelProperty("创建时间")
         private Date createTime;
         private Date createTime;
 
 
+        @ApiModelProperty("头像")
+        private String avatar;
+
+        @ApiModelProperty("声部Id")
+        private String subjectId;
+
+        @ApiModelProperty("声部名称")
+        private String subjectName;
+
 
 
         public String jsonString() {
         public String jsonString() {
             return JSON.toJSONString(this);
             return JSON.toJSONString(this);

+ 11 - 1
cooleshow-user/user-biz/src/main/resources/config/mybatis/TenantAlbumMapper.xml

@@ -21,10 +21,20 @@
         , t.create_time_ AS createTime
         , t.create_time_ AS createTime
         </sql> 
         </sql> 
     
     
-    <select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.entity.TenantAlbum">
+    <select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper$TenantAlbum">
 		SELECT         
 		SELECT         
         	<include refid="baseColumns" />
         	<include refid="baseColumns" />
+        i.name_ AS tenantName
 		FROM tenant_album t
 		FROM tenant_album t
+        LEFT JOIN tenant_album_ref r on  t.id_ = r.tenant_album_id_
+        left join tenant_info i on r.tenant_id_ = i.id_
+        where 1=1
+        <if test="param.name != null and param.name != ''">
+            and t.name_ = #{param.name}
+        </if>
+        <if test="param.tenantId != null ">
+            and i.id_= #{param.tenantId}
+        </if>
 	</select>
 	</select>
     
     
 </mapper>
 </mapper>

+ 6 - 1
cooleshow-user/user-biz/src/main/resources/config/mybatis/TenantAlbumRefMapper.xml

@@ -18,5 +18,10 @@
         	<include refid="baseColumns" />
         	<include refid="baseColumns" />
 		FROM tenant_album_ref t
 		FROM tenant_album_ref t
 	</select>
 	</select>
-    
+    <select id="selectByAlbumId" resultType="com.yonge.cooleshow.biz.dal.entity.TenantAlbumRef">
+        select <include refid="baseColumns" />
+        from tenant_album_ref
+        where tenant_album_id_ = #{id}
+    </select>
+
 </mapper>
 </mapper>

+ 30 - 6
cooleshow-user/user-biz/src/main/resources/config/mybatis/TenantInfoMapper.xml

@@ -27,11 +27,6 @@
         values (#{param.name},#{param.logo},#{param.briefIntroduction},#{param.provinceCode},#{param.cityCode},#{param.regionCode},#{param.username},#{param.phone})
         values (#{param.name},#{param.logo},#{param.briefIntroduction},#{param.provinceCode},#{param.cityCode},#{param.regionCode},#{param.username},#{param.phone})
     </insert>
     </insert>
 
 
-    <insert id="insertNow">
-        insert into tenant_entry_record (id_,tenant_id_,
-        )
-        (id_,)
-    </insert>
 
 
     <update id="updateInfo">
     <update id="updateInfo">
         update tenant_info
         update tenant_info
@@ -115,10 +110,16 @@
         SELECT count(t.tenant_id_) FROM teacher t where t.tenant_id_ IN (<foreach collection="listId" separator="," item="Id">#{Id}</foreach>)
         SELECT count(t.tenant_id_) FROM teacher t where t.tenant_id_ IN (<foreach collection="listId" separator="," item="Id">#{Id}</foreach>)
     </select>
     </select>
 
 
+    <select id="queryTeacherCount" resultType="java.lang.String">
+        SELECT count(t.tenant_id_) FROM teacher t where t.tenant_id_ = #{id}
+    </select>
+
     <select id="queryStudentCounts" resultType="java.lang.Integer">
     <select id="queryStudentCounts" resultType="java.lang.Integer">
         SELECT count(s.tenant_id_) FROM student s where s.tenant_id_ IN (<foreach collection="listId" separator="," item="Id">#{Id}</foreach>)
         SELECT count(s.tenant_id_) FROM student s where s.tenant_id_ IN (<foreach collection="listId" separator="," item="Id">#{Id}</foreach>)
     </select>
     </select>
-
+    <select id="queryStudentCount" resultType="java.lang.String">
+        SELECT count(s.tenant_id_) FROM student s where s.tenant_id_ = #{id}
+    </select>
     <select id="selectApplyPage" resultType="com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper$TenantInfo">
     <select id="selectApplyPage" resultType="com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper$TenantInfo">
         SELECT
         SELECT
         id_ as id,
         id_ as id,
@@ -202,5 +203,28 @@
         id_ = #{param.id}
         id_ = #{param.id}
         </if>
         </if>
     </select>
     </select>
+    <select id="selectInfoById" resultType="com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper$TenantInfo">
+        select
+                  t.id_ AS id
+                , t.name_ AS name
+                , t.logo_ AS logo
+                , t.province_code_ AS provinceCode
+                , t.city_code_ AS cityCode
+                , t.region_code_ AS regionCode
+                , t.username_ AS userName
+                , t.user_id_ AS userId
+                , t.phone_ AS phone
+                , t.update_time_ AS updateTime
+                , t.create_time_ AS createTime
+                , t.brief_Introduction_ AS briefIntroduction
+        from tenant_info t
+        where 1=1
+        <if test="id != null">
+           id_ = #{id}
+        </if>
+        }
+
+    </select>
+
 
 
 </mapper>
 </mapper>

+ 4 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/TenantUnbindRecordMapper.xml

@@ -28,6 +28,7 @@
         ,ti.phone_ as tenantUserPhone
         ,ti.phone_ as tenantUserPhone
         ,su.username_ as userName
         ,su.username_ as userName
         ,su.phone_ as phone
         ,su.phone_ as phone
+        ,su.avatar_ as avatar
         FROM tenant_unbind_record t
         FROM tenant_unbind_record t
         LEFT JOIN tenant_info ti ON ti.id_ = t.tenant_id_
         LEFT JOIN tenant_info ti ON ti.id_ = t.tenant_id_
         LEFT JOIN sys_user su on su.id_ = t.user_id_
         LEFT JOIN sys_user su on su.id_ = t.user_id_
@@ -53,6 +54,9 @@
             <if test="param.regionCode != null">
             <if test="param.regionCode != null">
                 AND ti.region_code_ = #{param.regionCode}
                 AND ti.region_code_ = #{param.regionCode}
             </if>
             </if>
+            <if test="param.status != null and param.status != ''">
+                AND t.status_ = #{param.status}
+            </if>
         </where>
         </where>
         order by t.id_ desc
         order by t.id_ desc
     </select>
     </select>

+ 3 - 2
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/StudentController.java

@@ -113,10 +113,11 @@ public class StudentController extends BaseController {
         try {
         try {
             ExcelDataReader<StudentWrapper.StudentExport> reader =
             ExcelDataReader<StudentWrapper.StudentExport> reader =
                     ExcelUtils.getReader(StudentWrapper.StudentExport.class, file);
                     ExcelUtils.getReader(StudentWrapper.StudentExport.class, file);
-            studentService.importStudentExcel(reader.getDataList(),user.getTenantId(), user.getId());
+            studentService.importStudentExcel(reader.getDataList(), user.getTenantId(), user.getId());
             return HttpResponseResult.succeed();
             return HttpResponseResult.succeed();
         } catch (ExcelException e) {
         } catch (ExcelException e) {
-            return HttpResponseResult.failed(BizHttpStatus.IMPORT.getCode(), e.getErrMsgList(), BizHttpStatus.IMPORT.getMsg());
+            return HttpResponseResult.failed(BizHttpStatus.IMPORT.getCode(), e.getErrMsgList(),
+                    BizHttpStatus.IMPORT.getMsg());
         }
         }
     }
     }
 
 

+ 91 - 0
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/TenantActivationCodeController.java

@@ -12,26 +12,51 @@ import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.entity.TenantActivationCode;
 import com.yonge.cooleshow.biz.dal.entity.TenantActivationCode;
 import com.yonge.cooleshow.biz.dal.entity.TenantAlbumPurchase;
 import com.yonge.cooleshow.biz.dal.entity.TenantAlbumPurchase;
 import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
 import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
 import com.yonge.cooleshow.biz.dal.service.TenantActivationCodeService;
 import com.yonge.cooleshow.biz.dal.service.TenantActivationCodeService;
 import com.yonge.cooleshow.biz.dal.service.TenantAlbumPurchaseService;
 import com.yonge.cooleshow.biz.dal.service.TenantAlbumPurchaseService;
 import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
 import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
+import com.yonge.cooleshow.biz.dal.vo.StudentVo;
+import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantActivationCodeWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantActivationCodeWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.BizHttpStatus;
+import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.cooleshow.common.enums.UserStatusEnum;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.cooleshow.tenant.vo.TenantActivationCodeVo;
 import com.yonge.cooleshow.tenant.vo.TenantActivationCodeVo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.utils.date.DateUtil;
+import com.yonge.toolset.utils.easyexcel.ErrMsg;
+import com.yonge.toolset.utils.easyexcel.ExcelDataReader;
+import com.yonge.toolset.utils.easyexcel.ExcelException;
+import com.yonge.toolset.utils.easyexcel.ExcelUtils;
+import com.yonge.toolset.utils.excel.POIUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.List;
 
 
 
 
 @Slf4j
 @Slf4j
@@ -53,6 +78,9 @@ public class TenantActivationCodeController extends BaseController {
     @Autowired
     @Autowired
     private TenantInfoService tenantInfoService;
     private TenantInfoService tenantInfoService;
 
 
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
     @ApiOperation(value = "详情", notes = "机构激活码-根据详情ID查询单条, 传入id")
     @ApiOperation(value = "详情", notes = "机构激活码-根据详情ID查询单条, 传入id")
 //    @GetMapping("/detail/{id}")
 //    @GetMapping("/detail/{id}")
     public R<TenantActivationCodeVo.TenantActivationCode> detail(@PathVariable("id") Long id) {
     public R<TenantActivationCodeVo.TenantActivationCode> detail(@PathVariable("id") Long id) {
@@ -95,6 +123,69 @@ public class TenantActivationCodeController extends BaseController {
         return succeed();
         return succeed();
     }
     }
 
 
+    @GetMapping("/exportActiveCode")
+    @ApiOperation(value = "导出模板")
+    public void exportActiveCode(HttpServletResponse response) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            throw new BizException("请登录");
+        }
+        Long tenantId = sysUser.getTenantId();
+
+        TenantActivationCodeWrapper.TenantActivationCodeQuery query =
+                new TenantActivationCodeWrapper.TenantActivationCodeQuery();
+        query.setTenantId(tenantId);
+        query.setActivationStatus(false);
+        query.setPage(1);
+        query.setRows(9999);
+        IPage<TenantActivationCodeWrapper.TenantActivationCode> queryInfo =
+                tenantActivationCodeService.selectPage(QueryInfo.getPage(query), query);
+        List<TenantActivationCodeWrapper.TenantActivationCode> rows = queryInfo.getRecords();
+        if (rows.isEmpty()) {
+            throw new BizException("没有可导出数据");
+        }
+
+        try (OutputStream outputStream = response.getOutputStream()) {
+            HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"激活码", "手机号"}, new String[]{
+                    "activationCode", "activationPhone"}, rows);
+            response.setContentType("application/octet-stream");
+            response.setHeader("Content-Disposition", "attac:wq" +
+                    "hment;filename=active_code-" + DateUtil.getDate(new Date()) + ".xls");
+            workbook.write(outputStream);
+            outputStream.flush();
+        } catch (Exception e) {
+            log.error("导出激活码异常", e);
+        }
+    }
+
+    @PostMapping("/importActiveCode")
+    @ApiOperation(value = "导入", notes = "传入file")
+    public HttpResponseResult<List<ErrMsg>> importActiveCode(
+            @RequestParam("file") MultipartFile file,
+            @RequestParam("tenantAlbumPurchaseId") Long tenantAlbumPurchaseId) {
+        if (null == file) {
+            return HttpResponseResult.failed("请上传文件");
+        }
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        TenantStaff tenantStaff = tenantStaffService.getByUserId(user.getId());
+        if (tenantStaff == null) {
+            return HttpResponseResult.failed("权限不足");
+        }
+
+        try {
+            ExcelDataReader<TenantActivationCodeWrapper.ImportTemplate> reader =
+                    ExcelUtils.getReader(TenantActivationCodeWrapper.ImportTemplate.class, file);
+            tenantActivationCodeService.importActiveCode(reader.getDataList(), user.getTenantId(), user.getId(), tenantAlbumPurchaseId);
+            return HttpResponseResult.succeed();
+        } catch (ExcelException e) {
+            return HttpResponseResult.failed(BizHttpStatus.IMPORT.getCode(), e.getErrMsgList(),
+                    BizHttpStatus.IMPORT.getMsg());
+        }
+    }
+
     @ApiOperation(value = "新增", notes = "机构激活码- 传入 TenantActivationCodeVo.TenantActivationCode")
     @ApiOperation(value = "新增", notes = "机构激活码- 传入 TenantActivationCodeVo.TenantActivationCode")
 //    @PostMapping("/save")
 //    @PostMapping("/save")
     public R<JSONObject> add(@Validated @RequestBody TenantActivationCodeVo.TenantActivationCode tenantActivationCodeVo) {
     public R<JSONObject> add(@Validated @RequestBody TenantActivationCodeVo.TenantActivationCode tenantActivationCodeVo) {

+ 1 - 1
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/TenantAlbumController.java

@@ -63,7 +63,7 @@ public class TenantAlbumController extends BaseController {
         TenantInfo tenantInfo = getTenantInfo();
         TenantInfo tenantInfo = getTenantInfo();
         query.setTenantId(tenantInfo.getId());
         query.setTenantId(tenantInfo.getId());
         // 查询数据
         // 查询数据
-        IPage<TenantAlbum> pages = tenantAlbumService.selectPage(QueryInfo.getPage(query), query);
+        IPage<TenantAlbumWrapper.TenantAlbum> pages = tenantAlbumService.selectPage(QueryInfo.getPage(query), query);
         // 数据类型转换
         // 数据类型转换
         List<TenantAlbumVo.TenantAlbum> records = JSON.parseArray(JSON.toJSONString(pages.getRecords()),
         List<TenantAlbumVo.TenantAlbum> records = JSON.parseArray(JSON.toJSONString(pages.getRecords()),
                 TenantAlbumVo.TenantAlbum.class);
                 TenantAlbumVo.TenantAlbum.class);

+ 100 - 0
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/TenantUnbindRecordController.java

@@ -0,0 +1,100 @@
+package com.yonge.cooleshow.tenant.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.entity.SysArea;
+import com.yonge.cooleshow.biz.dal.service.*;
+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.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 java.util.*;
+import java.util.stream.Collectors;
+
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("/tenantUnbindRecord")
+@Api(tags = "机构解绑申请记录")
+public class TenantUnbindRecordController extends BaseController {
+
+    @Autowired
+    private TenantUnbindRecordService tenantUnbindRecordService;
+
+    @Autowired
+    private SysAreaService sysAreaService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private EmployeeService employeeService;
+
+
+    @ApiOperation(value = "查询分页", notes = "机构解绑申请记录- 传入 TenantUnbindRecordVo.TenantUnbindRecordQuery")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<TenantUnbindRecordWrapper.TenantUnbindRecord>>
+    page(@RequestBody TenantUnbindRecordWrapper.TenantUnbindRecordQuery query) {
+        // 查询数据
+        IPage<TenantUnbindRecordWrapper.TenantUnbindRecord> pages =
+                tenantUnbindRecordService.selectPage(QueryInfo.getPage(query), query);
+
+
+        List<Integer> areaCodeList = pages.getRecords().stream().map(next -> {
+            HashSet<Integer> areaCodes = new HashSet<>();
+            areaCodes.add(next.getProvinceCode());
+            areaCodes.add(next.getCityCode());
+            areaCodes.add(next.getRegionCode());
+            return areaCodes;
+        }).flatMap(Collection::stream).filter(Objects::nonNull).distinct().collect(Collectors.toList());
+        if (!areaCodeList.isEmpty()) {
+            Map<Integer, String> codeNameMap = sysAreaService.lambdaQuery().in(SysArea::getCode, areaCodeList).list()
+                    .stream().collect(Collectors.toMap(SysArea::getCode, SysArea::getName));
+
+            pages.getRecords().forEach(next -> {
+                next.setProvinceName(codeNameMap.getOrDefault(next.getProvinceCode(), ""));
+                next.setCityName(codeNameMap.getOrDefault(next.getCityCode(), ""));
+                next.setRegionName(codeNameMap.getOrDefault(next.getRegionCode(), ""));
+            });
+        }
+        return succeed(QueryInfo.pageInfo(pages, pages.getRecords()));
+    }
+
+    @ApiOperation(value = "审核")
+    @PostMapping("/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("权限不足");
+        }
+
+        if (audio.getId() == null || audio.getStatus() == null) {
+            throw new BizException("参数错误");
+        }
+        Boolean entry = tenantUnbindRecordService.entry(audio);
+
+        return succeed();
+    }
+
+
+}

+ 35 - 21
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/open/OpenTenantController.java

@@ -1,34 +1,22 @@
 package com.yonge.cooleshow.tenant.controller.open;
 package com.yonge.cooleshow.tenant.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.yonge.cooleshow.biz.dal.entity.SysArea;
-import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
-import com.yonge.cooleshow.biz.dal.service.SysAreaService;
+import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
+import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
 import com.yonge.cooleshow.biz.dal.service.TenantApplyRecordService;
 import com.yonge.cooleshow.biz.dal.service.TenantApplyRecordService;
-import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
-import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
-import com.yonge.cooleshow.biz.dal.wrapper.SysAreaWrapper;
+import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantApplyRecordWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantApplyRecordWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
-import com.yonge.cooleshow.tenant.io.request.SysAreaVo;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.exception.BizException;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 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;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 
 
 @Validated
 @Validated
 @RestController
 @RestController
@@ -40,6 +28,12 @@ public class OpenTenantController {
     @Autowired
     @Autowired
     private TenantApplyRecordService tenantApplyRecordService;
     private TenantApplyRecordService tenantApplyRecordService;
 
 
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
+    @Autowired
+    private SmsCodeService smsCodeService;
+
 
 
     @PostMapping("/apply")
     @PostMapping("/apply")
     @ApiOperation(value = "申请")
     @ApiOperation(value = "申请")
@@ -50,4 +44,24 @@ public class OpenTenantController {
 
 
         return HttpResponseResult.status(true);
         return HttpResponseResult.status(true);
     }
     }
+
+
+    @GetMapping("/bindWechat")
+    @ApiOperation(value = "绑定微信")
+    public HttpResponseResult<Boolean> bindWechat(@RequestParam("phone") String phone,
+                                                  @RequestParam("openId") String openId,
+                                                  @RequestParam("code") String code) {
+        // 校验验证码
+        boolean validCode = smsCodeService.verifyValidCode(phone, code, "LOGIN");
+        if (!validCode) {
+            throw new BizException("验证码错误");
+        }
+        TenantStaff tenantStaff = tenantStaffService.getByPhone(phone);
+        if (tenantStaff == null) {
+            return HttpResponseResult.failed(5002, null, "请先申请机构入驻");
+        }
+        tenantStaff.setWxOpenid(openId);
+        tenantStaffService.updateById(tenantStaff);
+        return HttpResponseResult.succeed();
+    }
 }
 }

+ 1 - 1
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/vo/TenantActivationCodeVo.java

@@ -26,7 +26,7 @@ public class TenantActivationCodeVo {
         @NotNull(message = "专辑购买记录的ID不能为空")
         @NotNull(message = "专辑购买记录的ID不能为空")
         private Long tenantAlbumPurchaseId;
         private Long tenantAlbumPurchaseId;
 
 
-        @ApiModelProperty("激活码列表,批量导入时为空")
+        @ApiModelProperty("激活码列表,批量发送时为空")
         private List<String> activationCodeList = new ArrayList<>();
         private List<String> activationCodeList = new ArrayList<>();
 
 
         @ApiModelProperty("学生ID列表")
         @ApiModelProperty("学生ID列表")

+ 12 - 2
pom.xml

@@ -27,6 +27,14 @@
 
 
 	<dependencyManagement>
 	<dependencyManagement>
 		<dependencies>
 		<dependencies>
+
+			<!--统一版本管理-->
+			<!--<dependency>
+				<groupId>org.springframework.security.oauth.boot</groupId>
+				<artifactId>spring-security-oauth2-autoconfigure</artifactId>
+				<version>2.1.0.RELEASE</version>
+			</dependency>-->
+
 			<!--֧��Spring Boot 2.1.X -->
 			<!--֧��Spring Boot 2.1.X -->
 			<dependency>
 			<dependency>
 				<groupId>org.springframework.boot</groupId>
 				<groupId>org.springframework.boot</groupId>
@@ -223,8 +231,8 @@
 
 
 	<repositories>
 	<repositories>
 		<repository>
 		<repository>
-			<id>anigiomaven</id>
-			<name>AnigioMaven</name>
+			<id>dayamaven</id>
+			<name>Daya Maven</name>
 			<url>https://mvn.dayaedu.com/repository/maven-public/</url>
 			<url>https://mvn.dayaedu.com/repository/maven-public/</url>
 		</repository>
 		</repository>
 		<repository>
 		<repository>
@@ -359,6 +367,7 @@
 		</pluginManagement>
 		</pluginManagement>
 		<plugins>
 		<plugins>
 			<plugin>
 			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-compiler-plugin</artifactId>
 				<artifactId>maven-compiler-plugin</artifactId>
 				<version>3.8.0</version>
 				<version>3.8.0</version>
 				<configuration>
 				<configuration>
@@ -375,6 +384,7 @@
 			<plugin>
 			<plugin>
 				<groupId>org.apache.maven.plugins</groupId>
 				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-resources-plugin</artifactId>
 				<artifactId>maven-resources-plugin</artifactId>
+				<version>2.6</version>
 				<configuration>
 				<configuration>
 					<encoding>UTF-8</encoding>
 					<encoding>UTF-8</encoding>
 					<!-- 过滤后缀为pem、pfx的证书文件 -->
 					<!-- 过滤后缀为pem、pfx的证书文件 -->

+ 10 - 0
toolset/toolset-base/src/main/java/com/yonge/toolset/base/exception/BizException.java

@@ -4,6 +4,7 @@ import com.yonge.toolset.base.string.MessageFormatter;
 
 
 public class BizException extends RuntimeException {
 public class BizException extends RuntimeException {
 
 
+	private int code = 500;
 	/**
 	/**
 	 * 
 	 * 
 	 */
 	 */
@@ -17,6 +18,12 @@ public class BizException extends RuntimeException {
 		super(message);
 		super(message);
 	}
 	}
 
 
+	public BizException(Integer code, String message) {
+		super(message);
+		// 统一错误码
+		this.code = code;
+	}
+
 	public BizException(Throwable cause) {
 	public BizException(Throwable cause) {
 		super(cause);
 		super(cause);
 	}
 	}
@@ -33,4 +40,7 @@ public class BizException extends RuntimeException {
 		super(MessageFormatter.arrayFormat(message, args), cause);
 		super(MessageFormatter.arrayFormat(message, args), cause);
 	}
 	}
 
 
+	public int getCode() {
+		return code;
+	}
 }
 }