feat: 发布三笙AI情报局独立版公司研发基线
同步家纺情报 v2 数据、59 个严格权威源、趋势图库、移动端交互、Google/Yandex 翻译门控及静态 SEO/GEO 构建。 补充面向 C# 研发的 README,明确当前无 LLM、多模态与生图模型,记录翻译请求参数、缓存与失败策略、数据处理边界、前端职责和无 GitHub Pages 部署流程。 新增按日期倒序维护的 CHANGELOG,记录影响、验证与代码/数据/dist 回滚方法。 验证:11 个 Python 契约测试、13 个 Node 前端测试通过;静态构建生成 1096 个 Sitemap URL。
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
import { state } from "./render-intelligence-state.js?v=20260814e";
|
||||
import { TEXT, create, detectViewerCountry, currentTranslationProvider, formatVerified, sectionItems, matchesFilters, makeCard, renderCalendar, renderPlatforms } from "./render-intelligence-core.js?v=20260814k";
|
||||
import { renderExhibitions, renderPolicies, renderStandards, renderTrendNews, renderTrendSearchHub, trendItems } from "./render-intelligence-scenes.js?v=20260814i";
|
||||
import { renderActivities } from "./render-intelligence-activities.js?v=20260814h";
|
||||
|
||||
function renderStats(data, container) {
|
||||
if (!container) return;
|
||||
container.innerHTML = "";
|
||||
const values = [
|
||||
["新增权威源", `${data.source_success || 0}/${data.source_target || 0}`],
|
||||
["总体源基线", data.total_source_baseline || 0],
|
||||
["重点备货商机", data.summary?.calendar_featured || data.summary?.calendar_insights || 0],
|
||||
["已核实展会", data.summary?.exhibitions || 0],
|
||||
["政策与召回", data.summary?.policies || 0],
|
||||
["重点销售平台", data.summary?.platforms || data.platforms?.length || 0],
|
||||
["可参加活动", data.summary?.activities || data.activities?.length || 0],
|
||||
];
|
||||
values.forEach(([label, value]) => {
|
||||
const node = create("div", "intelligence-stat");
|
||||
node.append(create("span", "", label), create("strong", "", String(value)));
|
||||
container.appendChild(node);
|
||||
});
|
||||
}
|
||||
|
||||
function renderTabs(data, container, render) {
|
||||
if (!container) return;
|
||||
container.innerHTML = "";
|
||||
Object.entries(TEXT.tabs).forEach(([key, label]) => {
|
||||
const button = create("button", `intelligence-tab${state.activeSection === key ? " active" : ""}`, label);
|
||||
button.type = "button";
|
||||
button.setAttribute("role", "tab");
|
||||
button.setAttribute("aria-selected", String(state.activeSection === key));
|
||||
button.setAttribute("aria-controls", "intelligenceList");
|
||||
const count = key === "today"
|
||||
? data.today?.length
|
||||
: (key === "calendar"
|
||||
? (data.calendar_insights?.length || data.calendar?.length)
|
||||
: (key === "standards" ? ((data.standards?.length || 0) + trendItems(data).length) : data[key]?.length));
|
||||
button.appendChild(create("span", "intelligence-tab-count", String(count || 0)));
|
||||
button.addEventListener("click", () => {
|
||||
state.activeSection = key;
|
||||
render();
|
||||
state.onStateChange?.();
|
||||
});
|
||||
container.appendChild(button);
|
||||
});
|
||||
}
|
||||
|
||||
function renderRegionOptions(data, select) {
|
||||
if (!select) return;
|
||||
const previous = state.region;
|
||||
select.innerHTML = "";
|
||||
if (state.activeSection === "calendar") {
|
||||
state.region = "";
|
||||
select.disabled = true;
|
||||
const calendarOption = create("option", "", "使用下方日历市场筛选");
|
||||
calendarOption.value = "";
|
||||
select.appendChild(calendarOption);
|
||||
return;
|
||||
}
|
||||
select.disabled = false;
|
||||
const sourceItems = state.activeSection === "today" ? (data.today || []) : (data[state.activeSection] || []);
|
||||
const regions = new Set(sourceItems.map((item) => item.region).filter(Boolean));
|
||||
const all = create("option", "", TEXT.allRegions);
|
||||
all.value = "";
|
||||
select.appendChild(all);
|
||||
[...regions].sort((a, b) => a.localeCompare(b, "zh-CN")).forEach((value) => {
|
||||
const option = create("option", "", value);
|
||||
option.value = value;
|
||||
select.appendChild(option);
|
||||
});
|
||||
select.value = regions.has(previous) ? previous : "";
|
||||
state.region = select.value;
|
||||
}
|
||||
|
||||
function renderList(data, container) {
|
||||
if (!container) return;
|
||||
const filtered = sectionItems(data).filter(matchesFilters);
|
||||
container.innerHTML = "";
|
||||
["calendar", "exhibitions", "policies", "standards", "platforms", "activities"].forEach((section) => {
|
||||
container.classList.toggle(`is-${section}`, state.activeSection === section);
|
||||
});
|
||||
container.classList.toggle("is-today", state.activeSection === "today");
|
||||
if (!filtered.length) {
|
||||
const empty = create("div", "intelligence-empty", TEXT.empty);
|
||||
container.appendChild(empty);
|
||||
return;
|
||||
}
|
||||
if (state.activeSection === "calendar") {
|
||||
renderCalendar(data, container);
|
||||
return;
|
||||
}
|
||||
if (state.activeSection === "today") {
|
||||
const header = create("section", "today-briefing");
|
||||
header.append(
|
||||
create("strong", "", `今天有 ${filtered.length} 件值得处理的事`),
|
||||
create("span", "", "按截止时间、经营相关性和风险动态排序;继续下滑可查看全部事项"),
|
||||
);
|
||||
container.appendChild(header);
|
||||
}
|
||||
if (state.activeSection === "exhibitions") {
|
||||
renderExhibitions(data, container);
|
||||
return;
|
||||
}
|
||||
if (state.activeSection === "policies") {
|
||||
renderPolicies(data, container);
|
||||
return;
|
||||
}
|
||||
if (state.activeSection === "standards") {
|
||||
renderStandards(data, container);
|
||||
return;
|
||||
}
|
||||
if (state.activeSection === "platforms") {
|
||||
renderPlatforms(data, container);
|
||||
return;
|
||||
}
|
||||
if (state.activeSection === "activities") {
|
||||
renderActivities(data.activities || [], container, currentTranslationProvider());
|
||||
return;
|
||||
}
|
||||
const visible = filtered;
|
||||
visible.forEach((item) => container.appendChild(makeCard(item)));
|
||||
}
|
||||
|
||||
export function setIntelligenceSection(value) {
|
||||
if (value && Object.prototype.hasOwnProperty.call(TEXT.tabs, value)) state.activeSection = value;
|
||||
}
|
||||
|
||||
export function getIntelligenceSection() {
|
||||
return state.activeSection;
|
||||
}
|
||||
|
||||
export function renderIntelligence(data, options = {}) {
|
||||
state.currentData = data;
|
||||
if (!state.calendarYear) {
|
||||
state.calendarYear = Number(String(data.as_of_date || "").slice(0, 4));
|
||||
state.calendarMonth = 0;
|
||||
}
|
||||
state.onStateChange = options.onStateChange || null;
|
||||
const root = options.root || document.getElementById("intelligencePanel");
|
||||
if (!root || !data) return;
|
||||
|
||||
const stats = root.querySelector("#intelligenceStats");
|
||||
const tabs = root.querySelector("#intelligenceTabs");
|
||||
const list = root.querySelector("#intelligenceList");
|
||||
const search = root.querySelector("#intelligenceSearch");
|
||||
const regionSelect = root.querySelector("#intelligenceRegion");
|
||||
const updated = root.querySelector("#intelligenceUpdatedAt");
|
||||
|
||||
const rerender = () => {
|
||||
renderTabs(state.currentData, tabs, rerender);
|
||||
renderList(state.currentData, list);
|
||||
};
|
||||
state.activeIntelligenceRerender = rerender;
|
||||
|
||||
renderStats(data, stats);
|
||||
renderRegionOptions(data, regionSelect);
|
||||
renderTabs(data, tabs, rerender);
|
||||
renderList(data, list);
|
||||
if (updated) updated.textContent = `核验时间:${formatVerified(data.generated_at)}`;
|
||||
|
||||
if (search && !search.dataset.bound) {
|
||||
search.dataset.bound = "1";
|
||||
search.placeholder = TEXT.searchPlaceholder;
|
||||
search.addEventListener("input", (event) => {
|
||||
state.query = event.target.value;
|
||||
renderList(state.currentData, list);
|
||||
});
|
||||
}
|
||||
if (regionSelect && !regionSelect.dataset.bound) {
|
||||
regionSelect.dataset.bound = "1";
|
||||
regionSelect.addEventListener("change", (event) => {
|
||||
state.region = event.target.value;
|
||||
renderList(state.currentData, list);
|
||||
});
|
||||
}
|
||||
detectViewerCountry();
|
||||
}
|
||||
|
||||
export async function shareIntelligence() {
|
||||
const shareData = {
|
||||
title: "家纺跨境情报 · 每日机会与风险提醒",
|
||||
text: "全球备货日历、家纺展会、跨境政策与趋势雷达",
|
||||
url: window.location.href,
|
||||
};
|
||||
try {
|
||||
if (navigator.share) {
|
||||
await navigator.share(shareData);
|
||||
return "已打开系统分享面板";
|
||||
}
|
||||
await navigator.clipboard.writeText(shareData.url);
|
||||
return "分享链接已复制,可粘贴到微信或企业微信";
|
||||
} catch (error) {
|
||||
if (error?.name === "AbortError") return "已取消分享";
|
||||
console.error("[家纺跨境情报] 分享失败:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
state.renderList = renderList;
|
||||
Reference in New Issue
Block a user