修改文档列表
This commit is contained in:
@@ -19,22 +19,31 @@ export const meta: MetaFunction = () => {
|
||||
];
|
||||
};
|
||||
|
||||
// 文档状态定义
|
||||
enum DocumentStatus {
|
||||
WAITING = "waiting",
|
||||
PROCESSING = "processing",
|
||||
PASS = "pass",
|
||||
WARNING = "warning",
|
||||
FAIL = "fail"
|
||||
// 文档审核状态定义
|
||||
enum DocumentAuditStatus {
|
||||
FAIL = -1,
|
||||
WAITING = 0,
|
||||
PASS = 1,
|
||||
WARNING = 2,
|
||||
PROCESSING = 3
|
||||
}
|
||||
|
||||
// 文档状态对应的中文标签
|
||||
const STATUS_LABELS: Record<DocumentStatus, string> = {
|
||||
[DocumentStatus.WAITING]: "待审核",
|
||||
[DocumentStatus.PROCESSING]: "审核中",
|
||||
[DocumentStatus.PASS]: "通过",
|
||||
[DocumentStatus.WARNING]: "警告",
|
||||
[DocumentStatus.FAIL]: "不通过"
|
||||
const STATUS_LABELS: Record<DocumentAuditStatus, string> = {
|
||||
[DocumentAuditStatus.FAIL]: "不通过",
|
||||
[DocumentAuditStatus.WAITING]: "待审核",
|
||||
[DocumentAuditStatus.PASS]: "通过",
|
||||
[DocumentAuditStatus.WARNING]: "警告",
|
||||
[DocumentAuditStatus.PROCESSING]: "审核中"
|
||||
};
|
||||
|
||||
// 文档状态样式配置
|
||||
const STATUS_STYLES: Record<number, { color: string; icon: string }> = {
|
||||
[-1]: { color: "red", icon: "ri-close-line" },
|
||||
[0]: { color: "blue", icon: "ri-time-line" },
|
||||
[1]: { color: "green", icon: "ri-check-line" },
|
||||
[2]: { color: "yellow", icon: "ri-alert-line" },
|
||||
[3]: { color: "purple", icon: "ri-search-line" }
|
||||
};
|
||||
|
||||
// 格式化文件大小
|
||||
@@ -99,31 +108,31 @@ export async function action({ request }: ActionFunctionArgs) {
|
||||
// 从表单数据中提取字段
|
||||
const type = formData.get("type_id") as string;
|
||||
const documentNumber = formData.get("document_number") as string;
|
||||
const status = formData.get("status") as DocumentStatus;
|
||||
const auditStatus = parseInt(formData.get("audit_status") as string);
|
||||
const isTest = formData.get("is_test_document") === "on";
|
||||
const remark = formData.get("remark") as string;
|
||||
|
||||
// 验证必填字段
|
||||
if (!type || !status) {
|
||||
if (!type || auditStatus === undefined || isNaN(auditStatus)) {
|
||||
return Response.json(
|
||||
{
|
||||
error: "缺少必填字段",
|
||||
fieldErrors: {
|
||||
type_id: !type ? "文档类型不能为空" : null,
|
||||
status: !status ? "状态不能为空" : null
|
||||
audit_status: (auditStatus === undefined || isNaN(auditStatus)) ? "审核状态不能为空" : null
|
||||
}
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
console.log('提交更新:', { type, documentNumber, status, isTest, remark });
|
||||
console.log('提交更新:', { type, documentNumber, auditStatus, isTest, remark });
|
||||
|
||||
// 更新文档
|
||||
const updateResponse = await updateDocument(id, {
|
||||
type,
|
||||
documentNumber,
|
||||
status,
|
||||
auditStatus,
|
||||
isTest,
|
||||
remark
|
||||
});
|
||||
@@ -160,43 +169,38 @@ export default function DocumentEdit() {
|
||||
}
|
||||
|
||||
// 状态
|
||||
const [localStatus, setLocalStatus] = useState<DocumentStatus>(document.status as DocumentStatus);
|
||||
const [localStatus, setLocalStatus] = useState<number>(document.auditStatus);
|
||||
|
||||
// 处理状态变更
|
||||
const handleStatusChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
setLocalStatus(e.target.value as DocumentStatus);
|
||||
setLocalStatus(parseInt(e.target.value));
|
||||
};
|
||||
|
||||
// 获取文档类型名称
|
||||
const getDocumentTypeName = (typeId: string): string => {
|
||||
const docType = documentTypes.find((type) => (type as any).id.toString() === typeId);
|
||||
return docType ? (docType as any).name : "未知类型";
|
||||
const docType = documentTypes.find((type: DocType) => type.id.toString() === typeId);
|
||||
return docType ? docType.name : "未知类型";
|
||||
};
|
||||
|
||||
// 渲染状态徽章
|
||||
const renderStatusBadge = (status: string) => {
|
||||
const statusClasses: Record<string, string> = {
|
||||
"waiting": "status-badge status-pending",
|
||||
"processing": "status-badge status-processing",
|
||||
"pass": "status-badge status-pass",
|
||||
"warning": "status-badge status-warning",
|
||||
"fail": "status-badge status-fail"
|
||||
};
|
||||
|
||||
const statusLabel: Record<string, string> = {
|
||||
"waiting": "待审核",
|
||||
"processing": "审核中",
|
||||
"pass": "通过",
|
||||
"warning": "警告",
|
||||
"fail": "不通过"
|
||||
};
|
||||
const renderStatusBadge = (status: number) => {
|
||||
const style = STATUS_STYLES[status] || STATUS_STYLES[0];
|
||||
const label = STATUS_LABELS[status as DocumentAuditStatus] || STATUS_LABELS[DocumentAuditStatus.WAITING];
|
||||
|
||||
return (
|
||||
<span className={statusClasses[status] || "status-badge"}>
|
||||
{statusLabel[status] || status}
|
||||
<span className={`status-badge bg-${style.color}-100 text-${style.color}-800`}>
|
||||
<i className={`${style.icon} mr-1`}></i>
|
||||
{label}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
// 在新窗口打开文档预览
|
||||
const openPreview = () => {
|
||||
// 假设有一个预览URL的格式,比如 /preview?path=xxx
|
||||
const previewUrl = `/preview?path=${encodeURIComponent(document.path)}&name=${encodeURIComponent(document.name)}`;
|
||||
window.open(previewUrl, '_blank');
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="document-edit-page">
|
||||
@@ -250,7 +254,7 @@ export default function DocumentEdit() {
|
||||
<span>{formatFileSize(document.size)}</span>
|
||||
</div>
|
||||
<div className="meta-item">
|
||||
{renderStatusBadge(document.status)}
|
||||
{renderStatusBadge(document.auditStatus)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -271,7 +275,7 @@ export default function DocumentEdit() {
|
||||
defaultValue={document.type}
|
||||
required
|
||||
>
|
||||
{documentTypes.map(type => (
|
||||
{documentTypes.map((type: DocType) => (
|
||||
<option key={type.id} value={type.id}>{type.name}</option>
|
||||
))}
|
||||
</select>
|
||||
@@ -295,24 +299,24 @@ export default function DocumentEdit() {
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="status" className="form-label">状态 <span className="text-red-500">*</span></label>
|
||||
<label htmlFor="audit-status" className="form-label">审核状态 <span className="text-red-500">*</span></label>
|
||||
<select
|
||||
id="status"
|
||||
name="status"
|
||||
id="audit-status"
|
||||
name="audit_status"
|
||||
className="form-select"
|
||||
value={localStatus}
|
||||
onChange={handleStatusChange}
|
||||
required
|
||||
>
|
||||
<option value={DocumentStatus.WAITING}>{STATUS_LABELS[DocumentStatus.WAITING]}</option>
|
||||
<option value={DocumentStatus.PROCESSING}>{STATUS_LABELS[DocumentStatus.PROCESSING]}</option>
|
||||
<option value={DocumentStatus.PASS}>{STATUS_LABELS[DocumentStatus.PASS]}</option>
|
||||
<option value={DocumentStatus.WARNING}>{STATUS_LABELS[DocumentStatus.WARNING]}</option>
|
||||
<option value={DocumentStatus.FAIL}>{STATUS_LABELS[DocumentStatus.FAIL]}</option>
|
||||
<option value={DocumentAuditStatus.WAITING}>{STATUS_LABELS[DocumentAuditStatus.WAITING]}</option>
|
||||
<option value={DocumentAuditStatus.PROCESSING}>{STATUS_LABELS[DocumentAuditStatus.PROCESSING]}</option>
|
||||
<option value={DocumentAuditStatus.PASS}>{STATUS_LABELS[DocumentAuditStatus.PASS]}</option>
|
||||
<option value={DocumentAuditStatus.WARNING}>{STATUS_LABELS[DocumentAuditStatus.WARNING]}</option>
|
||||
<option value={DocumentAuditStatus.FAIL}>{STATUS_LABELS[DocumentAuditStatus.FAIL]}</option>
|
||||
</select>
|
||||
<div className="text-sm text-secondary mt-1">更改状态可能会影响此文档在列表中的显示和排序</div>
|
||||
{actionData?.fieldErrors?.status && (
|
||||
<div className="text-red-500 text-sm mt-1">{actionData.fieldErrors.status}</div>
|
||||
{actionData?.fieldErrors?.audit_status && (
|
||||
<div className="text-red-500 text-sm mt-1">{actionData.fieldErrors.audit_status}</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -356,7 +360,7 @@ export default function DocumentEdit() {
|
||||
<div className="document-preview">
|
||||
<div className="preview-toolbar">
|
||||
<div className="flex items-center">
|
||||
<i className="ri-file-pdf-line text-red-500 mr-1"></i>
|
||||
<i className={`ri-file-${document.fileType}-line text-${document.fileType === 'pdf' ? 'red' : 'blue'}-500 mr-1`}></i>
|
||||
<span>{document.name}</span>
|
||||
</div>
|
||||
<div>
|
||||
@@ -364,21 +368,31 @@ export default function DocumentEdit() {
|
||||
type="default"
|
||||
size="small"
|
||||
icon="ri-download-line"
|
||||
className="mr-2"
|
||||
>
|
||||
下载
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
size="small"
|
||||
icon="ri-external-link-line"
|
||||
onClick={openPreview}
|
||||
>
|
||||
在新窗口打开
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="preview-content">
|
||||
<div className="preview-placeholder">
|
||||
<i className="ri-file-pdf-line"></i>
|
||||
<i className={`ri-file-${document.fileType}-line`}></i>
|
||||
<p>预览功能暂不可用</p>
|
||||
<p className="text-xs mt-2">PDF文件需要外部查看器支持</p>
|
||||
<p className="text-xs mt-2">点击"在新窗口打开"查看完整文档</p>
|
||||
<Button
|
||||
type="primary"
|
||||
size="small"
|
||||
icon="ri-external-link-line"
|
||||
className="mt-4"
|
||||
onClick={openPreview}
|
||||
>
|
||||
在新窗口打开
|
||||
</Button>
|
||||
@@ -388,7 +402,7 @@ export default function DocumentEdit() {
|
||||
</Card>
|
||||
|
||||
{/* 修改历史 */}
|
||||
<Card title="修改历史">
|
||||
<Card title="修改历史" className="hidden">
|
||||
<div className="history-timeline">
|
||||
{[
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user