feat: 1. 本地化思源黑体的字体包并优先使用。

2. 添加权限映射表和全局查看权限的hook,便于路由控制不同权限按钮显示/隐藏。
3. 删除评查点分组的部分旧api方法。
4. 对接评查点分组接口,文档类型接口, 提示词管理接口, 入口模块管理的接口。
5. 优化角色权限管理的接口,完善不用地区的访问权限认证。
6. 优化主页交叉评查和设置的入口样式和布局。
7. 优化评查点分组,评查规则的功能权限校验。
This commit is contained in:
2025-11-29 10:37:35 +08:00
parent 61facf5d71
commit 30e100ef3e
29 changed files with 2527 additions and 2126 deletions
+66 -42
View File
@@ -1,6 +1,6 @@
import React, { useState, useEffect, useCallback, useRef } from 'react';
import { type MetaFunction, type LoaderFunctionArgs } from "@remix-run/node";
import { useLoaderData, useSearchParams, Link, useNavigate, useFetcher, useRouteLoaderData, useLocation } from "@remix-run/react";
import { useLoaderData, useSearchParams, Link, useNavigate, useFetcher, useLocation } from "@remix-run/react";
import { Button } from '~/components/ui/Button';
import { Card } from '~/components/ui/Card';
import { Tag } from '~/components/ui/Tag';
@@ -15,6 +15,7 @@ import { FilterPanel, FilterSelect, SearchFilter } from '~/components/ui/FilterP
import { Pagination } from '~/components/ui/Pagination';
import { messageService } from '~/components/ui/MessageModal';
import { toastService } from '~/components/ui/Toast';
import { usePermission } from '~/hooks/usePermission';
import {
getRulesList,
deleteRule,
@@ -25,7 +26,6 @@ import {
type RuleType as ApiRuleType,
type RuleGroup
} from '~/api/evaluation_points/rules';
import type { UserRole } from '~/root';
export const links = () => [
{ rel: "stylesheet", href: rulesStyles }
@@ -193,13 +193,20 @@ const priorityLabels = {
export default function RulesIndex() {
const loaderData = useLoaderData<typeof loader>();
const rootData = useRouteLoaderData("root") as { userRole: UserRole };
const { rules: initialRules, totalCount: initialTotalCount, currentPage, pageSize, ruleTypes: initialRuleTypes, initialLoad } = loaderData;
const [searchParams, setSearchParams] = useSearchParams();
const navigate = useNavigate();
const fetcher = useFetcher<ActionResponse>();
const location = useLocation();
// ✅ 使用权限 Hook
const { canCreate, canUpdate, canDelete, canBatch, canView } = usePermission();
const canCreateRule = canCreate('evaluation_point');
const canUpdateRule = canUpdate('evaluation_point');
const canDeleteRule = canDelete('evaluation_point');
const canBatchRule = canBatch('evaluation_point');
const canViewRule = canView('evaluation_point');
// 状态管理
const [ruleGroups, setRuleGroups] = useState<RuleGroup[]>([]);
const [loadingGroups, setLoadingGroups] = useState(false);
@@ -243,15 +250,6 @@ export default function RulesIndex() {
// 判断是否禁用规则组选择
const isRuleGroupSelectDisabled = loadingGroups || !ruleTypeParam || ruleGroups.length === 0;
// 检查用户是否为开发者角色
const userRole = rootData?.userRole || 'common';
const isDeveloper = userRole.includes('admin');
// 调试日志
// console.log("🔑 [Rules List] rootData:", rootData);
// console.log("🔑 [Rules List] 用户角色:", userRole);
// console.log("🔑 [Rules List] 是否为管理员:", isDeveloper);
// 在组件渲染时初始化状态
// useEffect(() => {
// setFilteredRules(initialRules);
@@ -523,6 +521,12 @@ export default function RulesIndex() {
// 删除评查点
const handleDeleteClick = (rule: Rule) => {
// ✅ 检查删除权限
if (!canDeleteRule) {
toastService.warning('您没有删除权限');
return;
}
messageService.show({
title: "确认删除",
message: `确认删除评查点【${rule.name}】吗?`,
@@ -535,7 +539,7 @@ export default function RulesIndex() {
const form = new FormData();
form.append("_action", "delete");
form.append("ruleId", rule.id);
fetcher.submit(form, { method: "post" });
}
});
@@ -563,6 +567,12 @@ export default function RulesIndex() {
// 批量启用/禁用
const handleBatchEnable = async (isEnabled: boolean) => {
// ✅ 检查批量操作权限
if (!canBatchRule) {
toastService.warning('您没有批量操作权限');
return;
}
if (selectedIds.length === 0) {
toastService.warning('请先选择要操作的评查点');
return;
@@ -594,6 +604,12 @@ export default function RulesIndex() {
// 批量删除
const handleBatchDelete = async () => {
// ✅ 检查批量删除权限
if (!canBatchRule || !canDeleteRule) {
toastService.warning('您没有批量删除权限');
return;
}
if (selectedIds.length === 0) {
toastService.warning('请先选择要删除的评查点');
return;
@@ -664,8 +680,8 @@ export default function RulesIndex() {
// 定义表格列配置
const columns = [
// 添加复选框列(仅开发者可见)
...(isDeveloper ? [{
// 添加复选框列(有批量操作权限时可见)
...(canBatchRule ? [{
title: (
<input
type="checkbox"
@@ -762,24 +778,30 @@ export default function RulesIndex() {
width: "10%",
render: (_: unknown, record: Rule) => (
<div className="operations-cell">
{isDeveloper ? (
// 开发者可以看到编辑、复制、删除
{/* ✅ 查看/编辑和复制按钮 - 需要查看权限 */}
{canViewRule && (
<>
<Link to={`/rules/new?id=${record.id}`} className="operation-btn">
<i className="ri-edit-line"></i>
{/* ✅ 编辑/查看按钮 - 根据权限显示编辑或查看 */}
<Link to={`/rules/new?id=${record.id}${!canUpdateRule ? '&mode=view' : ''}`} className="operation-btn">
<i className={canUpdateRule ? "ri-edit-line" : "ri-eye-line"}></i> {canUpdateRule ? '编辑' : '查看'}
</Link>
<button className="operation-btn" onClick={() => handleCopy(record)}>
<i className="ri-file-copy-line"></i>
</button>
<button className="operation-btn operation-btn-danger" onClick={() => handleDeleteClick(record)}>
<i className="ri-delete-bin-line"></i>
</button>
{/* ✅ 复制按钮 - 有创建权限时显示 */}
{canCreateRule && (
<button className="operation-btn" onClick={() => handleCopy(record)}>
<i className="ri-file-copy-line"></i>
</button>
)}
</>
) : (
// 普通用户只能查看
<Link to={`/rules/new?id=${record.id}&mode=view`} className="operation-btn">
<i className="ri-eye-line"></i>
</Link>
)}
{/* ✅ 删除按钮 - 只需要删除权限 */}
{canDeleteRule && (
<button className="operation-btn operation-btn-danger" onClick={() => handleDeleteClick(record)}>
<i className="ri-delete-bin-line"></i>
</button>
)}
{/* 如果什么权限都没有,显示 - */}
{!canViewRule && !canDeleteRule && (
<span className="text-gray-400">-</span>
)}
</div>
)
@@ -805,8 +827,8 @@ export default function RulesIndex() {
)}
</div>
<div className="flex items-center gap-2">
{/* 批量操作按钮(仅在有选择时显示) */}
{isDeveloper && selectedIds.length > 0 && (
{/* 批量操作按钮(有批量权限且有选择时显示) */}
{canBatchRule && selectedIds.length > 0 && (
<>
<Button
type="default"
@@ -824,18 +846,20 @@ export default function RulesIndex() {
>
({selectedIds.length})
</Button>
<Button
type="danger"
icon="ri-delete-bin-line"
onClick={handleBatchDelete}
className="btn-batch-delete"
>
({selectedIds.length})
</Button>
{canDeleteRule && (
<Button
type="danger"
icon="ri-delete-bin-line"
onClick={handleBatchDelete}
className="btn-batch-delete"
>
({selectedIds.length})
</Button>
)}
</>
)}
{/* 新增按钮 */}
{isDeveloper && (
{/* 新增按钮 - 有创建权限时显示 */}
{canCreateRule && (
<Button type="primary" icon="ri-add-line" to="/rules/new" className="btn-add-rule">
</Button>