Преглед изворни кода

生命周期sku级分析和数据总览后端接口

Zhu Jiaqi пре 4 месеци
родитељ
комит
233064d697

+ 9 - 0
.vscode/settings.json

@@ -0,0 +1,9 @@
+{
+    "python-envs.pythonProjects": [
+        {
+            "path": "",
+            "envManager": "ms-python.python:conda",
+            "packageManager": "ms-python.python:conda"
+        }
+    ]
+}

+ 5 - 0
dtm-admin/pom.xml

@@ -61,6 +61,11 @@
             <artifactId>dtm-generator</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 18 - 0
dtm-admin/src/main/java/com/dtm/web/controller/lifecycle/HotProdPredController.java

@@ -0,0 +1,18 @@
+package com.dtm.web.controller.lifecycle;
+
+import java.util.Map;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import com.dtm.common.core.domain.AjaxResult;
+
+@RestController
+@RequestMapping("/lifecycle/hotproduct")
+public class HotProdPredController 
+{
+    
+}

+ 96 - 0
dtm-admin/src/main/java/com/dtm/web/controller/statistics/LifecycleStatisticsController.java

@@ -0,0 +1,96 @@
+package com.dtm.web.controller.statistics;
+
+import java.util.Map;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import com.dtm.common.core.domain.AjaxResult;
+import com.dtm.statistics.service.ILifecycleStatisticsService;
+
+/**
+ * 生命周期统计分析控制器
+ * 
+ * @author dtm
+ */
+@RestController
+@RequestMapping("/statistics/lifecycle")
+public class LifecycleStatisticsController 
+{
+    @Autowired
+    private ILifecycleStatisticsService lifecycleStatisticsService;
+
+    /**
+     * 上传文件并分析
+     */
+    @PostMapping("/upload")
+    public AjaxResult uploadAndAnalyze(MultipartFile file)
+    {
+        if (file == null || file.isEmpty())
+        {
+            return AjaxResult.error("请选择要上传的文件");
+        }
+        
+        Map<String, Object> result = lifecycleStatisticsService.uploadAndAnalyze(file);
+        
+        Integer code = (Integer) result.get("code");
+        String msg = (String) result.get("msg");
+        Object data = result.get("data");
+        
+        if (code == 200)
+        {
+            return AjaxResult.success(msg, data);
+        }
+        else
+        {
+            return AjaxResult.error(msg);
+        }
+    }
+    
+    /**
+     * 获取生命周期分析总览
+     */
+    @GetMapping("/overview")
+    public AjaxResult getOverview(@RequestParam Map<String, Object> params)
+    {
+        Map<String, Object> result = lifecycleStatisticsService.getOverview(params);
+        
+        Integer code = (Integer) result.get("code");
+        String msg = (String) result.get("msg");
+        Object data = result.get("data");
+        
+        if (code == 200)
+        {
+            return AjaxResult.success(msg, data);
+        }
+        else
+        {
+            return AjaxResult.error(msg);
+        }
+    }
+    
+    /**
+     * 获取分析结果
+     */
+    @GetMapping("/results")
+    public AjaxResult getResults()
+    {
+        Map<String, Object> result = lifecycleStatisticsService.getResults();
+        
+        Integer code = (Integer) result.get("code");
+        String msg = (String) result.get("msg");
+        Object data = result.get("data");
+        
+        if (code == 200)
+        {
+            return AjaxResult.success(msg, data);
+        }
+        else
+        {
+            return AjaxResult.error(msg);
+        }
+    }
+}

+ 1 - 0
dtm-admin/src/main/java/com/dtm/web/controller/system/SysUserController.java

@@ -196,6 +196,7 @@ public class SysUserController extends BaseController
     {
         userService.checkUserAllowed(user);
         userService.checkUserDataScope(user.getUserId());
+        logger.info(user.toString());
         user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
         user.setUpdateBy(getUsername());
         return toAjax(userService.resetPwd(user));

+ 1 - 1
dtm-admin/src/main/resources/application-druid.yml

@@ -8,7 +8,7 @@ spring:
             master:
                 url: jdbc:mysql://140.143.100.189:3306/dtm?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                 username: root
-                password: 123456
+                password: dtm@1915116
             # 从库数据源
             slave:
                 # 从数据源开关/默认关闭

+ 8 - 2
dtm-admin/src/main/resources/application.yml

@@ -57,9 +57,9 @@ spring:
   servlet:
     multipart:
       # 单个文件大小
-      max-file-size: 10MB
+      max-file-size: 50MB
       # 设置总上传的文件大小
-      max-request-size: 20MB
+      max-request-size: 500MB
   # 服务模块
   devtools:
     restart:
@@ -134,3 +134,9 @@ xss:
   excludes: /system/notice
   # 匹配链接
   urlPatterns: /system/*,/monitor/*,/tool/*
+
+# Flask API配置
+flask:
+  api:
+    # Flask服务基础URL
+    base-url: http://localhost:8085

+ 5 - 0
dtm-common/pom.xml

@@ -119,6 +119,11 @@
             <artifactId>javax.servlet-api</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
     </dependencies>
 
 </project>

+ 189 - 0
dtm-common/src/main/java/com/dtm/common/utils/http/FlaskApiClient.java

@@ -0,0 +1,189 @@
+package com.dtm.common.utils.http;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.multipart.MultipartFile;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.dtm.common.utils.StringUtils;
+
+/**
+ * Flask API 客户端工具类
+ * 用于调用Flask后端API进行生命周期分析
+ * 
+ * @author dtm
+ */
+public class FlaskApiClient
+{
+    private static final Logger log = LoggerFactory.getLogger(FlaskApiClient.class);
+    
+    private static final String DEFAULT_FLASK_BASE_URL = "http://localhost:8085";
+    private static RestTemplate restTemplate = new RestTemplate();
+    
+    /**
+     * 获取Flask服务基础URL
+     */
+    private static String getFlaskBaseUrl()
+    {
+        // 优先从系统属性读取
+        String baseUrl = System.getProperty("flask.api.base.url");
+        if (StringUtils.isEmpty(baseUrl))
+        {
+            // 从环境变量读取
+            baseUrl = System.getenv("FLASK_API_BASE_URL");
+        }
+        if (StringUtils.isEmpty(baseUrl))
+        {
+            // 使用默认值
+            baseUrl = DEFAULT_FLASK_BASE_URL;
+        }
+        return baseUrl;
+    }
+    
+    /**
+     * 上传文件到Flask服务
+     * 
+     * @param file 上传的文件
+     * @return 响应结果
+     */
+    public static JSONObject uploadFile(MultipartFile file) throws Exception
+    {
+        String url = getFlaskBaseUrl() + "/api/upload";
+        
+        try
+        {
+            // 将MultipartFile转换为临时文件
+            File tempFile = convertMultipartFileToFile(file);
+            
+            try
+            {
+                // 创建请求体
+                MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
+                FileSystemResource resource = new FileSystemResource(tempFile);
+                body.add("file", resource);
+                
+                // 设置请求头
+                HttpHeaders headers = new HttpHeaders();
+                headers.setContentType(MediaType.MULTIPART_FORM_DATA);
+                
+                HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
+                
+                // 发送请求
+                log.info("调用Flask API上传文件: {}", url);
+                ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
+                
+                // 解析响应
+                JSONObject result = JSON.parseObject(response.getBody());
+                log.info("Flask API上传文件响应: {}", result);
+                
+                return result;
+            }
+            finally
+            {
+                // 删除临时文件
+                if (tempFile.exists())
+                {
+                    tempFile.delete();
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            log.error("调用Flask API上传文件失败: {}", e.getMessage(), e);
+            throw new Exception("上传文件到Flask服务失败: " + e.getMessage(), e);
+        }
+    }
+    
+    /**
+     * 分析文件
+     * 
+     * @return 分析结果
+     */
+    public static JSONObject analyzeFile() throws Exception
+    {
+        String url = getFlaskBaseUrl() + "/api/analyze";
+        
+        try
+        {
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            HttpEntity<String> requestEntity = new HttpEntity<>(headers);
+            
+            log.info("调用Flask API分析文件: {}", url);
+            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
+            
+            JSONObject result = JSON.parseObject(response.getBody());
+            log.info("Flask API分析文件响应: {}", result);
+            
+            return result;
+        }
+        catch (Exception e)
+        {
+            log.error("调用Flask API分析文件失败: {}", e.getMessage(), e);
+            throw new Exception("分析文件失败: " + e.getMessage(), e);
+        }
+    }
+    
+    /**
+     * 获取分析结果
+     * 
+     * @return 分析结果
+     */
+    public static JSONObject getResults() throws Exception
+    {
+        String url = getFlaskBaseUrl() + "/api/results";
+        
+        try
+        {
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            HttpEntity<String> requestEntity = new HttpEntity<>(headers);
+            
+            log.info("调用Flask API获取结果: {}", url);
+            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
+            
+            JSONObject result = JSON.parseObject(response.getBody());
+            log.info("Flask API获取结果响应: {}", result);
+            
+            return result;
+        }
+        catch (Exception e)
+        {
+            log.error("调用Flask API获取结果失败: {}", e.getMessage(), e);
+            throw new Exception("获取分析结果失败: " + e.getMessage(), e);
+        }
+    }
+    
+    /**
+     * 将MultipartFile转换为File
+     */
+    private static File convertMultipartFileToFile(MultipartFile multipartFile) throws IOException
+    {
+        File file = File.createTempFile("upload_", "_" + multipartFile.getOriginalFilename());
+        try (FileOutputStream fos = new FileOutputStream(file);
+             InputStream is = multipartFile.getInputStream())
+        {
+            byte[] buffer = new byte[1024];
+            int bytesRead;
+            while ((bytesRead = is.read(buffer)) != -1)
+            {
+                fos.write(buffer, 0, bytesRead);
+            }
+        }
+        return file;
+    }
+}
+

+ 5 - 0
dtm-system/pom.xml

@@ -23,6 +23,11 @@
             <artifactId>dtm-common</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+        </dependency>
+
     </dependencies>
 
 </project>

+ 30 - 0
dtm-system/src/main/java/com/dtm/statistics/service/ILifecycleStatisticsService.java

@@ -0,0 +1,30 @@
+package com.dtm.statistics.service;
+
+import java.util.Map;
+import org.springframework.web.multipart.MultipartFile;
+
+public interface ILifecycleStatisticsService 
+{
+    /**
+     * 上传文件并分析
+     * 
+     * @param file 上传的文件
+     * @return 上传结果
+     */
+    Map<String, Object> uploadAndAnalyze(MultipartFile file);
+    
+    /**
+     * 获取生命周期分析总览
+     * 
+     * @param params 查询参数
+     * @return 总览数据
+     */
+    Map<String, Object> getOverview(Map<String, Object> params);
+    
+    /**
+     * 获取分析结果
+     * 
+     * @return 分析结果
+     */
+    Map<String, Object> getResults();
+}

+ 136 - 0
dtm-system/src/main/java/com/dtm/statistics/service/impl/LifecycleStatisticsService.java

@@ -0,0 +1,136 @@
+package com.dtm.statistics.service.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.dtm.common.utils.StringUtils;
+import com.dtm.common.utils.http.FlaskApiClient;
+import com.dtm.statistics.service.ILifecycleStatisticsService;
+
+/**
+ * 生命周期统计分析服务实现类
+ * 
+ * @author dtm
+ */
+@Service
+public class LifecycleStatisticsService implements ILifecycleStatisticsService 
+{
+    private static final Logger log = LoggerFactory.getLogger(LifecycleStatisticsService.class);
+    
+    @Override
+    public Map<String, Object> uploadAndAnalyze(MultipartFile file)
+    {
+        Map<String, Object> result = new HashMap<>();
+        
+        try
+        {
+            // 1. 上传文件到Flask服务
+            log.info("开始上传文件到Flask服务: {}", file.getOriginalFilename());
+            JSONObject uploadResult = FlaskApiClient.uploadFile(file);
+            
+            if (!uploadResult.getBooleanValue("success"))
+            {
+                result.put("code", 500);
+                result.put("msg", uploadResult.getString("message"));
+                return result;
+            }
+            
+            // 2. 调用Flask服务进行分析
+            log.info("开始调用Flask服务进行分析");
+            JSONObject analyzeResult = FlaskApiClient.analyzeFile();
+            
+            if (!analyzeResult.getBooleanValue("success"))
+            {
+                result.put("code", 500);
+                result.put("msg", analyzeResult.getString("message"));
+                return result;
+            }
+            
+            // 3. 获取分析结果(Flask返回的data字段直接包含所有SKU的分析结果)
+            Object data = analyzeResult.get("data");
+            result.put("code", 200);
+            result.put("msg", "分析完成");
+            // 直接返回data,因为Flask返回的data已经是一个Map<String, Object>格式
+            result.put("data", data);
+            
+            log.info("生命周期分析完成");
+        }
+        catch (Exception e)
+        {
+            log.error("生命周期分析失败", e);
+            result.put("code", 500);
+            result.put("msg", "分析失败: " + e.getMessage());
+        }
+        
+        return result;
+    }
+    
+    @Override
+    public Map<String, Object> getOverview(Map<String, Object> params)
+    {
+        Map<String, Object> result = new HashMap<>();
+        
+        try
+        {
+            // 获取分析结果
+            JSONObject flaskResult = FlaskApiClient.getResults();
+            
+            if (!flaskResult.getBooleanValue("success"))
+            {
+                result.put("code", 500);
+                result.put("msg", flaskResult.getString("message"));
+                return result;
+            }
+            
+            // 提取数据
+            Object data = flaskResult.get("data");
+            result.put("code", 200);
+            result.put("msg", "获取成功");
+            result.put("data", data);
+        }
+        catch (Exception e)
+        {
+            log.error("获取生命周期分析总览失败", e);
+            result.put("code", 500);
+            result.put("msg", "获取失败: " + e.getMessage());
+        }
+        
+        return result;
+    }
+    
+    @Override
+    public Map<String, Object> getResults()
+    {
+        Map<String, Object> result = new HashMap<>();
+        
+        try
+        {
+            JSONObject flaskResult = FlaskApiClient.getResults();
+            
+            if (!flaskResult.getBooleanValue("success"))
+            {
+                result.put("code", 500);
+                result.put("msg", flaskResult.getString("message"));
+                return result;
+            }
+            
+            Object data = flaskResult.get("data");
+            result.put("code", 200);
+            result.put("msg", "获取成功");
+            result.put("data", data);
+        }
+        catch (Exception e)
+        {
+            log.error("获取分析结果失败", e);
+            result.put("code", 500);
+            result.put("msg", "获取失败: " + e.getMessage());
+        }
+        
+        return result;
+    }
+}

+ 5 - 0
pom.xml

@@ -243,6 +243,11 @@
                     <encoding>${project.build.sourceEncoding}</encoding>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring-boot.version}</version>
+            </plugin>
         </plugins>
     </build>
 



+ 0 - 1
text.txt

@@ -1 +0,0 @@
-测试