diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3b41682 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..667aaef --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..12fbe1e --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +wrapperVersion=3.3.2 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip diff --git a/src/main/java/com/rj/common/PasswordUtil.java b/src/main/java/com/rj/common/PasswordUtil.java index 4d1ad36..2e92510 100644 --- a/src/main/java/com/rj/common/PasswordUtil.java +++ b/src/main/java/com/rj/common/PasswordUtil.java @@ -101,6 +101,10 @@ public class PasswordUtil { + + + + diff --git a/src/main/java/com/rj/common/ServiceManager.java b/src/main/java/com/rj/common/ServiceManager.java index ffda6bc..8d90d8d 100644 --- a/src/main/java/com/rj/common/ServiceManager.java +++ b/src/main/java/com/rj/common/ServiceManager.java @@ -87,6 +87,10 @@ public class ServiceManager { + + + + diff --git a/src/main/java/com/rj/config/AliyunConfig.java b/src/main/java/com/rj/config/AliyunConfig.java index c83b6c0..8ba097d 100644 --- a/src/main/java/com/rj/config/AliyunConfig.java +++ b/src/main/java/com/rj/config/AliyunConfig.java @@ -68,3 +68,7 @@ public class AliyunConfig { + + + + diff --git a/src/main/java/com/rj/controller/biz/DifyWorkflowAnalysisController.java b/src/main/java/com/rj/controller/biz/DifyWorkflowAnalysisController.java deleted file mode 100644 index b3eb8f0..0000000 --- a/src/main/java/com/rj/controller/biz/DifyWorkflowAnalysisController.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.rj.controller.biz; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.rj.entity.bz.DifyWorkflowAnalysis; - -import com.rj.service.biz.IDifyWorkflowAnalysisService; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -/** - * Dify工作流分析结果控制器 - */ -@Slf4j -@RestController -@RequestMapping("/api/biz/dify-analysis") -public class DifyWorkflowAnalysisController { - - @Autowired - private IDifyWorkflowAnalysisService difyWorkflowAnalysisService; - - /** - * 保存Dify工作流分析结果 - */ - @PostMapping - public boolean saveAnalysis(@RequestBody DifyWorkflowAnalysis analysis) { - try { - return difyWorkflowAnalysisService.save(analysis); - } catch (Exception e) { - log.error("保存Dify工作流分析结果失败", e); - return false; - } - } - - /** - * 根据ID获取分析结果 - */ - @GetMapping("/{id}") - public DifyWorkflowAnalysis getAnalysisById(@PathVariable String id) { - return difyWorkflowAnalysisService.getById(id); - } - - /** - * 根据分析记录ID获取分析结果 - */ - @GetMapping("/record/{recordId}") - public List getAnalysisByRecordId(@PathVariable String recordId) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("analysis_record_id", recordId); - return difyWorkflowAnalysisService.list(queryWrapper); - } - - /** - * 分页查询分析结果 - */ - @GetMapping("/page") - public Page getAnalysisPage( - @RequestParam(defaultValue = "1") Integer pageNum, - @RequestParam(defaultValue = "10") Integer pageSize) { - Page page = new Page<>(pageNum, pageSize); - return difyWorkflowAnalysisService.page(page); - } - - /** - * 根据顾问ID查询分析结果 - */ - @GetMapping("/consultant/{consultantId}") - public List getAnalysisByConsultantId(@PathVariable String consultantId) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("consultant_id", consultantId); - return difyWorkflowAnalysisService.list(queryWrapper); - } - - /** - * 根据客户unionId查询分析结果 - */ - @GetMapping("/customer/{unionId}") - public List getAnalysisByUnionId(@PathVariable String unionId) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("union_id", unionId); - return difyWorkflowAnalysisService.list(queryWrapper); - } -} diff --git a/src/main/java/com/rj/controller/sys/AuthController.java b/src/main/java/com/rj/controller/sys/AuthController.java index b94edae..69541d9 100644 --- a/src/main/java/com/rj/controller/sys/AuthController.java +++ b/src/main/java/com/rj/controller/sys/AuthController.java @@ -184,6 +184,10 @@ public class AuthController { + + + + diff --git a/src/main/java/com/rj/controller/sys/MenuController.java b/src/main/java/com/rj/controller/sys/MenuController.java index 41d18cf..a6a87ca 100644 --- a/src/main/java/com/rj/controller/sys/MenuController.java +++ b/src/main/java/com/rj/controller/sys/MenuController.java @@ -323,6 +323,10 @@ public class MenuController { + + + + diff --git a/src/main/java/com/rj/controller/sys/RoleController.java b/src/main/java/com/rj/controller/sys/RoleController.java index 0e2ee0f..cfd788a 100644 --- a/src/main/java/com/rj/controller/sys/RoleController.java +++ b/src/main/java/com/rj/controller/sys/RoleController.java @@ -293,6 +293,10 @@ public class RoleController { + + + + diff --git a/src/main/java/com/rj/controller/sys/UserRoleController.java b/src/main/java/com/rj/controller/sys/UserRoleController.java index dcb5e46..fea86ba 100644 --- a/src/main/java/com/rj/controller/sys/UserRoleController.java +++ b/src/main/java/com/rj/controller/sys/UserRoleController.java @@ -299,6 +299,10 @@ public class UserRoleController { + + + + diff --git a/src/main/java/com/rj/dto/DifyWorkflowResponseDto.java b/src/main/java/com/rj/dto/DifyWorkflowResponseDto.java index 806efa0..9a2e4be 100644 --- a/src/main/java/com/rj/dto/DifyWorkflowResponseDto.java +++ b/src/main/java/com/rj/dto/DifyWorkflowResponseDto.java @@ -70,3 +70,7 @@ public class DifyWorkflowResponseDto { + + + + diff --git a/src/main/java/com/rj/embedding/EnbedingModelConfig.java b/src/main/java/com/rj/embedding/EnbedingModelConfig.java index 660ca72..44b8bc9 100644 --- a/src/main/java/com/rj/embedding/EnbedingModelConfig.java +++ b/src/main/java/com/rj/embedding/EnbedingModelConfig.java @@ -51,7 +51,7 @@ public class EnbedingModelConfig { // @Primary public EmbeddingStore embeddingStoreInMemory() { //1 , 加载知识库文档进 内存 - List documents = ClassPathDocumentLoader.loadDocuments("knowledge"); + List documents =ClassPathDocumentLoader.loadDocuments("knowledge"); //暂时去掉 2025-09-20 //2 , 构建向量数据库操作对象 InMemoryEmbeddingStore embeddingStore = new InMemoryEmbeddingStore<>(); //3, 构建EmbeddingStoreIngestor , 完成文本数据的切割, 向量化, 存储 diff --git a/src/main/java/com/rj/mapper/CustomerProfileAnalysisMapper.java b/src/main/java/com/rj/mapper/CustomerProfileAnalysisMapper.java index 08e74ff..9d787b3 100644 --- a/src/main/java/com/rj/mapper/CustomerProfileAnalysisMapper.java +++ b/src/main/java/com/rj/mapper/CustomerProfileAnalysisMapper.java @@ -14,3 +14,7 @@ import org.apache.ibatis.annotations.Mapper; public interface CustomerProfileAnalysisMapper extends BaseMapper { } + + + + diff --git a/src/main/java/com/rj/pojo/sys/LoginResponse.java b/src/main/java/com/rj/pojo/sys/LoginResponse.java index aa242ee..01a87a7 100644 --- a/src/main/java/com/rj/pojo/sys/LoginResponse.java +++ b/src/main/java/com/rj/pojo/sys/LoginResponse.java @@ -50,6 +50,10 @@ public class LoginResponse { + + + + diff --git a/src/main/java/com/rj/scheduler/AudioStatisticsScheduler.java b/src/main/java/com/rj/scheduler/AudioStatisticsScheduler.java index e5ef0d7..adb2607 100644 --- a/src/main/java/com/rj/scheduler/AudioStatisticsScheduler.java +++ b/src/main/java/com/rj/scheduler/AudioStatisticsScheduler.java @@ -72,5 +72,9 @@ public class AudioStatisticsScheduler { + + + + diff --git a/src/main/java/com/rj/scheduler/CustomerProfileStatisticScheduler.java b/src/main/java/com/rj/scheduler/CustomerProfileStatisticScheduler.java new file mode 100644 index 0000000..e8a9474 --- /dev/null +++ b/src/main/java/com/rj/scheduler/CustomerProfileStatisticScheduler.java @@ -0,0 +1,8 @@ +package com.rj.scheduler; + +/** + * Author: 李中华 wx: spllzh email(qq): 28668817@qq.com + * Date: 2025/9/20 9:30 + **/ +public class CustomerProfileStatisticScheduler { +} diff --git a/src/main/java/com/rj/service/DifyWorkflowService.java b/src/main/java/com/rj/service/DifyWorkflowService.java index cf54ad2..8709aa9 100644 --- a/src/main/java/com/rj/service/DifyWorkflowService.java +++ b/src/main/java/com/rj/service/DifyWorkflowService.java @@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.rj.entity.bz.DifyWorkflowAnalysis; import com.rj.entity.CustomerProfileAnalysis; -import com.rj.service.biz.IDifyWorkflowAnalysisService; import com.rj.service.biz.ICustomerProfileAnalysisService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -47,9 +46,6 @@ public class DifyWorkflowService { private final RestTemplate restTemplate; - @Autowired - private IDifyWorkflowAnalysisService difyWorkflowAnalysisService; - @Autowired private ICustomerProfileAnalysisService customerProfileAnalysisService; @@ -325,12 +321,12 @@ public class DifyWorkflowService { analysis.setUpdatedAt(now); // 保存到数据库 - boolean saveResult = difyWorkflowAnalysisService.save(analysis); - if (saveResult) { - log.info("分析结果保存成功,ID: {}", analysis.getId()); - } else { - log.error("分析结果保存失败"); - } +// boolean saveResult = difyWorkflowAnalysisService.save(analysis); +// if (saveResult) { +// log.info("分析结果保存成功,ID: {}", analysis.getId()); +// } else { +// log.error("分析结果保存失败"); +// } } catch (Exception e) { log.error("保存分析结果到数据库失败", e); diff --git a/src/main/java/com/rj/service/biz/DifyWorkflowAnalysisServiceImpl.java b/src/main/java/com/rj/service/biz/DifyWorkflowAnalysisServiceImpl.java index e00482c..504895a 100644 --- a/src/main/java/com/rj/service/biz/DifyWorkflowAnalysisServiceImpl.java +++ b/src/main/java/com/rj/service/biz/DifyWorkflowAnalysisServiceImpl.java @@ -1,5 +1,6 @@ package com.rj.service.biz; +import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.rj.entity.bz.DifyWorkflowAnalysis; @@ -11,5 +12,5 @@ import org.springframework.stereotype.Service; */ @Service public class DifyWorkflowAnalysisServiceImpl extends ServiceImpl - implements IDifyWorkflowAnalysisService { + implements IService { } diff --git a/src/main/java/com/rj/service/biz/ICustomerProfileAnalysisService.java b/src/main/java/com/rj/service/biz/ICustomerProfileAnalysisService.java index 650c86b..817e857 100644 --- a/src/main/java/com/rj/service/biz/ICustomerProfileAnalysisService.java +++ b/src/main/java/com/rj/service/biz/ICustomerProfileAnalysisService.java @@ -35,3 +35,7 @@ public interface ICustomerProfileAnalysisService extends IService { -} diff --git a/src/main/java/com/rj/service/biz/impl/CustomerProfileAnalysisServiceImpl.java b/src/main/java/com/rj/service/biz/impl/CustomerProfileAnalysisServiceImpl.java index 3a32bbf..fdcbc0f 100644 --- a/src/main/java/com/rj/service/biz/impl/CustomerProfileAnalysisServiceImpl.java +++ b/src/main/java/com/rj/service/biz/impl/CustomerProfileAnalysisServiceImpl.java @@ -67,3 +67,7 @@ public class CustomerProfileAnalysisServiceImpl extends ServiceImpl { + + + + diff --git a/src/main/java/com/rj/service/sys/IUserRoleService.java b/src/main/java/com/rj/service/sys/IUserRoleService.java index 6e09fbf..9effbab 100644 --- a/src/main/java/com/rj/service/sys/IUserRoleService.java +++ b/src/main/java/com/rj/service/sys/IUserRoleService.java @@ -32,6 +32,10 @@ public interface IUserRoleService extends IService { + + + + diff --git a/src/main/java/com/rj/service/sys/impl/MenuServiceImpl.java b/src/main/java/com/rj/service/sys/impl/MenuServiceImpl.java index 35ef827..e1438e1 100644 --- a/src/main/java/com/rj/service/sys/impl/MenuServiceImpl.java +++ b/src/main/java/com/rj/service/sys/impl/MenuServiceImpl.java @@ -36,6 +36,10 @@ public class MenuServiceImpl extends ServiceImpl implements IM + + + + diff --git a/src/main/java/com/rj/service/sys/impl/RoleServiceImpl.java b/src/main/java/com/rj/service/sys/impl/RoleServiceImpl.java index 443df52..509b3be 100644 --- a/src/main/java/com/rj/service/sys/impl/RoleServiceImpl.java +++ b/src/main/java/com/rj/service/sys/impl/RoleServiceImpl.java @@ -36,6 +36,10 @@ public class RoleServiceImpl extends ServiceImpl implements IR + + + + diff --git a/src/main/java/com/rj/service/sys/impl/UserRoleServiceImpl.java b/src/main/java/com/rj/service/sys/impl/UserRoleServiceImpl.java index 5607aec..2ba1149 100644 --- a/src/main/java/com/rj/service/sys/impl/UserRoleServiceImpl.java +++ b/src/main/java/com/rj/service/sys/impl/UserRoleServiceImpl.java @@ -36,6 +36,10 @@ public class UserRoleServiceImpl extends ServiceImpl i + + + + diff --git a/src/main/resources/application-audio.yml b/src/main/resources/application-audio.yml index 7a27775..85796e4 100644 --- a/src/main/resources/application-audio.yml +++ b/src/main/resources/application-audio.yml @@ -50,4 +50,8 @@ spring: + + + + diff --git a/src/main/resources/customer-profile-analysis-example.json b/src/main/resources/customer-profile-analysis-example.json new file mode 100644 index 0000000..6442b17 --- /dev/null +++ b/src/main/resources/customer-profile-analysis-example.json @@ -0,0 +1,13 @@ +{ + "chat": "客户:你好,我想了解一下沃尔沃XC60这款车。\n顾问:您好!很高兴为您介绍沃尔沃XC60。这是一款中型豪华SUV,在安全性和环保方面表现非常出色。\n客户:我比较关心安全性能,听说沃尔沃在安全方面做得很好?\n顾问:是的,沃尔沃XC60配备了City Safety城市安全系统,还有Pilot Assist领航辅助系统,在主动安全方面非常先进。\n客户:那价格方面怎么样?我预算大概在40-50万左右。\n顾问:XC60的指导价在37-47万之间,您的预算完全够用。而且我们现在有置换补贴和金融方案,可以帮您降低购车成本。\n客户:我目前开的是宝马X3,想置换。置换的话有什么优惠吗?\n顾问:宝马X3置换XC60的话,我们可以提供1万元的置换补贴,还有3年免费保养。您对XC60的哪个配置比较感兴趣?\n客户:我比较喜欢T5智远豪华版,配置比较均衡。\n顾问:T5智远豪华版确实是个不错的选择,配置很丰富,包括全景天窗、真皮座椅、哈曼卡顿音响等。您平时主要是家用还是商务用途?\n客户:主要是家用,偶尔会跑长途。\n顾问:那XC60非常适合您,空间宽敞,长途驾驶也很舒适。而且沃尔沃的环保理念很好,车内空气质量是同级最好的。", + "communicateDate": "2025-01-03 14:30:00", + "analysisScene": "wechat_chat", + "aiAnalysisRequestId": "ai_req_20250103_001", + "businessId": "union_12345", + "customerFlowId": "flow_67890", + "businessType": "wechat_chat" +} + + + + diff --git a/src/main/resources/dify-workflow-request-example.json b/src/main/resources/dify-workflow-request-example.json new file mode 100644 index 0000000..c97cae5 --- /dev/null +++ b/src/main/resources/dify-workflow-request-example.json @@ -0,0 +1,9 @@ +{ + "unionId": "test_union_12345", + "consultantId": "consultant_67890", + "communicateDate": "2025-01-03 10:30:00", + "analysisScene": "sales_consultation", + "aiAnalysisRequestId": "ai_req_20250103_001", + "version": 1, + "chat": "客户:你好,我想了解一下沃尔沃XC60这款车。\n顾问:您好!很高兴为您介绍沃尔沃XC60。这是一款非常优秀的中型SUV,请问您主要关注哪些方面呢?\n客户:我比较关心安全性能和油耗表现。\n顾问:XC60在安全方面表现非常出色,配备了City Safety城市安全系统,还有Pilot Assist领航辅助系统。油耗方面,2.0T发动机百公里综合油耗约8.5L。\n客户:价格大概是多少?\n顾问:XC60的指导价在37.39-47.49万元之间,目前有优惠活动,可以优惠3万元左右。\n客户:我预算在40万以内,有什么推荐的配置吗?\n顾问:根据您的预算,我推荐智逸豪华版,指导价39.69万,优惠后36.69万,完全符合您的预算。\n客户:好的,我考虑一下,什么时候可以试驾?\n顾问:明天下午2点可以安排试驾,您方便吗?\n客户:可以的,我明天下午过去。\n顾问:好的,我为您预约明天下午2点的试驾,地址是..." +} diff --git a/src/main/resources/knowledge/pdf/医院信息.pdf b/src/main/resources/knowledge/pdf/医院信息.pdf deleted file mode 100644 index 2ef2cb0..0000000 Binary files a/src/main/resources/knowledge/pdf/医院信息.pdf and /dev/null differ diff --git a/src/main/resources/knowledge/pdf/科室信息 b/src/main/resources/knowledge/pdf/科室信息 new file mode 100644 index 0000000..7c4a013 --- /dev/null +++ b/src/main/resources/knowledge/pdf/科室信息 @@ -0,0 +1 @@ +aaa \ No newline at end of file diff --git a/src/main/resources/knowledge/pdf/科室信息.pdf b/src/main/resources/knowledge/pdf/科室信息.pdf deleted file mode 100644 index 7cdb32c..0000000 Binary files a/src/main/resources/knowledge/pdf/科室信息.pdf and /dev/null differ diff --git a/src/main/resources/knowledge/医院信息.txt b/src/main/resources/knowledge/医院信息.txt index 2f6d313..7e529e0 100644 --- a/src/main/resources/knowledge/医院信息.txt +++ b/src/main/resources/knowledge/医院信息.txt @@ -13,25 +13,6 @@ (东单院区)010-69151188 (西单院区)010-69158100 -医院简介: -北京协和医院是集医疗、教学、科研于一体的现代化综合三级甲等医院,是国家卫生健康委指定的全国疑难重症诊治指导中心,最早承担外宾医疗任务的医院之一,也是高等医学教育和住院医师规范化培训国家级示范基地,临床医学研究和技术创新的国家级核心基地。以学科齐全、技术力量雄厚、特色专科突出、多学科综合优势强大享誉海内外。在国家三级公立医院绩效考核中排名第一。 - -东单院区乘车路线: -1. 106,108,110,111,116,到东单路口北 -2. 41,104,快到东单路口南 -3. 1,52,728,802,到东单路口西 -4. 10,20,25,37,39,到东单路口东 -5. 103,104,420,803,到新东安市场 -6. 地铁1号线或5号线到东单站,A或B出口向北 - -西单院区乘车路线: -1. 68到辟才胡同东口 -2. 22,46,102,105,109,603,604,626,690,808,826,到西单商场 -3. 1,10,37,52,70,728,802,到西单路口东 -4.地铁1号线或4号线到西单站,F1或G出口向北 - -东单院区预约号取号地点: -东院区老门诊楼一层大厅挂号窗口或新门诊楼各楼层挂号/收费窗口取号 西单院区预约号取号地点: 西院区门诊楼一层大厅挂号窗口取号 diff --git a/src/main/resources/mapper/AudioManagementStatisticsMapper.xml b/src/main/resources/mapper/AudioManagementStatisticsMapper.xml index cf08f74..de0d8ed 100644 --- a/src/main/resources/mapper/AudioManagementStatisticsMapper.xml +++ b/src/main/resources/mapper/AudioManagementStatisticsMapper.xml @@ -25,5 +25,9 @@ + + + + diff --git a/src/main/sql/dify_workflow_analysis.sql b/src/main/sql/dify_workflow_analysis.sql new file mode 100644 index 0000000..3aaa22d --- /dev/null +++ b/src/main/sql/dify_workflow_analysis.sql @@ -0,0 +1,3 @@ +INSERT INTO `dify_workflow_analysis` (`id`, `union_id`, `consultant_id`, `communicate_date`, `analysis_scene`, `analysis_record_id`, `version`, `analysis_result`, `customer_source`, `customer_occupation`, `customer_hobbies`, `home_address`, `car_purchase_need`, `purchase_type`, `purchase_buyer`, `car_user`, `intended_car_model`, `car_qualifications`, `car_budget`, `financial_installment`, `purchase_cycle`, `focus_points`, `concerns`, `car_contrast`, `product_description`, `solution`, `quotation`, `agreed_follow_up_actions`, `unresolved_issues`, `original_corpus`, `created_at`, `updated_at`, `is_deleted`) VALUES ('69f06d6c3ed1087d3555c848472a9801', 'test_union_2b7abfa2', 'consultant_052548e4', '2024-10-06 02:23:43', 'sales_consultation', 'ai_req_7b1b3815c0a4', 8, '客户罗总对XC90感兴趣,顾问报价58 - 66万,客户预算未明确,关注置换补贴与优惠政策。', '通过企微联系', '未提及', '未提及', '广州市', '家庭使用,需七座大空间车', '置换,现有车辆为19年底荣威RX5', '个人', '未提及', '沃尔沃XC90 T8或B6 六座', '未提及', '未明确提及,可能在60万左右', '考虑贷款,利率约6.99%,月供约11000元', '计划今年内换新,但不着急', '价格优惠、置换补贴、终身质保和保养', '贷款利率高,等待更多优惠政策', '未提及', '介绍XC90配置及优惠政策,包括购置税减免3万、贴息政策等', '提供试驾、详细报价、置换补贴方案(最高9万)', 'XC90智远豪华版裸车价59.9万,全款落地约58 - 66万', '安排试驾,邀约到店看车了解具体活动', '客户仍在观望优惠政策,未确定购车时间', NULL, NULL, NULL, 0); +INSERT INTO `dify_workflow_analysis` (`id`, `union_id`, `consultant_id`, `communicate_date`, `analysis_scene`, `analysis_record_id`, `version`, `analysis_result`, `customer_source`, `customer_occupation`, `customer_hobbies`, `home_address`, `car_purchase_need`, `purchase_type`, `purchase_buyer`, `car_user`, `intended_car_model`, `car_qualifications`, `car_budget`, `financial_installment`, `purchase_cycle`, `focus_points`, `concerns`, `car_contrast`, `product_description`, `solution`, `quotation`, `agreed_follow_up_actions`, `unresolved_issues`, `original_corpus`, `created_at`, `updated_at`, `is_deleted`) VALUES ('7bd664eda12709cede2c7d5e383f9442', 'test_union_8cd12a6b', 'consultant_c475e417', '2020-10-11 03:18:58', 'sales_consultation', 'ai_req_5cbd38b8f95a', 6, '客户罗总对XC90感兴趣,顾问报价全款落地588814元,客户有旧车置换需求,关注终身质保、保养及贷款利率等细节,计划在优惠活动期间到店详谈。', '通过企微联系', '未提及', '未提及', '广州', '家用七座车,出行宽敞', '置换,现有车辆为2019年底荣威RX5', '个人', '家庭成员', 'XC90 T8智远豪华版或B6六座', '未提及', '66万左右(含落地费用)', '考虑贷款,但对利率敏感,需进一步审批', '计划今年换新,不急于购车', '价格优惠、终身质保、保养政策、上牌及保险便利性', '贷款利率较高,购车成本控制', '未提及', '推荐XC90系列车型,强调安全性、空间宽敞及健康环保特性', '提供置换补贴方案,安排试驾及店内服务支持', '全款落地588814元(B6六座),T8裸车价59.9万', '客户计划周末或优惠活动期间到店详谈;顾问安排试驾并跟进政策同步', '贷款利率具体方案需银行审批后确定,贴息政策尚未明确', '{\"content\": \"我通过了你的联系人验证请求,现在我们可以开始聊天了\"}\r\n{\"content\": \"您好,感谢关注沃尔沃汽车🚗,我是您的专属顾问, 很荣幸为您提供一对一服务。\\n沃尔沃汽车品牌自1927年起一直致力于打造出行自由,助您个性化出行,享受安全可持续的驾乘体验。沃尔沃汽车也以其出色的安全性、车内材料健康环保全球知名。您有任何需要了解的车型或预约看车试驾随时都可以联系我🤝\\n\\n【唯爱与生命不可辜负,沃尔沃让安全更安全】\"}\r\n{\"content\": \"沃尔沃华南旗舰店(广州唯一六星经销商)\\n公司地址:广州市天河区大灵山路25号\\n客户经理:小杨 -18988968190\"}\r\n{\"content\": \"您好 罗总 XC90T8 七座落地是在66万多,大概每月月供是在1万1千多,详细的月供明细 需要银行同时审批下才清楚的哈\"}\r\n{\"content\": \"我给您算的就是大概\"}\r\n{\"content\": \"终身质保还是?\"}\r\n{\"content\": \"有呀 目前政策有\"}\r\n{\"content\": \"有终身质保的\"}\r\n{\"content\": \"终身保养\"} resources/corpus/qiwei\r\n{\"content\": \"终身保养也有呀\"}\r\n{\"content\": \"上牌,保险自己选?\"}\r\n{\"content\": \"您说选什么?\"}\r\n{\"content\": \"自己上牌,自己购买保险\"}\r\n{\"content\": \"您不是在广州吗?我们直接帮您上牌 买保险在店内全帮您搞定,您不是更方便呀[微笑]\"}\r\n{\"content\": \"自己买便宜点,上牌收费吗?\"}\r\n{\"content\": \"都一样的呀,我们是跟银行有银行和保险公司有合作,所以我们帮您处理的话,您会省很多事情,因为我们公司有上牌同事和金融专员的嘛,还有就是保险的同事驻店在这里的\"}\r\n{\"content\": \"其实罗总,我们现在做团购会优惠力度还是可以的,你可以来店里,我这边做个详细报价给您\"}\r\n{\"content\": \"购置税是可以免30000是吗\"}\r\n{\"content\": \"裸车价多少呀\"}\r\n{\"content\": \"是这个配置吗\"}\r\n{\"content\": \"T8智远豪华版,裸车价59.9\"}\r\n{\"content\": \"这是一条引用/回复消息:\\n\\\"罗敏:\\n[图片]\\\"\\n------\\n就这个配置哈\"}\r\n{\"content\": \"贷款的利率挺高,我在沃尔沃小程序看差不多要6.99\"}\r\n{\"content\": \"这个是看您个人条件是需要来店里做一下审批之后,我们才能给到您具体方案的\"}\r\n{\"content\": \"罗总,现在我们月底冲业绩,其实加上各种补贴,区补,公司补贴,其实价格也相当给力的\"}\r\n{\"content\": \"我们估计是今年换新\"}\r\n{\"content\": \"不着急哈\"}\r\n{\"content\": \"没事呀,不着急也可以了解下当下活动呀,没说看了一定让您买不让您走[呲牙]\"}\r\n{\"content\": \"反正也不远,了解下当下活动,后面在对比,我们晚上也提供客餐哦\"}\r\n{\"content\": \"罗老师您好呀,明天周六有空来这边看看车吗\"}\r\n{\"content\": \"了解下当下的活动价格呀\"}\r\n{\"content\": \"你好\"}\r\n{\"content\": \"在店里吗\"}\r\n{\"content\": \"罗总 您好,我在的\"}\r\n{\"content\": \"需要准备午餐吗\"}\r\n{\"content\": \"不用\"}\r\n{\"content\": \"大概几点到呢\"}\r\n{\"content\": \"我在优托邦\"}\r\n{\"content\": \"好呀,我安排下试驾车\"}\r\n{\"content\": \"罗总 是晚点过来吗?还是现在过来呢\"}\r\n{\"content\": \"现在\"}\r\n{\"content\": \"我们这里可以停的,我们在天河粮油这里\"}\r\n{\"content\": \"您有看到那个天河粮油吗?我们就在腾势和雷克萨斯旁边\"}\r\n{\"content\": \"您要从围墙外面过来哦,里面是不通的\"}\r\n{\"content\": \"罗总 可以找到吗\"}\r\n{\"content\": \"我是罗敏\"}\r\n{\"content\": \"您好,感谢关注沃尔沃汽车🚗,我是您的专属顾问, 很荣幸为您提供一对一服务。\\n沃尔沃汽车品牌自1927年起一直致力于打造出行自由,助您个性化出行,享受安全可持续的驾乘体验。沃尔沃汽车也以其出色的安全性、车内材料健康环保全球知名。您有任何需要了解的车型或预约看车试驾随时都可以联系我🤝\\n\\n【唯爱与生命不可辜负,沃尔沃让安全更安全】\"}\r\n{\"content\": \"18028866338\"}\r\n{\"content\": \"罗先生吃完饭了吗\"}\r\n{\"content\": \"带家人过来看一下\"}\r\n{\"content\": \"还在吃饭\"}\r\n{\"content\": \"吃完饭看看小孩子情况\"}\r\n{\"content\": \"罗先生还过来吗\"}\r\n{\"content\": \"[握手]\"}\r\n{\"content\": \"今天不过去了,找个周末时间咱再约\"}\r\n{\"content\": \"今天辛苦你了哈\"}\r\n{\"content\": \"罗先生今天过来是吗\"}\r\n{\"content\": \"今天在优托邦带小孩玩\"}\r\n{\"content\": \"好咧,玩完过来我们这哈\"}\r\n{\"content\": \"罗先生今天还过来吗?\"}\r\n{\"content\": \"今天不过去了,下雨没带雨伞\"}\r\n{\"content\": \"好\"}\r\n{\"content\": \"好消息:沃尔沃全新S90限时优惠\"}\r\n{\"content\": \"罗总,能确定明天来一趟吗\"}\r\n{\"content\": \"好\"}\r\n{\"content\": \"明天过来详细了解咯\"}\r\n{\"content\": \"因为真的是这周活动很给力\"}\r\n{\"content\": \"真不希望罗总您错过\"}\r\n{\"content\": \"反正您这么近\"}\r\n{\"content\": \"过来不远\"}\r\n{\"content\": \"这是一条引用/回复消息:\\n\\\"[语音]\\\"\\n------\\n[合十][合十][合十]感谢\"}\r\n{\"content\": \"罗总,大概几点到\"}\r\n{\"content\": \"可以的\"}\r\n{\"content\": \"我等您\"}\r\n{\"content\": \"罗总开始过来了吗\"}\r\n{\"content\": \"现在过来\"}\r\n{\"content\": \"蔡先生,九月份是不是有贴息\"}\r\n{\"content\": \"暂时没有收到消息\"}\r\n{\"content\": \"应该是有的,具体可能还要等\"}\r\n{\"content\": \"政府网的应该没有错的\"}\r\n{\"content\": \"现在也有的\"}\r\n{\"content\": \"贴三个点\"}\r\n{\"content\": \"嗯嗯\"}\r\n{\"content\": \"我们现在还是想要xc90,要大一点,一家人出门才够宽敞\"}\r\n{\"content\": \"所以想要等等\"}\r\n{\"content\": \"买的话,第一时间找你\"}\r\n{\"content\": \"你那边有什么好的政策也可以第一时间同步下\"}\r\n{\"content\": \"谢谢哈\"}\r\n{\"content\": \"好\"}\r\n{\"content\": \"我是罗敏\"}\r\n{\"content\": \"您好,感谢关注沃尔沃汽车🚗,有任何需要了解的车型或预约看车试驾随时都可以联系我🤝\\n\\n沃尔沃汽车品牌自1927年起一直致力于打造出行自由,助您个性化出行,享受安全可持续的驾乘体验。沃尔沃汽车也以其出色的安全性、车内材料健康环保全球知名。\\n\\n【唯爱与生命不可辜负,沃尔沃让安全更安全】\"}\r\n{\"content\": \"罗先生 工作日有空也可以给你安排个上门试驾感受一下XC90六座B6\"}\r\n{\"content\": \"「钟庆楷:[视频]」\\n- - - - - - - - - - - - - - -\\n这个现在落地要多少\"}\r\n{\"content\": \"全新Xc90 智逸版本B5下三万\"}\r\n{\"content\": \"B6,6座\"}\r\n{\"content\": \"全新Xc90 智远豪华版本B6六座 全款落地588814\"}\r\n{\"content\": \"这个是出厂自带宝华伟健的对吗?\"}\r\n{\"content\": \"宝华韦健音箱限时选配是➕12000\"}\r\n{\"content\": \"智雅版本是标配\"}\r\n{\"content\": \"这是一条引用/回复消息:\\n“钟庆楷:\\n[视频]”\\n------\\n罗先生 工作日有空也可以给你安排个上门试驾感受一下XC90六座B6\"}\r\n{\"content\": \"好的\"}\r\n{\"content\": \"谢谢\"}\r\n{\"content\": \"罗先生,现在的话明天开始有活动xc90 看明天有没有时间过来门店,这边看看车了解一下 广州正佳广场沃尔沃\"}\r\n{\"content\": \"是打算全款是嘛 我记得是没有旧车置换\"}\r\n{\"content\": \"旧车可以置换\"}\r\n{\"content\": \"几几年的旧车呀\"}\r\n{\"content\": \"19年底荣威RX5\"}\r\n{\"content\": \"现在还有百分之70 先到先得\"}\r\n{\"content\": \"#沃尔沃直营店-818购车节8⃣️\\n限时多重好礼等您到店享🚗\\n到店试驾参与抽奖,百分百中奖🎁\\n购车基金➕置换补贴➕818叠加享💰\\n#沃尔沃汽车广州正佳品牌体验店\"}\r\n{\"content\": \"快上车,趁现在❗ 8月19日起多款车型要涨价🔥\\n全新XC90涨2万、S90涨1.5万… \\n现在818购车节(8.15 - 8.18 )是最后优惠期,\\n早买省好几万,想冲的赶紧找我/来门店了解~\\n#沃尔沃汽车广州正佳品牌体验店\\n#沃尔沃 #购车优惠 #涨价预警\"}\r\n{\"content\": \"最后一天,最后一天❗ 8月19日起多款车型要涨价🔥 全新XC90涨2万、S90涨1.5万… 现在818购车节(8.15 - 8.18 )是最后优惠期, 早买省好几万,想冲的赶紧找我/来门店了解~ #沃尔沃汽车广州正佳品牌体验店 #沃尔沃 #购车优惠 #涨价预警\"}\r\n{\"content\": \"不是所有混动,都叫超级混动\\n8/27全新沃尔沃XC70开启预售\\n诚邀您到店品鉴首款#超级混动\\n#沃尔沃汽车广州正佳品牌体验店\"}\r\n{\"content\": \"我已经添加了你,现在我们可以开始聊天了。\"}\r\n{\"content\": \"您好,我是沃尔沃汽车的专属顾问谢家敏,非常感谢您抽空看车。为了更好地为您提供服务,请您点击下方的签到卡片完成签到。\"}\r\n{\"content\": \"您之前看的车现在入手超划算,厂家8月活动刚下来,置换补贴最高能到9万呢💰。您要是还想再了解细节,或者有其他问题,随时跟我说就行~\\n我这边帮您再详细算算具体优惠,或者安排一次深度试驾,让您更放心做决定。您看明天什么时候方便?我来给您提前安排好~☕\"}\r\n{\"content\": \"补贴9万是?\"}\r\n{\"content\": \"同品牌置换可以享受9万补贴\"}\r\n', '2025-09-07 23:48:58', '2025-09-07 23:48:58', 0); +INSERT INTO `dify_workflow_analysis` (`id`, `union_id`, `consultant_id`, `communicate_date`, `analysis_scene`, `analysis_record_id`, `version`, `analysis_result`, `customer_source`, `customer_occupation`, `customer_hobbies`, `home_address`, `car_purchase_need`, `purchase_type`, `purchase_buyer`, `car_user`, `intended_car_model`, `car_qualifications`, `car_budget`, `financial_installment`, `purchase_cycle`, `focus_points`, `concerns`, `car_contrast`, `product_description`, `solution`, `quotation`, `agreed_follow_up_actions`, `unresolved_issues`, `original_corpus`, `created_at`, `updated_at`, `is_deleted`) VALUES ('eba8209a6b75f77099ba7f58828f5840', 'test_union_3032301d', 'consultant_0bbd5683', '2020-01-05 10:19:56', 'sales_consultation', 'ai_req_c038575da2a4', 8, '客户罗总对XC90感兴趣,顾问报价全款落地58.8万起,客户预算未明确提及,需进一步沟通补贴和置换政策。', '未提及', '未提及', '未提及', '广州市天河区附近', '家用,多人出行需求', '置换,现有车辆为2019年底荣威RX5', '个人', '家庭成员', 'XC90(B6六座版本)', '未提及', '未明确提及具体预算金额', '未提及', '年内换新,不着急购车', '车辆空间、终身质保、保养政策、价格优惠', '贷款利率、上牌费用、保险选择', '未提及', '介绍XC90 B6智远豪华版,全款落地价58.8万,提供终身质保和保养政策', '推荐店内上牌及保险服务,并强调优惠政策和置换补贴', 'XC90 T8七座约66万、B6六座全款落地58.8万,具体根据配置调整', '安排试驾,邀约到店详细了解活动政策', '客户对贷款利率和贴息政策仍有疑问,具体购车预算未明确', NULL, '2025-09-07 23:36:48', '2025-09-07 23:36:48', 0); diff --git a/src/main/sql/适配准真实.sql b/src/main/sql/适配准真实.sql new file mode 100644 index 0000000..fac14e3 --- /dev/null +++ b/src/main/sql/适配准真实.sql @@ -0,0 +1,94 @@ +适配项目的JSON: +{ + "project_management": [ + { + "id": "1957424785875087363", + "project_name": "奔驰C级销售项目" + }, + { + "id": "1957424785875087364", + "project_name": "奥迪A4L项目" + }, + { + "id": "1957424785875087365", + "project_name": "宝马3系项目" + }, + { + "id": "1957424785875087366", + "project_name": "雷克萨斯RX项目" + }, + { + "id": "1957424785875087367", + "project_name": "保时捷911项目" + }, + { + "id": "1957424785875087368", + "project_name": "威兹曼GT项目" + } + ] +} + +适配销售顾问的JSON: +{ + "sales_management": [ + { + "id": "1957424800000000001", + "sales_name": "张明" + }, + { + "id": "1957424800000000002", + "sales_name": "李华" + }, + { + "id": "1957424800000000003", + "sales_name": "王强" + }, + { + "id": "1957424800000000004", + "sales_name": "刘芳" + }, + { + "id": "1957424800000000005", + "sales_name": "陈军" + }, + { + "id": "1957424800000000006", + "sales_name": "赵敏" + }, + { + "id": "1957424800000000007", + "sales_name": "孙丽" + }, + { + "id": "1957424800000000008", + "sales_name": "周涛" + } + ] +} + + +适配经销商门店的JSON* +{'1957424710587330562', '广州奔驰4S店'},{'1957424711560409089', '北京奥迪4S店'},{'1957424714953601026', '上海宝马4S店'},{'1957424739267981313', '深圳雷克萨斯4S店'},{'1957424740000000001', '成都保时捷4S店'},{'1957424740000000017', '昆明威兹曼4S店'},{} + +适配单向开口率的JSON: +{ + { + "id": "1957424800000000001","name":"沃尔沃M90续航亮点" + }, + { + "id": "1957424800000000002","name":"lexus RX350智能互联" + }, + { + "id": "1957424800000000003","name":"别克品牌主张" + }, + { + "id": "1957424800000000004","name":"lexusRX470刹车问题" + } +} + + + + + + + diff --git a/src/test/java/com/rj/AppTest.java b/src/test/java/com/rj/AppTest.java index 1627331..a45aae9 100644 --- a/src/test/java/com/rj/AppTest.java +++ b/src/test/java/com/rj/AppTest.java @@ -1,16 +1,287 @@ package com.rj; +import com.alibaba.fastjson.JSONObject; import dev.langchain4j.model.openai.OpenAiChatModel; +import java.util.concurrent.Semaphore; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + /** * Author: 李中华 wx: spllzh email(qq): 28668817@qq.com * Date: 2025/8/4 9:55 **/ public class AppTest { - + private static Semaphore semaphore = new Semaphore(3); // 限制并发数为3 + private static AtomicInteger completedTasks = new AtomicInteger(0); + public static void main(String[] args) { - System.out.println("Hello World!"); + System.out.println("=========================================="); + System.out.println("Semaphore测试程序"); + System.out.println("=========================================="); + System.out.println("请选择要运行的测试:"); + System.out.println("1. 基础并发控制测试 (threadPoolTest)"); + System.out.println("2. 资源池场景测试 (testResourcePool)"); + System.out.println("3. 公平性测试 (testSemaphoreFairness)"); + System.out.println("4. 运行所有测试"); + System.out.println("5. 其他测试 (indexof3, parseJson等)"); + System.out.println("=========================================="); + + // 默认运行基础测试 + System.out.println("运行基础并发控制测试...\n"); + threadPoolTest111(); + + // 可以取消注释下面的代码来运行其他测试 + // System.out.println("\n运行资源池场景测试...\n"); + // testResourcePool(); + + // System.out.println("\n运行公平性测试...\n"); + // testSemaphoreFairness(); + + // 其他测试 + // indexof3(); + // parseJson(); + // parseJsonForMQ(); + } + + /** + * Semaphore测试方法 - 测试并发控制功能 + * 使用线程池模拟多个任务并发执行,通过Semaphore限制同时执行的任务数量 + */ + public static void threadPoolTest111() { + System.out.println("=========================================="); + System.out.println("Semaphore并发控制测试开始"); + System.out.println("=========================================="); + System.out.println("Semaphore许可数: " + semaphore.availablePermits()); + System.out.println("总任务数: 10"); + System.out.println("最大并发数: 3"); + System.out.println("=========================================="); + + // 创建线程池 + ExecutorService executor = Executors.newFixedThreadPool(10); + long startTime = System.currentTimeMillis(); + + // 提交10个任务 + for (int i = 1; i <= 10; i++) { + final int taskId = i; + executor.submit(() -> { + try { + // 获取许可 + System.out.println(String.format("[任务%d] 尝试获取许可,当前可用许可数: %d", + taskId, semaphore.availablePermits())); + + semaphore.acquire(); // 获取许可 + + System.out.println(String.format("[任务%d] ✅ 成功获取许可,开始执行任务", taskId)); + System.out.println(String.format("[任务%d] 当前可用许可数: %d", + taskId, semaphore.availablePermits())); + + // 模拟任务执行(2秒) + Thread.sleep(8000); + + System.out.println(String.format("[任务%d] 🎯 任务执行完成", taskId)); + + } catch (InterruptedException e) { + System.out.println(String.format("[任务%d] ❌ 任务被中断: %s", taskId, e.getMessage())); + Thread.currentThread().interrupt(); + } finally { + // 释放许可 + semaphore.release(); + completedTasks.incrementAndGet(); + System.out.println(String.format("[任务%d] 🔓 释放许可,当前可用许可数: %d", + taskId, semaphore.availablePermits())); + } + }); + } + + // 等待所有任务完成 + executor.shutdown(); + try { + if (!executor.awaitTermination(30, TimeUnit.SECONDS)) { + executor.shutdownNow(); + } + } catch (InterruptedException e) { + executor.shutdownNow(); + Thread.currentThread().interrupt(); + } + + long endTime = System.currentTimeMillis(); + + // 输出测试结果 + System.out.println("=========================================="); + System.out.println("Semaphore测试结果统计"); + System.out.println("=========================================="); + System.out.println("总任务数: 10"); + System.out.println("完成任务数: " + completedTasks.get()); + System.out.println("总耗时: " + (endTime - startTime) + "ms"); + System.out.println("最终可用许可数: " + semaphore.availablePermits()); + System.out.println("=========================================="); + + // 测试Semaphore的其他功能 + testSemaphoreFeatures(); + } + + /** + * 测试Semaphore的其他功能 + */ + private static void testSemaphoreFeatures() { + System.out.println("\n=========================================="); + System.out.println("Semaphore功能特性测试"); + System.out.println("=========================================="); + + // 测试tryAcquire - 非阻塞获取许可 + System.out.println("1. 测试tryAcquire()方法:"); + boolean acquired = semaphore.tryAcquire(); + System.out.println("tryAcquire()结果: " + acquired); + if (acquired) { + System.out.println("成功获取许可,可用许可数: " + semaphore.availablePermits()); + semaphore.release(); + System.out.println("释放许可后,可用许可数: " + semaphore.availablePermits()); + } + + // 测试tryAcquire(timeout) - 带超时的获取许可 + System.out.println("\n2. 测试tryAcquire(timeout)方法:"); + try { + boolean acquiredWithTimeout = semaphore.tryAcquire(1, TimeUnit.SECONDS); + System.out.println("tryAcquire(1秒)结果: " + acquiredWithTimeout); + if (acquiredWithTimeout) { + semaphore.release(); + } + } catch (InterruptedException e) { + System.out.println("tryAcquire(timeout)被中断: " + e.getMessage()); + } + + // 测试acquire(permits) - 获取多个许可 + System.out.println("\n3. 测试acquire(permits)方法:"); + try { + System.out.println("尝试获取2个许可..."); + semaphore.acquire(2); + System.out.println("成功获取2个许可,可用许可数: " + semaphore.availablePermits()); + semaphore.release(2); + System.out.println("释放2个许可后,可用许可数: " + semaphore.availablePermits()); + } catch (InterruptedException e) { + System.out.println("acquire(permits)被中断: " + e.getMessage()); + } + + // 测试availablePermits() - 获取可用许可数 + System.out.println("\n4. 当前Semaphore状态:"); + System.out.println("可用许可数: " + semaphore.availablePermits()); + System.out.println("是否有等待的线程: " + semaphore.hasQueuedThreads()); + System.out.println("等待队列长度: " + semaphore.getQueueLength()); + + System.out.println("=========================================="); + System.out.println("Semaphore功能测试完成"); + System.out.println("=========================================="); + } + + /** + * 测试Semaphore在资源池场景下的应用 + * 模拟数据库连接池的使用 + */ + public static void testResourcePool() { + System.out.println("\n=========================================="); + System.out.println("Semaphore资源池场景测试"); + System.out.println("=========================================="); + + // 模拟数据库连接池,最多3个连接 + Semaphore connectionPool = new Semaphore(3); + ExecutorService executor = Executors.newFixedThreadPool(5); + + // 模拟5个客户端同时请求数据库连接 + for (int i = 1; i <= 5; i++) { + final int clientId = i; + executor.submit(() -> { + try { + System.out.println(String.format("[客户端%d] 请求数据库连接...", clientId)); + + // 尝试获取连接 + if (connectionPool.tryAcquire(2, TimeUnit.SECONDS)) { + System.out.println(String.format("[客户端%d] ✅ 获得数据库连接,剩余连接数: %d", + clientId, connectionPool.availablePermits())); + + // 模拟数据库操作 + Thread.sleep(3000); + + System.out.println(String.format("[客户端%d] 🎯 数据库操作完成", clientId)); + + // 释放连接 + connectionPool.release(); + System.out.println(String.format("[客户端%d] 🔓 释放数据库连接,剩余连接数: %d", + clientId, connectionPool.availablePermits())); + } else { + System.out.println(String.format("[客户端%d] ❌ 获取数据库连接超时", clientId)); + } + } catch (InterruptedException e) { + System.out.println(String.format("[客户端%d] ❌ 操作被中断: %s", clientId, e.getMessage())); + Thread.currentThread().interrupt(); + } + }); + } + + executor.shutdown(); + try { + if (!executor.awaitTermination(10, TimeUnit.SECONDS)) { + executor.shutdownNow(); + } + } catch (InterruptedException e) { + executor.shutdownNow(); + Thread.currentThread().interrupt(); + } + + System.out.println("=========================================="); + System.out.println("资源池场景测试完成"); + System.out.println("=========================================="); + } + + /** + * 测试Semaphore的公平性 + */ + public static void testSemaphoreFairness() { + System.out.println("\n=========================================="); + System.out.println("Semaphore公平性测试"); + System.out.println("=========================================="); + + // 创建公平的Semaphore + Semaphore fairSemaphore = new Semaphore(1, true); // 公平模式 + ExecutorService executor = Executors.newFixedThreadPool(3); + + // 创建3个线程,每个线程尝试获取许可 + for (int i = 1; i <= 3; i++) { + final int threadId = i; + executor.submit(() -> { + try { + System.out.println(String.format("[线程%d] 尝试获取许可...", threadId)); + fairSemaphore.acquire(); + System.out.println(String.format("[线程%d] ✅ 获得许可", threadId)); + + // 模拟工作 + Thread.sleep(1000); + + System.out.println(String.format("[线程%d] 🎯 工作完成,释放许可", threadId)); + fairSemaphore.release(); + } catch (InterruptedException e) { + System.out.println(String.format("[线程%d] ❌ 被中断: %s", threadId, e.getMessage())); + Thread.currentThread().interrupt(); + } + }); + } + + executor.shutdown(); + try { + if (!executor.awaitTermination(5, TimeUnit.SECONDS)) { + executor.shutdownNow(); + } + } catch (InterruptedException e) { + executor.shutdownNow(); + Thread.currentThread().interrupt(); + } + + System.out.println("=========================================="); + System.out.println("公平性测试完成"); + System.out.println("=========================================="); } public AppTest( String testName ) @@ -28,4 +299,68 @@ public class AppTest { System.out.println(chat); } + + public static void indexof3( ) + { + System.out.println( "Hello World!" ); + String ss = "SMART_ASSISTANT_NAMEPLATE-1967863854687916032"; + if (ss.indexOf("SMART_ASSISTANT_NAMEPLATE")>=0){ + System.out.println("ddd: "); + } + System.out.println("ttt: "+ss.indexOf("SMART_ASSISTANT_NAMEPLATE1")); + } + + + public static void parseJsonForMQ(){ + + String jsonNamplate="{\"outputs\":{\"customerFlowId\":\"1919618280323473410\",\"data\":{\"analysisDetail\":{\"purchaseIntention\":{\"familyIncomeLevel\":\"未提及\",\"targetModel\":\"XC90(7座)\",\"carBudget\":\"全款落地价44-47万\",\"financialInstallment\":\"未提及\",\"purchaseCycle\":\"5月前完成购车\",\"preferredConfiguration\":\"B5或B6智逸配置\",\"preferredPowerType\":\"未提及\",\"preferredColor\":\"未提及\",\"purchaseType\":\"未提及\"},\"purchaseConsideration\":{\"comparedVehicles\":\"未提及\",\"concerns\":\"报价与心理预期不符\",\"focusPoints\":\"价格、配置、优惠政策\"},\"consultantProposal\":{\"financialPlan\":\"未提及\",\"consultantQuote\":\"B5车型全款落地近50万,B6暂无车\",\"preferentialPolicies\":\"可申请优惠至47万\"},\"followUpSuggestions\":\"明确客户心理预算,提供详细报价和优惠政策,邀约到店体验试驾以促成成交。\",\"testDriveExperience\":\"未提及\",\"existingVehicle\":{\"licensePlateStatus\":\"未提及\",\"existingCarBrand\":\"未提及\",\"existingCarUsageYears\":\"未提及\"},\"basicInfo\":{\"carUser\":\"未提及\",\"occupation\":\"未提及\",\"educationLevel\":\"未提及\",\"hobbies\":\"未提及\",\"carPurchasePurpose\":\"未提及\",\"familyDailyTravelNumber\":\"未提及\",\"buyerType\":\"个人\",\"customerSource\":\"未提及\",\"purchaseQualification\":\"未提及\",\"homeAddress\":\"瑞丽\"}},\"analysisResult\":\"客户对XC90车型感兴趣,预算全款44-47万左右,希望了解具体报价并对比其他店价格。顾问建议客户到店详谈优惠政策和配置细节。\"},\"analysisScene\":\"3\",\"analysisRecordId\":\"SMART_ASSISTANT_NAMEPLATE-1968176478541664256\",\"version\":2},\"workflow_id\":\"745dc920-8ba0-4e95-8efb-1c8b68f21344\",\"id\":\"d08b3fc9-4986-477d-91d7-b43468ac757a\",\"status\":\"succeeded\"}"; + String jsonstr ="{\"outputs\":{\"customerFlowId\":\"1919618280323473410\",\"data\":{\"analysisDetail\":{\"purchaseIntention\":{\"familyIncomeLevel\":\"未提及\",\"targetModel\":\"XC90(7座)\",\"carBudget\":\"全款落地价44-47万\",\"financialInstallment\":\"未提及\",\"purchaseCycle\":\"5月前完成购车\",\"preferredConfiguration\":\"B5或B6智逸配置\",\"preferredPowerType\":\"未提及\",\"preferredColor\":\"未提及\",\"purchaseType\":\"未提及\"},\"purchaseConsideration\":{\"comparedVehicles\":\"未提及\",\"concerns\":\"报价与心理预期不符\",\"focusPoints\":\"价格、配置、优惠政策\"},\"consultantProposal\":{\"financialPlan\":\"未提及\",\"consultantQuote\":\"B5车型全款落地近50万,B6暂无车\",\"preferentialPolicies\":\"可申请优惠至47万\"},\"followUpSuggestions\":\"明确客户心理预算,提供详细报价和优惠政策,邀约到店体验试驾以促成成交。\",\"testDriveExperience\":\"未提及\",\"existingVehicle\":{\"licensePlateStatus\":\"未提及\",\"existingCarBrand\":\"未提及\",\"existingCarUsageYears\":\"未提及\"},\"basicInfo\":{\"carUser\":\"未提及\",\"occupation\":\"未提及\",\"educationLevel\":\"未提及\",\"hobbies\":\"未提及\",\"carPurchasePurpose\":\"未提及\",\"familyDailyTravelNumber\":\"未提及\",\"buyerType\":\"个人\",\"customerSource\":\"未提及\",\"purchaseQualification\":\"未提及\",\"homeAddress\":\"瑞丽\"}},\"analysisResult\":\"客户对XC90车型感兴趣,预算全款44-47万左右,希望了解具体报价并对比其他店价格。顾问建议客户到店详谈优惠政策和配置细节。\"},\"analysisScene\":\"3\",\"analysisRecordId\":\"SMART_ASSISTANT_NAMEPLATE-1968176478541664256\",\"version\":2},\"workflow_id\":\"745dc920-8ba0-4e95-8efb-1c8b68f21344\",\"id\":\"d08b3fc9-4986-477d-91d7-b43468ac757a\",\"status\":\"succeeded\"}"; + JSONObject analysisResp = JSONObject.parseObject(jsonstr); + + String text = analysisResp.getString("outputs"); + JSONObject outputss = JSONObject.parseObject(text); + String businessType = outputss.getString("businessType"); + System.out.println("businessType is : "+businessType); + + String businessId = outputss.getString("businessId"); + System.out.println("businessId is : "+businessId); + + + String aiAnalysisRequestId = outputss.getString("aiAnalysisRequestid") ; + System.out.println("aiAnalysisRequestId is : "+aiAnalysisRequestId); + + if (aiAnalysisRequestId.indexOf("CORPUS_PORTRAIT_NAMEPLATE")>=0){ + businessType="CORPUS_PORTRAIT_NAMEPLATE"; + } + System.out.println("businessType is : "+businessType); + } + + + + public static void parseJson(){ + String jsonPortraint1 = "{\"id\":\"fc32c67a-920f-43e0-9ec8-1c26b31785ee\",\"workflow_id\":\"e0ea47de-9861-45a8-adc6-f46655587419\",\"status\":\"succeeded\",\"outputs\":{\"result\":{\"info\":\"{\\n \\\"address\\\": \\\"未提及\\\",\\n \\\"buyCarUse\\\": \\\"未提及\\\",\\n \\\"actualDriver\\\": \\\"未提及\\\",\\n \\\"familyStructure\\\": \\\"未提及\\\",\\n \\\"familyNum\\\": 0,\\n \\\"familyIncomeMonth\\\": \\\"未提及\\\",\\n \\\"industry\\\": \\\"未提及\\\",\\n \\\"occupation\\\": \\\"未提及\\\",\\n \\\"enterpriseType\\\": \\\"未提及\\\",\\n \\\"avocation\\\": \\\"未提及\\\",\\n \\\"educationalLevel\\\": \\\"未提及\\\",\\n \\\"bookCarDate\\\": \\\"未提及\\\",\\n \\\"buyType\\\": \\\"首购\\\",\\n \\\"carBudget\\\": \\\"未提及\\\",\\n \\\"paymentMethod\\\": \\\"未提及\\\",\\n \\\"keepVehicleBrand\\\": [\\\"未提及\\\"],\\n \\\"failBrand\\\": [\\\"未提及\\\"],\\n \\\"carQuality\\\": \\\"未提及\\\",\\n \\\"remark\\\": \\\"对话中未提及任何有效信息,无法得出相关结论。\\\"\\n}\",\"entities\":\"{\\n \\\"brand\\\": \\\"中性\\\",\\n \\\"design\\\": \\\"中性\\\",\\n \\\"color\\\": \\\"中性\\\",\\n \\\"size\\\": \\\"中性\\\",\\n \\\"space\\\": \\\"中性\\\",\\n \\\"interior\\\": \\\"中性\\\",\\n \\\"audio\\\": \\\"中性\\\",\\n \\\"ivinfo\\\": \\\"中性\\\",\\n \\\"fsd\\\": \\\"中性\\\",\\n \\\"mileage\\\": \\\"中性\\\",\\n \\\"safety\\\": \\\"中性\\\",\\n \\\"eco\\\": \\\"中性\\\",\\n \\\"liscense\\\": \\\"中性\\\",\\n \\\"price\\\": \\\"中性\\\",\\n \\\"benefit\\\": \\\"中性\\\",\\n \\\"cost\\\": \\\"中性\\\",\\n \\\"value\\\": \\\"中性\\\",\\n \\\"power\\\": \\\"中性\\\",\\n \\\"control\\\": \\\"中性\\\",\\n \\\"tradein\\\": \\\"中性\\\",\\n \\\"finance\\\": \\\"中性\\\",\\n \\\"warranty\\\": \\\"中性\\\",\\n \\\"delivery\\\": \\\"中性\\\"\\n}\"},\"communicateDate\":\"Tue May 06 12:55:00 CST 2025\",\"analysisScene\":\"3\",\"analysisRecordId\":\"CORPUS_PORTRAIT_NAMEPLATE-1967954224931184640\",\"businessId\":\"1919618280323473410\",\"businessType\":\"CORPUS_PORTRAIT_NAMEPLATE\"},\"elapsed_time\":9.988657537847757,\"total_tokens\":4720,\"total_steps\":6,\"created_at\":1758031825,\"finished_at\":1758031835,\"aiAnalysisRequestId\":\"CORPUS_PORTRAIT_NAMEPLATE-1967954224931184640\"}" ; + String jsonNameplate1 ="{\"difyResponse\": {\"status\": \"succeeded\", \"id\": \"cb8de7e4-b96b-4588-bc6a-b9d3f296a814\", \"workflow_id\": \"745dc920-8ba0-4e95-8efb-1c8b68f21344\", \"outputs\": {\"analysisScene\": \"3\", \"customerFlowId\": \"1919618280323473410\", \"analysisRecordId\": \"SMART_ASSISTANT_NAMEPLATE-1967944330802950144\", \"version\": 2, \"data\": {\"analysisResult\": \"\\u5ba2\\u6237\\u5728\\u745e\\u4e3d\\uff0c\\u5bf9XC90 B6\\u667a\\u90387\\u5ea7\\u611f\\u5174\\u8da3\\uff0c\\u9884\\u7b9744\\u4e07\\u5de6\\u53f3\\u5168\\u6b3e\\u843d\\u5730\\uff0c\\u987e\\u95ee\\u62a5\\u4ef747\\u4e07\\uff0c\\u5ba2\\u6237\\u6682\\u672a\\u63a5\\u53d7\\u5e76\\u8ba1\\u5212\\u5bf9\\u6bd4\\u5176\\u4ed6\\u5e97\\u4ef7\\u683c\\u3002\", \"analysisDetail\": {\"basicInfo\": {\"customerSource\": \"\\u672a\\u63d0\\u53ca\", \"occupation\": \"\\u672a\\u63d0\\u53ca\", \"educationLevel\": \"\\u672a\\u63d0\\u53ca\", \"hobbies\": \"\\u672a\\u63d0\\u53ca\", \"homeAddress\": \"\\u5ba2\\u6237\\u5728\\u745e\\u4e3d\", \"carPurchasePurpose\": \"\\u672a\\u63d0\\u53ca\", \"buyerType\": \"\\u4e2a\\u4eba\", \"carUser\": \"\\u672a\\u63d0\\u53ca\", \"purchaseQualification\": \"\\u672a\\u63d0\\u53ca\", \"familyDailyTravelNumber\": \"\\u672a\\u63d0\\u53ca\"}, \"purchaseIntention\": {\"targetModel\": \"XC90 B6\\u667a\\u90387\\u5ea7\", \"preferredColor\": \"\\u672a\\u63d0\\u53ca\", \"preferredConfiguration\": \"\\u672a\\u63d0\\u53ca\", \"preferredPowerType\": \"\\u672a\\u63d0\\u53ca\", \"carBudget\": \"\\u5ba2\\u6237\\u9884\\u7b97\\u5168\\u6b3e\\u843d\\u5730\\u4ef744\\u4e07\\u5de6\\u53f3\", \"financialInstallment\": \"\\u5168\\u6b3e\\u8d2d\\u8f66\", \"familyIncomeLevel\": \"\\u672a\\u63d0\\u53ca\", \"purchaseType\": \"\\u672a\\u63d0\\u53ca\", \"purchaseCycle\": \"5\\u6708\\u524d\\u8d2d\\u8f66\"}, \"purchaseConsideration\": {\"focusPoints\": \"\\u4ef7\\u683c\\u3001\\u8f66\\u578b\\u914d\\u7f6e\", \"concerns\": \"\\u672a\\u63d0\\u53ca\", \"comparedVehicles\": \"\\u672a\\u63d0\\u53ca\"}, \"existingVehicle\": {\"existingCarBrand\": \"\\u672a\\u63d0\\u53ca\", \"existingCarUsageYears\": \"\\u672a\\u63d0\\u53ca\", \"licensePlateStatus\": \"\\u672a\\u63d0\\u53ca\"}, \"consultantProposal\": {\"consultantQuote\": \"\\u987e\\u95ee\\u62a5\\u4ef7\\u5168\\u6b3e\\u843d\\u5730\\u4ef747\\u4e07\\u5de6\\u53f3\", \"financialPlan\": \"\\u672a\\u63d0\\u53ca\", \"preferentialPolicies\": \"\\u672a\\u63d0\\u53ca\"}, \"testDriveExperience\": \"\\u672a\\u63d0\\u53ca\", \"followUpSuggestions\": \"\\u5efa\\u8bae\\u660e\\u786e\\u5ba2\\u6237\\u5173\\u6ce8\\u70b9\\uff0c\\u63d0\\u4f9b\\u66f4\\u8be6\\u7ec6\\u4f18\\u60e0\\u653f\\u7b56\\u53ca\\u5bf9\\u6bd4\\u4fe1\\u606f\\uff0c\\u4ee5\\u4e89\\u53d6\\u5ba2\\u6237\\u8fdb\\u5e97\\u6d3d\\u8c08\\u3002\"}}}}, \"customerFlowId\": \"1919618280323473410\", \"aiAnalysisRequestId\": \"SMART_ASSISTANT_NAMEPLATE-1967944330802950144\"}"; + + String jsonStr="{\"outputs\":{\"customerFlowId\":\"1919618280323473410\",\"data\":{\"analysisDetail\":{\"purchaseIntention\":{\"familyIncomeLevel\":\"未提及\",\"targetModel\":\"XC90(7座)\",\"carBudget\":\"全款落地价44-47万\",\"financialInstallment\":\"未提及\",\"purchaseCycle\":\"5月前完成购车\",\"preferredConfiguration\":\"B5或B6智逸配置\",\"preferredPowerType\":\"未提及\",\"preferredColor\":\"未提及\",\"purchaseType\":\"未提及\"},\"purchaseConsideration\":{\"comparedVehicles\":\"未提及\",\"concerns\":\"报价与心理预期不符\",\"focusPoints\":\"价格、配置、优惠政策\"},\"consultantProposal\":{\"financialPlan\":\"未提及\",\"consultantQuote\":\"B5车型全款落地近50万,B6暂无车\",\"preferentialPolicies\":\"可申请优惠至47万\"},\"followUpSuggestions\":\"明确客户心理预算,提供详细报价和优惠政策,邀约到店体验试驾以促成成交。\",\"testDriveExperience\":\"未提及\",\"existingVehicle\":{\"licensePlateStatus\":\"未提及\",\"existingCarBrand\":\"未提及\",\"existingCarUsageYears\":\"未提及\"},\"basicInfo\":{\"carUser\":\"未提及\",\"occupation\":\"未提及\",\"educationLevel\":\"未提及\",\"hobbies\":\"未提及\",\"carPurchasePurpose\":\"未提及\",\"familyDailyTravelNumber\":\"未提及\",\"buyerType\":\"个人\",\"customerSource\":\"未提及\",\"purchaseQualification\":\"未提及\",\"homeAddress\":\"瑞丽\"}},\"analysisResult\":\"客户对XC90车型感兴趣,预算全款44-47万左右,希望了解具体报价并对比其他店价格。顾问建议客户到店详谈优惠政策和配置细节。\"},\"analysisScene\":\"3\",\"analysisRecordId\":\"SMART_ASSISTANT_NAMEPLATE-1968176478541664256\",\"version\":2},\"workflow_id\":\"745dc920-8ba0-4e95-8efb-1c8b68f21344\",\"id\":\"d08b3fc9-4986-477d-91d7-b43468ac757a\",\"status\":\"succeeded\"}"; + + + JSONObject analysisResp = JSONObject.parseObject(jsonStr); + + String text = analysisResp.getString("outputs"); + JSONObject outputss = JSONObject.parseObject(text); + String businessType = outputss.getString("businessType"); + System.out.println("businessType is : "+businessType); + + String businessId = outputss.getString("businessId"); + System.out.println("businessId is : "+businessId); + + + String aiAnalysisRequestId = outputss.getString("aiAnalysisRequestid") ; + System.out.println("aiAnalysisRequestId is : "+aiAnalysisRequestId); + + if (aiAnalysisRequestId.indexOf("CORPUS_PORTRAIT_NAMEPLATE")>=0){ + businessType="CORPUS_PORTRAIT_NAMEPLATE"; + } + System.out.println("businessType is : "+businessType); + } } diff --git a/src/test/java/com/rj/AudioAsynCallTest.java b/src/test/java/com/rj/AudioAsynCallTest.java new file mode 100644 index 0000000..3b662f9 --- /dev/null +++ b/src/test/java/com/rj/AudioAsynCallTest.java @@ -0,0 +1,105 @@ +package com.rj; + +import com.alibaba.dashscope.audio.asr.transcription.*; +import com.alibaba.dashscope.common.TaskStatus; +import com.google.gson.*; + +import java.util.Arrays; +import java.util.List; + +/** + * Author: Li Zhonghua wx: spllzh email(qq): 28668817@qq.com + * Date: 2025/8/22 18:43 + * + * https://help.aliyun.com/zh/model-studio/paraformer-recorded-speech-recognition-java-sdk + * + * + **/ +public class AudioAsynCallTest { + + public static void main(String[] args) { + // 检查API Key + String apiKey = System.getenv("DASHSCOPE_API_KEY"); + if (apiKey == null || apiKey.trim().isEmpty()) { + System.err.println("错误: 请设置环境变量 DASHSCOPE_API_KEY"); + System.err.println("请按照以下步骤操作:"); + System.err.println("1. 登录阿里云控制台"); + System.err.println("2. 进入通义千问服务"); + System.err.println("3. 获取API Key"); + System.err.println("4. 设置环境变量: export DASHSCOPE_API_KEY=your-api-key"); + System.exit(1); + } + System.out.println(apiKey); //sk-0e5049c56b0f4ad3b65119c309a7eddc + // 创建转写请求参数 + TranscriptionParam param = + TranscriptionParam.builder() + .apiKey(apiKey) + .model("paraformer-v2") + // "language_hints"只支持paraformer-v2模型 + .parameter("language_hints", new String[]{"zh", "en"}) + .fileUrls( + Arrays.asList( + "https://api.huayang-star.com/api/audio/1957424645898579969_a2db5d76-b52c-4289-9c7e-ed55d7f15e42.mp3", + "https://api.huayang-star.com/api/audio/1957424665985101825_7b9b03f4-a458-4eb6-ac7b-b5cf827a2315.mp3", + "https://api.huayang-star.com/api/audio/1957424645898579969_a2db5d76-b52c-4289-9c7e-ed55d7f15e42.mp3")) + .build(); + + try { + Transcription transcription = new Transcription(); + + System.out.println("开始提交转写请求..."); + // 提交转写请求 + TranscriptionResult result = transcription.asyncCall(param); + System.out.println("RequestId: " + result.getRequestId()); + System.out.println("TaskId: " + result.getTaskId()); + + // Loop to get task execution results until task ends + System.out.println("开始轮询任务状态..."); + int maxRetries = 60; // 最多等待60秒 + int retryCount = 0; + + while (retryCount < maxRetries) { + result = transcription.fetch(TranscriptionQueryParam.FromTranscriptionParam(param, result.getTaskId())); + System.out.println("任务状态: " + result.getTaskStatus() + " (重试次数: " + (retryCount + 1) + ")"); + + if (result.getTaskStatus() == TaskStatus.SUCCEEDED) { + System.out.println("任务成功完成!"); + List taskResultList = result.getResults(); + + + break; + } else if (result.getTaskStatus() == TaskStatus.FAILED) { + System.err.println("任务失败"); + System.exit(1); + } + + Thread.sleep(1000); + retryCount++; + } + + if (retryCount >= maxRetries) { + System.err.println("任务超时,请检查网络连接或稍后重试"); + System.exit(1); + } + + // 打印结果 + System.out.println("转写结果:"); + System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(result.getOutput())); + + } catch (Exception e) { + System.err.println("发生错误: " + e.getMessage()); + e.printStackTrace(); + + // 提供具体的错误解决建议 + if (e.getMessage().contains("AccessDenied")) { + System.err.println("\n可能的解决方案:"); + System.err.println("1. 检查API Key是否正确"); + System.err.println("2. 确认API Key有足够的权限"); + System.err.println("3. 检查音频文件URL是否可访问"); + System.err.println("4. 确认阿里云账户余额充足"); + } + } + + System.exit(0); + } +} diff --git a/src/test/java/com/rj/service/CustomerProfileAnalysisFieldMappingTest.java b/src/test/java/com/rj/service/CustomerProfileAnalysisFieldMappingTest.java deleted file mode 100644 index 4c12ba6..0000000 --- a/src/test/java/com/rj/service/CustomerProfileAnalysisFieldMappingTest.java +++ /dev/null @@ -1,420 +0,0 @@ -package com.rj.service; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.rj.entity.CustomerProfileAnalysis; -import com.rj.service.biz.ICustomerProfileAnalysisService; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import java.time.LocalDateTime; - -/** - * 客户画像分析字段映射测试 - * - * @author 李中华 - * @date 2025/1/3 - */ -@SpringBootTest -public class CustomerProfileAnalysisFieldMappingTest { - - @Autowired - private ICustomerProfileAnalysisService customerProfileAnalysisService; - - @Test - public void testFieldMapping() { - // 模拟Dify工作流输出(使用MySQL表字段名) - String difyOutputJson = """ - { - "result": { - "info": { - "dealer_code": "BJ001", - "opportunity_id": "OPP_20250103_001", - "client_id": "CLIENT_12345", - "client_name": "张三", - "client_phone": "13800138000", - "home_address": "北京市朝阳区", - "vehicle_usage": "家庭接送", - "primary_driver": "本人", - "family_composition": "已婚-1孩", - "family_size": "3", - "monthly_income": "2万-3万元", - "industry_sector": "IT互联网科技/软件行业", - "job_title": "企业职员", - "company_type": "民营企业", - "hobby": "旅游", - "education_level": "本科", - "purchase_date": "1个月内", - "purchase_type": "置换", - "budget_range": "40-50万", - "payment_way": "分期", - "current_brand": "宝马", - "competitor_brand": "奔驰", - "purchase_qualification": "是", - "interest_focus": "智能驾驶、安全性能", - "concern_point": "保养成本、保值率", - "notes": "关注安全性能" - }, - "entities": { - "entity_brand": "积极", - "entity_brand_reason": "客户对沃尔沃品牌的安全理念很认可", - "entity_design": "中性", - "entity_design_reason": "客户对外观设计没有特别偏好", - "entity_color": "积极", - "entity_color_reason": "客户喜欢深色系,认为更显档次", - "entity_size": "积极", - "entity_size_reason": "客户认为车身尺寸适中,适合城市驾驶", - "entity_space": "积极", - "entity_space_reason": "客户对车内空间很满意,特别是后排", - "entity_interior": "中性", - "entity_interior_reason": "客户对内饰材质没有特别要求", - "entity_audio": "中性", - "entity_audio_reason": "客户对音响系统没有特别关注", - "entity_ivinfo": "积极", - "entity_ivinfo_reason": "客户对车机系统的智能化很感兴趣", - "entity_fsd": "积极", - "entity_fsd_reason": "客户对自动驾驶功能很期待", - "entity_mileage": "中性", - "entity_mileage_reason": "客户对续航里程没有特别要求", - "entity_safety": "积极", - "entity_safety_reason": "客户最关注安全性能,这是主要购买动机", - "entity_eco": "积极", - "entity_eco_reason": "客户支持环保理念,认为电动车是趋势", - "entity_liscense": "中性", - "entity_liscense_reason": "客户对绿牌政策了解不多", - "entity_price": "中性", - "entity_price_reason": "客户认为价格在可接受范围内", - "entity_benefit": "积极", - "entity_benefit_reason": "客户对购车权益很满意", - "entity_cost": "中性", - "entity_cost_reason": "客户对用车成本有一定关注", - "entity_value": "积极", - "entity_value_reason": "客户认为性价比不错", - "entity_power": "中性", - "entity_power_reason": "客户对动力性能没有特别要求", - "entity_control": "中性", - "entity_control_reason": "客户对操控性能没有特别关注", - "entity_tradein": "积极", - "entity_tradein_reason": "客户对置换政策很满意", - "entity_finance": "积极", - "entity_finance_reason": "客户对金融方案很感兴趣", - "entity_warranty": "积极", - "entity_warranty_reason": "客户对质保政策很满意", - "entity_delivery": "中性", - "entity_delivery_reason": "客户对交付时间没有特别要求" - } - } - } - """; - - // 解析JSON - JSONObject outputs = JSON.parseObject(difyOutputJson); - - // 创建客户画像分析对象 - CustomerProfileAnalysis analysis = new CustomerProfileAnalysis(); - - // 设置基础字段 - analysis.setProfileAnalysisRecordId("test_ai_req_20250103_001"); - analysis.setRelatedBusinessId("test_business_12345"); - analysis.setAnalysisSceneType(1); - analysis.setInteractionDate(LocalDateTime.now()); - - // 模拟字段映射逻辑 - if (outputs.containsKey("result")) { - JSONObject result = outputs.getJSONObject("result"); - - // 解析info部分(客户基础信息) - if (result.containsKey("info")) { - JSONObject info = result.getJSONObject("info"); - - // 直接使用MySQL表字段名进行赋值 - if (info.containsKey("dealer_code")) { - analysis.setDealerCode(info.getString("dealer_code")); - } - if (info.containsKey("opportunity_id")) { - analysis.setOpportunityId(info.getString("opportunity_id")); - } - if (info.containsKey("client_id")) { - analysis.setClientId(info.getString("client_id")); - } - if (info.containsKey("client_name")) { - analysis.setClientName(info.getString("client_name")); - } - if (info.containsKey("client_phone")) { - analysis.setClientPhone(info.getString("client_phone")); - } - if (info.containsKey("home_address")) { - analysis.setHomeAddress(info.getString("home_address")); - } - if (info.containsKey("vehicle_usage")) { - analysis.setVehicleUsage(info.getString("vehicle_usage")); - } - if (info.containsKey("primary_driver")) { - analysis.setPrimaryDriver(info.getString("primary_driver")); - } - if (info.containsKey("family_composition")) { - analysis.setFamilyComposition(info.getString("family_composition")); - } - if (info.containsKey("family_size")) { - analysis.setFamilySize(info.getString("family_size")); - } - if (info.containsKey("monthly_income")) { - analysis.setMonthlyIncome(info.getString("monthly_income")); - } - if (info.containsKey("industry_sector")) { - analysis.setIndustrySector(info.getString("industry_sector")); - } - if (info.containsKey("job_title")) { - analysis.setJobTitle(info.getString("job_title")); - } - if (info.containsKey("company_type")) { - analysis.setCompanyType(info.getString("company_type")); - } - if (info.containsKey("hobby")) { - analysis.setHobby(info.getString("hobby")); - } - if (info.containsKey("education_level")) { - analysis.setEducationLevel(info.getString("education_level")); - } - if (info.containsKey("purchase_date")) { - analysis.setPurchaseDate(info.getString("purchase_date")); - } - if (info.containsKey("purchase_type")) { - analysis.setPurchaseType(info.getString("purchase_type")); - } - if (info.containsKey("budget_range")) { - analysis.setBudgetRange(info.getString("budget_range")); - } - if (info.containsKey("payment_way")) { - analysis.setPaymentWay(info.getString("payment_way")); - } - if (info.containsKey("current_brand")) { - analysis.setCurrentBrand(info.getString("current_brand")); - } - if (info.containsKey("competitor_brand")) { - analysis.setCompetitorBrand(info.getString("competitor_brand")); - } - if (info.containsKey("purchase_qualification")) { - analysis.setPurchaseQualification(info.getString("purchase_qualification")); - } - if (info.containsKey("interest_focus")) { - analysis.setInterestFocus(info.getString("interest_focus")); - } - if (info.containsKey("concern_point")) { - analysis.setConcernPoint(info.getString("concern_point")); - } - if (info.containsKey("notes")) { - analysis.setNotes(info.getString("notes")); - } - } - - // 解析entities部分(情感分析) - if (result.containsKey("entities")) { - JSONObject entities = result.getJSONObject("entities"); - - // 直接使用MySQL表字段名进行赋值 - if (entities.containsKey("entity_brand")) { - analysis.setEntityBrand(entities.getString("entity_brand")); - } - if (entities.containsKey("entity_brand_reason")) { - analysis.setEntityBrandReason(entities.getString("entity_brand_reason")); - } - if (entities.containsKey("entity_design")) { - analysis.setEntityDesign(entities.getString("entity_design")); - } - if (entities.containsKey("entity_design_reason")) { - analysis.setEntityDesignReason(entities.getString("entity_design_reason")); - } - if (entities.containsKey("entity_color")) { - analysis.setEntityColor(entities.getString("entity_color")); - } - if (entities.containsKey("entity_color_reason")) { - analysis.setEntityColorReason(entities.getString("entity_color_reason")); - } - if (entities.containsKey("entity_size")) { - analysis.setEntitySize(entities.getString("entity_size")); - } - if (entities.containsKey("entity_size_reason")) { - analysis.setEntitySizeReason(entities.getString("entity_size_reason")); - } - if (entities.containsKey("entity_space")) { - analysis.setEntitySpace(entities.getString("entity_space")); - } - if (entities.containsKey("entity_space_reason")) { - analysis.setEntitySpaceReason(entities.getString("entity_space_reason")); - } - if (entities.containsKey("entity_interior")) { - analysis.setEntityInterior(entities.getString("entity_interior")); - } - if (entities.containsKey("entity_interior_reason")) { - analysis.setEntityInteriorReason(entities.getString("entity_interior_reason")); - } - if (entities.containsKey("entity_audio")) { - analysis.setEntityAudio(entities.getString("entity_audio")); - } - if (entities.containsKey("entity_audio_reason")) { - analysis.setEntityAudioReason(entities.getString("entity_audio_reason")); - } - if (entities.containsKey("entity_ivinfo")) { - analysis.setEntityIvinfo(entities.getString("entity_ivinfo")); - } - if (entities.containsKey("entity_ivinfo_reason")) { - analysis.setEntityIvinfoReason(entities.getString("entity_ivinfo_reason")); - } - if (entities.containsKey("entity_fsd")) { - analysis.setEntityFsd(entities.getString("entity_fsd")); - } - if (entities.containsKey("entity_fsd_reason")) { - analysis.setEntityFsdReason(entities.getString("entity_fsd_reason")); - } - if (entities.containsKey("entity_mileage")) { - analysis.setEntityMileage(entities.getString("entity_mileage")); - } - if (entities.containsKey("entity_mileage_reason")) { - analysis.setEntityMileageReason(entities.getString("entity_mileage_reason")); - } - if (entities.containsKey("entity_safety")) { - analysis.setEntitySafety(entities.getString("entity_safety")); - } - if (entities.containsKey("entity_safety_reason")) { - analysis.setEntitySafetyReason(entities.getString("entity_safety_reason")); - } - if (entities.containsKey("entity_eco")) { - analysis.setEntityEco(entities.getString("entity_eco")); - } - if (entities.containsKey("entity_eco_reason")) { - analysis.setEntityEcoReason(entities.getString("entity_eco_reason")); - } - if (entities.containsKey("entity_liscense")) { - analysis.setEntityLiscense(entities.getString("entity_liscense")); - } - if (entities.containsKey("entity_liscense_reason")) { - analysis.setEntityLiscenseReason(entities.getString("entity_liscense_reason")); - } - if (entities.containsKey("entity_price")) { - analysis.setEntityPrice(entities.getString("entity_price")); - } - if (entities.containsKey("entity_price_reason")) { - analysis.setEntityPriceReason(entities.getString("entity_price_reason")); - } - if (entities.containsKey("entity_benefit")) { - analysis.setEntityBenefit(entities.getString("entity_benefit")); - } - if (entities.containsKey("entity_benefit_reason")) { - analysis.setEntityBenefitReason(entities.getString("entity_benefit_reason")); - } - if (entities.containsKey("entity_cost")) { - analysis.setEntityCost(entities.getString("entity_cost")); - } - if (entities.containsKey("entity_cost_reason")) { - analysis.setEntityCostReason(entities.getString("entity_cost_reason")); - } - if (entities.containsKey("entity_value")) { - analysis.setEntityValue(entities.getString("entity_value")); - } - if (entities.containsKey("entity_value_reason")) { - analysis.setEntityValueReason(entities.getString("entity_value_reason")); - } - if (entities.containsKey("entity_power")) { - analysis.setEntityPower(entities.getString("entity_power")); - } - if (entities.containsKey("entity_power_reason")) { - analysis.setEntityPowerReason(entities.getString("entity_power_reason")); - } - if (entities.containsKey("entity_control")) { - analysis.setEntityControl(entities.getString("entity_control")); - } - if (entities.containsKey("entity_control_reason")) { - analysis.setEntityControlReason(entities.getString("entity_control_reason")); - } - if (entities.containsKey("entity_tradein")) { - analysis.setEntityTradein(entities.getString("entity_tradein")); - } - if (entities.containsKey("entity_tradein_reason")) { - analysis.setEntityTradeinReason(entities.getString("entity_tradein_reason")); - } - if (entities.containsKey("entity_finance")) { - analysis.setEntityFinance(entities.getString("entity_finance")); - } - if (entities.containsKey("entity_finance_reason")) { - analysis.setEntityFinanceReason(entities.getString("entity_finance_reason")); - } - if (entities.containsKey("entity_warranty")) { - analysis.setEntityWarranty(entities.getString("entity_warranty")); - } - if (entities.containsKey("entity_warranty_reason")) { - analysis.setEntityWarrantyReason(entities.getString("entity_warranty_reason")); - } - if (entities.containsKey("entity_delivery")) { - analysis.setEntityDelivery(entities.getString("entity_delivery")); - } - if (entities.containsKey("entity_delivery_reason")) { - analysis.setEntityDeliveryReason(entities.getString("entity_delivery_reason")); - } - } - } - - // 设置系统字段 - LocalDateTime now = LocalDateTime.now(); - analysis.setCreatedAt(now); - analysis.setUpdatedAt(now); - analysis.setRecordVersion(0); - analysis.setIsDeleted(0); - - // 验证字段映射结果 - System.out.println("=== 客户基础信息字段映射验证 ==="); - System.out.println("详细地址: " + analysis.getHomeAddress()); - System.out.println("购车用途: " + analysis.getVehicleUsage()); - System.out.println("实际驾驶人: " + analysis.getPrimaryDriver()); - System.out.println("家庭结构: " + analysis.getFamilyComposition()); - System.out.println("家庭人数: " + analysis.getFamilySize()); - System.out.println("家庭月收入: " + analysis.getMonthlyIncome()); - System.out.println("所属行业: " + analysis.getIndustrySector()); - System.out.println("职业: " + analysis.getJobTitle()); - System.out.println("企业性质: " + analysis.getCompanyType()); - System.out.println("个人爱好: " + analysis.getHobby()); - System.out.println("教育水平: " + analysis.getEducationLevel()); - System.out.println("预购日期: " + analysis.getPurchaseDate()); - System.out.println("购买类型: " + analysis.getPurchaseType()); - System.out.println("购车预算: " + analysis.getBudgetRange()); - System.out.println("付款方式: " + analysis.getPaymentWay()); - System.out.println("保有品牌: " + analysis.getCurrentBrand()); - System.out.println("竞品品牌: " + analysis.getCompetitorBrand()); - System.out.println("购车资质: " + analysis.getPurchaseQualification()); - System.out.println("备注: " + analysis.getNotes()); - - System.out.println("\n=== 实体情感分析字段映射验证 ==="); - System.out.println("品牌情感: " + analysis.getEntityBrand()); - System.out.println("外观设计情感: " + analysis.getEntityDesign()); - System.out.println("颜色情感: " + analysis.getEntityColor()); - System.out.println("尺寸情感: " + analysis.getEntitySize()); - System.out.println("空间情感: " + analysis.getEntitySpace()); - System.out.println("内饰情感: " + analysis.getEntityInterior()); - System.out.println("音响情感: " + analysis.getEntityAudio()); - System.out.println("车机情感: " + analysis.getEntityIvinfo()); - System.out.println("智驾情感: " + analysis.getEntityFsd()); - System.out.println("续航情感: " + analysis.getEntityMileage()); - System.out.println("安全情感: " + analysis.getEntitySafety()); - System.out.println("环保情感: " + analysis.getEntityEco()); - System.out.println("绿牌情感: " + analysis.getEntityLiscense()); - System.out.println("价格情感: " + analysis.getEntityPrice()); - System.out.println("权益情感: " + analysis.getEntityBenefit()); - System.out.println("成本情感: " + analysis.getEntityCost()); - System.out.println("性价比情感: " + analysis.getEntityValue()); - System.out.println("动力情感: " + analysis.getEntityPower()); - System.out.println("操控情感: " + analysis.getEntityControl()); - System.out.println("置换情感: " + analysis.getEntityTradein()); - System.out.println("金融情感: " + analysis.getEntityFinance()); - System.out.println("质保情感: " + analysis.getEntityWarranty()); - System.out.println("交付情感: " + analysis.getEntityDelivery()); - - // 保存到数据库进行测试 - boolean saveResult = customerProfileAnalysisService.saveCustomerProfileAnalysis(analysis); - System.out.println("\n=== 数据库保存结果 ==="); - System.out.println("保存成功: " + saveResult); - if (saveResult) { - System.out.println("记录ID: " + analysis.getId()); - } - } -} diff --git a/src/test/java/com/rj/service/DifyWorkflowServiceTest.java b/src/test/java/com/rj/service/DifyWorkflowServiceTest.java new file mode 100644 index 0000000..f921f09 --- /dev/null +++ b/src/test/java/com/rj/service/DifyWorkflowServiceTest.java @@ -0,0 +1,145 @@ +package com.rj.service; + +import com.rj.service.DifyWorkflowService.DifyWorkflowRequest; +import com.rj.service.DifyWorkflowService.DifyWorkflowResponse; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Dify工作流服务测试类 + * + * @author 李中华 + * @date 2025/1/3 + */ +@SpringBootTest +@ActiveProfiles("test") +public class DifyWorkflowServiceTest { + + @Autowired + private DifyWorkflowService difyWorkflowService; + + @Test + public void testCallConsultingScenarioWorkflow() { + // 准备测试数据 + Map inputs = new HashMap<>(); + inputs.put("unionId", "test_union_12345"); + inputs.put("consultantId", "consultant_67890"); + inputs.put("communicateDate", "2025-01-03 10:30:00"); + inputs.put("analysisScene", "sales_consultation"); + inputs.put("aiAnalysisRequestId", "ai_req_20250103_001"); + inputs.put("version", 1); + inputs.put("chat", "客户:你好,我想了解一下沃尔沃XC60这款车。\n" + + "顾问:您好!很高兴为您介绍沃尔沃XC60。这是一款非常优秀的中型SUV,请问您主要关注哪些方面呢?\n" + + "客户:我比较关心安全性能和油耗表现。\n" + + "顾问:XC60在安全方面表现非常出色,配备了City Safety城市安全系统,还有Pilot Assist领航辅助系统。油耗方面,2.0T发动机百公里综合油耗约8.5L。\n" + + "客户:价格大概是多少?\n" + + "顾问:XC60的指导价在37.39-47.49万元之间,目前有优惠活动,可以优惠3万元左右。\n" + + "客户:我预算在40万以内,有什么推荐的配置吗?\n" + + "顾问:根据您的预算,我推荐智逸豪华版,指导价39.69万,优惠后36.69万,完全符合您的预算。\n" + + "客户:好的,我考虑一下,什么时候可以试驾?\n" + + "顾问:明天下午2点可以安排试驾,您方便吗?\n" + + "客户:可以的,我明天下午过去。\n" + + "顾问:好的,我为您预约明天下午2点的试驾,地址是..."); + + DifyWorkflowRequest request = new DifyWorkflowRequest(inputs, "consultant_67890"); + + try { + // 调用工作流服务 + DifyWorkflowResponse response = difyWorkflowService.callConsultingScenarioWorkflow(request); + + // 验证响应结果 + assertNotNull(response, "响应结果不应为空"); + assertNotNull(response.getData(), "响应数据不应为空"); + + System.out.println("工作流调用成功!"); + System.out.println("工作流运行ID: " + response.getWorkflowRunId()); + System.out.println("任务ID: " + response.getTaskId()); + System.out.println("响应数据: " + response.getData().toJSONString()); + + } catch (Exception e) { + System.err.println("工作流调用失败: " + e.getMessage()); + e.printStackTrace(); + // 在测试环境中,如果网络不可达或API不可用,我们不应该让测试失败 + // 这里只是记录错误,不抛出异常 + } + } + + @Test + public void testWorkflowRequestCreation() { + // 测试请求对象创建 + Map inputs = new HashMap<>(); + inputs.put("testKey", "testValue"); + + DifyWorkflowRequest request = new DifyWorkflowRequest(inputs, "testUser"); + + assertEquals(inputs, request.getInputs()); + assertEquals("testUser", request.getUserId()); + } + + @Test + public void testCallDCCScenarioWorkflow() { + // 准备DCC测试数据 + Map inputs = new HashMap<>(); + inputs.put("unionId", "dcc_union_12345"); + inputs.put("consultantId", "dcc_consultant_67890"); + inputs.put("communicateDate", "2025-01-03 14:30:00"); + inputs.put("analysisScene", "dcc_consultation"); + inputs.put("aiAnalysisRequestId", "dcc_ai_req_20250103_001"); + inputs.put("version", 1); + inputs.put("chat", "客户:您好,我想咨询一下DCC服务。\n" + + "顾问:您好!欢迎咨询DCC服务。请问您需要了解哪方面的服务呢?\n" + + "客户:我想了解一下数据中心的建设方案。\n" + + "顾问:好的,我们提供完整的数据中心建设解决方案。请问您的企业规模大概是多少?\n" + + "客户:我们是一家中型企业,大概有500名员工。\n" + + "顾问:了解了。对于500人规模的企业,我们推荐中小型数据中心方案,包括服务器、存储、网络设备等。\n" + + "客户:大概需要多少预算?\n" + + "顾问:根据您的规模,预计投资在200-300万元左右,包括硬件设备、软件许可和建设费用。\n" + + "客户:建设周期大概多长?\n" + + "顾问:从设计到交付,大概需要3-4个月的时间。\n" + + "客户:好的,我需要和公司讨论一下,什么时候可以安排详细的技术交流?\n" + + "顾问:明天上午10点可以安排技术交流,您方便吗?\n" + + "客户:可以的,我明天上午过去。\n" + + "顾问:好的,我为您预约明天上午10点的技术交流,地址是..."); + + DifyWorkflowRequest request = new DifyWorkflowRequest(inputs, "dcc_consultant_67890"); + + try { + // 调用DCC工作流服务 + DifyWorkflowResponse response = difyWorkflowService.callDCCScenarioWorkflow(request); + + // 验证响应结果 + assertNotNull(response, "DCC响应结果不应为空"); + assertNotNull(response.getWorkflowRunId(), "DCC工作流运行ID不应为空"); + assertNotNull(response.getData(), "DCC响应数据不应为空"); + + System.out.println("DCC工作流调用成功!"); + System.out.println("DCC工作流运行ID: " + response.getWorkflowRunId()); + System.out.println("DCC任务ID: " + response.getTaskId()); + System.out.println("DCC响应数据: " + response.getData().toJSONString()); + + } catch (Exception e) { + System.err.println("DCC工作流调用失败: " + e.getMessage()); + e.printStackTrace(); + // 在测试环境中,如果网络不可达或API不可用,我们不应该让测试失败 + // 这里只是记录错误,不抛出异常 + } + } + + @Test + public void testWorkflowResponseCreation() { + // 测试响应对象创建 + DifyWorkflowResponse response = new DifyWorkflowResponse(); + response.setWorkflowRunId("test_run_id"); + response.setTaskId("test_task_id"); + + assertEquals("test_run_id", response.getWorkflowRunId()); + assertEquals("test_task_id", response.getTaskId()); + } +} diff --git a/src/test/java/com/rj/speech/DownloadParse.java b/src/test/java/com/rj/speech/DownloadParse.java new file mode 100644 index 0000000..ddd72a6 --- /dev/null +++ b/src/test/java/com/rj/speech/DownloadParse.java @@ -0,0 +1,171 @@ +package com.rj.speech; + +import com.google.gson.*; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +/** + * 快速语音识别结果演示 + * 直接测试您提供的transcription_url + * Author: Li Zhonghua wx: spllzh email(qq): 28668817@qq.com + * Date: 2025/8/24 + */ +public class DownloadParse { + + public static void main(String[] args) { + System.out.println("🎤 快速语音识别结果演示"); + System.out.println("=================================="); + + // 您提供的transcription_url + String transcriptionUrl = "https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/prod/paraformer-v2/20250824/10%3A42/83ab4e35-2db8-4eea-b890-7a6ed353f722-1.json?Expires=1756089779&OSSAccessKeyId=LTAI5tQZd8AEcZX6KZV4G8qL&Signature=KzkVdetZnpVu1WkLqt6PRMtjIxU%3D"; + + try { + System.out.println("📥 开始下载识别结果..."); + System.out.println("URL: " + transcriptionUrl); + + String jsonContent = downloadTranscriptionResult(transcriptionUrl); + + if (jsonContent != null) { + System.out.println("✅ 下载成功,开始解析..."); + parseAndOutputTranscription(jsonContent); + } else { + System.err.println("❌ 下载失败"); + } + + } catch (Exception e) { + System.err.println("💥 发生错误: " + e.getMessage()); + e.printStackTrace(); + } + + System.out.println("\n🏁 演示完成"); + } + + /** + * 下载识别结果文件 + */ + private static String downloadTranscriptionResult(String transcriptionUrl) { + try { + System.out.println("正在下载识别结果..."); + + HttpURLConnection connection = (HttpURLConnection) new URL(transcriptionUrl).openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(10000); + connection.setReadTimeout(30000); + connection.connect(); + + if (connection.getResponseCode() == 200) { + BufferedReader reader = new BufferedReader( + new InputStreamReader(connection.getInputStream(), "UTF-8") + ); + + StringBuilder content = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + content.append(line); + } + reader.close(); + + System.out.println("下载完成,文件大小: " + content.length() + " 字符"); + return content.toString(); + } else { + System.err.println("下载失败,HTTP状态码: " + connection.getResponseCode()); + return null; + } + + } catch (Exception e) { + System.err.println("下载识别结果时发生错误: " + e.getMessage()); + return null; + } + } + + /** + * 解析并输出识别内容 + */ + private static void parseAndOutputTranscription(String jsonContent) { + try { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + JsonObject jsonObject = gson.fromJson(jsonContent, JsonObject.class); + + System.out.println("\n🎉 识别内容解析结果:"); + System.out.println("=================================="); + + if (jsonObject.has("transcripts")) { + JsonArray transcripts = jsonObject.getAsJsonArray("transcripts"); + + for (JsonElement transcriptElement : transcripts) { + JsonObject transcript = transcriptElement.getAsJsonObject(); + + if (transcript.has("sentences")) { + JsonArray sentences = transcript.getAsJsonArray("sentences"); + + System.out.println("🗣️ 识别到的文本内容:"); + System.out.println("----------------------------------------"); + + StringBuilder fullText = new StringBuilder(); + + for (JsonElement sentenceElement : sentences) { + JsonObject sentence = sentenceElement.getAsJsonObject(); + + String content = ""; + String startTime = ""; + String endTime = ""; + String speakerId = "未知"; + + if (sentence.has("text")) { + content = sentence.get("text").getAsString(); + fullText.append(content).append(" "); + } + if (sentence.has("begin_time")) { + startTime = formatTime(sentence.get("begin_time").getAsDouble()); + } + if (sentence.has("end_time")) { + endTime = formatTime(sentence.get("end_time").getAsDouble()); + } + if (sentence.has("speaker_id")) { + speakerId = sentence.get("speaker_id").getAsString(); + } + + // 输出带时间戳和说话人ID的句子 + if (!"未知".equals(speakerId)) { + System.out.printf("👤 说话人%s [%s - %s]: %s\n", speakerId, startTime, endTime, content); + } else { + System.out.printf("💬 [%s - %s]: %s\n", startTime, endTime, content); + } + } + + System.out.println("----------------------------------------"); + System.out.println("📝 完整识别文本:"); + System.out.println(fullText.toString().trim()); + System.out.println("----------------------------------------"); + System.out.println("✅ 识别内容解析完成"); + } + } + } else { + System.out.println("⚠️ 未找到识别文本内容"); + // 输出原始JSON以便调试 + System.out.println("原始JSON内容:"); + System.out.println(gson.toJson(jsonObject)); + } + + } catch (Exception e) { + System.err.println("❌ 解析识别内容失败: " + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * 格式化时间显示 + */ + private static String formatTime(double milliseconds) { + int minutes = (int) (milliseconds / 60000); + int secs = (int) ((milliseconds % 60000) / 1000); + int millis = (int) (milliseconds % 1000); + return String.format("%02d:%02d.%03d", minutes, secs, millis); + } +}