Ver código fonte

Merge remote-tracking branch 'origin/saas' into saas

zouxuan 3 anos atrás
pai
commit
006f6075ac
21 arquivos alterados com 415 adições e 90 exclusões
  1. 10 0
      mec-auth/mec-auth-api/src/main/java/com/ym/mec/auth/api/entity/SysUser.java
  2. 9 5
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SysEmployeePositionDao.java
  3. 4 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TenantInfoDao.java
  4. 26 0
      mec-biz/src/main/java/com/ym/mec/biz/dal/dto/SysEmployeePositionDto.java
  5. 3 0
      mec-biz/src/main/java/com/ym/mec/biz/service/SysEmployeePositionService.java
  6. 1 1
      mec-biz/src/main/java/com/ym/mec/biz/service/TenantInfoSendMsgService.java
  7. 5 0
      mec-biz/src/main/java/com/ym/mec/biz/service/TenantInfoService.java
  8. 83 19
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/OrderPayOpsServiceImpl.java
  9. 4 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentPaymentOrderServiceImpl.java
  10. 7 0
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysEmployeePositionServiceImpl.java
  11. 24 5
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantAssetsInfoServiceImpl.java
  12. 53 16
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantInfoSendMsgServiceImpl.java
  13. 61 17
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantInfoServiceImpl.java
  14. 13 10
      mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantOrderRecordServiceImpl.java
  15. 2 2
      mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml
  16. 11 0
      mec-biz/src/main/resources/config/mybatis/SysEmployeePositionMapper.xml
  17. 34 0
      mec-biz/src/main/resources/config/mybatis/TenantInfoMapper.xml
  18. 1 1
      mec-common/common-core/src/main/java/com/ym/mec/common/page/WrapperUtil.java
  19. 34 0
      mec-teacher/src/main/java/com/ym/mec/teacher/controller/TenantConfigController.java
  20. 24 14
      mec-web/src/main/java/com/ym/mec/web/controller/EmployeeController.java
  21. 6 0
      mec-web/src/main/java/com/ym/mec/web/controller/TaskController.java

+ 10 - 0
mec-auth/mec-auth-api/src/main/java/com/ym/mec/auth/api/entity/SysUser.java

@@ -153,6 +153,8 @@ public class SysUser extends BaseEntity implements Serializable{
 
 	@ApiModelProperty(value = "开户行",required = false)
 	private String openBankAddress;
+	
+	private String positionName;
 
 	public String getCertificateType() {
 		return certificateType;
@@ -488,4 +490,12 @@ public class SysUser extends BaseEntity implements Serializable{
 	public void setDeptId(Integer deptId) {
 		this.deptId = deptId;
 	}
+
+	public String getPositionName() {
+		return positionName;
+	}
+
+	public void setPositionName(String positionName) {
+		this.positionName = positionName;
+	}
 }

+ 9 - 5
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/SysEmployeePositionDao.java

@@ -1,14 +1,16 @@
 package com.ym.mec.biz.dal.dao;
 
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ibatis.annotations.Param;
+
 import com.ym.mec.biz.dal.dto.SimpleUserDto;
+import com.ym.mec.biz.dal.dto.SysEmployeePositionDto;
 import com.ym.mec.biz.dal.entity.SysEmployeePosition;
 import com.ym.mec.biz.dal.enums.SysUserRoleEnum;
 import com.ym.mec.common.dal.BaseDAO;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 public interface SysEmployeePositionDao extends BaseDAO<Integer, SysEmployeePosition> {
 
@@ -44,4 +46,6 @@ public interface SysEmployeePositionDao extends BaseDAO<Integer, SysEmployeePosi
     * @date 2022/1/8 16:28
     */
     Set<Integer> queryUserIdByRoleId(@Param("roleArr") SysUserRoleEnum[] roleArr, @Param("organId") Integer organId, @Param("tenantId") Integer tenantId);
+    
+    List<SysEmployeePositionDto> queryByUserId(Integer userId);
 }

+ 4 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/TenantInfoDao.java

@@ -7,6 +7,8 @@ import com.ym.mec.biz.dal.entity.TenantInfo;
 import com.ym.mec.biz.dal.entity.TenantProductSumm;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.Date;
+import java.util.List;
 import java.util.Map;
 
 public interface TenantInfoDao extends BaseMapper<TenantInfo> {
@@ -20,4 +22,6 @@ public interface TenantInfoDao extends BaseMapper<TenantInfo> {
     TenantInfo queryTenantInfoByOrgan(@Param("organId") Integer organId);
 
     void updatePhone(@Param("newPhone")String newPhone, @Param("oldPhone")String oldPhone);
+
+    List<TenantInfo> queryExpiryTenant(@Param("expiryDate") Date expiryDate);
 }

+ 26 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/SysEmployeePositionDto.java

@@ -0,0 +1,26 @@
+package com.ym.mec.biz.dal.dto;
+
+import com.ym.mec.biz.dal.entity.SysEmployeePosition;
+
+public class SysEmployeePositionDto extends SysEmployeePosition {
+
+	private String positionName;
+	
+	private String positionCode;
+
+	public String getPositionName() {
+		return positionName;
+	}
+
+	public void setPositionName(String positionName) {
+		this.positionName = positionName;
+	}
+
+	public String getPositionCode() {
+		return positionCode;
+	}
+
+	public void setPositionCode(String positionCode) {
+		this.positionCode = positionCode;
+	}
+}

+ 3 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/SysEmployeePositionService.java

@@ -1,6 +1,7 @@
 package com.ym.mec.biz.service;
 
 import com.ym.mec.biz.dal.dto.SimpleUserDto;
+import com.ym.mec.biz.dal.dto.SysEmployeePositionDto;
 import com.ym.mec.biz.dal.entity.SysEmployeePosition;
 import com.ym.mec.biz.dal.enums.SysUserRoleEnum;
 import com.ym.mec.common.service.BaseService;
@@ -52,4 +53,6 @@ public interface SysEmployeePositionService extends BaseService<Integer, SysEmpl
      * @date 2022/1/4 11:36
      */
     Set<Integer> queryUserIdByRoleId(SysUserRoleEnum[] roleArr, Integer organId);
+
+    List<SysEmployeePositionDto> queryByUserId(Integer userId);
 }

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

@@ -2,5 +2,5 @@ package com.ym.mec.biz.service;
 
 public interface TenantInfoSendMsgService {
 
-    void sendToAll(String type, Integer userId, String email, Object... objs);
+    void sendToAll(String type, Integer userId, String email,String phone, Object[] objs);
 }

+ 5 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/TenantInfoService.java

@@ -1,6 +1,7 @@
 package com.ym.mec.biz.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ym.mec.biz.dal.dao.TenantInfoDao;
 import com.ym.mec.biz.dal.dto.TenantInfoDto;
 import com.ym.mec.biz.dal.entity.TenantInfo;
 import com.ym.mec.biz.dal.entity.TenantProductInfo;
@@ -16,6 +17,8 @@ import java.util.Map;
 
 public interface TenantInfoService extends IService<TenantInfo> {
 
+    TenantInfoDao baseMapper();
+
     void addTenantInfo(TenantInfoDto dto);
 
     void updateTenantInfo(TenantInfoDto dto);
@@ -64,4 +67,6 @@ public interface TenantInfoService extends IService<TenantInfo> {
     Boolean testEmail();
 
     void updatePhone(String newPhone, String oldPhone);
+
+    void checkTenantState();
 }

+ 83 - 19
mec-biz/src/main/java/com/ym/mec/biz/service/impl/OrderPayOpsServiceImpl.java

@@ -1,35 +1,50 @@
 package com.ym.mec.biz.service.impl;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BiPredicate;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.redisson.api.RBucket;
+import org.redisson.api.RedissonClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.DigestUtils;
+
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.ym.mec.biz.dal.entity.StudentPaymentOrder;
+import com.ym.mec.biz.dal.entity.TenantConfig;
 import com.ym.mec.biz.dal.entity.TenantOrderRecord;
 import com.ym.mec.biz.dal.entity.TenantPaymentOrder;
 import com.ym.mec.biz.dal.enums.DealStatusEnum;
-import com.ym.mec.biz.service.*;
+import com.ym.mec.biz.service.CloudTeacherOrderService;
+import com.ym.mec.biz.service.OrderPayOpsService;
+import com.ym.mec.biz.service.StudentPaymentOrderService;
+import com.ym.mec.biz.service.TenantConfigService;
+import com.ym.mec.biz.service.TenantOrderRecordService;
+import com.ym.mec.biz.service.TenantPaymentOrderService;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.WrapperUtil;
 import com.ym.mec.thirdparty.adapay.ConfigInit;
 import com.ym.mec.thirdparty.adapay.Payment;
 import com.ym.mec.util.date.DateUtil;
 import com.ym.mec.util.http.HttpUtil;
-import org.redisson.api.RBucket;
-import org.redisson.api.RedissonClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.util.DigestUtils;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.text.SimpleDateFormat;
-import java.util.*;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.function.BiPredicate;
-import java.util.function.Consumer;
-import java.util.function.Function;
+import com.ym.mec.util.json.JsonUtil;
 
 /**
  * @author hgw
@@ -49,6 +64,9 @@ public class OrderPayOpsServiceImpl implements OrderPayOpsService {
     private RedissonClient redissonClient;
     @Autowired
     private CloudTeacherOrderService cloudTeacherOrderService;
+    
+    @Autowired
+    private TenantConfigService tenantConfigService;
 
     //支付类型
     private static final Map<String, Function<PaymentParam, Map<String, Object>>> checkOrderType = new HashMap<>();
@@ -100,6 +118,7 @@ public class OrderPayOpsServiceImpl implements OrderPayOpsService {
     private Map<String, Object> teacher(PaymentParam payParam) {
         Map<String, Object> payment;
         TenantPaymentOrder tenantPaymentOrder = tenantPaymentOrderService.queryByOrderNo(payParam.getOrderNo());
+        payParam.setTenantId(1);
         try {
             payment = checkOrderAndGetParam(payParam,
                     tenantPaymentOrder,
@@ -118,6 +137,7 @@ public class OrderPayOpsServiceImpl implements OrderPayOpsService {
     private Map<String, Object> tenantRecharge(PaymentParam payParam) {
         Map<String, Object> payment;
         TenantOrderRecord tenantOrderRecord = getTenantOrderRecord(payParam.getOrderNo());
+        payParam.setTenantId(tenantOrderRecord.getTenantId());
         payment = checkOrderGetPayment(payParam, tenantOrderRecord);
         //主动延迟检查订单
         log.info("executePayment delayCheckTenantRecharge >>>>> ");
@@ -128,6 +148,7 @@ public class OrderPayOpsServiceImpl implements OrderPayOpsService {
     // 云教练支付
     private Map<String, Object> cloudTeacherOrder(PaymentParam payParam) {
         TenantOrderRecord tenantOrderRecord = getTenantOrderRecord(payParam.getOrderNo());
+        payParam.setTenantId(tenantOrderRecord.getTenantId());
         Map<String, Object> payment = checkOrderGetPayment(payParam, tenantOrderRecord);
         // 云教练支付 主动延迟检查订单
         log.info("executePayment delayCheckCloudTeacherOrder >>>>> ");
@@ -138,6 +159,7 @@ public class OrderPayOpsServiceImpl implements OrderPayOpsService {
     //机构开通、续费付款
     private Map<String, Object> openOrRenew(PaymentParam payParam) {
         TenantOrderRecord tenantOrderRecord = getTenantOrderRecord(payParam.getOrderNo());
+        payParam.setTenantId(tenantOrderRecord.getTenantId());
         Map<String, Object> payment = checkOrderGetPayment(payParam, tenantOrderRecord);
         //主动延迟检查订单
         delayCheckTenant();
@@ -270,7 +292,39 @@ public class OrderPayOpsServiceImpl implements OrderPayOpsService {
         paymentParams.put("pay_amt", payParam.getAmount().setScale(2, BigDecimal.ROUND_HALF_UP));
         paymentParams.put("goods_title", payParam.getOrderSubject());
         paymentParams.put("goods_desc", payParam.getOrderBody());
-        paymentParams.put("pay_mode", "delay");
+        
+        if (payParam.getTenantId() == 1) {
+			// 延时分账
+			paymentParams.put("pay_mode", "delay");
+		} else {
+
+			StudentPaymentOrder paymentOrder = studentPaymentOrderService.findOrderByOrderNo(payParam.getOrderNo());
+			if (paymentOrder == null) {
+				throw new BizException("订单[{}]找不到", payParam.getOrderNo());
+			}
+
+			TenantConfig tenantConfig = tenantConfigService.queryByTenantId(payParam.getTenantId());
+			if (tenantConfig == null) {
+				throw new BizException("机构[{}]信息找不到", payParam.getTenantId());
+			}
+
+			// 实时分账
+			List<Map<String, Object>> divMemberList = new ArrayList<Map<String, Object>>();
+			Map<String, Object> divMember = new HashMap<String, Object>();
+			divMember.put("member_id", paymentOrder.getMerNos());
+			divMember.put("amount",
+					paymentOrder.getActualAmount().multiply(tenantConfig.getChargeRate()).divide(new BigDecimal(1000)).setScale(2, BigDecimal.ROUND_HALF_UP));
+			divMember.put("fee_flag", "Y");
+
+			divMemberList.add(divMember);
+
+			paymentParams.put("div_members", JsonUtil.toJSONString(divMemberList));
+
+		}
+        
+        //手续费收取模式:O-商户手续费账户扣取手续费,I-交易金额中扣取手续费;值为空时,默认值为I;若为O时,分账对象列表中不支持传入手续费承担方
+        paymentParams.put("fee_mode", "I");
+        
         return paymentParams;
     }
 
@@ -359,6 +413,7 @@ public class OrderPayOpsServiceImpl implements OrderPayOpsService {
         private String sign;
         private String code;
         private String platform;
+        private Integer tenantId;
 
         PaymentParam(BigDecimal amount, String orderNo, String payChannel, String returnUrl, String orderSubject,
                      String orderBody, String sign, String code, String platform) {
@@ -444,6 +499,15 @@ public class OrderPayOpsServiceImpl implements OrderPayOpsService {
         public void setPlatform(String platform) {
             this.platform = platform;
         }
+
+		public Integer getTenantId() {
+			return tenantId;
+		}
+
+		public void setTenantId(Integer tenantId) {
+			this.tenantId = tenantId;
+		}
     }
 
 }
+

+ 4 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/impl/StudentPaymentOrderServiceImpl.java

@@ -374,6 +374,10 @@ public class StudentPaymentOrderServiceImpl extends BaseServiceImpl<Long, Studen
     }
 
     private Boolean confirmOrder(StudentPaymentOrder order) {
+		// 只有大雅延迟分账,其他实时分账
+		if (order.getTenantId() != 1) {
+			return true;
+		}
         Date date = new Date();
         List<StudentPaymentRouteOrder> routeOrders = studentPaymentRouteOrderDao.getRouteOrders(order.getOrderNo());
         for (StudentPaymentRouteOrder routeOrder : routeOrders) {

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

@@ -4,6 +4,7 @@ import com.ym.mec.biz.dal.dao.SysEmployeePositionDao;
 import com.ym.mec.biz.dal.dao.SysPositionDao;
 import com.ym.mec.biz.dal.dao.TenantInfoDao;
 import com.ym.mec.biz.dal.dto.SimpleUserDto;
+import com.ym.mec.biz.dal.dto.SysEmployeePositionDto;
 import com.ym.mec.biz.dal.entity.SysEmployeePosition;
 import com.ym.mec.biz.dal.entity.TenantInfo;
 import com.ym.mec.biz.dal.enums.SysUserRoleEnum;
@@ -12,6 +13,7 @@ import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.service.impl.BaseServiceImpl;
 import com.ym.mec.common.tenant.TenantContextHolder;
 import com.ym.mec.util.collection.MapUtil;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -105,4 +107,9 @@ public class SysEmployeePositionServiceImpl extends BaseServiceImpl<Integer, Sys
 		Integer tenantId = TenantContextHolder.getTenantId();
 		return sysEmployeePositionDao.queryUserIdByRoleId(roleArr,organId,tenantId);
     }
+
+	@Override
+	public List<SysEmployeePositionDto> queryByUserId(Integer userId) {
+		return sysEmployeePositionDao.queryByUserId(userId);
+	}
 }

+ 24 - 5
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantAssetsInfoServiceImpl.java

@@ -1,15 +1,14 @@
 package com.ym.mec.biz.service.impl;
 
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 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.biz.service.*;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.WrapperUtil;
 import com.ym.mec.thirdparty.yqpay.DateUtils;
@@ -27,6 +26,8 @@ import java.util.*;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
+import static com.ym.mec.biz.service.impl.TenantInfoSendMsgServiceImpl.INSUFFICIENT;
+
 /**
  * 机构资产信息(TenantAssetsInfo)表服务实现类
  *
@@ -42,6 +43,10 @@ public class TenantAssetsInfoServiceImpl extends ServiceImpl<TenantAssetsInfoDao
     private TenantConfigService tenantConfigService;
     @Autowired
     private TenantCloudCourseRecordService tenantCloudCourseRecordService;
+    @Autowired
+    private TenantInfoSendMsgService tenantInfoSendMsgService;
+    @Autowired
+    private TenantInfoService tenantInfoService;
 
     private final Predicate<String> VipPredicate = (o) -> Objects.equals(o, CourseSchedule.CourseScheduleType.VIP.getCode());
 
@@ -137,8 +142,22 @@ public class TenantAssetsInfoServiceImpl extends ServiceImpl<TenantAssetsInfoDao
             //写流水
             insertRecord(course, coursePrice, 1);
             log.info("deductAmount >>>>>> coursePrice {}  tenantId {}", coursePrice, course.getTenantId());
-            //扣余额
-            baseMapper.deductAmount(coursePrice, course.getTenantId());
+            //查询余额信息
+            TenantAssetsInfo assetsInfo = baseMapper.selectOne(new QueryWrapper<TenantAssetsInfo>()
+                    .eq("tenant_id_", course.getTenantId()));
+            if (Objects.nonNull(assetsInfo)) {
+                //扣余额
+                baseMapper.deductAmount(coursePrice, course.getTenantId());
+                //当前余额
+                BigDecimal balance = assetsInfo.getBalance();
+                //当前余额 减 本次扣费 的剩余额度
+                BigDecimal after = balance.subtract(coursePrice);
+                //当前余额大于300 并且 本次扣除后剩余额度小于300 就发信息提醒
+                if (balance.compareTo(new BigDecimal(300)) > -1 && balance.compareTo(after) < 0) {
+                    TenantInfo t = tenantInfoService.getById(course.getTenantId());
+                    tenantInfoSendMsgService.sendToAll(INSUFFICIENT, t.getUserId(), t.getEmail(), t.getPhone(), new Object[]{t.getName()});
+                }
+            }
         });
 
     }

+ 53 - 16
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantInfoSendMsgServiceImpl.java

@@ -4,14 +4,17 @@ import com.ym.mec.biz.dal.enums.MessageTypeEnum;
 import com.ym.mec.biz.service.SysMessageService;
 import com.ym.mec.biz.service.TenantInfoSendMsgService;
 import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
+
+import static com.ym.mec.biz.dal.enums.MessageTypeEnum.*;
 
 @Service
 public class TenantInfoSendMsgServiceImpl implements TenantInfoSendMsgService {
@@ -24,39 +27,73 @@ public class TenantInfoSendMsgServiceImpl implements TenantInfoSendMsgService {
     public static final String OPEN = "open";
     //续费
     public static final String RENEW = "renew";
+    //即将到期提醒
+    public static final String EXPIRATION = "expiration";
+    //云教室余额不足
+    public static final String INSUFFICIENT = "insufficient";
 
-    //发送邮件和短信
-    public static final Object[] sendAll = {MessageSenderPluginContext.MessageSender.EMAIL, MessageSenderPluginContext.MessageSender.AWSMS};
     //开通
     private static final Map<MessageSenderPluginContext.MessageSender, MessageTypeEnum> openMsgEnum = new HashMap<>();
     //续费
     private static final Map<MessageSenderPluginContext.MessageSender, MessageTypeEnum> renewMsgEnum = new HashMap<>();
+    //即将到期提醒
+    private static final Map<MessageSenderPluginContext.MessageSender, MessageTypeEnum> expirationMsgEnum = new HashMap<>();
+    //云教室余额不足
+    private static final Map<MessageSenderPluginContext.MessageSender, MessageTypeEnum> insufficientMsgEnum = new HashMap<>();
     //init
     private static final Map<String, Map<MessageSenderPluginContext.MessageSender, MessageTypeEnum>> sendMsgTypeEn = new HashMap<>();
 
     static {
         //开通
-        openMsgEnum.put(MessageSenderPluginContext.MessageSender.EMAIL, MessageTypeEnum.EMAIL_TENANT_ACTIVATION_SUCCESSFUL);
-        openMsgEnum.put(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_TENANT_ACTIVATION_SUCCESSFUL);
+        openMsgEnum.put(MessageSenderPluginContext.MessageSender.EMAIL, EMAIL_TENANT_ACTIVATION_SUCCESSFUL);
+        openMsgEnum.put(MessageSenderPluginContext.MessageSender.AWSMS, SMS_TENANT_ACTIVATION_SUCCESSFUL);
         //续费
-        renewMsgEnum.put(MessageSenderPluginContext.MessageSender.EMAIL, MessageTypeEnum.EMAIL_TENANT_RENEWAL_SUCCESSFUL);
-        renewMsgEnum.put(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_TENANT_RENEWAL_SUCCESSFUL);
+        renewMsgEnum.put(MessageSenderPluginContext.MessageSender.EMAIL, EMAIL_TENANT_RENEWAL_SUCCESSFUL);
+        renewMsgEnum.put(MessageSenderPluginContext.MessageSender.AWSMS, SMS_TENANT_RENEWAL_SUCCESSFUL);
+        //即将到期提醒
+        expirationMsgEnum.put(MessageSenderPluginContext.MessageSender.EMAIL, EMAIL_TENANT_EXPIRATION_REMINDERS);
+        expirationMsgEnum.put(MessageSenderPluginContext.MessageSender.AWSMS, SMS_TENANT_EXPIRATION_REMINDERS);
+        //云教室余额不足
+        insufficientMsgEnum.put(MessageSenderPluginContext.MessageSender.EMAIL, EMAIL_TENANT_INSUFFICIENT_BALANCE);
+        insufficientMsgEnum.put(MessageSenderPluginContext.MessageSender.AWSMS, SMS_TENANT_INSUFFICIENT_BALANCE);
+
         //init
         sendMsgTypeEn.put(OPEN, openMsgEnum);
         sendMsgTypeEn.put(RENEW, renewMsgEnum);
+        sendMsgTypeEn.put(EXPIRATION, expirationMsgEnum);
+        sendMsgTypeEn.put(INSUFFICIENT, insufficientMsgEnum);
     }
 
-    //发送邮件及短信提醒
+    /**
+     * 发送邮件及短信提醒
+     *
+     * @param type   OPEN/RENEW/EXPIRATION之类的
+     * @param userId 机构用户id
+     * @param email  发送的地址 电话或者邮件
+     * @param objs   发送的信息
+     */
     @Override
-    public void sendToAll(String type, Integer userId, String email, Object... objs) {
-        Map<Integer, String> receivers = new HashMap<>();
-        receivers.put(userId, email);
-        Arrays.stream(sendAll).forEach(o -> {
-            MessageSenderPluginContext.MessageSender msgType = (MessageSenderPluginContext.MessageSender) o;
-            sysMessageService.batchSendMessage(msgType,
-                    sendMsgTypeEn.get(type).get(msgType), receivers, null, 0, null,
+    public void sendToAll(String type, Integer userId, String email, String phone, Object[] objs) {
+        Map<Integer, String> sendPar = new HashMap<>();
+        if (Objects.isNull(userId)) {
+            return;
+        }
+        if (StringUtils.isNotBlank(email)) {
+            sendPar.put(userId, email);
+            MessageSenderPluginContext.MessageSender emailEn = MessageSenderPluginContext.MessageSender.EMAIL;
+            sysMessageService.batchSendMessage(emailEn,
+                    sendMsgTypeEn.get(type).get(emailEn), sendPar, null, 0, null,
                     "SYSTEM", objs);
-        });
+        }
+
+        if (StringUtils.isNotBlank(phone)) {
+            MessageSenderPluginContext.MessageSender smsEn = MessageSenderPluginContext.MessageSender.AWSMS;
+            sendPar.put(userId, phone);
+            sysMessageService.batchSendMessage(smsEn,
+                    sendMsgTypeEn.get(type).get(smsEn), sendPar, null, 0, null,
+                    "SYSTEM", objs);
+        }
+
     }
 
 }

+ 61 - 17
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantInfoServiceImpl.java

@@ -50,10 +50,16 @@ import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
+import static com.ym.mec.biz.service.impl.TenantInfoSendMsgServiceImpl.*;
+
 @Service
 public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoDao, TenantInfo> implements TenantInfoService {
     private static final Logger log = LoggerFactory.getLogger(TenantInfoServiceImpl.class);
 
+    public TenantInfoDao baseMapper() {
+        return baseMapper;
+    }
+
     @Autowired
     private SysUserFeignService sysUserFeignService;
     @Autowired
@@ -88,6 +94,8 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoDao, TenantInfo
     private StudentService studentService;
     @Autowired
     private SysMessageService sysMessageService;
+    @Autowired
+    private TenantInfoSendMsgService tenantInfoSendMsgService;
 
     /**
      * 新增机构
@@ -335,12 +343,9 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoDao, TenantInfo
         Date expiryDate = getExpiryDate(productInfo.getExpiryCount(), productInfo.getExpiryUnit(), now);
         productInfo.setExpiryDate(expiryDate);
         tenantProductInfoService.updateById(productInfo);
-        //发送邮件提醒
-        Map<Integer, String> receivers = new HashMap<>();
-        receivers.put(tenantInfo.getUserId(), tenantInfo.getEmail());
-        sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.EMAIL,
-                MessageTypeEnum.EMAIL_TENANT_ACTIVATION_SUCCESSFUL, receivers, null, 0, null,
-                "SYSTEM", tenantInfo.getName(), tenantInfo.getPhone(), "123456", "https://online.dayaedu.com");
+        //发送邮件及短信提醒
+        Object[] msg = {tenantInfo.getName(), tenantInfo.getPhone(), "123456", "https://online.dayaedu.com"};
+        tenantInfoSendMsgService.sendToAll(OPEN, tenantInfo.getUserId(), tenantInfo.getEmail(), tenantInfo.getPhone(), msg);
         //释放锁
         bucket.delete();
     }
@@ -499,14 +504,14 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoDao, TenantInfo
                     1,//临时写死
                     tenantEnum.getCode()
             );
+            //操作续费信息,把续费周期存起来
+            opsRenewInfo(tenantId).set(val, 1, TimeUnit.HOURS);
         } else {
             //续费成功
             renewSuccess(val, productInfo, amount);
             orderState = 1;
         }
         createOrderRecord(tenantId, amount, orderNo, tenantEnum, orderState);
-        //写入续费信息
-        opsRenewInfo(tenantId).set(val, 1, TimeUnit.HOURS);
         log.info("tenant pay >>>>> {} ", result);
         return result;
     }
@@ -525,6 +530,13 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoDao, TenantInfo
      * @param amount      续费总金额
      */
     public void renewSuccess(Integer val, TenantProductInfo productInfo, BigDecimal amount) {
+        Integer tenantId = productInfo.getTenantId();
+        RBucket<Object> bucket = redissonClient.getBucket("tenant_renew_success:" + tenantId);
+        if (!bucket.trySet(tenantId, 1, TimeUnit.MINUTES)) {
+            //防止重复修改数据
+            return;
+        }
+
         Date expiryDate;
         Date now = new Date();
         if (productInfo.getExpiryDate().compareTo(now) > 0) {
@@ -539,15 +551,12 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoDao, TenantInfo
         productInfo.setExpiryCount(productInfo.getExpiryCount() + val);
         tenantProductInfoService.updateById(productInfo);
 
-        TenantInfo tenantInfo = this.getById(productInfo.getTenantId());
-
-        //发送邮件提醒
-        Map<Integer, String> receivers = new HashMap<>();
-        receivers.put(tenantInfo.getUserId(), tenantInfo.getEmail());
-        sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.EMAIL,
-                MessageTypeEnum.EMAIL_TENANT_RENEWAL_SUCCESSFUL, receivers, null, 0, null,
-                "SYSTEM", tenantInfo.getName());
-
+        TenantInfo tenantInfo = this.getById(tenantId);
+        //发送邮件及短信提醒
+        Object[] msg = {tenantInfo.getName()};
+        tenantInfoSendMsgService.sendToAll(RENEW, tenantInfo.getUserId(), tenantInfo.getEmail(), tenantInfo.getPhone(), msg);
+        //释放锁
+        bucket.delete();
     }
 
     private TenantProductInfo getProductInfo(Integer tenantId) {
@@ -798,6 +807,41 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoDao, TenantInfo
         baseMapper.updatePhone(newPhone, oldPhone);
     }
 
+
+    /**
+     * 监测机构状态
+     */
+    public void checkTenantState() {
+        Date now = LocalDate.now().toDate();
+
+        //查询还差30天和1天过期的机构,并发送邮件和短信
+        Integer[] days = {30, 1};
+        Arrays.stream(days).forEach(d -> checkAndSend(now, d));
+
+        //查询过期并且没有停用的机构,将其停用
+        Date maturity = DateUtils.addDays(now, -1);
+        List<TenantInfo> maturityTenant = baseMapper.queryExpiryTenant(maturity);
+        maturityTenant.forEach(t -> {
+            t.setState(2);
+            t.setUpdatedBy(-1);
+            t.setUpdatedTime(now);
+            this.updateById(t);
+        });
+    }
+
+    private void checkAndSend(Date now, int i) {
+        Date one = DateUtils.addDays(now, i);
+        List<TenantInfo> oneTenant = baseMapper.queryExpiryTenant(one);
+        send(oneTenant, DateUtils.formatDate(one, "yyyy年MM月dd日"));
+    }
+
+    private void send(List<TenantInfo> infoList, String dateStr) {
+        infoList.forEach(t -> {
+            Object[] objects = {t.getName(), dateStr};
+            tenantInfoSendMsgService.sendToAll(EXPIRATION, t.getUserId(), t.getEmail(), t.getPhone(), objects);
+        });
+    }
+
     @Override
     public TenantInfo queryTenantInfoByOrgan(Integer organId) {
         return baseMapper.queryTenantInfoByOrgan(organId);

+ 13 - 10
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantOrderRecordServiceImpl.java

@@ -53,7 +53,16 @@ public class TenantOrderRecordServiceImpl extends ServiceImpl<TenantOrderRecordD
     private TenantAssetsInfoService assetsInfoService;
 
     //订单不存在
-    public static final String PAYMENT_ID_NOT_EXISTS = "payment_id_not_exists";
+    private static final String PAYMENT_ID_NOT_EXISTS = "payment_id_not_exists";
+
+    private static final Map<String, Consumer<TenantOrderRecord>> checkOrder = new HashMap<>();
+
+    {
+        //开通缴费
+        checkOrder.put(TenantOrderRecordEnum.TENANT_OPEN.getCode(), this::open);
+        //续费
+        checkOrder.put(TenantOrderRecordEnum.TENANT_RENEW.getCode(), this::renew);
+    }
 
     @Override
     public PageInfo<TenantOrderRecord> queryPage(TenantOrderRecordDto dto) {
@@ -108,14 +117,6 @@ public class TenantOrderRecordServiceImpl extends ServiceImpl<TenantOrderRecordD
         return result;
     }
 
-    private static final Map<String, Consumer<TenantOrderRecord>> checkOrder = new HashMap<>();
-    {
-        //开通缴费
-        checkOrder.put(TenantOrderRecordEnum.TENANT_OPEN.getCode(), this::open);
-        //续费
-        checkOrder.put(TenantOrderRecordEnum.TENANT_RENEW.getCode(), this::renew);
-    }
-
     @Override
     public void checkTenantOrder() {
         RBucket<Object> bucket = redissonClient.getBucket("tenant_check_order");
@@ -162,9 +163,11 @@ public class TenantOrderRecordServiceImpl extends ServiceImpl<TenantOrderRecordD
         TenantProductInfo productInfo = tenantProductInfoService.getOne(new WrapperUtil<TenantProductInfo>()
                 .hasEq("tenant_id_", record.getTenantId()).queryWrapper().eq("using_", 0));
         //获取机构续费时长
-        Integer val = (Integer) tenantInfoService.opsRenewInfo(record.getTenantId()).get();
+        RBucket<Object> bucket = tenantInfoService.opsRenewInfo(record.getTenantId());
+        Integer val = (Integer) bucket.get();
         //修改产品信息
         tenantInfoService.renewSuccess(val, productInfo, record.getActualAmount());
+        bucket.delete();
     }
 
     //主动去第三方查询订单状态

+ 2 - 2
mec-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -1110,7 +1110,7 @@
         CONCAT(cs.class_date_,' ',cs.end_class_time_) end_class_time_,
         cs.actual_teacher_id_ teacher_id_,
         cs.teach_mode_,
-        s.name_ school_name
+        s.name_ school_name_
         FROM course_schedule_student_payment cssp
         LEFT JOIN student_attendance sa ON cssp.course_schedule_id_ = sa.course_schedule_id_ AND cssp.user_id_ =
         sa.user_id_
@@ -1143,7 +1143,7 @@
                CONCAT(cs.class_date_, ' ', cs.end_class_time_)   end_class_time_,
                cs.teach_mode_,
                cs.class_group_id_,
-        		s.name_ school_name
+        		s.name_ school_name_
         FROM class_group_student_mapper cgsm
                  LEFT JOIN course_schedule cs ON cs.class_group_id_ = cgsm.class_group_id_
         		left join school s on s.id_ = cs.schoole_id_

+ 11 - 0
mec-biz/src/main/resources/config/mybatis/SysEmployeePositionMapper.xml

@@ -11,6 +11,11 @@
 		<result column="role_id_" property="roleId" />
 		<result column="tenant_id_" property="tenantId" />
 	</resultMap>
+		
+	<resultMap type="com.ym.mec.biz.dal.dto.SysEmployeePositionDto" id="SysEmployeePositionDto">
+		<result column="position_name_" property="positionName" />
+		<result column="position_code_" property="positionCode" />
+	</resultMap>
 	
 	<!-- 根据主键查询一条记录 -->
 	<select id="get" resultMap="SysEmployeePosition" parameterType="java.util.Map">
@@ -109,4 +114,10 @@
 			#{role}
 		</foreach>
 	</select>
+	
+	<select id="queryByUserId" resultMap="SysEmployeePositionDto">
+		SELECT sep.*,sp.role_name_ position_name_,sp.role_code_ position_code_ FROM sys_employee_position sep
+		LEFT JOIN sys_position sp ON sp.id_ = sep.role_id_
+		WHERE sep.user_id_ = #{userId}
+	</select>
 </mapper>

+ 34 - 0
mec-biz/src/main/resources/config/mybatis/TenantInfoMapper.xml

@@ -94,6 +94,7 @@
             </if>
         </where>
     </select>
+
     <select id="queryTenantInfoProductSumm" resultType="com.ym.mec.biz.dal.entity.TenantProductSumm">
             SELECT t.*, ps.name_ as serverName,
                    tp.pay_date_ as expiryDate,
@@ -110,12 +111,45 @@
                      left join platform_serve_detail psd on tp.serve_detail_id_ = psd.id_
             where t.id_ = #{tenantId}
     </select>
+
     <select id="getOpenTenant" resultType="com.ym.mec.biz.dal.entity.TenantInfo">
         SELECT * FROM tenant_info WHERE id_ = #{tenantId} AND state_ = 1
     </select>
+
     <select id="queryTenantInfoByOrgan" resultType="com.ym.mec.biz.dal.entity.TenantInfo">
         select * from tenant_info
         where id_ = (select tenant_id_ from organization where id_ = #{organId})
     </select>
 
+    <select id="queryExpiryTenant" resultMap="BaseResultMap">
+        SELECT a.id_,
+               a.name_,
+               a.contacts_,
+               a.phone_,
+               address_,
+               a.email_,
+               a.logo_,
+               a.a.customer_service_phone_,
+               a.remark_,
+               a.domain_name_,
+               a.data_source_,
+               a.pay_state_,
+               a.state_,
+               a.created_by_,
+               a.created_time_,
+               a.updated_by_,
+               a.updated_time_,
+               a.tsign_code_,
+               a.tsign_name_,
+               a.area_id_,
+               a.user_id_
+        FROM `tenant_info` AS a
+                 LEFT JOIN `tenant_product_info` AS b
+                           ON a.id_ = b.`tenant_id_`
+        WHERE a.`state_` = 1
+          AND a.`pay_state_` = 1
+          AND b.`using_` = 0
+          AND b.`expiry_date_` = #{expiryDate}
+    </select>
+
 </mapper>

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

@@ -151,7 +151,7 @@ public class WrapperUtil<T> {
     }
 
     public static List<String> collectToList(String[] b) {
-        return Arrays.stream(b).filter(StrPredicate).collect(Collectors.toList());
+        return Arrays.stream(b).filter(StrPredicate).distinct().collect(Collectors.toList());
     }
 
     /**

+ 34 - 0
mec-teacher/src/main/java/com/ym/mec/teacher/controller/TenantConfigController.java

@@ -0,0 +1,34 @@
+package com.ym.mec.teacher.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.ym.mec.biz.dal.entity.TenantConfig;
+import com.ym.mec.biz.service.TenantConfigService;
+import com.ym.mec.common.controller.BaseController;
+import com.ym.mec.common.tenant.TenantContextHolder;
+
+@RequestMapping("tenantConfig")
+@Api(tags = "机构配置管理")
+@RestController
+public class TenantConfigController extends BaseController {
+
+	@Autowired
+	private TenantConfigService tenantConfigService;
+
+	@ApiOperation("修改机构启用停用状态")
+	@GetMapping(value = "/get")
+	@PreAuthorize("@pcs.hasPermissions('tenantConfig/get')")
+	public Object get() {
+		// 查询云教室扣费标准
+		TenantConfig tenantConfig = tenantConfigService.queryByTenantId(TenantContextHolder.getTenantId());
+
+		return succeed(tenantConfig);
+	}
+}

+ 24 - 14
mec-web/src/main/java/com/ym/mec/web/controller/EmployeeController.java

@@ -1,31 +1,34 @@
 package com.ym.mec.web.controller;
 
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
 import com.ym.mec.auth.api.client.SysUserFeignService;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.dao.EmployeeDao;
 import com.ym.mec.biz.dal.dto.EmployeeLevelDto;
-import com.ym.mec.biz.dal.dto.SimpleUserDto;
+import com.ym.mec.biz.dal.dto.SysEmployeePositionDto;
 import com.ym.mec.biz.dal.entity.Employee;
 import com.ym.mec.biz.dal.enums.EmployeeOperateEnum;
-import com.ym.mec.biz.dal.enums.EmployeeRoleEnum;
 import com.ym.mec.biz.dal.page.EmployeeQueryInfo;
 import com.ym.mec.biz.service.EmployeeService;
 import com.ym.mec.biz.service.OrganizationService;
 import com.ym.mec.biz.service.StudentManageService;
+import com.ym.mec.biz.service.SysEmployeePositionService;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.HttpResponseResult;
-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.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Objects;
 
 /**
  * @Author Joburgess
@@ -46,6 +49,8 @@ public class EmployeeController extends BaseController {
     private OrganizationService organizationService;
     @Autowired
     private EmployeeDao employeeDao;
+    @Autowired
+    private SysEmployeePositionService sysEmployeePositionService;
 
     @ApiOperation(value = "根据部门获取下面的员工")
     @GetMapping("/queryEmployByOrganId")
@@ -145,6 +150,11 @@ public class EmployeeController extends BaseController {
             sysUser.setBankCard(employee.getBankCard());
             sysUser.setOpenBankAddress(employee.getOpenBankAddress());
             sysUser.setPostDeptIds(employee.getPostDeptIds());
+            
+            List<SysEmployeePositionDto> sysEmployeePositionDtoList = sysEmployeePositionService.queryByUserId(sysUser.getId());
+            if(sysEmployeePositionDtoList != null && sysEmployeePositionDtoList.size() > 0){
+            	sysUser.setPositionName(sysEmployeePositionDtoList.stream().map(SysEmployeePositionDto :: getPositionName).collect(Collectors.joining(",")));
+            }
             return succeed(sysUser);
         }
         return failed("获取用户信息失败");

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

@@ -529,4 +529,10 @@ public class TaskController extends BaseController {
     public void checkTenantOrder(){
         tenantOrderRecordService.checkTenantOrder();
     }
+
+    @ApiOperation("每晚12点-检查机构状态")
+    @GetMapping(value = "/checkTenantState")
+    public void checkTenantState(){
+        tenantInfoService.checkTenantState();
+    }
 }