mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-12 19:35:50 +00:00
feat: 引入文本提取功能,优化AI内容解析逻辑,移除冗余代码
This commit is contained in:
parent
ecb52c76b9
commit
0deb3113b5
@ -457,7 +457,7 @@ import SearchBox from "../components/SearchBox.vue";
|
||||
import AIAssistant from "../components/AIAssistant.vue";
|
||||
import transformEmojiToHtml from "../utils/emoji";
|
||||
import {languageName} from "../language";
|
||||
import {PROJECT_AI_SYSTEM_PROMPT} from "../utils/ai";
|
||||
import {AINormalizeJsonContent, PROJECT_AI_SYSTEM_PROMPT} from "../utils/ai";
|
||||
import Draggable from 'vuedraggable'
|
||||
|
||||
export default {
|
||||
@ -1197,39 +1197,8 @@ export default {
|
||||
return [];
|
||||
},
|
||||
|
||||
normalizeAIJsonContent(content) {
|
||||
if (!content) {
|
||||
return null;
|
||||
}
|
||||
const raw = String(content).trim();
|
||||
if (!raw) {
|
||||
return null;
|
||||
}
|
||||
const candidates = [raw];
|
||||
const block = raw.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
||||
if (block && block[1]) {
|
||||
candidates.push(block[1].trim());
|
||||
}
|
||||
const start = raw.indexOf('{');
|
||||
const end = raw.lastIndexOf('}');
|
||||
if (start !== -1 && end !== -1 && end > start) {
|
||||
candidates.push(raw.slice(start, end + 1));
|
||||
}
|
||||
for (const candidate of candidates) {
|
||||
if (!candidate) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
return JSON.parse(candidate);
|
||||
} catch (e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
parseProjectAIContent(content) {
|
||||
const payload = this.normalizeAIJsonContent(content);
|
||||
const payload = AINormalizeJsonContent(content);
|
||||
if (!payload || typeof payload !== 'object') {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -343,6 +343,7 @@ import longpress from "../../../../directives/longpress";
|
||||
import {inputLoadAdd, inputLoadIsLast, inputLoadRemove} from "./one";
|
||||
import {languageList, languageName} from "../../../../language";
|
||||
import {isMarkdownFormat, MarkdownConver} from "../../../../utils/markdown";
|
||||
import {extractPlainText} from "../../../../utils/text";
|
||||
import {MESSAGE_AI_SYSTEM_PROMPT} from "../../../../utils/ai";
|
||||
import emitter from "../../../../store/events";
|
||||
import historyMixin from "./history";
|
||||
@ -1911,7 +1912,6 @@ export default {
|
||||
emitter.emit('openAIAssistant', {
|
||||
placeholder: this.$L('请简要描述消息的主题、语气或要点,AI 将生成完整消息'),
|
||||
onBeforeSend: this.handleMessageAIBeforeSend,
|
||||
onRender: this.handleMessageAIRender,
|
||||
onApply: this.handleMessageAIApply,
|
||||
});
|
||||
},
|
||||
@ -1933,10 +1933,6 @@ export default {
|
||||
return prepared;
|
||||
},
|
||||
|
||||
handleMessageAIRender({rawOutput}) {
|
||||
return rawOutput || '';
|
||||
},
|
||||
|
||||
handleMessageAIApply({rawOutput}) {
|
||||
if (!rawOutput) {
|
||||
$A.messageWarning('AI 未生成内容');
|
||||
@ -1991,7 +1987,7 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
const draftText = this.extractPlainText(this.value);
|
||||
const draftText = extractPlainText(this.value);
|
||||
if (draftText) {
|
||||
sections.push('## 当前草稿');
|
||||
sections.push(this.cutText(draftText, 200));
|
||||
@ -2062,26 +2058,13 @@ export default {
|
||||
}
|
||||
try {
|
||||
const preview = $A.getMsgSimpleDesc(message);
|
||||
const plain = this.extractPlainText(preview || '');
|
||||
const plain = extractPlainText(preview || '');
|
||||
return this.cutText(plain, 160);
|
||||
} catch (error) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
extractPlainText(content) {
|
||||
if (!content) {
|
||||
return '';
|
||||
}
|
||||
const value = typeof content === 'string' ? content : JSON.stringify(content);
|
||||
if (typeof window === 'undefined' || !window.document) {
|
||||
return value.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
|
||||
}
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = value;
|
||||
return (div.textContent || div.innerText || '').replace(/\s+/g, ' ').trim();
|
||||
},
|
||||
|
||||
cutText(text, limit = 60) {
|
||||
const value = (text || '').trim();
|
||||
if (!value) {
|
||||
|
||||
@ -201,7 +201,8 @@ import TaskExistTips from "./TaskExistTips.vue";
|
||||
import TEditorTask from "../../../components/TEditorTask.vue";
|
||||
import nostyle from "../../../components/VMEditor/engine/nostyle";
|
||||
import {MarkdownConver} from "../../../utils/markdown";
|
||||
import {TASK_AI_SYSTEM_PROMPT} from "../../../utils/ai";
|
||||
import {extractPlainText} from "../../../utils/text";
|
||||
import {AINormalizeJsonContent, TASK_AI_SYSTEM_PROMPT} from "../../../utils/ai";
|
||||
|
||||
export default {
|
||||
name: "TaskAdd",
|
||||
@ -639,15 +640,11 @@ export default {
|
||||
buildTaskAIContextData() {
|
||||
const prompts = [];
|
||||
const plainText = (value, limit = 600) => {
|
||||
if (!value || typeof value !== 'string') {
|
||||
const text = extractPlainText(value || '');
|
||||
if (!text) {
|
||||
return '';
|
||||
}
|
||||
return value
|
||||
.replace(/<[^>]+>/g, ' ')
|
||||
.replace(/ /gi, ' ')
|
||||
.replace(/\s+/g, ' ')
|
||||
.slice(0, limit)
|
||||
.trim();
|
||||
return text.slice(0, limit).trim();
|
||||
};
|
||||
|
||||
const currentTitle = (this.addData.name || '').trim();
|
||||
@ -778,7 +775,7 @@ export default {
|
||||
},
|
||||
|
||||
parseTaskAIContent(content) {
|
||||
const payload = this.normalizeAIJsonContent(content);
|
||||
const payload = AINormalizeJsonContent(content);
|
||||
if (!payload || typeof payload !== 'object') {
|
||||
return null;
|
||||
}
|
||||
@ -802,37 +799,6 @@ export default {
|
||||
};
|
||||
},
|
||||
|
||||
normalizeAIJsonContent(content) {
|
||||
if (!content) {
|
||||
return null;
|
||||
}
|
||||
const raw = String(content).trim();
|
||||
if (!raw) {
|
||||
return null;
|
||||
}
|
||||
const candidates = [raw];
|
||||
const block = raw.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
||||
if (block && block[1]) {
|
||||
candidates.push(block[1].trim());
|
||||
}
|
||||
const start = raw.indexOf('{');
|
||||
const end = raw.lastIndexOf('}');
|
||||
if (start !== -1 && end !== -1 && end > start) {
|
||||
candidates.push(raw.slice(start, end + 1));
|
||||
}
|
||||
for (const candidate of candidates) {
|
||||
if (!candidate) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
return JSON.parse(candidate);
|
||||
} catch (e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
normalizeAISubtasks(value) {
|
||||
let raw = [];
|
||||
if (Array.isArray(value)) {
|
||||
|
||||
32
resources/assets/js/utils/ai.js
vendored
32
resources/assets/js/utils/ai.js
vendored
@ -11,6 +11,37 @@ const AIModelNames = (str) => {
|
||||
}, []).filter(item => item.value);
|
||||
}
|
||||
|
||||
const AINormalizeJsonContent = (content) => {
|
||||
if (!content) {
|
||||
return null;
|
||||
}
|
||||
const raw = String(content).trim();
|
||||
if (!raw) {
|
||||
return null;
|
||||
}
|
||||
const candidates = [raw];
|
||||
const block = raw.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
||||
if (block && block[1]) {
|
||||
candidates.push(block[1].trim());
|
||||
}
|
||||
const start = raw.indexOf('{');
|
||||
const end = raw.lastIndexOf('}');
|
||||
if (start !== -1 && end !== -1 && end > start) {
|
||||
candidates.push(raw.slice(start, end + 1));
|
||||
}
|
||||
for (const candidate of candidates) {
|
||||
if (!candidate) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
return JSON.parse(candidate);
|
||||
} catch (e) {
|
||||
// continue
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const AIBotList = []
|
||||
|
||||
const AIBotMap = {
|
||||
@ -295,6 +326,7 @@ const PROJECT_AI_SYSTEM_PROMPT = `你是一名资深的项目规划顾问,帮
|
||||
|
||||
export {
|
||||
AIModelNames,
|
||||
AINormalizeJsonContent,
|
||||
AIBotList,
|
||||
AIBotMap,
|
||||
AISystemConfig,
|
||||
|
||||
13
resources/assets/js/utils/text.js
vendored
Normal file
13
resources/assets/js/utils/text.js
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
export function extractPlainText(content) {
|
||||
if (!content) {
|
||||
return '';
|
||||
}
|
||||
const value = typeof content === 'string' ? content : JSON.stringify(content);
|
||||
if (typeof window === 'undefined' || !window.document) {
|
||||
return value.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
|
||||
}
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = value;
|
||||
return (div.textContent || div.innerText || '').replace(/\s+/g, ' ').trim();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user