|
|
|
|
@ -0,0 +1,624 @@
|
|
|
|
|
package net.micode.notes.tool;
|
|
|
|
|
|
|
|
|
|
import android.content.Context;
|
|
|
|
|
import android.os.AsyncTask;
|
|
|
|
|
import android.text.TextUtils;
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* AI服务类,用于智能生成标题
|
|
|
|
|
* 这里使用模拟实现,实际项目中可以替换为真实的AI API调用
|
|
|
|
|
*/
|
|
|
|
|
public class AIService {
|
|
|
|
|
private Context mContext;
|
|
|
|
|
private OnAITitleGeneratedListener mListener;
|
|
|
|
|
|
|
|
|
|
public interface OnAITitleGeneratedListener {
|
|
|
|
|
void onTitleGenerated(String title);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public AIService(Context context) {
|
|
|
|
|
mContext = context;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setOnAITitleGeneratedListener(OnAITitleGeneratedListener listener) {
|
|
|
|
|
mListener = listener;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 智能生成标题
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
*/
|
|
|
|
|
public void generateSmartTitle(String content) {
|
|
|
|
|
if (TextUtils.isEmpty(content)) {
|
|
|
|
|
if (mListener != null) {
|
|
|
|
|
mListener.onTitleGenerated("");
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 使用异步任务模拟AI调用
|
|
|
|
|
new GenerateTitleTask().execute(content);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 模拟AI生成标题的异步任务
|
|
|
|
|
*/
|
|
|
|
|
private class GenerateTitleTask extends AsyncTask<String, Void, String> {
|
|
|
|
|
@Override
|
|
|
|
|
protected String doInBackground(String... params) {
|
|
|
|
|
String content = params[0];
|
|
|
|
|
|
|
|
|
|
// 模拟AI处理延迟
|
|
|
|
|
try {
|
|
|
|
|
Thread.sleep(500);
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 模拟AI生成标题逻辑
|
|
|
|
|
// 这里可以替换为真实的AI API调用,如GPT、百度文心一言等
|
|
|
|
|
return generateMockAITitle(content);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void onPostExecute(String title) {
|
|
|
|
|
if (mListener != null) {
|
|
|
|
|
mListener.onTitleGenerated(title);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 模拟AI生成标题
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @return 生成的标题
|
|
|
|
|
*/
|
|
|
|
|
private String generateMockAITitle(String content) {
|
|
|
|
|
// 清理内容,去掉特殊字符
|
|
|
|
|
String cleanContent = content.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5 \\t\\n\\r\\f\\v]", "").trim();
|
|
|
|
|
|
|
|
|
|
// 分析内容主题
|
|
|
|
|
String theme = analyzeTheme(cleanContent);
|
|
|
|
|
|
|
|
|
|
// 分析内容类型
|
|
|
|
|
String contentType = analyzeContentType(cleanContent);
|
|
|
|
|
|
|
|
|
|
// 提取核心关键词
|
|
|
|
|
List<String> coreKeywords = extractCoreKeywords(cleanContent, theme);
|
|
|
|
|
|
|
|
|
|
// 根据主题、类型和核心关键词生成标题
|
|
|
|
|
return generateTitleByThemeTypeAndKeywords(cleanContent, theme, contentType, coreKeywords);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 分析内容主题
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @return 主题关键词
|
|
|
|
|
*/
|
|
|
|
|
private String analyzeTheme(String content) {
|
|
|
|
|
// 简洁的主题关键词库,只保留通用主题词汇,去掉重复和具体课程名称
|
|
|
|
|
String[] themes = {
|
|
|
|
|
"学习", "工作", "会议", "计划", "总结", "任务", "想法",
|
|
|
|
|
"灵感", "生活", "旅行", "美食", "健康", "运动", "训练",
|
|
|
|
|
"购物", "阅读", "写作", "思考", "讨论", "研究", "开发", "设计",
|
|
|
|
|
"项目", "方案", "报告", "文档", "邮件", "电话", "客户",
|
|
|
|
|
"产品", "市场", "销售", "运营", "财务", "人事", "管理",
|
|
|
|
|
"技术", "代码", "测试", "上线", "维护", "优化", "创新",
|
|
|
|
|
"家庭", "朋友", "聚会", "电影", "音乐", "游戏", "动漫",
|
|
|
|
|
"书籍", "文章", "新闻", "资讯", "医疗", "养生",
|
|
|
|
|
"烹饪", "烘焙", "餐厅", "外卖", "食材", "食谱",
|
|
|
|
|
"景点", "酒店", "交通", "攻略", "行程", "机票",
|
|
|
|
|
"商品", "价格", "优惠", "促销", "订单", "物流",
|
|
|
|
|
"健身", "锻炼", "瑜伽", "跑步", "游泳", "篮球", "足球"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 主题相关词汇映射,为每个主题添加丰富的相关词汇
|
|
|
|
|
Map<String, List<String>> themeRelatedWords = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
// 学习相关词汇
|
|
|
|
|
themeRelatedWords.put("学习", Arrays.asList("学习", "课程", "考试", "作业", "论文", "复习", "预习",
|
|
|
|
|
"毛概", "系统工程", "数据结构", "数学", "英语", "物理", "化学",
|
|
|
|
|
"语文", "历史", "地理", "政治", "计算机", "编程", "算法"));
|
|
|
|
|
|
|
|
|
|
// 工作相关词汇
|
|
|
|
|
themeRelatedWords.put("工作", Arrays.asList("工作", "会议", "报告", "项目", "计划", "总结", "方案",
|
|
|
|
|
"文档", "邮件", "电话", "客户", "产品", "市场", "销售",
|
|
|
|
|
"运营", "财务", "人事", "管理", "技术", "代码", "测试",
|
|
|
|
|
"上线", "维护", "优化", "创新"));
|
|
|
|
|
|
|
|
|
|
// 会议相关词汇
|
|
|
|
|
themeRelatedWords.put("会议", Arrays.asList("会议", "讨论", "议题", "议程", "记录", "结论", "决策",
|
|
|
|
|
"参会", "主持", "发言", "汇报", "演示", "PPT", "视频会议"));
|
|
|
|
|
|
|
|
|
|
// 计划相关词汇
|
|
|
|
|
themeRelatedWords.put("计划", Arrays.asList("计划", "安排", "日程", "时间", "任务", "目标", "步骤",
|
|
|
|
|
"进度", "时间表", "规划", "策划", "方案", "预算", "资源"));
|
|
|
|
|
|
|
|
|
|
// 总结相关词汇
|
|
|
|
|
themeRelatedWords.put("总结", Arrays.asList("总结", "回顾", "反思", "收获", "体会", "感悟", "经验",
|
|
|
|
|
"教训", "成果", "不足", "改进", "建议", "报告", "汇报"));
|
|
|
|
|
|
|
|
|
|
// 任务相关词汇
|
|
|
|
|
themeRelatedWords.put("任务", Arrays.asList("任务", "工作", "项目", "目标", "责任", "分工", "协作",
|
|
|
|
|
"完成", "交付", "验收", "评估", "绩效", "效率", "质量"));
|
|
|
|
|
|
|
|
|
|
// 生活相关词汇
|
|
|
|
|
themeRelatedWords.put("生活", Arrays.asList("生活", "家庭", "朋友", "聚会", "电影", "音乐", "游戏",
|
|
|
|
|
"动漫", "书籍", "文章", "新闻", "资讯", "健康", "医疗",
|
|
|
|
|
"养生", "烹饪", "烘焙", "美食", "餐厅", "外卖", "食材"));
|
|
|
|
|
|
|
|
|
|
// 旅行相关词汇
|
|
|
|
|
themeRelatedWords.put("旅行", Arrays.asList("旅行", "景点", "酒店", "交通", "攻略", "行程", "机票",
|
|
|
|
|
"车票", "住宿", "美食", "购物", "拍照", "打卡", "纪念品"));
|
|
|
|
|
|
|
|
|
|
// 美食相关词汇
|
|
|
|
|
themeRelatedWords.put("美食", Arrays.asList("美食", "烹饪", "烘焙", "餐厅", "外卖", "食材", "食谱",
|
|
|
|
|
"菜品", "口味", "味道", "营养", "健康", "养生", "减肥"));
|
|
|
|
|
|
|
|
|
|
// 健康相关词汇
|
|
|
|
|
themeRelatedWords.put("健康", Arrays.asList("健康", "医疗", "养生", "健身", "锻炼", "饮食", "睡眠",
|
|
|
|
|
"休息", "放松", "压力", "心理", "情绪", "疾病", "治疗"));
|
|
|
|
|
|
|
|
|
|
// 运动相关词汇
|
|
|
|
|
themeRelatedWords.put("运动", Arrays.asList("运动", "健身", "锻炼", "瑜伽", "跑步", "游泳", "篮球",
|
|
|
|
|
"足球", "羽毛球", "乒乓球", "网球", "排球", "健身操", "舞蹈"));
|
|
|
|
|
|
|
|
|
|
// 训练相关词汇
|
|
|
|
|
themeRelatedWords.put("训练", Arrays.asList("训练", "上肢", "下肢", "核心", "拉伸", "力量", "耐力",
|
|
|
|
|
"有氧", "无氧", "器械", "自由重量", "俯卧撑", "仰卧起坐", "深蹲"));
|
|
|
|
|
|
|
|
|
|
// 购物相关词汇
|
|
|
|
|
themeRelatedWords.put("购物", Arrays.asList("购物", "商品", "价格", "优惠", "促销", "订单", "物流",
|
|
|
|
|
"快递", "收货", "退货", "换货", "评价", "评分", "客服"));
|
|
|
|
|
|
|
|
|
|
// 阅读相关词汇
|
|
|
|
|
themeRelatedWords.put("阅读", Arrays.asList("阅读", "书籍", "文章", "小说", "散文", "诗歌", "传记",
|
|
|
|
|
"历史", "哲学", "科学", "技术", "杂志", "报纸", "电子书"));
|
|
|
|
|
|
|
|
|
|
// 写作相关词汇
|
|
|
|
|
themeRelatedWords.put("写作", Arrays.asList("写作", "文章", "小说", "散文", "诗歌", "传记", "历史",
|
|
|
|
|
"论文", "报告", "文档", "策划", "方案", "总结", "日记"));
|
|
|
|
|
|
|
|
|
|
// 统计每个主题相关词汇出现的次数
|
|
|
|
|
int[] counts = new int[themes.length];
|
|
|
|
|
for (int i = 0; i < themes.length; i++) {
|
|
|
|
|
String theme = themes[i];
|
|
|
|
|
// 检查主题词本身
|
|
|
|
|
if (content.contains(theme)) {
|
|
|
|
|
counts[i] += 3; // 主题词本身权重最高
|
|
|
|
|
}
|
|
|
|
|
// 检查主题相关词汇
|
|
|
|
|
List<String> relatedWords = themeRelatedWords.get(theme);
|
|
|
|
|
if (relatedWords != null) {
|
|
|
|
|
for (String word : relatedWords) {
|
|
|
|
|
if (content.contains(word)) {
|
|
|
|
|
counts[i]++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 找到出现次数最多的主题
|
|
|
|
|
int maxIndex = 0;
|
|
|
|
|
for (int i = 1; i < counts.length; i++) {
|
|
|
|
|
if (counts[i] > counts[maxIndex]) {
|
|
|
|
|
maxIndex = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果没有找到主题,返回通用主题
|
|
|
|
|
if (counts[maxIndex] == 0) {
|
|
|
|
|
return "笔记";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return themes[maxIndex];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 分析内容类型
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @return 内容类型
|
|
|
|
|
*/
|
|
|
|
|
private String analyzeContentType(String content) {
|
|
|
|
|
// 检查是否包含时间安排相关词汇,添加"上午"关键词
|
|
|
|
|
if (content.contains("上午") || content.contains("早上") || content.contains("下午") || content.contains("晚上") ||
|
|
|
|
|
content.contains("明天") || content.contains("今天") || content.contains("后天") ||
|
|
|
|
|
content.contains("周一") || content.contains("周二") || content.contains("周三") ||
|
|
|
|
|
content.contains("周四") || content.contains("周五") || content.contains("周六") ||
|
|
|
|
|
content.contains("周日")) {
|
|
|
|
|
return "schedule";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查是否包含任务列表相关词汇
|
|
|
|
|
if (content.contains("需要") || content.contains("要") || content.contains("必须") ||
|
|
|
|
|
content.contains("应该") || content.contains("完成") || content.contains("做")) {
|
|
|
|
|
return "task";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查是否包含总结相关词汇
|
|
|
|
|
if (content.contains("总结") || content.contains("回顾") || content.contains("反思") ||
|
|
|
|
|
content.contains("收获") || content.contains("体会") || content.contains("感悟")) {
|
|
|
|
|
return "summary";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 默认类型
|
|
|
|
|
return "normal";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据主题和类型生成标题
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @param theme 主题
|
|
|
|
|
* @param contentType 内容类型
|
|
|
|
|
* @return 生成的标题
|
|
|
|
|
*/
|
|
|
|
|
private String generateTitleByThemeAndType(String content, String theme, String contentType) {
|
|
|
|
|
switch (contentType) {
|
|
|
|
|
case "schedule":
|
|
|
|
|
return generateScheduleTitle(content, theme);
|
|
|
|
|
case "task":
|
|
|
|
|
return generateTaskTitle(content, theme);
|
|
|
|
|
case "summary":
|
|
|
|
|
return generateSummaryTitle(content, theme);
|
|
|
|
|
default:
|
|
|
|
|
return generateNormalTitle(content, theme);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成日程安排类型标题
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @param theme 主题
|
|
|
|
|
* @return 生成的标题
|
|
|
|
|
*/
|
|
|
|
|
private String generateScheduleTitle(String content, String theme) {
|
|
|
|
|
// 提取时间关键词
|
|
|
|
|
String timeKeywords = extractTimeKeywords(content);
|
|
|
|
|
|
|
|
|
|
// 优化标题生成逻辑
|
|
|
|
|
if (!TextUtils.isEmpty(timeKeywords)) {
|
|
|
|
|
// 生成更自然的标题格式:时间 + 主题 + 安排
|
|
|
|
|
return timeKeywords + theme + "安排";
|
|
|
|
|
} else {
|
|
|
|
|
// 没有时间关键词,使用默认格式
|
|
|
|
|
return theme + "安排";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成任务类型标题
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @param theme 主题
|
|
|
|
|
* @return 生成的标题
|
|
|
|
|
*/
|
|
|
|
|
private String generateTaskTitle(String content, String theme) {
|
|
|
|
|
// 提取任务数量
|
|
|
|
|
int taskCount = countTasks(content);
|
|
|
|
|
// 提取主要任务
|
|
|
|
|
String mainTask = extractMainActivity(content, theme);
|
|
|
|
|
|
|
|
|
|
if (taskCount > 0 && !TextUtils.isEmpty(mainTask)) {
|
|
|
|
|
return theme + ": " + mainTask + "等" + taskCount + "项任务";
|
|
|
|
|
} else if (taskCount > 0) {
|
|
|
|
|
return theme + ": " + taskCount + "项任务";
|
|
|
|
|
} else if (!TextUtils.isEmpty(mainTask)) {
|
|
|
|
|
return theme + ": " + mainTask;
|
|
|
|
|
} else {
|
|
|
|
|
return theme + "任务";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成总结类型标题
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @param theme 主题
|
|
|
|
|
* @return 生成的标题
|
|
|
|
|
*/
|
|
|
|
|
private String generateSummaryTitle(String content, String theme) {
|
|
|
|
|
// 提取时间关键词
|
|
|
|
|
String timeKeywords = extractTimeKeywords(content);
|
|
|
|
|
|
|
|
|
|
if (!TextUtils.isEmpty(timeKeywords)) {
|
|
|
|
|
return theme + ": " + timeKeywords + "总结";
|
|
|
|
|
} else {
|
|
|
|
|
return theme + "总结";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成普通类型标题
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @param theme 主题
|
|
|
|
|
* @return 生成的标题
|
|
|
|
|
*/
|
|
|
|
|
private String generateNormalTitle(String content, String theme) {
|
|
|
|
|
// 提取主要活动
|
|
|
|
|
String mainActivity = extractMainActivity(content, theme);
|
|
|
|
|
|
|
|
|
|
if (!TextUtils.isEmpty(mainActivity)) {
|
|
|
|
|
return theme + ": " + mainActivity;
|
|
|
|
|
} else {
|
|
|
|
|
return theme + "笔记";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 提取时间关键词
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @return 时间关键词
|
|
|
|
|
*/
|
|
|
|
|
private String extractTimeKeywords(String content) {
|
|
|
|
|
// 时间关键词优先级排序
|
|
|
|
|
String[] timeWords = {
|
|
|
|
|
"今天", "明天", "后天", "昨天", "上周", "本周", "下周",
|
|
|
|
|
"本月", "下月", "今年", "明年",
|
|
|
|
|
"周一", "周二", "周三", "周四", "周五", "周六", "周日"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 查找第一个时间关键词
|
|
|
|
|
for (String timeWord : timeWords) {
|
|
|
|
|
if (content.contains(timeWord)) {
|
|
|
|
|
return timeWord;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查是否包含早上、下午、晚上等时间词汇
|
|
|
|
|
if (content.contains("早上") || content.contains("下午") || content.contains("晚上")) {
|
|
|
|
|
return "今日";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 提取主要活动
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @param theme 主题
|
|
|
|
|
* @return 主要活动
|
|
|
|
|
*/
|
|
|
|
|
private String extractMainActivity(String content, String theme) {
|
|
|
|
|
// 去掉主题词
|
|
|
|
|
String contentWithoutTheme = content.replace(theme, "").trim();
|
|
|
|
|
|
|
|
|
|
// 按换行符分割
|
|
|
|
|
String[] lines = contentWithoutTheme.split("\\n");
|
|
|
|
|
|
|
|
|
|
// 查找第一个非空行
|
|
|
|
|
for (String line : lines) {
|
|
|
|
|
String trimmedLine = line.trim();
|
|
|
|
|
if (!TextUtils.isEmpty(trimmedLine)) {
|
|
|
|
|
// 提取活动关键词
|
|
|
|
|
String activity = extractActivityFromLine(trimmedLine);
|
|
|
|
|
if (!TextUtils.isEmpty(activity)) {
|
|
|
|
|
return activity;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从行中提取活动关键词
|
|
|
|
|
* @param line 行内容
|
|
|
|
|
* @return 活动关键词
|
|
|
|
|
*/
|
|
|
|
|
private String extractActivityFromLine(String line) {
|
|
|
|
|
// 常见活动动词
|
|
|
|
|
String[] verbs = {
|
|
|
|
|
"学习", "工作", "会议", "讨论", "研究", "开发", "设计",
|
|
|
|
|
"阅读", "写作", "思考", "运动", "锻炼", "跑步", "游泳",
|
|
|
|
|
"吃饭", "睡觉", "休息", "旅行", "购物", "参观", "访问"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 查找第一个动词
|
|
|
|
|
for (String verb : verbs) {
|
|
|
|
|
if (line.contains(verb)) {
|
|
|
|
|
// 提取动词后面的内容,最多10个字符
|
|
|
|
|
int verbIndex = line.indexOf(verb);
|
|
|
|
|
String activity = line.substring(verbIndex);
|
|
|
|
|
if (activity.length() > 10) {
|
|
|
|
|
activity = activity.substring(0, 10);
|
|
|
|
|
}
|
|
|
|
|
return activity;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果没有找到动词,返回行的前10个字符
|
|
|
|
|
if (line.length() > 10) {
|
|
|
|
|
return line.substring(0, 10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return line;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 统计任务数量
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @return 任务数量
|
|
|
|
|
*/
|
|
|
|
|
private int countTasks(String content) {
|
|
|
|
|
// 按换行符分割
|
|
|
|
|
String[] lines = content.split("\\n");
|
|
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
|
|
// 统计非空行数量
|
|
|
|
|
for (String line : lines) {
|
|
|
|
|
if (!TextUtils.isEmpty(line.trim())) {
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 提取核心关键词
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @param theme 主题
|
|
|
|
|
* @return 核心关键词列表
|
|
|
|
|
*/
|
|
|
|
|
private List<String> extractCoreKeywords(String content, String theme) {
|
|
|
|
|
List<String> keywords = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
// 常见关键词库,按领域分类
|
|
|
|
|
Map<String, List<String>> keywordLibrary = new HashMap<>();
|
|
|
|
|
keywordLibrary.put("学习", new ArrayList<String>() {{
|
|
|
|
|
add("毛概"); add("系统工程"); add("数据结构"); add("数学"); add("英语");
|
|
|
|
|
add("物理"); add("化学"); add("生物"); add("历史"); add("地理");
|
|
|
|
|
add("政治"); add("语文"); add("计算机"); add("编程"); add("算法");
|
|
|
|
|
}});
|
|
|
|
|
keywordLibrary.put("工作", new ArrayList<String>() {{
|
|
|
|
|
add("会议"); add("报告"); add("项目"); add("计划"); add("总结");
|
|
|
|
|
add("方案"); add("设计"); add("开发"); add("测试"); add("上线");
|
|
|
|
|
}});
|
|
|
|
|
keywordLibrary.put("生活", new ArrayList<String>() {{
|
|
|
|
|
add("吃饭"); add("睡觉"); add("运动"); add("购物"); add("旅行");
|
|
|
|
|
add("电影"); add("音乐"); add("阅读"); add("游戏"); add("社交");
|
|
|
|
|
}});
|
|
|
|
|
|
|
|
|
|
// 获取当前主题相关的关键词库
|
|
|
|
|
List<String> themeKeywords = keywordLibrary.getOrDefault(theme, new ArrayList<>());
|
|
|
|
|
|
|
|
|
|
// 查找内容中包含的主题相关关键词
|
|
|
|
|
for (String keyword : themeKeywords) {
|
|
|
|
|
if (content.contains(keyword) && !keywords.contains(keyword)) {
|
|
|
|
|
keywords.add(keyword);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果没有找到主题相关关键词,提取内容中的高频词
|
|
|
|
|
if (keywords.isEmpty()) {
|
|
|
|
|
// 简单的高频词提取逻辑
|
|
|
|
|
String[] words = content.split("\\s+");
|
|
|
|
|
Map<String, Integer> wordCount = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
// 统计词频
|
|
|
|
|
for (String word : words) {
|
|
|
|
|
if (!TextUtils.isEmpty(word) && word.length() > 1 && !word.equals(theme)) {
|
|
|
|
|
wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 按词频排序,取前3个
|
|
|
|
|
wordCount.entrySet().stream()
|
|
|
|
|
.sorted((a, b) -> b.getValue().compareTo(a.getValue()))
|
|
|
|
|
.limit(3)
|
|
|
|
|
.forEach(entry -> keywords.add(entry.getKey()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return keywords;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据主题、类型和核心关键词生成标题
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @param theme 主题
|
|
|
|
|
* @param contentType 内容类型
|
|
|
|
|
* @param coreKeywords 核心关键词
|
|
|
|
|
* @return 生成的标题
|
|
|
|
|
*/
|
|
|
|
|
private String generateTitleByThemeTypeAndKeywords(String content, String theme, String contentType, List<String> coreKeywords) {
|
|
|
|
|
switch (contentType) {
|
|
|
|
|
case "schedule":
|
|
|
|
|
return generateEnhancedScheduleTitle(content, theme, coreKeywords);
|
|
|
|
|
case "task":
|
|
|
|
|
return generateEnhancedTaskTitle(content, theme, coreKeywords);
|
|
|
|
|
case "summary":
|
|
|
|
|
return generateEnhancedSummaryTitle(content, theme, coreKeywords);
|
|
|
|
|
default:
|
|
|
|
|
return generateEnhancedNormalTitle(content, theme, coreKeywords);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成增强版日程安排标题
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @param theme 主题
|
|
|
|
|
* @param coreKeywords 核心关键词
|
|
|
|
|
* @return 生成的标题
|
|
|
|
|
*/
|
|
|
|
|
private String generateEnhancedScheduleTitle(String content, String theme, List<String> coreKeywords) {
|
|
|
|
|
String timeKeywords = extractTimeKeywords(content);
|
|
|
|
|
|
|
|
|
|
if (!TextUtils.isEmpty(timeKeywords)) {
|
|
|
|
|
// 生成简洁的标题:时间 + 主题 + 安排
|
|
|
|
|
return timeKeywords + theme + "安排";
|
|
|
|
|
} else {
|
|
|
|
|
// 没有时间关键词,生成:主题 + 安排
|
|
|
|
|
return theme + "安排";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成增强版任务标题
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @param theme 主题
|
|
|
|
|
* @param coreKeywords 核心关键词
|
|
|
|
|
* @return 生成的标题
|
|
|
|
|
*/
|
|
|
|
|
private String generateEnhancedTaskTitle(String content, String theme, List<String> coreKeywords) {
|
|
|
|
|
// 生成简洁的标题:主题 + 任务
|
|
|
|
|
return theme + "任务";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成增强版总结标题
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @param theme 主题
|
|
|
|
|
* @param coreKeywords 核心关键词
|
|
|
|
|
* @return 生成的标题
|
|
|
|
|
*/
|
|
|
|
|
private String generateEnhancedSummaryTitle(String content, String theme, List<String> coreKeywords) {
|
|
|
|
|
String timeKeywords = extractTimeKeywords(content);
|
|
|
|
|
|
|
|
|
|
if (!TextUtils.isEmpty(timeKeywords)) {
|
|
|
|
|
// 生成简洁的标题:时间 + 主题 + 总结
|
|
|
|
|
return timeKeywords + theme + "总结";
|
|
|
|
|
} else {
|
|
|
|
|
// 没有时间关键词,生成:主题 + 总结
|
|
|
|
|
return theme + "总结";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成增强版普通标题
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @param theme 主题
|
|
|
|
|
* @param coreKeywords 核心关键词
|
|
|
|
|
* @return 生成的标题
|
|
|
|
|
*/
|
|
|
|
|
private String generateEnhancedNormalTitle(String content, String theme, List<String> coreKeywords) {
|
|
|
|
|
// 生成简洁的标题:主题 + 笔记
|
|
|
|
|
return theme + "笔记";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取内容摘要
|
|
|
|
|
* @param content 正文内容
|
|
|
|
|
* @param maxLength 最大长度
|
|
|
|
|
* @return 内容摘要
|
|
|
|
|
*/
|
|
|
|
|
private String getContentSummary(String content, int maxLength) {
|
|
|
|
|
if (content.length() <= maxLength) {
|
|
|
|
|
return content;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 尝试在句子边界截断
|
|
|
|
|
for (int i = maxLength; i > 0; i--) {
|
|
|
|
|
char c = content.charAt(i);
|
|
|
|
|
if (c == '。' || c == '!' || c == '?' || c == '.' || c == '!' || c == '?') {
|
|
|
|
|
return content.substring(0, i + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 找不到合适的边界,直接截断
|
|
|
|
|
return content.substring(0, maxLength) + "...";
|
|
|
|
|
}
|
|
|
|
|
}
|