Commit 1cf5afe5 authored by David Yang's avatar David Yang

feat: enforce table view field permissions

parent f91ad267
...@@ -12,6 +12,7 @@ import { useSubjectRecord } from './hooks/useSubjectRecord'; ...@@ -12,6 +12,7 @@ import { useSubjectRecord } from './hooks/useSubjectRecord';
import SubjectViewContent from './components/SubjectViewContent'; import SubjectViewContent from './components/SubjectViewContent';
import { import {
checkViewCondition, checkViewCondition,
isFieldDisabledByView,
isViewAccessible, isViewAccessible,
} from '@/utils/subjectView'; } from '@/utils/subjectView';
...@@ -49,6 +50,7 @@ const RecordDetailDrawer = (props, ref) => { ...@@ -49,6 +50,7 @@ const RecordDetailDrawer = (props, ref) => {
filterView = [], filterView = [],
preferredViewName, preferredViewName,
disabledFields = EMPTY_ARRAY, disabledFields = EMPTY_ARRAY,
authorizationView = null,
} = props; } = props;
const [refreshKey, setRefreshKey] = useState(() => Date.now()); const [refreshKey, setRefreshKey] = useState(() => Date.now());
...@@ -135,7 +137,9 @@ const RecordDetailDrawer = (props, ref) => { ...@@ -135,7 +137,9 @@ const RecordDetailDrawer = (props, ref) => {
[disabledFields], [disabledFields],
); );
const isDrawerFieldDisabled = (fieldPath, currentView) => const isDrawerFieldDisabled = (fieldPath, currentView) =>
disabledFieldSet.has(fieldPath) || isFieldDisabled(fieldPath, currentView); disabledFieldSet.has(fieldPath) ||
isFieldDisabled(fieldPath, currentView) ||
isFieldDisabledByView(fieldPath, authorizationView);
const closeDrawer = () => { const closeDrawer = () => {
onClose?.(); onClose?.();
......
...@@ -1638,6 +1638,7 @@ export default function ProblemRectificationListPage() { ...@@ -1638,6 +1638,7 @@ export default function ProblemRectificationListPage() {
onDataChange={onDataChange} onDataChange={onDataChange}
disabledFields={[DELAY_REQUEST_FIELD, DELAY_REQUEST_ITEMS_FIELD]} disabledFields={[DELAY_REQUEST_FIELD, DELAY_REQUEST_ITEMS_FIELD]}
preferredViewName={activeGridView?.title || activeGridView?.name} preferredViewName={activeGridView?.title || activeGridView?.name}
authorizationView={activeGridView}
/> />
), ),
}} }}
......
...@@ -65,7 +65,9 @@ ...@@ -65,7 +65,9 @@
- `settings.restrictions` 与 `settings.filters.conditions` 共同决定该视图下可见的数据范围 - `settings.restrictions` 与 `settings.filters.conditions` 共同决定该视图下可见的数据范围
- `settings.viewAuth` 决定当前用户是否能看到该视图 - `settings.viewAuth` 决定当前用户是否能看到该视图
- `type = "detail"` 的视图用于详情抽屉字段编排,按 `columns` 顺序渲染字段 - `type = "detail"` 的视图用于详情抽屉字段编排,按 `columns` 顺序渲染字段
- `settings.auth` 与 `disableColumns` 用于控制详情抽屉内字段是否允许编辑 - 表格 Tab 的 `settings.auth` 按字段路径控制详情抽屉内对应字段是否允许编辑,规则结构与多维表格一致:`field` 使用 `title` 或 `metadata.<fieldName>`,`type` 支持 `group`、`role`、`permission`,授权值分别从 `groups`、`roles`、`permissions` 读取
- 表格 Tab 的 `settings.disableColumns` 与 `settings.auth`、当前详情视图自身的同名配置叠加生效;任一层禁止编辑时字段保留展示但进入只读状态,并显示“当前视图无编辑权限”,不隐藏列或字段
- 管理员、系统账号拥有字段编辑权限旁路;普通用户按当前登录用户的用户组、应用用户组、角色或权限集合匹配,未命中配置时不得编辑。切换表格 Tab 后,详情抽屉必须立即改用新 Tab 的权限配置
因此前端新增字段展示、部门视图调整、列顺序变化时,应优先改 Subject View 配置,而不是直接修改页面常量。 因此前端新增字段展示、部门视图调整、列顺序变化时,应优先改 Subject View 配置,而不是直接修改页面常量。
......
...@@ -35,10 +35,12 @@ export function getCurrentUserFromStorage() { ...@@ -35,10 +35,12 @@ export function getCurrentUserFromStorage() {
} }
function collectUserGroups(user) { function collectUserGroups(user) {
return toArray(user?.groups) const directGroups = toArray(user?.groups)
.flatMap((group) => [group?._id, group?.name, group?.display_name, group]) .flatMap((group) => [group?._id, group?.name, group?.display_name, group])
.map(normalizeText) .map(normalizeText)
.filter(Boolean); .filter(Boolean);
const appGroups = toArray(user?.applications).flatMap((app) => app?.groups || []);
return [...directGroups, ...appGroups].map(normalizeText).filter(Boolean);
} }
function collectUserRoles(user) { function collectUserRoles(user) {
...@@ -67,7 +69,7 @@ export function hasAuthAccess(authRule, user = getCurrentUserFromStorage()) { ...@@ -67,7 +69,7 @@ export function hasAuthAccess(authRule, user = getCurrentUserFromStorage()) {
return false; return false;
} }
if (user.type === 'admin') { if (user.type === 'admin' || user.type === 'system') {
return true; return true;
} }
...@@ -87,7 +89,7 @@ export function hasAuthAccess(authRule, user = getCurrentUserFromStorage()) { ...@@ -87,7 +89,7 @@ export function hasAuthAccess(authRule, user = getCurrentUserFromStorage()) {
return intersects([user.username, user.display_name, user._id], authRule.usernames); return intersects([user.username, user.display_name, user._id], authRule.usernames);
} }
return true; return intersects(collectUserRoles(user), ['管理']);
} }
export function getFieldValue(record, fieldPath) { export function getFieldValue(record, fieldPath) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment