feat: 实现管理员使用人统计数据计算及导出
This commit is contained in:
parent
b350e933d3
commit
e7fbef58a1
@ -23,6 +23,7 @@ public class CorsConfig {
|
|||||||
config.addAllowedHeader("*");
|
config.addAllowedHeader("*");
|
||||||
config.addAllowedMethod("*");
|
config.addAllowedMethod("*");
|
||||||
config.setMaxAge(3600L);
|
config.setMaxAge(3600L);
|
||||||
|
config.addExposedHeader("Content-Disposition");
|
||||||
|
|
||||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
source.registerCorsConfiguration("/**", config);
|
source.registerCorsConfiguration("/**", config);
|
||||||
|
@ -1,15 +1,28 @@
|
|||||||
package github.benjamin.equipreservebackend.controller;
|
package github.benjamin.equipreservebackend.controller;
|
||||||
|
|
||||||
|
import com.alibaba.excel.EasyExcel;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import github.benjamin.equipreservebackend.constant.ReservationStatus;
|
||||||
import github.benjamin.equipreservebackend.entity.Reservation;
|
import github.benjamin.equipreservebackend.entity.Reservation;
|
||||||
import github.benjamin.equipreservebackend.response.ResponseResult;
|
import github.benjamin.equipreservebackend.response.ResponseResult;
|
||||||
import github.benjamin.equipreservebackend.service.ReservationService;
|
import github.benjamin.equipreservebackend.service.ReservationService;
|
||||||
|
import github.benjamin.equipreservebackend.vo.DeviceStatsVO;
|
||||||
|
import github.benjamin.equipreservebackend.vo.ReservationStatsVO;
|
||||||
import github.benjamin.equipreservebackend.vo.ReservationVO;
|
import github.benjamin.equipreservebackend.vo.ReservationVO;
|
||||||
import github.benjamin.equipreservebackend.vo.UserReservationVO;
|
import github.benjamin.equipreservebackend.vo.UserReservationVO;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/reservation")
|
@RequestMapping("/reservation")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@ -42,4 +55,32 @@ public class ReservationController {
|
|||||||
return ResponseResult.success(reservationService.getReservationVO(id, page, size));
|
return ResponseResult.success(reservationService.getReservationVO(id, page, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
|
@GetMapping("/stats")
|
||||||
|
public ResponseResult<List<ReservationStatsVO>> getReservationStats(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate start,
|
||||||
|
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {
|
||||||
|
return ResponseResult.success(reservationService.getReservationStats(start, end));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
|
@GetMapping("/stats/export")
|
||||||
|
public void exportReservationStats(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate start,
|
||||||
|
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
|
||||||
|
String fileName = String.format("使用人统计_%s-%s.xlsx", start.format(DateTimeFormatter.ISO_DATE), end.format(DateTimeFormatter.ISO_DATE));
|
||||||
|
String encodedName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename=" + encodedName);
|
||||||
|
|
||||||
|
// 查询数据
|
||||||
|
List<ReservationStatsVO> data = reservationService.getReservationStats(start, end);
|
||||||
|
|
||||||
|
// 使用EasyExcel写入response流
|
||||||
|
EasyExcel.write(response.getOutputStream(), ReservationStatsVO.class)
|
||||||
|
.sheet("使用人统计")
|
||||||
|
.doWrite(data);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,13 @@ package github.benjamin.equipreservebackend.mapper;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import github.benjamin.equipreservebackend.entity.Reservation;
|
import github.benjamin.equipreservebackend.entity.Reservation;
|
||||||
|
import github.benjamin.equipreservebackend.vo.ReservationStatsVO;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface ReservationMapper extends BaseMapper<Reservation> {
|
public interface ReservationMapper extends BaseMapper<Reservation> {
|
||||||
|
List<ReservationStatsVO> getReservationStats(LocalDate start, LocalDate end);
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,12 @@ package github.benjamin.equipreservebackend.service;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import github.benjamin.equipreservebackend.entity.Reservation;
|
import github.benjamin.equipreservebackend.entity.Reservation;
|
||||||
|
import github.benjamin.equipreservebackend.vo.ReservationStatsVO;
|
||||||
import github.benjamin.equipreservebackend.vo.ReservationVO;
|
import github.benjamin.equipreservebackend.vo.ReservationVO;
|
||||||
import github.benjamin.equipreservebackend.vo.TimeRangeVO;
|
import github.benjamin.equipreservebackend.vo.TimeRangeVO;
|
||||||
import github.benjamin.equipreservebackend.vo.UserReservationVO;
|
import github.benjamin.equipreservebackend.vo.UserReservationVO;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface ReservationService {
|
public interface ReservationService {
|
||||||
@ -19,4 +21,6 @@ public interface ReservationService {
|
|||||||
List<TimeRangeVO> getUnavailableTimes(Long id);
|
List<TimeRangeVO> getUnavailableTimes(Long id);
|
||||||
|
|
||||||
Page<ReservationVO> getReservationVO(Long userId, Integer page, Integer size);
|
Page<ReservationVO> getReservationVO(Long userId, Integer page, Integer size);
|
||||||
|
|
||||||
|
List<ReservationStatsVO> getReservationStats(LocalDate start, LocalDate end);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import github.benjamin.equipreservebackend.exception.ApiException;
|
|||||||
import github.benjamin.equipreservebackend.mapper.*;
|
import github.benjamin.equipreservebackend.mapper.*;
|
||||||
import github.benjamin.equipreservebackend.service.ReservationService;
|
import github.benjamin.equipreservebackend.service.ReservationService;
|
||||||
import github.benjamin.equipreservebackend.utils.PageUtil;
|
import github.benjamin.equipreservebackend.utils.PageUtil;
|
||||||
|
import github.benjamin.equipreservebackend.vo.ReservationStatsVO;
|
||||||
import github.benjamin.equipreservebackend.vo.ReservationVO;
|
import github.benjamin.equipreservebackend.vo.ReservationVO;
|
||||||
import github.benjamin.equipreservebackend.vo.TimeRangeVO;
|
import github.benjamin.equipreservebackend.vo.TimeRangeVO;
|
||||||
import github.benjamin.equipreservebackend.vo.UserReservationVO;
|
import github.benjamin.equipreservebackend.vo.UserReservationVO;
|
||||||
@ -146,4 +147,9 @@ public class ReservationServiceImpl implements ReservationService {
|
|||||||
.toList());
|
.toList());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ReservationStatsVO> getReservationStats(LocalDate start, LocalDate end) {
|
||||||
|
return reservationMapper.getReservationStats(start, end);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
package github.benjamin.equipreservebackend.vo;
|
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelIgnore;
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ReservationStatsVO {
|
||||||
|
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@ExcelIgnore
|
||||||
|
private Long deviceId;
|
||||||
|
|
||||||
|
@ExcelProperty("设备名称")
|
||||||
|
@ColumnWidth(15)
|
||||||
|
private String deviceName;
|
||||||
|
|
||||||
|
@ExcelProperty("使用人")
|
||||||
|
@ColumnWidth(15)
|
||||||
|
private String applicantName;
|
||||||
|
|
||||||
|
@ExcelProperty("所属团队")
|
||||||
|
@ColumnWidth(15)
|
||||||
|
private String applicantTeam;
|
||||||
|
|
||||||
|
@ExcelProperty("使用次数")
|
||||||
|
@ColumnWidth(15)
|
||||||
|
private Integer usageCount;
|
||||||
|
|
||||||
|
}
|
28
src/main/resources/mapper/ReservationMapper.xml
Normal file
28
src/main/resources/mapper/ReservationMapper.xml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
|
<mapper namespace="github.benjamin.equipreservebackend.mapper.ReservationMapper">
|
||||||
|
|
||||||
|
<select id="getReservationStats" resultType="github.benjamin.equipreservebackend.vo.ReservationStatsVO">
|
||||||
|
SELECT
|
||||||
|
r.device_id,
|
||||||
|
d.name AS deviceName,
|
||||||
|
r.applicant_name,
|
||||||
|
r.applicant_team,
|
||||||
|
COUNT(*) AS usageCount
|
||||||
|
FROM
|
||||||
|
reservations r
|
||||||
|
JOIN
|
||||||
|
devices d ON r.device_id = d.id
|
||||||
|
WHERE
|
||||||
|
r.status IN ('APPROVED', 'APPROVED_ASSIST')
|
||||||
|
AND r.start_time >= #{start}
|
||||||
|
AND r.end_time <= #{end}
|
||||||
|
GROUP BY
|
||||||
|
r.device_id, r.applicant_name, r.applicant_team, d.name
|
||||||
|
ORDER BY
|
||||||
|
d.name, r.applicant_name;
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
Loading…
x
Reference in New Issue
Block a user