setDraft((state) => ({ ...state, keyword: event.target.value }))} onPressEnter={applyFilters} />
{canManage && 已选 {selectedIds.length} 条(当前页)
}{people.isError ? : rowKey="id" loading={people.isLoading} rowSelection={rowSelection} dataSource={people.data?.items} columns={columns} pagination={false} scroll={{ x: 1150 }} locale={{ emptyText: }} />} { setPage(next); setPageSize(size); setSelectedIds([]) }} />
+ setEditing(undefined)} onOk={() => form.submit()}> ({ value: item.id, label: `${item.collegeName} · ${item.majorName} · ${item.name}` }))} /> ({ value, label }))} /> ({ value, label }))} />个人资料 ({ value }))} placeholder="可输入任意国籍" /> ({ value }))} /> ({ value, label: value }))} />>}
+ setActivating(undefined)} onOk={() => activationForm.submit()}> ({ validator: (_, value) => !value || getFieldValue('password') === value ? Promise.resolve() : Promise.reject(new Error('两次输入的密码不一致')) })]}>
+ void applyArchive()} onCancel={() => setArchive((state) => ({ ...state, open: false }))}>符合条件 {eligible.length} / {archive.previews.length} 条。提交时会再次检查,受阻记录不执行。
{archive.busy && !archive.previews.length ? : archive.previews.map((item) => {item.name || '不可操作记录'}{item.error && {item.error}
}{!item.error && <>{item.isArchived ? '已归档' : '未归档'}{item.archiveReason ? ` · 原因:${item.archiveReason}` : ''}
{item.isArchived === archive.target && 已处于目标状态,无需重复操作。
}{item.blockers?.map((blocker, index) => {blocker.message}
)}{item.notices?.map((notice, index) => {notice.message}
)}>})}{!archive.results.length ? : archive.results.map((result) => )}
+ setHistory((state) => ({ ...state, open: false }))}>{history.busy ? : history.entries.length ? history.entries.map((entry) => {entry.isArchived ? '归档' : '恢复'} · {entry.actorName || entry.actorUserId}{new Date(entry.createdAt).toLocaleString('zh-CN', { hour12: false })}
{entry.reason}
) : }第 {history.page} 页
+
+}
diff --git a/web-react/src/pages/personnel-registry.css b/web-react/src/pages/personnel-registry.css
new file mode 100644
index 0000000..6e2bc04
--- /dev/null
+++ b/web-react/src/pages/personnel-registry.css
@@ -0,0 +1 @@
+.personnel-page{gap:16px}.registry-banner{display:grid;grid-template-columns:1fr 180px;border:1px solid var(--line);background:#fff}.registry-banner>div{padding:14px 18px}.registry-banner>div:last-child{border-left:3px solid var(--teal);background:var(--teal-soft)}.registry-banner span,.registry-banner strong,.registry-banner small{display:block}.registry-banner span{color:var(--teal);font:700 8px var(--font-data)}.registry-banner strong{margin:5px 0;color:var(--brand-deep);font-size:13px}.registry-banner>div:last-child strong{font:700 22px var(--font-data)}.registry-banner small{color:var(--ink-muted);font-size:8px}.registry-card{min-width:0;padding:16px;border:1px solid var(--line);background:#fff}.registry-filters,.registry-batch,.registry-actions{display:flex;align-items:center;flex-wrap:wrap;gap:7px}.registry-filters{margin-bottom:12px}.registry-filters>.ant-input-affix-wrapper{width:225px}.registry-filters>.ant-select{width:145px}.registry-filters>.ant-input-number{width:125px}.registry-batch{margin-bottom:12px}.registry-batch span{color:var(--ink-muted);font-size:8px}.registry-card>.ant-pagination{display:flex;justify-content:flex-end;margin-top:15px}.registry-number{color:var(--brand-deep);font:700 9px var(--font-data)}.registry-name{display:grid;gap:3px}.registry-name span{color:var(--ink-muted);font-size:8px}.registry-form-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}.registry-form-grid .ant-input-number{width:100%}.registry-archive{padding:11px 0;border-bottom:1px solid var(--line)}.registry-archive p{margin:5px 0;color:var(--ink-muted);line-height:1.55}.registry-archive .error{color:#b42318}.registry-reason{display:grid;gap:7px;margin-top:14px;font-weight:600}@media(max-width:850px){.registry-filters{align-items:stretch;flex-direction:column}.registry-filters>*{width:100%!important}}@media(max-width:600px){.registry-banner{grid-template-columns:1fr}.registry-banner>div:last-child{border-top:1px solid var(--line);border-left:3px solid var(--teal)}.registry-batch{align-items:stretch;flex-direction:column}.registry-batch>*{width:100%}.registry-form-grid{grid-template-columns:1fr}}