评查点规则编辑中添加多实体开关控制。
修复文档类型删除失败的bug
This commit is contained in:
@@ -589,8 +589,8 @@ export function ExtractionSettings({
|
|||||||
</div>
|
</div>
|
||||||
<div className="ant-card-body">
|
<div className="ant-card-body">
|
||||||
{/* 多实体抽取开关 */}
|
{/* 多实体抽取开关 */}
|
||||||
<div className="mb-6 p-3 bg-gray-50 rounded-md border border-gray-200 w-[40%]">
|
<div className="mb-6 p-3 bg-gray-50 rounded-md border border-gray-200 w-fit">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center gap-5">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<i className="ri-group-line text-lg mr-2 text-gray-600"></i>
|
<i className="ri-group-line text-lg mr-2 text-gray-600"></i>
|
||||||
<div>
|
<div>
|
||||||
@@ -599,7 +599,7 @@ export function ExtractionSettings({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label className="relative inline-flex items-center cursor-pointer ml-5">
|
<label className="relative inline-flex items-center cursor-pointer">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
className="sr-only peer"
|
className="sr-only peer"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect, useRef } from "react";
|
||||||
import { useSearchParams, useNavigate, useLoaderData } from "@remix-run/react";
|
import { useSearchParams, useNavigate, useLoaderData, useFetcher, useRevalidator } from "@remix-run/react";
|
||||||
import { ActionFunctionArgs, LoaderFunctionArgs, MetaFunction } from "@remix-run/node";
|
import { ActionFunctionArgs, LoaderFunctionArgs, MetaFunction } from "@remix-run/node";
|
||||||
import { Table } from "~/components/ui/Table";
|
import { Table } from "~/components/ui/Table";
|
||||||
import { Card } from "~/components/ui/Card";
|
import { Card } from "~/components/ui/Card";
|
||||||
@@ -46,6 +46,12 @@ interface LoaderData {
|
|||||||
frontendJWT?: string | null;
|
frontendJWT?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 定义 action 返回的数据类型
|
||||||
|
interface ActionResponse {
|
||||||
|
success?: boolean;
|
||||||
|
error?: string;
|
||||||
|
}
|
||||||
|
|
||||||
// 加载函数 - 获取文档类型列表
|
// 加载函数 - 获取文档类型列表
|
||||||
export async function loader({ request }: LoaderFunctionArgs) {
|
export async function loader({ request }: LoaderFunctionArgs) {
|
||||||
try {
|
try {
|
||||||
@@ -153,11 +159,31 @@ export async function action({ request }: ActionFunctionArgs) {
|
|||||||
export default function DocumentTypesList() {
|
export default function DocumentTypesList() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
const [isDeleting, setIsDeleting] = useState(false);
|
const fetcher = useFetcher<ActionResponse>();
|
||||||
|
const revalidator = useRevalidator();
|
||||||
|
const processedResponseRef = useRef<string | null>(null);
|
||||||
|
|
||||||
// 获取加载器数据
|
// 获取加载器数据
|
||||||
const { types, total, error, parentGroups, frontendJWT } = useLoaderData<LoaderData>();
|
const { types, total, error, parentGroups, frontendJWT } = useLoaderData<LoaderData>();
|
||||||
|
|
||||||
|
// 处理 fetcher 响应
|
||||||
|
useEffect(() => {
|
||||||
|
// 为每个响应生成唯一标识,避免重复处理
|
||||||
|
const responseKey = fetcher.data ? JSON.stringify(fetcher.data) : null;
|
||||||
|
|
||||||
|
if (responseKey && responseKey !== processedResponseRef.current) {
|
||||||
|
if (fetcher.data?.success) {
|
||||||
|
toastService.success('删除成功!');
|
||||||
|
processedResponseRef.current = responseKey;
|
||||||
|
// 只重新验证数据,不刷新整个页面
|
||||||
|
revalidator.revalidate();
|
||||||
|
} else if (fetcher.data?.error) {
|
||||||
|
toastService.error(`删除失败: ${fetcher.data.error}`);
|
||||||
|
processedResponseRef.current = responseKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [fetcher.data, revalidator]);
|
||||||
|
|
||||||
// 权限控制
|
// 权限控制
|
||||||
const { canCreate, canUpdate, canDelete, canView } = usePermission();
|
const { canCreate, canUpdate, canDelete, canView } = usePermission();
|
||||||
const canCreateType = canCreate('document_type');
|
const canCreateType = canCreate('document_type');
|
||||||
@@ -230,13 +256,18 @@ export default function DocumentTypesList() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 处理删除文档类型
|
// 处理删除文档类型
|
||||||
const handleDelete = async (id: number) => {
|
const handleDelete = (id: number) => {
|
||||||
// 权限检查
|
// 权限检查
|
||||||
if (!canDeleteType) {
|
if (!canDeleteType) {
|
||||||
toastService.warning('您没有删除权限');
|
toastService.warning('您没有删除权限');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查是否正在加载
|
||||||
|
if (fetcher.state === 'submitting') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
messageService.show({
|
messageService.show({
|
||||||
title: "确认删除",
|
title: "确认删除",
|
||||||
message: "确定要删除该文档类型吗?此操作不会影响关联的评查点分组,但可能会影响使用该类型的文档评查。",
|
message: "确定要删除该文档类型吗?此操作不会影响关联的评查点分组,但可能会影响使用该类型的文档评查。",
|
||||||
@@ -244,33 +275,13 @@ export default function DocumentTypesList() {
|
|||||||
confirmText: "删除",
|
confirmText: "删除",
|
||||||
cancelText: "取消",
|
cancelText: "取消",
|
||||||
confirmDelay: 4,
|
confirmDelay: 4,
|
||||||
onConfirm: async () => {
|
onConfirm: () => {
|
||||||
setIsDeleting(true);
|
const formData = new FormData();
|
||||||
|
formData.append('id', id.toString());
|
||||||
|
formData.append('intent', 'delete');
|
||||||
|
|
||||||
try {
|
// 使用 useFetcher 提交请求
|
||||||
const formData = new FormData();
|
fetcher.submit(formData, { method: 'post' });
|
||||||
formData.append('id', id.toString());
|
|
||||||
formData.append('intent', 'delete');
|
|
||||||
|
|
||||||
const response = await fetch('/document-types?index', {
|
|
||||||
method: 'POST',
|
|
||||||
body: formData
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await response.json();
|
|
||||||
|
|
||||||
if (result.success) {
|
|
||||||
toastService.success('删除成功!');
|
|
||||||
// 刷新页面
|
|
||||||
window.location.reload();
|
|
||||||
} else {
|
|
||||||
toastService.error(`删除失败: ${result.error || '未知错误'}`);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
toastService.error(`删除失败: ${error instanceof Error ? error.message : '未知错误'}`);
|
|
||||||
} finally {
|
|
||||||
setIsDeleting(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -382,7 +393,7 @@ export default function DocumentTypesList() {
|
|||||||
<button
|
<button
|
||||||
className="operation-btn text-error"
|
className="operation-btn text-error"
|
||||||
onClick={() => handleDelete(record.id)}
|
onClick={() => handleDelete(record.id)}
|
||||||
disabled={isDeleting}
|
disabled={fetcher.state === 'submitting'}
|
||||||
>
|
>
|
||||||
<i className="ri-delete-bin-line"></i> 删除
|
<i className="ri-delete-bin-line"></i> 删除
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
+30
-1
@@ -777,7 +777,36 @@ export default function ReviewDetails() {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
{/* 在面包屑右侧显示精简版的FileInfo */}
|
{/* 在面包屑右侧显示精简版的FileInfo */}
|
||||||
<div className=" ml-10 text-left flex-1 flex flex-row flex-wrap">
|
<div className=" ml-5 text-left flex-1 flex flex-row flex-wrap items-center">
|
||||||
|
{/* 评分tag:优秀、合格、不合格、待评价 */}
|
||||||
|
{/* {(() => {
|
||||||
|
const score = "";
|
||||||
|
let tagText = '待评价';
|
||||||
|
let tagClassName = 'bg-gray-100 text-gray-600 border-gray-300';
|
||||||
|
|
||||||
|
if (score >= 90) {
|
||||||
|
tagText = '优秀';
|
||||||
|
tagClassName = 'bg-green-50 text-green-700 border-green-300';
|
||||||
|
} else if (score >= 60) {
|
||||||
|
tagText = '合格';
|
||||||
|
tagClassName = 'bg-blue-50 text-blue-700 border-blue-300';
|
||||||
|
} else if (score > 0) {
|
||||||
|
tagText = '不合格';
|
||||||
|
tagClassName = 'bg-red-50 text-red-700 border-red-300';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span className={`
|
||||||
|
px-3 py-0.5 rounded-full text-xs font-medium border mr-1
|
||||||
|
${tagClassName}
|
||||||
|
`}
|
||||||
|
title="供应商评价"
|
||||||
|
>
|
||||||
|
{tagText}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
})()} */}
|
||||||
|
|
||||||
<span className="mr-2 text-xl font-medium">
|
<span className="mr-2 text-xl font-medium">
|
||||||
{reviewData.fileInfo.fileName}
|
{reviewData.fileInfo.fileName}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user