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
+67 -31
View File
@@ -9,6 +9,7 @@ import { Table } from "~/components/ui/Table";
import { Pagination } from "~/components/ui/Pagination";
import { getPromptTemplates, deletePromptTemplate, type PromptTemplateUI } from "~/api/prompts/prompts";
import { toastService, messageService } from "~/components/ui";
import { usePermission, PermissionGuard } from "~/hooks/usePermission";
// 样式链接
export function links() {
@@ -41,7 +42,7 @@ interface ActionData {
// 数据加载器
export async function loader({ request }: LoaderFunctionArgs) {
try {
// 获取用户会话信息
// 获取用户会话信息(服务端需要获取 JWT token
const { getUserSession } = await import("~/api/login/auth.server");
const { frontendJWT } = await getUserSession(request);
@@ -102,14 +103,14 @@ export async function loader({ request }: LoaderFunctionArgs) {
// Action函数 - 处理删除请求
export async function action({ request }: ActionFunctionArgs) {
// 获取用户会话信息(服务端需要获取 JWT token)
const { getUserSession } = await import("~/api/login/auth.server");
const { frontendJWT } = await getUserSession(request);
const formData = await request.formData();
const id = formData.get("id") as string;
const intent = formData.get("intent") as string;
// 获取用户会话信息
const { getUserSession } = await import("~/api/login/auth.server");
const { frontendJWT } = await getUserSession(request);
if (intent === "delete" && id) {
try {
const result = await deletePromptTemplate(id, frontendJWT);
@@ -138,16 +139,35 @@ export default function PromptsIndex() {
const [isLoading, setIsLoading] = useState(false);
const fetcher = useFetcher<ActionData>();
// 获取用户角色并判断权限
const rootData = useRouteLoaderData("root") as { userRole: string };
const userRole = rootData?.userRole || 'common';
const hasEditPermission = userRole.toLowerCase().includes('provin');
// 🔐 使用新的权限检查Hook
const {
canCreate,
canUpdate,
canDelete,
canView,
hasPermission,
permissions,
userRole
} = usePermission();
// 检查各项权限
const canCreateTemplate = canCreate('prompt_template');
const canEditTemplate = canUpdate('prompt_template');
const canDeleteTemplate = canDelete('prompt_template');
const canViewTemplate = canView('prompt_template');
// 调试信息
useEffect(() => {
console.log('📋 [Prompts] 用户角色:', userRole);
console.log('📋 [Prompts] 是否有编辑权限:', hasEditPermission);
}, [userRole, hasEditPermission]);
// useEffect(() => {
// console.log('📋 [Prompts] 模板数据:', templates);
// console.log('📋 [Prompts] 用户角色:', userRole);
// console.log('📋 [Prompts] 权限列表:', permissions);
// console.log('📋 [Prompts] 权限检查结果:', {
// canCreate: canCreateTemplate,
// canEdit: canEditTemplate,
// canDelete: canDeleteTemplate,
// canView: canViewTemplate
// });
// }, [userRole, permissions, templates, canCreateTemplate, canEditTemplate, canDeleteTemplate, canViewTemplate]);
// 处理搜索名称
const handleNameSearch = (value: string) => {
@@ -234,6 +254,13 @@ export default function PromptsIndex() {
});
};
// 监听 loader 错误
useEffect(() => {
if (error) {
toastService.error(error);
}
}, [error]);
// 监听 fetcher 状态变化
useEffect(() => {
if (fetcher.state === 'idle' && fetcher.data) {
@@ -366,6 +393,7 @@ export default function PromptsIndex() {
render: (_: unknown, record: PromptTemplateUI) => (
<div>
{record.status === 'system' ? (
// 系统预设模板:只能查看,有编辑权限的可以复制
<>
<button
className="operation-btn text-primary"
@@ -373,7 +401,8 @@ export default function PromptsIndex() {
>
<i className="ri-eye-line"></i>
</button>
{hasEditPermission && (
{/* 🔐 复制按钮需要创建权限 */}
{canCreateTemplate && (
<button
className="operation-btn text-primary"
onClick={() => handleCloneTemplate(record.id)}
@@ -383,14 +412,27 @@ export default function PromptsIndex() {
)}
</>
) : (
// 自定义模板:根据权限显示编辑/查看/删除
<>
<button
className="operation-btn text-primary"
onClick={() => hasEditPermission ? handleEditTemplate(record.id) : handleViewTemplate(record.id)}
>
<i className={hasEditPermission ? "ri-edit-line" : "ri-eye-line"}></i> {hasEditPermission ? '编辑' : '查看'}
</button>
{hasEditPermission && (
{/* 🔐 有编辑权限显示编辑按钮,否则显示查看按钮 */}
{canEditTemplate ? (
<button
className="operation-btn text-primary"
onClick={() => handleEditTemplate(record.id)}
>
<i className="ri-edit-line"></i>
</button>
) : canViewTemplate ? (
<button
className="operation-btn text-primary"
onClick={() => handleViewTemplate(record.id)}
>
<i className="ri-eye-line"></i>
</button>
) : null}
{/* 🔐 删除按钮需要删除权限 */}
{canDeleteTemplate && (
<button
className="operation-btn text-error"
onClick={() => handleDeleteTemplate(record.id)}
@@ -412,7 +454,8 @@ export default function PromptsIndex() {
<div className="page-header">
<h2 className="page-title"></h2>
<div>
{hasEditPermission && (
{/* 🔐 使用权限控制显示新增按钮 */}
<PermissionGuard permission="prompt_template:create:write">
<Button
type="primary"
icon="ri-add-line"
@@ -420,7 +463,7 @@ export default function PromptsIndex() {
>
</Button>
)}
</PermissionGuard>
</div>
</div>
@@ -485,14 +528,7 @@ export default function PromptsIndex() {
className="flex-1 min-w-[200px]"
/>
</FilterPanel>
{/* 错误信息 */}
{error && (
<div className="error-alert mb-4 p-4 bg-red-50 text-red-700 rounded-md">
<i className="ri-error-warning-line mr-2"></i> {error}
</div>
)}
{/* 数据表格 */}
<Card bodyClassName="px-4 py-4">
<Table