ソースを参照

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

zouxuan 1 年間 前
コミット
ead8696347
57 ファイル変更2133 行追加323 行削除
  1. 7 0
      cooleshow-api/pom.xml
  2. 17 0
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/AdminFeignService.java
  3. 115 0
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/dto/TenantWrapper.java
  4. 23 0
      cooleshow-api/src/main/java/com/yonge/cooleshow/api/feign/fallback/AdminFeignServiceFallback.java
  5. 16 13
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/core/provider/service/DefaultUserDetailsService.java
  6. 1 1
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/web/controller/UserController.java
  7. 6 2
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/SysUserType.java
  8. 64 4
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantInfoController.java
  9. 51 3
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/open/AdminClient.java
  10. 5 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/StudentSearch.java
  11. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/SysUser.java
  12. 3 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/TenantStaff.java
  13. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/ClientEnum.java
  14. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/GoodTypeEnum.java
  15. 14 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/TenantInfoMapper.java
  16. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ActivityPlanService.java
  17. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CacheKey.java
  18. 7 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseGroupService.java
  19. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseScheduleService.java
  20. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MemberPriceSettingsService.java
  21. 17 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetService.java
  22. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/PianoRoomBuyRecordService.java
  23. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/StudentService.java
  24. 10 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumRefService.java
  25. 16 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumService.java
  26. 35 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantInfoService.java
  27. 14 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantStaffService.java
  28. 17 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserOrderService.java
  29. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/VideoLessonPurchaseRecordService.java
  30. 52 18
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ActivityPlanServiceImpl.java
  31. 51 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseGroupServiceImpl.java
  32. 124 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java
  33. 37 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MemberPriceSettingsServiceImpl.java
  34. 96 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicSheetServiceImpl.java
  35. 36 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/PianoRoomBuyRecordServiceImpl.java
  36. 73 6
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/StudentServiceImpl.java
  37. 54 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantActivationCodeServiceImpl.java
  38. 15 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantAlbumRefServiceImpl.java
  39. 144 7
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantAlbumServiceImpl.java
  40. 315 65
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantInfoServiceImpl.java
  41. 15 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantStaffServiceImpl.java
  42. 42 28
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderServiceImpl.java
  43. 168 55
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserPaymentCoreServiceImpl.java
  44. 60 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/VideoLessonPurchaseRecordServiceImpl.java
  45. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/TeacherVo.java
  46. 51 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/StudentWrapper.java
  47. 29 8
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/TenantInfoWrapper.java
  48. 60 11
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/UserPaymentOrderWrapper.java
  49. 2 2
      cooleshow-user/user-biz/src/main/resources/config/mybatis/TenantActivationCodeMapper.xml
  50. 114 17
      cooleshow-user/user-biz/src/main/resources/config/mybatis/TenantInfoMapper.xml
  51. 2 1
      cooleshow-user/user-biz/src/main/resources/config/mybatis/TenantStaffMapper.xml
  52. 25 0
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/StudentController.java
  53. 3 1
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/TenantActivationCodeController.java
  54. 32 0
      cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/StudentController.java
  55. 4 0
      cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/TeacherController.java
  56. 18 2
      cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/UserOrderController.java
  57. 17 54
      cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/vo/UserPaymentOrderVo.java

+ 7 - 0
cooleshow-api/pom.xml

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

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

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

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

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

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

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

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

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

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

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

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

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

+ 64 - 4
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/TenantInfoController.java

@@ -1,6 +1,7 @@
 package com.yonge.cooleshow.admin.controller;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.req.TeacherSubmitReq;
 import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
 import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper;
@@ -33,12 +34,13 @@ public class TenantInfoController extends BaseController {
 
     /**
      * 查询分页
+     *
      * @param query
      */
     @PostMapping("/page")
     @ApiOperation(value = "查询分页", notes = "TenantInfo")
-    @PreAuthorize("@pcs.hasPermissions('tenantInfo/page')")
-        public HttpResponseResult<PageInfo<TenantInfoWrapper.TenantInfo>> page(@RequestBody TenantInfoWrapper.TenantInfoQuery query) {
+    //@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);
         return succeed(PageUtil.pageInfo(pages));
@@ -50,7 +52,7 @@ public class TenantInfoController extends BaseController {
     @PostMapping("/update")
     @ApiOperation(value = "修改", notes = "传入TenantInfo")
     @PreAuthorize("@pcs.hasPermissions('tenantInfo/update')")
-    public HttpResponseResult<Boolean> updateTenantInfo(@Valid @RequestBody  TenantInfo info) {
+    public HttpResponseResult<Boolean> updateTenantInfo(@Valid @RequestBody TenantInfo info) {
 
         return succeed(tenantInfoService.updateTenantInfo(info));
     }
@@ -73,11 +75,69 @@ public class TenantInfoController extends BaseController {
     @PostMapping("/state")
     @ApiOperation(value = "冻结", notes = "传入id和布尔类型")
     @PreAuthorize("@pcs.hasPermissions('tenantInfo/state')")
-    public HttpResponseResult<Boolean> state( @RequestBody TenantInfoWrapper.TenantInfoQuery query) {
+    public HttpResponseResult<Boolean> state(@RequestBody TenantInfoWrapper.TenantInfoQuery query) {
         if (StringUtil.isEmpty(query.getId())) {
             return failed("参数不能为空");
         }
         return status(tenantInfoService.state(query));
     }
 
+
+    /**
+     * 机构入驻审核分页查询
+     */
+    @PostMapping("/applyPage")
+    @ApiOperation(value = "机构申请查询", notes = "机构申请查询")
+    //@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));
+    }
+
+
+    /**
+     * 机构入驻审核历史记录查询
+     */
+
+    @PostMapping("/historyPage")
+    @ApiOperation(value = "机构审核历史记录", notes = "机构审核历史记录")
+    //@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));
+    }
+
+
+    /**
+     * 机构入驻审核本次提交查询
+     */
+    @PostMapping("/queryNow")
+    @ApiOperation(value = "机构审核本次提交", notes = "机构审核本次提交")
+    //@PreAuthorize("@pcs.hasPermissions('tenantInfo/now')")
+    public HttpResponseResult<TenantInfoWrapper.TenantInfo> queryNow(@RequestBody TenantInfoWrapper.TenantInfoQuery query) {
+
+        TenantInfoWrapper.TenantInfo tenantInfo = tenantInfoService.queryNow(query);
+        return succeed(tenantInfo);
+    }
+
+    /**
+     * 机构入驻审核功能
+     */
+    @PostMapping("/entry")
+    @ApiOperation(value = "机构审核功能", notes = "机构审核功能")
+    //@PreAuthorize("@pcs.hasPermissions('tenantInfo/now')")
+    public HttpResponseResult<Boolean> entry(@RequestBody TenantInfoWrapper.TenantInfoQuery query) {
+
+
+        return succeed(tenantInfoService.entry(query));
+    }
+
+
+
 }
+
+
+
+//sysUser     tenantStaff

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

@@ -1,14 +1,18 @@
 package com.yonge.cooleshow.admin.controller.open;
 
+import com.alibaba.fastjson.JSON;
 import com.microsvc.toolkit.config.jwt.utils.RsaKeyHelper;
 import com.yonge.cooleshow.admin.io.request.coupon.CouponOrderVO;
 import com.yonge.cooleshow.api.feign.dto.CouponInfoApi;
 import com.yonge.cooleshow.api.feign.dto.EmployeeApi;
 import com.yonge.cooleshow.api.feign.dto.StudentApi;
 import com.yonge.cooleshow.api.feign.dto.TeacherApi;
+import com.yonge.cooleshow.api.feign.dto.TenantWrapper;
 import com.yonge.cooleshow.biz.dal.entity.Employee;
 import com.yonge.cooleshow.biz.dal.entity.Student;
 import com.yonge.cooleshow.biz.dal.entity.Teacher;
+import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.coupon.CouponCategoryEnum;
 import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
@@ -17,6 +21,8 @@ import com.yonge.cooleshow.biz.dal.service.CouponInfoService;
 import com.yonge.cooleshow.biz.dal.service.EmployeeService;
 import com.yonge.cooleshow.biz.dal.service.StudentService;
 import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
 import com.yonge.cooleshow.biz.dal.service.UserFirstTimeService;
 import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.coupon.CouponOrderWrapper;
@@ -24,12 +30,13 @@ import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.UserFirstTimeTypeEnum;
 import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.joda.time.DateTime;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.jwt.Jwt;
@@ -46,12 +53,13 @@ import java.math.BigDecimal;
 import java.security.interfaces.RSAPublicKey;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
+@Slf4j
 @RestController
 @RequestMapping("/open/adminClient")
 public class AdminClient extends BaseController {
-    private final static Logger log = LoggerFactory.getLogger(UserOrderClient.class);
 
     @Autowired
     private UserFirstTimeService userFirstTimeService;
@@ -68,6 +76,12 @@ public class AdminClient extends BaseController {
     @Autowired
     private CouponInfoService couponInfoService;
 
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
     @GetMapping("/recordTime")
     public HttpResponseResult<Boolean> recordTime(
             @RequestParam("userId") Long userId,
@@ -132,6 +146,40 @@ public class AdminClient extends BaseController {
         return succeed(employeeApi);
     }
 
+    @ApiOperation(value = "机构信息查询", notes = "tenantId -> 机构ID")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "tenantId", value = "机构ID", required = true, dataType = "Long", paramType = "query")
+    })
+    @GetMapping("/getTenant")
+    public HttpResponseResult<TenantWrapper.Tenant> getTenant(@RequestParam("tenantId") Long tenantId) {
+
+        TenantWrapper.Tenant build = TenantWrapper.Tenant.builder().build();
+
+        TenantInfo tenantInfo = tenantInfoService.getById(tenantId);
+        if (Objects.nonNull(tenantInfo)) {
+            build = TenantWrapper.Tenant.from(JSON.toJSONString(tenantInfo));
+        }
+
+        return succeed(build);
+    }
+
+    @ApiOperation(value = "机构员工信息查询", notes = "userId -> 机构用户ID")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "userId", value = "机构用户ID", required = true, dataType = "Long", paramType = "query")
+    })
+    @GetMapping("/getTenantStaff")
+    public HttpResponseResult<TenantWrapper.Staff> getTenantStaff(@RequestParam("userId") Long userId) {
+
+        // 默认返回值
+        TenantWrapper.Staff ret = TenantWrapper.Staff.builder().build();
+
+        TenantStaff staff = tenantStaffService.getByUserId(userId);
+        if (Objects.nonNull(staff)) {
+            ret = TenantWrapper.Staff.from(JSON.toJSONString(staff));
+        }
+        return succeed(ret);
+    }
+
     /**
      * 订单优惠券信息
      * @return HttpResponseResult<CouponOrderVO.CouponPageInfo>

+ 5 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/StudentSearch.java

@@ -10,7 +10,9 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import org.springframework.format.annotation.DateTimeFormat;
 
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
 import java.util.Optional;
 
 /**
@@ -69,6 +71,9 @@ public class StudentSearch extends QueryInfo{
     @ApiModelProperty("机构名称")
     private String tenantName;
 
+    @ApiModelProperty(value = "手机号码列表", hidden = true)
+    private List<String> phoneList = new ArrayList<>();
+
     @ApiModelProperty(value = "排序方式",hidden = true)
     private String orderBy;
 

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

@@ -71,7 +71,7 @@ public class SysUser implements Serializable {
     @TableField("qq_openid_")
     private String qqOpenid;
 
-    @ApiModelProperty("用户类型(STUDENT/TEACHER/SYSTEM)")
+    @ApiModelProperty("用户类型(STUDENT/TEACHER/SYSTEM/ORGANIZATION)")
     @TableField("user_type_")
     private String userType;
 

+ 3 - 4
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/TenantStaff.java

@@ -3,11 +3,10 @@ package com.yonge.cooleshow.biz.dal.entity;
 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 lombok.Data;
-
+import com.yonge.cooleshow.common.enums.UserLockFlag;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
 import java.io.Serializable;
 import java.util.Date;
@@ -68,7 +67,7 @@ public class TenantStaff implements Serializable {
 
     @ApiModelProperty("帐号状态(注销,冻结,激活)") 
 	@TableField(value = "status_")
-    private String status;
+    private UserLockFlag status;
 
     @ApiModelProperty("更新时间") 
 	@TableField(value = "update_time_")

+ 1 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/ClientEnum.java

@@ -15,6 +15,7 @@ public enum ClientEnum implements BaseEnum<String, ClientEnum> {
     TENANT_STUDENT("机构-学生端"),
     SYSTEM("平台端"),
     WEBSITE("官网"),
+    TENANT("机构"),
 
     ;
     @EnumValue

+ 1 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/GoodTypeEnum.java

@@ -16,6 +16,7 @@ public enum GoodTypeEnum implements BaseEnum<String, GoodTypeEnum> {
     VIDEO("视频课购买"),
     MUSIC("单曲点播"),
     ALBUM("专辑购买"),
+    TENANT_ALBUM("机构专辑"),
     PIANO_ROOM("琴房时长"),
     ACTI_REGIST("活动报名")
     ;

+ 14 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/TenantInfoMapper.java

@@ -37,13 +37,25 @@ public interface TenantInfoMapper extends BaseMapper<TenantInfo> {
 	 * 冻结
 	 * @param id
 	 */
-	Boolean updateFlag(@Param("id") Integer id);
+	Boolean updateFlag(@Param("id") long id);
 
-	Boolean updateMethod(@Param("id") Integer id);
+	Boolean updateMethod(@Param("id") long id);
 
 	Boolean insertInfo(@Param("param") TenantInfo tenantInfo);
 
 	List<Integer> queryTeacherCounts(@Param("listId") List<Integer> listId);
 
 	List<Integer> queryStudentCounts(@Param("listId") List<Integer> listId);
+
+	List<TenantInfoWrapper.TenantInfo> selectApplyPage(@Param("page") IPage<TenantInfoWrapper.TenantInfo> page, @Param("param") TenantInfoWrapper.TenantInfoQuery query);
+
+	List<TenantInfoWrapper.TenantInfo> selectHistoryPage(@Param("page") IPage<TenantInfoWrapper.TenantInfo> page, @Param("id") long id);
+
+	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);
 }

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

@@ -8,10 +8,12 @@ import com.yonge.cooleshow.biz.dal.dto.SaveOrUpdateRewardDto;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.dto.search.ActivityPlanSearch;
 import com.yonge.cooleshow.biz.dal.entity.ActivityPlan;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.vo.ActivityPlanVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicActivityVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.ActivityShareEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
@@ -121,4 +123,10 @@ public interface ActivityPlanService extends IService<ActivityPlan>  {
 	 * @return
 	 */
 	YesOrNoEnum state(Long activityId);
+
+    /**
+     * 活动报名下单
+     *
+     */
+    void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }

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

@@ -24,7 +24,7 @@ public interface CacheKey {
     // 用户下单/付款/取消订单锁
     String PAYMENT_ORDER_LOCK = "paymentorder:{}";
     // 用户下单请求
-    String EXECUTE_ORDER_LOCK = "executeorder:{}";
+    String EXECUTE_ORDER_LOCK = "LOCK_EXECUTE_ORDER:{}";
     // 用户支付配置
     String USER_PAYMENT_CONFIG = "paymentconfig:{}:{}";
     // 用户下单配置

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

@@ -14,6 +14,7 @@ import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.vo.*;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
 import com.yonge.cooleshow.biz.dal.vo.res.RefundCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.base.page.PageInfo;
 import org.redisson.api.RMap;
@@ -349,5 +350,11 @@ public interface CourseGroupService extends IService<CourseGroup> {
      * @param dto
      */
     void updateLiveCourse(LiveCourseGroupDto dto);
+
+    /**
+     * 直播课购买前校验
+     *
+     */
+    void buyLiveCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }
 

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

@@ -10,8 +10,10 @@ import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
 import com.yonge.cooleshow.biz.dal.entity.CourseCalendarEntity;
 import com.yonge.cooleshow.biz.dal.entity.CourseSchedule;
 import com.yonge.cooleshow.biz.dal.entity.TeacherSubjectPrice;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.vo.*;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.page.PageInfo;
@@ -257,5 +259,11 @@ public interface CourseScheduleService extends IService<CourseSchedule> {
     PageInfo<CourseScheduleRecordVo> selectCourseList(Map<String, Object> param);
 
     IPage<PianoClassVo> queryPianoClass(IPage<PianoClassVo> page, MyCourseSearch search);
+
+    /**
+     * 购买陪练课
+     *
+     */
+    void buyPracticeCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }
 

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

@@ -6,6 +6,7 @@ import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dto.VipSubmitReq;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.entity.ActivityReward;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.vo.MemberPriceSettingsVo;
 import com.yonge.cooleshow.biz.dal.dto.search.MemberPriceSettingsSearch;
@@ -14,6 +15,7 @@ import com.yonge.cooleshow.biz.dal.vo.MemberPriceVo;
 import com.yonge.cooleshow.biz.dal.vo.ShareProfitVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 
 import java.util.List;
@@ -95,4 +97,10 @@ public interface MemberPriceSettingsService extends IService<MemberPriceSettings
      * @return
      */
     MemberPriceVo getVipShare(MemberPriceSettingsSearch query);
+
+    /**
+     * 订单创建前校验
+     *
+     */
+    void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }

+ 17 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetService.java

@@ -16,6 +16,7 @@ import com.yonge.cooleshow.biz.dal.dto.search.StudentMusicSheetSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.TeacherMusicSheetAuditSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.TeacherMusicSheetSearch;
 import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.OrderTypeEnum;
 import com.yonge.cooleshow.biz.dal.vo.HomeMusicSheetVo;
@@ -31,6 +32,7 @@ import com.yonge.cooleshow.biz.dal.vo.TeacherMusicSheetVo;
 import com.yonge.cooleshow.biz.dal.vo.TeacherTotalVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.utils.easyexcel.ExcelDataReaderProperty;
 
@@ -362,4 +364,19 @@ public interface MusicSheetService extends IService<MusicSheet> {
      * 添加上架曲目的虚拟数
      */
     void setVirtualNumber();
+
+    /**
+     * 购买曲目专辑
+     *
+     * @param orderGoodsInfo
+     * @return
+     */
+    void buyMusicSheetCheck(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
+
+
+    /**
+     * 购买曲目专辑
+     *
+     */
+    void orderAfterSheet(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }

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

@@ -3,11 +3,13 @@ package com.yonge.cooleshow.biz.dal.service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.vo.PianoRoomBuyRecordVo;
 import com.yonge.cooleshow.biz.dal.dto.search.PianoRoomBuyRecordSearch;
 import com.yonge.cooleshow.biz.dal.entity.PianoRoomBuyRecord;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 
 /**
@@ -44,4 +46,10 @@ public interface PianoRoomBuyRecordService extends IService<PianoRoomBuyRecord>
 	 * @return
 	 */
 	void orderSuccess(UserOrderDetailVo orderDetailVo);
+
+    /**
+     * 琴房课程购买
+     *
+     */
+    void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }

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

@@ -14,6 +14,7 @@ import com.yonge.cooleshow.biz.dal.vo.StudentVo;
 import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
 import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.utils.easyexcel.ExcelDataReaderProperty;
 
 import java.util.List;
 import java.util.Map;
@@ -112,4 +113,11 @@ public interface StudentService extends IService<Student> {
      * @param studentInfo 学生信息
      */
     Boolean save(StudentWrapper.Student studentInfo);
+
+    /**
+     * 导入学生
+     * @param dataList 数据列表
+     * @param id 操作人
+     */
+    void importStudentExcel(List<ExcelDataReaderProperty<StudentWrapper.StudentExport>> dataList, Long id);
 }

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

@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumRefWrapper;
 import com.yonge.cooleshow.biz.dal.entity.TenantAlbumRef;
 
+import java.util.List;
+
 /**
  * 机构专辑关联表
  * 2023-07-21 17:32:49
@@ -39,5 +41,12 @@ public interface TenantAlbumRefService extends IService<TenantAlbumRef>  {
      * @return Boolean
      */
      Boolean update(TenantAlbumRefWrapper.TenantAlbumRef tenantAlbumRef);
-     
+
+    /**
+     * 根据专辑ID获取专辑关联
+     *
+     * @param tenantAlbumId 专辑ID
+     * @return
+     */
+    List<TenantAlbumRef> getByAlbumId(Long tenantAlbumId);
 }

+ 16 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumService.java

@@ -2,8 +2,10 @@ package com.yonge.cooleshow.biz.dal.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.entity.TenantAlbum;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 
 /**
  * 机构专辑
@@ -39,5 +41,18 @@ public interface TenantAlbumService extends IService<TenantAlbum>  {
      * @return Boolean
      */
      Boolean update(TenantAlbumWrapper.TenantAlbum tenantAlbum);
-     
+
+    /**
+     * 订单创建前检测
+     *
+     * @param orderGoodsInfo
+     */
+    void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
+
+    /**
+     * 订单完成后
+     *
+     * @param userOrderDetailVo
+     */
+    void orderSuccess(UserOrderDetailVo userOrderDetailVo);
 }

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

@@ -53,5 +53,40 @@ public interface TenantInfoService extends IService<TenantInfo>  {
 
     HttpResponseResult<Boolean> submit(TenantInfoWrapper.TenantInfoQuery query);
 
+    /**
+     * 冻结
+     * @param query
+     * @return
+     */
     Boolean state(TenantInfoWrapper.TenantInfoQuery query);
+
+
+
+    /**
+     * 机构申请分页查询
+     * @param query
+     * @return
+     */
+    IPage<TenantInfoWrapper.TenantInfo> applyPage(IPage<TenantInfoWrapper.TenantInfo> page, TenantInfoWrapper.TenantInfoQuery query);
+
+    /**
+     * 机构入驻审核历史记录查询
+     * @param query
+     * @return
+     */
+    IPage<TenantInfoWrapper.TenantInfo> historyPage(IPage<TenantInfoWrapper.TenantInfo> page, TenantInfoWrapper.TenantInfoQuery query);
+
+    /**
+     * 机构入驻审核本次提交查询
+     * @param query
+     * @return
+     */
+    TenantInfoWrapper.TenantInfo queryNow(TenantInfoWrapper.TenantInfoQuery query);
+
+    /**
+     * 机构审核
+     * @param query
+     * @return
+     */
+    Boolean entry(TenantInfoWrapper.TenantInfoQuery query);
 }

+ 14 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantStaffService.java

@@ -2,8 +2,8 @@ package com.yonge.cooleshow.biz.dal.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.yonge.cooleshow.biz.dal.wrapper.TenantStaffWrapper;
 import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantStaffWrapper;
 
 /**
  * 机构员工表
@@ -40,5 +40,18 @@ public interface TenantStaffService extends IService<TenantStaff>  {
      */
      Boolean update(TenantStaffWrapper.TenantStaff tenantStaff);
 
+    /**
+     * 获取机构用户
+     *
+     * @param phone
+     * @return
+     */
     TenantStaff getByPhone(String phone);
+
+    /**
+     * 根据用户ID获取员工信息
+     * @param userId 用户Id
+     * @return TenantStaff
+     */
+    TenantStaff getByUserId(Long userId);
 }

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

@@ -14,6 +14,7 @@ import com.yonge.cooleshow.biz.dal.vo.res.OrderPayRes;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.payment.base.model.callback.PaymentCallBack;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.util.Date;
@@ -121,6 +122,8 @@ public interface UserOrderService extends IService<UserOrder> {
      */
     HttpResponseResult<Boolean> orderCancel(OrderPayReq payReq);
 
+    String getGoodUrlByType(GoodTypeEnum goodTypeEnum);
+
     /***
      * 取消订单(未判断付款单状态)
      * @author liweifan
@@ -167,6 +170,13 @@ public interface UserOrderService extends IService<UserOrder> {
     Boolean setOrderStatus(UserOrder param);
 
     /**
+     * 取消订单后续处理
+     *
+     * @param userOrder
+     */
+    void payCancel(UserOrderVo userOrder);
+
+    /**
      * 订单完成
      *
      * @param detail
@@ -174,6 +184,13 @@ public interface UserOrderService extends IService<UserOrder> {
     void orderSuccess(UserOrderVo detail, PaymentCallBack data);
 
 
+    /**
+     * 支付成功后续处理
+     *
+     * @param detail
+     */
+    void paySuccess(UserOrderVo detail);
+
     Date getAccountPeriodTime(UserOrderDetailVo orderDetailVo);
 
     /**

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

@@ -1,10 +1,12 @@
 package com.yonge.cooleshow.biz.dal.service;
 
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.entity.VideoLessonPurchaseRecord;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 
 /**
@@ -20,4 +22,10 @@ public interface VideoLessonPurchaseRecordService extends IService<VideoLessonPu
     void buyVideoCourseSuccess(UserOrderDetailVo orderParam);
 
     void buyVideoCourseFailed(UserOrderDetailVo orderParam);
+
+    /**
+     * 购买视频课程
+     *
+     */
+    void buyVideoCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }

+ 52 - 18
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ActivityPlanServiceImpl.java

@@ -19,29 +19,13 @@ import com.yonge.cooleshow.biz.dal.dto.SaveOrUpdateRewardDto;
 import com.yonge.cooleshow.biz.dal.dto.activity.ActivityTeacherQuery;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.dto.search.ActivityPlanSearch;
-import com.yonge.cooleshow.biz.dal.entity.ActivityEvaluation;
-import com.yonge.cooleshow.biz.dal.entity.ActivityEvaluationRecord;
-import com.yonge.cooleshow.biz.dal.entity.ActivityPlan;
-import com.yonge.cooleshow.biz.dal.entity.ActivityPlanReward;
-import com.yonge.cooleshow.biz.dal.entity.ActivityRegistration;
-import com.yonge.cooleshow.biz.dal.entity.ActivityReward;
-import com.yonge.cooleshow.biz.dal.entity.Student;
-import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.EQueryOp;
 import com.yonge.cooleshow.biz.dal.enums.MK;
 import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.activity.ActivityRankingMethodEnum;
-import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationRecordService;
-import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationService;
-import com.yonge.cooleshow.biz.dal.service.ActivityPlanEvaluationService;
-import com.yonge.cooleshow.biz.dal.service.ActivityPlanRewardService;
-import com.yonge.cooleshow.biz.dal.service.ActivityPlanService;
-import com.yonge.cooleshow.biz.dal.service.ActivityPlanStandardService;
-import com.yonge.cooleshow.biz.dal.service.ActivityRegistrationService;
-import com.yonge.cooleshow.biz.dal.service.ActivityRewardService;
-import com.yonge.cooleshow.biz.dal.service.SubjectService;
-import com.yonge.cooleshow.biz.dal.service.SysMessageService;
+import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.vo.ActivityMusicVo;
 import com.yonge.cooleshow.biz.dal.vo.ActivityPlanVo;
 import com.yonge.cooleshow.biz.dal.vo.ActivityRankingVo;
@@ -50,6 +34,7 @@ import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.activity.ActivityTeacherWrapper;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
 import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.ActivityResourceEnum;
 import com.yonge.cooleshow.common.enums.ActivityShareEnum;
@@ -129,6 +114,9 @@ public class ActivityPlanServiceImpl extends ServiceImpl<ActivityPlanDao, Activi
     @Autowired
     private SubjectService subjectService;
 
+    @Autowired
+    private UserOrderService userOrderService;
+
     //保存/更新拓展字段
     private static final Map<ActivityTypeEnum, Consumer<ActivityPlanDto>> saveOrUpdateExpand = new HashMap<>();
     //开始活动(活动刚开始触发)
@@ -953,6 +941,52 @@ public class ActivityPlanServiceImpl extends ServiceImpl<ActivityPlanDao, Activi
     }
 
     /**
+     * 活动报名下单
+     *
+     * @param orderGoodsInfo
+     */
+    @Override
+    public void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+
+        log.info("活动购买 参数 --> {}", JSON.toJSONString(orderGoodsInfo));
+
+        // 检查用户
+        getSysUser(orderGoodsInfo.getUserId());
+        ActivityPlanPayDto activityPlanPayDto = JSON.parseObject(
+                JSON.toJSONString(orderGoodsInfo.getBizContent()), ActivityPlanPayDto.class);
+
+        // 检查活动购买是否已购买
+        checkActivityPay(activityPlanPayDto.getActivityId());
+
+
+        if (checkoutJoinActivity(activityPlanPayDto.getActivityId(), orderGoodsInfo.getUserId())) {
+            throw new BizException("您已经参与了活动");
+        }
+
+
+        OrderCreateRes orderCreateRes = new OrderCreateRes();
+        if (activityPlanPayDto.getActivityId() == null) {
+            throw new BizException("活动id不能为空");
+        }
+        ActivityPlan activityPlan = getById(activityPlanPayDto.getActivityId());
+
+
+
+        UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
+
+        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
+        userOrderDetail.setMerchId(0L);
+        userOrderDetail.setBizId(activityPlanPayDto.getActivityId());
+        userOrderDetail.setGoodNum(1);
+        userOrderDetail.setOriginalPrice(activityPlan.getRegistrationPrice());
+        userOrderDetail.setCouponAmount(BigDecimal.ZERO);
+        userOrderDetail.setExpectPrice(activityPlan.getRegistrationPrice());
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(userOrderDetail.getCouponAmount()));
+
+        orderGoodsInfo.setUserOrderDetail(userOrderDetail);
+    }
+
+    /**
      * 参与活动消息
      */
     private void sendMessage(String activityName, Long userId) {

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

@@ -22,6 +22,7 @@ import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.support.WrapperUtil;
 import com.yonge.cooleshow.biz.dal.vo.*;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.coupon.CouponOrderWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
@@ -341,6 +342,56 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         coursePlanService.saveOrUpdateBatch(planList);
     }
 
+    @Override
+    public void buyLiveCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        log.info("buyLiveCourse  param:{}", JSON.toJSONString(orderGoodsInfo));
+        Map<String, Object> param = WrapperUtil.toMap(orderGoodsInfo.getBizContent());
+        Long groupId = WrapperUtil.toLong(param, "groupId", "课程组id不能为空!");
+        Long studentId = orderGoodsInfo.getUserId();
+        //校验学生信息
+        getSysUser(studentId);
+        //课程组信息
+        CourseGroup courseGroup = this.getOne(Wrappers.<CourseGroup>lambdaQuery()
+                .eq(CourseGroup::getId, groupId)
+                .eq(CourseGroup::getType, CourseScheduleEnum.LIVE.getCode())
+        );
+        if (Objects.isNull(courseGroup)) {
+            throw new BizException("课程组不存在!");
+        }
+        //只要不是销售中的课程组都提示无法购买
+        if (!courseGroup.getStatus().equals(CourseGroupEnum.APPLY.getCode())) {
+            throw new BizException("课程已结束销售!");
+        }
+        //课程信息
+        List<CourseSchedule> courseList = courseScheduleService.list(Wrappers.<CourseSchedule>lambdaQuery()
+                .eq(CourseSchedule::getCourseGroupId, groupId));
+        if (CollectionUtils.isEmpty(courseList)) {
+            throw new BizException("课程组课程不存在!");
+        }
+        //校验购买的课程组每节课时间是否和自己的课时冲突
+        batchCheckStudentCourseTime(studentId, courseList, CourseSchedule::getStartTime, CourseSchedule::getEndTime);
+
+        // TODO 写入学生购买课程记录 换到订单写入成功后写入
+        buyLiveCourseAfter(orderGoodsInfo.getOrderNo(), studentId, courseList, courseGroup,courseGroup.getCoursePrice());
+
+
+        UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
+
+        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
+        userOrderDetail.setMerchId(courseGroup.getTeacherId());
+        userOrderDetail.setBizId(courseGroup.getId());
+        userOrderDetail.setBizContent(orderGoodsInfo.getBizContent());
+        userOrderDetail.setGoodNum(orderGoodsInfo.getGoodNum());
+        userOrderDetail.setOriginalPrice(courseGroup.getCoursePrice());
+        userOrderDetail.setCouponAmount(BigDecimal.ZERO);
+        userOrderDetail.setExpectPrice(courseGroup.getCoursePrice());
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(userOrderDetail.getCouponAmount()));
+
+        log.info("buyLiveCourse  return {}", userOrderDetail);
+
+        orderGoodsInfo.setUserOrderDetail(userOrderDetail);
+    }
+
     /**
      * 取消课程组-下架课程组
      *

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

@@ -22,6 +22,7 @@ import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.*;
 import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.enums.PostStatusEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.payment.util.DistributedLock;
@@ -2469,4 +2470,127 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         monthToDate(search);
         return page.setRecords(baseMapper.queryPianoClass(page, search));
     }
+
+    @Override
+    public void buyPracticeCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        ObjectMapper objectMapper = new ObjectMapper();
+        PracticeScheduleDto scheduleDto = objectMapper.convertValue(orderGoodsInfo.getBizContent(), PracticeScheduleDto.class);
+
+        RLock lock = redissonClient.getLock("teacherId:" + scheduleDto.getTeacherId());
+        try {
+            if (lock.tryLock(10, 60, TimeUnit.SECONDS)) {
+                orderGoodsInfo.setUserOrderDetail( buyPracticeCourseTranV2(orderGoodsInfo));
+            }
+        } catch (InterruptedException e) {
+            throw new BizException("创建陪练课失败:{}", e.getMessage());
+        } finally {
+            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
+                lock.unlock();
+            }
+        }
+        throw  new BizException("创建陪练课失败");
+
+    }
+
+    private UserOrderDetail buyPracticeCourseTranV2(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        log.info("buyPracticeCourse  param:{}", JSON.toJSONString(orderGoodsInfo));
+        Long studentId = orderGoodsInfo.getUserId();
+
+        //校验学生信息
+        getSysUser(studentId);
+
+        ObjectMapper objectMapper = new ObjectMapper();
+        PracticeScheduleDto scheduleDto = objectMapper.convertValue(orderGoodsInfo.getBizContent(), PracticeScheduleDto.class);
+        List<CourseScheduleDate> dateList = scheduleDto.getClassTime();
+        Integer courseNum = scheduleDto.getCourseNum();//课程数
+
+        //校验课时数
+        if (dateList.size() != courseNum) {
+            throw new BizException("课程数与课时数不符");
+        }
+        BigDecimal price = baseMapper.selectPrice(scheduleDto.getTeacherId(), scheduleDto.getSubjectId());//老师设置声部价格
+        BigDecimal decimal = new BigDecimal(courseNum);//选购课程节数
+        BigDecimal multiply = price.multiply(decimal);//预计总价
+
+        //获取老师锁课缓存
+        RMap<Long, List<CourseTimeEntity>> map = courseGroupService.getExpireLiveLockTimeCache(scheduleDto.getTeacherId());
+        if (map.isExists()) {
+            List<CourseTimeEntity> courseTimeCache = map.get(scheduleDto.getTeacherId());
+            //校验缓存中的时间和当前自动生成的时间有没有重复
+            dateList.forEach(item ->
+            {
+                if (checkCourseTime(courseTimeCache, CourseTimeEntity::getStartTime, CourseTimeEntity::getEndTime, item.getStartTime(), item.getEndTime())) {
+                    throw new BizException("与缓存中时间存在中途");
+                }
+            });
+        }
+
+        //批量检查老师课时在数据库是否重复
+        batchCheckTeacherCourseTime(scheduleDto.getTeacherId(), dateList, CourseScheduleDate::getStartTime, CourseScheduleDate::getEndTime);
+        //批量检查学生课时在数据库是否重复
+        batchCheckStudentCourseTime(studentId, dateList, CourseScheduleDate::getStartTime, CourseScheduleDate::getEndTime);
+
+        // TODO 换在订单前处理
+        String orderNo = orderGoodsInfo.getOrderNo();
+        scheduleDto.setType(CourseScheduleEnum.PRACTICE.getCode());
+        scheduleDto.setStatus(CourseGroupEnum.NOT_SALE.getCode());
+        scheduleDto.setMixStudentNum(1);
+        scheduleDto.setStudentId(studentId);
+
+        //写入course_group
+        baseMapper.addCourseGroup(scheduleDto);
+        Long groupId = scheduleDto.getGroupId();
+
+        //根据老师id获取默认配置声部原价
+        TeacherSubjectPrice teacherSubjectPrice = teacherFreeTimeDao.selectSubjectPrice(scheduleDto.getTeacherId(), scheduleDto.getSubjectId());
+        BigDecimal subjectPrice = teacherSubjectPrice.getSubjectPrice();
+
+        //每课实际价格
+        Map<Integer, BigDecimal> courseAveragePrice = WrapperUtil.getAveragePrice(scheduleDto.getCourseNum(), multiply);
+
+        List<CourseScheduleDate> classTime = scheduleDto.getClassTime();
+        for (int i = 0; i < classTime.size(); i++) {
+            CourseScheduleDate date = classTime.get(i);
+            CourseSchedule schedule = new CourseSchedule();
+            schedule.setClassDate(date.getClassDate());
+            schedule.setStartTime(date.getStartTime());
+            schedule.setEndTime(date.getEndTime());
+            schedule.setCourseGroupId(groupId);
+            schedule.setType(CourseScheduleEnum.PRACTICE.getCode());
+            schedule.classNum(i + 1);
+            schedule.setTeacherId(scheduleDto.getTeacherId());
+            schedule.setLock(1);
+            schedule.setStatus(CourseScheduleEnum.NOT_START.getCode());
+            schedule.setCreatedBy(scheduleDto.getStudentId());
+            //写入course_schedule
+            baseMapper.insert(schedule);
+
+            Long scheduleId = schedule.getId();
+            CourseScheduleStudentPayment payment = new CourseScheduleStudentPayment();
+            payment.setUserId(scheduleDto.getStudentId());
+            payment.setCourseId(scheduleId);
+            payment.setCourseGroupId(groupId);
+            payment.setCourseType(CourseScheduleEnum.PRACTICE.getCode());
+            payment.setOrderNo(orderNo);
+            payment.setOriginalPrice(subjectPrice);//原价
+            payment.setExpectPrice(subjectPrice);//预计价格
+            payment.setActualPrice(courseAveragePrice.get(i + 1));//实际价格
+            //写入course_schedule_student_payment
+            courseScheduleStudentPaymentService.save(payment);
+        }
+
+        UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
+
+        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
+        userOrderDetail.setMerchId(scheduleDto.getTeacherId());
+        userOrderDetail.setBizId(groupId);
+        userOrderDetail.setGoodNum(scheduleDto.getCourseNum());
+        userOrderDetail.setOriginalPrice(multiply);
+        userOrderDetail.setCouponAmount(BigDecimal.ZERO);
+        userOrderDetail.setExpectPrice(multiply);
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(userOrderDetail.getCouponAmount()));
+
+        log.info("buyPracticeCourse  return {}", userOrderDetail);
+        return userOrderDetail;
+    }
 }

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

@@ -1,5 +1,6 @@
 package com.yonge.cooleshow.biz.dal.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.client.SysUserFeignService;
@@ -22,6 +23,7 @@ import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.*;
 
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.ActivityShareEnum;
@@ -63,6 +65,9 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
     @Autowired
     private ActivityPlanService activityPlanService;
 
+    @Autowired
+    private UserOrderService userOrderService;
+
     @Override
     public MemberPriceSettingsVo detail(Long id) {
         return baseMapper.detail(id);
@@ -245,6 +250,38 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
         return memberPriceVo;
     }
 
+    @Override
+    public void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        MemberPriceSettingsVo detail = detail(Long.parseLong(orderGoodsInfo.getBizContent()));
+        if (null == detail) {
+            throw new BizException("未找到会员卡信息");
+        }
+        BigDecimal couponAmount = BigDecimal.ZERO;
+        ActivityPlanVo activityPlanVo = activityPlanService.detail(orderGoodsInfo.getActivityId());
+
+        if (activityPlanVo != null && activityPlanVo.getActivityState() == 1) {
+            for (ActivityPlanRewardDto activityPlanRewardDto : activityPlanVo.getActivityRewardList()) {
+                if (activityPlanRewardDto.getActivityReward().getUnit().getCode().equals(detail.getPeriod().getCode())) {
+                    couponAmount = activityPlanRewardDto.getActivityReward().getDiscountPrice();
+                    break;
+                }
+            }
+        }
+
+        UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(detail), UserOrderDetail.class);
+
+        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
+        userOrderDetail.setMerchId(0l);
+        userOrderDetail.setBizId(detail.getId());
+        userOrderDetail.setBizContent("会员卡购买-" + detail.getPeriod().getMsg());
+        userOrderDetail.setGoodNum(1);
+        userOrderDetail.setOriginalPrice(detail.getOriginalPrice());
+        userOrderDetail.setCouponAmount(couponAmount);
+        userOrderDetail.setExpectPrice(detail.getSalePrice());
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(couponAmount));
+        orderGoodsInfo.setUserOrderDetail(userOrderDetail);
+    }
+
     private void sendAddVipMessage(Long userId, ClientEnum client, Integer times, PeriodEnum type, String reason) {
         try {
             SysUser user = sysUserFeignService.queryUserById(userId);

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

@@ -57,6 +57,7 @@ import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
 import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.ActivityShareEnum;
@@ -1553,6 +1554,101 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
         this.updateBatchById(musicSheets,100);
     }
 
+    /**
+     * 购买曲目专辑
+     *
+     * @param orderGoodsInfo
+     * @return
+     */
+    @Override
+    public void buyMusicSheetCheck(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+
+        // 下单前的验证
+        getSysUser(orderGoodsInfo.getUserId());
+
+        MusicSheetPayDto musicSheetPayDto = JSON.parseObject(
+                JSON.toJSONString(orderGoodsInfo.getBizContent()), MusicSheetPayDto.class);
+
+
+        UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
+
+        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
+
+
+        switch (orderGoodsInfo.getGoodType()) {
+            case MUSIC: // 单曲
+            {
+                MusicSheet musicSheet = this.getById(musicSheetPayDto.getMusicSheetId());
+                if (musicSheet == null) {
+                    throw new BizException("不存在曲目信息");
+                }
+
+                if (!musicSheet.getSourceType().getCode().equals(SourceTypeEnum.PLATFORM.getCode())) {
+                    userOrderDetail.setMerchId(musicSheet.getUserId());
+                }
+
+
+                userOrderDetail.setBizId(musicSheet.getId());
+                userOrderDetail.setOriginalPrice(musicSheet.getMusicPrice());
+                userOrderDetail.setExpectPrice(musicSheet.getMusicPrice());
+            }
+            break;
+            case ALBUM: // 专辑
+            {
+                MusicAlbum album = musicAlbumMapper.selectById(musicSheetPayDto.getMusicSheetId());
+
+                if (Objects.isNull(album)) {
+                    throw new BizException("无效的专辑信息");
+                }
+
+                userOrderDetail.setMerchId(0L);
+                userOrderDetail.setBizId(album.getId());
+                userOrderDetail.setOriginalPrice(BigDecimal.valueOf(album.getAlbumPrice()));
+                userOrderDetail.setExpectPrice(BigDecimal.valueOf(album.getAlbumPrice()));
+            }
+            break;
+            default:
+                break;
+        }
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(userOrderDetail.getCouponAmount()));
+
+        // 检查已经购买,抛出已购买异常
+        checkoutPay(orderGoodsInfo.getUserId(), musicSheetPayDto.getMusicSheetId(), musicSheetPayDto.getClientType(),
+                PurchaseRecordTypeEnum.valueOf(orderGoodsInfo.getGoodType().getCode()));
+
+        orderGoodsInfo.setUserOrderDetail(userOrderDetail);
+    }
+
+
+    /**
+     * 购买曲目专辑
+     *
+     * @param orderGoodsInfo
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void orderAfterSheet(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        // 保存购买记录
+        MusicSheetPurchaseRecord musicSheetPurchaseRecord = musicSheetPurchaseRecordService.checkPurchase(
+                orderGoodsInfo.getUserId(),
+                orderGoodsInfo.getBizId(),
+                orderGoodsInfo.getPaymentClient(),
+                PurchaseRecordTypeEnum.valueOf(orderGoodsInfo.getGoodType().getCode()));
+        if (musicSheetPurchaseRecord == null) {
+            musicSheetPurchaseRecord = new MusicSheetPurchaseRecord();
+        }
+        musicSheetPurchaseRecord.setClientType(orderGoodsInfo.getPaymentClient());
+        musicSheetPurchaseRecord.setMusicSheetId(orderGoodsInfo.getBizId());
+        musicSheetPurchaseRecord.setOrderNo(orderGoodsInfo.getOrderNo());
+        musicSheetPurchaseRecord.setTeacherId(orderGoodsInfo.getUserOrderDetail().getMerchId());
+        musicSheetPurchaseRecord.setOriginalPrice(orderGoodsInfo.getUserOrderDetail().getOriginalPrice());
+        musicSheetPurchaseRecord.setOrderStatus(OrderStatusEnum.WAIT_PAY);
+        musicSheetPurchaseRecord.setStudentId(orderGoodsInfo.getUserId());
+        musicSheetPurchaseRecord.setPurchaseType(PurchaseRecordTypeEnum.valueOf(orderGoodsInfo.getGoodType().getCode()));
+
+        musicSheetPurchaseRecordService.saveOrUpdate(musicSheetPurchaseRecord);
+    }
+
     @Override
     public Boolean updateMusicImg(MusicImgDto musicImgDto, Long musicSheetId) {
         MusicSheet musicSheet = new MusicSheet();

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

@@ -1,33 +1,33 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
-import com.yonge.cooleshow.biz.dal.entity.PianoRoomChangeRecord;
-import com.yonge.cooleshow.biz.dal.entity.PianoRoomTime;
-import com.yonge.cooleshow.biz.dal.entity.PlatformCashAccountRecord;
-import com.yonge.cooleshow.biz.dal.entity.UserOrder;
+import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.AccountBizTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.InOrOutEnum;
 import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.vo.*;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.CacheNameEnum;
 import com.yonge.cooleshow.common.enums.PostStatusEnum;
+import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.payment.util.DistributedLock;
 import org.redisson.api.RedissonClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import com.yonge.cooleshow.biz.dal.entity.PianoRoomBuyRecord;
 import com.yonge.cooleshow.biz.dal.dto.search.PianoRoomBuyRecordSearch;
 import com.yonge.cooleshow.biz.dal.dao.PianoRoomBuyRecordDao;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.math.BigDecimal;
 import java.util.Date;
 
 
@@ -47,6 +47,9 @@ public class PianoRoomBuyRecordServiceImpl extends ServiceImpl<PianoRoomBuyRecor
     private RedissonClient redissonClient;
 
     @Autowired
+    private UserOrderService userOrderService;
+
+    @Autowired
     private PianoRoomChangeRecordService pianoRoomChangeRecordService;
 
     @Override
@@ -119,4 +122,32 @@ public class PianoRoomBuyRecordServiceImpl extends ServiceImpl<PianoRoomBuyRecor
                         }, null, 10l);
     }
 
+    /**
+     * 琴房课程购买
+     *
+     * @param orderGoodsInfo
+     */
+    @Override
+    public void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        PianoRoomSettingsVo detail = pianoRoomSettingsService.detail(Long.parseLong(orderGoodsInfo.getBizContent()));
+        if (null == detail) {
+           throw new BizException("未找到时长包");
+        }
+
+
+        UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
+
+        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
+        userOrderDetail.setMerchId(0L);
+        userOrderDetail.setBizId(detail.getId());
+        userOrderDetail.setGoodNum(1);
+        userOrderDetail.setOriginalPrice(detail.getOriginalPrice());
+        userOrderDetail.setBizContent("琴房时长包购买-" + detail.getTimes() + "分");
+        userOrderDetail.setCouponAmount(BigDecimal.ZERO);
+        userOrderDetail.setExpectPrice(detail.getSalePrice());
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(userOrderDetail.getCouponAmount()));
+
+        orderGoodsInfo.setUserOrderDetail(userOrderDetail);
+    }
+
 }

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

@@ -6,8 +6,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
 import com.microsvc.toolkit.common.webportal.exception.BizException;
-import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dao.StudentDao;
 import com.yonge.cooleshow.biz.dal.dao.SubjectDao;
@@ -15,10 +15,20 @@ 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.*;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.StudentTotal;
+import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+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.*;
+import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.StudentTotalService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.service.UserTenantAlbumRecordService;
 import com.yonge.cooleshow.biz.dal.vo.MyFollow;
 import com.yonge.cooleshow.biz.dal.vo.StudentHomeVo;
 import com.yonge.cooleshow.biz.dal.vo.StudentVo;
@@ -30,7 +40,9 @@ import com.yonge.cooleshow.common.enums.CacheNameEnum;
 import com.yonge.cooleshow.common.enums.UserLockFlag;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
 import com.yonge.toolset.utils.date.DateUtil;
+import com.yonge.toolset.utils.easyexcel.ExcelDataReaderProperty;
 import com.yonge.toolset.utils.string.ValueUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.redisson.api.RMap;
@@ -46,6 +58,7 @@ import java.text.MessageFormat;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 
 @Service
@@ -120,12 +133,15 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
         studentHomeVo.setMusicSheetNum(null == total.getMusicSheetNum() ? 0 : total.getMusicSheetNum());
 
         // IM聊天用户ID
-        studentHomeVo.setImUserId(MessageFormat.format("{0}:{1}", String.valueOf(detail.getUserId()), ClientEnum.STUDENT.name()));
+        studentHomeVo.setImUserId(MessageFormat.format("{0}:{1}", String.valueOf(detail.getUserId()),
+                ClientEnum.STUDENT.name()));
 
         // 判断是否是机构学生 机构学生 检测机构专辑购买记录
         TenantInfo tenantInfo = tenantInfoService.detail(detail.getTenantId());
         if (tenantInfo != null) {
-            UserTenantAlbumRecord record = userTenantAlbumRecordService.getNewestByTenantIdAndUserId(tenantInfo.getId(), detail.getUserId(), ClientEnum.STUDENT);
+            UserTenantAlbumRecord record =
+                    userTenantAlbumRecordService.getNewestByTenantIdAndUserId(tenantInfo.getId(), detail.getUserId(),
+                            ClientEnum.STUDENT);
             if (record == null || record.getEndTime().getTime() < System.currentTimeMillis()) {
                 studentHomeVo.setTenantAlbumFlag(YesOrNoEnum.NO);
             } else {
@@ -353,6 +369,57 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
         }
     }
 
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void importStudentExcel(List<ExcelDataReaderProperty<StudentWrapper.StudentExport>> dataList, Long id) {
+        if (dataList.isEmpty()) {
+            throw new BizException("导入数据不能为空");
+        }
+        dataList.sort(Comparator.comparingInt(ExcelDataReaderProperty::getRowIndex));
+
+        // 校验数据的完整性
+        List<String> errMsg = new ArrayList<>();
+        Map<String, Integer> phoneMap = new HashMap<>();
+        for (ExcelDataReaderProperty<StudentWrapper.StudentExport> next : dataList) {
+            Integer rowIndex = next.getRowIndex();
+            StudentWrapper.StudentExport student = next.getClazz();
+
+            student.checkValid().forEach(err -> errMsg.add(String.format("第%s行%s", rowIndex, err)));
+
+            if (phoneMap.containsKey(student.getPhone().trim())) {
+                errMsg.add(String.format("第%s行手机号重复", rowIndex));
+            } else {
+                phoneMap.put(student.getPhone().trim(), rowIndex);
+            }
+
+            if (errMsg.size() > 100) {
+                break;
+            }
+        }
+
+        int row = 100;
+        int page = 1;
+        List<List<String>> phonePartition = Lists.partition(new ArrayList<>(phoneMap.keySet()), row);
+
+        StudentSearch studentSearch = new StudentSearch();
+        studentSearch.setRows(row);
+        studentSearch.setPage(page);
+        for (List<String> phones : phonePartition) {
+            studentSearch.setPhoneList(phones);
+            List<StudentVo> studentVos = baseMapper.selectPage(PageUtil.getPage(studentSearch), studentSearch);
+            page++;
+
+            if (!studentVos.isEmpty()) {
+                List<String> existPhoneList = studentVos.stream().map(StudentVo::getPhone).collect(Collectors.toList());
+                existPhoneList.forEach(phone -> errMsg.add(String.format("第%s行手机号已经注册学生", phoneMap.get(phone))));
+            }
+        }
+
+        if (!errMsg.isEmpty()) {
+            throw new BizException(String.join(",", errMsg));
+        }
+    }
+
     private Boolean updateStudent(StudentWrapper.Student studentInfo) {
         StudentVo student = detail(studentInfo.getId());
         if (student == null) {
@@ -425,7 +492,7 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
             sysUser.setUserType("STUDENT");
             sysUser.setBirthdate(studentInfo.getBirthdate());
 
-            String newPassword = MessageFormat.format("klx{0}", studentInfo.getPhone().substring(7));
+            String newPassword = MessageFormat.format("klxjg{0}", studentInfo.getPhone().substring(7));
             String password = new BCryptPasswordEncoder().encode(newPassword);
             sysUser.setPassword(password);
             sysUserMapper.insert(sysUser);

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

@@ -9,20 +9,23 @@ 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;
 import com.yonge.cooleshow.biz.dal.mapper.TenantActivationCodeMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumPurchaseMapper;
+import com.yonge.cooleshow.biz.dal.mapper.UserTenantAlbumRecordMapper;
 import com.yonge.cooleshow.biz.dal.service.TenantActivationCodeService;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantActivationCodeWrapper;
 import com.yonge.toolset.base.exception.BizException;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.CollectionUtils;
-import org.redisson.api.RLock;
-import org.redisson.api.RedissonClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -45,6 +48,9 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
     @Autowired
     private TenantAlbumPurchaseMapper tenantAlbumPurchaseMapper;
 
+    @Autowired
+    private UserTenantAlbumRecordMapper userTenantAlbumRecordMapper;
+
     /**
      * 查询详情
      *
@@ -165,11 +171,13 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
             throw new BizException("激活码已经被使用");
         }
 
+        SysUser sysUser = sysUserMapper.selectById(studentId);
         // 通过状态和ID同时判断更新是否存在竞争
         boolean update = this.lambdaUpdate()
                 .set(TenantActivationCode::getActivationStatus, true)
                 .set(TenantActivationCode::getActivationUserId, student.getUserId())
                 .set(TenantActivationCode::getActivationTime, new Date())
+                .set(TenantActivationCode::getActivationPhone, sysUser.getPhone())
                 .eq(TenantActivationCode::getId, code.getId())
                 .eq(TenantActivationCode::getActivationStatus, false)
                 .update();
@@ -177,7 +185,50 @@ public class TenantActivationCodeServiceImpl extends ServiceImpl<TenantActivatio
             throw new BizException("激活码已经被使用");
         }
 
-        // todo 更新会员信息,如果更新异常,回滚激活码
+        QueryWrapper<UserTenantAlbumRecord> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda()
+                .eq(UserTenantAlbumRecord::getTenantId, student.getTenantId())
+                .eq(UserTenantAlbumRecord::getUserId, student.getUserId())
+                .eq(UserTenantAlbumRecord::getTenantAlbumId, code.getTenantAlbumId())
+                .eq(UserTenantAlbumRecord::getClientType, ClientEnum.STUDENT)
+                .orderByDesc(UserTenantAlbumRecord::getEndTime);
+        List<UserTenantAlbumRecord> userTenantAlbumRecords = userTenantAlbumRecordMapper.selectList(queryWrapper);
+
+        UserTenantAlbumRecord userTenantAlbumRecord = new UserTenantAlbumRecord();
+        userTenantAlbumRecord.setTenantId(student.getTenantId());
+        userTenantAlbumRecord.setUserId(student.getUserId());
+        userTenantAlbumRecord.setTenantAlbumId(code.getTenantAlbumId());
+        userTenantAlbumRecord.setOrderNo("");
+        userTenantAlbumRecord.setSourceType(SourceTypeEnum.TENANT);
+        userTenantAlbumRecord.setClientType(ClientEnum.STUDENT);
+        userTenantAlbumRecord.setSubOrderNo("");
+        userTenantAlbumRecord.setCreateBy(student.getUserId());
+
+        Long tenantAlbumPurchaseId = code.getTenantAlbumPurchaseId();
+        TenantAlbumPurchase purchase = tenantAlbumPurchaseMapper.selectById(tenantAlbumPurchaseId);
+        Integer purchaseCycle = purchase.getPurchaseCycle();
+
+        userTenantAlbumRecord.setType("MONTH");
+        userTenantAlbumRecord.setTimes(purchaseCycle);
+
+        Calendar instance = Calendar.getInstance();
+        if (userTenantAlbumRecords.isEmpty()) {
+            instance.setTime(new Date());
+        } else {
+            // 如果最后一次的时间的小于当前时间,则以当前时间为会员的开始时间
+            // 如果最后一次的时间的大于当前时间,则以最后一次的结束时间为记录的开始时间,相当会员续期
+            UserTenantAlbumRecord lastRecord = userTenantAlbumRecords.get(0);
+            Date lastEndTime = lastRecord.getEndTime();
+            if (lastEndTime.before(new Date())) {
+                instance.setTime(new Date());
+            } else {
+                instance.setTime(lastEndTime);
+            }
+        }
+        userTenantAlbumRecord.setStartTime(instance.getTime());
+        instance.add(Calendar.MONTH, purchaseCycle);
+        userTenantAlbumRecord.setEndTime(instance.getTime());
+        userTenantAlbumRecordMapper.insert(userTenantAlbumRecord);
 
         // 更新购买记录中激活码使用统计数量值
         Integer activeCodeNumber = this.lambdaQuery()

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

@@ -11,6 +11,8 @@ import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumRefWrapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumRefMapper;
 import com.yonge.cooleshow.biz.dal.service.TenantAlbumRefService;
 
+import java.util.List;
+
 /**
  * 机构专辑关联表
  * 2023-07-21 17:32:49
@@ -63,4 +65,17 @@ public class TenantAlbumRefServiceImpl extends ServiceImpl<TenantAlbumRefMapper,
 
         return this.updateById(JSON.parseObject(tenantAlbumRef.jsonString(), TenantAlbumRef.class));       
     }
+
+    /**
+     * 根据专辑ID获取专辑关联
+     *
+     * @param tenantAlbumId 专辑ID
+     * @return
+     */
+    @Override
+    public List<TenantAlbumRef> getByAlbumId(Long tenantAlbumId) {
+        return this.lambdaQuery()
+                .eq(TenantAlbumRef::getTenantAlbumId, tenantAlbumId)
+                .list();
+    }
 }

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

@@ -3,13 +3,23 @@ package com.yonge.cooleshow.biz.dal.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.biz.dal.entity.*;
+import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import com.yonge.toolset.base.exception.BizException;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.beans.BeanUtils;
 import lombok.extern.slf4j.Slf4j;
-import com.yonge.cooleshow.biz.dal.entity.TenantAlbum;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMapper;
-import com.yonge.cooleshow.biz.dal.service.TenantAlbumService;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * 机构专辑
@@ -19,12 +29,27 @@ import com.yonge.cooleshow.biz.dal.service.TenantAlbumService;
 @Service
 public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, TenantAlbum> implements TenantAlbumService {
 
-	/**
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    @Autowired
+    private TenantAlbumRefService tenantAlbumRefService;
+
+    @Autowired
+    private UserOrderService userOrderService;
+
+    /**
      * 查询详情
      * @param id 详情ID
      * @return TenantAlbum
      */
-	@Override
+    @Override
     public TenantAlbum detail(Long id) {
         
         return baseMapper.selectById(id);
@@ -41,15 +66,15 @@ public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, Tenan
         
         return page.setRecords(baseMapper.selectPage(page, query));
     }
-	
+
     /**
      * 添加
      * @param tenantAlbum TenantAlbumWrapper.TenantAlbum
      * @return Boolean
      */
     @Override
-    public Boolean add(TenantAlbumWrapper.TenantAlbum tenantAlbum) {    	
-        
+    public Boolean add(TenantAlbumWrapper.TenantAlbum tenantAlbum) {
+
         return this.save(JSON.parseObject(tenantAlbum.jsonString(), TenantAlbum.class));
     }
 
@@ -63,4 +88,116 @@ public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, Tenan
 
         return this.updateById(JSON.parseObject(tenantAlbum.jsonString(), TenantAlbum.class));       
     }
+
+    /**
+     * 订单创建前检测
+     *
+     * @param orderGoodsInfo
+     */
+    @Override
+    public void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        log.info("订单创建前检测");
+        if (orderGoodsInfo == null) {
+            log.error("订单创建前检测,订单商品信息为空");
+            throw new BizException("订单商品信息为空");
+        }
+
+        TenantAlbumWrapper.TenantAlbumBuy tenantAlbumBuy = JSON
+                .parseObject(JSON.toJSONString(orderGoodsInfo.getBizContent()), TenantAlbumWrapper.TenantAlbumBuy.class);
+        if (tenantAlbumBuy == null) {
+            log.error("订单创建前检测,订单商品信息为空");
+            throw new BizException("订单商品信息为空");
+        }
+
+
+        // 专辑是否存在
+        TenantAlbum tenantAlbum = this.getById(orderGoodsInfo.getBizId());
+        if (tenantAlbum == null || tenantAlbum.getDelFlag() || Boolean.FALSE.equals(tenantAlbum.getStatus())) {
+            log.error("订单创建前检测,专辑不存在,bizId={}", orderGoodsInfo.getBizId());
+            throw new BizException("订单商品信息为空");
+        }
+
+        // 查询专辑所在机构
+        List<TenantAlbumRef> refList =
+                tenantAlbumRefService.getByAlbumId(tenantAlbum.getId());
+        if (CollectionUtils.isEmpty(refList)) {
+            log.error("订单创建前检测,专辑不在机构下,bizId={}", orderGoodsInfo.getBizId());
+            throw new BizException("用户不在当前机构");
+        }
+
+        // 机构ID集合
+        List<Long> tenantIdList =
+                refList.stream().map(TenantAlbumRef::getTenantId).collect(Collectors.toList());
+
+        UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
+
+        BigDecimal price = BigDecimal.ZERO;
+        // 学生购买机构专辑
+        switch (orderGoodsInfo.getPaymentClient()) {
+            case STUDENT: {
+                // 判断学生是否在当前专辑机构下
+                Student student = studentService.getById(orderGoodsInfo.getUserId());
+                if (student == null) {
+                    log.error("订单创建前检测,学生不存在,userId={}", orderGoodsInfo.getUserId());
+                    throw new BizException("用户信息未找到");
+                }
+                TenantInfo tenantInfo = tenantInfoService.detail(student.getTenantId());
+                if (tenantInfo == null || !tenantIdList.contains(tenantInfo.getId())) {
+                    log.error("订单创建前检测,学生不在当前机构下,userId={},tenantId={}", orderGoodsInfo.getUserId(), student.getTenantId());
+                    throw new BizException("用户不在当前机构");
+                }
+                price = tenantAlbum.getSalePrice();
+                userOrderDetail.setMerchId(tenantInfo.getId());
+                tenantAlbumBuy.setBuyCycle(1);
+                tenantAlbumBuy.setBuyNumber(1);
+                break;
+            }
+
+            case TENANT: {
+                // 专辑是否在机构下
+                TenantStaff tenantStaff = tenantStaffService.getByUserId(orderGoodsInfo.getUserId());
+                if (tenantStaff == null) {
+                    log.error("订单创建前检测,机构员工不存在,userId={}", orderGoodsInfo.getUserId());
+                    throw new BizException("用户信息未找到");
+                }
+                if (!tenantIdList.contains(tenantStaff.getTenantId())) {
+                    log.error("订单创建前检测,专辑不在机构下,userId={},tenantId={}", orderGoodsInfo.getUserId(), tenantStaff.getTenantId());
+                    throw new BizException("用户不在当前机构");
+                }
+                price = tenantAlbum.getOriginalPrice();
+                userOrderDetail.setMerchId(0L);
+                break;
+            }
+        }
+
+
+
+        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
+        userOrderDetail.setBizId(tenantAlbum.getId());
+        userOrderDetail.setGoodNum(orderGoodsInfo.getGoodNum());
+        userOrderDetail.setOriginalPrice(price.multiply(new BigDecimal(orderGoodsInfo.getGoodNum()))
+                .multiply(new BigDecimal(tenantAlbumBuy.getBuyCycle())));
+        userOrderDetail.setCouponAmount(BigDecimal.ZERO);
+        userOrderDetail.setExpectPrice(userOrderDetail.getOriginalPrice());
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(userOrderDetail.getCouponAmount()));
+
+        orderGoodsInfo.setUserOrderDetail(userOrderDetail);
+
+    }
+
+    /**
+     * 订单完成后
+     *
+     * @param userOrderDetailVo
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void orderSuccess(UserOrderDetailVo userOrderDetailVo) {
+
+        // 学生 插入机构专辑购买数据
+
+
+        // 机构   插入机构专辑购买记录,生成机构专辑激活码
+
+    }
 }

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

@@ -1,24 +1,38 @@
 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.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.yonge.cooleshow.biz.dal.entity.SysArea;
+import com.yonge.cooleshow.biz.dal.entity.*;
+import com.yonge.cooleshow.biz.dal.mapper.*;
 import com.yonge.cooleshow.biz.dal.service.SysAreaService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper;
+import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.SysUserType;
+import com.yonge.cooleshow.common.enums.UserLockFlag;
 import com.yonge.toolset.base.exception.BizException;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.checkerframework.checker.units.qual.A;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.stereotype.Service;
-import org.springframework.beans.BeanUtils;
-import lombok.extern.slf4j.Slf4j;
-import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
-import com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper;
-import com.yonge.cooleshow.biz.dal.mapper.TenantInfoMapper;
-import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.*;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
@@ -34,30 +48,48 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
     @Autowired
     TenantInfoMapper tenantInfoMapper;
 
+    @Autowired
+    private SysUserMapper sysUserMapper;
 
+    @Autowired
+    private SysConfigService sysConfigService;
 
-	/**
+    @Autowired
+    private TenantStaffMapper tenantStaffMapper;
+
+    @Autowired
+    TenantEntryRecordMapper tenantEntryRecordMapper;
+
+    @Autowired
+    TenantApplyRecordMapper tenantApplyRecordMapper;
+
+
+
+    /**
      * 查询详情
+     *
      * @param id 详情ID
      * @return TenantInfo
      */
-	@Override
+    @Override
     public TenantInfo detail(Long id) {
         if (id == null || id == -1) {
             return null;
         }
-        
+
         return baseMapper.selectById(id);
     }
-    
+
     /**
      * 分页查询
-     * @param page IPage<TenantInfo>
+     *
+     * @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(IPage<TenantInfoWrapper.TenantInfo> page,
+                                                          TenantInfoWrapper.TenantInfoQuery query) {
 
         //分页查询
         List<TenantInfoWrapper.TenantInfo> tenantInfos = baseMapper.selectPage(page, query);
@@ -65,16 +97,16 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
         ArrayList<Integer> listId = new ArrayList<>();
         for (int i = 0; i < tenantInfos.size(); i++) {
             TenantInfoWrapper.TenantInfo info = tenantInfos.get(i);
-            Integer id = info.getId();
-            listId.add(i,id);
+            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 (!CollectionUtils.isEmpty(listId)) {
+            listTeacher = tenantInfoMapper.queryTeacherCounts(listId);
+            listStudent = tenantInfoMapper.queryStudentCounts(listId);
         }
 
 
@@ -90,39 +122,72 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
 
 
         //获取省市区信息
-        List<Integer> areaCodeList = tenantInfos.stream().map(next -> {
-            Set<Integer> codes = new HashSet<>();
-            codes.add(next.getCityCode());
-            codes.add(next.getProvinceCode());
-            codes.add(next.getRegionCode());
-            return codes;
-        }).flatMap(Collection::stream).filter(Objects::nonNull).distinct().collect(Collectors.toList());
-
-        Map<Integer, String> codeNameMap = new HashMap<>();
-
-        if (!CollectionUtils.isEmpty(areaCodeList)) {
-            List<SysArea> sysAreaList = sysAreaService.queryByCodes(areaCodeList);
-            codeNameMap = sysAreaList.stream().collect(Collectors.toMap(SysArea::getCode,
-                    SysArea::getName));
-        }
-
-        for (TenantInfoWrapper.TenantInfo next : tenantInfos) {
-            next.setProvinceName(codeNameMap.getOrDefault(next.getProvinceCode(), ""));
-            next.setCityName(codeNameMap.getOrDefault(next.getCityCode(), ""));
-            next.setRegionName(codeNameMap.getOrDefault(next.getRegionCode(), ""));
-        }
-        return page.setRecords(tenantInfos);
+        List<TenantInfoWrapper.TenantInfo> tenantList = queryArea(tenantInfos);
+        return page.setRecords(tenantList);
     }
 
+
     /**
      * 添加
+     *
      * @param tenantInfo TenantInfoWrapper.TenantInfo
      * @return Boolean
      */
     @Override
     public Boolean add(TenantInfo tenantInfo) {
-        Boolean bool = tenantInfoMapper.insertInfo(tenantInfo);
-        return bool;
+        SysUser sysUser = getOrCreateAccount(tenantInfo);
+
+        TenantStaff tenantStaff = new TenantStaff();
+        tenantStaff.setTenantId(tenantStaff.getTenantId());
+        tenantStaff.setUserId(sysUser.getId());
+        tenantStaff.setAvatar(sysUser.getAvatar());
+        tenantStaff.setNickname(tenantInfo.getUsername());
+        tenantStaff.setStatus(UserLockFlag.NORMAL);
+        tenantStaffMapper.insert(tenantStaff);
+
+        tenantInfo.setEnableFlag(true);
+        tenantInfoMapper.insert(tenantInfo);
+        return true;
+    }
+
+    private SysUser getOrCreateAccount(TenantInfo tenantInfo) {
+        QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
+        sysUserQueryWrapper.lambda().eq(SysUser::getPhone, tenantInfo.getPhone());
+        List<SysUser> sysUsers = sysUserMapper.selectList(sysUserQueryWrapper);
+        SysUser sysUser;
+        //若存在信息
+        if (!sysUsers.isEmpty()) {
+            sysUser = sysUsers.get(0);
+            TenantStaff tenantStaff = tenantStaffMapper.selectById(sysUser.getId());
+            if (tenantStaff != null) {
+                throw new BizException("手机号已经注册机构账号");
+            }
+            //获取当前账户的用户类型
+            String userType = sysUser.getUserType();
+            //设置默认机构类型
+            String tenantUserType = SysUserType.ORGANIZATION.getCode();
+            if (StringUtils.isEmpty(userType)) {
+                sysUser.setUserType(tenantUserType);
+            } else if (!userType.contains(tenantUserType)) {
+                sysUser.setUserType(userType + "," + tenantUserType);
+            }
+
+            //更新当前账号的用户名
+            sysUser.setUsername(tenantInfo.getUsername());
+
+            sysUserMapper.updateById(sysUser);
+        } else {
+            sysUser = new SysUser();
+            sysUser.setPhone(tenantInfo.getPhone());
+            sysUser.setAvatar(sysConfigService.findConfigValue(SysConfigConstant.DEFAULT_HEARD));
+            sysUser.setUserType(SysUserType.ORGANIZATION.getCode());
+
+            String newPassword = MessageFormat.format("klxjg{0}", tenantInfo.getPhone().substring(7));
+            String password = new BCryptPasswordEncoder().encode(newPassword);
+            sysUser.setPassword(password);
+            sysUserMapper.insert(sysUser);
+        }
+        return sysUser;
     }
 	
 
@@ -165,6 +230,7 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
 
     /**
      * 冻结
+     *
      * @param query TenantInfoWrapper.TenantInfo
      * @return Boolean
      */
@@ -172,44 +238,228 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoMapper, TenantI
     @Override
     public Boolean state(TenantInfoWrapper.TenantInfoQuery query) {
         Boolean flag;
-        Integer id = query.getId();
-        long longId = id.longValue();
-        TenantInfo info = detail(longId);
+        long id = query.getId();
+        TenantInfo info = detail(id);
 
         //TenantInfo info = this.getById(id);
         if (Objects.isNull(info)) {
             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 (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;
+        }
         return flag;
     }
 
+
     /**
      * 更新
+     *
      * @param info TenantInfoWrapper.TenantInfo
      * @return Boolean
      */
     @Override
     public Boolean updateTenantInfo(TenantInfo info) {
-        Boolean bool = tenantInfoMapper.updateInfo(info);
-        return bool;
+        //更新或创建sysUser
+        SysUser sysUser = getOrCreateAccount(info);
+
+        TenantInfo oldTenantInfo = this.getById(info.getId());
+        tenantStaffMapper.update(null, Wrappers.<TenantStaff>lambdaUpdate()
+                .set(TenantStaff::getUserId, sysUser.getId())
+                .set(TenantStaff::getNickname, info.getUsername())
+                .eq(TenantStaff::getUserId, oldTenantInfo.getUserId())
+        );
+
+        tenantInfoMapper.update(null, Wrappers.<TenantInfo>lambdaUpdate()
+                .set(TenantInfo::getName, info.getName())
+                .set(TenantInfo::getLogo, info.getLogo())
+                .set(TenantInfo::getBriefIntroduction, info.getBriefIntroduction())
+                .set(TenantInfo::getProvinceCode, info.getProvinceCode())
+                .set(TenantInfo::getCityCode, info.getCityCode())
+                .set(TenantInfo::getRegionCode, info.getRegionCode())
+                .eq(TenantInfo::getId, info.getId())
+        );
+        return true;
     }
 
 
+    /**
+     * 机构申请分页查询
+     *
+     * @param query
+     * @return
+     */
+    @Override
+    public IPage<TenantInfoWrapper.TenantInfo> applyPage(IPage<TenantInfoWrapper.TenantInfo> page,
+                                                         TenantInfoWrapper.TenantInfoQuery query) {
+        //分页查询
+        List<TenantInfoWrapper.TenantInfo> tenantInfos = baseMapper.selectApplyPage(page, query);
+        List<TenantInfoWrapper.TenantInfo> infos = queryArea(tenantInfos);
+        return page.setRecords(infos);
+    }
+
+
+    /**
+     * 机构入驻审核历史记录查询
+     *
+     * @param query
+     * @return
+     */
+    @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);
+    }
+
+    /**
+     * 机构入驻审核本次提交查询
+     *
+     * @param query
+     * @return
+     */
+    @Override
+    public TenantInfoWrapper.TenantInfo queryNow(TenantInfoWrapper.TenantInfoQuery query) {
+        //查询本次提交记录
+        TenantInfoWrapper.TenantInfo info = tenantInfoMapper.queryNow(query);
+        Set<Integer> codes = new HashSet<>();
+        codes.add(info.getCityCode());
+        codes.add(info.getProvinceCode());
+        codes.add(info.getRegionCode());
+
+        //将地区码转化为对应的地名
+        List<Integer> areaCodeList = new ArrayList<>();
+        areaCodeList.addAll(codes);
+
+        Map<Integer, String> codeNameMap = new HashMap<>();
+
+        if (!CollectionUtils.isEmpty(areaCodeList)) {
+            List<SysArea> sysAreaList = sysAreaService.queryByCodes(areaCodeList);
+            codeNameMap = sysAreaList.stream().collect(Collectors.toMap(SysArea::getCode,
+                    SysArea::getName));
+        }
+
+        info.setProvinceName(codeNameMap.get(info.getProvinceCode()));
+        info.setCityName(codeNameMap.get(info.getCityCode()));
+        info.setRegionName(codeNameMap.get(info.getRegionCode()));
+        return info;
+    }
+
+    @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);
+
+
+        } 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;
+    }
+
+
+    /**
+     * 匹配地区码与省市区
+     *
+     * @param tenantInfos
+     * @return
+     */
+    private List<TenantInfoWrapper.TenantInfo> queryArea(List<TenantInfoWrapper.TenantInfo> tenantInfos) {
+        List<Integer> areaCodeList = tenantInfos.stream().map(next -> {
+            Set<Integer> codes = new HashSet<>();
+            codes.add(next.getCityCode());
+            codes.add(next.getProvinceCode());
+            codes.add(next.getRegionCode());
+            return codes;
+        }).flatMap(Collection::stream).filter(Objects::nonNull).distinct().collect(Collectors.toList());
+
+        Map<Integer, String> codeNameMap = new HashMap<>();
+
+        if (!CollectionUtils.isEmpty(areaCodeList)) {
+            List<SysArea> sysAreaList = sysAreaService.queryByCodes(areaCodeList);
+            codeNameMap = sysAreaList.stream().collect(Collectors.toMap(SysArea::getCode,
+                    SysArea::getName));
+        }
+
+        for (TenantInfoWrapper.TenantInfo next : tenantInfos) {
+            next.setProvinceName(codeNameMap.getOrDefault(next.getProvinceCode(), ""));
+            next.setCityName(codeNameMap.getOrDefault(next.getCityCode(), ""));
+            next.setRegionName(codeNameMap.getOrDefault(next.getRegionCode(), ""));
+        }
+
+        return tenantInfos;
+    }
+
 }

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

@@ -3,13 +3,12 @@ package com.yonge.cooleshow.biz.dal.service.impl;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import org.springframework.stereotype.Service;
-import org.springframework.beans.BeanUtils;
-import lombok.extern.slf4j.Slf4j;
 import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
-import com.yonge.cooleshow.biz.dal.wrapper.TenantStaffWrapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantStaffMapper;
 import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantStaffWrapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
 
 /**
  * 机构员工表
@@ -69,4 +68,16 @@ public class TenantStaffServiceImpl extends ServiceImpl<TenantStaffMapper, Tenan
         return baseMapper.getByPhone(phone);
 
     }
+
+    /**
+     * 根据用户ID获取员工信息
+     *
+     * @param userId 用户Id
+     * @return TenantStaff
+     */
+    @Override
+    public TenantStaff getByUserId(Long userId) {
+
+        return lambdaQuery().eq(TenantStaff::getUserId, userId).last("LIMIT 1").one();
+    }
 }

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

@@ -24,23 +24,7 @@ import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.coupon.CouponCategoryEnum;
 import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
 import com.yonge.cooleshow.biz.dal.queryInfo.CouponInfoQuery;
-import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationRecordService;
-import com.yonge.cooleshow.biz.dal.service.ActivityPlanService;
-import com.yonge.cooleshow.biz.dal.service.ActivityRegistrationService;
-import com.yonge.cooleshow.biz.dal.service.ActivityUserRewardService;
-import com.yonge.cooleshow.biz.dal.service.CouponInfoService;
-import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
-import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
-import com.yonge.cooleshow.biz.dal.service.MemberPriceSettingsService;
-import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
-import com.yonge.cooleshow.biz.dal.service.PianoRoomBuyRecordService;
-import com.yonge.cooleshow.biz.dal.service.PlatformCashAccountRecordService;
-import com.yonge.cooleshow.biz.dal.service.SysConfigService;
-import com.yonge.cooleshow.biz.dal.service.UserAccountService;
-import com.yonge.cooleshow.biz.dal.service.UserOrderDetailService;
-import com.yonge.cooleshow.biz.dal.service.UserOrderPaymentService;
-import com.yonge.cooleshow.biz.dal.service.UserOrderService;
-import com.yonge.cooleshow.biz.dal.service.VideoLessonPurchaseRecordService;
+import com.yonge.cooleshow.biz.dal.service.*;
 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;
@@ -139,6 +123,9 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
     @Autowired
     private CouponInfoService couponInfoService;
 
+    @Autowired
+    private TenantAlbumService tenantAlbumService;
+
     //验证订单是否可以下单,获取订单金额信息
     private static final Map<GoodTypeEnum, Function<OrderReq.OrderReqInfo, HttpResponseResult<OrderCreateRes>>> orderCreate = new HashMap<>();
     //插入订单后执行
@@ -192,6 +179,9 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
         //活动报名
         orderSuccess.put(GoodTypeEnum.ACTI_REGIST, activityPlanService::orderSuccess);
 
+        //机构专辑购买
+        orderSuccess.put(GoodTypeEnum.TENANT_ALBUM, tenantAlbumService::orderSuccess);
+
         /**********订单取消后******************/
         //陪练课购买
         orderCancel.put(GoodTypeEnum.PRACTICE, scheduleService::buyPracticeCourseFailed);
@@ -770,7 +760,8 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
      * @updateTime 2022/3/31 16:49
      * @return: java.math.BigDecimal
      */
-    private String getGoodUrlByType(GoodTypeEnum goodTypeEnum) {
+    @Override
+    public String getGoodUrlByType(GoodTypeEnum goodTypeEnum) {
         String configValue = "";
         if (GoodTypeEnum.VIP.equals(goodTypeEnum)) {
             configValue = sysConfigService.findConfigValue(SysConfigConstant.GOOD_LOGO_VIP);
@@ -821,6 +812,27 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
             return;
         }
 
+        payCancel(userOrder);
+        userOrder.setReason(reason);
+        userOrder.setStatus(orderStatus);
+        userOrder.setUpdateTime(new Date());
+        baseMapper.updateById(userOrder);
+
+        // 重置优惠券状态
+        couponInfoService.updateUserOrderCouponInfo(CouponOrderWrapper.builder()
+                        .orderNo(userOrder.getOrderNo())
+                        .reset(true)
+                .build());
+    }
+
+    /**
+     * 取消订单后续处理
+     *
+     * @param userOrder
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void payCancel(UserOrderVo userOrder) {
         List<UserOrderDetailVo> orderDetailList = orderDetailService.getOrderDetilListByOrderNo(userOrder.getOrderNo());
         for (UserOrderDetailVo orderDetailVo : orderDetailList) {
             orderDetailVo.setUserId(userOrder.getUserId());
@@ -832,16 +844,6 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
                 userOrderVoConsumer.accept(orderDetailVo);
             }
         }
-        userOrder.setReason(reason);
-        userOrder.setStatus(orderStatus);
-        userOrder.setUpdateTime(new Date());
-        baseMapper.updateById(userOrder);
-
-        // 重置优惠券状态
-        couponInfoService.updateUserOrderCouponInfo(CouponOrderWrapper.builder()
-                        .orderNo(userOrder.getOrderNo())
-                        .reset(true)
-                .build());
     }
 
     private void orderSuccess(UserOrderVo detail) {
@@ -896,6 +898,17 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
             }
         }
 
+        paySuccess(detail);
+    }
+
+    /**
+     * 支付成功后续处理
+     *
+     * @param detail
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void paySuccess(UserOrderVo detail) {
         //调用业务
         List<UserOrderDetailVo> orderDetailList = orderDetailService.getOrderDetilListByOrderNo(detail.getOrderNo());
 
@@ -906,6 +919,7 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
             orderDetailVo.setActivityId(detail.getActivityId());
             orderDetailVo.setRewardId(detail.getRewardId());
             orderDetailVo.setOrderType(detail.getOrderType());
+            orderDetailVo.setOrderClient(detail.getOrderClient());
 
             //记录平台收入和用户分润收入(未记录卖家收益,卖家收益业务逻辑处理)
             savePlatformAccountRecord(orderDetailVo);

+ 168 - 55
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserPaymentCoreServiceImpl.java

@@ -18,15 +18,23 @@ import com.microsvc.toolkit.middleware.payment.common.api.entity.PaymentReq;
 import com.microsvc.toolkit.middleware.payment.common.api.entity.PaymentResp;
 import com.microsvc.toolkit.middleware.payment.common.api.enums.PaymentStatus;
 import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
+import com.yonge.cooleshow.biz.dal.enums.GoodTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponCategoryEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponInfoQuery;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.coupon.CouponOrderWrapper;
+import com.yonge.cooleshow.common.enums.CacheNameEnum;
 import com.yonge.cooleshow.common.enums.ContractTemplateTypeEnum;
 import com.yonge.cooleshow.common.enums.SysUserType;
-import com.yonge.cooleshow.common.enums.payment.EGoodsType;
 import com.yonge.cooleshow.common.enums.payment.EPaymentChannel;
 import com.yonge.cooleshow.common.enums.payment.EPaymentStatus;
 import com.yonge.cooleshow.common.enums.payment.EPaymentType;
+import com.yonge.cooleshow.common.service.IdGeneratorService;
+import com.yonge.toolset.payment.core.props.PaymentProperties;
+import com.yonge.toolset.payment.core.service.PaymentClient;
 import com.yonge.toolset.payment.util.DistributedLock;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.CollectionUtils;
@@ -78,32 +86,87 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
     @Autowired
     private UserOrderDetailService userOrderDetailService;
 
+    @Autowired
+    private UserOrderService userOrderService;
+
+    @Autowired
+    private MemberPriceSettingsService memberPriceSettingsService;
+
+    @Autowired
+    private CourseGroupService courseGroupService;
+    @Autowired
+    private CourseScheduleService scheduleService;
+    @Autowired
+    private VideoLessonPurchaseRecordService recordService;
+    @Autowired
+    private MusicSheetService musicSheetService;
+    @Autowired
+    private PianoRoomBuyRecordService pianoRoomBuyRecordService;
+
+
+    @Autowired
+    private ActivityPlanService activityPlanService;
+
+    @Autowired
+    private CouponInfoService couponInfoService;
+
+    @Autowired
+    private TenantAlbumService tenantAlbumService;
+
+
 
     // 订单商品参数校验,获取订单支付金额
-    private static final Map<EGoodsType, Consumer<UserOrderDetail>> orderGoodsCreate = Maps.newHashMap();
-    // 支付订单类型参数校验
-    private static final Map<EPaymentType, Consumer<UserPaymentOrderWrapper.UserPaymentOrder>> orderCreate = Maps.newHashMap();
+    private static final Map<GoodTypeEnum, Consumer<UserPaymentOrderWrapper.OrderGoodsInfo>> orderGoodsCreate = Maps.newHashMap();
+
+
     // 支付创建前,数据库存
     private static final Map<EPaymentType, Consumer<UserPaymentOrderWrapper.UserPaymentOrder>> orderSuccessBefore = Maps.newHashMap();
-    // 支付创建前,数据库存
-//    private static final Map<EPaymentType, Consumer<UserPaymentOrder>> executeSuccessBefore = Maps.newHashMap();
-    // 订单完成后执行
-    private static final Map<EPaymentType, Consumer<UserPaymentOrderWrapper.UserPaymentOrder>> paymentSuccess = Maps.newHashMap();
 
-    @PostConstruct
-    private void init() {
+    // 订单支付后
+    private static final Map<GoodTypeEnum, Consumer<UserPaymentOrderWrapper.OrderGoodsInfo>> orderSuccessAfter = Maps.newHashMap();
 
-        /*订单参数校验*/
 
-        /*支付订单类型参数校验*/
+    // 订单完成后执行
+    private static final Map<EPaymentType, Consumer<UserPaymentOrderWrapper.UserPaymentOrder>> paymentSuccess = Maps.newHashMap();
+
 
-        /*订单创建前处理流程*/
 
-        /*订单支付完成后执行*/
+    @PostConstruct
+    private void init() {
 
-        /*退款订单类型参数校验*/
+        /**********订单生成前 商品校验******************/
+        //vip开通缴费
+        orderGoodsCreate.put(GoodTypeEnum.VIP, memberPriceSettingsService::orderCreate);
+        //直播课程购买
+        orderGoodsCreate.put(GoodTypeEnum.LIVE, courseGroupService::buyLiveCourse);
+        //陪练课购买
+        orderGoodsCreate.put(GoodTypeEnum.PRACTICE, scheduleService::buyPracticeCourse);
+        //视频课购买
+        orderGoodsCreate.put(GoodTypeEnum.VIDEO, recordService::buyVideoCourse);
+        //曲目购买
+        orderGoodsCreate.put(GoodTypeEnum.MUSIC, musicSheetService::buyMusicSheetCheck);
+        // 专辑购买
+        orderGoodsCreate.put(GoodTypeEnum.ALBUM, musicSheetService::buyMusicSheetCheck);
+        //琴房时长
+        orderGoodsCreate.put(GoodTypeEnum.PIANO_ROOM, pianoRoomBuyRecordService::orderCreate);
+        //活动报名
+        orderGoodsCreate.put(GoodTypeEnum.ACTI_REGIST, activityPlanService::orderCreate);
+
+        // 机构专辑
+        orderGoodsCreate.put(GoodTypeEnum.TENANT_ALBUM, tenantAlbumService::orderCreate);
+
+        /**********订单生成后 数据处理******************/
+        //曲目购买
+        orderSuccessAfter.put(GoodTypeEnum.MUSIC, musicSheetService::orderAfterSheet);
+        // 专辑购买
+        orderSuccessAfter.put(GoodTypeEnum.ALBUM, musicSheetService::orderAfterSheet);
+
+        /**********订单完成后 数据处理******************/
+        // 沿用以前的流程
+
+        /**********订单取消后******************/
+        // 沿用以前的流程
 
-        /*退款支付完成执行*/
 
         log.info("---> orderCreate.Keys={}", orderGoodsCreate.keySet());
         log.info("---> paymentSuccess.Keys={}", paymentSuccess.keySet());
@@ -221,9 +284,7 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
         userPaymentOrderService.updateById(order);
 
         // 不同订单类型支付成功,后续数据同步流程
-        if (paymentSuccess.containsKey(paymentOrder.getOrderType())) {
-            paymentSuccess.get(paymentOrder.getOrderType()).accept(paymentOrder);
-        }
+        userOrderService.paySuccess(userOrderService.detail(order.getId()));
 
         // 生成协议
         try {
@@ -270,46 +331,47 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
                 UserPaymentOrderWrapper.UserPaymentOrder order = UserPaymentOrderWrapper.UserPaymentOrder
                     .builder()
                     .id(paymentOrder.getId())
-                    //.status(EPaymentStatus.CLOSED)
-                    //.errorMsg(errorMessage)
+                    .status(EPaymentStatus.CLOSED)
+//                    .errorMsg(errorMessage)
                     .updateTime(DateTime.now().toDate())
                     .build();
 
-                if (StringUtils.isBlank(paymentResp.getMsg())) {
 
-                    String errorMessage = null;
-                    try {
-                        // 关闭三方支付订单状态
-                        PaymentClose paymentClose = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVender())
-                            .close(paymentOrder.getTransNo(), "用户取消支付", paymentOrder.getOrderNo());
+                String errorMessage = null;
+                try {
+                    // 关闭三方支付订单状态
+                    PaymentClose paymentClose = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVender())
+                        .close(paymentOrder.getTransNo(), "用户取消支付", paymentOrder.getOrderNo());
 
-                        if (Objects.nonNull(paymentClose)) {
-                            errorMessage = paymentClose.getMsg();
+                    if (Objects.nonNull(paymentClose)) {
+                        errorMessage = paymentClose.getMsg();
 
-                            // 订单取消,三方返回异常信息
-                            if (StringUtils.isNotEmpty(errorMessage)) {
-                                log.warn("cancelPayment orderNo={}, ex={}", paymentOrder.getOrderNo(), errorMessage);
-                                // 记录异常消息
-                                ThreadPool.getExecutor().submit(() -> {
-                                    order.setErrorMsg(paymentClose.getMsg());
+                        // 订单取消,三方返回异常信息
+                        if (StringUtils.isNotEmpty(errorMessage)) {
+                            log.warn("cancelPayment orderNo={}, ex={}", paymentOrder.getOrderNo(), errorMessage);
+                            // 记录异常消息
+                            ThreadPool.getExecutor().submit(() -> {
+                                order.setErrorMsg(paymentClose.getMsg());
 
-                                    // 更新订单退款异常信息
-                                    userPaymentOrderService.updateById(order);
-                                });
-                                throw new BizException("查询交易中,请耐心等待!");
-                            }
+                                // 更新订单退款异常信息
+                                userPaymentOrderService.updateById(order);
+                            });
+                            throw new BizException("查询交易中,请耐心等待!");
                         }
-                    } catch (Exception e) {
-                        log.error("cancelPayment orderNo={}", paymentOrder.getOrderNo(), e);
-                        throw new BizException("查询交易中,请耐心等待!");
                     }
-
-                    order.status(EPaymentStatus.CLOSED).setErrorMsg(errorMessage);
+                } catch (Exception e) {
+                    log.error("cancelPayment orderNo={}", paymentOrder.getOrderNo(), e);
+                    throw new BizException("查询交易中,请耐心等待!");
                 }
 
+                order.status(EPaymentStatus.CLOSED).setErrorMsg(errorMessage);
+
                 // 更新订单关闭状态
                 userPaymentOrderService.updateById(order);
 
+                // 订单关闭后的数据处理流程
+                userOrderService.payCancel(userOrderService.detail(order.getId()));
+
             }
 
         }, 10L, TimeUnit.SECONDS);
@@ -321,17 +383,17 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
      * @param orderReq UserPaymentOrderWrapper.UserPaymentOrder
      */
     @Override
+    @Transactional
     public UserPaymentOrderWrapper.PaymentConfig executeOrderCreate(UserPaymentOrderWrapper.UserPaymentOrder orderReq) {
 
         try {
 
             // 商品校验 orderCreate
 
-
             // 用户下单请求锁
-            String lockName = redisCacheService.getExecuteOrderCacheKey(orderReq.getUserId().toString());
             // 生成用户支付订单
-            return DistributedLock.of(redissonClient).runIfLockToFunction(lockName, this::executeOrder, orderReq, 10L);
+            return DistributedLock.of(redissonClient).runIfLockToFunction(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(orderReq.getUserId()),
+                    this::executeOrder, orderReq, 10L);
 
         } catch (BizException e) {
             log.error("executeOrder BizException, orderReq={}",  orderReq.jsonString(), e);
@@ -361,35 +423,74 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
             .status(EPaymentStatus.WAIT_PAY)
             .originalPrice(BigDecimal.ZERO);
 
+        List<UserOrderDetail> orderDetails = new ArrayList<>();
+        // 订单优惠券信息
+        CouponOrderWrapper couponOrderWrapper = CouponOrderWrapper.builder()
+                .discountedPrices(0D)
+                .couponInfos(Lists.newArrayList())
+                .build();
         // 购买商品信息
-        for (UserOrderDetail item : orderReq.getGoodsInfos()) {
+        for (UserPaymentOrderWrapper.OrderGoodsInfo item : orderReq.getGoodsInfos()) {
 
+            // 数据赋值
             item.setOrderNo(orderReq.getOrderNo());
             item.setSubOrderNo(IdWorker.getIdStr());
+            item.setActivityId(orderReq.getActivityId());
+            item.setUserId(orderReq.getUserId());
+            item.setPaymentClient(orderReq.getPaymentClient());
 
+
+            BigDecimal couponAmount = BigDecimal.ZERO;
             // 商品基本信息
             if (orderGoodsCreate.containsKey(item.getGoodType())) {
                 // 填充商品基础信息,校验参数合法以性
                 orderGoodsCreate.get(item.getGoodType()).accept(item);
+                UserOrderDetail userOrderDetail = item.getUserOrderDetail();
+                orderDetails.add(userOrderDetail);
+                // 根据优惠券计算实际优惠金额
+                // 计算优惠券金额
+                {
+                    if (StringUtils.isNotEmpty(orderReq.getCouponIds())) {
+
+                        couponOrderWrapper = couponInfoService.queryUserOrderCouponInfo(orderReq.getUserId(),
+                                CouponInfoQuery.CouponOrderQuery.builder()
+                                        .clientType(orderReq.getPaymentClient())
+                                        .couponTypes(CouponCategoryEnum.getCategory(orderReq.getOrderType().getCode()))
+                                        .useState(CouponUseStateEnum.USABLE)
+                                        .timestamp(DateTime.now().getMillis())
+                                        .amount(userOrderDetail.getExpectPrice().doubleValue())
+                                        .build()
+                                        .issueIds(orderReq.getCouponIds()));
+                    }
+
+                    // 优惠券优惠金额,暂时为0
+                    couponAmount = couponAmount.add(BigDecimal.valueOf(couponOrderWrapper.getDiscountedPrices()));
+
+                    if (couponAmount.compareTo(userOrderDetail.getExpectPrice()) > 0) {
+                        couponAmount = userOrderDetail.getExpectPrice();
+                    }
+                    userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(couponAmount).setScale(2, RoundingMode.HALF_UP));
+                    userOrderDetail.setCouponAmount(couponAmount);
+                }
             }
+
         }
 
         // 计算原始价格
-        BigDecimal originalPrice = orderReq.getGoodsInfos().stream()
+        BigDecimal originalPrice = orderDetails.stream()
             .map(UserOrderDetail::getOriginalPrice)
             .reduce(BigDecimal.ZERO, BigDecimal::add);
 
         // 支付金额
-        BigDecimal currentPrice = orderReq.getGoodsInfos().stream()
+        BigDecimal currentPrice = orderDetails.stream()
             .map(UserOrderDetail::getExpectPrice)
             .reduce(BigDecimal.ZERO, BigDecimal::add);
 
         // 实际支付金额
-        BigDecimal cashAmount = orderReq.getGoodsInfos().stream()
+        BigDecimal cashAmount = orderDetails.stream()
             .map(UserOrderDetail::getActualPrice)
             .reduce(BigDecimal.ZERO, BigDecimal::add);
 
-        // 根据优惠券计算实际优惠金额
 
         orderReq.originalPrice(originalPrice.setScale(2, RoundingMode.HALF_UP))
             .currentPrice(currentPrice.setScale(2, RoundingMode.HALF_UP))
@@ -418,11 +519,23 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
         }
         userPaymentOrderService.save(orderReq);
 
-        userOrderDetailService.saveBatch(orderReq.getGoodsInfos());
+        userOrderDetailService.saveBatch(orderDetails);
+
+        // 入库后处理流程
+        for (UserPaymentOrderWrapper.OrderGoodsInfo item : orderReq.getGoodsInfos()) {
+            if (orderSuccessAfter.containsKey(item.getGoodType())) {
+                orderSuccessAfter.get(item.getGoodType()).accept(item);
+            }
+        }
 
         // 更新用户订单优惠券使用状态
+        if (CollectionUtils.isNotEmpty(couponOrderWrapper.getCouponInfos())) {
+
+            couponOrderWrapper.useType(CouponCategoryEnum.goodTypeTo(orderReq.getOrderType().getCode()));
+            couponInfoService.updateUserOrderCouponInfo(couponOrderWrapper.orderNo(orderReq.getOrderNo()));
+        }
 
-        String subject = orderReq.getGoodsInfos().stream()
+        String subject = orderDetails.stream()
             .map(UserOrderDetail::getGoodName).collect(Collectors.joining(","));
         // 返回订单支付配置参数
         UserPaymentOrderWrapper.PaymentOrderReqConfig reqConfig = UserPaymentOrderWrapper.PaymentOrderReqConfig

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

@@ -19,6 +19,7 @@ import com.yonge.cooleshow.biz.dal.enums.course.CourseRelationTypeEnum;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.course.CourseRelationWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
@@ -272,6 +273,65 @@ public class VideoLessonPurchaseRecordServiceImpl extends ServiceImpl<VideoLesso
     }
 
     /**
+     * 购买视频课程
+     *
+     * @param orderGoodsInfo
+     */
+    @Override
+    public void buyVideoCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        log.info("buyVideoCourse  param:{}", JSON.toJSONString(orderGoodsInfo));
+        Long studentId = orderGoodsInfo.getUserId();
+        String orderNo = orderGoodsInfo.getOrderNo();
+
+        //校验学生信息
+        getSysUser(studentId);
+
+        ObjectMapper objectMapper = new ObjectMapper();
+        VideoLessonPurchaseRecord purchaseRecord = objectMapper.convertValue(orderGoodsInfo.getBizContent(), VideoLessonPurchaseRecord.class);
+
+        //校验视频课信息
+        Long groupId = purchaseRecord.getVideoLessonGroupId();
+        VideoLessonGroup lessonGroup = videoLessonGroupDao.selectById(groupId);
+        if (lessonGroup == null) {
+            throw new BizException("课程组不存在!");
+        }
+
+        //校验课程是否购买
+        VideoLessonPurchaseRecord isAlreadyBuy = videoLessonPurchaseRecordDao.selectOne(Wrappers.<VideoLessonPurchaseRecord>lambdaQuery()
+                .eq(VideoLessonPurchaseRecord::getStudentId, studentId)
+                .eq(VideoLessonPurchaseRecord::getVideoLessonGroupId, groupId));
+        if (!ObjectUtil.isEmpty(isAlreadyBuy)) {
+            throw new BizException("已购买过该课程,或存在该课程未完成订单");
+        }
+
+        // TODO 购买记录放在订单生成后
+        purchaseRecord.setOrderNo(orderNo);
+        purchaseRecord.setStudentId(studentId);
+        purchaseRecord.setOrderStatus(OrderStatusEnum.WAIT_PAY.getCode());
+        purchaseRecord.setOriginalPrice(lessonGroup.getLessonPrice());//原价
+        purchaseRecord.setExpectPrice(lessonGroup.getLessonPrice());//预计价格
+        purchaseRecord.setPayMoney(lessonGroup.getLessonPrice());
+        videoLessonPurchaseRecordDao.insert(purchaseRecord);
+
+
+
+        UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
+
+        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
+        userOrderDetail.setMerchId(lessonGroup.getTeacherId());
+        userOrderDetail.setBizId(lessonGroup.getId());
+        userOrderDetail.setGoodNum(lessonGroup.getLessonCount());
+        userOrderDetail.setOriginalPrice(lessonGroup.getLessonPrice());
+        userOrderDetail.setCouponAmount(BigDecimal.ZERO);
+        userOrderDetail.setExpectPrice(lessonGroup.getLessonPrice());
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(userOrderDetail.getCouponAmount()));
+
+        log.info("buyVideoCourse  return {}", userOrderDetail);
+
+        orderGoodsInfo.setUserOrderDetail(userOrderDetail);
+    }
+
+    /**
      * 获取用户信息
      */
     private SysUser getSysUser(Long userId) {

+ 4 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/TeacherVo.java

@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
 import com.yonge.cooleshow.biz.dal.entity.Teacher;
 import com.yonge.cooleshow.biz.dal.entity.TeacherStyleVideo;
 import com.yonge.cooleshow.biz.dal.enums.GenderEnum;
+import com.yonge.cooleshow.common.enums.ESettlementFrom;
 import com.yonge.cooleshow.common.enums.UserLockFlag;
 import com.yonge.cooleshow.common.enums.UserStatusEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
@@ -89,6 +90,9 @@ public class TeacherVo extends Teacher {
     @ApiModelProperty("机构名称")
     private String tenantName;
 
+    @ApiModelProperty("结算方式,TEACHER:结算给老师,TENANT:结算给机构")
+    private ESettlementFrom settlementFrom;
+
 
     public YesOrNoEnum getDelFlag() {
         return delFlag;

+ 51 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/StudentWrapper.java

@@ -1,5 +1,6 @@
 package com.yonge.cooleshow.biz.dal.wrapper;
 
+import com.alibaba.excel.annotation.ExcelProperty;
 import com.yonge.cooleshow.biz.dal.entity.SysUser;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -7,9 +8,13 @@ import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
 
 import java.io.Serializable;
 import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
 
 /**
  * 学生封装类
@@ -86,7 +91,7 @@ public class StudentWrapper {
 
     @Data
     @ApiModel("学生基础信息")
-    public static class Student{
+    public static class Student {
 
         @ApiModelProperty("id")
         private Long id;
@@ -119,7 +124,7 @@ public class StudentWrapper {
 
     @Data
     @ApiModel("解绑机构")
-    public static class UnbindTenant{
+    public static class UnbindTenant {
 
         @ApiModelProperty("短信验证码")
         private String code;
@@ -127,4 +132,48 @@ public class StudentWrapper {
         @ApiModelProperty("解绑原因")
         private String unbindReason;
     }
+
+
+    @Data
+    @ApiModel("学生导入模板模型")
+    public static class StudentExport {
+
+        @ExcelProperty(value = "学生姓名")
+        private String userName;
+
+        @ExcelProperty(value = "手机号码")
+        private String phone;
+
+        @ExcelProperty(value = "声部")
+        private String subjectId;
+
+        @ExcelProperty(value = "出生日期")
+        private String birthday;
+
+        @ExcelProperty(value = "性别")
+        private String gender;
+
+        public List<String> checkValid() {
+            ArrayList<String> errMsg = new ArrayList<>();
+            if (StringUtils.isEmpty(userName)) {
+                errMsg.add("姓名为空");
+            }
+            if (StringUtils.isEmpty(phone)) {
+                errMsg.add("手机号为空");
+            }
+            if (Pattern.matches("^1[3-9]\\d{9}$", phone)) {
+                errMsg.add("手机号格式错误");
+            }
+            if (StringUtils.isEmpty(subjectId)) {
+                errMsg.add("声部为空");
+            }
+            if (StringUtils.isEmpty(birthday)) {
+                errMsg.add("出生日期为空");
+            }
+            if (StringUtils.isEmpty(gender)) {
+                errMsg.add("性别为空");
+            }
+            return errMsg;
+        }
+    }
 }

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

@@ -1,9 +1,13 @@
 package com.yonge.cooleshow.biz.dal.wrapper;
 
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
 import com.yonge.toolset.base.page.QueryInfo;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Date;
 import java.util.Optional;
 
 import lombok.AllArgsConstructor;
@@ -26,7 +30,7 @@ public class TenantInfoWrapper {
     @ApiModel(" TenantInfoQuery-机构表")
     public static class TenantInfoQuery  extends QueryInfo {
         @ApiModelProperty("id")
-        private Integer id;
+        private long id;
 
         @ApiModelProperty("是否冻结")
         private Integer ifFreeze;
@@ -52,6 +56,9 @@ public class TenantInfoWrapper {
         @ApiModelProperty("地区街道编码")
         private Integer regionCode;
 
+        @ApiModelProperty("审核是否通过")
+        private Integer ifPass;
+
         
         public String getKeyword() {
             return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
@@ -74,7 +81,10 @@ public class TenantInfoWrapper {
     @ApiModel(" TenantInfo-机构表分页响应")
     public static class TenantInfo {
         @ApiModelProperty("id")
-        private Integer id;
+        private long id;
+
+        @ApiModelProperty("机构ID")
+        private Long tenantId;
 
         @ApiModelProperty("机构名称")
         private String name;
@@ -85,8 +95,8 @@ public class TenantInfoWrapper {
         @ApiModelProperty("简介")
         private String briefIntroduction;
 
-        @ApiModelProperty("所属地区")
-        private String area;
+        /*@ApiModelProperty("所属地区")
+        private String area;*/
 
         @ApiModelProperty("联系人")
         private String userName;
@@ -118,13 +128,24 @@ public class TenantInfoWrapper {
         @ApiModelProperty("地区街道名称")
         private String regionName;
 
-        @ApiModelProperty("当前页")
-        private int page;
+        @ApiModelProperty("审核状态 DOING、审核中 PASS、通过 UNPASS、不通过")
+        @TableField(value = "status_")
+        private AuthStatusEnum status;
 
-        @ApiModelProperty("分页行数")
-        private int rows;
+        @ApiModelProperty("机构入驻申请记录")
+        private Long tenantApplyRecordId;
+
+        @ApiModelProperty("审核人")
+        private Long verifyUserId;
+
+        @ApiModelProperty("审核理由")
+        private String reason;
 
+        @ApiModelProperty("审核时间")
+        private Date createTime;
 
+        @ApiModelProperty("更新时间")
+        private Date updateTime;
         
         public String jsonString() {
             return JSON.toJSONString(this);

+ 60 - 11
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/UserPaymentOrderWrapper.java

@@ -1,22 +1,17 @@
 package com.yonge.cooleshow.biz.dal.wrapper;
 
-import com.alibaba.excel.annotation.ExcelIgnore;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.alibaba.excel.annotation.write.style.ColumnWidth;
 import com.alibaba.fastjson.JSON;
-import com.baomidou.mybatisplus.annotation.TableField;
 import com.microsvc.toolkit.common.response.paging.QueryInfo;
-import com.sun.istack.internal.NotNull;
 import com.yonge.cooleshow.biz.dal.entity.UserOrder;
 import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.entity.UserOrderPayment;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.GoodTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.OrderTypeEnum;
 import com.yonge.cooleshow.common.enums.payment.EGoodsType;
 import com.yonge.cooleshow.common.enums.payment.EPaymentStatus;
 import com.yonge.cooleshow.common.enums.payment.EPaymentType;
-import io.rong.util.ParamNotNull;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
@@ -24,13 +19,14 @@ import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import org.apache.commons.lang3.StringUtils;
-import org.joda.time.DateTime;
 
-import javax.validation.constraints.NotBlank;
 import java.io.Serializable;
 import java.math.BigDecimal;
-import java.text.MessageFormat;
-import java.util.*;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
 
 /**
  * 平台订单表
@@ -164,6 +160,8 @@ public class UserPaymentOrderWrapper {
         @ApiModelProperty("支付厂商名")
         private String paymentVenderName;
 
+        @ApiModelProperty("优惠券Id;多个使用,隔开")
+        private String couponIds;
 
         @ApiModelProperty(value = "推荐用户id(有推荐人的情况)")
         private Long recomUserId;
@@ -250,7 +248,7 @@ public class UserPaymentOrderWrapper {
 
 
         @ApiModelProperty("商品信息")
-        private List<UserOrderDetail> goodsInfos;
+        private List<OrderGoodsInfo> goodsInfos;
 
 
         @ApiModelProperty("支付配置参数")
@@ -793,4 +791,55 @@ public class UserPaymentOrderWrapper {
         }
     }
 
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel("订单商品信息")
+    public static class OrderGoodsInfo implements Serializable {
+
+
+        @ApiModelProperty("优惠券Id")
+        private Long couponId;
+
+        @ApiModelProperty(value = "活动id",hidden = true)
+        private Long activityId;
+
+        @ApiModelProperty(value = "订单号 ",hidden = true)
+        private String orderNo;
+
+        @ApiModelProperty(value = "订单详情号 ",hidden = true)
+        private String subOrderNo;
+
+        @ApiModelProperty("订单类型: 学生端( VIP、开通会员  PRACTICE、陪练课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ACTI_REGIST、活动报名) 老师端(VIP、开通会员 PIANO_ROOM、琴房时长)")
+        private GoodTypeEnum goodType;
+
+        @ApiModelProperty("业务id ")
+        private Long bizId;
+        @ApiModelProperty("业务内容 ")
+        private String bizContent;
+
+
+        @ApiModelProperty("商品数量 ")
+        private Integer goodNum;
+
+        @ApiModelProperty("商品名称 ")
+        private String goodName;
+
+        @ApiModelProperty(value = "购买人ID ",hidden = true)
+        private Long userId;
+
+
+        @ApiModelProperty("用户身份")
+        private ClientEnum paymentClient;
+
+        @ApiModelProperty(value = "生成的订单详情信息",hidden = true)
+        private UserOrderDetail userOrderDetail;
+
+        public Integer getGoodNum() {
+            return Optional.ofNullable(goodNum).orElse(1);
+        }
+    }
+
 }

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

@@ -22,8 +22,8 @@
         SELECT
         <include refid="baseColumns"/>, ta.purchase_cycle_ as purchaseCycle, su.username_ as activationUserName
         FROM tenant_activation_code t
-        LEFT JOIN tenant_album ta on t.tenant_album_id_ = ta.id_
-        LEFT JOIN sys_user su on t.active_user_id = su.id_
+        LEFT JOIN tenant_album_purchase ta on t.tenant_album_purchase_id_ = ta.id_
+        LEFT JOIN sys_user su on t.activation_user_id_ = su.id_
         <where>
             <if test="param.keyword != null and param.keyword.trim() != ''">
                 AND (

+ 114 - 17
cooleshow-user/user-biz/src/main/resources/config/mybatis/TenantInfoMapper.xml

@@ -26,6 +26,13 @@
         (name_,logo_,brief_Introduction_,province_code_,city_code_,region_code_,username_,phone_)
         values (#{param.name},#{param.logo},#{param.briefIntroduction},#{param.provinceCode},#{param.cityCode},#{param.regionCode},#{param.username},#{param.phone})
     </insert>
+
+    <insert id="insertNow">
+        insert into tenant_entry_record (id_,tenant_id_,
+        )
+        (id_,)
+    </insert>
+
     <update id="updateInfo">
         update tenant_info
         set
@@ -68,19 +75,64 @@
         where tenant_id_ = #{id}
     </update>
 
+    <update id="updateStatusById">
+      update  tenant_apply_record
+      set status_ = 'PASS'
+      where  id_ =#{id}
+    </update>
+    <update id="updateUnpassStatusById">
+        update  tenant_apply_record
+      set status_ = 'UNPASS'
+      where  id_ =#{id}
+    </update>
+
     <select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper$TenantInfo">
-		SELECT
-            id_ as id,
-        	name_ AS name,
-        	logo_ AS logo,
-        	brief_Introduction_ AS briefIntroduction,
-        	username_ AS username,
-        	phone_ AS phone,
-            province_code_ AS provinceCode,
-            city_code_ AS cityCode,
-            region_code_ AS regionCode
-		FROM tenant_info t
-		where 1=1
+        SELECT
+        <include refid="baseColumns"/>
+        FROM tenant_info t
+        <where>
+            <if test="param.keyword != null and param.keyword  != ''">
+                and (
+                t.name_ like concat('%',#{param.keyword},'%')
+                or t.username_ like concat('%',#{param.keyword},'%')
+                or t.phone_ like concat('%',#{param.keyword},'%')
+                )
+            </if>
+            <if test="param.provinceCode != null">
+                and t.province_code_ = #{param.provinceCode}
+            </if>
+            <if test="param.cityCode != null">
+                and t.city_code_ = #{param.cityCode}
+            </if>
+            <if test="param.regionCode != null">
+                and t.region_code_ = #{param.regionCode}
+            </if>
+        </where>
+
+	</select>
+
+    <select id="queryTeacherCounts" resultType="java.lang.Integer">
+        SELECT count(t.tenant_id_) FROM teacher t where t.tenant_id_ IN (<foreach collection="listId" separator="," item="Id">#{Id}</foreach>)
+    </select>
+
+    <select id="queryStudentCounts" resultType="java.lang.Integer">
+        SELECT count(s.tenant_id_) FROM student s where s.tenant_id_ IN (<foreach collection="listId" separator="," item="Id">#{Id}</foreach>)
+    </select>
+
+    <select id="selectApplyPage" resultType="com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper$TenantInfo">
+        SELECT
+        id_ as id,
+        name_ AS name,
+        logo_ AS logo,
+        brief_Introduction_ AS briefIntroduction,
+        username_ AS username,
+        phone_ AS phone,
+        province_code_ AS provinceCode,
+        city_code_ AS cityCode,
+        region_code_ AS regionCode,
+        status_ AS status
+        FROM tenant_apply_record t
+        where 1=1
         <if test="param.keyword != null and param.keyword  != ''">
             and (
             t.name_ like concat('%',#{param.keyword},'%')
@@ -98,12 +150,57 @@
             and
             t.region_code_ = #{param.regionCode}
         </if>
-	</select>
-    <select id="queryTeacherCounts" resultType="java.lang.Integer">
-        SELECT count(t.tenant_id_) FROM teacher t where t.tenant_id_ IN (<foreach collection="listId" separator="," item="Id">#{Id}</foreach>)
     </select>
-    <select id="queryStudentCounts" resultType="java.lang.Integer">
-        SELECT count(s.tenant_id_) FROM student s where s.tenant_id_ IN (<foreach collection="listId" separator="," item="Id">#{Id}</foreach>)
+
+    <select id="selectHistoryPage"
+            resultType="com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper$TenantInfo">
+        select
+        id_ AS id,
+        tenant_apply_record_id_ AS tenantApplyRecordId,
+        name_ AS name,
+        logo_ as logo,
+        province_code_ AS provinceCode,
+        city_code_ AS cityCode,
+        region_code_ AS regionCode,
+        username_ AS username,
+        phone_ AS phone,
+        status_ AS status,
+        verify_user_id_ AS verifyUserId,
+        reason_ AS reason,
+        update_time_ AS updateTime,
+        create_time_ AS createTime
+        FROM
+        tenant_entry_record
+        WHERE
+        1=1
+        <if test="id != null">
+          and id_ = #{id}
+        </if>
+    </select>
+    <select id="queryNow" resultType="com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper$TenantInfo">
+        select
+        id_ AS id,
+        tenant_id_ AS tenantId,
+        name_ AS name,
+        logo_ as logo,
+        province_code_ AS provinceCode,
+        city_code_ AS cityCode,
+        region_code_ AS regionCode,
+        username_ AS username,
+        phone_ AS phone,
+        status_ AS status,
+        verify_user_id_ AS verifyUserId,
+        reason_ AS reason,
+        update_time_ AS updateTime,
+        create_time_ AS createTime
+        from
+        tenant_apply_record
+        where
+        1=1
+        <if test="param.id != null">
+        and
+        id_ = #{param.id}
+        </if>
     </select>
 
 </mapper>

+ 2 - 1
cooleshow-user/user-biz/src/main/resources/config/mybatis/TenantStaffMapper.xml

@@ -29,7 +29,8 @@
 	</select>
 
     <select id="getByPhone" resultType="com.yonge.cooleshow.biz.dal.entity.TenantStaff">
-        select *
+        select
+            <include refid="baseColumns" />
         from tenant_staff t
         left join sys_user t1 on t1.id_ = t.user_id_
         where t1.phone_ = #{phone}

+ 25 - 0
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/StudentController.java

@@ -191,4 +191,29 @@ public class StudentController extends BaseController {
         return succeed();
     }
 
+    @PostMapping("/logoffAccount")
+    @ApiOperation(value = "注销学生账户")
+    public HttpResponseResult<Boolean> logoffAccount(@RequestParam("code") String code) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if (StringUtils.isEmpty(code)) {
+            return failed("验证码不能为空");
+        }
+        boolean validCode = smsCodeService.verifyValidCode(user.getPhone(), code, "");
+        if (validCode) {
+            return failed("验证码错误");
+        }
+
+        studentService.lambdaUpdate()
+                .set(Student::getLockFlag, true)
+                .set(Student::getHideFlag, true)
+                .eq(Student::getUserId, user.getId())
+                .update();
+        user.setDelFlag(true);
+        sysUserFeignService.update(user);
+        return succeed();
+    }
+
 }

+ 3 - 1
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/TenantActivationCodeController.java

@@ -23,6 +23,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import javax.annotation.Resource;
+
 
 @Slf4j
 @Validated
@@ -34,7 +36,7 @@ public class TenantActivationCodeController extends BaseController {
     @Autowired
     private TenantActivationCodeService tenantActivationCodeService;
 
-    @Autowired
+    @Resource
     private SysUserFeignService sysUserFeignService;
 
     @Autowired

+ 32 - 0
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/StudentController.java

@@ -12,21 +12,30 @@ import com.yonge.cooleshow.biz.dal.vo.StudentVo;
 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.BizHttpStatus;
 import com.yonge.cooleshow.common.enums.UserLockFlag;
 import com.yonge.cooleshow.common.enums.UserStatusEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.page.PageInfo;
 import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.utils.easyexcel.ErrMsg;
+import com.yonge.toolset.utils.easyexcel.ExcelDataReader;
+import com.yonge.toolset.utils.easyexcel.ExcelException;
+import com.yonge.toolset.utils.easyexcel.ExcelUtils;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
 import java.util.List;
@@ -63,6 +72,9 @@ public class StudentController extends BaseController {
         List<StudentVo> rows = pages.getRecords();
 
         for (StudentVo vo : rows) {
+            if (StringUtils.isNotEmpty(vo.getPhone())) {
+                vo.setPhone(vo.getPhone().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
+            }
             if (vo.getDelFlag() == YesOrNoEnum.YES) {
                 vo.setUserStatus(UserStatusEnum.CLOSED);
             } else {
@@ -87,6 +99,26 @@ public class StudentController extends BaseController {
         return succeed();
     }
 
+    @PostMapping("/importExcel")
+    @ApiOperation(value = "导入", notes = "传入file")
+    public HttpResponseResult<List<ErrMsg>> importExcel(@RequestParam("file") MultipartFile file) {
+        if (null == file) {
+            return HttpResponseResult.failed("请上传文件");
+        }
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        try {
+            ExcelDataReader<StudentWrapper.StudentExport> reader =
+                    ExcelUtils.getReader(StudentWrapper.StudentExport.class, file);
+            studentService.importStudentExcel(reader.getDataList(), user.getId());
+            return HttpResponseResult.succeed();
+        } catch (ExcelException e) {
+            return HttpResponseResult.failed(BizHttpStatus.IMPORT.getCode(), e.getErrMsgList(), BizHttpStatus.IMPORT.getMsg());
+        }
+    }
+
     private TenantInfo getTenantInfo() {
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         TenantInfo tenantInfo = tenantInfoService.lambdaQuery().eq(TenantInfo::getUserId, sysUser.getId())

+ 4 - 0
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/TeacherController.java

@@ -23,6 +23,7 @@ import com.yonge.toolset.base.page.PageInfo;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -89,6 +90,9 @@ public class TeacherController extends BaseController {
         List<TeacherVo> rows = pages.getRecords();
 
         for (TeacherVo vo : rows) {
+            if (StringUtils.isNotEmpty(vo.getPhone())) {
+                vo.setPhone(vo.getPhone().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
+            }
             if (vo.getDelFlag() == YesOrNoEnum.YES) {
                 vo.setUserStatus(UserStatusEnum.CLOSED);
             } else {

+ 18 - 2
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/UserOrderController.java

@@ -5,6 +5,9 @@ import com.alibaba.fastjson.JSONObject;
 import com.microsvc.toolkit.common.response.template.R;
 import com.microsvc.toolkit.common.webportal.exception.BizException;
 import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.service.UserPaymentCoreService;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.tenant.vo.UserPaymentOrderVo;
@@ -26,6 +29,8 @@ import java.util.Objects;
 public class UserOrderController {
 
 
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
 
     @Autowired
     private UserPaymentCoreService userPaymentCoreService;
@@ -35,6 +40,12 @@ public class UserOrderController {
     public R<UserPaymentOrderWrapper.PaymentConfig> executeOrder(@Validated @RequestBody UserPaymentOrderVo.OrderReq orderReq) {
 
         // 设置下单用户信息
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(sysUser)) {
+            throw BizException.from("用户信息不存在");
+        }
+        orderReq.setUserId(sysUser.getId());
+        orderReq.setPaymentClient(ClientEnum.TENANT.name());
 
 
         // 用户下单请求
@@ -51,14 +62,19 @@ public class UserOrderController {
     @ApiOperation(value = "用户付款", notes = "用户付款")
     @PostMapping("/executePayment")
     public R<UserPaymentOrderWrapper.PaymentReq> executePayment(@Validated @RequestBody UserPaymentOrderVo.PaymentReqConfig config) {
-
+        // 设置下单用户信息
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(sysUser)) {
+            throw BizException.from("用户信息不存在");
+        }
 
 
         // 用户下单请求
         UserPaymentOrderWrapper.PaymentOrderReqConfig reqConfig = UserPaymentOrderWrapper.PaymentOrderReqConfig.from(config.jsonString());
 
         // 创建用户支付数据
-        UserPaymentOrderWrapper.PaymentReq paymentConfig = userPaymentCoreService.executePayment(new JwtUserInfo<>(), reqConfig);
+        UserPaymentOrderWrapper.PaymentReq paymentConfig = userPaymentCoreService.executePayment(JwtUserInfo.builder()
+                .userId(sysUser.getId().toString()).clientType(ClientEnum.TEACHER.getCode()).build(), reqConfig);
         if (Objects.isNull(paymentConfig)) {
             throw BizException.from("付款失败");
         }

+ 17 - 54
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/vo/UserPaymentOrderVo.java

@@ -1,13 +1,20 @@
 package com.yonge.cooleshow.tenant.vo;
 
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yonge.cooleshow.biz.dal.enums.GoodTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.OrderTypeEnum;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import org.springframework.format.annotation.DateTimeFormat;
 
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.util.Date;
@@ -128,8 +135,9 @@ public class UserPaymentOrderVo {
         @ApiModelProperty("业务类型Id")
         private String bizId;
 
-        @ApiModelProperty("订单类型:  VIP(开通会员), ORCHESTRA(乐团报名)")
-        private String orderType;
+        @NotNull(message = "订单类型不能为空")
+        @ApiModelProperty(value = "订单类型: 学生端( VIP、开通会员  PRACTICE、陪练课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ACTI_REGIST、活动报名 ) 老师端(VIP、开通会员 PIANO_ROOM、琴房时长 ACTI_REGIST 活动报名)", required = true)
+        private OrderTypeEnum orderType;
 
         @ApiModelProperty("现价")
         private BigDecimal currentPrice;
@@ -153,7 +161,7 @@ public class UserPaymentOrderVo {
         private String couponIds;
 
         @ApiModelProperty("订单商品信息")
-        private List<OrderGoodsInfo> goodsInfos;
+        private List<UserPaymentOrderWrapper.OrderGoodsInfo> goodsInfos;
 
         @ApiModelProperty(value = "用户身份", hidden = true)
         private String paymentClient;
@@ -161,6 +169,12 @@ public class UserPaymentOrderVo {
         @ApiModelProperty(value = "用户编号", hidden = true)
         private Long userId;
 
+        @ApiModelProperty(value = "推荐用户id(有推荐人的情况)")
+        private Long recomUserId;
+
+        @ApiModelProperty(value = "活动id")
+        private Long activityId;
+
         public String jsonString() {
             return JSON.toJSONString(this);
         }
@@ -180,57 +194,6 @@ public class UserPaymentOrderVo {
     @Builder
     @NoArgsConstructor
     @AllArgsConstructor
-    @ApiModel("订单商品信息")
-    public static class OrderGoodsInfo implements Serializable {
-
-        @ApiModelProperty("商品类型 ")
-        private String goodsType;
-
-        @ApiModelProperty("商品名称")
-        private String goodsName;
-
-        @ApiModelProperty("商品图片")
-        private String goodsUrl;
-
-        @ApiModelProperty("商品Id")
-        private String goodsId;
-
-        @ApiModelProperty("商品库存Id")
-        private Long goodsSkuId;
-
-        @ApiModelProperty("商品来源")
-        private String goodsSource;
-
-        @ApiModelProperty("商品描述")
-        private String description;
-
-        @ApiModelProperty("原价")
-        private BigDecimal originalPrice;
-
-        @ApiModelProperty("现价")
-        private BigDecimal currentPrice;
-
-        @ApiModelProperty("实付现金")
-        private BigDecimal paymentCashAmount;
-
-        @ApiModelProperty("优惠金额")
-        private BigDecimal paymentCouponAmount;
-
-        @ApiModelProperty("商品数量")
-        private Integer goodsNum;
-
-        @ApiModelProperty("优惠券Id")
-        private Long couponId;
-
-        public Integer getGoodsNum() {
-            return Optional.ofNullable(goodsNum).orElse(1);
-        }
-    }
-
-    @Data
-    @Builder
-    @NoArgsConstructor
-    @AllArgsConstructor
     @ApiModel("订单支付参数配置")
     public static class PaymentReqConfig implements Serializable {