|  | @@ -7,6 +7,7 @@ import com.ym.mec.biz.service.*;
 | 
	
		
			
				|  |  |  import com.ym.mec.common.dal.BaseDAO;
 | 
	
		
			
				|  |  |  import com.ym.mec.common.exception.BizException;
 | 
	
		
			
				|  |  |  import com.ym.mec.common.service.impl.BaseServiceImpl;
 | 
	
		
			
				|  |  | +import com.ym.mec.util.collection.MapUtil;
 | 
	
		
			
				|  |  |  import com.ym.mec.util.date.DateUtil;
 | 
	
		
			
				|  |  |  import org.slf4j.Logger;
 | 
	
		
			
				|  |  |  import org.slf4j.LoggerFactory;
 | 
	
	
		
			
				|  | @@ -20,235 +21,364 @@ import java.util.*;
 | 
	
		
			
				|  |  |  import java.util.stream.Collectors;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  @Service
 | 
	
		
			
				|  |  | -public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long, CourseScheduleTeacherSalary>  implements CourseScheduleTeacherSalaryService {
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | -	@Autowired
 | 
	
		
			
				|  |  | -	private CourseScheduleTeacherSalaryDao courseScheduleTeacherSalaryDao;
 | 
	
		
			
				|  |  | -	@Autowired
 | 
	
		
			
				|  |  | -	private VipGroupActivityDao vipGroupActivityDao;
 | 
	
		
			
				|  |  | -	@Autowired
 | 
	
		
			
				|  |  | -	private CourseScheduleComplaintsDao courseScheduleComplaintsDao;
 | 
	
		
			
				|  |  | -	@Autowired
 | 
	
		
			
				|  |  | -	private CourseScheduleStudentPaymentDao courseScheduleStudentPaymentDao;
 | 
	
		
			
				|  |  | -	@Autowired
 | 
	
		
			
				|  |  | -	private SysUserCashAccountService sysUserCashAccountService;
 | 
	
		
			
				|  |  | -	@Autowired
 | 
	
		
			
				|  |  | -	private VipGroupService vipGroupService;
 | 
	
		
			
				|  |  | -	@Autowired
 | 
	
		
			
				|  |  | -	private SchoolService schoolService;
 | 
	
		
			
				|  |  | -	@Autowired
 | 
	
		
			
				|  |  | -	private CourseScheduleDao courseScheduleDao;
 | 
	
		
			
				|  |  | -	@Autowired
 | 
	
		
			
				|  |  | -	private TeacherDefaultMusicGroupSalaryDao teacherDefaultMusicGroupSalaryDao;
 | 
	
		
			
				|  |  | -	
 | 
	
		
			
				|  |  | -	@Autowired
 | 
	
		
			
				|  |  | -	private SysConfigDao sysConfigDao;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	private static final Logger LOGGER = LoggerFactory
 | 
	
		
			
				|  |  | -			.getLogger(CourseScheduleTeacherSalaryServiceImpl.class);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	@Override
 | 
	
		
			
				|  |  | -	public BaseDAO<Long, CourseScheduleTeacherSalary> getDAO() {
 | 
	
		
			
				|  |  | -		return courseScheduleTeacherSalaryDao;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	@Override
 | 
	
		
			
				|  |  | -	public int createCourseScheduleTeacherVipSalary(VipGroup vipGroup,
 | 
	
		
			
				|  |  | -													List<CourseSchedule> vipCourseSchedules,
 | 
	
		
			
				|  |  | -													BigDecimal onlineTeacherSalary,
 | 
	
		
			
				|  |  | -													BigDecimal offlineTeacherSalary) {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		School school = schoolService.get(vipGroup.getTeacherSchoolId());
 | 
	
		
			
				|  |  | -		if(Objects.isNull(school)){
 | 
	
		
			
				|  |  | -			throw new BizException("未找到该教学点");
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		//获取活动信息
 | 
	
		
			
				|  |  | -		VipGroupActivity vipGroupActivity = vipGroupActivityDao.get(vipGroup.getVipGroupActivityId().intValue());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaries=new ArrayList<>();
 | 
	
		
			
				|  |  | -		Map<TeachModeEnum, List<CourseSchedule>> courseScheduleGroupByTeachMode = vipCourseSchedules.stream().collect(Collectors.groupingBy(CourseSchedule::getTeachMode));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		for(TeachModeEnum teachModeEnum:courseScheduleGroupByTeachMode.keySet()){
 | 
	
		
			
				|  |  | -			List<CourseSchedule> courseSchedules = courseScheduleGroupByTeachMode.get(teachModeEnum)
 | 
	
		
			
				|  |  | -					.stream()
 | 
	
		
			
				|  |  | -					.sorted(Comparator.comparing(CourseSchedule::getStartClassTime)).collect(Collectors.toList());
 | 
	
		
			
				|  |  | -			for(int i=0;i<courseSchedules.size();i++){
 | 
	
		
			
				|  |  | -				//创建教师课程薪水记录
 | 
	
		
			
				|  |  | -				CourseScheduleTeacherSalary courseScheduleTeacherSalary=new CourseScheduleTeacherSalary();
 | 
	
		
			
				|  |  | -				courseScheduleTeacherSalary.setCourseScheduleId(courseSchedules.get(i).getId());
 | 
	
		
			
				|  |  | -				courseScheduleTeacherSalary.setTeacherRole(TeachTypeEnum.BISHOP);
 | 
	
		
			
				|  |  | -				courseScheduleTeacherSalary.setUserId(courseSchedules.get(i).getActualTeacherId().intValue());
 | 
	
		
			
				|  |  | -				courseScheduleTeacherSalary.setClassGroupId(courseSchedules.get(i).getClassGroupId());
 | 
	
		
			
				|  |  | -				courseScheduleTeacherSalary.setSubsidy(school.getSubsidy());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -				Map<String,BigDecimal> feeInfo = vipGroupService.countVipGroupPredictFee(vipGroup,
 | 
	
		
			
				|  |  | -						courseSchedules.get(i).getActualTeacherId().intValue(),
 | 
	
		
			
				|  |  | -						onlineTeacherSalary,
 | 
	
		
			
				|  |  | -						offlineTeacherSalary,
 | 
	
		
			
				|  |  | -						false,
 | 
	
		
			
				|  |  | -						false);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -				if(vipGroupActivity.getType()== VipGroupActivityTypeEnum.GIVE_CLASS
 | 
	
		
			
				|  |  | -						&&vipGroup.getGiveTeachMode()==teachModeEnum
 | 
	
		
			
				|  |  | -						&&i>=Integer.parseInt(vipGroupActivity.getAttribute1())
 | 
	
		
			
				|  |  | -						&&"0".equals(vipGroupActivity.getGiveClassPaySalaryFlag())){
 | 
	
		
			
				|  |  | -					courseScheduleTeacherSalary.setExpectSalary(new BigDecimal(0));
 | 
	
		
			
				|  |  | -				}else {
 | 
	
		
			
				|  |  | -					if(teachModeEnum==TeachModeEnum.ONLINE){
 | 
	
		
			
				|  |  | -						courseScheduleTeacherSalary.setExpectSalary(feeInfo.get("onlineTeacherSalary"));
 | 
	
		
			
				|  |  | -					}else{
 | 
	
		
			
				|  |  | -						courseScheduleTeacherSalary.setExpectSalary(feeInfo.get("offlineTeacherSalary"));
 | 
	
		
			
				|  |  | -					}
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -				courseScheduleTeacherSalaries.add(courseScheduleTeacherSalary);
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		return courseScheduleTeacherSalaryDao.batchInsert(courseScheduleTeacherSalaries);
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	@Override
 | 
	
		
			
				|  |  | -	@Transactional(rollbackFor = Exception.class)
 | 
	
		
			
				|  |  | -	public void teacherSalarySettlement() {
 | 
	
		
			
				|  |  | -		
 | 
	
		
			
				|  |  | -		int days = Integer.parseInt(sysConfigDao.findConfigValue(SysConfigService.VIP_SETTLEMENT_CYCLE));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		//获取教师未结算课程记录
 | 
	
		
			
				|  |  | -		List<CourseScheduleTeacherSalary> someDayAgoTeacherCourseSalaryNoSettlement = courseScheduleTeacherSalaryDao.findSomeDayAgoTeacherCourseSalaryNoSettlement(days);
 | 
	
		
			
				|  |  | -		if(CollectionUtils.isEmpty(someDayAgoTeacherCourseSalaryNoSettlement)){
 | 
	
		
			
				|  |  | -			LOGGER.info("未获取到未结算课酬记录!");
 | 
	
		
			
				|  |  | -			return;
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		Date now=new Date();
 | 
	
		
			
				|  |  | -		//获取未结算课程编号列表
 | 
	
		
			
				|  |  | -		List<Long> courseScheduleIds = someDayAgoTeacherCourseSalaryNoSettlement.stream().map(CourseScheduleTeacherSalary::getCourseScheduleId).collect(Collectors.toList());
 | 
	
		
			
				|  |  | -		//获取未结算课程投诉记录
 | 
	
		
			
				|  |  | -		List<CourseScheduleComplaints> courseScheduleComplaints = courseScheduleComplaintsDao.findByCourseScheduleIds(courseScheduleIds);
 | 
	
		
			
				|  |  | -		//获取未结算课程学生缴费信息
 | 
	
		
			
				|  |  | -		List<CourseScheduleStudentPayment> courseScheduleStudentPayments = courseScheduleStudentPaymentDao.findByCourseScheduleIds(courseScheduleIds);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		//根据课程将投诉信息分组
 | 
	
		
			
				|  |  | -		Map<Long, List<CourseScheduleComplaints>> complaintsGroupByCourse = courseScheduleComplaints.stream().collect(Collectors.groupingBy(CourseScheduleComplaints::getCourseScheduleId));
 | 
	
		
			
				|  |  | -		//根据课程将学生缴费信息分组
 | 
	
		
			
				|  |  | -		Map<Long, List<CourseScheduleStudentPayment>> studentPaymentGroupByCourse = courseScheduleStudentPayments.stream().collect(Collectors.groupingBy(CourseScheduleStudentPayment::getCourseScheduleId));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		//需更新教师课程结算记录
 | 
	
		
			
				|  |  | -		List<CourseScheduleTeacherSalary> updateTeacherSalarys=new ArrayList<>();
 | 
	
		
			
				|  |  | -		//需更新学生课程缴费记录
 | 
	
		
			
				|  |  | -		List<CourseScheduleStudentPayment> updateStudentPayments=new ArrayList<>();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		//用户账户自己变动信息列表
 | 
	
		
			
				|  |  | -		List<SysUserCashAccountDetail> userCashAccountDetails=new ArrayList<>();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		//处理课酬信息
 | 
	
		
			
				|  |  | -		someDayAgoTeacherCourseSalaryNoSettlement.forEach(courseScheduleTeacherSalary -> {
 | 
	
		
			
				|  |  | -			//获取当前课程学生缴费记录
 | 
	
		
			
				|  |  | -			List<CourseScheduleStudentPayment> studentPaymentsWithCourse = studentPaymentGroupByCourse.get(courseScheduleTeacherSalary.getCourseScheduleId());
 | 
	
		
			
				|  |  | -			//当前课程缴费学生数量
 | 
	
		
			
				|  |  | -			BigDecimal courseStudentNum=new BigDecimal(studentPaymentsWithCourse.size());
 | 
	
		
			
				|  |  | -			//教师预计课酬
 | 
	
		
			
				|  |  | -			BigDecimal expectSalary=courseScheduleTeacherSalary.getExpectSalary();
 | 
	
		
			
				|  |  | -			//当前课程每个学生平均课酬
 | 
	
		
			
				|  |  | -			BigDecimal avgSalary=expectSalary.divide(courseStudentNum);
 | 
	
		
			
				|  |  | -			//教师当前课程责任总占比,当前课程应得课酬
 | 
	
		
			
				|  |  | -			BigDecimal teacherLiabilityAllratio;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			//当前课程学生投诉记录
 | 
	
		
			
				|  |  | -			List<CourseScheduleComplaints> courseStudentComplaints=complaintsGroupByCourse.get(courseScheduleTeacherSalary.getCourseScheduleId());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			//如果存在投诉记录,需要扣除相应费用
 | 
	
		
			
				|  |  | -			if(Objects.nonNull(courseStudentComplaints)){
 | 
	
		
			
				|  |  | -				//获取审批中的投诉
 | 
	
		
			
				|  |  | -				List<CourseScheduleComplaints> auditIng = courseStudentComplaints.stream().filter(courseScheduleComplaint -> courseScheduleComplaint.getStatus() == AuditStatusEnum.ING).collect(Collectors.toList());
 | 
	
		
			
				|  |  | -				if(!CollectionUtils.isEmpty(auditIng)){
 | 
	
		
			
				|  |  | -					//如果当前课程存在未处理的投诉,则不做结算处理
 | 
	
		
			
				|  |  | -					return;
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -				//计算教师责任总占比
 | 
	
		
			
				|  |  | -				double teacherLiabilityRatioSum = courseStudentComplaints.stream().mapToDouble(CourseScheduleComplaints::getTeacherLiabilityRatio).sum();
 | 
	
		
			
				|  |  | -				teacherLiabilityAllratio=new BigDecimal(teacherLiabilityRatioSum);
 | 
	
		
			
				|  |  | -			}else{
 | 
	
		
			
				|  |  | -				//如果没有投诉,则教师和学生的责任占比为0
 | 
	
		
			
				|  |  | -				teacherLiabilityAllratio=new BigDecimal(0);
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			//教师应扣除费用
 | 
	
		
			
				|  |  | -			BigDecimal deductPrice=avgSalary.multiply(teacherLiabilityAllratio);
 | 
	
		
			
				|  |  | -			//教师实际课酬
 | 
	
		
			
				|  |  | -			BigDecimal actualSalary=expectSalary.subtract(deductPrice).add(courseScheduleTeacherSalary.getSubsidy());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			//更新教师结算信息
 | 
	
		
			
				|  |  | -			courseScheduleTeacherSalary.setActualSalary(actualSalary);
 | 
	
		
			
				|  |  | -			courseScheduleTeacherSalary.setSettlementTime(now);
 | 
	
		
			
				|  |  | -			courseScheduleTeacherSalaryDao.update(courseScheduleTeacherSalary);
 | 
	
		
			
				|  |  | -			updateTeacherSalarys.add(courseScheduleTeacherSalary);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			//生成教师账户资金变动记录
 | 
	
		
			
				|  |  | -			sysUserCashAccountService.updateBalance(courseScheduleTeacherSalary.getUserId(),actualSalary);
 | 
	
		
			
				|  |  | -			SysUserCashAccount teacherCashAccount = sysUserCashAccountService.get(courseScheduleTeacherSalary.getUserId().intValue());
 | 
	
		
			
				|  |  | -			SysUserCashAccountDetail teacherCashAccountDetail=new SysUserCashAccountDetail();
 | 
	
		
			
				|  |  | -			teacherCashAccountDetail.setUserId(courseScheduleTeacherSalary.getUserId());
 | 
	
		
			
				|  |  | -			teacherCashAccountDetail.setType(PlatformCashAccountDetailTypeEnum.REFUNDS);
 | 
	
		
			
				|  |  | -			teacherCashAccountDetail.setStatus(DealStatusEnum.SUCCESS);
 | 
	
		
			
				|  |  | -			teacherCashAccountDetail.setAmount(actualSalary);
 | 
	
		
			
				|  |  | -			teacherCashAccountDetail.setBalance(teacherCashAccount.getBalance());
 | 
	
		
			
				|  |  | -			teacherCashAccountDetail.setAttribute(courseScheduleTeacherSalary.getCourseScheduleId().toString());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			userCashAccountDetails.add(teacherCashAccountDetail);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			//根据学生进行投诉分组
 | 
	
		
			
				|  |  | -			Map<Integer, List<CourseScheduleComplaints>> complainsGroupByStudent = courseStudentComplaints.stream().collect(Collectors.groupingBy(CourseScheduleComplaints::getUserId));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			//计算学生当前课程应缴费用
 | 
	
		
			
				|  |  | -			studentPaymentsWithCourse.forEach(studentPayment -> {
 | 
	
		
			
				|  |  | -				//当前课程学生应缴费用
 | 
	
		
			
				|  |  | -				BigDecimal studentExpectPrice=studentPayment.getExpectPrice();
 | 
	
		
			
				|  |  | -				//当前课程学生责任占比
 | 
	
		
			
				|  |  | -				BigDecimal studentLiabilityRatio;
 | 
	
		
			
				|  |  | -				List<CourseScheduleComplaints> currentCourseScheduleComplaints = complainsGroupByStudent.get(studentPayment.getUserId());
 | 
	
		
			
				|  |  | -				if(CollectionUtils.isEmpty(currentCourseScheduleComplaints)){
 | 
	
		
			
				|  |  | -					Double temp=currentCourseScheduleComplaints.get(0).getStudentLiabilityRatio();
 | 
	
		
			
				|  |  | -					studentLiabilityRatio=new BigDecimal(temp);
 | 
	
		
			
				|  |  | -				}else{
 | 
	
		
			
				|  |  | -					studentLiabilityRatio=new BigDecimal(0);
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -				//当前课程学生应退费用
 | 
	
		
			
				|  |  | -				BigDecimal returnPrice=studentExpectPrice.multiply(studentLiabilityRatio);
 | 
	
		
			
				|  |  | -				//当前课程学生实际缴费
 | 
	
		
			
				|  |  | -				BigDecimal actualPrice=expectSalary.subtract(returnPrice);
 | 
	
		
			
				|  |  | -				//更新学生结算信息
 | 
	
		
			
				|  |  | -				studentPayment.setActualPrice(actualPrice);
 | 
	
		
			
				|  |  | -				studentPayment.setSettlementTime(now);
 | 
	
		
			
				|  |  | -				courseScheduleStudentPaymentDao.update(studentPayment);
 | 
	
		
			
				|  |  | -				updateStudentPayments.add(studentPayment);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -				//生成学生账户资金变动记录
 | 
	
		
			
				|  |  | -				sysUserCashAccountService.updateBalance(studentPayment.getUserId(),returnPrice);
 | 
	
		
			
				|  |  | -				SysUserCashAccount studentCashAccount = sysUserCashAccountService.get(studentPayment.getUserId().intValue());
 | 
	
		
			
				|  |  | -				SysUserCashAccountDetail studentAccountDetail=new SysUserCashAccountDetail();
 | 
	
		
			
				|  |  | -				studentAccountDetail.setUserId(studentPayment.getUserId());
 | 
	
		
			
				|  |  | -				studentAccountDetail.setType(PlatformCashAccountDetailTypeEnum.REFUNDS);
 | 
	
		
			
				|  |  | -				studentAccountDetail.setStatus(DealStatusEnum.SUCCESS);
 | 
	
		
			
				|  |  | -				studentAccountDetail.setAmount(returnPrice);
 | 
	
		
			
				|  |  | -				studentAccountDetail.setBalance(studentCashAccount.getBalance());
 | 
	
		
			
				|  |  | -				studentAccountDetail.setAttribute(courseScheduleTeacherSalary.getCourseScheduleId().toString());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -				userCashAccountDetails.add(studentAccountDetail);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			});
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		});
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	@Override
 | 
	
		
			
				|  |  | -	public void musicGroupTeacherSalarySettlement() {
 | 
	
		
			
				|  |  | -		Date now=new Date();
 | 
	
		
			
				|  |  | -		Date yesterday= DateUtil.addDays1(now,-1);
 | 
	
		
			
				|  |  | -		List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaryList = new ArrayList<>();
 | 
	
		
			
				|  |  | -		//获取昨天的课程计划
 | 
	
		
			
				|  |  | -		List<CourseSchedule> yesterdayCourseSchedules = courseScheduleDao.findCourseScheduleWithDate(yesterday);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | +public class CourseScheduleTeacherSalaryServiceImpl extends BaseServiceImpl<Long, CourseScheduleTeacherSalary> implements CourseScheduleTeacherSalaryService {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private CourseScheduleTeacherSalaryDao courseScheduleTeacherSalaryDao;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private VipGroupActivityDao vipGroupActivityDao;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private CourseScheduleComplaintsDao courseScheduleComplaintsDao;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private CourseScheduleStudentPaymentDao courseScheduleStudentPaymentDao;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private SysUserCashAccountService sysUserCashAccountService;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private VipGroupService vipGroupService;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private SchoolService schoolService;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private CourseScheduleDao courseScheduleDao;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private TeacherDefaultMusicGroupSalaryDao teacherDefaultMusicGroupSalaryDao;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private SysUserCashAccountDetailDao sysUserCashAccountDetailDao;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private SysConfigService sysConfigDao;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private static final Logger LOGGER = LoggerFactory
 | 
	
		
			
				|  |  | +            .getLogger(CourseScheduleTeacherSalaryServiceImpl.class);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public BaseDAO<Long, CourseScheduleTeacherSalary> getDAO() {
 | 
	
		
			
				|  |  | +        return courseScheduleTeacherSalaryDao;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public int createCourseScheduleTeacherVipSalary(VipGroup vipGroup,
 | 
	
		
			
				|  |  | +                                                    List<CourseSchedule> vipCourseSchedules,
 | 
	
		
			
				|  |  | +                                                    BigDecimal onlineTeacherSalary,
 | 
	
		
			
				|  |  | +                                                    BigDecimal offlineTeacherSalary) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        School school = schoolService.get(vipGroup.getTeacherSchoolId());
 | 
	
		
			
				|  |  | +        if (Objects.isNull(school)) {
 | 
	
		
			
				|  |  | +            throw new BizException("未找到该教学点");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //获取活动信息
 | 
	
		
			
				|  |  | +        VipGroupActivity vipGroupActivity = vipGroupActivityDao.get(vipGroup.getVipGroupActivityId().intValue());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaries = new ArrayList<>();
 | 
	
		
			
				|  |  | +        Map<TeachModeEnum, List<CourseSchedule>> courseScheduleGroupByTeachMode = vipCourseSchedules.stream().collect(Collectors.groupingBy(CourseSchedule::getTeachMode));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        for (TeachModeEnum teachModeEnum : courseScheduleGroupByTeachMode.keySet()) {
 | 
	
		
			
				|  |  | +            List<CourseSchedule> courseSchedules = courseScheduleGroupByTeachMode.get(teachModeEnum)
 | 
	
		
			
				|  |  | +                    .stream()
 | 
	
		
			
				|  |  | +                    .sorted(Comparator.comparing(CourseSchedule::getStartClassTime)).collect(Collectors.toList());
 | 
	
		
			
				|  |  | +            for (int i = 0; i < courseSchedules.size(); i++) {
 | 
	
		
			
				|  |  | +                //创建教师课程薪水记录
 | 
	
		
			
				|  |  | +                CourseScheduleTeacherSalary courseScheduleTeacherSalary = new CourseScheduleTeacherSalary();
 | 
	
		
			
				|  |  | +                courseScheduleTeacherSalary.setCourseScheduleId(courseSchedules.get(i).getId());
 | 
	
		
			
				|  |  | +                courseScheduleTeacherSalary.setTeacherRole(TeachTypeEnum.BISHOP);
 | 
	
		
			
				|  |  | +                courseScheduleTeacherSalary.setUserId(courseSchedules.get(i).getActualTeacherId().intValue());
 | 
	
		
			
				|  |  | +                courseScheduleTeacherSalary.setClassGroupId(courseSchedules.get(i).getClassGroupId());
 | 
	
		
			
				|  |  | +                courseScheduleTeacherSalary.setSubsidy(school.getSubsidy());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                Map<String, BigDecimal> feeInfo = vipGroupService.countVipGroupPredictFee(vipGroup,
 | 
	
		
			
				|  |  | +                        courseSchedules.get(i).getActualTeacherId().intValue(),
 | 
	
		
			
				|  |  | +                        onlineTeacherSalary,
 | 
	
		
			
				|  |  | +                        offlineTeacherSalary,
 | 
	
		
			
				|  |  | +                        false,
 | 
	
		
			
				|  |  | +                        false);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                if (vipGroupActivity.getType() == VipGroupActivityTypeEnum.GIVE_CLASS
 | 
	
		
			
				|  |  | +                        && vipGroup.getGiveTeachMode() == teachModeEnum
 | 
	
		
			
				|  |  | +                        && i >= Integer.parseInt(vipGroupActivity.getAttribute1())
 | 
	
		
			
				|  |  | +                        && "0".equals(vipGroupActivity.getGiveClassPaySalaryFlag())) {
 | 
	
		
			
				|  |  | +                    courseScheduleTeacherSalary.setExpectSalary(new BigDecimal(0));
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                    if (teachModeEnum == TeachModeEnum.ONLINE) {
 | 
	
		
			
				|  |  | +                        courseScheduleTeacherSalary.setExpectSalary(feeInfo.get("onlineTeacherSalary"));
 | 
	
		
			
				|  |  | +                    } else {
 | 
	
		
			
				|  |  | +                        courseScheduleTeacherSalary.setExpectSalary(feeInfo.get("offlineTeacherSalary"));
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                courseScheduleTeacherSalaries.add(courseScheduleTeacherSalary);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return courseScheduleTeacherSalaryDao.batchInsert(courseScheduleTeacherSalaries);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    @Transactional(rollbackFor = Exception.class)
 | 
	
		
			
				|  |  | +    public void teacherSalarySettlement() {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        int days = Integer.parseInt(sysConfigDao.findByParamName(SysConfigService.VIP_SETTLEMENT_CYCLE).getParanValue());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //获取教师未结算课程记录
 | 
	
		
			
				|  |  | +        List<CourseScheduleTeacherSalary> someDayAgoTeacherCourseSalaryNoSettlement = courseScheduleTeacherSalaryDao.findSomeDayAgoTeacherCourseSalaryNoSettlement(days);
 | 
	
		
			
				|  |  | +        if (CollectionUtils.isEmpty(someDayAgoTeacherCourseSalaryNoSettlement)) {
 | 
	
		
			
				|  |  | +            LOGGER.info("未获取到未结算课酬记录!");
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        Date now = new Date();
 | 
	
		
			
				|  |  | +        //获取未结算课程编号列表
 | 
	
		
			
				|  |  | +        List<Long> courseScheduleIds = someDayAgoTeacherCourseSalaryNoSettlement.stream().map(CourseScheduleTeacherSalary::getCourseScheduleId).collect(Collectors.toList());
 | 
	
		
			
				|  |  | +        //获取未结算课程投诉记录
 | 
	
		
			
				|  |  | +        List<CourseScheduleComplaints> courseScheduleComplaints = courseScheduleComplaintsDao.findByCourseScheduleIds(courseScheduleIds);
 | 
	
		
			
				|  |  | +        //获取未结算课程学生缴费信息
 | 
	
		
			
				|  |  | +        List<CourseScheduleStudentPayment> courseScheduleStudentPayments = courseScheduleStudentPaymentDao.findByCourseScheduleIds(courseScheduleIds);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //根据课程将投诉信息分组
 | 
	
		
			
				|  |  | +        Map<Long, List<CourseScheduleComplaints>> complaintsGroupByCourse = courseScheduleComplaints.stream().collect(Collectors.groupingBy(CourseScheduleComplaints::getCourseScheduleId));
 | 
	
		
			
				|  |  | +        //根据课程将学生缴费信息分组
 | 
	
		
			
				|  |  | +        Map<Long, List<CourseScheduleStudentPayment>> studentPaymentGroupByCourse = courseScheduleStudentPayments.stream().collect(Collectors.groupingBy(CourseScheduleStudentPayment::getCourseScheduleId));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //需更新教师课程结算记录
 | 
	
		
			
				|  |  | +        List<CourseScheduleTeacherSalary> updateTeacherSalarys = new ArrayList<>();
 | 
	
		
			
				|  |  | +        //需更新学生课程缴费记录
 | 
	
		
			
				|  |  | +        List<CourseScheduleStudentPayment> updateStudentPayments = new ArrayList<>();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //用户账户自己变动信息列表
 | 
	
		
			
				|  |  | +        List<SysUserCashAccountDetail> userCashAccountDetails = new ArrayList<>();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //处理课酬信息
 | 
	
		
			
				|  |  | +        someDayAgoTeacherCourseSalaryNoSettlement.forEach(courseScheduleTeacherSalary -> {
 | 
	
		
			
				|  |  | +            //获取当前课程学生缴费记录
 | 
	
		
			
				|  |  | +            List<CourseScheduleStudentPayment> studentPaymentsWithCourse = studentPaymentGroupByCourse.get(courseScheduleTeacherSalary.getCourseScheduleId());
 | 
	
		
			
				|  |  | +            //当前课程缴费学生数量
 | 
	
		
			
				|  |  | +            BigDecimal courseStudentNum = new BigDecimal(studentPaymentsWithCourse.size());
 | 
	
		
			
				|  |  | +            //教师预计课酬
 | 
	
		
			
				|  |  | +            BigDecimal expectSalary = courseScheduleTeacherSalary.getExpectSalary();
 | 
	
		
			
				|  |  | +            //当前课程每个学生平均课酬
 | 
	
		
			
				|  |  | +            BigDecimal avgSalary = expectSalary.divide(courseStudentNum);
 | 
	
		
			
				|  |  | +            //教师当前课程责任总占比,当前课程应得课酬
 | 
	
		
			
				|  |  | +            BigDecimal teacherLiabilityAllratio;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //当前课程学生投诉记录
 | 
	
		
			
				|  |  | +            List<CourseScheduleComplaints> courseStudentComplaints = complaintsGroupByCourse.get(courseScheduleTeacherSalary.getCourseScheduleId());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //如果存在投诉记录,需要扣除相应费用
 | 
	
		
			
				|  |  | +            if (Objects.nonNull(courseStudentComplaints)) {
 | 
	
		
			
				|  |  | +                //获取审批中的投诉
 | 
	
		
			
				|  |  | +                List<CourseScheduleComplaints> auditIng = courseStudentComplaints.stream().filter(courseScheduleComplaint -> courseScheduleComplaint.getStatus() == AuditStatusEnum.ING).collect(Collectors.toList());
 | 
	
		
			
				|  |  | +                if (!CollectionUtils.isEmpty(auditIng)) {
 | 
	
		
			
				|  |  | +                    //如果当前课程存在未处理的投诉,则不做结算处理
 | 
	
		
			
				|  |  | +                    return;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                //计算教师责任总占比
 | 
	
		
			
				|  |  | +                double teacherLiabilityRatioSum = courseStudentComplaints.stream().mapToDouble(CourseScheduleComplaints::getTeacherLiabilityRatio).sum();
 | 
	
		
			
				|  |  | +                teacherLiabilityAllratio = new BigDecimal(teacherLiabilityRatioSum);
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                //如果没有投诉,则教师和学生的责任占比为0
 | 
	
		
			
				|  |  | +                teacherLiabilityAllratio = new BigDecimal(0);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //教师应扣除费用
 | 
	
		
			
				|  |  | +            BigDecimal deductPrice = avgSalary.multiply(teacherLiabilityAllratio);
 | 
	
		
			
				|  |  | +            //教师实际课酬
 | 
	
		
			
				|  |  | +            BigDecimal actualSalary = expectSalary.subtract(deductPrice).add(courseScheduleTeacherSalary.getSubsidy());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //更新教师结算信息
 | 
	
		
			
				|  |  | +            courseScheduleTeacherSalary.setActualSalary(actualSalary);
 | 
	
		
			
				|  |  | +            courseScheduleTeacherSalary.setSettlementTime(now);
 | 
	
		
			
				|  |  | +            courseScheduleTeacherSalaryDao.update(courseScheduleTeacherSalary);
 | 
	
		
			
				|  |  | +            updateTeacherSalarys.add(courseScheduleTeacherSalary);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //生成教师账户资金变动记录
 | 
	
		
			
				|  |  | +            sysUserCashAccountService.updateBalance(courseScheduleTeacherSalary.getUserId(), actualSalary);
 | 
	
		
			
				|  |  | +            SysUserCashAccount teacherCashAccount = sysUserCashAccountService.get(courseScheduleTeacherSalary.getUserId().intValue());
 | 
	
		
			
				|  |  | +            SysUserCashAccountDetail teacherCashAccountDetail = new SysUserCashAccountDetail();
 | 
	
		
			
				|  |  | +            teacherCashAccountDetail.setUserId(courseScheduleTeacherSalary.getUserId());
 | 
	
		
			
				|  |  | +            teacherCashAccountDetail.setType(PlatformCashAccountDetailTypeEnum.REFUNDS);
 | 
	
		
			
				|  |  | +            teacherCashAccountDetail.setStatus(DealStatusEnum.SUCCESS);
 | 
	
		
			
				|  |  | +            teacherCashAccountDetail.setAmount(actualSalary);
 | 
	
		
			
				|  |  | +            teacherCashAccountDetail.setBalance(teacherCashAccount.getBalance());
 | 
	
		
			
				|  |  | +            teacherCashAccountDetail.setAttribute(courseScheduleTeacherSalary.getCourseScheduleId().toString());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            userCashAccountDetails.add(teacherCashAccountDetail);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //根据学生进行投诉分组
 | 
	
		
			
				|  |  | +            Map<Integer, List<CourseScheduleComplaints>> complainsGroupByStudent = courseStudentComplaints.stream().collect(Collectors.groupingBy(CourseScheduleComplaints::getUserId));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //计算学生当前课程应缴费用
 | 
	
		
			
				|  |  | +            studentPaymentsWithCourse.forEach(studentPayment -> {
 | 
	
		
			
				|  |  | +                //当前课程学生应缴费用
 | 
	
		
			
				|  |  | +                BigDecimal studentExpectPrice = studentPayment.getExpectPrice();
 | 
	
		
			
				|  |  | +                //当前课程学生责任占比
 | 
	
		
			
				|  |  | +                BigDecimal studentLiabilityRatio;
 | 
	
		
			
				|  |  | +                List<CourseScheduleComplaints> currentCourseScheduleComplaints = complainsGroupByStudent.get(studentPayment.getUserId());
 | 
	
		
			
				|  |  | +                if (CollectionUtils.isEmpty(currentCourseScheduleComplaints)) {
 | 
	
		
			
				|  |  | +                    Double temp = currentCourseScheduleComplaints.get(0).getStudentLiabilityRatio();
 | 
	
		
			
				|  |  | +                    studentLiabilityRatio = new BigDecimal(temp);
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                    studentLiabilityRatio = new BigDecimal(0);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                //当前课程学生应退费用
 | 
	
		
			
				|  |  | +                BigDecimal returnPrice = studentExpectPrice.multiply(studentLiabilityRatio);
 | 
	
		
			
				|  |  | +                //当前课程学生实际缴费
 | 
	
		
			
				|  |  | +                BigDecimal actualPrice = expectSalary.subtract(returnPrice);
 | 
	
		
			
				|  |  | +                //更新学生结算信息
 | 
	
		
			
				|  |  | +                studentPayment.setActualPrice(actualPrice);
 | 
	
		
			
				|  |  | +                studentPayment.setSettlementTime(now);
 | 
	
		
			
				|  |  | +                courseScheduleStudentPaymentDao.update(studentPayment);
 | 
	
		
			
				|  |  | +                updateStudentPayments.add(studentPayment);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                //生成学生账户资金变动记录
 | 
	
		
			
				|  |  | +                sysUserCashAccountService.updateBalance(studentPayment.getUserId(), returnPrice);
 | 
	
		
			
				|  |  | +                SysUserCashAccount studentCashAccount = sysUserCashAccountService.get(studentPayment.getUserId().intValue());
 | 
	
		
			
				|  |  | +                SysUserCashAccountDetail studentAccountDetail = new SysUserCashAccountDetail();
 | 
	
		
			
				|  |  | +                studentAccountDetail.setUserId(studentPayment.getUserId());
 | 
	
		
			
				|  |  | +                studentAccountDetail.setType(PlatformCashAccountDetailTypeEnum.REFUNDS);
 | 
	
		
			
				|  |  | +                studentAccountDetail.setStatus(DealStatusEnum.SUCCESS);
 | 
	
		
			
				|  |  | +                studentAccountDetail.setAmount(returnPrice);
 | 
	
		
			
				|  |  | +                studentAccountDetail.setBalance(studentCashAccount.getBalance());
 | 
	
		
			
				|  |  | +                studentAccountDetail.setAttribute(courseScheduleTeacherSalary.getCourseScheduleId().toString());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                userCashAccountDetails.add(studentAccountDetail);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        sysUserCashAccountDetailDao.batchInsert(userCashAccountDetails);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    @Transactional(rollbackFor = Exception.class)
 | 
	
		
			
				|  |  | +    public void musicGroupTeacherSalarySettlement() {
 | 
	
		
			
				|  |  | +        Date now = new Date();
 | 
	
		
			
				|  |  | +        Date yesterday = DateUtil.addDays1(now, -1);
 | 
	
		
			
				|  |  | +        Integer settlementClassMinutes = Integer.parseInt(sysConfigDao.findByParamName(SysConfigService.MUSIC_GROUP_SETTLEMENT_CLASS_MINUTES).getParanValue());
 | 
	
		
			
				|  |  | +        Integer singleClassTime = Integer.parseInt(sysConfigDao.findByParamName(SysConfigService.MUSIC_GROUP_SETTLEMENT_SINGLE_CLASS_MINUTES).getParanValue());
 | 
	
		
			
				|  |  | +        //获取昨天的课程计划
 | 
	
		
			
				|  |  | +        List<CourseSchedule> yesterdayCourseSchedules = courseScheduleDao.findCourseScheduleWithDate(yesterday);
 | 
	
		
			
				|  |  | +        //课程编号列表
 | 
	
		
			
				|  |  | +        List<Long> courseScheduleIds = yesterdayCourseSchedules.stream().map(CourseSchedule::getId).collect(Collectors.toList());
 | 
	
		
			
				|  |  | +        //获取课程对应教学点补贴
 | 
	
		
			
				|  |  | +        List<Map<Integer, BigDecimal>> courseSubsidyByCourses = courseScheduleTeacherSalaryDao.findCourseSubsidyByCourses(courseScheduleIds);
 | 
	
		
			
				|  |  | +        Map<Integer, BigDecimal> courseSubsidyMap = MapUtil.convertMybatisMap(courseSubsidyByCourses);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //课程编号与课程对应集合
 | 
	
		
			
				|  |  | +        Map<Long, CourseSchedule> courseScheduleIdMap = yesterdayCourseSchedules.stream()
 | 
	
		
			
				|  |  | +                .collect(Collectors.toMap(CourseSchedule::getId, courseSchedule -> courseSchedule));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //课程教师课酬
 | 
	
		
			
				|  |  | +        List<CourseScheduleTeacherSalary> courseScheduleTeacherSalaries = courseScheduleTeacherSalaryDao.findByCourseSchedules(courseScheduleIds);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //课程对应乐团结算方式集合
 | 
	
		
			
				|  |  | +        List<Map<String, String>> musicGroupSettlementTypeByCourse = courseScheduleTeacherSalaryDao.findMusicGroupSettlementTypeByCourse(courseScheduleIds);
 | 
	
		
			
				|  |  | +        Map<String, String> musicGroupSettlementsMap = MapUtil.convertMybatisMap(musicGroupSettlementTypeByCourse);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //教师对应课程列表集合
 | 
	
		
			
				|  |  | +        Map<Integer, List<CourseScheduleTeacherSalary>> teacherSalarysByTeacher = courseScheduleTeacherSalaries.stream()
 | 
	
		
			
				|  |  | +                .collect(Collectors.groupingBy(CourseScheduleTeacherSalary::getUserId));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //所有老师编号
 | 
	
		
			
				|  |  | +        List<Integer> allTeacherIds = courseScheduleTeacherSalaries.stream()
 | 
	
		
			
				|  |  | +                .map(CourseScheduleTeacherSalary::getUserId)
 | 
	
		
			
				|  |  | +                .collect(Collectors.toList());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //所有老师默认乐团课酬
 | 
	
		
			
				|  |  | +        List<TeacherDefaultMusicGroupSalary> teacherDefaultMusicGroupSalaries = teacherDefaultMusicGroupSalaryDao.findByTeacher(allTeacherIds);
 | 
	
		
			
				|  |  | +        Map<CourseSchedule.CourseScheduleType, List<TeacherDefaultMusicGroupSalary>> teacherDefaultMusicGroupSalariesGroupByCourseType = teacherDefaultMusicGroupSalaries.stream().collect(Collectors.groupingBy(TeacherDefaultMusicGroupSalary::getCourseScheduleType));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //教师对应的每个教学点的总课时
 | 
	
		
			
				|  |  | +        Map<Integer, Map<Integer, Integer>> teacherClassMinutesMap = new HashMap<>();
 | 
	
		
			
				|  |  | +        //计算老师对应的总课时
 | 
	
		
			
				|  |  | +        teacherSalarysByTeacher.forEach((teacherId, teacherSalarys) -> {
 | 
	
		
			
				|  |  | +            //当前老师所在课程的编号列表
 | 
	
		
			
				|  |  | +            List<Long> currentTeacherCourscheduleIds = teacherSalarys.stream()
 | 
	
		
			
				|  |  | +                    .map(CourseScheduleTeacherSalary::getCourseScheduleId)
 | 
	
		
			
				|  |  | +                    .collect(Collectors.toList());
 | 
	
		
			
				|  |  | +            //当前老师的课程列表
 | 
	
		
			
				|  |  | +            List<CourseSchedule> currentTeacherCourseSchedules = yesterdayCourseSchedules.stream()
 | 
	
		
			
				|  |  | +                    .filter(courseSchedule -> currentTeacherCourscheduleIds.contains(courseSchedule.getId()))
 | 
	
		
			
				|  |  | +                    .collect(Collectors.toList());
 | 
	
		
			
				|  |  | +            //根据教学点将当前老师的课程分组
 | 
	
		
			
				|  |  | +            Map<Integer, List<CourseSchedule>> schoolCourseSchedules = currentTeacherCourseSchedules.stream()
 | 
	
		
			
				|  |  | +                    .collect(Collectors.groupingBy(CourseSchedule::getSchoolId));
 | 
	
		
			
				|  |  | +            Map<Integer, Integer> schoolClassMinutesMap = new HashMap<>();
 | 
	
		
			
				|  |  | +            for (Integer schoolId : schoolCourseSchedules.keySet()) {
 | 
	
		
			
				|  |  | +                Integer classMinutes = 0;
 | 
	
		
			
				|  |  | +                //当前教学点的课程
 | 
	
		
			
				|  |  | +                List<CourseSchedule> currentSchoolCourseSchedules = schoolCourseSchedules.get(schoolId);
 | 
	
		
			
				|  |  | +                for (CourseSchedule courseSchedule : currentSchoolCourseSchedules) {
 | 
	
		
			
				|  |  | +                    //如果课程为单机课或者为合奏课,则算入总课时长
 | 
	
		
			
				|  |  | +                    if (courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.SINGLE)
 | 
	
		
			
				|  |  | +                            || courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.MIX)) {
 | 
	
		
			
				|  |  | +                        classMinutes += DateUtil.minutesBetween(courseSchedule.getStartClassTime(), courseSchedule.getEndClassTime());
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                schoolClassMinutesMap.put(schoolId, classMinutes);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            teacherClassMinutesMap.put(teacherId, schoolClassMinutesMap);
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        //用户账户自己变动信息列表
 | 
	
		
			
				|  |  | +        List<SysUserCashAccountDetail> userCashAccountDetails = new ArrayList<>();
 | 
	
		
			
				|  |  | +        //计算课酬
 | 
	
		
			
				|  |  | +        courseScheduleTeacherSalaries.forEach(courseScheduleTeacherSalary -> {
 | 
	
		
			
				|  |  | +            //当前课酬对应的课程信息
 | 
	
		
			
				|  |  | +            CourseSchedule courseSchedule = courseScheduleIdMap.get(courseScheduleTeacherSalary.getCourseScheduleId());
 | 
	
		
			
				|  |  | +            Map<Integer, Integer> schoolClassMinutesMap = teacherClassMinutesMap.get(courseScheduleTeacherSalary.getUserId());
 | 
	
		
			
				|  |  | +            Integer schoolClassMinutes = schoolClassMinutesMap.get(courseSchedule.getSchoolId());
 | 
	
		
			
				|  |  | +            //当前课程的时长
 | 
	
		
			
				|  |  | +            int duration = DateUtil.minutesBetween(courseSchedule.getStartClassTime(), courseSchedule.getEndClassTime());
 | 
	
		
			
				|  |  | +            //如果是单技课或者合奏课
 | 
	
		
			
				|  |  | +            if (courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.SINGLE)
 | 
	
		
			
				|  |  | +                    || courseSchedule.getType().equals(CourseSchedule.CourseScheduleType.MIX)) {
 | 
	
		
			
				|  |  | +                if (schoolClassMinutes >= settlementClassMinutes && duration < singleClassTime) {
 | 
	
		
			
				|  |  | +                    duration = singleClassTime;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            //根据课程类型获取对应的默认课酬设置列表
 | 
	
		
			
				|  |  | +            List<TeacherDefaultMusicGroupSalary> teacherDefaultMusicGroupSalariesWithCourseType = teacherDefaultMusicGroupSalariesGroupByCourseType.get(courseSchedule.getType());
 | 
	
		
			
				|  |  | +            if (CollectionUtils.isEmpty(teacherDefaultMusicGroupSalariesWithCourseType)) {
 | 
	
		
			
				|  |  | +                throw new BizException("存在未指定结算方式的课程类型");
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //根据教师编号将对应结算方式下的默认课酬设置分组
 | 
	
		
			
				|  |  | +            Map<Integer, TeacherDefaultMusicGroupSalary> teacherDefaultMusicGroupSalariesGroupByTeacherId = teacherDefaultMusicGroupSalariesWithCourseType.stream().collect(Collectors.toMap(TeacherDefaultMusicGroupSalary::getUserId,teacherDefaultMusicGroupSalary -> teacherDefaultMusicGroupSalary));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            TeacherDefaultMusicGroupSalary teacherDefaultMusicGroupSalaryWithTeacherId=teacherDefaultMusicGroupSalariesGroupByTeacherId.get(courseScheduleTeacherSalary.getUserId());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //教师课酬
 | 
	
		
			
				|  |  | +            BigDecimal teacherSalary = new BigDecimal(0);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            String settlementType=musicGroupSettlementsMap.get(courseScheduleTeacherSalary.getCourseScheduleId());
 | 
	
		
			
				|  |  | +            //如果结算方式是教师默认课酬
 | 
	
		
			
				|  |  | +            if (settlementType.equals(SalarySettlementTypeEnum.TEACHER_DEFAULT)) {
 | 
	
		
			
				|  |  | +                //课程时长与结算单位时长占比
 | 
	
		
			
				|  |  | +                BigDecimal classTimeDuty = new BigDecimal(duration).divide(new BigDecimal(30));
 | 
	
		
			
				|  |  | +                BigDecimal teacherDefaultSalary = courseScheduleTeacherSalary.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalaryWithTeacherId.getMainTeacher30MinSalary() : teacherDefaultMusicGroupSalaryWithTeacherId.getAssistantTeacher30MinSalary();
 | 
	
		
			
				|  |  | +                teacherSalary = teacherDefaultSalary.multiply(classTimeDuty).setScale(2, BigDecimal.ROUND_HALF_UP);
 | 
	
		
			
				|  |  | +            } else if (settlementType.equals(SalarySettlementTypeEnum.GRADIENT_SALARY)) {
 | 
	
		
			
				|  |  | +                //课程时长与结算单位时长占比
 | 
	
		
			
				|  |  | +                BigDecimal classTimeDuty = new BigDecimal(duration).divide(new BigDecimal(90));
 | 
	
		
			
				|  |  | +                BigDecimal teacherDefaultSalary = courseScheduleTeacherSalary.getTeacherRole().equals(TeachTypeEnum.BISHOP) ? teacherDefaultMusicGroupSalaryWithTeacherId.getMainTeacher90MinSalary() : teacherDefaultMusicGroupSalaryWithTeacherId.getAssistantTeacher90MinSalary();
 | 
	
		
			
				|  |  | +                teacherSalary = teacherDefaultSalary.multiply(classTimeDuty).setScale(2, BigDecimal.ROUND_HALF_UP);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            BigDecimal subsidy = courseSubsidyMap.get(courseSchedule.getSchoolId());
 | 
	
		
			
				|  |  | +            teacherSalary=teacherSalary.add(subsidy);
 | 
	
		
			
				|  |  | +            //更新教师结算信息
 | 
	
		
			
				|  |  | +            courseScheduleTeacherSalary.setActualSalary(teacherSalary);
 | 
	
		
			
				|  |  | +            courseScheduleTeacherSalary.setSettlementTime(now);
 | 
	
		
			
				|  |  | +            courseScheduleTeacherSalaryDao.update(courseScheduleTeacherSalary);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //生成教师账户资金变动记录
 | 
	
		
			
				|  |  | +            sysUserCashAccountService.updateBalance(courseScheduleTeacherSalary.getUserId(), teacherSalary);
 | 
	
		
			
				|  |  | +            SysUserCashAccount teacherCashAccount = sysUserCashAccountService.get(courseScheduleTeacherSalary.getUserId().intValue());
 | 
	
		
			
				|  |  | +            SysUserCashAccountDetail teacherCashAccountDetail = new SysUserCashAccountDetail();
 | 
	
		
			
				|  |  | +            teacherCashAccountDetail.setUserId(courseScheduleTeacherSalary.getUserId());
 | 
	
		
			
				|  |  | +            teacherCashAccountDetail.setType(PlatformCashAccountDetailTypeEnum.REFUNDS);
 | 
	
		
			
				|  |  | +            teacherCashAccountDetail.setStatus(DealStatusEnum.SUCCESS);
 | 
	
		
			
				|  |  | +            teacherCashAccountDetail.setAmount(teacherSalary);
 | 
	
		
			
				|  |  | +            teacherCashAccountDetail.setBalance(teacherCashAccount.getBalance());
 | 
	
		
			
				|  |  | +            teacherCashAccountDetail.setAttribute(courseScheduleTeacherSalary.getCourseScheduleId().toString());
 | 
	
		
			
				|  |  | +            userCashAccountDetails.add(teacherCashAccountDetail);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        sysUserCashAccountDetailDao.batchInsert(userCashAccountDetails);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  }
 |