更新了商品管理模块
This commit is contained in:
parent
a451cc632e
commit
2cda8e26c6
pom.xml
src
main
java/com/cultural/heritage
config
controller
book
good
wx
mapper
model
dto
appointment/single
book
good/service
timeinterval
timeperiod
entity
vo
service
utils
resources
test/java/com/cultural/heritage/test
6
pom.xml
6
pom.xml
|
@ -177,6 +177,12 @@
|
||||||
<version>5.2.0</version>
|
<version>5.2.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 微信支付-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.wechatpay-apiv3</groupId>
|
||||||
|
<artifactId>wechatpay-java</artifactId>
|
||||||
|
<version>0.2.10</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
78
src/main/java/com/cultural/heritage/config/WxPayConfig.java
Normal file
78
src/main/java/com/cultural/heritage/config/WxPayConfig.java
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
package com.cultural.heritage.config;
|
||||||
|
|
||||||
|
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
|
||||||
|
import com.wechat.pay.java.core.util.IOUtil;
|
||||||
|
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
|
||||||
|
import com.wechat.pay.java.service.refund.RefundService;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Slf4j
|
||||||
|
@Configuration
|
||||||
|
@Component("WxPayConfig")
|
||||||
|
@ConfigurationProperties(prefix = "wx.pay")
|
||||||
|
public class WxPayConfig {
|
||||||
|
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
private String apiV3Key;
|
||||||
|
|
||||||
|
private String notifyUrl;
|
||||||
|
|
||||||
|
private String merchantId;
|
||||||
|
|
||||||
|
private String privateKeyPath;
|
||||||
|
|
||||||
|
private String merchantSerialNumber;
|
||||||
|
|
||||||
|
// RSA配置
|
||||||
|
private RSAAutoCertificateConfig RSAConfig;
|
||||||
|
|
||||||
|
// JSAPI支付
|
||||||
|
private JsapiServiceExtension jsapiServiceExtension;
|
||||||
|
|
||||||
|
// 退款
|
||||||
|
private RefundService refundService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化配置
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public boolean initWxPayConfig() throws IOException {
|
||||||
|
this.RSAConfig = buildRSAAutoCertificateConfig();
|
||||||
|
this.jsapiServiceExtension = buildJsapiServiceExtension(RSAConfig);
|
||||||
|
this.refundService = buildRefundService(RSAConfig);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建并使用自动更新平台证书的RSA配置,一个商户号只能初始化一个配置,否则会因为重复的下载任务报错
|
||||||
|
private RSAAutoCertificateConfig buildRSAAutoCertificateConfig() throws IOException {
|
||||||
|
// 将 resource 目录下的文件转为 InputStream,然后利用 IOUtil.toString(inputStream) 转化为密钥
|
||||||
|
String privateKey = IOUtil.toString(new ClassPathResource(privateKeyPath).getInputStream());
|
||||||
|
return new RSAAutoCertificateConfig.Builder()
|
||||||
|
.merchantId(merchantId)
|
||||||
|
.privateKey(privateKey)
|
||||||
|
.merchantSerialNumber(merchantSerialNumber)
|
||||||
|
.apiV3Key(apiV3Key)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建JSAPI支付
|
||||||
|
private JsapiServiceExtension buildJsapiServiceExtension(RSAAutoCertificateConfig config) {
|
||||||
|
return new JsapiServiceExtension.Builder().config(config).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建退款
|
||||||
|
private RefundService buildRefundService(RSAAutoCertificateConfig config) {
|
||||||
|
return new RefundService.Builder().config(config).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
package com.cultural.heritage.controller.book;
|
package com.cultural.heritage.controller.book;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateTime;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.cultural.heritage.annotation.AuthCheck;
|
import com.cultural.heritage.annotation.AuthCheck;
|
||||||
import com.cultural.heritage.common.BaseResponse;
|
import com.cultural.heritage.common.BaseResponse;
|
||||||
|
@ -11,27 +13,35 @@ import com.cultural.heritage.constant.UserConstant;
|
||||||
import com.cultural.heritage.exception.BusinessException;
|
import com.cultural.heritage.exception.BusinessException;
|
||||||
import com.cultural.heritage.exception.ThrowUtils;
|
import com.cultural.heritage.exception.ThrowUtils;
|
||||||
import com.cultural.heritage.model.dto.CommonStringRequest;
|
import com.cultural.heritage.model.dto.CommonStringRequest;
|
||||||
import com.cultural.heritage.model.dto.book.BookingDateUpdateRequest;
|
import com.cultural.heritage.model.dto.book.BookingDateAddRequest;
|
||||||
|
import com.cultural.heritage.model.dto.timeinterval.TimeIntervalAddRequest;
|
||||||
import com.cultural.heritage.model.entity.BookingDate;
|
import com.cultural.heritage.model.entity.BookingDate;
|
||||||
|
import com.cultural.heritage.model.entity.TimeInterval;
|
||||||
import com.cultural.heritage.model.vo.book.BookingDateVO;
|
import com.cultural.heritage.model.vo.book.BookingDateVO;
|
||||||
|
import com.cultural.heritage.model.vo.timeinterval.TimeIntervalVO;
|
||||||
import com.cultural.heritage.service.book.BookingDateService;
|
import com.cultural.heritage.service.book.BookingDateService;
|
||||||
|
import com.cultural.heritage.service.book.TimeIntervalService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/book")
|
@RequestMapping("/book")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Tag(name = "预约日期管理模块")
|
@Tag(name = "写真预约日期管理模块")
|
||||||
public class BookingDateController {
|
public class BookingDateController {
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,75 +49,130 @@ public class BookingDateController {
|
||||||
private BookingDateService bookingDateService;
|
private BookingDateService bookingDateService;
|
||||||
|
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TimeIntervalService timeIntervalService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (写真预约)初始化未来一天的预约日期
|
* Web端管理员添加写真预约日期和时间段
|
||||||
|
* @param bookingDateAddRequestList 预约日期列表
|
||||||
|
* @return 是否添加成功
|
||||||
*/
|
*/
|
||||||
// @Scheduled(cron = "*/5 * * * * ?")
|
@PostMapping("/add")
|
||||||
// 每天00:00-00:00调用
|
@Operation(summary = "Web端管理员添加写真预约日期和时间段", description = "参数:预约日期列表,权限:管理员(admin, boss),方法名:addBookingDate")
|
||||||
@Scheduled(cron = "0 0 0 * * ?")
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@PostMapping("/init")
|
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||||
@Operation(summary = "(自动调用)初始化未来一天的预约日期", description = "参数:无,权限:自动调用,方法名:initCurrentBookingDate")
|
public BaseResponse<Boolean> addBookingDate(@RequestBody List<BookingDateAddRequest> bookingDateAddRequestList) {
|
||||||
public void initCurrentBookingDate() {
|
if (bookingDateAddRequestList == null) {
|
||||||
// 初始化预约日期
|
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||||
List<BookingDate> bookingDateList = new ArrayList<>();
|
}
|
||||||
BookingDate bookingDateRent = bookingDateService.initBookingDate(BookConstant.RENT_CLOTHES, 3);
|
// 添加写真预约日期
|
||||||
BookingDate bookingDateOwn = bookingDateService.initBookingDate(BookConstant.OWN_CLOTHES, 3);
|
List<BookingDate> bookingDateList = bookingDateAddRequestList.stream().map(bookingDateAddRequest -> {
|
||||||
bookingDateList.add(bookingDateRent);
|
BookingDate bookingDate = new BookingDate();
|
||||||
bookingDateList.add(bookingDateOwn);
|
BeanUtils.copyProperties(bookingDateAddRequest, bookingDate);
|
||||||
|
bookingDateService.validBookingDate(bookingDate, false);
|
||||||
|
return bookingDate;
|
||||||
|
}).toList();
|
||||||
boolean result = bookingDateService.saveBatch(bookingDateList);
|
boolean result = bookingDateService.saveBatch(bookingDateList);
|
||||||
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
|
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
|
||||||
|
|
||||||
|
// 添加写真预约时间段
|
||||||
|
List<TimeInterval> timeIntervals = new ArrayList<>();
|
||||||
|
for (int i = 0; i < bookingDateAddRequestList.size(); i++) {
|
||||||
|
BookingDate bookingDate = bookingDateList.get(i);
|
||||||
|
Long dateId = bookingDate.getId();
|
||||||
|
BookingDateAddRequest bookingDateAddRequest = bookingDateAddRequestList.get(i);
|
||||||
|
List<TimeIntervalAddRequest> timeIntervalAddRequestList = bookingDateAddRequest.getTimeIntervalAddRequestList();
|
||||||
|
List<TimeInterval> timeIntervalList = timeIntervalAddRequestList.stream().map(timeIntervalAddRequest -> {
|
||||||
|
TimeInterval timeInterval = new TimeInterval();
|
||||||
|
BeanUtils.copyProperties(timeIntervalAddRequest, timeInterval);
|
||||||
|
timeInterval.setBookingDateId(dateId);
|
||||||
|
timeIntervalService.validTimeInterval(timeInterval, false);
|
||||||
|
return timeInterval;
|
||||||
|
}).toList();
|
||||||
|
timeIntervals.addAll(timeIntervalList);
|
||||||
|
}
|
||||||
|
boolean success = timeIntervalService.saveBatch(timeIntervals);
|
||||||
|
ThrowUtils.throwIf(!success, ErrorCode.OPERATION_ERROR);
|
||||||
|
return ResultUtils.success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据预约类别查询未来四天(包括今天)的预约日期
|
* Web端管理员根据预约类型查询预约时间表
|
||||||
* @param commonStringRequest 预约类型
|
* @param commonStringRequest 预约类型
|
||||||
* @return 当前预约类型未来四天的预约日期列表
|
* @return 预约时间表
|
||||||
*/
|
*/
|
||||||
@PostMapping("/list")
|
@PostMapping("/list/type")
|
||||||
@Operation(summary = "(小程序端)根据预约类别查询未来四天(包括今天)的预约日期", description = "参数:预约类型, 权限:所有人,方法名:listBookingDateByType")
|
@Operation(summary = "Web端管理员根据预约类型查询预约时间表", description = "参数:预约类型,权限:管理员(admin, boss),方法名:listBookingDateByType")
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||||
public BaseResponse<List<BookingDateVO>> listBookingDateByType(@RequestBody CommonStringRequest commonStringRequest) {
|
public BaseResponse<List<BookingDateVO>> listBookingDateByType(@RequestBody CommonStringRequest commonStringRequest) {
|
||||||
if (commonStringRequest == null || StringUtils.isBlank(commonStringRequest.getType())) {
|
if (commonStringRequest == null || StringUtils.isBlank(commonStringRequest.getType())) {
|
||||||
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||||
}
|
}
|
||||||
String type = commonStringRequest.getType();
|
String type = commonStringRequest.getType();
|
||||||
|
if (!type.equals(BookConstant.RENT_CLOTHES) && !type.equals(BookConstant.OWN_CLOTHES)) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "类型参数错误");
|
||||||
|
}
|
||||||
QueryWrapper<BookingDate> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<BookingDate> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq("type", type);
|
queryWrapper.eq("type", type);
|
||||||
List<BookingDate> bookingDateList = bookingDateService.list(queryWrapper);
|
List<BookingDate> bookingDateList = bookingDateService.list(queryWrapper);
|
||||||
// 封装预约日期VO
|
List<TimeInterval> timeIntervalList = timeIntervalService.list();
|
||||||
List<BookingDateVO> bookingDateVOS = bookingDateList.stream().map(bookingDate -> {
|
// 存储写真预约时间段的map集合(键:预约日期id, 值:预约时间段列表)
|
||||||
|
Map<Long, List<TimeIntervalVO>> timeMap = new HashMap<>();
|
||||||
|
// 处理预约时间段,将预约时间段存入map集合
|
||||||
|
for (TimeInterval timeInterval : timeIntervalList) {
|
||||||
|
TimeIntervalVO timeIntervalVO = new TimeIntervalVO();
|
||||||
|
BeanUtils.copyProperties(timeInterval, timeIntervalVO);
|
||||||
|
Long bookingDateId = timeInterval.getBookingDateId();
|
||||||
|
List<TimeIntervalVO> timeIntervalVOS = timeMap.get(bookingDateId);
|
||||||
|
if (timeIntervalVOS == null) {
|
||||||
|
timeIntervalVOS = new ArrayList<>();
|
||||||
|
}
|
||||||
|
timeIntervalVOS.add(timeIntervalVO);
|
||||||
|
timeMap.put(bookingDateId, timeIntervalVOS);
|
||||||
|
}
|
||||||
|
// 处理预约日期,填充当前预约日期对应的预约时间段
|
||||||
|
List<BookingDateVO> bookingDateVOList = new ArrayList<>();
|
||||||
|
for (BookingDate bookingDate : bookingDateList) {
|
||||||
BookingDateVO bookingDateVO = new BookingDateVO();
|
BookingDateVO bookingDateVO = new BookingDateVO();
|
||||||
BeanUtils.copyProperties(bookingDate, bookingDateVO);
|
BeanUtils.copyProperties(bookingDate, bookingDateVO);
|
||||||
return bookingDateVO;
|
Long dateId = bookingDate.getId();
|
||||||
}).toList();
|
List<TimeIntervalVO> timeIntervalVOS = timeMap.get(dateId);
|
||||||
return ResultUtils.success(bookingDateVOS);
|
bookingDateVO.setTimeIntervalVOList(timeIntervalVOS);
|
||||||
|
bookingDateVOList.add(bookingDateVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将预约日期从小到大排序
|
||||||
|
bookingDateVOList.sort((book1, book2) -> {
|
||||||
|
DateTime date1 = DateUtil.parse(book1.getSpecificDate(), "yyyy-MM-dd");
|
||||||
|
DateTime date2 = DateUtil.parse(book2.getSpecificDate(), "yyyy-MM-dd");
|
||||||
|
return date1.compareTo(date2);
|
||||||
|
});
|
||||||
|
|
||||||
|
return ResultUtils.success(bookingDateVOList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
// @PostMapping("/update")
|
||||||
* 更新当天的预约情况
|
// @Operation(summary = "Web端管理员根据预约类型更新预约时间表", description = "参数:预约类型,权限:管理员(admin, boss),方法名:updateBookingDate")
|
||||||
* @param bookingDateUpdateRequest 预约日期更新请求体
|
// @Transactional(rollbackFor = Exception.class)
|
||||||
* @return 是否更新成功
|
// @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||||
*/
|
// public BaseResponse<Boolean> updateBookingDate(@RequestBody CommonStringRequest commonStringRequest) {
|
||||||
@PostMapping("/update")
|
// if (commonStringRequest == null || StringUtils.isBlank(commonStringRequest.getType())) {
|
||||||
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
// throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||||
@Operation(summary = "Web端管理员更新当天的预约情况", description = "参数:预约日期更新请求体, 权限:管理员(admin, boss),方法名:updateBookingDate")
|
// }
|
||||||
public BaseResponse<Boolean> updateBookingDate(@RequestBody BookingDateUpdateRequest bookingDateUpdateRequest) {
|
// String type = commonStringRequest.getType();
|
||||||
if (bookingDateUpdateRequest == null || bookingDateUpdateRequest.getId() <= 0) {
|
// if (!type.equals(BookConstant.RENT_CLOTHES) && !type.equals(BookConstant.OWN_CLOTHES)) {
|
||||||
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
// throw new BusinessException(ErrorCode.PARAMS_ERROR, "类型参数错误");
|
||||||
}
|
// }
|
||||||
BookingDate bookingDate = new BookingDate();
|
// QueryWrapper<BookingDate> queryWrapper = new QueryWrapper<>();
|
||||||
BeanUtils.copyProperties(bookingDateUpdateRequest, bookingDate);
|
// queryWrapper.eq("type", type);
|
||||||
boolean result = bookingDateService.updateById(bookingDate);
|
// return null;
|
||||||
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
|
// }
|
||||||
return ResultUtils.success(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,210 @@
|
||||||
|
package com.cultural.heritage.controller.good;
|
||||||
|
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||||
|
import com.cultural.heritage.annotation.AuthCheck;
|
||||||
|
import com.cultural.heritage.common.BaseResponse;
|
||||||
|
import com.cultural.heritage.common.ErrorCode;
|
||||||
|
import com.cultural.heritage.common.ResultUtils;
|
||||||
|
import com.cultural.heritage.constant.UserConstant;
|
||||||
|
import com.cultural.heritage.exception.BusinessException;
|
||||||
|
import com.cultural.heritage.exception.ThrowUtils;
|
||||||
|
import com.cultural.heritage.model.dto.CommonRequest;
|
||||||
|
import com.cultural.heritage.model.dto.appointment.single.AppointmentDateSingleAddRequest;
|
||||||
|
import com.cultural.heritage.model.dto.timeperiod.TimePeriodAddRequest;
|
||||||
|
import com.cultural.heritage.model.dto.timeperiod.single.TimePeriodSingleAddRequest;
|
||||||
|
import com.cultural.heritage.model.dto.timeperiod.single.TimePeriodSingleUpdateRequest;
|
||||||
|
import com.cultural.heritage.model.entity.AppointmentDate;
|
||||||
|
import com.cultural.heritage.model.entity.TimePeriod;
|
||||||
|
import com.cultural.heritage.service.good.AppointmentDateService;
|
||||||
|
import com.cultural.heritage.service.good.TimePeriodService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/appointmentDate")
|
||||||
|
@Slf4j
|
||||||
|
@Tag(name = "服务类商品预约日期模块")
|
||||||
|
public class AppointmentDateController {
|
||||||
|
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AppointmentDateService appointmentDateService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TimePeriodService timePeriodService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web端管理员根据id删除预约日期
|
||||||
|
* @param commonRequest 预约日期id
|
||||||
|
* @return 是否删除成功
|
||||||
|
*/
|
||||||
|
@PostMapping("/del/id")
|
||||||
|
@Operation(summary = "Web端管理员根据id删除预约日期", description = "参数:预约日期id,权限:管理员(admin, boss),方法名:delAppointmentDateById")
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||||
|
public BaseResponse<Boolean> delAppointmentDateById(@RequestBody CommonRequest commonRequest) {
|
||||||
|
if (commonRequest == null || commonRequest.getId() <= 0) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||||
|
}
|
||||||
|
Long id = commonRequest.getId();
|
||||||
|
// 删除这个预约日期关联的所有时间段
|
||||||
|
QueryWrapper<TimePeriod> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("appointmentDateId", id);
|
||||||
|
boolean remove = timePeriodService.remove(queryWrapper);
|
||||||
|
ThrowUtils.throwIf(!remove, ErrorCode.OPERATION_ERROR, "预约时间段删除失败");
|
||||||
|
|
||||||
|
// 删除这个预约日期
|
||||||
|
boolean success = appointmentDateService.removeById(id);
|
||||||
|
ThrowUtils.throwIf(!success, ErrorCode.OPERATION_ERROR, "预约日期删除失败");
|
||||||
|
return ResultUtils.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web端管理员根据id删除预约时间段
|
||||||
|
* @param commonRequest 预约时间段id
|
||||||
|
* @return 是否删除成功
|
||||||
|
*/
|
||||||
|
@PostMapping("/del/time/id")
|
||||||
|
@Operation(summary = "Web端管理员根据id删除预约时间段", description = "参数:预约日期段id,权限:管理员(admin, boss),方法名:delTimePeriodById")
|
||||||
|
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||||
|
public BaseResponse<Boolean> delTimePeriodById(@RequestBody CommonRequest commonRequest) {
|
||||||
|
if (commonRequest == null || commonRequest.getId() <= 0) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||||
|
}
|
||||||
|
Long id = commonRequest.getId();
|
||||||
|
boolean remove = timePeriodService.removeById(id);
|
||||||
|
ThrowUtils.throwIf(!remove, ErrorCode.OPERATION_ERROR, "预约时间段删除失败");
|
||||||
|
return ResultUtils.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web端管理员根据id修改预约日期的状态
|
||||||
|
* @param commonRequest 预约日期id
|
||||||
|
* @return 是否更新成功
|
||||||
|
*/
|
||||||
|
@PostMapping("/update/status")
|
||||||
|
@Operation(summary = "Web端管理员根据id修改预约日期的状态", description = "参数:预约日期id,权限:管理员(admin, boss),方法名:updateTimePeriodStatusById")
|
||||||
|
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||||
|
public BaseResponse<Boolean> updateTimePeriodStatusById(@RequestBody CommonRequest commonRequest) {
|
||||||
|
if (commonRequest == null || commonRequest.getId() <= 0) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||||
|
}
|
||||||
|
Long id = commonRequest.getId();
|
||||||
|
AppointmentDate appointmentDate = appointmentDateService.getById(id);
|
||||||
|
ThrowUtils.throwIf(appointmentDate == null, ErrorCode.OPERATION_ERROR, "预约日期不存在");
|
||||||
|
Integer status = appointmentDate.getIsAvailable() == 0 ? 1 : 0;
|
||||||
|
UpdateWrapper<AppointmentDate> updateWrapper = new UpdateWrapper<>();
|
||||||
|
updateWrapper.eq("id", id);
|
||||||
|
updateWrapper.set("isAvailable", status);
|
||||||
|
boolean update = appointmentDateService.update(updateWrapper);
|
||||||
|
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "预约日期状态修改失败");
|
||||||
|
return ResultUtils.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web端管理员根据id修改预约时间段的人数
|
||||||
|
* @param timePeriodSingleUpdateRequest 预约日期id
|
||||||
|
* @return 是否更新成功
|
||||||
|
*/
|
||||||
|
@PostMapping("/update/time")
|
||||||
|
@Operation(summary = "Web端管理员根据id修改预约时间段的人数", description = "参数:预约日期id,权限:管理员(admin, boss),方法名:updateTimePeriodPersonNumberById")
|
||||||
|
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||||
|
public BaseResponse<Boolean> updateTimePeriodPersonNumberById(@RequestBody TimePeriodSingleUpdateRequest timePeriodSingleUpdateRequest) {
|
||||||
|
if (timePeriodSingleUpdateRequest == null || timePeriodSingleUpdateRequest.getId() <= 0) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||||
|
}
|
||||||
|
// 根据id获取当前的预约日期
|
||||||
|
Long id = timePeriodSingleUpdateRequest.getId();
|
||||||
|
TimePeriod time = timePeriodService.getById(id);
|
||||||
|
// 封装更新后的预约时间段
|
||||||
|
TimePeriod timePeriod = new TimePeriod();
|
||||||
|
BeanUtils.copyProperties(timePeriodSingleUpdateRequest, timePeriod);
|
||||||
|
timePeriod.setId(time.getId());
|
||||||
|
timePeriod.setTimeSlot(time.getTimeSlot());
|
||||||
|
|
||||||
|
boolean update = timePeriodService.updateById(timePeriod);
|
||||||
|
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "预约时间段人数修改失败");
|
||||||
|
return ResultUtils.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web端管理员添加预约时间段
|
||||||
|
* @param timePeriodSingleAddRequest 预约时间段添加请求体
|
||||||
|
* @return 是否添加成功
|
||||||
|
*/
|
||||||
|
@PostMapping("/add/time")
|
||||||
|
@Operation(summary = "Web端管理员添加预约时间段", description = "参数:预约时间段添加请求体,权限:管理员(admin, boss),方法名:addAppointmentDate")
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||||
|
public BaseResponse<Boolean> addTimePeriod(@RequestBody TimePeriodSingleAddRequest timePeriodSingleAddRequest) {
|
||||||
|
if (timePeriodSingleAddRequest == null) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||||
|
}
|
||||||
|
TimePeriod timePeriod = new TimePeriod();
|
||||||
|
BeanUtils.copyProperties(timePeriodSingleAddRequest, timePeriod);
|
||||||
|
boolean save = timePeriodService.save(timePeriod);
|
||||||
|
ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR, "预约时间段添加失败");
|
||||||
|
return ResultUtils.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web端管理员添加预约日期
|
||||||
|
* @param appointmentDateSingleAddRequest 预约日期添加请求体
|
||||||
|
* @return 是否添加成功
|
||||||
|
*/
|
||||||
|
@PostMapping("/add")
|
||||||
|
@Operation(summary = "Web端管理员添加预约日期", description = "参数:预约日期添加请求体,权限:管理员(admin, boss),方法名:addAppointmentDate")
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||||
|
public BaseResponse<Boolean> addAppointmentDate(@RequestBody AppointmentDateSingleAddRequest appointmentDateSingleAddRequest) {
|
||||||
|
if (appointmentDateSingleAddRequest == null) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||||
|
}
|
||||||
|
// 添加当前商品的预约日期
|
||||||
|
AppointmentDate appointmentDate = new AppointmentDate();
|
||||||
|
BeanUtils.copyProperties(appointmentDateSingleAddRequest, appointmentDate);
|
||||||
|
boolean save = appointmentDateService.save(appointmentDate);
|
||||||
|
ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR, "预约日期添加失败");
|
||||||
|
|
||||||
|
// 添加当前预约日期的预约时间段
|
||||||
|
Long appointmentDateId = appointmentDate.getId();
|
||||||
|
List<TimePeriodAddRequest> timePeriodAddRequestList = appointmentDateSingleAddRequest.getTimePeriodAddRequestList();
|
||||||
|
List<TimePeriod> timePeriodList = timePeriodAddRequestList.stream().map(timePeriodAddRequest -> {
|
||||||
|
TimePeriod timePeriod = new TimePeriod();
|
||||||
|
BeanUtils.copyProperties(timePeriodAddRequest, timePeriod);
|
||||||
|
timePeriod.setAppointmentDateId(appointmentDateId);
|
||||||
|
return timePeriod;
|
||||||
|
}).toList();
|
||||||
|
boolean result = timePeriodService.saveBatch(timePeriodList);
|
||||||
|
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "批量添加预约时间段失败");
|
||||||
|
|
||||||
|
return ResultUtils.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
package com.cultural.heritage.controller.good;
|
package com.cultural.heritage.controller.good;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateTime;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
@ -14,7 +16,6 @@ import com.cultural.heritage.exception.ThrowUtils;
|
||||||
import com.cultural.heritage.model.dto.CommonDelBatchRequest;
|
import com.cultural.heritage.model.dto.CommonDelBatchRequest;
|
||||||
import com.cultural.heritage.model.dto.CommonRequest;
|
import com.cultural.heritage.model.dto.CommonRequest;
|
||||||
import com.cultural.heritage.model.dto.appointment.AppointmentDateAddRequest;
|
import com.cultural.heritage.model.dto.appointment.AppointmentDateAddRequest;
|
||||||
import com.cultural.heritage.model.dto.appointment.AppointmentDateUpdateRequest;
|
|
||||||
import com.cultural.heritage.model.dto.good.GoodAddRequest;
|
import com.cultural.heritage.model.dto.good.GoodAddRequest;
|
||||||
import com.cultural.heritage.model.dto.good.GoodQueryRequest;
|
import com.cultural.heritage.model.dto.good.GoodQueryRequest;
|
||||||
import com.cultural.heritage.model.dto.good.GoodUpdateRequest;
|
import com.cultural.heritage.model.dto.good.GoodUpdateRequest;
|
||||||
|
@ -291,7 +292,7 @@ public class GoodController {
|
||||||
public BaseResponse<Page<GoodPageVO>> listGoodByPage(@RequestBody GoodQueryRequest goodQueryRequest) {
|
public BaseResponse<Page<GoodPageVO>> listGoodByPage(@RequestBody GoodQueryRequest goodQueryRequest) {
|
||||||
long current = goodQueryRequest.getCurrent();
|
long current = goodQueryRequest.getCurrent();
|
||||||
long pageSize = goodQueryRequest.getPageSize();
|
long pageSize = goodQueryRequest.getPageSize();
|
||||||
QueryWrapper<Good> goodQueryWrapper = goodService.getGoodQueryWrapper(goodQueryRequest, true);
|
QueryWrapper<Good> goodQueryWrapper = goodService.getGoodQueryWrapper(goodQueryRequest, false);
|
||||||
Page<Good> page = goodService.page(new Page<>(current, pageSize), goodQueryWrapper);
|
Page<Good> page = goodService.page(new Page<>(current, pageSize), goodQueryWrapper);
|
||||||
List<Good> records = page.getRecords();
|
List<Good> records = page.getRecords();
|
||||||
List<GoodPageVO> goodPageVOS = records.stream().map(good -> {
|
List<GoodPageVO> goodPageVOS = records.stream().map(good -> {
|
||||||
|
@ -409,6 +410,13 @@ public class GoodController {
|
||||||
appointmentDateVOList.add(appointmentDateVO);
|
appointmentDateVOList.add(appointmentDateVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 将预约日期从小到大排序
|
||||||
|
appointmentDateVOList.sort((app1, app2) -> {
|
||||||
|
DateTime date1 = DateUtil.parse(app1.getSpecificDate(), "yyyy-MM-dd");
|
||||||
|
DateTime date2 = DateUtil.parse(app2.getSpecificDate(), "yyyy-MM-dd");
|
||||||
|
return date1.compareTo(date2);
|
||||||
|
});
|
||||||
|
|
||||||
List<ServiceGoodVO> serviceGoodVOList = new ArrayList<>();
|
List<ServiceGoodVO> serviceGoodVOList = new ArrayList<>();
|
||||||
for (Good good : records) {
|
for (Good good : records) {
|
||||||
ServiceGoodVO serviceGoodVO = new ServiceGoodVO();
|
ServiceGoodVO serviceGoodVO = new ServiceGoodVO();
|
||||||
|
@ -481,6 +489,14 @@ public class GoodController {
|
||||||
appointmentDateVO.setTimePeriodVOList(timePeriodVOList);
|
appointmentDateVO.setTimePeriodVOList(timePeriodVOList);
|
||||||
appointmentDateVOList.add(appointmentDateVO);
|
appointmentDateVOList.add(appointmentDateVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 将预约日期从小到大排序
|
||||||
|
appointmentDateVOList.sort((app1, app2) -> {
|
||||||
|
DateTime date1 = DateUtil.parse(app1.getSpecificDate(), "yyyy-MM-dd");
|
||||||
|
DateTime date2 = DateUtil.parse(app2.getSpecificDate(), "yyyy-MM-dd");
|
||||||
|
return date1.compareTo(date2);
|
||||||
|
});
|
||||||
|
|
||||||
serviceGoodVO.setAppointmentDateVOList(appointmentDateVOList);
|
serviceGoodVO.setAppointmentDateVOList(appointmentDateVOList);
|
||||||
return ResultUtils.success(serviceGoodVO);
|
return ResultUtils.success(serviceGoodVO);
|
||||||
}
|
}
|
||||||
|
@ -517,6 +533,7 @@ public class GoodController {
|
||||||
*/
|
*/
|
||||||
@PostMapping("/service/update")
|
@PostMapping("/service/update")
|
||||||
@Operation(summary = "Web端管理员更新服务类商品", description = "参数:服务类商品更新请求体,权限:管理员(admin, boss),方法名:updateServiceGoodById")
|
@Operation(summary = "Web端管理员更新服务类商品", description = "参数:服务类商品更新请求体,权限:管理员(admin, boss),方法名:updateServiceGoodById")
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||||
public BaseResponse<Boolean> updateServiceGoodById(@RequestBody ServiceGoodUpdateRequest serviceGoodUpdateRequest) {
|
public BaseResponse<Boolean> updateServiceGoodById(@RequestBody ServiceGoodUpdateRequest serviceGoodUpdateRequest) {
|
||||||
if (serviceGoodUpdateRequest == null || serviceGoodUpdateRequest.getId() <= 0) {
|
if (serviceGoodUpdateRequest == null || serviceGoodUpdateRequest.getId() <= 0) {
|
||||||
|
@ -534,17 +551,74 @@ public class GoodController {
|
||||||
boolean result = goodService.updateById(good);
|
boolean result = goodService.updateById(good);
|
||||||
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "商品不存在");
|
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "商品不存在");
|
||||||
|
|
||||||
List<AppointmentDateUpdateRequest> appointmentDateUpdateRequestList = serviceGoodUpdateRequest.getAppointmentDateUpdateRequestList();
|
// 删除当前商品关联的所有日期和时间段
|
||||||
List<AppointmentDate> appointmentDateList = appointmentDateUpdateRequestList.stream().map(appointmentDateUpdateRequest -> {
|
CommonRequest commonRequest = new CommonRequest();
|
||||||
|
commonRequest.setId(good.getId());
|
||||||
|
deleteServiceGoodAppointment(commonRequest);
|
||||||
|
// 为当前商品重新添加预约日期和时间段
|
||||||
|
ServiceGoodAddRequest serviceGoodAddRequest = new ServiceGoodAddRequest();
|
||||||
|
BeanUtils.copyProperties(serviceGoodUpdateRequest, serviceGoodAddRequest);
|
||||||
|
dealServiceGoodAppointmentDate(serviceGoodAddRequest, good);
|
||||||
|
return ResultUtils.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void deleteServiceGoodAppointment(CommonRequest commonRequest) {
|
||||||
|
if (commonRequest == null || commonRequest.getId() <= 0) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||||
|
}
|
||||||
|
Long id = commonRequest.getId();
|
||||||
|
|
||||||
|
//删除预约时间段表中与该商品关联的记录
|
||||||
|
QueryWrapper<AppointmentDate> dateQueryWrapper = new QueryWrapper<>();
|
||||||
|
dateQueryWrapper.eq("goodId", id);
|
||||||
|
List<AppointmentDate> appointmentDateList = appointmentDateService.list(dateQueryWrapper);
|
||||||
|
List<Long> ids = appointmentDateList.stream().map(AppointmentDate::getId).toList();
|
||||||
|
QueryWrapper<TimePeriod> timePeriodQueryWrapper = new QueryWrapper<>();
|
||||||
|
timePeriodQueryWrapper.in("appointmentDateId", ids);
|
||||||
|
boolean remove = timePeriodService.remove(timePeriodQueryWrapper);
|
||||||
|
ThrowUtils.throwIf(!remove, ErrorCode.OPERATION_ERROR, "服务类商品预约时间段删除失败");
|
||||||
|
|
||||||
|
// 删除预约日期表中与该商品关联的记录
|
||||||
|
boolean isSuccess = appointmentDateService.remove(dateQueryWrapper);
|
||||||
|
ThrowUtils.throwIf(!isSuccess, ErrorCode.OPERATION_ERROR, "服务类商品预约日期删除失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void dealServiceGoodAppointmentDate(ServiceGoodAddRequest serviceGoodAddRequest, Good good) {
|
||||||
|
// 添加当前商品的预约日期
|
||||||
|
List<AppointmentDateAddRequest> appointmentDateAddRequestList = serviceGoodAddRequest.getAppointmentDateAddRequestList();
|
||||||
|
List<AppointmentDate> appointmentDateList = appointmentDateAddRequestList.stream().map(appointmentDateAddRequest -> {
|
||||||
AppointmentDate appointmentDate = new AppointmentDate();
|
AppointmentDate appointmentDate = new AppointmentDate();
|
||||||
BeanUtils.copyProperties(appointmentDateUpdateRequest, appointmentDate);
|
BeanUtils.copyProperties(appointmentDateAddRequest, appointmentDate);
|
||||||
appointmentDate.setGoodId(good.getId());
|
appointmentDate.setGoodId(good.getId());
|
||||||
|
// 校验
|
||||||
|
appointmentDateService.validAppointmentDate(appointmentDate, false);
|
||||||
return appointmentDate;
|
return appointmentDate;
|
||||||
}).toList();
|
}).toList();
|
||||||
|
boolean isSaveBatch = appointmentDateService.saveBatch(appointmentDateList);
|
||||||
|
ThrowUtils.throwIf(!isSaveBatch, ErrorCode.OPERATION_ERROR);
|
||||||
|
|
||||||
|
// 添加当前商品的预约时间段
|
||||||
|
List<TimePeriod> timePeriods = new ArrayList<>();
|
||||||
return ResultUtils.success(true);
|
for (int i = 0; i < appointmentDateAddRequestList.size(); i++) {
|
||||||
|
AppointmentDate appointmentDate = appointmentDateList.get(i);
|
||||||
|
AppointmentDateAddRequest appointmentDateAddRequest = appointmentDateAddRequestList.get(i);
|
||||||
|
Long appointmentDateId = appointmentDate.getId();
|
||||||
|
List<TimePeriodAddRequest> timePeriodAddRequestList = appointmentDateAddRequest.getTimePeriodAddRequestList();
|
||||||
|
List<TimePeriod> timePeriodList = timePeriodAddRequestList.stream().map(timePeriodAddRequest -> {
|
||||||
|
TimePeriod timePeriod = new TimePeriod();
|
||||||
|
BeanUtils.copyProperties(timePeriodAddRequest, timePeriod);
|
||||||
|
timePeriod.setAppointmentDateId(appointmentDateId);
|
||||||
|
// 校验
|
||||||
|
timePeriodService.validTimePeriod(timePeriod, false);
|
||||||
|
return timePeriod;
|
||||||
|
}).toList();
|
||||||
|
timePeriods.addAll(timePeriodList);
|
||||||
|
}
|
||||||
|
boolean result = timePeriodService.saveBatch(timePeriods);
|
||||||
|
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
package com.cultural.heritage.controller.wx;
|
||||||
|
|
||||||
|
|
||||||
|
import com.cultural.heritage.annotation.AuthCheck;
|
||||||
|
import com.cultural.heritage.common.BaseResponse;
|
||||||
|
import com.cultural.heritage.common.ErrorCode;
|
||||||
|
import com.cultural.heritage.common.ResultUtils;
|
||||||
|
import com.cultural.heritage.constant.UserConstant;
|
||||||
|
import com.cultural.heritage.exception.BusinessException;
|
||||||
|
import com.cultural.heritage.exception.ThrowUtils;
|
||||||
|
import com.cultural.heritage.model.dto.CommonRequest;
|
||||||
|
import com.cultural.heritage.model.entity.Order;
|
||||||
|
import com.cultural.heritage.model.entity.User;
|
||||||
|
import com.cultural.heritage.service.order.OrderService;
|
||||||
|
import com.cultural.heritage.service.user.UserService;
|
||||||
|
import com.cultural.heritage.service.wxpay.WeChatService;
|
||||||
|
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
|
||||||
|
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||||
|
import com.wechat.pay.java.service.refund.model.Refund;
|
||||||
|
import com.wechat.pay.java.service.refund.model.RefundNotification;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信小程序相关接口
|
||||||
|
**/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@Tag(name = "微信支付接口")
|
||||||
|
@RequestMapping("/wechat")
|
||||||
|
public class WeChatPayController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private OrderService ordersService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private WeChatService weChatService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSAPI 下单
|
||||||
|
*/
|
||||||
|
@PostMapping("/payment/create")
|
||||||
|
public BaseResponse<PrepayWithRequestPaymentResponse> createPayment(@RequestBody CommonRequest commonRequest, HttpServletRequest request) {
|
||||||
|
User loginUser = userService.getLoginUser(request);
|
||||||
|
String miniOpenId = loginUser.getMiniOpenId();
|
||||||
|
ThrowUtils.throwIf(miniOpenId == null, ErrorCode.NOT_FOUND_ERROR, "不是小程序用户");
|
||||||
|
Long orderId = commonRequest.getId();
|
||||||
|
Order order = ordersService.getById(orderId);
|
||||||
|
ThrowUtils.throwIf(order == null, ErrorCode.NOT_FOUND_ERROR, "订单不存在");
|
||||||
|
// ThrowUtils.throwIf(order.getState() != 0, ErrorCode.OPERATION_ERROR, "订单状态错误");
|
||||||
|
if (!loginUser.getId().equals(order.getUserId())) {
|
||||||
|
throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "你不是该订单用户!");
|
||||||
|
}
|
||||||
|
PrepayWithRequestPaymentResponse response = weChatService.createPayment(String.valueOf(orderId), miniOpenId, order.getTotalAmount());
|
||||||
|
return ResultUtils.success(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSAPI 下单回调
|
||||||
|
*/
|
||||||
|
@PostMapping("/payment/callback")
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public synchronized BaseResponse<Boolean> callbackPayment(HttpServletRequest request) throws IOException {
|
||||||
|
// 获取下单信息
|
||||||
|
Transaction transaction = weChatService.getTransactionInfo(request);
|
||||||
|
System.out.println("下单信息:" + transaction);
|
||||||
|
// 支付回调
|
||||||
|
boolean result = weChatService.paymentCallback(transaction);
|
||||||
|
ThrowUtils.throwIf(!result, ErrorCode.SYSTEM_ERROR, "微信支付回调失败");
|
||||||
|
return ResultUtils.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款(仅管理员和商家)
|
||||||
|
*/
|
||||||
|
@PostMapping("/refund/create")
|
||||||
|
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||||
|
public BaseResponse<Refund> createRefund(@RequestBody CommonRequest commonRequest) {
|
||||||
|
Long orderId = commonRequest.getId();
|
||||||
|
Order order = ordersService.getById(orderId);
|
||||||
|
ThrowUtils.throwIf(order == null, ErrorCode.NOT_FOUND_ERROR, "订单不存在");
|
||||||
|
Refund refund = weChatService.refundPayment(String.valueOf(orderId), order.getTotalAmount());
|
||||||
|
return ResultUtils.success(refund);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款回调
|
||||||
|
*/
|
||||||
|
@PostMapping("/refund/callback")
|
||||||
|
public BaseResponse<Boolean> callbackRefund(HttpServletRequest request) {
|
||||||
|
// 获取退款信息
|
||||||
|
RefundNotification refundNotification = weChatService.getRefundInfo(request);
|
||||||
|
// 退款回调
|
||||||
|
boolean result = weChatService.refundCallback(refundNotification);
|
||||||
|
ThrowUtils.throwIf(!result, ErrorCode.SYSTEM_ERROR, "退款回调失败");
|
||||||
|
return ResultUtils.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送订阅消息
|
||||||
|
*/
|
||||||
|
@GetMapping("/refund/callback")
|
||||||
|
public BaseResponse<Boolean> testSendMessage() {
|
||||||
|
String miniOpenId = "o0o_B5CMLFiOs96dJZwtkyHcJzcM";
|
||||||
|
String templateId = "MK13FfX0XxsPV6m1vi6J8_8Bf7JT8rsayFs9q3f4FW4";
|
||||||
|
boolean subscribeMessage = weChatService.sendSubscribeMessage(miniOpenId, templateId);
|
||||||
|
return ResultUtils.success(subscribeMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.cultural.heritage.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.cultural.heritage.model.entity.TimeInterval;
|
||||||
|
|
||||||
|
public interface TimeIntervalMapper extends BaseMapper<TimeInterval> {
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.cultural.heritage.model.dto.appointment.single;
|
||||||
|
|
||||||
|
import com.cultural.heritage.model.dto.timeperiod.TimePeriodAddRequest;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "预约日期请求体", requiredProperties = {
|
||||||
|
"specificDate", "isAvailable", "timePeriodAddRequestList"
|
||||||
|
})
|
||||||
|
public class AppointmentDateSingleAddRequest implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品id
|
||||||
|
*/
|
||||||
|
@Schema(description = "商品id", example = "2")
|
||||||
|
private Long goodId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 具体预约时间
|
||||||
|
*/
|
||||||
|
@Schema(description = "具体预约时间", example = "2024-12-04")
|
||||||
|
private String specificDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否可预约
|
||||||
|
*/
|
||||||
|
@Schema(description = "是否可预约", example = "1")
|
||||||
|
private Integer isAvailable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约时间段列表
|
||||||
|
*/
|
||||||
|
private List<TimePeriodAddRequest> timePeriodAddRequestList;
|
||||||
|
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
|
@ -1,13 +1,15 @@
|
||||||
package com.cultural.heritage.model.dto.book;
|
package com.cultural.heritage.model.dto.book;
|
||||||
|
|
||||||
|
import com.cultural.heritage.model.dto.timeinterval.TimeIntervalAddRequest;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Schema(description = "预约日期添加请求体", requiredProperties = {"specificDate", "timeSlot", "isAvailable", "maxNumber", "type"})
|
@Schema(description = "预约日期添加请求体", requiredProperties = {"specificDate", "isAvailable", "type"})
|
||||||
public class BookingDateAddRequest implements Serializable {
|
public class BookingDateAddRequest implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,13 +19,6 @@ public class BookingDateAddRequest implements Serializable {
|
||||||
private String specificDate;
|
private String specificDate;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 时间段
|
|
||||||
*/
|
|
||||||
@Schema(description = "时间段", example = "8:00-10:00;12:00-14:00")
|
|
||||||
private String timeSlot;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否可预约
|
* 是否可预约
|
||||||
*/
|
*/
|
||||||
|
@ -31,13 +26,6 @@ public class BookingDateAddRequest implements Serializable {
|
||||||
private Integer isAvailable;
|
private Integer isAvailable;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 各个时间段的最大预约人数(4,6..)
|
|
||||||
*/
|
|
||||||
@Schema(description = "各个时间段的最大预约人数(4,6..)", example = "4,5,6")
|
|
||||||
private String maxNumber;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预约类别
|
* 预约类别
|
||||||
*/
|
*/
|
||||||
|
@ -45,6 +33,13 @@ public class BookingDateAddRequest implements Serializable {
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约时间段列表
|
||||||
|
*/
|
||||||
|
@Schema(description = "预约时间段列表")
|
||||||
|
private List<TimeIntervalAddRequest> timeIntervalAddRequestList;
|
||||||
|
|
||||||
|
|
||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Schema(description = "预约日期更新请求体", requiredProperties = {"id", "specificDate", "timeSlot", "isAvailable", "maxNumber","type"})
|
@Schema(description = "预约日期更新请求体", requiredProperties = {"id", "specificDate", "isAvailable","type"})
|
||||||
public class BookingDateUpdateRequest implements Serializable {
|
public class BookingDateUpdateRequest implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,13 +25,6 @@ public class BookingDateUpdateRequest implements Serializable {
|
||||||
private String specificDate;
|
private String specificDate;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 时间段
|
|
||||||
*/
|
|
||||||
@Schema(description = "时间段", example = "8:00-10:00;12:00-14:00")
|
|
||||||
private String timeSlot;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否可预约
|
* 是否可预约
|
||||||
*/
|
*/
|
||||||
|
@ -39,13 +32,6 @@ public class BookingDateUpdateRequest implements Serializable {
|
||||||
private Integer isAvailable;
|
private Integer isAvailable;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 各个时间段的最大预约人数(4,6..)
|
|
||||||
*/
|
|
||||||
@Schema(description = "各个时间段的最大预约人数(4,6..)", example = "4,5,6")
|
|
||||||
private String maxNumber;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预约类别
|
* 预约类别
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.cultural.heritage.model.dto.good.service;
|
package com.cultural.heritage.model.dto.good.service;
|
||||||
|
|
||||||
import com.cultural.heritage.model.dto.appointment.AppointmentDateUpdateRequest;
|
import com.cultural.heritage.model.dto.appointment.AppointmentDateAddRequest;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ public class ServiceGoodUpdateRequest implements Serializable {
|
||||||
* 未来几天的预约时间表
|
* 未来几天的预约时间表
|
||||||
*/
|
*/
|
||||||
@Schema(description = "未来的预约时间表")
|
@Schema(description = "未来的预约时间表")
|
||||||
private List<AppointmentDateUpdateRequest> appointmentDateUpdateRequestList;
|
private List<AppointmentDateAddRequest> appointmentDateAddRequestList;
|
||||||
|
|
||||||
|
|
||||||
@Serial
|
@Serial
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.cultural.heritage.model.dto.timeinterval;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "写真预约时间段添加请求体", requiredProperties = {
|
||||||
|
"timeSlot", "minNumber", "maxNumber"})
|
||||||
|
public class TimeIntervalAddRequest implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间段
|
||||||
|
*/
|
||||||
|
@Schema(description = "时间段", example = "08:00-10:00")
|
||||||
|
private String timeSlot;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最小预约人数
|
||||||
|
*/
|
||||||
|
@Schema(description = "最小预约人数", example = "3")
|
||||||
|
private Integer minNumber;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最大预约人数
|
||||||
|
*/
|
||||||
|
@Schema(description = "最大预约人数", example = "10")
|
||||||
|
private Integer maxNumber;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ public class TimePeriodUpdateRequest implements Serializable {
|
||||||
@Schema(description = "预约时间段id(id > 0)", example = "10")
|
@Schema(description = "预约时间段id(id > 0)", example = "10")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 时间段
|
* 时间段
|
||||||
*/
|
*/
|
||||||
|
@ -39,6 +40,13 @@ public class TimePeriodUpdateRequest implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约日期id
|
||||||
|
*/
|
||||||
|
@Schema(description = "预约日期id", example = "12")
|
||||||
|
private Long appointmentDateId;
|
||||||
|
|
||||||
|
|
||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.cultural.heritage.model.dto.timeperiod.single;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "预约时间段添加请求体", requiredProperties = {
|
||||||
|
"timeSlot", "minNumber", "maxNumber"
|
||||||
|
})
|
||||||
|
public class TimePeriodSingleAddRequest implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间段
|
||||||
|
*/
|
||||||
|
@Schema(description = "时间段", example = "08:00-10:00")
|
||||||
|
private String timeSlot;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最小预约人数
|
||||||
|
*/
|
||||||
|
@Schema(description = "最小预约人数", example = "3")
|
||||||
|
private Integer minNumber;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最大预约人数
|
||||||
|
*/
|
||||||
|
@Schema(description = "最大预约人数", example = "10")
|
||||||
|
private Integer maxNumber;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约日期id
|
||||||
|
*/
|
||||||
|
@Schema(description = "预约日期id", example = "12")
|
||||||
|
private Long appointmentDateId;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.cultural.heritage.model.dto.timeperiod.single;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "预约时间段更新请求体", requiredProperties = {"id", "minNumber", "maxNumber"})
|
||||||
|
public class TimePeriodSingleUpdateRequest implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约时间段id
|
||||||
|
*/
|
||||||
|
@Schema(description = "预约时间段id(id > 0)", example = "10")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最小预约人数
|
||||||
|
*/
|
||||||
|
@Schema(description = "最小预约人数", example = "3")
|
||||||
|
private Integer minNumber;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最大预约人数
|
||||||
|
*/
|
||||||
|
@Schema(description = "最大预约人数", example = "10")
|
||||||
|
private Integer maxNumber;
|
||||||
|
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
|
@ -31,24 +31,12 @@ public class BookingDate implements Serializable {
|
||||||
private String specificDate;
|
private String specificDate;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 时间段
|
|
||||||
*/
|
|
||||||
private String timeSlot;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否可预约
|
* 是否可预约
|
||||||
*/
|
*/
|
||||||
private Integer isAvailable;
|
private Integer isAvailable;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 各个时间段的最大预约人数(4,6..)
|
|
||||||
*/
|
|
||||||
private String maxNumber;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预约类别
|
* 预约类别
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.cultural.heritage.model.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 写真预约时间段表
|
||||||
|
* @TableName time_interval
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("time_interval")
|
||||||
|
public class TimeInterval implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约时间段id
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间段
|
||||||
|
*/
|
||||||
|
private String timeSlot;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最小预约人数
|
||||||
|
*/
|
||||||
|
private Integer minNumber;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最大预约人数
|
||||||
|
*/
|
||||||
|
private Integer maxNumber;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约日期id
|
||||||
|
*/
|
||||||
|
private Long bookingDateId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否删除
|
||||||
|
*/
|
||||||
|
private Integer isDelete;
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
|
@ -1,9 +1,11 @@
|
||||||
package com.cultural.heritage.model.vo.book;
|
package com.cultural.heritage.model.vo.book;
|
||||||
|
|
||||||
|
import com.cultural.heritage.model.vo.timeinterval.TimeIntervalVO;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class BookingDateVO implements Serializable {
|
public class BookingDateVO implements Serializable {
|
||||||
|
@ -21,30 +23,23 @@ public class BookingDateVO implements Serializable {
|
||||||
private String specificDate;
|
private String specificDate;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 时间段
|
|
||||||
*/
|
|
||||||
private String timeSlot;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否可预约
|
* 是否可预约
|
||||||
*/
|
*/
|
||||||
private Integer isAvailable;
|
private Integer isAvailable;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 各个时间段的最大预约人数(4,6..)
|
|
||||||
*/
|
|
||||||
private String maxNumber;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预约类别
|
* 预约类别
|
||||||
*/
|
*/
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约时间段
|
||||||
|
*/
|
||||||
|
private List<TimeIntervalVO> timeIntervalVOList;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Serial
|
@Serial
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.cultural.heritage.model.vo.timeinterval;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class TimeIntervalVO implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约时间段id
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间段
|
||||||
|
*/
|
||||||
|
private String timeSlot;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最小预约人数
|
||||||
|
*/
|
||||||
|
private Integer minNumber;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最大预约人数
|
||||||
|
*/
|
||||||
|
private Integer maxNumber;
|
||||||
|
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ public interface BookingDateService extends IService<BookingDate> {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化未来一天的预约日期
|
* 校验
|
||||||
*/
|
*/
|
||||||
BookingDate initBookingDate(String type, int offset);
|
void validBookingDate(BookingDate bookingDate, boolean update);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.cultural.heritage.service.book;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.cultural.heritage.model.entity.TimeInterval;
|
||||||
|
|
||||||
|
public interface TimeIntervalService extends IService<TimeInterval> {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验
|
||||||
|
*/
|
||||||
|
void validTimeInterval(TimeInterval timeInterval, boolean update);
|
||||||
|
}
|
|
@ -1,28 +1,37 @@
|
||||||
package com.cultural.heritage.service.book.impl;
|
package com.cultural.heritage.service.book.impl;
|
||||||
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.cultural.heritage.common.ErrorCode;
|
||||||
|
import com.cultural.heritage.exception.BusinessException;
|
||||||
import com.cultural.heritage.mapper.BookingDateMapper;
|
import com.cultural.heritage.mapper.BookingDateMapper;
|
||||||
import com.cultural.heritage.model.entity.BookingDate;
|
import com.cultural.heritage.model.entity.BookingDate;
|
||||||
import com.cultural.heritage.service.book.BookingDateService;
|
import com.cultural.heritage.service.book.BookingDateService;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class BookingDateServiceImpl extends ServiceImpl<BookingDateMapper, BookingDate> implements BookingDateService {
|
public class BookingDateServiceImpl extends ServiceImpl<BookingDateMapper, BookingDate> implements BookingDateService {
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化未来一天的预约日期
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public BookingDate initBookingDate(String type, int offset) {
|
public void validBookingDate(BookingDate bookingDate, boolean update) {
|
||||||
String currentDate = DateUtil.formatDate(DateUtil.offsetDay(DateUtil.date(), offset));
|
Long dateId = bookingDate.getId();
|
||||||
BookingDate bookingDate = new BookingDate();
|
String specificDate = bookingDate.getSpecificDate();
|
||||||
bookingDate.setSpecificDate(currentDate);
|
Integer isAvailable = bookingDate.getIsAvailable();
|
||||||
bookingDate.setTimeSlot("00:00-00:00");
|
String type = bookingDate.getType();
|
||||||
bookingDate.setIsAvailable(0);
|
|
||||||
bookingDate.setMaxNumber("0");
|
if (update) {
|
||||||
bookingDate.setType(type);
|
if (dateId == null) {
|
||||||
return bookingDate;
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "id参数错误");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ObjectUtils.isEmpty(isAvailable) || isAvailable != 1 && isAvailable != 0) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "是否可预约参数错误");
|
||||||
|
}
|
||||||
|
if (StringUtils.isAnyBlank(specificDate, type)) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "存在字符串类型参数为空");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.cultural.heritage.service.book.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.cultural.heritage.common.ErrorCode;
|
||||||
|
import com.cultural.heritage.exception.BusinessException;
|
||||||
|
import com.cultural.heritage.mapper.TimeIntervalMapper;
|
||||||
|
import com.cultural.heritage.model.entity.TimeInterval;
|
||||||
|
import com.cultural.heritage.service.book.TimeIntervalService;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class TimeIntervalServiceImpl extends ServiceImpl<TimeIntervalMapper, TimeInterval> implements TimeIntervalService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void validTimeInterval(TimeInterval timeInterval, boolean update) {
|
||||||
|
|
||||||
|
Long id = timeInterval.getId();
|
||||||
|
Integer minNumber = timeInterval.getMinNumber();
|
||||||
|
Integer maxNumber = timeInterval.getMaxNumber();
|
||||||
|
String timeSlot = timeInterval.getTimeSlot();
|
||||||
|
Long bookingDateId = timeInterval.getBookingDateId();
|
||||||
|
|
||||||
|
if (update) {
|
||||||
|
if (id == null) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "预约日期id参数错误");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ObjectUtils.anyNull(minNumber, maxNumber, bookingDateId)) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "存在参数为空");
|
||||||
|
}
|
||||||
|
if (minNumber > maxNumber) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "最小预约人数不能超过最大预约人数");
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(timeSlot)) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "时间段参数为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.cultural.heritage.service.wxpay;
|
||||||
|
|
||||||
|
|
||||||
|
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
|
||||||
|
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||||
|
import com.wechat.pay.java.service.refund.model.Refund;
|
||||||
|
import com.wechat.pay.java.service.refund.model.RefundNotification;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 玄德
|
||||||
|
*/
|
||||||
|
public interface WeChatService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付
|
||||||
|
*/
|
||||||
|
PrepayWithRequestPaymentResponse createPayment(String orderId, String miniOpenId, BigDecimal amount);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取支付回调信息
|
||||||
|
*/
|
||||||
|
Transaction getTransactionInfo(HttpServletRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付回调
|
||||||
|
*/
|
||||||
|
boolean paymentCallback(Transaction transaction) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款申请
|
||||||
|
*/
|
||||||
|
Refund refundPayment(String orderId, BigDecimal amount);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取退款回调信息
|
||||||
|
*/
|
||||||
|
RefundNotification getRefundInfo(HttpServletRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款回调
|
||||||
|
*/
|
||||||
|
boolean refundCallback(RefundNotification refundNotification);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送订阅模板消息
|
||||||
|
*/
|
||||||
|
boolean sendSubscribeMessage(String openid, String templateId);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,265 @@
|
||||||
|
package com.cultural.heritage.service.wxpay.impl;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.binarywang.wx.miniapp.api.WxMaMsgService;
|
||||||
|
import cn.binarywang.wx.miniapp.api.WxMaService;
|
||||||
|
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
|
||||||
|
import cn.hutool.core.util.RandomUtil;
|
||||||
|
import com.cultural.heritage.common.ErrorCode;
|
||||||
|
import com.cultural.heritage.config.WxOpenConfig;
|
||||||
|
import com.cultural.heritage.config.WxPayConfig;
|
||||||
|
import com.cultural.heritage.exception.BusinessException;
|
||||||
|
import com.cultural.heritage.model.entity.Order;
|
||||||
|
import com.cultural.heritage.service.order.OrderService;
|
||||||
|
import com.cultural.heritage.service.wxpay.WeChatService;
|
||||||
|
import com.wechat.pay.java.core.notification.NotificationParser;
|
||||||
|
import com.wechat.pay.java.core.notification.RequestParam;
|
||||||
|
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
|
||||||
|
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
|
||||||
|
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
|
||||||
|
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
|
||||||
|
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||||
|
import com.wechat.pay.java.service.refund.model.AmountReq;
|
||||||
|
import com.wechat.pay.java.service.refund.model.CreateRequest;
|
||||||
|
import com.wechat.pay.java.service.refund.model.Refund;
|
||||||
|
import com.wechat.pay.java.service.refund.model.RefundNotification;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 玄德
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class WeChatServiceImpl implements WeChatService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private WxPayConfig wxPayConfig;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private WxOpenConfig wxOpenConfig;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private OrderService ordersService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求参数
|
||||||
|
*/
|
||||||
|
public static RequestParam requestParam = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public synchronized PrepayWithRequestPaymentResponse createPayment(String orderId, String miniOpenId, BigDecimal amount) {
|
||||||
|
// request.setXxx(val)设置所需参数,具体参数可见Request定义
|
||||||
|
PrepayRequest request = new PrepayRequest();
|
||||||
|
// 金额
|
||||||
|
Amount WxAmount = new Amount();
|
||||||
|
WxAmount.setTotal(amount.movePointRight(2).intValue());
|
||||||
|
WxAmount.setCurrency("CNY");
|
||||||
|
request.setAmount(WxAmount);
|
||||||
|
// 公众号id
|
||||||
|
request.setAppid(wxPayConfig.getAppId());
|
||||||
|
// 商户号
|
||||||
|
request.setMchid(wxPayConfig.getMerchantId());
|
||||||
|
// 支付者信息
|
||||||
|
Payer payer = new Payer();
|
||||||
|
payer.setOpenid(miniOpenId);
|
||||||
|
request.setPayer(payer);
|
||||||
|
// 描述
|
||||||
|
request.setDescription("订单号:" + orderId);
|
||||||
|
// 微信回调地址
|
||||||
|
request.setNotifyUrl(wxPayConfig.getNotifyUrl() + "/api/wechat/payment/callback");
|
||||||
|
// 商户订单号
|
||||||
|
request.setOutTradeNo(RandomUtil.randomNumbers(12));
|
||||||
|
//返回数据,前端调起支付
|
||||||
|
return wxPayConfig.getJsapiServiceExtension().prepayWithRequestPayment(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Transaction getTransactionInfo(HttpServletRequest request) {
|
||||||
|
NotificationParser notificationParser = getNotificationParser(request);
|
||||||
|
return notificationParser.parse(requestParam, Transaction.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public synchronized boolean paymentCallback(Transaction transaction) throws IOException {
|
||||||
|
System.out.println("---------------------------微信支付回调(开始)-------------------------------");
|
||||||
|
// 获取订单信息
|
||||||
|
String orderIdByString = transaction.getOutTradeNo();
|
||||||
|
Order order = ordersService.getById(orderIdByString);
|
||||||
|
if (order == null) {
|
||||||
|
log.error("订单不存在");
|
||||||
|
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "订单不存在,订单号:" + transaction.getOutTradeNo());
|
||||||
|
}
|
||||||
|
// 生成取餐码
|
||||||
|
// 获取当日的日期
|
||||||
|
LocalDate today = LocalDate.now();
|
||||||
|
// 获取当日的 00:00 时间
|
||||||
|
LocalDateTime startTime = today.atStartOfDay();
|
||||||
|
// 获取当日的 23:59 时间
|
||||||
|
LocalDateTime endTime = today.atTime(LocalTime.MAX);
|
||||||
|
// // 生成取餐码
|
||||||
|
// QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
|
||||||
|
// queryWrapper.eq("businessId", order.getBusinessId());
|
||||||
|
// queryWrapper.between("createTime", startTime, endTime);
|
||||||
|
// queryWrapper.in("state", 1, 2);
|
||||||
|
// long count = ordersService.count(queryWrapper);
|
||||||
|
// String pickupCode = String.format("%04d", count + 1);
|
||||||
|
// // 修改订单信息
|
||||||
|
// order.setState(1);
|
||||||
|
// order.setPickupCode(pickupCode);
|
||||||
|
// Date date = new Date();
|
||||||
|
// order.setUpdateTime(date);
|
||||||
|
// boolean update = ordersService.updateById(order);
|
||||||
|
// ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "修改订单状态失败");
|
||||||
|
// // 通知商家新订单
|
||||||
|
// Business business = businessService.getById(order.getBusinessId());
|
||||||
|
// Long userId = order.getUserId();
|
||||||
|
// Long businessId = business.getUserId();
|
||||||
|
// MessageVO messageVO = new MessageVO();
|
||||||
|
// messageVO.setType(1);
|
||||||
|
// messageVO.setUserId(userId);
|
||||||
|
// messageVO.setToUserId(businessId);
|
||||||
|
// messageVO.setContent(orderIdByString);
|
||||||
|
// String message = JSONUtil.toJsonStr(messageVO);
|
||||||
|
// // 通知商家新订单
|
||||||
|
// webSocketServer.onMessage(message);
|
||||||
|
System.out.println("---------------------------微信支付回调(结束)-------------------------------");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Refund refundPayment(String orderId, BigDecimal amount) {
|
||||||
|
// 退款请求
|
||||||
|
CreateRequest createRequest = new CreateRequest();
|
||||||
|
// 商户订单号
|
||||||
|
createRequest.setOutTradeNo(orderId);
|
||||||
|
// 商户退款单号
|
||||||
|
createRequest.setOutRefundNo(orderId);
|
||||||
|
// 退款结果回调
|
||||||
|
createRequest.setNotifyUrl(wxPayConfig.getNotifyUrl() + "/api/wechat/refund/callback");
|
||||||
|
// 退款金额
|
||||||
|
AmountReq amountReq = new AmountReq();
|
||||||
|
long refundAmount = amount.movePointRight(2).intValue();
|
||||||
|
amountReq.setRefund(refundAmount);
|
||||||
|
amountReq.setTotal(refundAmount);
|
||||||
|
amountReq.setCurrency("CNY");
|
||||||
|
createRequest.setAmount(amountReq);
|
||||||
|
// 申请退款
|
||||||
|
System.out.println("退款请求:" + createRequest);
|
||||||
|
Refund refund = wxPayConfig.getRefundService().create(createRequest);
|
||||||
|
System.out.println("退款申请结果:" + refund);
|
||||||
|
return refund;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RefundNotification getRefundInfo(HttpServletRequest request) {
|
||||||
|
NotificationParser notificationParser = getNotificationParser(request);
|
||||||
|
return notificationParser.parse(requestParam, RefundNotification.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public synchronized boolean refundCallback(RefundNotification refundNotification) {
|
||||||
|
System.out.println("---------------------------微信退款回调(开始)-------------------------------");
|
||||||
|
// 获取订单信息
|
||||||
|
String orderIdByString = refundNotification.getOutTradeNo();
|
||||||
|
Order order = ordersService.getById(orderIdByString);
|
||||||
|
// 修改订单信息
|
||||||
|
order.setOrderStatus("已退款");
|
||||||
|
ordersService.updateById(order);
|
||||||
|
System.out.println("---------------------------微信退款回调(结束)-------------------------------");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean sendSubscribeMessage(String openid, String templateId) {
|
||||||
|
try {
|
||||||
|
// 获取小程序对象
|
||||||
|
WxMaService wxMaService = wxOpenConfig.getWxMaService();
|
||||||
|
// 获取消息接口
|
||||||
|
WxMaMsgService msgService = wxMaService.getMsgService();
|
||||||
|
// 构建订阅消息体
|
||||||
|
WxMaSubscribeMessage wxMaSubscribeMessage = new WxMaSubscribeMessage();
|
||||||
|
wxMaSubscribeMessage.setToUser(openid);
|
||||||
|
wxMaSubscribeMessage.setTemplateId(templateId);
|
||||||
|
List<WxMaSubscribeMessage.MsgData> msgDataList = getMsgData();
|
||||||
|
wxMaSubscribeMessage.setData(msgDataList);
|
||||||
|
// 发送消息
|
||||||
|
msgService.sendSubscribeMsg(wxMaSubscribeMessage);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("发送订阅消息失败:", e);
|
||||||
|
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "发送订阅消息失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提取消息数据
|
||||||
|
*/
|
||||||
|
private static List<WxMaSubscribeMessage.MsgData> getMsgData() {
|
||||||
|
List<WxMaSubscribeMessage.MsgData> msgDataList = new ArrayList<>();
|
||||||
|
String[][] dataItems = {
|
||||||
|
{"thing1", "新订单"},
|
||||||
|
{"phrase2", "已支付"},
|
||||||
|
{"amount3", "666"},
|
||||||
|
{"thing10", "666666"},
|
||||||
|
{"time8", "2019-12-18 12:12:12"}
|
||||||
|
};
|
||||||
|
for (String[] item : dataItems) {
|
||||||
|
WxMaSubscribeMessage.MsgData msgData = new WxMaSubscribeMessage.MsgData();
|
||||||
|
msgData.setName(item[0]);
|
||||||
|
msgData.setValue(item[1]);
|
||||||
|
msgDataList.add(msgData);
|
||||||
|
}
|
||||||
|
return msgDataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据微信官方发送的请求获取信息
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public NotificationParser getNotificationParser(HttpServletRequest request) {
|
||||||
|
System.out.println("---------------------------获取信息-------------------------------");
|
||||||
|
// 获取RSA配置
|
||||||
|
NotificationParser notificationParser = new NotificationParser(wxPayConfig.getRSAConfig());
|
||||||
|
// 构建请求
|
||||||
|
StringBuilder bodyBuilder = new StringBuilder();
|
||||||
|
BufferedReader reader = request.getReader();
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
bodyBuilder.append(line);
|
||||||
|
}
|
||||||
|
String body = bodyBuilder.toString();
|
||||||
|
String timestamp = request.getHeader("Wechatpay-Timestamp");
|
||||||
|
String nonce = request.getHeader("Wechatpay-Nonce");
|
||||||
|
String signature = request.getHeader("Wechatpay-Signature");
|
||||||
|
String singType = request.getHeader("Wechatpay-Signature-Type");
|
||||||
|
String wechatPayCertificateSerialNumber = request.getHeader("Wechatpay-Serial");
|
||||||
|
requestParam = new RequestParam.Builder()
|
||||||
|
.serialNumber(wechatPayCertificateSerialNumber)
|
||||||
|
.nonce(nonce)
|
||||||
|
.signature(signature)
|
||||||
|
.timestamp(timestamp)
|
||||||
|
.signType(singType)
|
||||||
|
.body(body)
|
||||||
|
.build();
|
||||||
|
System.out.println(requestParam.toString());
|
||||||
|
System.out.println("---------------------------信息获取完毕-------------------------------");
|
||||||
|
return notificationParser;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,23 +0,0 @@
|
||||||
package com.cultural.heritage.utils;
|
|
||||||
|
|
||||||
import cn.hutool.core.date.DateTime;
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class AppointmentDateUtil {
|
|
||||||
|
|
||||||
// 将当天及未来三天的日期加入到集合中
|
|
||||||
public static List<String> getDates() {
|
|
||||||
List<String> dates = new ArrayList<>();
|
|
||||||
for (int i = 0; i < 4; i ++ ) {
|
|
||||||
DateTime date = DateUtil.date();
|
|
||||||
DateTime dateTime = DateUtil.offsetDay(date, i);
|
|
||||||
String formatDate = DateUtil.formatDate(dateTime);
|
|
||||||
dates.add(formatDate);
|
|
||||||
}
|
|
||||||
return dates;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
28
src/main/resources/apiclient_key.pem
Normal file
28
src/main/resources/apiclient_key.pem
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDQvDoLQ9+041aV
|
||||||
|
lLvDgIdhenuq54wx+UeuIWd2Zc4E4Io+47PCr6kzpbkLhq47//dKAG1Fobb2vCRu
|
||||||
|
HG+CUfhkOzYLxt9qC4k9TOAtQPWp3Hc3dTldw42C/pGzh8aro7rHtpRHDzQYdJgB
|
||||||
|
w4dPQ0+RoZ2U9meiGWsy2DVOydPVxabxN9gFeeP5FRKjZP2JUAoKJRgWrBD9Fgyn
|
||||||
|
mX/crOa8z5HTBK/LY+jBy57Bp9ZpUS9nDIpXSgdI7mZn3xvLmGfjki8WG9X8Ad99
|
||||||
|
jvyTzD0HDcm7XoGo+Rp2Evh0pqQQf33R/OkH1WIFtcrqfwGUugTLDfIrFvDr3Qgc
|
||||||
|
KE2Z2U7pAgMBAAECggEAXgIn8iLjgchRmpSd6/LbBh/vyoz2KxumGNqaikxXeQLX
|
||||||
|
wHM05p3OiqA8suA5YHRrnzyJ+i5XBNC/Z4gPAJaCVEIGmU88F7qSWLVi0X7MJXBR
|
||||||
|
kPyOlZgZB8I3RLAF3g+jc4bbSRWj1M/OFh1Ft4ENOP2cxxYinnLsQL33ZECp00Cc
|
||||||
|
IXlX4lqjkoFbBaeCZLEV5tzZ3R/NsYZ5HTtvEh+vX7WdIqmgfL/cndfC+fIlWqbi
|
||||||
|
kKITyfI//Ik02/07qbFaZOwCLAQccUBT/0K8v7b0rqr0XeiqN3a+lXkVY6DpFxXx
|
||||||
|
aplsZ8rljBZ51AcAw8bS/JpwMkAQ5tYbgN2luEq3MQKBgQD/x2yk6YECbutRDsFA
|
||||||
|
EOlZK1cwMbJSkCMgVxIrfzv0Ubj937CCzZ7StxiHCxAa3+Oj8uX3aL57ZEatudyU
|
||||||
|
PsbZP6WWMqD3HiWUZoD1qcqRbp57FR9a3sFkgXoN9o93xdLiUS8LVAVLaqGSfO76
|
||||||
|
o7euReXlK+hNAFmkAwFsPnVdawKBgQDQ6mWSaefUfDVddw8mPdgCtjCIKMBWTNs9
|
||||||
|
U0ygVEsDs2FDxcC8175GQBbCNvtgh7DxWfOs847TVjH2CpZk74vSyt0Y59295Xx+
|
||||||
|
t4Vn3CHCBxvYGIRCTOXjBRRUOxQLXjb+X6XN3y9pxhkhVdwr5m5q49JIWcNyNuAJ
|
||||||
|
LTqq6CLl+wKBgAjaAeyDGC/ZXtNjS1TIQQsQ8Od+EMnCqzSHTt2qfYyq91fx0c31
|
||||||
|
B7YLGBI0U85aSSp3UXYKbe0fP0Lr17JZqdAC39wezGtA49QK6BOYWKZHybxAsuEW
|
||||||
|
LGMqB+tLyRNACVhDrvkZY0WE3yqOoEaUO9sQGDCiIFvp0zBV2krArpcZAoGAHiwM
|
||||||
|
GVY0RireJi6AwJwj61hWsAN6q7wT2cqDAZDK+LDadkhEKsHZ2Bl/b/My4OEX+/Nq
|
||||||
|
zuqqEPmc45Tp3Y//GKV1wxgRnVBcZ4yntrVDJtuR+Oapi03B0cS1B+k0XuPve1Nj
|
||||||
|
BdWa6mLS1E6rKqfwAH4Aq7RTFta4Cns+wtod2CsCgYAu7gHrFJfB6C/Dl93ZXTiL
|
||||||
|
HQdxpk0+L0hmXYaHFVK+0L2lswd7jlx6NLE3CNKEbUVr2fdhi8Qr2PLqiK/sAUCD
|
||||||
|
yRN6z17oSZ6eUfax5wKO5yXkuKq9DAoWpLitLgQmrxV1xfBx/q8ojVnFAG17q3F+
|
||||||
|
lN+FSz/IRCR9pAaVuVKw0w==
|
||||||
|
-----END PRIVATE KEY-----
|
|
@ -61,11 +61,26 @@ hwyun:
|
||||||
|
|
||||||
wx:
|
wx:
|
||||||
mini:
|
mini:
|
||||||
appId: wx3f968a09e31d6bed
|
appId: wx61b63e27bddf4ea2
|
||||||
appSecret: 847bdda7c2b01e88d59948b9ba50ef8d
|
appSecret: 5ef9e1f17acd8180afe2d80199fd466e
|
||||||
official:
|
official:
|
||||||
appId: wx5d04ca2de0e628a8
|
appId: wx5d04ca2de0e628a8
|
||||||
appSecret: 495af5bc4df1b86ffcfc21bb12daea76
|
appSecret: 495af5bc4df1b86ffcfc21bb12daea76
|
||||||
|
pay:
|
||||||
|
#应用id(小程序id)
|
||||||
|
appId: wx61b63e27bddf4ea2
|
||||||
|
#商户号
|
||||||
|
merchantId: 1700326544
|
||||||
|
#商户API私钥
|
||||||
|
privateKeyPath: apiclient_key.pem
|
||||||
|
#商户证书序列号
|
||||||
|
merchantSerialNumber: 6DC8953AB741D309920DA650B92F837BE38A2757
|
||||||
|
#商户APIv3密钥
|
||||||
|
apiV3Key: fbemuj4Xql7CYlQJAoTEPYxvPSNgYT2t
|
||||||
|
# 通知地址
|
||||||
|
notifyUrl: https://winning-mouse-internally.ngrok-free.app
|
||||||
|
# notifyUrl: http://localhost:9092
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
knife4j:
|
knife4j:
|
||||||
|
|
7
src/main/resources/mapper/TimeIntervalMapper.xml
Normal file
7
src/main/resources/mapper/TimeIntervalMapper.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?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="com.cultural.heritage.mapper.TimeIntervalMapper">
|
||||||
|
|
||||||
|
</mapper>
|
39
src/test/java/com/cultural/heritage/test/Animal.java
Normal file
39
src/test/java/com/cultural/heritage/test/Animal.java
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package com.cultural.heritage.test;
|
||||||
|
|
||||||
|
class Animal {
|
||||||
|
String name;
|
||||||
|
int age;
|
||||||
|
|
||||||
|
public Animal(String name, int age) {
|
||||||
|
this.name = name;
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Bird extends Animal {
|
||||||
|
public Bird(String name, int age) {
|
||||||
|
super(name, age);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fly() {
|
||||||
|
System.out.println(name + " 能飞行");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showBirdInfo() {
|
||||||
|
System.out.println("鸟的名称: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Bird bird = new Bird("麻雀", 2);
|
||||||
|
bird.showBirdInfo();
|
||||||
|
bird.fly();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,11 @@
|
||||||
package com.cultural.heritage.test;
|
package com.cultural.heritage.test;
|
||||||
|
|
||||||
public class B {
|
public class B {
|
||||||
public Long num = 10L;
|
static {
|
||||||
|
System.out.println("静态块已执行");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new B(); // 创建对象,观察静态块是否执行
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user