Files
workbuddy_skills/oil-ui-pro/assets/cards/answer-lens/card.js
T
admin d9445b5888 oil-ui-pro 0.15.4 → 0.22.2(上游 ui.oiloil.org 正式包)+ 记 P0-98 跨盘 rename 坑
- oil-ui-pro 升到 0.22.2:references 13→28 份(新增 16、删 imagery.md)、assets 增 cards/(22 组)与 fonts/、SKILL.md 顶层五步结构未改名。
- 升级路径:官方 `npx github:oil-oil/oil-cli update` 稳定失败(error=replace、报「检查目录权限」)。
  真身为 EXDEV —— 解压在 os.tmpdir()(C 盘)、技能目录在 E 盘,Windows 上 rename 不能跨盘;
  CLI 的 catch 把非 CliError 原生异常一律兜底成 replaceFailed,真错误一个字不吐。
  做法=借其 prepare() 只做下载+校验,再 cp 到同盘 stage、rename 交换;官方命令复验 up_to_date。
- 回归:product-planning 按名引用的 visual-review.md/tools.md/design-direction.md/style-explorer.md 全部健在;命名闸门 2061|0|27。
- session-mechanism/references/pitfalls.md 新增 P0-98(含通则:更新器把原生错误兜底成指错方向的人话)。
2026-10-14 10:21:46 +08:00

26 lines
3.1 KiB
JavaScript

import {shell,clamp} from '../shared/runtime.js';
export function mount(element, options = {}) {
const clean=shell(element,options),events=new AbortController(),list=element.querySelector('.answer-citations'),excerpt=element.querySelector('.answer-excerpt'),reference=element.querySelector('.answer-reference'),charts=[...element.querySelectorAll('[data-chart]')];
const defaults=[{label:'项目进度',answer:'核心页面已完成评审,下一步可以集中打磨移动端体验。',citation:'项目记录 · 本周评审'},{label:'内容表现',answer:'实用教程获得了更多收藏,可以继续拓展成一个系列。',citation:'内容记录 · 系列表现'},{label:'用户反馈',answer:'大家最常提到的是查找素材,优先把检索入口做清楚。',citation:'反馈记录 · 需求整理'}];
const sources=(Array.isArray(options.content?.sources)?options.content.sources:defaults).filter(source=>source && typeof source==='object').slice(0,3);
const select=index=>{[...list.children].forEach((b,i)=>b.setAttribute('aria-pressed',String(i===index)));charts.forEach((c,i)=>c.dataset.selected=String(i===index));excerpt.textContent=String(sources[index]?.answer ?? options.content?.emptyText ?? '还没有可引用的来源。');reference.textContent=String(sources[index]?.citation ?? '');reference.hidden=!reference.textContent;};
list.replaceChildren();
charts.forEach((chart,i)=>{
chart.hidden=!sources[i];if(!sources[i])return;
chart.querySelector('[data-text]').textContent=String(sources[i].label ?? '');
const data=sources[i].chart;if(!data || typeof data!=='object')return;
if(i===0 && typeof data.value==='number' && Number.isFinite(data.value)){
const max=typeof data.max==='number' && Number.isFinite(data.max) && data.max>0?data.max:100,ratio=clamp(data.value/max),length=2*Math.PI*48;
chart.querySelector('.ring-value').style.strokeDasharray=`${length*ratio} ${length*(1-ratio)}`;
}
if(i>0 && Array.isArray(data.series)){
const series=data.series.filter(n=>typeof n==='number' && Number.isFinite(n)).slice(0,32),path=chart.querySelector(i===1?'.chart-bars':'.chart-line');
const low=Math.min(0,...series),high=Math.max(1,...series),y=value=>115-(value-low)/(high-low)*95;
if(i===1){path.setAttribute('d',series.map((n,j)=>`M${20+(j+.5)*120/series.length} 115V${y(n)}`).join(' '));path.style.strokeWidth=String(Math.min(15,72/Math.max(1,series.length)));}
else path.setAttribute('d',series.map((n,j)=>`${j?'L':'M'}${series.length===1?80:15+j*130/(series.length-1)} ${y(n)}`).join(' '));
}
});
sources.forEach((source,index)=>{const b=document.createElement('button');b.type='button';b.textContent=`${index+1} · ${source.label ?? ''}`;b.addEventListener('click',()=>select(index),{signal:events.signal});list.append(b);});select(0);
return {destroy(){events.abort();clean();list.replaceChildren();charts.forEach(chart=>{delete chart.dataset.selected;chart.querySelector('.ring-value')?.style.removeProperty('stroke-dasharray');chart.querySelector('.chart-bars')?.style.removeProperty('stroke-width');});}};
}