main
HuangHai 1 month ago
parent 035eed1882
commit aca663f6f4

@ -0,0 +1,91 @@
# **云南省文山州与楚雄州教育数据综合分析报告2012-2035年**
## **一、引言**
云南省文山州与楚雄州作为边疆民族地区其教育发展状况对区域经济社会进步具有重要意义。本报告基于2012-2035年的教育数据从学前教育、义务教育小学、初中到高中阶段教育的招生、在校生规模、城乡分布及资源供需等方面进行综合分析揭示两州教育发展的核心趋势与挑战并提出优化建议。
---
## **二、关键数据分析**
### **1. 学前教育2012-2035年**
#### **1总在园人数变化**
- **文山州**2012年8.22万人持续增长至2022年16.88万人峰值随后缓慢下降至2035年14.83万人呈现“倒U型”趋势。2020年出现显著跃升15.82万人),可能与普惠性幼儿园政策推动有关。
- **楚雄州**规模较小从2012年5.11万人增至2022年7.5万人峰值2035年降至6.64万人,增速较文山州缓和。
#### **2城乡结构**
- **城区**两州均稳步增长。文山州城区占比从12.7%2012年升至16.3%2035年楚雄州从18.2%升至35.5%,反映城镇化对学前教育的拉动作用。
- **乡村**文山州乡村在园人数2020年激增8.14万人后逐步回落楚雄州则持续下降2035年占比仅12.2%,凸显乡村生源萎缩问题。
#### **3区域差异**
- 文山州总规模约为楚雄州的2倍但楚雄州城区教育发展更快2035年城区占比高出文山州19个百分点
- 文山州乡村教育需求更显著而楚雄州乡村生源流失明显2035年人数仅为2012年的35.5%)。
### **2. 义务教育(小学、初中)**
#### **1招生总量**
- **小学阶段**
- 文山州2012-2021年波动上升5.41万→6.49万2022年起显著下降2035年预测4.8万)。
- 楚雄州持续下降2012年2.79万→2035年2.01万降幅28%。
- **初中阶段**
- 文山州2012-2022年先降后升5.65万→6.49万2035年预测5.7万。
- 楚雄州整体下降2012年3.42万→2035年2.26万降幅34%。
#### **2在校生规模**
- **文山州小学**2012-2021年持续增长34.54万→38.2万2035年降至32.02万。
- **楚雄州小学**2012年19.25万→2035年13.12万降幅31.8%。
- **城乡分化**
- 城区在校生占比显著提升文山州小学城区占比从5.4%升至14.5%)。
- 乡村在校生锐减楚雄州初中乡村生源从3.66万→0.24万2035年占比仅3.6%)。
### **3. 高中阶段教育**
#### **1招生规模**
- **文山州**2012年1.7万人→2021年峰值3.11万人→2035年回落至2.78万人。
- **楚雄州**2012年1.53万人→2022年1.8万人→2035年回落至1.53万人。
#### **2城乡分布**
- 两州在校生以镇区为主文山州镇区占比超80%),城区次之,乡村占比极低。
- 楚雄州城区招生占比显著提升2012年36%→2035年54%)。
---
## **三、核心问题与挑战**
### **1. 城镇化驱动的城乡教育失衡**
- **城区压力增大**两州城区在校生占比持续上升如楚雄州初中城区占比从12.3%升至30.5%),导致学位紧张。
- **乡村资源闲置**乡村生源锐减如楚雄州乡村初中生源2035年仅剩0.07万),部分学校面临整合或关闭。
### **2. 人口结构变化影响教育需求**
- **学龄人口下降**两州小学、初中招生总量均呈下降趋势如楚雄州小学招生减少28%),需调整师资与设施配置。
- **低生育率与人口外流**:楚雄州义务教育阶段总规模萎缩明显,可能反映本地生育率下降或青壮年外流。
### **3. 教育资源结构性矛盾**
- **师资供需失衡**
- 文山州小学师资富余2035年富余2100人但高中师资缺口800人。
- 楚雄州小学师资富余801人高中缺口500人。
- **校舍利用率不均**小学、初中用房富余文山州小学富余52.07万㎡),但需优化城乡布局。
---
## **四、政策建议**
### **1. 优化城乡教育资源配置**
- **城区扩容**:增加城区学位供给,扩建或新建学校应对人口集聚。
- **乡村整合**:推动小规模学校集约化发展,探索“中心校+教学点”模式。
### **2. 动态调整师资与设施**
- **教师转岗培训**:引导富余小学教师向高中或紧缺学科转岗。
- **校舍功能转型**:闲置乡村校舍可改造为社区教育中心或普惠性幼儿园。
### **3. 加强人口监测与规划**
- **建立学龄人口预警机制**:结合生育率、迁移数据动态调整教育资源。
- **中长期规划**:文山州需关注高中资源补充,楚雄州应优化镇区学校布局。
### **4. 保障教育公平与质量**
- **倾斜支持乡村教育**:加强留守儿童关爱,提升边疆学校(如文山州“国门学校”)保障水平。
- **推动教师流动**:鼓励城区教师支教乡村,均衡师资配置。
---
## **五、结论**
文山州与楚雄州的教育发展呈现明显的城镇化驱动特征,乡村生源萎缩与城区资源紧张并存。未来需通过精准规划、动态调整和结构性改革,实现教育资源的高效配置,确保教育公平与质量同步提升,为区域可持续发展提供人力支撑。
字数2980

@ -5,6 +5,7 @@ import com.dsideal.base.Util.LocalMysqlConnectUtil;
import com.jfinal.plugin.activerecord.Db; import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record; import com.jfinal.plugin.activerecord.Record;
import com.dsideal.base.Util.CallDeepSeek; import com.dsideal.base.Util.CallDeepSeek;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -13,7 +14,9 @@ import java.util.ArrayList;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import java.io.File; import java.io.File;
public class TestMax32K { public class TestMax32K {
@ -21,27 +24,27 @@ public class TestMax32K {
public static void main(String[] args) { public static void main(String[] args) {
LocalMysqlConnectUtil.Init(); LocalMysqlConnectUtil.Init();
// 直接调用生成综合报告 // 直接调用生成综合报告
String report = generateComprehensiveReport(); String report = generateComprehensiveReport();
System.out.println("\n=== 最终报告 ==="); System.out.println("\n=== 最终报告 ===");
System.out.println(report); System.out.println(report);
} }
/** /**
* *
*/ */
private static List<String> splitLargeTable(String tableName, Set<String> fieldNames, private static List<String> splitLargeTable(Set<String> fieldNames,
List<Record> allTableData, int maxSize) { List<Record> allTableData, int maxSize) {
List<String> chunks = new ArrayList<>(); List<String> chunks = new ArrayList<>();
StringBuilder currentTableChunk = new StringBuilder(); StringBuilder currentTableChunk = new StringBuilder();
for (Record dataRecord : allTableData) { for (Record dataRecord : allTableData) {
Map<String, Object> columns = dataRecord.getColumns(); Map<String, Object> columns = dataRecord.getColumns();
StringBuilder rowData = new StringBuilder(); StringBuilder rowData = new StringBuilder();
rowData.append("["); rowData.append("[");
boolean first = true; boolean first = true;
for (String fieldName : fieldNames) { for (String fieldName : fieldNames) {
if (!first) rowData.append(","); if (!first) rowData.append(",");
@ -54,7 +57,7 @@ public class TestMax32K {
first = false; first = false;
} }
rowData.append("]\n"); rowData.append("]\n");
// 检查是否超过限制 // 检查是否超过限制
if (currentTableChunk.length() + rowData.length() > maxSize) { if (currentTableChunk.length() + rowData.length() > maxSize) {
if (currentTableChunk.length() > 0) { if (currentTableChunk.length() > 0) {
@ -64,59 +67,50 @@ public class TestMax32K {
} }
currentTableChunk.append(rowData); currentTableChunk.append(rowData);
} }
if (currentTableChunk.length() > 0) { if (currentTableChunk.length() > 0) {
chunks.add(currentTableChunk.toString()); chunks.add(currentTableChunk.toString());
} }
return chunks; return chunks;
} }
/**
*
*/
public static String[] getDataChunks() {
// 这里可以将main方法中的逻辑提取出来返回分块数据
// 为了简化,这里只是示例
return new String[]{"示例数据块1", "示例数据块2"};
}
public static String generateComprehensiveReport() { public static String generateComprehensiveReport() {
String[] regions = {"文山州", "楚雄州"}; 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')"; 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); List<Record> tableList = Db.use(DataEaseModel.DB_NAME).find(sql);
// 获取分块数据 // 获取分块数据
String[] dataChunks = getDataChunks(regions, tableList); String[] dataChunks = getDataChunks(regions, tableList);
List<String> chunkAnalyses = new ArrayList<>(); List<String> chunkAnalyses = new ArrayList<>();
System.out.println("开始分析 " + dataChunks.length + " 个数据块..."); System.out.println("开始分析 " + dataChunks.length + " 个数据块...");
// 第一阶段:流式分析各个数据块 // 第一阶段:流式分析各个数据块
for (int i = 0; i < dataChunks.length; i++) { for (int i = 0; i < dataChunks.length; i++) {
final int chunkIndex = i; final int chunkIndex = i;
final StringBuilder chunkResult = new StringBuilder(); final StringBuilder chunkResult = new StringBuilder();
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
String prompt = "请对以下教育数据进行简要分析重点关注关键指标和趋势控制在500字以内\n" + dataChunks[i]; String prompt = "请对以下教育数据进行简要分析重点关注关键指标和趋势控制在500字以内\n" + dataChunks[i];
System.out.println("\n=== 正在分析第 " + (i + 1) + " 个数据块 ==="); System.out.println("\n=== 正在分析第 " + (i + 1) + " 个数据块 ===");
CallDeepSeek.callDeepSeekStream(prompt, new CallDeepSeek.SSEListener() { CallDeepSeek.callDeepSeekStream(prompt, new CallDeepSeek.SSEListener() {
@Override @Override
public void onData(String data) { public void onData(String data) {
System.out.print(data); System.out.print(data);
chunkResult.append(data); chunkResult.append(data);
} }
@Override @Override
public void onComplete(String fullResponse) { public void onComplete(String fullResponse) {
System.out.println("\n--- 第 " + (chunkIndex + 1) + " 个数据块分析完成 ---\n"); System.out.println("\n--- 第 " + (chunkIndex + 1) + " 个数据块分析完成 ---\n");
chunkAnalyses.add(chunkResult.toString()); chunkAnalyses.add(chunkResult.toString());
latch.countDown(); latch.countDown();
} }
@Override @Override
public void onError(String error) { public void onError(String error) {
System.err.println("分析第 " + (chunkIndex + 1) + " 个数据块时出错: " + error); System.err.println("分析第 " + (chunkIndex + 1) + " 个数据块时出错: " + error);
@ -124,7 +118,7 @@ public class TestMax32K {
latch.countDown(); latch.countDown();
} }
}); });
try { try {
// 等待当前块分析完成 // 等待当前块分析完成
latch.await(); latch.await();
@ -133,47 +127,47 @@ public class TestMax32K {
System.err.println("等待分析结果时被中断: " + e.getMessage()); System.err.println("等待分析结果时被中断: " + e.getMessage());
} }
} }
// 第二阶段:流式生成综合报告 // 第二阶段:流式生成综合报告
System.out.println("\n=== 开始生成综合分析报告 ==="); System.out.println("\n=== 开始生成综合分析报告 ===");
StringBuilder combinedAnalysis = new StringBuilder(); StringBuilder combinedAnalysis = new StringBuilder();
combinedAnalysis.append("基于以下分块分析结果请生成一份完整的教育数据综合分析报告3000字以内\n\n"); combinedAnalysis.append("基于以下分块分析结果请生成一份完整的教育数据综合分析报告3000字以内\n\n");
for (int i = 0; i < chunkAnalyses.size(); i++) { for (int i = 0; i < chunkAnalyses.size(); i++) {
combinedAnalysis.append("数据块").append(i + 1).append("分析:\n"); combinedAnalysis.append("数据块").append(i + 1).append("分析:\n");
combinedAnalysis.append(chunkAnalyses.get(i)).append("\n\n"); combinedAnalysis.append(chunkAnalyses.get(i)).append("\n\n");
} }
final StringBuilder finalReport = new StringBuilder(); final StringBuilder finalReport = new StringBuilder();
final CountDownLatch finalLatch = new CountDownLatch(1); final CountDownLatch finalLatch = new CountDownLatch(1);
CallDeepSeek.callDeepSeekStream(combinedAnalysis.toString(), new CallDeepSeek.SSEListener() { CallDeepSeek.callDeepSeekStream(combinedAnalysis.toString(), new CallDeepSeek.SSEListener() {
@Override @Override
public void onData(String data) { public void onData(String data) {
System.out.print(data); System.out.print(data);
finalReport.append(data); finalReport.append(data);
} }
@Override @Override
public void onComplete(String fullResponse) { public void onComplete(String fullResponse) {
System.out.println("\n\n=== 综合分析报告生成完成 ==="); System.out.println("\n\n=== 综合分析报告生成完成 ===");
// 保存报告到文件 // 保存报告到文件
try { try {
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String fileName = "教育数据综合分析报告_" + timestamp + ".txt"; String fileName = "教育数据综合分析报告_" + timestamp + ".txt";
String filePath = "WebRoot/upload/" + fileName; String filePath = "WebRoot/upload/" + fileName;
FileUtil.writeString(finalReport.toString(), new File(filePath), "UTF-8"); FileUtil.writeString(finalReport.toString(), new File(filePath), "UTF-8");
System.out.println("报告已保存到: " + filePath); System.out.println("报告已保存到: " + filePath);
} catch (Exception e) { } catch (Exception e) {
System.err.println("保存报告时出错: " + e.getMessage()); System.err.println("保存报告时出错: " + e.getMessage());
} }
finalLatch.countDown(); finalLatch.countDown();
} }
@Override @Override
public void onError(String error) { public void onError(String error) {
System.err.println("生成综合报告时出错: " + error); System.err.println("生成综合报告时出错: " + error);
@ -181,41 +175,41 @@ public class TestMax32K {
finalLatch.countDown(); finalLatch.countDown();
} }
}); });
try { try {
finalLatch.await(); finalLatch.await();
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.err.println("等待最终报告时被中断: " + e.getMessage()); System.err.println("等待最终报告时被中断: " + e.getMessage());
} }
return finalReport.toString(); return finalReport.toString();
} }
/** /**
* *
*/ */
private static String[] getDataChunks(String[] regions, List<Record> tableList) { private static String[] getDataChunks(String[] regions, List<Record> tableList) {
List<String> dataChunks = new ArrayList<>(); List<String> dataChunks = new ArrayList<>();
StringBuilder currentChunk = new StringBuilder(); StringBuilder currentChunk = new StringBuilder();
String header = "数据说明: 以下是云南省教育数据的压缩格式\n" + String header = "数据说明: 以下是云南省教育数据的压缩格式\n" +
"格式: 表名 -> 字段列表 -> 数据行(数组格式)\n" + "格式: 表名 -> 字段列表 -> 数据行(数组格式)\n" +
"地区范围: " + String.join(",", regions) + "\n\n"; "地区范围: " + String.join(",", regions) + "\n\n";
currentChunk.append(header); currentChunk.append(header);
// 遍历所有相关数据表 // 遍历所有相关数据表
for (Record record : tableList) { for (Record record : tableList) {
String tableName = record.getStr("TABLE_NAME"); String tableName = record.getStr("TABLE_NAME");
// 为当前表收集所有数据 // 为当前表收集所有数据
List<Record> allTableData = new ArrayList<>(); List<Record> allTableData = new ArrayList<>();
Set<String> fieldNames = new LinkedHashSet<>(); Set<String> fieldNames = new LinkedHashSet<>();
// 为每个地区收集数据 // 为每个地区收集数据
for (String region : regions) { for (String region : regions) {
String sql = "select * from `" + tableName + "` where `行政区划`=?"; String sql = "select * from `" + tableName + "` where `行政区划`=?";
List<Record> listContent = Db.use(DataEaseModel.DB_NAME).find(sql, region); List<Record> listContent = Db.use(DataEaseModel.DB_NAME).find(sql, region);
if (!listContent.isEmpty()) { if (!listContent.isEmpty()) {
allTableData.addAll(listContent); allTableData.addAll(listContent);
// 收集字段名(使用第一条记录的字段结构) // 收集字段名(使用第一条记录的字段结构)
@ -224,18 +218,18 @@ public class TestMax32K {
} }
} }
} }
if (!allTableData.isEmpty()) { if (!allTableData.isEmpty()) {
// 构建当前表的完整数据块 // 构建当前表的完整数据块
StringBuilder tableData = new StringBuilder(); StringBuilder tableData = new StringBuilder();
tableData.append("\n表: ").append(tableName).append("\n"); tableData.append("\n表: ").append(tableName).append("\n");
tableData.append("字段: ").append(String.join(",", fieldNames)).append("\n"); tableData.append("字段: ").append(String.join(",", fieldNames)).append("\n");
// 输出压缩格式的数据 // 输出压缩格式的数据
for (Record dataRecord : allTableData) { for (Record dataRecord : allTableData) {
Map<String, Object> columns = dataRecord.getColumns(); Map<String, Object> columns = dataRecord.getColumns();
tableData.append("["); tableData.append("[");
boolean first = true; boolean first = true;
for (String fieldName : fieldNames) { for (String fieldName : fieldNames) {
if (!first) tableData.append(","); if (!first) tableData.append(",");
@ -247,10 +241,10 @@ public class TestMax32K {
} }
first = false; first = false;
} }
tableData.append("]\n"); tableData.append("]\n");
} }
// 检查是否需要分块 // 检查是否需要分块
String tableDataStr = tableData.toString(); String tableDataStr = tableData.toString();
if (currentChunk.length() + tableDataStr.length() > MAX_CHUNK_SIZE) { if (currentChunk.length() + tableDataStr.length() > MAX_CHUNK_SIZE) {
@ -260,10 +254,10 @@ public class TestMax32K {
currentChunk = new StringBuilder(); currentChunk = new StringBuilder();
currentChunk.append(header); currentChunk.append(header);
} }
// 如果单个表数据超过限制,需要进一步分割 // 如果单个表数据超过限制,需要进一步分割
if (tableDataStr.length() > MAX_CHUNK_SIZE - header.length()) { if (tableDataStr.length() > MAX_CHUNK_SIZE - header.length()) {
List<String> tableChunks = splitLargeTable(tableName, fieldNames, allTableData, MAX_CHUNK_SIZE - header.length()); List<String> tableChunks = splitLargeTable(fieldNames, allTableData, MAX_CHUNK_SIZE - header.length());
for (int i = 0; i < tableChunks.size(); i++) { for (int i = 0; i < tableChunks.size(); i++) {
StringBuilder chunkBuilder = new StringBuilder(); StringBuilder chunkBuilder = new StringBuilder();
chunkBuilder.append(header); chunkBuilder.append(header);
@ -280,12 +274,12 @@ public class TestMax32K {
} }
} }
} }
// 添加最后一个块 // 添加最后一个块
if (currentChunk.length() > header.length()) { if (currentChunk.length() > header.length()) {
dataChunks.add(currentChunk.toString()); dataChunks.add(currentChunk.toString());
} }
return dataChunks.toArray(new String[0]); return dataChunks.toArray(new String[0]);
} }
} }

Loading…
Cancel
Save