日期Data与数学Math

日期Date

创建日期对象

var date = new Date();

Date()对象的方法有很多,可以把它分为3组

第一组:setXXX:设置时间

第二组:getXXX:获取时间

第三组:toXXX:转化时间格式
方法描述
date.getFullYear()返回四位年份
date.getMonth()返回月份 (0 ~ 11) 注:需要加1
date.getDate()返回一个月中的某一天 (1 ~ 31)
date.getHours()返回小时 (0 ~ 23)。
date.getMinutes()返回分钟(0~59)
date.getSeconds()返回秒(0-59)
date.getDay()返回一周中的某一天 (0 ~ 6)。
date.getTime();返回 1970 年 1 月 1 日至今的毫秒数(时间戳)

用日期(Date)对象方法输出格式:

xxxx年xx月xx日 xx:xx:xx 星期一

<script>
var date = new Date();
// 年
var y = date.getFullYear();
console.log(date.getFullYear());
// 月
var m = date.getMonth() + 1;
console.log(date.getMonth() + 1);
// 日
var d = date.getDate();
console.log(date.getDate());
// 时
var h = date.getHours();
console.log(date.getHours());
// 分
var min1 = date.getMinutes();
console.log(date.getMinutes());
// 秒
var s = date.getSeconds();
console.log(date.getSeconds());

// 星期 0 - 6
var week = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'];

// xxxx年xx月xx日 xx:xx:xx 星期一
console.log(y + "年" + m + "月" + d + "日 " + h + ":" + min1 + ":" + s + week[date.getDay()]);
</script>
设置日期
    1. 粗野模式,简单粗暴,但是会清零时分秒

        var d = new Date("2008/8/8");
        
    2.复杂模式

        var d = new Date();

        d.setFullYear(2009);    //设置年

        d.setMonth(6);          //设置月,超过11,累加年

        d.setDate(27);          //设置日,超过最大日期,累加月

        d.setHours(40);         //设置小时,超过24,累加天

        d.setMinutes(40);       //设置分钟,超过60,累加小时

        d.setSeconds(40);       //设置秒,超过60,累加分钟

        d.setMilliseconds(40);  //设置毫秒,超过1000,累加秒
 例:设置2008年1月12号 17:58:58
 
    var d = new Date()
		console.log(d)
		
//		设置日期:
//			1.直接传参
       // 设置年份
		d.setFullYear(2008)
		// 设置月份
		d.setMonth(0)  // 0 表示1月份  1 表示2月份
		// 设置日期
		d.setDate(12)
		// 小时
		d.setHours(17)
		// 设置分钟
		d.setMinutes(58)
		// 设置秒
		d.setSeconds(58)
         // 设置毫秒
		d.setMilliseconds(666)
		
		console.log(d)

日期转化为毫秒数

console.log(d.setFullYear(2009));

//返回从1970年1月1日,到当前设置的时间的毫秒数

时间的转化

toLocalString() 方法可根据本地时间把 Date 对象转换为字符串,并返回结果。

例1:根据本地时间将其转化为字符串

var d=new Date();
var n=d.toLocaleString(); 
console.log(n);

toLocaleTimeString() 方法可根据本地时间把 Date 对象的时间部分转换为字符串,并返回结果。

var d=new Date();
var n=d.toLocaleTimeString(); 
console.log(n);

toLocaleDateString() 方法可根据本地时间把 Date 对象的日期部分转换为字符串,并返回结果。

var d=new Date();
var n=d.toLocaleDateString(); 
console.log(n);
Math(数学对象介绍)

在脚本初始化被创建,不用实例化,.

格式为:Math.方法名(),如调用random方法,Math.random();

方法描述
Math.max(num1,num2,num3,…,numN)返回最大的一个数,可以写多个
Math.min(num1,num2,num3,…,numN)返回最小的一个数,可以写多个
Math.abs(num)返回绝对值
Math.ceil(num)向上取整,1.1、1.8
Math.floor(num)向下取整,1.1、1.8
Math.round(num)四舍五入
Math.pow(x,y)求x的y次幂 pow(2,2) 4
Math.sqrt(x)求x的平方根 sqrt(9) 3
Math.random()返回0~1之间的随机数

例1:产生随机数

0~10之间的随机整数

10~20之间的随机整数

20~30之间的随机整数

// 0~10之间的随机整数
console.log(Math.round(Math.random() * 10))

// 10~20之间的随机整数
console.log(Math.round(Math.random() * 10) + 10)

// 20~30之间的随机整数
console.log(Math.round(Math.random() * 10) + 20)
随机数如何设定范围
    function myRandom(max,min){

        return Math.round(Math.random()*(max-min)+min);

    }
    myRandom(5,10);

    myRandom(20,4);
    最大值减去最小值得到差,乘以0.1-0.9之间的数,再加上最小值,从而得到他们之间的随机数.
十进制数字转16进制或8进制(了解)

十六进制数:

在数学中是一种逢16进1的[进位制]一般用数字0到9和字母A到F(或af)表示,其中:AF表示10~15,

八进制数

八进制,Octal,缩写OCT或O,一种以8为基数的计数法,采用0,1,2,3,4,5,6,7八个数字,逢八进1

number.toString(radix) 把数字转换为字符串

radix为2时 数字以二进制值显示.

radix为8时 数字以八进制值显示

radix为16时 数字以十六进制值显示

   //十进制转其他
    var x=110;
    console.log(x);
    console.log(x.toString(8) + "这是8");
    console.log(x.toString(16) + "这是16");

parseInt(x,radix) 将其他进制的转化为十进制,

//其他转十进制
    var x='110';
    console.log(parseInt(x,2));
    console.log(parseInt(x,8));
    console.log(parseInt(x,16));
data:<think> data:由于 data:您 data:没有 data:提供 data:具体的 data:统计 data:内容 data:, data:我将 data:为您 data:生成 data:一个 data:示例 data:统计 data:表 data:。 data:假设 data:我们要 data:统计 data:一个 data:班级 data:学生的 data:成绩 data:情况 data:, data:包括 data:学生 data:姓名 data:、 data:学 data:号 data:、 data:各 data:科 data:成绩 data:( data:语文 data:、 data:数学 data:、 data:英语 data:) data:和 data:总分 data:。 data:我们可以 data:创建一个 data:包含 data:以下 data:列的 data:表格 data:: data:1 data:. data:学 data:号 data: ( data:Student data: ID data:) data:2 data:. data:姓名 data: ( data:Name data:) data:3 data:. data:语文 data: ( data:Chinese data:) data:4 data:. data:数学 data: ( data:Math data:) data:5 data:. data:英语 data: ( data:English data:) data:6 data:. data:总分 data: ( data:Total data:) data:假设 data:有 data:5 data:个 data:学生 data:, data:我们将 data:生成 data:一个 data:示例 data:表格 data:。 data:注意 data:: data:由于 data:您 data:没有 data:指定 data:具体 data:数据 data:, data:我将 data:使用 data:随机 data:数据 data:填充 data:。 data:如果您 data:有 data:具体 data:数据 data:, data:请 data:提供 data:, data:我可以 data:帮 data:您 data:填充 data:。 data:</think> data:当然 data:可以 data:! data:为了 data:生成 data:一个 data:符合 data:您 data:需求的 data:统计 data:表 data:, data:我需要 data:了解 data:一些 data:具体 data:信息 data:。 data:请 data:告诉我 data:: data:1 data:. data: ** data:统计 data:主题 data:** data:: data:您 data:想 data:统计 data:什么 data:?( data:例如 data:: data:学生 data:成绩 data:、 data:销售 data:数据 data:、 data:项目 data:进度 data:、 data:调查 data:结果 data:等 data:) data:2 data:. data: ** data:统计 data:维度 data:** data:: data:需要 data:包含 data:哪些 data:列 data:?( data:例如 data:: data:姓名 data:、 data:日期 data:、 data:数量 data:、 data:百分比 data:、 data:分类 data:等 data:) data:3 data:. data: ** data:数据 data:范围 data:** data:: data:需要 data:多少 data:行 data:数据 data:? data:是否需要 data:示例 data:数据 data:还是 data:仅 data:要 data:表格 data:结构 data:? data:4 data:. data: ** data:格式 data:要求 data:** data:: data:是否需要 data:特定 data:样式 data:( data:如 data:颜色 data:、 data:图表 data:) data:或 data:导出 data:格式 data:( data:如 data:Excel data:、 data:Mark data:down data:) data:? data:--- data:### data:示例 data:模板 data:( data:供 data:参考 data:) data:: data:如果您 data:暂时 data:没有 data:具体 data:需求 data:, data:这里 data:是一个 data:通用 data:统计 data:表示 data:例 data:( data:Mark data:down data:格式 data:): data:| data:项目 data: | data:数量 data: | data:占比 data: (%) data: | data:同比增长 data: | data:备注 data: | data:| data:------------- data:| data:------ data:| data:---------- data:| data:----------- data:| data:-------------- data:| data:| data:类别 data:A data: | data:150 data: | data:30 data:% data: | data: + data:5 data:% data: | data:表现 data:稳定 data: | data:| data:类别 data:B data: | data:200 data: | data:40 data:% data: | data: + data:12 data:% data: | data:显著 data:增长 data: | data:| data:类别 data:C data: | data:100 data: | data:20 data:% data: | data: - data:3 data:% data: | data:需 data:关注 data:下滑 data: | data:| data:其他 data: | data:50 data: | data:10 data:% data: | data: + data:1 data:% data: | data:保持 data:平稳 data: | data:| data: ** data:总计 data:** data: | data: ** data:500 data:** data: | data: ** data:100 data:% data:** data: | data: — data: | data: — data: | data:--- data:请 data:提供 data:更多 data:细节 data:, data:我会 data:为您 data:定制 data:生成 data:! 这是后台反的数据 private completeIncrementalMarkdown( chunk: string, accumulatedText: string, isFinal: boolean = false, ): string { if (!chunk) return chunk; let processed = chunk; const fullText = accumulatedText + chunk; // 1. 处理代码块:检测未闭合的代码块 // 统计完整文本中代码块标记的数量(开始和结束都是 ```) const codeBlockMarkers = (fullText.match(/```/g) || []).length; // 如果标记数量是奇数,说明有未闭合的代码块 if (codeBlockMarkers % 2 !== 0 && !isFinal) { // 检查当前块末尾是否有代码块开始标记 const lastCodeBlockIndex = processed.lastIndexOf("```"); if (lastCodeBlockIndex !== -1) { // 检查从最后一个```到末尾是否有结束标记 const afterLastCodeBlock = processed.substring(lastCodeBlockIndex + 3); if (!afterLastCodeBlock.includes("```")) { // 临时添加结束标记(后续数据到达时会重新解析) processed = processed + "\n```"; } } else { // 如果当前块中没有```,但整体有未闭合的代码块,检查是否在代码块内 // 通过分析累积文本来判断 const accumulatedMarkers = (accumulatedText.match(/```/g) || []).length; if (accumulatedMarkers % 2 !== 0) { // 在代码块内,但当前块没有标记,不需要处理 } } } // 2. 处理表格:检测表格边界,补全缺失的管道符和换行 // 检测表格行(以 | 开头和结尾的行) const lines = processed.split("\n"); const processedLines: string[] = []; let inTable = false; let tableColumnCount = 0; for (let i = 0; i < lines.length; i++) { const line = lines[i]; if (line === undefined || line === "") { processedLines.push(line || ""); continue; } // 检测表格行 const isTableRow = /^\s*\|.*\|\s*$/.test(line); const isTableSeparator = /^\s*\|[\s\-:]+\|\s*$/.test(line); if (isTableRow || isTableSeparator) { if (!inTable) { inTable = true; // 计算列数 tableColumnCount = (line.match(/\|/g) || []).length - 1; } // 确保表格行有正确的管道符数量 const pipeCount = (line.match(/\|/g) || []).length; if (pipeCount < tableColumnCount + 1 && !isTableSeparator) { // 补全缺失的管道符 const missingPipes = tableColumnCount + 1 - pipeCount; let fixedLine = line; if (!line.trim().endsWith("|")) { fixedLine = line.trim() + " |".repeat(missingPipes); } processedLines.push(fixedLine); } else { processedLines.push(line); } } else { // 如果之前在表格中,现在不是表格行,结束表格 if (inTable && line.trim() !== "") { inTable = false; tableColumnCount = 0; } processedLines.push(line); } } // 如果最后还在表格中且不是最终块,确保表格有结束 if (inTable && !isFinal) { // 不需要特殊处理,让后续数据自然结束表格 } processed = processedLines.join("\n"); // 3. 处理列表:检测列表项,确保格式正确 // 检测列表项标记(-、*、+、1. 等) const listItemRegex = /^(\s*)([-*+]|\d+\.)\s+/; const linesForList = processed.split("\n"); const processedListLines: string[] = []; for (let i = 0; i < linesForList.length; i++) { const line = linesForList[i]; if (line === undefined || line === "") { processedListLines.push(line || ""); continue; } const listMatch = line.match(listItemRegex); if (listMatch) { // 这是一个列表项 // 确保列表项标记后有空格 if (!line.match(/^(\s*)([-*+]|\d+\.)\s+/)) { // 补全空格 const fixedLine = line.replace( /^(\s*)([-*+]|\d+\.)([^\s])/, "$1$2 $3", ); processedListLines.push(fixedLine); } else { processedListLines.push(line); } } else { // 检查是否是截断的列表项(只有标记,没有内容) const incompleteListMatch = line.match(/^(\s*)([-*+]|\d+\.)\s*$/); if (incompleteListMatch && !isFinal) { // 如果下一行有内容,应该合并 const nextLine = linesForList[i + 1]; if (nextLine && nextLine.trim() !== "") { // 检查下一行是否是列表项或其他特殊格式 const nextIsListItem = /^(\s*)([-*+]|\d+\.)\s+/.test(nextLine); const nextIsHeading = /^#{1,6}\s+/.test(nextLine); const nextIsCodeBlock = nextLine.trim().startsWith("```"); const nextIsTableRow = /^\s*\|.*\|\s*$/.test(nextLine); if ( !nextIsListItem && !nextIsHeading && !nextIsCodeBlock && !nextIsTableRow ) { // 合并为列表项 const indent = incompleteListMatch[1] || ""; const marker = incompleteListMatch[2] || ""; processedListLines.push(indent + marker + " " + nextLine.trim()); i++; // 跳过下一行 continue; } } // 如果无法合并,补全换行符 processedListLines.push(line + "\n"); } else { processedListLines.push(line); } } } processed = processedListLines.join("\n"); // 4. 处理其他块级元素(标题、段落等) // 确保标题前后有换行(在流式传输中可能被截断) if (!isFinal) { // 检查末尾是否有未完成的标题 const lastLine = processed.split("\n").pop() || ""; const headingMatch = lastLine.match(/^(#{1,6})\s*([^\n]*)$/); if (headingMatch && !headingMatch[2]) { // 标题标记后没有内容,可能是被截断了 // 不需要特殊处理,等待后续数据 } } return processed; } /** * 最终Markdown结构修复函数 * 在流结束时调用,确保所有Markdown结构完整 * @param text 完整的文本内容 * @returns 修复后的文本 */ private finalizeMarkdownStructure(text: string): string { if (!text) return text; let processed = text; // 1. 修复未闭合的代码块 const codeBlockMarkers = (processed.match(/```/g) || []).length; if (codeBlockMarkers % 2 !== 0) { // 有未闭合的代码块,添加结束标记 processed = processed + "\n```"; } // 2. 修复表格:确保表格行结构完整 const lines = processed.split("\n"); const fixedLines: string[] = []; let inTable = false; let tableColumnCount = 0; for (let i = 0; i < lines.length; i++) { const line = lines[i]; if (line === undefined || line === "") { fixedLines.push(line || ""); continue; } const isTableRow = /^\s*\|.*\|\s*$/.test(line); const isTableSeparator = /^\s*\|[\s\-:]+\|\s*$/.test(line); if (isTableRow || isTableSeparator) { if (!inTable) { inTable = true; tableColumnCount = (line.match(/\|/g) || []).length - 1; } // 确保表格行有正确的管道符数量 const pipeCount = (line.match(/\|/g) || []).length; if (pipeCount < tableColumnCount + 1 && !isTableSeparator) { // 补全缺失的管道符 const missingPipes = tableColumnCount + 1 - pipeCount; let fixedLine = line.trim(); if (!fixedLine.endsWith("|")) { fixedLine = fixedLine + " |".repeat(missingPipes); } else { // 如果已经有结束的|,在中间补全 const parts = fixedLine.split("|"); while (parts.length < tableColumnCount + 2) { parts.splice(-1, 0, ""); } fixedLine = parts.join("|"); } fixedLines.push(fixedLine); } else { fixedLines.push(line); } } else { if (inTable && line.trim() !== "") { inTable = false; tableColumnCount = 0; } fixedLines.push(line); } } processed = fixedLines.join("\n"); // 3. 修复列表:确保列表项格式正确 const listLines = processed.split("\n"); const fixedListLines: string[] = []; for (let i = 0; i < listLines.length; i++) { const line = listLines[i]; if (line === undefined || line === "") { fixedListLines.push(line || ""); continue; } // 检测不完整的列表项(只有标记,没有内容) const incompleteListMatch = line.match(/^(\s*)([-*+]|\d+\.)\s*$/); if (incompleteListMatch) { // 移除不完整的列表项标记 fixedListLines.push(""); } else { // 确保列表项标记后有空格 const fixedLine = line.replace( /^(\s*)([-*+]|\d+\.)([^\s\n])/, "$1$2 $3", ); fixedListLines.push(fixedLine); } } processed = fixedListLines.join("\n"); // 4. 清理多余的空行(保留最多3个连续换行) processed = processed.replace(/\n{4,}/g, "\n\n\n"); return processed; } private handleStreamMessage( data: StreamMessageData, message: ChatHistoryItem, ) { // 初始化 answer 字段(如果还没有) if (message.answer === undefined || message.answer === null) { message.answer = ""; } // 处理深度思考数据 (redacted_reasoning) if ( data.redacted_reasoning !== undefined && data.redacted_reasoning !== null ) { // 记录思考开始时间(如果还没有) if (!message.reasoningStartTime) { message.reasoningStartTime = Date.now(); } // 累积思考内容 const previousReasoning = message.redactedReasoning || ""; message.redactedReasoning = previousReasoning + (data.redacted_reasoning || ""); // 计算当前思考时间(秒) const currentTime = Date.now(); message.reasoningTime = Math.floor( (currentTime - message.reasoningStartTime) / 1000, ); } // 提取文本内容 let textContent = ""; // 如果 data 本身是字符串 if (typeof data === "string") { // 检查是否包含 think 标签 if (data.includes("<think>") || data.includes("</think>")) { // 如果包含 think 标签,按照 message 字符串的处理逻辑处理 const reasoningMatch = data.match(/<think>(.*?)<\/think>/s); if (reasoningMatch) { // 提取深度思考内容 const reasoningContent = reasoningMatch[1]; if (!message.reasoningStartTime) { message.reasoningStartTime = Date.now(); } const previousReasoning = message.redactedReasoning || ""; message.redactedReasoning = previousReasoning + reasoningContent; const currentTime = Date.now(); message.reasoningTime = Math.floor( (currentTime - message.reasoningStartTime) / 1000, ); message.reasoningEnded = true; textContent = data.replace(/<think>.*?<\/think>/s, ""); } else if (data.includes("<think>")) { if (!message.reasoningStartTime) { message.reasoningStartTime = Date.now(); } const afterStartTag = data.replace(/<think>/, ""); if (afterStartTag.trim()) { const previousReasoning = message.redactedReasoning || ""; message.redactedReasoning = previousReasoning + afterStartTag; const currentTime = Date.now(); if (message.reasoningStartTime) { message.reasoningTime = Math.floor( (currentTime - message.reasoningStartTime) / 1000, ); } } textContent = ""; } else if (data.includes("</think>")) { const beforeEndTag = data.replace(/<\/think>.*$/, ""); if (beforeEndTag.trim()) { const previousReasoning = message.redactedReasoning || ""; message.redactedReasoning = previousReasoning + beforeEndTag; const currentTime = Date.now(); if (message.reasoningStartTime) { message.reasoningTime = Math.floor( (currentTime - message.reasoningStartTime) / 1000, ); } } message.reasoningEnded = true; const afterEndTag = data.replace(/.*?<\/think>/, ""); textContent = afterEndTag.trim() || ""; } else if (message.reasoningStartTime && !message.reasoningEnded) { // 在思考过程中,内容应该添加到 redactedReasoning const previousReasoning = message.redactedReasoning || ""; message.redactedReasoning = previousReasoning + data; const currentTime = Date.now(); if (message.reasoningStartTime) { message.reasoningTime = Math.floor( (currentTime - message.reasoningStartTime) / 1000, ); } textContent = ""; } else { textContent = data; } } else if (message.reasoningStartTime && !message.reasoningEnded) { // 在思考过程中,内容应该添加到 redactedReasoning const previousReasoning = message.redactedReasoning || ""; message.redactedReasoning = previousReasoning + data; const currentTime = Date.now(); if (message.reasoningStartTime) { message.reasoningTime = Math.floor( (currentTime - message.reasoningStartTime) / 1000, ); } textContent = ""; } else { textContent = data; } } // 如果 data.message 是字符串 else if (data.message !== undefined && data.message !== null) { if (typeof data.message === "string") { // 检查是否包含完整的 <think>...</think> 标签 const reasoningMatch = data.message.match(/<think>(.*?)<\/think>/s); if (reasoningMatch) { // 提取深度思考内容 const reasoningContent = reasoningMatch[1]; if (!message.reasoningStartTime) { message.reasoningStartTime = Date.now(); } const previousReasoning = message.redactedReasoning || ""; message.redactedReasoning = previousReasoning + reasoningContent; const currentTime = Date.now(); message.reasoningTime = Math.floor( (currentTime - message.reasoningStartTime) / 1000, ); // 标记思考已结束 message.reasoningEnded = true; // 从 textContent 中移除深度思考标签及其内容 textContent = data.message.replace(/<think>.*?<\/think>/s, ""); } else { // 检查是否只是开始标签或结束标签(流式传输中可能分多次) if (data.message.includes("<think>")) { // 开始标签,记录开始时间 if (!message.reasoningStartTime) { message.reasoningStartTime = Date.now(); } // 提取开始标签后的内容 const afterStartTag = data.message.replace(/<think>/, ""); if (afterStartTag.trim()) { const previousReasoning = message.redactedReasoning || ""; message.redactedReasoning = previousReasoning + afterStartTag; const currentTime = Date.now(); if (message.reasoningStartTime) { message.reasoningTime = Math.floor( (currentTime - message.reasoningStartTime) / 1000, ); } } textContent = ""; // 不添加到 answer 中 } else if (data.message.includes("</think>")) { // 结束标签,提取结束标签前的内容 const beforeEndTag = data.message.replace(/<\/think>.*$/, ""); if (beforeEndTag.trim()) { const previousReasoning = message.redactedReasoning || ""; message.redactedReasoning = previousReasoning + beforeEndTag; const currentTime = Date.now(); if (message.reasoningStartTime) { message.reasoningTime = Math.floor( (currentTime - message.reasoningStartTime) / 1000, ); } } // 标记思考已结束 message.reasoningEnded = true; // 提取结束标签后的内容作为实际回复 const afterEndTag = data.message.replace(/.*?<\/think>/, ""); textContent = afterEndTag.trim() || ""; } else if (message.reasoningStartTime && !message.reasoningEnded) { // 如果已经在思考过程中,且思考还未结束 // 这些内容应该被添加到 redactedReasoning 而不是 answer const previousReasoning = message.redactedReasoning || ""; message.redactedReasoning = previousReasoning + data.message; const currentTime = Date.now(); if (message.reasoningStartTime) { message.reasoningTime = Math.floor( (currentTime - message.reasoningStartTime) / 1000, ); } textContent = ""; // 不添加到 answer 中 } else { // 普通消息内容(思考已结束或未开始思考) textContent = data.message; } } } else if (typeof data.message === "object") { // 如果 message 是对象,尝试提取文本内容 // 同时检查是否有 redacted_reasoning 字段 if ( "redacted_reasoning" in data.message && typeof (data.message as any).redacted_reasoning === "string" ) { // 处理嵌套在 message 中的 redacted_reasoning if (!message.reasoningStartTime) { message.reasoningStartTime = Date.now(); } const previousReasoning = message.redactedReasoning || ""; message.redactedReasoning = previousReasoning + (data.message as any).redacted_reasoning; const currentTime = Date.now(); message.reasoningTime = Math.floor( (currentTime - message.reasoningStartTime) / 1000, ); } if ( "content" in data.message && typeof (data.message as any).content === "string" ) { textContent = (data.message as any).content; } else if ( "text" in data.message && typeof (data.message as any).text === "string" ) { textContent = (data.message as any).text; } else { // 尝试 JSON 序列化 textContent = JSON.stringify(data.message); } } } // 如果 data.messageOutput 是字符串 else if ( data.messageOutput !== undefined && typeof data.messageOutput === "string" ) { textContent = data.messageOutput; } // 如果 data 是对象但没有 message 字段,尝试转换为字符串 else if (data && typeof data === "object") { // 如果对象有 content 字段(使用类型断言检查) if ((data as any).content && typeof (data as any).content === "string") { textContent = (data as any).content; } else if ((data as any).text && typeof (data as any).text === "string") { textContent = (data as any).text; } else { // 否则尝试 JSON 序列化(用于调试) const dataStr = JSON.stringify(data); // 如果整个对象看起来像文本数据,使用它 if (dataStr.length < 200) { textContent = dataStr; } } } // 累加文本内容(打字机效果) if (textContent) { const previousAnswer = message.answer || ""; // 对当前块进行Markdown结构补全 const isFinal = data.event === StreamEventType.STOP; const completedChunk = this.completeIncrementalMarkdown( textContent, previousAnswer, isFinal, ); message.answer = previousAnswer + completedChunk; if (message.answer) { message.answer = message.answer.replace(/<think>.*?<\/think>/gs, ""); message.answer = message.answer.replace(/<think>/g, ""); message.answer = message.answer.replace(/<\/think>/g, ""); } // 设置事件类型 if (data.event) { message.eventType = data.event; } } else { console.warn("handleStreamMessage - 未提取到文本内容", data); } // 处理特殊事件 if (data.event === StreamEventType.STOP) { // 对话结束,保存logID if ( data.message && typeof data.message === "object" && "id" in data.message ) { message.id = data.message.id; } // 最终计算思考时间 if (message.reasoningStartTime && message.redactedReasoning) { const currentTime = Date.now(); message.reasoningTime = Math.floor( (currentTime - message.reasoningStartTime) / 1000, ); } // 最终清理:从 answer 中移除所有深度思考标签及其内容 if (message.answer) { message.answer = message.answer.replace(/<think>.*?<\/think>/gs, ""); // 清理可能残留的开始或结束标签 message.answer = message.answer.replace(/<think>/g, ""); message.answer = message.answer.replace(/<\/think>/g, ""); // 最终Markdown结构修复:确保所有结构完整 message.answer = this.finalizeMarkdownStructure(message.answer); } } else if (data.event === StreamEventType.ERROR) { // 错误处理 if (typeof data.message === "string") { message.eventType = data.event; } } // 实时清理:从 answer 中移除已提取的深度思考标签(避免重复显示) if (message.answer && message.reasoningStartTime) { // 如果正在思考过程中,确保 answer 中不包含思考内容 // 这个清理会在每次更新时进行,确保思考内容不会出现在最终答案中 message.answer = message.answer.replace(/<think>.*?<\/think>/gs, ""); // 清理可能残留的开始或结束标签 message.answer = message.answer.replace(/<think>/g, ""); message.answer = message.answer.replace(/<\/think>/g, ""); } } 这是处理数据的方法 const html = marked.parse(markdown, { gfm: true, breaks: true, });这是渲染方法,为什么表格换行等全部没有正确展示html---###包括这种符号渲染在内容中
12-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值