feat: 可以切换多种引用格式
This commit is contained in:
parent
cbc1e7068b
commit
9b835bbadd
|
@ -30,6 +30,7 @@ const statePersistConfig = {
|
||||||
"language",
|
"language",
|
||||||
"isJumpToReference",
|
"isJumpToReference",
|
||||||
"isEvaluateTopicMatch",
|
"isEvaluateTopicMatch",
|
||||||
|
"citationStyle",
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ export interface APIState {
|
||||||
language: string;
|
language: string;
|
||||||
isJumpToReference: boolean;
|
isJumpToReference: boolean;
|
||||||
isEvaluateTopicMatch: boolean;
|
isEvaluateTopicMatch: boolean;
|
||||||
|
citationStyle: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: APIState = {
|
const initialState: APIState = {
|
||||||
|
@ -17,6 +18,7 @@ const initialState: APIState = {
|
||||||
language: "en",
|
language: "en",
|
||||||
isJumpToReference: false,
|
isJumpToReference: false,
|
||||||
isEvaluateTopicMatch: false,
|
isEvaluateTopicMatch: false,
|
||||||
|
citationStyle: "custom-chinese",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const stateSlice = createSlice({
|
export const stateSlice = createSlice({
|
||||||
|
@ -50,6 +52,9 @@ export const stateSlice = createSlice({
|
||||||
setIsEvaluateTopicMatch: (state, action: PayloadAction<boolean>) => {
|
setIsEvaluateTopicMatch: (state, action: PayloadAction<boolean>) => {
|
||||||
state.isEvaluateTopicMatch = action.payload;
|
state.isEvaluateTopicMatch = action.payload;
|
||||||
},
|
},
|
||||||
|
setCitationStyle: (state, action: PayloadAction<string>) => {
|
||||||
|
state.citationStyle = action.payload;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -62,6 +67,7 @@ export const {
|
||||||
setLanguage,
|
setLanguage,
|
||||||
setIsJumpToReference,
|
setIsJumpToReference,
|
||||||
setIsEvaluateTopicMatch,
|
setIsEvaluateTopicMatch,
|
||||||
|
setCitationStyle,
|
||||||
} = stateSlice.actions;
|
} = stateSlice.actions;
|
||||||
|
|
||||||
export const stateReducer = stateSlice.reducer;
|
export const stateReducer = stateSlice.reducer;
|
||||||
|
|
|
@ -13,6 +13,7 @@ type ParaIn = {
|
||||||
|
|
||||||
const ExportDocx = ({ editor }: ParaIn) => {
|
const ExportDocx = ({ editor }: ParaIn) => {
|
||||||
const references = useAppSelector((state) => state.auth.referencesRedux);
|
const references = useAppSelector((state) => state.auth.referencesRedux);
|
||||||
|
const citationStyle = useAppSelector((state) => state.state.citationStyle);
|
||||||
|
|
||||||
const prepareReferencesForQuill = (references: Reference[]) => {
|
const prepareReferencesForQuill = (references: Reference[]) => {
|
||||||
// 首先添加一个标题
|
// 首先添加一个标题
|
||||||
|
@ -25,8 +26,17 @@ const ExportDocx = ({ editor }: ParaIn) => {
|
||||||
insert: "\n参考文献\n",
|
insert: "\n参考文献\n",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const referencesString = getAllFullReferences(references);
|
const referencesString = getAllFullReferences(references, citationStyle);
|
||||||
const quillReferences = [{ insert: referencesString }];
|
const quillReferences = [
|
||||||
|
{
|
||||||
|
attributes: {
|
||||||
|
// 提供默认值,即使这些值不会改变文本样式
|
||||||
|
bold: false, // 默认为false,因为引用通常不需要加粗
|
||||||
|
align: "left", // 默认为left,这是大多数文本的常规对齐方式
|
||||||
|
},
|
||||||
|
insert: referencesString,
|
||||||
|
},
|
||||||
|
];
|
||||||
// 合并标题和引用列表
|
// 合并标题和引用列表
|
||||||
return referencesWithTitle.concat(quillReferences);
|
return referencesWithTitle.concat(quillReferences);
|
||||||
};
|
};
|
||||||
|
|
|
@ -66,18 +66,18 @@ async function getPubMedPaperDetails(idList: IDList) {
|
||||||
// 解析XML数据
|
// 解析XML数据
|
||||||
const parser = new xml2js.Parser({
|
const parser = new xml2js.Parser({
|
||||||
explicitArray: false,
|
explicitArray: false,
|
||||||
ignoreAttrs: true, // 忽略XML属性
|
ignoreAttrs: false, // 忽略XML属性
|
||||||
charkey: "text", // 字符数据的键
|
charkey: "text", // 字符数据的键
|
||||||
trim: true, // 去除文本前后空格
|
trim: true, // 去除文本前后空格
|
||||||
});
|
});
|
||||||
let result = await parser.parseStringPromise(data);
|
let result = await parser.parseStringPromise(data);
|
||||||
|
|
||||||
console.log(result);
|
// console.log(result);
|
||||||
// 提取并处理文章详细信息
|
// 提取并处理文章详细信息
|
||||||
const articles = result.PubmedArticleSet.PubmedArticle.map((article) => {
|
const articles = result.PubmedArticleSet.PubmedArticle.map((article) => {
|
||||||
const medlineCitation = article.MedlineCitation;
|
const medlineCitation = article.MedlineCitation;
|
||||||
const articleDetails = medlineCitation.Article;
|
const articleDetails = medlineCitation.Article;
|
||||||
console.log("atricledetails", articleDetails);
|
// console.log("atricledetails", articleDetails);
|
||||||
const abstractTexts = articleDetails.Abstract.AbstractText;
|
const abstractTexts = articleDetails.Abstract.AbstractText;
|
||||||
|
|
||||||
let abstract;
|
let abstract;
|
||||||
|
@ -85,7 +85,7 @@ async function getPubMedPaperDetails(idList: IDList) {
|
||||||
if (Array.isArray(abstractTexts)) {
|
if (Array.isArray(abstractTexts)) {
|
||||||
// 如果是数组,遍历数组并连接每个元素的文本
|
// 如果是数组,遍历数组并连接每个元素的文本
|
||||||
abstract = abstractTexts
|
abstract = abstractTexts
|
||||||
.map((text) => (typeof text === "object" ? text._ : text))
|
.map((text) => (typeof text === "object" ? text.text : text))
|
||||||
.join(" ");
|
.join(" ");
|
||||||
} else if (typeof abstractTexts === "string") {
|
} else if (typeof abstractTexts === "string") {
|
||||||
// 如果 abstractTexts 直接就是字符串
|
// 如果 abstractTexts 直接就是字符串
|
||||||
|
@ -133,7 +133,7 @@ async function getPubMedPaperDetails(idList: IDList) {
|
||||||
journalTitle += `: ${articleDetails.Pagination.StartPage}-${articleDetails.Pagination.EndPage}`;
|
journalTitle += `: ${articleDetails.Pagination.StartPage}-${articleDetails.Pagination.EndPage}`;
|
||||||
}
|
}
|
||||||
// 构建文章的 PubMed URL
|
// 构建文章的 PubMed URL
|
||||||
const articleUrl = `https://pubmed.ncbi.nlm.nih.gov/${medlineCitation.PMID}/`;
|
const articleUrl = `https://pubmed.ncbi.nlm.nih.gov/${medlineCitation.PMID.text}/`;
|
||||||
// console.log("medlineCitation", medlineCitation);
|
// console.log("medlineCitation", medlineCitation);
|
||||||
console.log("\n,journalTitle", journalTitle);
|
console.log("\n,journalTitle", journalTitle);
|
||||||
let title = articleDetails.ArticleTitle;
|
let title = articleDetails.ArticleTitle;
|
||||||
|
@ -141,14 +141,36 @@ async function getPubMedPaperDetails(idList: IDList) {
|
||||||
if (title.endsWith(".")) {
|
if (title.endsWith(".")) {
|
||||||
title = title.slice(0, -1);
|
title = title.slice(0, -1);
|
||||||
}
|
}
|
||||||
|
// 提取DOI
|
||||||
|
let doi = null;
|
||||||
|
if (
|
||||||
|
article.PubmedData &&
|
||||||
|
article.PubmedData.ArticleIdList &&
|
||||||
|
Array.isArray(article.PubmedData.ArticleIdList.ArticleId)
|
||||||
|
) {
|
||||||
|
const doiObject = article.PubmedData.ArticleIdList.ArticleId.find(
|
||||||
|
(idObj) => idObj.$.IdType === "doi"
|
||||||
|
);
|
||||||
|
if (doiObject) {
|
||||||
|
doi = doiObject.text; // 获取DOI值
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("doi", doi);
|
||||||
|
console.log(
|
||||||
|
"链接",
|
||||||
|
medlineCitation.PMID.text,
|
||||||
|
"属性",
|
||||||
|
typeof medlineCitation.PMID.text
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
id: medlineCitation.PMID._,
|
id: Number(medlineCitation.PMID.text),
|
||||||
title: title,
|
title: title,
|
||||||
abstract: abstract,
|
abstract: abstract,
|
||||||
authors: authors,
|
authors: authors,
|
||||||
url: articleUrl,
|
url: articleUrl,
|
||||||
year: publishedDate,
|
year: publishedDate,
|
||||||
journal: journalTitle,
|
journal: journalTitle,
|
||||||
|
doi: doi,
|
||||||
// 其他需要的字段可以继续添加
|
// 其他需要的字段可以继续添加
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -34,7 +34,8 @@ async function getSemanticPapers(
|
||||||
offset: offset,
|
offset: offset,
|
||||||
limit: limit,
|
limit: limit,
|
||||||
year: year,
|
year: year,
|
||||||
fields: "title,year,authors.name,abstract,venue,url,journal",
|
fields:
|
||||||
|
"title,year,authors.name,abstract,venue,url,journal,externalIds",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// 提取并处理论文数据
|
// 提取并处理论文数据
|
||||||
|
|
|
@ -359,6 +359,7 @@ const QEditor = ({ lng }) => {
|
||||||
author: entry.authors?.slice(0, 3).join(", "),
|
author: entry.authors?.slice(0, 3).join(", "),
|
||||||
venue: entry.venue,
|
venue: entry.venue,
|
||||||
journal: formatJournalReference(entry),
|
journal: formatJournalReference(entry),
|
||||||
|
doi: entry.externalIds.DOI,
|
||||||
}));
|
}));
|
||||||
dataString = rawData
|
dataString = rawData
|
||||||
.map((entry: any) => {
|
.map((entry: any) => {
|
||||||
|
@ -391,6 +392,7 @@ const QEditor = ({ lng }) => {
|
||||||
journal: entry.journal, // 文章的发表杂志
|
journal: entry.journal, // 文章的发表杂志
|
||||||
url: entry.url, // 文章的 URL
|
url: entry.url, // 文章的 URL
|
||||||
source: "PubMed", // 指示这些引用来自 PubMed
|
source: "PubMed", // 指示这些引用来自 PubMed
|
||||||
|
doi: entry.doi, // 文章的 DOI
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// 打印 newReferences
|
// 打印 newReferences
|
||||||
|
@ -411,7 +413,7 @@ const QEditor = ({ lng }) => {
|
||||||
// )}`;
|
// )}`;
|
||||||
const content = `之前用户已经完成的内容上下文:${getTextBeforeCursor(
|
const content = `之前用户已经完成的内容上下文:${getTextBeforeCursor(
|
||||||
quill!,
|
quill!,
|
||||||
900
|
800
|
||||||
)},搜索到的论文内容:${trimmedMessage},需要完成的论文主题:${topic},请根据搜索到的论文内容完成用户的论文`;
|
)},搜索到的论文内容:${trimmedMessage},需要完成的论文主题:${topic},请根据搜索到的论文内容完成用户的论文`;
|
||||||
await sendMessageToOpenAI(
|
await sendMessageToOpenAI(
|
||||||
content,
|
content,
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { useLocalStorage } from "react-use";
|
||||||
|
|
||||||
import { Reference } from "@/utils/global";
|
import { Reference } from "@/utils/global";
|
||||||
import {
|
import {
|
||||||
copyToClipboard,
|
copyToClipboard,
|
||||||
getFullReference,
|
getFullReference,
|
||||||
|
renderCitation,
|
||||||
getAllFullReferences,
|
getAllFullReferences,
|
||||||
delteIndexUpdateBracketNumbersInDeltaKeepSelection,
|
delteIndexUpdateBracketNumbersInDeltaKeepSelection,
|
||||||
} from "@/utils/others/quillutils";
|
} from "@/utils/others/quillutils";
|
||||||
|
@ -17,7 +19,9 @@ import {
|
||||||
removeReferenceRedux,
|
removeReferenceRedux,
|
||||||
clearReferencesRedux,
|
clearReferencesRedux,
|
||||||
swapReferencesRedux,
|
swapReferencesRedux,
|
||||||
|
setReferencesRedux,
|
||||||
} from "@/app/store/slices/authSlice";
|
} from "@/app/store/slices/authSlice";
|
||||||
|
import { setCitationStyle } from "@/app/store/slices/stateSlice";
|
||||||
//supabase
|
//supabase
|
||||||
import { submitPaper } from "@/utils/supabase/supabaseutils";
|
import { submitPaper } from "@/utils/supabase/supabaseutils";
|
||||||
import { createClient } from "@/utils/supabase/client";
|
import { createClient } from "@/utils/supabase/client";
|
||||||
|
@ -27,10 +31,22 @@ type ReferenceListProps = {
|
||||||
editor: any;
|
editor: any;
|
||||||
lng: string;
|
lng: string;
|
||||||
};
|
};
|
||||||
|
//引用转换
|
||||||
|
import Cite from "citation-js";
|
||||||
|
|
||||||
|
const citationStyles = [
|
||||||
|
{ name: "中文", template: "custom-chinese" }, // 假设你有一个自定义的“中文”格式
|
||||||
|
{ name: "APA", template: "apa" },
|
||||||
|
{ name: "MLA", template: "mla" },
|
||||||
|
{ name: "Chicago", template: "chicago" },
|
||||||
|
{ name: "Harvard", template: "harvard" },
|
||||||
|
{ name: "Vancouver", template: "vancouver" },
|
||||||
|
{ name: "IEEE", template: "ieee" },
|
||||||
|
];
|
||||||
function ReferenceList({ editor, lng }: ReferenceListProps) {
|
function ReferenceList({ editor, lng }: ReferenceListProps) {
|
||||||
//i18n
|
//i18n
|
||||||
const { t } = useTranslation(lng);
|
const { t } = useTranslation(lng);
|
||||||
|
//自定义文献
|
||||||
const [newTitle, setNewTitle] = useState("");
|
const [newTitle, setNewTitle] = useState("");
|
||||||
const [newAuthor, setNewAuthor] = useState("");
|
const [newAuthor, setNewAuthor] = useState("");
|
||||||
const [newYear, setNewYear] = useState("");
|
const [newYear, setNewYear] = useState("");
|
||||||
|
@ -43,6 +59,7 @@ function ReferenceList({ editor, lng }: ReferenceListProps) {
|
||||||
(state) => state.state.paperNumberRedux
|
(state) => state.state.paperNumberRedux
|
||||||
);
|
);
|
||||||
const isVip = useAppSelector((state) => state.state.isVip);
|
const isVip = useAppSelector((state) => state.state.isVip);
|
||||||
|
const citationStyle = useAppSelector((state) => state.state.citationStyle);
|
||||||
//supabase
|
//supabase
|
||||||
const supabase = createClient();
|
const supabase = createClient();
|
||||||
|
|
||||||
|
@ -95,6 +112,44 @@ function ReferenceList({ editor, lng }: ReferenceListProps) {
|
||||||
}
|
}
|
||||||
}, [references]);
|
}, [references]);
|
||||||
|
|
||||||
|
async function generateCitation(doi, style) {
|
||||||
|
try {
|
||||||
|
const citation = await Cite.async(doi);
|
||||||
|
const output = citation.format("bibliography", {
|
||||||
|
format: "text",
|
||||||
|
template: style,
|
||||||
|
lang: "en-US",
|
||||||
|
});
|
||||||
|
return output;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error generating citation:", error);
|
||||||
|
return ""; // Return an empty string in case of error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchCitations = async () => {
|
||||||
|
const updatedReferences = await Promise.all(
|
||||||
|
references.map(async (ref) => {
|
||||||
|
// 检查是否已经有当前风格的引用
|
||||||
|
if (!ref[citationStyle]) {
|
||||||
|
// 如果没有,则生成新的引用
|
||||||
|
const citationText = await generateCitation(ref.doi, citationStyle);
|
||||||
|
return { ...ref, [citationStyle]: citationText }; // 添加新的引用到对象
|
||||||
|
}
|
||||||
|
return ref; // 如果已有引用,则不做改变
|
||||||
|
})
|
||||||
|
);
|
||||||
|
dispatch(setReferencesRedux(updatedReferences));
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchCitations();
|
||||||
|
}, [citationStyle]);
|
||||||
|
|
||||||
|
const handleStyleChange = (event) => {
|
||||||
|
dispatch(setCitationStyle(event.target.value));
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className=" mx-auto p-4">
|
<div className=" mx-auto p-4">
|
||||||
{/* 引用列表显示区域 */}
|
{/* 引用列表显示区域 */}
|
||||||
|
@ -106,7 +161,9 @@ function ReferenceList({ editor, lng }: ReferenceListProps) {
|
||||||
<li key={index} className="mb-3 p-2 border-b">
|
<li key={index} className="mb-3 p-2 border-b">
|
||||||
{/* 显示序号 */}
|
{/* 显示序号 */}
|
||||||
<span className="font-bold mr-2">[{index + 1}].</span>
|
<span className="font-bold mr-2">[{index + 1}].</span>
|
||||||
{getFullReference(reference)}
|
{/* {getFullReference(reference)} */}
|
||||||
|
{/* 根据当前风格渲染引用 */}
|
||||||
|
{renderCitation(reference, citationStyle)}
|
||||||
{reference.url && (
|
{reference.url && (
|
||||||
<a
|
<a
|
||||||
href={reference.url}
|
href={reference.url}
|
||||||
|
@ -133,7 +190,9 @@ function ReferenceList({ editor, lng }: ReferenceListProps) {
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="bg-gray-500 hover:bg-gray-700 text-white font-bold py-1 px-2 ml-2 rounded"
|
className="bg-gray-500 hover:bg-gray-700 text-white font-bold py-1 px-2 ml-2 rounded"
|
||||||
onClick={() => copyToClipboard(getFullReference(reference))}
|
onClick={() =>
|
||||||
|
copyToClipboard(renderCitation(reference, citationStyle))
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{t("复制")}
|
{t("复制")}
|
||||||
</button>
|
</button>
|
||||||
|
@ -230,6 +289,29 @@ function ReferenceList({ editor, lng }: ReferenceListProps) {
|
||||||
>
|
>
|
||||||
{t("删除所有引用")}
|
{t("删除所有引用")}
|
||||||
</button>
|
</button>
|
||||||
|
{/* 下拉框用于更改引用风格 */}
|
||||||
|
<div className="mt-4">
|
||||||
|
<label
|
||||||
|
htmlFor="citation-style"
|
||||||
|
className="block text-sm font-medium text-gray-700"
|
||||||
|
>
|
||||||
|
选择引用格式:
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
id="citation-style"
|
||||||
|
className="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md"
|
||||||
|
value={citationStyle}
|
||||||
|
onChange={handleStyleChange}
|
||||||
|
>
|
||||||
|
<option value="apa">APA</option>
|
||||||
|
<option value="mla">MLA</option>
|
||||||
|
<option value="chicago">Chicago</option>
|
||||||
|
<option value="harvard">Harvard</option>
|
||||||
|
<option value="vancouver">Vancouver</option>
|
||||||
|
<option value="ieee">IEEE</option>
|
||||||
|
<option value="custom-chinese">中文</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,3 +1,71 @@
|
||||||
|
// // Path: utils/others/aiutils.ts
|
||||||
|
// import { sendMessageToOpenAI } from "@/components/chatAI";
|
||||||
|
// //判断返回的文献是否跟用户输入的主题相关
|
||||||
|
// export async function evaluateTopicMatch(
|
||||||
|
// userMessage: any[],
|
||||||
|
// apiKey: string,
|
||||||
|
// upsreamUrl: string,
|
||||||
|
// selectedModel: string,
|
||||||
|
// topic: string
|
||||||
|
// ): Promise<{ relevantPapers: string[]; nonRelevantPapers: string[] }> {
|
||||||
|
// const prompt = "请判断文献是否跟用户输入的主题相关,只需要返回true或者false";
|
||||||
|
// let relevantPapers: string[] = []; // 存储相关论文的数组
|
||||||
|
// let nonRelevantPapers: string[] = []; // 存储不相关论文的数组
|
||||||
|
|
||||||
|
// for (const paper of userMessage) {
|
||||||
|
// if (relevantPapers.length >= 2) {
|
||||||
|
// console.log("已找到两篇相关文献,停止处理剩余文献。");
|
||||||
|
// break; // 如果已经有两篇相关文献,则停止处理
|
||||||
|
// }
|
||||||
|
// // 检查是否存在 abstract,如果不存在,直接将论文添加到 nonRelevantPapers
|
||||||
|
// if (!paper.abstract) {
|
||||||
|
// nonRelevantPapers.push(paper);
|
||||||
|
// console.log(
|
||||||
|
// `Paper titled "${paper.title}" has no abstract and was added to non-relevant papers.`
|
||||||
|
// );
|
||||||
|
// continue; // 跳过当前迭代,继续下一个论文
|
||||||
|
// }
|
||||||
|
// const input = `user's topic:${topic}, \n paper's title: ${paper.title}, \n paper's abstract: ${paper.abstract}`;
|
||||||
|
// const isRelevantResult = await sendMessageToOpenAI(
|
||||||
|
// input,
|
||||||
|
// null,
|
||||||
|
// selectedModel!,
|
||||||
|
// apiKey,
|
||||||
|
// upsreamUrl,
|
||||||
|
// prompt,
|
||||||
|
// null,
|
||||||
|
// false
|
||||||
|
// );
|
||||||
|
// console.log("isRelevantResult", isRelevantResult);
|
||||||
|
// // 尝试解析 JSON 结果,如果无法解析则直接使用结果字符串
|
||||||
|
// let isRelevant;
|
||||||
|
// try {
|
||||||
|
// const parsedResult = JSON.parse(isRelevantResult);
|
||||||
|
// isRelevant =
|
||||||
|
// parsedResult === true || parsedResult.toLowerCase() === "true";
|
||||||
|
// } catch {
|
||||||
|
// isRelevant =
|
||||||
|
// isRelevantResult.includes("true") || isRelevantResult.includes("True");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (isRelevant) {
|
||||||
|
// relevantPapers.push(paper); // 如果论文相关,则添加到数组中
|
||||||
|
// } else {
|
||||||
|
// nonRelevantPapers.push(paper); // 如果论文不相关,则添加到不相关论文数组中
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// console.log(
|
||||||
|
// `这次有${nonRelevantPapers.length}篇文献没有通过相关性检查`,
|
||||||
|
// nonRelevantPapers
|
||||||
|
// );
|
||||||
|
// //如果相关文献大于两片则缩减到两篇
|
||||||
|
// // if (relevantPapers.length > 2) {
|
||||||
|
// // relevantPapers = relevantPapers.slice(0, 2);
|
||||||
|
// // console.log("文献太多了,只取前两篇");
|
||||||
|
// // }
|
||||||
|
// return { relevantPapers, nonRelevantPapers };
|
||||||
|
// }
|
||||||
|
|
||||||
// Path: utils/others/aiutils.ts
|
// Path: utils/others/aiutils.ts
|
||||||
import { sendMessageToOpenAI } from "@/components/chatAI";
|
import { sendMessageToOpenAI } from "@/components/chatAI";
|
||||||
//判断返回的文献是否跟用户输入的主题相关
|
//判断返回的文献是否跟用户输入的主题相关
|
||||||
|
@ -8,26 +76,41 @@ export async function evaluateTopicMatch(
|
||||||
selectedModel: string,
|
selectedModel: string,
|
||||||
topic: string
|
topic: string
|
||||||
): Promise<{ relevantPapers: string[]; nonRelevantPapers: string[] }> {
|
): Promise<{ relevantPapers: string[]; nonRelevantPapers: string[] }> {
|
||||||
const prompt = "请判断文献是否跟用户输入的主题相关,只需要返回true或者false";
|
const prompt =
|
||||||
|
"请判断文献是否跟用户输入的主题相关,只需要返回true或false的数组";
|
||||||
let relevantPapers: string[] = []; // 存储相关论文的数组
|
let relevantPapers: string[] = []; // 存储相关论文的数组
|
||||||
let nonRelevantPapers: string[] = []; // 存储不相关论文的数组
|
let nonRelevantPapers: string[] = []; // 存储不相关论文的数组
|
||||||
|
|
||||||
for (const paper of userMessage) {
|
// 修改循环逻辑,每次处理两篇文献
|
||||||
|
for (let i = 0; i < userMessage.length; i += 2) {
|
||||||
|
// 检查是否已有足够的相关论文
|
||||||
if (relevantPapers.length >= 2) {
|
if (relevantPapers.length >= 2) {
|
||||||
console.log("已找到两篇相关文献,停止处理剩余文献。");
|
console.log("已找到两篇相关文献,停止处理剩余文献。");
|
||||||
break; // 如果已经有两篇相关文献,则停止处理
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inputs = [];
|
||||||
|
let papersToEvaluate = userMessage.slice(i, i + 2); // 获取当前迭代的两篇文献
|
||||||
|
|
||||||
|
for (const paper of papersToEvaluate) {
|
||||||
// 检查是否存在 abstract,如果不存在,直接将论文添加到 nonRelevantPapers
|
// 检查是否存在 abstract,如果不存在,直接将论文添加到 nonRelevantPapers
|
||||||
if (!paper.abstract) {
|
if (!paper.abstract) {
|
||||||
nonRelevantPapers.push(paper);
|
nonRelevantPapers.push(paper);
|
||||||
console.log(
|
console.log(
|
||||||
`Paper titled "${paper.title}" has no abstract and was added to non-relevant papers.`
|
`Paper titled "${paper.title}" has no abstract and was added to non-relevant papers.`
|
||||||
);
|
);
|
||||||
continue; // 跳过当前迭代,继续下一个论文
|
continue; // 跳过当前论文,继续下一个论文
|
||||||
}
|
}
|
||||||
|
// 准备输入数据
|
||||||
const input = `user's topic: ${topic}, \n paper's title: ${paper.title}, \n paper's abstract: ${paper.abstract}`;
|
const input = `user's topic: ${topic}, \n paper's title: ${paper.title}, \n paper's abstract: ${paper.abstract}`;
|
||||||
const isRelevantResult = await sendMessageToOpenAI(
|
inputs.push(input);
|
||||||
input,
|
}
|
||||||
|
|
||||||
|
// 如果有需要评估的文献,则发送请求
|
||||||
|
if (inputs.length > 0) {
|
||||||
|
const combinedInput = inputs.join("\n\n");
|
||||||
|
const isRelevantResults = await sendMessageToOpenAI(
|
||||||
|
combinedInput,
|
||||||
null,
|
null,
|
||||||
selectedModel!,
|
selectedModel!,
|
||||||
apiKey,
|
apiKey,
|
||||||
|
@ -36,32 +119,34 @@ export async function evaluateTopicMatch(
|
||||||
null,
|
null,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
console.log("isRelevantResult", isRelevantResult);
|
console.log("isrelevantResults in 相关性检查", isRelevantResults);
|
||||||
// 尝试解析 JSON 结果,如果无法解析则直接使用结果字符串
|
// 处理每篇文献的相关性结果
|
||||||
|
papersToEvaluate.forEach((paper, index) => {
|
||||||
let isRelevant;
|
let isRelevant;
|
||||||
try {
|
try {
|
||||||
const parsedResult = JSON.parse(isRelevantResult);
|
const parsedResults = JSON.parse(isRelevantResults); // 将字符串解析成数组
|
||||||
isRelevant =
|
isRelevant =
|
||||||
parsedResult === true || parsedResult.toLowerCase() === "true";
|
parsedResults[index] === true ||
|
||||||
|
parsedResults[index].toString().toLowerCase() === "true";
|
||||||
} catch {
|
} catch {
|
||||||
isRelevant =
|
console.log("Error parsing isRelevantResults or accessing index");
|
||||||
isRelevantResult.includes("true") || isRelevantResult.includes("True");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRelevant) {
|
if (isRelevant) {
|
||||||
relevantPapers.push(paper); // 如果论文相关,则添加到数组中
|
relevantPapers.push(paper);
|
||||||
|
console.log(`Paper titled "${paper.title}" is relevant.`);
|
||||||
} else {
|
} else {
|
||||||
nonRelevantPapers.push(paper); // 如果论文不相关,则添加到不相关论文数组中
|
nonRelevantPapers.push(paper);
|
||||||
|
console.log(`Paper titled "${paper.title}" is not relevant.`);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`这次有${nonRelevantPapers.length}篇文献没有通过相关性检查`,
|
`这次有${nonRelevantPapers.length}篇文献没有通过相关性检查`,
|
||||||
nonRelevantPapers
|
nonRelevantPapers
|
||||||
);
|
);
|
||||||
//如果相关文献大于两片则缩减到两篇
|
|
||||||
// if (relevantPapers.length > 2) {
|
|
||||||
// relevantPapers = relevantPapers.slice(0, 2);
|
|
||||||
// console.log("文献太多了,只取前两篇");
|
|
||||||
// }
|
|
||||||
return { relevantPapers, nonRelevantPapers };
|
return { relevantPapers, nonRelevantPapers };
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,14 +323,25 @@ export function getFullReference(reference: Reference) {
|
||||||
fullReference += formatReference(reference);
|
fullReference += formatReference(reference);
|
||||||
return fullReference;
|
return fullReference;
|
||||||
}
|
}
|
||||||
export function getAllFullReferences(references: Reference[]) {
|
export function getAllFullReferences(references: Reference[], style: string) {
|
||||||
return references
|
return references
|
||||||
.map((reference, index) => {
|
.map((reference, index) => {
|
||||||
return `[${index + 1}] ${getFullReference(reference)}`;
|
return `[${index + 1}] ${renderCitation(reference, style)}`;
|
||||||
})
|
})
|
||||||
.join("\n");
|
.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function renderCitation(reference: any, style: string) {
|
||||||
|
// 检查当前的引用风格
|
||||||
|
if (style === "custom-chinese") {
|
||||||
|
// 如果是“custom-chinese”,则调用 getFullReference 来渲染引用
|
||||||
|
return getFullReference(reference);
|
||||||
|
} else {
|
||||||
|
// 否则,返回引用对象中对应风格的引用文本
|
||||||
|
return reference[style];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getTextBeforeCursor,
|
getTextBeforeCursor,
|
||||||
updateBracketNumbersInDelta,
|
updateBracketNumbersInDelta,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user