docs(readme): 添加项目启动和编译问题解决方案文档
- 新增 FIX_COMPILE.md 文件,提供修复IDE编译问题的四种方法 - 新增 HOW_TO_START.md 文件,详细说明如何正确启动后端服务 - 强调必须启动 mt-pay 模块的 MtPayApplication 类 - 提供 IntelliJ IDEA 和 Maven 两种启动方式 - 列出常见启动错误及解决方案 - 添加快速检查清单帮助验证启动状态
This commit is contained in:
108
FIX_COMPILE.md
Normal file
108
FIX_COMPILE.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# 修复编译问题指南
|
||||
|
||||
## 问题描述
|
||||
IDE提示"Java file is located outside of the module source root, so it won't be compiled"
|
||||
|
||||
## 解决步骤
|
||||
|
||||
### 方法1:在 IntelliJ IDEA 中重新导入项目(推荐)
|
||||
|
||||
1. **关闭项目**
|
||||
- File → Close Project
|
||||
|
||||
2. **重新打开项目**
|
||||
- File → Open
|
||||
- 选择 `E:\MTKJPAY` 目录
|
||||
- 选择 "Open as Project"
|
||||
|
||||
3. **等待 Maven 导入完成**
|
||||
- 右下角会显示 "Importing Maven projects..."
|
||||
- 等待完成
|
||||
|
||||
4. **刷新 Maven 项目**
|
||||
- 右键根目录项目 → Maven → Reload Project
|
||||
- 或者:View → Tool Windows → Maven → 点击刷新按钮
|
||||
|
||||
5. **重新构建项目**
|
||||
- Build → Rebuild Project
|
||||
|
||||
### 方法2:手动配置 Source Root
|
||||
|
||||
1. **打开项目结构**
|
||||
- File → Project Structure (Ctrl+Alt+Shift+S)
|
||||
|
||||
2. **检查 Modules**
|
||||
- 左侧选择 "Modules"
|
||||
- 确认有两个模块:
|
||||
- `MTKJPAY` (根模块)
|
||||
- `mt-pay` (子模块)
|
||||
|
||||
3. **配置 MTKJPAY 模块**
|
||||
- 选择 `MTKJPAY` 模块
|
||||
- 在 "Sources" 标签页
|
||||
- 确认 `src/main/java` 标记为蓝色(Source Folders)
|
||||
- 确认 `src/main/resources` 标记为绿色(Resources Folders)
|
||||
- 如果没有标记,右键文件夹 → Mark Directory as → Sources Root / Resources Root
|
||||
|
||||
4. **配置 mt-pay 模块**
|
||||
- 选择 `mt-pay` 模块
|
||||
- 在 "Sources" 标签页
|
||||
- 确认 `mt-pay/src/main/java` 标记为蓝色
|
||||
- 确认 `mt-pay/src/main/resources` 标记为绿色
|
||||
|
||||
5. **应用并确定**
|
||||
- 点击 "Apply" → "OK"
|
||||
|
||||
### 方法3:使用 Maven 命令编译
|
||||
|
||||
```bash
|
||||
# 进入项目根目录
|
||||
cd E:\MTKJPAY
|
||||
|
||||
# 清理并编译
|
||||
mvn clean compile
|
||||
|
||||
# 或者安装到本地仓库
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
### 方法4:检查 IDE 设置
|
||||
|
||||
1. **检查 Maven 设置**
|
||||
- File → Settings → Build, Execution, Deployment → Build Tools → Maven
|
||||
- 确认 "Maven home directory" 正确
|
||||
- 确认 "User settings file" 正确
|
||||
|
||||
2. **检查 Java 设置**
|
||||
- File → Settings → Build, Execution, Deployment → Compiler → Java Compiler
|
||||
- 确认 "Project bytecode version" 是 17
|
||||
|
||||
3. **检查项目 SDK**
|
||||
- File → Project Structure → Project
|
||||
- 确认 "SDK" 是 Java 17
|
||||
- 确认 "Language level" 是 17
|
||||
|
||||
## 验证修复
|
||||
|
||||
编译成功后:
|
||||
1. 在 IDE 中,Java 文件不应该有红色波浪线
|
||||
2. 可以正常启动 `MtkjpayApplication`
|
||||
3. 控制台没有编译错误
|
||||
|
||||
## 如果仍然有问题
|
||||
|
||||
1. **删除 .idea 文件夹**(需要关闭项目)
|
||||
- 关闭 IntelliJ IDEA
|
||||
- 删除 `E:\MTKJPAY\.idea` 文件夹
|
||||
- 重新打开项目
|
||||
|
||||
2. **删除 target 文件夹**
|
||||
```bash
|
||||
cd E:\MTKJPAY
|
||||
rmdir /s /q target
|
||||
rmdir /s /q mt-pay\target
|
||||
```
|
||||
|
||||
3. **重新导入项目**
|
||||
- 按照方法1重新导入
|
||||
|
||||
121
HOW_TO_START.md
Normal file
121
HOW_TO_START.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# 如何正确启动后端服务
|
||||
|
||||
## ⚠️ 重要:启动正确的模块
|
||||
|
||||
项目有两个启动类,**必须启动 `mt-pay` 模块的启动类**:
|
||||
|
||||
### ✅ 正确的启动类
|
||||
- **类名**:`com.mtkj.mtpay.MtPayApplication`
|
||||
- **位置**:`MTKJPAY/mt-pay/src/main/java/com/mtkj/mtpay/MtPayApplication.java`
|
||||
- **端口**:8082
|
||||
- **包含**:所有业务代码、控制器、服务等
|
||||
|
||||
### ❌ 错误的启动类(不要启动这个!)
|
||||
- **类名**:`com.mtkj.mtkjpay.MtkjpayApplication`
|
||||
- **位置**:`MTKJPAY/src/main/java/com/mtkj/mtkjpay/MtkjpayApplication.java`
|
||||
- **端口**:8080
|
||||
- **包含**:仅占位代码,无业务功能
|
||||
|
||||
## 在 IntelliJ IDEA 中启动
|
||||
|
||||
### 步骤1:确认项目结构
|
||||
确保在 Project 视图中能看到 `mt-pay` 模块:
|
||||
```
|
||||
MTKJPAY
|
||||
├── mt-pay ← 这个模块
|
||||
│ └── src
|
||||
│ └── main
|
||||
│ └── java
|
||||
│ └── com
|
||||
│ └── mtkj
|
||||
│ └── mtpay
|
||||
│ └── MtPayApplication.java ← 启动这个
|
||||
└── src ← 根目录(不要启动这个)
|
||||
└── main
|
||||
└── java
|
||||
└── com
|
||||
└── mtkj
|
||||
└── mtkjpay
|
||||
└── MtkjpayApplication.java ← 不要启动这个
|
||||
```
|
||||
|
||||
### 步骤2:打开正确的启动类
|
||||
1. 在 Project 视图中,导航到:
|
||||
`MTKJPAY` → `mt-pay` → `src` → `main` → `java` → `com` → `mtkj` → `mtpay` → `MtPayApplication.java`
|
||||
|
||||
2. 双击打开 `MtPayApplication.java`
|
||||
|
||||
### 步骤3:运行启动类
|
||||
1. 右键点击 `MtPayApplication.java` 文件
|
||||
2. 选择 **"Run 'MtPayApplication.main()'"**
|
||||
3. 或者点击类名旁边的绿色运行按钮
|
||||
|
||||
### 步骤4:确认启动成功
|
||||
启动成功后,控制台会显示:
|
||||
```
|
||||
╔══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ ✅ MTKJ PAY 支付系统启动成功! ✅ ║
|
||||
║ ║
|
||||
╠══════════════════════════════════════════════════════════╣
|
||||
║ 应用名称: mt-pay ║
|
||||
║ 运行环境: dev ║
|
||||
║ 服务端口: 8082 ║
|
||||
║ 后端服务: http://localhost:8082/ ║
|
||||
║ API接口: http://localhost:8082/api ║
|
||||
║ 状态: 🟢 服务运行中,可以接收请求 ║
|
||||
╚══════════════════════════════════════════════════════════╝
|
||||
```
|
||||
|
||||
## 使用 Maven 命令启动
|
||||
|
||||
```bash
|
||||
# 进入 mt-pay 模块目录
|
||||
cd E:\MTKJPAY\mt-pay
|
||||
|
||||
# 启动应用
|
||||
mvn spring-boot:run
|
||||
```
|
||||
|
||||
## 验证启动成功
|
||||
|
||||
1. **检查端口**:
|
||||
```bash
|
||||
netstat -ano | findstr :8082
|
||||
```
|
||||
应该能看到端口 8082 在监听
|
||||
|
||||
2. **访问接口**:
|
||||
在浏览器访问:http://localhost:8082/api/product/1
|
||||
如果返回 JSON 响应,说明启动成功
|
||||
|
||||
3. **查看日志**:
|
||||
控制台应该显示启动成功的标识框
|
||||
|
||||
## 常见错误
|
||||
|
||||
### 错误1:启动的是根目录的 Application
|
||||
- **症状**:端口是 8080,没有业务功能
|
||||
- **解决**:确保启动的是 `mt-pay` 模块的 `MtPayApplication`
|
||||
|
||||
### 错误2:找不到启动类
|
||||
- **症状**:IDE 中找不到 `MtPayApplication`
|
||||
- **解决**:
|
||||
1. 确认 `mt-pay` 模块已正确导入
|
||||
2. 刷新 Maven 项目:右键项目 → Maven → Reload Project
|
||||
3. 重新构建项目:Build → Rebuild Project
|
||||
|
||||
### 错误3:端口被占用
|
||||
- **症状**:启动失败,提示端口 8082 被占用
|
||||
- **解决**:
|
||||
1. 查找占用进程:`netstat -ano | findstr :8082`
|
||||
2. 结束进程或修改端口配置
|
||||
|
||||
## 快速检查清单
|
||||
|
||||
- [ ] 启动的是 `com.mtkj.mtpay.MtPayApplication`
|
||||
- [ ] 不是 `com.mtkj.mtkjpay.MtkjpayApplication`
|
||||
- [ ] 端口是 8082(不是 8080)
|
||||
- [ ] 看到启动成功的标识框
|
||||
- [ ] 可以访问 http://localhost:8082/api/product/1
|
||||
|
||||
46
PORT_CONFIG.md
Normal file
46
PORT_CONFIG.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# 端口配置说明
|
||||
|
||||
## 端口分配
|
||||
|
||||
- **前端(Vite开发服务器)**: `3000`
|
||||
- **后端(Spring Boot应用)**: `8082`
|
||||
|
||||
## 访问地址
|
||||
|
||||
- **前端访问地址**: `http://localhost:3000`
|
||||
- **后端API地址**: `http://localhost:8082`
|
||||
- **Druid监控**: `http://localhost:8082/druid`
|
||||
|
||||
## 代理配置
|
||||
|
||||
前端通过 Vite 代理将 `/api/*` 请求转发到后端:
|
||||
|
||||
```javascript
|
||||
// vite.config.js
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://127.0.0.1:8082',
|
||||
changeOrigin: true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 启动顺序
|
||||
|
||||
1. **启动后端**:运行 `MtPayApplication`,监听 `8082` 端口
|
||||
2. **启动前端**:运行 `npm run dev`,监听 `3000` 端口
|
||||
|
||||
## 配置文件位置
|
||||
|
||||
### 前端
|
||||
- `MTKJPAY-FRONT/vite.config.js` - Vite配置,端口 3000
|
||||
|
||||
### 后端
|
||||
- `MTKJPAY/mt-pay/src/main/resources/application.yml` - 主配置,端口 8082
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 确保两个端口都没有被其他程序占用
|
||||
2. 前端启动后会自动通过代理访问后端
|
||||
3. 如果修改端口,需要同步更新相关配置
|
||||
|
||||
193
mt-pay/logs/mt-pay-error.2025-12-19.log
Normal file
193
mt-pay/logs/mt-pay-error.2025-12-19.log
Normal file
@@ -0,0 +1,193 @@
|
||||
2025-12-19 18:31:44.610 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
|
||||
java.lang.IllegalArgumentException: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String
|
||||
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getTypeForFactoryBeanFromAttributes(FactoryBeanRegistrySupport.java:86)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBean(AbstractAutowireCapableBeanFactory.java:838)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:620)
|
||||
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:573)
|
||||
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:532)
|
||||
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:138)
|
||||
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:775)
|
||||
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:597)
|
||||
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753)
|
||||
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:455)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:323)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
|
||||
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
|
||||
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
|
||||
at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1442)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:552)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
|
||||
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
|
||||
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
|
||||
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
|
||||
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
|
||||
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
|
||||
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:247)
|
||||
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$10(ClassBasedTestDescriptor.java:378)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:383)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$11(ClassBasedTestDescriptor.java:378)
|
||||
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
|
||||
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
|
||||
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
|
||||
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
|
||||
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
|
||||
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
|
||||
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
|
||||
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
|
||||
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:377)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:290)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:289)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:279)
|
||||
at java.base/java.util.Optional.orElseGet(Optional.java:364)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:278)
|
||||
at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
|
||||
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:106)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:105)
|
||||
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:69)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
|
||||
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
|
||||
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
|
||||
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
|
||||
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
|
||||
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
|
||||
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
|
||||
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
|
||||
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
|
||||
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:198)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:169)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:93)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:58)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:141)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:57)
|
||||
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:103)
|
||||
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:85)
|
||||
at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:47)
|
||||
at org.apache.maven.surefire.junitplatform.LazyLauncher.execute(LazyLauncher.java:56)
|
||||
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:184)
|
||||
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:148)
|
||||
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:122)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
|
||||
2025-12-19 18:31:44.617 [main] ERROR o.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener] to prepare test instance [com.mtkj.mtpay.MtPayApplicationTests@3138953b]
|
||||
java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@1756f7cc testClass = com.mtkj.mtpay.MtPayApplicationTests, locations = [], classes = [com.mtkj.mtpay.MtPayApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@6933b6c6, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@1f9e9475, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@23941fb4, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@5c86dbc5, org.springframework.boot.test.context.SpringBootTestAnnotation@95981886], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
|
||||
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:180)
|
||||
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
|
||||
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
|
||||
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
|
||||
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:247)
|
||||
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$10(ClassBasedTestDescriptor.java:378)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:383)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$11(ClassBasedTestDescriptor.java:378)
|
||||
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
|
||||
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
|
||||
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
|
||||
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
|
||||
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
|
||||
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
|
||||
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
|
||||
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
|
||||
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:377)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:290)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:289)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:279)
|
||||
at java.base/java.util.Optional.orElseGet(Optional.java:364)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:278)
|
||||
at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
|
||||
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:106)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:105)
|
||||
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:69)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
|
||||
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
|
||||
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
|
||||
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
|
||||
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
|
||||
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
|
||||
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
|
||||
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
|
||||
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
|
||||
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:198)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:169)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:93)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:58)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:141)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:57)
|
||||
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:103)
|
||||
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:85)
|
||||
at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:47)
|
||||
at org.apache.maven.surefire.junitplatform.LazyLauncher.execute(LazyLauncher.java:56)
|
||||
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:184)
|
||||
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:148)
|
||||
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:122)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
|
||||
Caused by: java.lang.IllegalArgumentException: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String
|
||||
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getTypeForFactoryBeanFromAttributes(FactoryBeanRegistrySupport.java:86)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBean(AbstractAutowireCapableBeanFactory.java:838)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:620)
|
||||
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:573)
|
||||
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:532)
|
||||
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:138)
|
||||
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:775)
|
||||
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:597)
|
||||
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753)
|
||||
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:455)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:323)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
|
||||
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
|
||||
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
|
||||
at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1442)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:552)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
|
||||
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
|
||||
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
|
||||
... 73 common frames omitted
|
||||
197
mt-pay/logs/mt-pay.2025-12-19.log
Normal file
197
mt-pay/logs/mt-pay.2025-12-19.log
Normal file
@@ -0,0 +1,197 @@
|
||||
2025-12-19 18:31:43.770 [background-preinit] INFO org.hibernate.validator.internal.util.Version - HV000001: Hibernate Validator 8.0.1.Final
|
||||
2025-12-19 18:31:43.792 [main] INFO com.mtkj.mtpay.MtPayApplicationTests - Starting MtPayApplicationTests using Java 17.0.12 with PID 20120 (started by 18969 in E:\MTKJPAY\mt-pay)
|
||||
2025-12-19 18:31:43.793 [main] INFO com.mtkj.mtpay.MtPayApplicationTests - No active profile set, falling back to 1 default profile: "default"
|
||||
2025-12-19 18:31:44.587 [main] WARN o.s.w.context.support.GenericWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: java.lang.IllegalArgumentException: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String
|
||||
2025-12-19 18:31:44.610 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
|
||||
java.lang.IllegalArgumentException: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String
|
||||
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getTypeForFactoryBeanFromAttributes(FactoryBeanRegistrySupport.java:86)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBean(AbstractAutowireCapableBeanFactory.java:838)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:620)
|
||||
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:573)
|
||||
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:532)
|
||||
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:138)
|
||||
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:775)
|
||||
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:597)
|
||||
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753)
|
||||
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:455)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:323)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
|
||||
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
|
||||
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
|
||||
at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1442)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:552)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
|
||||
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
|
||||
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
|
||||
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
|
||||
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
|
||||
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
|
||||
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:247)
|
||||
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$10(ClassBasedTestDescriptor.java:378)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:383)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$11(ClassBasedTestDescriptor.java:378)
|
||||
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
|
||||
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
|
||||
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
|
||||
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
|
||||
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
|
||||
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
|
||||
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
|
||||
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
|
||||
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:377)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:290)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:289)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:279)
|
||||
at java.base/java.util.Optional.orElseGet(Optional.java:364)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:278)
|
||||
at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
|
||||
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:106)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:105)
|
||||
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:69)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
|
||||
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
|
||||
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
|
||||
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
|
||||
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
|
||||
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
|
||||
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
|
||||
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
|
||||
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
|
||||
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:198)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:169)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:93)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:58)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:141)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:57)
|
||||
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:103)
|
||||
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:85)
|
||||
at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:47)
|
||||
at org.apache.maven.surefire.junitplatform.LazyLauncher.execute(LazyLauncher.java:56)
|
||||
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:184)
|
||||
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:148)
|
||||
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:122)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
|
||||
2025-12-19 18:31:44.617 [main] ERROR o.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener] to prepare test instance [com.mtkj.mtpay.MtPayApplicationTests@3138953b]
|
||||
java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@1756f7cc testClass = com.mtkj.mtpay.MtPayApplicationTests, locations = [], classes = [com.mtkj.mtpay.MtPayApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@6933b6c6, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@1f9e9475, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@23941fb4, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@5c86dbc5, org.springframework.boot.test.context.SpringBootTestAnnotation@95981886], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
|
||||
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:180)
|
||||
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
|
||||
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191)
|
||||
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130)
|
||||
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:247)
|
||||
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$10(ClassBasedTestDescriptor.java:378)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:383)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$11(ClassBasedTestDescriptor.java:378)
|
||||
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
|
||||
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
|
||||
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
|
||||
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
|
||||
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
|
||||
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
|
||||
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
|
||||
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
|
||||
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:377)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:290)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:289)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:279)
|
||||
at java.base/java.util.Optional.orElseGet(Optional.java:364)
|
||||
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:278)
|
||||
at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
|
||||
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:106)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:105)
|
||||
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:69)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
|
||||
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
|
||||
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
|
||||
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
|
||||
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
|
||||
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
|
||||
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
|
||||
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
|
||||
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
|
||||
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
|
||||
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
|
||||
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:198)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:169)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:93)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:58)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:141)
|
||||
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:57)
|
||||
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:103)
|
||||
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:85)
|
||||
at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:47)
|
||||
at org.apache.maven.surefire.junitplatform.LazyLauncher.execute(LazyLauncher.java:56)
|
||||
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:184)
|
||||
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:148)
|
||||
at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:122)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
|
||||
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
|
||||
Caused by: java.lang.IllegalArgumentException: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String
|
||||
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getTypeForFactoryBeanFromAttributes(FactoryBeanRegistrySupport.java:86)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBean(AbstractAutowireCapableBeanFactory.java:838)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:620)
|
||||
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:573)
|
||||
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:532)
|
||||
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:138)
|
||||
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:775)
|
||||
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:597)
|
||||
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753)
|
||||
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:455)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:323)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
|
||||
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
|
||||
at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
|
||||
at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1442)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:552)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
|
||||
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
|
||||
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
|
||||
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
|
||||
... 73 common frames omitted
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.mtkj.mtpay.common.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 支付类型枚举
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PaymentType {
|
||||
|
||||
/**
|
||||
* 直接付款
|
||||
*/
|
||||
SALE("SALE", "直接付款"),
|
||||
|
||||
/**
|
||||
* 预授权
|
||||
*/
|
||||
AUTH("AUTH", "预授权");
|
||||
|
||||
/**
|
||||
* 类型码
|
||||
*/
|
||||
private final String code;
|
||||
|
||||
/**
|
||||
* 类型描述
|
||||
*/
|
||||
private final String description;
|
||||
|
||||
/**
|
||||
* 根据类型码获取枚举
|
||||
*/
|
||||
public static PaymentType getByCode(String code) {
|
||||
for (PaymentType type : values()) {
|
||||
if (type.getCode().equalsIgnoreCase(code)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.mtkj.mtpay.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* PingPong支付配置属性
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "pingpong")
|
||||
public class PingPongProperties {
|
||||
|
||||
/**
|
||||
* PingPong商户号
|
||||
*/
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
* PingPong商户店铺编号
|
||||
*/
|
||||
private String accId;
|
||||
|
||||
/**
|
||||
* 签名密钥(secret/salt)
|
||||
*/
|
||||
private String secret;
|
||||
|
||||
/**
|
||||
* 签名类型:MD5或SHA256
|
||||
*/
|
||||
private String signType = "MD5";
|
||||
|
||||
/**
|
||||
* API网关地址
|
||||
*/
|
||||
private String gateway = "https://sandbox-acquirer-payment.pingpongx.com";
|
||||
|
||||
/**
|
||||
* 收银台CDN地址
|
||||
*/
|
||||
private String sdkCdnUrl = "https://pay-cdn.pingpongx.com/production/static/sdk/1.2.0/ppPay.min.js";
|
||||
|
||||
/**
|
||||
* 环境模式:sandbox-沙箱,test-测试,build-生产
|
||||
*/
|
||||
private String mode = "sandbox";
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
private Boolean enabled = true;
|
||||
}
|
||||
|
||||
64
mt-pay/src/main/java/com/mtkj/mtpay/entity/MtProduct.java
Normal file
64
mt-pay/src/main/java/com/mtkj/mtpay/entity/MtProduct.java
Normal file
@@ -0,0 +1,64 @@
|
||||
package com.mtkj.mtpay.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 商品实体类
|
||||
*/
|
||||
@TableName(value = "mt_product")
|
||||
@Data
|
||||
public class MtProduct {
|
||||
|
||||
/**
|
||||
* 商品ID
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
@TableField(value = "name", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 商品价格(基础价格,SKU可能有不同价格)
|
||||
*/
|
||||
@TableField(value = "price", jdbcType = org.apache.ibatis.type.JdbcType.DECIMAL)
|
||||
private BigDecimal price;
|
||||
|
||||
/**
|
||||
* 主图URL(最大4000字符)
|
||||
*/
|
||||
@TableField(value = "main_image", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String mainImage;
|
||||
|
||||
/**
|
||||
* 商品状态:ACTIVE-上架,INACTIVE-下架,DELETED-已删除
|
||||
*/
|
||||
@TableField(value = "status", jdbcType = org.apache.ibatis.type.JdbcType.VARCHAR)
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 店铺ID
|
||||
*/
|
||||
@TableField(value = "shop_id", jdbcType = org.apache.ibatis.type.JdbcType.BIGINT)
|
||||
private Long shopId;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(value = "create_time", fill = FieldFill.INSERT)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.mtkj.mtpay.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.mtkj.mtpay.entity.PaymentRecord;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 支付记录Mapper
|
||||
*/
|
||||
@Mapper
|
||||
public interface PaymentRecordMapper extends BaseMapper<PaymentRecord> {
|
||||
|
||||
/**
|
||||
* 根据商户订单号查询记录(按创建时间倒序)
|
||||
*/
|
||||
default List<PaymentRecord> findByMerchantTransactionIdOrderByCreateTimeDesc(String merchantTransactionId) {
|
||||
LambdaQueryWrapper<PaymentRecord> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(PaymentRecord::getMerchantTransactionId, merchantTransactionId)
|
||||
.orderByDesc(PaymentRecord::getCreateTime);
|
||||
return selectList(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据PingPong交易流水号查询记录(按创建时间倒序)
|
||||
*/
|
||||
default List<PaymentRecord> findByTransactionIdOrderByCreateTimeDesc(String transactionId) {
|
||||
LambdaQueryWrapper<PaymentRecord> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(PaymentRecord::getTransactionId, transactionId)
|
||||
.orderByDesc(PaymentRecord::getCreateTime);
|
||||
return selectList(wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.mtkj.mtpay.service;
|
||||
|
||||
import com.mtkj.mtpay.dto.request.CheckoutRequestDTO;
|
||||
import com.mtkj.mtpay.dto.response.CheckoutResponseDTO;
|
||||
|
||||
/**
|
||||
* PingPong支付服务接口
|
||||
* 负责调用PingPong支付API
|
||||
*/
|
||||
public interface PingPongPayService {
|
||||
|
||||
/**
|
||||
* 创建支付订单(调用checkout接口)
|
||||
*
|
||||
* @param request 支付请求
|
||||
* @return 支付响应
|
||||
*/
|
||||
CheckoutResponseDTO checkout(CheckoutRequestDTO request);
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.mtkj.mtpay.service.impl;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.mtkj.mtpay.config.PingPongProperties;
|
||||
import com.mtkj.mtpay.dto.request.CheckoutRequestDTO;
|
||||
import com.mtkj.mtpay.dto.response.CheckoutResponseDTO;
|
||||
import com.mtkj.mtpay.service.PingPongPayService;
|
||||
import com.mtkj.mtpay.service.SignatureService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* PingPong支付服务实现类
|
||||
* 负责调用PingPong支付API
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PingPongPayServiceImpl implements PingPongPayService {
|
||||
|
||||
private final PingPongProperties pingPongProperties;
|
||||
private final SignatureService signatureService;
|
||||
private final RestClient restClient;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
@Override
|
||||
public CheckoutResponseDTO checkout(CheckoutRequestDTO request) {
|
||||
log.info("创建支付订单,商户订单号: {}", request.getMerchantTransactionId());
|
||||
|
||||
// 构建请求参数Map
|
||||
Map<String, Object> requestMap = buildRequestMap(request);
|
||||
|
||||
// 生成签名
|
||||
String sign = signatureService.generateSign(requestMap);
|
||||
requestMap.put("sign", sign);
|
||||
|
||||
// 调用PingPong API
|
||||
String url = pingPongProperties.getGateway() + "/v2/checkout";
|
||||
log.info("调用PingPong API: {}", url);
|
||||
|
||||
try {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
|
||||
String requestBody = objectMapper.writeValueAsString(requestMap);
|
||||
log.debug("请求体: {}", requestBody);
|
||||
|
||||
ResponseEntity<CheckoutResponseDTO> response = restClient.post()
|
||||
.uri(url)
|
||||
.headers(httpHeaders -> httpHeaders.addAll(headers))
|
||||
.body(requestBody)
|
||||
.retrieve()
|
||||
.toEntity(CheckoutResponseDTO.class);
|
||||
|
||||
CheckoutResponseDTO responseDTO = response.getBody();
|
||||
if (responseDTO == null) {
|
||||
throw new RuntimeException("PingPong API返回响应为空");
|
||||
}
|
||||
|
||||
log.info("PingPong API响应,code: {}, description: {}", responseDTO.getCode(), responseDTO.getDescription());
|
||||
|
||||
// 验证响应签名
|
||||
Map<String, Object> responseMap = objectMapper.convertValue(responseDTO, Map.class);
|
||||
if (!signatureService.verifySign(responseMap)) {
|
||||
log.warn("PingPong响应签名验证失败");
|
||||
// 根据业务需求决定是否抛出异常
|
||||
}
|
||||
|
||||
return responseDTO;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("调用PingPong API失败", e);
|
||||
throw new RuntimeException("调用PingPong API失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建请求参数Map
|
||||
*/
|
||||
private Map<String, Object> buildRequestMap(CheckoutRequestDTO request) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
|
||||
// 设置基础参数
|
||||
map.put("accId", request.getAccId() != null ? request.getAccId() : pingPongProperties.getAccId());
|
||||
map.put("amount", request.getAmount());
|
||||
map.put("currency", request.getCurrency());
|
||||
map.put("merchantTransactionId", request.getMerchantTransactionId());
|
||||
map.put("paymentType", request.getPaymentType());
|
||||
map.put("shopperResultUrl", request.getShopperResultUrl());
|
||||
map.put("shopperCancelUrl", request.getShopperCancelUrl());
|
||||
map.put("signType", request.getSignType() != null ? request.getSignType() : pingPongProperties.getSignType());
|
||||
|
||||
// 可选参数
|
||||
if (request.getPaymentBrand() != null && !request.getPaymentBrand().isEmpty()) {
|
||||
map.put("paymentBrand", request.getPaymentBrand());
|
||||
}
|
||||
if (request.getMerchantUserId() != null && !request.getMerchantUserId().isEmpty()) {
|
||||
map.put("merchantUserId", request.getMerchantUserId());
|
||||
}
|
||||
if (request.getLanguage() != null && !request.getLanguage().isEmpty()) {
|
||||
map.put("language", request.getLanguage());
|
||||
}
|
||||
if (request.getThreeDSecure() != null && !request.getThreeDSecure().isEmpty()) {
|
||||
map.put("threeDSecure", request.getThreeDSecure());
|
||||
}
|
||||
if (request.getPrimaryMerchantTransactionId() != null && !request.getPrimaryMerchantTransactionId().isEmpty()) {
|
||||
map.put("primaryMerchantTransactionId", request.getPrimaryMerchantTransactionId());
|
||||
}
|
||||
if (request.getPeriodsNum() != null) {
|
||||
map.put("periodsNum", request.getPeriodsNum());
|
||||
}
|
||||
if (request.getNotificationUrl() != null && !request.getNotificationUrl().isEmpty()) {
|
||||
map.put("notificationUrl", request.getNotificationUrl());
|
||||
}
|
||||
if (request.getRemark() != null && !request.getRemark().isEmpty()) {
|
||||
map.put("remark", request.getRemark());
|
||||
}
|
||||
|
||||
// 风控信息
|
||||
if (request.getRiskInfo() != null) {
|
||||
map.put("riskInfo", objectMapper.convertValue(request.getRiskInfo(), Map.class));
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
67
src/main/resources/application-dev.yml
Normal file
67
src/main/resources/application-dev.yml
Normal file
@@ -0,0 +1,67 @@
|
||||
spring:
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
druid:
|
||||
# 主库数据源(开发环境)
|
||||
master:
|
||||
url: jdbc:mysql://rm-j6c3u06k2afwn8hxw6o.mysql.rds.aliyuncs.com:3306/mtpay?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
|
||||
username: mtkj2025
|
||||
password: aXs-Q876#pxBesA
|
||||
# 初始连接数
|
||||
initial-size: 5
|
||||
# 最小连接池数量
|
||||
min-idle: 10
|
||||
# 最大连接池数量
|
||||
max-active: 200
|
||||
# 配置获取连接等待超时的时间
|
||||
max-wait: 60000
|
||||
# 配置连接超时时间
|
||||
connect-timeout: 30000
|
||||
# 配置网络超时时间
|
||||
socket-timeout: 60000
|
||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
time-between-eviction-runs-millis: 60000
|
||||
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||
min-evictable-idle-time-millis: 300000
|
||||
# 配置一个连接在池中最大生存的时间,单位是毫秒
|
||||
max-evictable-idle-time-millis: 900000
|
||||
# 配置检测连接是否有效
|
||||
validation-query: SELECT 1 FROM DUAL
|
||||
test-while-idle: true
|
||||
test-on-borrow: false
|
||||
test-on-return: false
|
||||
# 从库数据源
|
||||
slave:
|
||||
# 从数据源开关/默认关闭
|
||||
enabled: false
|
||||
url:
|
||||
username:
|
||||
password:
|
||||
# Druid监控配置
|
||||
web-stat-filter:
|
||||
enabled: true
|
||||
stat-view-servlet:
|
||||
enabled: true
|
||||
# 设置白名单,不填则允许所有访问
|
||||
allow:
|
||||
url-pattern: /druid/*
|
||||
# 控制台管理用户名和密码
|
||||
login-username: ruoyi
|
||||
login-password: 123456
|
||||
filter:
|
||||
stat:
|
||||
enabled: true
|
||||
# 慢SQL记录
|
||||
log-slow-sql: false
|
||||
slow-sql-millis: 1000
|
||||
merge-sql: true
|
||||
wall:
|
||||
config:
|
||||
multi-statement-allow: true
|
||||
|
||||
# PingPong支付配置(开发环境使用沙箱)
|
||||
pingpong:
|
||||
gateway: https://sandbox-acquirer-payment.pingpongx.com
|
||||
mode: sandbox
|
||||
|
||||
99
src/main/resources/application.yml
Normal file
99
src/main/resources/application.yml
Normal file
@@ -0,0 +1,99 @@
|
||||
spring:
|
||||
application:
|
||||
name: MTKJPAY
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
druid:
|
||||
# 从库数据源
|
||||
slave:
|
||||
# 从数据源开关/默认关闭
|
||||
enabled: false
|
||||
url:
|
||||
username:
|
||||
password:
|
||||
# Druid监控配置
|
||||
web-stat-filter:
|
||||
enabled: true
|
||||
stat-view-servlet:
|
||||
enabled: true
|
||||
# 设置白名单,不填则允许所有访问
|
||||
allow:
|
||||
url-pattern: /druid/*
|
||||
# 控制台管理用户名和密码
|
||||
login-username: ruoyi
|
||||
login-password: 123456
|
||||
filter:
|
||||
stat:
|
||||
enabled: true
|
||||
# 慢SQL记录
|
||||
log-slow-sql: false
|
||||
slow-sql-millis: 1000
|
||||
merge-sql: true
|
||||
wall:
|
||||
config:
|
||||
multi-statement-allow: true
|
||||
# MyBatis-Plus配置
|
||||
mybatis-plus:
|
||||
# 配置扫描mapper.xml文件路径
|
||||
mapper-locations: classpath*:/mapper/**/*.xml
|
||||
# 配置实体类包路径
|
||||
type-aliases-package: com.mtkj.mtpay.entity
|
||||
# 配置MyBatis-Plus全局配置
|
||||
configuration:
|
||||
# 开启驼峰命名转换
|
||||
map-underscore-to-camel-case: true
|
||||
# 开启二级缓存
|
||||
cache-enabled: false
|
||||
# 日志实现
|
||||
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
|
||||
# 全局配置
|
||||
global-config:
|
||||
db-config:
|
||||
# 主键类型:AUTO-数据库自增
|
||||
id-type: auto
|
||||
# 逻辑删除字段
|
||||
logic-delete-field: deleted
|
||||
# 逻辑删除值
|
||||
logic-delete-value: 1
|
||||
# 逻辑未删除值
|
||||
logic-not-delete-value: 0
|
||||
|
||||
# PingPong支付配置
|
||||
pingpong:
|
||||
client-id: your-client-id
|
||||
acc-id: your-acc-id
|
||||
secret: your-secret-key
|
||||
sign-type: MD5
|
||||
gateway: https://sandbox-acquirer-payment.pingpongx.com
|
||||
mode: sandbox
|
||||
enabled: true
|
||||
|
||||
# 服务器配置
|
||||
server:
|
||||
port: 8082
|
||||
servlet:
|
||||
context-path: /
|
||||
# 文件上传配置
|
||||
multipart:
|
||||
# 单个文件最大大小(10MB)
|
||||
max-file-size: 10MB
|
||||
# 请求最大大小(50MB,支持多文件上传)
|
||||
max-request-size: 50MB
|
||||
# 文件写入磁盘的阈值(超过此大小会写入临时文件)
|
||||
file-size-threshold: 2MB
|
||||
|
||||
# 应用配置
|
||||
app:
|
||||
# 前端访问地址(用于生成商品详情页URL等)
|
||||
frontend:
|
||||
url: http://localhost:3000
|
||||
|
||||
# 阿里云OSS相关配置
|
||||
aliyun:
|
||||
oss:
|
||||
accessId: LTAI5tHbwvzWfANvNxju2yN1
|
||||
accessKey: sAQR2swByBgmMOofH97hSJT638aVcJ
|
||||
endpoint: https://oss-cn-hangzhou.aliyuncs.com
|
||||
bucketName: mtkj2025
|
||||
|
||||
Reference in New Issue
Block a user