liujc 2 anni fa
parent
commit
446f1c7d19
100 ha cambiato i file con 4107 aggiunte e 983 eliminazioni
  1. 16 0
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/TenantFeignService.java
  2. 16 0
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/fallback/TenantFeignServiceFallback.java
  3. 18 0
      cooleshow-auth/auth-api/pom.xml
  4. 10 0
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/LoginEntity.java
  5. 95 0
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/WxConfigInfo.java
  6. 55 0
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/WxTemplateConfig.java
  7. 63 0
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/entity/WxTemplateMessage.java
  8. 4 1
      cooleshow-auth/auth-server/pom.xml
  9. 14 10
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/config/WebSecurityConfig.java
  10. 3 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/filter/PhoneLoginAuthenticationFilter.java
  11. 15 8
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/handler/BaseAuthenticationFailureEvenHandler.java
  12. 147 82
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/provider/PhoneAuthenticationProvider.java
  13. 7 8
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/SysUserDao.java
  14. 27 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/WxConfigInfoMapper.java
  15. 27 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/WxTemplateConfigMapper.java
  16. 27 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/WxTemplateMessageMapper.java
  17. 63 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/wrapper/WxConfigInfoWrapper.java
  18. 63 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/wrapper/WxTemplateConfigWrapper.java
  19. 63 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/wrapper/WxTemplateMessageWrapper.java
  20. 76 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/enums/ELoginType.java
  21. 50 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/MWxMpService.java
  22. 43 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/WxCacheService.java
  23. 113 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/domain/WxConfigStorageWrapper.java
  24. 25 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/domain/WxContentWrapper.java
  25. 51 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/handler/WxMessageRouteEvent.java
  26. 292 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/impl/MWxMpServiceImpl.java
  27. 115 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/middleware/wechat/impl/WxCacheServiceImpl.java
  28. 10 4
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/SysUserService.java
  29. 67 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/WxConfigInfoService.java
  30. 43 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/WxTemplateConfigService.java
  31. 43 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/WxTemplateMessageService.java
  32. 14 5
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/SysUserServiceImpl.java
  33. 145 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/WxConfigInfoServiceImpl.java
  34. 65 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/WxTemplateConfigServiceImpl.java
  35. 65 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/WxTemplateMessageServiceImpl.java
  36. 1 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/web/controller/TokenController.java
  37. 20 0
      cooleshow-auth/auth-server/src/main/resources/config/mybatis/SysUserMapper.xml
  38. 35 0
      cooleshow-auth/auth-server/src/main/resources/config/mybatis/WxConfigInfoMapper.xml
  39. 25 0
      cooleshow-auth/auth-server/src/main/resources/config/mybatis/WxTemplateConfigMapper.xml
  40. 27 0
      cooleshow-auth/auth-server/src/main/resources/config/mybatis/WxTemplateMessageMapper.xml
  41. 4 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/AppConstant.java
  42. 21 15
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/controller/BaseController.java
  43. 19 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/jobs/TenantPersonStatTask.java
  44. 123 95
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/StudentController.java
  45. 70 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/SysGoodsPriceController.java
  46. 165 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantAlbumController.java
  47. 28 35
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantInfoController.java
  48. 1 23
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantUnbindRecordController.java
  49. 120 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/TenantAlbumVo.java
  50. 69 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/TenantInfoVo.java
  51. 1 7
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/task/TaskController.java
  52. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/StudentDao.java
  53. 11 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/TeacherDao.java
  54. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/UserOrderDao.java
  55. 15 96
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/OrderSearch.java
  56. 4 55
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/PlatformCashAccountRecordSearch.java
  57. 3 79
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/TeacherWithdrawalSearch.java
  58. 27 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/StudentCounts.java
  59. 26 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/TeacherCounts.java
  60. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/TenantAlbum.java
  61. 2 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/TenantAlbumMusic.java
  62. 14 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserOrder.java
  63. 36 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/SubjectTypeEnum.java
  64. 7 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/PaymentDivMemberRecordMapper.java
  65. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/TenantAlbumMapper.java
  66. 3 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/TenantAlbumRefMapper.java
  67. 11 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/TenantInfoMapper.java
  68. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/TenantStaffMapper.java
  69. 5 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/queryInfo/SysMusicCompareRecordQueryInfo.java
  70. 4 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/PaymentDivMemberRecordService.java
  71. 7 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/StudentService.java
  72. 26 10
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantActivationCodeService.java
  73. 3 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumRefService.java
  74. 25 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumService.java
  75. 6 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantInfoService.java
  76. 6 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantUnbindRecordService.java
  77. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserOrderService.java
  78. 24 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/PaymentDivMemberRecordServiceImpl.java
  79. 40 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/StudentServiceImpl.java
  80. 90 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantActivationCodeServiceImpl.java
  81. 8 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantAlbumRefServiceImpl.java
  82. 94 14
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantAlbumServiceImpl.java
  83. 163 134
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantInfoServiceImpl.java
  84. 4 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantPersonStatServiceImpl.java
  85. 144 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantUnbindRecordServiceImpl.java
  86. 11 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderServiceImpl.java
  87. 30 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/PaymentDivMemberRecordWrapper.java
  88. 13 14
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/StudentWrapper.java
  89. 43 6
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/SysGoodsPriceWrapper.java
  90. 32 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantActivationCodeWrapper.java
  91. 124 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantAlbumWrapper.java
  92. 41 29
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantInfoWrapper.java
  93. 0 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantPersonStatWrapper.java
  94. 13 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantUnbindRecordWrapper.java
  95. 24 2
      cooleshow-user/user-biz/src/main/resources/config/mybatis/PaymentDivMemberRecordMapper.xml
  96. 6 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/PlatformCashAccountRecordMapper.xml
  97. 11 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/StudentMapper.xml
  98. 35 22
      cooleshow-user/user-biz/src/main/resources/config/mybatis/SysMusicCompareRecordMapper.xml
  99. 192 161
      cooleshow-user/user-biz/src/main/resources/config/mybatis/TeacherMapper.xml
  100. 20 12
      cooleshow-user/user-biz/src/main/resources/config/mybatis/TenantAlbumMapper.xml

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

@@ -0,0 +1,16 @@
+package com.yonge.cooleshow.api.feign;
+
+import com.yonge.cooleshow.api.feign.fallback.AdminFeignServiceFallback;
+import com.yonge.cooleshow.common.constant.AppConstant;
+import com.yonge.toolset.feign.config.FeignConfiguration;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+
+@FeignClient(name = AppConstant.APPLICATION_TENANT + AppConstant.SERVER, configuration = FeignConfiguration.class,
+        fallback = AdminFeignServiceFallback.class)
+public interface TenantFeignService {
+
+    //机构人员汇总
+    @GetMapping(value = "/task/tenantPersonStat")
+    void tenantPersonStat();
+}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

+ 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;
 
-import java.util.List;
-
-import com.yonge.cooleshow.common.enums.SysUserType;
-import io.swagger.models.auth.In;
-import org.apache.ibatis.annotations.Param;
-
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
 import com.yonge.cooleshow.auth.api.dto.UserSetReq;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
-import com.yonge.cooleshow.common.enums.UserLockFlag;
 import com.yonge.cooleshow.auth.api.vo.UserSetVo;
-import com.yonge.toolset.mybatis.dal.BaseDAO;
 import com.yonge.cooleshow.common.entity.ImUserModel;
+import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.toolset.mybatis.dal.BaseDAO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 public interface SysUserDao extends BaseDAO<Long, SysUser> {
 
@@ -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);
 
     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;
 
-import java.util.List;
-
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.dto.SysUserInfo;
 import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
@@ -10,10 +8,10 @@ import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.api.vo.UserSetVo;
 import com.yonge.cooleshow.auth.enums.EClientType;
 import com.yonge.cooleshow.common.entity.ImUserModel;
-import com.yonge.cooleshow.common.enums.SysUserType;
-import com.yonge.cooleshow.common.enums.UserLockFlag;
 import com.yonge.toolset.mybatis.service.BaseService;
 
+import java.util.List;
+
 public interface SysUserService extends BaseService<Long, SysUser> {
 
     /**
@@ -214,4 +212,12 @@ public interface SysUserService extends BaseService<Long, SysUser> {
 
     //根据用户类型获取机构编号
     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.google.common.collect.Lists;
 import com.yonge.cooleshow.api.feign.AdminFeignService;
-import com.yonge.cooleshow.api.feign.TeacherFeignService;
 import com.yonge.cooleshow.api.feign.dto.UserFriendInfoVO;
 import com.yonge.cooleshow.auth.api.dto.QRLoginDto;
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
@@ -69,8 +68,6 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
     private AdminFeignService adminFeignService;
     @Autowired
     private CustomerServiceConfig customerServiceConfig;
-    @Autowired
-    private TeacherFeignService teacherFeignService;
 
     @Override
     public BaseDAO<Long, SysUser> getDAO() {
@@ -120,12 +117,12 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
         userInfo.setSysUser(sysUser);
 
         List<String> roleCodeList = sysUserRoleService.queryRoleCodeListByUserId(sysUser.getId());
-        userInfo.setRoles(roleCodeList.toArray(new String[roleCodeList.size()]));
+        userInfo.setRoles(roleCodeList.toArray(new String[0]));
 
         List<Long> roleIdList = sysUserRoleService.queryRoleIdListByUserId(sysUser.getId());
         List<String> permissionList = sysRoleMenuService.queryPermissionsByRoleIdList(roleIdList);
 
-        userInfo.setPermissions(permissionList.toArray(new String[permissionList.size()]));
+        userInfo.setPermissions(permissionList.toArray(new String[0]));
 
         return userInfo;
     }
@@ -410,4 +407,16 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
         // 查询用户机构信息,若没有则返回-1
         return Optional.ofNullable(sysUserDao.getTenantByClient(userId, clientId)).orElse(-1L);
     }
+
+    /**
+     * 根据openId获取用户信息
+     *
+     * @param openId 用户openId
+     * @param clientId 客户端ID
+     * @return SysUser
+     */
+    @Override
+    public SysUser getSysUserByOpenId(String openId, String clientId) {
+        return sysUserDao.getSysUserByOpenId(openId, clientId);
+    }
 }

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

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

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

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

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

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

+ 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 = "smsCode", value = "验证码", required = true, dataType = "String"),
             @ApiImplicitParam(name = "isSurportRegister", value = "是否在登录时注册", dataType = "Boolean"),
+            @ApiImplicitParam(name = "loginType", value = "登陆类型", dataType = "String", defaultValue = "PASSWORD"),
             @ApiImplicitParam(name = "loginUserType", value = "登录用户类型 STUDENT TEACHER(官网登录)", dataType = "String")
     })
     public Object smsLogin() {

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

@@ -335,4 +335,24 @@
         </if>
     </update>
 
+    <select id="getSysUserByOpenId" resultType="com.yonge.cooleshow.auth.api.entity.SysUser">
+        SELECT t1.*
+        FROM sys_user t1 LEFT JOIN
+        <choose>
+            <when test="clientId == 'STUDENT'">
+                student
+            </when>
+            <when test="clientId == 'TEACHER'">
+                teacher
+            </when>
+            <when test="clientId == 'ORGANIZATION'">
+                tenant_staff
+            </when>
+            <otherwise>
+                employee
+            </otherwise>
+        </choose> t2 ON (t1.id_ = t2.user_id_)
+        WHERE t1.del_flag_ = 0 and t2.wx_openid_ = #{openId} LIMIT 1
+    </select>
+
 </mapper>

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

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

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

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

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

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

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

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

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

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

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

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

+ 123 - 95
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/StudentController.java

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

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

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

@@ -0,0 +1,165 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.admin.io.request.TenantAlbumVo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.TenantAlbum;
+import com.yonge.cooleshow.biz.dal.entity.TenantAlbumMusic;
+import com.yonge.cooleshow.biz.dal.entity.TenantAlbumRef;
+import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.enums.SubjectTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.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.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @Author:haonan
+ * @Date:2023/7/27 18:26
+ * @Filename:TenantAlbumController
+ */
+
+@RestController
+@RequestMapping("/tenantAlbum")
+@Api(value = "机构管理", tags = "机构管理")
+public class TenantAlbumController {
+    @Autowired
+    TenantAlbumService tenantAlbumService;
+
+    @Autowired
+    private TenantAlbumMusicService tenantAlbumMusicService;
+
+    @Autowired
+    private TenantAlbumRefService tenantAlbumRefService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    /**
+     * 查询分页
+     *
+     * @param query
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "tenantAlbum")
+    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/page')")
+    public HttpResponseResult<PageInfo<TenantAlbumWrapper.TenantAlbum>> page(@RequestBody TenantAlbumWrapper.TenantAlbumQuery query) {
+        IPage<TenantAlbumWrapper.TenantAlbum> pages = tenantAlbumService.selectPage(QueryInfo.getPage(query), query);
+        return HttpResponseResult.succeed(PageUtil.pageInfo(pages));
+    }
+
+
+    /**
+     * 查询详情
+     *
+     * @param id 详情ID
+     * @return TenantAlbum
+     */
+    @PostMapping("/detail")
+    @ApiOperation(value = "查询详情", notes = "detail")
+    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/detail')")
+    public HttpResponseResult<TenantAlbumWrapper.TenantAlbum> detail(@RequestParam("id") Long id) {
+        TenantAlbum tenantAlbum = tenantAlbumService.detail(id);
+        if (tenantAlbum == null) {
+            throw new BizException("专辑信息不存在");
+        }
+
+        TenantAlbumWrapper.TenantAlbum vo = JSON.parseObject(JSON.toJSONString(tenantAlbum),
+                TenantAlbumWrapper.TenantAlbum.class);
+
+        //查关联表
+        TenantAlbumRef one = tenantAlbumRefService.lambdaQuery().eq(TenantAlbumRef::getTenantAlbumId, id)
+                .last("limit 1").one();
+        vo.setTenantId(one.getTenantId());
+        //查询曲目表
+
+        TenantInfo tenantInfo = tenantInfoService.getById(one.getTenantId());
+        vo.setTenantName(tenantInfo.getName());
+        List<TenantAlbumMusic> tenantAlbumMusics = tenantAlbumMusicService.lambdaQuery()
+                .eq(TenantAlbumMusic::getTenantAlbumId, id)
+                .eq(TenantAlbumMusic::getDelFlag, false)
+                .list();
+
+        Map<SubjectTypeEnum, List<TenantAlbumMusic>> groupByType =
+                tenantAlbumMusics.stream().collect(Collectors.groupingBy(TenantAlbumMusic::getSubjectType));
+
+        List<TenantAlbumWrapper.MusicSheetData> musicSheetData = vo.getMusicSheetData();
+        groupByType.forEach((key, value) -> {
+            value.sort(Comparator.comparing(TenantAlbumMusic::getSortNumber));
+            TenantAlbumWrapper.MusicSheetData sheetData = new TenantAlbumWrapper.MusicSheetData();
+            sheetData.setSubjectType(key);
+            sheetData.setMusicSheetList(value);
+            musicSheetData.add(sheetData);
+
+        });
+
+        return HttpResponseResult.succeed(vo);
+    }
+
+
+    /**
+     * 新增专辑
+     */
+    @PostMapping("/save")
+    @ApiOperation(value = "新增专辑", notes = "新增专辑")
+    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/save')")
+    public HttpResponseResult<Boolean> save(@Validated @RequestBody TenantAlbumVo.TenantAlbum album) {
+        TenantAlbum tenantAlbum = JSON.parseObject(album.jsonString(), TenantAlbum.class);
+        List<TenantAlbumVo.MusicSheetData> musicSheetData = album.getMusicSheetData();
+
+        List<TenantAlbumWrapper.MusicSheetData> musicSheetDataList = musicSheetData.stream().map(next ->
+                        JSON.parseObject(JSON.toJSONString(next), TenantAlbumWrapper.MusicSheetData.class))
+                .collect(Collectors.toList());
+        tenantAlbumService.insertTenantAlbum(album.getTenantId(), tenantAlbum, musicSheetDataList);
+        return HttpResponseResult.succeed();
+    }
+
+    @PostMapping("/update")
+    @ApiOperation(value = "修改专辑", notes = "修改专辑")
+    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/save')")
+    public HttpResponseResult<Boolean> update(@Validated @RequestBody TenantAlbumVo.TenantAlbum album) {
+        TenantAlbum tenantAlbum = JSON.parseObject(album.jsonString(), TenantAlbum.class);
+        List<TenantAlbumVo.MusicSheetData> musicSheetData = album.getMusicSheetData();
+
+        List<TenantAlbumWrapper.MusicSheetData> musicSheetDataList = musicSheetData.stream().map(next ->
+                        JSON.parseObject(JSON.toJSONString(next), TenantAlbumWrapper.MusicSheetData.class))
+                .collect(Collectors.toList());
+        tenantAlbumService.updateAlbum(album.getTenantId(), tenantAlbum, musicSheetDataList);
+        return HttpResponseResult.succeed();
+    }
+
+    @PostMapping("/updateStatus")
+    @ApiOperation(value = "启用/冻结", notes = "启用/冻结")
+    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/updateStatus')")
+    public HttpResponseResult<Boolean> updateStatus(@Validated @RequestBody TenantAlbumVo.UpdateStatus status) {
+        tenantAlbumService.lambdaUpdate()
+                .set(TenantAlbum::getStatus, status.getStatus())
+                .eq(TenantAlbum::getId, status.getId())
+                .update();
+        return HttpResponseResult.succeed();
+    }
+
+}

+ 28 - 35
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantInfoController.java

@@ -1,14 +1,14 @@
 package com.yonge.cooleshow.admin.controller;
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.yonge.cooleshow.biz.dal.dto.req.TeacherSubmitReq;
+import com.yonge.cooleshow.admin.io.request.TenantInfoVo;
 import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
 import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.base.page.PageInfo;
-import com.yonge.toolset.base.util.StringUtil;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -39,47 +39,43 @@ public class TenantInfoController extends BaseController {
      */
     @PostMapping("/page")
     @ApiOperation(value = "查询分页", notes = "TenantInfo")
-    //@PreAuthorize("@pcs.hasPermissions('tenantInfo/page')")
+    @PreAuthorize("@pcs.hasPermissions('tenantInfo/page')")
     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(query);
         return succeed(PageUtil.pageInfo(pages));
     }
 
-    /**
-     * 修改数据
-     */
-    @PostMapping("/update")
-    @ApiOperation(value = "修改", notes = "传入TenantInfo")
-    @PreAuthorize("@pcs.hasPermissions('tenantInfo/update')")
-    public HttpResponseResult<Boolean> updateTenantInfo(@Valid @RequestBody TenantInfo info) {
-
-        return succeed(tenantInfoService.updateTenantInfo(info));
-    }
-
 
     /**
      * 插入数据
      */
-    @PostMapping("/insert")
+    @PostMapping("/add")
     @ApiOperation(value = "更新", notes = "传入TenantInfo")
-    @PreAuthorize("@pcs.hasPermissions('tenantInfo/insert')")
-    public HttpResponseResult<Boolean> insertTenantInfo(@Validated(TenantInfo.class) @RequestBody TenantInfo info) {
-        return succeed(tenantInfoService.add(info));
+    @PreAuthorize("@pcs.hasPermissions('tenantInfo/add')")
+    public HttpResponseResult<Boolean> add(@Validated @RequestBody TenantInfoVo.TenantInfo info) {
+        return succeed(tenantInfoService.add(JSON.parseObject(info.jsonString(), TenantInfo.class)));
     }
 
+    /**
+     * 修改数据
+     */
+    @PostMapping("/update")
+    @ApiOperation(value = "修改", notes = "传入TenantInfo")
+    @PreAuthorize("@pcs.hasPermissions('tenantInfo/update')")
+    public HttpResponseResult<Boolean> update(@Valid @RequestBody TenantInfoVo.TenantInfo info) {
+        return succeed(tenantInfoService.update(JSON.parseObject(info.jsonString(), TenantInfo.class)));
+    }
 
     /**
      * 冻结
      */
-    @PostMapping("/state")
+    @PostMapping("/updateStatus")
     @ApiOperation(value = "冻结", notes = "传入id和布尔类型")
-    @PreAuthorize("@pcs.hasPermissions('tenantInfo/state')")
-    public HttpResponseResult<Boolean> state(@RequestBody TenantInfoWrapper.TenantInfoQuery query) {
-        if (StringUtil.isEmpty(query.getId())) {
-            return failed("参数不能为空");
-        }
-        return status(tenantInfoService.state(query));
+    @PreAuthorize("@pcs.hasPermissions('tenantInfo/updateStatus')")
+    public HttpResponseResult<Boolean> updateStatus(@RequestBody TenantInfoWrapper.UpdateStatus updateStatus) {
+        tenantInfoService.updateStatus(updateStatus);
+        return succeed();
     }
 
 
@@ -91,8 +87,9 @@ public class TenantInfoController extends BaseController {
     //@PreAuthorize("@pcs.hasPermissions('tenantInfo/applyPage')")
     public HttpResponseResult<PageInfo<TenantInfoWrapper.TenantInfo>> applyPage(@RequestBody TenantInfoWrapper.TenantInfoQuery query) {
 
-        IPage<TenantInfoWrapper.TenantInfo> pages = tenantInfoService.applyPage(PageUtil.getPage(query), query);
-        return succeed(PageUtil.pageInfo(pages));
+//        IPage<TenantInfoWrapper.TenantInfo> pages = tenantInfoService.applyPage(PageUtil.getPage(query), query);
+//        return succeed(PageUtil.pageInfo(pages));
+        return null;
     }
 
 
@@ -105,8 +102,9 @@ public class TenantInfoController extends BaseController {
     //@PreAuthorize("@pcs.hasPermissions('tenantInfo/historyPage')")
     public HttpResponseResult<PageInfo<TenantInfoWrapper.TenantInfo>> historyPage(@RequestBody TenantInfoWrapper.TenantInfoQuery query) {
 
-        IPage<TenantInfoWrapper.TenantInfo> pages = tenantInfoService.historyPage(PageUtil.getPage(query), query);
-        return succeed(PageUtil.pageInfo(pages));
+//        IPage<TenantInfoWrapper.TenantInfo> pages = tenantInfoService.historyPage(PageUtil.getPage(query), query);
+//        return succeed(PageUtil.pageInfo(pages));
+        return null;
     }
 
 
@@ -135,9 +133,4 @@ 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) {
             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();
     }
 

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

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

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

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

+ 1 - 7
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/task/TaskController.java

@@ -9,11 +9,7 @@ import org.redisson.api.RBucket;
 import org.redisson.api.RedissonClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 import springfox.documentation.annotations.ApiIgnore;
 
 import java.io.File;
@@ -56,8 +52,6 @@ public class TaskController extends BaseController {
     private TeacherStyleVideoService teacherStyleVideoService;
 
     @Autowired
-    private VideoLessonGroupService videoLessonGroupService;
-    @Autowired
     private CustomerServiceBatchSendingService customerServiceBatchSendingService;
 
     @Autowired

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

@@ -11,6 +11,7 @@ import com.yonge.cooleshow.biz.dal.entity.Student;
 import com.yonge.cooleshow.biz.dal.entity.Subject;
 import com.yonge.cooleshow.biz.dal.vo.MyFollow;
 import com.yonge.cooleshow.biz.dal.vo.StudentVo;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper;
 import org.apache.ibatis.annotations.Param;
 
 public interface StudentDao extends BaseMapper<Student> {
@@ -74,4 +75,6 @@ public interface StudentDao extends BaseMapper<Student> {
     List<Map<Integer, String>> getStudentSubjectMapList(List<Long> studentIds);
 
     int countStudentsWithTenant(Map<String, Object> params);
+
+    List<TenantInfoWrapper.UserCount> countTeacherByTenantIds(@Param("tenantIdList") List<Long> tenantIdList);
 }

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

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

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

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

+ 15 - 96
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/OrderSearch.java

@@ -5,6 +5,7 @@ import com.yonge.cooleshow.common.enums.EPaymentVersion;
 import com.yonge.toolset.base.page.QueryInfo;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
 import java.time.LocalDateTime;
 
@@ -12,129 +13,47 @@ import java.time.LocalDateTime;
  * @Author: liweifan
  * @Data: 2022-03-30 13:53:51
  */
+@Data
 @ApiModel(value = "OrderSearch对象", description = "平台订单表查询对象")
 public class OrderSearch extends QueryInfo{
     @ApiModelProperty("交易流水号/订单号")
 	private String searchNo;
+
 	@ApiModelProperty("下单应用:STUDENT 学生端 TEACHER 老师端")
 	private String orderClient;
+
 	@ApiModelProperty("交易类型:  VIP、开通会员  PRACTICE、陪练课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ACTI_REGIST、活动报名(多选用,分割)")
 	private String orderType;
+
 	@ApiModelProperty("订单状态 WAIT_PAY 待支付 PAYING 支付中  PAID 已付款 CLOSE 已关闭 FAIL 支付失败 (多选用,分割)")
 	private String status;
+
 	@ApiModelProperty(value = "交易开始时间")
 	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
 	private LocalDateTime startTime;
+
 	@ApiModelProperty(value = "交易结束时间")
 	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
 	private LocalDateTime endTime;
+
 	@ApiModelProperty("买家id")
 	private Long userId;
+
 	@ApiModelProperty("卖家id")
 	private Long merchId;
+
+	@ApiModelProperty("机构编号")
+	private Long tenantId;
+
 	@ApiModelProperty("查询时间(yyyy-mm) ")
 	private String searchDate;
+
 	@ApiModelProperty(hidden = true)
 	private String goodType;
+
 	@ApiModelProperty(hidden = true)
 	private Long bizId;
 
     @ApiModelProperty(value = "版本",hidden = true)
     private EPaymentVersion paymentVersion;
-
-    public EPaymentVersion getPaymentVersion() {
-        return paymentVersion;
-    }
-
-    public void setPaymentVersion(EPaymentVersion paymentVersion) {
-        this.paymentVersion = paymentVersion;
-    }
-
-    public String getSearchNo() {
-		return searchNo;
-	}
-
-	public void setSearchNo(String searchNo) {
-		this.searchNo = searchNo;
-	}
-
-	public String getOrderType() {
-		return orderType;
-	}
-
-	public void setOrderType(String orderType) {
-		this.orderType = orderType;
-	}
-
-	public String getStatus() {
-		return status;
-	}
-
-	public void setStatus(String status) {
-		this.status = status;
-	}
-
-	public LocalDateTime getStartTime() {
-		return startTime;
-	}
-
-	public void setStartTime(LocalDateTime startTime) {
-		this.startTime = startTime;
-	}
-
-	public LocalDateTime getEndTime() {
-		return endTime;
-	}
-
-	public void setEndTime(LocalDateTime endTime) {
-		this.endTime = endTime;
-	}
-
-	public Long getUserId() {
-		return userId;
-	}
-
-	public void setUserId(Long userId) {
-		this.userId = userId;
-	}
-
-	public Long getMerchId() {
-		return merchId;
-	}
-
-	public void setMerchId(Long merchId) {
-		this.merchId = merchId;
-	}
-
-	public String getSearchDate() {
-		return searchDate;
-	}
-
-	public void setSearchDate(String searchDate) {
-		this.searchDate = searchDate;
-	}
-
-	public String getGoodType() {
-		return goodType;
-	}
-
-	public void setGoodType(String goodType) {
-		this.goodType = goodType;
-	}
-
-	public Long getBizId() {
-		return bizId;
-	}
-
-	public void setBizId(Long bizId) {
-		this.bizId = bizId;
-	}
-
-	public String getOrderClient() {
-		return orderClient;
-	}
-
-	public void setOrderClient(String orderClient) {
-		this.orderClient = orderClient;
-	}
 }

+ 4 - 55
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/PlatformCashAccountRecordSearch.java

@@ -8,7 +8,9 @@ import io.swagger.annotations.ApiModelProperty;
 import java.util.Date;
 
 import com.yonge.toolset.base.page.QueryInfo;
+import lombok.Data;
 
+@Data
 public class PlatformCashAccountRecordSearch extends QueryInfo {
 
 	@ApiModelProperty("关联订单号")
@@ -33,59 +35,6 @@ public class PlatformCashAccountRecordSearch extends QueryInfo {
 	@ApiModelProperty("记录结束时间")
 	private Date endDate;
 
-	public String getOrderNo() {
-		return orderNo;
-	}
-
-	public void setOrderNo(String orderNo) {
-		this.orderNo = orderNo;
-	}
-
-	public Long getBizId() {
-		return bizId;
-	}
-
-	public void setBizId(Long bizId) {
-		this.bizId = bizId;
-	}
-
-	public String getInOrOut() {
-		return inOrOut;
-	}
-
-	public void setInOrOut(String inOrOut) {
-		this.inOrOut = inOrOut;
-	}
-
-	public AccountBizTypeEnum getBizType() {
-		return bizType;
-	}
-
-	public void setBizType(AccountBizTypeEnum bizType) {
-		this.bizType = bizType;
-	}
-
-	public PostStatusEnum getPostStatus() {
-		return postStatus;
-	}
-
-	public void setPostStatus(PostStatusEnum postStatus) {
-		this.postStatus = postStatus;
-	}
-
-	public Date getStartDate() {
-		return startDate;
-	}
-
-	public void setStartDate(Date startDate) {
-		this.startDate = startDate;
-	}
-
-	public Date getEndDate() {
-		return endDate;
-	}
-
-	public void setEndDate(Date endDate) {
-		this.endDate = endDate;
-	}
+	@ApiModelProperty("机构编号")
+	private Long tenantId;
 }

+ 3 - 79
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/TeacherWithdrawalSearch.java

@@ -7,6 +7,7 @@ import com.yonge.toolset.base.page.QueryInfo;
 import com.yonge.toolset.payment.base.enums.TradeStatusEnum;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
 import java.time.LocalDateTime;
 
@@ -14,6 +15,7 @@ import java.time.LocalDateTime;
  * @Author: liweifan
  * @Data: 2022-03-30 13:53:51
  */
+@Data
 @ApiModel(value = "TeacherWithdrawalSearch对象", description = "老师账户结算表查询对象")
 public class TeacherWithdrawalSearch extends QueryInfo{
 	private static final long serialVersionUID = 1L;
@@ -42,83 +44,5 @@ public class TeacherWithdrawalSearch extends QueryInfo{
 
 	private Long userId;
 
-	public String getTransNo() {
-		return transNo;
-	}
-
-	public void setTransNo(String transNo) {
-		this.transNo = transNo;
-	}
-
-	public String getUsername() {
-		return username;
-	}
-
-	public void setUsername(String username) {
-		this.username = username;
-	}
-
-	public TradeStatusEnum getTradeStatus() {
-		return tradeStatus;
-	}
-
-	public void setTradeStatus(TradeStatusEnum tradeStatus) {
-		this.tradeStatus = tradeStatus;
-	}
-
-	public LocalDateTime getStartTime() {
-		return startTime;
-	}
-
-	public void setStartTime(LocalDateTime startTime) {
-		this.startTime = startTime;
-	}
-
-	public LocalDateTime getEndTime() {
-		return endTime;
-	}
-
-	public void setEndTime(LocalDateTime endTime) {
-		this.endTime = endTime;
-	}
-
-	public String getSearchDate() {
-		return searchDate;
-	}
-
-	public void setSearchDate(String searchDate) {
-		this.searchDate = searchDate;
-	}
-
-	public Long getUserId() {
-		return userId;
-	}
-
-	public void setUserId(Long userId) {
-		this.userId = userId;
-	}
-
-	public AuthStatusEnum getAuthStatus() {
-		return authStatus;
-	}
-
-	public void setAuthStatus(AuthStatusEnum authStatus) {
-		this.authStatus = authStatus;
-	}
-
-	public String getVerifyUser() {
-		return verifyUser;
-	}
-
-	public void setVerifyUser(String verifyUser) {
-		this.verifyUser = verifyUser;
-	}
-
-	public String getStatus() {
-		return status;
-	}
-
-	public void setStatus(String status) {
-		this.status = status;
-	}
+	private Long tenantId;
 }

+ 27 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/StudentCounts.java

@@ -0,0 +1,27 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @Author:haonan
+ * @Date:2023/7/31 18:45
+ * @Filename:TeacherCounts
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class StudentCounts {
+
+    @ApiModelProperty("学生数量")
+    private Integer studentCounts;
+
+
+    @ApiModelProperty("对应id")
+    private Integer id;
+
+}

+ 26 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/TeacherCounts.java

@@ -0,0 +1,26 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @Author:haonan
+ * @Date:2023/7/31 18:45
+ * @Filename:TeacherCounts
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class TeacherCounts {
+
+    @ApiModelProperty("老师数量")
+    private Integer teacherCounts;
+
+    @ApiModelProperty("对应id")
+    private Integer id;
+
+}

+ 4 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/TenantAlbum.java

@@ -43,6 +43,10 @@ public class TenantAlbum implements Serializable {
 	@TableField(value = "music_num_")
     private Integer musicNum;
 
+    @ApiModelProperty("原价")
+    @TableField(value = "cost_price_")
+    private BigDecimal costPrice;
+
     @ApiModelProperty("平台价格") 
 	@TableField(value = "original_price_")
     private BigDecimal originalPrice;

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

+ 14 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserOrder.java

@@ -39,7 +39,6 @@ public class UserOrder implements Serializable {
     @TableField(value = "order_no_")
     private String orderNo;
 
-
     @ApiModelProperty("支付版本 ")
     @TableField(value = "payment_version_")
     private EPaymentVersion paymentVersion;
@@ -79,50 +78,64 @@ public class UserOrder implements Serializable {
     @ApiModelProperty("订单名称 ")
     @TableField(value = "order_name_")
     private String orderName;
+
     @ApiModelProperty("下单应用:STUDENT 学生端 TEACHER 老师端")
     @TableField(value = "order_client_")
     private ClientEnum orderClient;
+
     @ApiModelProperty("订单类型: 学生端( VIP、开通会员  PRACTICE、陪练课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ACTI_REGIST、活动报名 TENANT_ALBUM 平台专辑) " +
             "老师端(VIP、开通会员 PIANO_ROOM、琴房时长)")
     @TableField(value = "order_type_")
     private OrderTypeEnum orderType;
+
     @ApiModelProperty("订单描述信息 ")
     @TableField(value = "order_desc_")
     private String orderDesc;
+
     @ApiModelProperty("订单状态 WAIT_PAY 待支付 PAYING 支付中  PAID 已付款 CLOSE 已关闭 FAIL 支付失败")
     @TableField(value = "status_")
     private OrderStatusEnum status;
+
     @ApiModelProperty("原价 ")
     @TableField(value = "original_price_")
     private BigDecimal originalPrice;
+
     @ApiModelProperty("预计价格 ")
     @TableField(value = "expect_price_")
     private BigDecimal expectPrice;
+
     @ApiModelProperty("实际价格 ")
     @TableField(value = "actual_price_")
     private BigDecimal actualPrice;
+
     @ApiModelProperty("优惠金额 ")
     @TableField(value = "coupon_amount_")
     private BigDecimal couponAmount;
+
     @ApiModelProperty("平台服务费 ")
     @TableField(value = "plantform_fee_")
     private BigDecimal plantformFee;
+
     @ApiModelProperty("用户备注 ")
     @TableField(value = "user_note_")
     private String userNote;
+
     @ApiModelProperty("下单时间 ")
     @TableField(value = "create_time_")
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date createTime;
+
     @ApiModelProperty("支付时间 ")
     @TableField(value = "pay_time_")
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date payTime;
+
     @ApiModelProperty("原因 ")
     @TableField(value = "reason_")
     private String reason;
+
     @TableField(value = "update_time_")
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")

+ 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) {
+        code = this.name();
+        this.msg = msg;
+    }
+
+    public String getMsg() {
+        return this.msg;
+    }
+
+    @Override
+    public String getCode() {
+        return this.code;
+    }
+}

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

@@ -29,5 +29,11 @@ public interface PaymentDivMemberRecordMapper extends BaseMapper<PaymentDivMembe
 																		@Param("param") PaymentDivMemberRecordWrapper.IndexIncomeQuery param);
 
 	//小程序首页订单详情
-    PaymentDivMemberRecordWrapper.OrderDetailDto getOrderDetail(@Param("orderNo") String orderNo, @Param("tenantId") Long tenantId);
+    PaymentDivMemberRecordWrapper.OrderDetailDto getIncomeOrderDetail(@Param("orderNo") String orderNo, @Param("tenantId") Long tenantId);
+
+	//首页收入汇总
+	List<PaymentDivMemberRecordWrapper.IndexIncomeSummaryDetailDto> incomeSummary(@Param("query") PaymentDivMemberRecordWrapper.IndexIncomeQuery query);
+
+	//首页支出汇总
+    List<PaymentDivMemberRecordWrapper.IndexIncomeSummaryDetailDto> expendSummary(@Param("query") PaymentDivMemberRecordWrapper.IndexIncomeQuery query);
 }

+ 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
 	 * @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>
 	 */
 	List<TenantAlbumRef> selectPage(@Param("page") IPage<TenantAlbumRef> page, @Param("param") TenantAlbumRefWrapper.TenantAlbumRefQuery param);
-	
+
+
+    TenantAlbumRef selectByAlbumId(@Param("id") Long id);
 }

+ 11 - 4
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/TenantInfoMapper.java

@@ -1,10 +1,12 @@
 package com.yonge.cooleshow.biz.dal.mapper;
 
-import java.util.ArrayList;
+
 import java.util.List;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.entity.StudentCounts;
+import com.yonge.cooleshow.biz.dal.entity.TeacherCounts;
 import org.apache.ibatis.annotations.Param;
 import org.springframework.stereotype.Repository;
 import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
@@ -43,9 +45,9 @@ public interface TenantInfoMapper extends BaseMapper<TenantInfo> {
 
 	Boolean insertInfo(@Param("param") TenantInfo tenantInfo);
 
-	List<Integer> queryTeacherCounts(@Param("listId") List<Integer> listId);
+	TeacherCounts queryTeacherCounts(@Param("id") Long id);
 
-	List<Integer> queryStudentCounts(@Param("listId") List<Integer> listId);
+	StudentCounts queryStudentCounts(@Param("id") Long id);
 
 	List<TenantInfoWrapper.TenantInfo> selectApplyPage(@Param("page") IPage<TenantInfoWrapper.TenantInfo> page, @Param("param") TenantInfoWrapper.TenantInfoQuery query);
 
@@ -53,9 +55,14 @@ public interface TenantInfoMapper extends BaseMapper<TenantInfo> {
 
 	TenantInfoWrapper.TenantInfo queryNow(@Param("param") TenantInfoWrapper.TenantInfoQuery query);
 
-	Boolean insertNow(@Param("info") TenantInfoWrapper.TenantInfo info);
 
 	Boolean updateStatusById(@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);
 }

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

@@ -26,4 +26,5 @@ public interface TenantStaffMapper extends BaseMapper<TenantStaff> {
 
     TenantStaff getByPhone(@Param("phone") String phone);
 
+    TenantStaff selectByUserId(@Param("id") Long id);
 }

+ 5 - 5
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/queryInfo/SysMusicCompareRecordQueryInfo.java

@@ -40,10 +40,10 @@ public class SysMusicCompareRecordQueryInfo {
 
     @Data
     public static class WechatCompareRecordQueryInfo extends QueryInfo{
-        @ApiModelProperty(name = "训练开始时间")
+        @ApiModelProperty(name = "训练开始时间(年月日 时分秒)")
         private String startTime;
 
-        @ApiModelProperty(name = "训练结束时间")
+        @ApiModelProperty(name = "训练结束时间(年月日 时分秒)")
         private String endTime;
 
         @ApiModelProperty(name = "机构编号")
@@ -142,13 +142,13 @@ public class SysMusicCompareRecordQueryInfo {
         private String subjectName;
 
         @ApiModelProperty(name = "训练总时长")
-        private Integer trainTimes;
+        private Integer trainTimes = 0;
 
         @ApiModelProperty(name = "训练天数")
-        private Integer trainDays;
+        private Integer trainDays = 0;
 
         @ApiModelProperty(name = "平均训练时长")
-        private Integer avgTrainTimes;
+        private Integer avgTrainTimes = 0;
 
     }
 

+ 4 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/PaymentDivMemberRecordService.java

@@ -51,7 +51,10 @@ public interface PaymentDivMemberRecordService extends IService<PaymentDivMember
                                                                          PaymentDivMemberRecordWrapper.IndexIncomeQuery query);
 
     //小程序首页订单详情
-    PaymentDivMemberRecordWrapper.OrderDetailDto getOrderDetail(String orderNo,Long tenantId);
+    PaymentDivMemberRecordWrapper.OrderDetailDto getIncomeOrderDetail(String orderNo,Long tenantId);
+
+    //首页收入汇总
+    PaymentDivMemberRecordWrapper.IndexIncomeSummaryDto incomeSummary(PaymentDivMemberRecordWrapper.IndexIncomeQuery query);
 
     /**
      * 专辑分账

+ 7 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/StudentService.java

@@ -122,4 +122,11 @@ public interface StudentService extends IService<Student> {
      */
     void importStudentExcel(List<ExcelDataReaderProperty<StudentWrapper.StudentExport>> dataList,Long tenantId,
                             Long suerId);
+
+    /**
+     * 学生修改机构
+     * @param student 学生信息
+     * @param toTenantId 机构ID
+     */
+    void updateTenant(Student student, Long toTenantId);
 }

+ 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.wrapper.TenantActivationCodeWrapper;
 import com.yonge.cooleshow.biz.dal.entity.TenantActivationCode;
+import com.yonge.toolset.utils.easyexcel.ExcelDataReaderProperty;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
@@ -13,49 +14,64 @@ import java.util.List;
  * 机构激活码
  * 2023-07-21 17:32:49
  */
-public interface TenantActivationCodeService extends IService<TenantActivationCode>  {
+public interface TenantActivationCodeService extends IService<TenantActivationCode> {
 
-	/**
+    /**
      * 查询详情
+     *
      * @param id 详情ID
      * @return TenantActivationCode
      */
-	TenantActivationCode detail(Long id);
+    TenantActivationCode detail(Long id);
 
     /**
      * 分页查询
-     * @param page IPage<TenantActivationCode>
+     *
+     * @param page  IPage<TenantActivationCode>
      * @param query TenantActivationCodeWrapper.TenantActivationCodeQuery
      * @return IPage<TenantActivationCode>
      */
     IPage<TenantActivationCodeWrapper.TenantActivationCode> selectPage(IPage<TenantActivationCodeWrapper.TenantActivationCode> page,
                                                                        TenantActivationCodeWrapper.TenantActivationCodeQuery query);
-	
+
     /**
      * 添加
+     *
      * @param tenantActivationCode TenantActivationCodeWrapper.TenantActivationCode
      * @return Boolean
      */
-     Boolean add(TenantActivationCodeWrapper.TenantActivationCode tenantActivationCode);   
+    Boolean add(TenantActivationCodeWrapper.TenantActivationCode tenantActivationCode);
 
     /**
      * 更新
+     *
      * @param tenantActivationCode TenantActivationCodeWrapper.TenantActivationCode
      * @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);
 
 
-
     /**
      * 添加用户机构专辑激活记录
      *
-     * @param studentId 学生ID
+     * @param studentId         学生ID
      * @param 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
      * @return Boolean
      */
-     Boolean add(TenantAlbumRefWrapper.TenantAlbumRef tenantAlbumRef);   
+     Boolean add(TenantAlbumRef tenantAlbumRef);
 
     /**
      * 更新
@@ -49,4 +49,6 @@ public interface TenantAlbumRefService extends IService<TenantAlbumRef>  {
      * @return
      */
     List<TenantAlbumRef> getByAlbumId(Long tenantAlbumId);
+
+    TenantAlbumRef getBytenantAlbumId(Long id);
 }

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

@@ -7,6 +7,8 @@ import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.entity.TenantAlbum;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 
+import java.util.List;
+
 /**
  * 机构专辑
  * 2023-07-21 17:32:49
@@ -26,14 +28,14 @@ public interface TenantAlbumService extends IService<TenantAlbum>  {
      * @param query TenantAlbumWrapper.TenantAlbumQuery
      * @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
      * @return Boolean
      */
-     Boolean add(TenantAlbumWrapper.TenantAlbum tenantAlbum);   
+     Boolean add(TenantAlbum tenantAlbum);
 
     /**
      * 更新
@@ -55,4 +57,25 @@ public interface TenantAlbumService extends IService<TenantAlbum>  {
      * @param userOrderDetailVo
      */
     void orderSuccess(UserOrderDetailVo userOrderDetailVo);
+
+    void insertTenantAlbum(Long tenantId,TenantAlbum tenantAlbum,
+                           List<TenantAlbumWrapper.MusicSheetData> musicSheetDataList);
+
+    void updateAlbum(Long id, TenantAlbum tenantAlbum, List<TenantAlbumWrapper.MusicSheetData> musicSheetDataList);
+
+
+    /**
+     * 添加机构专辑数据
+     * @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);
 }

+ 6 - 5
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantInfoService.java

@@ -24,11 +24,10 @@ public interface TenantInfoService extends IService<TenantInfo>  {
 
     /**
      * 分页查询
-     * @param page IPage<TenantInfo>
      * @param query TenantInfoWrapper.TenantInfoQuery
      * @return IPage<TenantInfo>
      */
-    IPage<TenantInfoWrapper.TenantInfo> selectPage(IPage<TenantInfoWrapper.TenantInfo> page, TenantInfoWrapper.TenantInfoQuery query);
+    IPage<TenantInfoWrapper.TenantInfo> selectPage(TenantInfoWrapper.TenantInfoQuery query);
 	
     /**
      * 添加
@@ -42,7 +41,7 @@ public interface TenantInfoService extends IService<TenantInfo>  {
      * @param info TenantInfoWrapper.TenantInfo
      * @return Boolean
      */
-    Boolean updateTenantInfo(TenantInfo info);
+    Boolean update(TenantInfo info);
 
     /**
      * 机构信息
@@ -55,10 +54,10 @@ public interface TenantInfoService extends IService<TenantInfo>  {
 
     /**
      * 冻结
-     * @param query
+     * @param updateStatus
      * @return
      */
-    Boolean state(TenantInfoWrapper.TenantInfoQuery query);
+    Boolean updateStatus(TenantInfoWrapper.UpdateStatus updateStatus);
 
 
 
@@ -89,4 +88,6 @@ public interface TenantInfoService extends IService<TenantInfo>  {
      * @return
      */
     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);
 
+    /**
+     * 审核
+     * @param audio
+     * @return
+     */
+    Boolean entry(TenantUnbindRecordWrapper.Audio audio);
 }

+ 8 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserOrderService.java

@@ -11,6 +11,7 @@ import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderVo;
 import com.yonge.cooleshow.biz.dal.dto.search.OrderSearch;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderPayRes;
+import com.yonge.cooleshow.biz.dal.wrapper.PaymentDivMemberRecordWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.payment.base.model.callback.PaymentCallBack;
@@ -215,4 +216,11 @@ public interface UserOrderService extends IService<UserOrder> {
      * @param orderNo 订单号
      */
     UserOrder getByOrderNo(String orderNo);
+
+    //首页支出明细列表
+    IPage<PaymentDivMemberRecordWrapper.IndexIncomeQueryDto> queryExpend(IPage<PaymentDivMemberRecordWrapper.IndexIncomeQueryDto> page,
+                                                                         PaymentDivMemberRecordWrapper.IndexIncomeQuery query);
+
+    //首页支出订单详情
+    PaymentDivMemberRecordWrapper.OrderDetailDto getExpendOrderDetail(String orderNo);
 }

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

@@ -36,6 +36,8 @@ import com.yonge.toolset.base.exception.BizException;
 import org.apache.commons.collections.CollectionUtils;
 import org.joda.time.DateTime;
 import org.springframework.beans.factory.annotation.Autowired;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantPersonStatWrapper;
+import org.apache.commons.collections.CollectionUtils;
 import org.springframework.stereotype.Service;
 import lombok.extern.slf4j.Slf4j;
 import com.yonge.cooleshow.biz.dal.mapper.PaymentDivMemberRecordMapper;
@@ -43,6 +45,8 @@ import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
+import java.util.List;
+import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
@@ -184,8 +188,26 @@ public class PaymentDivMemberRecordServiceImpl extends ServiceImpl<PaymentDivMem
     }
 
     @Override
-    public PaymentDivMemberRecordWrapper.OrderDetailDto getOrderDetail(String orderNo,Long tenantId) {
-        return baseMapper.getOrderDetail(orderNo,tenantId);
+    public PaymentDivMemberRecordWrapper.OrderDetailDto getIncomeOrderDetail(String orderNo,Long tenantId) {
+        return baseMapper.getIncomeOrderDetail(orderNo,tenantId);
+    }
+
+    @Override
+    public PaymentDivMemberRecordWrapper.IndexIncomeSummaryDto incomeSummary(PaymentDivMemberRecordWrapper.IndexIncomeQuery query) {
+        List<PaymentDivMemberRecordWrapper.IndexIncomeSummaryDetailDto> incomeSummary = baseMapper.incomeSummary(query);
+        PaymentDivMemberRecordWrapper.IndexIncomeSummaryDto result = new PaymentDivMemberRecordWrapper.IndexIncomeSummaryDto();
+        if(CollectionUtils.isNotEmpty(incomeSummary)){
+            BigDecimal reduce = incomeSummary.stream().map(e -> e.getAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);
+            result.setIncomeDtos(incomeSummary);
+            result.setTotalIncome(reduce);
+        }
+        List<PaymentDivMemberRecordWrapper.IndexIncomeSummaryDetailDto> expendSummary = baseMapper.expendSummary(query);
+        if(CollectionUtils.isNotEmpty(expendSummary)){
+            BigDecimal reduce = expendSummary.stream().map(e -> e.getAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);
+            result.setExpendDtos(expendSummary);
+            result.setTotalExpend(reduce);
+        }
+        return result;
     }
 
     /**

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

@@ -15,6 +15,7 @@ import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
 import com.yonge.cooleshow.biz.dal.dao.UserBindingTeacherDao;
 import com.yonge.cooleshow.biz.dal.dto.search.QueryMyFollowSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.StudentSearch;
+import com.yonge.cooleshow.biz.dal.entity.ImGroupMember;
 import com.yonge.cooleshow.biz.dal.entity.Student;
 import com.yonge.cooleshow.biz.dal.entity.StudentTotal;
 import com.yonge.cooleshow.biz.dal.entity.Subject;
@@ -23,6 +24,8 @@ import com.yonge.cooleshow.biz.dal.entity.UserBindingTeacher;
 import com.yonge.cooleshow.biz.dal.entity.UserTenantAlbumRecord;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
+import com.yonge.cooleshow.biz.dal.service.ImGroupMemberService;
+import com.yonge.cooleshow.biz.dal.service.ImGroupService;
 import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
 import com.yonge.cooleshow.biz.dal.service.StudentService;
 import com.yonge.cooleshow.biz.dal.service.StudentTotalService;
@@ -44,6 +47,7 @@ import com.yonge.toolset.mybatis.support.PageUtil;
 import com.yonge.toolset.utils.date.DateUtil;
 import com.yonge.toolset.utils.easyexcel.ExcelDataReaderProperty;
 import com.yonge.toolset.utils.string.ValueUtil;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.redisson.api.RMap;
 import org.redisson.api.RedissonClient;
@@ -63,6 +67,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 
+@Slf4j
 @Service
 public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> implements StudentService {
     @Autowired
@@ -86,6 +91,12 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
     @Autowired
     private SysConfigService sysConfigService;
 
+    @Autowired
+    private ImGroupService imGroupService;
+
+    @Autowired
+    private ImGroupMemberService imGroupMemberService;
+
     @Override
     public StudentDao getDao() {
         return baseMapper;
@@ -445,17 +456,41 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
         }
     }
 
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void updateTenant(Student student, Long toTenantId) {
+        if (student.getTenantId().equals(toTenantId)) {
+            return;
+        }
+        List<ImGroupMember> groupMembers = imGroupMemberService.lambdaQuery()
+                .eq(ImGroupMember::getUserId, student.getUserId())
+                .eq(ImGroupMember::getRoleType, ClientEnum.STUDENT.getCode())
+                .eq(ImGroupMember::getIsAdmin, false).list();
+        List<String> groupIdList = groupMembers.stream().map(ImGroupMember::getGroupId).distinct()
+                .collect(Collectors.toList());
+        for (String groupId : groupIdList) {
+            try {
+                imGroupService.quit(groupId, student.getUserId(), ClientEnum.STUDENT);
+            } catch (Exception e) {
+                log.error("退出群聊失败:{}", e);
+            }
+        }
+        this.lambdaUpdate().set(Student::getTenantId, toTenantId)
+                .eq(Student::getUserId, student.getUserId())
+                .update();
+    }
+
     private Boolean updateStudent(StudentWrapper.Student studentInfo) {
         StudentVo student = detail(studentInfo.getId());
         if (student == null) {
             throw new BizException("学生信息不存在");
         }
         // 解绑
-        if (Boolean.FALSE.equals(studentInfo.getBindTenant())) {
-            studentInfo.setTenantId(-1L);
-            // 退群,删除好友
-            imUserFriendService.delFriendByTenantId(student.getTenantId(), student.getUserId());
-        }
+//        if (Boolean.FALSE.equals(studentInfo.getBindTenant())) {
+//            studentInfo.setTenantId(-1L);
+//            // 退群,删除好友
+//            imUserFriendService.delFriendByTenantId(student.getTenantId(), student.getUserId());
+//        }
         // 手机号码修改
         com.yonge.cooleshow.biz.dal.entity.SysUser sysUser = getOrCreateAccount(studentInfo);
         if (!student.getPhone().equals(studentInfo.getPhone())) {

+ 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.metadata.IPage;
 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.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.SourceTypeEnum;
 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.common.enums.EActivationCode;
 import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.utils.easyexcel.ExcelDataReaderProperty;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Comparator;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -193,7 +202,7 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
         Integer purchaseCycle = purchase.getPurchaseCycle();
 
 
-        addUserTenantAlbumRecord(student.getUserId(), purchase,null);
+        addUserTenantAlbumRecord(student.getUserId(), purchase, null);
 
         // 更新购买记录中激活码使用统计数量值
         Integer activeCodeNumber = this.lambdaQuery()
@@ -211,7 +220,7 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
     /**
      * 添加用户机构专辑激活记录
      *
-     * @param studentId 学生ID
+     * @param studentId         学生ID
      * @param userOrderDetailVo 订单详情
      */
     @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();
@@ -253,7 +339,6 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
         }
 
 
-
         QueryWrapper<UserTenantAlbumRecord> queryWrapper = new QueryWrapper<>();
         queryWrapper.lambda()
                 .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
      */
     @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)
                 .list();
     }
+
+    @Override
+    public TenantAlbumRef getBytenantAlbumId(Long id) {
+        return baseMapper.selectByAlbumId(id);
+    }
 }

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

@@ -1,12 +1,11 @@
 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.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 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.enums.OrderStatusEnum;
 import com.yonge.cooleshow.biz.dal.service.*;
@@ -14,7 +13,6 @@ import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 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.util.StringUtil;
 import org.apache.commons.collections.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -23,10 +21,15 @@ import lombok.extern.slf4j.Slf4j;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMapper;
 import org.springframework.transaction.annotation.Transactional;
+import springfox.documentation.spring.web.json.Json;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collection;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
 /**
@@ -53,54 +56,65 @@ public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, Tenan
     private UserOrderService userOrderService;
 
     @Autowired
-    private TenantActivationCodeService tenantActivationCodeService;
+    private SysUserFeignService sysUserFeignService;
 
     @Autowired
     private TenantAlbumPurchaseService tenantAlbumPurchaseService;
 
+    @Autowired
+    private TenantAlbumMusicService tenantAlbumMusicService;
+
+    @Autowired
+    private TenantActivationCodeService tenantActivationCodeService;
+
     /**
      * 查询详情
+     *
      * @param id 详情ID
      * @return TenantAlbum
      */
     @Override
     public TenantAlbum detail(Long id) {
-        
+
         return baseMapper.selectById(id);
     }
-    
+
     /**
      * 分页查询
-     * @param page IPage<TenantAlbum>
+     *
+     * @param page  IPage<TenantAlbum>
      * @param query TenantAlbumWrapper.TenantAlbumQuery
      * @return IPage<TenantAlbum>
      */
     @Override
-    public IPage<TenantAlbum> selectPage(IPage<TenantAlbum> page, TenantAlbumWrapper.TenantAlbumQuery query) {
-        
+    public IPage<TenantAlbumWrapper.TenantAlbum> selectPage(IPage<TenantAlbumWrapper.TenantAlbum> page,
+                                                            TenantAlbumWrapper.TenantAlbumQuery query) {
         return page.setRecords(baseMapper.selectPage(page, query));
     }
 
     /**
      * 添加
+     *
      * @param tenantAlbum TenantAlbumWrapper.TenantAlbum
      * @return Boolean
      */
     @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);
     }
 
     /**
      * 更新
+     *
      * @param tenantAlbum TenantAlbumWrapper.TenantAlbum
      * @return Boolean
      */
     @Override
-    public Boolean update(TenantAlbumWrapper.TenantAlbum tenantAlbum){
+    public Boolean update(TenantAlbumWrapper.TenantAlbum tenantAlbum) {
 
-        return this.updateById(JSON.parseObject(tenantAlbum.jsonString(), TenantAlbum.class));       
+        return this.updateById(JSON.parseObject(tenantAlbum.jsonString(), TenantAlbum.class));
     }
 
     /**
@@ -259,4 +273,70 @@ public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, Tenan
         }
 
     }
+
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void insertTenantAlbum(Long tenantId, TenantAlbum tenantAlbum,
+                                  List<TenantAlbumWrapper.MusicSheetData> musicSheetDataList) {
+
+        List<String> subjectTypeNames = musicSheetDataList.stream().map(next -> next.getSubjectType().name())
+                .distinct().collect(Collectors.toList());
+        tenantAlbum.setSubjectTypes(String.join(",", subjectTypeNames));
+        //给机构专辑赋值
+        tenantAlbum.setStatus(true);
+        tenantAlbum.setDelFlag(false);
+        this.add(tenantAlbum);
+
+        //关联表赋值
+        TenantAlbumRef ref = new TenantAlbumRef();
+        ref.setTenantAlbumId(tenantAlbum.getId());
+        ref.setTenantId(tenantId);
+        tenantAlbumRefService.add(ref);
+
+        //曲目表赋值
+        insertAlbumMusic(tenantId, tenantAlbum, musicSheetDataList);
+    }
+
+    @Override
+    public void updateAlbum(Long tenantId, TenantAlbum tenantAlbum,
+                            List<TenantAlbumWrapper.MusicSheetData> musicSheetDataList) {
+
+        List<String> subjectTypeNames = musicSheetDataList.stream().map(next -> next.getSubjectType().name())
+                .distinct().collect(Collectors.toList());
+        tenantAlbum.setSubjectTypes(String.join(",", subjectTypeNames));
+        this.updateById(tenantAlbum);
+
+        tenantAlbumMusicService.lambdaUpdate()
+                .set(TenantAlbumMusic::getDelFlag, true)
+                .eq(TenantAlbumMusic::getTenantAlbumId, tenantAlbum)
+                .eq(TenantAlbumMusic::getTenantId, tenantId)
+                .update();
+
+        insertAlbumMusic(tenantId, tenantAlbum, musicSheetDataList);
+
+    }
+
+    private void insertAlbumMusic(Long tenantId, TenantAlbum tenantAlbum,
+                                  List<TenantAlbumWrapper.MusicSheetData> musicSheetDataList) {
+        //曲目表赋值
+        List<TenantAlbumMusic> tenantAlbumMusics = musicSheetDataList.stream().map(next -> {
+            AtomicInteger sort = new AtomicInteger(1);
+            return next.getMusicSheetIdList().stream().map(tenantAlbumMusic -> {
+                TenantAlbumMusic tenantAlbumMusic1 = new TenantAlbumMusic();
+                tenantAlbumMusic1.setTenantId(tenantId);
+                tenantAlbumMusic1.setSubjectType(next.getSubjectType());
+                tenantAlbumMusic1.setTenantAlbumId(tenantAlbum.getId());
+                tenantAlbumMusic1.setMusicSheetId(tenantAlbumMusic);
+                tenantAlbumMusic1.setSortNumber(sort.getAndIncrement());
+                tenantAlbumMusic1.setDelFlag(false);
+                return tenantAlbumMusic1;
+            }).collect(Collectors.toList());
+        }).flatMap(Collection::stream).collect(Collectors.toList());
+
+        if (!tenantAlbumMusics.isEmpty()) {
+            tenantAlbumMusicService.saveBatch(tenantAlbumMusics, 100);
+        }
+    }
+
 }

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

@@ -4,9 +4,12 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.biz.dal.dao.StudentDao;
+import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
 import com.yonge.cooleshow.biz.dal.entity.SysArea;
 import com.yonge.cooleshow.biz.dal.entity.SysUser;
-import com.yonge.cooleshow.biz.dal.entity.TenantEntryRecord;
+import com.yonge.cooleshow.biz.dal.entity.Teacher;
 import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
 import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
 import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
@@ -70,6 +73,11 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
     @Autowired
     TenantApplyRecordMapper tenantApplyRecordMapper;
 
+    @Autowired
+    private TeacherDao teacherDao;
+
+    @Autowired
+    private StudentDao studentDao;
 
 
     /**
@@ -83,50 +91,45 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
         if (id == null || id == -1) {
             return null;
         }
-
-        return baseMapper.selectById(id);
+        TenantInfo info = baseMapper.selectById(id);
+        return info;
     }
 
     /**
      * 分页查询
      *
-     * @param page  IPage<TenantInfo>
      * @param query TenantInfoWrapper.TenantInfoQuery
      * @return IPage<TenantInfo>
      */
     @Override
-    public IPage<TenantInfoWrapper.TenantInfo> selectPage(IPage<TenantInfoWrapper.TenantInfo> page,
-                                                          TenantInfoWrapper.TenantInfoQuery query) {
+    public IPage<TenantInfoWrapper.TenantInfo> selectPage(TenantInfoWrapper.TenantInfoQuery query) {
 
         //分页查询
+        IPage<TenantInfoWrapper.TenantInfo> page = QueryInfo.getPage(query);
         List<TenantInfoWrapper.TenantInfo> tenantInfos = baseMapper.selectPage(page, query);
-        //获取id
-        ArrayList<Integer> listId = new ArrayList<>();
-        for (int i = 0; i < tenantInfos.size(); i++) {
-            TenantInfoWrapper.TenantInfo info = tenantInfos.get(i);
-            long id = info.getId();
-            listId.add(i, (int) id);
-        }
-        //查询对应机构的老师数量
-        List<Integer> listTeacher = new ArrayList<>();
-        //查询对应机构的学生数量
-        List<Integer> listStudent = new ArrayList<>();
-        if (!CollectionUtils.isEmpty(listId)) {
-            listTeacher = tenantInfoMapper.queryTeacherCounts(listId);
-            listStudent = tenantInfoMapper.queryStudentCounts(listId);
+        if (tenantInfos.isEmpty()) {
+            return page.setRecords(new ArrayList<>());
         }
 
+        List<Long> tenantIdList =
+                tenantInfos.stream().map(TenantInfoWrapper.TenantInfo::getId).collect(Collectors.toList());
 
-        for (int j = 0; j < tenantInfos.size(); j++) {
-            TenantInfoWrapper.TenantInfo tenantInfo = tenantInfos.get(j);
-            for (int z = 0; z < listTeacher.size(); z++) {
-                tenantInfo.setTeacherCounts(listTeacher.get(z).toString());
-            }
-            for (int t = 0; t < listStudent.size(); t++) {
-                tenantInfo.setStudentCounts(listStudent.get(t).toString());
-            }
-        }
+        List<TenantInfoWrapper.UserCount> teacherByTenantIds = teacherDao.countTeacherByTenantIds(tenantIdList);
+        List<TenantInfoWrapper.UserCount> studentByTenantIds = studentDao.countTeacherByTenantIds(tenantIdList);
 
+        Map<Long, Integer> teacherIdCountMap = teacherByTenantIds.stream()
+                .collect(Collectors.toMap(TenantInfoWrapper.UserCount::getTenantId,
+                        TenantInfoWrapper.UserCount::getCount));
+
+        Map<Long, Integer> studentIdCountMap = studentByTenantIds.stream()
+                .collect(Collectors.toMap(TenantInfoWrapper.UserCount::getTenantId,
+                        TenantInfoWrapper.UserCount::getCount));
+
+
+        for (TenantInfoWrapper.TenantInfo info : tenantInfos) {
+            info.setTeacherCounts(teacherIdCountMap.getOrDefault(info.getId(), 0));
+            info.setTeacherCounts(studentIdCountMap.getOrDefault(info.getId(), 0));
+        }
 
         //获取省市区信息
         List<TenantInfoWrapper.TenantInfo> tenantList = queryArea(tenantInfos);
@@ -140,24 +143,31 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
      * @param tenantInfo TenantInfoWrapper.TenantInfo
      * @return Boolean
      */
+    @Transactional(rollbackFor = Exception.class)
     @Override
     public Boolean add(TenantInfo tenantInfo) {
-        SysUser sysUser = getOrCreateAccount(tenantInfo);
+        SysUser sysUser = getOrCreateAccount(tenantInfo, null);
+        tenantInfo.setEnableFlag(true);
+        if (StringUtils.isEmpty(tenantInfo.getLogo())) {
+            // todo 设置默认logo
+            tenantInfo.setLogo("");
+        }
+        tenantInfo.setEnableFlag(true);
+        tenantInfo.setUserId(sysUser.getId());
+        tenantInfoMapper.insert(tenantInfo);
 
         TenantStaff tenantStaff = new TenantStaff();
-        tenantStaff.setTenantId(tenantStaff.getTenantId());
+        tenantStaff.setTenantId(tenantInfo.getId());
         tenantStaff.setUserId(sysUser.getId());
         tenantStaff.setAvatar(sysUser.getAvatar());
         tenantStaff.setNickname(tenantInfo.getUsername());
         tenantStaff.setStatus(UserLockFlag.NORMAL);
+        tenantStaff.setManageAdmin(true);
         tenantStaffMapper.insert(tenantStaff);
-
-        tenantInfo.setEnableFlag(true);
-        tenantInfoMapper.insert(tenantInfo);
         return true;
     }
 
-    private SysUser getOrCreateAccount(TenantInfo tenantInfo) {
+    private SysUser getOrCreateAccount(TenantInfo tenantInfo, TenantInfo oldTenantInfo) {
         QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
         sysUserQueryWrapper.lambda().eq(SysUser::getPhone, tenantInfo.getPhone());
         List<SysUser> sysUsers = sysUserMapper.selectList(sysUserQueryWrapper);
@@ -165,8 +175,9 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
         //若存在信息
         if (!sysUsers.isEmpty()) {
             sysUser = sysUsers.get(0);
-            TenantStaff tenantStaff = tenantStaffMapper.selectById(sysUser.getId());
-            if (tenantStaff != null) {
+            TenantStaff tenantStaff = tenantStaffMapper.selectByUserId(sysUser.getId());
+            if (tenantStaff != null && oldTenantInfo != null &&
+                    !tenantStaff.getUserId().equals(oldTenantInfo.getUserId())) {
                 throw new BizException("手机号已经注册机构账号");
             }
             //获取当前账户的用户类型
@@ -188,7 +199,7 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
             sysUser.setPhone(tenantInfo.getPhone());
             sysUser.setAvatar(sysConfigService.findConfigValue(SysConfigConstant.DEFAULT_HEARD));
             sysUser.setUserType(SysUserType.ORGANIZATION.getCode());
-
+            sysUser.setUsername(tenantInfo.getUsername());
             String newPassword = MessageFormat.format("klxjg{0}", tenantInfo.getPhone().substring(7));
             String password = new BCryptPasswordEncoder().encode(newPassword);
             sysUser.setPassword(password);
@@ -236,39 +247,35 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
     }
 
     /**
-     * 冻结
+     * 修改状态
      *
-     * @param query TenantInfoWrapper.TenantInfo
-     * @return Boolean
+     * @param updateStatus updateStatus
+     * @return true
      */
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public Boolean state(TenantInfoWrapper.TenantInfoQuery query) {
-        Boolean flag;
-        long id = query.getId();
-        TenantInfo info = detail(id);
+    public Boolean updateStatus(TenantInfoWrapper.UpdateStatus updateStatus) {
 
-        //TenantInfo info = this.getById(id);
-        if (Objects.isNull(info)) {
+        boolean update = this.lambdaUpdate()
+                .set(TenantInfo::getEnableFlag, updateStatus.getEnableFlag())
+                .eq(TenantInfo::getId, updateStatus.getId())
+                .update();
+        if (!update) {
             throw new BizException("机构信息不存在");
         }
-        //获取是否冻结
-        if (query.getIfFreeze() == 1) {
-            if (!info.getEnableFlag()) {
-                return false;
-            }
-            //修改机构账号冻结状态
-            flag = tenantInfoMapper.updateFlag(id);
-            //是否更改结算方式
-            if (query.getIfMethod() == 1) {
-                tenantInfoMapper.updateMethod(id);
-            } else {
-                return true;
-            }
-        } else {
-            return false;
+
+        if (!updateStatus.getEnableFlag()) {
+            tenantStaffMapper.update(null, Wrappers.<TenantStaff>lambdaUpdate()
+                    .set(TenantStaff::getStatus, UserLockFlag.LOCKED)
+                    .eq(TenantStaff::getTenantId, updateStatus.getId()));
+        }
+
+        if (updateStatus.getSettlement() != null) {
+            teacherDao.update(null, Wrappers.<Teacher>lambdaUpdate()
+                    .set(Teacher::getSettlementFrom, updateStatus.getSettlement())
+                    .eq(Teacher::getTenantId, updateStatus.getId()));
         }
-        return flag;
+        return true;
     }
 
 
@@ -279,17 +286,22 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
      * @return Boolean
      */
     @Override
-    public Boolean updateTenantInfo(TenantInfo info) {
+    public Boolean update(TenantInfo info) {
+        // todo  机构冻结状态是否允许修改
         //更新或创建sysUser
-        SysUser sysUser = getOrCreateAccount(info);
-
         TenantInfo oldTenantInfo = this.getById(info.getId());
+        SysUser sysUser = getOrCreateAccount(info, oldTenantInfo);
+
         tenantStaffMapper.update(null, Wrappers.<TenantStaff>lambdaUpdate()
                 .set(TenantStaff::getUserId, sysUser.getId())
                 .set(TenantStaff::getNickname, info.getUsername())
                 .eq(TenantStaff::getUserId, oldTenantInfo.getUserId())
         );
 
+        if (StringUtils.isEmpty(info.getLogo())) {
+            // todo 设置默认logo
+            info.setLogo("");
+        }
         tenantInfoMapper.update(null, Wrappers.<TenantInfo>lambdaUpdate()
                 .set(TenantInfo::getName, info.getName())
                 .set(TenantInfo::getLogo, info.getLogo())
@@ -297,6 +309,9 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
                 .set(TenantInfo::getProvinceCode, info.getProvinceCode())
                 .set(TenantInfo::getCityCode, info.getCityCode())
                 .set(TenantInfo::getRegionCode, info.getRegionCode())
+                .set(TenantInfo::getPhone, info.getPhone())
+                .set(TenantInfo::getUsername, info.getUsername())
+                .set(TenantInfo::getUserId, sysUser.getId())
                 .eq(TenantInfo::getId, info.getId())
         );
         return true;
@@ -328,13 +343,14 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
     @Override
     public IPage<TenantInfoWrapper.TenantInfo> historyPage(IPage<TenantInfoWrapper.TenantInfo> page,
                                                            TenantInfoWrapper.TenantInfoQuery query) {
-        long id = query.getId();
-        //分页查询
-        List<TenantInfoWrapper.TenantInfo> tenantInfos = baseMapper.selectHistoryPage(page, id);
-        //查询对应省市区
-        List<TenantInfoWrapper.TenantInfo> infos = queryArea(tenantInfos);
-
-        return page.setRecords(infos);
+//        long id = query.getId();
+//        //分页查询
+//        List<TenantInfoWrapper.TenantInfo> tenantInfos = baseMapper.selectHistoryPage(page, id);
+//        //查询对应省市区
+//        List<TenantInfoWrapper.TenantInfo> infos = queryArea(tenantInfos);
+//
+//        return page.setRecords(infos);
+        return null;
     }
 
     /**
@@ -372,68 +388,81 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
 
     @Override
     public Boolean entry(TenantInfoWrapper.TenantInfoQuery query) {
-        Integer pass = query.getIfPass();
-        //审核通过
-        if (pass == 1) {
-            //查询本次提交记录,并插入审核表
-            TenantInfoWrapper.TenantInfo info = queryNow(query);
-            TenantEntryRecord entryRecord = new TenantEntryRecord();
-            entryRecord.setId(info.getId());
-            entryRecord.setName(info.getName());
-            entryRecord.setLogo(info.getLogo());
-            entryRecord.setProvinceCode(info.getProvinceCode());
-            entryRecord.setCityCode(info.getCityCode());
-            entryRecord.setRegionCode(info.getRegionCode());
-            entryRecord.setUsername(info.getUserName());
-            entryRecord.setPhone(info.getPhone());
-            entryRecord.setStatus("PASS");
-            entryRecord.setVerifyUserId(info.getVerifyUserId());
-            entryRecord.setReason(info.getReason());
-            entryRecord.setCreateTime(info.getCreateTime());
-            tenantEntryRecordMapper.insert(entryRecord);
-            //更改当前记录的审核状态
-            long id = info.getId();
-            tenantInfoMapper.updateStatusById(id);
-
-            //机构账户新增逻辑
-            TenantInfo tenantInfo = new TenantInfo();
-            tenantInfo.setId(info.getId());
-            tenantInfo.setLogo(info.getLogo());
-            tenantInfo.setName(info.getName());
-            tenantInfo.setProvinceCode(info.getProvinceCode());
-            tenantInfo.setCityCode(info.getCityCode());
-            tenantInfo.setRegionCode(info.getRegionCode());
-            tenantInfo.setUsername(info.getUserName());
-            tenantInfo.setPhone(info.getPhone());
-            tenantInfo.setEnableFlag(true);
-            tenantInfo.setBriefIntroduction(info.getBriefIntroduction());
-            tenantInfo.setUpdateTime(info.getUpdateTime());
-            tenantInfo.setCreateTime(info.getCreateTime());
-            add(tenantInfo);
-
+//        Integer pass = query.getIfPass();
+//        //审核通过
+//        if (pass == 1) {
+//            //查询本次提交记录,并插入审核表
+//            TenantInfoWrapper.TenantInfo info = queryNow(query);
+//            TenantEntryRecord entryRecord = new TenantEntryRecord();
+//            entryRecord.setId(info.getId());
+//            entryRecord.setName(info.getName());
+//            entryRecord.setLogo(info.getLogo());
+//            entryRecord.setProvinceCode(info.getProvinceCode());
+//            entryRecord.setCityCode(info.getCityCode());
+//            entryRecord.setRegionCode(info.getRegionCode());
+//            entryRecord.setUsername(info.getUserName());
+//            entryRecord.setPhone(info.getPhone());
+//            entryRecord.setStatus("PASS");
+//            entryRecord.setVerifyUserId(info.getVerifyUserId());
+//            entryRecord.setReason(info.getReason());
+//            entryRecord.setCreateTime(info.getCreateTime());
+//            tenantEntryRecordMapper.insert(entryRecord);
+//            //更改当前记录的审核状态
+//            long id = info.getId();
+//            tenantInfoMapper.updateStatusById(id);
+//
+//            //机构账户新增逻辑
+//            TenantInfo tenantInfo = new TenantInfo();
+//            tenantInfo.setId(info.getId());
+//            tenantInfo.setLogo(info.getLogo());
+//            tenantInfo.setName(info.getName());
+//            tenantInfo.setProvinceCode(info.getProvinceCode());
+//            tenantInfo.setCityCode(info.getCityCode());
+//            tenantInfo.setRegionCode(info.getRegionCode());
+//            tenantInfo.setUsername(info.getUserName());
+//            tenantInfo.setPhone(info.getPhone());
+//            tenantInfo.setEnableFlag(true);
+//            tenantInfo.setBriefIntroduction(info.getBriefIntroduction());
+//            tenantInfo.setUpdateTime(info.getUpdateTime());
+//            tenantInfo.setCreateTime(info.getCreateTime());
+//            add(tenantInfo);
+//
+//
+//        } else {
+//            //查询本次提交记录,并插入审核表
+//            TenantInfoWrapper.TenantInfo info = queryNow(query);
+//            TenantEntryRecord entryRecord = new TenantEntryRecord();
+//            entryRecord.setId(info.getId());
+//            entryRecord.setName(info.getName());
+//            entryRecord.setLogo(info.getLogo());
+//            entryRecord.setProvinceCode(info.getProvinceCode());
+//            entryRecord.setCityCode(info.getCityCode());
+//            entryRecord.setRegionCode(info.getRegionCode());
+//            entryRecord.setUsername(info.getUserName());
+//            entryRecord.setPhone(info.getPhone());
+//            entryRecord.setStatus("UNPASS");
+//            entryRecord.setVerifyUserId(info.getVerifyUserId());
+//            entryRecord.setReason(info.getReason());
+//            entryRecord.setCreateTime(info.getCreateTime());
+//            tenantEntryRecordMapper.insert(entryRecord);
+//            //更改当前记录的审核状态
+//            long id = info.getId();
+//            tenantInfoMapper.updateUnpassStatusById(id);
+//        }
+        return true;
+    }
 
-        } else {
-            //查询本次提交记录,并插入审核表
-            TenantInfoWrapper.TenantInfo info = queryNow(query);
-            TenantEntryRecord entryRecord = new TenantEntryRecord();
-            entryRecord.setId(info.getId());
-            entryRecord.setName(info.getName());
-            entryRecord.setLogo(info.getLogo());
-            entryRecord.setProvinceCode(info.getProvinceCode());
-            entryRecord.setCityCode(info.getCityCode());
-            entryRecord.setRegionCode(info.getRegionCode());
-            entryRecord.setUsername(info.getUserName());
-            entryRecord.setPhone(info.getPhone());
-            entryRecord.setStatus("UNPASS");
-            entryRecord.setVerifyUserId(info.getVerifyUserId());
-            entryRecord.setReason(info.getReason());
-            entryRecord.setCreateTime(info.getCreateTime());
-            tenantEntryRecordMapper.insert(entryRecord);
-            //更改当前记录的审核状态
-            long id = info.getId();
-            tenantInfoMapper.updateUnpassStatusById(id);
-        }
-        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;
+        return null;
     }
 
 

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

@@ -30,7 +30,7 @@ public class TenantPersonStatServiceImpl extends ServiceImpl<TenantPersonStatMap
         Date date = DateUtil.addDays(new Date(), -1);
         String day = DateUtil.format(date, DateUtil.DEFAULT_PATTERN);
         this.lambdaUpdate().eq(TenantPersonStat::getDay,day).remove();
-        String month = DateUtil.getMonth(date);
+        String month = DateUtil.format(date,DateUtil.ISO_YEAR_MONTH_FORMAT);
         String year = DateUtil.getYear(date);
         //获取初始化数据
         List<TenantPersonStat> stats = baseMapper.init();
@@ -61,7 +61,9 @@ public class TenantPersonStatServiceImpl extends ServiceImpl<TenantPersonStatMap
                 dtos.add(dateMap.get(date));
             } else {
                 // 如果不存在对应日期的数据
-                dtos.add(new TenantPersonStatWrapper.TenantPersonStatDto(date));
+                TenantPersonStatWrapper.TenantPersonStatDto dto = new TenantPersonStatWrapper.TenantPersonStatDto();
+                dto.setDate(date);
+                dtos.add(dto);
             }
         }
         return new TenantPersonStatWrapper.TenantPersonStatSum(baseMapper.sumByNow(query.getTenantId()),dtos);

+ 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;
 
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 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.beans.BeanUtils;
 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.service.TenantUnbindRecordService;
 
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
 /**
  * 机构解绑申请记录
  * 2023-07-21 17:32:49
@@ -19,6 +36,28 @@ import com.yonge.cooleshow.biz.dal.service.TenantUnbindRecordService;
 @Service
 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
@@ -38,8 +77,83 @@ public class TenantUnbindRecordServiceImpl extends ServiceImpl<TenantUnbindRecor
      */
     @Override
     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));       
     }
+
+    @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;
+    }
 }

+ 11 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderServiceImpl.java

@@ -19,6 +19,7 @@ import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderPayRes;
+import com.yonge.cooleshow.biz.dal.wrapper.PaymentDivMemberRecordWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.coupon.CouponOrderWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
@@ -1096,6 +1097,16 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
         return this.lambdaQuery().eq(UserOrder::getOrderNo, orderNo).last("limit 1").one();
     }
 
+    @Override
+    public IPage<PaymentDivMemberRecordWrapper.IndexIncomeQueryDto> queryExpend(IPage<PaymentDivMemberRecordWrapper.IndexIncomeQueryDto> page, PaymentDivMemberRecordWrapper.IndexIncomeQuery query) {
+        return page.setRecords(baseMapper.queryExpend(page, query));
+    }
+
+    @Override
+    public PaymentDivMemberRecordWrapper.OrderDetailDto getExpendOrderDetail(String orderNo) {
+        return baseMapper.getExpendOrderDetail(orderNo);
+    }
+
     /**
      * 获取平台服务费率
      *

+ 30 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/PaymentDivMemberRecordWrapper.java

@@ -9,6 +9,7 @@ import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
 import java.math.BigDecimal;
+import java.util.List;
 import java.util.Optional;
 
 import lombok.AllArgsConstructor;
@@ -66,10 +67,10 @@ public class PaymentDivMemberRecordWrapper {
         @ApiModelProperty("关键字匹配")
 		private String keyword;
 
-        @ApiModelProperty("支付时")
+        @ApiModelProperty("支付时(年月日 时分秒)")
 		private String startTime;
 
-        @ApiModelProperty("支付时间")
+        @ApiModelProperty("支付时间(年月日 时分秒)")
 		private String endTime;
 
         @ApiModelProperty("订单类型")
@@ -123,6 +124,33 @@ public class PaymentDivMemberRecordWrapper {
     }
 
     @Data
+    @ApiModel("首页收入、支出汇总")
+    public static class IndexIncomeSummaryDto{
+
+        @ApiModelProperty("累计收入")
+        private BigDecimal totalIncome = BigDecimal.ZERO;
+
+        @ApiModelProperty("累计支出")
+        private BigDecimal totalExpend = BigDecimal.ZERO;
+
+        @ApiModelProperty("收入汇总详情")
+        private List<IndexIncomeSummaryDetailDto> incomeDtos;
+
+        @ApiModelProperty("支出汇总详情")
+        private List<IndexIncomeSummaryDetailDto> expendDtos;
+    }
+
+    @Data
+    @ApiModel("首页收入、支出汇总")
+    public static class IndexIncomeSummaryDetailDto{
+        @ApiModelProperty("金额")
+        private BigDecimal amount = BigDecimal.ZERO;
+
+        @ApiModelProperty("订单类型")
+        private EOrderType orderType;
+    }
+
+    @Data
     @ApiModel("首页订单详情")
     public static class OrderDetailDto extends IndexIncomeQueryDto{
 

+ 13 - 14
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/StudentWrapper.java

@@ -118,24 +118,12 @@ public class StudentWrapper {
         @ApiModelProperty("声部,多个用逗号隔开")
         private String subjectId;
 
-        @ApiModelProperty("是否解绑")
-        private Boolean bindTenant;
+//        @ApiModelProperty("是否解绑")
+//        private Boolean bindTenant;
 
     }
 
     @Data
-    @ApiModel("解绑机构")
-    public static class UnbindTenant {
-
-        @ApiModelProperty("短信验证码")
-        private String code;
-
-        @ApiModelProperty("解绑原因")
-        private String unbindReason;
-    }
-
-
-    @Data
     @ApiModel("学生导入模板模型")
     public static class StudentExport {
 
@@ -190,4 +178,15 @@ public class StudentWrapper {
             return errMsg;
         }
     }
+
+    @Data
+    @ApiModel("学生修改机构")
+    public static class StudentUpdateTenant {
+
+        @ApiModelProperty("学生ID")
+        private Long studentId;
+
+        @ApiModelProperty("机构ID")
+        private Long tenantId;
+    }
 }

+ 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;
 
 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.ApiModelProperty;
+
+import java.math.BigDecimal;
+import java.util.Date;
 import java.util.Optional;
 
 import lombok.AllArgsConstructor;
@@ -24,13 +29,13 @@ public class SysGoodsPriceWrapper {
     @NoArgsConstructor
     @AllArgsConstructor
     @ApiModel(" SysGoodsPriceQuery-商品价格设置")
-    public static class SysGoodsPriceQuery implements QueryInfo {
+    public static class SysGoodsPriceQuery extends QueryInfo {
     
     	@ApiModelProperty("当前页")
-        private Integer page;
+        private int page;
         
         @ApiModelProperty("分页行数")
-        private Integer rows;
+        private int rows;
         
         @ApiModelProperty("关键字匹配")
 		private String keyword;
@@ -46,11 +51,43 @@ public class SysGoodsPriceWrapper {
         public static SysGoodsPriceQuery from(String json) {
             return JSON.parseObject(json, SysGoodsPriceQuery.class);
         }
-    }  
+    }
 
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
 	@ApiModel(" 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() {
             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;
 
+import com.alibaba.excel.annotation.ExcelProperty;
 import com.alibaba.fastjson.JSON;
 import com.microsvc.toolkit.common.response.paging.QueryInfo;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
 import java.util.Optional;
+import java.util.regex.Pattern;
 
 import lombok.AllArgsConstructor;
 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;
+        }
+
+
+    }
+
 }

+ 124 - 3
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantAlbumWrapper.java

@@ -3,10 +3,17 @@ package com.yonge.cooleshow.biz.dal.wrapper;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.entity.TenantAlbumMusic;
+import com.yonge.cooleshow.biz.dal.enums.SubjectTypeEnum;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
 import java.math.BigDecimal;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
 import java.util.Optional;
 
 import lombok.AllArgsConstructor;
@@ -15,6 +22,8 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 import org.apache.commons.lang3.StringUtils;
 
+import javax.validation.constraints.NotNull;
+
 /**
  * 机构专辑
  * 2023-07-21 17:32:49
@@ -41,6 +50,9 @@ public class TenantAlbumWrapper {
         @ApiModelProperty("机构ID")
         private Long tenantId;
 
+        @ApiModelProperty("专辑名称")
+        private String name;
+
         public String getKeyword() {
             return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
         }
@@ -54,9 +66,64 @@ public class TenantAlbumWrapper {
         }
     }
 
-    @ApiModel(" TenantAlbum-机构专辑")
+    @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 tenantName;
+
+        @ApiModelProperty("专辑介绍")
+        private String describe;
+
+        @ApiModelProperty("专辑封面")
+        private String coverImg;
+
+        @ApiModelProperty("曲目数")
+        private Integer musicNum;
+
+        @ApiModelProperty("平台价格")
+        private BigDecimal originalPrice;
+
+        @ApiModelProperty("机构价格")
+        private BigDecimal salePrice;
+
+        @ApiModelProperty("原价")
+        private BigDecimal costPrice;
+
+        @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() {
             return JSON.toJSONString(this);
         }
@@ -110,10 +177,10 @@ public class TenantAlbumWrapper {
         @ApiModelProperty("采购倍数")
         private Integer buyMultiple;
 
-        @ApiModelProperty(value = "采购周期",hidden = true)
+        @ApiModelProperty(value = "采购周期", hidden = true)
         private Integer buyCycle;
 
-        @ApiModelProperty(value = "采购机构",hidden = true)
+        @ApiModelProperty(value = "采购机构", hidden = true)
         private Long tenantId;
 
 
@@ -125,4 +192,58 @@ public class TenantAlbumWrapper {
 
 
     }
+
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" 机构专辑新增")
+    public static class TenantAlbumVo {
+        @ApiModelProperty("机构ID")
+        private Long tenantId;
+
+        @ApiModelProperty("专辑名称")
+        @NotNull
+        private String name;
+
+        @ApiModelProperty("机构名称")
+        private String tenantName;
+
+        @ApiModelProperty("专辑介绍")
+        @NotNull
+        private String describe;
+
+        @ApiModelProperty("专辑封面")
+        @NotNull
+        private String coverImg;
+
+        @ApiModelProperty("曲目声部分类(多个,分隔)")
+        private String subjectTypes;
+
+        @ApiModelProperty("曲目相关信息")
+        private List<MusicSheetData> musicSheetData = new ArrayList<>();
+
+        @ApiModelProperty("机构价格")
+        private BigDecimal salePrice;
+
+        @ApiModelProperty("原价")
+        private BigDecimal costPrice;
+
+        @ApiModelProperty("购买周期")
+        private Integer purchaseCycle;
+
+    }
+
+    @Data
+    public static class MusicSheetData {
+
+        private SubjectTypeEnum subjectType;
+
+        @ApiModelProperty(value = "声部列表",hidden = true)
+        private List<Long> musicSheetIdList = new ArrayList<>();
+
+        @ApiModelProperty("声部列表")
+        private List<TenantAlbumMusic> musicSheetList = new ArrayList<>();
+    }
 }

+ 41 - 29
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantInfoWrapper.java

@@ -2,8 +2,9 @@ package com.yonge.cooleshow.biz.dal.wrapper;
 
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.annotation.TableField;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
 import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
-import com.yonge.toolset.base.page.QueryInfo;
+import com.yonge.cooleshow.common.enums.ESettlementFrom;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
@@ -24,28 +25,20 @@ import org.apache.commons.lang3.StringUtils;
 public class TenantInfoWrapper {
 
     @Data
-	@Builder
+    @Builder
     @NoArgsConstructor
     @AllArgsConstructor
     @ApiModel(" TenantInfoQuery-机构表")
-    public static class TenantInfoQuery  extends QueryInfo {
-        @ApiModelProperty("id")
-        private long id;
+    public static class TenantInfoQuery implements QueryInfo {
 
-        @ApiModelProperty("是否冻结")
-        private Integer ifFreeze;
+        @ApiModelProperty("当前页")
+        private Integer page;
 
-        @ApiModelProperty("是否更改结算方式")
-        private Integer ifMethod;
-    
-    	@ApiModelProperty("当前页")
-        private int page;
-        
         @ApiModelProperty("分页行数")
-        private int rows;
-        
+        private Integer rows;
+
         @ApiModelProperty("关键字匹配")
-		private String keyword;
+        private String keyword;
 
         @ApiModelProperty("省份编码")
         private Integer provinceCode;
@@ -56,14 +49,10 @@ public class TenantInfoWrapper {
         @ApiModelProperty("地区街道编码")
         private Integer regionCode;
 
-        @ApiModelProperty("审核是否通过")
-        private Integer ifPass;
-
-        
         public String getKeyword() {
             return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
         }
-        
+
         public String jsonString() {
             return JSON.toJSONString(this);
         }
@@ -71,7 +60,7 @@ public class TenantInfoWrapper {
         public static TenantInfoQuery from(String json) {
             return JSON.parseObject(json, TenantInfoQuery.class);
         }
-    }  
+    }
 
 
     @Data
@@ -83,9 +72,6 @@ public class TenantInfoWrapper {
         @ApiModelProperty("id")
         private long id;
 
-        @ApiModelProperty("机构ID")
-        private Long tenantId;
-
         @ApiModelProperty("机构名称")
         private String name;
 
@@ -105,10 +91,10 @@ public class TenantInfoWrapper {
         private String phone;
 
         @ApiModelProperty("教师数量")
-        private String teacherCounts;
+        private Integer teacherCounts;
 
         @ApiModelProperty("学生数量")
-        private String studentCounts;
+        private Integer studentCounts;
 
         @ApiModelProperty("省份编码")
         private Integer provinceCode;
@@ -146,7 +132,10 @@ public class TenantInfoWrapper {
 
         @ApiModelProperty("更新时间")
         private Date updateTime;
-        
+
+        @ApiModelProperty("启用/冻结")
+        private Boolean enableFlag;
+
         public String jsonString() {
             return JSON.toJSONString(this);
         }
@@ -154,6 +143,29 @@ public class TenantInfoWrapper {
         public static TenantInfo from(String json) {
             return JSON.parseObject(json, TenantInfo.class);
         }
-	}
+    }
+
+    @ApiModel("启用/冻结")
+    @Data
+    public static class UpdateStatus {
+
+        @ApiModelProperty("id")
+        private Long id;
+
+        @ApiModelProperty("true:启用/false:冻结")
+        private Boolean enableFlag;
+
+        @ApiModelProperty("结算方式")
+        private ESettlementFrom settlement;
+    }
+
+    @Data
+    public static class UserCount {
+
+        private Long tenantId;
+
+        private Integer count;
+
+    }
 
 }

+ 0 - 4
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantPersonStatWrapper.java

@@ -39,10 +39,6 @@ public class TenantPersonStatWrapper {
 
         @ApiModelProperty("时间节点")
         private String date;
-
-        public TenantPersonStatDto(String date) {
-            this.date = date;
-        }
     }
 
 	@Data

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

+ 24 - 2
cooleshow-user/user-biz/src/main/resources/config/mybatis/PaymentDivMemberRecordMapper.xml

@@ -56,7 +56,7 @@
           </if>
            ORDER BY ${param.sortField} ${param.sortType}
     </select>
-    <select id="getOrderDetail"
+    <select id="getIncomeOrderDetail"
             resultType="com.yonge.cooleshow.biz.dal.wrapper.PaymentDivMemberRecordWrapper$OrderDetailDto">
         select
             pdmr.order_no_ as orderNo,
@@ -79,8 +79,30 @@
                 left join
             sys_user su ON su.id_ = sut.user_id_
                 left join
-            user_order_detail uod ON uod.order_id_ = uo.id_
+            user_order_detail uod ON uod.order_no_ = uo.order_no_
             WHERE pdmr.order_no_ = #{orderNo} AND pdmr.tenant_id_ = #{tenantId} LIMIT 1
     </select>
+    <select id="incomeSummary"
+            resultType="com.yonge.cooleshow.biz.dal.wrapper.PaymentDivMemberRecordWrapper$IndexIncomeSummaryDetailDto">
+        select uo.order_type_ as orderType,SUM(pdmr.amount_) amount
+        from payment_div_member_record pdmr
+        left join user_order uo ON uo.order_no_ = pdmr.order_no_
+        where pdmr.status_ = 'SUCCESS' AND pdmr.tenant_id_ = #{query.tenantId}
+        <if test="query.startTime != null and query.startTime != ''">
+            AND uo.pay_time_ BETWEEN #{query.startTime} AND #{query.endTime}
+        </if>
+        group by uo.order_type_
+    </select>
+    <select id="expendSummary"
+            resultType="com.yonge.cooleshow.biz.dal.wrapper.PaymentDivMemberRecordWrapper$IndexIncomeSummaryDetailDto">
+        select uo.order_type_ as orderType,SUM(uo.actual_price_) amount
+        from user_order uo
+        where uo.status_ = 'SUCCESS' AND uo.order_type_ = 'TENANT_ALBUM'
+        AND uo.tenant_id_ = #{query.tenantId}
+        <if test="query.startTime != null and query.startTime != ''">
+            AND uo.pay_time_ BETWEEN #{query.startTime} AND #{query.endTime}
+        </if>
+        group by uo.order_type_
+    </select>
 
 </mapper>

+ 6 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/PlatformCashAccountRecordMapper.xml

@@ -80,6 +80,9 @@
 	<sql id="selectSql">
 		select * from platform_cash_account_record
 		<where>
+			<if test="param.tenantId">
+				and tenant_id_ = #{param.tenantId}
+			</if>
 			<if test="param.orderNo">
 				and order_no_ = #{param.orderNo}
 			</if>
@@ -119,6 +122,9 @@
 			sum(case when in_or_out_ = 'OUT' and post_status_ = 'RECORDED' then trans_amount_ else 0 end) settledPayment
 		from platform_cash_account_record
 		<where>
+			<if test="param.tenantId">
+				and tenant_id_ = #{param.tenantId}
+			</if>
 			<if test="param.orderNo">
 				and order_no_ = #{param.orderNo}
 			</if>

+ 11 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/StudentMapper.xml

@@ -315,4 +315,15 @@
             AND (su.username_ LIKE CONCAT('%', #{search}, '%') OR su.phone_ LIKE CONCAT('%', #{search}, '%'))
         </if>
     </select>
+
+    <select id="countTeacherByTenantIds" resultType="com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper$UserCount">
+        select tenant_id_ tenantId, count(tenant_id_) count
+        from student
+        where tenant_id_ in
+        <foreach collection="tenantIdList" item="item" separator="," open="(" close=")">
+            #{item}
+        </foreach>
+        group by tenant_id_
+
+    </select>
 </mapper>

+ 35 - 22
cooleshow-user/user-biz/src/main/resources/config/mybatis/SysMusicCompareRecordMapper.xml

@@ -345,28 +345,38 @@
 	</select>
     <select id="queryWeChatStudentTrainData"
             resultType="com.yonge.cooleshow.biz.dal.queryInfo.SysMusicCompareRecordQueryInfo$WechatCompareRecordPageDto">
-		select su.id_ userId,su.avatar_ avatar,su.username_ username,GROUP_CONCAT(DISTINCT sb.name_) subjectName,
-			   SUM(mprs.playTime) trainTimes,COUNT(DISTINCT mprs.create_time_) trainDays,
-			   SUM(mprs.playTime) / COUNT(DISTINCT mprs.create_time_) avgTrainTimes
-		from (select st.user_id_,DATE_FORMAT(smcr.create_time_,'%Y-%m-%d') create_time_,SUM(smcr.play_time_) playTime,st.subject_id_
-			  from student st
-					   LEFT JOIN sys_music_compare_record smcr ON smcr.user_id_ = st.user_id_
-			  where st.membership_end_time_ >= NOW()
-			  <if test="startTime != null and startTime != ''">
-				  AND smcr.create_time_ BETWEEN #{startTime} AND #{endTime}
-			  </if>
-			<if test="queryInfo.tenantId != null">
-				AND smcr.tenant_id_ = #{queryInfo.tenantId}
-			</if>
-			  group by st.user_id_,DATE_FORMAT(create_time_,'%Y-%m-%d')) mprs
-				 left join sys_user su ON mprs.user_id_ = su.id_
-				 left join subject sb ON FIND_IN_SET(sb.id_,mprs.subject_id_)
+		select st.user_id_                                                 userId,
+		su.avatar_                                             avatar,
+		su.username_                                           username,
+		GROUP_CONCAT(DISTINCT sb.name_)                        subjectName,
+		SUM(mprs.playTime)                                     trainTimes,
+		COUNT(DISTINCT mprs.create_time_)                      trainDays,
+		SUM(mprs.playTime) / COUNT(DISTINCT mprs.create_time_) avgTrainTimes
+		from student st
+		left join
+		(select smcr.user_id_,
+		DATE_FORMAT(smcr.create_time_, '%Y-%m-%d') create_time_,
+		SUM(smcr.play_time_)                       playTime
+		from sys_music_compare_record smcr
 		<where>
-			<if test="search != null and search != ''">
-				AND su.username_ LIKE CONCAT('%',#{keyword},'%')
+			<if test="startTime != null and startTime != ''">
+				AND smcr.create_time_ BETWEEN #{startTime} AND #{endTime}
+			</if>
+			<if test="tenantId != null">
+				AND smcr.tenant_id_ = #{tenantId}
 			</if>
 		</where>
-		group by mprs.user_id_
+		group by smcr.user_id_, DATE_FORMAT(create_time_, '%Y-%m-%d')) mprs ON mprs.user_id_ = st.user_id_
+		left join sys_user su ON st.user_id_ = su.id_
+		left join subject sb ON sb.id_ = st.subject_id_
+		where st.membership_end_time_ >= NOW()
+		<if test="search != null and search != ''">
+			AND su.username_ LIKE CONCAT('%',#{keyword},'%')
+		</if>
+		<if test="tenantId != null">
+			AND st.tenant_id_ = #{tenantId}
+		</if>
+		group by st.user_id_
 		ORDER BY ${sortField} ${sortType}
 	</select>
 	<select id="countWeChatStudentTrainData" resultType="java.lang.Integer">
@@ -375,8 +385,8 @@
 		left join sys_user su ON st.user_id_ = su.id_
 		LEFT JOIN sys_music_compare_record smcr ON smcr.user_id_ = st.user_id_
 		where st.membership_end_time_ >= NOW()
-		<if test="queryInfo.tenantId != null">
-			AND smcr.tenant_id_ = #{queryInfo.tenantId}
+		<if test="tenantId != null">
+			AND smcr.tenant_id_ = #{tenantId}
 		</if>
 		<if test="startTime != null and startTime != ''">
 			AND smcr.create_time_ BETWEEN #{startTime} AND #{endTime}
@@ -387,7 +397,7 @@
 	</select>
 	<select id="wechatCompareRecordSum"
 			resultType="com.yonge.cooleshow.biz.dal.queryInfo.SysMusicCompareRecordQueryInfo$WechatCompareRecordSumDto">
-		select COUNT(st.user_id_),COUNT(DISTINCT DATE_FORMAT(smcr.create_time_,'%Y-%m-%d')) trainNum,SUM(smcr.play_time_) playTime
+		select COUNT(st.user_id_) studentNum,COUNT(DISTINCT DATE_FORMAT(smcr.create_time_,'%Y-%m-%d')) trainDays,SUM(smcr.play_time_) trainTimes
 		from student st
 		LEFT JOIN sys_music_compare_record smcr ON smcr.user_id_ = st.user_id_
 		where st.membership_end_time_ >= NOW()
@@ -397,6 +407,9 @@
 		<if test="queryInfo.tenantId != null">
 			AND smcr.tenant_id_ = #{queryInfo.tenantId}
 		</if>
+		<if test="queryInfo.tenantId != null">
+			AND st.tenant_id_ = #{queryInfo.tenantId}
+		</if>
 	</select>
     <select id="queryStudentTrain"
             resultType="com.yonge.cooleshow.biz.dal.queryInfo.SysMusicCompareRecordQueryInfo$StudentMusicCompareRecord">

+ 192 - 161
cooleshow-user/user-biz/src/main/resources/config/mybatis/TeacherMapper.xml

@@ -2,56 +2,56 @@
 <!DOCTYPE  mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 <mapper namespace="com.yonge.cooleshow.biz.dal.dao.TeacherDao">
     <resultMap id="BaseResultMap" type="com.yonge.cooleshow.biz.dal.entity.Teacher">
-        <result column="user_id_" property="userId" />
-        <result column="education_background_" property="educationBackground" />
-        <result column="graduate_school_" property="graduateSchool" />
-        <result column="technical_titles_" property="technicalTitles" />
-        <result column="work_unit_" property="workUnit" />
-        <result column="subject_id_" property="subjectId" />
-        <result column="default_subject_" property="defaultSubject" />
-        <result column="introduction_" property="introduction" />
-        <result column="subject_" property="subject" />
-        <result column="grad_certificate_" property="gradCertificate" />
-        <result column="degree_certificate_" property="degreeCertificate" />
-        <result column="teacher_certificate_" property="teacherCertificate" />
-        <result column="entry_flag_" property="entryFlag" />
-        <result column="entry_auth_date_" property="entryAuthDate" />
-        <result column="musician_flag_" property="musicianFlag" />
-        <result column="musician_date_" property="musicianDate" />
+        <result column="user_id_" property="userId"/>
+        <result column="education_background_" property="educationBackground"/>
+        <result column="graduate_school_" property="graduateSchool"/>
+        <result column="technical_titles_" property="technicalTitles"/>
+        <result column="work_unit_" property="workUnit"/>
+        <result column="subject_id_" property="subjectId"/>
+        <result column="default_subject_" property="defaultSubject"/>
+        <result column="introduction_" property="introduction"/>
+        <result column="subject_" property="subject"/>
+        <result column="grad_certificate_" property="gradCertificate"/>
+        <result column="degree_certificate_" property="degreeCertificate"/>
+        <result column="teacher_certificate_" property="teacherCertificate"/>
+        <result column="entry_flag_" property="entryFlag"/>
+        <result column="entry_auth_date_" property="entryAuthDate"/>
+        <result column="musician_flag_" property="musicianFlag"/>
+        <result column="musician_date_" property="musicianDate"/>
         <result column="member_rank_setting_id_" property="memberRankSettingId"/>
         <result column="membership_start_time_" property="membershipStartTime"/>
         <result column="membership_end_time_" property="membershipEndTime"/>
-        <result column="live_flag_" property="liveFlag" />
-        <result column="live_date_" property="liveDate" />
-        <result column="music_date_" property="musicDate" />
-        <result column="video_date_" property="videoDate" />
-        <result column="style_date_" property="styleDate" />
-        <result column="degree_date_" property="degreeDate" />
-        <result column="teacher_date_" property="teacherDate" />
-        <result column="degree_flag_" property="degreeFlag" />
-        <result column="teacher_flag_" property="teacherFlag" />
-        <result column="browse_" property="browse" />
-        <result column="memo_" property="memo" />
-        <result column="lock_flag_" property="lockFlag" />
-        <result column="is_settlement_" property="isSettlement" />
-        <result column="is_test_user_" property="isTestUser" />
-        <result column="tenant_id_" property="tenantId" />
-        <result column="settlement_from_" property="settlementFrom" />
-        <result column="create_time_" property="createTime" />
-        <result column="update_time_" property="updateTime" />
+        <result column="live_flag_" property="liveFlag"/>
+        <result column="live_date_" property="liveDate"/>
+        <result column="music_date_" property="musicDate"/>
+        <result column="video_date_" property="videoDate"/>
+        <result column="style_date_" property="styleDate"/>
+        <result column="degree_date_" property="degreeDate"/>
+        <result column="teacher_date_" property="teacherDate"/>
+        <result column="degree_flag_" property="degreeFlag"/>
+        <result column="teacher_flag_" property="teacherFlag"/>
+        <result column="browse_" property="browse"/>
+        <result column="memo_" property="memo"/>
+        <result column="lock_flag_" property="lockFlag"/>
+        <result column="is_settlement_" property="isSettlement"/>
+        <result column="is_test_user_" property="isTestUser"/>
+        <result column="tenant_id_" property="tenantId"/>
+        <result column="settlement_from_" property="settlementFrom"/>
+        <result column="create_time_" property="createTime"/>
+        <result column="update_time_" property="updateTime"/>
     </resultMap>
-    
+
     <resultMap id="HotTeacherVoMap" type="com.yonge.cooleshow.biz.dal.vo.HotTeacherVo">
-        <result column="user_id_" property="userId" />
-        <result column="avatar_" property="avatar" />
-        <result column="graduate_school_" property="graduateSchool" />
-        <result column="username_" property="username" />
-        <result column="isLiving_" property="isLiving" />
+        <result column="user_id_" property="userId"/>
+        <result column="avatar_" property="avatar"/>
+        <result column="graduate_school_" property="graduateSchool"/>
+        <result column="username_" property="username"/>
+        <result column="isLiving_" property="isLiving"/>
     </resultMap>
 
     <!-- 表字段 -->
     <sql id="baseColumns">
-         t.user_id_ as "userId"
+        t.user_id_ as "userId"
         , t.education_background_ as "educationBackground"
         , t.graduate_school_ as "graduateSchool"
         , t.technical_titles_ as "technicalTitles"
@@ -89,29 +89,29 @@
         , t.evaluate_time_ as evaluateTime
         , t.tenant_id_ as tenantId
         , t.settlement_from_ as settlementFrom
-        </sql>
+    </sql>
 
     <!-- 分页查询 -->
-    <select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.vo.TeacherVo" >
+    <select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.vo.TeacherVo">
         SELECT
-            <include refid="baseColumns"/>,
-            if(u.lock_flag_ = 0 and t.lock_flag_ = 0,0,1) as lockFlag,
-            u.username_ as username,
-            u.phone_ as phone,
-            u.real_name_ as realName,
-            u.avatar_ as avatar,
-            u.birthdate_ as birthdate,
-            u.gender_ as gender,
-            (case when t.membership_end_time_ &gt;= now() then 1 else 0 end) isVip,
-<!--            t.tag_ tag,-->
-            u.del_flag_ as delFlag,
-            (case when isnull(u.id_card_no_) then 0 else 1 end) as isReal,
-            (case when isnull(b.user_id_) then 0 else 1 end) as isBank,
-            (case when t.tenant_id_ = -1 then '平台老师' else ti.name_ end) as tenantName
+        <include refid="baseColumns"/>,
+        if(u.lock_flag_ = 0 and t.lock_flag_ = 0,0,1) as lockFlag,
+        u.username_ as username,
+        u.phone_ as phone,
+        u.real_name_ as realName,
+        u.avatar_ as avatar,
+        u.birthdate_ as birthdate,
+        u.gender_ as gender,
+        (case when t.membership_end_time_ &gt;= now() then 1 else 0 end) isVip,
+        <!--            t.tag_ tag,-->
+        u.del_flag_ as delFlag,
+        (case when isnull(u.id_card_no_) then 0 else 1 end) as isReal,
+        (case when isnull(b.user_id_) then 0 else 1 end) as isBank,
+        (case when t.tenant_id_ = -1 then '平台老师' else ti.name_ end) as tenantName
         FROM teacher t
         left join sys_user u on t.user_id_ = u.id_
         left join (
-            select distinct user_id_ from user_bank_card where del_flag_ = 0
+        select distinct user_id_ from user_bank_card where del_flag_ = 0
         ) b on t.user_id_ = b.user_id_
         left join tenant_info ti on t.tenant_id_ = ti.id_
         <where>
@@ -125,28 +125,28 @@
             </if>
             <if test="null != param.teacherType and '' != param.teacherType">
                 and (
-                    1=0
-                    <if test='param.teacherType.contains("TOURIST")'>
-                        or (t.entry_flag_ = 0 and t.musician_flag_ = 0)
-                    </if>
-                    <if test='param.teacherType.contains("ENTRY")'>
-                        or t.entry_flag_ = 1
-                    </if>
-                    <if test='param.teacherType.contains("MUSICIAN")'>
-                        or t.musician_flag_ = 1
-                    </if>
+                1=0
+                <if test='param.teacherType.contains("TOURIST")'>
+                    or (t.entry_flag_ = 0 and t.musician_flag_ = 0)
+                </if>
+                <if test='param.teacherType.contains("ENTRY")'>
+                    or t.entry_flag_ = 1
+                </if>
+                <if test='param.teacherType.contains("MUSICIAN")'>
+                    or t.musician_flag_ = 1
+                </if>
                 )
             </if>
             <if test="param.isVip != null">
-            	<if test="param.isVip == 0">
-            		and (t.membership_end_time_ is null or t.membership_end_time_ &lt; now())
-            	</if>
-            	<if test="param.isVip == 1">
-            		and t.membership_end_time_ &gt;= now()
-            	</if>
+                <if test="param.isVip == 0">
+                    and (t.membership_end_time_ is null or t.membership_end_time_ &lt; now())
+                </if>
+                <if test="param.isVip == 1">
+                    and t.membership_end_time_ &gt;= now()
+                </if>
             </if>
             <if test="param.tag != null">
-            	and find_in_set(#{param.tag},t.tag_)
+                and find_in_set(#{param.tag},t.tag_)
             </if>
             <if test="null != param.lockFlag">
                 and t.lock_flag_ = #{param.lockFlag}
@@ -155,13 +155,13 @@
                 and u.del_flag_ = #{param.delFlag}
             </if>
             <if test="param.subjectId != null">
-            	and find_in_set(#{param.subjectId},t.subject_id_)
+                and find_in_set(#{param.subjectId},t.subject_id_)
             </if>
             <if test="param.isSettlement != null">
-            	and t.is_settlement_ = #{param.isSettlement}
+                and t.is_settlement_ = #{param.isSettlement}
             </if>
             <if test="param.isTestUser != null">
-            	and t.is_test_user_ = #{param.isTestUser}
+                and t.is_test_user_ = #{param.isTestUser}
             </if>
             <if test="null != param.vipEndTime">
                 and t.membership_end_time_ &lt;= #{param.vipEndTime}
@@ -195,111 +195,125 @@
         </choose>
     </select>
 
-	<resultMap id="BasicUserInfo" type="com.yonge.cooleshow.biz.dal.dto.BasicUserInfo">
-		<result property="userId" column="user_id_"/>
-		<result property="username" column="username_"/>
-		<result property="realName" column="real_name_"/>
-		<result property="avatar" column="avatar_"/>
-	</resultMap>
-	<select id="getBasicUserInfo" resultMap="BasicUserInfo">
-		SELECT id_ user_id_,username_,real_name_,avatar_ FROM sys_user
-		WHERE del_flag_ = 0 and id_ = #{userId} LIMIT 1
-	</select>
+    <resultMap id="BasicUserInfo" type="com.yonge.cooleshow.biz.dal.dto.BasicUserInfo">
+        <result property="userId" column="user_id_"/>
+        <result property="username" column="username_"/>
+        <result property="realName" column="real_name_"/>
+        <result property="avatar" column="avatar_"/>
+    </resultMap>
+    <select id="getBasicUserInfo" resultMap="BasicUserInfo">
+        SELECT id_ user_id_, username_, real_name_, avatar_
+        FROM sys_user
+        WHERE del_flag_ = 0
+          and id_ = #{userId}
+        LIMIT 1
+    </select>
 
-	<select id="findBasicUserInfo" resultMap="BasicUserInfo">
-		SELECT id_ user_id_,username_,real_name_,avatar_ FROM sys_user
-		WHERE del_flag_ = 0 and id_ IN
-		<foreach collection="studentIds" open="(" close=")" separator="," item="userId">
-			#{userId}
-		</foreach>
-	</select>
+    <select id="findBasicUserInfo" resultMap="BasicUserInfo">
+        SELECT id_ user_id_,username_,real_name_,avatar_ FROM sys_user
+        WHERE del_flag_ = 0 and id_ IN
+        <foreach collection="studentIds" open="(" close=")" separator="," item="userId">
+            #{userId}
+        </foreach>
+    </select>
 
     <select id="detail" resultType="com.yonge.cooleshow.biz.dal.vo.TeacherVo">
         SELECT
-            <include refid="baseColumns"/>,
-            if(u.lock_flag_ = 0 and t.lock_flag_ = 0,0,1) as lockFlag,
-            u.avatar_ as avatar,
-            u.username_ as username,
-            u.gender_ as `gender`,
-            u.birthdate_ as birthdate,
-            u.phone_ as phone,
-            (case when isnull(u.id_card_no_) then 0 else 1 end) as isReal,
-            (!isnull(membership_end_time_) and membership_end_time_ > now()) as isVip,
-            u.real_name_ as realName,
-            u.id_card_no_ as idCardNo,
-            (case when isnull(b.user_id_) then 0 else 1 end) as isBank,
-            (
-                SELECT GROUP_CONCAT(name_ ORDER by locate(id_,t.subject_id_)) FROM subject WHERE FIND_IN_SET(id_,t.subject_id_)
-            ) as subjectName,
-            u.user_type_ as userType
+        <include refid="baseColumns"/>,
+        if(u.lock_flag_ = 0 and t.lock_flag_ = 0,0,1) as lockFlag,
+        u.avatar_ as avatar,
+        u.username_ as username,
+        u.gender_ as `gender`,
+        u.birthdate_ as birthdate,
+        u.phone_ as phone,
+        (case when isnull(u.id_card_no_) then 0 else 1 end) as isReal,
+        (!isnull(membership_end_time_) and membership_end_time_ > now()) as isVip,
+        u.real_name_ as realName,
+        u.id_card_no_ as idCardNo,
+        (case when isnull(b.user_id_) then 0 else 1 end) as isBank,
+        (
+        SELECT GROUP_CONCAT(name_ ORDER by locate(id_,t.subject_id_)) FROM subject WHERE FIND_IN_SET(id_,t.subject_id_)
+        ) as subjectName,
+        u.user_type_ as userType
         FROM teacher t
         left join sys_user u on t.user_id_ = u.id_
         left join (
-            select distinct user_id_ from user_bank_card where del_flag_ = 0 and user_id_ = #{userId}
+        select distinct user_id_ from user_bank_card where del_flag_ = 0 and user_id_ = #{userId}
         ) b on t.user_id_ = b.user_id_
         where u.del_flag_ = 0 and t.user_id_ = #{userId}
     </select>
 
     <select id="querySubject" resultMap="com.yonge.cooleshow.biz.dal.dao.SubjectDao.Subject">
-        SELECT s.* FROM `subject` s
-        LEFT JOIN teacher t ON FIND_IN_SET(s.id_,t.subject_id_)
+        SELECT s.*
+        FROM `subject` s
+                 LEFT JOIN teacher t ON FIND_IN_SET(s.id_, t.subject_id_)
         WHERE t.user_id_ = #{userId}
     </select>
 
     <update id="setSubject">
-        update teacher set subject_id_ = #{subjectIds},update_time_ = now() where user_id_ = #{id}
+        update teacher
+        set subject_id_  = #{subjectIds},
+            update_time_ = now()
+        where user_id_ = #{id}
     </update>
 
     <update id="addHomeBrowse">
-        update teacher set browse_ = browse_ + 1 where user_id_ = #{userId}
+        update teacher
+        set browse_ = browse_ + 1
+        where user_id_ = #{userId}
     </update>
 
     <select id="querySubjectItem" resultType="com.yonge.cooleshow.biz.dal.entity.Subject">
         select t.* from subject t
         join (
-            select a.subject_id_ from (
-                <trim prefixOverrides="union all">
-                    <if test="type == null or type =='MUSIC'">union all
-                        (select music_subject_ as subject_id_ from music_sheet where user_id_ = #{userId} GROUP BY
-                        music_subject_)
-                    </if>
-                    <if test="type == null or type =='VIDEO'">
-                        union all
-                        (select lesson_subject_ as subject_id_ from video_lesson_group where teacher_id_ = #{userId} GROUP BY lesson_subject_)
-                    </if>
-                    <if test="type == null or type =='PIANO_ROOM'">
-                        union all
-                        (select subject_id_ as subject_id_ from course_group where type_ = 'PIANO_ROOM_CLASS' and teacher_id_ = #{userId} GROUP BY subject_id_)
-                    </if>
-                    <if test="type == null or type =='PRACTICE'">
-                        union all
-                        (select subject_id_ as subject_id_ from course_group where type_ = 'PRACTICE' and teacher_id_ = #{userId} GROUP BY subject_id_)
-                    </if>
-                    <if test="type == null or type =='LIVE'">
-                        union all
-                        (select subject_id_ as subject_id_ from course_group where type_ = 'LIVE' and teacher_id_ = #{userId} GROUP BY subject_id_)
-                    </if>
-                </trim>
-            ) a group by a.subject_id_
+        select a.subject_id_ from (
+        <trim prefixOverrides="union all">
+            <if test="type == null or type =='MUSIC'">
+                union all
+                (select music_subject_ as subject_id_ from music_sheet where user_id_ = #{userId} GROUP BY
+                music_subject_)
+            </if>
+            <if test="type == null or type =='VIDEO'">
+                union all
+                (select lesson_subject_ as subject_id_ from video_lesson_group where teacher_id_ = #{userId} GROUP BY
+                lesson_subject_)
+            </if>
+            <if test="type == null or type =='PIANO_ROOM'">
+                union all
+                (select subject_id_ as subject_id_ from course_group where type_ = 'PIANO_ROOM_CLASS' and teacher_id_ =
+                #{userId} GROUP BY subject_id_)
+            </if>
+            <if test="type == null or type =='PRACTICE'">
+                union all
+                (select subject_id_ as subject_id_ from course_group where type_ = 'PRACTICE' and teacher_id_ =
+                #{userId} GROUP BY subject_id_)
+            </if>
+            <if test="type == null or type =='LIVE'">
+                union all
+                (select subject_id_ as subject_id_ from course_group where type_ = 'LIVE' and teacher_id_ = #{userId}
+                GROUP BY subject_id_)
+            </if>
+        </trim>
+        ) a group by a.subject_id_
         ) a on t.id_ = a.subject_id_
         where t.parent_subject_id_ != 0
         and not exists(
-            select 1 from teacher s where s.user_id_ = #{userId} and find_in_set(t.id_,s.subject_id_)
+        select 1 from teacher s where s.user_id_ = #{userId} and find_in_set(t.id_,s.subject_id_)
         )
     </select>
 
     <select id="queryMyFans" resultType="com.yonge.cooleshow.biz.dal.vo.MyFens">
         SELECT
-            s.student_id_ AS userId,
-            s.create_time_ AS starTime,
-            u.avatar_ AS avatar,
-            u.username_ AS userName,
-            u.real_name_ AS realName,
-            u.gender_ AS gender,
-            u.phone_ AS phone,
-            u.birthdate_ AS birthdate,
-            (SELECT group_concat(name_) FROM `subject` WHERE find_in_set(id_,sr.subject_id_)) AS subjectName,
-            if(sr.membership_start_time_ &lt;= now() and sr.membership_end_time_ &gt;= now(),1,0) AS isVip
+        s.student_id_ AS userId,
+        s.create_time_ AS starTime,
+        u.avatar_ AS avatar,
+        u.username_ AS userName,
+        u.real_name_ AS realName,
+        u.gender_ AS gender,
+        u.phone_ AS phone,
+        u.birthdate_ AS birthdate,
+        (SELECT group_concat(name_) FROM `subject` WHERE find_in_set(id_,sr.subject_id_)) AS subjectName,
+        if(sr.membership_start_time_ &lt;= now() and sr.membership_end_time_ &gt;= now(),1,0) AS isVip
         FROM student_star s
         LEFT JOIN sys_user u ON s.student_id_ = u.id_
         LEFT JOIN student sr ON s.student_id_ = sr.user_id_
@@ -322,15 +336,21 @@
             </if>
         </where>
     </select>
-    
+
     <select id="queryHotTeacherList" resultMap="HotTeacherVoMap">
-		select t.user_id_,t.graduate_school_,u.username_,u.avatar_,ifnull(a.speaker_id_,0) isLiving_
-		from teacher t 
-		left join sys_user u on t.user_id_ = u.id_   
-		left join teacher_total tt on tt.user_id_ = t.user_id_
-		left join (SELECT lr.speaker_id_ from live_room lr WHERE live_state_ = 1 and type_ = 'temp' group by lr.speaker_id_) a on a.speaker_id_ = t.user_id_
-		where t.entry_flag_ = 1 and t.is_test_user_ = 0 and find_in_set(#{subjectId},t.subject_id_)
-		order by tt.fans_num_ desc limit 10
+        select t.user_id_, t.graduate_school_, u.username_, u.avatar_, ifnull(a.speaker_id_, 0) isLiving_
+        from teacher t
+                 left join sys_user u on t.user_id_ = u.id_
+                 left join teacher_total tt on tt.user_id_ = t.user_id_
+                 left join (SELECT lr.speaker_id_
+                            from live_room lr
+                            WHERE live_state_ = 1 and type_ = 'temp'
+                            group by lr.speaker_id_) a on a.speaker_id_ = t.user_id_
+        where t.entry_flag_ = 1
+          and t.is_test_user_ = 0
+          and find_in_set(#{subjectId}, t.subject_id_)
+        order by tt.fans_num_ desc
+        limit 10
     </select>
 
     <!--老师学生人数统计-->
@@ -339,11 +359,22 @@
         SELECT t1.teacher_id_ AS id, COUNT(DISTINCT t1.id_) AS total FROM user_binding_teacher t1
         <where>
             <if test="teacherIds != null">
-                AND t1.teacher_id_ IN (<foreach collection="teacherIds" separator="," item="item">#{item}</foreach>)
+                AND t1.teacher_id_ IN (<foreach collection="teacherIds" separator="," item="item">
+                #{item}
+            </foreach>)
             </if>
         </where>
         GROUP BY t1.teacher_id_
     </select>
-    <!--老师学生人数统计-->
 
+    <select id="countTeacherByTenantIds" resultType="com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper$UserCount">
+        select tenant_id_ tenantId, count(tenant_id_) count
+        from teacher
+        where tenant_id_ in
+        <foreach collection="tenantIdList" item="item" separator="," open="(" close=")">
+            #{item}
+        </foreach>
+        group by tenant_id_
+    </select>
+    <!--老师学生人数统计-->
 </mapper>

+ 20 - 12
cooleshow-user/user-biz/src/main/resources/config/mybatis/TenantAlbumMapper.xml

@@ -1,12 +1,9 @@
 <?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.biz.dal.mapper.TenantAlbumMapper">
-
-	 
-    
     <!-- 表字段 -->
     <sql id="baseColumns">
-         t.id_ AS id
+        t.id_ AS id
         , t.name_ AS `name`
         , t.describe_ AS `describe`
         , t.cover_img_ AS coverImg
@@ -19,12 +16,23 @@
         , t.del_flag_ AS delFlag
         , t.update_time_ AS updateTime
         , t.create_time_ AS createTime
-        </sql> 
-    
-    <select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.entity.TenantAlbum">
-		SELECT         
-        	<include refid="baseColumns" />
-		FROM tenant_album t
-	</select>
-    
+        , t.cost_price_ AS costPrice
+    </sql>
+
+    <select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper$TenantAlbum">
+        SELECT
+        <include refid="baseColumns"/>
+        , i.name_ AS tenantName
+        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>
+            <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>
+        </where>
+    </select>
 </mapper>

Some files were not shown because too many files changed in this diff