|
|
|
@ -1,13 +1,17 @@
|
|
|
|
|
package com.example.venue_reservation_service.service.impl;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
|
|
import com.alibaba.excel.EasyExcel;
|
|
|
|
|
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
|
|
import com.example.venue_reservation_service.domain.*;
|
|
|
|
|
import com.example.venue_reservation_service.dto.DelDTO;
|
|
|
|
|
import com.example.venue_reservation_service.dto.RAddDTO;
|
|
|
|
|
import com.example.venue_reservation_service.dto.ReservationDTO;
|
|
|
|
|
import com.example.venue_reservation_service.dto.SignInDTO;
|
|
|
|
|
import com.example.venue_reservation_service.mapper.*;
|
|
|
|
|
import com.example.venue_reservation_service.mq.DelayMessageSender;
|
|
|
|
|
import com.example.venue_reservation_service.service.*;
|
|
|
|
@ -15,6 +19,7 @@ import com.example.venue_reservation_service.utils.DateUtil;
|
|
|
|
|
import com.example.venue_reservation_service.utils.DownExcel;
|
|
|
|
|
import com.example.venue_reservation_service.utils.ScheduleUtil;
|
|
|
|
|
import com.example.venue_reservation_service.vo.*;
|
|
|
|
|
import com.example.venue_reservation_service.vo.excel.PaymentExportDTO;
|
|
|
|
|
import com.example.venue_reservation_service.vo.excel.ReservationExcel;
|
|
|
|
|
import jakarta.annotation.Resource;
|
|
|
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
|
|
@ -25,10 +30,12 @@ import org.springframework.stereotype.Service;
|
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.time.LocalDate;
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
|
import java.time.LocalTime;
|
|
|
|
|
import java.net.URLEncoder;
|
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
|
import java.time.*;
|
|
|
|
|
import java.time.temporal.ChronoUnit;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @author 31586
|
|
|
|
@ -189,6 +196,8 @@ public class ReservationServiceImpl extends ServiceImpl<ReservationMapper, Reser
|
|
|
|
|
// 设置预约开始和结束时间
|
|
|
|
|
reservation.setStartTime(start);
|
|
|
|
|
reservation.setEndTime(end);
|
|
|
|
|
reservation.setCreateTime(LocalDateTime.now());
|
|
|
|
|
reservation.setIsDelete(0);
|
|
|
|
|
// 保存预约信息
|
|
|
|
|
save(reservation);
|
|
|
|
|
|
|
|
|
@ -228,9 +237,11 @@ public class ReservationServiceImpl extends ServiceImpl<ReservationMapper, Reser
|
|
|
|
|
// 修改交易记录
|
|
|
|
|
Payment payment = paymentService.getById(reservation.getPayId());
|
|
|
|
|
payment.setSituation("过期");
|
|
|
|
|
paymentService.updateById(payment);
|
|
|
|
|
// 归还支付金额
|
|
|
|
|
balanceService.returnMoney(reservation.getUserId(), payment.getAmount());
|
|
|
|
|
payment.setAmount(0.0);
|
|
|
|
|
paymentService.updateById(payment);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -268,7 +279,7 @@ public class ReservationServiceImpl extends ServiceImpl<ReservationMapper, Reser
|
|
|
|
|
wrapper.eq(Reservation::getUserId, userId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wrapper.orderByDesc(Reservation::getReservationDate);
|
|
|
|
|
wrapper.eq(Reservation::getIsDelete, 0).orderByDesc(Reservation::getReservationDate).orderByDesc(Reservation::getCreateTime);
|
|
|
|
|
page = page(page, wrapper);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -345,18 +356,25 @@ public class ReservationServiceImpl extends ServiceImpl<ReservationMapper, Reser
|
|
|
|
|
paymentService.updateById(payment);
|
|
|
|
|
// 修改用户账户余额
|
|
|
|
|
balanceService.returnMoney(reservation.getUserId(), payment.getAmount());
|
|
|
|
|
|
|
|
|
|
return Result.ok().message("预约订单取消成功");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Result signInReservation(Integer reservationId) {
|
|
|
|
|
Reservation reservation = getById(reservationId);
|
|
|
|
|
public Result signInReservation(SignInDTO dto) {
|
|
|
|
|
Reservation reservation = getById(dto.getReservationId());
|
|
|
|
|
|
|
|
|
|
if (Optional.ofNullable(reservation).isEmpty()) {
|
|
|
|
|
return Result.fail().message("预约信息不存在");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!Objects.equals(reservation.getUserId(), dto.getUserId())){
|
|
|
|
|
return Result.fail().message("非本人订单");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!Objects.equals(reservation.getVenueId(), dto.getVenueId())) {
|
|
|
|
|
return Result.fail().message("非该场地二维码,请更换正确的");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (reservation.getAuditStatus() != 1) {
|
|
|
|
|
return Result.fail().message("预约信息不为待签到状态");
|
|
|
|
|
}
|
|
|
|
@ -413,16 +431,138 @@ public class ReservationServiceImpl extends ServiceImpl<ReservationMapper, Reser
|
|
|
|
|
return Result.ok(detail).message("ok");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Result exportData(String time) {
|
|
|
|
|
LocalDateTime startTime = null;
|
|
|
|
|
LocalDateTime endTime = LocalDateTime.now(); // 查询截止到当前时间
|
|
|
|
|
|
|
|
|
|
// 根据时间范围计算起始时间
|
|
|
|
|
switch (time) {
|
|
|
|
|
case "今年" -> startTime = LocalDateTime.of(LocalDateTime.now().getYear(), 1, 1, 0, 0, 0);
|
|
|
|
|
case "本月" -> {
|
|
|
|
|
YearMonth currentMonth = YearMonth.now();
|
|
|
|
|
startTime = LocalDateTime.of(currentMonth.getYear(), currentMonth.getMonthValue(), 1, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
case "近三月" -> startTime = LocalDateTime.now().minus(3, ChronoUnit.MONTHS);
|
|
|
|
|
}
|
|
|
|
|
// 构建查询条件
|
|
|
|
|
LambdaQueryWrapper<Reservation> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
if (startTime != null) {
|
|
|
|
|
queryWrapper.ge(Reservation::getCreateTime, startTime)
|
|
|
|
|
.le(Reservation::getCreateTime, endTime);
|
|
|
|
|
}
|
|
|
|
|
// 附加逻辑删除条件(Mybatis-plus默认会处理,但显式添加更清晰)
|
|
|
|
|
// queryWrapper.eq(Reservation::getIsDelete, 0);
|
|
|
|
|
|
|
|
|
|
return Result.ok(this.list(queryWrapper)).message("查询成功");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void exportExcel(HttpServletResponse response, Integer userId) {
|
|
|
|
|
ReservationMapper mapper = getBaseMapper();
|
|
|
|
|
try {
|
|
|
|
|
DownExcel.download(response, ReservationExcel.class, mapper.selectByUserId(userId));
|
|
|
|
|
DownExcel.download(response, ReservationExcel.class, mapper.selectByUserId(userId), "reservation");
|
|
|
|
|
} catch (IOException | IllegalAccessException | InstantiationException e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Result removeBatch(DelDTO dto) {
|
|
|
|
|
List<Integer> list = dto.getList();
|
|
|
|
|
if(Optional.ofNullable(list).isEmpty() || list.size() == 0){
|
|
|
|
|
return Result.fail().message("请选择需要清理的数据");
|
|
|
|
|
}
|
|
|
|
|
int notDeleted = 0;
|
|
|
|
|
for (Integer id : list) {
|
|
|
|
|
Reservation reservation = getById(id);
|
|
|
|
|
if(reservation.getAuditStatus() == 1 || !Objects.equals(reservation.getUserId(), dto.getUserId()) || (reservation.getAuditStatus() == 2 && LocalDateTime.now().toLocalTime().isBefore(reservation.getEndTime()))){
|
|
|
|
|
notDeleted++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
reservation.setIsDelete(1);
|
|
|
|
|
updateById(reservation);
|
|
|
|
|
}
|
|
|
|
|
return Result.ok().message(notDeleted == 0 ? "清理成功" : "移除订单中,存在不可删除订单,已为您自动过滤");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Result removeSingle(Integer userId, Integer id) {
|
|
|
|
|
Reservation reservation = getById(id);
|
|
|
|
|
if (Optional.ofNullable(reservation).isEmpty()) {
|
|
|
|
|
return Result.fail().message("订单信息不存在");
|
|
|
|
|
}
|
|
|
|
|
if (reservation.getAuditStatus() == 1) {
|
|
|
|
|
return Result.fail().message("订单处于待预约状态,不可删除");
|
|
|
|
|
}
|
|
|
|
|
if (reservation.getAuditStatus() == 2 && LocalDateTime.now().toLocalTime().isBefore(reservation.getEndTime())) {
|
|
|
|
|
return Result.fail().message("订单处于正在使用中状态,不可删除");
|
|
|
|
|
}
|
|
|
|
|
if (!Objects.equals(reservation.getUserId(), userId)) {
|
|
|
|
|
return Result.fail().message("非非本人订单");
|
|
|
|
|
}
|
|
|
|
|
reservation.setIsDelete(1);
|
|
|
|
|
updateById(reservation);
|
|
|
|
|
return Result.ok().message("订单删除成功");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void exportPayments(HttpServletResponse response, String yearFilter) {
|
|
|
|
|
try {
|
|
|
|
|
// 确定要查询的年份
|
|
|
|
|
Year targetYear = parseYearFilter(yearFilter);
|
|
|
|
|
|
|
|
|
|
// 获取该年份所有账单
|
|
|
|
|
List<Payment> payments = getPaymentsForYear(targetYear);
|
|
|
|
|
List<PaymentExportDTO> dtos = payments.stream()
|
|
|
|
|
.map(PaymentExportDTO::fromEntity)
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
|
|
|
|
// 设置响应头
|
|
|
|
|
String fileName = URLEncoder.encode(
|
|
|
|
|
String.format("交易账单_%s年数据", targetYear), StandardCharsets.UTF_8);
|
|
|
|
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
|
|
|
response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xlsx");
|
|
|
|
|
response.setCharacterEncoding("UTF-8");
|
|
|
|
|
|
|
|
|
|
// 导出Excel
|
|
|
|
|
EasyExcel.write(response.getOutputStream(), PaymentExportDTO.class)
|
|
|
|
|
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
|
|
|
|
.sheet("交易账单明细")
|
|
|
|
|
.doWrite(dtos);
|
|
|
|
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
throw new RuntimeException("导出账单失败", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 解析年份过滤参数
|
|
|
|
|
* @param yearFilter 年份参数(current-今年, last-去年)
|
|
|
|
|
* @return 要查询的目标年份
|
|
|
|
|
*/
|
|
|
|
|
private Year parseYearFilter(String yearFilter) {
|
|
|
|
|
if ("last".equalsIgnoreCase(yearFilter)) {
|
|
|
|
|
return Year.now().minusYears(1);
|
|
|
|
|
}
|
|
|
|
|
// 默认返回今年
|
|
|
|
|
return Year.now();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取指定年份的所有支付记录
|
|
|
|
|
* @param year 目标年份
|
|
|
|
|
* @return 该年份的支付记录列表
|
|
|
|
|
*/
|
|
|
|
|
private List<Payment> getPaymentsForYear(Year year) {
|
|
|
|
|
// 计算该年份的开始和结束时间
|
|
|
|
|
LocalDateTime startOfYear = LocalDate.of(year.getValue(), 1, 1).atStartOfDay();
|
|
|
|
|
LocalDateTime endOfYear = LocalDate.of(year.getValue(), 12, 31).atTime(23, 59, 59);
|
|
|
|
|
|
|
|
|
|
return paymentService.list(Wrappers.<Payment>lambdaQuery()
|
|
|
|
|
.in(Payment::getSituation, "预约花费", "账户余额充值")
|
|
|
|
|
.between(Payment::getTime, startOfYear, endOfYear));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|