kai.wu 8 miesięcy temu
commit
5e0a0664c7
83 zmienionych plików z 2398 dodań i 0 usunięć
  1. 3 0
      .idea/.gitignore
  2. 6 0
      .idea/MarsCodeWorkspaceAppSettings.xml
  3. 19 0
      .idea/compiler.xml
  4. 6 0
      .idea/encodings.xml
  5. 20 0
      .idea/jarRepositories.xml
  6. 14 0
      .idea/misc.xml
  7. 9 0
      .idea/product-calendar.iml
  8. 74 0
      pom.xml
  9. 17 0
      src/main/java/com/poyee/ProductCalendarApplication.java
  10. 17 0
      src/main/java/com/poyee/config/CorsConfig.java
  11. 31 0
      src/main/java/com/poyee/config/ExchangeRateConfig.java
  12. 97 0
      src/main/java/com/poyee/controller/BlowoutRecordController.java
  13. 154 0
      src/main/java/com/poyee/controller/ProductCalendarController.java
  14. 13 0
      src/main/java/com/poyee/controller/TestController.java
  15. 11 0
      src/main/java/com/poyee/dto/BlowoutRecordDto.java
  16. 90 0
      src/main/java/com/poyee/dto/BlowoutRecordGroupDto.java
  17. 14 0
      src/main/java/com/poyee/dto/CommonResult.java
  18. 29 0
      src/main/java/com/poyee/dto/ProductCalendarDetailDto.java
  19. 20 0
      src/main/java/com/poyee/dto/ProductCalendarDto.java
  20. 20 0
      src/main/java/com/poyee/dto/ProductCalendarPriceDto.java
  21. 13 0
      src/main/java/com/poyee/dto/ProductSimpleDto.java
  22. 24 0
      src/main/java/com/poyee/entity/BlowoutDetailRecord.java
  23. 23 0
      src/main/java/com/poyee/entity/BlowoutRecordNewDailyNew.java
  24. 35 0
      src/main/java/com/poyee/entity/ProductCalendar.java
  25. 28 0
      src/main/java/com/poyee/entity/ProductCalendarPrice.java
  26. 11 0
      src/main/java/com/poyee/mapper/BlowoutDetailRecordMapper.java
  27. 13 0
      src/main/java/com/poyee/mapper/BlowoutRecordMapper.java
  28. 11 0
      src/main/java/com/poyee/mapper/BlowoutRecordNewDailyNewMapper.java
  29. 29 0
      src/main/java/com/poyee/mapper/ProductCalendarMapper.java
  30. 8 0
      src/main/java/com/poyee/service/BlowoutDetailRecordService.java
  31. 8 0
      src/main/java/com/poyee/service/BlowoutRecordNewDailyNewService.java
  32. 18 0
      src/main/java/com/poyee/service/BlowoutRecordService.java
  33. 33 0
      src/main/java/com/poyee/service/ProductCalendarService.java
  34. 21 0
      src/main/java/com/poyee/service/impl/BlowoutDetailRecordServiceImpl.java
  35. 21 0
      src/main/java/com/poyee/service/impl/BlowoutRecordNewDailyNewServiceImpl.java
  36. 29 0
      src/main/java/com/poyee/service/impl/BlowoutRecordServiceImpl.java
  37. 118 0
      src/main/java/com/poyee/service/impl/ProductCalendarServiceImpl.java
  38. 160 0
      src/main/resources/application.yml
  39. 33 0
      src/main/resources/mapper/BlowoutDetailRecord.xml
  40. 153 0
      src/main/resources/mapper/BlowoutRecord.xml
  41. 32 0
      src/main/resources/mapper/BlowoutRecordNewDailyNewMapper.xml
  42. 255 0
      src/main/resources/mapper/ProductCalendarMapper.xml
  43. 160 0
      target/classes/application.yml
  44. BIN
      target/classes/com/poyee/ProductCalendarApplication.class
  45. BIN
      target/classes/com/poyee/config/CorsConfig.class
  46. BIN
      target/classes/com/poyee/config/ExchangeRateConfig.class
  47. BIN
      target/classes/com/poyee/controller/BlowoutRecordController.class
  48. BIN
      target/classes/com/poyee/controller/ProductCalendarController.class
  49. BIN
      target/classes/com/poyee/controller/TestController.class
  50. BIN
      target/classes/com/poyee/dto/BlowoutRecordDto.class
  51. BIN
      target/classes/com/poyee/dto/BlowoutRecordGroupDto.class
  52. BIN
      target/classes/com/poyee/dto/CommonResult.class
  53. BIN
      target/classes/com/poyee/dto/ProductCalendarDetailDto.class
  54. BIN
      target/classes/com/poyee/dto/ProductCalendarDto.class
  55. BIN
      target/classes/com/poyee/dto/ProductCalendarPriceDto.class
  56. BIN
      target/classes/com/poyee/dto/ProductSimpleDto.class
  57. BIN
      target/classes/com/poyee/entity/BlowoutDetailRecord.class
  58. BIN
      target/classes/com/poyee/entity/BlowoutRecordNewDailyNew.class
  59. BIN
      target/classes/com/poyee/entity/ProductCalendar.class
  60. BIN
      target/classes/com/poyee/entity/ProductCalendarPrice.class
  61. BIN
      target/classes/com/poyee/mapper/BlowoutDetailRecordMapper.class
  62. BIN
      target/classes/com/poyee/mapper/BlowoutRecordMapper.class
  63. BIN
      target/classes/com/poyee/mapper/BlowoutRecordNewDailyNewMapper.class
  64. BIN
      target/classes/com/poyee/mapper/ProductCalendarMapper.class
  65. BIN
      target/classes/com/poyee/service/BlowoutDetailRecordService.class
  66. BIN
      target/classes/com/poyee/service/BlowoutRecordNewDailyNewService.class
  67. BIN
      target/classes/com/poyee/service/BlowoutRecordService.class
  68. BIN
      target/classes/com/poyee/service/ProductCalendarService.class
  69. BIN
      target/classes/com/poyee/service/impl/BlowoutDetailRecordServiceImpl.class
  70. BIN
      target/classes/com/poyee/service/impl/BlowoutRecordNewDailyNewServiceImpl.class
  71. BIN
      target/classes/com/poyee/service/impl/BlowoutRecordServiceImpl.class
  72. BIN
      target/classes/com/poyee/service/impl/ProductCalendarServiceImpl.class
  73. 33 0
      target/classes/mapper/BlowoutDetailRecord.xml
  74. 153 0
      target/classes/mapper/BlowoutRecord.xml
  75. 32 0
      target/classes/mapper/BlowoutRecordNewDailyNewMapper.xml
  76. 255 0
      target/classes/mapper/ProductCalendarMapper.xml
  77. 3 0
      target/maven-archiver/pom.properties
  78. 11 0
      target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
  79. 11 0
      target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
  80. 0 0
      target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
  81. 0 0
      target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
  82. BIN
      target/product-calendar-0.0.1-SNAPSHOT.jar
  83. BIN
      target/product-calendar-0.0.1-SNAPSHOT.jar.original

+ 3 - 0
.idea/.gitignore

@@ -0,0 +1,3 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml

+ 6 - 0
.idea/MarsCodeWorkspaceAppSettings.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="com.codeverse.userSettings.MarscodeWorkspaceAppSettingsState">
+    <option name="ckgOperationStatus" value="SUCCESS" />
+  </component>
+</project>

+ 19 - 0
.idea/compiler.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <annotationProcessing>
+      <profile default="true" name="Default" enabled="true" />
+      <profile name="Maven default annotation processors profile" enabled="true">
+        <sourceOutputDir name="target/generated-sources/annotations" />
+        <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
+        <outputRelativeToContentRoot value="true" />
+        <module name="product-calendar" />
+      </profile>
+    </annotationProcessing>
+  </component>
+  <component name="JavacSettings">
+    <option name="ADDITIONAL_OPTIONS_OVERRIDE">
+      <module name="product-calendar" options="-parameters" />
+    </option>
+  </component>
+</project>

+ 6 - 0
.idea/encodings.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding">
+    <file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
+  </component>
+</project>

+ 20 - 0
.idea/jarRepositories.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RemoteRepositoriesConfiguration">
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Central Repository" />
+      <option name="url" value="https://repo.maven.apache.org/maven2" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Maven Central repository" />
+      <option name="url" value="https://repo1.maven.org/maven2" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="jboss.community" />
+      <option name="name" value="JBoss Community repository" />
+      <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
+    </remote-repository>
+  </component>
+</project>

+ 14 - 0
.idea/misc.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="MavenProjectsManager">
+    <option name="originalFiles">
+      <list>
+        <option value="$PROJECT_DIR$/pom.xml" />
+      </list>
+    </option>
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="corretto-1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>

+ 9 - 0
.idea/product-calendar.iml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 74 - 0
pom.xml

@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.example</groupId>
+    <artifactId>product-calendar</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>product-calendar</name>
+    <description>Product Calendar Project</description>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.1.17.RELEASE</version>
+        <relativePath/>
+    </parent>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>1.2.19</version>
+        </dependency>
+
+        <!-- MyBatis Spring Boot Starter -->
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+            <version>2.3.1</version>
+        </dependency>
+
+
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 17 - 0
src/main/java/com/poyee/ProductCalendarApplication.java

@@ -0,0 +1,17 @@
+package com.poyee;
+
+import com.poyee.config.ExchangeRateConfig;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+
+@SpringBootApplication
+@MapperScan("com.poyee.mapper")
+@EnableConfigurationProperties(ExchangeRateConfig.class)
+public class ProductCalendarApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(ProductCalendarApplication.class, args);
+    }
+}

+ 17 - 0
src/main/java/com/poyee/config/CorsConfig.java

@@ -0,0 +1,17 @@
+package com.poyee.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class CorsConfig implements WebMvcConfigurer {
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+        registry.addMapping("/**")
+                .allowedOrigins("http://localhost:8081")
+                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
+                .allowedHeaders("*")
+                .allowCredentials(true);
+    }
+}

+ 31 - 0
src/main/java/com/poyee/config/ExchangeRateConfig.java

@@ -0,0 +1,31 @@
+package com.poyee.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+
+@Component
+@Configuration
+@ConfigurationProperties(prefix = "exchange.rate")
+public class ExchangeRateConfig {
+    private Map<String, BigDecimal> rates = new HashMap<>();
+
+    public Map<String, BigDecimal> getRates() {
+        return rates;
+    }
+
+    public void setRates(Map<String, BigDecimal> rates) {
+        this.rates = rates;
+    }
+
+    public BigDecimal getExchangeRate(String currencyCode) {
+        //String s = currencyCode.toLowerCase() + "-to-rmb";
+        //BigDecimal rate = rates.get(s);
+        BigDecimal rate= BigDecimal.valueOf(7);
+        return rate;
+    }
+}

+ 97 - 0
src/main/java/com/poyee/controller/BlowoutRecordController.java

@@ -0,0 +1,97 @@
+package com.poyee.controller;
+
+import com.poyee.dto.BlowoutRecordDto;
+import com.poyee.dto.BlowoutRecordGroupDto;
+import com.poyee.dto.CommonResult;
+import com.poyee.entity.BlowoutRecordNewDailyNew;
+import com.poyee.entity.BlowoutDetailRecord;
+import com.poyee.service.BlowoutRecordNewDailyNewService;
+import com.poyee.service.BlowoutDetailRecordService;
+import com.poyee.service.BlowoutRecordService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/blowout")
+public class BlowoutRecordController {
+
+    @Autowired
+    private BlowoutRecordNewDailyNewService blowoutRecordNewDailyNewService;
+
+    @Autowired
+    private BlowoutDetailRecordService blowoutDetailRecordService;
+
+    @Autowired
+    private BlowoutRecordService blowoutRecordService;
+
+    @GetMapping("/records")
+    public List<BlowoutRecordNewDailyNew> getAllRecords() {
+        return blowoutRecordNewDailyNewService.getAllRecords();
+    }
+
+    @GetMapping("/details")
+    public List<BlowoutDetailRecord> getAllDetails() {
+        return blowoutDetailRecordService.getAllDetails();
+    }
+
+    @GetMapping("/records/page")
+    public CommonResult<BlowoutRecordDto> getBlowoutRecordsByPage(
+            @RequestParam(required = false) String releaseDatePattern,
+            @RequestParam(required = false) String productYear,
+            @RequestParam(required = false) String brand,
+            @RequestParam(required = false) String category,
+            @RequestParam(required = false) Integer preorder,
+            @RequestParam Integer offset,
+            @RequestParam Integer limit
+    ) {
+        Map<String, Object> params = new HashMap<>();
+        if (releaseDatePattern != null) {
+            params.put("releaseDatePattern", releaseDatePattern);
+        }
+        if (productYear != null) {
+            params.put("productYear", productYear);
+        }
+        if (brand != null) {
+            params.put("brand", brand);
+        }
+        if (category != null) {
+            params.put("category", category);
+        }
+        params.put("offset", offset);
+        params.put("limit", limit);
+        List<BlowoutRecordDto> records = blowoutRecordService.getBlowoutRecordsByPage(params);
+        // 封装结果到 CommonResult
+        return new CommonResult<>(200, "查询成功", records);
+    }
+
+    @GetMapping("/records/latest-group")
+    public CommonResult<BlowoutRecordGroupDto> getLatestBlowoutRecordsByGroup(
+            @RequestParam(required = false) String releaseDatePattern,
+            @RequestParam(required = false) String productYear,
+            @RequestParam(required = false) String brand,
+            @RequestParam(required = false) String category
+    ) {
+        Map<String, Object> params = new HashMap<>();
+        if (releaseDatePattern != null) {
+            params.put("releaseDatePattern", releaseDatePattern);
+        }
+        if (productYear != null) {
+            params.put("productYear", productYear);
+        }
+        if (brand != null) {
+            params.put("brand", brand);
+        }
+        if (category != null) {
+            params.put("category", category);
+        }
+        List<BlowoutRecordGroupDto> records = blowoutRecordService.getLatestBlowoutRecordsByGroup(params);
+        return new CommonResult<>(200, "查询成功", records);
+    }
+}

+ 154 - 0
src/main/java/com/poyee/controller/ProductCalendarController.java

@@ -0,0 +1,154 @@
+package com.poyee.controller;
+
+import com.poyee.dto.ProductCalendarDetailDto;
+import com.poyee.dto.ProductCalendarDto;
+import com.poyee.dto.ProductCalendarPriceDto;
+import com.poyee.dto.ProductSimpleDto;
+import com.poyee.entity.ProductCalendarPrice;
+import com.poyee.service.ProductCalendarService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/ProductCalendar")
+public class ProductCalendarController {
+
+    @Autowired
+    private ProductCalendarService productCalendarService;
+
+    /**
+     * 根据条件查询产品日历信息的接口
+     * @param releaseYear 发布年份
+     * @param releaseMonth 发布月份
+     * @param sport 运动类型
+     * @param manufacturer 制造商
+     * @return 符合条件的产品日历信息列表
+     */
+    @GetMapping("/list")
+    public List<ProductCalendarDto> getProductCalendarsByIds(
+            @RequestParam(required = false) Integer releaseYear,
+            @RequestParam(required = false) Integer releaseMonth,
+            @RequestParam(required = false) String sport,
+            @RequestParam(required = false) String manufacturer) {
+        // 创建参数 Map
+        Map<String, Object> params = new HashMap<>();
+        if (releaseYear != null) {
+            params.put("releaseYear", releaseYear);
+            if (releaseMonth != null) {
+                params.put("releaseMonth", releaseMonth);
+            }
+        }
+        if (sport != null && !sport.isEmpty()) {
+            params.put("sport", sport);
+        }
+        if (manufacturer != null && !manufacturer.isEmpty()) {
+            params.put("manufacturer", manufacturer);
+        }
+        // 调用 Service 层方法
+        return productCalendarService.getProductCalendarsList(params);
+    }
+
+    @GetMapping("/detail")
+    public ProductCalendarDetailDto getProductCalendarByIdAndDays(
+            @RequestParam(required = true) Long id,
+            @RequestParam(required = true) int days) {
+        return productCalendarService.getProductCalendarByIdAndDays(id, days);
+    }
+
+    @GetMapping("/detail/prices")
+    public ProductCalendarPriceDto getProductCalendarPricesByIdAndDays(
+            @RequestParam(required = true) Long id,
+            @RequestParam(required = true) int days) {
+        return productCalendarService.getProductCalendarPricesByIdAndDays(id, days);
+    }
+
+    /**
+     * 根据条件查询产品日历总数
+     * @param releaseYear 发布年份
+     * @param releaseMonth 发布月份
+     * @param sport 运动类型
+     * @param manufacturer 制造商
+     * @return 符合条件的产品日历总数
+     */
+    @GetMapping("/count")
+    public Integer getProductCalendarCount(
+            @RequestParam(required = false) Integer releaseYear,
+            @RequestParam(required = false) Integer releaseMonth,
+            @RequestParam(required = false) String sport,
+            @RequestParam(required = false) String manufacturer) {
+        // 创建参数 Map
+        Map<String, Object> params = new HashMap<>();
+        if (releaseYear != null) {
+            params.put("releaseYear", releaseYear);
+        }
+        if (releaseMonth != null) {
+            params.put("releaseMonth", releaseMonth);
+        }
+        if (sport != null && !sport.isEmpty()) {
+            params.put("sport", sport);
+        }
+        if (manufacturer != null && !manufacturer.isEmpty()) {
+            params.put("manufacturer", manufacturer);
+        }
+        // 调用 Service 层方法
+        return productCalendarService.getProductCalendarCountByIds(params);
+    }
+
+    /**
+     * 根据条件和分页信息查询产品日历信息
+     * @param releaseYear 发布年份
+     * @param releaseMonth 发布月份
+     * @param sport 运动类型
+     * @param manufacturer 制造商
+     * @param startRow 起始行
+     * @param endRow 结束行
+     * @return 符合条件的产品日历信息列表
+     */
+    @GetMapping("/page")
+    public List<ProductCalendarDto> getProductCalendarsByPageAndCondition(
+            @RequestParam(required = false) Integer releaseYear,
+            @RequestParam(required = false) Integer releaseMonth,
+            @RequestParam(required = false) String sport,
+            @RequestParam(required = false) String manufacturer,
+            @RequestParam(required = false) String productName,
+            @RequestParam(required = false, defaultValue = "1") int startRow,
+            @RequestParam(required = false, defaultValue = "5") int endRow) {
+        Map<String, Object> params = new HashMap<>();
+        if (releaseYear != null) {
+            params.put("releaseYear", releaseYear);
+        }
+        if (releaseMonth != null) {
+            params.put("releaseMonth", releaseMonth);
+        }
+        if (sport != null && !sport.isEmpty()) {
+            params.put("sport", sport);
+        }
+        if (manufacturer != null && !manufacturer.isEmpty()) {
+            params.put("manufacturer", manufacturer);
+        }
+        if(productName!=null && !productName.isEmpty()){
+            params.put("productName",productName);
+        }
+        params.put("startRow", startRow);
+        params.put("endRow", endRow);
+        return productCalendarService.getProductCalendarsByPageAndCondition(params);
+    }
+
+    /**
+     * 根据产品名称模糊查询产品日历信息的接口
+     * @param productName 产品名称
+     * @return 符合条件的产品日历信息列表
+     */
+    @GetMapping("/searchByProductName")
+    public List<ProductSimpleDto> getProductCalendarsByProductName(
+            @RequestParam(required = false) String productName) {
+        return productCalendarService.getProductCalendarsByProductName(productName);
+    }
+}

+ 13 - 0
src/main/java/com/poyee/controller/TestController.java

@@ -0,0 +1,13 @@
+package com.poyee.controller;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class TestController {
+
+    @GetMapping("/hello")
+    public String helloWorld() {
+        return "Hello World!";
+    }
+}

+ 11 - 0
src/main/java/com/poyee/dto/BlowoutRecordDto.java

@@ -0,0 +1,11 @@
+package com.poyee.dto;
+
+import com.poyee.entity.BlowoutDetailRecord;
+import com.poyee.entity.BlowoutRecordNewDailyNew;
+import lombok.Data;
+
+@Data
+public class BlowoutRecordDto {
+    private BlowoutDetailRecord blowoutDetailRecord;
+    private BlowoutRecordNewDailyNew blowoutRecordNewDailyNew;
+}

+ 90 - 0
src/main/java/com/poyee/dto/BlowoutRecordGroupDto.java

@@ -0,0 +1,90 @@
+package com.poyee.dto;
+
+import java.util.Date;
+
+public class BlowoutRecordGroupDto {
+    private String releaseDate;
+    private String productYear;
+    private String brand;
+    private String sport;
+    private String boxStyle;
+    private String title;
+    private Double price;
+    private Double suggestedPrice;
+    private String category;
+
+    // 构造函数、getter 和 setter 方法
+    public BlowoutRecordGroupDto() {}
+
+    public String getReleaseDate() {
+        return releaseDate;
+    }
+
+    public void setReleaseDate(String releaseDate) {
+        this.releaseDate = releaseDate;
+    }
+
+    public String getProductYear() {
+        return productYear;
+    }
+
+    public void setProductYear(String productYear) {
+        this.productYear = productYear;
+    }
+
+    public String getBrand() {
+        return brand;
+    }
+
+    public void setBrand(String brand) {
+        this.brand = brand;
+    }
+
+    public String getSport() {
+        return sport;
+    }
+
+    public void setSport(String sport) {
+        this.sport = sport;
+    }
+
+    public String getBoxStyle() {
+        return boxStyle;
+    }
+
+    public void setBoxStyle(String boxStyle) {
+        this.boxStyle = boxStyle;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public Double getPrice() {
+        return price;
+    }
+
+    public void setPrice(Double price) {
+        this.price = price;
+    }
+
+    public Double getSuggestedPrice() {
+        return suggestedPrice;
+    }
+
+    public void setSuggestedPrice(Double suggestedPrice) {
+        this.suggestedPrice = suggestedPrice;
+    }
+
+    public String getCategory() {
+        return category;
+    }
+
+    public void setCategory(String category) {
+        this.category = category;
+    }
+}

+ 14 - 0
src/main/java/com/poyee/dto/CommonResult.java

@@ -0,0 +1,14 @@
+package com.poyee.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+public class CommonResult<T> {
+    private int code;
+    private String message;
+    private List<T> data;
+}

+ 29 - 0
src/main/java/com/poyee/dto/ProductCalendarDetailDto.java

@@ -0,0 +1,29 @@
+package com.poyee.dto;
+
+import com.poyee.entity.ProductCalendarPrice;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ProductCalendarDetailDto {
+    private Long Id;
+    private String imagesUrl;
+    private String productName;
+    private String releaseYear;
+    private String baseConfig;
+    private String boxBreak;
+    private String productHighlights;
+    private BigDecimal lastBasePrice;
+    private BigDecimal lastSuggestedPrice;
+    private String lastCurrencyUnit;
+    private BigDecimal lastRmbBasePrice;
+    private BigDecimal lastRmbSuggestedPrice;
+    private ProductCalendarPriceDto productCalendarPrices;
+}

+ 20 - 0
src/main/java/com/poyee/dto/ProductCalendarDto.java

@@ -0,0 +1,20 @@
+package com.poyee.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+public class ProductCalendarDto {
+    private int id;
+    private String productName;
+    private Date releaseTime;
+    private String imageUrl;
+    private BigDecimal basePrice;
+    private BigDecimal suggestedPrice;
+    private BigDecimal rmbBasePrice;
+    private BigDecimal rmbSuggestedPrice;
+    private String currencyUnit;
+    private Date priceDate;
+}

+ 20 - 0
src/main/java/com/poyee/dto/ProductCalendarPriceDto.java

@@ -0,0 +1,20 @@
+package com.poyee.dto;
+
+import com.poyee.entity.ProductCalendarPrice;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ProductCalendarPriceDto {
+    private BigDecimal maxSuggestedPrice;
+    private String maxCurrencyType;
+    private BigDecimal minSuggestedPrice;
+    private String minCurrencyType;
+    private List<ProductCalendarPrice> prices;
+}

+ 13 - 0
src/main/java/com/poyee/dto/ProductSimpleDto.java

@@ -0,0 +1,13 @@
+package com.poyee.dto;
+
+import lombok.Data;
+
+/**
+ * 用于接收产品简单信息的 DTO 类
+ */
+@Data
+public class ProductSimpleDto {
+    private Long id;
+    private String productName;
+    private String imageUrl;
+}

+ 24 - 0
src/main/java/com/poyee/entity/BlowoutDetailRecord.java

@@ -0,0 +1,24 @@
+package com.poyee.entity;
+
+import lombok.Data;
+import java.sql.Timestamp;
+
+@Data
+public class BlowoutDetailRecord {
+    private Long id;
+    private String url;
+    private String images;
+    private String configuration;
+    private String productHighlights;
+    private String boxBreak;
+    private String releaseDate;
+    private String productYear;
+    private String brand;
+    private String sport;
+    private String boxStyle;
+    private String promo;
+    private Timestamp gmtCreateTime;
+    private String imageUri;
+    private Integer imageStat;
+    private Timestamp gmtModifiedTime;
+}

+ 23 - 0
src/main/java/com/poyee/entity/BlowoutRecordNewDailyNew.java

@@ -0,0 +1,23 @@
+package com.poyee.entity;
+
+import lombok.Data;
+
+import java.sql.Timestamp;
+
+@Data
+public class BlowoutRecordNewDailyNew {
+    private Long id;
+    private String img;
+    private String title;
+    private String price;
+    private String suggestedPrice;
+    private String href;
+    private String category;
+    private Integer preorder;
+    private Integer newField; // "new" 是 Java 关键字,这里使用 newField 替代
+    private Integer detailState;
+    private Integer lowState;
+    private Timestamp firstCreateTime;
+    private Timestamp gmtCreateTime;
+    private Timestamp gmtModifiedTime;
+}

+ 35 - 0
src/main/java/com/poyee/entity/ProductCalendar.java

@@ -0,0 +1,35 @@
+package com.poyee.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.sql.Timestamp;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ProductCalendar {
+    private Long id;
+    private String year;
+    private String sport;
+    private String manufacturer;
+    private String sets;
+    private String setsVersion;
+    private String productName;
+    private String releaseDate;
+    private String baseConfig;
+    private String imagesUrl;
+    private String imageUrl;
+    private String productHighlights;
+    private String boxBreak;
+    private String prop1;
+    private String prop2;
+    private String prop3;
+    private String prop4;
+    private Timestamp createTime;
+    private String createBy;
+    private Timestamp updateTime;
+    private String updateBy;
+    private Timestamp releaseTime;
+}

+ 28 - 0
src/main/java/com/poyee/entity/ProductCalendarPrice.java

@@ -0,0 +1,28 @@
+package com.poyee.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ProductCalendarPrice {
+    private Long id;
+    private Long productCalendarId;
+    private BigDecimal basePrice;
+    private BigDecimal suggestedPrice;
+    private Timestamp priceDate;
+    private String priceResource;
+    private Timestamp createTime;
+    private String createBy;
+    private Timestamp updateTime;
+    private String updateBy;
+    private String currencyUnit;
+    // 新增两个字段用于存储人民币价格
+    private BigDecimal rmbBasePrice;
+    private BigDecimal rmbSuggestedPrice;
+}

+ 11 - 0
src/main/java/com/poyee/mapper/BlowoutDetailRecordMapper.java

@@ -0,0 +1,11 @@
+package com.poyee.mapper;
+
+import com.poyee.entity.BlowoutDetailRecord;
+import org.apache.ibatis.annotations.Mapper;
+import java.util.List;
+
+@Mapper
+public interface BlowoutDetailRecordMapper {
+    List<BlowoutDetailRecord> getAllDetails();
+    BlowoutDetailRecord getDetailById(Long id);
+}

+ 13 - 0
src/main/java/com/poyee/mapper/BlowoutRecordMapper.java

@@ -0,0 +1,13 @@
+package com.poyee.mapper;
+
+import com.poyee.dto.BlowoutRecordDto;
+import com.poyee.dto.BlowoutRecordGroupDto;
+
+import java.util.List;
+import java.util.Map;
+
+public interface BlowoutRecordMapper {
+    List<BlowoutRecordDto> getBlowoutRecordsByPage(Map<String, Object> params);
+
+    List<BlowoutRecordGroupDto>  getLatestBlowoutRecordsByGroup(Map<String, Object> params);
+}

+ 11 - 0
src/main/java/com/poyee/mapper/BlowoutRecordNewDailyNewMapper.java

@@ -0,0 +1,11 @@
+package com.poyee.mapper;
+
+import com.poyee.entity.BlowoutRecordNewDailyNew;
+import org.apache.ibatis.annotations.Mapper;
+import java.util.List;
+
+@Mapper
+public interface BlowoutRecordNewDailyNewMapper {
+    List<BlowoutRecordNewDailyNew> getAllRecords();
+    BlowoutRecordNewDailyNew getRecordById(Long id);
+}

+ 29 - 0
src/main/java/com/poyee/mapper/ProductCalendarMapper.java

@@ -0,0 +1,29 @@
+package com.poyee.mapper;
+
+import com.poyee.dto.ProductCalendarDto;
+import com.poyee.dto.ProductSimpleDto;
+import com.poyee.entity.ProductCalendar;
+import com.poyee.entity.ProductCalendarPrice;
+
+import java.util.List;
+import java.util.Map;
+
+public interface ProductCalendarMapper {
+
+    List<ProductCalendarDto> getProductCalendarsList(Map<String, Object> params);
+
+    ProductCalendar getProductCalendarById(Long id);
+
+    List<ProductCalendarPrice> getProductCalendarPricesByProductCalendarId(Long id, Integer days);
+
+    Integer getProductCalendarCountByIds(Map<String, Object> params);
+
+    /**
+     * 根据条件和分页信息查询产品日历信息
+     * @param params 包含查询条件和分页信息的参数,如 releaseYear, releaseMonth, sport, manufacturer, startRow, endRow
+     * @return 符合条件的产品日历信息列表
+     */
+    List<ProductCalendarDto> getProductCalendarsByPageAndCondition(Map<String, Object> params);
+
+    List<ProductSimpleDto> getProductCalendarsByProductName(String productName);
+}

+ 8 - 0
src/main/java/com/poyee/service/BlowoutDetailRecordService.java

@@ -0,0 +1,8 @@
+package com.poyee.service;
+
+import com.poyee.entity.BlowoutDetailRecord;
+import java.util.List;
+
+public interface BlowoutDetailRecordService {
+    List<BlowoutDetailRecord> getAllDetails();
+}

+ 8 - 0
src/main/java/com/poyee/service/BlowoutRecordNewDailyNewService.java

@@ -0,0 +1,8 @@
+package com.poyee.service;
+
+import com.poyee.entity.BlowoutRecordNewDailyNew;
+import java.util.List;
+
+public interface BlowoutRecordNewDailyNewService {
+    List<BlowoutRecordNewDailyNew> getAllRecords();
+}

+ 18 - 0
src/main/java/com/poyee/service/BlowoutRecordService.java

@@ -0,0 +1,18 @@
+package com.poyee.service;
+
+import com.poyee.dto.BlowoutRecordDto;
+import com.poyee.dto.BlowoutRecordGroupDto;
+
+import java.util.List;
+import java.util.Map;
+
+public interface BlowoutRecordService {
+    /**
+     * 根据参数分页查询BlowoutRecord信息
+     * @param params 查询参数,包含分页信息、筛选条件等
+     * @return 查询到的BlowoutRecordDto列表
+     */
+    List<BlowoutRecordDto> getBlowoutRecordsByPage(Map<String, Object> params);
+
+    List<BlowoutRecordGroupDto> getLatestBlowoutRecordsByGroup(Map<String, Object> params);
+}

+ 33 - 0
src/main/java/com/poyee/service/ProductCalendarService.java

@@ -0,0 +1,33 @@
+package com.poyee.service;
+
+import com.poyee.dto.ProductCalendarDetailDto;
+import com.poyee.dto.ProductCalendarDto;
+import com.poyee.dto.ProductCalendarPriceDto;
+import com.poyee.dto.ProductSimpleDto;
+
+import java.util.List;
+import java.util.Map;
+
+public interface ProductCalendarService {
+    /**
+     * 根据条件查询产品日历信息
+     * @param params 包含查询条件的参数,如 releaseYear, releaseMonth, sport, manufacturer
+     * @return 符合条件的产品日历信息列表
+     */
+    List<ProductCalendarDto> getProductCalendarsList(Map<String, Object> params);
+
+    ProductCalendarDetailDto getProductCalendarByIdAndDays(Long id, int days);
+
+    ProductCalendarPriceDto getProductCalendarPricesByIdAndDays(Long id, int days);
+
+    Integer getProductCalendarCountByIds(Map<String, Object> params);
+
+    List<ProductCalendarDto> getProductCalendarsByPageAndCondition(Map<String, Object> params);
+
+    /**
+     * 根据产品名称模糊查询产品日历信息
+     * @param productName 产品名称
+     * @return 符合条件的产品日历信息列表
+     */
+    List<ProductSimpleDto> getProductCalendarsByProductName(String productName);
+}

+ 21 - 0
src/main/java/com/poyee/service/impl/BlowoutDetailRecordServiceImpl.java

@@ -0,0 +1,21 @@
+package com.poyee.service.impl;
+
+import com.poyee.entity.BlowoutDetailRecord;
+import com.poyee.mapper.BlowoutDetailRecordMapper;
+import com.poyee.service.BlowoutDetailRecordService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class BlowoutDetailRecordServiceImpl implements BlowoutDetailRecordService {
+
+    @Autowired
+    private BlowoutDetailRecordMapper blowoutDetailRecordMapper;
+
+    @Override
+    public List<BlowoutDetailRecord> getAllDetails() {
+        return blowoutDetailRecordMapper.getAllDetails();
+    }
+}

+ 21 - 0
src/main/java/com/poyee/service/impl/BlowoutRecordNewDailyNewServiceImpl.java

@@ -0,0 +1,21 @@
+package com.poyee.service.impl;
+
+import com.poyee.entity.BlowoutRecordNewDailyNew;
+import com.poyee.mapper.BlowoutRecordNewDailyNewMapper;
+import com.poyee.service.BlowoutRecordNewDailyNewService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class BlowoutRecordNewDailyNewServiceImpl implements BlowoutRecordNewDailyNewService {
+
+    @Autowired
+    private BlowoutRecordNewDailyNewMapper blowoutRecordNewDailyNewMapper;
+
+    @Override
+    public List<BlowoutRecordNewDailyNew> getAllRecords() {
+        return blowoutRecordNewDailyNewMapper.getAllRecords();
+    }
+}

+ 29 - 0
src/main/java/com/poyee/service/impl/BlowoutRecordServiceImpl.java

@@ -0,0 +1,29 @@
+package com.poyee.service.impl;
+
+import com.poyee.dto.BlowoutRecordDto;
+import com.poyee.mapper.BlowoutRecordMapper;
+import com.poyee.service.BlowoutRecordService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.poyee.dto.BlowoutRecordGroupDto;
+
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class BlowoutRecordServiceImpl implements BlowoutRecordService {
+
+    @Autowired
+    private BlowoutRecordMapper blowoutRecordMapper;
+
+    @Override
+    public List<BlowoutRecordDto> getBlowoutRecordsByPage(Map<String, Object> params) {
+        return blowoutRecordMapper.getBlowoutRecordsByPage(params);
+    }
+
+    @Override
+    public List<BlowoutRecordGroupDto> getLatestBlowoutRecordsByGroup(Map<String, Object> params)  {
+        return blowoutRecordMapper.getLatestBlowoutRecordsByGroup(params);
+    }
+
+}

+ 118 - 0
src/main/java/com/poyee/service/impl/ProductCalendarServiceImpl.java

@@ -0,0 +1,118 @@
+package com.poyee.service.impl;
+
+import com.poyee.config.ExchangeRateConfig;
+import com.poyee.dto.ProductCalendarDetailDto;
+import com.poyee.dto.ProductCalendarDto;
+import com.poyee.dto.ProductCalendarPriceDto;
+import com.poyee.dto.ProductSimpleDto;
+import com.poyee.entity.ProductCalendar;
+import com.poyee.entity.ProductCalendarPrice;
+import com.poyee.mapper.ProductCalendarMapper;
+import com.poyee.service.ProductCalendarService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class ProductCalendarServiceImpl implements ProductCalendarService {
+
+    @Autowired
+    private ProductCalendarMapper productCalendarMapper;
+    @Autowired
+    private ExchangeRateConfig exchangeRateConfig;
+
+    @Override
+    public List<ProductCalendarDto> getProductCalendarsList(Map<String, Object> params) {
+        return productCalendarMapper.getProductCalendarsList(params);
+    }
+
+    @Override
+    public ProductCalendarDetailDto getProductCalendarByIdAndDays(Long id, int days) {
+        ProductCalendarDetailDto productCalendarDetailDto = new ProductCalendarDetailDto();
+        // 获取产品日历信息
+        ProductCalendar productCalendar = productCalendarMapper.getProductCalendarById(id);
+        BeanUtils.copyProperties(productCalendar, productCalendarDetailDto);
+        // 查询价格走势
+        List<ProductCalendarPrice> productCalendarPrices = productCalendarMapper.getProductCalendarPricesByProductCalendarId(id, days);
+        if (!productCalendarPrices.isEmpty()) {
+            ProductCalendarPriceDto productCalendarPriceDto = new ProductCalendarPriceDto();
+            productCalendarPriceDto.setPrices(productCalendarPrices);
+            // 设置最新价格
+            ProductCalendarPrice lastProductCalendarPrice = productCalendarPrices.get(0);
+            productCalendarDetailDto.setLastBasePrice(lastProductCalendarPrice.getBasePrice());
+            productCalendarDetailDto.setLastSuggestedPrice(lastProductCalendarPrice.getSuggestedPrice());
+            productCalendarDetailDto.setLastCurrencyUnit(lastProductCalendarPrice.getCurrencyUnit());
+            BigDecimal lastPriceExchangeRate = exchangeRateConfig.getExchangeRate(lastProductCalendarPrice.getCurrencyUnit());
+            productCalendarDetailDto.setLastRmbBasePrice(roundUpToHundreds(lastProductCalendarPrice.getBasePrice().multiply(lastPriceExchangeRate)));
+            productCalendarDetailDto.setLastRmbSuggestedPrice(roundUpToHundreds(lastProductCalendarPrice.getSuggestedPrice().multiply(lastPriceExchangeRate)));
+            //设置价格走势list
+            productCalendarDetailDto.setProductCalendarPrices(productCalendarPriceDto);
+            // 价格走势最大值
+            ProductCalendarPrice maxSuggestedPrice = productCalendarPrices.stream().max(Comparator.comparing(ProductCalendarPrice::getSuggestedPrice)).orElse(null);
+            productCalendarPriceDto.setMaxSuggestedPrice(maxSuggestedPrice.getSuggestedPrice());
+            productCalendarPriceDto.setMaxCurrencyType(maxSuggestedPrice.getCurrencyUnit());
+            //最小值
+            ProductCalendarPrice minSuggestedPrice = productCalendarPrices.stream().min(Comparator.comparing(ProductCalendarPrice::getSuggestedPrice)).orElse(null);
+            productCalendarPriceDto.setMinSuggestedPrice(minSuggestedPrice.getSuggestedPrice());
+            productCalendarPriceDto.setMinCurrencyType(minSuggestedPrice.getCurrencyUnit());
+        }
+        return productCalendarDetailDto;
+    }
+
+    @Override
+    public ProductCalendarPriceDto getProductCalendarPricesByIdAndDays(Long id, int days) {
+        ProductCalendarPriceDto productCalendarPriceDto = new ProductCalendarPriceDto();
+        List<ProductCalendarPrice> productCalendarPrices = productCalendarMapper.getProductCalendarPricesByProductCalendarId(id, days);
+        // 查询价格走势
+        if (!productCalendarPrices.isEmpty()) {
+            productCalendarPriceDto.setPrices(productCalendarPrices);
+            // 价格走势最大值
+            ProductCalendarPrice maxSuggestedPrice = productCalendarPrices.stream().max(Comparator.comparing(ProductCalendarPrice::getSuggestedPrice)).orElse(null);
+            productCalendarPriceDto.setMaxSuggestedPrice(maxSuggestedPrice.getSuggestedPrice());
+            productCalendarPriceDto.setMaxCurrencyType(maxSuggestedPrice.getCurrencyUnit());
+            //最小值
+            ProductCalendarPrice minSuggestedPrice = productCalendarPrices.stream().min(Comparator.comparing(ProductCalendarPrice::getSuggestedPrice)).orElse(null);
+            productCalendarPriceDto.setMinSuggestedPrice(minSuggestedPrice.getSuggestedPrice());
+            productCalendarPriceDto.setMinCurrencyType(minSuggestedPrice.getCurrencyUnit());
+        }
+        return productCalendarPriceDto;
+    }
+
+    @Override
+    public Integer getProductCalendarCountByIds(Map<String, Object> params) {
+        return productCalendarMapper.getProductCalendarCountByIds(params);
+    }
+
+    @Override
+    public List<ProductCalendarDto> getProductCalendarsByPageAndCondition(Map<String, Object> params) {
+        List<ProductCalendarDto> productCalendarDtos = productCalendarMapper.getProductCalendarsByPageAndCondition(params);
+        for (ProductCalendarDto productCalendarDto : productCalendarDtos) {
+            BigDecimal exchangeRate = exchangeRateConfig.getExchangeRate(productCalendarDto.getCurrencyUnit());
+            if (exchangeRate!= null) {
+                productCalendarDto.setRmbBasePrice(roundUpToHundreds(productCalendarDto.getBasePrice().multiply(exchangeRate)));
+                productCalendarDto.setRmbSuggestedPrice(roundUpToHundreds(productCalendarDto.getSuggestedPrice().multiply(exchangeRate)));
+            }
+        }
+        return productCalendarDtos;
+    }
+
+    @Override
+    public List<ProductSimpleDto> getProductCalendarsByProductName(String productName) {
+        return productCalendarMapper.getProductCalendarsByProductName(productName);
+    }
+
+    /**
+     * 将 BigDecimal 数字在百位向上取整
+     * @param number 要处理的 BigDecimal 数字
+     * @return 百位向上取整后的 BigDecimal 数字
+     */
+    private BigDecimal roundUpToHundreds(BigDecimal number) {
+        // 先将数字除以 100,然后向上取整,最后再乘以 100
+        return BigDecimal.valueOf(Math.ceil(number.doubleValue() / 100)).multiply(BigDecimal.valueOf(100));
+    }
+}

+ 160 - 0
src/main/resources/application.yml

@@ -0,0 +1,160 @@
+# 项目相关配置
+poyee:
+  # 名称
+  name: product-calendar
+  # 版本
+  version: 1.0.1
+  # 获取ip地址开关
+  addressEnabled: false
+  #版本
+  app-version: dev
+  #app-version: prod
+
+exchange:
+  rate:
+    usd-to-rmb: 7.0
+    jpy-to-rmb: 0.05
+
+management:
+  health:
+    defaults.enabled: false
+    db.enabled: true
+    diskspace.enabled: true
+
+#Forest
+forest:
+  #bean-id: config0 # 在spring上下文中bean的id(默认为 forestConfiguration)
+  #backend: okhttp3 # 后端HTTP框架(默认为 okhttp3)
+  #max-connections: 1000 # 连接池最大连接数(默认为 500)
+  #max-route-connections: 500 # 每个路由的最大连接数(默认为 500)你这
+  #timeout: 30000 # 请求超时时间,单位为毫秒(默认为 3000)
+  #connect-timeout: 30000 # 连接超时时间,单位为毫秒(默认为 timeout)
+  read-timeout: 10000 # 数据读取超时时间,单位为毫秒(默认为 timeout)
+  #max-retry-count: 0 # 请求失败后重试次数(默认为 0 次不重试)
+  #ssl-protocol: SSLv3 # 单向验证的HTTPS的默认SSL协议(默认为 SSLv3)
+  #logEnabled: true # 打开或关闭日志(默认为 true)
+  #log-request: true # 打开/关闭Forest请求日志(默认为 true)
+  #log-response-status: true # 打开/关闭Forest响应状态日志(默认为 true)
+  #log-response-content: true # 打开/关闭Forest响应内容日志(默认为 false)
+  variables:
+    appleUrl: https://appleid.apple.com/auth
+# 开发环境配置
+server:
+  # 服务器的HTTP端口,默认为80
+  port: 8088
+  tomcat:
+    # tomcat的URI编码
+    uri-encoding: UTF-8
+    # tomcat最大线程数,默认为200
+    max-threads: ${SERVER_TOMCAT_MAX_THREADS:800}
+    # Tomcat启动初始化的线程数,默认值25
+    min-spare-threads: ${SERVER_TOMCAT_MIN_SPARE_THREADS:30}
+    #超时时间
+    connection-timeout: 600000
+    #basedir: c://tmp/logs
+    accesslog:
+      enabled: false
+      buffered: true
+      prefix: access_log
+      file-date-format: .yyyy-MM-dd
+
+
+# 日志配置
+logging:
+  console.enabled: ${CONSOLE_ENABLED:true}
+  file.enabled: ${FILE_ENABLED:false}
+  level:
+    com.poyee: debug
+    org.springframework: warn
+  fluentd:
+    enabled: ${FLUENTD_ENABLED:false}
+    host: ${FLUENTD_HOST:127.0.0.1}
+    port: ${FLUENTD_PORT:24225}
+
+
+# Spring配置
+spring:
+  jackson:
+    time-zone: GMT+8
+    date-format: yyyy-MM-dd HH:mm:ss
+    #default-property-inclusion: non_null
+  # 服务模块
+  devtools:
+    restart:
+      # 热部署开关
+      enabled: true
+  #数据源配置
+  datasource:
+    url: jdbc:postgresql://m2-dev.hobbystocks.cn:5432/tzy_system
+    username: postgres
+    password: 123456
+    type: com.alibaba.druid.pool.DruidDataSource
+    driver-class-name: org.postgresql.Driver
+    druid:
+      # 初始连接数
+      initialSize: 5
+      # 最小连接池数量
+      minIdle: 10
+      # 最大连接池数量
+      maxActive: 20
+      # 配置获取连接等待超时的时间
+      maxWait: 60000
+      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+      timeBetweenEvictionRunsMillis: 30000
+      #验证连接超时时间(ms)
+      validationQueryTimeout: 300
+      # 配置一个连接在池中最小生存的时间,单位是毫秒
+      minEvictableIdleTimeMillis: 300000
+      # 配置一个连接在池中最大生存的时间,单位是毫秒
+      maxEvictableIdleTimeMillis: 900000
+      webStatFilter:
+        enabled: false
+  jpa:
+    hibernate:
+      ddl-auto: none
+      naming:
+        physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
+    #show-sql: true
+    properties:
+      hibernate:
+        temp:
+          use_jdbc_metadata_defaults: false
+  redis:
+    database: 1
+    host: 127.0.0.1
+    #host: hobbystock.cn
+    port: 6379
+    password: 123456    # 密码(默认为空)
+    timeout: 60000  # 连接超时时长(毫秒)
+    pool:
+      max-active: 1000  # 连接池最大连接数(使用负值表示没有限制)
+      max-wait: -1ms    # 连接池最大阻塞等待时间(使用负值表示没有限制)
+      max-idle: 10      # 连接池中的最大空闲连接
+      min-idle: 5       # 连接池中的最小空闲连接
+
+# Swagger配置
+swagger:
+  # 是否开启swagger
+  enabled: true
+
+#服务前缀路径
+coreService:
+  baseurl: ${CORESERV_BASEURL:https://coresvc-dev.hobbystocks.cn}
+  smsUrl: /api/reminder/live/on
+  appSmsUrl: /api/appmsg/live/on
+  ipUrl: /api/geo/city
+  #用户服务
+  user:
+    # 用户内网地址
+    useServiceUrl: ${CORESERV_BASEURL:https://coresvc-dev.hobbystocks.cn}
+    #用户详情
+    userInfoUrl: /user
+    #商家app用户信息
+    merchantUrl: /user/merchant
+
+#消息推送服务地址
+pushBaseUrl: ${CORESERV_BASEURL:https://coresvc-dev.hobbystocks.cn}
+
+# MyBatis
+mybatis:
+  mapper-locations: classpath:mapper/*.xml

+ 33 - 0
src/main/resources/mapper/BlowoutDetailRecord.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.poyee.mapper.BlowoutDetailRecordMapper">
+
+    <resultMap id="BlowoutDetailRecordResultMap" type="com.poyee.entity.BlowoutDetailRecord">
+        <id property="id" column="id"/>
+        <result property="url" column="url"/>
+        <result property="images" column="images"/>
+        <result property="configuration" column="configuration"/>
+        <result property="productHighlights" column="product_highlights"/>
+        <result property="boxBreak" column="box_break"/>
+        <result property="releaseDate" column="release_date"/>
+        <result property="productYear" column="product_year"/>
+        <result property="brand" column="brand"/>
+        <result property="sport" column="sport"/>
+        <result property="boxStyle" column="box_style"/>
+        <result property="promo" column="promo"/>
+        <result property="gmtCreateTime" column="gmt_create_time"/>
+        <result property="imageUri" column="image_uri"/>
+        <result property="imageStat" column="image_stat"/>
+        <result property="gmtModifiedTime" column="gmt_modified_time"/>
+    </resultMap>
+
+    <select id="getAllDetails" resultMap="BlowoutDetailRecordResultMap">
+        SELECT * FROM public.blowout_detail_record LIMIT 5
+    </select>
+
+    <select id="getDetailById" resultMap="BlowoutDetailRecordResultMap">
+        SELECT * FROM public.blowout_detail_record WHERE id = #{id}
+    </select>
+</mapper>

+ 153 - 0
src/main/resources/mapper/BlowoutRecord.xml

@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.poyee.mapper.BlowoutRecordMapper">
+
+    <resultMap id="BlowoutRecordResultMap" type="com.poyee.dto.BlowoutRecordDto">
+        <!-- BlowoutDetailRecord 表映射 -->
+        <id property="blowoutDetailRecord.id" column="t1_id"/>
+        <result property="blowoutDetailRecord.url" column="t1_url"/>
+        <result property="blowoutDetailRecord.images" column="t1_images"/>
+        <result property="blowoutDetailRecord.configuration" column="t1_configuration"/>
+        <result property="blowoutDetailRecord.productHighlights" column="t1_product_highlights"/>
+        <result property="blowoutDetailRecord.boxBreak" column="t1_box_break"/>
+        <result property="blowoutDetailRecord.releaseDate" column="t1_release_date"/>
+        <result property="blowoutDetailRecord.productYear" column="t1_product_year"/>
+        <result property="blowoutDetailRecord.brand" column="t1_brand"/>
+        <result property="blowoutDetailRecord.sport" column="t1_sport"/>
+        <result property="blowoutDetailRecord.boxStyle" column="t1_box_style"/>
+        <result property="blowoutDetailRecord.promo" column="t1_promo"/>
+        <result property="blowoutDetailRecord.gmtCreateTime" column="t1_gmt_create_time"/>
+        <result property="blowoutDetailRecord.imageUri" column="t1_image_uri"/>
+        <result property="blowoutDetailRecord.imageStat" column="t1_image_stat"/>
+        <result property="blowoutDetailRecord.gmtModifiedTime" column="t1_gmt_modified_time"/>
+        <!-- BlowoutRecordNewDailyNew 表映射 -->
+        <result property="blowoutRecordNewDailyNew.id" column="t2_id"/>
+        <result property="blowoutRecordNewDailyNew.img" column="t2_img"/>
+        <result property="blowoutRecordNewDailyNew.title" column="t2_title"/>
+        <result property="blowoutRecordNewDailyNew.price" column="t2_price"/>
+        <result property="blowoutRecordNewDailyNew.suggestedPrice" column="t2_suggestedPrice"/>
+        <result property="blowoutRecordNewDailyNew.href" column="t2_href"/>
+        <result property="blowoutRecordNewDailyNew.category" column="t2_category"/>
+        <result property="blowoutRecordNewDailyNew.preorder" column="t2_preorder"/>
+        <result property="blowoutRecordNewDailyNew.newField" column="t2_newField"/>
+        <result property="blowoutRecordNewDailyNew.detailState" column="t2_detailState"/>
+        <result property="blowoutRecordNewDailyNew.lowState" column="t2_lowState"/>
+        <result property="blowoutRecordNewDailyNew.firstCreateTime" column="t2_firstCreateTime"/>
+        <result property="blowoutRecordNewDailyNew.gmtCreateTime" column="t2_gmtCreateTime"/>
+        <result property="blowoutRecordNewDailyNew.gmtModifiedTime" column="t2_gmtModifiedTime"/>
+    </resultMap>
+
+
+    <resultMap id="BlowoutRecordGroupResultMap" type="com.poyee.dto.BlowoutRecordGroupDto">
+        <result property="releaseDate" column="t1_release_date"/>
+        <result property="productYear" column="t1_product_year"/>
+        <result property="brand" column="t1_brand"/>
+        <result property="sport" column="t1_sport"/>
+        <result property="boxStyle" column="t1_box_style"/>
+        <result property="title" column="t2_title"/>
+        <result property="price" column="t2_price"/>
+        <result property="suggestedPrice" column="t2_suggestedPrice"/>
+        <result property="category" column="t2_category"/>
+    </resultMap>
+
+    <select id="getBlowoutRecordsByPage" resultMap="BlowoutRecordResultMap">
+        SELECT
+        t1.id as t1_id,
+        t1.url as t1_url,
+        t1.images as t1_images,
+        t1.configuration as t1_configuration,
+        t1.product_highlights as t1_product_highlights,
+        t1.box_break as t1_box_break,
+        t1.release_date as t1_release_date,
+        t1.product_year as t1_product_year,
+        t1.brand as t1_brand,
+        t1.sport as t1_sport,
+        t1.box_style as t1_box_style,
+        t1.promo as t1_promo,
+        t1.gmt_create_time as t1_gmt_create_time,
+        t1.image_uri as t1_image_uri,
+        t1.image_stat as t1_image_stat,
+        t1.gmt_modified_time as t1_gmt_modified_time,
+        t2.id as t2_id,
+        t2.img as t2_img,
+        t2.title as t2_title,
+        t2.price as t2_price,
+        t2.suggested_Price as t2_suggestedPrice,
+        t2.href as t2_href,
+        t2.category as t2_category,
+        t2.preorder as t2_preorder,
+        t2.new as t2_newField,
+        t2.detail_State as t2_detailState,
+        t2.low_State as t2_lowState,
+        t2.first_Create_Time as t2_firstCreateTime,
+        t2.gmt_Create_Time as t2_gmtCreateTime,
+        t2.gmt_Modified_Time as t2_gmtModifiedTime
+        FROM blowout_detail_record t1
+        INNER JOIN blowout_record_new_daily_new t2 ON t1.url = 'https://www.blowoutcards.com' || t2.href
+        <where>
+            <if test="releaseDatePattern != null and releaseDatePattern != ''">
+                t1.release_date LIKE CONCAT(#{releaseDatePattern}, '%')
+            </if>
+            <if test="productYear != null and productYear != ''">
+                AND t1.product_year = #{productYear}
+            </if>
+            <if test="brand != null and brand != ''">
+                AND LOWER(t1.brand) = LOWER(#{brand})
+            </if>
+            <if test="category != null and category != ''">
+                AND LOWER(t2.category) = LOWER(#{category})
+            </if>
+        </where>
+        ORDER BY t1.id DESC
+        LIMIT #{limit} OFFSET #{offset};
+    </select>
+
+    <select id="getLatestBlowoutRecordsByGroup" resultMap="BlowoutRecordGroupResultMap">
+        SELECT
+        t1_release_date,
+        t1_product_year,
+        t1_brand,
+        t1_sport,
+        t1_box_style,
+        t2_title,
+        t2_price,
+        t2_suggestedPrice,
+        t2_category
+        FROM (
+        SELECT
+        t1.release_date as t1_release_date,
+        t1.product_year as t1_product_year,
+        t1.brand as t1_brand,
+        t1.sport as t1_sport,
+        t1.box_style as t1_box_style,
+        t2.title as t2_title,
+        t2.price as t2_price,
+        t2.suggested_Price as t2_suggestedPrice,
+        t2.category as t2_category,
+        ROW_NUMBER() OVER (
+        PARTITION BY t1.product_year, t1.brand, t1.sport, t1.box_style, t2.title, t2.category
+        ORDER BY t1.gmt_create_time DESC
+        ) as rn
+        FROM blowout_detail_record t1
+        left JOIN blowout_record_new_daily_new t2 ON t1.url = 'https://www.blowoutcards.com' || t2.href
+        <where>
+            <if test="releaseDatePattern != null and releaseDatePattern != ''">
+                t1.release_date LIKE CONCAT(#{releaseDatePattern}, '%')
+            </if>
+            <if test="productYear != null and productYear != ''">
+                AND t1.product_year = #{productYear}
+            </if>
+            <if test="brand != null and brand != ''">
+                AND LOWER(t1.brand) = LOWER(#{brand})
+            </if>
+            <if test="category != null and category != ''">
+                AND LOWER(t1.sport) = LOWER(#{category})
+            </if>
+        </where>
+        ) subquery
+        WHERE rn = 1
+        ORDER BY to_date(t1_release_date, 'Mon DD, YYYY') ASC;
+    </select>
+</mapper>

+ 32 - 0
src/main/resources/mapper/BlowoutRecordNewDailyNewMapper.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.poyee.mapper.BlowoutRecordNewDailyNewMapper">
+
+    <resultMap id="BlowoutRecordNewDailyNewResultMap" type="com.poyee.entity.BlowoutRecordNewDailyNew">
+        <id property="id" column="id"/>
+        <result property="img" column="img"/>
+        <result property="title" column="title"/>
+        <result property="price" column="price"/>
+        <result property="suggestedPrice" column="suggested_price"/>
+        <result property="href" column="href"/>
+        <result property="category" column="category"/>
+        <result property="preorder" column="preorder"/>
+        <result property="newField" column="new"/>
+        <result property="detailState" column="detail_state"/>
+        <result property="lowState" column="low_state"/>
+        <result property="firstCreateTime" column="first_create_time"/>
+        <result property="gmtCreateTime" column="gmt_create_time"/>
+        <result property="gmtModifiedTime" column="gmt_modified_time"/>
+    </resultMap>
+
+    <select id="getAllRecords" resultMap="BlowoutRecordNewDailyNewResultMap">
+        SELECT * FROM public.blowout_record_new_daily_new LIMIT 5
+    </select>
+
+    <select id="getRecordById" resultMap="BlowoutRecordNewDailyNewResultMap">
+        SELECT * FROM public.blowout_record_new_daily_new WHERE id = #{id}
+    </select>
+
+</mapper>

+ 255 - 0
src/main/resources/mapper/ProductCalendarMapper.xml

@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.poyee.mapper.ProductCalendarMapper">
+
+    <resultMap id="ProductSimpleResultMap" type="com.poyee.dto.ProductSimpleDto">
+        <id property="id" column="id"/>
+        <result property="productName" column="product_name"/>
+        <result property="imageUrl" column="image_url"/>
+    </resultMap>
+
+    <resultMap id="ProductCalendarResultMap" type="com.poyee.dto.ProductCalendarDto">
+        <id property="id" column="id"/>
+        <result property="productName" column="product_name"/>
+        <result property="releaseTime" column="release_time"/>
+        <result property="imageUrl" column="image_url"/>
+        <result property="basePrice" column="base_price"/>
+        <result property="suggestedPrice" column="suggested_price"/>
+        <result property="priceDate" column="price_date"/>
+        <result property="currencyUnit" column="currency_unit"/>
+    </resultMap>
+
+    <resultMap id="ProductCalendarResultEntityMap" type="com.poyee.entity.ProductCalendar">
+        <id property="id" column="id"/>
+        <result property="year" column="year"/>
+        <result property="sport" column="sport"/>
+        <result property="manufacturer" column="manufacturer"/>
+        <result property="sets" column="sets"/>
+        <result property="setsVersion" column="sets_version"/>
+        <result property="productName" column="product_name"/>
+        <result property="releaseDate" column="release_date"/>
+        <result property="baseConfig" column="base_config"/>
+        <result property="imagesUrl" column="images_url"/>
+        <result property="imageUrl" column="image_url"/>
+        <result property="productHighlights" column="product_highlights"/>
+        <result property="boxBreak" column="box_break"/>
+        <result property="prop1" column="prop1"/>
+        <result property="prop2" column="prop2"/>
+        <result property="prop3" column="prop3"/>
+        <result property="prop4" column="prop4"/>
+        <result property="createTime" column="create_time"/>
+        <result property="createBy" column="create_by"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="updateBy" column="update_by"/>
+        <result property="releaseTime" column="release_time"/>
+    </resultMap>
+
+    <resultMap id="ProductCalendarPriceResultMap" type="com.poyee.entity.ProductCalendarPrice">
+        <id property="id" column="id"/>
+        <result property="productCalendarId" column="product_calendar_id"/>
+        <result property="basePrice" column="base_price"/>
+        <result property="suggestedPrice" column="suggested_price"/>
+        <result property="priceDate" column="price_date"/>
+        <result property="priceResource" column="price_resource"/>
+        <result property="createTime" column="create_time"/>
+        <result property="createBy" column="create_by"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="updateBy" column="update_by"/>
+        <result property="currencyUnit" column="currency_unit"/>
+    </resultMap>
+
+    <select id="getProductCalendarById" resultMap="ProductCalendarResultEntityMap">
+        SELECT
+        pc.id,
+        pc.year,
+        pc.sport,
+        pc.manufacturer,
+        pc.sets,
+        pc.sets_version,
+        pc.product_name,
+        pc.release_date,
+        pc.base_config,
+        pc.images_url,
+        pc.image_url,
+        pc.product_highlights,
+        pc.box_break,
+        pc.prop1,
+        pc.prop2,
+        pc.prop3,
+        pc.prop4,
+        pc.create_time,
+        pc.create_by,
+        pc.update_time,
+        pc.update_by,
+        pc.release_time
+        FROM
+        product_calendar pc
+        WHERE
+        pc.id = #{id}
+    </select>
+
+    <select id="getProductCalendarPricesByProductCalendarId" resultMap="ProductCalendarPriceResultMap">
+        SELECT
+        pcp.id,
+        pcp.product_calendar_id,
+        pcp.base_price,
+        pcp.suggested_price,
+        pcp.price_date,
+        pcp.price_resource,
+        pcp.create_time,
+        pcp.create_by,
+        pcp.update_time,
+        pcp.update_by,
+        pcp.currency_unit
+        FROM
+        product_calendar_price pcp
+        WHERE
+        pcp.product_calendar_id = #{id}
+        <if test="days != null">
+            AND pcp.price_date >= CURRENT_DATE - INTERVAL '1 days' * #{days}
+        </if>
+        order by pcp.price_date desc, pcp.id desc
+    </select>
+
+    <select id="getProductCalendarsList" resultMap="ProductCalendarResultMap">
+        SELECT
+            pc.id,
+            pc.product_name,
+            pc.release_time,
+            pc.image_url,
+            pcp.base_price,
+            pcp.suggested_price,
+            pcp.price_date
+        FROM
+            product_calendar pc
+        LEFT JOIN (
+            SELECT
+                product_calendar_id,
+                base_price,
+                suggested_price,
+                price_date,
+                ROW_NUMBER() OVER (
+                    PARTITION BY product_calendar_id
+                    ORDER BY price_date DESC
+                ) as rn
+            FROM
+                product_calendar_price
+        ) pcp ON pc.id = pcp.product_calendar_id AND pcp.rn = 1
+        <where>
+            <!-- 新增的条件 -->
+            <if test="releaseYear != null">
+                AND EXTRACT(YEAR FROM pc.release_time) = #{releaseYear}
+            </if>
+            <if test="releaseYear != null and releaseMonth != null">
+                AND EXTRACT(MONTH FROM pc.release_time) = #{releaseMonth}
+            </if>
+            <if test="sport != null and sport != ''">
+                AND LOWER(pc.sport) = LOWER(#{sport})
+            </if>
+            <if test="manufacturer != null and manufacturer != ''">
+                AND LOWER(pc.manufacturer) = LOWER(#{manufacturer})
+            </if>
+        </where>
+        ORDER BY
+            pc.release_time;
+    </select>
+
+    <select id="getProductCalendarCountByIds" resultType="java.lang.Integer">
+        SELECT COUNT(*)
+        FROM
+        product_calendar pc
+        <where>
+            <if test="releaseYear != null">
+                AND EXTRACT(YEAR FROM pc.release_time) = #{releaseYear}
+            </if>
+            <if test="releaseYear != null and releaseMonth != null">
+                AND EXTRACT(MONTH FROM pc.release_time) = #{releaseMonth}
+            </if>
+            <if test="sport != null and sport != ''">
+                AND LOWER(pc.sport) = LOWER(#{sport})
+            </if>
+            <if test="manufacturer != null and manufacturer != ''">
+                AND LOWER(pc.manufacturer) = LOWER(#{manufacturer})
+            </if>
+        </where>
+    </select>
+
+    <select id="getProductCalendarsByPageAndCondition" resultMap="ProductCalendarResultMap">
+        SELECT
+        subquery.id,
+        subquery.product_name,
+        subquery.release_time,
+        subquery.image_url,
+        subquery.base_price,
+        subquery.suggested_price,
+        subquery.price_date,
+        <!-- 新增字段 -->
+        subquery.currency_unit,
+        subquery.rn
+        FROM (
+        SELECT
+        pc.id,
+        pc.product_name,
+        pc.release_time,
+        pc.image_url,
+        pcp.base_price,
+        pcp.suggested_price,
+        pcp.price_date,
+        <!-- 新增字段 -->
+        pcp.currency_unit,
+        ROW_NUMBER() OVER (ORDER BY pc.release_time, pc.id) as rn
+        FROM
+        product_calendar pc
+        LEFT JOIN (
+        SELECT
+        product_calendar_id,
+        base_price,
+        suggested_price,
+        price_date,
+        <!-- 新增字段 -->
+        currency_unit,
+        ROW_NUMBER() OVER (
+        PARTITION BY product_calendar_id
+        ORDER BY price_date DESC
+        ) as rn
+        FROM
+        product_calendar_price
+        ) pcp ON pc.id = pcp.product_calendar_id AND pcp.rn = 1
+        <where>
+            <if test="releaseYear != null">
+                AND EXTRACT(YEAR FROM pc.release_time) = #{releaseYear}
+            </if>
+            <if test="releaseYear != null and releaseMonth != null">
+                AND EXTRACT(MONTH FROM pc.release_time) = #{releaseMonth}
+            </if>
+            <if test="sport != null and sport != ''">
+                AND LOWER(pc.sport) = LOWER(#{sport})
+            </if>
+            <if test="manufacturer != null and manufacturer != ''">
+                AND LOWER(pc.manufacturer) = LOWER(#{manufacturer})
+            </if>
+            <!-- 新增的模糊查询条件 -->
+            <if test="productName != null and productName != ''">
+                AND LOWER(pc.product_name) LIKE '%' || LOWER(#{productName}) || '%'
+            </if>
+        </where>
+        ) subquery
+        WHERE rn BETWEEN #{startRow} AND #{endRow};
+    </select>
+
+    <!-- 新增的查询方法 -->
+    <select id="getProductCalendarsByProductName" resultMap="ProductSimpleResultMap">
+        SELECT
+            pc.id,
+            pc.product_name,
+            pc.image_url
+        FROM
+            product_calendar pc
+        WHERE
+            LOWER(pc.product_name) LIKE '%' || LOWER(#{productName}) || '%'
+        LIMIT 10;
+    </select>
+
+</mapper>

+ 160 - 0
target/classes/application.yml

@@ -0,0 +1,160 @@
+# 项目相关配置
+poyee:
+  # 名称
+  name: product-calendar
+  # 版本
+  version: 1.0.1
+  # 获取ip地址开关
+  addressEnabled: false
+  #版本
+  app-version: dev
+  #app-version: prod
+
+exchange:
+  rate:
+    usd-to-rmb: 7.0
+    jpy-to-rmb: 0.05
+
+management:
+  health:
+    defaults.enabled: false
+    db.enabled: true
+    diskspace.enabled: true
+
+#Forest
+forest:
+  #bean-id: config0 # 在spring上下文中bean的id(默认为 forestConfiguration)
+  #backend: okhttp3 # 后端HTTP框架(默认为 okhttp3)
+  #max-connections: 1000 # 连接池最大连接数(默认为 500)
+  #max-route-connections: 500 # 每个路由的最大连接数(默认为 500)你这
+  #timeout: 30000 # 请求超时时间,单位为毫秒(默认为 3000)
+  #connect-timeout: 30000 # 连接超时时间,单位为毫秒(默认为 timeout)
+  read-timeout: 10000 # 数据读取超时时间,单位为毫秒(默认为 timeout)
+  #max-retry-count: 0 # 请求失败后重试次数(默认为 0 次不重试)
+  #ssl-protocol: SSLv3 # 单向验证的HTTPS的默认SSL协议(默认为 SSLv3)
+  #logEnabled: true # 打开或关闭日志(默认为 true)
+  #log-request: true # 打开/关闭Forest请求日志(默认为 true)
+  #log-response-status: true # 打开/关闭Forest响应状态日志(默认为 true)
+  #log-response-content: true # 打开/关闭Forest响应内容日志(默认为 false)
+  variables:
+    appleUrl: https://appleid.apple.com/auth
+# 开发环境配置
+server:
+  # 服务器的HTTP端口,默认为80
+  port: 8088
+  tomcat:
+    # tomcat的URI编码
+    uri-encoding: UTF-8
+    # tomcat最大线程数,默认为200
+    max-threads: ${SERVER_TOMCAT_MAX_THREADS:800}
+    # Tomcat启动初始化的线程数,默认值25
+    min-spare-threads: ${SERVER_TOMCAT_MIN_SPARE_THREADS:30}
+    #超时时间
+    connection-timeout: 600000
+    #basedir: c://tmp/logs
+    accesslog:
+      enabled: false
+      buffered: true
+      prefix: access_log
+      file-date-format: .yyyy-MM-dd
+
+
+# 日志配置
+logging:
+  console.enabled: ${CONSOLE_ENABLED:true}
+  file.enabled: ${FILE_ENABLED:false}
+  level:
+    com.poyee: debug
+    org.springframework: warn
+  fluentd:
+    enabled: ${FLUENTD_ENABLED:false}
+    host: ${FLUENTD_HOST:127.0.0.1}
+    port: ${FLUENTD_PORT:24225}
+
+
+# Spring配置
+spring:
+  jackson:
+    time-zone: GMT+8
+    date-format: yyyy-MM-dd HH:mm:ss
+    #default-property-inclusion: non_null
+  # 服务模块
+  devtools:
+    restart:
+      # 热部署开关
+      enabled: true
+  #数据源配置
+  datasource:
+    url: jdbc:postgresql://m2-dev.hobbystocks.cn:5432/tzy_system
+    username: postgres
+    password: 123456
+    type: com.alibaba.druid.pool.DruidDataSource
+    driver-class-name: org.postgresql.Driver
+    druid:
+      # 初始连接数
+      initialSize: 5
+      # 最小连接池数量
+      minIdle: 10
+      # 最大连接池数量
+      maxActive: 20
+      # 配置获取连接等待超时的时间
+      maxWait: 60000
+      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+      timeBetweenEvictionRunsMillis: 30000
+      #验证连接超时时间(ms)
+      validationQueryTimeout: 300
+      # 配置一个连接在池中最小生存的时间,单位是毫秒
+      minEvictableIdleTimeMillis: 300000
+      # 配置一个连接在池中最大生存的时间,单位是毫秒
+      maxEvictableIdleTimeMillis: 900000
+      webStatFilter:
+        enabled: false
+  jpa:
+    hibernate:
+      ddl-auto: none
+      naming:
+        physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
+    #show-sql: true
+    properties:
+      hibernate:
+        temp:
+          use_jdbc_metadata_defaults: false
+  redis:
+    database: 1
+    host: 127.0.0.1
+    #host: hobbystock.cn
+    port: 6379
+    password: 123456    # 密码(默认为空)
+    timeout: 60000  # 连接超时时长(毫秒)
+    pool:
+      max-active: 1000  # 连接池最大连接数(使用负值表示没有限制)
+      max-wait: -1ms    # 连接池最大阻塞等待时间(使用负值表示没有限制)
+      max-idle: 10      # 连接池中的最大空闲连接
+      min-idle: 5       # 连接池中的最小空闲连接
+
+# Swagger配置
+swagger:
+  # 是否开启swagger
+  enabled: true
+
+#服务前缀路径
+coreService:
+  baseurl: ${CORESERV_BASEURL:https://coresvc-dev.hobbystocks.cn}
+  smsUrl: /api/reminder/live/on
+  appSmsUrl: /api/appmsg/live/on
+  ipUrl: /api/geo/city
+  #用户服务
+  user:
+    # 用户内网地址
+    useServiceUrl: ${CORESERV_BASEURL:https://coresvc-dev.hobbystocks.cn}
+    #用户详情
+    userInfoUrl: /user
+    #商家app用户信息
+    merchantUrl: /user/merchant
+
+#消息推送服务地址
+pushBaseUrl: ${CORESERV_BASEURL:https://coresvc-dev.hobbystocks.cn}
+
+# MyBatis
+mybatis:
+  mapper-locations: classpath:mapper/*.xml

BIN
target/classes/com/poyee/ProductCalendarApplication.class


BIN
target/classes/com/poyee/config/CorsConfig.class


BIN
target/classes/com/poyee/config/ExchangeRateConfig.class


BIN
target/classes/com/poyee/controller/BlowoutRecordController.class


BIN
target/classes/com/poyee/controller/ProductCalendarController.class


BIN
target/classes/com/poyee/controller/TestController.class


BIN
target/classes/com/poyee/dto/BlowoutRecordDto.class


BIN
target/classes/com/poyee/dto/BlowoutRecordGroupDto.class


BIN
target/classes/com/poyee/dto/CommonResult.class


BIN
target/classes/com/poyee/dto/ProductCalendarDetailDto.class


BIN
target/classes/com/poyee/dto/ProductCalendarDto.class


BIN
target/classes/com/poyee/dto/ProductCalendarPriceDto.class


BIN
target/classes/com/poyee/dto/ProductSimpleDto.class


BIN
target/classes/com/poyee/entity/BlowoutDetailRecord.class


BIN
target/classes/com/poyee/entity/BlowoutRecordNewDailyNew.class


BIN
target/classes/com/poyee/entity/ProductCalendar.class


BIN
target/classes/com/poyee/entity/ProductCalendarPrice.class


BIN
target/classes/com/poyee/mapper/BlowoutDetailRecordMapper.class


BIN
target/classes/com/poyee/mapper/BlowoutRecordMapper.class


BIN
target/classes/com/poyee/mapper/BlowoutRecordNewDailyNewMapper.class


BIN
target/classes/com/poyee/mapper/ProductCalendarMapper.class


BIN
target/classes/com/poyee/service/BlowoutDetailRecordService.class


BIN
target/classes/com/poyee/service/BlowoutRecordNewDailyNewService.class


BIN
target/classes/com/poyee/service/BlowoutRecordService.class


BIN
target/classes/com/poyee/service/ProductCalendarService.class


BIN
target/classes/com/poyee/service/impl/BlowoutDetailRecordServiceImpl.class


BIN
target/classes/com/poyee/service/impl/BlowoutRecordNewDailyNewServiceImpl.class


BIN
target/classes/com/poyee/service/impl/BlowoutRecordServiceImpl.class


BIN
target/classes/com/poyee/service/impl/ProductCalendarServiceImpl.class


+ 33 - 0
target/classes/mapper/BlowoutDetailRecord.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.poyee.mapper.BlowoutDetailRecordMapper">
+
+    <resultMap id="BlowoutDetailRecordResultMap" type="com.poyee.entity.BlowoutDetailRecord">
+        <id property="id" column="id"/>
+        <result property="url" column="url"/>
+        <result property="images" column="images"/>
+        <result property="configuration" column="configuration"/>
+        <result property="productHighlights" column="product_highlights"/>
+        <result property="boxBreak" column="box_break"/>
+        <result property="releaseDate" column="release_date"/>
+        <result property="productYear" column="product_year"/>
+        <result property="brand" column="brand"/>
+        <result property="sport" column="sport"/>
+        <result property="boxStyle" column="box_style"/>
+        <result property="promo" column="promo"/>
+        <result property="gmtCreateTime" column="gmt_create_time"/>
+        <result property="imageUri" column="image_uri"/>
+        <result property="imageStat" column="image_stat"/>
+        <result property="gmtModifiedTime" column="gmt_modified_time"/>
+    </resultMap>
+
+    <select id="getAllDetails" resultMap="BlowoutDetailRecordResultMap">
+        SELECT * FROM public.blowout_detail_record LIMIT 5
+    </select>
+
+    <select id="getDetailById" resultMap="BlowoutDetailRecordResultMap">
+        SELECT * FROM public.blowout_detail_record WHERE id = #{id}
+    </select>
+</mapper>

+ 153 - 0
target/classes/mapper/BlowoutRecord.xml

@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.poyee.mapper.BlowoutRecordMapper">
+
+    <resultMap id="BlowoutRecordResultMap" type="com.poyee.dto.BlowoutRecordDto">
+        <!-- BlowoutDetailRecord 表映射 -->
+        <id property="blowoutDetailRecord.id" column="t1_id"/>
+        <result property="blowoutDetailRecord.url" column="t1_url"/>
+        <result property="blowoutDetailRecord.images" column="t1_images"/>
+        <result property="blowoutDetailRecord.configuration" column="t1_configuration"/>
+        <result property="blowoutDetailRecord.productHighlights" column="t1_product_highlights"/>
+        <result property="blowoutDetailRecord.boxBreak" column="t1_box_break"/>
+        <result property="blowoutDetailRecord.releaseDate" column="t1_release_date"/>
+        <result property="blowoutDetailRecord.productYear" column="t1_product_year"/>
+        <result property="blowoutDetailRecord.brand" column="t1_brand"/>
+        <result property="blowoutDetailRecord.sport" column="t1_sport"/>
+        <result property="blowoutDetailRecord.boxStyle" column="t1_box_style"/>
+        <result property="blowoutDetailRecord.promo" column="t1_promo"/>
+        <result property="blowoutDetailRecord.gmtCreateTime" column="t1_gmt_create_time"/>
+        <result property="blowoutDetailRecord.imageUri" column="t1_image_uri"/>
+        <result property="blowoutDetailRecord.imageStat" column="t1_image_stat"/>
+        <result property="blowoutDetailRecord.gmtModifiedTime" column="t1_gmt_modified_time"/>
+        <!-- BlowoutRecordNewDailyNew 表映射 -->
+        <result property="blowoutRecordNewDailyNew.id" column="t2_id"/>
+        <result property="blowoutRecordNewDailyNew.img" column="t2_img"/>
+        <result property="blowoutRecordNewDailyNew.title" column="t2_title"/>
+        <result property="blowoutRecordNewDailyNew.price" column="t2_price"/>
+        <result property="blowoutRecordNewDailyNew.suggestedPrice" column="t2_suggestedPrice"/>
+        <result property="blowoutRecordNewDailyNew.href" column="t2_href"/>
+        <result property="blowoutRecordNewDailyNew.category" column="t2_category"/>
+        <result property="blowoutRecordNewDailyNew.preorder" column="t2_preorder"/>
+        <result property="blowoutRecordNewDailyNew.newField" column="t2_newField"/>
+        <result property="blowoutRecordNewDailyNew.detailState" column="t2_detailState"/>
+        <result property="blowoutRecordNewDailyNew.lowState" column="t2_lowState"/>
+        <result property="blowoutRecordNewDailyNew.firstCreateTime" column="t2_firstCreateTime"/>
+        <result property="blowoutRecordNewDailyNew.gmtCreateTime" column="t2_gmtCreateTime"/>
+        <result property="blowoutRecordNewDailyNew.gmtModifiedTime" column="t2_gmtModifiedTime"/>
+    </resultMap>
+
+
+    <resultMap id="BlowoutRecordGroupResultMap" type="com.poyee.dto.BlowoutRecordGroupDto">
+        <result property="releaseDate" column="t1_release_date"/>
+        <result property="productYear" column="t1_product_year"/>
+        <result property="brand" column="t1_brand"/>
+        <result property="sport" column="t1_sport"/>
+        <result property="boxStyle" column="t1_box_style"/>
+        <result property="title" column="t2_title"/>
+        <result property="price" column="t2_price"/>
+        <result property="suggestedPrice" column="t2_suggestedPrice"/>
+        <result property="category" column="t2_category"/>
+    </resultMap>
+
+    <select id="getBlowoutRecordsByPage" resultMap="BlowoutRecordResultMap">
+        SELECT
+        t1.id as t1_id,
+        t1.url as t1_url,
+        t1.images as t1_images,
+        t1.configuration as t1_configuration,
+        t1.product_highlights as t1_product_highlights,
+        t1.box_break as t1_box_break,
+        t1.release_date as t1_release_date,
+        t1.product_year as t1_product_year,
+        t1.brand as t1_brand,
+        t1.sport as t1_sport,
+        t1.box_style as t1_box_style,
+        t1.promo as t1_promo,
+        t1.gmt_create_time as t1_gmt_create_time,
+        t1.image_uri as t1_image_uri,
+        t1.image_stat as t1_image_stat,
+        t1.gmt_modified_time as t1_gmt_modified_time,
+        t2.id as t2_id,
+        t2.img as t2_img,
+        t2.title as t2_title,
+        t2.price as t2_price,
+        t2.suggested_Price as t2_suggestedPrice,
+        t2.href as t2_href,
+        t2.category as t2_category,
+        t2.preorder as t2_preorder,
+        t2.new as t2_newField,
+        t2.detail_State as t2_detailState,
+        t2.low_State as t2_lowState,
+        t2.first_Create_Time as t2_firstCreateTime,
+        t2.gmt_Create_Time as t2_gmtCreateTime,
+        t2.gmt_Modified_Time as t2_gmtModifiedTime
+        FROM blowout_detail_record t1
+        INNER JOIN blowout_record_new_daily_new t2 ON t1.url = 'https://www.blowoutcards.com' || t2.href
+        <where>
+            <if test="releaseDatePattern != null and releaseDatePattern != ''">
+                t1.release_date LIKE CONCAT(#{releaseDatePattern}, '%')
+            </if>
+            <if test="productYear != null and productYear != ''">
+                AND t1.product_year = #{productYear}
+            </if>
+            <if test="brand != null and brand != ''">
+                AND LOWER(t1.brand) = LOWER(#{brand})
+            </if>
+            <if test="category != null and category != ''">
+                AND LOWER(t2.category) = LOWER(#{category})
+            </if>
+        </where>
+        ORDER BY t1.id DESC
+        LIMIT #{limit} OFFSET #{offset};
+    </select>
+
+    <select id="getLatestBlowoutRecordsByGroup" resultMap="BlowoutRecordGroupResultMap">
+        SELECT
+        t1_release_date,
+        t1_product_year,
+        t1_brand,
+        t1_sport,
+        t1_box_style,
+        t2_title,
+        t2_price,
+        t2_suggestedPrice,
+        t2_category
+        FROM (
+        SELECT
+        t1.release_date as t1_release_date,
+        t1.product_year as t1_product_year,
+        t1.brand as t1_brand,
+        t1.sport as t1_sport,
+        t1.box_style as t1_box_style,
+        t2.title as t2_title,
+        t2.price as t2_price,
+        t2.suggested_Price as t2_suggestedPrice,
+        t2.category as t2_category,
+        ROW_NUMBER() OVER (
+        PARTITION BY t1.product_year, t1.brand, t1.sport, t1.box_style, t2.title, t2.category
+        ORDER BY t1.gmt_create_time DESC
+        ) as rn
+        FROM blowout_detail_record t1
+        left JOIN blowout_record_new_daily_new t2 ON t1.url = 'https://www.blowoutcards.com' || t2.href
+        <where>
+            <if test="releaseDatePattern != null and releaseDatePattern != ''">
+                t1.release_date LIKE CONCAT(#{releaseDatePattern}, '%')
+            </if>
+            <if test="productYear != null and productYear != ''">
+                AND t1.product_year = #{productYear}
+            </if>
+            <if test="brand != null and brand != ''">
+                AND LOWER(t1.brand) = LOWER(#{brand})
+            </if>
+            <if test="category != null and category != ''">
+                AND LOWER(t1.sport) = LOWER(#{category})
+            </if>
+        </where>
+        ) subquery
+        WHERE rn = 1
+        ORDER BY to_date(t1_release_date, 'Mon DD, YYYY') ASC;
+    </select>
+</mapper>

+ 32 - 0
target/classes/mapper/BlowoutRecordNewDailyNewMapper.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.poyee.mapper.BlowoutRecordNewDailyNewMapper">
+
+    <resultMap id="BlowoutRecordNewDailyNewResultMap" type="com.poyee.entity.BlowoutRecordNewDailyNew">
+        <id property="id" column="id"/>
+        <result property="img" column="img"/>
+        <result property="title" column="title"/>
+        <result property="price" column="price"/>
+        <result property="suggestedPrice" column="suggested_price"/>
+        <result property="href" column="href"/>
+        <result property="category" column="category"/>
+        <result property="preorder" column="preorder"/>
+        <result property="newField" column="new"/>
+        <result property="detailState" column="detail_state"/>
+        <result property="lowState" column="low_state"/>
+        <result property="firstCreateTime" column="first_create_time"/>
+        <result property="gmtCreateTime" column="gmt_create_time"/>
+        <result property="gmtModifiedTime" column="gmt_modified_time"/>
+    </resultMap>
+
+    <select id="getAllRecords" resultMap="BlowoutRecordNewDailyNewResultMap">
+        SELECT * FROM public.blowout_record_new_daily_new LIMIT 5
+    </select>
+
+    <select id="getRecordById" resultMap="BlowoutRecordNewDailyNewResultMap">
+        SELECT * FROM public.blowout_record_new_daily_new WHERE id = #{id}
+    </select>
+
+</mapper>

+ 255 - 0
target/classes/mapper/ProductCalendarMapper.xml

@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.poyee.mapper.ProductCalendarMapper">
+
+    <resultMap id="ProductSimpleResultMap" type="com.poyee.dto.ProductSimpleDto">
+        <id property="id" column="id"/>
+        <result property="productName" column="product_name"/>
+        <result property="imageUrl" column="image_url"/>
+    </resultMap>
+
+    <resultMap id="ProductCalendarResultMap" type="com.poyee.dto.ProductCalendarDto">
+        <id property="id" column="id"/>
+        <result property="productName" column="product_name"/>
+        <result property="releaseTime" column="release_time"/>
+        <result property="imageUrl" column="image_url"/>
+        <result property="basePrice" column="base_price"/>
+        <result property="suggestedPrice" column="suggested_price"/>
+        <result property="priceDate" column="price_date"/>
+        <result property="currencyUnit" column="currency_unit"/>
+    </resultMap>
+
+    <resultMap id="ProductCalendarResultEntityMap" type="com.poyee.entity.ProductCalendar">
+        <id property="id" column="id"/>
+        <result property="year" column="year"/>
+        <result property="sport" column="sport"/>
+        <result property="manufacturer" column="manufacturer"/>
+        <result property="sets" column="sets"/>
+        <result property="setsVersion" column="sets_version"/>
+        <result property="productName" column="product_name"/>
+        <result property="releaseDate" column="release_date"/>
+        <result property="baseConfig" column="base_config"/>
+        <result property="imagesUrl" column="images_url"/>
+        <result property="imageUrl" column="image_url"/>
+        <result property="productHighlights" column="product_highlights"/>
+        <result property="boxBreak" column="box_break"/>
+        <result property="prop1" column="prop1"/>
+        <result property="prop2" column="prop2"/>
+        <result property="prop3" column="prop3"/>
+        <result property="prop4" column="prop4"/>
+        <result property="createTime" column="create_time"/>
+        <result property="createBy" column="create_by"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="updateBy" column="update_by"/>
+        <result property="releaseTime" column="release_time"/>
+    </resultMap>
+
+    <resultMap id="ProductCalendarPriceResultMap" type="com.poyee.entity.ProductCalendarPrice">
+        <id property="id" column="id"/>
+        <result property="productCalendarId" column="product_calendar_id"/>
+        <result property="basePrice" column="base_price"/>
+        <result property="suggestedPrice" column="suggested_price"/>
+        <result property="priceDate" column="price_date"/>
+        <result property="priceResource" column="price_resource"/>
+        <result property="createTime" column="create_time"/>
+        <result property="createBy" column="create_by"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="updateBy" column="update_by"/>
+        <result property="currencyUnit" column="currency_unit"/>
+    </resultMap>
+
+    <select id="getProductCalendarById" resultMap="ProductCalendarResultEntityMap">
+        SELECT
+        pc.id,
+        pc.year,
+        pc.sport,
+        pc.manufacturer,
+        pc.sets,
+        pc.sets_version,
+        pc.product_name,
+        pc.release_date,
+        pc.base_config,
+        pc.images_url,
+        pc.image_url,
+        pc.product_highlights,
+        pc.box_break,
+        pc.prop1,
+        pc.prop2,
+        pc.prop3,
+        pc.prop4,
+        pc.create_time,
+        pc.create_by,
+        pc.update_time,
+        pc.update_by,
+        pc.release_time
+        FROM
+        product_calendar pc
+        WHERE
+        pc.id = #{id}
+    </select>
+
+    <select id="getProductCalendarPricesByProductCalendarId" resultMap="ProductCalendarPriceResultMap">
+        SELECT
+        pcp.id,
+        pcp.product_calendar_id,
+        pcp.base_price,
+        pcp.suggested_price,
+        pcp.price_date,
+        pcp.price_resource,
+        pcp.create_time,
+        pcp.create_by,
+        pcp.update_time,
+        pcp.update_by,
+        pcp.currency_unit
+        FROM
+        product_calendar_price pcp
+        WHERE
+        pcp.product_calendar_id = #{id}
+        <if test="days != null">
+            AND pcp.price_date >= CURRENT_DATE - INTERVAL '1 days' * #{days}
+        </if>
+        order by pcp.price_date desc, pcp.id desc
+    </select>
+
+    <select id="getProductCalendarsList" resultMap="ProductCalendarResultMap">
+        SELECT
+            pc.id,
+            pc.product_name,
+            pc.release_time,
+            pc.image_url,
+            pcp.base_price,
+            pcp.suggested_price,
+            pcp.price_date
+        FROM
+            product_calendar pc
+        LEFT JOIN (
+            SELECT
+                product_calendar_id,
+                base_price,
+                suggested_price,
+                price_date,
+                ROW_NUMBER() OVER (
+                    PARTITION BY product_calendar_id
+                    ORDER BY price_date DESC
+                ) as rn
+            FROM
+                product_calendar_price
+        ) pcp ON pc.id = pcp.product_calendar_id AND pcp.rn = 1
+        <where>
+            <!-- 新增的条件 -->
+            <if test="releaseYear != null">
+                AND EXTRACT(YEAR FROM pc.release_time) = #{releaseYear}
+            </if>
+            <if test="releaseYear != null and releaseMonth != null">
+                AND EXTRACT(MONTH FROM pc.release_time) = #{releaseMonth}
+            </if>
+            <if test="sport != null and sport != ''">
+                AND LOWER(pc.sport) = LOWER(#{sport})
+            </if>
+            <if test="manufacturer != null and manufacturer != ''">
+                AND LOWER(pc.manufacturer) = LOWER(#{manufacturer})
+            </if>
+        </where>
+        ORDER BY
+            pc.release_time;
+    </select>
+
+    <select id="getProductCalendarCountByIds" resultType="java.lang.Integer">
+        SELECT COUNT(*)
+        FROM
+        product_calendar pc
+        <where>
+            <if test="releaseYear != null">
+                AND EXTRACT(YEAR FROM pc.release_time) = #{releaseYear}
+            </if>
+            <if test="releaseYear != null and releaseMonth != null">
+                AND EXTRACT(MONTH FROM pc.release_time) = #{releaseMonth}
+            </if>
+            <if test="sport != null and sport != ''">
+                AND LOWER(pc.sport) = LOWER(#{sport})
+            </if>
+            <if test="manufacturer != null and manufacturer != ''">
+                AND LOWER(pc.manufacturer) = LOWER(#{manufacturer})
+            </if>
+        </where>
+    </select>
+
+    <select id="getProductCalendarsByPageAndCondition" resultMap="ProductCalendarResultMap">
+        SELECT
+        subquery.id,
+        subquery.product_name,
+        subquery.release_time,
+        subquery.image_url,
+        subquery.base_price,
+        subquery.suggested_price,
+        subquery.price_date,
+        <!-- 新增字段 -->
+        subquery.currency_unit,
+        subquery.rn
+        FROM (
+        SELECT
+        pc.id,
+        pc.product_name,
+        pc.release_time,
+        pc.image_url,
+        pcp.base_price,
+        pcp.suggested_price,
+        pcp.price_date,
+        <!-- 新增字段 -->
+        pcp.currency_unit,
+        ROW_NUMBER() OVER (ORDER BY pc.release_time, pc.id) as rn
+        FROM
+        product_calendar pc
+        LEFT JOIN (
+        SELECT
+        product_calendar_id,
+        base_price,
+        suggested_price,
+        price_date,
+        <!-- 新增字段 -->
+        currency_unit,
+        ROW_NUMBER() OVER (
+        PARTITION BY product_calendar_id
+        ORDER BY price_date DESC
+        ) as rn
+        FROM
+        product_calendar_price
+        ) pcp ON pc.id = pcp.product_calendar_id AND pcp.rn = 1
+        <where>
+            <if test="releaseYear != null">
+                AND EXTRACT(YEAR FROM pc.release_time) = #{releaseYear}
+            </if>
+            <if test="releaseYear != null and releaseMonth != null">
+                AND EXTRACT(MONTH FROM pc.release_time) = #{releaseMonth}
+            </if>
+            <if test="sport != null and sport != ''">
+                AND LOWER(pc.sport) = LOWER(#{sport})
+            </if>
+            <if test="manufacturer != null and manufacturer != ''">
+                AND LOWER(pc.manufacturer) = LOWER(#{manufacturer})
+            </if>
+            <!-- 新增的模糊查询条件 -->
+            <if test="productName != null and productName != ''">
+                AND LOWER(pc.product_name) LIKE '%' || LOWER(#{productName}) || '%'
+            </if>
+        </where>
+        ) subquery
+        WHERE rn BETWEEN #{startRow} AND #{endRow};
+    </select>
+
+    <!-- 新增的查询方法 -->
+    <select id="getProductCalendarsByProductName" resultMap="ProductSimpleResultMap">
+        SELECT
+            pc.id,
+            pc.product_name,
+            pc.image_url
+        FROM
+            product_calendar pc
+        WHERE
+            LOWER(pc.product_name) LIKE '%' || LOWER(#{productName}) || '%'
+        LIMIT 10;
+    </select>
+
+</mapper>

+ 3 - 0
target/maven-archiver/pom.properties

@@ -0,0 +1,3 @@
+version=0.0.1-SNAPSHOT
+groupId=com.example
+artifactId=product-calendar

+ 11 - 0
target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst

@@ -0,0 +1,11 @@
+com\poyee\service\BlowoutRecordNewDailyNewService.class
+com\poyee\mapper\BlowoutDetailRecordMapper.class
+com\poyee\controller\TestController.class
+com\poyee\mapper\BlowoutRecordNewDailyNewMapper.class
+com\poyee\service\impl\BlowoutDetailRecordServiceImpl.class
+com\poyee\ProductCalendarApplication.class
+com\poyee\controller\BlowoutRecordController.class
+com\poyee\entity\BlowoutRecordNewDailyNew.class
+com\poyee\service\impl\BlowoutRecordNewDailyNewServiceImpl.class
+com\poyee\service\BlowoutDetailRecordService.class
+com\poyee\entity\BlowoutDetailRecord.class

+ 11 - 0
target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst

@@ -0,0 +1,11 @@
+C:\code\newcode\product-calendar\src\main\java\com\poyee\entity\BlowoutRecordNewDailyNew.java
+C:\code\newcode\product-calendar\src\main\java\com\poyee\service\BlowoutDetailRecordService.java
+C:\code\newcode\product-calendar\src\main\java\com\poyee\controller\BlowoutRecordController.java
+C:\code\newcode\product-calendar\src\main\java\com\poyee\entity\BlowoutDetailRecord.java
+C:\code\newcode\product-calendar\src\main\java\com\poyee\mapper\BlowoutRecordNewDailyNewMapper.java
+C:\code\newcode\product-calendar\src\main\java\com\poyee\ProductCalendarApplication.java
+C:\code\newcode\product-calendar\src\main\java\com\poyee\service\impl\BlowoutRecordNewDailyNewServiceImpl.java
+C:\code\newcode\product-calendar\src\main\java\com\poyee\service\impl\BlowoutDetailRecordServiceImpl.java
+C:\code\newcode\product-calendar\src\main\java\com\poyee\mapper\BlowoutDetailRecordMapper.java
+C:\code\newcode\product-calendar\src\main\java\com\poyee\service\BlowoutRecordNewDailyNewService.java
+C:\code\newcode\product-calendar\src\main\java\com\poyee\controller\TestController.java

+ 0 - 0
target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst


+ 0 - 0
target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst


BIN
target/product-calendar-0.0.1-SNAPSHOT.jar


BIN
target/product-calendar-0.0.1-SNAPSHOT.jar.original