616f059f1e
2. 修复交叉评查的任务中的文档列表的历史文档的查看跳转路径。 3. 修复评查点新增中评查点类型只能显示当前文档类型绑定的这几个一级分组。评查点类型=一级分组。 4. 修复文档列表关于pdf的下载失败的问题。
235 lines
9.0 KiB
TypeScript
235 lines
9.0 KiB
TypeScript
import { useState } from 'react';
|
||
import type { RuleGroup, DocTypeInfo } from '~/api/evaluation_points/rule-groups';
|
||
|
||
interface RebindModalProps {
|
||
/** 是否显示弹窗 */
|
||
visible: boolean;
|
||
/** 要删除的分组ID */
|
||
groupId: string;
|
||
/** 要删除的分组名称 */
|
||
groupName: string;
|
||
/** 关联的评查点数量 */
|
||
pointsCount: number;
|
||
/** 只绑定当前分组的文档类型(换绑时会替换为新分组) */
|
||
singleBoundDocTypes: DocTypeInfo[];
|
||
/** 绑定多个分组的文档类型(换绑时会移除当前分组) */
|
||
multiBoundDocTypes: DocTypeInfo[];
|
||
/** 所有一级分组列表(用于选择新分组) */
|
||
allFirstLevelGroups: RuleGroup[];
|
||
/** 换绑并删除操作是否加载中 */
|
||
loading?: boolean;
|
||
/** 关闭弹窗 */
|
||
onClose: () => void;
|
||
/** 确认换绑并删除 */
|
||
onConfirm: (newGroupId: string) => void;
|
||
}
|
||
|
||
export function RebindModal({
|
||
visible,
|
||
groupId,
|
||
groupName,
|
||
pointsCount,
|
||
singleBoundDocTypes,
|
||
multiBoundDocTypes,
|
||
allFirstLevelGroups,
|
||
loading = false,
|
||
onClose,
|
||
onConfirm
|
||
}: RebindModalProps) {
|
||
// 选中的新一级分组ID
|
||
const [selectedGroupId, setSelectedGroupId] = useState<string>('');
|
||
|
||
// 过滤掉当前要删除的一级分组
|
||
const availableGroups = allFirstLevelGroups.filter(g => g.id !== groupId);
|
||
|
||
// 处理确认换绑
|
||
const handleConfirm = () => {
|
||
if (!selectedGroupId) {
|
||
return;
|
||
}
|
||
onConfirm(selectedGroupId);
|
||
};
|
||
|
||
// 重置状态
|
||
const handleClose = () => {
|
||
setSelectedGroupId('');
|
||
onClose();
|
||
};
|
||
|
||
if (!visible) return null;
|
||
|
||
return (
|
||
<div className="fixed inset-0 z-[9999] flex items-center justify-center">
|
||
{/* 遮罩层 */}
|
||
<div
|
||
className="absolute inset-0 bg-black/50"
|
||
onClick={handleClose}
|
||
/>
|
||
|
||
{/* 弹窗内容 */}
|
||
<div className="relative bg-white rounded-lg shadow-xl w-[800px] min-h-[500px] max-h-[85vh] overflow-hidden flex flex-col">
|
||
{/* 标题栏 */}
|
||
<div className="flex items-center justify-between px-6 py-4 border-b border-gray-200">
|
||
<h3 className="text-lg font-medium text-gray-900">
|
||
<i className="ri-exchange-line mr-2 text-primary"></i>
|
||
分组换绑
|
||
</h3>
|
||
<button
|
||
type="button"
|
||
onClick={handleClose}
|
||
className="text-gray-400 hover:text-gray-600 transition-colors"
|
||
>
|
||
<i className="ri-close-line text-xl"></i>
|
||
</button>
|
||
</div>
|
||
|
||
{/* 主体内容 */}
|
||
<div className="px-6 py-4 overflow-y-auto flex-1">
|
||
{/* 提示信息 */}
|
||
<div className="mb-6 p-4 bg-amber-50 border border-amber-200 rounded-lg">
|
||
<div className="flex items-start">
|
||
<i className="ri-alert-line text-amber-500 text-xl mr-3 mt-0.5"></i>
|
||
<div>
|
||
<p className="text-amber-800 font-medium">
|
||
一级分组「{groupName}」下有 <span className="text-amber-900 font-bold">{pointsCount}</span> 个评查点
|
||
</p>
|
||
<p className="text-amber-700 text-sm mt-1">
|
||
请选择新的一级分组进行换绑后,才能删除该分组。
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* 两栏布局 */}
|
||
<div className="grid grid-cols-2 gap-6 mb-6">
|
||
{/* 左侧:需要更换绑定的文档类型 */}
|
||
<div className="border border-gray-200 rounded-lg p-4">
|
||
<h4 className="text-sm font-medium text-gray-700 mb-3 flex items-center">
|
||
<i className="ri-file-transfer-line mr-2 text-blue-500"></i>
|
||
需要更换绑定的文档类型
|
||
</h4>
|
||
{singleBoundDocTypes.length > 0 ? (
|
||
<>
|
||
<p className="text-xs text-gray-500 mb-3">
|
||
以下文档类型只绑定了当前分组,换绑后将绑定到新选择的分组:
|
||
</p>
|
||
<div className="flex flex-wrap gap-2">
|
||
{singleBoundDocTypes.map(docType => (
|
||
<span
|
||
key={docType.id}
|
||
className="inline-flex items-center px-2.5 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800"
|
||
>
|
||
<i className="ri-file-text-line mr-1"></i>
|
||
{docType.name}
|
||
</span>
|
||
))}
|
||
</div>
|
||
</>
|
||
) : (
|
||
<p className="text-sm text-gray-400 italic">无需要更换绑定的文档类型</p>
|
||
)}
|
||
</div>
|
||
|
||
{/* 右侧:选择新的一级分组 */}
|
||
<div className="border border-gray-200 rounded-lg p-4">
|
||
<h4 className="text-sm font-medium text-gray-700 mb-3 flex items-center">
|
||
<i className="ri-folder-transfer-line mr-2 text-primary"></i>
|
||
选择新的一级分组
|
||
</h4>
|
||
<p className="text-xs text-gray-500 mb-3">
|
||
请选择一个一级分组作为换绑目标(单选):
|
||
</p>
|
||
{availableGroups.length > 0 ? (
|
||
<div className="min-h-[280px] overflow-y-auto space-y-2">
|
||
{availableGroups.map(group => (
|
||
<label
|
||
key={group.id}
|
||
className={`flex items-center p-2 rounded-md cursor-pointer transition-colors ${
|
||
selectedGroupId === group.id
|
||
? 'bg-primary/10 border border-primary'
|
||
: 'hover:bg-gray-50 border border-transparent'
|
||
}`}
|
||
>
|
||
<input
|
||
type="radio"
|
||
name="newGroup"
|
||
value={group.id}
|
||
checked={selectedGroupId === group.id}
|
||
onChange={(e) => setSelectedGroupId(e.target.value)}
|
||
className="mr-3 text-primary focus:ring-primary"
|
||
/>
|
||
<i className="ri-folder-line mr-2 text-gray-400"></i>
|
||
<span className="text-sm text-gray-700">{group.name}</span>
|
||
{group.code && (
|
||
<span className="ml-2 text-xs text-gray-400">({group.code})</span>
|
||
)}
|
||
</label>
|
||
))}
|
||
</div>
|
||
) : (
|
||
<p className="text-sm text-gray-400 italic">暂无可选的一级分组</p>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
{/* 下方:会移除绑定的文档类型 */}
|
||
{multiBoundDocTypes.length > 0 && (
|
||
<div className="border border-gray-200 rounded-lg p-4">
|
||
<h4 className="text-sm font-medium text-gray-700 mb-3 flex items-center">
|
||
<i className="ri-delete-bin-line mr-2 text-orange-500"></i>
|
||
会移除当前分组绑定的文档类型
|
||
</h4>
|
||
<p className="text-xs text-gray-500 mb-3">
|
||
以下文档类型绑定了多个一级分组,换绑后将移除当前分组的绑定关系:
|
||
</p>
|
||
<div className="flex flex-wrap gap-2">
|
||
{multiBoundDocTypes.map(docType => (
|
||
<span
|
||
key={docType.id}
|
||
className="inline-flex items-center px-2.5 py-1 rounded-full text-xs font-medium bg-orange-100 text-orange-800"
|
||
>
|
||
<i className="ri-file-text-line mr-1"></i>
|
||
{docType.name}
|
||
</span>
|
||
))}
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* 底部按钮 */}
|
||
<div className="flex items-center justify-end gap-3 px-6 py-4 border-t border-gray-200 bg-gray-50">
|
||
<button
|
||
type="button"
|
||
onClick={handleClose}
|
||
disabled={loading}
|
||
className="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary disabled:opacity-50 disabled:cursor-not-allowed"
|
||
>
|
||
取消
|
||
</button>
|
||
<button
|
||
type="button"
|
||
onClick={handleConfirm}
|
||
disabled={!selectedGroupId || loading}
|
||
className="inline-flex items-center px-4 py-2 text-sm font-medium text-white bg-primary border border-transparent rounded-md hover:bg-primary-hover focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary disabled:opacity-50 disabled:cursor-not-allowed"
|
||
>
|
||
{loading ? (
|
||
<>
|
||
<i className="ri-loader-4-line animate-spin mr-2"></i>
|
||
处理中...
|
||
</>
|
||
) : (
|
||
<>
|
||
<i className="ri-exchange-line mr-2"></i>
|
||
更换绑定并删除
|
||
</>
|
||
)}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export default RebindModal;
|