package com.yonge.cooleshow.biz.dal.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.additional.update.impl.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
import com.yonge.cooleshow.auth.api.entity.SysUser;
import com.yonge.cooleshow.biz.dal.dao.MusicAlbumDao;
import com.yonge.cooleshow.biz.dal.dto.*;
import com.yonge.cooleshow.biz.dal.enums.album.PurchaseRecordTypeEnum;
import com.yonge.cooleshow.biz.dal.support.WrapperUtil;
import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
import com.yonge.cooleshow.common.enums.ActivityShareEnum;
import com.yonge.cooleshow.common.enums.PostStatusEnum;
import com.yonge.cooleshow.biz.dal.dao.MusicSheetDao;
import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
import com.yonge.cooleshow.biz.dal.dto.req.TeacherMusicSheetAuditReq;
import com.yonge.cooleshow.biz.dal.dto.search.*;
import com.yonge.cooleshow.biz.dal.entity.*;
import com.yonge.cooleshow.biz.dal.enums.*;
import com.yonge.cooleshow.biz.dal.service.*;
import com.yonge.cooleshow.common.enums.YesOrNoEnum;
import com.yonge.toolset.mybatis.support.PageUtil;
import com.yonge.cooleshow.biz.dal.vo.*;
import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
import com.yonge.cooleshow.common.constant.SysConfigConstant;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.toolset.base.exception.BizException;
import com.yonge.toolset.base.string.MessageFormatter;
import com.yonge.toolset.base.util.StringUtil;
import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
import com.yonge.toolset.utils.easyexcel.ErrMsg;
import com.yonge.toolset.utils.easyexcel.ExcelDataReaderProperty;
import com.yonge.toolset.utils.easyexcel.ExcelException;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.MessageFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * MusicSheetService服务实现类
 *
 * @author yzp
 * @version v1.0
 * @date 2022-03-26 00:01:37
 **/
@Service
public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet> implements MusicSheetService {

    private static final Logger log = LoggerFactory.getLogger(MusicSheetServiceImpl.class);

    @Resource
    private MusicSheetDao musicSheetDao;

    @Autowired
    private MusicSheetAccompanimentService musicSheetAccompanimentService;

    @Autowired
    private MusicFavoriteService musicFavoriteService;

    @Autowired
    private ActivityPlanService  activityPlanService;

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private MusicSheetPurchaseRecordService musicSheetPurchaseRecordService;

    @Autowired
    private MusicSheetPracticeRecordService musicSheetPracticeRecordService;

    @Autowired
    private MusicAlbumService musicAlbumService;

    @Autowired
    private StudentService studentService;

    @Autowired
    private MusicSheetAuthRecordService musicSheetAuthRecordService;

    @Autowired
    private AlbumMusicRelateService albumMusicRelateService;

    @Resource
    private SysUserFeignService sysUserFeignService;

    @Autowired
    private TeacherTotalService totalService;

    @Autowired
    private SysMessageService sysMessageService;

    @Autowired
    private UserAccountService userAccountService;

    @Autowired
    private MusicTagService musicTagService;

    @Autowired
    private SubjectService subjectService;

    @Autowired
    private TeacherService teacherService;

    @Autowired
    private StudentStarService studentStarService;
    @Autowired
    private UserOrderService userOrderService;
    @Autowired
    private MusicAlbumDao musicAlbumMapper;
    @Autowired
    private MusicSheetService musicSheetService;

    public MusicSheetDao getDao() {
        return musicSheetDao;
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean saveMp3AndAccompaniment(MusicSheetDto musicSheetDto, Long userId, Long originalMusicSheetId, Long lastMusicSheetId) {
        MusicSheet musicSheet = new MusicSheet();
        BeanUtils.copyProperties(musicSheetDto, musicSheet);
        //保存主表
        musicSheet.setUpdateBy(userId);
        musicSheet.setUpdateTime(new Date());
        musicSheet.setState(YesOrNoEnum.NO);
        this.saveOrUpdate(musicSheet);

        if (musicSheet.getAuditStatus() == null || AuthStatusEnum.DOING.getCode().equals(musicSheet.getAuditStatus().getCode())) {
            musicSheetAuthRecordService.setAuditDoing(musicSheet.getId(), originalMusicSheetId, lastMusicSheetId);
        }

        Long sheetId = musicSheet.getId();
        List<MusicSheetAccompaniment> list = musicSheetDto.getBackground();
        list.forEach(musicSheetAccompaniment -> musicSheetAccompaniment.setMusicSheetId(sheetId).setCreateBy(userId).setCreateTime(new Date()));
        return musicSheetAccompanimentService.saveBatch(list);

    }

    @Override
    public IPage<MusicSheetVo> selectPage(IPage<MusicSheetVo> page, MusicSheetSearch query) {
        return page.setRecords(baseMapper.selectPage(page, query));
    }

    @Override
	public IPage<MusicSheetVo> queryRelatedList(IPage<MusicSheetVo> page, Long albumId, Long musicSheetId) {

		if (albumId == null) {
			// 查询专辑下的所有曲目

			MusicSheet musicSheet = baseMapper.selectById(musicSheetId);

			if (musicSheet != null) {
				MusicAlbumDetailSearch query = new MusicAlbumDetailSearch();
				query.setMusicTagIds(musicSheet.getMusicTag());
				return page.setRecords(baseMapper.selectPage(page, query));
			}
		} else {
			// 查询带有当前曲目标签的所有曲目
			MusicAlbumDetailSearch query = new MusicAlbumDetailSearch();
			query.setId(albumId);
			query.setType(2);
			return page.setRecords(baseMapper.selectAlbumDetailPage(page, query));
		}
		return null;
	}

	@Override
    @Transactional(rollbackFor = Exception.class)
    public boolean state(Long id, String reason, ClientEnum client) {
        MusicSheet musicSheet = this.getById(id);
        if (musicSheet == null) {
            throw new BizException("未找到曲目信息");
        }
        if (YesOrNoEnum.NO.getCode().equals(musicSheet.getState().getCode())) {
            musicSheet.setState(YesOrNoEnum.YES);
        } else {
            musicSheet.setState(YesOrNoEnum.NO);
            musicSheet.setTopFlag(YesOrNoEnum.NO);

            // 下架发送推送
            if (client.equals(ClientEnum.SYSTEM)) {
                sendOutSaleMessage(reason, musicSheet);
            }

        }
        musicSheet.setReason(reason);
        return this.updateById(musicSheet);

    }

    private void sendOutSaleMessage(String reason, MusicSheet musicSheet) {
        try {
            if(musicSheet.getSourceType().equals(SourceTypeEnum.TEACHER)) {
                SysUser sysUser = getSysUser(musicSheet.getUserId());
                // 推送老师
                Map<Long, String> teacherReceivers = new HashMap<>();
                teacherReceivers.put(sysUser.getId(), sysUser.getPhone());

                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.MUSIC_SHEET_OUT_SALE_REASON, teacherReceivers, null,
                                                   0, null, ClientEnum.TEACHER.getCode(), musicSheet.getMusicSheetName(),reason);
            }
        } catch (Exception e) {
            log.error("曲目下架失败 -->{}",e.fillInStackTrace());
        }

    }

    @Override
    public IPage<MusicSheetVo> selectAlbumDetailPage(IPage<MusicSheetVo> page, MusicAlbumDetailSearch query) {
        return page.setRecords(baseMapper.selectAlbumDetailPage(page, query));
    }

    @Override
    public MusicSheetShareVo shareMusicSheet(SysUser sysUser) {
        MusicSheetSearch query = new MusicSheetSearch();
        // 设置只查老师用户
        query.setCreateBy(sysUser.getId());
        query.setAuditStatus(AuthStatusEnum.PASS);
        query.setState(YesOrNoEnum.YES);
        query.setDelFlag(false);
        query.setSourceType(SourceTypeEnum.TEACHER);
        // 只查3条
        query.setRows(3);
        IPage<MusicSheetVo> musicSheetVoIPage = selectPage(PageUtil.getPage(query), query);
        MusicSheetShareVo musicSheetShareVo = new MusicSheetShareVo();
        musicSheetShareVo.setMusicSheetCount(musicSheetVoIPage.getTotal());
        musicSheetShareVo.setMusicSheetVoList(musicSheetVoIPage.getRecords());
        musicSheetShareVo.setName(sysUser.getUsername());
        musicSheetShareVo.setAvatar(sysUser.getAvatar());

        String teacherMusicShareUrl = sysConfigService.findConfigValue(SysConfigConstant.TEACHER_MUSIC_SHEET_SHARE_URL);
        musicSheetShareVo.setUrl(MessageFormatter.arrayFormat(teacherMusicShareUrl, sysUser.getId()));

        return musicSheetShareVo;
    }

    @Override
    public MusicSheetDetailVo detail(Long id, SysUser sysUser, ClientEnum userType) {
        MusicSheetDetailVo detail = baseMapper.detail(id);
        if (detail == null) {
            throw new BizException("未找到曲目信息");
        }
        if (sysUser == null) {
            return detail;
        }
        if (AuthStatusEnum.UNPASS.getCode().equals(detail.getAuditStatus().getCode())) {
            String reason = musicSheetAuthRecordService.selectAuditReason(id);
            detail.setReason(reason);
        }
        if (detail.getPaymentType().contains(ChargeTypeEnum.FREE.getCode())) {
            detail.setPlay(YesOrNoEnum.YES);
        } else if (ClientEnum.STUDENT.getCode().equals(userType.getCode())
                || ClientEnum.TEACHER.getCode().equals(userType.getCode())) {
            // 2022 7 20  老师也能购买曲目
            if (ClientEnum.TEACHER.getCode().equals(userType.getCode()) && detail.getUserId().equals(sysUser.getId())) {
                detail.setPlay(YesOrNoEnum.YES);
            } else {
                setMusicSheetPlay(sysUser.getId(), detail, userType);
            }
        } else {
            detail.setPlay(YesOrNoEnum.YES);
        }
        if (ClientEnum.STUDENT.getCode().equals(userType.getCode())) {
            // 学生进入小酷Ai练习，添加一条练习记录
            musicSheetPracticeRecordService.addRecord(id, sysUser.getId());
        }
        return detail;
    }

    /**
     * 设置学生曲目信息
     * <p>
     * 2022 7 20  老师也能购买曲目
     *
     * @param studentId 学生id
     * @param detail    曲目详情
     * @param userType  用户类型
     */
    private void setMusicSheetPlay(Long studentId, MusicSheetDetailVo detail, ClientEnum userType) {
        detail.setPlay(YesOrNoEnum.NO);
        // 单曲购买 判断购买记录，有记录课播放
        if (detail.getPaymentType().contains(ChargeTypeEnum.CHARGE.getCode())) {
            // 学生须判断是否能播放曲目
            MusicSheetPurchaseRecord musicSheetPurchaseRecord = musicSheetPurchaseRecordService.checkPurchase(
                    studentId, detail.getId(), userType, PurchaseRecordTypeEnum.MUSIC);
            if (musicSheetPurchaseRecord != null) {
                detail.setOrderStatus(musicSheetPurchaseRecord.getOrderStatus());
                detail.setOrderNo(musicSheetPurchaseRecord.getOrderNo());
                if (OrderStatusEnum.PAID.getCode().equals(musicSheetPurchaseRecord.getOrderStatus().getCode())) {
                    detail.setPlay(YesOrNoEnum.YES);
                    return;
                }
            }
        }
        if (detail.getPaymentType().contains(ChargeTypeEnum.VIP.getCode())) {
            // 先判断是否购买过
            MusicSheetPurchaseRecord musicSheetPurchaseRecord = musicSheetPurchaseRecordService.checkPurchase(
                    studentId, detail.getId(), userType, PurchaseRecordTypeEnum.MUSIC);
            if (musicSheetPurchaseRecord != null) {
                detail.setPlay(YesOrNoEnum.YES);
            } else
            // 会员 判断是否为会员， 会员可播放
            if (userType.equals(ClientEnum.STUDENT)) {
                StudentVo studentVo = studentService.detail(studentId);
                if (studentVo != null && YesOrNoEnum.YES.getCode().equals(studentVo.getIsVip().getCode())) {
                    detail.setPlay(YesOrNoEnum.YES);
                }
            } else if (userType.equals(ClientEnum.TEACHER)) {
                TeacherVo teacher = teacherService.detail(studentId);
                if (teacher != null && YesOrNoEnum.YES.getCode().equals(teacher.getIsVip().getCode())) {
                    detail.setPlay(YesOrNoEnum.YES);
                }
            }
        }

        if (detail.getPlay().equals(YesOrNoEnum.YES)) {
            return;
        }

        // 判断专辑购买

        // 1 查询曲目所在的专辑
        List<AlbumMusicRelate> albumMusicRelateList = albumMusicRelateService.lambdaQuery()
                                                             .eq(AlbumMusicRelate::getMusicSheetId, detail.getId())
                                                             .list();
        if (CollectionUtils.isEmpty(albumMusicRelateList)) {
            return;
        }
        List<Long> albumIdList = albumMusicRelateList.stream()
                                                 .map(AlbumMusicRelate::getAlbumId)
                                                 .collect(Collectors.toList());

        // 2 检查是否购买过专辑
        Integer count = musicSheetPurchaseRecordService.lambdaQuery()
                                                       .eq(MusicSheetPurchaseRecord::getClientType, userType)
                                                       .eq(MusicSheetPurchaseRecord::getOrderStatus,
                                                           OrderStatusEnum.PAID)
                                                       .in(MusicSheetPurchaseRecord::getMusicSheetId, albumIdList)
                                                       .eq(MusicSheetPurchaseRecord::getPurchaseType,
                                                           PurchaseRecordTypeEnum.ALBUM)
                                                       .eq(MusicSheetPurchaseRecord::getStudentId, studentId)
                                                       .count();
        if (count >0) {
            detail.setPlay(YesOrNoEnum.YES);
        }

    }

    @Override
    public IPage<MusicSheetVo> selectStudentPage(IPage<MusicSheetVo> page, StudentMusicSheetSearch query, ClientEnum clientType) {
    	List<MusicSheetVo> records = baseMapper.selectStudentMusicPage(page, query, clientType);

        if (CollectionUtils.isNotEmpty(records)) {

            // 统计单曲归属专辑数
            updateMusicAlbumNumInfo(records);
        }
    	
    	/*if(query.getMyself() != null && query.getMyself() == false){//首页
        	if(records == null || records.size() == 0){
        		query.setSubjectIds(null);
        		records = baseMapper.selectStudentMusicPage(page, query);
        	}
    	}*/
    	
        IPage<MusicSheetVo> musicSheetVoIPage = page.setRecords(records);
        if (query.getStudentId() != null) {
            StudentVo studentVo = studentService.detail(query.getStudentId());
            if (studentVo == null) {
                return musicSheetVoIPage;
            }
            for (MusicSheetVo record : records) {
                if (ChargeTypeEnum.VIP.getCode().equals(record.getChargeType().getCode())
                        && YesOrNoEnum.YES.getCode().equals(studentVo.getIsVip().getCode())) {
                    record.setPlay(YesOrNoEnum.YES);
                }
            }
        }
        return musicSheetVoIPage;

    }

    /**
     * 更新曲目专辑数
     * @param records List<MusicSheetVo>
     * @return List<MusicSheetVo>
     */
    public List<MusicSheetVo> updateMusicAlbumNumInfo(List<MusicSheetVo> records) {
        List<Long> musicIds = records.stream()
                .map(MusicSheet::getId).distinct().collect(Collectors.toList());

        Map<Long, Integer> collect = getBaseMapper().selectMusicAlbumStatInfo(musicIds).stream()
                .collect(Collectors.toMap(StatGroupWrapper::getId, StatGroupWrapper::getTotal, (o, n) -> n));

        for (MusicSheetVo item : records) {

            item.setAlbumNums(collect.getOrDefault(item.getId(), 0));
        }

        return records;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setFavorite(Long userId, Long musicSheetId, ClientEnum clientType) {
        List<MusicFavorite> musicFavorites = musicFavoriteService.getFavorite(userId, musicSheetId, clientType);
        if (CollectionUtils.isEmpty(musicFavorites)) {
            MusicFavorite musicFavorite = new MusicFavorite();
            musicFavorite.setMusicSheetId(musicSheetId);
            musicFavorite.setClientType(clientType);
            musicFavorite.setUserId(userId);
            musicFavorite.setFavoriteTime(new Date());
            return musicFavoriteService.save(musicFavorite);
        } else {
            List<Long> ids = musicFavorites.stream().map(MusicFavorite::getId).collect(Collectors.toList());
            return musicFavoriteService.removeByIds(ids);
        }
    }

    @Override
    public IPage<MusicSheetVo> myMusic(IPage<MusicSheetVo> page, StudentMusicSheetSearch query) {
        query.setDelFlag(null);

        List<MusicSheetVo> records = baseMapper.selectMyMusicPage(page, query);

        // 统计曲目专辑数
        if (CollectionUtils.isNotEmpty(records)) {

            // 更新曲目专辑数量
            musicSheetService.updateMusicAlbumNumInfo(records);
        }

        return page.setRecords(baseMapper.selectMyMusicPage(page, query));
    }

    @Override
    public IPage<MusicSheetVo> favoriteMusic(IPage<MusicSheetVo> page, StudentMusicSheetSearch query, ClientEnum clientType) {

        List<MusicSheetVo> records = baseMapper.selectFavoriteMusicPage(page, query, clientType);

        if (CollectionUtils.isNotEmpty(records)) {

            // 更新曲目专辑数量
            musicSheetService.updateMusicAlbumNumInfo(records);
        }

        return page.setRecords(records);
    }

    @Override
    public IPage<MusicSheetVo> practiceMusic(IPage<MusicSheetVo> page, StudentMusicSheetSearch query) {
        // 预计最近练习表数据量会很多
        // 先找到最近练习的曲目id 在根据曲目id进行精确查找
        IPage<Long> practiceMusicIdPage = musicSheetPracticeRecordService.selectPracticeMusic(query, page.getCurrent(), page.getSize());
        List<Long> practiceMusicIdList = practiceMusicIdPage.getRecords();
        if (CollectionUtils.isEmpty(practiceMusicIdList)) {
            page.setRecords(new ArrayList<>());
            return page;
        }

        // 设置学生端收藏联系
        query.setClientType(ClientEnum.STUDENT);
        // 构建分页信息
        page.setRecords(baseMapper.selectPracticeMusicPage(query, practiceMusicIdList));
        page.setPages(practiceMusicIdPage.getPages());
        page.setCurrent(practiceMusicIdPage.getCurrent());
        page.setSize(practiceMusicIdPage.getSize());
        page.setTotal(practiceMusicIdPage.getTotal());

        if (CollectionUtils.isNotEmpty(page.getRecords())) {

            // 更新曲目专辑数量
            musicSheetService.updateMusicAlbumNumInfo(page.getRecords());
        }
        return page;
    }

    @Override
    public IPage<StudentMusicSheetOrderVo> selectStudentOrderPage(IPage<StudentMusicSheetOrderVo> page, StudentMusicSheetOrderSearch query) {
        return page.setRecords(baseMapper.selectStudentOrderPage(page, query));
    }

    @Override
    public IPage<TeacherMusicSheetVo> selectTeacherPage(IPage<TeacherMusicSheetVo> page, TeacherMusicSheetSearch query) {
        return page.setRecords(baseMapper.selectTeacherPage(page, query));
    }

    @Override
    public IPage<TeacherMusicSheetVo> selectAuditPage(IPage<TeacherMusicSheetVo> page, TeacherMusicSheetAuditSearch query) {
        return page.setRecords(baseMapper.selectAuditPage(page, query));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean audit(TeacherMusicSheetAuditReq param, Long userId) {

        MusicSheet musicSheet = this.getById(param.getMusicSheetId());
        if (musicSheet == null) {
            throw new BizException("未找到曲目信息");
        }
        if (!AuthStatusEnum.DOING.getCode().equals(musicSheet.getAuditStatus().getCode())) {
            throw new BizException("曲目已经过审批");
        }

        boolean flag;
        Long originalMusicSheetId = musicSheetAuthRecordService.audit(param, userId);
        musicSheet.setAuditStatus(param.getAuthStatus());
            if (param.getAuthStatus().equals(AuthStatusEnum.PASS) && StringUtil.isEmpty(param.getMusicImg())) {
                throw new BizException("曲目渲染失败");
            } else if (param.getAuthStatus().equals(AuthStatusEnum.PASS) && !StringUtil.isEmpty(param.getMusicImg())) {
                musicSheet.setMusicImg(param.getMusicImg());
            }
        musicSheet.setUpdateBy(userId);
        musicSheet.setUpdateTime(new Date());
        if (AuthStatusEnum.PASS.getCode().equals(param.getAuthStatus().getCode())) {

            // 更新曲谱评测，指法、简谱、节拍器状态
            musicSheet
                    .notation(param.getNotation())
                    .canEvaluate(param.getCanEvaluate())
                    .showFingering(param.getShowFingering())
                    //.hasBeat(param.getHasBeat())
                    .mp3Type(param.getMp3Type())
                    //.audioType(param.getAudioType())
                    //.audioFileUrl(param.getAudioFileUrl())
                    .setState(YesOrNoEnum.YES);
            // 替换曲目id
            replaceMusicSheet(param, musicSheet, originalMusicSheetId);

            // 修改老师标签
            teacherService.setTeacherTag(musicSheet.getUserId(), TeacherTagEnum.MUSIC);

        }
        flag = this.updateById(musicSheet);


        // 发送审核通知
        Map<Long, String> receivers = new HashMap<>();
        SysUser teacher = sysUserFeignService.queryUserById(musicSheet.getUserId());
        receivers.put(musicSheet.getUserId(), teacher.getPhone());
        try {
            sendMusicSheetAuditMessage(param, musicSheet, receivers);
        } catch (Exception e) {
            log.warn("曲目审核消息发送失败，{}", e.getMessage());
        }

        return flag;
    }

    private void replaceMusicSheet(TeacherMusicSheetAuditReq param, MusicSheet musicSheet, Long originalMusicSheetId) {
        if (!musicSheet.getId().equals(originalMusicSheetId)) {
            MusicSheet originalMusicSheet = getById(originalMusicSheetId);
            originalMusicSheet.setId(param.getMusicSheetId());
            this.saveOrUpdate(originalMusicSheet);

            // 替换 伴奏
            List<MusicSheetAccompaniment> musicSheetAccompanimentList = musicSheetAccompanimentService.getByMusicSheetId(
                                                                                                              musicSheet.getId()).stream()
                                                                                                      .peek(musicSheetAccompaniment -> musicSheetAccompaniment.setMusicSheetId(
                                                                                                              originalMusicSheetId))
                                                                                                      .collect(Collectors.toList());
            List<MusicSheetAccompaniment> originalMusicSheetAccompanimentList = musicSheetAccompanimentService.getByMusicSheetId(
                                                                                                                      originalMusicSheetId).stream()
                                                                                                              .peek(musicSheetAccompaniment -> musicSheetAccompaniment.setMusicSheetId(
                                                                                                                      musicSheet.getId()))
                                                                                                              .collect(Collectors.toList());
            musicSheetAccompanimentList.addAll(originalMusicSheetAccompanimentList);
            if (CollectionUtils.isEmpty(musicSheetAccompanimentList)) {
                return;
            }
            musicSheetAccompanimentService.saveOrUpdateBatch(musicSheetAccompanimentList);
            musicSheet.setId(originalMusicSheetId);
        }
    }

    // 发送曲目审核消息
    private void sendMusicSheetAuditMessage(TeacherMusicSheetAuditReq param, MusicSheet musicSheet, Map<Long, String> receivers) {
        if (AuthStatusEnum.PASS.getCode().equals(param.getAuthStatus().getCode())) {
            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.MUSIC_SHEET_AUTH_PASS,
                    receivers, null, 0, null, ClientEnum.TEACHER.getCode(), musicSheet.getMusicSheetName());
        } else if (AuthStatusEnum.UNPASS.getCode().equals(param.getAuthStatus().getCode())) {
            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.MUSIC_SHEET_AUTH_UNPASS,
                    receivers, null, 0, null, ClientEnum.TEACHER.getCode(), musicSheet.getMusicSheetName(),
                    param.getRemark());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean del(Long id) {

        MusicSheet musicSheet = super.getById(id);
        if (YesOrNoEnum.YES.getCode().equals(musicSheet.getState().getCode())) {
            throw new BizException("启用状态下，不可删除");
        }
        musicSheet.setDelFlag(true);
        return this.updateById(musicSheet);
    }

    @Override
    public Integer countTeacherMusicSheet(SysUser sysUser) {
        return this.lambdaQuery()
                .eq(MusicSheet::getAuditStatus, AuthStatusEnum.PASS)
                .eq(MusicSheet::getCreateBy, sysUser.getId())
                .eq(MusicSheet::getState, YesOrNoEnum.YES)
                .eq(MusicSheet::getDelFlag, YesOrNoEnum.NO)
                .eq(MusicSheet::getSourceType, SourceTypeEnum.TEACHER.getCode())
                .count();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveMusicSheet(MusicSheetDto musicSheetDto, Long userId) {

        MusicSheet oldMusicSheet = null;
        Long originalMusicSheetId = null;
        Long lastMusicSheetId = musicSheetDto.getId();
        if (musicSheetDto.getId() != null) {
            oldMusicSheet = getById(musicSheetDto.getId());
        }
        // 保存审核拒绝的数据
        if (musicSheetDto.getId() != null && AuthStatusEnum.DOING.getCode().equals(musicSheetDto.getAuditStatus().getCode())) {
            // 保存删除的曲目
            if (oldMusicSheet != null && !AuthStatusEnum.DOING.equals(oldMusicSheet.getAuditStatus())) {
                oldMusicSheet.setDelFlag(true);
                this.saveOrUpdate(oldMusicSheet);
                List<MusicSheetAuthRecord> list = musicSheetAuthRecordService.lambdaQuery()
                                                                             .eq(MusicSheetAuthRecord::getMusicSheetId,
                                                                                 musicSheetDto.getId())
                                                                             .list();
                if (!CollectionUtils.isEmpty(list)) {
                    originalMusicSheetId = list.get(0).getOriginalMusicSheetId();
                }
                musicSheetDto.setId(null);
            }

        }

        if (musicSheetDto.getId() != null) {
            musicSheetAccompanimentService.delByMusicSheetId(musicSheetDto.getId());
        }

        if (musicSheetDto.getAuditVersion() == null) {
            musicSheetDto.setAuditVersion(YesOrNoEnum.NO);
        }
        List<String> collect = Arrays.stream(musicSheetDto.getPaymentType().split(",")).collect(Collectors.toList());
        // 非付费方式，默认曲目价格为0
        if (!collect.contains(ChargeTypeEnum.CHARGE.getCode())) {
            musicSheetDto.setMusicPrice(BigDecimal.ZERO);
        }

        /*if (musicSheetDto.getChargeType().equals(ChargeTypeEnum.VIP) || musicSheetDto.getChargeType().equals(ChargeTypeEnum.FREE)) {
            musicSheetDto.setMusicPrice(BigDecimal.ZERO);
        }*/

        // 删除曲目专辑关联
        if (oldMusicSheet != null && !oldMusicSheet.getMusicSubject().equals(musicSheetDto.getMusicSubject())) {
            delAlbumSheetRef(musicSheetDto.getId(), musicSheetDto.getMusicSubject());
        }

        List<MusicSheetAccompaniment> list;
        if (!AudioTypeEnum.MIDI.getCode().equals(musicSheetDto.getAudioType().getCode())) {
            list = musicSheetDto.getBackground();
            if (CollectionUtils.isEmpty(list)) {
                throw new BizException("mp3音频文件对应的主音或者伴奏文件没有提供");
            }
            return saveMp3AndAccompaniment(musicSheetDto, userId,originalMusicSheetId,lastMusicSheetId);
        } else {
            MusicSheet musicSheet = new MusicSheet();
            BeanUtils.copyProperties(musicSheetDto, musicSheet);
            musicSheet.setUpdateTime(new Date());
            musicSheet.setUpdateBy(userId);
            musicSheet.setState(YesOrNoEnum.NO);
            this.saveOrUpdate(musicSheet);
            if (musicSheet.getAuditStatus() == null || AuthStatusEnum.DOING.getCode().equals(musicSheet.getAuditStatus().getCode())) {
                musicSheetAuthRecordService.setAuditDoing(musicSheet.getId(),originalMusicSheetId,lastMusicSheetId);
            }

            return true;
        }
    }

    /**
     * 删除专辑曲目关联
     *
     * @param id        曲目id
     * @param subjectId 声部id
     */
    private void delAlbumSheetRef(Long id, String subjectId) {

        if (id == null) {
            return;
        }
        MusicSheet musicSheet = this.getById(id);
        if (musicSheet.getMusicSubject().equals(subjectId)) {
            return;
        }
        albumMusicRelateService.delByMusicSheet(musicSheet.getId());


    }

    @Override
    public HttpResponseResult<OrderCreateRes> buyMusicSheetCheck(OrderReq.OrderReqInfo orderReqInfo) {

        // 下单前的验证
        getSysUser(orderReqInfo.getUserId());

        MusicSheetPayDto musicSheetPayDto = JSON.parseObject(
                JSON.toJSONString(orderReqInfo.getBizContent()), MusicSheetPayDto.class);

        OrderCreateRes orderCreateRes = new OrderCreateRes();
        orderCreateRes.setGoodType(orderCreateRes.getGoodType());
        orderCreateRes.setGoodNum(1);
        orderCreateRes.setOrderType(orderReqInfo.getOrderType());

        switch (orderReqInfo.getGoodType()) {
            case MUSIC: // 单曲
                {
                    MusicSheet musicSheet = this.getById(musicSheetPayDto.getMusicSheetId());
                    if (musicSheet == null) {
                        throw new BizException("不存在曲目信息");
                    }

                    orderCreateRes.setRes(true);
                    if (!musicSheet.getSourceType().getCode().equals(SourceTypeEnum.PLATFORM.getCode())) {
                        orderCreateRes.setMerchId(musicSheet.getUserId());
                    }


                    orderCreateRes.setBizId(musicSheet.getId());
                    orderCreateRes.setOriginalPrice(musicSheet.getMusicPrice());
                    orderCreateRes.setExpectPrice(musicSheet.getMusicPrice());
                }
                break;
            case ALBUM: // 专辑
                {
                    MusicAlbum album = musicAlbumMapper.selectById(musicSheetPayDto.getMusicSheetId());

                    if (Objects.isNull(album)) {
                        throw new BizException("无效的专辑信息");
                    }

                    orderCreateRes.setRes(true);
                    orderCreateRes.setMerchId(0L);
                    orderCreateRes.setBizId(album.getId());
                    orderCreateRes.setOriginalPrice(BigDecimal.valueOf(album.getAlbumPrice()));
                    orderCreateRes.setExpectPrice(BigDecimal.valueOf(album.getAlbumPrice()));
                }
                break;
            default:
                break;
        }

        // 检查已经购买，抛出已购买异常
        checkoutPay(orderReqInfo.getUserId(), musicSheetPayDto.getMusicSheetId(), musicSheetPayDto.getClientType(),
                PurchaseRecordTypeEnum.valueOf(orderReqInfo.getGoodType().getCode()));

        return HttpResponseResult.succeed(orderCreateRes);

    }

    /**
     * 检查是否已购买当前曲目
     *
     * @param userId       用户id
     * @param musicSheetId 曲目id
     * @param clientType
     */
    private void checkoutPay(Long userId, Long musicSheetId, String clientType, PurchaseRecordTypeEnum purchaseType) {
        List<MusicSheetPurchaseRecord> list = musicSheetPurchaseRecordService
                .lambdaQuery()
                .eq(MusicSheetPurchaseRecord::getMusicSheetId, musicSheetId)
                .eq(MusicSheetPurchaseRecord::getStudentId, userId)
                .eq(MusicSheetPurchaseRecord::getClientType, clientType)
                .eq(MusicSheetPurchaseRecord::getPurchaseType, purchaseType)
                .eq(MusicSheetPurchaseRecord::getOrderStatus, OrderStatusEnum.PAID)
                .list();
        if (!CollectionUtils.isEmpty(list)) {
            throw new BizException(MessageFormat.format("已经购买了当前{0}", purchaseType.getMsg()));
        }
    }

    @Override
    @Transactional
    public void buyMusicSheetSuccess(UserOrderDetailVo userOrderDetailVo) {
        // 曲目服务费比例
        String musicSheetServiceFee = sysConfigService.findConfigValue(SysConfigConstant.MUSIC_SHEET_SERVICE_FEE);
        BigDecimal serviceFee = new BigDecimal(musicSheetServiceFee).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
        //支付金额
        BigDecimal actualPrice = userOrderDetailVo.getActualPrice();
        BigDecimal expectPrice = userOrderDetailVo.getExpectPrice();

        //服务费  原价的平台服务费 ，减去优惠券金额
        BigDecimal serviceFeeAmount = expectPrice.multiply(serviceFee).subtract(userOrderDetailVo.getCouponAmount()).setScale(2, RoundingMode.HALF_UP);
        if (serviceFeeAmount.compareTo(BigDecimal.ZERO) <0) {
            serviceFeeAmount = BigDecimal.ZERO;
        }

        // 保存购买记录
        addMusicSheetPurchaseRecord(userOrderDetailVo, actualPrice, serviceFeeAmount);

        // 曲目判断老师收入
        if (userOrderDetailVo.getOrderType().equals(OrderTypeEnum.MUSIC)) {
            MusicSheet musicSheet = this.getById(userOrderDetailVo.getBizId());
            if (!musicSheet.getSourceType().getCode().equals(SourceTypeEnum.PLATFORM.getCode())) {

                // 老师收入
                BigDecimal teacherAmount = BigDecimal.ONE.subtract(serviceFee).multiply(expectPrice);

                // 加入账户
                addTeacherAccount(userOrderDetailVo, teacherAmount, userOrderDetailVo.getBizId());
            }
        }

        // 消息通知
        try {
            sendBuyMessage(userOrderDetailVo.getMerchId(), userOrderDetailVo.getUserId(), userOrderDetailVo.getBizId(), userOrderDetailVo.getOrderClient(),userOrderDetailVo.getOrderType());
        } catch (Exception e) {
            log.warn("购买曲目消息推送失败 {}", e.getMessage());
        }
    }

    /**
     * 发送购买消息通知
     *  @param teacherId    老师id
     * @param studentId    学生id
     * @param musicSheetId 曲目id
     * @param orderClient
     * @param orderType
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean sendBuyMessage(Long teacherId, Long studentId, Long musicSheetId, ClientEnum orderClient, OrderTypeEnum orderType) {

        String name = null;
        MusicSheet musicSheet = null;
        MessageTypeEnum messageType = null;
        MessageTypeEnum smsMessageType = null;
        if (orderType.equals(OrderTypeEnum.MUSIC)) {
            musicSheet = this.getById(musicSheetId);
            name = musicSheet.getMusicSheetName();
            if (orderClient.equals(ClientEnum.STUDENT)) {
                messageType = MessageTypeEnum.STUDENT_BUY_MUSIC_SHEET_SUCCESS;
            } else {
                messageType = MessageTypeEnum.TEACHER_BUY_MUSIC_SHEET_SUCCESS;
            }
            smsMessageType = MessageTypeEnum.SMS_STUDENT_BUY_MUSIC_SHEET_SUCCESS;
        } else if (orderType.equals(OrderTypeEnum.ALBUM)) {
            name = musicAlbumService.getById(musicSheetId).getAlbumName();
            if (orderClient.equals(ClientEnum.STUDENT)) {
                messageType = MessageTypeEnum.STUDENT_BUY_MUSIC_ALBUM_SUCCESS;
            } else {
                messageType = MessageTypeEnum.TEACHER_BUY_MUSIC_ALBUM_SUCCESS;
            }
            smsMessageType = MessageTypeEnum.SMS_STUDENT_BUY_MUSIC_ALBUM_SUCCESS;
        } else {
            return false;
        }

        SysUser student = sysUserFeignService.queryUserById(studentId);
        if (orderType.equals(OrderTypeEnum.MUSIC) && musicSheet.getSourceType().equals(SourceTypeEnum.TEACHER)) {
            SysUser teacher = sysUserFeignService.queryUserById(teacherId);
            if (StringUtil.isEmpty(teacher.getPhone())) {
                log.warn("teacher id {} name {} 手机号不存在，消息推送失败", teacher.getId(), teacher.getUsername());
            }

            // 推送老师
            Map<Long, String> teacherReceivers = new HashMap<>();
            teacherReceivers.put(teacherId, teacher.getPhone());

            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_BUY_TEACHER_MUSIC_SHEET, teacherReceivers, null,
                                               0, null, ClientEnum.TEACHER.getCode(), student.getUsername(), name);

        }
        // 推送学生
        Map<Long, String> studentReceivers = new HashMap<>();
        studentReceivers.put(studentId, student.getPhone());


        String url = sysMessageService.selectConfigUrl(messageType.getCode());

        sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG,
                                           messageType, studentReceivers, null,
                0, url, orderClient.getCode(), name);
        // 推送学生
        Map<Long, String> studentSMS = new HashMap<>();
        studentSMS.put(studentId, student.getPhone());
        // 推送短信
        url = sysMessageService.selectConfigUrl(smsMessageType.getCode());
        sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, smsMessageType,
                studentSMS, null, 0, url, null, name);

        return true;
    }

    /**
     * 保存购买记录
     *
     * @param userOrderDetailVo 订单信息
     * @param actualPrice       付款价格
     * @param serviceFeeAmount  服务费
     */
    private void addMusicSheetPurchaseRecord(UserOrderDetailVo userOrderDetailVo, BigDecimal actualPrice, BigDecimal serviceFeeAmount) {
        MusicSheetPurchaseRecord musicSheetPurchaseRecord = musicSheetPurchaseRecordService.checkPurchase(
                userOrderDetailVo.getUserId(),
                userOrderDetailVo.getBizId(),
                userOrderDetailVo.getOrderClient(),
                PurchaseRecordTypeEnum.valueOf(userOrderDetailVo.getOrderType().getCode()));
        if (musicSheetPurchaseRecord == null) {
            musicSheetPurchaseRecord = new MusicSheetPurchaseRecord();
        }
        musicSheetPurchaseRecord.setClientType(userOrderDetailVo.getOrderClient());
        musicSheetPurchaseRecord.setMusicSheetId(userOrderDetailVo.getBizId());
        musicSheetPurchaseRecord.setOrderNo(userOrderDetailVo.getOrderNo());
        musicSheetPurchaseRecord.setPurchasePrice(actualPrice);
        musicSheetPurchaseRecord.setPurchaseTime(new Date());
        musicSheetPurchaseRecord.setTeacherId(userOrderDetailVo.getMerchId());
        musicSheetPurchaseRecord.setOriginalPrice(userOrderDetailVo.getOriginalPrice());
        musicSheetPurchaseRecord.setMusicSheetServiceFee(serviceFeeAmount);
        musicSheetPurchaseRecord.setOrderStatus(OrderStatusEnum.PAID);
        musicSheetPurchaseRecord.setStudentId(userOrderDetailVo.getUserId());
        musicSheetPurchaseRecord.setPurchaseType(PurchaseRecordTypeEnum.valueOf(userOrderDetailVo.getGoodType().getCode()));
        musicSheetPurchaseRecordService.saveOrUpdate(musicSheetPurchaseRecord);
    }

    /**
     * 添加金额到老师账户
     *
     * @param userOrderDetailVo 订单信息
     * @param transAmount       老师收入
     * @param musicSheetId      曲目id
     */
    private void addTeacherAccount(UserOrderDetailVo userOrderDetailVo, BigDecimal transAmount,
                                   Long musicSheetId) {
        //获取账期时间
        Date accountPeriodTime = userOrderService.getAccountPeriodTime(userOrderDetailVo);

        //插入老师账户变更记录-老师预收
        userAccountService.accountRecord(
                new UserAccountRecordDto(userOrderDetailVo.getMerchId(), PostStatusEnum.WAIT, transAmount, InOrOutEnum.IN,
                        AccountBizTypeEnum.MUSIC, musicSheetId, userOrderDetailVo.getGoodName(), userOrderDetailVo.getOrderNo(), userOrderDetailVo.getUserId(), accountPeriodTime));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderAfterSheet(UserOrderDetailVo userOrderDetailVo) {
        // 保存购买记录
        MusicSheetPurchaseRecord musicSheetPurchaseRecord = musicSheetPurchaseRecordService.checkPurchase(
                userOrderDetailVo.getUserId(),
                userOrderDetailVo.getBizId(),
                userOrderDetailVo.getOrderClient(),
                PurchaseRecordTypeEnum.valueOf(userOrderDetailVo.getOrderType().getCode()));
        if (musicSheetPurchaseRecord == null) {
            musicSheetPurchaseRecord = new MusicSheetPurchaseRecord();
        }
        musicSheetPurchaseRecord.setClientType(userOrderDetailVo.getOrderClient());
        musicSheetPurchaseRecord.setMusicSheetId(userOrderDetailVo.getBizId());
        musicSheetPurchaseRecord.setOrderNo(userOrderDetailVo.getOrderNo());
        musicSheetPurchaseRecord.setTeacherId(userOrderDetailVo.getMerchId());
        musicSheetPurchaseRecord.setOriginalPrice(userOrderDetailVo.getOriginalPrice());
        musicSheetPurchaseRecord.setOrderStatus(OrderStatusEnum.WAIT_PAY);
        musicSheetPurchaseRecord.setStudentId(userOrderDetailVo.getUserId());
        musicSheetPurchaseRecord.setPurchaseType(PurchaseRecordTypeEnum.valueOf(userOrderDetailVo.getGoodType().getCode()));

        musicSheetPurchaseRecordService.saveOrUpdate(musicSheetPurchaseRecord);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void buyMusicSheetCancel(UserOrderDetailVo userOrderDetailVo) {
        MusicSheetPurchaseRecord musicSheetPurchaseRecord = musicSheetPurchaseRecordService.checkPurchase(
                userOrderDetailVo.getUserId(),
                userOrderDetailVo.getBizId(),
                userOrderDetailVo.getOrderClient(),
                PurchaseRecordTypeEnum.valueOf(userOrderDetailVo.getGoodType().getCode()));

        if (musicSheetPurchaseRecord == null) return;
        musicSheetPurchaseRecordService.removeById(musicSheetPurchaseRecord.getId());
    }

    @Override
    public Integer getTeacherMusicSheetCount(Long userId) {
        return baseMapper.selectTeacherMusicSheetCount(userId);

    }

    @Override
    public HomeMusicSheetVo getMusicSheetHome() {

        HomeMusicSheetVo homeMusicSheetVo = baseMapper.selectMusicNum();
        homeMusicSheetVo.setMusicSheetSmallList(baseMapper.selectPayMusicSheet());

        return homeMusicSheetVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importExcel(List<ExcelDataReaderProperty<MusicSheetExport>> dataList, Long userId) {

        List<ErrMsg> errMsgList = new ArrayList<>();
        dataList.sort(Comparator.comparingInt(ExcelDataReaderProperty::getRowIndex));
        List<MusicSheetDto> musicSheetDtoList = new ArrayList<>();
        List<MusicTagVo> musicTagVoList = musicTagService.selectMusicTagTree();
        List<Subject> subjects = subjectService.subjectSelect(null, null);
        Date date = new Date();
        for (ExcelDataReaderProperty<MusicSheetExport> readerProperty : dataList) {
            MusicSheetDto musicSheetDto = new MusicSheetDto();
            musicSheetDto.setUserId(userId);
            musicSheetDto.setAuditVersion(YesOrNoEnum.NO);
            musicSheetDto.setSourceType(SourceTypeEnum.PLATFORM);
            musicSheetDto.setChargeType(ChargeTypeEnum.FREE);
            musicSheetDto.setAuditStatus(AuthStatusEnum.PASS);
            musicSheetDto.setState(YesOrNoEnum.NO);
            musicSheetDto.setDelFlag(false);
            musicSheetDto.setCreateBy(userId);
            musicSheetDto.setUpdateBy(userId);
            musicSheetDto.setCreateTime(date);
            musicSheetDto.setUpdateTime(date);

            String errMsg = readerProperty.getErrorMessage();
            if (!StringUtil.isEmpty(errMsg)) {
                errMsgList.add(new ErrMsg(readerProperty.getRowIndex(), errMsg));
                continue;
            }
            MusicSheetExport sheetExport = readerProperty.getClazz();
            BeanUtils.copyProperties(sheetExport, musicSheetDto);

            if (AudioTypeEnum.MIDI.getCode().equals(musicSheetDto.getAudioType().getCode())) {
                musicSheetDto.setMp3Type(null);
            }

            if (musicSheetDto.getAudioType().equals(AudioTypeEnum.MP3)) {
                musicSheetDto.setUrl(musicSheetDto.getMidiUrl());
                musicSheetDto.setMidiUrl("");
            }

            String musicTags = sheetExport.getMusicTags();
            StringBuilder musicTagIds = new StringBuilder();
            if (musicTags == null || musicTags.equals("")) {
                errMsgList.add(new ErrMsg(readerProperty.getRowIndex(), "曲目标签不能为空"));
            } else {
                String[] stringList = musicTags.split("[,，]");
                List<MusicTag> childrenMusicTag = new ArrayList<>();
                for (MusicTagVo musicTagVo : musicTagVoList) {
                    childrenMusicTag.addAll(musicTagVo.getChildren());
                }
                for (String s : stringList) {
                    boolean b = false;
                    for (MusicTag musicTag : childrenMusicTag) {
                        if (musicTag.getName().equals(s)) {
                            if (musicTagIds.length() != 0) {
                                musicTagIds.append(",");
                            }
                            musicTagIds.append(musicTag.getId());
                            b = true;
                        }
                    }
                    if (!b) {
                        errMsgList.add(new ErrMsg(readerProperty.getRowIndex(), "曲目名称错误：" + s));
                    }
                }
            }
            if (StringUtil.isEmpty(sheetExport.getComposer())) {
                errMsgList.add(new ErrMsg(readerProperty.getRowIndex(), "音乐人不能为空"));
            }
            if (StringUtil.isEmpty(sheetExport.getMusicSubjects())) {
                errMsgList.add(new ErrMsg(readerProperty.getRowIndex(), "曲目声部不能为空"));
            } else {
                List<Subject> childrenSubject = new ArrayList<>();
                for (Subject subject : subjects) {
                    if (CollectionUtils.isEmpty(subject.getSubjects())) {
                        continue;
                    }
                    childrenSubject.addAll(subject.getSubjects());
                }
                List<Subject> collect = childrenSubject.stream()
                        .filter(subject -> subject.getName().equals(sheetExport.getMusicSubjects()))
                        .collect(Collectors.toList());
                if (CollectionUtils.isEmpty(collect)) {
                    errMsgList.add(new ErrMsg(readerProperty.getRowIndex(), "曲目声部名错误：" + sheetExport.getMusicSubjects()));
                } else {
                    musicSheetDto.setMusicSubject(collect.get(0).getId().toString());
                }
            }
            if (!StringUtil.isEmpty(sheetExport.getAudioFileUrls())) {

                List<MusicSheetAccompaniment> background = new ArrayList<>();
                String[] audioFileUrls = sheetExport.getAudioFileUrls().split("[,，]");
                for (String audioFileUrl : audioFileUrls) {
                    MusicSheetAccompaniment musicSheetAccompaniment = new MusicSheetAccompaniment();
                    musicSheetAccompaniment.setAudioFileUrl(audioFileUrl);
                    background.add(musicSheetAccompaniment);
                }
                musicSheetDto.setBackground(background);
            }

            musicSheetDto.setMusicTag(musicTagIds.toString());

            musicSheetDtoList.add(musicSheetDto);
        }

        if (!CollectionUtils.isEmpty(errMsgList)) {
            throw new ExcelException("导入异常", errMsgList);
        }

        musicSheetDtoList.forEach(musicSheetDto -> saveMusicSheet(musicSheetDto, userId));

    }

    @Override
    public MusicSheetWebsiteDetailVo websiteDetail(Long musicSheetId, SysUser sysUser, ClientEnum clientType) {
        MusicSheetDetailVo detail = detail(musicSheetId, null, null);
        MusicSheetWebsiteDetailVo musicSheetWebsiteDetailVo = new MusicSheetWebsiteDetailVo();
        BeanUtils.copyProperties(detail, musicSheetWebsiteDetailVo);

        // 曲目收藏数
        long musicSheetFavoriteNum = musicFavoriteService.getMusicSheetFavoriteNum(musicSheetId);
        musicSheetWebsiteDetailVo.setFavoriteNum(musicSheetFavoriteNum);

        // 老师信息
        TeacherVo teacherVo = teacherService.detail(detail.getUserId());
        TeacherMusicSheetListVo teacherMusicSheetListVo = new TeacherMusicSheetListVo();
        teacherMusicSheetListVo.setUserAvatar(teacherVo.getAvatar());
        teacherMusicSheetListVo.setUserName(teacherVo.getUsername());
        teacherMusicSheetListVo.setUserId(teacherVo.getUserId());
        teacherMusicSheetListVo.setEntryFlag(teacherVo.getEntryFlag());
        teacherMusicSheetListVo.setMusicianFlag(teacherVo.getMusicianFlag());
        teacherMusicSheetListVo.setTag(teacherVo.getTag());

        TeacherTotal total = totalService.getTotalById(detail.getUserId());
        if (total != null) {
            teacherMusicSheetListVo.setFansNum(total.getFansNum());
        }
        teacherMusicSheetListVo.setIsVip(teacherVo.getIsVip());

        if (sysUser != null) {
            // 老师关注
            StudentStar studentStar = studentStarService.getByStudentIdAndTeacherId(sysUser.getId(), teacherVo.getUserId());
            if (studentStar != null) {
                teacherMusicSheetListVo.setStar(YesOrNoEnum.YES);
            }

            // 曲目收藏
            List<MusicFavorite> favorite = musicFavoriteService.getFavorite(sysUser.getId(), detail.getId(), clientType);
            if (!CollectionUtils.isEmpty(favorite)) {
                musicSheetWebsiteDetailVo.setFavorite(YesOrNoEnum.YES);
            }
        }

        // 老师的曲目
        MusicSheetSearch musicSheetSearch = new MusicSheetSearch();
        musicSheetSearch.setCreateBy(teacherVo.getUserId());
        musicSheetSearch.setState(YesOrNoEnum.YES);
        musicSheetSearch.setAuditStatus(AuthStatusEnum.PASS);
        musicSheetSearch.setPage(1);
        musicSheetSearch.setRows(5);
        List<MusicSheetVo> musicSheetVos = baseMapper.selectPage(PageUtil.getPage(musicSheetSearch), musicSheetSearch);
        musicSheetVos = musicSheetVos .stream() .filter(musicAlbumVo -> !musicAlbumVo.getId()
                                                              .equals(musicSheetId))
                                                             .collect(Collectors.toList());
        if (musicSheetVos.size() > 4) {
            musicSheetVos = musicSheetVos.subList(0,4);
        }
        teacherMusicSheetListVo.setMusicSheetList(musicSheetVos);

        musicSheetWebsiteDetailVo.setTeacher(teacherMusicSheetListVo);
        return musicSheetWebsiteDetailVo;
    }

    @Override
    public TeacherAuditMusicSheetVo selectTeacherCount(Long userId) {
        return baseMapper.selectTeacherCount(userId);
    }

    @Override
    public List<TeacherTotalVo> queryTeacherTotal(Long userId) {
        return baseMapper.queryTeacherTotal(userId);
    }

    @Override
    public List<StudentTotalVo> queryStudentTotal(Long userId) {
        return baseMapper.queryStudentTotal(userId);
    }

    @Override
    public ShareProfitVo shareMusicSheetProfit(SysUser sysUser, Long musicSheetId) {
        ShareProfitVo result = new ShareProfitVo();
        MusicSheetDetailVo musicSheet = detail(musicSheetId, null, null);

        YesOrNoEnum discount = YesOrNoEnum.NO;
        if (ChargeTypeEnum.VIP.equals(musicSheet.getChargeType())) {
            ActivityPlanVo activityPlanVo = activityPlanService.activityShare(ActivityShareEnum.VIP, sysUser.getId());
            if (activityPlanVo != null) {
                result.setActivityId(activityPlanVo.getId());
                discount = YesOrNoEnum.YES;
            }
        } else if (ChargeTypeEnum.CHARGE.equals(musicSheet.getChargeType())) {
            ActivityPlanVo activityPlanVo = activityPlanService.activityShare(ActivityShareEnum.MUSIC_SHEET,
                                                                              sysUser.getId());
            if (activityPlanVo != null) {
                result.setActivityId(activityPlanVo.getId());
                discount = YesOrNoEnum.YES;
            }
        }
        result.setDiscount(discount);
        result.setTeacherId(sysUser.getId());
        result.setType("MUSIC");
        result.setMusicSheet(musicSheet);
        result.setAvatar(sysUser.getAvatar());
        result.setName(sysUser.getUsername());
        String teacherMusicShareProfitUrl = sysConfigService.findConfigValue(SysConfigConstant.TEACHER_MUSIC_SHEET_SHARE_PROFIT_URL);
        result.setUrl(MessageFormatter.arrayFormat(teacherMusicShareProfitUrl, musicSheetId, sysUser.getId()));
        return result;
    }

    @Override
    public Boolean top(Long musicSheetId) {
        MusicSheet musicSheet = getById(musicSheetId);

        if (YesOrNoEnum.NO.equals(musicSheet.getState())) {
            throw new BizException("下架的曲目不能置顶");
        }

        if (YesOrNoEnum.YES.equals(musicSheet.getTopFlag())) {
            musicSheet.setTopFlag(YesOrNoEnum.NO);
            return this.saveOrUpdate(musicSheet);
        }
        String subjectIdsStr = musicSheet.getMusicSubject();
        
		for (String subjectId : subjectIdsStr.split(",")) {
			Integer count = this.lambdaQuery().eq(MusicSheet::getDelFlag, YesOrNoEnum.NO).eq(MusicSheet::getTopFlag, YesOrNoEnum.YES)
					.eq(MusicSheet::getState, YesOrNoEnum.YES).apply(!subjectId.isEmpty(), "FIND_IN_SET ('" + subjectId + "',music_subject_)").count();
            String topNum = sysConfigService.findConfigValue(SysConfigConstant.MUSIC_SHEET_TOP_NUM);
            if (StringUtil.isEmpty(topNum)) {
                throw new BizException("获取置顶配置失败");
            }
            if (count >= Integer.parseInt(topNum)) {
				throw new BizException("首页推荐数量达到[" +topNum+"]上限，请先取消其他曲谱推荐");
			}
		}
        musicSheet.setTopFlag(YesOrNoEnum.YES);
        return this.saveOrUpdate(musicSheet);
    }

    @Override
    public Boolean stateList(ReasonDto reasonDto) {
        List<Long> idList = WrapperUtil.toLongList(reasonDto.getMusicSheetIds());

        Collection<MusicSheet> musicSheets = this.listByIds(idList);
        List<MusicSheet> musicSheetList = musicSheets.stream()
                                              .filter(musicSheet -> !musicSheet.getState().equals(reasonDto.getState()))
                                              .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(musicSheetList)) {
            return true;
        }
        LambdaUpdateChainWrapper<MusicSheet> wrapper = this.lambdaUpdate()
                                                       .in(MusicSheet::getId, musicSheetList.stream()
                                                                .map(MusicSheet::getId)
                                                                .collect(Collectors.toList()))
                                                       .set(MusicSheet::getState, reasonDto.getState());
        if (reasonDto.getState().equals(YesOrNoEnum.NO)) {
            wrapper.set(MusicSheet::getTopFlag,0);
        }
        wrapper.update();

        // 发送推送
        if (reasonDto.getState().equals(YesOrNoEnum.YES)){
            return true;
        }
        for (MusicSheet musicSheet : musicSheetList) {
             if (SourceTypeEnum.TEACHER.equals(musicSheet.getSourceType())) {
                 sendOutSaleMessage(reasonDto.getReason(),musicSheet);
             }
        }

        return true;

    }

    @Override
    public MusicSheetDetailVo auditDetail(Long authMusicSheetId) {

        MusicSheetAuthRecord musicSheetAuthRecord = musicSheetAuthRecordService.getById(authMusicSheetId);
        MusicSheetDetailVo detail = detail(musicSheetAuthRecord.getMusicSheetId(), null, null);
        List<MusicSheetDetailVo> musicSheetDetailVos = auditDetailList(authMusicSheetId);
        if (!CollectionUtils.isEmpty(musicSheetDetailVos)) {
            detail.setLastMusicSheet(musicSheetDetailVos.get(0));
        }
        return detail;
    }

    @Override
    public List<MusicSheetDetailVo> auditDetailList(Long authMusicSheetId) {
        MusicSheetAuthRecord musicSheetAuthRecord = musicSheetAuthRecordService.getById(authMusicSheetId);
        return baseMapper.auditDetailList(musicSheetAuthRecord.getOriginalMusicSheetId(),authMusicSheetId);
    }

    @Override
    public Boolean updateMusicImg(String musicImg, Long musicSheetId) {
        MusicSheet musicSheet = new MusicSheet();
        musicSheet.setMusicImg(musicImg);
        musicSheet.setId(musicSheetId);
        this.updateById(musicSheet);

        return true;
    }

	private SysUser getSysUser(Long userId) {
        return Optional.ofNullable(userId)
                .map(sysUserFeignService::queryUserById)
                .orElseThrow(() -> new BizException("用户不存在"));
    }
}