63 lines
6.5 KiB
JavaScript
63 lines
6.5 KiB
JavaScript
'use strict';
|
|
pageInfo.households=['我的家庭与场所','家庭、办公室或工厂,分别组织,各自授权。'];
|
|
const scopeKind=h=>({home:'家庭',office:'办公场所',factory:'工厂'}[h.kind||'home']||'家庭');
|
|
function renderHouseholds(){
|
|
const homes=state.households||[];
|
|
setOptions($('#household-filter'),homes.map(h=>`<option value="${esc(h.id)}">${esc(scopeKind(h)+' · '+h.name)}</option>`).join(''));
|
|
$('#household-filter').value=state.familyId||'';
|
|
if(activePage!=='households')return;
|
|
const cards=h=>`<article class="site-card home-card"><div class="home-cover ${h.coverUrl?'has-photo':''}">${h.coverUrl?`<img src="${esc(h.coverUrl)}" alt="${esc(h.name)}封面照片" loading="lazy">`:'<div class="home-cover-placeholder" aria-hidden="true">山川有归处 · 灯火有人家</div>'}<div class="home-cover-content"><div class="site-heading"><span class="badge">${h.id===state.familyId?'当前归属 · ':''}${scopeKind(h)}</span>${isAdmin()?`<button class="quiet" data-edit-household="${esc(h.id)}">编辑档案</button>`:''}</div><h3>${esc(h.name)}</h3><p class="home-location">${esc([h.province,h.city,h.district].filter(Boolean).join(' · ')||'地区待填写')}</p></div></div><div class="home-card-body"><p class="description">${esc(h.note||'区域与设备归属独立管理')}</p><dl><div><dt>${!h.kind||h.kind==='home'?'一家之主':'主要负责人'}</dt><dd>${esc(h.ownerName||'待指定')}</dd></div><div><dt>备用负责人</dt><dd>${esc(h.successorName||'待指定')}</dd></div><div><dt>账号 / 空间</dt><dd>${h.members} 个 / ${h.sites} 处</dd></div></dl>${!h.successorId?'<p class="description">尚未指定备用负责人,建议提前安排可信人员接管。</p>':''}<div class="household-actions"><button class="secondary" data-enter-household="${esc(h.id)}">进入${esc(h.name)}</button>${h.canAssignOwner?`<button class="quiet" data-leadership="${esc(h.id)}">负责人安排与交接</button>`:''}</div>${h.leadershipHistory?.length?`<details><summary>交接记录</summary>${h.leadershipHistory.slice().reverse().map(r=>`<p class="description">${esc(new Date(r.at).toLocaleString())} · ${esc(r.actor)}<br>${esc(r.reason)}</p>`).join('')}</details>`:''}</div></article>`;
|
|
const groups=new Map();for(const h of homes){const key=[h.province,h.city||'未填写地级市'].filter(Boolean).join(' / ');if(!groups.has(key))groups.set(key,[]);groups.get(key).push(h);}
|
|
$('#household-list').innerHTML=[...groups].sort(([a],[b])=>a.localeCompare(b,'zh-CN')).map(([city,rows])=>`<section class="home-city-group"><h3>${esc(city)} <small>${rows.length} 个家庭或场所</small></h3><div class="site-grid">${rows.map(cards).join('')}</div></section>`).join('');
|
|
}
|
|
async function switchHousehold(id){
|
|
if(!isPlatformAdmin()||!id||id===state.familyId)return;
|
|
const user=currentUser;
|
|
// Invalidate outstanding API responses, video players and dialogs before changing scope.
|
|
clearPrivateView();
|
|
householdScope=id;currentUser=user;loggedIn=true;
|
|
await auth();
|
|
}
|
|
function openHousehold(id){
|
|
if(!isAdmin())return;
|
|
const item=(state.households||[]).find(h=>h.id===id);
|
|
if(!item&&!isPlatformAdmin())return;
|
|
fillForm($('#household-form'),item||{});coverDraft=undefined;$('#household-cover-preview').hidden=!item?.coverUrl;if(item?.coverUrl)$('#household-cover-preview').src=item.coverUrl;else $('#household-cover-preview').removeAttribute('src');$('#household-cover-status').textContent='照片仅向有权进入该家庭或场所的账号开放。';$('#household-dialog').showModal();
|
|
}
|
|
async function openLeadership(id){
|
|
try{
|
|
if(id!==state.familyId)await switchHousehold(id);
|
|
const home=(state.households||[]).find(h=>h.id===id);
|
|
if(!home?.canAssignOwner)return;
|
|
const result=await api('/api/users');
|
|
const candidates=result.users.filter(u=>u.role==='family_admin'&&!u.disabled);
|
|
const f=$('#leadership-form'),options=candidates.map(u=>`<option value="${esc(u.id)}">${esc(u.name+' / '+u.username)}</option>`).join('');
|
|
f.elements.ownerId.innerHTML='<option value="">请选择主要负责人</option>'+options;
|
|
f.elements.successorId.innerHTML='<option value="">暂未指定</option>'+options;
|
|
fillForm(f,{id:home.id,revision:home.leadershipRevision||0,ownerId:home.ownerId||'',successorId:home.successorId||''});
|
|
$('#leadership-dialog').showModal();
|
|
}catch(error){if(!error.stale)toast(error.message);}
|
|
}
|
|
$('#leadership-form').addEventListener('submit',async e=>{
|
|
e.preventDefault();const f=e.currentTarget,b=f.querySelector('[type=submit]');b.disabled=true;
|
|
try{const d=formValues(f);d.revision=Number(d.revision);await api('/api/households/leadership',d);f.closest('dialog').close();await refresh();showPage('households');toast('负责人已更新,交接记录已保存');}
|
|
catch(error){if(!error.stale)f.querySelector('.form-error').textContent=error.message;}finally{b.disabled=false;}
|
|
});
|
|
$('#household-filter').onchange=async e=>{await switchHousehold(e.target.value);if(loggedIn)showPage('overview');};
|
|
$('#new-household').onclick=()=>openHousehold();
|
|
$('#household-form').addEventListener('submit',async e=>{
|
|
e.preventDefault();const f=e.currentTarget,b=f.querySelector('[type=submit]');b.disabled=true;
|
|
try{await api('/api/households',{...formValues(f),...(coverDraft!==undefined?{coverData:coverDraft}:{})});f.closest('dialog').close();await refresh();toast('归属档案已保存');}
|
|
catch(error){if(!error.stale)f.querySelector('.form-error').textContent=error.message;}
|
|
finally{b.disabled=false;}
|
|
});
|
|
document.addEventListener('click',async e=>{
|
|
const b=e.target.closest('button');if(!b)return;
|
|
if(b.dataset.editHousehold)openHousehold(b.dataset.editHousehold);
|
|
if(b.dataset.leadership)await openLeadership(b.dataset.leadership);
|
|
if(b.dataset.enterHousehold){await switchHousehold(b.dataset.enterHousehold);if(loggedIn)showPage('overview');}
|
|
});
|
|
|
|
$('#household-cover-file').onchange=async e=>{const householdId=$('#household-form').elements.id.value,generation=sessionGeneration;try{const image=await readImage(e.target.files[0],960);if(generation!==sessionGeneration||!$('#household-dialog').open||$('#household-form').elements.id.value!==householdId)return;coverDraft=image;$('#household-cover-preview').src=image;$('#household-cover-preview').hidden=false;$('#household-cover-status').textContent='照片已准备,保存档案后更新卡片。';}catch(e){$('#household-cover-status').textContent=e.message;}};
|
|
$('#household-cover-reset').onclick=()=>{coverDraft='';$('#household-cover-preview').hidden=true;$('#household-cover-preview').removeAttribute('src');$('#household-cover-status').textContent='保存后使用默认封面。';};
|