瀏覽代碼

Merge branch 'saas' of http://git.dayaedu.com/yonge/mec into saas

yonge 3 年之前
父節點
當前提交
c107fe8571
共有 40 個文件被更改,包括 371 次插入289 次删除
  1. 2 2
      mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/core/provider/PhoneAuthenticationProvider.java
  2. 3 2
      mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/core/provider/service/DefaultUserDetailsService.java
  3. 4 2
      mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/dal/dao/SysUserDao.java
  4. 2 2
      mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/service/SysUserService.java
  5. 18 27
      mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/service/impl/SysUserServiceImpl.java
  6. 2 2
      mec-auth/mec-auth-server/src/main/resources/config/mybatis/SysUserMapper.xml
  7. 2 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/RedemptionCodeDao.java
  8. 3 4
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TenantAssetsInfoDao.java
  9. 4 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TenantCloudCourseRecordDao.java
  10. 6 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysUserCashAccount.java
  11. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/TenantCloudCourseRecord.java
  12. 5 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/entity/TenantProductInfo.java
  13. 2 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/enums/MessageTypeEnum.java
  14. 11 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/vo/TenantCloudCourseRecordVo.java
  15. 2 0
      mec-biz/src/main/java/com/ym/mec/biz/service/AppRedemptionCodeService.java
  16. 2 1
      mec-biz/src/main/java/com/ym/mec/biz/service/CloudTeacherOrderService.java
  17. 2 5
      mec-biz/src/main/java/com/ym/mec/biz/service/TenantAssetsInfoService.java
  18. 2 1
      mec-biz/src/main/java/com/ym/mec/biz/service/TenantCloudCourseRecordService.java
  19. 38 10
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/AppRedemptionCodeServiceImpl.java
  20. 13 7
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CloudTeacherOrderServiceImpl.java
  21. 7 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java
  22. 102 138
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantAssetsInfoServiceImpl.java
  23. 3 3
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantCloudCourseRecordServiceImpl.java
  24. 13 1
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantInfoServiceImpl.java
  25. 4 0
      mec-biz/src/main/resources/config/mybatis/RedemptionCodeMapper.xml
  26. 6 6
      mec-biz/src/main/resources/config/mybatis/SysManualMapper.xml
  27. 7 14
      mec-biz/src/main/resources/config/mybatis/TenantAssetsInfoMapper.xml
  28. 10 10
      mec-biz/src/main/resources/config/mybatis/TenantCloudCourseRecordMapper.xml
  29. 1 1
      mec-client-api/src/main/java/com/ym/mec/web/WebFeignService.java
  30. 1 1
      mec-client-api/src/main/java/com/ym/mec/web/fallback/WebFeignServiceFallback.java
  31. 23 18
      mec-common/common-core/src/main/java/com/ym/mec/common/page/WrapperUtil.java
  32. 12 1
      mec-common/common-core/src/main/java/com/ym/mec/common/security/AuthUser.java
  33. 1 0
      mec-im/src/main/java/com/ym/common/ErrorEnum.java
  34. 12 4
      mec-im/src/main/java/com/ym/service/Impl/RoomServiceImpl.java
  35. 2 2
      mec-web/src/main/java/com/ym/mec/web/controller/APIController.java
  36. 3 0
      mec-web/src/main/java/com/ym/mec/web/controller/AppRedemptionCodeController.java
  37. 18 22
      mec-web/src/main/java/com/ym/mec/web/controller/CloudTeacherOrderController.java
  38. 1 1
      mec-web/src/main/java/com/ym/mec/web/controller/SysManualController.java
  39. 8 0
      mec-web/src/main/java/com/ym/mec/web/controller/TaskController.java
  40. 13 0
      mec-web/src/main/java/com/ym/mec/web/controller/TenantAssetsInfoController.java

+ 2 - 2
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/core/provider/PhoneAuthenticationProvider.java

@@ -96,9 +96,9 @@ public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider
 					// 添加userType以及附加信息
 					if (StringUtils.equals("STUDENT", clientId)) {
 						user.setOrganId(sysUserService.getLesseeOrganId());
-						sysUserService.saveStudent(user.getId());
+						sysUserService.saveStudent(user.getId(),loginEntity.getTenantId());
 					} else if (StringUtils.equals("TEACHER", clientId)) {
-						sysUserService.saveTeacher(user.getId());
+						sysUserService.saveTeacher(user.getId(),loginEntity.getTenantId());
 					}
 					sysUserService.update(user);
 				}

+ 3 - 2
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/core/provider/service/DefaultUserDetailsService.java

@@ -73,8 +73,9 @@ public class DefaultUserDetailsService implements UserDetailsService {
 
 		SysUser sysUser = userInfo.getSysUser();
 
-		return new AuthUser(sysUser.getId(), sysUser.getOrganId(), username, BCRYPT + sysUser.getPassword(), sysUser.getLockFlag() == 0, true, true, true,
-				authorities);
+		return new AuthUser(sysUser.getId(), sysUser.getOrganId(), username, BCRYPT + sysUser.getPassword(),
+				sysUser.getLockFlag() == 0, true, true, true,
+				authorities,tenantId);
 	}
 
 }

+ 4 - 2
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/dal/dao/SysUserDao.java

@@ -72,7 +72,9 @@ public interface SysUserDao extends BaseDAO<Integer, SysUser> {
 	 * @param userId
 	 * @param lesseeOrganId
 	 */
-	void insertTeacher(@Param("userId") Integer userId, @Param("lesseeOrganId") Integer lesseeOrganId);
+	void insertTeacher(@Param("userId") Integer userId,
+					   @Param("lesseeOrganId") Integer lesseeOrganId,
+					   @Param("tenantId") Integer tenantId);
 
 	/**
 	 * 获取教师分部编号
@@ -98,5 +100,5 @@ public interface SysUserDao extends BaseDAO<Integer, SysUser> {
 	 * 保存student
 	 * @param userId
 	 */
-    void saveStudent(@Param("userId") Integer userId);
+    void saveStudent(@Param("userId") Integer userId,@Param("tenantId") Integer tenantId);
 }

+ 2 - 2
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/service/SysUserService.java

@@ -115,13 +115,13 @@ public interface SysUserService extends BaseService<Integer, SysUser> {
 	 * 保存student数据
 	 * @param userId
 	 */
-	void saveStudent(Integer userId);
+	void saveStudent(Integer userId,Integer tenantId);
 	
 	/**
 	 * 保存teacher数据
 	 * @param userId
 	 */
-	void saveTeacher(Integer userId);
+	void saveTeacher(Integer userId,Integer tenantId);
 	
 	Integer getLesseeOrganId();
 }

+ 18 - 27
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/service/impl/SysUserServiceImpl.java

@@ -1,14 +1,5 @@
 package com.ym.mec.auth.service.impl;
 
-import java.util.Date;
-import java.util.List;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
 import com.ym.mec.auth.api.dto.SysUserInfo;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.auth.api.enums.YesOrNoEnum;
@@ -20,20 +11,25 @@ import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.entity.ImResult;
 import com.ym.mec.common.entity.ImUserModel;
 import com.ym.mec.common.exception.BizException;
-import com.ym.mec.common.service.IdGeneratorService;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
 import com.ym.mec.im.ImFeignService;
 import com.ym.mec.web.WebFeignService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+import java.util.List;
 
 @Service
 public class SysUserServiceImpl extends BaseServiceImpl<Integer, SysUser> implements SysUserService {
 
 	@Autowired
 	private SysUserDao sysUserDao;
-
 	@Autowired
 	private SysUserRoleService sysUserRoleService;
-
 	@Autowired
 	private SysRoleMenuService sysRoleMenuService;
 	@Autowired
@@ -42,8 +38,6 @@ public class SysUserServiceImpl extends BaseServiceImpl<Integer, SysUser> implem
 	private WebFeignService userFeignService;
 	@Autowired
 	private SysUserService sysUserService;
-	@Autowired
-	private IdGeneratorService smsCodeService;
 
 	@Value("${auth.sysconfig.tenantId}")
 	private Integer lesseeOrganId;
@@ -158,14 +152,15 @@ public class SysUserServiceImpl extends BaseServiceImpl<Integer, SysUser> implem
 			SysUser sysUser = new SysUser();
 			sysUser.setPhone(phone);
 			sysUser.setUserType("TEACHER");
+			sysUser.setTenantId(tenantId);
 			sysUserDao.insert(sysUser);
 			//添加用户现金账户
 			imFeignService.register(new ImUserModel(sysUser.getId().toString(),phone,null));
-			userFeignService.createCashAccount(sysUser.getId());
+			userFeignService.createCashAccount(sysUser.getId(),tenantId);
 			//sysTenantAccount
 			sysUserDao.insertSysTenantAccount(sysUser.getId());
 			//创建teacher表
-			sysUserDao.insertTeacher(sysUser.getId(),lesseeOrganId);
+			sysUserDao.insertTeacher(sysUser.getId(),lesseeOrganId,tenantId);
 			return queryUserInfoByPhone(phone);
 		}else if(StringUtils.equalsIgnoreCase(clientId,"STUDENT")){
 			SysUser sysUser = new SysUser();
@@ -176,16 +171,12 @@ public class SysUserServiceImpl extends BaseServiceImpl<Integer, SysUser> implem
 			}else{
 				sysUser.setOrganId(Integer.parseInt(organId));
 			}
-			//注册是否赠送会员
-			if(sysUser.getOrganId() == 59){
-				
-			}
-			
+			sysUser.setTenantId(tenantId);
 			sysUserDao.insert(sysUser);
-			sysUserService.saveStudent(sysUser.getId());
+			sysUserService.saveStudent(sysUser.getId(),tenantId);
 			//添加用户现金账户
 			imFeignService.register(new ImUserModel(sysUser.getId().toString(),phone,null));
-			userFeignService.createCashAccount(sysUser.getId());
+			userFeignService.createCashAccount(sysUser.getId(),tenantId);
 			return queryUserInfoByPhone(phone);
 		}
 		return null;
@@ -198,13 +189,13 @@ public class SysUserServiceImpl extends BaseServiceImpl<Integer, SysUser> implem
 	}
 
 	@Override
-	public void saveStudent(Integer userId) {
-		sysUserDao.saveStudent(userId);
+	public void saveStudent(Integer userId,Integer tenantId) {
+		sysUserDao.saveStudent(userId,tenantId);
 	}
 
 	@Override
-	public void saveTeacher(Integer userId) {
-		sysUserDao.insertTeacher(userId, lesseeOrganId);
+	public void saveTeacher(Integer userId,Integer tenantId) {
+		sysUserDao.insertTeacher(userId, lesseeOrganId,tenantId);
 	}
 
 	@Override

+ 2 - 2
mec-auth/mec-auth-server/src/main/resources/config/mybatis/SysUserMapper.xml

@@ -79,7 +79,7 @@
     </insert>
     <insert id="insertTeacher">
         INSERT INTO teacher
-        (id_,organ_id_,create_time_,update_time_)VALUES(#{userId},#{lesseeOrganId},NOW(),NOW())
+        (id_,organ_id_,create_time_,update_time_,tenant_id_)VALUES(#{userId},#{lesseeOrganId},NOW(),NOW(),#{tenantId})
     </insert>
     <insert id="insertSysTenantAccount">
         INSERT INTO sys_tenant_account
@@ -87,7 +87,7 @@
 		VALUES(#{userId},0,0,1,NOW(),NOW())
     </insert>
     <insert id="saveStudent">
-        INSERT INTO student (user_id_,create_time_,update_time_,service_tag_,operating_tag_) VALUES(#{userId},NOW(),NOW(),0,0)
+        INSERT INTO student (user_id_,create_time_,update_time_,service_tag_,operating_tag_,tenant_id_) VALUES(#{userId},NOW(),NOW(),0,0,#{tenantId})
     </insert>
 
     <!-- 根据主键查询一条记录 -->

+ 2 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/RedemptionCodeDao.java

@@ -17,5 +17,7 @@ public interface RedemptionCodeDao extends BaseMapper<AppRedemptionCode> {
    int insertBatch(@Param("entities") List<AppRedemptionCode> entities);
 
     AppRedemptionCode findFirstNull();
+
+    int findNull();
 }
 

+ 3 - 4
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TenantAssetsInfoDao.java

@@ -2,6 +2,7 @@ package com.ym.mec.biz.dal.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.ym.mec.biz.dal.entity.TenantAssetsInfo;
+import io.swagger.models.auth.In;
 import org.apache.ibatis.annotations.Param;
 
 import java.math.BigDecimal;
@@ -17,10 +18,8 @@ public interface TenantAssetsInfoDao extends BaseMapper<TenantAssetsInfo> {
 
     int insertBatch(@Param("entities") List<TenantAssetsInfo> entities);
 
-    int frozenAmount(BigDecimal frozenAmount);
+    int deductAmount(BigDecimal deductAmount, Integer tenantId);
 
-    int recoverAmount(BigDecimal recoverAmount);
-
-    int deductAmount(BigDecimal deductAmount);
+    int checkDeductAmount(BigDecimal deductAmount, Integer tenantId);
 }
 

+ 4 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TenantCloudCourseRecordDao.java

@@ -4,8 +4,10 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ym.mec.biz.dal.entity.TenantCloudCourseRecord;
+import com.ym.mec.biz.dal.vo.TenantCloudCourseRecordVo;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -18,6 +20,7 @@ public interface TenantCloudCourseRecordDao extends BaseMapper<TenantCloudCourse
 
     <T> IPage<T> queryPage(Page<T> page, @Param("param") Map<String, Object> param);
 
-    TenantCloudCourseRecord queryLastRecord(Integer courseId);
+    List<TenantCloudCourseRecordVo> queryPage(@Param("param") Map<String, Object> param);
+
 }
 

+ 6 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/SysUserCashAccount.java

@@ -55,6 +55,12 @@ public class SysUserCashAccount extends BaseEntity {
 		this.currency = currency;
 	}
 
+	public SysUserCashAccount(Integer userId,Integer tenantId, String currency) {
+		this.userId = userId;
+		this.setTenantId(tenantId);
+		this.currency = currency;
+	}
+
 	public SysUserCashAccount() {
 	}
 

+ 1 - 1
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/TenantCloudCourseRecord.java

@@ -33,7 +33,7 @@ public class TenantCloudCourseRecord implements Serializable {
     private Integer courseId;
 
     @TableField("deduct_state_")
-    @ApiModelProperty(value = "扣费状态 0冻结 1扣费 2取消冻结")
+    @ApiModelProperty(value = "扣费状态 0冻结 1扣费 2取消冻结 3未扣费")
     private Integer deductState;
 
     @TableField("amount_")

+ 5 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/entity/TenantProductInfo.java

@@ -18,6 +18,11 @@ import java.util.Date;
  */
 @ApiModel(value = "机构产品设置表")
 public class TenantProductInfo implements Serializable {
+
+    public static final String MONTH = "MONTH";
+
+    public static final String YEAR = "YEAR";
+
     @TableId(value = "id_", type = IdType.AUTO)
     @ApiModelProperty(value = "主键")
     private Integer id;

+ 2 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/enums/MessageTypeEnum.java

@@ -195,6 +195,8 @@ public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
     NO_TRAIN_STUDENT_PUSH("NO_TRAIN_STUDENT_PUSH", "云教练训练提醒"),
 
     COUPON_STOCK_WARNING("COUPON_STOCK_WARNING", "优惠券库存预警"),
+
+    APP_REDEMPTION_CODE("APP_REDEMPTION_CODE", "兑换码分配量预警"),
     ;
 
     MessageTypeEnum(String code, String msg) {

+ 11 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/vo/TenantCloudCourseRecordVo.java

@@ -28,6 +28,9 @@ public class TenantCloudCourseRecordVo implements Serializable {
     @ApiModelProperty(value = "分部名称")
     private Integer organName;
 
+    @ApiModelProperty(value = "机构Id")
+    private Integer tenantId;
+
     @ApiModelProperty(value = "机构名称")
     private Integer tenantName;
 
@@ -87,6 +90,14 @@ public class TenantCloudCourseRecordVo implements Serializable {
         this.organName = organName;
     }
 
+    public Integer getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(Integer tenantId) {
+        this.tenantId = tenantId;
+    }
+
     public Integer getTenantName() {
         return tenantName;
     }

+ 2 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/AppRedemptionCodeService.java

@@ -17,5 +17,7 @@ public interface AppRedemptionCodeService extends IService<AppRedemptionCode> {
     List<AppRedemptionCode> importRedemptionCode(MultipartFile file) throws Exception;
 
     AppRedemptionCode allocation(Integer userId);
+
+    void checkLowVolume();
 }
 

+ 2 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/CloudTeacherOrderService.java

@@ -112,9 +112,10 @@ public interface CloudTeacherOrderService extends BaseService<Long, CloudTeacher
 
     Msg payNotify(Msg msg) throws Exception;
 
-    Boolean payCheck(String orderNo);
+    Boolean payCheck(String orderNo) throws Exception;
 
     PageInfo<CloudTeacherStudent> queryRecord(CloudTeacherOrderQueryInfo cloudTeacherOrderQueryInfo);
 
     boolean addStudents(CloudTeacherAddQueryInfo cloudTeacherAddQueryInfo);
+
 }

+ 2 - 5
mec-biz/src/main/java/com/ym/mec/biz/service/TenantAssetsInfoService.java

@@ -15,12 +15,9 @@ import java.util.List;
  */
 public interface TenantAssetsInfoService extends IService<TenantAssetsInfo> {
 
-    void courseFrozenAmount(List<CourseSchedule> dto);
+    void manualDeductAmount(List<Integer> ids);
 
-    void courseRecoverAmount(Integer courseId);
+    void deductAmount(List<CourseSchedule> dto);
 
-    void courseDeductAmount(Integer courseId);
-
-    void groupFrozenAmount(VipGroup vipGroup, List<CourseSchedule> dto);
 }
 

+ 2 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/TenantCloudCourseRecordService.java

@@ -5,6 +5,7 @@ import com.ym.mec.biz.dal.entity.TenantCloudCourseRecord;
 import com.ym.mec.biz.dal.vo.TenantCloudCourseRecordVo;
 import com.ym.mec.common.page.PageInfo;
 
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -17,7 +18,7 @@ public interface TenantCloudCourseRecordService extends IService<TenantCloudCour
 
     PageInfo<TenantCloudCourseRecordVo> queryPage(Map<String,Object> param);
 
-    TenantCloudCourseRecord queryLastRecord(Integer courseId);
+    List<TenantCloudCourseRecordVo> queryList(Map<String, Object> param);
 
 }
 

+ 38 - 10
mec-biz/src/main/java/com/ym/mec/biz/service/impl/AppRedemptionCodeServiceImpl.java

@@ -2,18 +2,22 @@ package com.ym.mec.biz.service.impl;
 
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.mysql.cj.protocol.MessageSender;
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.biz.dal.dao.RedemptionCodeDao;
 import com.ym.mec.biz.dal.entity.AppRedemptionCode;
 import com.ym.mec.biz.dal.enums.*;
 import com.ym.mec.biz.service.AppRedemptionCodeService;
+import com.ym.mec.biz.service.SysMessageService;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.WrapperUtil;
+import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
 import com.ym.mec.util.excel.POIUtil;
 import com.ym.mec.util.ini.IniFileUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.ClassPathResource;
+import org.springframework.security.core.parameters.P;
 import org.springframework.stereotype.Service;
 
 import org.slf4j.Logger;
@@ -31,7 +35,8 @@ import java.util.*;
  * @since 2021-12-27 14:27:57
  */
 @Service("redemptionCodeService")
-public class AppRedemptionCodeServiceImpl extends ServiceImpl<RedemptionCodeDao, AppRedemptionCode> implements AppRedemptionCodeService {
+public class AppRedemptionCodeServiceImpl extends ServiceImpl<RedemptionCodeDao, AppRedemptionCode>
+        implements AppRedemptionCodeService {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(AppRedemptionCodeServiceImpl.class);
 
@@ -41,14 +46,18 @@ public class AppRedemptionCodeServiceImpl extends ServiceImpl<RedemptionCodeDao,
     @Autowired
     private SysUserFeignService sysUserFeignService;
 
+    @Autowired
+    private SysMessageService sysMessageService;
+
     private final static Logger logger = LoggerFactory.getLogger(AppRedemptionCodeServiceImpl.class);
 
     @Override
     public List<AppRedemptionCode> importRedemptionCode(MultipartFile file) throws Exception {
-        Map<String, List<Map<String, Object>>> sheetsListMap = POIUtil.importExcel(new ByteArrayInputStream(file.getBytes()), 2, file.getOriginalFilename());
-        
+        Map<String, List<Map<String, Object>>> sheetsListMap = POIUtil.importExcel(
+                new ByteArrayInputStream(file.getBytes()), 2, file.getOriginalFilename());
+
         InputStream inputStream = new ClassPathResource("columnMapper.ini").getInputStream();
-        Map<String,String> columns = IniFileUtil.readIniFile(inputStream, TemplateTypeEnum.REDEMPTIONCODE.getMsg());
+        Map<String, String> columns = IniFileUtil.readIniFile(inputStream, TemplateTypeEnum.REDEMPTIONCODE.getMsg());
 
         List<AppRedemptionCode> redemptionCodesList = new ArrayList<>();
         for (String e : sheetsListMap.keySet()) {
@@ -60,18 +69,19 @@ public class AppRedemptionCodeServiceImpl extends ServiceImpl<RedemptionCodeDao,
 
                 JSONObject objectMap = new JSONObject();
                 for (String s : row.keySet()) {
-                    if(!columns.containsKey(s)){
+                    if (!columns.containsKey(s)) {
                         continue;
                     }
                     String columnValue = columns.get(s);
-                    if(null == row.get(s) || StringUtils.isBlank(row.get(s).toString())){
-                        LOGGER.error("导入异常:参数{}不可为空 param:{}",columnValue,objectMap);
-                        continue ;
+                    if (null == row.get(s) || StringUtils.isBlank(row.get(s).toString())) {
+                        LOGGER.error("导入异常:参数{}不可为空 param:{}", columnValue, objectMap);
+                        continue;
                     }
                     objectMap.put(columnValue, row.get(s));
                 }
                 try {
-                    AppRedemptionCode redemptionCode = JSONObject.parseObject(objectMap.toJSONString(),AppRedemptionCode.class);
+                    AppRedemptionCode redemptionCode = JSONObject.parseObject(objectMap.toJSONString(),
+                                                                              AppRedemptionCode.class);
                     redemptionCodesList.add(redemptionCode);
                     redemptionCodeDao.insert(redemptionCode);
                 } catch (Exception ex) {
@@ -85,9 +95,27 @@ public class AppRedemptionCodeServiceImpl extends ServiceImpl<RedemptionCodeDao,
     @Override
     public AppRedemptionCode allocation(Integer userId) {
         AppRedemptionCode redemptionCode = redemptionCodeDao.findFirstNull();
+        if (redemptionCode == null) {
+            return null;
+        }
         redemptionCode.setUserId(userId);
-        redemptionCodeDao.update(redemptionCode, new WrapperUtil<AppRedemptionCode>().queryWrapper());
+        int retCount = redemptionCodeDao.update(redemptionCode, new WrapperUtil<AppRedemptionCode>().queryWrapper());
+        if (retCount == 0) {
+            return null;
+        }
         return redemptionCode;
     }
+
+    @Override
+    public void checkLowVolume() {
+        int volume = redemptionCodeDao.findNull();
+        if (volume < 10) {
+            Map<Integer, String> receivers = new HashMap<>(1);
+            receivers.put(0, "13512341234");
+            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS,
+                                               MessageTypeEnum.APP_REDEMPTION_CODE, receivers, null, 0, null, null,
+                                               volume, null, null);
+        }
+    }
 }
 

+ 13 - 7
mec-biz/src/main/java/com/ym/mec/biz/service/impl/CloudTeacherOrderServiceImpl.java

@@ -19,6 +19,7 @@ import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.service.IdGeneratorService;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
+import com.ym.mec.thirdparty.adapay.Payment;
 import com.ym.mec.thirdparty.yqpay.Msg;
 import com.ym.mec.util.collection.MapUtil;
 import com.ym.mec.util.date.DateUtil;
@@ -38,7 +39,7 @@ import static com.ym.mec.biz.dal.enums.PeriodEnum.*;
 
 @Service
 public class CloudTeacherOrderServiceImpl extends BaseServiceImpl<Long, CloudTeacherOrder> implements CloudTeacherOrderService {
-    private static final Logger log = LoggerFactory.getLogger(TenantInfoServiceImpl.class);
+    private static final Logger log = LoggerFactory.getLogger(CloudTeacherOrderServiceImpl.class);
     @Autowired
     private CloudTeacherOrderDao cloudTeacherOrderDao;
     @Autowired
@@ -115,6 +116,7 @@ public class CloudTeacherOrderServiceImpl extends BaseServiceImpl<Long, CloudTea
         if (count == 0) {
             return pageInfo;
         }
+        assert dataList != null;
         for (CloudTeacherStudent cst: dataList) {
             TenantConfig tenantConfig = tenantConfigService.getOne(new QueryWrapper<TenantConfig>().eq("tenant_id_", cst.getTenantId()));
             if (tenantConfig == null) {
@@ -160,7 +162,7 @@ public class CloudTeacherOrderServiceImpl extends BaseServiceImpl<Long, CloudTea
         }
         List<Integer> ids = cloudTeacherStudents.stream().map(CloudTeacherStudent::getCloudTeacherOrderId).collect(
                 Collectors.toList());
-        if (cloudTeacherOrderDao.checkOrdered(StringUtil.join(ids, ",")) >= 0) {
+        if (cloudTeacherOrderDao.checkOrdered(StringUtil.join(ids, ",")) != 0) {
             throw new Exception("学生已经支付");
         }
         Integer tenantId = null;
@@ -183,12 +185,11 @@ public class CloudTeacherOrderServiceImpl extends BaseServiceImpl<Long, CloudTea
      * 团练宝支付
      * @param payAmount 金额
      * @param tenantId 分部
-     * @return
+     * @return 支付结果
      */
     private Map<String, Object> payExec(BigDecimal payAmount, Integer tenantId, List<CloudTeacherStudent> cloudTeacherStudents) throws Exception {
         //生成订单编号
         String orderNo = idGenerator.generatorId("payment") + "";
-        String baseApiUrl = sysConfigDao.findConfigValue("base_api_url");
         TenantOrderRecordEnum tenantEnum = TenantOrderRecordEnum.CLOUD_TEACHER;
 
         Map<String, Object> payMap = new HashMap<>();
@@ -199,8 +200,8 @@ public class CloudTeacherOrderServiceImpl extends BaseServiceImpl<Long, CloudTea
                     payAmount,
                     BigDecimal.ZERO,
                     orderNo,
-                    baseApiUrl + "/api-web/cloudTeacherOrder/payNotify",
-                    baseApiUrl + "/api-student/studentOrder/paymentResult?orderNo=" + orderNo,
+                    null,
+                    null,
                     tenantEnum.getMsg(),
                     tenantEnum.getMsg(),
                     1,//临时写死
@@ -285,8 +286,13 @@ public class CloudTeacherOrderServiceImpl extends BaseServiceImpl<Long, CloudTea
         return record;
     }
 
-    public Boolean payCheck(String orderNo) {
+    public Boolean payCheck(String orderNo) throws Exception {
         TenantOrderRecord record = tenantOrderRecordService.getOne(new QueryWrapper<TenantOrderRecord>().eq("order_no_", orderNo));
+        Map<String, Object> payment = Payment.queryPayment(record.getTransNo());
+        if ("succeeded".equals(payment.get("status")) ) {
+            this.paySuccess(record);
+            return true;
+        }
         return record.getOrderState() == 1;
     }
 

+ 7 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/CourseScheduleServiceImpl.java

@@ -163,6 +163,8 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 	private MusicGroupTrainPlanService musicGroupTrainPlanService;
     @Autowired
 	private PracticeGroupSellPriceDao practiceGroupSellPriceDao;
+    @Autowired
+	private TenantAssetsInfoService tenantAssetsInfoService;
 
     private final Logger LOGGER = LoggerFactory
             .getLogger(this.getClass());
@@ -4135,6 +4137,11 @@ public class CourseScheduleServiceImpl extends BaseServiceImpl<Long, CourseSched
 
 		if (updateList.size() > 0) {
             courseScheduleDao.batchUpdate(updateList);
+			try {
+				tenantAssetsInfoService.deductAmount(updateList);
+			}catch (Exception e){
+				LOGGER.error("deductAmount  >>>>>>>>>",e);
+			}
 			List<Long> courseIds = updateList.stream().map(CourseSchedule::getId).collect(Collectors.toList());
 			List<CourseSchedule> beMergeCourses = courseScheduleDao.getBeMergeCourseWithMainCourseIds(courseIds);
 			if(!CollectionUtils.isEmpty(beMergeCourses)){

+ 102 - 138
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantAssetsInfoServiceImpl.java

@@ -2,25 +2,22 @@ package com.ym.mec.biz.service.impl;
 
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.ym.mec.auth.api.client.SysUserFeignService;
-import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.dao.TenantAssetsInfoDao;
 import com.ym.mec.biz.dal.entity.*;
 import com.ym.mec.biz.dal.entity.TenantConfigDetail.CloudRoomRule;
 import com.ym.mec.biz.dal.enums.TeachModeEnum;
+import com.ym.mec.biz.dal.vo.TenantCloudCourseRecordVo;
 import com.ym.mec.biz.service.TenantAssetsInfoService;
 import com.ym.mec.biz.service.TenantCloudCourseRecordService;
 import com.ym.mec.biz.service.TenantConfigService;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.WrapperUtil;
-import com.ym.mec.common.tenant.TenantContextHolder;
 import com.ym.mec.thirdparty.yqpay.DateUtils;
 import org.apache.commons.collections.CollectionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.math.MathContext;
@@ -43,151 +40,124 @@ public class TenantAssetsInfoServiceImpl extends ServiceImpl<TenantAssetsInfoDao
     @Autowired
     private TenantConfigService tenantConfigService;
     @Autowired
-    private SysUserFeignService sysUserFeignService;
-    @Autowired
     private TenantCloudCourseRecordService tenantCloudCourseRecordService;
 
     /**
-     * 课程
-     * 扣除冻结的金额
+     * 手动执行未扣费的流水
      *
-     * @param courseId 课程id
+     * @param ids 流水表id集合
      */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void courseDeductAmount(Integer courseId) {
-        TenantCloudCourseRecord lastRecord = checkLastRecord(courseId);
-        if (Objects.isNull(lastRecord)) {
+    public void manualDeductAmount(List<Integer> ids) {
+        if (CollectionUtils.isEmpty(ids)) {
             return;
         }
-        //写入流水
-        lastRecord.setDeductState(1);
-        tenantCloudCourseRecordService.save(lastRecord);
-        if (baseMapper.deductAmount(lastRecord.getAmount()) != 1) {
-            throw new BizException("解除冻结金额失败!");
-        }
-    }
-
-    /**
-     * 课程
-     * 恢复/取消 冻结的金额
-     *
-     * @param courseId 课程id
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void courseRecoverAmount(Integer courseId) {
-        TenantCloudCourseRecord lastRecord = checkLastRecord(courseId);
-        if (Objects.isNull(lastRecord)) {
+        List<TenantCloudCourseRecordVo> records = tenantCloudCourseRecordService.queryList(new HashMap<String, Object>() {{
+            put("ids", ids);
+            put("deductState", 3);
+        }});
+        if (CollectionUtils.isEmpty(records)) {
             return;
         }
-        //写入流水
-        lastRecord.setDeductState(2);
-        tenantCloudCourseRecordService.save(lastRecord);
-        //解除冻结金额,恢复余额
-        if (baseMapper.recoverAmount(lastRecord.getAmount()) != 1) {
-            throw new BizException("解除冻结金额失败!");
-        }
-    }
+        records.forEach(record -> {
+            log.info("manualDeductAmount >>>>>> {}", record);
+            //获取总人数 ,+1是算上老师
+            Integer totalPeople = record.getStudentNum() + 1;
+            //获取云教室规则  String人数-BigDecimal每分钟扣费标准
+            Map<String, BigDecimal> rule = getRule(record.getTenantId());
+            if (Objects.isNull(rule)) {
+                throw new BizException("未查询到该机构的课程收费标准!");
+            }
+            //获取每分钟扣费标准
+            BigDecimal minutePrice = rule.get(String.valueOf(totalPeople));
+            if (Objects.isNull(minutePrice)) {
+                throw new BizException("未查到 [" + totalPeople + "人(含老师)] 的课程收费标准!");
+            }
+            //计算总上课时间
+            BigDecimal courseDate = getCourseDate(record.getClassDate(), record.getStartClassTime(), record.getEndClassTime());
+            //课程总价 = 每分钟扣费标准 * 总上课时间
+            BigDecimal coursePrice = minutePrice.multiply(courseDate, new MathContext(2, RoundingMode.HALF_UP));
+            //修改流水
+            TenantCloudCourseRecord sourceCord = new TenantCloudCourseRecord();
+            sourceCord.setId(record.getId());
+            sourceCord.setAmount(coursePrice);
+            sourceCord.setDeductState(1);
+            tenantCloudCourseRecordService.updateById(sourceCord);
+            //扣余额
+            if (baseMapper.checkDeductAmount(coursePrice, record.getTenantId()) == 0) {
+                throw new BizException("余额不足!");
+            }
+        });
 
-    private TenantCloudCourseRecord checkLastRecord(Integer courseId) {
-        TenantCloudCourseRecord lastRecord = tenantCloudCourseRecordService.queryLastRecord(courseId);
-        if (Objects.isNull(lastRecord)) {
-            return null;
-        }
-        //判断是否是冻结的状态
-        if (lastRecord.getDeductState() != 0) {
-            //只有冻结的才能取消冻结 或者 扣费
-            throw new BizException("该课程非线上课!");
-        }
-        lastRecord.setCreatedBy(getUserId());
-        lastRecord.setCreatedTime(new Date());
-        return lastRecord;
     }
 
     /**
-     * 课程组金额冻结
+     * 上课时间到了后扣除账户余额,可以为负数
      *
-     * @param vipGroup 课程组信息
-     * @param dto      课程组中的课程
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void groupFrozenAmount(VipGroup vipGroup, List<CourseSchedule> dto) {
-
-    }
-
-    /**
-     * 冻结课程的总价格
-     * 1.线上排课计算出的总价格不能超过账户余额(注意多人同时操作账户余额多扣问题)
-     * 2.若符合规则冻结部分账户
+     * @param dto 课程集合
      */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void courseFrozenAmount(List<CourseSchedule> dto) {
-        Integer tenantId = TenantContextHolder.getTenantId();
-
+    public void deductAmount(List<CourseSchedule> dto) {
         //校验课程 筛选出线上课
         dto = getOnlineCourse(dto);
         if (CollectionUtils.isEmpty(dto)) {
             return;
         }
-
-        TenantAssetsInfo assetsInfo = this.getOne(new WrapperUtil<TenantAssetsInfo>()
-                .hasEq("tenant_id_", tenantId).queryWrapper());
-        if (Objects.isNull(assetsInfo)) {
-            throw new BizException("未查询到该账户资产信息!");
-        }
-
-        //获取云教室规则  String人数-BigDecimal每分钟扣费标准
-        Map<String, BigDecimal> rule = getRule(tenantId);
-        BigDecimal frozenAmount = BigDecimal.ZERO;
-
-        for (CourseSchedule course : dto) {
-            TenantCloudCourseRecord lastRecord = tenantCloudCourseRecordService.queryLastRecord(course.getId().intValue());
-            if (Objects.nonNull(lastRecord) && lastRecord.getDeductState() == 0) {
-                //该课程id最后一条记录也是冻结状态
-                throw new BizException("该课程已是线上课!");
+        //开始扣费
+        dto.forEach(course -> {
+            log.info("deductAmount >>>>>> {}", course);
+            if (Objects.isNull(course.getTenantId())) {
+                return;
             }
-
             //获取总人数 ,+1是算上老师
             Integer totalPeople = course.getStudentNum() + 1;
+            //获取云教室规则  String人数-BigDecimal每分钟扣费标准
+            Map<String, BigDecimal> rule = getRule(course.getTenantId());
+            if (Objects.isNull(rule)) {
+                //没有这个扣费标准,写未扣费流水记录
+                insertRecord(course, BigDecimal.ZERO, 3);
+                return;
+            }
             //获取每分钟扣费标准
             BigDecimal minutePrice = rule.get(String.valueOf(totalPeople));
             if (Objects.isNull(minutePrice)) {
-                //没有这个扣费标准
-                throw new BizException("课程人数已达上限,请联系教务老师!");
+                //没有这个扣费标准,写未扣费流水记录
+                insertRecord(course, BigDecimal.ZERO, 3);
+                return;
             }
             //计算总上课时间
-            BigDecimal courseDate = getCourseDate(course);
-            //课程价 = 每分钟扣费标准 * 总上课时间
+            BigDecimal courseDate = getCourseDate(course.getClassDate(), course.getStartClassTime(), course.getEndClassTime());
+            //课程价 = 每分钟扣费标准 * 总上课时间
             BigDecimal coursePrice = minutePrice.multiply(courseDate, new MathContext(2, RoundingMode.HALF_UP));
-            frozenAmount = frozenAmount.add(coursePrice);
-
-            //写入流水
-            TenantCloudCourseRecord record = new TenantCloudCourseRecord();
-            record.setCourseId(course.getId().intValue());
-            record.setAmount(coursePrice);
-            record.setTenantId(tenantId);
-            record.setDeductState(0);
-            record.setCreatedBy(getUserId());
-            record.setCreatedTime(new Date());
-            tenantCloudCourseRecordService.save(record);
-        }
+            //写流水
+            insertRecord(course, coursePrice, 1);
+            //扣余额
+            baseMapper.deductAmount(coursePrice, course.getTenantId());
+        });
 
-        //直接修改余额,利用数据库的规则来防ABA的出现
-        if (baseMapper.frozenAmount(frozenAmount) != 1) {
-            //可能是余额不足
-            throw new BizException("线上课预约火爆,请联系教务老师!");
-        }
+    }
 
+    /**
+     * 写入流水
+     *
+     * @param course      课程
+     * @param coursePrice 课程总价
+     * @param state       扣费状态 1扣费  3未扣费
+     */
+    private void insertRecord(CourseSchedule course, BigDecimal coursePrice, Integer state) {
+        //写入流水
+        TenantCloudCourseRecord record = new TenantCloudCourseRecord();
+        record.setCourseId(course.getId().intValue());
+        record.setTenantId(course.getTenantId());
+        record.setAmount(coursePrice);
+        record.setDeductState(state);
+        record.setCreatedTime(new Date());
+        tenantCloudCourseRecordService.save(record);
     }
 
     private List<CourseSchedule> getOnlineCourse(List<CourseSchedule> dto) {
-        return Optional.ofNullable(dto)
-                .filter(CollectionUtils::isNotEmpty)
-                .orElseThrow(() -> new BizException("请传入课程数据!"))
-                .stream()
+        if (CollectionUtils.isEmpty(dto)) {
+            return null;
+        }
+        return dto.stream()
                 .filter(c -> c.getTeachMode().equals(TeachModeEnum.ONLINE))
                 .collect(Collectors.toList());
     }
@@ -197,41 +167,35 @@ public class TenantAssetsInfoServiceImpl extends ServiceImpl<TenantAssetsInfoDao
         TenantConfig tenantConfig = tenantConfigService.getOne(new WrapperUtil<TenantConfig>()
                 .hasEq("tenant_id_", tenantId).queryWrapper());
         if (Objects.isNull(tenantConfig)) {
-            throw new BizException("未查询到云教室规则信息!");
+            return null;
         }
         return Optional.ofNullable(tenantConfig.getConfig())
                 .map(c -> JSON.parseObject(c, TenantConfigDetail.class))
                 .map(TenantConfigDetail::getCloud_room_rule)
                 .map(CloudRoomRule::getCloud_room_config)
-                .orElseThrow(() -> new BizException("未查询到云教室规则!"));
+                .orElse(null);
     }
 
-    private BigDecimal getCourseDate(CourseSchedule course) {
-        String date = DateUtils.formatDate(course.getClassDate(), DateUtils.YYYY_MM_DD_DEF);
-        Date startDT = getDateTime(date, course.getStartClassTime());
-        Date endDT = getDateTime(date, course.getEndClassTime());
-        //课程结束时间-课程开始时间
-        long durationTime = endDT.getTime() - startDT.getTime();
-        //相差多少分钟
-        int durationMinute = new Long(durationTime / 1000 / 60).intValue();
-        return BigDecimal.valueOf(durationMinute);
-    }
-
-    private Date getDateTime(String dateStr, Date time) {
-        String timeStr = DateUtils.formatDate(time, "HH:mm:ss");
-        String s = dateStr + " " + timeStr;
+    private BigDecimal getCourseDate(Date date, Date startTime, Date endTime) {
+        String dateStr = DateUtils.formatDate(date, DateUtils.YYYY_MM_DD_DEF);
+        int durationMinute = 0;
         try {
-            return DateUtils.parseDate(s, DateUtils.DATE_WEB_FORMAT);
+            Date startDT = getDateTime(dateStr, startTime);
+            Date endDT = getDateTime(dateStr, endTime);
+            //课程结束时间-课程开始时间
+            long durationTime = endDT.getTime() - startDT.getTime();
+            //相差多少分钟
+            durationMinute = new Long(durationTime / 1000 / 60).intValue();
         } catch (ParseException e) {
-            throw new BizException("课程时间格式错误!");
+            log.error("deductAmount >>>>>> 计算时间出错 : {} {} {}", date, startTime, endTime);
         }
+        return BigDecimal.valueOf(durationMinute);
     }
 
-    private Integer getUserId() {
-        //修改机构基础信息
-        return Optional.ofNullable(sysUserFeignService.queryUserInfo())
-                .map(SysUser::getId)
-                .orElseThrow(() -> new BizException("用户信息获取失败,请刷新页面或者重新登录!"));
+    private Date getDateTime(String dateStr, Date time) throws ParseException {
+        String timeStr = DateUtils.formatDate(time, "HH:mm:ss");
+        String s = dateStr + " " + timeStr;
+        return DateUtils.parseDate(s, DateUtils.DATE_WEB_FORMAT);
     }
 
 }

+ 3 - 3
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantCloudCourseRecordServiceImpl.java

@@ -12,6 +12,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -30,12 +31,11 @@ public class TenantCloudCourseRecordServiceImpl extends ServiceImpl<TenantCloudC
         Page<TenantCloudCourseRecordVo> pageInfo = PageUtil.getPageInfo(param);
         pageInfo.setAsc("a.created_time_");
         return PageUtil.pageInfo(baseMapper.queryPage(pageInfo, param));
-
     }
 
     @Override
-    public TenantCloudCourseRecord queryLastRecord(Integer courseId) {
-        return baseMapper.queryLastRecord(courseId);
+    public List<TenantCloudCourseRecordVo> queryList(Map<String, Object> param) {
+        return baseMapper.queryPage(param);
     }
 }
 

+ 13 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantInfoServiceImpl.java

@@ -24,6 +24,7 @@ import com.ym.mec.common.page.PageInfo;
 import com.ym.mec.common.page.PageUtil;
 import com.ym.mec.common.page.WrapperUtil;
 import com.ym.mec.common.service.IdGeneratorService;
+import com.ym.mec.thirdparty.yqpay.DateUtils;
 import com.ym.mec.thirdparty.yqpay.Msg;
 import org.apache.commons.collections.CollectionUtils;
 import org.joda.time.LocalDate;
@@ -317,6 +318,17 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoDao, TenantInfo
         assetsInfo.setFrozenAmount(BigDecimal.ZERO);
         assetsInfo.setCreatedTime(new Date());
         assetsInfoService.save(assetsInfo);
+        //修改有效期
+        Date expiryDate;
+        if (TenantProductInfo.MONTH.equals(productInfo.getExpiryUnit())) {
+            expiryDate = DateUtils.addMonths(new Date(), productInfo.getExpiryCount());
+        } else if (TenantProductInfo.YEAR.equals(productInfo.getExpiryUnit())) {
+            expiryDate = DateUtils.addYears(new Date(), productInfo.getExpiryCount());
+        } else {
+            throw new BizException("产品信息异常!开通失败!");
+        }
+        productInfo.setExpiryDate(expiryDate);
+        tenantProductInfoService.updateById(productInfo);
         //释放锁
         bucket.delete();
     }
@@ -410,7 +422,7 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoDao, TenantInfo
             if (tenantInfo.getPayState() == 1) {
                 throw new BizException("已缴费请勿重复缴费!");
             }
-            throw new BizException("该机构数正在缴费中请勿频繁操作");
+            throw new BizException("正在缴费中请稍后!");
         }
         //机构产品信息
         TenantProductInfo productInfo = tenantProductInfoService.getOne(new QueryWrapper<TenantProductInfo>()

+ 4 - 0
mec-biz/src/main/resources/config/mybatis/RedemptionCodeMapper.xml

@@ -29,5 +29,9 @@
         order by rc.import_time_ desc
         limit 1 for update;
     </select>
+    <select id="findNull" resultType="java.lang.Integer">
+        select count(1) from app_redemption_code rc where rc.user_id_ is null
+    </select>
+
 
 </mapper>

+ 6 - 6
mec-biz/src/main/resources/config/mybatis/SysManualMapper.xml

@@ -29,12 +29,12 @@
         select count(1) from sys_manual sm
         left join sys_user u on sm.operator_id_ = u.id_
         <where>
-            1 = 1 AND
+            1 = 1
             <if test="menuId != null and menuId != '' ">
-                menu_id_ = #{menuId}
+                AND menu_id_ = #{menuId}
             </if>
             <if test="search != null and search != '' ">
-                (name_ like concat('%', #{menuId} '%') )
+                AND (name_ like concat('%', #{menuId} '%') )
             </if>
         </where>
         <include refid="global.limit"/>
@@ -45,12 +45,12 @@
              , u.username_ as operatorName from sys_manual sm
         left join sys_user u on sm.operator_id_ = u.id_
         <where>
-            1 = 1 AND
+            1 = 1
             <if test="menuId != null and menuId != '' ">
-                sm.menu_id_ = #{menuId}
+                AND sm.menu_id_ = #{menuId}
             </if>
             <if test="search != null and search != '' ">
-                (name_ like concat('%', #{menuId} '%') )
+                AND (name_ like concat('%', #{menuId} '%') )
             </if>
         </where>
         <include refid="global.limit"/>

+ 7 - 14
mec-biz/src/main/resources/config/mybatis/TenantAssetsInfoMapper.xml

@@ -25,24 +25,17 @@
         </foreach>
     </insert>
 
-    <update id="frozenAmount" parameterType="decimal">
+    <update id="deductAmount" parameterType="object">
         update tenant_assets_info
-        set balance_       = balance_ - #{frozenAmount},
-            frozen_amount_ = frozen_amount_ + #{frozenAmount}
-        where balance_  <![CDATA[ >= ]]> #{frozenAmount}
+        set balance_ = balance_ - #{deductAmount}
+        where tenant_id_ = #{tenantId}
     </update>
 
-    <update id="recoverAmount" parameterType="decimal">
+    <update id="checkDeductAmount" parameterType="object">
         update tenant_assets_info
-        set balance_       = balance_ + #{recoverAmount},
-            frozen_amount_ = frozen_amount_ - #{recoverAmount}
-        where frozen_amount_  <![CDATA[ >= ]]> #{recoverAmount}
-    </update>
-
-    <update id="deductAmount" parameterType="decimal">
-        update tenant_assets_info
-        set frozen_amount_ = frozen_amount_ - #{deductAmount}
-        where frozen_amount_  <![CDATA[ >= ]]> #{deductAmount}
+        set balance_ = balance_ - #{deductAmount}
+        where tenant_id_ = #{tenantId}
+          and balance_  <![CDATA[ >= ]]> #{deductAmount}
     </update>
 
 </mapper>

+ 10 - 10
mec-biz/src/main/resources/config/mybatis/TenantCloudCourseRecordMapper.xml

@@ -21,6 +21,7 @@
         select a.id_ as id,
         b.id_ as courseId,
         o.name_ as organName,
+        t.id_ as tenantId
         t.name_ as tenantName,
         b.type_ as type,
         s.real_name_ as teacherName,
@@ -60,6 +61,9 @@
             <if test="param.teacherId!= null ">
                 AND b.teacher_id_ = #{param.teacherId}
             </if>
+            <if test="param.deductState != null ">
+                AND a.deduct_state_ = #{param.deductState}
+            </if>
             <if test="param.status != null ">
                 AND b.status_ = #{param.status}
             </if>
@@ -72,17 +76,13 @@
             <if test="param.endDate != null ">
                 AND b.`class_date_` <![CDATA[ <= ]]>  #{param.endDate}
             </if>
+            <if test="param.ids != null ">
+               AND a.id_ IN
+                <foreach collection="ids" item="id" open="(" close=")" separator=",">
+                    #{id}
+                </foreach>
+            </if>
         </where>
     </select>
 
-    <select id="queryLastRecord" parameterType="integer" resultMap="BaseResultMap">
-        select
-        <include refid="Base_Column_List"/>
-        from
-        tenant_cloud_course_record
-        where course_id_=#{courseId}
-        order by created_time_ desc
-        limit 1
-    </select>
-
 </mapper>

+ 1 - 1
mec-client-api/src/main/java/com/ym/mec/web/WebFeignService.java

@@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 public interface WebFeignService {
 
 	@RequestMapping(value = "api/createCashAccount")
-	Boolean createCashAccount(@RequestParam("userId") Integer userId);
+	Boolean createCashAccount(@RequestParam("userId") Integer userId,@RequestParam("tenantId") Integer tenantId);
 
 	@RequestMapping(value = "api/queryTeacherOrganId")
 	Integer queryTeacherOrganId(@RequestParam("userId") Integer userId);

+ 1 - 1
mec-client-api/src/main/java/com/ym/mec/web/fallback/WebFeignServiceFallback.java

@@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 public class WebFeignServiceFallback implements WebFeignService {
 
 	@Override
-	public Boolean createCashAccount(Integer userId) {
+	public Boolean createCashAccount(Integer userId,Integer tenantId) {
 		return false;
 	}
 

+ 23 - 18
mec-common/common-core/src/main/java/com/ym/mec/common/page/WrapperUtil.java

@@ -4,10 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
+import java.util.*;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
@@ -21,13 +18,24 @@ public class WrapperUtil<T> {
 
     private final Predicate<? super Object> ObjPredicate = (Predicate<Object>) Objects::nonNull;
 
-    private final Predicate<? super Object> StrPredicate = (Predicate<Object>) o -> StringUtils.isNotBlank((String) o);
+    private final Predicate<? super String> StrPredicate = (Predicate<String>) StringUtils::isNotBlank;
+
+    private final Predicate<? super Collection<?>> ListPredicate = (Predicate<Collection<?>>) CollectionUtils::isNotEmpty;
 
     public WrapperUtil() {
         this.queryWrapper = new QueryWrapper<>();
     }
 
     /**
+     * 返回QueryWrapper
+     *
+     * @return QueryWrapper
+     */
+    public QueryWrapper<T> queryWrapper() {
+        return queryWrapper;
+    }
+
+    /**
      * 值如果不为空则添加到查询条件中
      * 仅支持简单的类型
      *
@@ -45,27 +53,24 @@ public class WrapperUtil<T> {
     }
 
     /**
-     * in 查询
+     * in 查询,值如果不为空则添加到查询条件中
      *
      * @param column 列名称
-     * @param val    逗号分开的值
+     * @param val    集合
      */
-    public WrapperUtil<T> hasSplitIn(String column, String val) {
-        if (StrPredicate.test(val)) {
-            List<String> strings = WrapperUtil.toList(val);
-            if (CollectionUtils.isNotEmpty(strings)) {
-                queryWrapper.in(column, strings);
-            }
-        }
+    public WrapperUtil<T> hasIn(String column, Collection<?> val) {
+        queryWrapper.in(ListPredicate.test(val), column, val);
         return this;
     }
 
     /**
-     * 返回QueryWrapper
-     * @return QueryWrapper
+     * in 查询
+     *
+     * @param column 列名称
+     * @param val    逗号分开的值
      */
-    public QueryWrapper<T> queryWrapper() {
-        return queryWrapper;
+    public WrapperUtil<T> hasSplitIn(String column, String val) {
+        return this.hasIn(column, WrapperUtil.toList(val));
     }
 
     public static List<String> toList(String key) {

+ 12 - 1
mec-common/common-core/src/main/java/com/ym/mec/common/security/AuthUser.java

@@ -22,11 +22,22 @@ public class AuthUser extends User {
 	 */
 	private Integer organId;
 
+	private Integer tenantId;
+
 	public AuthUser(Integer userId, Integer organId, String username, String password, boolean enabled, boolean accountNonExpired,
-			boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
+			boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities,Integer tenantId) {
 		super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
 		this.userId = userId;
 		this.organId = organId;
+		this.tenantId = tenantId;
+	}
+
+	public Integer getTenantId() {
+		return tenantId;
+	}
+
+	public void setTenantId(Integer tenantId) {
+		this.tenantId = tenantId;
 	}
 
 	public Integer getUserId() {

+ 1 - 0
mec-im/src/main/java/com/ym/common/ErrorEnum.java

@@ -19,6 +19,7 @@ public enum ErrorEnum {
     ERR_JOIN_ROOM_ERROR(12, "Join room error"),
     JOIN_ROOM_ERROR(35, "加入房间失败,请前往线下教室"),
     ROOM_NOT_START(36, "网络教室暂未开启,请稍后重试"),
+    CLOUD_BALANCE_NOT_FEE(37, "云教室余额不足,请联系教务老师"),
     ERR_MESSAGE_ERROR(13, "IM Message send error"),
 
 

+ 12 - 4
mec-im/src/main/java/com/ym/service/Impl/RoomServiceImpl.java

@@ -21,11 +21,9 @@ import com.ym.mec.biz.dal.dto.RongyunBasicUserDto;
 import com.ym.mec.biz.dal.entity.*;
 import com.ym.mec.biz.dal.enums.GroupType;
 import com.ym.mec.biz.dal.enums.TeachModeEnum;
-import com.ym.mec.biz.service.StudentAttendanceService;
-import com.ym.mec.biz.service.SysConfigService;
-import com.ym.mec.biz.service.SysTenantConfigService;
-import com.ym.mec.biz.service.TeacherAttendanceService;
+import com.ym.mec.biz.service.*;
 import com.ym.mec.common.exception.BizException;
+import com.ym.mec.common.page.WrapperUtil;
 import com.ym.mec.im.IMHelper;
 import com.ym.mec.im.message.*;
 import com.ym.mec.util.collection.MapUtil;
@@ -38,6 +36,7 @@ import com.ym.utils.DateTimeUtils;
 import com.ym.utils.IdentifierUtils;
 import com.ym.whiteboard.WhiteBoardHelper;
 import lombok.extern.slf4j.Slf4j;
+import lombok.val;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
@@ -98,6 +97,8 @@ public class RoomServiceImpl implements RoomService {
     @Autowired
     private SysTenantConfigService sysTenantConfigService;
     @Autowired
+    private TenantAssetsInfoService tenantAssetsInfoService;
+    @Autowired
     private RedisTemplate<String,String> redisTemplate;
 
     @Override
@@ -148,6 +149,13 @@ public class RoomServiceImpl implements RoomService {
             throw new ApiException(ErrorEnum.ROOM_NOT_START);
 //            throw new BizException("网络教室暂未开启,请在{}分钟后进入教室",DateUtil.minutesBetween(addMinutes,courseSchedule.getStartClassTime()));
         }
+        final TenantAssetsInfo one = tenantAssetsInfoService.getOne(new WrapperUtil<TenantAssetsInfo>()
+                .hasEq("tenant_id_", courseSchedule.getTenantId())
+                .queryWrapper()
+                .gt("balance_", 0));
+        if(one == null){
+            throw new ApiException(ErrorEnum.CLOUD_BALANCE_NOT_FEE);
+        }
 
         //是否是连堂课
         String continueCourseTime = sysTenantConfigService.getTenantConfigValue(SysConfigService.ONLINE_CONTINUE_COURSE_TIME,courseSchedule.getTenantId());

+ 2 - 2
mec-web/src/main/java/com/ym/mec/web/controller/APIController.java

@@ -45,9 +45,9 @@ public class APIController extends BaseController {
 	private SysTenantConfigService sysTenantConfigService;
 
 	@GetMapping("/createCashAccount")
-	public Boolean createCashAccount(Integer userId) {
+	public Boolean createCashAccount(Integer userId,Integer tenantId) {
 		// 添加用户现金账户
-		sysUserCashAccountDao.insert(new SysUserCashAccount(userId, "CNY"));
+		sysUserCashAccountDao.insert(new SysUserCashAccount(userId,tenantId, "CNY"));
 
 		return true;
 	}

+ 3 - 0
mec-web/src/main/java/com/ym/mec/web/controller/AppRedemptionCodeController.java

@@ -35,6 +35,9 @@ public class AppRedemptionCodeController extends BaseController {
     @PostMapping(value = "allocation")
     @PreAuthorize("@pcs.hasPermissions('appRedemptionCode/allocation')")
     public HttpResponseResult<AppRedemptionCode> allocation(@RequestParam("userId")Integer userId) throws Exception {
+        if (userId == null) {
+            throw new Exception("用户Id必须填写");
+        }
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         if (sysUser == null) {
             return failed("用户信息获取失败");

+ 18 - 22
mec-web/src/main/java/com/ym/mec/web/controller/CloudTeacherOrderController.java

@@ -5,14 +5,22 @@ import com.ym.mec.biz.dal.entity.CloudTeacherStudent;
 import com.ym.mec.biz.dal.page.CloudTeacherAddQueryInfo;
 import com.ym.mec.biz.dal.page.CloudTeacherOrderQueryInfo;
 import com.ym.mec.biz.service.CloudTeacherOrderService;
+import com.ym.mec.biz.service.OrderPayOpsService;
+import com.ym.mec.biz.service.impl.TenantInfoServiceImpl;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.thirdparty.yqpay.Msg;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
+import java.math.BigDecimal;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Description
@@ -27,16 +35,19 @@ public class CloudTeacherOrderController extends BaseController {
 
     @Autowired
     private CloudTeacherOrderService cloudTeacherOrderService;
+    @Autowired
+    private OrderPayOpsService orderPayOpsService;
 
+    private static final Logger log = LoggerFactory.getLogger(CloudTeacherOrderController.class);
 
-    @ApiOperation(value ="手动添加会员")
+    @ApiOperation(value = "手动添加会员")
     @PostMapping("/addStudents")
     // @PreAuthorize("@pcs.hasPermissions('cloudTeacherOrder/addStudents')")
     public Object addStudents(@RequestBody CloudTeacherAddQueryInfo cloudTeacherAddQueryInfo) {
         return succeed(cloudTeacherOrderService.addStudents(cloudTeacherAddQueryInfo));
     }
 
-    @ApiOperation(value ="查询未激活团练宝用户")
+    @ApiOperation(value = "查询未激活团练宝用户")
     @PostMapping("/queryInactive")
     // @PreAuthorize("@pcs.hasPermissions('cloudTeacherOrder/queryUnActive')")
     public Object queryInactive(@RequestBody CloudTeacherOrderQueryInfo cloudTeacherOrderQueryInfo) throws Exception {
@@ -47,7 +58,7 @@ public class CloudTeacherOrderController extends BaseController {
         return succeed(cloudTeacherOrderService.queryInactive(cloudTeacherOrderQueryInfo));
     }
 
-    @ApiOperation(value ="查询已激活团练宝用户")
+    @ApiOperation(value = "查询已激活团练宝用户")
     @PostMapping("/queryActive")
     // @PreAuthorize("@pcs.hasPermissions('cloudTeacherOrder/queryActive')")
     public Object queryActive(@RequestBody CloudTeacherOrderQueryInfo cloudTeacherOrderQueryInfo) throws Exception {
@@ -58,39 +69,24 @@ public class CloudTeacherOrderController extends BaseController {
         return succeed(cloudTeacherOrderService.queryInactive(cloudTeacherOrderQueryInfo));
     }
 
-    @ApiOperation(value ="激活记录")
+    @ApiOperation(value = "激活记录")
     @PostMapping("/queryActiveRecord")
     // @PreAuthorize("@pcs.hasPermissions('cloudTeacherOrder/queryActiveRecord')")
     public Object queryActiveRecord(CloudTeacherOrderQueryInfo cloudTeacherOrderQueryInfo) {
         return succeed(cloudTeacherOrderService.queryRecord(cloudTeacherOrderQueryInfo));
     }
 
-    @ApiOperation(value ="测试支付通知")
-    @PostMapping("/testPayNotify")
-    // @PreAuthorize("@pcs.hasPermissions('cloudTeacherOrder/queryActive')")
-    public Object testPayNotify(@RequestBody Msg msg) throws Exception {
-        return succeed(cloudTeacherOrderService.payNotify(msg));
-    }
-
-
-    @ApiOperation(value ="激活团练宝用户")
+    @ApiOperation(value = "激活团练宝用户")
     @PostMapping("/pay")
     // @PreAuthorize("@pcs.hasPermissions('cloudTeacherOrder/pay')")
     public Object pay(@RequestBody List<CloudTeacherStudent> cloudTeacherStudents) throws Exception {
         return succeed(cloudTeacherOrderService.pay(cloudTeacherStudents));
     }
 
-    @ApiOperation(value ="支付回调")
-    @PostMapping("/payNotify")
-    // @PreAuthorize("@pcs.hasPermissions('cloudTeacherOrder/payNotify')")
-    public Msg payNotify(@ModelAttribute Msg msg) throws Exception {
-        return cloudTeacherOrderService.payNotify(msg);
-    }
-
-    @ApiOperation(value ="轮询查询订单状态")
+    @ApiOperation(value = "轮询查询订单状态")
     @GetMapping("/payCheck")
     // @PreAuthorize("@pcs.hasPermissions('cloudTeacherOrder/payCheck')")
-    public Object payCheck(@RequestParam String orderNo ) {
+    public Object payCheck(@RequestParam String orderNo) throws Exception {
         return succeed(cloudTeacherOrderService.payCheck(orderNo));
     }
 }

+ 1 - 1
mec-web/src/main/java/com/ym/mec/web/controller/SysManualController.java

@@ -40,7 +40,7 @@ public class SysManualController extends BaseController {
     @ApiOperation(value = "查询操作手册")
     @RequestMapping("/list")
     public Object list(SysManualQueryInfo queryInfo) {
-        return sysManualService.query(queryInfo);
+        return succeed(sysManualService.query(queryInfo));
     }
 
     @ApiOperation(value = "新增帮助手册")

+ 8 - 0
mec-web/src/main/java/com/ym/mec/web/controller/TaskController.java

@@ -108,6 +108,8 @@ public class TaskController extends BaseController {
 	private TenantInfoService tenantInfoService;
     @Autowired
     private TenantOrderRecordService tenantOrderRecordService;
+	@Autowired
+	private AppRedemptionCodeService appRedemptionCodeService;
 
 	@GetMapping(value = "/syncImHistoryMessageTask")
 	// 同步即时通讯聊天记录
@@ -512,6 +514,12 @@ public class TaskController extends BaseController {
 //		studentService.remarkCountFlag();
 	}
 
+	@ApiOperation("兑换码分配量检测")
+	@GetMapping(value = "/redemptionCodeWarn")
+	public void redemptionCodeWarn(){
+		appRedemptionCodeService.checkLowVolume();
+	}
+
     @ApiOperation("定时校验-机构订单状态")
     @GetMapping(value = "/checkTenantOrder")
     public void checkTenantOrder(){

+ 13 - 0
mec-web/src/main/java/com/ym/mec/web/controller/TenantAssetsInfoController.java

@@ -2,10 +2,14 @@ package com.ym.mec.web.controller;
 
 import com.ym.mec.biz.service.TenantAssetsInfoService;
 import com.ym.mec.common.controller.BaseController;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import java.util.List;
 
 /**
  * 机构资产信息(TenantAssetsInfo)表控制层
@@ -16,11 +20,20 @@ import javax.annotation.Resource;
 @RestController
 @RequestMapping("/tenantAssetsInfo")
 public class TenantAssetsInfoController extends BaseController {
+
     /**
      * 服务对象
      */
     @Resource
     private TenantAssetsInfoService tenantAssetsInfoService;
 
+    @ApiOperation("手动扣费")
+    @PostMapping(value = "/manualDeduct")
+//    @PreAuthorize("@pcs.hasPermissions('tenantAssetsInfo/manualDeduct')")
+    public Object manualDeductAmount(@RequestBody List<Integer> ids) {
+        tenantAssetsInfoService.manualDeductAmount(ids);
+        return succeed();
+    }
+
 }