feat: 1.修改提示词模板的不用角色的操作权限。

2. 对接数据看板的数据。
3. 添加入口模块管理的页面。
This commit is contained in:
2025-11-21 17:16:07 +08:00
parent 3850d05bdd
commit dab0835605
13 changed files with 1877 additions and 297 deletions
+53 -35
View File
@@ -1,5 +1,5 @@
import { MetaFunction, type LoaderFunctionArgs, type ActionFunctionArgs } from "@remix-run/node";
import { useSearchParams, useNavigate, useLoaderData, useFetcher } from "@remix-run/react";
import { useSearchParams, useNavigate, useLoaderData, useFetcher, useRouteLoaderData } from "@remix-run/react";
import { useState, useEffect } from "react";
import indexStyles from "~/styles/pages/prompts_index.css?url";
import { Card } from "~/components/ui/Card";
@@ -137,7 +137,18 @@ export default function PromptsIndex() {
const { templates, total, currentPage, pageSize, error } = useLoaderData<typeof loader>();
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');
// 调试信息
useEffect(() => {
console.log('📋 [Prompts] 用户角色:', userRole);
console.log('📋 [Prompts] 是否有编辑权限:', hasEditPermission);
}, [userRole, hasEditPermission]);
// 处理搜索名称
const handleNameSearch = (value: string) => {
const newParams = new URLSearchParams(searchParams);
@@ -247,7 +258,7 @@ export default function PromptsIndex() {
{
title: "模板名称",
key: "template_name",
width: "300px",
width: "25%",
render: (_: unknown, record: PromptTemplateUI) => (
<div className="flex items-center">
<i className="ri-file-list-line text-primary mr-2"></i>
@@ -258,11 +269,11 @@ export default function PromptsIndex() {
{
title: "类型",
key: "template_type",
width: "120px",
width: "100px",
render: (_: unknown, record: PromptTemplateUI) => {
let typeText = '';
let typeClass = '';
switch (record.template_type) {
case 'LLM_Extraction':
typeText = '抽取';
@@ -285,15 +296,16 @@ export default function PromptsIndex() {
typeClass = 'type-common';
break;
}
return <span className={`type-badge ${typeClass}`}>{typeText}</span>;
}
},
{
title: "描述",
key: "description",
width: "30%",
render: (_: unknown, record: PromptTemplateUI) => (
<div className="text-secondary text-sm max-w-xs text-wrap" title={record.description}>
<div className="text-secondary text-sm text-wrap" title={record.description}>
{record.description}
</div>
)
@@ -301,17 +313,17 @@ export default function PromptsIndex() {
{
title: "版本",
key: "version",
width: "80px",
width: "70px",
render: (_: unknown, record: PromptTemplateUI) => record.version
},
{
title: "状态",
key: "status",
width: "100px",
width: "110px",
render: (_: unknown, record: PromptTemplateUI) => {
let statusText = '';
let statusClass = '';
switch (record.status) {
case 'active':
statusText = '启用';
@@ -326,14 +338,14 @@ export default function PromptsIndex() {
statusClass = 'status-system';
break;
}
return <span className={`status-badge ${statusClass}`}>{statusText}</span>;
}
},
{
title: "创建者",
key: "created_by",
width: "100px",
width: "120px",
render: (_: unknown, record: PromptTemplateUI) => (
// <span className="text-secondary">用户 {record.created_by}</span>
<span className="text-secondary">{record.created_by_username}</span>
@@ -342,7 +354,7 @@ export default function PromptsIndex() {
{
title: "操作",
key: "operation",
width: "150px",
width: "160px",
render: (_: unknown, record: PromptTemplateUI) => (
<div>
{record.status === 'system' ? (
@@ -353,28 +365,32 @@ export default function PromptsIndex() {
>
<i className="ri-eye-line"></i>
</button>
<button
className="operation-btn text-primary"
onClick={() => handleCloneTemplate(record.id)}
>
<i className="ri-file-copy-line"></i>
</button>
{hasEditPermission && (
<button
className="operation-btn text-primary"
onClick={() => handleCloneTemplate(record.id)}
>
<i className="ri-file-copy-line"></i>
</button>
)}
</>
) : (
<>
<button
className="operation-btn text-primary"
onClick={() => handleEditTemplate(record.id)}
onClick={() => hasEditPermission ? handleEditTemplate(record.id) : handleViewTemplate(record.id)}
>
<i className="ri-edit-line"></i>
</button>
<button
className="operation-btn text-error"
onClick={() => handleDeleteTemplate(record.id)}
disabled={isLoading}
>
<i className="ri-delete-bin-line"></i>
<i className={hasEditPermission ? "ri-edit-line" : "ri-eye-line"}></i> {hasEditPermission ? '编辑' : '查看'}
</button>
{hasEditPermission && (
<button
className="operation-btn text-error"
onClick={() => handleDeleteTemplate(record.id)}
disabled={isLoading}
>
<i className="ri-delete-bin-line"></i>
</button>
)}
</>
)}
</div>
@@ -388,13 +404,15 @@ export default function PromptsIndex() {
<div className="page-header">
<h2 className="page-title"></h2>
<div>
<Button
type="primary"
icon="ri-add-line"
onClick={() => navigate("/prompts/new")}
>
</Button>
{hasEditPermission && (
<Button
type="primary"
icon="ri-add-line"
onClick={() => navigate("/prompts/new")}
>
</Button>
)}
</div>
</div>