18 Commits

Author SHA1 Message Date
wol
52772c4e13 上传文件至 sql脚本/客户管理完整sql 2025-01-12 23:44:16 +08:00
wol
2cb02bc4c7 上传文件至 sql脚本 2025-01-12 23:43:56 +08:00
wol
e4d2affa2c 上传文件至 sql脚本 2025-01-12 23:43:31 +08:00
wol
44fa58536a 上传文件至 面试题 2025-01-12 23:43:01 +08:00
wol
8decbd4df0 上传文件至 讲义 2025-01-12 23:41:17 +08:00
wol
caec81c767 上传文件至 讲义 2025-01-12 23:40:42 +08:00
wol
f06af34163 添加 ReadMe.md 2025-01-12 23:39:20 +08:00
JIAN
921a83d5c3 Merge branch 'dev_market' 2024-10-01 15:57:17 +08:00
JIAN
0d8561edc7 Merge branch 'dev_health' 2024-09-20 11:00:33 +08:00
JIAN
b4d10a7306 feat(health):新增延时队列处理超时订单 2024-09-20 11:00:06 +08:00
JIAN
084455fd76 fix(health):修复已预约人数没有跟随订单变化的bug 2024-09-17 23:17:09 +08:00
JIAN
9d3d19ef7a feat(health):新增统计不同订单状态订单的数量的功能 2024-09-17 22:54:11 +08:00
JIAN
db85c197a8 feat(health):新增用户取消/退款订单的功能 2024-09-16 23:16:06 +08:00
JIAN
a48fae5d30 feat(health):新增MQ接收支付成功结果的功能 2024-09-16 22:31:32 +08:00
JIAN
79b7dbcadd feat(health):新增用户下单及支付的相关功能 2024-09-16 13:13:37 +08:00
JIAN
a0fa46f873 feat(health):新增订单查询相关功能
1. 分页查询 2. 查询订单详情
2024-09-14 23:19:26 +08:00
JIAN
6003aca88e feat(health):新增预约设置相关功能
1. 查询某月的预约设置 2. 查询可用的预约日期 3. (批量)设置预约人数
2024-09-14 21:57:39 +08:00
JIAN
c1dce10d9e refactor(health):导入项目体检模块初始工程 2024-09-14 21:55:06 +08:00
143 changed files with 10580 additions and 0 deletions

3
ReadMe.md Normal file
View File

@@ -0,0 +1,3 @@
## 云岚到家
飞书讲义https://mx67xggunk5.feishu.cn/wiki/P93bwwgNoihG7yk7PEzcpKn6nbZ

9
jzo2o-health/Dockerfile Normal file
View File

@@ -0,0 +1,9 @@
FROM openjdk:11-jdk
LABEL maintainer="研究院研发组 <research-maint@itcast.cn>"
RUN echo "Asia/Shanghai" > /etc/timezone
ARG PACKAGE_PATH=./target/jzo2o-health.jar
ADD ${PACKAGE_PATH:-./} app.jar
EXPOSE 8080
EXPOSE 9999
ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS app.jar"]

103
jzo2o-health/pom.xml Normal file
View File

@@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-health</artifactId>
<version>1.0-SNAPSHOT</version>
<name>jzo2o-health</name>
<description>jzo2o-health</description>
<parent>
<artifactId>jzo2o-parent</artifactId>
<groupId>com.jzo2o</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-mvc</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-knife4j-web</artifactId>
</dependency>
<!--单元测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-api</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-thirdparty</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-mysql</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-redis</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-xxl-job</artifactId>
</dependency>
<dependency>
<groupId>com.jzo2o</groupId>
<artifactId>jzo2o-rabbitmq</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.jzo2o.health.HealthApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,18 @@
package com.jzo2o.health;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@Slf4j
@MapperScan("com.jzo2o.health.mapper")
@SpringBootApplication
public class HealthApplication {
public static void main(String[] args) {
SpringApplication.run(HealthApplication.class, args);
log.info("家政服务-健康服务启动");
}
}

View File

@@ -0,0 +1,19 @@
package com.jzo2o.health.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 忽略token校验的注解
* 虽然在注册JwtTokenInterceptor时可以指定忽略的请求路径但是无法指定请求方式。
* 对于同一个请求url请求方式可以有多种无法做到区别对待
* 例如请求url为/dish其中POST方式对应的方法需要进行token校验GET方式对应的方法不需要进行token校验
* 此时就需要通过IgnoreToken注解来标识当前方法不需要校验
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreToken {
}

View File

@@ -0,0 +1,61 @@
package com.jzo2o.health.config;
import com.jzo2o.health.constant.HealthMqConstants;
import com.jzo2o.rabbitmq.config.RabbitMqConfiguration;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import java.util.concurrent.TimeUnit;
/**
* RabbitMQ延时队列
* @author JIAN
*/
@Configuration
@Import(RabbitMqConfiguration.class)
public class DelayQueueConfiguration {
@Bean
public Exchange delayExchange() {
return ExchangeBuilder
.topicExchange(HealthMqConstants.Exchanges.HEALTH_ORDER)
.durable(true)
.build();
}
@Bean
public Queue delayQueueIn() {
return QueueBuilder
.durable(HealthMqConstants.Queues.DELAY_IN)
// 订单默认15分钟超时
.ttl((int) TimeUnit.MINUTES.toMillis(15))
.deadLetterExchange(HealthMqConstants.Exchanges.HEALTH_ORDER)
.deadLetterRoutingKey(HealthMqConstants.RoutingKeys.ORDER_OVERTIME_OUT)
.build();
}
@Bean
public Queue delayQueueOut() {
return QueueBuilder.durable(HealthMqConstants.Queues.DELAY_OUT)
.build();
}
@Bean
public Binding bindDelayQueueIn() {
return BindingBuilder
.bind(delayQueueIn())
.to(delayExchange())
.with(HealthMqConstants.RoutingKeys.ORDER_OVERTIME_IN)
.noargs();
}
@Bean
public Binding bindDelayQueueOut() {
return BindingBuilder
.bind(delayQueueOut())
.to(delayExchange())
.with(HealthMqConstants.RoutingKeys.ORDER_OVERTIME_OUT)
.noargs();
}
}

View File

@@ -0,0 +1,23 @@
package com.jzo2o.health.config;
import com.jzo2o.common.utils.JwtTool;
import com.jzo2o.health.properties.ApplicationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
/**
* @author itcast
*/
@Configuration
public class JwtConfiguration {
@Resource
private ApplicationProperties applicationProperties;
@Bean
public JwtTool jwtTool() {
return new JwtTool(applicationProperties.getJwtKey());
}
}

View File

@@ -0,0 +1,19 @@
package com.jzo2o.health.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* @author itcast
*/
@Configuration
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}

View File

@@ -0,0 +1,30 @@
package com.jzo2o.health.config;
import com.jzo2o.health.interceptor.JwtTokenInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
@Slf4j
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Resource
private JwtTokenInterceptor jwtTokenInterceptor;
/**
* 注册拦截器
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtTokenInterceptor)
.addPathPatterns("/admin/**", "/user/**")//指定拦截的路径
.excludePathPatterns("/open/**");//添加不拦截路径
}
}

View File

@@ -0,0 +1,23 @@
package com.jzo2o.health.constant;
import com.jzo2o.common.constants.MqConstants;
/**
* 即刻体检MQ常量
* @author JIAN
*/
public interface HealthMqConstants extends MqConstants {
interface Exchanges extends MqConstants.Exchanges {
String HEALTH_ORDER = "health.exchange.topic.order";
}
interface Queues extends MqConstants.Queues {
String DELAY_IN = "health.queue.orders.delay.in";
String DELAY_OUT = "health.queue.orders.delay.out";
}
interface RoutingKeys extends MqConstants.RoutingKeys {
String ORDER_OVERTIME_IN = "order.overtime.in";
String ORDER_OVERTIME_OUT = "order.overtime.out";
}
}

View File

@@ -0,0 +1,19 @@
package com.jzo2o.health.constant;
/**
* 支付相关常量
*
* @author itcast
* @create 2023/11/7 17:46
**/
public class RedisConstants {
/**
* 用户端订单滚动分页查询
*/
public static final String ORDER_PAGE_QUERY = "HEALTH:ORDERS:PAGE_QUERY:PAGE_%s";
/**
* 用户端下单订单号生成器
*/
public static final String ORDER_ID_GENERATOR = "HEALTH:ORDERS:GENERATOR";
}

View File

@@ -0,0 +1,20 @@
package com.jzo2o.health.constant;
/**
* 支付相关常量
*
* @author itcast
* @create 2023/11/7 17:46
**/
public class TradeConstants {
/**
* 支付来源
*/
public static final String PRODUCT_APP_ID="health";
/**
* rabbitmq支付更新状态队列
*/
public static final String MQ_TRADE_QUEUE="jzo2o.queue.health.trade.update.Status";
}

View File

@@ -0,0 +1,43 @@
package com.jzo2o.health.controller.admin;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.health.model.dto.request.OrdersPageQueryReqDTO;
import com.jzo2o.health.model.dto.response.AdminOrdersDetailResDTO;
import com.jzo2o.health.model.dto.response.OrdersResDTO;
import com.jzo2o.health.service.IOrderManagerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @author itcast
*/
@RestController("adminOrdersQueryController")
@RequestMapping("/admin/orders")
@Api(tags = "管理端 - 订单查询接口")
public class OrdersQueryController {
@Resource
private IOrderManagerService orderManagerService;
@ApiOperation("分页查询")
@GetMapping("/page")
public PageResult<OrdersResDTO> pageQuery(OrdersPageQueryReqDTO ordersPageQueryReqDTO) {
return orderManagerService.pageQuery(ordersPageQueryReqDTO);
}
@GetMapping("/{id}")
@ApiOperation("根据订单id查询")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "订单id", required = true, dataTypeClass = Long.class)
})
public AdminOrdersDetailResDTO aggregation(@PathVariable("id") Long id) {
return orderManagerService.getAggregationInfo(id);
}
}

View File

@@ -0,0 +1,28 @@
package com.jzo2o.health.controller.admin;
import com.jzo2o.health.model.dto.response.OrdersCountResDTO;
import com.jzo2o.health.service.IOrderManagerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @author itcast
*/
@RestController("adminOrdersStatsController")
@RequestMapping("/admin/orders")
@Api(tags = "管理端 - 根据状态统计订单数量")
public class OrdersStatsController {
@Resource
private IOrderManagerService orderManagerService;
@GetMapping("/countByStatus")
@ApiOperation("根据状态统计数量")
public OrdersCountResDTO countByStatus() {
return orderManagerService.countByStatus();
}
}

View File

@@ -0,0 +1,51 @@
package com.jzo2o.health.controller.admin;
import com.alibaba.excel.EasyExcel;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.health.model.excel.ReservationImportData;
import com.jzo2o.health.service.IReservationSettingService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.InputStream;
import java.util.List;
/**
* 预约设置操作
* @author itcast
*/
@Slf4j
@RestController("adminReservationBatchSettingController")
@RequestMapping("/admin/reservation-setting")
@Api(tags = "管理端 - 批量预约设置相关接口")
public class ReservationBatchSettingController {
@Resource
private IReservationSettingService reservationSettingService;
@PostMapping("/upload")
@ApiOperation("上传文件批量预约设置")
public void upload(@RequestPart("file") MultipartFile file) {
List<ReservationImportData> reservationDataList;
try (InputStream inputStream = file.getInputStream()) {
reservationDataList = EasyExcel.read(inputStream)
.head(ReservationImportData.class)
.sheet("预约设置模板")
.doReadSync();
} catch (Exception e) {
// 防止过度包装
throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e);
}
if (CollUtils.isNotEmpty(reservationDataList)) {
reservationSettingService.editNumberByDateBatch(reservationDataList);
}
}
}

View File

@@ -0,0 +1,42 @@
package com.jzo2o.health.controller.admin;
import com.jzo2o.health.model.dto.request.ReservationSettingUpsertReqDTO;
import com.jzo2o.health.model.dto.response.ReservationSettingResDTO;
import com.jzo2o.health.service.IReservationSettingService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.time.YearMonth;
import java.util.List;
/**
* 预约设置操作
*
* @author itcast
*/
@Slf4j
@RestController("adminReservationSettingController")
@RequestMapping("/admin/reservation-setting")
@Api(tags = "管理端 - 预约设置相关接口")
public class ReservationSettingController {
@Resource
private IReservationSettingService reservationSettingService;
@GetMapping("/getReservationSettingByMonth")
@ApiOperation("按月查询预约设置")
@ApiImplicitParam(name = "date", value = "月份格式yyyy-MM", required = true, dataTypeClass = String.class)
public List<ReservationSettingResDTO> getReservationSettingByMonth(@RequestParam("date") String date) {
YearMonth yearMonth = YearMonth.parse(date);
return reservationSettingService.getReservationSettingByMonth(yearMonth);
}
@PutMapping("/editNumberByDate")
@ApiOperation("编辑预约设置")
public void editNumberByDate(@RequestBody ReservationSettingUpsertReqDTO reservationSettingUpsertReqDTO) {
reservationSettingService.editNumberByDate(reservationSettingUpsertReqDTO);
}
}

View File

@@ -0,0 +1,36 @@
package com.jzo2o.health.controller.admin;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.health.model.domain.Setmeal;
import com.jzo2o.health.model.dto.request.CommonPageQueryReqDTO;
import com.jzo2o.health.service.ISetmealService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* 体检套餐管理
*/
@RestController("adminSetmealController")
@RequestMapping("/admin/setmeal")
@Api(tags = "管理端 - 套餐相关接口")
public class SetmealController {
@Resource
private ISetmealService setmealService;
@PostMapping("/add")
@ApiOperation("新增套餐")
@ApiImplicitParam(name = "checkgroupIds", value = "检查组id列表", required = true, dataTypeClass = Integer.class)
public void add(@RequestBody Setmeal setmeal, @RequestParam("checkgroupIds") Integer[] checkgroupIds) {
setmealService.add(setmeal, checkgroupIds);
}
@GetMapping("/findPage")
@ApiOperation("分页查询套餐")
public PageResult<Setmeal> findPage(CommonPageQueryReqDTO commonPageQueryReqDTO) {
return setmealService.findPage(commonPageQueryReqDTO);
}
}

View File

@@ -0,0 +1,40 @@
package com.jzo2o.health.controller.open;
import com.jzo2o.health.model.dto.request.LoginReqDTO;
import com.jzo2o.health.model.dto.request.MemberLoginReqDTO;
import com.jzo2o.health.model.dto.response.LoginResDTO;
import com.jzo2o.health.service.ILoginService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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 javax.annotation.Resource;
/**
* @author itcast
*/
@RestController("openLoginController")
@RequestMapping("/open/login")
@Api(tags = "白名单接口 - 登录相关接口")
public class LoginController {
@Resource
private ILoginService loginService;
@PostMapping("/admin")
@ApiOperation("管理员登录")
public LoginResDTO adminLogin(@RequestBody LoginReqDTO loginReqDTO) {
String token = loginService.adminLogin(loginReqDTO);
return new LoginResDTO(token);
}
@PostMapping("/user")
@ApiOperation("普通用户登录")
public LoginResDTO userLogin(@RequestBody MemberLoginReqDTO memberLoginReqDTO) {
String token = loginService.memberLogin(memberLoginReqDTO);
return new LoginResDTO(token);
}
}

View File

@@ -0,0 +1,50 @@
package com.jzo2o.health.controller.user;
import com.jzo2o.api.trade.enums.PayChannelEnum;
import com.jzo2o.health.model.dto.request.PlaceOrderReqDTO;
import com.jzo2o.health.model.dto.response.OrdersPayResDTO;
import com.jzo2o.health.model.dto.response.PlaceOrderResDTO;
import com.jzo2o.health.service.IOrderCreateService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* @author itcast
*/
@RestController("userOrdersController")
@RequestMapping("/user/orders")
@Api(tags = "用户端 - 下单支付相关接口")
public class OrdersController {
@Resource
private IOrderCreateService orderCreateService;
@ApiOperation("下单接口")
@PostMapping("/place")
public PlaceOrderResDTO place(@RequestBody PlaceOrderReqDTO placeOrderReqDTO) {
return orderCreateService.placeOrder(placeOrderReqDTO);
}
@PutMapping("/pay/{id}")
@ApiOperation("订单支付")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "订单id", required = true, dataTypeClass = Long.class),
@ApiImplicitParam(name = "tradingChannel", value = "支付渠道ALI_PAY、WECHAT_PAY", required = true, dataTypeClass = PayChannelEnum.class),
})
public OrdersPayResDTO pay(@PathVariable("id") Long id, @RequestParam("tradingChannel") PayChannelEnum tradingChannel) {
return orderCreateService.payOrder(id, tradingChannel);
}
@GetMapping("/pay/{id}/result")
@ApiOperation("查询订单支付结果")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "订单id", required = true, dataTypeClass = Long.class)
})
public OrdersPayResDTO payResult(@PathVariable("id") Long id) {
return orderCreateService.getPayResult(id);
}
}

View File

@@ -0,0 +1,44 @@
package com.jzo2o.health.controller.user;
import com.jzo2o.health.model.dto.response.OrdersDetailResDTO;
import com.jzo2o.health.model.dto.response.OrdersResDTO;
import com.jzo2o.health.service.IOrderManagerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* @author itcast
*/
@RestController("userOrdersQueryController")
@RequestMapping("/user/orders")
@Api(tags = "用户端 - 订单查询相关接口")
public class OrdersQueryController {
@Resource
private IOrderManagerService orderManagerService;
@ApiOperation("滚动分页查询")
@GetMapping("/page")
@ApiImplicitParams({
@ApiImplicitParam(name = "ordersStatus", value = "订单状态0未支付100待体检200已体检300已关闭400已取消", dataTypeClass = Integer.class),
@ApiImplicitParam(name = "sortBy", value = "排序字段", dataTypeClass = Long.class)
})
public List<OrdersResDTO> pageQuery(@RequestParam(value = "ordersStatus", required = false) Integer ordersStatus,
@RequestParam(value = "sortBy", required = false) Long sortBy) {
return orderManagerService.pageQuery(ordersStatus, sortBy);
}
@GetMapping("/{id}")
@ApiOperation("根据订单id查询")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "订单id", required = true, dataTypeClass = Long.class)
})
public OrdersDetailResDTO detail(@PathVariable("id") Long id) {
return orderManagerService.getOrderById(id);
}
}

View File

@@ -0,0 +1,38 @@
package com.jzo2o.health.controller.user;
import com.jzo2o.health.model.dto.request.OrdersCancelReqDTO;
import com.jzo2o.health.service.IOrderCancelService;
import com.jzo2o.health.service.IOrderRefundService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @author itcast
*/
@RestController("userOrdersRefundController")
@RequestMapping("/user/orders")
@Api(tags = "用户端 - 取消订单退款相关接口")
public class OrdersRefundController {
@Resource
private IOrderCancelService orderCancelService;
@Resource
private IOrderRefundService orderRefundService;
@PutMapping("/cancel")
@ApiOperation("订单取消")
public void cancel(@RequestBody OrdersCancelReqDTO ordersCancelReqDTO) {
orderCancelService.cancelOrder(ordersCancelReqDTO);
}
@PutMapping("/refund")
@ApiOperation("订单退款")
public void refund(@RequestBody OrdersCancelReqDTO ordersCancelReqDTO) {
orderRefundService.refundOrder(ordersCancelReqDTO);
}
}

View File

@@ -0,0 +1,38 @@
package com.jzo2o.health.controller.user;
import com.jzo2o.health.annotation.IgnoreToken;
import com.jzo2o.health.model.dto.response.ReservationDateResDTO;
import com.jzo2o.health.service.IReservationSettingService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.time.YearMonth;
/**
* 预约设置操作
* @author itcast
*/
@Slf4j
@RestController("userReservationSettingController")
@RequestMapping("/user/reservation-setting")
@Api(tags = "用户端 - 预约设置相关接口")
public class ReservationSettingController {
@Resource
private IReservationSettingService reservationSettingService;
@GetMapping("/getReservationDateByMonth")
@IgnoreToken
@ApiOperation("按月查询可预约日期")
@ApiImplicitParam(name = "month", value = "月份格式yyyy-MM", required = true, dataTypeClass = String.class)
public ReservationDateResDTO getReservationDateByMonth(@RequestParam("month") String month) {
YearMonth yearMonth = YearMonth.parse(month);
return reservationSettingService.getReservationDateByMonth(yearMonth);
}
}

View File

@@ -0,0 +1,39 @@
package com.jzo2o.health.controller.user;
import com.jzo2o.health.annotation.IgnoreToken;
import com.jzo2o.health.model.domain.Setmeal;
import com.jzo2o.health.model.dto.response.SetmealDetailResDTO;
import com.jzo2o.health.service.ISetmealService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController("userSetmealController")
@RequestMapping("/user/setmeal")
@Api(tags = "用户端 - 套餐相关接口")
public class SetmealController {
@Resource
private ISetmealService setmealService;
@GetMapping("/getSetmeal")
@IgnoreToken
@ApiOperation("获取所有套餐信息")
public List<Setmeal> getSetmeal() {
return setmealService.findAll();
}
@GetMapping("/findDetail/{id}")
@IgnoreToken
@ApiOperation("根据id查询套餐信息")
@ApiImplicitParam(name = "id", value = "套餐id", required = true, dataTypeClass = Integer.class)
public SetmealDetailResDTO findById(@PathVariable("id") Integer id) {
return setmealService.findDetail(id);
}
}

View File

@@ -0,0 +1,25 @@
package com.jzo2o.health.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author itcast
*/
@Getter
@AllArgsConstructor
public enum OrderPayStatusEnum {
NO_PAY(0, "未支付"),
PAY_SUCCESS(1, "已支付"),
REFUNDING(2, "退款中"),
REFUND_SUCCESS(3, "退款成功"),
REFUND_FAIL(4, "退款失败");
@EnumValue
@JsonValue
private final Integer status;
private final String desc;
}

View File

@@ -0,0 +1,39 @@
package com.jzo2o.health.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author itcast
*/
@Getter
@AllArgsConstructor
public enum OrderStatusEnum {
NO_PAY(0, "待支付"),
WAITING_CHECKUP(100, "待体检"),
COMPLETED_CHECKUP(200, "已体检"),
CLOSED(300, "已关闭"),
CANCELLED(400, "已取消");
@EnumValue
@JsonValue
private final Integer status;
private final String desc;
/**
* 根据状态值获得对应枚举
*
* @param status 状态
* @return 状态对应枚举
*/
public static OrderStatusEnum codeOf(Integer status) {
for (OrderStatusEnum orderStatusEnum : values()) {
if (orderStatusEnum.status.equals(status)) {
return orderStatusEnum;
}
}
return null;
}
}

View File

@@ -0,0 +1,83 @@
package com.jzo2o.health.interceptor;
import com.jzo2o.common.expcetions.RequestUnauthorizedException;
import com.jzo2o.common.model.CurrentUserInfo;
import com.jzo2o.common.utils.JwtTool;
import com.jzo2o.common.utils.StringUtils;
import com.jzo2o.health.annotation.IgnoreToken;
import com.jzo2o.health.model.UserThreadLocal;
import com.jzo2o.health.properties.ApplicationProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* token检查拦截器用于检查后台系统发送的请求
*/
@Slf4j
@Component
public class JwtTokenInterceptor implements HandlerInterceptor {
@Resource
private ApplicationProperties applicationProperties;
/**
* token header名称
*/
private static final String HEADER_TOKEN = "Authorization";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
log.info("拦截器拦截到请求:{}", request.getRequestURI());
// 如果不是映射到方法的请求则直接放行,例如 /doc.html
if (!(handler instanceof HandlerMethod)) {
log.info("{}无需处理,直接放行", request.getRequestURI());
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
//检查当前请求的Controller方法上是否有IgnoreToken注解
boolean hasIgnoreToken = handlerMethod.hasMethodAnnotation(IgnoreToken.class);
if (hasIgnoreToken) {
return true;
}
//获取前端提交的token
String token = request.getHeader(HEADER_TOKEN);
if (StringUtils.isEmpty(token)) {
throw new RequestUnauthorizedException();
}
log.info("获取到token:{}", token);
try {
log.info("开始解析token");
String tokenKey = applicationProperties.getTokenKey().get(JwtTool.getUserType(token) + "");
if (StringUtils.isEmpty(tokenKey)) {
throw new RequestUnauthorizedException();
}
JwtTool jwtTool = new JwtTool(tokenKey);
CurrentUserInfo currentUserInfo = jwtTool.parseToken(token);
UserThreadLocal.set(currentUserInfo);
//token解析成功放行
return true;
} catch (Exception ex) {
log.error("token解析失败");
//401表示未授权需要前端配合跳转回登录页面
response.setStatus(401);
return false;
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
// 清理用户信息
UserThreadLocal.clear();
}
}

View File

@@ -0,0 +1,40 @@
package com.jzo2o.health.job;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.health.model.domain.OrdersRefund;
import com.jzo2o.health.properties.OrdersJobProperties;
import com.jzo2o.health.service.IOrderRefundService;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
/**
* 订单退款任务
* @author JIAN
*/
@Slf4j
@Component
@SuppressWarnings("unused")
public class OrderRefundJob {
@Resource
private IOrderRefundService orderRefundService;
@Resource
private OrdersJobProperties ordersJobProperties;
/**
* 订单退款异步任务
*/
@XxlJob(value = "handleRefundOrders")
public void handleRefundOrders() {
List<OrdersRefund> latestRefundInfo = orderRefundService.getLatestRefundInfo(ordersJobProperties.getRefundOrderCount());
if (CollUtils.isEmpty(latestRefundInfo)) {
log.info("没有需要退款的订单");
}
latestRefundInfo.forEach(refundInfo -> orderRefundService.refundOrder(refundInfo));
}
}

View File

@@ -0,0 +1,133 @@
package com.jzo2o.health.listener;
import com.jzo2o.api.trade.TradingApi;
import com.jzo2o.api.trade.dto.response.TradingResDTO;
import com.jzo2o.api.trade.enums.TradingStateEnum;
import com.jzo2o.common.constants.UserType;
import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.common.model.msg.TradeStatusMsg;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.JsonUtils;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.health.constant.HealthMqConstants;
import com.jzo2o.health.constant.TradeConstants;
import com.jzo2o.health.enums.OrderPayStatusEnum;
import com.jzo2o.health.enums.OrderStatusEnum;
import com.jzo2o.health.model.OrderUpdateStatusDTO;
import com.jzo2o.health.model.domain.Orders;
import com.jzo2o.health.model.domain.OrdersCancelled;
import com.jzo2o.health.service.IOrderCancelService;
import com.jzo2o.health.service.IOrderCommonService;
import com.jzo2o.health.service.IOrderCreateService;
import com.jzo2o.health.service.IReservationSettingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
/**
* 监听MQ消息
* @author itcast
**/
@Slf4j
@Component
public class OrderStatusListener {
@Resource
private IOrderCommonService orderCommonService;
@Resource
private TransactionTemplate transactionTemplate;
@Resource
private IOrderCancelService orderCancelService;
@Resource
private IReservationSettingService reservationSettingService;
@Resource
private TradingApi tradingApi;
/**
* 接收支付成功信息
* @param msg 消息
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = TradeConstants.MQ_TRADE_QUEUE),
exchange = @Exchange(name = HealthMqConstants.Exchanges.TRADE, type = ExchangeTypes.TOPIC),
key = HealthMqConstants.RoutingKeys.TRADE_UPDATE_STATUS))
public void listenTradeUpdatePayStatusMsg(String msg) {
log.info("接收到支付结果状态的消息 ({})-> {}", HealthMqConstants.Queues.ORDERS_TRADE_UPDATE_STATUS, msg);
List<TradeStatusMsg> msgList = JsonUtils.parseArray(msg).toList(TradeStatusMsg.class);
if (CollUtils.isEmpty(msgList)) {
return;
}
// 处理当前微服务并且支付成功的订单
List<TradeStatusMsg> tradeStatusMsgList = msgList.stream()
.filter(statusMsg -> IOrderCreateService.PRODUCT_APP_ID.equals(statusMsg.getProductAppId())
&& TradingStateEnum.YJS.getCode().equals(statusMsg.getStatusCode()))
.collect(Collectors.toList());
transactionTemplate.executeWithoutResult(status -> {
for (TradeStatusMsg tradeStatusMsg : tradeStatusMsgList) {
if (!orderCommonService.updateStatus(OrderUpdateStatusDTO.builder()
.id(tradeStatusMsg.getProductOrderNo())
.originStatus(OrderStatusEnum.NO_PAY)
.targetStatus(OrderStatusEnum.WAITING_CHECKUP)
.payStatus(OrderPayStatusEnum.PAY_SUCCESS)
.tradingOrderNo(tradeStatusMsg.getTradingOrderNo())
.transactionId(tradeStatusMsg.getTransactionId())
.tradingChannel(tradeStatusMsg.getTradingChannel())
.payTime(LocalDateTime.now()).build())) {
throw new DBException("更新订单状态失败");
}
}
});
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = HealthMqConstants.Queues.DELAY_OUT),
exchange = @Exchange(name = HealthMqConstants.Exchanges.HEALTH_ORDER, type = ExchangeTypes.TOPIC),
key = HealthMqConstants.RoutingKeys.ORDER_OVERTIME_OUT))
public void handleOverTimeOrder(String msg) {
Long orderId = Long.parseLong(msg);
if (ObjectUtils.isEmpty(orderId)) {
return;
}
Orders order = orderCommonService.getById(orderId);
if (ObjectUtils.isEmpty(order)) {
return;
}
if (order.getOrderStatus() == OrderStatusEnum.NO_PAY && order.getPayStatus() == OrderPayStatusEnum.NO_PAY) {
Long tradingOrderNo = order.getTradingOrderNo();
if (ObjectUtils.isNotEmpty(tradingOrderNo)) {
// 再次请求防止已支付
TradingResDTO tradingResDTO = tradingApi.findTradResultByTradingOrderNo(tradingOrderNo);
if (ObjectUtils.isNotEmpty(tradingResDTO) && tradingResDTO.getTradingState() == TradingStateEnum.YJS) {
return;
}
}
// 事务更新数据表(取消订单)
transactionTemplate.executeWithoutResult(status -> {
orderCancelService.cancelOrder(OrdersCancelled.builder()
.id(orderId)
.cancelTime(LocalDateTime.now())
.cancelReason("订单超时自动取消")
.cancellerType(UserType.SYSTEM)
.build());
// 已预约人数 - 1
reservationSettingService.plusReservationCount(order.getReservationDate(), -1);
});
}
}
}

View File

@@ -0,0 +1,16 @@
package com.jzo2o.health.mapper;
import com.jzo2o.health.model.domain.CheckgroupCheckitem;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author itcast
* @since 2023-10-31
*/
public interface CheckgroupCheckitemMapper extends BaseMapper<CheckgroupCheckitem> {
}

View File

@@ -0,0 +1,16 @@
package com.jzo2o.health.mapper;
import com.jzo2o.health.model.domain.Checkgroup;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author itcast
* @since 2023-10-31
*/
public interface CheckgroupMapper extends BaseMapper<Checkgroup> {
}

View File

@@ -0,0 +1,16 @@
package com.jzo2o.health.mapper;
import com.jzo2o.health.model.domain.Checkitem;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author itcast
* @since 2023-10-31
*/
public interface CheckitemMapper extends BaseMapper<Checkitem> {
}

View File

@@ -0,0 +1,16 @@
package com.jzo2o.health.mapper;
import com.jzo2o.health.model.domain.Member;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 普通用户 Mapper 接口
* </p>
*
* @author itcast
* @since 2023-11-02
*/
public interface MemberMapper extends BaseMapper<Member> {
}

View File

@@ -0,0 +1,16 @@
package com.jzo2o.health.mapper;
import com.jzo2o.health.model.domain.OrdersCancelled;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 订单取消表 Mapper 接口
* </p>
*
* @author itcast
* @since 2023-11-07
*/
public interface OrdersCancelledMapper extends BaseMapper<OrdersCancelled> {
}

View File

@@ -0,0 +1,21 @@
package com.jzo2o.health.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jzo2o.health.model.domain.Orders;
import com.jzo2o.health.model.dto.OrderCountDTO;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* <p>
* 订单表 Mapper 接口
* </p>
*
* @author itcast
* @since 2023-11-02
*/
public interface OrdersMapper extends BaseMapper<Orders> {
@Select("SELECT order_status AS orderStatus,COUNT(id) AS count FROM orders GROUP BY order_status")
List<OrderCountDTO> countStatus();
}

View File

@@ -0,0 +1,16 @@
package com.jzo2o.health.mapper;
import com.jzo2o.health.model.domain.OrdersRefund;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 订单退款表 Mapper 接口
* </p>
*
* @author itcast
* @since 2023-11-07
*/
public interface OrdersRefundMapper extends BaseMapper<OrdersRefund> {
}

View File

@@ -0,0 +1,25 @@
package com.jzo2o.health.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jzo2o.health.model.domain.ReservationSetting;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.time.LocalDate;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
* @author itcast
* @since 2023-11-01
*/
public interface ReservationSettingMapper extends BaseMapper<ReservationSetting> {
@Update("UPDATE reservation_setting SET reservations = reservations + #{count} WHERE order_date = #{time} AND reservations < number")
Integer plusReservationCount(@Param("time") LocalDate time, @Param("count") Integer count);
@Select("SELECT order_date FROM reservation_setting WHERE #{start} <= order_date AND order_date <= #{end}")
List<String> getReservationDate(@Param("start") LocalDate start, @Param("end") LocalDate end);
}

View File

@@ -0,0 +1,16 @@
package com.jzo2o.health.mapper;
import com.jzo2o.health.model.domain.SetmealCheckgroup;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author itcast
* @since 2023-10-31
*/
public interface SetmealCheckgroupMapper extends BaseMapper<SetmealCheckgroup> {
}

View File

@@ -0,0 +1,24 @@
package com.jzo2o.health.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jzo2o.health.model.domain.Setmeal;
import com.jzo2o.health.model.dto.response.SetmealDetailResDTO;
import org.apache.ibatis.annotations.Param;
/**
* <p>
* Mapper 接口
* </p>
*
* @author itcast
* @since 2023-10-31
*/
public interface SetmealMapper extends BaseMapper<Setmeal> {
/**
* 查询套餐详情(包含关联检查组、检查项)
*
* @param id 套餐id
* @return 套餐详情
*/
SetmealDetailResDTO findDetail(@Param("id") Integer id);
}

View File

@@ -0,0 +1,16 @@
package com.jzo2o.health.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jzo2o.health.model.domain.User;
/**
* <p>
* 管理员 Mapper 接口
* </p>
*
* @author itcast
* @since 2023-10-31
*/
public interface UserMapper extends BaseMapper<User> {
}

View File

@@ -0,0 +1,70 @@
package com.jzo2o.health.model;
import com.jzo2o.health.enums.OrderPayStatusEnum;
import com.jzo2o.health.enums.OrderStatusEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* 通用订单更新DTO
* @author JIAN
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrderUpdateStatusDTO {
/**
* 订单id
*/
private Long id;
/**
* 原订单状态
*/
private OrderStatusEnum originStatus;
/**
* 目标订单状态
*/
private OrderStatusEnum targetStatus;
/**
* 支付状态
*/
private OrderPayStatusEnum payStatus;
/**
* 支付时间
*/
private LocalDateTime payTime;
/**
* 支付服务交易单号
*/
private Long tradingOrderNo;
/**
* 第三方支付的交易号
*/
private String transactionId;
/**
* 支付服务退款单号
*/
private Long refundNo;
/**
* 第三方支付的退款单号
*/
private String refundId;
/**
* 支付渠道
*/
private String tradingChannel;
}

View File

@@ -0,0 +1,37 @@
package com.jzo2o.health.model;
import com.jzo2o.common.model.CurrentUserInfo;
public class UserThreadLocal {
private static final ThreadLocal<CurrentUserInfo> THREAD_LOCAL_USER = new ThreadLocal<>();
/**
* 获取当前用户id
*
* @return 用户id
*/
public static Long currentUserId() {
return THREAD_LOCAL_USER.get().getId();
}
public static CurrentUserInfo currentUser() {
return THREAD_LOCAL_USER.get();
}
/**
* 设置当前用户id
*
* @param currentUserInfo 当前用户信息
*/
public static void set(CurrentUserInfo currentUserInfo) {
THREAD_LOCAL_USER.set(currentUserInfo);
}
/**
* 清理当前线程中的用户信息
*/
public static void clear() {
THREAD_LOCAL_USER.remove();
}
}

View File

@@ -0,0 +1,61 @@
package com.jzo2o.health.model.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author itcast
* @since 2023-10-31
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("checkgroup")
public class Checkgroup implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 检查组编码
*/
private String code;
/**
* 检查组名称
*/
private String name;
/**
* 检查组助记码
*/
private String helpCode;
/**
* 检查组性别
*/
private String sex;
/**
* 检查组说明
*/
private String remark;
/**
* 检查组注意事项
*/
private String attention;
}

View File

@@ -0,0 +1,37 @@
package com.jzo2o.health.model.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* <p>
*
* </p>
*
* @author itcast
* @since 2023-10-31
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("checkgroup_checkitem")
public class CheckgroupCheckitem implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 检查组id
*/
private Integer checkgroupId;
/**
* 检查项id
*/
private Integer checkitemId;
}

View File

@@ -0,0 +1,72 @@
package com.jzo2o.health.model.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* <p>
*
* </p>
*
* @author itcast
* @since 2023-10-31
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("checkitem")
public class Checkitem implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 检查项编码
*/
private String code;
/**
* 检查项名称
*/
private String name;
/**
* 检查项性别0不限12
*/
private String sex;
/**
* 检查项适用年龄
*/
private String age;
/**
* 检查项价格
*/
private Float price;
/**
* 查检项类型,分为检查和检验两种
*/
private String type;
/**
* 检查项注意事项
*/
private String attention;
/**
* 检查项说明
*/
private String remark;
}

View File

@@ -0,0 +1,65 @@
package com.jzo2o.health.model.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 普通用户
* </p>
*
* @author itcast
* @since 2023-11-02
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("member")
public class Member implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
/**
* 昵称
*/
private String nickname;
/**
* 电话
*/
private String phone;
/**
* 头像
*/
private String avatar;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
/**
* 是否已删除0未删除1已删除
*/
private Integer isDeleted;
}

View File

@@ -0,0 +1,167 @@
package com.jzo2o.health.model.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.jzo2o.health.enums.OrderPayStatusEnum;
import com.jzo2o.health.enums.OrderStatusEnum;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* <p>
* 订单表
* </p>
*
* @author itcast
* @since 2023-11-02
*/
@Data
@Builder
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("orders")
public class Orders implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 订单id
*/
@TableId(value = "id", type = IdType.NONE)
private Long id;
/**
* 订单状态0未支付100待体检200已体检300已关闭400已取消
*/
private OrderStatusEnum orderStatus;
/**
* 支付状态0未支付1已支付2退款中3退款成功4退款失败
*/
private OrderPayStatusEnum payStatus;
/**
* 套餐id
*/
private Integer setmealId;
/**
* 套餐名称
*/
private String setmealName;
/**
* 套餐价格
*/
private BigDecimal setmealPrice;
/**
* 套餐适用性别0不限12
*/
private Integer setmealSex;
/**
* 套餐适用年龄
*/
private String setmealAge;
/**
* 套餐图片
*/
private String setmealImg;
/**
* 套餐说明
*/
private String setmealRemark;
/**
* 预约日期格式yyyy-MM-dd
*/
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate reservationDate;
/**
* 体检人姓名
*/
private String checkupPersonName;
/**
* 体检人性别0不限12女
*/
private Integer checkupPersonSex;
/**
* 体检人电话
*/
private String checkupPersonPhone;
/**
* 体检人身份证号
*/
private String checkupPersonIdcard;
/**
* 用户id
*/
private Long memberId;
/**
* 用户电话
*/
private String memberPhone;
/**
* 支付时间
*/
private LocalDateTime payTime;
/**
* 支付渠道
*/
private String tradingChannel;
/**
* 支付服务交易单号
*/
private Long tradingOrderNo;
/**
* 第三方支付的交易号
*/
private String transactionId;
/**
* 支付服务退款单号
*/
private Long refundNo;
/**
* 第三方支付的退款单号
*/
private String refundId;
/**
* 排序字段(取创建时间的时间戳)
*/
private Long sortBy;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,70 @@
package com.jzo2o.health.model.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 订单取消表
* </p>
* @author itcast
* @since 2023-11-07
*/
@Data
@Builder
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("orders_cancelled")
public class OrdersCancelled implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 订单id
*/
@TableId(value = "id", type = IdType.NONE)
private Long id;
/**
* 取消人
*/
private Long cancellerId;
/**
* 取消人名称
*/
private String cancellerName;
/**
* 取消人类型1普通用户4管理员
*/
private Integer cancellerType;
/**
* 取消原因
*/
private String cancelReason;
/**
* 取消时间
*/
private LocalDateTime cancelTime;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,51 @@
package com.jzo2o.health.model.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* <p>
* 订单退款表
* </p>
* @author itcast
* @since 2023-11-07
*/
@Data
@Builder
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("orders_refund")
public class OrdersRefund implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 订单id
*/
@TableId(value = "id", type = IdType.NONE)
private Long id;
/**
* 支付服务交易单号
*/
private Long tradingOrderNo;
/**
* 实付金额
*/
private BigDecimal realPayAmount;
/**
* 创建时间
*/
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,50 @@
package com.jzo2o.health.model.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDate;
/**
* <p>
*
* </p>
*
* @author itcast
* @since 2023-11-01
*/
@Data
@Builder
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("reservation_setting")
public class ReservationSetting implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 预约日期
*/
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate orderDate;
/**
* 可预约人数
*/
private Integer number;
/**
* 已预约人数
*/
private Integer reservations;
}

View File

@@ -0,0 +1,78 @@
package com.jzo2o.health.model.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* <p>
*
* </p>
*
* @author itcast
* @since 2023-10-31
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("setmeal")
public class Setmeal implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 套餐名称
*/
private String name;
/**
* 套餐编码
*/
private String code;
/**
* 套餐助记码
*/
private String helpCode;
/**
* 套餐助记码
*/
private Integer sex;
/**
* 套餐适用年龄
*/
private String age;
/**
* 套餐价格
*/
private BigDecimal price;
/**
* 套餐说明
*/
private String remark;
/**
* 套餐注意事项
*/
private String attention;
/**
* 套餐图片
*/
private String img;
}

View File

@@ -0,0 +1,37 @@
package com.jzo2o.health.model.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* <p>
*
* </p>
*
* @author itcast
* @since 2023-10-31
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("setmeal_checkgroup")
public class SetmealCheckgroup implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 套餐id
*/
private Integer setmealId;
/**
* 检查组id
*/
private Integer checkgroupId;
}

View File

@@ -0,0 +1,90 @@
package com.jzo2o.health.model.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 管理员
* </p>
*
* @author itcast
* @since 2023-10-31
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
/**
* 用户名
*/
private String username;
/**
* 头像
*/
private String avatar;
/**
* 管理员姓名
*/
private String name;
/**
* 手机号
*/
private String phone;
/**
* 密码
*/
private String password;
/**
* 账户状态0-禁用 1-正常
*/
private Integer status;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
/**
* 创建者id
*/
private Long createBy;
/**
* 更新者id
*/
private Long updateBy;
/**
* 逻辑删除默认0
*/
private Integer isDeleted;
}

View File

@@ -0,0 +1,14 @@
package com.jzo2o.health.model.dto;
import lombok.Data;
/**
* 订单数量响应
* @author itcast
* @create 2023/11/9 16:54
**/
@Data
public class OrderCountDTO {
private Integer orderStatus;
private Integer count;
}

View File

@@ -0,0 +1,19 @@
package com.jzo2o.health.model.dto.request;
import com.jzo2o.common.model.dto.PageQueryDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 检查组分页查询类
*
* @author itcast
* @create 2023/7/4 12:43
**/
@Data
@ApiModel("检查组分页查询类")
public class CommonPageQueryReqDTO extends PageQueryDTO {
@ApiModelProperty("关键词,查询编码或者名称")
private String keyword;
}

View File

@@ -0,0 +1,21 @@
package com.jzo2o.health.model.dto.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("管理员登录模型")
@Data
public class LoginReqDTO {
/**
* 管理员账号
*/
@ApiModelProperty("管理员账号")
private String username;
/**
* 登录密码
*/
@ApiModelProperty("登录密码")
private String password;
}

View File

@@ -0,0 +1,27 @@
package com.jzo2o.health.model.dto.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 普通用户登录请求模型
*
* @author itcast
* @create 2023/11/2 15:48
**/
@Data
@ApiModel("普通用户登录模型")
public class MemberLoginReqDTO {
/**
* 手机号
*/
@ApiModelProperty(value = "手机号", required = true)
private String phone;
/**
* 验证码
*/
@ApiModelProperty(value = "验证码", required = true)
private String verifyCode;
}

View File

@@ -0,0 +1,22 @@
package com.jzo2o.health.model.dto.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 订单取消或退款模型
*
* @author itcast
* @create 2023/11/10 10:04
**/
@Data
@ApiModel("订单取消或退款请求模型")
public class OrdersCancelReqDTO {
@ApiModelProperty(value = "订单id", required = true)
private Long id;
@ApiModelProperty(value = "取消或退款原因", required = true)
private String cancelReason;
}

View File

@@ -0,0 +1,34 @@
package com.jzo2o.health.model.dto.request;
import com.jzo2o.common.model.dto.PageQueryDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* 订单分页查询请求模型
*
* @author itcast
* @create 2023/11/3 19:25
**/
@Data
@ApiModel("订单分页查询请求模型")
public class OrdersPageQueryReqDTO extends PageQueryDTO {
@ApiModelProperty(value = "订单id列表", hidden = true)
private List<Long> ids;
/**
* 订单状态0未支付100待体检200已体检300已关闭400已取消
*/
@ApiModelProperty("订单状态0未支付100待体检200已体检300已关闭400已取消")
private Integer orderStatus;
/**
* 用户电话
*/
@ApiModelProperty("用户电话")
private String memberPhone;
}

View File

@@ -0,0 +1,22 @@
package com.jzo2o.health.model.dto.request;
import com.jzo2o.api.trade.enums.PayChannelEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 订单支付请求体
*
* @author itcast
* @create 2023/9/4 10:00
**/
@Data
@ApiModel("订单支付请求体")
public class OrdersPayReqDTO {
@ApiModelProperty(value = "支付渠道", required = true)
@NotNull(message = "支付渠道不能为空")
private PayChannelEnum tradingChannel;
}

View File

@@ -0,0 +1,33 @@
package com.jzo2o.health.model.dto.request;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate;
@Data
@ApiModel("下单请求信息")
public class PlaceOrderReqDTO {
@ApiModelProperty(value = "套餐id", required = true)
private Integer setmealId;
@ApiModelProperty(value = "预约日期", required = true)
@JsonFormat(pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate reservationDate;
@ApiModelProperty(value = "体检人姓名", required = true)
private String checkupPersonName;
@ApiModelProperty(value = "体检人性别0不限12女", required = true)
private Integer checkupPersonSex;
@ApiModelProperty(value = "体检人电话", required = true)
private String checkupPersonPhone;
@ApiModelProperty(value = "体检人身份证号", required = true)
private String checkupPersonIdcard;
}

View File

@@ -0,0 +1,35 @@
package com.jzo2o.health.model.dto.request;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import java.time.LocalDate;
/**
* <p>
*
* </p>
*
* @author itcast
* @since 2023-11-01
*/
@Data
@Builder
@ApiModel("预约设置更新请求模型")
public class ReservationSettingUpsertReqDTO {
/**
* 预约日期
*/
@ApiModelProperty(value = "预约日期格式yyyy-MM-dd", required = true)
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate orderDate;
/**
* 可预约人数
*/
@ApiModelProperty(value = "可预约人数", required = true)
private Integer number;
}

View File

@@ -0,0 +1,197 @@
package com.jzo2o.health.model.dto.response;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 管理端订单详情
* @author itcast
* @create 2023/11/6 17:31
**/
@Data
public class AdminOrdersDetailResDTO {
@ApiModelProperty("订单信息")
private OrderInfo orderInfo;
@ApiModelProperty("支付信息")
private PayInfo payInfo;
@ApiModelProperty("退款信息")
private RefundInfo refundInfo;
@ApiModelProperty("订单取消理由")
private CancelInfo cancelInfo;
@Data
@ApiModel("订单信息模型")
public static class OrderInfo {
/**
* 订单id
*/
@ApiModelProperty("订单id")
private Long id;
/**
* 订单状态0未支付100待体检200已体检300已关闭400已取消
*/
@ApiModelProperty("订单状态0未支付100待体检200已体检300已关闭400已取消")
private Integer orderStatus;
/**
* 套餐id
*/
@ApiModelProperty("套餐id")
private Integer setmealId;
/**
* 套餐名称
*/
@ApiModelProperty("套餐名称")
private String setmealName;
/**
* 套餐价格
*/
@ApiModelProperty("套餐价格")
private BigDecimal setmealPrice;
/**
* 预约日期格式yyyy-MM-dd
*/
@ApiModelProperty("预约日期格式yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate reservationDate;
/**
* 体检人姓名
*/
@ApiModelProperty("体检人姓名")
private String checkupPersonName;
/**
* 体检人性别0不限12女
*/
@ApiModelProperty("体检人性别0不限12女")
private Integer checkupPersonSex;
/**
* 体检人电话
*/
@ApiModelProperty("体检人电话")
private String checkupPersonPhone;
/**
* 体检人身份证号
*/
@ApiModelProperty("体检人身份证号")
private String checkupPersonIdcard;
/**
* 用户id
*/
@ApiModelProperty("用户id")
private Long memberId;
/**
* 用户电话
*/
@ApiModelProperty("用户电话")
private String memberPhone;
/**
* 创建时间
*/
@ApiModelProperty("创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
}
@Data
@ApiModel("支付记录模型")
public static class PayInfo {
/**
* 支付状态0未支付1已支付
*/
@ApiModelProperty("支付状态0未支付1已支付")
private Integer payStatus;
/**
* 支付渠道ALI_PAY支付宝WECHAT_PAY微信
*/
@ApiModelProperty("支付渠道ALI_PAY支付宝WECHAT_PAY微信")
private String tradingChannel;
/**
* 三方流水,微信支付订单号或支付宝订单号
*/
@ApiModelProperty("三方流水,微信支付订单号或支付宝订单号")
private String thirdOrderId;
/**
* 支付时间
*/
@ApiModelProperty("支付时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime payTime;
}
@Data
@Builder
@ApiModel("退款信息模型")
public static class RefundInfo {
/**
* 退款状态2退款中3退款成功4退款失败
*/
@ApiModelProperty("退款状态2退款中3退款成功4退款失败")
private Integer refundStatus;
/**
* 退款时间;和取消时间保持一致
*/
@ApiModelProperty("退款时间;和取消时间保持一致")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime cancelTime;
/**
* 退款理由和取消理由一致
*/
@ApiModelProperty("退款理由和取消理由一致")
private String cancelReason;
/**
* 支付渠道ALI_PAY支付宝WECHAT_PAY微信
*/
@ApiModelProperty("支付渠道ALI_PAY支付宝WECHAT_PAY微信")
private String tradingChannel;
/**
* 第三方支付的退款单号
*/
@ApiModelProperty("第三方支付的退款单号")
private String refundId;
}
@Data
@Builder
@ApiModel("订单取消模型")
public static class CancelInfo {
/**
* 取消时间
*/
@ApiModelProperty("取消时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime cancelTime;
/**
* 取消理由
*/
@ApiModelProperty("取消理由")
private String cancelReason;
}
}

View File

@@ -0,0 +1,33 @@
package com.jzo2o.health.model.dto.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* @author itcast
* @create 2023/11/3 18:53
**/
@Data
@ApiModel("检查组详情")
public class CheckGroupDetailResDTO {
/**
* 检查组id
*/
@ApiModelProperty("检查组id")
private Integer id;
/**
* 检查组名称
*/
@ApiModelProperty("检查组名称")
private String name;
/**
* 检查项列表
*/
@ApiModelProperty("检查项列表")
private List<CheckItemResDTO> checkItemList;
}

View File

@@ -0,0 +1,21 @@
package com.jzo2o.health.model.dto.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("检查项响应模型")
public class CheckItemResDTO {
/**
* 检查项id
*/
@ApiModelProperty("检查项id")
private Integer id;
/**
* 检查项名称
*/
@ApiModelProperty("检查项名称")
private String name;
}

View File

@@ -0,0 +1,17 @@
package com.jzo2o.health.model.dto.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@ApiModel("登录结果")
@NoArgsConstructor
@AllArgsConstructor
public class LoginResDTO {
@ApiModelProperty("运营端访问token")
private String token;
}

View File

@@ -0,0 +1,56 @@
package com.jzo2o.health.model.dto.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 订单数量
*
* @author itcast
* @create 2023/11/8 16:02
**/
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("订单数量响应模型")
public class OrdersCountResDTO {
/**
* 待支付数量
*/
@ApiModelProperty("待支付数量")
private Integer noPayCount = 0;
/**
* 待体检数量
*/
@ApiModelProperty("待体检数量")
private Integer waitingCheckupCount = 0;
/**
* 已体检数量
*/
@ApiModelProperty("已体检数量")
private Integer completedCheckupCount = 0;
/**
* 已关闭数量
*/
@ApiModelProperty("已关闭数量")
private Integer closedCount = 0;
/**
* 已取消数量
*/
@ApiModelProperty("已取消数量")
private Integer cancelledCount = 0;
/**
* 全部数量
*/
@ApiModelProperty("全部数量")
private Integer totalCount = 0;
}

View File

@@ -0,0 +1,197 @@
package com.jzo2o.health.model.dto.response;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.jzo2o.health.enums.OrderPayStatusEnum;
import com.jzo2o.health.enums.OrderStatusEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* <p>
* 订单表
* </p>
*
* @author itcast
* @since 2023-11-02
*/
@Data
@ApiModel("订单详情响应体")
public class OrdersDetailResDTO {
/**
* 订单id
*/
@ApiModelProperty("订单id")
private Long id;
/**
* 订单状态0未支付100待体检200已体检300已关闭400已取消
*/
@ApiModelProperty("订单状态0未支付100待体检200已体检300已关闭400已取消")
private OrderStatusEnum orderStatus;
/**
* 支付状态0未支付1已支付2退款中3退款成功4退款失败
*/
@ApiModelProperty("支付状态0未支付1已支付2退款中3退款成功4退款失败")
private OrderPayStatusEnum payStatus;
/**
* 套餐id
*/
@ApiModelProperty("套餐id")
private Integer setmealId;
/**
* 套餐名称
*/
@ApiModelProperty("套餐名称")
private String setmealName;
/**
* 套餐价格
*/
@ApiModelProperty("套餐价格")
private BigDecimal setmealPrice;
/**
* 套餐适用性别0不限12
*/
@ApiModelProperty("套餐适用性别0不限12")
private Integer setmealSex;
/**
* 套餐适用年龄
*/
@ApiModelProperty("套餐适用年龄")
private String setmealAge;
/**
* 套餐图片
*/
@ApiModelProperty("套餐图片")
private String setmealImg;
/**
* 套餐说明
*/
@ApiModelProperty("套餐说明")
private String setmealRemark;
/**
* 预约日期格式yyyy-MM-dd
*/
@ApiModelProperty("预约日期格式yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate reservationDate;
/**
* 体检人姓名
*/
@ApiModelProperty("体检人姓名")
private String checkupPersonName;
/**
* 体检人性别0不限12女
*/
@ApiModelProperty("体检人性别0不限12女")
private Integer checkupPersonSex;
/**
* 体检人电话
*/
@ApiModelProperty("体检人电话")
private String checkupPersonPhone;
/**
* 体检人身份证号
*/
@ApiModelProperty("体检人身份证号")
private String checkupPersonIdcard;
/**
* 用户id
*/
@ApiModelProperty("用户id")
private Long memberId;
/**
* 用户电话
*/
@ApiModelProperty("用户电话")
private String memberPhone;
/**
* 支付时间
*/
@ApiModelProperty("支付时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime payTime;
/**
* 支付渠道
*/
@ApiModelProperty("支付渠道")
private String tradingChannel;
/**
* 支付服务交易单号
*/
@ApiModelProperty("支付服务交易单号")
private Long tradingOrderNo;
/**
* 第三方支付的交易号
*/
@ApiModelProperty("第三方支付的交易号")
private String transactionId;
/**
* 支付服务退款单号
*/
@ApiModelProperty("支付服务退款单号")
private Long refundNo;
/**
* 第三方支付的退款单号
*/
@ApiModelProperty("第三方支付的退款单号")
private String refundId;
/**
* 排序字段(取创建时间的时间戳)
*/
@ApiModelProperty("排序字段(取创建时间的时间戳)")
private Long sortBy;
/**
* 创建时间
*/
@ApiModelProperty("创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
/**
* 更新时间
*/
@ApiModelProperty("更新时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
/**
* 取消或退款时间
*/
@ApiModelProperty("取消或退款时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime cancelTime;
/**
* 取消或退款原因
*/
@ApiModelProperty("取消或退款原因")
private String cancelReason;
}

View File

@@ -0,0 +1,33 @@
package com.jzo2o.health.model.dto.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 订单支付响应体
*
* @author itcast
* @create 2023/9/4 10:00
**/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("订单支付响应体")
public class OrdersPayResDTO {
@ApiModelProperty(value = "二维码base64数据")
private String qrCode;
@ApiModelProperty(value = "业务系统订单号")
private Long productOrderNo;
@ApiModelProperty(value = "交易系统订单号【对于三方来说:商户订单】")
private Long tradingOrderNo;
@ApiModelProperty(value = "支付渠道【支付宝、微信、现金、免单挂账】")
private String tradingChannel;
@ApiModelProperty(value = "支付状态0待支付1支付成功")
private Integer payStatus;
}

View File

@@ -0,0 +1,126 @@
package com.jzo2o.health.model.dto.response;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.jzo2o.health.enums.OrderPayStatusEnum;
import com.jzo2o.health.enums.OrderStatusEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* 订单响应
* @author itcast
* @create 2023/11/3 19:17
**/
@Data
@ApiModel("订单响应模型")
public class OrdersResDTO {
/**
* 订单id
*/
@ApiModelProperty("订单id")
private Long id;
/**
* 订单状态0未支付100待体检200已体检300已关闭400已取消
*/
@ApiModelProperty("订单状态0未支付100待体检200已体检300已关闭400已取消")
private OrderStatusEnum orderStatus;
/**
* 支付状态0未支付1已支付2退款中3退款成功4退款失败
*/
@ApiModelProperty("支付状态0未支付1已支付2退款中3退款成功4退款失败")
private OrderPayStatusEnum payStatus;
/**
* 套餐id
*/
@ApiModelProperty("套餐id")
private Integer setmealId;
/**
* 套餐名称
*/
@ApiModelProperty("套餐名称")
private String setmealName;
/**
* 套餐价格
*/
@ApiModelProperty("套餐价格")
private BigDecimal setmealPrice;
/**
* 套餐适用年龄
*/
@ApiModelProperty("套餐适用年龄")
private String setmealAge;
/**
* 套餐适用性别
*/
@ApiModelProperty("套餐适用性别")
private Integer setmealSex;
/**
* 套餐图片
*/
@ApiModelProperty("套餐图片")
private String setmealImg;
/**
* 套餐说明
*/
@ApiModelProperty("套餐说明")
private String setmealRemark;
/**
* 预约日期
*/
@ApiModelProperty("预约日期")
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate reservationDate;
/**
* 体检人
*/
@ApiModelProperty("体检人")
private String checkupPersonName;
/**
* 体检人身份证号
*/
@ApiModelProperty("体检人身份证号")
private String checkupPersonIdcard;
/**
* 用户电话
*/
@ApiModelProperty("用户电话")
private String memberPhone;
/**
* 排序字段(取创建时间的时间戳)
*/
@ApiModelProperty("排序字段(取创建时间的时间戳)")
private Long sortBy;
/**
* 创建时间
*/
@ApiModelProperty("创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
/**
* 更新时间
*/
@ApiModelProperty("更新时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,19 @@
package com.jzo2o.health.model.dto.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author itcast
*/
@ApiModel("下单响应信息")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PlaceOrderResDTO {
@ApiModelProperty("订单id")
private Long id;
}

View File

@@ -0,0 +1,27 @@
package com.jzo2o.health.model.dto.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 预约日期响应模型
*
* @author itcast
* @create 2023/11/6 10:19
**/
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("预约日期响应模型")
public class ReservationDateResDTO {
/**
* 可预约日期
*/
@ApiModelProperty("可预约日期")
private List<String> dateList;
}

View File

@@ -0,0 +1,37 @@
package com.jzo2o.health.model.dto.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
/**
* <p>
*
* </p>
*
* @author itcast
* @since 2023-11-01
*/
@Data
@Builder
@ApiModel("预约设置响应模型")
public class ReservationSettingResDTO {
/**
* 预约日期
*/
@ApiModelProperty("预约日期")
private String date;
/**
* 可预约人数
*/
@ApiModelProperty("可预约人数")
private Integer number;
/**
* 已预约人数
*/
@ApiModelProperty("已预约人数")
private Integer reservations;
}

View File

@@ -0,0 +1,87 @@
package com.jzo2o.health.model.dto.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author itcast
* @since 2023-10-31
*/
@Data
@ApiModel("套餐详情响应模型")
public class SetmealDetailResDTO {
/**
* 套餐id
*/
@ApiModelProperty("套餐id")
private Integer id;
/**
* 套餐名称
*/
@ApiModelProperty("套餐名称")
private String name;
/**
* 套餐编码
*/
@ApiModelProperty("套餐编码")
private String code;
/**
* 套餐助记码
*/
@ApiModelProperty("套餐助记码")
private String helpCode;
/**
* 性别0不限12
*/
@ApiModelProperty("性别0不限12")
private String sex;
/**
* 适用年龄
*/
@ApiModelProperty("适用年龄")
private String age;
/**
* 价格
*/
@ApiModelProperty("价格")
private Float price;
/**
* 说明
*/
@ApiModelProperty("说明")
private String remark;
/**
* 注意事项
*/
@ApiModelProperty("注意事项")
private String attention;
/**
* 图片
*/
@ApiModelProperty("图片")
private String img;
/**
* 检查组列表
*/
@ApiModelProperty("检查组列表")
private List<CheckGroupDetailResDTO> checkGroupList;
}

View File

@@ -0,0 +1,25 @@
package com.jzo2o.health.model.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
/**
* 预约导入数据
*
* @author itcast
* @create 2023/11/1 19:16
**/
@Data
public class ReservationImportData {
/**
* 日期格式yyyy-MM-dd
*/
@ExcelProperty(index = 0)
private String date;
/**
* 预约人数
*/
@ExcelProperty(index = 1)
private Integer number;
}

View File

@@ -0,0 +1,46 @@
package com.jzo2o.health.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Configuration
@ConfigurationProperties(prefix = "jzo2o")
@Data
public class ApplicationProperties {
/**
* jwt 加密秘钥
*/
private String jwtKey;
/**
* 每一个端都要配置一个token解析key
* “1”xxx c端用户token生成key
* "2": xxx 服务端用户token生成key
* "3": xxx 机构端用户token生成key
* "4": xxx 运营端用户token生成key
* tokenkey
*/
@NestedConfigurationProperty
private final Map<String,String> tokenKey = new HashMap<>();
/**
* 访问路径地址白名单
*/
@NestedConfigurationProperty
private List<String> accessPathWhiteList = new ArrayList<>();
/**
* 访问路径黑名单
*/
@NestedConfigurationProperty
private List<String> accessPathBlackList = new ArrayList<>();
}

View File

@@ -0,0 +1,23 @@
package com.jzo2o.health.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author itcast
*/
@Data
@Component
@ConfigurationProperties(prefix = "jzo2o.job")
public class OrdersJobProperties {
/**
* 退款订单数量默认100
*/
private Integer refundOrderCount = 100;
/**
* 超时支付订单数量默认100
*/
private Integer overTimePayOrderCount = 100;
}

View File

@@ -0,0 +1,24 @@
package com.jzo2o.health.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author itcast
*/
@Data
@Component
@ConfigurationProperties(prefix = "jzo2o.trade")
public class TradeProperties {
/**
* 支付宝商户id
*/
private Long aliEnterpriseId;
/**
* 微信支付商户id
*/
private Long wechatEnterpriseId;
}

View File

@@ -0,0 +1,47 @@
package com.jzo2o.health.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.health.model.domain.CheckgroupCheckitem;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author itcast
* @since 2023-10-31
*/
public interface ICheckgroupCheckitemService extends IService<CheckgroupCheckitem> {
/**
* 删除关联关系
*
* @param checkGroupId 检查组id
*/
void deleteAssociation(Integer checkGroupId);
/**
* 根据检查组id查询检查项id
*
* @param checkGroupId 检查组id
* @return 检查项id
*/
List<Integer> findCheckItemIdsByCheckGroupId(Integer checkGroupId);
/**
* 新增关联关系
*
* @param checkGroupId 检查组id
* @param checkItemId 检查项id
*/
void add(Integer checkGroupId, Integer checkItemId);
/**
* 根据检查项id查询数量
*
* @param checkItemId 检查项id
* @return 数量
*/
long findCountByCheckItemId(Integer checkItemId);
}

View File

@@ -0,0 +1,15 @@
package com.jzo2o.health.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.health.model.domain.Checkgroup;
/**
* <p>
* 服务类
* </p>
*
* @author itcast
* @since 2023-10-31
*/
public interface ICheckgroupService extends IService<Checkgroup> {
}

View File

@@ -0,0 +1,15 @@
package com.jzo2o.health.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.health.model.domain.Checkitem;
/**
* <p>
* 服务类
* </p>
*
* @author itcast
* @since 2023-10-31
*/
public interface ICheckitemService extends IService<Checkitem> {
}

View File

@@ -0,0 +1,27 @@
package com.jzo2o.health.service;
import com.jzo2o.health.model.dto.request.LoginReqDTO;
import com.jzo2o.health.model.dto.request.MemberLoginReqDTO;
/**
* 登录相关业务
*
* @author itcast
*/
public interface ILoginService {
/**
* 管理员登录
*
* @param loginReqDTO 管理员登录请求模型
* @return token
*/
String adminLogin(LoginReqDTO loginReqDTO);
/**
* 普通用户登录
*
* @param memberLoginReqDTO 普通用户登录请求模型
* @return token
*/
String memberLogin(MemberLoginReqDTO memberLoginReqDTO);
}

View File

@@ -0,0 +1,30 @@
package com.jzo2o.health.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.health.model.domain.Member;
/**
* <p>
* 普通用户 服务类
* </p>
*
* @author itcast
* @since 2023-11-02
*/
public interface IMemberService extends IService<Member> {
/**
* 根据手机号查询普通用户
*
* @param phone 手机号
* @return 普通用户
*/
Member findByPhone(String phone);
/**
* 新增普通用户
*
* @param phone 手机号
* @return 普通用户
*/
Member add(String phone);
}

View File

@@ -0,0 +1,21 @@
package com.jzo2o.health.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.health.model.domain.OrdersCancelled;
import com.jzo2o.health.model.dto.request.OrdersCancelReqDTO;
/**
* 取消订单相关业务层
* @author JIAN
*/
public interface IOrderCancelService extends IService<OrdersCancelled> {
/**
* 用户取消订单
*/
void cancelOrder(OrdersCancelReqDTO ordersCancelReqDTO);
/**
* 取消订单(内部使用)
*/
void cancelOrder(OrdersCancelled ordersCancelled);
}

View File

@@ -0,0 +1,20 @@
package com.jzo2o.health.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.health.model.OrderUpdateStatusDTO;
import com.jzo2o.health.model.domain.Orders;
/**
* <p>
* 订单表 服务类
* </p>
*
* @author itcast
* @since 2023-08-02
*/
public interface IOrderCommonService extends IService<Orders> {
/**
* 更新指定id订单的状态
*/
Boolean updateStatus(OrderUpdateStatusDTO orderUpdateStatusReqDTO);
}

View File

@@ -0,0 +1,35 @@
package com.jzo2o.health.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.api.trade.enums.PayChannelEnum;
import com.jzo2o.health.model.domain.Orders;
import com.jzo2o.health.model.dto.request.PlaceOrderReqDTO;
import com.jzo2o.health.model.dto.response.OrdersPayResDTO;
import com.jzo2o.health.model.dto.response.PlaceOrderResDTO;
/**
* 订单创建相关业务层
* @author JIAN
*/
public interface IOrderCreateService extends IService<Orders> {
/**
* 微服务标识
*/
String PRODUCT_APP_ID = "health.orders";
/**
* 用户下单
*/
PlaceOrderResDTO placeOrder(PlaceOrderReqDTO placeOrderReqDTO);
/**
* 用户支付(返回支付二维码)
* @param id 本系统的订单id
*/
OrdersPayResDTO payOrder(Long id, PayChannelEnum tradingChannel);
/**
* 获取指定订单的支付结果
*/
OrdersPayResDTO getPayResult(Long id);
}

View File

@@ -0,0 +1,43 @@
package com.jzo2o.health.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.health.model.domain.Orders;
import com.jzo2o.health.model.dto.request.OrdersPageQueryReqDTO;
import com.jzo2o.health.model.dto.response.AdminOrdersDetailResDTO;
import com.jzo2o.health.model.dto.response.OrdersCountResDTO;
import com.jzo2o.health.model.dto.response.OrdersDetailResDTO;
import com.jzo2o.health.model.dto.response.OrdersResDTO;
import java.util.List;
/**
* 订单管理相关业务层
* @author JIAN
*/
public interface IOrderManagerService extends IService<Orders> {
/**
* 管理端订单分页查询
*/
PageResult<OrdersResDTO> pageQuery(OrdersPageQueryReqDTO ordersPageQueryReqDTO);
/**
* 用户端订单分页查询
*/
List<OrdersResDTO> pageQuery(Integer orderStatus, Long sortBy);
/**
* 管理端查询订单详情
*/
AdminOrdersDetailResDTO getAggregationInfo(Long id);
/**
* 用户端获取订单详情
*/
OrdersDetailResDTO getOrderById(Long id);
/**
* 获取每种状态的订单数
*/
OrdersCountResDTO countByStatus();
}

View File

@@ -0,0 +1,29 @@
package com.jzo2o.health.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.health.model.domain.OrdersRefund;
import com.jzo2o.health.model.dto.request.OrdersCancelReqDTO;
import java.util.List;
/**
* 订单退款相关业务层
* @author JIAN
*/
public interface IOrderRefundService extends IService<OrdersRefund> {
/**
* 用户订单退款
*/
void refundOrder(OrdersCancelReqDTO ordersCancelReqDTO);
/**
* 调用API退款(内部使用)
*/
void refundOrder(OrdersRefund ordersRefund);
/**
* 获取最新的订单退款信息
* @param count 处理数量
*/
List<OrdersRefund> getLatestRefundInfo(Integer count);
}

View File

@@ -0,0 +1,47 @@
package com.jzo2o.health.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.health.model.domain.ReservationSetting;
import com.jzo2o.health.model.dto.request.ReservationSettingUpsertReqDTO;
import com.jzo2o.health.model.dto.response.ReservationDateResDTO;
import com.jzo2o.health.model.dto.response.ReservationSettingResDTO;
import com.jzo2o.health.model.excel.ReservationImportData;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.List;
/**
* <p>
* 预约设置 服务类
* </p>
* @author JIAN
*/
public interface IReservationSettingService extends IService<ReservationSetting> {
/**
* 获取指定月份的所有预约数据
*/
List<ReservationSettingResDTO> getReservationSettingByMonth(YearMonth yearMonth);
/**
* 更新/插入指定日期的预约数据
*/
void editNumberByDate(ReservationSettingUpsertReqDTO reservationSettingUpsertReqDTO);
/**
* 批量更新/插入指定日期的预约数据
*/
void editNumberByDateBatch(List<ReservationImportData> reservationDataList);
/**
* 获取当前月份可用预约日期
*/
ReservationDateResDTO getReservationDateByMonth(YearMonth yearMonth);
/**
* 增加已预约人数数量
* @param time
* @param count 数量
*/
void plusReservationCount(LocalDate time, Integer count);
}

View File

@@ -0,0 +1,22 @@
package com.jzo2o.health.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.health.model.domain.SetmealCheckgroup;
/**
* <p>
* 服务类
* </p>
*
* @author itcast
* @since 2023-10-31
*/
public interface ISetmealCheckgroupService extends IService<SetmealCheckgroup> {
/**
* 绑定套餐和检查组的关系
*
* @param setmealId 套餐id
* @param checkgroupId 检查组id
*/
void setSetmealAndCheckGroup(Integer setmealId, Integer checkgroupId);
}

View File

@@ -0,0 +1,35 @@
package com.jzo2o.health.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.health.model.domain.Setmeal;
import com.jzo2o.health.model.dto.request.CommonPageQueryReqDTO;
import com.jzo2o.health.model.dto.response.SetmealDetailResDTO;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author itcast
* @since 2023-10-31
*/
public interface ISetmealService extends IService<Setmeal> {
void add(Setmeal setmeal, Integer[] checkgroupIds);
List<Setmeal> findAll();
Setmeal findById(int id);
/**
* 查询套餐详情(包含关联检查组、检查项)
*
* @param id 套餐id
* @return 套餐详情
*/
SetmealDetailResDTO findDetail(Integer id);
PageResult<Setmeal> findPage(CommonPageQueryReqDTO commonPageQueryReqDTO);
}

View File

@@ -0,0 +1,22 @@
package com.jzo2o.health.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.health.model.domain.User;
/**
* <p>
* 管理员 服务类
* </p>
*
* @author itcast
* @since 2023-10-31
*/
public interface IUserService extends IService<User> {
/**
* 根据用户名查询用户
*
* @param username 用户名
* @return 用户信息
*/
User findByUsername(String username);
}

View File

@@ -0,0 +1,81 @@
package com.jzo2o.health.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.health.mapper.CheckgroupCheckitemMapper;
import com.jzo2o.health.model.domain.CheckgroupCheckitem;
import com.jzo2o.health.service.ICheckgroupCheckitemService;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author itcast
* @since 2023-10-31
*/
@Service
public class CheckgroupCheckitemServiceImpl extends ServiceImpl<CheckgroupCheckitemMapper, CheckgroupCheckitem> implements ICheckgroupCheckitemService {
/**
* 删除关联关系
*
* @param checkGroupId 检查组id
*/
@Override
public void deleteAssociation(Integer checkGroupId) {
LambdaQueryWrapper<CheckgroupCheckitem> queryWrapper = Wrappers.<CheckgroupCheckitem>lambdaQuery().eq(CheckgroupCheckitem::getCheckgroupId, checkGroupId);
baseMapper.delete(queryWrapper);
}
/**
* 根据检查组id查询检查项id
*
* @param checkGroupId 检查组id
* @return 检查项id
*/
@Override
public List<Integer> findCheckItemIdsByCheckGroupId(Integer checkGroupId) {
LambdaQueryWrapper<CheckgroupCheckitem> queryWrapper = Wrappers.<CheckgroupCheckitem>lambdaQuery()
.eq(CheckgroupCheckitem::getCheckgroupId, checkGroupId)
.select(CheckgroupCheckitem::getCheckitemId);
List<CheckgroupCheckitem> checkgroupCheckitemList = baseMapper.selectList(queryWrapper);
if (ObjectUtil.isEmpty(checkgroupCheckitemList)) {
return Collections.emptyList();
}
return checkgroupCheckitemList.stream().map(CheckgroupCheckitem::getCheckitemId).collect(Collectors.toList());
}
/**
* 新增关联关系
*
* @param checkGroupId 检查组id
* @param checkItemId 检查项id
*/
@Override
public void add(Integer checkGroupId, Integer checkItemId) {
CheckgroupCheckitem checkgroupCheckitem = new CheckgroupCheckitem();
checkgroupCheckitem.setCheckgroupId(checkGroupId);
checkgroupCheckitem.setCheckitemId(checkItemId);
baseMapper.insert(checkgroupCheckitem);
}
/**
* 根据检查项id查询数量
*
* @param checkItemId 检查项id
* @return 数量
*/
@Override
public long findCountByCheckItemId(Integer checkItemId) {
LambdaQueryWrapper<CheckgroupCheckitem> queryWrapper = Wrappers.<CheckgroupCheckitem>lambdaQuery().eq(CheckgroupCheckitem::getCheckitemId, checkItemId);
return baseMapper.selectCount(queryWrapper);
}
}

View File

@@ -0,0 +1,19 @@
package com.jzo2o.health.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.health.mapper.CheckgroupMapper;
import com.jzo2o.health.model.domain.Checkgroup;
import com.jzo2o.health.service.ICheckgroupService;
import org.springframework.stereotype.Service;
/**
* <p>
* 服务实现类
* </p>
*
* @author itcast
* @since 2023-10-31
*/
@Service
public class CheckgroupServiceImpl extends ServiceImpl<CheckgroupMapper, Checkgroup> implements ICheckgroupService {
}

View File

@@ -0,0 +1,19 @@
package com.jzo2o.health.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.health.mapper.CheckitemMapper;
import com.jzo2o.health.model.domain.Checkitem;
import com.jzo2o.health.service.ICheckitemService;
import org.springframework.stereotype.Service;
/**
* <p>
* 服务实现类
* </p>
*
* @author itcast
* @since 2023-10-31
*/
@Service
public class CheckitemServiceImpl extends ServiceImpl<CheckitemMapper, Checkitem> implements ICheckitemService {
}

View File

@@ -0,0 +1,90 @@
package com.jzo2o.health.service.impl;
import com.jzo2o.api.publics.SmsCodeApi;
import com.jzo2o.common.constants.UserType;
import com.jzo2o.common.enums.SmsBusinessTypeEnum;
import com.jzo2o.common.expcetions.BadRequestException;
import com.jzo2o.common.expcetions.RequestForbiddenException;
import com.jzo2o.common.utils.JwtTool;
import com.jzo2o.common.utils.StringUtils;
import com.jzo2o.health.model.domain.Member;
import com.jzo2o.health.model.domain.User;
import com.jzo2o.health.model.dto.request.LoginReqDTO;
import com.jzo2o.health.model.dto.request.MemberLoginReqDTO;
import com.jzo2o.health.service.ILoginService;
import com.jzo2o.health.service.IMemberService;
import com.jzo2o.health.service.IUserService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @author itcast
*/
@Service
public class LoginServiceImpl implements ILoginService {
@Resource
private IUserService userService;
@Resource
private JwtTool jwtTool;
@Resource
private PasswordEncoder passwordEncoder;
@Resource
private SmsCodeApi smsCodeApi;
@Resource
private IMemberService memberService;
/**
* 管理员登录
*
* @param loginReqDTO 管理员登录请求模型
* @return token
*/
@Override
public String adminLogin(LoginReqDTO loginReqDTO) {
//根据输入的账号查询用户信息
User user = userService.findByUsername(loginReqDTO.getUsername());
if (user == null) {
throw new RequestForbiddenException("账号或密码错误,请重新输入");
}
// 比对密码
if (!passwordEncoder.matches(loginReqDTO.getPassword(), user.getPassword())) {
throw new RequestForbiddenException("账号或密码错误,请重新输入");
}
//生成令牌
return jwtTool.createToken(user.getId(), user.getName(), user.getAvatar(), UserType.OPERATION);
}
/**
* 普通用户登录
*
* @param memberLoginReqDTO 普通用户登录请求模型
* @return token
*/
@Override
public String memberLogin(MemberLoginReqDTO memberLoginReqDTO) {
// 校验验证码是否为空
if (StringUtils.isBlank(memberLoginReqDTO.getVerifyCode())) {
throw new BadRequestException("手机号码或短信验证码错误");
}
// 校验验证码是否正确
//家政项目中,验证码业务类型是枚举类,固定死的,这里我们借用 SmsBusinessTypeEnum.SERVE_STAFF_LOGIN 类型
boolean verifyResult = smsCodeApi.verify(memberLoginReqDTO.getPhone(), SmsBusinessTypeEnum.SERVE_STAFF_LOGIN, memberLoginReqDTO.getVerifyCode()).getIsSuccess();
if (!verifyResult) {
throw new BadRequestException("手机号码或短信验证码错误");
}
// 登录校验,根据手机查询普通用户信息
Member member = memberService.findByPhone(memberLoginReqDTO.getPhone());
// 自动注册
if (member == null) {
member = memberService.add(memberLoginReqDTO.getPhone());
}
// 生成登录token
return jwtTool.createToken(member.getId(), member.getNickname(), member.getAvatar(), UserType.C_USER);
}
}

View File

@@ -0,0 +1,54 @@
package com.jzo2o.health.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.health.mapper.MemberMapper;
import com.jzo2o.health.model.domain.Member;
import com.jzo2o.health.service.IMemberService;
import org.springframework.stereotype.Service;
/**
* <p>
* 普通用户 服务实现类
* </p>
*
* @author itcast
* @since 2023-11-02
*/
@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements IMemberService {
/**
* 默认头像
*/
private static final String DEFAULT_AVATAR = "https://yjy-oss-videos.oss-accelerate.aliyuncs.com/tx.png";
/**
* 根据手机号查询普通用户
*
* @param phone 手机号
* @return 普通用户
*/
@Override
public Member findByPhone(String phone) {
LambdaQueryWrapper<Member> queryWrapper = Wrappers.<Member>lambdaQuery().eq(Member::getPhone, phone);
return baseMapper.selectOne(queryWrapper);
}
/**
* 新增普通用户
*
* @param phone 手机号
* @return 普通用户
*/
@Override
public Member add(String phone) {
Member member = new Member();
member.setNickname("普通用户");
member.setPhone(phone);
//设置默认头像
member.setAvatar(DEFAULT_AVATAR);
baseMapper.insert(member);
return member;
}
}

View File

@@ -0,0 +1,85 @@
package com.jzo2o.health.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.model.CurrentUserInfo;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.health.enums.OrderPayStatusEnum;
import com.jzo2o.health.enums.OrderStatusEnum;
import com.jzo2o.health.mapper.OrdersCancelledMapper;
import com.jzo2o.health.model.OrderUpdateStatusDTO;
import com.jzo2o.health.model.UserThreadLocal;
import com.jzo2o.health.model.domain.Orders;
import com.jzo2o.health.model.domain.OrdersCancelled;
import com.jzo2o.health.model.dto.request.OrdersCancelReqDTO;
import com.jzo2o.health.service.IOrderCancelService;
import com.jzo2o.health.service.IOrderCommonService;
import com.jzo2o.health.service.IReservationSettingService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
/**
* 取消订单相关业务层实现
* @author JIAN
*/
@Service
public class OrderCancelServiceImpl extends ServiceImpl<OrdersCancelledMapper, OrdersCancelled> implements IOrderCancelService {
@Resource
private IOrderCommonService orderCommonService;
@Resource
private IReservationSettingService reservationSettingService;
@Override
@Transactional
public void cancelOrder(OrdersCancelReqDTO ordersCancelReqDTO) {
CurrentUserInfo currentUser = UserThreadLocal.currentUser();
if (ObjectUtils.isEmpty(currentUser) || ObjectUtils.isEmpty(currentUser.getId())) {
throw new ForbiddenOperationException("无法获取用户信息无法取消");
}
Long orderId = ordersCancelReqDTO.getId();
Orders orders = orderCommonService.getById(orderId);
if (ObjectUtils.isEmpty(orders)) {
throw new ForbiddenOperationException("订单不存在无法取消");
}
if (orders.getOrderStatus() != OrderStatusEnum.NO_PAY || orders.getPayStatus() != OrderPayStatusEnum.NO_PAY) {
throw new ForbiddenOperationException("订单状态错误无法取消");
}
this.cancelOrder(OrdersCancelled.builder()
.id(orderId)
.cancelTime(LocalDateTime.now())
.cancelReason(ordersCancelReqDTO.getCancelReason())
.cancellerName(currentUser.getName())
.cancellerId(currentUser.getId())
.cancellerType(currentUser.getUserType())
.build());
// 已预约人数 - 1
reservationSettingService.plusReservationCount(orders.getReservationDate(), -1);
}
@Override
@Transactional
public void cancelOrder(OrdersCancelled ordersCancelled) {
Long orderId = ordersCancelled.getId();
if (!orderCommonService.updateStatus(OrderUpdateStatusDTO.builder()
.id(orderId)
.originStatus(OrderStatusEnum.NO_PAY)
.targetStatus(OrderStatusEnum.CANCELLED)
.build())) {
throw new DBException("更新订单表失败");
}
if (!SqlHelper.retBool(baseMapper.insert(ordersCancelled))) {
throw new DBException("更新取消表失败");
}
}
}

View File

@@ -0,0 +1,36 @@
package com.jzo2o.health.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.health.mapper.OrdersMapper;
import com.jzo2o.health.model.OrderUpdateStatusDTO;
import com.jzo2o.health.model.domain.Orders;
import com.jzo2o.health.service.IOrderCommonService;
import org.springframework.stereotype.Service;
/**
* <p>
* 订单表 服务实现类
* </p>
* @author itcast
* @since 2023-08-02
*/
@Service
public class OrderCommonServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrderCommonService {
@Override
public Boolean updateStatus(OrderUpdateStatusDTO orderUpdateStatusReqDTO) {
return lambdaUpdate()
.eq(Orders::getId, orderUpdateStatusReqDTO.getId())
.gt(Orders::getMemberId, 0)
.eq(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getOriginStatus()), Orders::getOrderStatus, orderUpdateStatusReqDTO.getOriginStatus())
.set(Orders::getOrderStatus, orderUpdateStatusReqDTO.getTargetStatus())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getPayStatus()), Orders::getPayStatus, orderUpdateStatusReqDTO.getPayStatus())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getPayTime()), Orders::getPayTime, orderUpdateStatusReqDTO.getPayTime())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getTradingOrderNo()), Orders::getTradingOrderNo, orderUpdateStatusReqDTO.getTradingOrderNo())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getTransactionId()), Orders::getTransactionId, orderUpdateStatusReqDTO.getTransactionId())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getTradingChannel()), Orders::getTradingChannel, orderUpdateStatusReqDTO.getTradingChannel())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getRefundNo()), Orders::getRefundNo, orderUpdateStatusReqDTO.getRefundNo())
.set(ObjectUtil.isNotNull(orderUpdateStatusReqDTO.getRefundId()), Orders::getRefundId, orderUpdateStatusReqDTO.getRefundId())
.update();
}
}

View File

@@ -0,0 +1,223 @@
package com.jzo2o.health.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.jzo2o.api.trade.NativePayApi;
import com.jzo2o.api.trade.TradingApi;
import com.jzo2o.api.trade.dto.request.NativePayReqDTO;
import com.jzo2o.api.trade.dto.response.NativePayResDTO;
import com.jzo2o.api.trade.dto.response.TradingResDTO;
import com.jzo2o.api.trade.enums.PayChannelEnum;
import com.jzo2o.api.trade.enums.TradingStateEnum;
import com.jzo2o.common.expcetions.CommonException;
import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.expcetions.ServerErrorException;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.DateUtils;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.health.constant.RedisConstants;
import com.jzo2o.health.enums.OrderPayStatusEnum;
import com.jzo2o.health.enums.OrderStatusEnum;
import com.jzo2o.health.mapper.OrdersMapper;
import com.jzo2o.health.model.OrderUpdateStatusDTO;
import com.jzo2o.health.model.UserThreadLocal;
import com.jzo2o.health.model.domain.Member;
import com.jzo2o.health.model.domain.Orders;
import com.jzo2o.health.model.domain.Setmeal;
import com.jzo2o.health.model.dto.request.PlaceOrderReqDTO;
import com.jzo2o.health.model.dto.response.OrdersPayResDTO;
import com.jzo2o.health.model.dto.response.PlaceOrderResDTO;
import com.jzo2o.health.properties.TradeProperties;
import com.jzo2o.health.service.*;
import com.jzo2o.rabbitmq.client.RabbitClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 订单创建相关业务层
* @author JIAN
*/
@Slf4j
@Service
public class OrderCreateServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrderCreateService {
@Resource
private IMemberService memberService;
@Resource
private ISetmealService setmealService;
@Resource
private IOrderCommonService ordersCommonService;
@Resource
private IReservationSettingService reservationSettingService;
@Resource
private TradingApi tradingApi;
@Resource
private NativePayApi nativePayApi;
@Resource
private TradeProperties tradeProperties;
@Resource
private RedisTemplate<String, Long> redisTemplate;
@Resource
private TransactionTemplate transactionTemplate;
@Resource
private RabbitClient rabbitClient;
/**
* 生成订单号(2位年+2位月+2位日+13位序号)
*/
private Long generateOrderId() {
Long idNo = redisTemplate.opsForValue().increment(RedisConstants.ORDER_ID_GENERATOR, 1);
String orderId = DateUtils.format(LocalDateTime.now(), "yyMMdd") + String.format("%013d", idNo);
return Long.valueOf(orderId);
}
@Override
public PlaceOrderResDTO placeOrder(PlaceOrderReqDTO placeOrderReqDTO) {
Long currentUserId = UserThreadLocal.currentUserId();
if (ObjectUtils.isEmpty(currentUserId)) {
throw new ForbiddenOperationException("用户信息不存在无法下单");
}
Member member = memberService.getById(currentUserId);
if (ObjectUtils.isEmpty(member)) {
throw new ForbiddenOperationException("用户信息不存在无法下单");
}
Setmeal setmeal = setmealService.getById(placeOrderReqDTO.getSetmealId());
if (ObjectUtils.isEmpty(setmeal)) {
throw new ForbiddenOperationException("套餐信息不存在无法下单");
}
// 生成订单id
Long orderId = this.generateOrderId();
if (ObjectUtils.isEmpty(orderId)) {
throw new ServerErrorException("生成订单id失败无法下单");
}
transactionTemplate.executeWithoutResult(status -> {
if (!SqlHelper.retBool(baseMapper.insert(Orders.builder()
.id(orderId)
.orderStatus(OrderStatusEnum.NO_PAY)
.payStatus(OrderPayStatusEnum.NO_PAY)
.setmealId(setmeal.getId())
.setmealName(setmeal.getName())
.setmealPrice(setmeal.getPrice())
.setmealSex(setmeal.getSex())
.setmealAge(setmeal.getAge())
.setmealImg(setmeal.getImg())
.setmealRemark(setmeal.getRemark())
.reservationDate(placeOrderReqDTO.getReservationDate())
.checkupPersonName(placeOrderReqDTO.getCheckupPersonName())
.checkupPersonSex(placeOrderReqDTO.getCheckupPersonSex())
.checkupPersonPhone(placeOrderReqDTO.getCheckupPersonPhone())
.checkupPersonIdcard(placeOrderReqDTO.getCheckupPersonIdcard())
.memberId(member.getId())
.memberPhone(member.getPhone())
.sortBy(DateUtils.toEpochMilli(LocalDateTime.now()))
.build()))) {
throw new DBException("订单表插入失败下单失败");
}
// 已预约人数 + 1
reservationSettingService.plusReservationCount(placeOrderReqDTO.getReservationDate(), 1);
});
// 发送消息到延时队列处理超时订单(发送检测的订单id)
rabbitClient.sendMsg("health.exchange.topic.order", "order.overtime.in", orderId.toString());
return new PlaceOrderResDTO(orderId);
}
@Override
public OrdersPayResDTO payOrder(Long id, PayChannelEnum tradingChannel) {
Orders orderInfo = baseMapper.selectById(id);
if (ObjectUtils.isEmpty(orderInfo)) {
throw new ForbiddenOperationException("订单不存在无法支付");
}
// 初步防止重复发起支付请求
if (orderInfo.getPayStatus() == OrderPayStatusEnum.PAY_SUCCESS) {
OrdersPayResDTO ordersPayResDTO = BeanUtils.toBean(orderInfo, OrdersPayResDTO.class);
ordersPayResDTO.setProductOrderNo(id);
return ordersPayResDTO;
}
// 下单
String tradingChannelOld = orderInfo.getTradingChannel();
NativePayResDTO nativePayResDTO = nativePayApi.createDownLineTrading(NativePayReqDTO.builder()
.productOrderNo(id)
.productAppId(IOrderCreateService.PRODUCT_APP_ID)
.tradingChannel(tradingChannel)
.tradingAmount(/*orderInfo.getSetmealPrice()*/ new BigDecimal("0.01"))
.memo(orderInfo.getSetmealName())
.changeChannel(ObjectUtils.isNotEmpty(tradingChannelOld)
&& !tradingChannelOld.equals(tradingChannel.name()))
.enterpriseId(tradingChannel == PayChannelEnum.WECHAT_PAY
? tradeProperties.getWechatEnterpriseId()
: tradeProperties.getAliEnterpriseId())
.build());
if (!lambdaUpdate()
.eq(Orders::getId, id)
.set(Orders::getTradingOrderNo, nativePayResDTO.getTradingOrderNo())
.set(Orders::getTradingChannel, nativePayResDTO.getTradingChannel())
.update()) {
log.warn("订单表更新失败(已正常生成支付二维码), 订单id: {}", id);
}
OrdersPayResDTO ordersPayResDTO = BeanUtils.toBean(nativePayResDTO, OrdersPayResDTO.class);
ordersPayResDTO.setPayStatus(OrderPayStatusEnum.NO_PAY.getStatus());
return ordersPayResDTO;
}
@Override
public OrdersPayResDTO getPayResult(Long id) {
Orders orders = baseMapper.selectById(id);
if (ObjectUtils.isEmpty(orders)) {
throw new CommonException("订单不存在");
}
// 公共返回参数
OrdersPayResDTO ordersPayResDTO = BeanUtils.toBean(orders, OrdersPayResDTO.class);
ordersPayResDTO.setProductOrderNo(id);
// 未支付订单更新状态
Long tradingOrderNo = orders.getTradingOrderNo();
if (ObjectUtils.isNotEmpty(tradingOrderNo)
&& orders.getPayStatus() == OrderPayStatusEnum.NO_PAY) {
TradingResDTO tradingResDTO = tradingApi.findTradResultByTradingOrderNo(tradingOrderNo);
// 支付成功
if (ObjectUtils.isNotEmpty(tradingResDTO)
&& tradingResDTO.getTradingState() == TradingStateEnum.YJS) {
if (!ordersCommonService.updateStatus(OrderUpdateStatusDTO.builder()
.id(id)
.originStatus(OrderStatusEnum.NO_PAY)
.targetStatus(OrderStatusEnum.WAITING_CHECKUP)
.payStatus(OrderPayStatusEnum.PAY_SUCCESS)
.tradingOrderNo(tradingResDTO.getTradingOrderNo())
.transactionId(tradingResDTO.getTransactionId())
.tradingChannel(tradingResDTO.getTradingChannel())
.payTime(LocalDateTime.now())
.build())) {
throw new DBException("订单表更新失败");
}
// 支付成功更新最终响应信息的状态
ordersPayResDTO.setPayStatus(OrderPayStatusEnum.PAY_SUCCESS.getStatus());
} else {
// 未支付成功返回二维码
ordersPayResDTO.setQrCode(tradingResDTO.getQrCode());
}
}
return ordersPayResDTO;
}
}

Some files were not shown because too many files have changed in this diff Show More