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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.beust.jcommander.internal.Lists;
import com.dayaedu.cbs.common.enums.music.EMusicAvailableType;
import com.dayaedu.cbs.common.enums.music.EMusicPaymentType;
import com.dayaedu.cbs.common.enums.school.EMusicSheetType;
import com.dayaedu.cbs.openfeign.client.MusicFeignClientService;
import com.dayaedu.cbs.openfeign.properties.OpenFeignClientConfigProperties;
import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetApplicationExtendClientWrapper;
import com.dayaedu.cbs.openfeign.wrapper.music.CbsMusicSheetWrapper;
import com.dayaedu.cbs.openfeign.wrapper.music.CbsSubjectApiWrapper;
import com.google.common.collect.Maps;
import com.microsvc.toolkit.common.response.paging.PageInfo;
import com.microsvc.toolkit.common.response.template.R;
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.dao.MusicSheetDao;
import com.yonge.cooleshow.biz.dal.dto.MusicImgDto;
import com.yonge.cooleshow.biz.dal.dto.MusicSheetPayDto;
import com.yonge.cooleshow.biz.dal.dto.ReasonDto;
import com.yonge.cooleshow.biz.dal.dto.UserAccountRecordDto;
import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
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.enums.album.PurchaseRecordTypeEnum;
import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMusicMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantGroupAlbumMapper;
import com.yonge.cooleshow.biz.dal.mapper.UserTenantAlbumRecordMapper;
import com.yonge.cooleshow.biz.dal.service.*;
import com.yonge.cooleshow.biz.dal.service.cbs.CbsMusicScoreService;
import com.yonge.cooleshow.biz.dal.vo.*;
import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.TenantGroupAlbumWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.music.MusicCompareWrapper;
import com.yonge.cooleshow.common.constant.SysConfigConstant;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.cooleshow.common.enums.ActivityShareEnum;
import com.yonge.cooleshow.common.enums.PostStatusEnum;
import com.yonge.cooleshow.common.enums.YesOrNoEnum;
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.mybatis.support.PageUtil;
import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
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.function.Function;
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;
    @Resource
    private MusicFavoriteService musicFavoriteService;
    @Resource
    private ActivityPlanService  activityPlanService;
    @Resource
    private SysConfigService sysConfigService;
    @Resource
    private MusicSheetPurchaseRecordService musicSheetPurchaseRecordService;
    @Resource
    private MusicSheetPracticeRecordService musicSheetPracticeRecordService;
    @Resource
    private MusicAlbumService musicAlbumService;
    @Resource
    private StudentService studentService;
    @Resource
    private MusicSheetAuthRecordService musicSheetAuthRecordService;
    @Resource
    private AlbumMusicRelateService albumMusicRelateService;
    @Resource
    private SysUserFeignService sysUserFeignService;
    @Resource
    private TeacherTotalService totalService;
    @Resource
    private SysMessageService sysMessageService;
    @Resource
    private UserAccountService userAccountService;
    @Resource
    private MusicTagService musicTagService;
    @Resource
    private SubjectService subjectService;
    @Resource
    private TeacherService teacherService;
    @Resource
    private CourseCoursewareService courseCoursewareService;
    @Resource
    private PlatformCashAccountRecordService platformCashAccountRecordService;
    @Resource
    private StudentStarService studentStarService;
    @Resource
    private UserOrderService userOrderService;
    @Resource
    private MusicAlbumDao musicAlbumMapper;
    @Resource
    private MusicSheetService musicSheetService;
    @Resource
    private AlbumFavoriteService albumFavoriteService;
    @Resource
    private TenantInfoService tenantInfoService;
    @Resource
    private UserTenantAlbumRecordMapper userTenantAlbumRecordMapper;
    @Resource
    private TenantAlbumMusicService tenantAlbumMusicService;
    @Resource
    private CbsMusicScoreService cbsMusicScoreService;
    @Resource
    private TenantGroupAlbumMapper tenantGroupAlbumMapper;
    @Resource
    private TenantAlbumMusicMapper tenantAlbumMusicMapper;
    @Resource
    private MusicSheetAccompanimentService musicSheetAccompanimentService;
    @Resource
    private MusicFeignClientService musicFeignClientService;
    @Resource
    private OpenFeignClientConfigProperties openFeignClientConfigProperties;

    @Value("${openfeign-client.app-id:1745637981387108354}")
    public Long applicationId;

    public MusicSheetDao getDao() {
        return musicSheetDao;
    }

    @Override
    public IPage<MusicSheetVo> selectPage(IPage<MusicSheetVo> page, MusicSheetSearch query) {

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

        if (CollectionUtils.isNotEmpty(records)) {

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

        // 来源为机构的曲目设置机构名称
        List<Long> tenantIds = records.stream()
                .filter(o -> o.getSourceType() != null && o.getSourceType().equals(SourceTypeEnum.TENANT))
                .map(o -> o.getUserId()).distinct()
                .collect(Collectors.toList());

        Map<Long, TenantInfo> tenantInfoMap = tenantInfoService.getMapByIds(tenantIds);
        for (MusicSheetVo record : records) {
            if (record.getSourceType() == null) {
                break;
            }
            switch (record.getSourceType()) {
                case TENANT:
                    TenantInfo tenantInfo = tenantInfoMap.get(record.getUserId());
                    if (tenantInfo != null) {
                        record.setSourceName(tenantInfo.getName());
                    }
                    break;
                case TEACHER:

                case PLATFORM:
                    record.setSourceName(record.getSourceType().getMsg());
                default:
                    break;
            }
        }

        return page.setRecords(records);
    }

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

    public List<MusicSheetVo> musicDataFormat(List<MusicSheetVo> musicSheets) {
        if (CollectionUtils.isEmpty(musicSheets)) {
            return musicSheets;
        }
        List<Long> cbsMusicSheetIds = musicSheets.stream().map(MusicSheet::getCbsMusicSheetId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(cbsMusicSheetIds)) {
            return new ArrayList<>();
        }
        // 调用内容平台查询曲目信息
        R<PageInfo<CbsMusicSheetWrapper.MusicSheetApplication>> pageInfoR = musicFeignClientService
                .musicSheetPageByApplication(CbsMusicSheetWrapper.MusicSheetApplicationQuery.builder()
                        .musicSheetIds(cbsMusicSheetIds).detailFlag(false).rows(-1).delFlag(true)
                        .applicationId(Long.parseLong(openFeignClientConfigProperties.getAppId())).build());
        List<CbsMusicSheetWrapper.MusicSheetApplication> rows;
        try {

            PageInfo<CbsMusicSheetWrapper.MusicSheetApplication> musicSheetApplicationPageInfo = pageInfoR.feignData();
            rows = musicSheetApplicationPageInfo.getRows();
        }catch (Exception e) {
            log.error("调用内容平台服务异常", e);
            throw com.microsvc.toolkit.common.webportal.exception.BizException.from("内容平台服务异常");
        }
        if (CollectionUtils.isEmpty(rows)) {
            return new ArrayList<>();
        }
        //  rows 转 map
        Map<Long, CbsMusicSheetWrapper.MusicSheetApplication> musicSheetApplicationMap = Maps.uniqueIndex(rows, CbsMusicSheetWrapper.MusicSheetApplication::getId);
        // 曲目信息转换
        for (MusicSheetVo musicSheet : musicSheets) {
            CbsMusicSheetWrapper.MusicSheetApplication musicSheetApplication = musicSheetApplicationMap.get(musicSheet.getCbsMusicSheetId());
            if (musicSheetApplication == null) {
                continue;
            }
            musicSheetApplicationToMusicSheet(musicSheetApplication, musicSheet);
        }
        return musicSheets;
    }

    @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());
                query.setAuditVersion(musicSheet.getAuditVersion());
                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.YES.equals(musicSheet.getState()) &&
                musicSheet.getSourceType().equals(SourceTypeEnum.TEACHER) && StringUtil.isEmpty(reason)) {
            throw new BizException("请填写下架原因");
        }
        CbsMusicSheetWrapper.MusicSheetApplicationQuery query = new CbsMusicSheetWrapper.MusicSheetApplicationQuery();
        query.setApplicationId(applicationId);
        query.setMusicSheetIds(Collections.singletonList(musicSheet.getCbsMusicSheetId()));
        query.setDelFlag(true);
        query.setPage(1);
        query.setRows(1);
        R<com.microsvc.toolkit.common.response.paging.PageInfo<CbsMusicSheetWrapper.MusicSheetApplication>> pageInfoR = musicFeignClientService.musicSheetPageByApplication(query);
        if (pageInfoR.getCode() != 200) {
            throw new BizException("获取曲目信息异常,{}", pageInfoR.getMessage());
        }
        List<CbsMusicSheetWrapper.MusicSheetApplication> rows = pageInfoR.feignData().getRows();
        if (CollectionUtils.isEmpty(rows)) {
            throw new BizException("获取曲目信息失败");
        }
        CbsMusicSheetWrapper.MusicSheetApplication musicSheetApplication = rows.get(0);
        CbsMusicSheetApplicationExtendClientWrapper.MusicSheetApplicationExtendStatus extendStatus = new CbsMusicSheetApplicationExtendClientWrapper.MusicSheetApplicationExtendStatus();
        extendStatus.setIds(musicSheetApplication.getApplicationExtendId().toString());
        extendStatus.setStatus(musicSheet.getState()!=YesOrNoEnum.YES);
        R<JSONObject> jsonObjectR = musicFeignClientService.musicSheetApplicationExtendStatus(extendStatus);
        if (jsonObjectR.getCode() != 200) {
            throw new BizException("修改曲目状态失败,{}", jsonObjectR.getMessage());
        }
        return true;
    }

    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) {
        IPage<MusicSheetVo> musicSheetVoIPage = page.setRecords(baseMapper.selectAlbumDetailPage(page, query));

        List<MusicSheetVo> records = musicSheetVoIPage.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return musicSheetVoIPage;
        }
        // 是否关注
        if (query.getStudentId() != null) {
            List<Long> musicIdList = records.stream().map(MusicSheetVo::getId).collect(Collectors.toList());
            List<MusicFavorite> musicFavoriteList = musicFavoriteService.lambdaQuery()
                    .eq(MusicFavorite::getUserId, query.getStudentId())
                    .eq(MusicFavorite::getClientType, query.getClientType())
                    .in(MusicFavorite::getMusicSheetId, musicIdList)
                    .list();
            if (CollectionUtils.isNotEmpty(musicFavoriteList)) {
                Set<Long> set = musicFavoriteList.stream()
                        .map(MusicFavorite::getMusicSheetId)
                        .collect(Collectors.toSet());
                for (MusicSheetVo record : records) {
                    record.setFavorite(set.contains(record.getId())?YesOrNoEnum.YES:YesOrNoEnum.NO);
                }
            }
        }

        return musicSheetVoIPage;
    }

    @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;
    }

    public MusicSheetDetailVo getCbsDetail(Long id) {
        MusicSheet musicSheet = this.baseMapper.get(id);
        if (musicSheet == null || musicSheet.getDelFlag()) {
            throw new BizException("未找到曲目信息");
        }
        if(musicSheet.getCbsMusicSheetId() == null){
            throw new BizException("曲目信息未同步");
        }
        MusicSheetDetailVo detailVo = JSON.parseObject(JSON.toJSONString(musicSheet), MusicSheetDetailVo.class);
        this.initMusicSheetDetailVo(detailVo,musicSheet);
        return detailVo;
    }

    @Override
    public MusicSheetDetailVo getAuditDetail(Long id) {
        MusicSheet musicSheet = this.baseMapper.get(id);
        if (musicSheet == null) {
            throw new BizException("未找到曲目信息");
        }
        MusicSheetDetailVo detailVo = JSON.parseObject(JSON.toJSONString(musicSheet), MusicSheetDetailVo.class);
        List<MusicSheetAccompaniment> list = musicSheetAccompanimentService.lambdaQuery().eq(MusicSheetAccompaniment::getMusicSheetId, id).list();
        detailVo.setBackground(list);
        return detailVo;
    }

    public void initMusicSheetDetailVo(MusicSheetDetailVo detailVo,MusicSheet musicSheet) {
        R<CbsMusicSheetWrapper.MusicSheet> musicSheetR = cbsMusicScoreService.musicSheetDetail(musicSheet.getCbsMusicSheetId());
        if(musicSheetR.getCode() != 200){
            throw new BizException("获取曲目信息失败");
        }
        CbsMusicSheetWrapper.MusicSheet musicSheet1 = musicSheetR.getData();
        if (musicSheet1 == null) {
            throw new BizException("未找到曲目信息");
        }
        CbsMusicSheetWrapper.MusicSheetExtend musicSheetExtend = musicSheet1.getMusicSheetExtend();
        if (musicSheetExtend != null && musicSheetExtend.getUserId() != null) {
            detailVo.setUserName(musicSheetExtend.getUserName());
            detailVo.setUserId(musicSheetExtend.getUserId());
            //获取用户头像
            SysUser sysUser = sysUserFeignService.queryUserById(musicSheetExtend.getUserId());
            if (sysUser != null) {
                detailVo.setUserAvatar(sysUser.getAvatar());
            }
        }

        if(StringUtils.isNotEmpty(musicSheet1.getSubjectIds())){
            CbsSubjectApiWrapper.SubjectQuery subjectQuery = new CbsSubjectApiWrapper.SubjectQuery();
            subjectQuery.setCbsSubjectIds(Arrays.stream(musicSheet1.getSubjectIds().split(",")).map(Long::parseLong).collect(Collectors.toList()));
            List<CbsSubjectApiWrapper.Subject> subjects = subjectService.getDao().queryCbsList(subjectQuery);
            if(CollectionUtils.isNotEmpty(subjects)){
                detailVo.setSubjectNames(subjects.stream().map(CbsSubjectApiWrapper.Subject::getSubjectName).collect(Collectors.joining(",")));
                detailVo.setCode(subjects.stream().map(CbsSubjectApiWrapper.Subject::getCode).collect(Collectors.joining(",")));
            }
        }
        detailVo.setId(musicSheet.getId());
        detailVo.setCbsMusicSheetId(musicSheet1.getId());
        detailVo.setMp3Type(AudioTypeEnum.valueOf(musicSheet1.getIsPlayBeat()&&musicSheet1.getIsUseSystemBeat()?"MP3":"MP3_METRONOME"));
        detailVo.setIsPlayBeat(musicSheet1.getIsPlayBeat());
        detailVo.setAudioType(AudioTypeEnum.valueOf(musicSheet1.getPlayMode().getCode()));
        detailVo.setCanEvaluate(musicSheet1.getIsEvaluated() ? YesOrNoEnum.YES : YesOrNoEnum.NO);
        detailVo.setShowFingering(musicSheet1.getIsShowFingering() ? YesOrNoEnum.YES : YesOrNoEnum.NO);
        detailVo.setMusicTag(musicSheet1.getMusicTag());
        detailVo.setMusicTagNames(musicSheet1.getMusicTagNames());
        List<CbsMusicSheetWrapper.MusicSheetAccompaniment> accompanimentList = musicSheet1.getMusicSheetAccompanimentList();
        if (CollectionUtils.isNotEmpty(accompanimentList)) {
            detailVo.setMetronomeUrl(accompanimentList.get(0).getAudioFileUrl());
        }
        detailVo.setXmlFileUrl(musicSheet1.getXmlFileUrl());
        detailVo.setMidiUrl(musicSheet1.getMidiFileUrl());
        detailVo.setAuditVersion(musicSheet1.getAppAuditFlag() ? YesOrNoEnum.YES : YesOrNoEnum.NO);
        detailVo.setHasBeat((musicSheet1.getIsPlayBeat() && !musicSheet1.getIsUseSystemBeat()) ? YesOrNoEnum.YES : YesOrNoEnum.NO);
        detailVo.setExtConfigJson(musicSheet1.getExtConfigJson());
        detailVo.setMusicJSON(musicSheet1.getMusicJson());
        detailVo.setMusicJianSvg(musicSheet1.getMusicJianSvg());
        detailVo.setMusicFirstSvg(musicSheet1.getMusicFirstSvg());
        detailVo.setFirstTone(musicSheet1.getMusicFirstImg());
        detailVo.setFixedTone(musicSheet1.getMusicJianImg());
        List<CbsMusicSheetWrapper.MusicSheetSound> soundList = musicSheet1.getMusicSheetSoundList();
        if (CollectionUtils.isNotEmpty(soundList)) {
            List<MusicSheetAccompaniment> background = new ArrayList<>();
            for (CbsMusicSheetWrapper.MusicSheetSound sound : soundList) {
                MusicSheetAccompaniment accompaniment = new MusicSheetAccompaniment();
                accompaniment.setMusicSheetId(musicSheet.getId());
                accompaniment.setAudioFileUrl(sound.getAudioFileUrl());
                accompaniment.setSortNumber(sound.getSortNumber());
                accompaniment.setTrack(sound.getTrack());
                background.add(accompaniment);
            }
            //按照sortNumber排序
//            background.sort(Comparator.comparing(MusicSheetAccompaniment::getSortNumber));
            detailVo.setBackground(background);
        }
    }

    @Override
    public MusicSheetDetailVo detail(Long id, SysUser sysUser, ClientEnum userType) {
        return detail(id, sysUser, userType,null);
    }

    private void musicSheetApplicationToMusicSheet(CbsMusicSheetWrapper.MusicSheetApplication musicSheetApplication, MusicSheetVo sheet) {
        sheet.setMusicSheetName(musicSheetApplication.getName());
        if (musicSheetApplication.getMusicSheetType() != null) {
            sheet.setMusicSheetType(MusicSheetTypeEnum.valueOf(musicSheetApplication.getMusicSheetType().name()));
        }
        sheet.setTitleImg(musicSheetApplication.getMusicCover());
        sheet.setUserId(musicSheetApplication.getUserId());
//        if(musicSheetApplication.getSourceType() != null){
//            sheet.setSourceType(musicSheetApplication.getSourceType() == EMusicSourceType.PERSON ? SourceTypeEnum.TEACHER :
//                    musicSheetApplication.getSourceType() == EMusicSourceType.ORG ? SourceTypeEnum.TENANT :SourceTypeEnum.PLATFORM);
//        }
        sheet.setComposer(musicSheetApplication.getComposer());
        sheet.setAudioType(AudioTypeEnum.valueOf(musicSheetApplication.getPlayMode().getCode()));
        sheet.setMp3Type(AudioTypeEnum.valueOf(musicSheetApplication.getIsPlayBeat()&&musicSheetApplication.getIsUseSystemBeat()?"MP3":"MP3_METRONOME"));
        if (StringUtils.isNotEmpty(musicSheetApplication.getPlaySpeed())) {
            sheet.setPlaySpeed(musicSheetApplication.getPlaySpeed());
        }
        if (musicSheetApplication.getIsConvertibleScore() != null){
            sheet.setNotation(musicSheetApplication.getIsConvertibleScore()?YesOrNoEnum.YES:YesOrNoEnum.NO);
        }
        if (musicSheetApplication.getIsEvaluated() != null){
            sheet.setCanEvaluate(musicSheetApplication.getIsEvaluated()?YesOrNoEnum.YES:YesOrNoEnum.NO);
        }
        if (musicSheetApplication.getIsShowFingering() != null){
            sheet.setShowFingering(musicSheetApplication.getIsShowFingering()?YesOrNoEnum.YES:YesOrNoEnum.NO);
        }
        if (musicSheetApplication.getAudioType() != null) {
            sheet.setAccompanimentType(AccompanimentTypeEnum.valueOf(musicSheetApplication.getAudioType().getCode()));
        }
        sheet.setMusicTagNames(musicSheetApplication.getMusicTagNames());
        sheet.setSubjectNames(musicSheetApplication.getSubjectNames());
        sheet.setPaymentType(musicSheetApplication.getPaymentType());
        sheet.setSortNumber(musicSheetApplication.getSortNo());
        if (musicSheetApplication.getTopFlag() != null){
            sheet.setTopFlag(musicSheetApplication.getTopFlag()?YesOrNoEnum.YES:YesOrNoEnum.NO);
        }
        if (musicSheetApplication.getExquisiteFlag() != null){
            sheet.setExquisiteFlag(musicSheetApplication.getExquisiteFlag()?YesOrNoEnum.YES:YesOrNoEnum.NO);
        }
        sheet.setMusicPrice(musicSheetApplication.getMusicPrice());
        if (CollectionUtils.isNotEmpty(musicSheetApplication.getMusicSheetAccompanimentList())) {
            sheet.setAudioFileUrl(musicSheetApplication.getMusicSheetAccompanimentList().get(0).getAudioFileUrl());
            sheet.setMetronomeUrl(musicSheetApplication.getMusicSheetAccompanimentList().get(0).getAudioFileUrl());
        }
        sheet.setXmlFileUrl(musicSheetApplication.getXmlFileUrl());
        sheet.setMidiUrl(musicSheetApplication.getMidiFileUrl());
        if (musicSheetApplication.getAppAuditFlag() != null){
            sheet.setAuditVersion(musicSheetApplication.getAppAuditFlag()?YesOrNoEnum.YES:YesOrNoEnum.NO);
        }
        sheet.setUpdateBy(musicSheetApplication.getUpdateBy());
        sheet.setExtConfigJson(musicSheetApplication.getExtConfigJson());
        sheet.setMusicJSON(musicSheetApplication.getMusicJson());
        sheet.setMusicSvg(musicSheetApplication.getMusicSvg());
        sheet.setMusicJianSvg(musicSheetApplication.getMusicJianImg());
        sheet.setMusicFirstSvg(musicSheetApplication.getMusicFirstImg());
        if(musicSheetApplication.getMusicSheetType() != null){
            sheet.setMusicSheetType(musicSheetApplication.getMusicSheetType() == EMusicSheetType.SINGLE ? MusicSheetTypeEnum.SINGLE : MusicSheetTypeEnum.CONCERT);
        }
        if(musicSheetApplication.getMusicSheetExtend() != null){
            sheet.setAddName(musicSheetApplication.getMusicSheetExtend().getUserName());
        }
        List<CbsMusicSheetWrapper.MusicSheetAccompaniment> accompanimentList = musicSheetApplication.getMusicSheetAccompanimentList();
        if (CollectionUtils.isNotEmpty(accompanimentList)){
            sheet.setMetronomeUrl(accompanimentList.get(0).getAudioFileUrl());
        }
    }

    @Override
    public MusicSheetDetailVo detail(Long id, SysUser sysUser, ClientEnum userType,String tenantAlbumId) {

        MusicSheetDetailVo detail = this.getCbsDetail(id);
        // 设置收藏人数
        detail.setFavoriteCount(detail.getFavoriteCount() + detail.getVirtualNumber());

        if (sysUser == null) {
            return detail;
        }

        // 设置课件
        List<CourseCourseware> list = courseCoursewareService.lambdaQuery()
                                                             .eq(CourseCourseware::getClientType, userType)
                                                             .eq(CourseCourseware::getMusicSheetId, id)
                                                             .eq(CourseCourseware::getUserId, sysUser.getId())
                                                             .eq(CourseCourseware::getDelFlag, false)
                                                             .list();
        if (CollectionUtils.isNotEmpty(list)) {
            detail.setCoursewareStatus(YesOrNoEnum.YES);
            detail.setCoursewareId(list.get(0).getId());
        }


        // 收藏
        YesOrNoEnum favorite = musicFavoriteService.checkFavorite(id,sysUser.getId(),userType);
        detail.setFavorite(favorite);

        // 播放状态
        if (AuthStatusEnum.UNPASS.getCode().equals(detail.getAuditStatus().getCode())) {
            String reason = musicSheetAuthRecordService.selectAuditReason(id);
            detail.setReason(reason);
        }
        if (StringUtil.isEmpty(tenantAlbumId)) {
            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);
            }
        } else {
            // 机构专辑购买
            detail.setPlay(YesOrNoEnum.NO);
            List<Long> collected = Arrays.stream(tenantAlbumId.split(",")).map(Long::parseLong).collect(Collectors.toList());

            // 学生生效中的机构专辑
            if (ClientEnum.STUDENT == userType) {
                List<Long> tenantAlbumIds = userTenantAlbumRecordMapper.selectTenantIds(sysUser.getId());
                if (CollectionUtils.isNotEmpty(tenantAlbumIds)) {
                    // tenantAlbumIds collected 取交集到 新的集合
                    List<Long> collect = tenantAlbumIds.stream().filter(collected::contains).collect(Collectors.toList());
                    List<Long> musicSheetIds = tenantAlbumMusicService.getMusicIdsByIds(collect);
                    if (CollectionUtils.isNotEmpty(musicSheetIds) && musicSheetIds.contains(detail.getId())) {
                        detail.setPlay(YesOrNoEnum.YES);
                    }
                }
            } else if (ClientEnum.TEACHER == userType) {
                // 老师所在机构启用的专辑
                Teacher teacher = teacherService.getById(sysUser.getId());
                if (teacher.getTenantId() !=null) {
                    List<Long> musicSheetIds = tenantAlbumMusicService.getMusicIdsByTenantIds(teacher.getTenantId());
                    if (musicSheetIds.contains(detail.getId())) {
                        detail.setPlay(YesOrNoEnum.YES);
                    }
                }
            }
        }



        List<MusicSheetAccompaniment> background = detail.getBackground();
        if (CollectionUtils.isNotEmpty(background)) {
            // 兼容管乐迷曲目同步数据
            long count = background.stream().map(MusicSheetAccompaniment::getSortNumber)
                .filter(x -> Objects.nonNull(x) && x <= 0).count();
            if (count == background.size()) {
                // 管乐迷原音排序字段
                background.sort(Comparator.comparing(MusicSheetAccompaniment::getId));
            } else {
                // 酷乐秀原音排序字段
                background.sort(Comparator.comparing(MusicSheetAccompaniment::getSortNumber));
            }
        }
        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 && OrderStatusEnum.PAID.getCode().equals(musicSheetPurchaseRecord.getOrderStatus().getCode())) {
                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)) {

            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);
                return;
            }
        }

        // 机构专辑购买

        // 学生生效中的机构专辑
        if (ClientEnum.STUDENT == userType) {
            List<Long> tenantAlbumIds = userTenantAlbumRecordMapper.selectTenantIds(studentId);
            if (CollectionUtils.isNotEmpty(tenantAlbumIds)) {
                List<Long> musicSheetIds = tenantAlbumMusicService.getMusicIdsByIds(tenantAlbumIds);
                if (musicSheetIds.contains(detail.getId())) {
                    detail.setPlay(YesOrNoEnum.YES);
                    return;
                }
            }
        } else if (ClientEnum.TEACHER == userType) {
            // 老师所在机构启用的专辑
            Teacher teacher = teacherService.getById(studentId);
            if (teacher.getTenantId() !=null) {
                List<Long> musicSheetIds = tenantAlbumMusicService.getMusicIdsByTenantIds(teacher.getTenantId());
                if (musicSheetIds.contains(detail.getId())) {
                    detail.setPlay(YesOrNoEnum.YES);
                    return;
                }
            }
        }
    }

    public void initMusicSheetVo(MusicSheetVo record,CbsMusicSheetWrapper.MusicSheetApplication musicSheetApplication,Map<Long, CbsSubjectApiWrapper.Subject> subjectMap){
        if(StringUtils.isNotEmpty(musicSheetApplication.getSubjectIds())){
            StringBuffer sb = new StringBuffer();
            for (String s : musicSheetApplication.getSubjectIds().split(",")) {
                CbsSubjectApiWrapper.Subject subject = subjectMap.get(Long.parseLong(s));
                if(subject != null){
                    if (sb.length() > 0) {
                        sb.append(",");
                    }
                    sb.append(subject.getSubjectName());
                }
            }
            record.setSubjectNames(sb.toString());
        }
        record.setCbsMusicSheetId(musicSheetApplication.getId());
        record.setAudioType(AudioTypeEnum.valueOf(musicSheetApplication.getPlayMode().getCode()));
        record.setCanEvaluate(musicSheetApplication.getIsEvaluated() ? YesOrNoEnum.YES : YesOrNoEnum.NO);
        record.setShowFingering(musicSheetApplication.getIsShowFingering() ? YesOrNoEnum.YES : YesOrNoEnum.NO);
        record.setMusicTag(musicSheetApplication.getMusicTagIds());
        record.setMusicTagNames(musicSheetApplication.getMusicTagNames());
        List<CbsMusicSheetWrapper.MusicSheetAccompaniment> accompanimentList = musicSheetApplication.getMusicSheetAccompanimentList();
        if (CollectionUtils.isNotEmpty(accompanimentList)) {
            record.setMetronomeUrl(accompanimentList.get(0).getAudioFileUrl());
        }
        record.setXmlFileUrl(musicSheetApplication.getXmlFileUrl());
        record.setMidiUrl(musicSheetApplication.getMidiFileUrl());
        record.setAuditVersion(musicSheetApplication.getAppAuditFlag() ? YesOrNoEnum.YES : YesOrNoEnum.NO);
        record.setHasBeat((musicSheetApplication.getIsPlayBeat() && !musicSheetApplication.getIsUseSystemBeat()) ? YesOrNoEnum.YES : YesOrNoEnum.NO);
        record.setExtConfigJson(musicSheetApplication.getExtConfigJson());
        record.setMusicJSON(musicSheetApplication.getMusicJson());
        record.setMusicJianSvg(musicSheetApplication.getMusicJianSvg());
        record.setMusicFirstSvg(musicSheetApplication.getMusicFirstSvg());
        record.setFirstTone(musicSheetApplication.getMusicFirstImg());
        record.setFixedTone(musicSheetApplication.getMusicJianImg());
        record.setMusicSheetExtend(musicSheetApplication.getMusicSheetExtend());
    }


    public void initMusicSheetVos(List<MusicSheetVo> records) {
        if(CollectionUtils.isNotEmpty(records)){
            List<Long> cbsMusicSheetIds = records.stream().map(e -> e.getCbsMusicSheetId()).collect(Collectors.toList());
            CbsMusicSheetWrapper.MusicSheetApplicationQuery query = new CbsMusicSheetWrapper.MusicSheetApplicationQuery();
            query.setMusicSheetIds(cbsMusicSheetIds);
            query.setDetailFlag(true);
            R<PageInfo<CbsMusicSheetWrapper.MusicSheetApplication>> pageInfoR = cbsMusicScoreService.selectPage(query);
            if(pageInfoR.getCode() != 200){
                throw new BizException("获取曲目信息失败");
            }
            PageInfo<CbsMusicSheetWrapper.MusicSheetApplication> pageInfo = pageInfoR.getData();
            if(pageInfo != null && CollectionUtils.isNotEmpty(pageInfo.getRows())){
                Map<Long, CbsMusicSheetWrapper.MusicSheetApplication> musicSheetApplicationMap = pageInfo.getRows()
                        .stream().collect(Collectors.toMap(CbsMusicSheetWrapper.MusicSheetApplication::getId, Function.identity()));
                CbsSubjectApiWrapper.SubjectQuery subjectQuery = new CbsSubjectApiWrapper.SubjectQuery();
                subjectQuery.setCbsSubjectIds(records.stream().map(MusicSheetVo::getMusicSubject).filter(StringUtils::isNotEmpty).map(Long::parseLong).distinct().collect(Collectors.toList()));
                List<CbsSubjectApiWrapper.Subject> subjects = subjectService.getDao().queryCbsList(subjectQuery);
                Map<Long, CbsSubjectApiWrapper.Subject> subjectMap = subjects.stream().collect(Collectors.toMap(CbsSubjectApiWrapper.Subject::getSubjectId, Function.identity()));
                for (MusicSheetVo record : records) {
                    CbsMusicSheetWrapper.MusicSheetApplication musicSheetApplication = musicSheetApplicationMap.get(record.getCbsMusicSheetId());
                    if(musicSheetApplication != null){
                        this.initMusicSheetVo(record,musicSheetApplication,subjectMap);
                    }
                }
            }
        }

    }

    @Override
    public IPage<MusicSheetVo> selectStudentPage(IPage<MusicSheetVo> page, StudentMusicSheetSearch query, ClientEnum clientType) {
        List<MusicSheetVo> records = baseMapper.selectStudentMusicPage(page, query, clientType);
        //设置内容平台曲目信息
        this.initMusicSheetVos(records);
        if (CollectionUtils.isNotEmpty(records)) {

            // 统计单曲归属专辑数
            updateMusicAlbumNumInfo(records);

            // 声部

            List<Long> collect = records.stream().map(MusicSheetVo::getMusicSubject)
                                          .filter(StringUtils::isNotEmpty)
                                            .map(Long::parseLong)
                                          .collect(Collectors.toList());


            List<Subject> subjectList = subjectService.findBySubjectByIdList(collect);
            if (CollectionUtils.isNotEmpty(subjectList)) {
                Map<Long, String> subjectMap = subjectList.stream()
                                                        .collect(Collectors.toMap(Subject::getId, Subject::getName));
                for (MusicSheetVo record : records) {
                    if (StringUtils.isNotEmpty(record.getMusicSubject())) {
                        record.setSubjectNames(subjectMap.get(Long.parseLong(record.getMusicSubject())));
                    }
                }
            }

            // 标签

            collect = records.stream().map(MusicSheetVo::getMusicTag)
                             .filter(StringUtils::isNotEmpty)
                             .flatMap(s -> Arrays.stream(s.split(",")))
                             .filter(StringUtils::isNotEmpty)
                             .map(Long::parseLong)
                             .collect(Collectors.toList());
            List<MusicTag> list = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(collect)) {
                list = musicTagService.lambdaQuery()
                                      .in(MusicTag::getId, collect)
                                      .eq(MusicTag::getDelFlag, 0)
                                      .eq(MusicTag::getState, 1)
                                      .list();
            }
            if (CollectionUtils.isNotEmpty(list)) {
                Map<Long, String> tagMap = list.stream()
                                                          .collect(Collectors.toMap(MusicTag::getId, MusicTag::getName));
                for (MusicSheetVo record : records) {
                    if (StringUtils.isNotEmpty(record.getMusicTag())) {

                        List<Long> tagIdList = Arrays.stream(record.getMusicTag().split(","))
                                                    .filter(StringUtils::isNotEmpty)
                                                    .map(Long::parseLong)
                                                    .collect(Collectors.toList());
                        String tagNames = tagIdList.stream().map(tagMap::get).collect(Collectors.joining(","));
                        record.setMusicTagNames(tagNames);
                    }
                }
            }

            // 是否关注
            if (query.getStudentId() != null) {
                List<Long> musicIdList = records.stream().map(MusicSheetVo::getId).collect(Collectors.toList());
                List<MusicFavorite> musicFavoriteList = musicFavoriteService.lambdaQuery()
                                                                .eq(MusicFavorite::getUserId, query.getStudentId())
                                                                .eq(MusicFavorite::getClientType, clientType)
                                                                .in(MusicFavorite::getMusicSheetId, musicIdList)
                                                                .list();
                if (CollectionUtils.isNotEmpty(musicFavoriteList)) {
                    Set<Long> set = musicFavoriteList.stream()
                                                          .map(MusicFavorite::getMusicSheetId)
                                                          .collect(Collectors.toSet());
                    for (MusicSheetVo record : records) {
                        record.setFavorite(set.contains(record.getId())?YesOrNoEnum.YES:YesOrNoEnum.NO);
                    }
                }
            }

        }
        return page.setRecords(records);

    }

    /**
     * 更新曲目专辑数
     * @param records List<MusicSheetVo>
     * @return List<MusicSheetVo>
     */
    public List<MusicSheetVo> updateMusicAlbumNumInfo(List<MusicSheetVo> records) {
        for (MusicSheetVo record : records) {
            // 设置收藏人数
            record.setFavoriteCount(record.getFavoriteCount() + record.getVirtualNumber());
        }
        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());
            musicSheetDao.updateFavoriteCount(musicSheetId,YesOrNoEnum.YES);
            return musicFavoriteService.save(musicFavorite);
        } else {
            List<Long> ids = musicFavorites.stream().map(MusicFavorite::getId).collect(Collectors.toList());
            musicSheetDao.updateFavoriteCount(musicSheetId,YesOrNoEnum.NO);
            return musicFavoriteService.removeByIds(ids);
        }
    }

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

        List<MusicSheetVo> records = baseMapper.selectMyMusicPage(page, query);
        //设置内容平台曲目信息
        this.initMusicSheetVos(records);

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

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

        return page.setRecords(records);
    }

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

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

        if (CollectionUtils.isNotEmpty(records)) {
            this.initMusicSheetVos(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);
        // 构建分页信息
        List<MusicSheetVo> musicSheetVos = baseMapper.selectPracticeMusicPage(query, practiceMusicIdList);
        //设置内容平台曲目信息
        this.initMusicSheetVos(musicSheetVos);
        page.setRecords(musicSheetVos);
        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
    @Transactional(rollbackFor = Exception.class)
    public boolean del(Long id) {

        MusicSheet musicSheet = super.getById(id);
        if (musicSheet == null) {
            throw new BizException("曲目不存在");
        }
        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
    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.setSourceType(musicSheet.getSourceType());


                    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.setSourceType(SourceTypeEnum.PLATFORM);

                    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).setScale(2, RoundingMode.HALF_UP);

                // 判断是否结算给老师，不结算，不写入老师入账记录
                Teacher teacher = teacherService.getById(musicSheet.getUserId());
                if (teacher != null && teacher.getIsSettlement() != null && teacher.getIsSettlement()) {
                    // 加入账户
                    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<>(1);
        studentReceivers.put(studentId,student.getPhone());

        try {
            Student studentInfo = studentService.getById(studentId);
            if (studentInfo != null && orderClient.equals(ClientEnum.STUDENT) &&
                    studentInfo.getTenantId() != null && studentInfo.getTenantId() > 0 && orderType.equals(OrderTypeEnum.MUSIC)) {
                try {
                    sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.TENANT_MUSIC_BUY,
                            studentReceivers, null, 0, null, ClientEnum.TENANT_STUDENT.getCode(), name);
                } catch (Exception e) {
                    log.error("学生购买曲目推送失败,", e);
                }
            } else {

                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);
            }
        } catch (Exception e) {
            log.error("购买曲目消息推送失败,", e);
        }
        return true;
    }

    /**
     * 保存购买记录
     *
     * @param userOrderDetailVo 订单信息
     * @param actualPrice       付款价格
     * @param serviceFeeAmount  服务费
     */
    @Transactional
    @Override
    public 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()));
        musicSheetPurchaseRecord.setCourseMusicAlbumId(0L);
        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));

        // 插入平台账户 支出
        PlatformCashAccountRecord platformCashAccountRecord = new PlatformCashAccountRecord(userOrderDetailVo.getUserId(), transAmount,
                                                                                            InOrOutEnum.OUT, PostStatusEnum.WAIT, AccountBizTypeEnum.MUSIC, musicSheetId,
                                                                                            userOrderDetailVo.getOrderNo(), accountPeriodTime);
        platformCashAccountRecordService.save(platformCashAccountRecord);
    }

    @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
    public MusicSheetWebsiteDetailVo websiteDetail(Long musicSheetId, SysUser sysUser, ClientEnum clientType) {
        MusicSheetDetailVo detail = detail(musicSheetId, null, null);
        if (detail == null) {
            throw new BizException("曲目不存在");
        }
        MusicSheetWebsiteDetailVo musicSheetWebsiteDetailVo = new MusicSheetWebsiteDetailVo();
        BeanUtils.copyProperties(detail, musicSheetWebsiteDetailVo);

        // 老师信息
        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);
            }
        }
        Integer favoriteCount = detail.getFavoriteCount();
        if (favoriteCount == null) {
            favoriteCount = 0;
        }
        musicSheetWebsiteDetailVo.setFavoriteNum(Long.valueOf(favoriteCount));

        // 老师的曲目
        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 (musicSheet.getPaymentType().contains(ChargeTypeEnum.VIP.getCode())) {
            ActivityPlanVo activityPlanVo = activityPlanService.activityShare(ActivityShareEnum.VIP, sysUser.getId());
            if (activityPlanVo != null) {
                result.setActivityId(activityPlanVo.getId());
                discount = YesOrNoEnum.YES;
            }
        } else if (musicSheet.getPaymentType().contains(ChargeTypeEnum.CHARGE.getCode())) {
            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 (musicSheet == null || musicSheet.getCbsMusicSheetId() == null) {
            throw new BizException("曲目不存在");
        }
        if (YesOrNoEnum.NO.equals(musicSheet.getState())) {
            throw new BizException("下架的曲目不能置顶");
        }
        CbsMusicSheetApplicationExtendClientWrapper.AddMusicSheetApplicationExtend addMusicSheetApplicationExtend = new CbsMusicSheetApplicationExtendClientWrapper.AddMusicSheetApplicationExtend();
        addMusicSheetApplicationExtend.setApplicationId(applicationId);
        addMusicSheetApplicationExtend.setMusicSheetId(musicSheet.getCbsMusicSheetId());
        addMusicSheetApplicationExtend.setTopFlag(musicSheet.getTopFlag() != YesOrNoEnum.YES);
        addMusicSheetApplicationExtend.setMusicTagIds(musicSheet.getMusicTag());
        addMusicSheetApplicationExtend.setMusicPrice(musicSheet.getMusicPrice());
        addMusicSheetApplicationExtend.setPaymentType(EMusicPaymentType.valueOf(musicSheet.getPaymentType()));
        addMusicSheetApplicationExtend.setAvailableType(EMusicAvailableType.valueOf("TEACHER".equals(musicSheet.getPaymentType()) ?
                "PERSON" : "PLATFORM".equals(musicSheet.getPaymentType()) ? "PLATFORM":"ORG"));
        addMusicSheetApplicationExtend.setTopFlag(musicSheet.getTopFlag() == YesOrNoEnum.YES);
        addMusicSheetApplicationExtend.setExquisiteFlag(musicSheet.getExquisiteFlag() == YesOrNoEnum.YES);
        addMusicSheetApplicationExtend.setSortNo(musicSheet.getSortNumber());
        R<JSONObject> jsonObjectR = musicFeignClientService.musicSheetApplicationExtendUpdate(addMusicSheetApplicationExtend);
        if (jsonObjectR.getCode() != 200) {
            throw new BizException("修改失败,{}",jsonObjectR.getMessage());
        }
        return true;
    }

    @Override
    public Boolean stateList(ReasonDto reasonDto) {
        List<Long> musicSheets = Arrays.stream(reasonDto.getMusicSheetIds().split(",")).map(Long::parseLong).collect(Collectors.toList());
        List<MusicSheet> musicSheetList = musicSheetService.lambdaQuery().in(MusicSheet::getId, musicSheets).list();

        CbsMusicSheetWrapper.MusicSheetApplicationQuery query = new CbsMusicSheetWrapper.MusicSheetApplicationQuery();
        query.setApplicationId(applicationId);
        query.setMusicSheetIds(musicSheetList.stream().map(MusicSheet::getCbsMusicSheetId).collect(Collectors.toList()));
        query.setDelFlag(true);
        query.setPage(1);
        query.setRows(musicSheets.size());
        R<com.microsvc.toolkit.common.response.paging.PageInfo<CbsMusicSheetWrapper.MusicSheetApplication>> pageInfoR = musicFeignClientService.musicSheetPageByApplication(query);
        if (pageInfoR.getCode() != 200) {
            throw new BizException("获取曲目信息异常,{}", pageInfoR.getMessage());
        }
        List<CbsMusicSheetWrapper.MusicSheetApplication> rows = pageInfoR.feignData().getRows();
        if (CollectionUtils.isEmpty(rows)) {
            throw new BizException("获取曲目信息失败");
        }
        String applicationExtendIds = rows.stream().map(e -> e.getApplicationExtendId().toString()).collect(Collectors.joining(","));
        CbsMusicSheetApplicationExtendClientWrapper.MusicSheetApplicationExtendStatus extendStatus = new CbsMusicSheetApplicationExtendClientWrapper.MusicSheetApplicationExtendStatus();
        extendStatus.setIds(applicationExtendIds);
        extendStatus.setStatus(reasonDto.getState()==YesOrNoEnum.YES);
        R<JSONObject> jsonObjectR = musicFeignClientService.musicSheetApplicationExtendStatus(extendStatus);
        if (jsonObjectR.getCode() != 200) {
            throw new BizException("修改曲目状态失败,{}", jsonObjectR.getMessage());
        }
        // 发送推送
        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 void initMusicSheetDetailVo(List<MusicSheetDetailVo> sheetDetailVos){
        if(CollectionUtils.isEmpty(sheetDetailVos)){
            return;
        }
        CbsMusicSheetWrapper.MusicSheetApplicationQuery query = new CbsMusicSheetWrapper.MusicSheetApplicationQuery();
        query.setApplicationId(applicationId);
        query.setMusicSheetIds(sheetDetailVos.stream().map(e->e.getCbsMusicSheetId()).collect(Collectors.toList()));
        query.setDelFlag(true);
        query.setPage(1);
        query.setRows(query.getMusicSheetIds().size());
        R<PageInfo<CbsMusicSheetWrapper.MusicSheetApplication>> pageInfoR = musicFeignClientService.musicSheetPageByApplication(query);
        if(pageInfoR.getCode() != 200){
            throw new BizException("查询曲谱信息异常");
        }
        List<CbsMusicSheetWrapper.MusicSheetApplication> rows = pageInfoR.feignData().getRows();
        if (CollectionUtils.isEmpty(rows)){
            throw new BizException("查询曲谱信息失败");
        }
        List<Subject> subjects = subjectService.getDao().getByCbsSubjectIds(rows.stream().map(CbsMusicSheetWrapper.MusicSheetApplication::getSubjectIds).
                filter(StringUtils::isNotEmpty).collect(Collectors.joining(",")));
        Map<Long, String> subjectMap = subjects.stream().collect(Collectors.toMap(Subject::getCbsSubjectId, Subject::getName));

        Map<Long,CbsMusicSheetWrapper.MusicSheetApplication> musicSheetMap =
                rows.stream().collect(Collectors.toMap(CbsMusicSheetWrapper.MusicSheetApplication::getId, Function.identity()));
        for (MusicSheetDetailVo record : sheetDetailVos) {
            CbsMusicSheetWrapper.MusicSheetApplication musicSheetApplication = musicSheetMap.get(record.getCbsMusicSheetId());
            if(musicSheetApplication == null){
                continue;
            }
            if(StringUtils.isNotEmpty(musicSheetApplication.getSubjectIds())){
                StringBuffer sb = new StringBuffer();
                for (String s : musicSheetApplication.getSubjectIds().split(",")) {
                    String subjectName = subjectMap.get(Long.parseLong(s));
                    if(StringUtils.isNotEmpty(subjectName)){
                        if (sb.length() > 0) {
                            sb.append(",");
                        }
                        sb.append(subjectName);
                    }
                }
                record.setSubjectNames(sb.toString());
            }
            record.setCbsMusicSheetId(musicSheetApplication.getId());
            record.setAudioType(AudioTypeEnum.valueOf(musicSheetApplication.getPlayMode().getCode()));
            record.setCanEvaluate(musicSheetApplication.getIsEvaluated() ? YesOrNoEnum.YES : YesOrNoEnum.NO);
            record.setShowFingering(musicSheetApplication.getIsShowFingering() ? YesOrNoEnum.YES : YesOrNoEnum.NO);
            record.setMusicTag(musicSheetApplication.getMusicTagIds());
            record.setMusicTagNames(musicSheetApplication.getMusicTagNames());
            record.setXmlFileUrl(musicSheetApplication.getXmlFileUrl());
            record.setMidiUrl(musicSheetApplication.getMidiFileUrl());
            record.setAuditVersion(musicSheetApplication.getAppAuditFlag() ? YesOrNoEnum.YES : YesOrNoEnum.NO);
            record.setHasBeat((musicSheetApplication.getIsPlayBeat() && !musicSheetApplication.getIsUseSystemBeat()) ? YesOrNoEnum.YES : YesOrNoEnum.NO);
            record.setExtConfigJson(musicSheetApplication.getExtConfigJson());
            record.setMusicJSON(musicSheetApplication.getMusicJson());
            record.setMusicJianSvg(musicSheetApplication.getMusicJianSvg());
            record.setMusicFirstSvg(musicSheetApplication.getMusicFirstSvg());
            record.setFirstTone(musicSheetApplication.getMusicFirstImg());
            record.setFixedTone(musicSheetApplication.getMusicJianImg());
            List<CbsMusicSheetWrapper.MusicSheetAccompaniment> accompanimentList = musicSheetApplication.getMusicSheetAccompanimentList();
            if (CollectionUtils.isNotEmpty(accompanimentList)) {
                List<MusicSheetAccompaniment> background = new ArrayList<>();
                for (CbsMusicSheetWrapper.MusicSheetAccompaniment accompaniment : accompanimentList) {
                    MusicSheetAccompaniment musicSheetAccompaniment = new MusicSheetAccompaniment();
                    musicSheetAccompaniment.setAudioFileUrl(accompaniment.getAudioFileUrl());
                    background.add(musicSheetAccompaniment);
                }
            }
        }
    }

    @Override
    public void setVirtualNumber() {
        List<MusicSheet> musicSheets = this.lambdaQuery().select(MusicSheet::getId,MusicSheet::getVirtualNumber)
                                               .eq(MusicSheet::getState, 1)
                                               .eq(MusicSheet::getDelFlag, false)
                                               .eq(MusicSheet::getAuditVersion,0)
                                               .eq(MusicSheet::getAuditStatus, AuthStatusEnum.PASS)
                .list();
        if (CollectionUtils.isEmpty(musicSheets)) {
            return;
        }
        //给每个曲目设置增长值
        String value = sysConfigService.findConfigValue(SysConfigConstant.MUSIC_SHEET_VIRTUAL_NUMBER);
        for (MusicSheet musicSheet : musicSheets) {
            int i = (int) (Math.random() * Integer.parseInt(value));
            musicSheet.setVirtualNumber(i + musicSheet.getVirtualNumber());
        }

        // 保存虚拟人数
        this.updateBatchById(musicSheets,100);
    }

    /**
     * 购买曲目专辑
     *
     * @param orderGoodsInfo
     * @return
     */
    @Override
    public void buyMusicSheetCheck(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {

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

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


        UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);

        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));


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

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


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

                if (Objects.isNull(album)) {
                    throw new BizException("无效的专辑信息");
                }
                userOrderDetail.setBizId(album.getId());
                userOrderDetail.setOriginalPrice(BigDecimal.valueOf(album.getAlbumPrice()));
                userOrderDetail.setExpectPrice(BigDecimal.valueOf(album.getAlbumPrice()));
            }
            break;
            default:
                break;
        }
        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice());

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

        orderGoodsInfo.setUserOrderDetail(userOrderDetail);


        // 设置金额入账去向
        Long teacherId = null;
        if (orderGoodsInfo.getGoodType().equals(GoodTypeEnum.MUSIC)) {
            MusicSheet musicSheet = this.getById(orderGoodsInfo.getUserOrderDetail().getBizId());
            if (musicSheet != null && musicSheet.getSourceType().equals(SourceTypeEnum.TEACHER)) {
                teacherId = musicSheet.getUserId();
            }
        }
        userOrderDetail.setAccountConfig(teacherService.teacherSettlementFrom(teacherId,orderGoodsInfo.getRecomUserId()).jsonString());
        // 存入缓存
//        redisCacheService.saveUserAccountConfig(orderGoodsInfo.getSubOrderNo(), teacherService.teacherSettlementFrom(teacherId,orderGoodsInfo.getRecomUserId()).jsonString());

    }


    /**
     * 购买曲目专辑
     *
     * @param orderGoodsInfo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderAfterSheet(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
        // 保存购买记录
        MusicSheetPurchaseRecord musicSheetPurchaseRecord = musicSheetPurchaseRecordService.checkPurchase(
                orderGoodsInfo.getUserId(),
                orderGoodsInfo.getBizId(),
                orderGoodsInfo.getPaymentClient(),
                PurchaseRecordTypeEnum.valueOf(orderGoodsInfo.getGoodType().getCode()));
        if (musicSheetPurchaseRecord == null) {
            musicSheetPurchaseRecord = new MusicSheetPurchaseRecord();
        }
        musicSheetPurchaseRecord.setClientType(orderGoodsInfo.getPaymentClient());
        musicSheetPurchaseRecord.setMusicSheetId(orderGoodsInfo.getBizId());
        musicSheetPurchaseRecord.setOrderNo(orderGoodsInfo.getOrderNo());
        musicSheetPurchaseRecord.setTeacherId(orderGoodsInfo.getUserOrderDetail().getMerchId());
        musicSheetPurchaseRecord.setOriginalPrice(orderGoodsInfo.getUserOrderDetail().getOriginalPrice());
        musicSheetPurchaseRecord.setOrderStatus(OrderStatusEnum.WAIT_PAY);
        musicSheetPurchaseRecord.setStudentId(orderGoodsInfo.getUserId());
        musicSheetPurchaseRecord.setPurchaseType(PurchaseRecordTypeEnum.valueOf(orderGoodsInfo.getGoodType().getCode()));

        musicSheetPurchaseRecordService.saveOrUpdate(musicSheetPurchaseRecord);
    }

    @Override
    public List<MusicSheetUploadCountVo> countByUser(List<Long> userIds) {
        return this.getDao().countByUser(userIds);
    }

    @Override
    public Map<Long, MusicSheet> getMapByIds(List<Long> bizIds) {
        if (CollectionUtils.isEmpty(bizIds)) {
            return new HashMap<>();
        }
        List<MusicSheet> sheetList = this.lambdaQuery()
                .in(MusicSheet::getId, bizIds)
                .list();
        if (CollectionUtils.isEmpty(sheetList)) {
            return new HashMap<>();
        }
        return sheetList.stream().collect(Collectors.toMap(MusicSheet::getId, Function.identity()));

    }

    @Override
    public MusicCompareWrapper.SearchData search(MusicCompareWrapper.MusicSearch queryInfo) {
        MusicCompareWrapper.SearchData searchData= new MusicCompareWrapper.SearchData();
        List<MusicCompareWrapper.MusicName> musicNames = new ArrayList<>();
        if (StringUtil.isEmpty(queryInfo.getType()) || queryInfo.getType().equals("MUSIC")) {

            // 查询曲目列表
            List<Long> musicIds = musicSheetDao.searchMusic(PageUtil.getPage(queryInfo),queryInfo);

            if (CollectionUtils.isNotEmpty(musicIds)) {


                MusicSheetSearch musicSheetSearch = new MusicSheetSearch();
                musicSheetSearch.setMusicSheetIdlist(musicIds);
                IPage<MusicSheetVo> musicSheetVoIPage = selectPage(PageUtil.getPage(queryInfo), musicSheetSearch);
                List<MusicSheetVo> records = musicSheetVoIPage.getRecords();
                if (CollectionUtils.isNotEmpty(records)) {
                    for (MusicSheetVo record : records) {
                        MusicCompareWrapper.MusicName musicName = new MusicCompareWrapper.MusicName();
                        musicName.setId(record.getId());
                        musicName.setName(record.getMusicSheetName());
                        musicName.setType("MUSIC");
                        musicName.setHotFlag(record.getHotFlag() != null?record.getHotFlag():YesOrNoEnum.NO);
                        musicName.setSort(Optional.ofNullable(record.getFavoriteCount()).orElse(0));
                        musicNames.add(musicName);
                    }
                    searchData.setMusic(PageUtil.pageInfo(musicSheetVoIPage));
                }

                // 是否关注
                if (queryInfo.getUserId() != null) {
                    List<MusicFavorite> musicFavoriteList = musicFavoriteService.lambdaQuery()
                            .eq(MusicFavorite::getUserId, queryInfo.getUserId())
                            .eq(MusicFavorite::getClientType, ClientEnum.STUDENT)
                            .in(MusicFavorite::getMusicSheetId, musicIds)
                            .list();
                    if (CollectionUtils.isNotEmpty(musicFavoriteList)) {
                        Set<Long> set = musicFavoriteList.stream()
                                .map(MusicFavorite::getMusicSheetId)
                                .collect(Collectors.toSet());
                        for (MusicCompareWrapper.MusicName record : musicNames) {
                            record.setFavorite(set.contains(record.getId()) ? YesOrNoEnum.YES : YesOrNoEnum.NO);
                        }
                    }
                }
            }
        }
        if (StringUtil.isEmpty(queryInfo.getType()) || queryInfo.getType().equals("ALBUM")) {

            // 查询专辑列表
            List<Long> albumIds = musicSheetDao.searchAlbum(PageUtil.getPage(queryInfo),queryInfo);

            if (CollectionUtils.isNotEmpty(albumIds)) {
                MusicAlbumSearch musicSheetSearch = new MusicAlbumSearch();
                musicSheetSearch.setAlbumIds(albumIds);
                IPage<MusicAlbumVo> musicAlbumVoIPage = musicAlbumService.selectPage(PageUtil.getPage(queryInfo), musicSheetSearch);
                List<MusicAlbumVo> records = musicAlbumVoIPage.getRecords();
                albumIds = albumFavoriteService.selectFavorite(queryInfo.getUserId(), albumIds, ClientEnum.STUDENT);
                for (MusicAlbumVo record : records) {
                    if (albumIds.contains(record.getId())) {
                        record.setFavorite(YesOrNoEnum.YES);
                    } else {
                        record.setFavorite(YesOrNoEnum.NO);
                    }
                }
                if (CollectionUtils.isNotEmpty(records)) {
                    for (MusicAlbumVo record : records) {
                        MusicCompareWrapper.MusicName musicName = new MusicCompareWrapper.MusicName();
                        musicName.setId(record.getId());
                        musicName.setName(record.getAlbumName());
                        musicName.setType("ALBUM");
                        musicName.setHotFlag(record.getHotFlag() !=null?record.getHotFlag():YesOrNoEnum.NO);
                        musicName.setFavorite(record.getFavorite());
                        musicName.setSort(Optional.ofNullable(record.getAlbumFavoriteCount()).orElse(0));
                        musicNames.add(musicName);
                    }
                    searchData.setAlbum(PageUtil.pageInfo(musicAlbumVoIPage));
                }
            }
        }
        musicNames.sort(Comparator.comparing(MusicCompareWrapper.MusicName::getSort).reversed());
        if (musicNames.size() > queryInfo.getRows()) {
            musicNames = musicNames.subList(0,queryInfo.getRows());
        }
        searchData.setMusicNames(musicNames);
        return searchData;
    }

    @Override
    public MusicCompareWrapper.SearchData searchTenant(MusicCompareWrapper.MusicSearch queryInfo) {
        MusicCompareWrapper.SearchData searchData = new MusicCompareWrapper.SearchData();
        List<MusicCompareWrapper.MusicName> musicNames = new ArrayList<>();
        searchData.setMusicNames(musicNames);

        // 查询学生机构
        Student student = studentService.getById(queryInfo.getUserId());
        if (student == null) {
            throw new BizException("学生不存在");
        }
        if (student.getTenantId() == null || student.getTenantId() == -1 || student.getTenantGroupId() == null) {
            return searchData;
        }
        // 查询机构 小组下的专辑
        TenantGroupAlbumWrapper.BuyTenantAlbumQuery query = new TenantGroupAlbumWrapper.BuyTenantAlbumQuery();
        query.setTenantGroupId(student.getTenantGroupId());

        List<TenantGroupAlbumWrapper.BuyTenantAlbum> buyAlbumInfo = tenantGroupAlbumMapper.getBuyAlbumInfo(query);
        List<Long> albumIds;
        if (CollectionUtils.isNotEmpty(buyAlbumInfo)) {
            albumIds = buyAlbumInfo.stream().map(TenantGroupAlbumWrapper.BuyTenantAlbum::getId).distinct().collect(Collectors.toList());
        } else {
            return searchData;
        }

        List<TenantAlbumMusic> list = tenantAlbumMusicMapper.getByAlbumAndEnable(albumIds);
        // 过滤出曲目
        List<SubjectTypeEnum> enumList = Lists.newArrayList(SubjectTypeEnum.MUSIC, SubjectTypeEnum.SUBJECT, SubjectTypeEnum.ENSEMBLE);
        list = list.stream().filter(tenantAlbumMusic -> enumList.contains(tenantAlbumMusic.getSubjectType())).collect(Collectors.toList());

        // 根据曲目ID分组
        Map<Long, List<Long>> map = list.stream()
            .collect(Collectors.groupingBy(TenantAlbumMusic::getMusicSheetId, Collectors.mapping(TenantAlbumMusic::getTenantAlbumId, Collectors.toList())));

        queryInfo.setTenantAlbumIds(albumIds);

        // 查询曲目列表
        List<Long> musicIds = musicSheetDao.searchMusic(PageUtil.getPage(queryInfo),queryInfo);
        if (CollectionUtils.isNotEmpty(musicIds)) {


            MusicSheetSearch musicSheetSearch = new MusicSheetSearch();
            musicSheetSearch.setMusicSheetIdlist(musicIds);
            IPage<MusicSheetVo> musicSheetVoIPage = selectPage(PageUtil.getPage(queryInfo), musicSheetSearch);
            List<MusicSheetVo> records = musicSheetVoIPage.getRecords();
            if (CollectionUtils.isNotEmpty(records)) {
                for (MusicSheetVo record : records) {
                    MusicCompareWrapper.MusicName musicName = new MusicCompareWrapper.MusicName();
                    musicName.setId(record.getId());
                    musicName.setName(record.getMusicSheetName());
                    musicName.setType("MUSIC");
                    musicName.setHotFlag(record.getHotFlag() != null?record.getHotFlag():YesOrNoEnum.NO);
                    musicName.setSort(Optional.ofNullable(record.getFavoriteCount()).orElse(0));
                    musicName.setTenantAlbumId(Optional.ofNullable(map.get(record.getId())).orElse(new ArrayList<>()).stream().map(String::valueOf).collect(Collectors.joining(",")));
                    musicNames.add(musicName);
                    record.setTenantAlbumId(Optional.ofNullable(map.get(record.getId())).orElse(new ArrayList<>()).stream().map(String::valueOf).collect(Collectors.joining(",")));

                }
                musicSheetVoIPage.setRecords(records);
                searchData.setMusic(PageUtil.pageInfo(musicSheetVoIPage));
            }

            // 是否关注
            if (queryInfo.getUserId() != null) {
                List<MusicFavorite> musicFavoriteList = musicFavoriteService.lambdaQuery()
                        .eq(MusicFavorite::getUserId, queryInfo.getUserId())
                        .eq(MusicFavorite::getClientType, ClientEnum.STUDENT)
                        .in(MusicFavorite::getMusicSheetId, musicIds)
                        .list();
                if (CollectionUtils.isNotEmpty(musicFavoriteList)) {
                    Set<Long> set = musicFavoriteList.stream()
                            .map(MusicFavorite::getMusicSheetId)
                            .collect(Collectors.toSet());
                    for (MusicCompareWrapper.MusicName record : musicNames) {
                        record.setFavorite(set.contains(record.getId()) ? YesOrNoEnum.YES : YesOrNoEnum.NO);
                    }
                }
            }
        }

        musicNames.sort(Comparator.comparing(MusicCompareWrapper.MusicName::getSort).reversed());
        return searchData;
    }

    @Override
    public Boolean updateMusicImg(MusicImgDto musicImgDto, Long musicSheetId) {
        MusicSheet musicSheet = new MusicSheet();
        musicSheet.setMusicImg(musicImgDto.getMusicImg());
        musicSheet.setFirstTone(musicImgDto.getFirstTone());
        musicSheet.setFixedTone(musicImgDto.getFixedTone());
        musicSheet.setId(musicSheetId);
        this.updateById(musicSheet);

        return true;
    }

    /**
     * 曲目修复
     *
     * @param musicImgDto  MusicImgDto
     * @param musicSheetId 曲目Id
     * @return Boolean
     */
    @Override
    public Boolean updateMusicCorrect(MusicImgDto musicImgDto, Long musicSheetId) {
        MusicSheet musicSheet = new MusicSheet();
        musicSheet.setCorrectTime(DateTime.now().toDate());
        musicSheet.setFixedTone(musicImgDto.getFixedTone());
        musicSheet.setId(musicSheetId);
        this.updateById(musicSheet);
        return true;
    }

    @Override
    public MusicSheet initMusicSheet(String musicSheetJson) {
        if(org.springframework.util.StringUtils.isEmpty(musicSheetJson)){
            throw new BizException("曲目信息不能为空");
        }
        CbsMusicSheetWrapper.AddMusicSheet addMusicSheet = JSON.parseObject(musicSheetJson, CbsMusicSheetWrapper.AddMusicSheet.class);
        List<CbsMusicSheetApplicationExtendClientWrapper.AddMusicSheetApplicationExtend> addMusicSheetApplicationExtend = addMusicSheet.getAddMusicSheetApplicationExtend();
        if(org.apache.commons.collections.CollectionUtils.isEmpty(addMusicSheetApplicationExtend)){
            throw new BizException("曲目应用不能为空");
        }
        MusicSheet musicSheetAudit = new MusicSheet();
        musicSheetAudit.setSubmitAuditTime(new Date());
        musicSheetAudit.setProviderType(SourceTypeEnum.TEACHER);
        musicSheetAudit.setSourceType(SourceTypeEnum.TEACHER);
        musicSheetAudit.setAuditStatus(AuthStatusEnum.DOING);
        musicSheetAudit.setState(YesOrNoEnum.NO);
        musicSheetAudit.setDelFlag(true);
        musicSheetAudit.setMusicSheetName(addMusicSheet.getName());
        musicSheetAudit.setMusicSubject(addMusicSheet.getSubjectIds());
        musicSheetAudit.setMusicSvg(addMusicSheet.getMusicSvg());
        musicSheetAudit.setComposer(addMusicSheet.getComposer());
        musicSheetAudit.setTitleImg(addMusicSheet.getMusicCover());
        if(addMusicSheet.getAudioType() != null){
            musicSheetAudit.setAccompanimentType(AccompanimentTypeEnum.valueOf(addMusicSheet.getAudioType().getCode()));
        }
        musicSheetAudit.setPlaySpeed(addMusicSheet.getPlaySpeed());
        if(addMusicSheet.getIsConvertibleScore() != null){
            musicSheetAudit.setNotation(addMusicSheet.getIsConvertibleScore()? YesOrNoEnum.YES: YesOrNoEnum.NO);
        }
        if(addMusicSheet.getMusicSheetType() != null){
            musicSheetAudit.setMusicSheetType(MusicSheetTypeEnum.valueOf(addMusicSheet.getMusicSheetType().getCode()));
        }
        if(addMusicSheet.getPlayMode() != null){
            musicSheetAudit.setAudioType(AudioTypeEnum.valueOf(addMusicSheet.getPlayMode().getCode()));
        }
        if(addMusicSheet.getIsShowFingering() != null){
            musicSheetAudit.setShowFingering(addMusicSheet.getIsShowFingering()? YesOrNoEnum.YES: YesOrNoEnum.NO);
        }
        if(addMusicSheet.getIsEvaluated() != null){
            musicSheetAudit.setCanEvaluate(addMusicSheet.getIsEvaluated()? YesOrNoEnum.YES: YesOrNoEnum.NO);
        }
        List<CbsMusicSheetWrapper.MusicSheetAccompaniment> accompanimentList = addMusicSheet.getMusicSheetAccompanimentList();
        if (CollectionUtils.isNotEmpty(accompanimentList)) {
            musicSheetAudit.setMetronomeUrl(accompanimentList.get(0).getAudioFileUrl());
        }
        musicSheetAudit.setXmlFileUrl(addMusicSheet.getXmlFileUrl());
        musicSheetAudit.setMidiUrl(addMusicSheet.getMidiFileUrl());
        List<CbsMusicSheetApplicationExtendClientWrapper.AddMusicSheetApplicationExtend> extend = addMusicSheet.getAddMusicSheetApplicationExtend();
        if(CollectionUtils.isNotEmpty(extend)){
            CbsMusicSheetApplicationExtendClientWrapper.AddMusicSheetApplicationExtend applicationExtend = extend.get(0);
            musicSheetAudit.setMusicTag(applicationExtend.getMusicTagIds());
            if(applicationExtend.getPaymentType() != null){
                musicSheetAudit.setPaymentType(applicationExtend.getPaymentType().getCode());
                musicSheetAudit.setChargeType(ChargeTypeEnum.valueOf(applicationExtend.getPaymentType().getCode()));
            }
            if(applicationExtend.getTopFlag() != null){
                musicSheetAudit.setTopFlag(applicationExtend.getTopFlag()? YesOrNoEnum.YES: YesOrNoEnum.NO);
            }
            if(applicationExtend.getExquisiteFlag() != null){
                musicSheetAudit.setExquisiteFlag(applicationExtend.getExquisiteFlag()? YesOrNoEnum.YES: YesOrNoEnum.NO);
            }
            if(applicationExtend.getExquisiteFlag() != null){
                musicSheetAudit.setExquisiteFlag(applicationExtend.getExquisiteFlag()? YesOrNoEnum.YES: YesOrNoEnum.NO);
            }
            musicSheetAudit.setSortNumber(applicationExtend.getSortNo());
            musicSheetAudit.setMusicPrice(applicationExtend.getMusicPrice());
        }
        return musicSheetAudit;
    }

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