mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-12 09:18:14 +08:00
fix(parser): 完善数据解析
This commit is contained in:
@@ -62,9 +62,10 @@ import TLoading from "../components/t-loading.vue";
|
||||
import { fs, http } from "@tauri-apps/api";
|
||||
// store
|
||||
import useAppStore from "../store/modules/app";
|
||||
// plugin
|
||||
import Mys_Oper from "../plugins/Mys";
|
||||
// utils
|
||||
import { createTGWindow } from "../utils/TGWindow";
|
||||
import { StructuredPostParser } from "../plugins/Mys/utils/parser";
|
||||
// interface
|
||||
import {
|
||||
GachaResponse,
|
||||
@@ -180,7 +181,7 @@ async function toPost(post_id: string) {
|
||||
return res.data.post.post;
|
||||
});
|
||||
// 结构化渲染
|
||||
const parseDoc = StructuredPostParser(post.structured_content);
|
||||
const parseDoc = Mys_Oper.PostParser(post.structured_content);
|
||||
// 将解析后的 doc 保存到 文件
|
||||
await fs.writeTextFile(
|
||||
`${appStore.dataPath.temp}\\${post_id}_home.html`,
|
||||
|
||||
@@ -132,9 +132,10 @@ import useAppStore from "../store/modules/app";
|
||||
// tools
|
||||
// @ts-ignore
|
||||
import "../tools/svg-inject.js";
|
||||
// plugin
|
||||
import Mys_Oper from "../plugins/Mys";
|
||||
// utils
|
||||
import { createTGWindow } from "../utils/TGWindow";
|
||||
import { StructuredPostParser } from "../plugins/Mys/utils/parser";
|
||||
// interface
|
||||
import {
|
||||
Post,
|
||||
@@ -215,7 +216,7 @@ async function toPost(post_id: string) {
|
||||
// 获取渲染模式
|
||||
if (renderMode.value) {
|
||||
// 结构化渲染
|
||||
parseDoc = StructuredPostParser(post.structured_content);
|
||||
parseDoc = Mys_Oper.PostParser(post.structured_content);
|
||||
} else {
|
||||
// 原始渲染
|
||||
parseDoc = new DOMParser().parseFromString(post.content, "text/html");
|
||||
|
||||
14
src/plugins/Mys/index.ts
Normal file
14
src/plugins/Mys/index.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* @file plugins Mys index.ts
|
||||
* @description Mys plugin index
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha
|
||||
*/
|
||||
|
||||
import { PostParser } from "./utils/parser";
|
||||
|
||||
const Mys_Oper = {
|
||||
PostParser,
|
||||
};
|
||||
|
||||
export default Mys_Oper;
|
||||
@@ -322,4 +322,4 @@ export interface PostStructuredContent {
|
||||
color?: string;
|
||||
link?: string;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
* @author BTMuli<bt-muli@outlook.com>
|
||||
* @since Alpha
|
||||
*/
|
||||
|
||||
import { PostStructuredContent } from "../interface/post";
|
||||
|
||||
/**
|
||||
@@ -13,87 +12,26 @@ import { PostStructuredContent } from "../interface/post";
|
||||
* @description 为了安全考虑,不会解析所有的属性,只会解析几个常用的属性
|
||||
* @returns {Document} 解析后的 HTML 文档
|
||||
*/
|
||||
export function StructuredPostParser(data: string): Document {
|
||||
export function PostParser(data: string): Document {
|
||||
// Json 化
|
||||
let jsonData: PostStructuredContent[] = JSON.parse(data);
|
||||
// 创建 HTML 文档
|
||||
const doc = document.implementation.createHTMLDocument();
|
||||
// 遍历 Json 数据
|
||||
jsonData.forEach((item: any) => {
|
||||
if (item.insert.image) {
|
||||
// 创建 div
|
||||
const div = document.createElement("div");
|
||||
// 创建图片
|
||||
const img = document.createElement("img");
|
||||
img.src = item.insert.image;
|
||||
// 设置图片属性
|
||||
img.height = item.attributes.height; // 设置高度
|
||||
img.width = item.attributes.width; // 设置宽度
|
||||
// 如果宽度超过 800,将其设置为 800,图片自适应
|
||||
if (img.width > 800) img.width = 800;
|
||||
// 高度自适应
|
||||
img.style.height = "auto";
|
||||
// 插入图片
|
||||
div.appendChild(img);
|
||||
// 设置 div 属性
|
||||
div.style.display = "center"; // 居中
|
||||
div.style.margin = "20px auto"; // 设置 margin
|
||||
// 插入 div
|
||||
doc.body.appendChild(div);
|
||||
if (typeof item.insert === "string") {
|
||||
const text = TextParser(item);
|
||||
doc.body.appendChild(text);
|
||||
} else if (item.insert.image) {
|
||||
const img = ImageParser(item);
|
||||
doc.body.appendChild(img);
|
||||
} else if (item.insert.vod) {
|
||||
// 创建 div
|
||||
const div = document.createElement("div");
|
||||
// 创建视频
|
||||
const video = document.createElement("video");
|
||||
// 获取最高分辨率的视频
|
||||
let resolution;
|
||||
// 获取 resolutions中definition="1080P"的视频
|
||||
resolution = item.insert.vod.resolutions.find(
|
||||
(resolution: any) => resolution.definition === "1080P"
|
||||
);
|
||||
if (!resolution) {
|
||||
// 如果没有找到,就获取720P的视频
|
||||
resolution = item.insert.vod.resolutions.find(
|
||||
(resolution: any) => resolution.definition === "720P"
|
||||
);
|
||||
}
|
||||
if (!resolution) {
|
||||
// 如果还是没有找到,就获取第一个
|
||||
resolution = item.insert.vod.resolutions[0];
|
||||
}
|
||||
// 设置一些属性
|
||||
video.poster = item.insert.vod.cover; // 设置封面
|
||||
video.width = resolution.width > 800 ? 800 : resolution.width; // 设置宽度(取最高分辨率的宽度)
|
||||
video.height = resolution.width > 800 ? 450 : resolution.height; // 设置高度(取最高分辨率的高度)
|
||||
video.controls = true; // 设置 controls
|
||||
// 添加 source
|
||||
const source = document.createElement("source");
|
||||
source.src = resolution.url;
|
||||
source.type = resolution.format === ".mp4" ? "video/mp4" : "video/webm";
|
||||
video.appendChild(source);
|
||||
// 添加 controls
|
||||
video.controls = true;
|
||||
// 插入 video
|
||||
div.appendChild(video);
|
||||
// 设置 div 属性
|
||||
div.style.display = "center"; // 居中
|
||||
div.style.margin = "20px auto"; // 设置 margin
|
||||
const video = VideoParser(item);
|
||||
// 插入 div
|
||||
doc.body.appendChild(div);
|
||||
} else if (typeof item.insert === "string") {
|
||||
// 创建文本
|
||||
const text = document.createElement("span");
|
||||
// 设置文本属性
|
||||
// 创建 style string
|
||||
if (item.attributes) {
|
||||
let styleString = "";
|
||||
if (item.attributes.color) styleString += `color: ${item.attributes.color};`;
|
||||
// 设置 style
|
||||
text.style.cssText = styleString;
|
||||
}
|
||||
text.innerText = item.insert; // 设置文本
|
||||
// 插入文本
|
||||
doc.body.appendChild(text);
|
||||
doc.body.appendChild(video);
|
||||
} else if (item.insert.backup_text) {
|
||||
// TODO: 折叠内容
|
||||
}
|
||||
});
|
||||
// doc 宽度设为 800,居中
|
||||
@@ -101,3 +39,123 @@ export function StructuredPostParser(data: string): Document {
|
||||
doc.body.style.margin = "20px auto";
|
||||
return doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 解析文本
|
||||
* @since Alpha
|
||||
* @param {PostStructuredContent} data Mys数据
|
||||
* @returns {HTMLSpanElement} 解析后的文本
|
||||
*/
|
||||
function TextParser(data: PostStructuredContent): HTMLSpanElement {
|
||||
// 检查数据
|
||||
if (typeof data.insert !== "string") {
|
||||
throw new Error("data.insert is not a string");
|
||||
}
|
||||
// 创建文本
|
||||
const text = document.createElement("span");
|
||||
// 设置文本属性
|
||||
if (data.attributes) {
|
||||
if (data.attributes.bold) text.style.fontWeight = "bold";
|
||||
if (data.attributes.color) text.style.color = data.attributes.color;
|
||||
if (data.attributes.link) {
|
||||
const a = document.createElement("a");
|
||||
a.href = data.attributes.link;
|
||||
a.target = "_blank";
|
||||
a.innerText = data.insert;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
// 行间距
|
||||
text.style.lineHeight = "2";
|
||||
// 设置 span 内容
|
||||
text.innerText = data.insert;
|
||||
// 返回文本
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 解析图片
|
||||
* @since Alpha
|
||||
* @param {PostStructuredContent} data Mys数据
|
||||
* @returns {HTMLDivElement} 解析后的图片
|
||||
*/
|
||||
function ImageParser(data: PostStructuredContent): HTMLDivElement {
|
||||
// 检查数据
|
||||
if (typeof data.insert === "string") {
|
||||
throw new Error("data.insert is a string");
|
||||
}
|
||||
if (!data.insert.image) {
|
||||
throw new Error("data.insert.image is not defined");
|
||||
}
|
||||
if (!data.attributes) {
|
||||
throw new Error("data.attributes is not defined");
|
||||
}
|
||||
if (!data.attributes.width) {
|
||||
throw new Error("data.attributes.width is not defined");
|
||||
}
|
||||
if (!data.attributes.height) {
|
||||
throw new Error("data.attributes.height is not defined");
|
||||
}
|
||||
const div = document.createElement("div");
|
||||
// 创建图片
|
||||
const img = document.createElement("img");
|
||||
img.src = data.insert.image;
|
||||
// 设置图片属性,窗口宽度 900,页面宽度 800
|
||||
img.style.height = "auto"; // 高度自适应
|
||||
img.width = 800; // 设置宽度
|
||||
// 判断是否是 cover
|
||||
if (data.attributes.width === 690 && data.attributes.height === 320) {
|
||||
// 添加 border-radius
|
||||
img.style.borderRadius = "10px";
|
||||
}
|
||||
// 插入图片
|
||||
div.appendChild(img);
|
||||
// 设置 div 属性
|
||||
div.style.display = "center"; // 居中
|
||||
div.style.margin = "20px auto"; // 设置 margin
|
||||
// 返回 div
|
||||
return div;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 解析视频
|
||||
* @since Alpha
|
||||
* @param {PostStructuredContent} data Mys数据
|
||||
* @returns {HTMLDivElement} 解析后的视频
|
||||
*/
|
||||
function VideoParser(data: PostStructuredContent): HTMLDivElement {
|
||||
// 检查数据
|
||||
if (typeof data.insert === "string") {
|
||||
throw new Error("data.insert is a string");
|
||||
}
|
||||
if (!data.insert.vod) {
|
||||
throw new Error("data.insert.vod is not defined");
|
||||
}
|
||||
// 创建 div
|
||||
const div = document.createElement("div");
|
||||
// 创建视频
|
||||
const video = document.createElement("video");
|
||||
// 获取 resolutions中size最大的视频
|
||||
const resolution = data.insert.vod.resolutions.reduce((prev: any, curr: any) => {
|
||||
if (prev.size > curr.size) return prev;
|
||||
return curr;
|
||||
});
|
||||
// 设置视频属性
|
||||
video.poster = data.insert.vod.cover; // 设置封面
|
||||
video.width = 800; // 设置宽度
|
||||
video.height = 450; // 设置高度
|
||||
video.controls = true; // 设置 controls
|
||||
// 添加 source
|
||||
const source = document.createElement("source");
|
||||
source.src = resolution.url;
|
||||
source.type = resolution.format === ".mp4" ? "video/mp4" : "video/webm";
|
||||
// 插入 source
|
||||
video.appendChild(source);
|
||||
// 插入 video
|
||||
div.appendChild(video);
|
||||
// 设置 div 属性
|
||||
div.style.display = "center"; // 居中
|
||||
div.style.margin = "20px auto"; // 设置 margin
|
||||
// 返回 div
|
||||
return div;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user