|
@@ -235,9 +235,11 @@ function renderRawCases(rawCasesObj) {
|
|
|
const renderPaneContent = (pList) => {
|
|
const renderPaneContent = (pList) => {
|
|
|
let paneHtml = '';
|
|
let paneHtml = '';
|
|
|
let totalCases = 0;
|
|
let totalCases = 0;
|
|
|
- let gridHtml = '';
|
|
|
|
|
let seenIds = new Set();
|
|
let seenIds = new Set();
|
|
|
|
|
|
|
|
|
|
+ let groupedHtml = {};
|
|
|
|
|
+ const getGroupKey = (c, p) => (p === 'filtered_cases' && c.filter_reason) ? `🚫 过滤原因: ${c.filter_reason}` : 'default';
|
|
|
|
|
+
|
|
|
pList.forEach(p => {
|
|
pList.forEach(p => {
|
|
|
if (!rawCasesObj[p]) return;
|
|
if (!rawCasesObj[p]) return;
|
|
|
if (rawCasesObj[p].error) {
|
|
if (rawCasesObj[p].error) {
|
|
@@ -248,11 +250,27 @@ function renderRawCases(rawCasesObj) {
|
|
|
</div>`;
|
|
</div>`;
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
- if (rawCasesObj[p].reason) {
|
|
|
|
|
- paneHtml += `<div style="padding:0.5rem 1rem; background:rgba(239, 68, 68, 0.1); border:1px solid var(--danger); border-radius:6px; margin-bottom:1rem; color:var(--danger); font-size:0.9rem;">🛑 ${p} 过滤原因: ${rawCasesObj[p].reason}</div>`;
|
|
|
|
|
|
|
+ if (rawCasesObj[p].reason && p !== 'filtered_cases') {
|
|
|
|
|
+ paneHtml += `<div style="padding:0.5rem 1rem; background:rgba(239, 68, 68, 0.1); border:1px solid var(--danger); border-radius:6px; margin-bottom:1rem; color:var(--danger); font-size:0.9rem;">🛑 ${p} 提示: ${rawCasesObj[p].reason}</div>`;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const cases = Array.isArray(rawCasesObj[p]) ? rawCasesObj[p] : (rawCasesObj[p].cases || rawCasesObj[p].sources || []);
|
|
|
|
|
|
|
+ let cases = [];
|
|
|
|
|
+ if (Array.isArray(rawCasesObj[p])) {
|
|
|
|
|
+ cases = rawCasesObj[p];
|
|
|
|
|
+ } else if (rawCasesObj[p].cases) {
|
|
|
|
|
+ cases = rawCasesObj[p].cases;
|
|
|
|
|
+ } else if (rawCasesObj[p].sources) {
|
|
|
|
|
+ cases = rawCasesObj[p].sources;
|
|
|
|
|
+ } else if (rawCasesObj[p].by_reason) {
|
|
|
|
|
+ Object.entries(rawCasesObj[p].by_reason).forEach(([reasonKey, reasonObj]) => {
|
|
|
|
|
+ if (reasonObj.sources && Array.isArray(reasonObj.sources)) {
|
|
|
|
|
+ reasonObj.sources.forEach(src => {
|
|
|
|
|
+ if (!src.filter_reason) src.filter_reason = reasonKey;
|
|
|
|
|
+ cases.push(src);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
if (cases.length > 0) {
|
|
if (cases.length > 0) {
|
|
|
if (!rawCasesObj['source'] && p !== 'source_ex' && p !== 'filtered_cases' && p !== 'source') {
|
|
if (!rawCasesObj['source'] && p !== 'source_ex' && p !== 'filtered_cases' && p !== 'source') {
|
|
|
paneHtml += `<div style="padding:1rem; background:rgba(0, 0, 0, 0.05); border:1px solid rgba(0, 0, 0, 0.1); border-radius:8px; margin-bottom:1rem;">
|
|
paneHtml += `<div style="padding:1rem; background:rgba(0, 0, 0, 0.05); border:1px solid rgba(0, 0, 0, 0.1); border-radius:8px; margin-bottom:1rem;">
|
|
@@ -266,6 +284,10 @@ function renderRawCases(rawCasesObj) {
|
|
|
totalCases++;
|
|
totalCases++;
|
|
|
const cId = c.case_id || (c._raw && c._raw.case_id) || (c.post && c.post.channel_content_id) || `temp_${p}_${idx}`;
|
|
const cId = c.case_id || (c._raw && c._raw.case_id) || (c.post && c.post.channel_content_id) || `temp_${p}_${idx}`;
|
|
|
const cUrl = c.source_url || c.url || (c.post && c.post.link) || '';
|
|
const cUrl = c.source_url || c.url || (c.post && c.post.link) || '';
|
|
|
|
|
+
|
|
|
|
|
+ const groupKey = getGroupKey(c, p);
|
|
|
|
|
+ if (!groupedHtml[groupKey]) groupedHtml[groupKey] = '';
|
|
|
|
|
+
|
|
|
if (cId || cUrl || c.post) {
|
|
if (cId || cUrl || c.post) {
|
|
|
const mappedS = sourceMap[cId] || sourceMap[cUrl] || (c._raw && sourceMap[c._raw.case_id]);
|
|
const mappedS = sourceMap[cId] || sourceMap[cUrl] || (c._raw && sourceMap[c._raw.case_id]);
|
|
|
if (p !== 'filtered_cases' && p !== 'source' && p !== 'source_ex' && !mappedS) return;
|
|
if (p !== 'filtered_cases' && p !== 'source' && p !== 'source_ex' && !mappedS) return;
|
|
@@ -300,7 +322,7 @@ function renderRawCases(rawCasesObj) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- gridHtml += `<div class="masonry-card" style="position:relative;" onclick="openCaseDetail('${p}', ${idx})">
|
|
|
|
|
|
|
+ groupedHtml[groupKey] += `<div class="masonry-card" style="position:relative;" onclick="openCaseDetail('${p}', ${idx})">
|
|
|
${platBadge}
|
|
${platBadge}
|
|
|
${actionBtn}
|
|
${actionBtn}
|
|
|
${allImages.length > 0 ? `<img class="cover-img" src="${coverImgUrl}" onerror="this.onerror=null; this.src='${fallbackImgUrl}';">` : ''}
|
|
${allImages.length > 0 ? `<img class="cover-img" src="${coverImgUrl}" onerror="this.onerror=null; this.src='${fallbackImgUrl}';">` : ''}
|
|
@@ -314,7 +336,7 @@ function renderRawCases(rawCasesObj) {
|
|
|
</div>
|
|
</div>
|
|
|
</div>`;
|
|
</div>`;
|
|
|
} else {
|
|
} else {
|
|
|
- gridHtml += `<div class="masonry-card" style="padding:12px; font-family:monospace; font-size:0.8em;" onclick="openCaseDetail('${p}', ${idx})">
|
|
|
|
|
|
|
+ groupedHtml[groupKey] += `<div class="masonry-card" style="padding:12px; font-family:monospace; font-size:0.8em;" onclick="openCaseDetail('${p}', ${idx})">
|
|
|
📝 旧版格式 / 解析失败<br>点击查看详情
|
|
📝 旧版格式 / 解析失败<br>点击查看详情
|
|
|
</div>`;
|
|
</div>`;
|
|
|
}
|
|
}
|
|
@@ -324,8 +346,15 @@ function renderRawCases(rawCasesObj) {
|
|
|
|
|
|
|
|
if (totalCases === 0 && pList.length > 0 && !paneHtml.includes('解析失败') && !paneHtml.includes('未进行')) {
|
|
if (totalCases === 0 && pList.length > 0 && !paneHtml.includes('解析失败') && !paneHtml.includes('未进行')) {
|
|
|
paneHtml += `<div style="padding:1rem; color:var(--text-muted); text-align:center;">暂无数据</div>`;
|
|
paneHtml += `<div style="padding:1rem; color:var(--text-muted); text-align:center;">暂无数据</div>`;
|
|
|
- } else if (gridHtml) {
|
|
|
|
|
- paneHtml += `<div class="masonry-grid">${gridHtml}</div>`;
|
|
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Object.entries(groupedHtml).forEach(([groupName, gHtml]) => {
|
|
|
|
|
+ if (gHtml) {
|
|
|
|
|
+ if (groupName !== 'default') {
|
|
|
|
|
+ paneHtml += `<h3 style="margin-top: 1rem; margin-bottom: 0.5rem; font-size: 1.1rem; color: var(--text-main); border-left: 4px solid var(--accent-primary); padding-left: 8px;">${groupName}</h3>`;
|
|
|
|
|
+ }
|
|
|
|
|
+ paneHtml += `<div class="masonry-grid">${gHtml}</div>`;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
return paneHtml;
|
|
return paneHtml;
|
|
|
};
|
|
};
|
|
@@ -1824,9 +1853,29 @@ window.openCaseDetail = function(p, initialIdx) {
|
|
|
|
|
|
|
|
platformsToAggregate.forEach(plat => {
|
|
platformsToAggregate.forEach(plat => {
|
|
|
if (!ctx.rawCasesObj[plat]) return;
|
|
if (!ctx.rawCasesObj[plat]) return;
|
|
|
- const platCases = ctx.rawCasesObj[plat].cases || ctx.rawCasesObj[plat].sources || [];
|
|
|
|
|
|
|
+ let platCases = [];
|
|
|
|
|
+ if (Array.isArray(ctx.rawCasesObj[plat])) {
|
|
|
|
|
+ platCases = ctx.rawCasesObj[plat];
|
|
|
|
|
+ } else if (ctx.rawCasesObj[plat].cases) {
|
|
|
|
|
+ platCases = ctx.rawCasesObj[plat].cases;
|
|
|
|
|
+ } else if (ctx.rawCasesObj[plat].sources) {
|
|
|
|
|
+ platCases = ctx.rawCasesObj[plat].sources;
|
|
|
|
|
+ } else if (ctx.rawCasesObj[plat].by_reason) {
|
|
|
|
|
+ Object.entries(ctx.rawCasesObj[plat].by_reason).forEach(([reasonKey, reasonObj]) => {
|
|
|
|
|
+ if (reasonObj.sources && Array.isArray(reasonObj.sources)) {
|
|
|
|
|
+ reasonObj.sources.forEach(src => {
|
|
|
|
|
+ if (!src.filter_reason) src.filter_reason = reasonKey;
|
|
|
|
|
+ platCases.push(src);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
platCases.forEach((c, idx) => {
|
|
platCases.forEach((c, idx) => {
|
|
|
const cId = c.case_id || (c._raw && c._raw.case_id) || (c.post && c.post.channel_content_id) || `temp_${plat}_${idx}`;
|
|
const cId = c.case_id || (c._raw && c._raw.case_id) || (c.post && c.post.channel_content_id) || `temp_${plat}_${idx}`;
|
|
|
|
|
+ const cUrl = c.source_url || c.url || (c.post && c.post.link) || '';
|
|
|
|
|
+
|
|
|
|
|
+ const mappedS = ctx.sourceMap[cId] || ctx.sourceMap[cUrl] || (c._raw && ctx.sourceMap[c._raw.case_id]);
|
|
|
|
|
+ if (plat !== 'filtered_cases' && plat !== 'source' && plat !== 'source_ex' && !mappedS) return;
|
|
|
|
|
|
|
|
if (seenIds.has(cId)) return;
|
|
if (seenIds.has(cId)) return;
|
|
|
seenIds.add(cId);
|
|
seenIds.add(cId);
|
|
@@ -1914,13 +1963,40 @@ window.renderSingleCaseDetail = function(idx) {
|
|
|
const title = post.title || c.title || '无标题';
|
|
const title = post.title || c.title || '无标题';
|
|
|
const workflowUrl = s.source_url || s.url || cUrl;
|
|
const workflowUrl = s.source_url || s.url || cUrl;
|
|
|
|
|
|
|
|
- // Header
|
|
|
|
|
|
|
+ const publishedTime = post.publish_timestamp || post.published_at || '-';
|
|
|
|
|
+ const likeCount = post.like_count !== undefined ? post.like_count : (post.likes !== undefined ? post.likes : '-');
|
|
|
|
|
+ const collectCount = post.collect_count !== undefined ? post.collect_count : (post.collects !== undefined ? post.collects : '-');
|
|
|
|
|
+ const commentCount = post.comment_count !== undefined ? post.comment_count : (post.comments !== undefined ? post.comments : '-');
|
|
|
|
|
+ const shareCount = post.share_count !== undefined ? post.share_count : (post.shares !== undefined ? post.shares : '-');
|
|
|
|
|
+
|
|
|
const headerHtml = `
|
|
const headerHtml = `
|
|
|
<h2 style="margin: 0 0 0.5rem 0; font-size: 1.4em; color: var(--text-main);">${title}</h2>
|
|
<h2 style="margin: 0 0 0.5rem 0; font-size: 1.4em; color: var(--text-main);">${title}</h2>
|
|
|
- <div style="display: flex; gap: 12px; margin-bottom: 1rem;">
|
|
|
|
|
|
|
+ <div style="display: flex; gap: 12px; margin-bottom: 0.8rem;">
|
|
|
${workflowUrl ? `<a href="${workflowUrl}" target="_blank" style="color: var(--accent-primary); text-decoration: none; font-size: 0.9em;">原文 ↗</a>` : ''}
|
|
${workflowUrl ? `<a href="${workflowUrl}" target="_blank" style="color: var(--accent-primary); text-decoration: none; font-size: 0.9em;">原文 ↗</a>` : ''}
|
|
|
<span style="color: var(--text-muted); font-size: 0.9em;">平台: ${platformName}</span>
|
|
<span style="color: var(--text-muted); font-size: 0.9em;">平台: ${platformName}</span>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <div style="display: flex; gap: 10px; margin-bottom: 1rem; flex-wrap: wrap;">
|
|
|
|
|
+ <div style="display: flex; flex-direction: column; background: rgba(0,0,0,0.02); border: 1px solid rgba(0,0,0,0.06); padding: 4px 10px; border-radius: 6px;">
|
|
|
|
|
+ <span style="font-size: 0.7em; color: var(--text-muted); text-transform: uppercase;">Published</span>
|
|
|
|
|
+ <span style="font-size: 0.9rem; font-weight: 500; color: var(--text-main);">${publishedTime}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div style="display: flex; flex-direction: column; background: rgba(0,0,0,0.02); border: 1px solid rgba(0,0,0,0.06); padding: 4px 10px; border-radius: 6px;">
|
|
|
|
|
+ <span style="font-size: 0.7em; color: var(--text-muted); text-transform: uppercase;">Likes</span>
|
|
|
|
|
+ <span style="font-size: 0.9rem; font-weight: 500; color: var(--text-main);">${likeCount}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div style="display: flex; flex-direction: column; background: rgba(0,0,0,0.02); border: 1px solid rgba(0,0,0,0.06); padding: 4px 10px; border-radius: 6px;">
|
|
|
|
|
+ <span style="font-size: 0.7em; color: var(--text-muted); text-transform: uppercase;">Collects</span>
|
|
|
|
|
+ <span style="font-size: 0.9rem; font-weight: 500; color: var(--text-main);">${collectCount}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div style="display: flex; flex-direction: column; background: rgba(0,0,0,0.02); border: 1px solid rgba(0,0,0,0.06); padding: 4px 10px; border-radius: 6px;">
|
|
|
|
|
+ <span style="font-size: 0.7em; color: var(--text-muted); text-transform: uppercase;">Comments</span>
|
|
|
|
|
+ <span style="font-size: 0.9rem; font-weight: 500; color: var(--text-main);">${commentCount}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div style="display: flex; flex-direction: column; background: rgba(0,0,0,0.02); border: 1px solid rgba(0,0,0,0.06); padding: 4px 10px; border-radius: 6px;">
|
|
|
|
|
+ <span style="font-size: 0.7em; color: var(--text-muted); text-transform: uppercase;">Shares</span>
|
|
|
|
|
+ <span style="font-size: 0.9rem; font-weight: 500; color: var(--text-main);">${shareCount}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
`;
|
|
`;
|
|
|
document.getElementById('modal-main-header').innerHTML = headerHtml;
|
|
document.getElementById('modal-main-header').innerHTML = headerHtml;
|
|
|
|
|
|
|
@@ -1969,6 +2045,40 @@ window.renderSingleCaseDetail = function(idx) {
|
|
|
</div>
|
|
</div>
|
|
|
`;
|
|
`;
|
|
|
|
|
|
|
|
|
|
+ // Evaluation Panel
|
|
|
|
|
+ if (s.evaluation && Object.keys(s.evaluation).length > 0) {
|
|
|
|
|
+ const renderEvalNode = (node, indent = 0) => {
|
|
|
|
|
+ let html = '';
|
|
|
|
|
+ if (typeof node === 'object' && node !== null) {
|
|
|
|
|
+ Object.entries(node).forEach(([k, v]) => {
|
|
|
|
|
+ html += `<div style="display: flex; flex-direction: column; padding-left: ${indent}px; margin-bottom: 8px;">
|
|
|
|
|
+ <span style="color: var(--text-muted); font-size: 0.85rem; font-weight: bold; text-transform: uppercase;">${k.replace(/_/g, ' ')}</span>`;
|
|
|
|
|
+ if (typeof v === 'object' && v !== null) {
|
|
|
|
|
+ html += `<div style="margin-top: 4px; border-left: 2px solid rgba(0,0,0,0.1); padding-left: 8px;">${renderEvalNode(v, 0)}</div>`;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const valColor = typeof v === 'number' ? '#3b82f6' : 'var(--text-main)';
|
|
|
|
|
+ html += `<span style="font-weight: 500; font-size: 0.95rem; color: ${valColor}; margin-top: 2px;">${String(v).replace(/</g, '<').replace(/>/g, '>')}</span>`;
|
|
|
|
|
+ }
|
|
|
|
|
+ html += `</div>`;
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ return html;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ mainScrollableHtml += `
|
|
|
|
|
+ <div class="case-section" style="margin-top: 1rem;">
|
|
|
|
|
+ <div style="background: rgba(0,0,0,0.02); border: 1px solid rgba(0,0,0,0.05); border-radius: 8px; padding: 1rem;">
|
|
|
|
|
+ <h3 style="margin: 0 0 1rem 0; color: var(--text-main); font-size: 1.1rem; display: flex; align-items: center; gap: 10px;">
|
|
|
|
|
+ <span style="color: #10b981;">📊</span> 质量评估 (Evaluation)
|
|
|
|
|
+ </h3>
|
|
|
|
|
+ <div style="display: flex; flex-direction: column; gap: 4px;">
|
|
|
|
|
+ ${renderEvalNode(s.evaluation)}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>`;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
// Extracted Data
|
|
// Extracted Data
|
|
|
const wf = ctx.detailMap[cId] || (workflowUrl ? ctx.detailMapByUrl[workflowUrl] : null) || c;
|
|
const wf = ctx.detailMap[cId] || (workflowUrl ? ctx.detailMapByUrl[workflowUrl] : null) || c;
|
|
|
|
|
|
|
@@ -2236,11 +2346,57 @@ window.renderStructuredData = function(items, type, parentItem = null) {
|
|
|
// Stage rendering removed per request
|
|
// Stage rendering removed per request
|
|
|
// Render effects
|
|
// Render effects
|
|
|
if (item.effects && Array.isArray(item.effects) && item.effects.length > 0) {
|
|
if (item.effects && Array.isArray(item.effects) && item.effects.length > 0) {
|
|
|
|
|
+ let effectsHtml = '';
|
|
|
|
|
+ item.effects.forEach(effectItem => {
|
|
|
|
|
+ if (typeof effectItem === 'string') {
|
|
|
|
|
+ effectsHtml += `<li style="margin-bottom: 4px;">${effectItem.replace(/</g, '<').replace(/>/g, '>')}</li>`;
|
|
|
|
|
+ } else if (typeof effectItem === 'object' && effectItem !== null) {
|
|
|
|
|
+ const stmt = effectItem.statement ? effectItem.statement.replace(/</g, '<').replace(/>/g, '>') : 'Effect';
|
|
|
|
|
+ let detailsHtml = '';
|
|
|
|
|
+ const excludeKeys = ['statement'];
|
|
|
|
|
+ Object.entries(effectItem).forEach(([k, v]) => {
|
|
|
|
|
+ if (!excludeKeys.includes(k) && v !== null && v !== undefined && v !== '' && (!Array.isArray(v) || v.length > 0)) {
|
|
|
|
|
+ let valStr = '';
|
|
|
|
|
+ if (Array.isArray(v)) {
|
|
|
|
|
+ valStr = `<ul style="margin: 2px 0 0 20px; padding: 0;">` + v.map(vi => `<li>${String(vi).replace(/</g, '<').replace(/>/g, '>')}</li>`).join('') + `</ul>`;
|
|
|
|
|
+ } else if (typeof v === 'object') {
|
|
|
|
|
+ valStr = JSON.stringify(v);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ valStr = String(v).replace(/</g, '<').replace(/>/g, '>');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (Array.isArray(v)) {
|
|
|
|
|
+ detailsHtml += `<div style="margin-top: 6px; font-size: 0.9em;">
|
|
|
|
|
+ <div style="color: var(--text-muted); font-weight: 500; margin-bottom: 2px; text-transform: capitalize;">${k.replace(/_/g, ' ')}:</div>
|
|
|
|
|
+ <div style="color: var(--text-main);">${valStr}</div>
|
|
|
|
|
+ </div>`;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ detailsHtml += `<div style="margin-top: 4px; font-size: 0.9em;">
|
|
|
|
|
+ <span style="color: var(--text-muted); font-weight: 500; text-transform: capitalize;">${k.replace(/_/g, ' ')}:</span>
|
|
|
|
|
+ <span style="color: var(--text-main);">${valStr}</span>
|
|
|
|
|
+ </div>`;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ effectsHtml += `<li style="list-style: none; margin-bottom: 8px; margin-left: -20px;">
|
|
|
|
|
+ <details style="background: rgba(0,0,0,0.02); border: 1px solid rgba(0,0,0,0.06); border-radius: 6px; padding: 6px 10px;">
|
|
|
|
|
+ <summary style="cursor: pointer; font-weight: 500; color: var(--accent-primary); outline: none;">
|
|
|
|
|
+ ${stmt}
|
|
|
|
|
+ </summary>
|
|
|
|
|
+ <div style="padding-top: 8px; margin-top: 6px; border-top: 1px dashed rgba(0,0,0,0.1);">
|
|
|
|
|
+ ${detailsHtml}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </details>
|
|
|
|
|
+ </li>`;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
html += `<div class="structured-row">
|
|
html += `<div class="structured-row">
|
|
|
<div class="structured-label">effects</div>
|
|
<div class="structured-label">effects</div>
|
|
|
<div class="structured-value">
|
|
<div class="structured-value">
|
|
|
<ul class="effects-list">
|
|
<ul class="effects-list">
|
|
|
- ${item.effects.map(li => `<li>${li.replace(/</g, '<').replace(/>/g, '>')}</li>`).join('')}
|
|
|
|
|
|
|
+ ${effectsHtml}
|
|
|
</ul>
|
|
</ul>
|
|
|
</div>
|
|
</div>
|
|
|
</div>`;
|
|
</div>`;
|
|
@@ -2334,6 +2490,8 @@ window.renderStructuredData = function(items, type, parentItem = null) {
|
|
|
return list.map(io => {
|
|
return list.map(io => {
|
|
|
const desc = isValid(io.description) ? io.description.replace(/</g, '<').replace(/>/g, '>') : '';
|
|
const desc = isValid(io.description) ? io.description.replace(/</g, '<').replace(/>/g, '>') : '';
|
|
|
const mod = isValid(io.modality) ? io.modality : '';
|
|
const mod = isValid(io.modality) ? io.modality : '';
|
|
|
|
|
+ const relation = isValid(io.relation) ? io.relation.replace(/</g, '<').replace(/>/g, '>') : '';
|
|
|
|
|
+
|
|
|
let content = '';
|
|
let content = '';
|
|
|
if (mod) {
|
|
if (mod) {
|
|
|
content += `<span class="data-type-badge" style="background:#e0e7ff;color:#3730a3;font-weight:normal;margin-right:6px;margin-bottom:2px;display:inline-block;">${mod}</span>`;
|
|
content += `<span class="data-type-badge" style="background:#e0e7ff;color:#3730a3;font-weight:normal;margin-right:6px;margin-bottom:2px;display:inline-block;">${mod}</span>`;
|
|
@@ -2341,6 +2499,12 @@ window.renderStructuredData = function(items, type, parentItem = null) {
|
|
|
if (desc) {
|
|
if (desc) {
|
|
|
content += desc;
|
|
content += desc;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ let extraHtml = '';
|
|
|
|
|
+ if (relation) {
|
|
|
|
|
+ extraHtml = `<div style="font-size: 0.85em; color: #94a3b8; margin-top: 2px; font-weight: normal;">↳ relation: ${relation}</div>`;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (!content) {
|
|
if (!content) {
|
|
|
const keys = Object.keys(io);
|
|
const keys = Object.keys(io);
|
|
|
if (keys.length === 1 && typeof io[keys[0]] === 'string') {
|
|
if (keys.length === 1 && typeof io[keys[0]] === 'string') {
|
|
@@ -2349,7 +2513,7 @@ window.renderStructuredData = function(items, type, parentItem = null) {
|
|
|
content = `<span class="data-type-badge">未知</span>`;
|
|
content = `<span class="data-type-badge">未知</span>`;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- return `<div style="margin-bottom: 6px; color: var(--text-main); font-weight: bold; line-height: 1.5; word-wrap: break-word;">${content}</div>`;
|
|
|
|
|
|
|
+ return `<div style="margin-bottom: 6px; color: var(--text-main); font-weight: bold; line-height: 1.5; word-wrap: break-word;">${content}${extraHtml}</div>`;
|
|
|
}).join('');
|
|
}).join('');
|
|
|
};
|
|
};
|
|
|
|
|
|