refine Semi UI identity permissions

This commit is contained in:
lingniu
2026-07-18 17:20:25 +08:00
parent dbd1d9d6ca
commit 29b9ce9594
3 changed files with 303 additions and 6 deletions

View File

@@ -433,17 +433,57 @@ export default function UsersPage() {
<Tabs className="v2-user-editor-tabs" activeKey={activeSection} onChange={(key) => setActiveSection(String(key) as EditorSection)}>
<Tabs.TabPane tab="登录身份" itemKey="identity">
<Card className="v2-user-editor-section v2-user-identity-section" title="登录身份" headerLine>
<div className="v2-user-fields">
<label><span></span><Input required disabled={!creating} value={draft.username} onChange={(value) => setDraft((current) => ({ ...current, username: value }))} placeholder="例如 customer-huadong" /></label>
<label><span></span><Input required value={draft.displayName} onChange={(value) => setDraft((current) => ({ ...current, displayName: value }))} placeholder="显示在平台右上角" /></label>
<label><span>{creating ? '初始密码' : '重置密码(可选)'}</span><Input required={creating} mode="password" autoComplete="new-password" value={draft.password} onChange={(value) => setDraft((current) => ({ ...current, password: value }))} placeholder="至少 10 位,包含三类字符" /></label>
<label><span></span><Input value={draft.customerRef} onChange={(value) => setDraft((current) => ({ ...current, customerRef: value }))} placeholder="为 OneOS / RuoYi 映射预留" /></label>
<div className="v2-user-identity-overview" aria-label="登录身份摘要">
<div>
<span><small></small><strong>{draft.username || '待设置'}</strong></span>
<Tag color={creating ? 'blue' : 'grey'} type="light" size="small">{creating ? '新账号' : '不可修改'}</Tag>
</div>
<div>
<span><small></small><strong>{draft.displayName || '待设置'}</strong></span>
<Tag color={draft.displayName ? 'green' : 'amber'} type="light" size="small">{draft.displayName ? '已设置' : '待完善'}</Tag>
</div>
<div>
<span><small></small><strong>{selected?.authProvider && selected.authProvider !== 'local' ? selected.authProvider : '本地账号'}</strong></span>
<Tag color="blue" type="light" size="small"></Tag>
</div>
</div>
<div className="v2-user-field-group" role="group" aria-labelledby="v2-user-primary-identity">
<header>
<span><strong id="v2-user-primary-identity"></strong><small></small></span>
<Tag color="blue" type="light" size="small"></Tag>
</header>
<div className="v2-user-fields is-primary">
<label><span></span><Input required disabled={!creating} value={draft.username} onChange={(value) => setDraft((current) => ({ ...current, username: value }))} placeholder="例如 customer-huadong" /></label>
<label><span></span><Input required value={draft.displayName} onChange={(value) => setDraft((current) => ({ ...current, displayName: value }))} placeholder="显示在平台右上角" /></label>
</div>
</div>
<div className="v2-user-field-group" role="group" aria-labelledby="v2-user-security-mapping">
<header>
<span><strong id="v2-user-security-mapping"></strong><small>{creating ? '设置初始密码,并按需关联外部客户标识' : '密码留空则保持不变,客户标识用于后续系统对接'}</small></span>
<Tag color="grey" type="light" size="small">{creating ? '密码必填' : '按需修改'}</Tag>
</header>
<div className="v2-user-fields is-secondary">
<label><span>{creating ? '初始密码' : '重置密码(可选)'}</span><Input required={creating} mode="password" autoComplete="new-password" value={draft.password} onChange={(value) => setDraft((current) => ({ ...current, password: value }))} placeholder="至少 10 位,包含三类字符" /></label>
<label><span></span><Input value={draft.customerRef} onChange={(value) => setDraft((current) => ({ ...current, customerRef: value }))} placeholder="为 OneOS / RuoYi 映射预留" /></label>
</div>
</div>
</Card>
</Tabs.TabPane>
<Tabs.TabPane tab={<span className="v2-user-tab-label"><Tag color="blue" type="light" size="small">{draft.menuKeys.length}</Tag></span>} itemKey="menus">
<Card className="v2-user-editor-section v2-user-menu-section" title={<span className="v2-user-section-title"> <Tag color="blue" type="light" size="small"></Tag></span>} headerLine>
<div className="v2-menu-permissions">{customerMenus.map((menu) => <label key={menu.key} className={draft.menuKeys.includes(menu.key) ? 'is-selected' : ''}><Checkbox checked={draft.menuKeys.includes(menu.key)} onChange={() => setDraft((value) => ({ ...value, menuKeys: value.menuKeys.includes(menu.key) ? value.menuKeys.filter((item) => item !== menu.key) : [...value.menuKeys, menu.key] }))} /><span><b>{menu.label}</b><small>{menu.description}</small></span></label>)}</div>
<div className="v2-user-menu-overview" aria-label={`已开放 ${draft.menuKeys.length} 个菜单,共 ${customerMenus.length}`}>
<span><small></small><strong>{draft.menuKeys.length}<i> / {customerMenus.length}</i></strong></span>
<p><b>{draft.menuKeys.length === customerMenus.length ? '客户工作台已完整开放' : '客户工作台按最小权限开放'}</b><small> 30 </small></p>
<Tag color={draft.menuKeys.length ? 'green' : 'amber'} type="light" size="small">{draft.menuKeys.length ? '权限已配置' : '尚未开放'}</Tag>
</div>
<div className="v2-menu-permissions">{customerMenus.map((menu) => {
const selectedMenu = draft.menuKeys.includes(menu.key);
return <label key={menu.key} className={selectedMenu ? 'is-selected' : ''}>
<Checkbox checked={selectedMenu} onChange={() => setDraft((value) => ({ ...value, menuKeys: value.menuKeys.includes(menu.key) ? value.menuKeys.filter((item) => item !== menu.key) : [...value.menuKeys, menu.key] }))} />
<span className="v2-menu-permission-copy"><b>{menu.label}</b><small>{menu.description}</small></span>
<Tag className="v2-menu-permission-state" color={selectedMenu ? 'blue' : 'grey'} type="light" size="small">{selectedMenu ? '已开放' : '未开放'}</Tag>
</label>;
})}</div>
</Card>
</Tabs.TabPane>
<Tabs.TabPane tab={<span className="v2-user-tab-label"><Tag color={draft.vehicleGrants.length ? 'blue' : 'grey'} type="light" size="small">{draft.vehicleGrants.length}</Tag></span>} itemKey="vehicles">