package com.dsideal.base.AI ;
import com.dsideal.base.DataEase.Model.DataEaseModel ;
import com.dsideal.base.Util.LocalMysqlConnectUtil ;
import com.jfinal.plugin.activerecord.Db ;
import com.jfinal.plugin.activerecord.Record ;
import com.dsideal.base.Util.CallDeepSeek ;
import java.util.List ;
import java.util.Map ;
import java.util.Set ;
import java.util.LinkedHashSet ;
import java.util.ArrayList ;
import java.util.concurrent.CountDownLatch ;
import java.text.SimpleDateFormat ;
import java.util.Date ;
import cn.hutool.core.io.FileUtil ;
import java.io.File ;
public class TestMax32K {
private static final int MAX_CHUNK_SIZE = 30000 ; // 30K字符限制
public static void main ( String [ ] args ) {
LocalMysqlConnectUtil . Init ( ) ;
// 直接调用生成综合报告
String report = generateComprehensiveReport ( ) ;
System . out . println ( "\n=== 最终报告 ===" ) ;
System . out . println ( report ) ;
}
/ * *
* 分 割 过 大 的 单 表 数 据
* /
private static List < String > splitLargeTable ( Set < String > fieldNames ,
List < Record > allTableData , int maxSize ) {
List < String > chunks = new ArrayList < > ( ) ;
StringBuilder currentTableChunk = new StringBuilder ( ) ;
for ( Record dataRecord : allTableData ) {
Map < String , Object > columns = dataRecord . getColumns ( ) ;
StringBuilder rowData = new StringBuilder ( ) ;
rowData . append ( "[" ) ;
boolean first = true ;
for ( String fieldName : fieldNames ) {
if ( ! first ) rowData . append ( "," ) ;
Object value = columns . get ( fieldName ) ;
if ( value instanceof String ) {
rowData . append ( "\"" ) . append ( value ) . append ( "\"" ) ;
} else {
rowData . append ( value ) ;
}
first = false ;
}
rowData . append ( "]\n" ) ;
// 检查是否超过限制
if ( currentTableChunk . length ( ) + rowData . length ( ) > maxSize ) {
if ( ! currentTableChunk . isEmpty ( ) ) {
chunks . add ( currentTableChunk . toString ( ) ) ;
currentTableChunk = new StringBuilder ( ) ;
}
}
currentTableChunk . append ( rowData ) ;
}
if ( ! currentTableChunk . isEmpty ( ) ) {
chunks . add ( currentTableChunk . toString ( ) ) ;
}
return chunks ;
}
public static String generateComprehensiveReport ( ) {
String [ ] regions = { "文山州" , "楚雄州" } ;
String sql = "select table_name as TABLE_NAME from core_dataset_table where dataset_group_id in (select id from core_dataset_group where pid='1036317909951057920')" ;
List < Record > tableList = Db . use ( DataEaseModel . DB_NAME ) . find ( sql ) ;
// 获取分块数据
String [ ] dataChunks = getDataChunks ( regions , tableList ) ;
System . out . println ( "开始逐步提交 " + dataChunks . length + " 个数据块..." ) ;
final StringBuilder finalReport = new StringBuilder ( ) ;
final CountDownLatch finalLatch = new CountDownLatch ( 1 ) ;
// 逐步提交数据块
for ( int i = 0 ; i < dataChunks . length ; i + + ) {
final int chunkIndex = i ;
final boolean isLastChunk = ( i = = dataChunks . length - 1 ) ;
String prompt ;
if ( isLastChunk ) {
// 最后一个数据块:要求返回完整分析报告
prompt = "这是最后一部分教育数据, 请基于之前提交的所有数据生成一份完整的综合分析报告( 3000字以内) : \n" + dataChunks [ i ] ;
} else {
// 中间数据块:只提交数据,不要求返回分析
prompt = "这是第" + ( i + 1 ) + "部分教育数据,共" + dataChunks . length + "部分,请接收并记录,暂不需要分析:\n" + dataChunks [ i ] ;
}
System . out . println ( "\n=== 提交第 " + ( i + 1 ) + "/" + dataChunks . length + " 个数据块 ===" ) ;
final CountDownLatch chunkLatch = new CountDownLatch ( 1 ) ;
CallDeepSeek . callDeepSeekStream ( prompt , new CallDeepSeek . SSEListener ( ) {
@Override
public void onData ( String data ) {
if ( isLastChunk ) {
// 只有最后一个数据块才显示和保存返回内容
System . out . print ( data ) ;
finalReport . append ( data ) ;
} else {
// 中间数据块的响应不显示(或只显示确认信息)
// System.out.print("."); // 可选:显示进度点
}
}
@Override
public void onComplete ( String fullResponse ) {
if ( isLastChunk ) {
System . out . println ( "\n\n=== 综合分析报告生成完成 ===" ) ;
// 保存报告到文件
try {
String timestamp = new SimpleDateFormat ( "yyyyMMdd_HHmmss" ) . format ( new Date ( ) ) ;
String fileName = "教育数据综合分析报告_" + timestamp + ".txt" ;
String filePath = "WebRoot/upload/" + fileName ;
FileUtil . writeString ( finalReport . toString ( ) , new File ( filePath ) , "UTF-8" ) ;
System . out . println ( "报告已保存到: " + filePath ) ;
} catch ( Exception e ) {
System . err . println ( "保存报告时出错: " + e . getMessage ( ) ) ;
}
finalLatch . countDown ( ) ;
} else {
System . out . println ( "第 " + ( chunkIndex + 1 ) + " 个数据块已提交" ) ;
}
chunkLatch . countDown ( ) ;
}
@Override
public void onError ( String error ) {
System . err . println ( "提交第 " + ( chunkIndex + 1 ) + " 个数据块时出错: " + error ) ;
if ( isLastChunk ) {
finalReport . append ( "生成失败: " ) . append ( error ) ;
finalLatch . countDown ( ) ;
}
chunkLatch . countDown ( ) ;
}
} ) ;
try {
// 等待当前块处理完成
chunkLatch . await ( ) ;
if ( ! isLastChunk ) {
Thread . sleep ( 1000 ) ; // 中间块之间稍微延迟
}
} catch ( InterruptedException e ) {
System . err . println ( "等待数据块处理时被中断: " + e . getMessage ( ) ) ;
}
}
try {
finalLatch . await ( ) ;
} catch ( InterruptedException e ) {
System . err . println ( "等待最终报告时被中断: " + e . getMessage ( ) ) ;
}
return finalReport . toString ( ) ;
}
/ * *
* 提 取 数 据 分 块 逻 辑 为 独 立 方 法
* /
private static String [ ] getDataChunks ( String [ ] regions , List < Record > tableList ) {
List < String > dataChunks = new ArrayList < > ( ) ;
StringBuilder currentChunk = new StringBuilder ( ) ;
String header = "数据说明: 以下是云南省教育数据的压缩格式\n" +
"格式: 表名 -> 字段列表 -> 数据行(数组格式)\n" +
"地区范围: " + String . join ( "," , regions ) + "\n\n" ;
currentChunk . append ( header ) ;
// 遍历所有相关数据表
for ( Record record : tableList ) {
String tableName = record . getStr ( "TABLE_NAME" ) ;
// 为当前表收集所有数据
List < Record > allTableData = new ArrayList < > ( ) ;
Set < String > fieldNames = new LinkedHashSet < > ( ) ;
// 为每个地区收集数据
for ( String region : regions ) {
String sql = "select * from `" + tableName + "` where `行政区划`=?" ;
List < Record > listContent = Db . use ( DataEaseModel . DB_NAME ) . find ( sql , region ) ;
if ( ! listContent . isEmpty ( ) ) {
allTableData . addAll ( listContent ) ;
// 收集字段名(使用第一条记录的字段结构)
if ( fieldNames . isEmpty ( ) ) {
fieldNames . addAll ( listContent . get ( 0 ) . getColumns ( ) . keySet ( ) ) ;
}
}
}
if ( ! allTableData . isEmpty ( ) ) {
// 构建当前表的完整数据块
StringBuilder tableData = new StringBuilder ( ) ;
tableData . append ( "\n表: " ) . append ( tableName ) . append ( "\n" ) ;
tableData . append ( "字段: " ) . append ( String . join ( "," , fieldNames ) ) . append ( "\n" ) ;
// 输出压缩格式的数据
for ( Record dataRecord : allTableData ) {
Map < String , Object > columns = dataRecord . getColumns ( ) ;
tableData . append ( "[" ) ;
boolean first = true ;
for ( String fieldName : fieldNames ) {
if ( ! first ) tableData . append ( "," ) ;
Object value = columns . get ( fieldName ) ;
if ( value instanceof String ) {
tableData . append ( "\"" ) . append ( value ) . append ( "\"" ) ;
} else {
tableData . append ( value ) ;
}
first = false ;
}
tableData . append ( "]\n" ) ;
}
// 检查是否需要分块
String tableDataStr = tableData . toString ( ) ;
if ( currentChunk . length ( ) + tableDataStr . length ( ) > MAX_CHUNK_SIZE ) {
// 当前块已满,保存并开始新块
if ( currentChunk . length ( ) > header . length ( ) ) {
dataChunks . add ( currentChunk . toString ( ) ) ;
currentChunk = new StringBuilder ( ) ;
currentChunk . append ( header ) ;
}
// 如果单个表数据超过限制,需要进一步分割
if ( tableDataStr . length ( ) > MAX_CHUNK_SIZE - header . length ( ) ) {
List < String > tableChunks = splitLargeTable ( fieldNames , allTableData , MAX_CHUNK_SIZE - header . length ( ) ) ;
for ( int i = 0 ; i < tableChunks . size ( ) ; i + + ) {
StringBuilder chunkBuilder = new StringBuilder ( ) ;
chunkBuilder . append ( header ) ;
chunkBuilder . append ( "\n[续] 表: " ) . append ( tableName ) . append ( " (第" ) . append ( i + 1 ) . append ( "部分)\n" ) ;
chunkBuilder . append ( "字段: " ) . append ( String . join ( "," , fieldNames ) ) . append ( "\n" ) ;
chunkBuilder . append ( tableChunks . get ( i ) ) ;
dataChunks . add ( chunkBuilder . toString ( ) ) ;
}
} else {
currentChunk . append ( tableDataStr ) ;
}
} else {
currentChunk . append ( tableDataStr ) ;
}
}
}
// 添加最后一个块
if ( currentChunk . length ( ) > header . length ( ) ) {
dataChunks . add ( currentChunk . toString ( ) ) ;
}
return dataChunks . toArray ( new String [ 0 ] ) ;
}
}