Files
knowledge-governance/web/src/ScopeRuleEditor.tsx
T
zheromiku f6cb90cd70 feat(web): login gate, session identity UI and member management
- main.tsx 挂 AuthProvider 门控:未登录→登录页;must_change_password→强制改密页
- 登录页/改密页/顶栏身份(头像+姓名+角色徽章+退出)按 A·Data-console token 样式
- 全局 fetch 拦截器:任意业务请求 401 自动回登录页(会话过期/被撤销不留死表单)
- 系统设置新增「成员与角色」分区(仅 admin 可见):名单、角色调整、启停、重置临时密码、新增成员
- 消灭全部手填操作人:审核/封批/确认计划集/范围规则/来源调度/UI 设置/开始处理/批量重试/
  目录差异确认共 9 处输入框删除,请求体不再携带 actor 字段(服务端从会话注入)
- 测试断言方向翻转:显式验证请求体不含 operator_ref/created_by 等字段
- 附带修复:登录失败计数 SQL 参数类型无法推断导致 500(pgx 扩展协议),显式 cast 解决

前端门禁:tsc 0 错、125 用例全绿、build 通过
2026-09-30 10:54:07 +08:00

32 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState } from 'react'
import type { ClearScopeRuleDecision, ScopeRule, ScopeRuleDecision, ScopeRuleTarget, Visibility } from './scopeRules'
interface Props {
target: ScopeRuleTarget
currentRule?: ScopeRule
saving: boolean
error?: string|null
onSave: (decision:ScopeRuleDecision)=>void
onClear: (decision:ClearScopeRuleDecision)=>void
}
export function ScopeRuleEditor({target,currentRule,saving,error,onSave,onClear}:Props){
const [visibility,setVisibility]=useState<Visibility|''>(currentRule?.visibility||'')
const [reason,setReason]=useState('')
const reasonReady=reason.trim()!==''&&!saving
const saveReady=reasonReady&&visibility!==''
const label=target.target_type==='item'?'仅此文件':target.directory_path?'此目录及子目录':'整个来源'
const base={...target,reason:reason.trim()}
return <section className="scope-editor" aria-label="对内对外范围设置">
<div className="scope-editor-heading"><div><strong>对内/对外设置</strong><span>{label}</span></div>{currentRule?<span className={`scope-badge ${currentRule.visibility}`}>当前设置:{currentRule.visibility==='external'?'对外':'对内'}</span>:<span className="inherited-badge">当前没有本级设置</span>}</div>
{currentRule?<p className="scope-rule-meta">由 {currentRule.updated_by} 设置 · 原因:{currentRule.reason}</p>:<p className="scope-rule-meta">当前继承上级规则或来源原始标记。</p>}
<div className="scope-editor-fields">
<label>拟修改为<select value={visibility} onChange={event=>setVisibility(event.target.value as Visibility|'')}><option value="">选择新范围</option><option value="internal">对内</option><option value="external">对外</option></select></label>
<label className="scope-reason">判断原因<input value={reason} maxLength={500} placeholder="例如:官网已公开 / 含内部参数" onChange={event=>setReason(event.target.value)} /></label>
</div>
{error?<p className="scope-error" role="alert">{error}</p>:null}
<div className="scope-editor-actions"><button disabled={!saveReady} onClick={()=>onSave({...base,visibility:visibility as Visibility})}>{saving?'保存中…':'保存范围'}</button>{currentRule?<button className="secondary" disabled={!reasonReady} onClick={()=>onClear(base)}>移除本级设置,恢复继承</button>:null}</div>
<small>这里只更新治理规则并记录审计,操作自动记在当前登录人名下;不会修改源文件,也不会自动发布到生产。</small>
</section>
}