cxd hai 4 meses
pai
achega
e2fe3897da

+ 20 - 0
gqy-admin/src/main/java/com/gqy/web/controller/document/DesigerController.java

@@ -0,0 +1,20 @@
+package com.gqy.web.controller.document;
+
+import com.gqy.common.core.controller.BaseController;
+import com.gqy.common.core.domain.AjaxResultCQY;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+
+@RestController
+@RequestMapping("/desiger")
+public class DesigerController extends BaseController {
+
+    @RequestMapping("/add")
+    public AjaxResultCQY add(@RequestBody Map map){
+        return  AjaxResultCQY.success();
+    }
+}

+ 463 - 0
gqy-common/src/main/java/com/gqy/common/utils/hanlp/Word2VecWordSimilarity.java

@@ -0,0 +1,463 @@
+package com.gqy.common.utils.hanlp;
+
+import javafx.util.Pair;
+import org.deeplearning4j.models.word2vec.Word2Vec;
+import org.deeplearning4j.models.word2vec.VocabWord;
+import org.deeplearning4j.models.word2vec.wordstore.inmemory.AbstractCache;
+import org.deeplearning4j.models.word2vec.wordstore.VocabCache;
+import org.nd4j.linalg.api.ndarray.INDArray;
+import org.nd4j.linalg.factory.Nd4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.hankcs.hanlp.HanLP;
+import com.hankcs.hanlp.seg.common.Term;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ThreadFactory;
+
+/**
+ * Word2Vec 词语相似度计算工具类
+ */
+public class Word2VecWordSimilarity {
+    private static final Logger log = LoggerFactory.getLogger(Word2VecWordSimilarity.class);
+    private static Word2Vec vec;
+    private static final String FASTTEXT_PATH = "D:\\word2\\wiki.zh.vec"; // 修改为你的实际路径
+
+    // 添加静态Map来存储词向量
+    static Map<String, INDArray> wordVectorsMap = new HashMap<>();
+
+    static {
+        try {
+            initializeModel();
+        } catch (Exception e) {
+            log.error("FastText模型初始化失败", e);
+            throw new RuntimeException("FastText模型初始化失败", e);
+        }
+    }
+
+    /**
+     * 初始化FastText模型
+     */
+    private static void initializeModel() throws IOException {
+        log.info("开始加载FastText模型...");
+        File vectorFile = new File(FASTTEXT_PATH);
+        if (!vectorFile.exists()) {
+            throw new FileNotFoundException("FastText向量文件不存在: " + FASTTEXT_PATH);
+        }
+
+        try (BufferedReader reader = new BufferedReader(new FileReader(vectorFile), 8 * 1024 * 1024)) {
+            log.info("成功打开文件,开始读取...");
+
+            // 读取第一行获取维度信息
+            String firstLine = reader.readLine();
+            String[] dims = firstLine.split(" ");
+            int vocabSize = Integer.parseInt(dims[0]);
+            int vectorSize = Integer.parseInt(dims[1]);
+            log.info("词汇量: {}, 向量维度: {}", vocabSize, vectorSize);
+
+            // 预分配容量
+            wordVectorsMap = new ConcurrentHashMap<>(vocabSize);
+
+            // 读取所有行到内存
+            log.info("开始读取词向量...");
+            String line;
+            int lineCount = 0;
+            int successCount = 0;
+
+            while ((line = reader.readLine()) != null) {
+                lineCount++;
+                try {
+                    String[] tokens = line.trim().split("\\s+");
+                    if (tokens.length != vectorSize + 1) {
+                        continue;
+                    }
+
+                    float[] vector = new float[vectorSize];
+                    for (int j = 0; j < vectorSize; j++) {
+                        vector[j] = Float.parseFloat(tokens[j + 1]);
+                    }
+                    wordVectorsMap.put(tokens[0], Nd4j.create(vector));
+                    successCount++;
+
+                    if (lineCount % 10000 == 0) {
+                        log.info("已处理 {} 行,成功加载 {} 个词向量", lineCount, successCount);
+                    }
+                } catch (Exception e) {
+                    log.warn("处理第 {} 行时发生错误: {}", lineCount, e.getMessage());
+                }
+            }
+
+            log.info("FastText模型加载完成,总行数: {},成功加载词向量: {}", lineCount, successCount);
+
+            // 创建Word2Vec实例
+            vec = new Word2Vec.Builder()
+                    .layerSize(vectorSize)
+                    .minWordFrequency(1)
+                    .iterations(1)
+                    .epochs(1)
+                    .learningRate(0.025)
+                    .windowSize(5)
+                    .build();
+
+            // 设置词汇表
+            VocabCache<VocabWord> vocabCache = new AbstractCache<>();
+            for (String word : wordVectorsMap.keySet()) {
+                VocabWord vocabWord = new VocabWord(1.0, word);
+                vocabCache.addToken(vocabWord);
+                vocabCache.addWordToIndex(vocabCache.numWords(), word);
+            }
+            vec.setVocab(vocabCache);
+
+        } catch (Exception e) {
+            log.error("加载FastText模型失败", e);
+            throw new RuntimeException("加载FastText模型失败", e);
+        }
+    }
+
+    /**
+     * 计算两个词的相似度
+     */
+    public static double calculateSimilarity(String text1, String text2) {
+        try {
+            log.info("开始计算文本相似度: '{}' vs '{}'", text1, text2);
+
+            // 对输入文本进行分词,并过滤掉标点符号和停用词
+            List<Term> terms1 = HanLP.segment(text1).stream()
+                    .filter(term -> !term.nature.startsWith("w")  // 过滤标点符号
+                            && !isStopWord(term.word))           // 过滤停用词
+                    .collect(Collectors.toList());
+
+            List<Term> terms2 = HanLP.segment(text2).stream()
+                    .filter(term -> !term.nature.startsWith("w")
+                            && !isStopWord(term.word))
+                    .collect(Collectors.toList());
+
+            log.info("分词结果(过滤后): text1={}, text2={}", terms1, terms2);
+
+            // 获取所有词的向量并计算加权平均值
+            INDArray vector1 = getWeightedAverageVector(terms1);
+            INDArray vector2 = getWeightedAverageVector(terms2);
+
+            if (vector1 == null || vector2 == null) {
+                log.warn("无法为文本生成有效的向量表示: text1={}, text2={}",
+                        vector1 == null ? "null" : "valid",
+                        vector2 == null ? "null" : "valid");
+                return 0.0;
+            }
+
+            // 计算余弦相似度
+            double similarity = calculateCosineSimilarity(vector1, vector2);
+
+            // 应用长度惩罚因子
+            double lengthPenalty = calculateLengthPenalty(terms1.size(), terms2.size());
+            similarity *= lengthPenalty;
+
+            log.info("最终相似度计算完成: rawSimilarity={}, lengthPenalty={}, finalSimilarity={}",
+                    similarity/lengthPenalty, lengthPenalty, similarity);
+            return similarity;
+        } catch (Exception e) {
+            log.error("计算文本相似度失败: {} vs {}", text1, text2, e);
+            return 0.0;
+        }
+    }
+
+    private static boolean isStopWord(String word) {
+        // 扩展停用词表
+        Set<String> stopWords = new HashSet<>(Arrays.asList(
+            "的", "了", "和", "是", "就", "都", "而", "及", "与", "着",
+            "之", "用", "其", "中", "你", "我", "他", "她", "它", "要",
+            "把", "被", "让", "在", "有", "个", "好", "这", "那", "什么",
+            "啊", "哦", "呢", "吧", "啦", "么", "呀", "嘛", "哪", "那么",
+            "这么", "怎么", "为", "以", "到", "得", "着", "过", "很", "对",
+            "真", "的话", "所以", "因为", "但是", "不过", "可以", "现在"
+        ));
+        return stopWords.contains(word);
+    }
+
+    private static INDArray getWeightedAverageVector(List<Term> terms) {
+        try {
+            log.debug("开始计算加权平均向量,输入词项数: {}", terms.size());
+            List<Pair<INDArray, Double>> vectorsWithWeights = new ArrayList<>();
+            double totalWeight = 0.0;
+
+            for (Term term : terms) {
+                String word = term.word;
+                INDArray vector = wordVectorsMap.get(word);
+                if (vector != null) {
+                    // 根据词性赋予不同权重
+                    double weight = getTermWeight(term);
+                    vectorsWithWeights.add(new Pair<>(vector, weight));
+                    totalWeight += weight;
+                    log.debug("找到词 '{}' 的向量,权重: {}", word, weight);
+                } else {
+                    log.debug("词 '{}' 不在词向量表中", word);
+                }
+            }
+
+            if (vectorsWithWeights.isEmpty()) {
+                log.warn("没有找到任何有效的词向量,输入词项: {}", terms);
+                return null;
+            }
+
+            // 计算加权平均
+            INDArray weightedSum = Nd4j.zeros(vectorsWithWeights.get(0).getKey().shape());
+            for (Pair<INDArray, Double> pair : vectorsWithWeights) {
+                weightedSum.addi(pair.getKey().mul(pair.getValue()));
+            }
+            return weightedSum.divi(totalWeight);
+        } catch (Exception e) {
+            log.error("计算加权平均向量失败,输入词项: {}", terms, e);
+            return null;
+        }
+    }
+
+    private static double getTermWeight(Term term) {
+        // 根据词性赋予权重
+        switch (term.nature.toString()) {
+            case "n":   // 名词
+            case "v":   // 动词
+            case "a":   // 形容词
+                return 1.0;
+            case "t":   // 时间词
+            case "s":   // 处所词
+                return 0.8;
+            case "f":   // 方位词
+            case "b":   // 区别词
+                return 0.6;
+            default:
+                return 0.4;
+        }
+    }
+
+    private static double calculateCosineSimilarity(INDArray vector1, INDArray vector2) {
+        double dotProduct = vector1.mul(vector2).sumNumber().doubleValue();
+        double norm1 = vector1.norm2Number().doubleValue();
+        double norm2 = vector2.norm2Number().doubleValue();
+        return dotProduct / (norm1 * norm2);
+    }
+
+    private static double calculateLengthPenalty(int len1, int len2) {
+        // 加强长度差异惩罚
+        double ratio = Math.min(len1, len2) / (double) Math.max(len1, len2);
+        return Math.pow(ratio, 1.2);  // 进一步增加惩罚力度
+    }
+
+    /**
+     * 判断两个词是否相似
+     */
+    public static boolean areWordsSimilar(String word1, String word2, double threshold) {
+        try {
+            log.info("开始判断词语相似性: word1='{}', word2='{}', threshold={}", word1, word2, threshold);
+
+            if (word1 == null || word2 == null) {
+                log.warn("输入词语为null: word1={}, word2={}", word1, word2);
+                return false;
+            }
+
+            if (word1.equals(word2)) {
+                log.info("词语完全相同,直接返回true");
+                return true;
+            }
+
+            // 预处理:去除标点符号
+            word1 = word1.replaceAll("[\\p{P}\\p{S}]", "");
+            word2 = word2.replaceAll("[\\p{P}\\p{S}]", "");
+
+            if (word1.isEmpty() || word2.isEmpty()) {
+                log.warn("清理标点符号后文本为空: word1='{}', word2='{}'", word1, word2);
+                return false;
+            }
+
+            // 获取词性
+            List<Term> terms1 = HanLP.segment(word1);
+            List<Term> terms2 = HanLP.segment(word2);
+
+            // 提取主要词性(名词、动词、形容词)
+            Set<String> mainNatures1 = terms1.stream()
+                    .map(t -> t.nature.toString())
+                    .filter(n -> n.startsWith("n") || n.startsWith("v") || n.startsWith("a"))
+                    .collect(Collectors.toSet());
+            Set<String> mainNatures2 = terms2.stream()
+                    .map(t -> t.nature.toString())
+                    .filter(n -> n.startsWith("n") || n.startsWith("v") || n.startsWith("a"))
+                    .collect(Collectors.toSet());
+
+            // 计算主要词性的交集
+            Set<String> commonNatures = new HashSet<>(mainNatures1);
+            commonNatures.retainAll(mainNatures2);
+
+            // 如果主要词性完全不同,直接返回false
+            if (commonNatures.isEmpty() && !mainNatures1.isEmpty() && !mainNatures2.isEmpty()) {
+                log.info("主要词性完全不同: natures1={}, natures2={}", mainNatures1, mainNatures2);
+                return false;
+            }
+
+            double similarity = calculateSimilarity(word1, word2);
+
+            // 根据词性和长度差异动态调整阈值
+            double adjustedThreshold = threshold;
+
+            // 如果词性差异大,提高阈值
+            if (commonNatures.size() < Math.min(mainNatures1.size(), mainNatures2.size())) {
+                adjustedThreshold *= 1.3;
+            }
+
+            // 如果长度差异大,提高阈值
+            int lenDiff = Math.abs(terms1.size() - terms2.size());
+            if (lenDiff > 2) {
+                adjustedThreshold *= (1.0 + lenDiff * 0.1);
+            }
+
+            boolean isSimilar = similarity >= adjustedThreshold;
+
+            log.info("相似度判断完成: rawSimilarity={}, adjustedThreshold={}, isSimilar={}, " +
+                    "mainNatures1={}, mainNatures2={}, commonNatures={}",
+                    similarity, adjustedThreshold, isSimilar,
+                    mainNatures1, mainNatures2, commonNatures);
+
+            return isSimilar;
+        } catch (Exception e) {
+            log.error("判断词语相似性失败: {} vs {}", word1, word2, e);
+            return false;
+        }
+    }
+
+    /**
+     * 获取与给定词最相似的N个词
+     */
+    public static Collection<String> findSimilarWords(String text, int n) {
+        try {
+            log.info("开始查找与文本 '{}' 相似的 {} 个词", text, n);
+
+            List<Term> terms = HanLP.segment(text);
+            log.info("分词结果: {}", terms);
+
+            INDArray queryVector = getWeightedAverageVector(terms);
+            if (queryVector == null) {
+                log.warn("无法为文本 '{}' 生成有效的向量表示", text);
+                return Collections.emptyList();
+            }
+            log.info("成功生成查询向量");
+
+            // 使用并行流和ConcurrentHashMap来加速计算
+            log.info("开始并行计算相似度...");
+            ConcurrentHashMap<String, Double> similarities = new ConcurrentHashMap<>(wordVectorsMap.size());
+            AtomicInteger processedCount = new AtomicInteger(0);
+
+            // 将词向量分批处理
+            int batchSize = 1000;
+            List<List<Map.Entry<String, INDArray>>> batches = new ArrayList<>();
+            List<Map.Entry<String, INDArray>> currentBatch = new ArrayList<>();
+
+            for (Map.Entry<String, INDArray> entry : wordVectorsMap.entrySet()) {
+                currentBatch.add(entry);
+                if (currentBatch.size() == batchSize) {
+                    batches.add(new ArrayList<>(currentBatch));
+                    currentBatch.clear();
+                }
+            }
+            if (!currentBatch.isEmpty()) {
+                batches.add(currentBatch);
+            }
+
+            // 并行处理每个批次
+            batches.parallelStream().forEach(batch -> {
+                for (Map.Entry<String, INDArray> entry : batch) {
+                    String word = entry.getKey();
+                    INDArray vector = entry.getValue();
+
+                    // 批量计算相似度
+                    double similarity = queryVector.mul(vector).sumNumber().doubleValue() /
+                            (queryVector.norm2Number().doubleValue() * vector.norm2Number().doubleValue());
+                    similarities.put(word, similarity);
+
+                    int count = processedCount.incrementAndGet();
+                    if (count % 10000 == 0) {
+                        log.info("已处理 {} / {} 个词向量", count, wordVectorsMap.size());
+                    }
+                }
+            });
+
+            log.info("相似度计算完成,开始排序...");
+
+            // 使用优先队列来获取top N,避免全量排序
+            PriorityQueue<Map.Entry<String, Double>> topN = new PriorityQueue<>(
+                n + 1, Map.Entry.<String, Double>comparingByValue()
+            );
+
+            for (Map.Entry<String, Double> entry : similarities.entrySet()) {
+                topN.offer(entry);
+                if (topN.size() > n) {
+                    topN.poll();
+                }
+            }
+
+            // 转换结果
+            List<String> result = new ArrayList<>(n);
+            while (!topN.isEmpty()) {
+                result.add(0, topN.poll().getKey());
+            }
+
+            log.info("找到 {} 个相似词: {}", result.size(), result);
+            return result;
+        } catch (Exception e) {
+            log.error("查找相似词失败: {}", text, e);
+            return Collections.emptyList();
+        }
+    }
+
+    /**
+     * 检查词是否在词汇表中
+     */
+    public static boolean hasWord(String word) {
+        return vec.hasWord(word);
+    }
+
+    /**
+     * 获取词向量
+     */
+    public static double[] getWordVector(String word) {
+        try {
+            return vec.getWordVector(word);
+        } catch (Exception e) {
+            log.error("获取词向量失败: {}", word, e);
+            return null;
+        }
+    }
+
+    // 使用示例
+    public static void main(String[] args) {
+        try {
+            // 计算相似度
+            String word1 = "你要选择什么产品名称?";
+            String word2 = "产品代码";
+          //  double similarity = calculateSimilarity(word1, word2);
+            //System.out.println("相似度: " + similarity);
+
+            // 查找相似词
+//            Collection<String> similarWords = findSimilarWords(word1, 5);
+//            System.out.println("相似词: " + similarWords);
+
+            // 判断是否相似
+            for(int i=0;i<=10;i++){
+                boolean isSimilar = areWordsSimilar(word1, word2, 0.7);
+                System.out.println("是否相似: " + isSimilar);
+            }
+
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 139 - 63
gqy-system/src/main/java/com/gqy/document/service/impl/DcProductServiceImpl.java

@@ -7,9 +7,13 @@ import com.gqy.common.utils.bean.BeanUtils;
 import com.gqy.document.domain.*;
 import com.gqy.document.mapper.*;
 import com.gqy.document.service.IDcProductService;
+import com.gqy.document.service.IDocumentCategoryService;
 import com.gqy.system.mapper.DcPsParamMapper;
 import org.apache.commons.compress.utils.Lists;
 import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
@@ -26,6 +30,9 @@ import java.util.stream.Collectors;
 @Service
 public class DcProductServiceImpl implements IDcProductService {
 
+    private static final Logger log = LoggerFactory.getLogger(DcProductServiceImpl.class);
+
+
     @Autowired
     private DcProductMapper dcProductMapper;
 
@@ -404,78 +411,147 @@ public class DcProductServiceImpl implements IDcProductService {
     }
 
     private int processAndSaveProduct(String context) {
-        // 解析JSON
-        Map mapResult = CustomJsonParser.getParam(context);
-
-        // 获取系统信息
-        String sys_name = mapResult.get("sys_name").toString();
-        // 查询系统信息
-       // DcSystem dcSystem = dcSystemMapper.selectDcSystemByName(sys_name);
-        DcSystem dcSystem = dcSystemMapper.selectDcSystemBySysNo(sys_name);
-        mapResult.put("sys_no", dcSystem.getSysId());
-        // 获取工程信息
-        String wk_name = mapResult.get("wk_name").toString();
-        DcWork  dcWork = workMapper.selectWorkByName(wk_name);
-        mapResult.put("wr_id", dcWork.getWkId());
-
-//        workMapper.selectWorkByName()
-
-//        DcWorkSystem dcWorkSystemQuery = new DcWorkSystem();
-//        dcWorkSystemQuery.setSys_id(dcSystem.getSysId().intValue());
-//        List<DcWorkSystem> dcWorkSystemList = dcWorkSystemMapper.selectDcWorkSystemList(dcWorkSystemQuery);
-//        if(!CollectionUtils.isEmpty(dcWorkSystemList)){
-//            DcWorkSystem dcWorkSystem = dcWorkSystemList.get(0);
-//            mapResult.put("wr_id", dcWorkSystem.getWr_id());
-//
-//        }
-        // 查询规格参数
-        DcPsParam queryDcPsParam = new DcPsParam();
-        List<DcPsParam> listDcPsParam = dcPsParamMapper.selectDcPsParamList(queryDcPsParam);
+        log.info("开始处理产品导入数据...");
+        int totalLines = 0;
+        int successCount = 0;
+        int failCount = 0;
 
-        // 保存产品基本信息
-        int dcpId = getDcpIdAdd(mapResult);
-
-        // 处理规格信息
-        List<Map> specs = new ArrayList<>();
-        for (DcPsParam dcPsParam : listDcPsParam) {
-            if (ObjectUtils.isNotEmpty(mapResult.get(dcPsParam.getPsp_mode()))) {
-                Map maps = new HashMap();
-                maps.put("ps_no", dcPsParam.getPsp_mode());
-                maps.put("psp_name", dcPsParam.getPsp_name());
-                maps.put("ps_name", mapResult.get(dcPsParam.getPsp_mode()));
-                maps.put("psp_type",dcPsParam.getPsp_type());
-                specs.add(maps);
-            }
-        }
-        mapResult.put("specs", specs);
+        try {
+            // 按行分割内容
+            String[] lines = context.split("\n");
+            totalLines = lines.length;
+            log.info("共读取到 {} 行数据", totalLines);
+
+            for (String line : lines) {
+                if (StringUtils.isBlank(line)) {
+                    log.warn("跳过空行数据");
+                    continue;
+                }
 
-        // 保存产品信息
-        extractedAdd(specs, dcpId);
+                try {
+                    log.info("开始处理第 {} 行数据: {}", successCount + failCount + 1, line);
+
+                    // 解析JSON数据
+                    log.debug("正在解析JSON数据...");
+                    Map mapResult = CustomJsonParser.getParam(line);
+                    log.debug("JSON解析结果: {}", mapResult);
+
+                    // 获取系统信息
+                    String sys_name = mapResult.get("sys_name").toString();
+                    log.debug("获取系统信息, 系统名称: {}", sys_name);
+                    DcSystem dcSystem = dcSystemMapper.selectDcSystemBySysNo(sys_name);
+                    if (dcSystem == null) {
+                        log.error("未找到对应的系统信息: {}", sys_name);
+                        throw new RuntimeException("系统信息不存在");
+                    }
+                    mapResult.put("sys_no", dcSystem.getSysId());
+                    log.debug("系统信息获取成功, 系统ID: {}", dcSystem.getSysId());
+
+                    // 获取工程信息
+                    String wk_name = mapResult.get("wk_name").toString();
+                    log.debug("获取工程信息, 工程名称: {}", wk_name);
+                    DcWork dcWork = workMapper.selectWorkByName(wk_name);
+                    if (dcWork == null) {
+                        log.error("未找到对应的工程信息: {}", wk_name);
+                        throw new RuntimeException("工程信息不存在");
+                    }
+                    mapResult.put("wr_id", dcWork.getWkId());
+                    log.debug("工程信息获取成功, 工程ID: {}", dcWork.getWkId());
+
+                    // 查询规格参数
+                    log.debug("开始查询规格参数...");
+                    DcPsParam queryDcPsParam = new DcPsParam();
+                    List<DcPsParam> listDcPsParam = dcPsParamMapper.selectDcPsParamList(queryDcPsParam);
+                    log.debug("查询到 {} 个规格参数", listDcPsParam.size());
+
+                    // 保存产品基本信息
+                    log.info("开始保存产品基本信息...");
+                    int dcpId = getDcpIdAdd(mapResult);
+                    log.info("产品基本信息保存成功, 产品ID: {}", dcpId);
+
+                    // 处理规格信息
+                    log.debug("开始处理规格信息...");
+                    List<Map> specs = new ArrayList<>();
+                    for (DcPsParam dcPsParam : listDcPsParam) {
+                        if (ObjectUtils.isNotEmpty(mapResult.get(dcPsParam.getPsp_mode()))) {
+                            Map maps = new HashMap();
+                            maps.put("ps_no", dcPsParam.getPsp_mode());
+                            maps.put("psp_name", dcPsParam.getPsp_name());
+                            maps.put("ps_name", mapResult.get(dcPsParam.getPsp_mode()));
+                            maps.put("psp_type", dcPsParam.getPsp_type());
+                            specs.add(maps);
+                            log.debug("添加规格信息: {}", maps);
+                        }
+                    }
+                    mapResult.put("specs", specs);
+                    log.debug("规格信息处理完成, 共 {} 个规格", specs.size());
 
+                    // 保存产品规格信息
+                    log.info("开始保存产品规格信息...");
+                    extractedAdd(specs, dcpId);
+                    log.info("产品规格信息保存成功");
 
-        // 创建新的规格列表用于JSON序列化
-        List<Map<String, String>> newSpecs = new ArrayList<>();
+                    // 更新产品规格JSON
+                    log.debug("开始更新产品规格JSON...");
+                    updateProductSpecsJson(specs, dcpId);
+                    log.info("产品规格JSON更新成功");
 
-        // 遍历specs并构建新的JSON格式
-        for (Map spec : specs) {
-            Map<String, String> newSpec = new HashMap<>();
-            newSpec.put("ps_no", String.valueOf(spec.get("ps_no")));
-            newSpec.put("psp_name", String.valueOf(spec.get("psp_name")));
-            newSpec.put("psp_type", String.valueOf(spec.get("psp_type")));
-            newSpec.put("ps_name", String.valueOf(spec.get("ps_name")));
-            newSpecs.add(newSpec);
-        }
+                    successCount++;
+                    log.info("第 {} 行数据处理成功", successCount + failCount);
 
-        // 将新的规格列表转换为JSON字符串
-        String specsJson = JSON.toJSONString(newSpecs);
+                } catch (Exception e) {
+                    failCount++;
+                    log.error("处理第 {} 行数据失败: {}", successCount + failCount, line, e);
+                }
+            }
 
-        // 更新产品基本信息
-        DcProduct dcProduct = dcProductMapper.selectDcProductById(new Long(dcpId));
-        dcProduct.setDcp_p_no(specsJson);
-        dcProductMapper.updateDcProduct(dcProduct);
+            // 处理完成,输出统计信息
+            log.info("数据处理完成 ======================");
+            log.info("总行数: {}", totalLines);
+            log.info("成功处理: {}", successCount);
+            log.info("处理失败: {}", failCount);
+            
+            return successCount > 0 ? 1 : 0;
 
-        return 1;
+        } catch (Exception e) {
+            log.error("处理产品导入数据时发生异常", e);
+            return 0;
+        }
     }
 
+    /**
+     * 更新产品规格JSON
+     */
+    private void updateProductSpecsJson(List<Map> specs, int dcpId) {
+        try {
+            log.debug("开始构建规格JSON数据...");
+            List<Map<String, String>> newSpecs = new ArrayList<>();
+            
+            for (Map spec : specs) {
+                Map<String, String> newSpec = new HashMap<>();
+                newSpec.put("ps_no", String.valueOf(spec.get("ps_no")));
+                newSpec.put("psp_name", String.valueOf(spec.get("psp_name")));
+                newSpec.put("psp_type", String.valueOf(spec.get("psp_type")));
+                newSpec.put("ps_name", String.valueOf(spec.get("ps_name")));
+                newSpecs.add(newSpec);
+                log.debug("添加规格JSON: {}", newSpec);
+            }
+            
+            String specsJson = JSON.toJSONString(newSpecs);
+            log.debug("规格JSON生成完成: {}", specsJson);
+            
+            DcProduct dcProduct = dcProductMapper.selectDcProductById(new Long(dcpId));
+            if (dcProduct != null) {
+                dcProduct.setDcp_p_no(specsJson);
+                dcProductMapper.updateDcProduct(dcProduct);
+                log.info("更新产品规格JSON成功, 产品ID: {}", dcpId);
+            } else {
+                log.error("未找到产品信息, 产品ID: {}", dcpId);
+            }
+        } catch (Exception e) {
+            log.error("更新产品规格JSON失败, 产品ID: {}", dcpId, e);
+            throw e;
+        }
+    }
 
 }