#!/usr/bin/env node import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const root = path.join(path.dirname(fileURLToPath(import.meta.url)), '..'); const outDir = path.join(root, 'public', 'learn'); const sharedCss = fs.readFileSync(path.join(root, 'scripts/build-tang-learning-assistant-pages.mjs'), 'utf8') .match(/const sharedCss = `([\s\S]*?)`;/)[1]; function childPage() { return ` 我的学习小助手
v2
`; } function childScriptBody() { // childScript() 在 tang 构建里经 template literal 会把 \\' 变成 \'; // 这里直接读源码,需手动还原为 inline `; } function parentDashboardScript() { return ` function renderLogin(){return renderAuth()} async function login(){await ensureFamily();await loadAll();render()} function renderDash(){var s=state.stats;var tp=s.today.total?Math.round(s.today.done/s.today.total*100):0;var wp=s.week.total?Math.round(s.week.done/s.week.total*100):0;var st=s.children.length?s.children[0].streak:0;var html='

数据看板 📊

'+s.children.map(function(c){return esc(c.emoji)+' '+esc(c.name)+' 连续 '+c.streak+' 天🔥'}).join(' ')+'
'+tp+'%
今日完成率 '+(s.today.done+'/'+s.today.total)+'
'+wp+'%
本周完成率
'+st+'
连续全勤(天)
';s.trend.forEach(function(d){var p=d.total?Math.round(d.done/d.total*100):0;html+='
'+d.d.slice(5)+'
'+p+'%
'});return html} function renderTemplates(){var html='

任务模板 📋

';state.templates.forEach(function(t){html+='
'+esc(t.title)+'
+'+t.points+' 能量 · 每周 '+weekdaysCN(t.weekdays)+'
'});html+='';return html} function tplForm(t){var kids=state.children.map(function(c){return ''}).join('');var cats=state.categories.map(function(c){return ''}).join('');var wchk=WD.map(function(w,i){return ''+w+''}).join('');return '
'} function newTpl(){document.getElementById('app').insertAdjacentHTML('beforeend',tplForm(null))} async function saveTpl(id){var wds=[];document.querySelectorAll('.overlay .chip.on').forEach(function(c,i){wds.push(String(i+1))});var body={child_id:+document.getElementById('f_child').value,title:document.getElementById('f_title').value,task_type:document.getElementById('f_type').value,weekdays:wds,start_date:new Date().toISOString().slice(0,10),points:10};if(id)await api('/parent/templates/'+id,{method:'PUT',body:JSON.stringify(body)});else await api('/parent/templates',{method:'POST',body:JSON.stringify(body)});document.querySelector('.overlay').remove();await loadAll();render()} function renderCats(){var html='

分类管理 🏷️

';state.categories.forEach(function(c){html+=''});html+='
'+esc(c.name)+'
';return html} async function addCat(){var n=document.getElementById('c_name').value.trim();if(!n)return;await api('/parent/categories',{method:'POST',body:JSON.stringify({name:n,color:'#3b5bfd'})});await loadAll();render()} function renderKids(){var html='

孩子管理 👦

';state.children.forEach(function(c){html+='
'+esc(c.emoji)+' '+esc(c.name)+'
'});html+='
';return html} async function addKid(){var n=document.getElementById('k_name').value.trim();if(!n)return;await api('/parent/children',{method:'POST',body:JSON.stringify({name:n,emoji:'🙂'})});await loadAll();render()} async function loadAll(){if(state.tab==='dash')state.stats=await api('/parent/stats');if(state.tab==='tpl'){state.templates=(await api('/parent/templates')).data;state.categories=(await api('/parent/categories')).data;state.children=(await api('/parent/children')).data}if(state.tab==='cat'){state.categories=(await api('/parent/categories')).data}if(state.tab==='kid'){state.children=(await api('/parent/children')).data}} function render(){var app=document.getElementById('app');if(!state.family){app.innerHTML=renderAuth();return}var tabs=[['dash','📊','看板'],['tpl','📋','模板'],['cat','🏷️','分类'],['kid','👦','孩子'],['set','⚙️','设置']];var body=state.tab==='dash'?renderDash():state.tab==='tpl'?renderTemplates():state.tab==='cat'?renderCats():state.tab==='kid'?renderKids():renderSet();app.innerHTML=body+'
'+tabs.map(function(t){return ''}).join('')+'
'} async function go(tab){state.tab=tab;await loadAll();render()} `; } function joinPage() { return `加入家庭

加入学习家庭

正在处理邀请…

`; } function indexPage() { return `学习小助手

学习小助手

家长注册 Memind 后配置任务;孩子打开链接打卡。

家长后台儿童端示例 登录 / 注册 Memind
`; } fs.mkdirSync(outDir, { recursive: true }); fs.writeFileSync(path.join(outDir, 'child.html'), childPage()); fs.writeFileSync(path.join(outDir, 'parent.html'), parentPage()); fs.writeFileSync(path.join(outDir, 'join.html'), joinPage()); fs.writeFileSync(path.join(outDir, 'index.html'), indexPage()); console.log(JSON.stringify({ ok: true, outDir }, null, 2));