const [query,setQuery]=useState("");
const [domainSel,setDomainSel]=useState(domainFilter==null?"":String(domainFilter));
const [statusSel,setStatusSel]=useState("");
- const [preview,setPreview]=useState<any|null>(null);
const [pageIndex,setPageIndex]=useState(1);
const [pageSize,setPageSize]=useState(10);
const {confirm,el:confirmEl}=useConfirm();
const load=async()=>{ try{ setList(await fetchDb("/domain-templates") as any[]); }catch(e:any){ notify("加载失败:"+e.message); }finally{ setLoading(false); } };
useEffect(()=>{ load(); },[]);
useEffect(()=>{ setDomainSel(domainFilter==null?"":String(domainFilter)); },[domainFilter]);
- const remove=async(row:any)=>{ if(!(await confirm(`确定删除领域方案「${row.name}」?此操作不可恢复`))) return; try{ await fetchDb(`/domain-templates/${row.id}`,{method:"DELETE"}); setPreview(null); await load(); notify("领域方案已删除"); }catch(e:any){ notify("删除失败:"+e.message); } };
+ const remove=async(row:any)=>{ if(!(await confirm(`确定删除领域方案「${row.name}」?此操作不可恢复`))) return; try{ await fetchDb(`/domain-templates/${row.id}`,{method:"DELETE"}); await load(); notify("领域方案已删除"); }catch(e:any){ notify("删除失败:"+e.message); } };
const counts=useMemo(()=>({all:list.length,available:list.filter(x=>x.status==="available").length,unavailable:list.filter(x=>x.status!=="available").length}),[list]);
const filtered=useMemo(()=>list.filter(row=>(!statusSel||(statusSel==="available"?row.status==="available":row.status!=="available"))&&(!domainSel||String(row.domain_id)===domainSel)&&(!query.trim()||`${row.name} ${row.domain_name} ${row.creator}`.toLowerCase().includes(query.trim().toLowerCase()))),[list,statusSel,domainSel,query]);
useEffect(()=>setPageIndex(1),[statusSel,domainSel,query]);
<select value={domainSel} onChange={e=>setDomainSel(e.target.value)}><option value="">全部领域</option>{domainOptions.map(d=><option key={d.id} value={String(d.id)}>{d.name}</option>)}</select>
<div className="filter-actions"><Button onClick={()=>notify(`已显示 ${filtered.length} 个领域方案`)}>查询</Button><Button secondary onClick={()=>{setQuery("");setDomainSel("");setStatusSel("");}}>重置</Button></div>
</div>
- {loading?<div className="empty-state">加载中…</div>:<><table className="data-table company-table resource-table domain-resource-table"><thead><tr><th>方案名称</th><th>所属领域</th><th>版本</th><th>设备</th><th>页面</th><th>文档</th><th>状态</th><th>创建人</th><th>从模板创建</th><th>操作</th></tr></thead><tbody>{filtered.slice((pageIndex-1)*pageSize,pageIndex*pageSize).map(row=><tr key={row.id} onClick={()=>setPreview(row)}><td><button className="link company-record-link" title={row.name} onClick={e=>{e.stopPropagation();setPreview(row);}}><b>{row.name||"未命名方案"}</b></button></td><td>{row.domain_name||"—"}</td><td>{row.version||"—"}</td><td>{row.device_count||0}</td><td>{row.page_count||0}</td><td>{row.doc_count||0}</td><td><Status>{row.status==="available"?"可用":"不可用"}</Status></td><td>{row.creator||"—"}</td><td onClick={e=>e.stopPropagation()}><button className="link" onClick={async(e:React.MouseEvent)=>{e.stopPropagation();try{const s=await fetchDb(`/domain-templates/${row.id}/create-site`,{method:"POST",headers:{"Content-Type":"application/json"}}) as any;go("siteEdit",s.id);}catch(err:any){notify("创建站点失败:"+(err?.message||err));}}}>创建</button></td><td onClick={e=>e.stopPropagation()}><Dropdown trigger={["click"]} menu={{items:[{key:"edit",label:"编辑方案",icon:<EditOutlined/>},{key:"delete",label:"删除",danger:true,icon:<DeleteOutlined/>}],onClick:({key})=>key==="edit"?onOpen(row.id):remove(row)}}><AntButton type="text" aria-label="更多操作" icon={<EllipsisOutlined/>}/></Dropdown></td></tr>)}</tbody></table>{filtered.length===0&&<div className="empty-state">暂无符合条件的领域方案</div>}<div className="pagination"><span>{filtered.length} / 总数</span><button disabled={pageIndex<=1} onClick={()=>setPageIndex(p=>Math.max(1,p-1))}>‹</button><button className="active">{pageIndex}</button><button disabled={pageIndex>=Math.max(1,Math.ceil(filtered.length/pageSize))} onClick={()=>setPageIndex(p=>Math.min(Math.max(1,Math.ceil(filtered.length/pageSize)),p+1))}>›</button><select value={pageSize} onChange={e=>{setPageSize(Number(e.target.value));setPageIndex(1);}}><option value={10}>10 / 页</option><option value={20}>20 / 页</option><option value={50}>50 / 页</option></select></div></>}
+ {loading?<div className="empty-state">加载中…</div>:<><table className="data-table company-table resource-table domain-resource-table"><thead><tr><th>方案名称</th><th>所属领域</th><th>版本</th><th>设备</th><th>页面</th><th>文档</th><th>状态</th><th>创建人</th><th>从模板创建</th><th>操作</th></tr></thead><tbody>{filtered.slice((pageIndex-1)*pageSize,pageIndex*pageSize).map(row=><tr key={row.id} onClick={()=>onOpen(row.id)}><td><button className="link company-record-link" title={row.name} onClick={e=>{e.stopPropagation();onOpen(row.id);}}><b>{row.name||"未命名方案"}</b></button></td><td>{row.domain_name||"—"}</td><td>{row.version||"—"}</td><td>{row.device_count||0}</td><td>{row.page_count||0}</td><td>{row.doc_count||0}</td><td><Status>{row.status==="available"?"可用":"不可用"}</Status></td><td>{row.creator||"—"}</td><td onClick={e=>e.stopPropagation()}><button className="link" onClick={async(e:React.MouseEvent)=>{e.stopPropagation();try{const s=await fetchDb(`/domain-templates/${row.id}/create-site`,{method:"POST",headers:{"Content-Type":"application/json"}}) as any;go("siteEdit",s.id);}catch(err:any){notify("创建站点失败:"+(err?.message||err));}}}>创建</button></td><td onClick={e=>e.stopPropagation()}><Dropdown trigger={["click"]} menu={{items:[{key:"edit",label:"编辑方案",icon:<EditOutlined/>},{key:"delete",label:"删除",danger:true,icon:<DeleteOutlined/>}],onClick:({key})=>key==="edit"?onOpen(row.id):remove(row)}}><AntButton type="text" aria-label="更多操作" icon={<EllipsisOutlined/>}/></Dropdown></td></tr>)}</tbody></table>{filtered.length===0&&<div className="empty-state">暂无符合条件的领域方案</div>}<div className="pagination"><span>{filtered.length} / 总数</span><button disabled={pageIndex<=1} onClick={()=>setPageIndex(p=>Math.max(1,p-1))}>‹</button><button className="active">{pageIndex}</button><button disabled={pageIndex>=Math.max(1,Math.ceil(filtered.length/pageSize))} onClick={()=>setPageIndex(p=>Math.min(Math.max(1,Math.ceil(filtered.length/pageSize)),p+1))}>›</button><select value={pageSize} onChange={e=>{setPageSize(Number(e.target.value));setPageIndex(1);}}><option value={10}>10 / 页</option><option value={20}>20 / 页</option><option value={50}>50 / 页</option></select></div></>}
</Panel>
- <Drawer title={preview?.name||"方案详情"} width={440} open={!!preview} onClose={()=>setPreview(null)} extra={preview&&<Button onClick={()=>onOpen(preview.id)}>编辑方案</Button>}>
- {preview&&<div className="company-detail resource-detail"><div className="detail-status"><Status>{preview.status==="available"?"可用":"不可用"}</Status></div><h3>基础信息</h3><dl><dt>所属领域</dt><dd>{preview.domain_name||"—"}</dd><dt>版本</dt><dd>{preview.version||"—"}</dd><dt>创建人</dt><dd>{preview.creator||"—"}</dd></dl><h3>方案内容</h3><dl><dt>设备模板</dt><dd>{preview.device_count||0}</dd><dt>页面</dt><dd>{preview.page_count||0}</dd><dt>知识文档</dt><dd>{preview.doc_count||0}</dd></dl>{preview.description&&<><h3>方案说明</h3><p>{preview.description}</p></>}</div>}
- </Drawer>
</>;
}