Pu Zhibing
2025-01-22 c8cee43365a79b026502908b4aa361f08d59b42a
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TParkingRecordController.java
@@ -5,13 +5,15 @@
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.chargingPile.api.dto.GetSiteListDTO;
import com.ruoyi.chargingPile.api.feignClient.PartnerClient;
import com.ruoyi.chargingPile.api.feignClient.SiteClient;
import com.ruoyi.chargingPile.api.model.TParkingLot;
import com.ruoyi.chargingPile.api.model.TParkingRecord;
import com.ruoyi.chargingPile.api.query.ParkingRecordQuery;
import com.ruoyi.chargingPile.api.vo.GetParkingRecord;
import com.ruoyi.chargingPile.api.vo.TParkingRecordPageInfoVO;
import com.ruoyi.chargingPile.api.vo.TParkingRecordVO;
import com.ruoyi.chargingPile.api.vo.*;
import com.ruoyi.chargingPile.dto.ParkingRecordPageQuery;
import com.ruoyi.chargingPile.dto.ParkingRecordQueryDto;
import com.ruoyi.chargingPile.export.TParkingRecordExport;
import com.ruoyi.chargingPile.service.TParkingLotService;
import com.ruoyi.chargingPile.service.TParkingRecordService;
@@ -22,8 +24,15 @@
import com.ruoyi.common.core.web.page.PageInfo;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.log.enums.OperatorType;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.common.security.annotation.Logical;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.order.api.query.TOrderInvoiceQuery;
import com.ruoyi.order.api.vo.TCharingUserEquimentVO;
import com.ruoyi.order.api.vo.TOrderInvoiceVO;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.feignClient.SysUserClient;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
@@ -33,9 +42,16 @@
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * <p>
@@ -52,31 +68,100 @@
    private TParkingRecordService parkingRecordService;
    @Resource
    private TParkingLotService parkingLotService;
    @Resource
    private SiteClient siteClient;
    @Resource
    private TokenService tokenService;
    @Resource
    private PartnerClient partnerClient;
    @Resource
    private SysUserClient sysUserClient;
    @RequiresPermissions(value = {"/parkingRecord"}, logical = Logical.OR)
    @ApiOperation(tags = {"后台-订单管理-停车记录"},value = "列表")
    @PostMapping(value = "/page")
    public R<Page<TParkingRecord>> page(@RequestBody ParkingRecordPageQuery query) {
        Page<TParkingRecord> page = parkingRecordService.lambdaQuery().ge(query.getStart() != null, TParkingRecord::getCreateTime, query.getStart())
                .le(query.getEnd() != null, TParkingRecord::getCreateTime, query.getEnd())
        Long userid = tokenService.getLoginUser().getUserid();
        SysUser sysUser = sysUserClient.getSysUser(tokenService.getLoginUser().getUserid()).getData();
        Integer roleType = sysUser.getRoleType();
        List<Integer> siteIds = new ArrayList<>();
        List<GetSiteListDTO> data = siteClient.getSiteListByUserId(userid).getData();
        for (GetSiteListDTO datum : data) {
            siteIds.add(datum.getId());
        }
        if (siteIds.isEmpty()){
            siteIds.add(-1);
        }else{
            if (roleType == 2){
                List<Integer> integers = new ArrayList<>();
                for (Integer siteId : siteIds) {
                    // 校验有没有这个站点的权限
                    List<Boolean> t1= partnerClient.parkingRecordListMenu(sysUser.getObjectId(),siteId).getData();
                    Boolean b = t1.get(1);
                    if (b){
                        integers.add(siteId);
                    }
                }
                siteIds = integers;
            }
        }
        if (siteIds.isEmpty()){
            siteIds.add(-1);
        }
        List<TParkingLot> list = parkingLotService.lambdaQuery().in( TParkingLot::getSiteId, siteIds).list();
        List<Integer> ids = new ArrayList<>();
        for (TParkingLot tParkingLot : list) {
            ids.add(tParkingLot.getId());
        }
        String s1 = "";
        String s2 = "";
        if (query.getTimePeriod()!=null){
             s1 = query.getTimePeriod().split(" - ")[0];
             s2 = query.getTimePeriod().split(" - ")[1];
        }
        Page<TParkingRecord> page = parkingRecordService.lambdaQuery()
                .in(null != ids && ids.size() > 0, TParkingRecord::getParkingLotId,ids)
                .like(query.getLicensePlate() != null, TParkingRecord::getLicensePlate, query.getLicensePlate())
                .eq(query.getStatus() != null, TParkingRecord::getStatus, query.getStatus())
                .eq(query.getOutParkingType() != null, TParkingRecord::getOutParkingType, query.getOutParkingType())
                .between(query.getTimePeriod()!=null,TParkingRecord::getInParkingTime,s1,s2)
                .or()
                .between(query.getTimePeriod()!=null,TParkingRecord::getOutParkingTime,s1,s2)
                .orderByDesc(TParkingRecord::getCreateTime)
                .page(Page.of(query.getPageCurr(), query.getPageSize()));
        for (TParkingRecord record : page.getRecords()) {
            record.setName(parkingLotService.getById(record.getParkingLotId()).getName());
            TParkingLot byId = parkingLotService.getById(record.getParkingLotId());
            record.setUid(record.getId().toString());
            if (byId!=null) {
                record.setParkName(byId.getName());
                if (roleType==2){
                    List<Boolean> data1 = partnerClient.parkingRecordListMenu(sysUser.getObjectId(), byId.getSiteId()).getData();
                    record.setAuthInfo(data1.get(0));
                    record.setAuthOut(data1.get(1));
                }
            }
        }
        return R.ok(page);
    }
    @RequiresPermissions(value = {"/parkingPaymentOrder"}, logical = Logical.OR)
    @ApiOperation(tags = {"后台-订单管理-停车记录"},value = "停车缴费订单列表")
    @PostMapping(value = "/pageList")
    public R<TParkingRecordPageInfoVO> pageList(@RequestBody ParkingRecordQuery query) {
        return R.ok(parkingRecordService.pageList(query));
    }
    @RequiresPermissions(value = {"/parkingPaymentOrder/export"}, logical = Logical.OR)
    @ApiOperation(tags = {"后台-订单管理-停车记录"},value = "导出")
    @PutMapping("/export")
    @Log(title = "【停车记录】导出停车记录", businessType = BusinessType.EXPORT,operatorType = OperatorType.MANAGE)
    public void export(@RequestBody ParkingRecordQuery query)
    {
        List<TParkingRecordVO> records = parkingRecordService.pageList(query).getParkingRecordVOS().getRecords();
@@ -119,17 +204,25 @@
            }
        }
    }
    @ApiOperation(tags = {"后台-订单管理-停车记录"},value = "详情")
    @GetMapping(value = "/detail")
    public R<TParkingRecord> detail(Long id) {
      return R.ok(parkingRecordService.getById(id));
    }
    @RequiresPermissions(value = {"/parkingRecord/already_appeared"}, logical = Logical.OR)
    @ApiOperation(tags = {"后台-订单管理-停车记录"},value = "出场")
    @GetMapping(value = "/out")
    @Log(title = "【停车记录】修改出场状态", businessType = BusinessType.UPDATE,operatorType = OperatorType.MANAGE)
    public R out(Long id) {
        TParkingRecord byId = parkingRecordService.getById(id);
        byId.setStatus(2);
        byId.setOutParkingTime(LocalDateTime.now());
        parkingRecordService.updateById(byId);
        return R.ok();
@@ -179,5 +272,206 @@
    public void addParkingRecord(@RequestBody TParkingRecord parkingRecord){
        parkingRecordService.save(parkingRecord);
    }
    @RequiresPermissions(value = {"/parkingOperationAnalysis"}, logical = Logical.OR)
    @ResponseBody
    @PostMapping(value = "/parking/data")
    @ApiOperation(value = "统计", tags = {"管理后台-数据分析-车场运营分析"})
    public R<TParkLotRecordVO> data(@RequestBody ParkingRecordQueryDto parkingRecordQueryDto){
        //上方折线图
        TParkLotRecordVO tParkLotRecordVO = new TParkLotRecordVO();
        // 查询当前登陆人按钮权限
        SysUser sysUser = sysUserClient.getSysUser(tokenService.getLoginUser().getUserid()).getData();
        Integer roleType = sysUser.getRoleType();
        Long userId = tokenService.getLoginUser().getUserid();
        //如果没传siteId,获取当前登陆人所有的siteIds
        List<Integer> siteIds = new ArrayList<>();
        if (userId != null){
            List<GetSiteListDTO> data2 = siteClient.getSiteListByUserId(userId).getData();
            for (GetSiteListDTO datum : data2) {
                siteIds.add(datum.getId());
            }
        }
        if (siteIds.isEmpty()){
            siteIds.add(-1);
        }
        parkingRecordQueryDto.setSiteIds(siteIds);
        if (parkingRecordQueryDto.getDayType()==1) {
            List<Map<String, Object>> maps = parkingRecordService.parkingData(parkingRecordQueryDto);
            List<Map<String, Object>> charMap = new ArrayList<>();
            // 生成从 "00:00" 到 "23:00" 的时间数据-------
            for (int hour = 0; hour < 24; hour++) {
                String time = String.format("%02d:00", hour);
                Map<String, Object> mapWithTimeValue = findMapWithTimeValue(maps, time);
                if (mapWithTimeValue!=null){
                    charMap.add(mapWithTimeValue);
                }else {
                    Map<String, Object> timeMap = new HashMap<>();
                    timeMap.put("time", time); // 初始化值为 null
                    timeMap.put("orders", 0);
                    timeMap.put("timeoutAmount", 0);
                    charMap.add(timeMap);
                }
            }
            tParkLotRecordVO.setMaps(charMap);
        }else {
            List<Map<String, Object>> maps = parkingRecordService.parkingDataByDate(parkingRecordQueryDto);
            if(parkingRecordQueryDto.getDayType()==2||parkingRecordQueryDto.getDayType()==3){
                //按日
                // 解析 startTime 和 endTime 为 LocalDate
                LocalDate startDate = parkingRecordQueryDto.getStartTime();
                LocalDate endDate = parkingRecordQueryDto.getEndTime();
                List<Map<String, Object>> dateRangeStatistics = new ArrayList<>();
                // 遍历日期范围
                while (!startDate.isAfter(endDate)) {
                    String formattedDate = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    Map<String, Object> dailyStats = findMapWithDateValue(maps, formattedDate);
                    if (dailyStats != null) {
                        dateRangeStatistics.add(dailyStats);
                    } else {
                        Map<String, Object> dateMap = new HashMap<>();
                        dateMap.put("time", formattedDate);
                        dateMap.put("electrovalence", 0);
                        dateMap.put("orderCount", 0);
                        dateMap.put("servicecharge", 0);
                        dateMap.put("electricity", 0);
                        dateRangeStatistics.add(dateMap);
                    }
                    // 移动到下一天
                    startDate = startDate.plusDays(1);
                }
                tParkLotRecordVO.setMaps(dateRangeStatistics);
            }else {
            }
            tParkLotRecordVO.setMaps(maps);
        }
        //车辆类型饼图
        List<Map<String, Object>> carColor  =   parkingRecordService.getCarColor(parkingRecordQueryDto);
        //出场类型
        List<Map<String, Object>> outType  =   parkingRecordService.getOutType(parkingRecordQueryDto);
        //进场充电占比
        List<Map<String, Object>> isCharge  =   parkingRecordService.getIsCharge(parkingRecordQueryDto);
        tParkLotRecordVO.setCarColor(carColor);
        tParkLotRecordVO.setOutType(outType);
        tParkLotRecordVO.setIsCharge(isCharge);
        return R.ok(tParkLotRecordVO);
    }
    private static Map<String, Object> findMapWithTimeValue(List<Map<String, Object>> charMap1,String timeValue) {
        for (Map<String, Object> map : charMap1) {
            if (map.containsKey("time") && map.get("time").equals(timeValue)) {
                return map;
            }
        }
        return null; // 如果没有找到,返回 null
    }
    private Map<String, Object> findMapWithDateValue(List<Map<String, Object>> list, String date) {
        for (Map<String, Object> map : list) {
            if (date.equals(map.get("time"))) {
                return map;
            }
        }
        return null;
    }
    @RequiresPermissions(value = {"/workbench"}, logical = Logical.OR)
    @ResponseBody
    @PostMapping(value = "/parking/work")
    @ApiOperation(value = "停车订单统计", tags = {"管理后台-工作台"})
    public R<TParkLotRecordCountVo> work(@RequestBody ParkingRecordQueryDto parkingRecordQueryDto){
        List<TParkingRecord> list = parkingRecordService.lambdaQuery().isNotNull(TParkingRecord::getOutParkingType).eq(parkingRecordQueryDto.getParkingLotId() != null, TParkingRecord::getParkingLotId, parkingRecordQueryDto.getParkingLotId())
                .ge(parkingRecordQueryDto.getStartTime()!=null,TParkingRecord::getCreateTime, parkingRecordQueryDto.getStartTime())
                .le(parkingRecordQueryDto.getEndTime()!=null,TParkingRecord::getCreateTime, parkingRecordQueryDto.getEndTime().plusDays(1)).list();
        int count1 = list.size();
        //统计出list中chargingOrderId为null的数据个数
        int count2 = list.stream().filter(item -> item.getChargingOrderId() != null).collect(Collectors.toList()).size();
        int count3 = list.stream().filter(item -> item.getOutParkingType() == 2).collect(Collectors.toList()).size();
        //计算出list中parkingDuration的总和
        int count4 = 0;
        for (TParkingRecord tParkingRecord : list) {
            count4 = count4+tParkingRecord.getParkingDuration();
        }
        //计算出list中orderAmount的总和
        BigDecimal count5 = list.stream().map(TParkingRecord::getOrderAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        TParkLotRecordCountVo tParkLotRecordCountVo = new TParkLotRecordCountVo();
        tParkLotRecordCountVo.setCount1(count1);
        tParkLotRecordCountVo.setCount2(count2);
        tParkLotRecordCountVo.setCount3(count3);
        tParkLotRecordCountVo.setCount4(count4);
        tParkLotRecordCountVo.setCount5(count5);
        return R.ok(tParkLotRecordCountVo);
    }
    @RequiresPermissions(value = {"/workbench"}, logical = Logical.OR)
    @ResponseBody
    @PostMapping(value = "/parking/work1")
    @ApiOperation(value = "停车订单统计", tags = {"管理后台-工作台"})
    public R<TParkLotRecordCountVo> work1(@RequestBody ParkingRecordQueryDto parkingRecordQueryDto){
        List<TParkingRecord> list = parkingRecordService.lambdaQuery().isNotNull(TParkingRecord::getOutParkingType).eq(parkingRecordQueryDto.getParkingLotId() != null, TParkingRecord::getParkingLotId, parkingRecordQueryDto.getParkingLotId()).list();
        int count1 = list.size();
        //统计出list中chargingOrderId为null的数据个数
        int count2 = list.stream().filter(item -> item.getChargingOrderId() != null).collect(Collectors.toList()).size();
        int count3 = list.stream().filter(item -> item.getOutParkingType() == 2).collect(Collectors.toList()).size();
        //计算出list中parkingDuration的总和
        int count4 = 0;
        for (TParkingRecord tParkingRecord : list) {
            count4 = count4+tParkingRecord.getParkingDuration();
        }
        //计算出list中orderAmount的总和
        BigDecimal count5 = list.stream().map(TParkingRecord::getOrderAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        TParkLotRecordCountVo tParkLotRecordCountVo = new TParkLotRecordCountVo();
        tParkLotRecordCountVo.setCount1(count1);
        tParkLotRecordCountVo.setCount2(count2);
        tParkLotRecordCountVo.setCount3(count3);
        tParkLotRecordCountVo.setCount4(count4);
        tParkLotRecordCountVo.setCount5(count5);
        return R.ok(tParkLotRecordCountVo);
    }
    @RequiresPermissions(value = {"/workbench"}, logical = Logical.OR)
    @ResponseBody
    @PostMapping(value = "/parking/income")
    @ApiOperation(value = "停车收入统计", tags = {"管理后台-工作台"})
    public R income(@RequestBody ParkingRecordQueryDto parkingRecordQueryDto){
       List<Map<String,Object>>  maps =  parkingRecordService.income(parkingRecordQueryDto);
        return R.ok(maps);
    }
}