feat:初始化项目模型

This commit is contained in:
amos wong
2025-11-01 19:58:08 +08:00
commit 850b5a76d7
49 changed files with 2011 additions and 0 deletions

43
.gitignore vendored Normal file
View File

@@ -0,0 +1,43 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
*.log
.DS_Store
logs/
/.xcodemap
.cursorindexingignore
.specstory
### SQL Files ###
*.sql
*.md

20
common/pom.xml Normal file
View File

@@ -0,0 +1,20 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>pers.amos</groupId>
<artifactId>tech-mall</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>common</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@@ -0,0 +1,28 @@
package pers.amos.mall.common.constant;
/**
* 通用错误码
*/
public interface CommonErrorCode {
/**
* 系统错误
*/
String SYSTEM_ERROR = "SYSTEM_ERROR";
/**
* 参数错误
*/
String PARAM_ERROR = "PARAM_ERROR";
/**
* 数据不存在
*/
String DATA_NOT_FOUND = "DATA_NOT_FOUND";
/**
* 操作失败
*/
String OPERATION_FAILED = "OPERATION_FAILED";
}

View File

@@ -0,0 +1,36 @@
package pers.amos.mall.common.exception;
import lombok.Getter;
import pers.amos.mall.common.response.ErrorType;
/**
* 业务异常
*/
@Getter
public class BusinessException extends RuntimeException {
private String errorCode;
private String errorDesc;
private ErrorType errorType;
public BusinessException(String errorDesc) {
super(errorDesc);
this.errorDesc = errorDesc;
this.errorType = ErrorType.BUSINESS;
}
public BusinessException(String errorCode, String errorDesc) {
super(errorDesc);
this.errorCode = errorCode;
this.errorDesc = errorDesc;
this.errorType = ErrorType.BUSINESS;
}
public BusinessException(String errorCode, String errorDesc, ErrorType errorType) {
super(errorDesc);
this.errorCode = errorCode;
this.errorDesc = errorDesc;
this.errorType = errorType;
}
}

View File

@@ -0,0 +1,90 @@
package pers.amos.mall.common.page;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* 通用分页结果
*
* @param <T> 数据类型
*/
@Data
public class CommonPage<T> implements Serializable {
private static final long serialVersionUID = -2207524948286807221L;
/**
* 当前页码
*/
private Integer pageNum;
/**
* 每页数量
*/
private Integer pageSize;
/**
* 总页数
*/
private Integer totalPage;
/**
* 总条数
*/
private Long total;
/**
* 分页数据
*/
private List<T> list;
/**
* 将PageHelper分页后的list转为分页信息
*/
public static <T> CommonPage<T> buildPage(Integer pageNum, Integer pageSize, Integer totalPage, Long total, List<T> list) {
CommonPage<T> result = new CommonPage<>();
result.setPageNum(pageNum);
result.setPageSize(pageSize);
result.setTotalPage(totalPage);
result.setTotal(total);
result.setList(list);
return result;
}
/**
* 返回空分页数据
*
* @return 空分页
*/
public static CommonPage buildEmptyPage() {
CommonPage result = new CommonPage<>();
result.setPageNum(0);
result.setPageSize(0);
result.setTotalPage(0);
result.setTotal(0L);
result.setList(new ArrayList(0));
return result;
}
/**
* 页内数据转换
*
* @param commonPage 原分页数据
* @param list 新数据列表
* @param <T> 原数据类型
* @param <R> 新数据类型
* @return 转换后的分页数据
*/
public static <T, R> CommonPage<R> copyMetaWithNewData(CommonPage<T> commonPage, List<R> list) {
CommonPage<R> result = new CommonPage<>();
result.setPageNum(commonPage.getPageNum());
result.setPageSize(commonPage.getPageSize());
result.setTotalPage(commonPage.getTotalPage());
result.setTotal(commonPage.getTotal());
result.setList(list);
return result;
}
}

View File

@@ -0,0 +1,27 @@
package pers.amos.mall.common.response;
/**
* 错误类型枚举
*/
public enum ErrorType {
/**
* 系统错误
*/
SYSTEM,
/**
* 业务错误
*/
BUSINESS,
/**
* 参数错误
*/
PARAM,
/**
* 第三方错误
*/
THIRD_PARTY
}

View File

@@ -0,0 +1,191 @@
package pers.amos.mall.common.response;
import lombok.Data;
import lombok.Getter;
import java.io.Serializable;
/**
* 统一响应结果封装
*
* @param <T> 数据类型
*/
@Getter
@Data
@SuppressWarnings("all")
public class Result<T> implements Serializable {
/**
* SID
*/
private static final long serialVersionUID = -9015635270304492869L;
/**
* 成功标志
*/
private boolean success;
/**
* 错误码名称
*/
private String errorCode;
/**
* 错误码描述, 主要针对保险产生的统一错误码的描述
*/
private String errorDesc;
/**
* 失败时异常类型
*/
private ErrorType errorType = ErrorType.SYSTEM;
/**
* exceptionType
* 由于facade不抛出异常通过InsException把异常扔出
* 需增加exceptionType去打印异常类型
*/
private String exceptionType;
/**
* 业务数据
*/
private T data;
public Result() {
}
public Result(boolean success, T data) {
this.success = success;
this.data = data;
}
public Result(boolean success, String errorCode, String errorDesc, T model) {
this.success = success;
this.errorCode = errorCode;
this.errorDesc = errorDesc;
this.data = model;
}
public Result(boolean success, String errorCode, String errorDesc, ErrorType errorType) {
this.success = success;
this.errorCode = errorCode;
this.errorDesc = errorDesc;
this.errorType = errorType;
}
public Result(boolean success, String errorCode, String errorDesc, String exceptionType) {
this.success = success;
this.errorCode = errorCode;
this.errorDesc = errorDesc;
this.exceptionType = exceptionType;
}
public Result(boolean success, String errorCode, String errorDesc) {
this.success = success;
this.errorCode = errorCode;
this.errorDesc = errorDesc;
}
/**
* 成功结果构造
*
* @param data 数据
* @param <T> 数据类型
* @return 成功结果
*/
public static <T> Result<T> success(T data) {
return new Result<>(true, data);
}
/**
* 成功结果构造(无数据)
*
* @param <T> 数据类型
* @return 成功结果
*/
public static <T> Result<T> success() {
return new Result<>(true, null);
}
/**
* 失败结果构造
*
* @param errorCode 错误码
* @param errorDesc 错误描述
* @param errorType 错误类型
* @param <T> 数据类型
* @return 失败结果
*/
public static <T> Result<T> fail(String errorCode, String errorDesc, ErrorType errorType) {
return new Result<>(false, errorCode, errorDesc, errorType);
}
/**
* 失败结果构造
*
* @param errorCode 错误码
* @param errorDesc 错误描述
* @param <T> 数据类型
* @return 失败结果
*/
public static <T> Result<T> fail(String errorCode, String errorDesc) {
return new Result<>(false, errorCode, errorDesc);
}
/**
* 失败结果构造
*
* @param errorCode 错误码
* @param errorDesc 错误描述
* @param exceptionType 异常类型
* @param <T> 数据类型
* @return 失败结果
*/
public static <T> Result<T> fail(String errorCode, String errorDesc, String exceptionType) {
return new Result<>(false, errorCode, errorDesc, exceptionType);
}
public Result<T> setData(T data) {
this.data = data;
return this;
}
/**
* Setter method for property <tt>success</tt>.
*
* @param success value to be assigned to property success
*/
public void setSuccess(boolean success) {
this.success = success;
}
/**
* Setter method for property <tt>errorCode</tt>.
*
* @param errorCode value to be assigned to property errorCode
*/
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
/**
* Setter method for property <tt>errorDesc</tt>.
*
* @param errorDesc value to be assigned to property errorDesc
*/
public void setErrorDesc(String errorDesc) {
this.errorDesc = errorDesc;
}
public Result<T> setErrorType(ErrorType errorType) {
this.errorType = errorType;
return this;
}
public void setExceptionType(String exceptionType) {
this.exceptionType = exceptionType;
}
}

71
perform/pom.xml Normal file
View File

@@ -0,0 +1,71 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>pers.amos</groupId>
<artifactId>tech-mall</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>perform</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- 内部依赖 -->
<dependency>
<groupId>pers.amos</groupId>
<artifactId>common</artifactId>
</dependency>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Mybatis Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- PageHelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!-- Nacos -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</dependency>
<!-- RocketMQ -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,20 @@
package pers.amos.mall.perform;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 履约核销模块启动类
*/
@EnableDubbo
@SpringBootApplication
@MapperScan("pers.amos.mall.perform.dal.mapper")
public class PerformApplicationStarter {
public static void main(String[] args) {
SpringApplication.run(PerformApplicationStarter.class, args);
}
}

View File

@@ -0,0 +1,96 @@
package pers.amos.mall.perform.dal.dataobject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 电子车票实体
*/
@Data
@TableName("ticket")
public class Ticket implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 车票号(唯一)
*/
private String ticketNo;
/**
* 订单ID
*/
private Long orderId;
/**
* 持票人用户ID
*/
private Long userId;
/**
* 线路ID
*/
private Long routeId;
/**
* 班次ID
*/
private Long scheduleId;
/**
* 票种
*/
private String ticketType;
/**
* 二维码内容加密后的ticketNo
*/
private String qrCode;
/**
* 二维码图片URL
*/
private String qrCodeUrl;
/**
* 状态VALID-有效USED-已使用EXPIRED-已过期REFUNDED-已退款
*/
private String status;
/**
* 出票时间
*/
private LocalDateTime issueTime;
/**
* 核销时间
*/
private LocalDateTime usedTime;
/**
* 过期时间(班次发车时间)
*/
private LocalDateTime expireTime;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,71 @@
package pers.amos.mall.perform.dal.dataobject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 车票核销记录实体
*/
@Data
@TableName("ticket_verification")
public class TicketVerification implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 车票ID
*/
private Long ticketId;
/**
* 实际核销的班次ID
*/
private Long scheduleId;
/**
* 二维码
*/
private String qrCode;
/**
* 核销结果SUCCESS-成功FAILED-失败
*/
private String verifyResult;
/**
* 失败原因
*/
private String failReason;
/**
* 核销设备ID
*/
private String deviceId;
/**
* 设备位置
*/
private String deviceLocation;
/**
* 核销时间
*/
private LocalDateTime verifyTime;
/**
* 创建时间
*/
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,13 @@
package pers.amos.mall.perform.dal.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import pers.amos.mall.perform.dal.dataobject.Ticket;
/**
* 电子车票Mapper
*/
@Mapper
public interface TicketMapper extends BaseMapper<Ticket> {
}

View File

@@ -0,0 +1,13 @@
package pers.amos.mall.perform.dal.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import pers.amos.mall.perform.dal.dataobject.TicketVerification;
/**
* 车票核销记录Mapper
*/
@Mapper
public interface TicketVerificationMapper extends BaseMapper<TicketVerification> {
}

View File

@@ -0,0 +1,11 @@
package pers.amos.mall.perform.dal.repository;
import com.baomidou.mybatisplus.extension.service.IService;
import pers.amos.mall.perform.dal.dataobject.Ticket;
/**
* 电子车票Repository
*/
public interface TicketRepository extends IService<Ticket> {
}

View File

@@ -0,0 +1,11 @@
package pers.amos.mall.perform.dal.repository;
import com.baomidou.mybatisplus.extension.service.IService;
import pers.amos.mall.perform.dal.dataobject.TicketVerification;
/**
* 车票核销记录Repository
*/
public interface TicketVerificationRepository extends IService<TicketVerification> {
}

View File

@@ -0,0 +1,15 @@
package pers.amos.mall.perform.dal.repository.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import pers.amos.mall.perform.dal.dataobject.Ticket;
import pers.amos.mall.perform.dal.mapper.TicketMapper;
import pers.amos.mall.perform.dal.repository.TicketRepository;
/**
* 电子车票Repository实现
*/
@Service
public class TicketRepositoryImpl extends ServiceImpl<TicketMapper, Ticket> implements TicketRepository {
}

View File

@@ -0,0 +1,15 @@
package pers.amos.mall.perform.dal.repository.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import pers.amos.mall.perform.dal.dataobject.TicketVerification;
import pers.amos.mall.perform.dal.mapper.TicketVerificationMapper;
import pers.amos.mall.perform.dal.repository.TicketVerificationRepository;
/**
* 车票核销记录Repository实现
*/
@Service
public class TicketVerificationRepositoryImpl extends ServiceImpl<TicketVerificationMapper, TicketVerification> implements TicketVerificationRepository {
}

View File

@@ -0,0 +1,57 @@
server:
port: 8083
spring:
application:
name: tech-mall-perform
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/tech_mall_perform?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: root
# Jackson配置
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
# Mybatis Plus配置
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: auto
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
# PageHelper配置
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countSql
# Dubbo配置
dubbo:
application:
name: ${spring.application.name}
protocol:
name: dubbo
port: 20883
registry:
address: nacos://localhost:8848
scan:
base-packages: pers.amos.mall.perform.api
# RocketMQ配置
rocketmq:
name-server: localhost:9876
producer:
group: perform-producer-group
consumer:
group: perform-consumer-group

158
pom.xml Normal file
View File

@@ -0,0 +1,158 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pers.amos</groupId>
<artifactId>tech-mall</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>common</module>
<module>route</module>
<module>trade</module>
<module>perform</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 版本管理 -->
<spring-boot.version>2.7.18</spring-boot.version>
<dubbo.version>3.2.9</dubbo.version>
<nacos.version>2.2.1</nacos.version>
<mybatis-plus.version>3.5.5</mybatis-plus.version>
<rocketmq.version>2.2.3</rocketmq.version>
<mysql.version>8.0.33</mysql.version>
<pagehelper.version>1.4.7</pagehelper.version>
<commons-lang3.version>3.17.0</commons-lang3.version>
<hutool.version>5.8.41</hutool.version>
<lombok.version>1.18.38</lombok.version>
<fastjson2.version>2.0.43</fastjson2.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bom</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!-- Nacos -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
</dependency>
<!-- RocketMQ -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>${rocketmq.version}</version>
</dependency>
<!-- Mybatis Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- PageHelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.version}</version>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- FastJson2 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson2.version}</version>
</dependency>
<!-- Commons Lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<!-- Hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<!-- 内部模块 -->
<dependency>
<groupId>pers.amos</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 所有模块都需要的依赖 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
</dependency>
</dependencies>
</project>

70
route/pom.xml Normal file
View File

@@ -0,0 +1,70 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>pers.amos</groupId>
<artifactId>tech-mall</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>route</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- 内部依赖 -->
<dependency>
<groupId>pers.amos</groupId>
<artifactId>common</artifactId>
</dependency>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Mybatis Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- PageHelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!-- Nacos -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</dependency>
<!-- RocketMQ -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,20 @@
package pers.amos.mall.route;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 线路调度模块启动类
*/
@EnableDubbo
@SpringBootApplication
@MapperScan("pers.amos.mall.route.dal.mapper")
public class RouteApplicationStarter {
public static void main(String[] args) {
SpringApplication.run(RouteApplicationStarter.class, args);
}
}

View File

@@ -0,0 +1,97 @@
package pers.amos.mall.route.dal.dataobject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 线路实体
*/
@Data
@TableName("route")
public class Route implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 线路编码
*/
private String routeCode;
/**
* 线路名称
*/
private String routeName;
/**
* 起点站
*/
private String startStation;
/**
* 终点站
*/
private String endStation;
/**
* 里程(公里)
*/
private Integer distance;
/**
* 预计时长(分钟)
*/
private Integer estimatedDuration;
/**
* 基础票价(成人票)
*/
private BigDecimal basePrice;
/**
* 学生票价
*/
private BigDecimal studentPrice;
/**
* 儿童票价
*/
private BigDecimal childPrice;
/**
* 班次类型INTERVAL-间隔发车FIXED-固定时刻
*/
private String scheduleType;
/**
* 班次间隔(分钟)- 仅当scheduleType=INTERVAL时有效
*/
private Integer scheduleInterval;
/**
* 状态1-运营中0-停运
*/
private Integer status;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,96 @@
package pers.amos.mall.route.dal.dataobject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
/**
* 班次实体(包含库存管理)
*/
@Data
@TableName("schedule")
public class Schedule implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 所属线路ID
*/
private Long routeId;
/**
* 班次编号
*/
private String scheduleCode;
/**
* 班次日期
*/
private LocalDate scheduleDate;
/**
* 发车时间
*/
private LocalTime departureTime;
/**
* 到达时间
*/
private LocalTime arrivalTime;
/**
* 总座位数
*/
private Integer totalSeats;
/**
* 可售座位数(可用库存)
*/
private Integer availableSeats;
/**
* 已售座位数
*/
private Integer soldSeats;
/**
* 班次票价(如果为空则使用线路价格)
*/
private BigDecimal price;
/**
* 状态1-可售2-售罄3-已发车4-已取消
*/
private Integer status;
/**
* 乐观锁版本号(防止超卖)
*/
@Version
private Integer version;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,66 @@
package pers.amos.mall.route.dal.dataobject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 班次库存变动日志
*/
@Data
@TableName("schedule_inventory_log")
public class ScheduleInventoryLog implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 班次ID
*/
private Long scheduleId;
/**
* 操作类型LOCK-锁定UNLOCK-解锁DEDUCT-扣减RELEASE-释放
*/
private String operationType;
/**
* 变动数量
*/
private Integer quantity;
/**
* 操作前库存
*/
private Integer beforeQty;
/**
* 操作后库存
*/
private Integer afterQty;
/**
* 关联订单ID
*/
private Long orderId;
/**
* 操作描述
*/
private String remark;
/**
* 创建时间
*/
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,13 @@
package pers.amos.mall.route.dal.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import pers.amos.mall.route.dal.dataobject.Route;
/**
* 线路Mapper
*/
@Mapper
public interface RouteMapper extends BaseMapper<Route> {
}

View File

@@ -0,0 +1,13 @@
package pers.amos.mall.route.dal.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import pers.amos.mall.route.dal.dataobject.ScheduleInventoryLog;
/**
* 班次库存变动日志Mapper
*/
@Mapper
public interface ScheduleInventoryLogMapper extends BaseMapper<ScheduleInventoryLog> {
}

View File

@@ -0,0 +1,13 @@
package pers.amos.mall.route.dal.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import pers.amos.mall.route.dal.dataobject.Schedule;
/**
* 班次Mapper
*/
@Mapper
public interface ScheduleMapper extends BaseMapper<Schedule> {
}

View File

@@ -0,0 +1,11 @@
package pers.amos.mall.route.dal.repository;
import com.baomidou.mybatisplus.extension.service.IService;
import pers.amos.mall.route.dal.dataobject.Route;
/**
* 线路Repository
*/
public interface RouteRepository extends IService<Route> {
}

View File

@@ -0,0 +1,11 @@
package pers.amos.mall.route.dal.repository;
import com.baomidou.mybatisplus.extension.service.IService;
import pers.amos.mall.route.dal.dataobject.ScheduleInventoryLog;
/**
* 班次库存变动日志Repository
*/
public interface ScheduleInventoryLogRepository extends IService<ScheduleInventoryLog> {
}

View File

@@ -0,0 +1,11 @@
package pers.amos.mall.route.dal.repository;
import com.baomidou.mybatisplus.extension.service.IService;
import pers.amos.mall.route.dal.dataobject.Schedule;
/**
* 班次Repository
*/
public interface ScheduleRepository extends IService<Schedule> {
}

View File

@@ -0,0 +1,15 @@
package pers.amos.mall.route.dal.repository.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import pers.amos.mall.route.dal.dataobject.Route;
import pers.amos.mall.route.dal.mapper.RouteMapper;
import pers.amos.mall.route.dal.repository.RouteRepository;
/**
* 线路Repository实现
*/
@Service
public class RouteRepositoryImpl extends ServiceImpl<RouteMapper, Route> implements RouteRepository {
}

View File

@@ -0,0 +1,15 @@
package pers.amos.mall.route.dal.repository.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import pers.amos.mall.route.dal.dataobject.ScheduleInventoryLog;
import pers.amos.mall.route.dal.mapper.ScheduleInventoryLogMapper;
import pers.amos.mall.route.dal.repository.ScheduleInventoryLogRepository;
/**
* 班次库存变动日志Repository实现
*/
@Service
public class ScheduleInventoryLogRepositoryImpl extends ServiceImpl<ScheduleInventoryLogMapper, ScheduleInventoryLog> implements ScheduleInventoryLogRepository {
}

View File

@@ -0,0 +1,15 @@
package pers.amos.mall.route.dal.repository.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import pers.amos.mall.route.dal.dataobject.Schedule;
import pers.amos.mall.route.dal.mapper.ScheduleMapper;
import pers.amos.mall.route.dal.repository.ScheduleRepository;
/**
* 班次Repository实现
*/
@Service
public class ScheduleRepositoryImpl extends ServiceImpl<ScheduleMapper, Schedule> implements ScheduleRepository {
}

View File

@@ -0,0 +1,55 @@
server:
port: 8081
spring:
application:
name: tech-mall-route
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/tech_mall_route?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: root
# Jackson配置
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
# Mybatis Plus配置
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: auto
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
# PageHelper配置
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countSql
# Dubbo配置
dubbo:
application:
name: ${spring.application.name}
protocol:
name: dubbo
port: 20881
registry:
address: nacos://localhost:8848
scan:
base-packages: pers.amos.mall.route.api
# RocketMQ配置
rocketmq:
name-server: localhost:9876
producer:
group: route-producer-group

70
trade/pom.xml Normal file
View File

@@ -0,0 +1,70 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>pers.amos</groupId>
<artifactId>tech-mall</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>trade</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- 内部依赖 -->
<dependency>
<groupId>pers.amos</groupId>
<artifactId>common</artifactId>
</dependency>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Mybatis Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- PageHelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!-- Nacos -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</dependency>
<!-- RocketMQ -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,19 @@
package pers.amos.mall.trade;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 交易核销模块启动类
*/
@EnableDubbo
@SpringBootApplication
@MapperScan("pers.amos.mall.trade.dal.mapper")
public class TradeApplicationStarter {
public static void main(String[] args) {
SpringApplication.run(TradeApplicationStarter.class, args);
}
}

View File

@@ -0,0 +1,92 @@
package pers.amos.mall.trade.dal.dataobject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 订单实体
*/
@Data
@TableName("orders")
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 订单号
*/
private String orderNo;
/**
* 用户ID
*/
private Long userId;
/**
* 线路ID
*/
private Long routeId;
/**
* 班次ID
*/
private Long scheduleId;
/**
* 票种ADULT-成人票STUDENT-学生票CHILD-儿童票
*/
private String ticketType;
/**
* 购票数量
*/
private Integer quantity;
/**
* 单价
*/
private BigDecimal unitPrice;
/**
* 总金额
*/
private BigDecimal totalAmount;
/**
* 订单状态UNPAID-待支付PAID-已支付USING-使用中COMPLETED-已完成CANCELLED-已取消REFUNDED-已退款
*/
private String orderStatus;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 支付时间
*/
private LocalDateTime payTime;
/**
* 支付超时时间
*/
private LocalDateTime expireTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,72 @@
package pers.amos.mall.trade.dal.dataobject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 支付记录实体
*/
@Data
@TableName("payment")
public class Payment implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 订单ID
*/
private Long orderId;
/**
* 支付流水号
*/
private String paymentNo;
/**
* 支付金额
*/
private BigDecimal paymentAmount;
/**
* 支付方式ALIPAY-支付宝WECHAT-微信
*/
private String paymentMethod;
/**
* 支付状态PENDING-待支付SUCCESS-成功FAILED-失败
*/
private String paymentStatus;
/**
* 第三方交易号
*/
private String transactionNo;
/**
* 支付时间
*/
private LocalDateTime paymentTime;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,77 @@
package pers.amos.mall.trade.dal.dataobject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 退款记录实体
*/
@Data
@TableName("refund")
public class Refund implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 订单ID
*/
private Long orderId;
/**
* 退款单号
*/
private String refundNo;
/**
* 退款金额
*/
private BigDecimal refundAmount;
/**
* 退款手续费
*/
private BigDecimal refundFee;
/**
* 实际退款金额
*/
private BigDecimal actualRefundAmount;
/**
* 退款原因
*/
private String refundReason;
/**
* 退款状态PENDING-待退款SUCCESS-成功FAILED-失败
*/
private String refundStatus;
/**
* 退款时间
*/
private LocalDateTime refundTime;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,13 @@
package pers.amos.mall.trade.dal.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import pers.amos.mall.trade.dal.dataobject.Order;
/**
* 订单Mapper
*/
@Mapper
public interface OrderMapper extends BaseMapper<Order> {
}

View File

@@ -0,0 +1,13 @@
package pers.amos.mall.trade.dal.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import pers.amos.mall.trade.dal.dataobject.Payment;
/**
* 支付记录Mapper
*/
@Mapper
public interface PaymentMapper extends BaseMapper<Payment> {
}

View File

@@ -0,0 +1,13 @@
package pers.amos.mall.trade.dal.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import pers.amos.mall.trade.dal.dataobject.Refund;
/**
* 退款记录Mapper
*/
@Mapper
public interface RefundMapper extends BaseMapper<Refund> {
}

View File

@@ -0,0 +1,11 @@
package pers.amos.mall.trade.dal.repository;
import com.baomidou.mybatisplus.extension.service.IService;
import pers.amos.mall.trade.dal.dataobject.Order;
/**
* 订单Repository
*/
public interface OrderRepository extends IService<Order> {
}

View File

@@ -0,0 +1,11 @@
package pers.amos.mall.trade.dal.repository;
import com.baomidou.mybatisplus.extension.service.IService;
import pers.amos.mall.trade.dal.dataobject.Payment;
/**
* 支付记录Repository
*/
public interface PaymentRepository extends IService<Payment> {
}

View File

@@ -0,0 +1,11 @@
package pers.amos.mall.trade.dal.repository;
import com.baomidou.mybatisplus.extension.service.IService;
import pers.amos.mall.trade.dal.dataobject.Refund;
/**
* 退款记录Repository
*/
public interface RefundRepository extends IService<Refund> {
}

View File

@@ -0,0 +1,15 @@
package pers.amos.mall.trade.dal.repository.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import pers.amos.mall.trade.dal.dataobject.Order;
import pers.amos.mall.trade.dal.mapper.OrderMapper;
import pers.amos.mall.trade.dal.repository.OrderRepository;
/**
* 订单Repository实现
*/
@Service
public class OrderRepositoryImpl extends ServiceImpl<OrderMapper, Order> implements OrderRepository {
}

View File

@@ -0,0 +1,15 @@
package pers.amos.mall.trade.dal.repository.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import pers.amos.mall.trade.dal.dataobject.Payment;
import pers.amos.mall.trade.dal.mapper.PaymentMapper;
import pers.amos.mall.trade.dal.repository.PaymentRepository;
/**
* 支付记录Repository实现
*/
@Service
public class PaymentRepositoryImpl extends ServiceImpl<PaymentMapper, Payment> implements PaymentRepository {
}

View File

@@ -0,0 +1,15 @@
package pers.amos.mall.trade.dal.repository.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import pers.amos.mall.trade.dal.dataobject.Refund;
import pers.amos.mall.trade.dal.mapper.RefundMapper;
import pers.amos.mall.trade.dal.repository.RefundRepository;
/**
* 退款记录Repository实现
*/
@Service
public class RefundRepositoryImpl extends ServiceImpl<RefundMapper, Refund> implements RefundRepository {
}

View File

@@ -0,0 +1,57 @@
server:
port: 8082
spring:
application:
name: tech-mall-trade
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/tech_mall_trade?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: root
# Jackson配置
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
# Mybatis Plus配置
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: auto
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
# PageHelper配置
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countSql
# Dubbo配置
dubbo:
application:
name: ${spring.application.name}
protocol:
name: dubbo
port: 20882
registry:
address: nacos://localhost:8848
scan:
base-packages: pers.amos.mall.trade.api
# RocketMQ配置
rocketmq:
name-server: localhost:9876
producer:
group: trade-producer-group
consumer:
group: trade-consumer-group