package com.yuchen.saas.park.service.service.pldoor.impl;

import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.thinkunion.sdk.iot.bean.api.CallingDeviceServiceResponse;
import com.yuchen.saas.park.api.dto.park.IoTEvent;
import com.yuchen.saas.park.api.dto.pldoor.CallDeviceServiceDto;
import com.yuchen.saas.park.api.entity.pldoor.*;
import com.yuchen.saas.park.api.vo.door.PlDoorPointInOutVO;
import com.yuchen.saas.park.api.vo.pldoor.*;
import com.yuchen.saas.park.service.iot.IoTRemoteService;
import com.yuchen.saas.park.service.mapper.pldoor.PlDoorInoutRecodeMapper;
import com.yuchen.saas.park.service.service.pldoor.*;
import com.yuchen.saas.park.service.util.EncryptUntil;
import com.yuchen.saas.parking.api.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.tool.utils.Func;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 门禁出入记录 服务实现类
 * </p>
 *
 * @author miaoqs
 * @since 2024-04-12
 */
@Slf4j
@Service
public class PlDoorInoutRecodeServiceImpl extends BaseServiceImpl<PlDoorInoutRecodeMapper, PlDoorInoutRecode> implements PlDoorInoutRecodeService {

    // 门禁出入记录上报功能识别符
    private final String openDoorUpload = "openDoorUpload";
    //铁军二维码透传
    private final String qrCodeEvent = "qrCodeEvent";
    //文本转语音
    private final String TEXTTOVOICE = "textToVoice";
    // 通行语音
    private final String VOICEMSGSTR = "请通行";
    // 铁军标识
    private final String TieJun = "铁军";

    @Resource
    private PlDoorPointService plDoorPointService;
    @Resource
    private PlDoorUserPointSetService plDoorUserPointSetService;
    @Resource
    private PlDoorUserPointSetItemService plDoorUserPointSetItemService;
    @Resource
    private PlVisitorCrewService plVisitorCrewService;
    @Resource
    private PlDoorInoutRecodeMapper plDoorInoutRecodeMapper;
    @Resource
    private IoTRemoteService ioTRemoteService;

    @Override
    public boolean receiveIotEvent(String jsonObjectContent) throws Exception{
        // 处理接收到的iot事件
        log.info("====== 接收到的iot上报设备事件:{}", jsonObjectContent);
        if(Func.isEmpty(jsonObjectContent)){
            log.error("====== 接收到的iot上报事件为空");
            return false;
        }

        IoTEvent ioTEvent = JSON.parseObject(jsonObjectContent, IoTEvent.class);
        if(Func.isEmpty(ioTEvent) || Func.isEmpty(ioTEvent.getIdentifier())){
            throw new RuntimeException("====== 接收到的iot上报事件为空");
        }
        String identifier = ioTEvent.getIdentifier();
        if(identifier.equals(openDoorUpload)){
            //开门记录
            log.info("====== 接收到的iot上报开门记录事件:{}", jsonObjectContent);
            saveOpenDoorUpload(ioTEvent);
        }else if(identifier.equals(qrCodeEvent)){
            //铁军二维码记录
            saveQrCodeEvent(ioTEvent);
        }
        return true;
    }

    /**
     * 保存门禁出入记录-刷脸/二维码
     * @param ioTEvent
     */
    public void saveOpenDoorUpload(IoTEvent ioTEvent) {
        log.info("====== 保存iot上报开门记录事件:{}", JSON.toJSONString(ioTEvent));
        if(Func.isNotEmpty(ioTEvent) && Func.isNotEmpty(ioTEvent.getOut())){
                Map<String, Object> out = ioTEvent.getOut();
                List<Map<String, Object>> list = (List<Map<String, Object>>) out.get("list");
                List<PlDoorInoutRecode> plDoorInoutRecodeList = new ArrayList<>();
                for (Map<String, Object> outMap : list) {
                    PlDoorInoutRecode plDoorInoutRecode = new PlDoorInoutRecode();
                    String openDoorType = "";
                    if(outMap.get("type").toString().equals("21")){
                        openDoorType = "1";
                    }else if(outMap.get("type").toString().equals("22")){
                        openDoorType = "2";
                    }else{
                        openDoorType = outMap.get("type").toString();
                    }

                    plDoorInoutRecode.setOpenDoorType(openDoorType);
                    if(Func.isNotEmpty(outMap.get("userId"))){
                        //人员登记唯一标识
                        Long userId = Long.valueOf(outMap.get("userId").toString());
                        PlDoorUserPointSet pointSet = plDoorUserPointSetService.getOne(new LambdaQueryWrapper<PlDoorUserPointSet>()
                                .eq(PlDoorUserPointSet::getUserId, userId).last("limit 1"));
                        PlVisitorCrew visitorCrew = plVisitorCrewService.getOne(new LambdaQueryWrapper<PlVisitorCrew>().eq(PlVisitorCrew::getId, userId));
                        if(Func.isNotEmpty(pointSet) || Func.isNotEmpty(visitorCrew)) {
                            //访客
                            if(Func.isEmpty(pointSet)) {
                                plDoorInoutRecode.setUserType("2");
                            }
                            plDoorInoutRecode.setUserId(null == pointSet ? visitorCrew.getId() : pointSet.getId());
                            plDoorInoutRecode.setUserName(null == pointSet ? visitorCrew.getVisitorName() : pointSet.getUserName());
                        }
                    }
                    //plDoorInoutRecode.setFloorId();
                    //plDoorInoutRecode.setRoomId();
                    plDoorInoutRecode.setInoutTime(DateUtils.parseDate("yyyy-MM-dd HH:mm:ss", outMap.get("openDateTime").toString()));
                    //判断门禁点
                    if(Func.isNotEmpty(outMap.get("terminalNumber"))){
                        String terminalNumber = outMap.get("terminalNumber").toString();
                        PlDoorPoint point = plDoorPointService.getOne(new LambdaQueryWrapper<PlDoorPoint>()
                                .eq(PlDoorPoint::getTerminalNumber, terminalNumber)
                                .last("limit 1"));
                        plDoorInoutRecode.setDoorPointId(null==point?null:point.getId());
                        plDoorInoutRecode.setParkId(null==point?null:point.getParkId());
                        plDoorInoutRecode.setBuildingId(null==point?null:point.getBuildingId());
                        plDoorInoutRecode.setElementId(null==point?null:point.getElementId());
                        //安装方向
                        plDoorInoutRecode.setInOrOut(null==point?null:point.getInstallationDimension());
                        //铁军播放语音
                        if(Func.isNotEmpty(point) && Func.isNotEmpty(point.getBrandModel()) && point.getBrandModel().contains(TieJun)){
                            log.info("====== 调用iot接口,铁军语音播报");
                            tiejunVoice(VOICEMSGSTR, point.getParkId(), point.getId());
                        }
                    }
                    plDoorInoutRecode.setTerminalNumber(null==outMap.get("terminalNumber")?"":outMap.get("terminalNumber").toString());
                    plDoorInoutRecode.setDoorName(null==outMap.get("doorName")?"":outMap.get("doorName").toString());
                    plDoorInoutRecode.setDoorNo(null==outMap.get("doorNo")?"":outMap.get("doorNo").toString());
                    plDoorInoutRecode.setCaptureFaceUrl(null==outMap.get("captureFaceUrl")?"":outMap.get("captureFaceUrl").toString());
                    plDoorInoutRecodeList.add(plDoorInoutRecode);
                }
                saveBatch(plDoorInoutRecodeList);
        }
    }

    @Override
    public PlDoorPointInOutVO getPointInOutByPointId(Long pointId) {
        PlDoorPointInOutVO plDoorPointInOutVO = new PlDoorPointInOutVO();
        PlDoorPoint point = plDoorPointService.getById(pointId);
        if(Func.isNotEmpty(point)){
            plDoorPointInOutVO.setDoorPointId(point.getId());
            plDoorPointInOutVO.setDoorPointName(point.getDoorName());
            plDoorPointInOutVO.setDoorPointAddress(point.getDeviceLocation());
            plDoorPointInOutVO.setDoorPointIp(point.getDoorIp());
            plDoorPointInOutVO.setCurrentTime(new Date());
            plDoorPointInOutVO.setOnLineState(point.getOnlineState());
            //plDoorPointInOutVO.setOpenDoorState();
            int count = this.count(new LambdaQueryWrapper<PlDoorInoutRecode>()
                    .eq(PlDoorInoutRecode::getDoorPointId, pointId));
            plDoorPointInOutVO.setSumInOutNum(count);
            //plDoorPointInOutVO.setInNum();
            //plDoorPointInOutVO.setOutNum();
        }
        return plDoorPointInOutVO;
    }

    @Override
    public PlDoorPassedTodayCountVO todayPassCount(Long parkId) {
        PlDoorPassedTodayCountVO plDoorTodayPassCountVO = new PlDoorPassedTodayCountVO();
        Integer count1 = plDoorInoutRecodeMapper.todayPassCount(parkId, "1");
        Integer count2 = plDoorInoutRecodeMapper.todayPassCount(parkId, "2");
        plDoorTodayPassCountVO.setSumInOutNum(count1+count2);
        plDoorTodayPassCountVO.setLiverInOutNum(count1);
        plDoorTodayPassCountVO.setVisiterInOutNum(count2);
        return plDoorTodayPassCountVO;
    }

    @Override
    public List<PlDoorPassedTimeFrameCountVO> passedTimeFrameCount(Long parkId, String userType) {
        List<PlDoorPassedTimeFrameCountVO> countVOList = new ArrayList<>();
        //获取近7天日期
        List<String> days = getRecentSevenDaysFormatted();
        List<PlDoorPassedTimeFrameCountVO> voList = plDoorInoutRecodeMapper.passedTimeFrameCount(parkId, userType);
        for (String day : days) {
            PlDoorPassedTimeFrameCountVO vo = new PlDoorPassedTimeFrameCountVO();
            vo.setDateTime(day);
            for (PlDoorPassedTimeFrameCountVO VO : voList) {
                if(VO.getDateTime().equals(day)){
                    vo.setPassedCount(VO.getPassedCount());
                }
            }
            countVOList.add(vo);
        }
        return countVOList;
    }

    @Override
    public PlDoorPassedTypeCountVO passedTypeCount(Long parkId, String userType) {
        PlDoorPassedTypeCountVO plDoorPassedTypeCountVO = new PlDoorPassedTypeCountVO();
        int count1 = this.count(new LambdaQueryWrapper<PlDoorInoutRecode>().eq(PlDoorInoutRecode::getParkId, parkId)
                .eq(PlDoorInoutRecode::getOpenDoorType, "1")
                .eq(Func.isNotEmpty(userType),PlDoorInoutRecode::getUserType, userType));
        int count2 = this.count(new LambdaQueryWrapper<PlDoorInoutRecode>().eq(PlDoorInoutRecode::getParkId, parkId)
                .eq(PlDoorInoutRecode::getOpenDoorType, "2")
                .eq(Func.isNotEmpty(userType),PlDoorInoutRecode::getUserType, userType));
        int count3 = this.count(new LambdaQueryWrapper<PlDoorInoutRecode>().eq(PlDoorInoutRecode::getParkId, parkId)
                .eq(PlDoorInoutRecode::getOpenDoorType, "5")
                .eq(Func.isNotEmpty(userType),PlDoorInoutRecode::getUserType, userType));
        plDoorPassedTypeCountVO.setQrCodePassedCount(count1);
        plDoorPassedTypeCountVO.setFacePassedCount(count2);
        plDoorPassedTypeCountVO.setIcCradPassedCount(count3);
        return plDoorPassedTypeCountVO;
    }

    @Override
    public List<PlDoorPassedUserTypeVO> userTypeCount(Long parkId) {
        List<PlDoorPassedUserTypeVO> PlDoorPassedUserTypeVOList = new ArrayList<>();
        PlDoorPassedUserTypeVO plDoorPassedUserTypeVO1 = new PlDoorPassedUserTypeVO();
        PlDoorPassedUserTypeVO plDoorPassedUserTypeVO2 = new PlDoorPassedUserTypeVO();
        int count1 = this.count(new LambdaQueryWrapper<PlDoorInoutRecode>()
                .eq(PlDoorInoutRecode::getParkId, parkId)
                .eq(PlDoorInoutRecode::getUserType, "1"));
        int count2 = this.count(new LambdaQueryWrapper<PlDoorInoutRecode>()
                .eq(PlDoorInoutRecode::getParkId, parkId)
                .eq(PlDoorInoutRecode::getUserType, "2"));
        plDoorPassedUserTypeVO1.setUserType("1");
        plDoorPassedUserTypeVO1.setPassedCount(count1);
        plDoorPassedUserTypeVO2.setUserType("2");
        plDoorPassedUserTypeVO2.setPassedCount(count2);
        PlDoorPassedUserTypeVOList.add(plDoorPassedUserTypeVO1);
        PlDoorPassedUserTypeVOList.add(plDoorPassedUserTypeVO2);
        return PlDoorPassedUserTypeVOList;
    }

    @Override
    public PlDoorVistorDateTypeCountVO visitorDateTypeCount(Long parkId) {
        PlDoorVistorDateTypeCountVO plDoorVistorDateTypeCountVO = new PlDoorVistorDateTypeCountVO();
        //查询今天的数量
        QueryWrapper<PlDoorInoutRecode> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.apply("DATE(inout_time) = CURDATE()");
        int todayCount = plDoorInoutRecodeMapper.selectCount(queryWrapper1);
        plDoorVistorDateTypeCountVO.setTodayVisitorCount(todayCount);
        // 查询昨天的数据量
        QueryWrapper<PlDoorInoutRecode> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.apply("DATE(inout_time) = CURDATE() - INTERVAL 1 DAY");
        int yesterdayCount =  plDoorInoutRecodeMapper.selectCount(queryWrapper2);
        plDoorVistorDateTypeCountVO.setYesterdayVisitorCount(yesterdayCount);
        // 查询本周的数据量
        QueryWrapper<PlDoorInoutRecode> queryWrapper3 = new QueryWrapper<>();
        queryWrapper3.apply("YEARWEEK(inout_time) = YEARWEEK(CURDATE())");
        int weekCount =  plDoorInoutRecodeMapper.selectCount(queryWrapper3);
        plDoorVistorDateTypeCountVO.setWeekVisitorCount(weekCount);
        // 查询本月的数据量
        QueryWrapper<PlDoorInoutRecode> queryWrapper4 = new QueryWrapper<>();
        queryWrapper4.apply("YEAR(inout_time) = YEAR(CURDATE()) AND MONTH(inout_time) = MONTH(CURDATE())");
        int monthCount =  plDoorInoutRecodeMapper.selectCount(queryWrapper4);
        plDoorVistorDateTypeCountVO.setMonthVisitorCount(monthCount);
        return plDoorVistorDateTypeCountVO;
    }

    @Override
    public List<PlDoorPassedTimeFrameCountVO> getDaysOfCurrentMonth(Long parkId) {
        List<PlDoorPassedTimeFrameCountVO> countVOList = new ArrayList<>();
        List<String> days = getDaysOfCurrentMonth();
        List<PlDoorPassedTimeFrameCountVO> days1 = plDoorInoutRecodeMapper.getDaysOfCurrentMonth(parkId);
        for (String day : days) {
            PlDoorPassedTimeFrameCountVO countVO = new PlDoorPassedTimeFrameCountVO();
            countVO.setDateTime(day);
            for (PlDoorPassedTimeFrameCountVO VO : days1) {
                if(VO.getDateTime().equals(day)){
                    countVO.setPassedCount(VO.getPassedCount());
                    break;
                }
            }
            countVOList.add(countVO);
        }
        return countVOList;
    }

    @Override
    public List<PlDoorPassedTimeFrameCountVO> getMonthsOfCurrentYear(Long parkId) {
        List<String> months = getMonthsOfCurrentYear();
        List<PlDoorPassedTimeFrameCountVO> countVOList = new ArrayList<>();
        List<PlDoorPassedTimeFrameCountVO> plDoorPassedTimeFrameCountVOList = plDoorInoutRecodeMapper.getMonthsOfCurrentYear(parkId);
        for (String month : months) {
            PlDoorPassedTimeFrameCountVO countVO = new PlDoorPassedTimeFrameCountVO();
            countVO.setDateTime(month);
            for (PlDoorPassedTimeFrameCountVO VO : plDoorPassedTimeFrameCountVOList) {
                if(VO.getDateTime().equals(month)){
                    countVO.setPassedCount(VO.getPassedCount());
                    break;
                }
            }
            countVOList.add(countVO);
        }
        return countVOList;

    }

    @Override
    public List<PlDoorPassedTimeFrameCountVO> getHourOfDay(Long parkId) {
        List<PlDoorPassedTimeFrameCountVO> list = plDoorInoutRecodeMapper.getHourOfDay(parkId);
        List<PlDoorPassedTimeFrameCountVO> countVOList = new ArrayList<>();
        for (int i = 0; i < 24; i++) {
            PlDoorPassedTimeFrameCountVO countVO = new PlDoorPassedTimeFrameCountVO();
            countVO.setDateTime(String.valueOf(i));
            for (PlDoorPassedTimeFrameCountVO vo : list) {
                if(i == Integer.parseInt(vo.getDateTime())){
                    countVO.setPassedCount(vo.getPassedCount());
                }
            }
            countVOList.add(countVO);
        }
        return countVOList;
    }

    @Override
    public PlVistorByTypeCountVO vistorCountByType(Long parkId, String type) {
        PlVistorByTypeCountVO plVistorByTypeCountVO = new PlVistorByTypeCountVO();
        if("1".equals(type)){

        }
        return null;
    }

    @Override
    public boolean tiejunVoice(String voiceStr, Long parkId, Long pointId) {
        if(Func.isNotEmpty(parkId) && Func.isNotEmpty(pointId)){
            PlDoorPoint point = plDoorPointService.getOne(new LambdaQueryWrapper<PlDoorPoint>()
                    .eq(PlDoorPoint::getDoorId, pointId)
                    .eq(PlDoorPoint::getParkId, parkId));
            if(Func.isEmpty(point)){
                log.info("====== 铁军语音播报，门禁点不存在");
                return false;
            }
            CallDeviceServiceDto callDeviceServiceDto = new CallDeviceServiceDto();
            callDeviceServiceDto.setIdentify(TEXTTOVOICE);
            callDeviceServiceDto.setProductKey(point.getProductKey());
            callDeviceServiceDto.setDeviceName(point.getDeviceNo());
            Map<String, Object> in = new HashMap<>();
            in.put("voice", voiceStr);
            callDeviceServiceDto.setParams(in);
            String json = JSONObject.toJSONString(callDeviceServiceDto);
            Map map = JSONObject.parseObject(json, Map.class);

            //调用接口
            log.info("====== 铁军调用iot语音播报参数：{}",json);
            CallingDeviceServiceResponse response = ioTRemoteService.callServiceReturn(map);
            if(Func.isNotEmpty(response)){
                boolean result = false;
                String resultJson = JSONObject.toJSONString(response);
                log.info("====== 铁军调用iot语音播报参数：{}",resultJson);
                if(response.getCode().equals("200")){
                    result = true;
                }
                return result;
            }
            return false;
        }
        return false;
    }

    /**
     * 铁军二维码透传
     */
    private void saveQrCodeEvent(IoTEvent ioTEvent) throws Exception {
        if(Func.isNotEmpty(ioTEvent) && Func.isNotEmpty(ioTEvent.getOut())){
            Map<String, Object> out = ioTEvent.getOut();
            String terminalNumber = out.get("terminalNumber").toString();
            String qrCode = out.get("qrCode").toString();
            //String devs = out.get("devs").toString();
            String eventTime = out.get("eventTime").toString();

            byte[] bytes = Base64.decode(qrCode);
            byte[] abc = EncryptUntil.decrypt(bytes);
            String pointSetId = new String(abc);
            PlDoorPoint point = null;
            if(Func.isNotEmpty(pointSetId)){
                //人员登记id
                PlDoorUserPointSet pointSet = plDoorUserPointSetService.getOne(new LambdaQueryWrapper<PlDoorUserPointSet>()
                        .eq(PlDoorUserPointSet::getId, pointSetId).last("limit 1"));
                if(Func.isNotEmpty(pointSet)){
                    if(Func.isNotEmpty(pointSet.getValidStartTime()) && Func.isNotEmpty(pointSet.getValidEndTime())){
                        if(DateUtils.timeOfStrToDate(eventTime).compareTo(pointSet.getValidStartTime())<0 || DateUtils.timeOfStrToDate(eventTime).compareTo(pointSet.getValidEndTime())>0){
                            log.error("====== 二维码透传时间不在人员登记有效时间范围内");
                            throw new RuntimeException("二维码有效时间不在人员登记有效时间范围内");
                        }
                    }
                    List<PlDoorUserPointSetItem> itemList = plDoorUserPointSetItemService.list(new LambdaQueryWrapper<PlDoorUserPointSetItem>().
                            eq(PlDoorUserPointSetItem::getUserPointSetId, pointSet.getId()));
                    if(Func.isNotEmpty(itemList)){
                        List<Long> pointIds = itemList.stream().map(PlDoorUserPointSetItem::getDoorPointId).collect(Collectors.toList());
                        List<PlDoorPoint> plDoorPointList = plDoorPointService.listByIds(pointIds);
                        if(Func.isNotEmpty(plDoorPointList)){
                            List<String> terminalNumbers = plDoorPointList.stream().map(PlDoorPoint::getTerminalNumber).collect(Collectors.toList());
                            if(Func.isNotEmpty(terminalNumbers) && terminalNumbers.contains(terminalNumber)){
                                point = plDoorPointService.getOne(new LambdaQueryWrapper<PlDoorPoint>()
                                        .eq(PlDoorPoint::getTerminalNumber, terminalNumber).last("limit 1"));
                                if(Func.isNotEmpty(point)){
                                    //远程开门
                                    plDoorUserPointSetService.doorOperation(Long.valueOf(pointSet.getUserId()), point.getId());
                                }
                            }
                        }
                    }

                    PlDoorInoutRecode plDoorInoutRecode = new PlDoorInoutRecode();
                    plDoorInoutRecode.setOpenDoorType("1");
                    plDoorInoutRecode.setUserId(Long.valueOf(pointSet.getUserId()));
                    plDoorInoutRecode.setUserName(pointSet.getUserName());
                    plDoorInoutRecode.setDoorPointId(point.getId());
                    plDoorInoutRecode.setParkId(point.getParkId());
                    plDoorInoutRecode.setBuildingId(point.getBuildingId());
                    plDoorInoutRecode.setElementId(point.getElementId());
                    //plDoorInoutRecode.setFloorId();
                    //plDoorInoutRecode.setRoomId();
                    plDoorInoutRecode.setInoutTime(DateUtils.parseDate("yyyy-MM-dd HH:mm:ss", eventTime));
                    plDoorInoutRecode.setTerminalNumber(terminalNumber);
                    plDoorInoutRecode.setDoorName(point.getDoorName());
                    plDoorInoutRecode.setDoorNo(point.getDeviceNo());
                    //plDoorInoutRecode.setCaptureFaceUrl();
                    save(plDoorInoutRecode);
                }
            }
        }
    }

    /**
     * 获取当年12个月份 yyyy-MM
     * @return
     */
    private List<String> getMonthsOfCurrentYear() {
        List<String> months = new ArrayList<>();
        LocalDate currentDate = LocalDate.now();
        int currentYear = currentDate.getYear();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
        for (int i = 1; i <= 12; i++) {
            LocalDate date = LocalDate.of(currentYear, i, 1);
            String formattedMonth = date.format(formatter);
            months.add(formattedMonth);
        }
        return months;
    }

    /**
     * 获取当月所有天 yyyy-MM-dd
     * @return
     */
    public List<String> getDaysOfCurrentMonth() {
        List<String> daysList = new ArrayList<>();
        LocalDate now = LocalDate.now();
        int year = now.getYear();
        int month = now.getMonthValue();
        // 获取当月的第一天
        LocalDate firstDayOfMonth = LocalDate.of(year, month, 1);
        // 获取当月的最后一天
        LocalDate lastDayOfMonth = firstDayOfMonth.withDayOfMonth(firstDayOfMonth.lengthOfMonth());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 循环添加从第一天到最后一天的日期
        while (!firstDayOfMonth.isAfter(lastDayOfMonth)) {
            daysList.add(firstDayOfMonth.format(formatter));
            firstDayOfMonth = firstDayOfMonth.plusDays(1);
        }
        return daysList;
    }

    /**
     * 获取近7天的日期集合
     * @return
     */
    public static List<String> getRecentSevenDaysFormatted() {
        List<String> recentSevenDaysFormatted = new ArrayList<>();
        LocalDate today = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        for (int i = 6; i >= 0; i--) {
            LocalDate date = today.minusDays(i);
            String formattedDate = date.format(formatter);
            recentSevenDaysFormatted.add(formattedDate);
        }
        return recentSevenDaysFormatted;
    }

}
