fix: harden permission-gated UI — minimum-org endpoint, modal/Popconfirm fail-closed on revocation

This commit is contained in:
2026-07-23 14:27:58 +08:00
parent a7a7af1667
commit 446c6bcc91
4 changed files with 21 additions and 23 deletions

View File

@@ -313,10 +313,8 @@ interface MatchModalProps {
const JinshujuMatchModal: React.FC<MatchModalProps> = ({ open, onClose, onApplied }) => { const JinshujuMatchModal: React.FC<MatchModalProps> = ({ open, onClose, onApplied }) => {
const { hasPermission, hasAllPermissions, permissionsReady } = usePermission(); const { hasPermission, hasAllPermissions, permissionsReady } = usePermission();
const canReadSync = hasPermission('sync:read');
const canTriggerSync = hasPermission('sync:trigger'); const canTriggerSync = hasPermission('sync:trigger');
const canEnterModal = permissionsReady && hasAllPermissions('sync:read', 'sync:trigger'); const canEnterModal = permissionsReady && hasAllPermissions('sync:read', 'sync:trigger');
const canWriteRules = permissionsReady && canTriggerSync;
const [step, setStep] = useState<'connection' | 'rule' | 'match' | 'applying'>('connection'); const [step, setStep] = useState<'connection' | 'rule' | 'match' | 'applying'>('connection');
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [selectedRuleId, setSelectedRuleId] = useState<number | undefined>(); const [selectedRuleId, setSelectedRuleId] = useState<number | undefined>();

View File

@@ -27,8 +27,8 @@ interface ExamDetail extends ExamItem {
} }
const PhoneCell: React.FC<{ row: ScoreRow }> = ({ row }) => { const PhoneCell: React.FC<{ row: ScoreRow }> = ({ row }) => {
const reveal = useViewSensitive(row.studentId, '考试管理', hasPermission('log:create'));
const { hasPermission } = usePermission(); const { hasPermission } = usePermission();
const reveal = useViewSensitive(row.studentId, '考试管理', hasPermission('log:create'));
if (!row.phone) return <>-</>; if (!row.phone) return <>-</>;
return ( return (
<Space size={4}> <Space size={4}>

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useState, useMemo, useCallback, useRef } from 'react'; import React, { useEffect, useState, useMemo, useCallback } from 'react';
import { import {
Table, Table,
Button, Button,
@@ -594,8 +594,8 @@ const OccupanciesPage: React.FC = () => {
> >
退宿 退宿
</PermissionButton> </PermissionButton>
</>)} ) : (
{canDelete ? ( canDelete ? (
<Popconfirm <Popconfirm
title={`确定归档选中的 ${selectedRowKeys.length} 条入住记录?在住记录会自动跳过`} title={`确定归档选中的 ${selectedRowKeys.length} 条入住记录?在住记录会自动跳过`}
onConfirm={handleBatchDelete} onConfirm={handleBatchDelete}
@@ -612,7 +612,7 @@ const OccupanciesPage: React.FC = () => {
</Button> </Button>
</Popconfirm> </Popconfirm>
) : null} ) : null
)} )}
<Button size="small" onClick={() => setSelectedRowKeys([])} style={{ marginLeft: 8 }}> <Button size="small" onClick={() => setSelectedRowKeys([])} style={{ marginLeft: 8 }}>

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { import {
Alert, Alert,
App, App,