package com.ym.mec.biz.service.impl;

import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PayUserType.SCHOOL;
import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PayUserType.STUDENT;
import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentCalenderStatusEnum.AUDITING;
import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentCalenderStatusEnum.REJECT;
import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentType.ADD_COURSE;
import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentType.ADD_STUDENT;
import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentType.MUSIC_APPLY;
import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentType.MUSIC_RENEW;
import static com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentType.SPAN_GROUP_CLASS_ADJUST;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;

import com.ym.mec.biz.dal.enums.GroupType;
import com.ym.mec.biz.service.*;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.auth.api.entity.SysUserRole;
import com.ym.mec.biz.dal.dao.ClassGroupDao;
import com.ym.mec.biz.dal.dao.ClassGroupStudentMapperDao;
import com.ym.mec.biz.dal.dao.CourseScheduleDao;
import com.ym.mec.biz.dal.dao.CourseScheduleTeacherSalaryDao;
import com.ym.mec.biz.dal.dao.MusicGroupBuildLogDao;
import com.ym.mec.biz.dal.dao.MusicGroupDao;
import com.ym.mec.biz.dal.dao.MusicGroupOrganizationCourseSettingsDao;
import com.ym.mec.biz.dal.dao.MusicGroupOrganizationCourseSettingsDetailDao;
import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderCourseSettingsDao;
import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDao;
import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDetailDao;
import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderStudentDetailDao;
import com.ym.mec.biz.dal.dao.MusicGroupPaymentStudentCourseDetailDao;
import com.ym.mec.biz.dal.dao.MusicGroupStudentClassAdjustDao;
import com.ym.mec.biz.dal.dao.MusicGroupStudentFeeDao;
import com.ym.mec.biz.dal.dao.OrganizationCourseUnitPriceSettingsDao;
import com.ym.mec.biz.dal.dao.OrganizationDao;
import com.ym.mec.biz.dal.dao.SysConfigDao;
import com.ym.mec.biz.dal.dao.TeacherAttendanceDao;
import com.ym.mec.biz.dal.dto.CalenderPushDto;
import com.ym.mec.biz.dal.dto.ClassGroup4MixDto;
import com.ym.mec.biz.dal.dto.MusicGroupPaymentCalenderAuditDetailDto;
import com.ym.mec.biz.dal.dto.MusicGroupPaymentCalenderAuditDto;
import com.ym.mec.biz.dal.dto.MusicGroupPaymentCalenderDto;
import com.ym.mec.biz.dal.dto.MusicGroupPaymentCalenderDto.MusicGroupPaymentDateRange;
import com.ym.mec.biz.dal.entity.ClassGroup;
import com.ym.mec.biz.dal.entity.CourseSchedule.CourseScheduleType;
import com.ym.mec.biz.dal.entity.MusicGroup;
import com.ym.mec.biz.dal.entity.MusicGroupBuildLog;
import com.ym.mec.biz.dal.entity.MusicGroupOrganizationCourseSettings;
import com.ym.mec.biz.dal.entity.MusicGroupOrganizationCourseSettingsDetail;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PayUserType;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentCalenderStatusEnum;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender.PaymentType;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalenderCourseSettings;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalenderDetail;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalenderStudentDetail;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentStudentCourseDetail;
import com.ym.mec.biz.dal.entity.MusicGroupStudentClassAdjust;
import com.ym.mec.biz.dal.entity.MusicGroupStudentFee;
import com.ym.mec.biz.dal.entity.MusicGroupStudentFee.PaymentStatus;
import com.ym.mec.biz.dal.entity.Organization;
import com.ym.mec.biz.dal.entity.OrganizationCourseUnitPriceSettings;
import com.ym.mec.biz.dal.enums.MessageTypeEnum;
import com.ym.mec.biz.dal.enums.MusicGroupStatusEnum;
import com.ym.mec.biz.dal.page.MusicGroupPaymentCalenderQueryInfo;
import com.ym.mec.common.dal.BaseDAO;
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.message.MessageSenderPluginContext;
import com.ym.mec.util.collection.MapUtil;
import com.ym.mec.util.date.DateUtil;

@Service
public class MusicGroupPaymentCalenderServiceImpl extends BaseServiceImpl<Long, MusicGroupPaymentCalender> implements MusicGroupPaymentCalenderService {

	@Autowired
	private MusicGroupPaymentCalenderDao musicGroupPaymentCalenderDao;
	@Autowired
	private MusicGroupPaymentCalenderDetailDao musicGroupPaymentCalenderDetailDao;
	@Autowired
	private MusicGroupStudentFeeDao musicGroupStudentFeeDao;
	
	@Autowired
	private MusicGroupPaymentCalenderCourseSettingsDao musicGroupPaymentCalenderCourseSettingsDao;
	
	@Autowired
	private MusicGroupOrganizationCourseSettingsDetailDao musicGroupOrganizationCourseSettingsDetailDao;

	@Autowired
	private MusicGroupOrganizationCourseSettingsDao musicGroupOrganizationCourseSettingsDao;
	
	@Autowired
	private OrganizationCourseUnitPriceSettingsDao organizationCourseUnitPriceSettingsDao;
	
	@Autowired
	private MusicGroupPaymentStudentCourseDetailDao musicGroupPaymentStudentCourseDetailDao;
	
	@Autowired
	private IdGeneratorService idGeneratorService;
	
	@Autowired
	private ClassGroupService classGroupService;
	
	@Autowired
	private MusicGroupDao musicGroupDao;

	@Autowired
	private ClassGroupDao classGroupDao;

	@Autowired
	private CourseScheduleDao courseScheduleDao;

	@Autowired
	private CourseScheduleTeacherSalaryDao courseScheduleTeacherSalaryDao;

	@Autowired
	private TeacherAttendanceDao teacherAttendanceDao;
	@Autowired
	private MusicGroupBuildLogDao musicGroupBuildLogDao;
	@Autowired
	private SysConfigDao sysConfigDao;
	@Autowired
	private OrganizationDao organizationDao;
	@Autowired
	private SysMessageService sysMessageService;
	@Autowired
	private SysUserFeignService sysUserFeignService;
	@Autowired
	private ImGroupMemberService imGroupMemberService;
	@Autowired
	private ImUserFriendService imUserFriendService;
	@Autowired
	private ClassGroupStudentMapperDao classGroupStudentMapperDao;
	@Autowired
	private MusicGroupStudentClassAdjustDao musicGroupStudentClassAdjustDao;
	@Autowired
	private MusicGroupPaymentCalenderDetailService musicGroupPaymentCalenderDetailService;
	@Autowired
	private MusicGroupPaymentCalenderStudentDetailDao musicGroupPaymentCalenderStudentDetailDao;

	@Override
	public BaseDAO<Long, MusicGroupPaymentCalender> getDAO() {
		return musicGroupPaymentCalenderDao;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String create(MusicGroupPaymentCalenderDto musicGroupPaymentCalenderDto) {

		String musicGroupId = musicGroupPaymentCalenderDto.getMusicGroupId();

		PaymentType paymentType = musicGroupPaymentCalenderDto.getPaymentType();

		PayUserType payUserType = musicGroupPaymentCalenderDto.getPayUserType();

		List<MusicGroupPaymentDateRange> musicGroupPaymentDateRangeList = musicGroupPaymentCalenderDto.getMusicGroupPaymentDateRangeList();

		if ((paymentType == PaymentType.ADD_COURSE)) {
			if(musicGroupPaymentDateRangeList.size() > 1){
				throw new BizException("[临时加课]不支持多周期缴费");
			}
		}
		
		if ((paymentType == PaymentType.ADD_STUDENT)) {
			Integer userId = Integer.parseInt(musicGroupPaymentCalenderDto.getStudentIds());
			List<MusicGroupPaymentCalenderDetail> musicGroupPaymentCalenderDetailList = musicGroupPaymentCalenderDetailDao.queryNotPaymentStudentByUserIdAndMusicGroupId(userId, musicGroupId);
			if(musicGroupPaymentCalenderDetailList != null && musicGroupPaymentCalenderDetailList.size() > 0){
				throw new BizException("创建缴费失败：已存在缴费项目");
			}
		}

		MusicGroup musicGroup = musicGroupDao.getLocked(musicGroupId);

		if (musicGroup == null) {
			throw new BizException("乐团查询失败，请检查参数");
		}
		
		if (musicGroup.getStatus() != MusicGroupStatusEnum.PROGRESS && musicGroup.getStatus() != MusicGroupStatusEnum.PRE_BUILD_FEE) {
			throw new BizException("创建失败：乐团当前状态不能创建缴费");
		}
		
		SysUser sysUser = sysUserFeignService.queryUserInfo();
		if (sysUser == null) {
			throw new BizException("请登录");
		}
		// 所有缴费项目已完成排课才能创建下一个缴费项目
		String orignBatchNo = musicGroupPaymentStudentCourseDetailDao.getUnUseBatchNoWithStudentAndCourseTypeAndCourseMinutes(musicGroupId, null, null,musicGroupPaymentCalenderDto.getIgnoreBatchNoList());
		if (StringUtils.isNoneBlank(orignBatchNo)) {
			if(StringUtils.isEmpty(musicGroupPaymentCalenderDto.getBatchNo()) || !musicGroupPaymentCalenderDto.getBatchNo().equals(orignBatchNo)){
				throw new BizException("当前乐团存在未排课的缴费项目，请先完成排课再操作");
			}
		}

		// 不是进行中，只能创建一次缴费
		if (musicGroup.getStatus() != MusicGroupStatusEnum.PROGRESS) {
			List<MusicGroupPaymentCalender> list = musicGroupPaymentCalenderDao.findByMusicGroupId(musicGroupId);
			if (list.size() > 0) {
				throw new BizException("创建失败，已经存在缴费信息");
			}
		}

		PaymentCalenderStatusEnum status = PaymentCalenderStatusEnum.NO;

		Date date = new Date();
		String batchNo = idGeneratorService.generatorId() + "";

		// 获取设置的课程
		List<MusicGroupPaymentCalenderCourseSettings> musicGroupPaymentCalenderCourseSettingsList = musicGroupPaymentCalenderDto
				.getMusicGroupPaymentCalenderCourseSettingsList();
		if (musicGroupPaymentCalenderCourseSettingsList == null) {
			musicGroupPaymentCalenderCourseSettingsList = new ArrayList<>();
		}

		if (payUserType == SCHOOL) {
			status = AUDITING;
		} else {
			if (paymentType == MUSIC_APPLY || paymentType == MUSIC_RENEW) {
				// 当前缴费的课程费用
				Map<CourseScheduleType, BigDecimal> currentCoursePrice = musicGroupPaymentCalenderCourseSettingsList.stream().collect(
						Collectors
								.toMap(MusicGroupPaymentCalenderCourseSettings::getCourseType, MusicGroupPaymentCalenderCourseSettings::getCourseCurrentPrice));

				// 查询默认课程费用
				Integer musicGroupOrganizationCourseSettingId = musicGroupPaymentCalenderDto.getMusicGroupOrganizationCourseSettingId();
				Map<CourseScheduleType, BigDecimal> defaultCoursePrice = musicGroupOrganizationCourseSettingsDetailDao
						.queryByMusicGroupOrganizationCourseSettingsId(musicGroupOrganizationCourseSettingId)
						.stream()
						.collect(
								Collectors.toMap(MusicGroupOrganizationCourseSettingsDetail::getCourseType,
										MusicGroupOrganizationCourseSettingsDetail::getCourseCurrentPrice));

				// 相同类型的课程如果修改了课程费用，需要走审批
				for (Entry<CourseScheduleType, BigDecimal> entry : currentCoursePrice.entrySet()) {
					if (defaultCoursePrice.get(entry.getKey()).compareTo(entry.getValue()) != 0) {
						status = AUDITING;
						break;
					}
				}
			} else if (paymentType == PaymentType.ADD_COURSE || paymentType == PaymentType.ADD_STUDENT) {
				PaymentCalenderStatusEnum dtoStatus = musicGroupPaymentCalenderDto.getStatus();
				if(dtoStatus != null && dtoStatus == AUDITING){
					status = AUDITING;
				}else {
					// 如果是临时加课，判断是否审核
					for (MusicGroupPaymentCalenderCourseSettings courseSettings : musicGroupPaymentCalenderCourseSettingsList) {
						OrganizationCourseUnitPriceSettings defaultUnitPrice = organizationCourseUnitPriceSettingsDao.queryByOrganIdAndCourseTypeAndChargeType(
								musicGroup.getOrganId(), courseSettings.getCourseType(), musicGroup.getChargeTypeId());
						if (defaultUnitPrice == null) {
							throw new BizException("请先设置分部课程类型单价");
						}
						if (courseSettings.getCourseTotalMinuties() != 0) {
							
							if (defaultUnitPrice.getUnitPrice().multiply(new BigDecimal(courseSettings.getCourseTotalMinuties())).setScale(0, BigDecimal.ROUND_HALF_UP)
									.compareTo(courseSettings.getCourseCurrentPrice()) != 0) {

								status = AUDITING;
								break;
							}
						} else {
							status = AUDITING;
							break;
						}
					}
				}
			}else if(paymentType == SPAN_GROUP_CLASS_ADJUST){
				status = musicGroupPaymentCalenderDto.getStatus();
			}
		}

		int times = musicGroupPaymentDateRangeList.size();

		// 排序
		Collections.sort(musicGroupPaymentDateRangeList, new Comparator<MusicGroupPaymentDateRange>() {

			@Override
			public int compare(MusicGroupPaymentDateRange o1, MusicGroupPaymentDateRange o2) {
				return o1.getPaymentValidStartDate().compareTo(o2.getPaymentValidStartDate());
			}
		});

		for (int i = 0; i < musicGroupPaymentDateRangeList.size(); i++) {

			MusicGroupPaymentDateRange musicGroupPaymentDateRange = musicGroupPaymentDateRangeList.get(i);

			MusicGroupPaymentCalender musicGroupPaymentCalender = new MusicGroupPaymentCalender();
			musicGroupPaymentCalender.setAttribute1(musicGroupPaymentCalenderDto.getAttribute1());
			musicGroupPaymentCalender.setAttribute2(musicGroupPaymentCalenderDto.getAttribute2());
			musicGroupPaymentCalender.setDeadlinePaymentDate(musicGroupPaymentDateRange.getDeadlinePaymentDate());
			musicGroupPaymentCalender.setIsGiveMusicNetwork(musicGroupPaymentCalenderDto.getIsGiveMusicNetwork());
			musicGroupPaymentCalender.setMemo(musicGroupPaymentCalenderDto.getMemo());
			musicGroupPaymentCalender.setMusicGroupId(musicGroupId);
			musicGroupPaymentCalender.setMusicGroupOrganizationCourseSettingId(musicGroupPaymentCalenderDto.getMusicGroupOrganizationCourseSettingId());

			List<MusicGroupPaymentCalenderCourseSettings> newCSList = new ArrayList<MusicGroupPaymentCalenderCourseSettings>(
					musicGroupPaymentCalenderCourseSettingsList.size());

			BigDecimal totalPaymentAmount = musicGroupPaymentCalenderDto.getMasterTotalPrice();
			for (MusicGroupPaymentCalenderCourseSettings pccs : musicGroupPaymentCalenderCourseSettingsList) {
				
				MusicGroupPaymentCalenderCourseSettings tempPccs = new MusicGroupPaymentCalenderCourseSettings();
				try {
					BeanUtils.copyProperties(tempPccs, pccs);
				} catch (Exception e) {
					throw new BizException("克隆对象出错", e);
				}
				if (i == 0) {
					if (pccs.getIsStudentOptional()) {
						tempPccs.setCourseCurrentPrice(pccs.getCourseCurrentPrice());
						tempPccs.setCourseOriginalPrice(pccs.getCourseOriginalPrice());
						tempPccs.setCourseTotalMinuties(pccs.getCourseTotalMinuties());
					} else {
						tempPccs.setCourseCurrentPrice(pccs.getCourseCurrentPrice().subtract(
								pccs.getCourseCurrentPrice().divide(new BigDecimal(times), 0, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(times - 1))
										.setScale(0, BigDecimal.ROUND_DOWN)));
						tempPccs.setCourseOriginalPrice(pccs.getCourseOriginalPrice().subtract(
								pccs.getCourseOriginalPrice().divide(new BigDecimal(times), 0, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(times - 1))
										.setScale(0, BigDecimal.ROUND_DOWN)));
						tempPccs.setCourseTotalMinuties(pccs.getCourseTotalMinuties() - pccs.getCourseTotalMinuties() / times * (times - 1));
					}
				} else {
					if (!pccs.getIsStudentOptional()) {
						tempPccs.setCourseCurrentPrice(pccs.getCourseCurrentPrice().divide(new BigDecimal(times), 0, BigDecimal.ROUND_DOWN));
						tempPccs.setCourseOriginalPrice(pccs.getCourseOriginalPrice().divide(new BigDecimal(times), 0, BigDecimal.ROUND_DOWN));
						tempPccs.setCourseTotalMinuties(pccs.getCourseTotalMinuties() / times);
					} else {
						continue;
					}
				}
				totalPaymentAmount = totalPaymentAmount.add(tempPccs.getCourseCurrentPrice());
				newCSList.add(tempPccs);
			}
			
			musicGroupPaymentCalender.setMusicGroupPaymentCalenderCourseSettingsList(newCSList);
			musicGroupPaymentCalender.setPaymentAmount(totalPaymentAmount);

			musicGroupPaymentCalender.setPaymentPattern(musicGroupPaymentCalenderDto.getPaymentPattern());
			musicGroupPaymentCalender.setPaymentValidEndDate(musicGroupPaymentDateRange.getPaymentValidEndDate());
			musicGroupPaymentCalender.setPaymentValidStartDate(musicGroupPaymentDateRange.getPaymentValidStartDate());
			
			if (paymentType == PaymentType.MUSIC_APPLY) {
				if (i == 0) {
					musicGroupPaymentCalender.setPaymentType(paymentType);
				} else {
					musicGroupPaymentCalender.setPaymentType(PaymentType.MUSIC_RENEW);
				}
			} else {
				musicGroupPaymentCalender.setPaymentType(paymentType);
			}
			musicGroupPaymentCalender.setPayUserType(musicGroupPaymentCalenderDto.getPayUserType());
			musicGroupPaymentCalender.setStartPaymentDate(musicGroupPaymentDateRange.getStartPaymentDate());
			musicGroupPaymentCalender.setStudentIds(musicGroupPaymentCalenderDto.getStudentIds());
			musicGroupPaymentCalender.setOperator(sysUser.getId());
			musicGroupPaymentCalender.setCreateTime(date);
			musicGroupPaymentCalender.setUpdateTime(date);
			musicGroupPaymentCalender.setStatus(status);

			if (musicGroupPaymentCalender.getDeadlinePaymentDate() == null && payUserType == PayUserType.STUDENT) {
				musicGroupPaymentCalender.setDeadlinePaymentDate(DateUtil.addDays(musicGroupPaymentCalender.getStartPaymentDate(), 3));
			}
			if (paymentType != ADD_STUDENT && paymentType != ADD_COURSE && paymentType != SPAN_GROUP_CLASS_ADJUST) {
				int count = musicGroupPaymentCalenderDao.queryIntersectionByValidDate(musicGroupId, musicGroupPaymentCalender.getPayUserType(),
						musicGroupPaymentCalender.getPaymentValidStartDate(), musicGroupPaymentCalender.getPaymentValidEndDate(), null);
				if (count > 0) {
					throw new BizException("缴费有效期存在冲突，请修改缴费有效期");
				}
			}

			if (paymentType == PaymentType.ADD_STUDENT) {
				musicGroupPaymentCalender.setPayUserType(STUDENT);
				musicGroupPaymentCalender.setIsGiveMusicNetwork(false);
				if (musicGroupPaymentCalender.getStatus() != AUDITING) {
					musicGroupPaymentCalender.setExpectNum(1);
				}
			}
			if (musicGroupPaymentCalender.getStatus() != AUDITING) {
				if (date.after(musicGroupPaymentCalender.getStartPaymentDate())) {
					musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.OPEN);
				} else if (date.after(musicGroupPaymentCalender.getDeadlinePaymentDate())) {
					musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.OVER);
				} else {
					musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.NO);
				}
			}

			// 设置批次号
			musicGroupPaymentCalender.setBatchNo(batchNo);
			musicGroupPaymentCalenderDto.setBatchNo(batchNo);
			musicGroupPaymentCalenderDao.insert(musicGroupPaymentCalender);


			List<MusicGroupPaymentCalenderCourseSettings> currentMusicGroupPaymentCalenderCourseSettings = musicGroupPaymentCalender
					.getMusicGroupPaymentCalenderCourseSettingsList();

			if (currentMusicGroupPaymentCalenderCourseSettings.size() > 0) {
				MusicGroupOrganizationCourseSettings courseSettings = musicGroupOrganizationCourseSettingsDao.get(musicGroupPaymentCalender
						.getMusicGroupOrganizationCourseSettingId());
				for (MusicGroupPaymentCalenderCourseSettings musicGroupPaymentCalenderCourseSettings : currentMusicGroupPaymentCalenderCourseSettings) {
					musicGroupPaymentCalenderCourseSettings.setMusicGroupPaymentCalenderId(musicGroupPaymentCalender.getId());
					if (courseSettings != null) {
						musicGroupPaymentCalenderCourseSettings.setName(courseSettings.getName());
					}
				}
				musicGroupPaymentCalenderCourseSettingsDao.batchInsert(currentMusicGroupPaymentCalenderCourseSettings);
			}

			//如果是跨团班级合并,保存用户缴费详情
			List<MusicGroupPaymentCalenderStudentDetail> musicGroupPaymentCalenderStudentDetails = null;
			if (musicGroupPaymentCalender.getPaymentType() == SPAN_GROUP_CLASS_ADJUST){
				musicGroupPaymentCalenderStudentDetails = musicGroupPaymentCalenderDto.getMusicGroupPaymentCalenderStudentDetails();
				//记录学员缴费详情
				musicGroupPaymentCalenderStudentDetailDao.batchInsert(musicGroupPaymentCalenderStudentDetails,musicGroupPaymentCalender.getBatchNo());
			}

			if (musicGroupPaymentCalender.getStatus() != AUDITING) {
				// 如果是进行中加学生
				if (musicGroupPaymentCalender.getPaymentType() == PaymentType.ADD_STUDENT) {
					addStudent(musicGroupPaymentCalender, currentMusicGroupPaymentCalenderCourseSettings);
				}else if(musicGroupPaymentCalender.getPaymentType() == SPAN_GROUP_CLASS_ADJUST){
					//如果是跨团班级合并,添加学员
					musicGroupPaymentCalenderDetailService.batchAdd(musicGroupPaymentCalender,musicGroupPaymentCalenderStudentDetails);
				}else if(musicGroupPaymentCalenderDto.getMergeClassFlag()){
					//缴费项目添加学员
					int[] ints = Arrays.stream(musicGroupPaymentCalenderDto.getStudentIds().split(",")).mapToInt(Integer::parseInt).toArray();
					Set<Integer> list2 = Arrays.stream(ints).boxed().collect(Collectors.toSet());
					musicGroupPaymentCalenderDetailService.batchAdd(musicGroupPaymentCalender.getId(),list2);
				}
			}
		}

		// 如果是报名，需要修改乐团状态
		if (paymentType == MUSIC_APPLY) {
			if (status != AUDITING) {
				musicGroup.setStatus(MusicGroupStatusEnum.APPLY);
				// 记录操作日志
				musicGroupBuildLogDao.insert(new MusicGroupBuildLog(musicGroupId, "报名缴费项目创建成功（创建缴费 -> 报名中）", sysUser.getId(), ""));
			} else {
				musicGroup.setStatus(MusicGroupStatusEnum.FEE_AUDIT);
				// 记录操作日志
				musicGroupBuildLogDao.insert(new MusicGroupBuildLog(musicGroupId, "报名缴费项目创建成功（创建缴费 -> 费用审核中）", sysUser.getId(), ""));
			}
			musicGroup.setUpdateTime(date);
			musicGroupDao.update(musicGroup);
		} else if (paymentType == ADD_STUDENT) {

			if (status != AUDITING) {
				// 学生加到班级
				String classGroupIdStr = musicGroupPaymentCalenderDto.getAttribute1();
				if (StringUtils.isNotBlank(classGroupIdStr)) {
					classGroupService.addStudentToClassGroupAndCourseArranging(Integer.parseInt(musicGroupPaymentCalenderDto.getStudentIds()), classGroupIdStr,
							batchNo, musicGroupPaymentCalenderCourseSettingsList);
				}
			}
		}

		if (status == AUDITING) {
			// 如果是审核中
			Set<Integer> roleIds = new HashSet<>(1);
			roleIds.add(SysUserRole.ADMINISTRATOR);
			Organization organization = organizationDao.get(musicGroup.getOrganId());
			sysMessageService.batchSeoMessage(musicGroupDao.queryUserIdByRoleId(roleIds, musicGroup.getOrganId()),
					MessageTypeEnum.BACKSTAGE_PAYMENT_CALENDER_AUDIT, "", organization.getName(), musicGroup.getName());
		}else {
			imUserFriendService.refreshGroupImUserFriend(musicGroupId, GroupType.MUSIC);
		}
		return batchNo;
	}

	@Override
	public Object getDetail(Long id) {
		MusicGroupPaymentCalender calender = musicGroupPaymentCalenderDao.get(id);
		Map<Long, Long> expectNumMap = MapUtil.convertIntegerMap(musicGroupPaymentCalenderDao.countExpectNum(id));
		Map<Long, Long> actualNumMap = MapUtil.convertIntegerMap(musicGroupPaymentCalenderDao.countActualNum(id));
		calender.setActualNum(actualNumMap.get(id) == null ? 0 : actualNumMap.get(id).intValue());
		calender.setExpectNum(expectNumMap.get(id) == null ? 0 : expectNumMap.get(id).intValue());
		BigDecimal sumActualAmount = musicGroupPaymentCalenderDetailDao.sumActualAmount(id);
		//收费标准名称
		String name = musicGroupPaymentCalenderDao.getCalenderSettingsName(id);
		List<MusicGroupPaymentCalenderCourseSettings> musicGroupPaymentCalenderCourseSettings = musicGroupPaymentCalenderCourseSettingsDao.queryCalenderCourseSettings(id);
		Map<String, Object> result = new HashMap<>(4);
		result.put("musicGroupPaymentCalenderCourseSettings", musicGroupPaymentCalenderCourseSettings);
		result.put("calender", calender);
		result.put("calenderSettingsName", name);
		result.put("sumActualAmount", sumActualAmount);
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String merge(MusicGroupPaymentCalenderDto musicGroupPaymentCalenderDto) {
		
		String batchNo = musicGroupPaymentCalenderDto.getBatchNo();
		
		List<MusicGroupPaymentCalender> musicGroupPaymentCalenderList = musicGroupPaymentCalenderDao.findByBatchNo(batchNo);
		if(musicGroupPaymentCalenderList == null || musicGroupPaymentCalenderList.size() == 0){
			throw new BizException("[批次号]参数错误");
		}
		
		PaymentCalenderStatusEnum status = musicGroupPaymentCalenderList.get(0).getStatus();
		if(status != PaymentCalenderStatusEnum.REJECT){
			throw new BizException("只有[拒绝]状态的缴费才能修改");
		}
		String musicGroupId = musicGroupPaymentCalenderDto.getMusicGroupId();

		PaymentType paymentType = musicGroupPaymentCalenderDto.getPaymentType();

		PayUserType payUserType = musicGroupPaymentCalenderDto.getPayUserType();

		List<MusicGroupPaymentDateRange> musicGroupPaymentDateRangeList = musicGroupPaymentCalenderDto.getMusicGroupPaymentDateRangeList();

		if ((paymentType == PaymentType.ADD_COURSE) && musicGroupPaymentDateRangeList.size() > 1) {
			throw new BizException("[临时加课]不支持多周期缴费");
		}

		MusicGroup musicGroup = musicGroupDao.getLocked(musicGroupId);

		if (musicGroup == null) {
			throw new BizException("乐团查询失败，请检查参数");
		}
		SysUser sysUser = sysUserFeignService.queryUserInfo();
		if (sysUser == null) {
			throw new BizException("请登录");
		}

		List<Long> calenderIds = musicGroupPaymentCalenderList.stream().map(MusicGroupPaymentCalender :: getId).collect(Collectors.toList());
		//删除原来数据
		musicGroupPaymentCalenderDao.delByIds(calenderIds);
		musicGroupPaymentCalenderCourseSettingsDao.deleteByMusicGroupPaymentCalenderId(calenderIds);

		status = PaymentCalenderStatusEnum.NO;

		Date date = new Date();

		// 获取设置的课程
		List<MusicGroupPaymentCalenderCourseSettings> musicGroupPaymentCalenderCourseSettingsList = musicGroupPaymentCalenderDto
				.getMusicGroupPaymentCalenderCourseSettingsList();
		if (musicGroupPaymentCalenderCourseSettingsList == null) {
			musicGroupPaymentCalenderCourseSettingsList = new ArrayList<>();
		}

		if (payUserType == SCHOOL) {
			status = AUDITING;
		} else {
			if (paymentType == MUSIC_APPLY || paymentType == MUSIC_RENEW) {
				// 当前缴费的课程费用
				Map<CourseScheduleType, BigDecimal> currentCoursePrice = musicGroupPaymentCalenderCourseSettingsList.stream().collect(
						Collectors
								.toMap(MusicGroupPaymentCalenderCourseSettings::getCourseType, MusicGroupPaymentCalenderCourseSettings::getCourseCurrentPrice));

				// 查询默认课程费用
				Integer musicGroupOrganizationCourseSettingId = musicGroupPaymentCalenderDto.getMusicGroupOrganizationCourseSettingId();
				Map<CourseScheduleType, BigDecimal> defaultCoursePrice = musicGroupOrganizationCourseSettingsDetailDao
						.queryByMusicGroupOrganizationCourseSettingsId(musicGroupOrganizationCourseSettingId)
						.stream()
						.collect(
								Collectors.toMap(MusicGroupOrganizationCourseSettingsDetail::getCourseType,
										MusicGroupOrganizationCourseSettingsDetail::getCourseCurrentPrice));

				// 相同类型的课程如果修改了课程费用，需要走审批
				for (Entry<CourseScheduleType, BigDecimal> entry : currentCoursePrice.entrySet()) {
					if (defaultCoursePrice.get(entry.getKey()).compareTo(entry.getValue()) != 0) {
						status = AUDITING;
						break;
					}
				}
			} else if (paymentType == PaymentType.ADD_COURSE || paymentType == PaymentType.ADD_STUDENT) {
				// 如果是临时加课，判断是否审核
				for (MusicGroupPaymentCalenderCourseSettings courseSettings : musicGroupPaymentCalenderCourseSettingsList) {
					OrganizationCourseUnitPriceSettings defaultUnitPrice = organizationCourseUnitPriceSettingsDao.queryByOrganIdAndCourseTypeAndChargeType(
							musicGroup.getOrganId(), courseSettings.getCourseType(), musicGroup.getChargeTypeId());
					if (defaultUnitPrice == null) {
						throw new BizException("请先设置分部课程类型单价");
					}
					if (courseSettings.getCourseTotalMinuties() != 0) {
						if (defaultUnitPrice.getUnitPrice().multiply(new BigDecimal(courseSettings.getCourseTotalMinuties())).setScale(0, BigDecimal.ROUND_HALF_UP)
								.compareTo(courseSettings.getCourseCurrentPrice()) != 0) {

							status = AUDITING;
							break;
						}
					} else {
						status = AUDITING;
						break;
					}
				}
			}else if(paymentType == SPAN_GROUP_CLASS_ADJUST){
				MusicGroupStudentClassAdjust adjust = musicGroupStudentClassAdjustDao.findByBatchNo(batchNo);
				//获取默认的学员缴费详情
				List<Integer> studentIds = JSON.parseArray(adjust.getStudentIds(), Integer.class);
				List<MusicGroupPaymentCalenderStudentDetail> musicGroupPaymentCalenderStudentDetails = classGroupService.queryStudentPaymentCalenders(adjust.getMasterClassGroupId(),
						adjust.getClassGroupStudents(),studentIds);
				List<MusicGroupPaymentCalenderStudentDetail> calenderStudentDetails = musicGroupPaymentCalenderDto.getMusicGroupPaymentCalenderStudentDetails();

				boolean containsAll = musicGroupPaymentCalenderStudentDetails.containsAll(calenderStudentDetails);
				if(!containsAll){
					status = AUDITING;
					//保存新的学员详情
				}
				//删除之前的记录
				musicGroupPaymentCalenderStudentDetailDao.delByBatchNo(batchNo);
				//保存现有记录
				musicGroupPaymentCalenderStudentDetailDao.batchInsert(calenderStudentDetails,batchNo);
			}
		}

		int times = musicGroupPaymentDateRangeList.size();

		// 排序
		Collections.sort(musicGroupPaymentDateRangeList, new Comparator<MusicGroupPaymentDateRange>() {

			@Override
			public int compare(MusicGroupPaymentDateRange o1, MusicGroupPaymentDateRange o2) {
				return o1.getPaymentValidStartDate().compareTo(o2.getPaymentValidStartDate());
			}
		});

		for (int i = 0; i < musicGroupPaymentDateRangeList.size(); i++) {

			MusicGroupPaymentDateRange musicGroupPaymentDateRange = musicGroupPaymentDateRangeList.get(i);

			MusicGroupPaymentCalender musicGroupPaymentCalender = new MusicGroupPaymentCalender();
			musicGroupPaymentCalender.setAttribute1(musicGroupPaymentCalenderDto.getAttribute1());
			musicGroupPaymentCalender.setAttribute2(musicGroupPaymentCalenderDto.getAttribute2());
			musicGroupPaymentCalender.setDeadlinePaymentDate(musicGroupPaymentDateRange.getDeadlinePaymentDate());
			musicGroupPaymentCalender.setIsGiveMusicNetwork(musicGroupPaymentCalenderDto.getIsGiveMusicNetwork());
			musicGroupPaymentCalender.setMemo(musicGroupPaymentCalenderDto.getMemo());
			musicGroupPaymentCalender.setMusicGroupId(musicGroupId);
			musicGroupPaymentCalender.setMusicGroupOrganizationCourseSettingId(musicGroupPaymentCalenderDto.getMusicGroupOrganizationCourseSettingId());

			List<MusicGroupPaymentCalenderCourseSettings> newCSList = new ArrayList<MusicGroupPaymentCalenderCourseSettings>(
					musicGroupPaymentCalenderCourseSettingsList.size());

			BigDecimal totalPaymentAmount = new BigDecimal(0);
			if(musicGroupPaymentCalenderDto.getPaymentType() == SPAN_GROUP_CLASS_ADJUST){
				totalPaymentAmount = musicGroupPaymentDateRange.getPaymentAmount();
			}
			for (MusicGroupPaymentCalenderCourseSettings pccs : musicGroupPaymentCalenderCourseSettingsList) {

				MusicGroupPaymentCalenderCourseSettings tempPccs = new MusicGroupPaymentCalenderCourseSettings();
				try {
					BeanUtils.copyProperties(tempPccs, pccs);
				} catch (Exception e) {
					throw new BizException("克隆对象出错", e);
				}
				if (i == 0) {
					if (pccs.getIsStudentOptional()) {
						tempPccs.setCourseCurrentPrice(pccs.getCourseCurrentPrice());
						tempPccs.setCourseOriginalPrice(pccs.getCourseOriginalPrice());
						tempPccs.setCourseTotalMinuties(pccs.getCourseTotalMinuties());
					} else {
						tempPccs.setCourseCurrentPrice(pccs.getCourseCurrentPrice().subtract(
								pccs.getCourseCurrentPrice().divide(new BigDecimal(times), 0, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(times - 1))
										.setScale(0, BigDecimal.ROUND_DOWN)));
						tempPccs.setCourseOriginalPrice(pccs.getCourseOriginalPrice().subtract(
								pccs.getCourseOriginalPrice().divide(new BigDecimal(times), 0, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(times - 1))
										.setScale(0, BigDecimal.ROUND_DOWN)));
						tempPccs.setCourseTotalMinuties(pccs.getCourseTotalMinuties() - pccs.getCourseTotalMinuties() / times * (times - 1));
					}
				} else {
					if (!pccs.getIsStudentOptional()) {
						tempPccs.setCourseCurrentPrice(pccs.getCourseCurrentPrice().divide(new BigDecimal(times), 0, BigDecimal.ROUND_DOWN));
						tempPccs.setCourseOriginalPrice(pccs.getCourseOriginalPrice().divide(new BigDecimal(times), 0, BigDecimal.ROUND_DOWN));
						tempPccs.setCourseTotalMinuties(pccs.getCourseTotalMinuties() / times);
					}
				}
				totalPaymentAmount = totalPaymentAmount.add(tempPccs.getCourseCurrentPrice());
				newCSList.add(tempPccs);
			}
			musicGroupPaymentCalender.setMusicGroupPaymentCalenderCourseSettingsList(newCSList);
			musicGroupPaymentCalender.setPaymentAmount(totalPaymentAmount);

			musicGroupPaymentCalender.setPaymentPattern(musicGroupPaymentCalenderDto.getPaymentPattern());
			musicGroupPaymentCalender.setPaymentValidEndDate(musicGroupPaymentDateRange.getPaymentValidEndDate());
			musicGroupPaymentCalender.setPaymentValidStartDate(musicGroupPaymentDateRange.getPaymentValidStartDate());
			
			if (paymentType == PaymentType.MUSIC_APPLY) {
				if (i == 0) {
					musicGroupPaymentCalender.setPaymentType(paymentType);
				} else {
					musicGroupPaymentCalender.setPaymentType(PaymentType.MUSIC_RENEW);
				}
			} else {
				musicGroupPaymentCalender.setPaymentType(paymentType);
			}
			musicGroupPaymentCalender.setPayUserType(musicGroupPaymentCalenderDto.getPayUserType());
			musicGroupPaymentCalender.setStartPaymentDate(musicGroupPaymentDateRange.getStartPaymentDate());
			if(StringUtils.isNotEmpty(musicGroupPaymentCalenderDto.getStudentIds())){
				musicGroupPaymentCalender.setStudentIds(musicGroupPaymentCalenderDto.getStudentIds());
			}
			musicGroupPaymentCalender.setOperator(sysUser.getId());
			musicGroupPaymentCalender.setCreateTime(date);
			musicGroupPaymentCalender.setUpdateTime(date);
			musicGroupPaymentCalender.setStatus(status);

			if (musicGroupPaymentCalender.getDeadlinePaymentDate() == null && payUserType == PayUserType.STUDENT) {
				musicGroupPaymentCalender.setDeadlinePaymentDate(DateUtil.addDays(musicGroupPaymentCalender.getStartPaymentDate(), 3));
			}
			if (paymentType != ADD_STUDENT && paymentType != ADD_COURSE && paymentType != SPAN_GROUP_CLASS_ADJUST) {
				int count = musicGroupPaymentCalenderDao.queryIntersectionByValidDate(musicGroupId, musicGroupPaymentCalender.getPayUserType(),
						musicGroupPaymentCalender.getPaymentValidStartDate(), musicGroupPaymentCalender.getPaymentValidEndDate(), null);
				if (count > 0) {
					throw new BizException("缴费有效期存在冲突，请修改缴费有效期");
				}
			}

			if (paymentType == PaymentType.ADD_STUDENT) {
				musicGroupPaymentCalender.setPayUserType(STUDENT);
				musicGroupPaymentCalender.setIsGiveMusicNetwork(false);
				if (musicGroupPaymentCalender.getStatus() != AUDITING) {
					musicGroupPaymentCalender.setExpectNum(1);
				}
			}
			if (musicGroupPaymentCalender.getStatus() != AUDITING) {
				if (date.after(musicGroupPaymentCalender.getStartPaymentDate())) {
					musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.OPEN);
				} else if (date.after(musicGroupPaymentCalender.getDeadlinePaymentDate())) {
					musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.OVER);
				} else {
					musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.NO);
				}
			}

			// 设置批次号
			musicGroupPaymentCalender.setBatchNo(batchNo);
			musicGroupPaymentCalenderDao.insert(musicGroupPaymentCalender);

			List<MusicGroupPaymentCalenderCourseSettings> currentMusicGroupPaymentCalenderCourseSettings = musicGroupPaymentCalender
					.getMusicGroupPaymentCalenderCourseSettingsList();

			if (musicGroupPaymentCalender.getStatus() != AUDITING) {
				// 如果是进行中加学生
				if (musicGroupPaymentCalender.getPaymentType() == PaymentType.ADD_STUDENT) {
					addStudent(musicGroupPaymentCalender, currentMusicGroupPaymentCalenderCourseSettings);
				}else if(musicGroupPaymentCalender.getPaymentType() == SPAN_GROUP_CLASS_ADJUST){
					//如果是跨团班级合并,添加学员
					musicGroupPaymentCalenderDetailService.batchAdd(musicGroupPaymentCalender,musicGroupPaymentCalenderDto.getMusicGroupPaymentCalenderStudentDetails());
				}
			}

			if (currentMusicGroupPaymentCalenderCourseSettings.size() > 0) {
				MusicGroupOrganizationCourseSettings courseSettings = musicGroupOrganizationCourseSettingsDao.get(musicGroupPaymentCalender
						.getMusicGroupOrganizationCourseSettingId());
				for (MusicGroupPaymentCalenderCourseSettings musicGroupPaymentCalenderCourseSettings : currentMusicGroupPaymentCalenderCourseSettings) {
					musicGroupPaymentCalenderCourseSettings.setMusicGroupPaymentCalenderId(musicGroupPaymentCalender.getId());
					if (courseSettings != null) {
						musicGroupPaymentCalenderCourseSettings.setName(courseSettings.getName());
					}
				}
				musicGroupPaymentCalenderCourseSettingsDao.batchInsert(currentMusicGroupPaymentCalenderCourseSettings);
			}
		}

		// 如果是报名，需要修改乐团状态
		if (paymentType == MUSIC_APPLY) {
			if (status != AUDITING) {
				musicGroup.setStatus(MusicGroupStatusEnum.APPLY);
				// 记录操作日志
				musicGroupBuildLogDao.insert(new MusicGroupBuildLog(musicGroupId, "报名缴费项目创建成功（创建缴费 -> 报名中）", sysUser.getId(), ""));
			} else {
				musicGroup.setStatus(MusicGroupStatusEnum.FEE_AUDIT);
				// 记录操作日志
				musicGroupBuildLogDao.insert(new MusicGroupBuildLog(musicGroupId, "报名缴费项目创建成功（创建缴费 -> 费用审核中）", sysUser.getId(), ""));
			}
			musicGroup.setUpdateTime(date);
			musicGroupDao.update(musicGroup);
		} else if (paymentType == ADD_STUDENT) {
			if (status != AUDITING) {
				// 学生加到班级
				String classGroupIdStr = musicGroupPaymentCalenderDto.getAttribute1();
				if (StringUtils.isNotBlank(classGroupIdStr)) {
					classGroupService.addStudentToClassGroupAndCourseArranging(Integer.parseInt(musicGroupPaymentCalenderDto.getStudentIds()), classGroupIdStr,
							batchNo, musicGroupPaymentCalenderCourseSettingsList);
				}
			}
		}

		if (status == AUDITING) {
			// 如果是审核中
			Set<Integer> roleIds = new HashSet<>(1);
			roleIds.add(SysUserRole.ADMINISTRATOR);
			Organization organization = organizationDao.get(musicGroup.getOrganId());
			sysMessageService.batchSeoMessage(musicGroupDao.queryUserIdByRoleId(roleIds, musicGroup.getOrganId()),
					MessageTypeEnum.BACKSTAGE_PAYMENT_CALENDER_AUDIT, "", organization.getName(), musicGroup.getName());
		}else {
			if(paymentType == ADD_STUDENT){
				MusicGroupStudentClassAdjust musicGroupStudentClassAdjust = musicGroupStudentClassAdjustDao.findByBatchNo(batchNo);
				if(musicGroupStudentClassAdjust != null){
					//如果是合班缴费
					autoClassGroupAdjust(musicGroupStudentClassAdjust);
				}else {
					imUserFriendService.refreshGroupImUserFriend(musicGroupId,GroupType.MUSIC);
				}
			}else if(paymentType == SPAN_GROUP_CLASS_ADJUST){
				//删除和解冻班级，课程信息
				MusicGroupStudentClassAdjust adjust = musicGroupStudentClassAdjustDao.findByBatchNo(batchNo);
				List<Map> classGroupStudents = JSON.parseArray(adjust.getClassGroupStudents(),Map.class);
				List<Integer> studentIds = JSON.parseArray(adjust.getStudentIds(), Integer.class);
				List<Long> courseIds = JSON.parseArray(adjust.getSubLockCourseIds(), Long.class);
				List<Long> allLockCourseIds = JSON.parseArray(adjust.getAllLockCourseIds(), Long.class);
				classGroupService.spanGroupClassAdjustPass(adjust.getMasterClassGroupId()
						,studentIds,courseIds,classGroupStudents,allLockCourseIds,batchNo,adjust.getMasterTotalPrice());
			}
		}
		return batchNo;
	}

	@Override
	public boolean makesureSchoolePaid(Long id, String memo) {
		MusicGroupPaymentCalender musicGroupPaymentCalender = musicGroupPaymentCalenderDao.get(id);
		if(musicGroupPaymentCalender == null){
			throw new BizException("查询缴费信息失败");
		}
		
		if(musicGroupPaymentCalender.getPayUserType() != PayUserType.SCHOOL){
			throw new BizException("只有学校缴费才能确认缴费状态");
		}
		
		musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.PAID);
		musicGroupPaymentCalender.setMemo(memo);
		musicGroupPaymentCalender.setUpdateTime(new Date());
		musicGroupPaymentCalenderDao.update(musicGroupPaymentCalender);
		
		return true;
	}

	public void addStudent(MusicGroupPaymentCalender musicGroupPaymentCalender,List<MusicGroupPaymentCalenderCourseSettings> musicGroupPaymentCalenderCourseSettingsList){
		//如果是进行中加学生
		Date date = new Date();
		String studentIdStr = musicGroupPaymentCalender.getStudentIds();
		if (StringUtils.isNoneBlank(studentIdStr)) {
			//计算总费用
			BigDecimal totalPrice = new BigDecimal(0);
			for(MusicGroupPaymentCalenderCourseSettings musicGroupPaymentCalenderCourseSettings : musicGroupPaymentCalenderCourseSettingsList){
				totalPrice = totalPrice.add(musicGroupPaymentCalenderCourseSettings.getCourseCurrentPrice());
			}

			List<MusicGroupPaymentStudentCourseDetail> musicGroupPaymentStudentCourseDetailList = new ArrayList<MusicGroupPaymentStudentCourseDetail>();
			MusicGroupPaymentStudentCourseDetail musicGroupPaymentStudentCourseDetail = null;

			for (String studentId : studentIdStr.split(",")) {
				// 学生加到calenderDetail
				MusicGroupPaymentCalenderDetail musicGroupPaymentCalenderDetail = new MusicGroupPaymentCalenderDetail();
				musicGroupPaymentCalenderDetail.setMusicGroupPaymentCalenderId(musicGroupPaymentCalender.getId());
				musicGroupPaymentCalenderDetail.setCreateTime(date);
				musicGroupPaymentCalenderDetail.setExpectAmount(totalPrice);
				musicGroupPaymentCalenderDetail.setPaymentStatus(PaymentStatus.NON_PAYMENT);
				musicGroupPaymentCalenderDetail.setUpdateTime(date);
				musicGroupPaymentCalenderDetail.setUserId(Integer.parseInt(studentId));
				musicGroupPaymentCalenderDetail.setStartPaymentDate(musicGroupPaymentCalender.getStartPaymentDate());
				musicGroupPaymentCalenderDetail.setDeadlinePaymentDate(musicGroupPaymentCalender.getDeadlinePaymentDate());

				musicGroupPaymentCalenderDetailDao.insert(musicGroupPaymentCalenderDetail);

				// 学生加课程明细
				for(MusicGroupPaymentCalenderCourseSettings courseSettings : musicGroupPaymentCalenderCourseSettingsList){
					if (courseSettings.getIsStudentOptional() == true) {
						continue;
					}
					musicGroupPaymentStudentCourseDetail = new MusicGroupPaymentStudentCourseDetail();
					musicGroupPaymentStudentCourseDetail.setCourseType(courseSettings.getCourseType());
					musicGroupPaymentStudentCourseDetail.setCreateTime(date);
					musicGroupPaymentStudentCourseDetail.setMusicGroupPaymentCalenderId(musicGroupPaymentCalender.getId());
					musicGroupPaymentStudentCourseDetail.setMusicGroupPaymentCalenderDetailId(musicGroupPaymentCalenderDetail.getId());
					musicGroupPaymentStudentCourseDetail.setTotalCourseMinutes(courseSettings.getCourseTotalMinuties());
					musicGroupPaymentStudentCourseDetail.setUpdateTime(date);
					musicGroupPaymentStudentCourseDetail.setUsedCourseMinutes(courseSettings.getCourseTotalMinuties());
					musicGroupPaymentStudentCourseDetail.setUserId(Integer.parseInt(studentId));

					musicGroupPaymentStudentCourseDetailList.add(musicGroupPaymentStudentCourseDetail);
				}

				if(musicGroupPaymentStudentCourseDetailList.size() > 0){
					musicGroupPaymentStudentCourseDetailDao.batchInsert(musicGroupPaymentStudentCourseDetailList);
				}
			}
		}
	}

	@Override
	public void autoUpdateMusicGroupStudentFeeStatus() {
		Date date = new Date();
		String format = DateUtil.format(date, DateUtil.DEFAULT_PATTERN);
		// 获取距离缴费开启指定天数后的缴费明细
		String configValue = sysConfigDao.findConfigValue("push_payment_detail");
		Map<Long, Long> maps = MapUtil.convertIntegerMap(musicGroupPaymentCalenderDao.queryCalenderByDay(configValue, format));
		if (maps != null && maps.size() > 0) {
			Set<Long> calenderId = maps.keySet();
			List<CalenderPushDto> calenderPushDtos = musicGroupPaymentCalenderDao.getCalenderPushDto(calenderId);
			Map<Long, List<CalenderPushDto>> collect = calenderPushDtos.stream().collect(Collectors.groupingBy(CalenderPushDto::getCalenderId));
			calenderId.forEach(e -> {
				CalenderPushDto calenderPushDto = collect.get(e).get(0);
				Map<Integer, String> receivers = new HashMap<>(1);
				receivers.put(calenderPushDto.getTeacherId(), calenderPushDto.getTeacherPhone());
				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_PAYMENT_DETAIL, receivers, null, 0,
						null, null, calenderPushDto.getMusicGroupName(), calenderPushDto.getPaymentValidStartDate(), calenderPushDto.getPaymentValidEndDate(),
						maps.get(e));
				Map<Integer, String> receivers1 = new HashMap<>(1);
				receivers1.put(calenderPushDto.getTeacherId(), calenderPushDto.getTeacherId().toString());
				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.SMS_PAYMENT_DETAIL, receivers1, null, 0,
						null, "SYSTEM", calenderPushDto.getMusicGroupName(), calenderPushDto.getPaymentValidStartDate(), calenderPushDto.getPaymentValidEndDate(),
						maps.get(e));
			});
		}
		// 获取离截止还有指定时间的缴费项，并发送推送消息给指定老师
		String configValue1 = sysConfigDao.findConfigValue("push_create_payment_calender");
		List<Long> calenderIds = musicGroupPaymentCalenderDao.queryEndIds(configValue1, format);
		if (calenderIds != null && calenderIds.size() > 0) {
			List<CalenderPushDto> calenderPushDtos = musicGroupPaymentCalenderDao.getCalenderPushDto(calenderIds);
			Map<Long, List<CalenderPushDto>> collect = calenderPushDtos.stream().collect(Collectors.groupingBy(CalenderPushDto::getCalenderId));
			calenderIds.forEach(e -> {
				CalenderPushDto calenderPushDto = collect.get(e).get(0);
				Map<Integer, String> receivers = new HashMap<>(1);
				receivers.put(calenderPushDto.getTeacherId(), calenderPushDto.getTeacherPhone());
				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_PAYMENT_CREATE, receivers, null, 0,
						null, null, calenderPushDto.getMusicGroupName(), calenderPushDto.getPaymentValidStartDate(), calenderPushDto.getPaymentValidEndDate());
				Map<Integer, String> receivers1 = new HashMap<>(1);
				receivers1.put(calenderPushDto.getTeacherId(), calenderPushDto.getTeacherId().toString());
				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.SMS_PAYMENT_CREATE, receivers1, null, 0,
						null, "SYSTEM", calenderPushDto.getMusicGroupName(), calenderPushDto.getPaymentValidStartDate(), calenderPushDto.getPaymentValidEndDate());
			});
		}

		// 乐团报名到期，提醒教务老师创建缴费
		List<CalenderPushDto> calenderPushDtos = musicGroupPaymentCalenderDao.getMusicCalenderPushDto(configValue1, format);
		if (calenderPushDtos != null && calenderPushDtos.size() > 0) {
			calenderPushDtos.forEach(e -> {
				Map<Integer, String> receivers = new HashMap<>(1);
				receivers.put(e.getTeacherId(), e.getTeacherPhone());
				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_PAYMENT_CREATE, receivers, null, 0,
						null, null, e.getMusicGroupName(), e.getPaymentValidStartDate(), e.getPaymentValidEndDate());
				Map<Integer, String> receivers1 = new HashMap<>(1);
				receivers1.put(e.getTeacherId(), e.getTeacherId().toString());
				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.SMS_PAYMENT_CREATE, receivers1, null, 0,
						null, "SYSTEM", e.getMusicGroupName(), e.getPaymentValidStartDate(), e.getPaymentValidEndDate());
			});
		}
	}

	@Override
	public PageInfo<MusicGroupPaymentCalenderAuditDto> auditList(MusicGroupPaymentCalenderQueryInfo queryInfo) {
		PageInfo<MusicGroupPaymentCalenderAuditDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
		Map<String, Object> params = new HashMap<>();
		MapUtil.populateMap(params, queryInfo);

		List<MusicGroupPaymentCalenderAuditDto> dataList = null;
		int count = musicGroupPaymentCalenderDao.countAuditList(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = musicGroupPaymentCalenderDao.queryAuditList(params);
			List<Integer> collect = dataList.stream().map(e -> e.getOrganId()).collect(Collectors.toList());
			collect.removeAll(Collections.singleton(null));
			Map<Integer, String> organNameMap = getMap("organization", "id_", "name_", collect, Integer.class, String.class);
			List<Integer> operatorIds = dataList.stream().map(e -> e.getOperator()).collect(Collectors.toList());
			operatorIds.removeAll(Collections.singleton(null));
			Map<Integer, String> realNameMap = getMap("sys_user", "id_", "real_name_", operatorIds, Integer.class, String.class);
			dataList.forEach(e->{
				e.setOrganName(organNameMap.get(e.getOrganId()));
				e.setOperatorName(realNameMap.get(e.getOperator()));
			});
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	public MusicGroupPaymentCalenderAuditDetailDto auditListDetail(String batchNo) {
		MusicGroupPaymentCalenderAuditDetailDto calenderAuditDetailDto = new MusicGroupPaymentCalenderAuditDetailDto();
		MusicGroupPaymentCalenderAuditDto auditDto = musicGroupPaymentCalenderDao.getAuditDetail(batchNo);
		calenderAuditDetailDto.setAuditDto(auditDto);
		//获取收费标准
		calenderAuditDetailDto.setMusicGroupPaymentCalenderCourseSettings(musicGroupPaymentCalenderCourseSettingsDao.queryCalenderCourseSettingsByBatchNo(batchNo));
		//获取缴费周期
		List<MusicGroupPaymentCalender> groupPaymentCalenders = musicGroupPaymentCalenderDao.findByBatchNo(batchNo);
		calenderAuditDetailDto.setMusicGroupPaymentCalenders(groupPaymentCalenders);
		//获取跨团合班学员缴费详情
		calenderAuditDetailDto.setMusicGroupPaymentCalenderStudentDetails(musicGroupPaymentCalenderStudentDetailDao.findByBatchNo(batchNo));
		return calenderAuditDetailDto;
	}

	//审核通过后自动排课
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void autoClassGroupAdjust(MusicGroupStudentClassAdjust musicGroupStudentClassAdjust){
		List<MusicGroupPaymentCalender> musicGroupPaymentCalenders = musicGroupPaymentCalenderDao.findByBatchNo(musicGroupStudentClassAdjust.getBatchNo());
		for (MusicGroupPaymentCalender musicGroupPaymentCalender : musicGroupPaymentCalenders) {
			if(musicGroupPaymentCalender.getStatus() == AUDITING || musicGroupPaymentCalender.getStatus() == REJECT){
				return;
			}
		}
		List<ClassGroup4MixDto> classGroup4MixDtos = JSON.parseArray(musicGroupStudentClassAdjust.getNewClassGroupJson(), ClassGroup4MixDto.class);

		for (MusicGroupPaymentCalender calender : musicGroupPaymentCalenders) {
			//缴费项目添加学员
			int[] ints = Arrays.stream(calender.getStudentIds().split(",")).mapToInt(Integer::parseInt).toArray();
			Set<Integer> list2 = Arrays.stream(ints).boxed().collect(Collectors.toSet());
			musicGroupPaymentCalenderDetailService.batchAdd(calender.getId(),list2);
		}
		//每种课程类型单独排课
		ClassGroup classGroup = null;
		for (ClassGroup4MixDto classGroup4MixDto : classGroup4MixDtos) {
			classGroup4MixDto.setClassGroup(classGroup);
			classGroup4MixDto.setMusicGroupStudentClassAdjustId(musicGroupStudentClassAdjust.getId());
			classGroup4MixDto.setClassCourseMinute(musicGroupStudentClassAdjust.getClassCourseMinute());
			classGroup = classGroupService.classGroupAdjust2(classGroup4MixDto);
		}
		//排课完成后删除所选课程
		List<Long> courseIds = JSON.parseArray(musicGroupStudentClassAdjust.getSubLockCourseIds(), Long.class);
		List<Integer> studentIds = JSON.parseArray(musicGroupStudentClassAdjust.getStudentIds(), Integer.class);
		courseScheduleDao.deleteMusicGroupCourseSchedulesWithStudents(courseIds,studentIds);
		//解冻课程
		List<Long> allCourseIds = JSON.parseArray(musicGroupStudentClassAdjust.getAllLockCourseIds(), Long.class);
		courseScheduleDao.batchUpdateLockByCourseIds(allCourseIds,0);
		//解冻班级
		List<Integer> classGroupIds = JSON.parseArray(musicGroupStudentClassAdjust.getClassGroupIds(), Integer.class);
		classGroupDao.batchUpdateLockByClassGroupIds(classGroupIds,0);
		//删除班级学员
		musicGroupStudentClassAdjustDao.update(musicGroupStudentClassAdjust);
		String classGroupStudents = musicGroupStudentClassAdjust.getClassGroupStudents();
		if(StringUtils.isNotEmpty(classGroupStudents)){
			List<Map> maps = JSON.parseArray(classGroupStudents, Map.class);
			for (Map<Integer, String> classGroupStudent : maps) {
				Set<Integer> integers = classGroupStudent.keySet();
				for (Integer integer : integers) {
					List<Integer> collect = Arrays.asList(classGroupStudent.get(integer).split(",")).stream().map(e -> Integer.parseInt(e)).collect(Collectors.toList());
					//学员退出群聊
					imGroupMemberService.quit(integer.longValue(),collect);
					classGroupStudentMapperDao.deleteByClassGroupIdAndStudents(integer,classGroupStudent.get(integer));
				}
			}
		}
		//获取没有学员的课程列表
		List<Long> delCourseIds = courseScheduleDao.findNoStudentCourseIds(courseIds);
		if(delCourseIds != null && delCourseIds.size() > 0){
			//删除课程
			courseScheduleDao.deleteCourseSchedulesByClassGroupIds(delCourseIds);
			//删除教师考勤
			teacherAttendanceDao.batchDeleteByCourseSchedules(delCourseIds);
			//删除教师课酬
			courseScheduleTeacherSalaryDao.batchDeleteByCourseScheduleIds(delCourseIds);
		}
		imUserFriendService.refreshGroupImUserFriend(musicGroupPaymentCalenders.get(0).getMusicGroupId(),GroupType.MUSIC);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void auditPass(String batchNo,String auditMemo) {
		List<MusicGroupPaymentCalender> musicGroupPaymentCalenders = musicGroupPaymentCalenderDao.findByBatchNo(batchNo);
		if(musicGroupPaymentCalenders == null || musicGroupPaymentCalenders.size() == 0){
			throw new BizException("缴费项目不存在");
		}
		Date date = new Date();
		for (MusicGroupPaymentCalender musicGroupPaymentCalender : musicGroupPaymentCalenders) {
			//如果是报名项目，将乐团改为审核中，缴费项目修改状态，审核状态改为审核通过
			if(musicGroupPaymentCalender.getPayUserType() == SCHOOL){
				musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.OPEN);
			}else if (date.after(musicGroupPaymentCalender.getStartPaymentDate())) {
				musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.OPEN);
			}else if (date.after(musicGroupPaymentCalender.getDeadlinePaymentDate())) {
				musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.OVER);
			}else {
				musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.NO);
			}
			musicGroupPaymentCalender.setAuditMemo(auditMemo);
			musicGroupPaymentCalender.setUpdateTime(date);

			if (musicGroupPaymentCalender.getPaymentType() == PaymentType.ADD_STUDENT) {
				musicGroupPaymentCalender.setExpectNum(1);
				List<MusicGroupPaymentCalenderCourseSettings> musicGroupPaymentCalenderCourseSettings = musicGroupPaymentCalenderCourseSettingsDao.queryCalenderCourseSettings(musicGroupPaymentCalender.getId());
				addStudent(musicGroupPaymentCalender,musicGroupPaymentCalenderCourseSettings);
			}
		}
		MusicGroupPaymentCalender calender = musicGroupPaymentCalenders.get(0);
		//如果是报名，并且所有的报名都审核通过，需要修改乐团状态
		if (calender.getPaymentType() == MUSIC_APPLY) {
			//统计乐团还在审核中或者审核被拒的缴费
			int count = musicGroupPaymentCalenderDao.countAuditReject(calender.getMusicGroupId(),calender.getId());
			if(count == 0){
				MusicGroup musicGroup = musicGroupDao.get(calender.getMusicGroupId());
				musicGroup.setStatus(MusicGroupStatusEnum.APPLY);
				musicGroup.setUpdateTime(date);
				musicGroupDao.update(musicGroup);
				SysUser sysUser = sysUserFeignService.queryUserInfo();
				if(sysUser == null || sysUser.getId() == null){
					throw new BizException("请重新登录");
				}
				//记录操作日志
				musicGroupBuildLogDao.insert(new MusicGroupBuildLog(musicGroup.getId(), "报名缴费项目通过（费用审核中 -> 报名中）", sysUser.getId(), ""));
			}
		} else if (calender.getPaymentType() == ADD_STUDENT) {
			// 学生加到班级
			String classGroupIdStr = calender.getAttribute1();
			if (StringUtils.isNotBlank(classGroupIdStr)) {
				classGroupService.addStudentToClassGroupAndCourseArranging(Integer.parseInt(calender.getStudentIds()), classGroupIdStr, batchNo,
						musicGroupPaymentCalenderCourseSettingsDao.queryCalenderCourseSettingsByBatchNo(batchNo));
			}
			MusicGroupStudentClassAdjust musicGroupStudentClassAdjust = musicGroupStudentClassAdjustDao.findByBatchNo(batchNo);
			if(musicGroupStudentClassAdjust != null){
				//如果是合班缴费
				autoClassGroupAdjust(musicGroupStudentClassAdjust);
			}else {
				imUserFriendService.refreshGroupImUserFriend(calender.getMusicGroupId(),GroupType.MUSIC);
			}
		}else if(calender.getPaymentType() == SPAN_GROUP_CLASS_ADJUST){
			//删除和解冻班级，课程信息
			MusicGroupStudentClassAdjust adjust = musicGroupStudentClassAdjustDao.findByBatchNo(batchNo);
			List<Map> classGroupStudents = JSON.parseArray(adjust.getClassGroupStudents(),Map.class);
			List<Integer> studentIds = JSON.parseArray(adjust.getStudentIds(), Integer.class);
			List<Long> courseIds = JSON.parseArray(adjust.getSubLockCourseIds(), Long.class);
			List<Long> allLockCourseIds = JSON.parseArray(adjust.getAllLockCourseIds(), Long.class);
			//如果是跨团班级合并,添加学员
			musicGroupPaymentCalenderDetailService.batchAdd(calender,musicGroupPaymentCalenderStudentDetailDao.findByBatchNo(batchNo));
			classGroupService.spanGroupClassAdjustPass(adjust.getMasterClassGroupId()
					,studentIds,courseIds,classGroupStudents,allLockCourseIds,batchNo,adjust.getMasterTotalPrice());
		}
		musicGroupPaymentCalenderDao.batchUpdate(musicGroupPaymentCalenders);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void auditRefuse(String batchNo,String auditMemo) {
		SysUser sysUser = sysUserFeignService.queryUserInfo();
		if(sysUser == null || sysUser.getId() == null){
			throw new BizException("请重新登录");
		}
		List<MusicGroupPaymentCalender> musicGroupPaymentCalenders = musicGroupPaymentCalenderDao.findByBatchNo(batchNo);
		if(musicGroupPaymentCalenders == null || musicGroupPaymentCalenders.size() == 0){
			throw new BizException("缴费项目不存在");
		}
		Date date = new Date();
		for (MusicGroupPaymentCalender musicGroupPaymentCalender : musicGroupPaymentCalenders) {
			musicGroupPaymentCalender.setStatus(PaymentCalenderStatusEnum.REJECT);
			musicGroupPaymentCalender.setUpdateTime(date);
			musicGroupPaymentCalender.setAuditMemo(auditMemo);
		}
		MusicGroupPaymentCalender calender = musicGroupPaymentCalenders.get(0);
		//如果是报名，并且所有的报名都审核通过，需要修改乐团状态
		if (calender.getPaymentType() == MUSIC_APPLY) {
			MusicGroup musicGroup = musicGroupDao.get(calender.getMusicGroupId());
			musicGroup.setStatus(MusicGroupStatusEnum.PRE_BUILD_FEE);
			musicGroup.setUpdateTime(date);
			musicGroupDao.update(musicGroup);
			//记录操作日志
			musicGroupBuildLogDao.insert(new MusicGroupBuildLog(musicGroup.getId(), "报名缴费项目失败（费用审核中 -> 审核拒绝）", sysUser.getId(), ""));
		}
		musicGroupPaymentCalenderDao.batchUpdate(musicGroupPaymentCalenders);
	}

	//推送待续费通知
	public void pushWaitRenewMessage(Long calenderId,MusicGroup musicGroup,Set<Integer> studentIds){
		if(studentIds == null){
			studentIds = musicGroupPaymentCalenderDetailDao.queryNoPaymentStudentIds(calenderId);
		}
		if (studentIds.size() > 0) {
			String baseUrl = sysConfigDao.findConfigValue(SysConfigService.BASE_API_URL);
			String memo = "4?" + baseUrl + "/#/musicGroupRenew?calenderId="+calenderId+"&id=" + musicGroup.getId();
			Map<Integer, String> push = new HashMap<>();
			for (Integer userId : studentIds) {
				push.put(userId, userId + "");
			}
			// 发送续费通知
			sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_PUSH_WAIT_RENEW_MESSAGE, push,
					null, 0, memo, "STUDENT", musicGroup.getName());

			//获取未缴费且不是0元的学员列表
			Map<Integer,String> studentMaps = MapUtil.convertMybatisMap(musicGroupPaymentCalenderDetailDao.queryNoPaymentAndNotZeroStudent(calenderId,studentIds));
			if(studentMaps.size() > 0){
				sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.STUDENT_PUSH_WAIT_RENEW_MESSAGE, studentMaps,
						null, 0, memo, null, musicGroup.getName());
			}
		}
	}

    @Override
	@Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
	public boolean autoUpdateMusicGroupPaymentCalenderStatus() {
		Date date = new Date();
		List<PaymentCalenderStatusEnum> statusList = new ArrayList<>();
		statusList.add(PaymentCalenderStatusEnum.NO);
		statusList.add(PaymentCalenderStatusEnum.OPEN);
		List<MusicGroupPaymentCalender> musicGroupPaymentCalenderList = musicGroupPaymentCalenderDao.queryByPaymentStatus(statusList,PayUserType.STUDENT.getCode());

		List<MusicGroupPaymentCalender> updateMusicGroupPaymentCalenderList = new ArrayList<MusicGroupPaymentCalender>();
		for (MusicGroupPaymentCalender mgpc : musicGroupPaymentCalenderList) {
			if (mgpc.getDeadlinePaymentDate() != null && date.after(mgpc.getDeadlinePaymentDate()) && mgpc.getStatus() == PaymentCalenderStatusEnum.OPEN) {
				// “进行中”更新至“已结束”
				mgpc.setUpdateTime(date);
				mgpc.setStatus(PaymentCalenderStatusEnum.OVER);
				updateMusicGroupPaymentCalenderList.add(mgpc);
				//将0元未缴费学员缴费状态更新为已缴费
				musicGroupPaymentCalenderDetailDao.updateNoPaymentAndZeroPaymentStatus(mgpc.getId());
			} else if (mgpc.getStartPaymentDate() != null && date.after(mgpc.getStartPaymentDate()) && mgpc.getStatus() == PaymentCalenderStatusEnum.NO) {
				MusicGroup musicGroup = musicGroupDao.get(mgpc.getMusicGroupId());
				if(musicGroup == null){
					continue;
				}
				//如果乐团还在审核中
				if(musicGroup.getStatus() == MusicGroupStatusEnum.DRAFT || musicGroup.getStatus() == MusicGroupStatusEnum.AUDIT|| musicGroup.getStatus() == MusicGroupStatusEnum.AUDIT_FAILED || musicGroup.getStatus() == MusicGroupStatusEnum.CLOSE){
					continue;
				}
				// “未开始”更新至“进行中”
				mgpc.setUpdateTime(date);
				mgpc.setStatus(PaymentCalenderStatusEnum.OPEN);
				updateMusicGroupPaymentCalenderList.add(mgpc);
				if(mgpc.getPayUserType() == STUDENT){
					//推送待续费通知
					pushWaitRenewMessage(mgpc.getId(),musicGroup,null);
				}
			}
		}
		if (updateMusicGroupPaymentCalenderList.size() > 0) {
			musicGroupPaymentCalenderDao.batchUpdate(updateMusicGroupPaymentCalenderList);
		}
		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void batchInsert(List<MusicGroupPaymentCalender> musicGroupPaymentCalenders) {
		if (musicGroupPaymentCalenders != null && musicGroupPaymentCalenders.size() > 0) {
			musicGroupPaymentCalenderDao.delByGroupId(musicGroupPaymentCalenders.get(0).getMusicGroupId());
			musicGroupPaymentCalenders.forEach(e -> {
				musicGroupPaymentCalenderDao.insert(e);
			});
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void del(Long id) {
		if (id == null) {
			throw new BizException("参数校验失败");
		}
		MusicGroupPaymentCalender calender = musicGroupPaymentCalenderDao.getForLock(id);
		if (calender == null) {
			throw new BizException("缴费信息不存在");
		}
		if (calender.getStatus() != PaymentCalenderStatusEnum.AUDITING && calender.getStatus() != PaymentCalenderStatusEnum.NO
				&& calender.getStatus() != PaymentCalenderStatusEnum.REJECT) {
			throw new BizException("删除失败,只有[审核中]、[拒绝]或[未开启缴费]状态才能删除");
		}
		MusicGroupStudentClassAdjust byBatchNo = musicGroupStudentClassAdjustDao.findByBatchNo(calender.getBatchNo());
		if(byBatchNo != null){
			throw new BizException("删除失败,班级调整的缴费项目不允许删除");
		}

		List<MusicGroupPaymentCalenderDetail> musicGroupPaymentCalenderDetailList = musicGroupPaymentCalenderDetailDao.queryByCalenderId(id,null);
		if (musicGroupPaymentCalenderDetailList != null && musicGroupPaymentCalenderDetailList.size() > 0) {
			List<MusicGroupPaymentCalenderDetail> paidList = musicGroupPaymentCalenderDetailList.stream()
					.filter(MusicGroupPaymentCalenderDetail -> MusicGroupPaymentCalenderDetail.getPaymentStatus() != PaymentStatus.NON_PAYMENT)
					.collect(Collectors.toList());
			if (paidList.size() > 0) {
				throw new BizException("存在已缴费的学生不能删除");
			}
			
			List<Long> calenderDetailIdList = musicGroupPaymentCalenderDetailList.stream().map(cd -> cd.getId()).collect(Collectors.toList());
			//是否已排课
			List<MusicGroupPaymentStudentCourseDetail> musicGroupPaymentStudentCourseDetailList = musicGroupPaymentStudentCourseDetailDao.queryByMusicGroupPaymentStudentCourseDetailId(calenderDetailIdList);
			long count = musicGroupPaymentStudentCourseDetailList.stream().filter(e -> e.getUsedCourseMinutes() > 0).count();
			if(count > 0){
				throw new BizException("存在已排课的学员");
			}
		}

		musicGroupPaymentCalenderDao.delete(id);
		musicGroupPaymentCalenderDetailDao.deleteByCalenderId(id);
		musicGroupPaymentStudentCourseDetailDao.deleteByMusicGroupPaymentCalenderId(id);
		
		List<Long> calenderIds = new ArrayList<Long>();
		calenderIds.add(id);
		musicGroupPaymentCalenderCourseSettingsDao.deleteByMusicGroupPaymentCalenderId(calenderIds);
		
		//如果乐团是“费用审核”，则需要修改状态
		MusicGroup musicGroup = musicGroupDao.get(calender.getMusicGroupId());
		if(musicGroup != null){
			if(musicGroup.getStatus() == MusicGroupStatusEnum.FEE_AUDIT){
				musicGroup.setStatus(MusicGroupStatusEnum.PRE_BUILD_FEE);
				musicGroup.setUpdateTime(new Date());
				musicGroupDao.update(musicGroup);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deleteByBatchNo(String batchNo) {
		if(StringUtils.isBlank(batchNo)){
			throw new BizException("参数错误");
		}
		List<MusicGroupPaymentCalender> musicGroupPaymentCalenderList = musicGroupPaymentCalenderDao.findByBatchNo(batchNo);
		for(MusicGroupPaymentCalender musicGroupPaymentCalender : musicGroupPaymentCalenderList){
			del(musicGroupPaymentCalender.getId());
		}
		return true;
	}

	@Override
	public MusicGroupPaymentCalender findByMusicGroupRegCalender(String musicGroupId) {
		return musicGroupPaymentCalenderDao.findByMusicGroupRegCalender(musicGroupId);
	}

	@Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
	public MusicGroupStudentFee updateCalender(Long calenderDetailId,Integer userId){
		Date date = new Date();
		MusicGroupPaymentCalenderDetail calenderDetail = musicGroupPaymentCalenderDetailDao.get(calenderDetailId);
		MusicGroupPaymentCalender calender = this.get(calenderDetail.getMusicGroupPaymentCalenderId());
		MusicGroupStudentFee musicGroupStudentFee = musicGroupStudentFeeDao.findByUser(userId, calender.getMusicGroupId());
		if(calender.getIsGiveMusicNetwork() && musicGroupStudentFee != null){
			//赠送网管课
			musicGroupStudentFee.setRemainNetworkClassTimes(musicGroupStudentFee.getRemainNetworkClassTimes() + 1);
		}
		//更新学生的缴费记录状态
		calenderDetail.setPaymentStatus(MusicGroupStudentFee.PaymentStatus.PAID_COMPLETED);
		calenderDetail.setActualAmount(calenderDetail.getExpectAmount());
		calenderDetail.setPayTime(date);
		calenderDetail.setUpdateTime(date);
		musicGroupPaymentCalenderDetailDao.update(calenderDetail);

		//更新实际缴费人数
		Integer actualNum = calender.getActualNum() == null ? 0 : calender.getActualNum();
		calender.setActualNum(actualNum + 1);
		calender.setUpdateTime(date);
		musicGroupPaymentCalenderDao.update(calender);
		return musicGroupStudentFee;
	}

}
