diff --git a/logs/mt-pay-error.2025-12-19.log b/logs/mt-pay-error.2025-12-19.log new file mode 100644 index 0000000..3a325bd --- /dev/null +++ b/logs/mt-pay-error.2025-12-19.log @@ -0,0 +1,144 @@ +2025-12-19 18:34:38.656 [restartedMain] 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.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) + 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 com.mtkj.mtpay.MtPayApplication.main(MtPayApplication.java:24) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) +2025-12-19 18:34:38.658 [restartedMain] ERROR com.mtkj.mtpay.MtPayApplication - +╔══════════════════════════════════════════════════════════╗ +║ ║ +║ ❌ MTKJ PAY 支付系统启动失败! ❌ ║ +║ ║ +╚══════════════════════════════════════════════════════════╝ + +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.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) + 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 com.mtkj.mtpay.MtPayApplication.main(MtPayApplication.java:24) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) +2025-12-19 18:34:38.661 [main] ERROR com.mtkj.mtpay.MtPayApplication - +╔══════════════════════════════════════════════════════════╗ +║ ║ +║ ❌ MTKJ PAY 支付系统启动失败! ❌ ║ +║ ║ +╚══════════════════════════════════════════════════════════╝ + +org.springframework.boot.devtools.restart.SilentExitExceptionHandler$SilentExitException: null + at org.springframework.boot.devtools.restart.SilentExitExceptionHandler.exitCurrentThread(SilentExitExceptionHandler.java:92) + at org.springframework.boot.devtools.restart.Restarter.immediateRestart(Restarter.java:179) + at org.springframework.boot.devtools.restart.Restarter.initialize(Restarter.java:163) + at org.springframework.boot.devtools.restart.Restarter.initialize(Restarter.java:532) + at org.springframework.boot.devtools.restart.RestartApplicationListener.onApplicationStartingEvent(RestartApplicationListener.java:98) + at org.springframework.boot.devtools.restart.RestartApplicationListener.onApplicationEvent(RestartApplicationListener.java:51) + at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:178) + at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:171) + at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:149) + at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:137) + at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136) + at org.springframework.boot.context.event.EventPublishingRunListener.starting(EventPublishingRunListener.java:75) + at org.springframework.boot.SpringApplicationRunListeners.lambda$starting$0(SpringApplicationRunListeners.java:54) + at java.base/java.lang.Iterable.forEach(Iterable.java:75) + at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118) + at org.springframework.boot.SpringApplicationRunListeners.starting(SpringApplicationRunListeners.java:54) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) + at com.mtkj.mtpay.MtPayApplication.main(MtPayApplication.java:24) +2025-12-19 18:34:49.156 [restartedMain] 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.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) + 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 com.mtkj.mtpay.MtPayApplication.main(MtPayApplication.java:24) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) +2025-12-19 18:34:49.158 [restartedMain] ERROR com.mtkj.mtpay.MtPayApplication - +╔══════════════════════════════════════════════════════════╗ +║ ║ +║ ❌ MTKJ PAY 支付系统启动失败! ❌ ║ +║ ║ +╚══════════════════════════════════════════════════════════╝ + +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.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) + 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 com.mtkj.mtpay.MtPayApplication.main(MtPayApplication.java:24) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) +2025-12-19 18:34:49.161 [main] ERROR com.mtkj.mtpay.MtPayApplication - +╔══════════════════════════════════════════════════════════╗ +║ ║ +║ ❌ MTKJ PAY 支付系统启动失败! ❌ ║ +║ ║ +╚══════════════════════════════════════════════════════════╝ + +org.springframework.boot.devtools.restart.SilentExitExceptionHandler$SilentExitException: null + at org.springframework.boot.devtools.restart.SilentExitExceptionHandler.exitCurrentThread(SilentExitExceptionHandler.java:92) + at org.springframework.boot.devtools.restart.Restarter.immediateRestart(Restarter.java:179) + at org.springframework.boot.devtools.restart.Restarter.initialize(Restarter.java:163) + at org.springframework.boot.devtools.restart.Restarter.initialize(Restarter.java:532) + at org.springframework.boot.devtools.restart.RestartApplicationListener.onApplicationStartingEvent(RestartApplicationListener.java:98) + at org.springframework.boot.devtools.restart.RestartApplicationListener.onApplicationEvent(RestartApplicationListener.java:51) + at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:178) + at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:171) + at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:149) + at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:137) + at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136) + at org.springframework.boot.context.event.EventPublishingRunListener.starting(EventPublishingRunListener.java:75) + at org.springframework.boot.SpringApplicationRunListeners.lambda$starting$0(SpringApplicationRunListeners.java:54) + at java.base/java.lang.Iterable.forEach(Iterable.java:75) + at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118) + at org.springframework.boot.SpringApplicationRunListeners.starting(SpringApplicationRunListeners.java:54) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) + at com.mtkj.mtpay.MtPayApplication.main(MtPayApplication.java:24) diff --git a/logs/mt-pay-error.2025-12-22.log b/logs/mt-pay-error.2025-12-22.log new file mode 100644 index 0000000..dc2ec2f --- /dev/null +++ b/logs/mt-pay-error.2025-12-22.log @@ -0,0 +1,72 @@ +2025-12-22 09:18:35.818 [restartedMain] 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.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) + 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 com.mtkj.mtpay.MtPayApplication.main(MtPayApplication.java:24) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) +2025-12-22 09:18:35.820 [restartedMain] ERROR com.mtkj.mtpay.MtPayApplication - +╔══════════════════════════════════════════════════════════╗ +║ ║ +║ ❌ MTKJ PAY 支付系统启动失败! ❌ ║ +║ ║ +╚══════════════════════════════════════════════════════════╝ + +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.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) + 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 com.mtkj.mtpay.MtPayApplication.main(MtPayApplication.java:24) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) +2025-12-22 09:18:35.825 [main] ERROR com.mtkj.mtpay.MtPayApplication - +╔══════════════════════════════════════════════════════════╗ +║ ║ +║ ❌ MTKJ PAY 支付系统启动失败! ❌ ║ +║ ║ +╚══════════════════════════════════════════════════════════╝ + +org.springframework.boot.devtools.restart.SilentExitExceptionHandler$SilentExitException: null + at org.springframework.boot.devtools.restart.SilentExitExceptionHandler.exitCurrentThread(SilentExitExceptionHandler.java:92) + at org.springframework.boot.devtools.restart.Restarter.immediateRestart(Restarter.java:179) + at org.springframework.boot.devtools.restart.Restarter.initialize(Restarter.java:163) + at org.springframework.boot.devtools.restart.Restarter.initialize(Restarter.java:532) + at org.springframework.boot.devtools.restart.RestartApplicationListener.onApplicationStartingEvent(RestartApplicationListener.java:98) + at org.springframework.boot.devtools.restart.RestartApplicationListener.onApplicationEvent(RestartApplicationListener.java:51) + at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:178) + at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:171) + at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:149) + at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:137) + at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136) + at org.springframework.boot.context.event.EventPublishingRunListener.starting(EventPublishingRunListener.java:75) + at org.springframework.boot.SpringApplicationRunListeners.lambda$starting$0(SpringApplicationRunListeners.java:54) + at java.base/java.lang.Iterable.forEach(Iterable.java:75) + at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118) + at org.springframework.boot.SpringApplicationRunListeners.starting(SpringApplicationRunListeners.java:54) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) + at com.mtkj.mtpay.MtPayApplication.main(MtPayApplication.java:24) diff --git a/logs/mt-pay.2025-12-22.log b/logs/mt-pay.2025-12-22.log new file mode 100644 index 0000000..1a0a16b --- /dev/null +++ b/logs/mt-pay.2025-12-22.log @@ -0,0 +1,76 @@ +2025-12-22 09:18:34.910 [background-preinit] INFO org.hibernate.validator.internal.util.Version - HV000001: Hibernate Validator 8.0.1.Final +2025-12-22 09:18:34.954 [restartedMain] INFO com.mtkj.mtpay.MtPayApplication - Starting MtPayApplication using Java 17.0.12 with PID 19392 (E:\MTKJPAY\mt-pay\target\classes started by 18969 in E:\MTKJPAY) +2025-12-22 09:18:34.955 [restartedMain] INFO com.mtkj.mtpay.MtPayApplication - No active profile set, falling back to 1 default profile: "default" +2025-12-22 09:18:35.783 [restartedMain] WARN o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: java.lang.IllegalArgumentException: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String +2025-12-22 09:18:35.818 [restartedMain] 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.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) + 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 com.mtkj.mtpay.MtPayApplication.main(MtPayApplication.java:24) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) +2025-12-22 09:18:35.820 [restartedMain] ERROR com.mtkj.mtpay.MtPayApplication - +╔══════════════════════════════════════════════════════════╗ +║ ║ +║ ❌ MTKJ PAY 支付系统启动失败! ❌ ║ +║ ║ +╚══════════════════════════════════════════════════════════╝ + +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.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) + 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 com.mtkj.mtpay.MtPayApplication.main(MtPayApplication.java:24) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) +2025-12-22 09:18:35.825 [main] ERROR com.mtkj.mtpay.MtPayApplication - +╔══════════════════════════════════════════════════════════╗ +║ ║ +║ ❌ MTKJ PAY 支付系统启动失败! ❌ ║ +║ ║ +╚══════════════════════════════════════════════════════════╝ + +org.springframework.boot.devtools.restart.SilentExitExceptionHandler$SilentExitException: null + at org.springframework.boot.devtools.restart.SilentExitExceptionHandler.exitCurrentThread(SilentExitExceptionHandler.java:92) + at org.springframework.boot.devtools.restart.Restarter.immediateRestart(Restarter.java:179) + at org.springframework.boot.devtools.restart.Restarter.initialize(Restarter.java:163) + at org.springframework.boot.devtools.restart.Restarter.initialize(Restarter.java:532) + at org.springframework.boot.devtools.restart.RestartApplicationListener.onApplicationStartingEvent(RestartApplicationListener.java:98) + at org.springframework.boot.devtools.restart.RestartApplicationListener.onApplicationEvent(RestartApplicationListener.java:51) + at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:178) + at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:171) + at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:149) + at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:137) + at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136) + at org.springframework.boot.context.event.EventPublishingRunListener.starting(EventPublishingRunListener.java:75) + at org.springframework.boot.SpringApplicationRunListeners.lambda$starting$0(SpringApplicationRunListeners.java:54) + at java.base/java.lang.Iterable.forEach(Iterable.java:75) + at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118) + at org.springframework.boot.SpringApplicationRunListeners.starting(SpringApplicationRunListeners.java:54) + at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) + at com.mtkj.mtpay.MtPayApplication.main(MtPayApplication.java:24) diff --git a/mt-pay/src/main/java/com/mtkj/mtpay/common/enums/ProductStatus.java b/mt-pay/src/main/java/com/mtkj/mtpay/common/enums/ProductStatus.java new file mode 100644 index 0000000..3f50605 --- /dev/null +++ b/mt-pay/src/main/java/com/mtkj/mtpay/common/enums/ProductStatus.java @@ -0,0 +1,48 @@ +package com.mtkj.mtpay.common.enums; + +/** + * 商品状态枚举 + */ +public enum ProductStatus { + + /** + * 上架 + */ + ACTIVE("ACTIVE", "上架"), + + /** + * 下架 + */ + INACTIVE("INACTIVE", "下架"), + + /** + * 已删除 + */ + DELETED("DELETED", "已删除"); + + private final String code; + private final String description; + + ProductStatus(String code, String description) { + this.code = code; + this.description = description; + } + + public String getCode() { + return code; + } + + public String getDescription() { + return description; + } + + public static ProductStatus fromCode(String code) { + for (ProductStatus status : values()) { + if (status.code.equals(code)) { + return status; + } + } + return null; + } +} + diff --git a/mt-pay/src/main/java/com/mtkj/mtpay/controller/ProductController.java b/mt-pay/src/main/java/com/mtkj/mtpay/controller/ProductController.java new file mode 100644 index 0000000..7660462 --- /dev/null +++ b/mt-pay/src/main/java/com/mtkj/mtpay/controller/ProductController.java @@ -0,0 +1,206 @@ +package com.mtkj.mtpay.controller; + +import com.mtkj.mtpay.common.Result; +import com.mtkj.mtpay.dto.request.CreateProductRequestDTO; +import com.mtkj.mtpay.dto.response.ProductResponseDTO; +import com.mtkj.mtpay.service.ProductService; +import jakarta.validation.Valid; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 商品管理控制器 + */ +@Slf4j +@RestController +@RequestMapping("/api/product") +public class ProductController { + + @Autowired + private ProductService productService; + + @Autowired + private com.mtkj.mtpay.service.OssService ossService; + + /** + * 创建商品 + */ + @PostMapping + public Result createProduct(@Valid @RequestBody CreateProductRequestDTO request) { + log.info("创建商品请求:{}", request); + ProductResponseDTO product = productService.createProduct(request); + return Result.success("商品创建成功", product); + } + + /** + * 获取商品详情 + */ + @GetMapping("/{id}") + public Result getProduct(@PathVariable Long id) { + log.info("获取商品详情,商品ID:{}", id); + ProductResponseDTO product = productService.getProductById(id); + return Result.success(product); + } + + /** + * 获取商品详情页URL + */ + @GetMapping("/{id}/url") + public Result> getProductUrl(@PathVariable Long id) { + log.info("获取商品URL,商品ID:{}", id); + String url = productService.getProductUrl(id); + Map result = new HashMap<>(); + result.put("url", url); + return Result.success(result); + } + + /** + * 上传商品图片(单文件上传,参考mt-admin的CommonController实现) + */ + @PostMapping("/upload/image") + public Result> uploadImage(@RequestParam("file") MultipartFile file) { + try { + if (file == null || file.isEmpty()) { + return Result.fail("文件不能为空"); + } + + String originalFilename = file.getOriginalFilename(); + if (originalFilename == null) { + return Result.fail("文件名不能为空"); + } + + // 验证文件类型 + String extension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase(); + if (!isImageFile(extension)) { + return Result.fail("只支持图片文件(jpg、jpeg、png、gif、webp、bmp)"); + } + + // 验证文件大小(最大10MB) + if (file.getSize() > 10 * 1024 * 1024) { + return Result.fail("文件大小不能超过10MB"); + } + + // 上传到OSS(参考mt-admin实现) + byte[] content = file.getBytes(); + String imageUrl = ossService.upload(content, originalFilename); + + Map result = new HashMap<>(); + result.put("url", imageUrl); + result.put("fileName", imageUrl); + result.put("originalFilename", originalFilename); + + log.info("图片上传成功,文件名: {}, URL: {}", originalFilename, imageUrl); + return Result.success("图片上传成功", result); + + } catch (Exception e) { + log.error("图片上传失败", e); + return Result.fail("图片上传失败:" + e.getMessage()); + } + } + + /** + * 批量上传商品图片(多文件上传) + */ + @PostMapping("/upload/images") + public Result> uploadImages(@RequestParam("file") MultipartFile[] files) { + if (files == null || files.length == 0) { + return Result.fail("文件不能为空"); + } + + try { + List> uploadedFiles = new ArrayList<>(); + List errors = new ArrayList<>(); + + for (int i = 0; i < files.length; i++) { + MultipartFile uploadFile = files[i]; + + if (uploadFile == null || uploadFile.isEmpty()) { + errors.add("第" + (i + 1) + "个文件为空"); + continue; + } + + // 验证文件类型 + String originalFilename = uploadFile.getOriginalFilename(); + if (originalFilename == null) { + errors.add("第" + (i + 1) + "个文件名不能为空"); + continue; + } + + String extension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase(); + if (!isImageFile(extension)) { + errors.add("第" + (i + 1) + "个文件不是图片格式(" + originalFilename + ")"); + continue; + } + + // 验证文件大小(最大10MB) + if (uploadFile.getSize() > 10 * 1024 * 1024) { + errors.add("第" + (i + 1) + "个文件大小超过10MB(" + originalFilename + ")"); + continue; + } + + try { + // 上传到OSS + byte[] content = uploadFile.getBytes(); + String imageUrl = ossService.upload(content, originalFilename); + + Map fileInfo = new HashMap<>(); + fileInfo.put("url", imageUrl); + fileInfo.put("originalFilename", originalFilename); + fileInfo.put("size", String.valueOf(uploadFile.getSize())); + uploadedFiles.add(fileInfo); + + log.info("图片上传成功,文件名: {}, URL: {}", originalFilename, imageUrl); + } catch (Exception e) { + log.error("上传第{}个文件失败: {}", i + 1, originalFilename, e); + errors.add("第" + (i + 1) + "个文件上传失败: " + e.getMessage()); + } + } + + Map result = new HashMap<>(); + result.put("files", uploadedFiles); + result.put("successCount", uploadedFiles.size()); + result.put("totalCount", files.length); + + if (!errors.isEmpty()) { + result.put("errors", errors); + } + + if (uploadedFiles.isEmpty()) { + return Result.fail("所有文件上传失败: " + String.join("; ", errors)); + } + + String message = String.format("成功上传%d/%d个文件", uploadedFiles.size(), files.length); + if (!errors.isEmpty()) { + message += ",部分文件上传失败"; + } + + log.info("批量图片上传完成,成功: {}/{}, 失败: {}", uploadedFiles.size(), files.length, errors.size()); + return Result.success(message, result); + + } catch (Exception e) { + log.error("批量图片上传失败", e); + return Result.fail("图片上传失败:" + e.getMessage()); + } + } + + /** + * 判断是否为图片文件 + */ + private boolean isImageFile(String extension) { + String[] imageExtensions = {"jpg", "jpeg", "png", "gif", "webp", "bmp"}; + for (String ext : imageExtensions) { + if (ext.equalsIgnoreCase(extension)) { + return true; + } + } + return false; + } +} + diff --git a/mt-pay/src/main/java/com/mtkj/mtpay/dto/response/ProductResponseDTO.java b/mt-pay/src/main/java/com/mtkj/mtpay/dto/response/ProductResponseDTO.java new file mode 100644 index 0000000..b4ff0ba --- /dev/null +++ b/mt-pay/src/main/java/com/mtkj/mtpay/dto/response/ProductResponseDTO.java @@ -0,0 +1,143 @@ +package com.mtkj.mtpay.dto.response; + +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 商品响应DTO + */ +@Data +public class ProductResponseDTO implements Serializable { + + /** + * 商品ID + */ + private Long id; + + /** + * 商品名称 + */ + private String name; + + /** + * 商品价格(基础价格) + */ + private BigDecimal price; + + /** + * 主图URL(单个,兼容旧版本,取mainImages的第一个) + */ + private String mainImage; + + /** + * 主图URL列表(支持多张主图) + */ + private List mainImages; + + /** + * 商品状态 + */ + private String status; + + /** + * 店铺ID + */ + private Long shopId; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * SKU列表 + */ + private List skus; + + /** + * SKU响应DTO + */ + @Data + public static class ProductSkuResponseDTO implements Serializable { + + /** + * SKU ID + */ + private Long id; + + /** + * 商品ID + */ + private Long productId; + + /** + * SKU编码 + */ + private String sku; + + /** + * 价格 + */ + private BigDecimal price; + + /** + * 货币 + */ + private String currency; + + /** + * 库存数量 + */ + private Integer stock; + + /** + * 销售属性(JSON格式) + */ + private String salesAttrs; + + /** + * SKU图片URL + */ + private String skuImage; + + /** + * 重量 + */ + private BigDecimal weight; + + /** + * 大小/尺寸(JSON格式) + */ + private String size; + + /** + * 规格 + */ + private String specification; + + /** + * SKU状态 + */ + private String status; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + } +} + diff --git a/mt-pay/src/main/java/com/mtkj/mtpay/service/ProductService.java b/mt-pay/src/main/java/com/mtkj/mtpay/service/ProductService.java new file mode 100644 index 0000000..2c842a5 --- /dev/null +++ b/mt-pay/src/main/java/com/mtkj/mtpay/service/ProductService.java @@ -0,0 +1,32 @@ +package com.mtkj.mtpay.service; + +import com.mtkj.mtpay.dto.request.CreateProductRequestDTO; +import com.mtkj.mtpay.dto.response.ProductResponseDTO; + +/** + * 商品服务接口 + */ +public interface ProductService { + + /** + * 创建商品 + * @param request 创建商品请求 + * @return 商品响应 + */ + ProductResponseDTO createProduct(CreateProductRequestDTO request); + + /** + * 根据ID获取商品详情 + * @param id 商品ID + * @return 商品响应 + */ + ProductResponseDTO getProductById(Long id); + + /** + * 获取商品详情页URL + * @param id 商品ID + * @return 商品详情页URL + */ + String getProductUrl(Long id); +} + diff --git a/mt-pay/src/main/java/com/mtkj/mtpay/service/impl/ProductServiceImpl.java b/mt-pay/src/main/java/com/mtkj/mtpay/service/impl/ProductServiceImpl.java new file mode 100644 index 0000000..4dbf5b2 --- /dev/null +++ b/mt-pay/src/main/java/com/mtkj/mtpay/service/impl/ProductServiceImpl.java @@ -0,0 +1,215 @@ +package com.mtkj.mtpay.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.mtkj.mtpay.common.ResultCode; +import com.mtkj.mtpay.common.enums.ProductStatus; +import com.mtkj.mtpay.common.enums.SkuStatus; +import com.mtkj.mtpay.dto.request.CreateProductRequestDTO; +import com.mtkj.mtpay.dto.response.ProductResponseDTO; +import com.mtkj.mtpay.entity.MtProduct; +import com.mtkj.mtpay.entity.MtProductSku; +import com.mtkj.mtpay.exception.BusinessException; +import com.mtkj.mtpay.mapper.MtProductMapper; +import com.mtkj.mtpay.mapper.MtProductSkuMapper; +import com.mtkj.mtpay.service.ProductService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 商品服务实现类 + */ +@Slf4j +@Service +public class ProductServiceImpl implements ProductService { + + @Autowired + private MtProductMapper productMapper; + + @Autowired + private MtProductSkuMapper productSkuMapper; + + @Autowired + private ObjectMapper objectMapper; + + @Value("${server.port:8082}") + private String serverPort; + + @Value("${server.servlet.context-path:}") + private String contextPath; + + /** + * 前端访问地址(用于生成商品详情页URL) + */ + @Value("${app.frontend.url:http://localhost:3000}") + private String frontendUrl; + + @Override + @Transactional(rollbackFor = Exception.class) + public ProductResponseDTO createProduct(CreateProductRequestDTO request) { + log.info("开始创建商品,商品名称: {}, 店铺ID: {}, SKU数量: {}", + request.getName(), request.getShopId(), + request.getSkus() != null ? request.getSkus().size() : 0); + + // 创建商品 + MtProduct product = new MtProduct(); + product.setName(request.getName()); + product.setPrice(request.getPrice()); + + // 处理主图:优先使用mainImages(多图),如果没有则使用mainImage(单图,兼容旧版本) + String mainImageValue = null; + if (request.getMainImages() != null && !request.getMainImages().isEmpty()) { + // 多个主图,转换为JSON数组存储 + try { + mainImageValue = objectMapper.writeValueAsString(request.getMainImages()); + log.debug("商品主图(多图): {}", mainImageValue); + } catch (Exception e) { + log.error("转换主图列表为JSON失败", e); + throw new BusinessException(ResultCode.SYSTEM_ERROR, "主图数据格式错误"); + } + } else if (StringUtils.hasText(request.getMainImage())) { + // 单个主图,兼容旧版本 + mainImageValue = request.getMainImage(); + log.debug("商品主图(单图): {}", mainImageValue); + } + product.setMainImage(mainImageValue); + + product.setStatus(request.getStatus() != null ? request.getStatus() : ProductStatus.ACTIVE.getCode()); + product.setShopId(request.getShopId()); + + int result = productMapper.insert(product); + if (result <= 0) { + log.error("创建商品失败,商品名称: {}", request.getName()); + throw new BusinessException(ResultCode.SYSTEM_ERROR, "创建商品失败"); + } + log.debug("商品基础信息插入成功,商品ID: {}", product.getId()); + + // 创建SKU + if (request.getSkus() != null && !request.getSkus().isEmpty()) { + log.debug("开始创建SKU,数量: {}", request.getSkus().size()); + for (CreateProductRequestDTO.CreateProductSkuDTO skuDTO : request.getSkus()) { + MtProductSku sku = new MtProductSku(); + sku.setProductId(product.getId()); + sku.setSku(skuDTO.getSku()); + sku.setPrice(skuDTO.getPrice()); + sku.setCurrency(skuDTO.getCurrency()); + sku.setStock(skuDTO.getStock()); + sku.setSalesAttrs(skuDTO.getSalesAttrs()); + sku.setSkuImage(skuDTO.getSkuImage()); + sku.setWeight(skuDTO.getWeight()); + sku.setSize(skuDTO.getSize()); + sku.setSpecification(skuDTO.getSpecification()); + sku.setStatus(skuDTO.getStatus() != null ? skuDTO.getStatus() : SkuStatus.ACTIVE.getCode()); + + int skuResult = productSkuMapper.insert(sku); + if (skuResult <= 0) { + log.error("创建SKU失败,商品ID: {}, SKU编码: {}", product.getId(), skuDTO.getSku()); + throw new BusinessException(ResultCode.SYSTEM_ERROR, "创建SKU失败"); + } + log.debug("SKU创建成功,商品ID: {}, SKU编码: {}, SKU ID: {}", + product.getId(), skuDTO.getSku(), sku.getId()); + } + } + + log.info("商品创建成功,商品ID: {}, 商品名称: {}, SKU数量: {}", + product.getId(), product.getName(), + request.getSkus() != null ? request.getSkus().size() : 0); + + // 返回商品详情 + return getProductById(product.getId()); + } + + @Override + public ProductResponseDTO getProductById(Long id) { + log.debug("查询商品详情,商品ID: {}", id); + MtProduct product = productMapper.selectById(id); + if (product == null) { + log.warn("商品不存在,商品ID: {}", id); + throw new BusinessException(ResultCode.DATA_NOT_FOUND, "商品不存在"); + } + + // 查询SKU列表 + LambdaQueryWrapper skuWrapper = new LambdaQueryWrapper<>(); + skuWrapper.eq(MtProductSku::getProductId, id); + skuWrapper.eq(MtProductSku::getStatus, SkuStatus.ACTIVE.getCode()); + List skus = productSkuMapper.selectList(skuWrapper); + log.debug("查询到商品SKU数量: {}, 商品ID: {}", skus.size(), id); + + // 转换为响应DTO + ProductResponseDTO response = new ProductResponseDTO(); + BeanUtils.copyProperties(product, response); + + // 处理主图:解析JSON数组或使用单个URL + if (StringUtils.hasText(product.getMainImage())) { + try { + // 尝试解析为JSON数组 + if (product.getMainImage().trim().startsWith("[")) { + List mainImages = objectMapper.readValue( + product.getMainImage(), + new TypeReference>() {} + ); + response.setMainImages(mainImages); + // 兼容:第一个作为mainImage + if (!mainImages.isEmpty()) { + response.setMainImage(mainImages.get(0)); + } + log.debug("解析商品主图(多图),数量: {}", mainImages.size()); + } else { + // 单个URL + response.setMainImage(product.getMainImage()); + List singleImageList = new ArrayList<>(); + singleImageList.add(product.getMainImage()); + response.setMainImages(singleImageList); + log.debug("解析商品主图(单图)"); + } + } catch (Exception e) { + log.warn("解析商品主图失败,使用原始值,商品ID: {}", id, e); + response.setMainImage(product.getMainImage()); + List singleImageList = new ArrayList<>(); + singleImageList.add(product.getMainImage()); + response.setMainImages(singleImageList); + } + } + + List skuDTOs = skus.stream().map(sku -> { + ProductResponseDTO.ProductSkuResponseDTO skuDTO = new ProductResponseDTO.ProductSkuResponseDTO(); + BeanUtils.copyProperties(sku, skuDTO); + return skuDTO; + }).collect(Collectors.toList()); + + response.setSkus(skuDTOs); + + log.info("获取商品详情成功,商品ID: {}, 商品名称: {}, SKU数量: {}, 主图数量: {}", + id, product.getName(), skuDTOs.size(), + response.getMainImages() != null ? response.getMainImages().size() : 0); + return response; + } + + @Override + public String getProductUrl(Long id) { + log.debug("获取商品URL,商品ID: {}", id); + // 检查商品是否存在 + MtProduct product = productMapper.selectById(id); + if (product == null) { + log.warn("商品不存在,无法生成URL,商品ID: {}", id); + throw new BusinessException(ResultCode.DATA_NOT_FOUND, "商品不存在"); + } + + // 构建商品详情页URL(使用前端地址) + // 格式:http://前端地址/product/{id} + String productUrl = frontendUrl + "/product/" + id; + log.info("生成商品URL成功,商品ID: {}, URL: {}", id, productUrl); + return productUrl; + } +} +