fix: 1. 全局axios添加formData文件上传的检测,删除Content-Type让axios自动检测。
2. 完善入口模块管理的接口的对接。 3. 完善角色权限管理的接口对接和测试。 4. 完善主页的入口模块的图标的显示和图片的显示。
This commit is contained in:
@@ -1,19 +1,18 @@
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import { useNavigate, useSearchParams, useLoaderData } from "@remix-run/react";
|
||||
import { ClientLoaderFunctionArgs, MetaFunction } from "@remix-run/react";
|
||||
import { useNavigate, useSearchParams, useLoaderData, ClientLoaderFunctionArgs, MetaFunction } from "@remix-run/react";
|
||||
import { Card } from "~/components/ui/Card";
|
||||
import { Button } from "~/components/ui/Button";
|
||||
import { toastService } from "~/components/ui/Toast";
|
||||
import { Modal } from "~/components/ui/Modal";
|
||||
import { usePermission } from "~/hooks/usePermission";
|
||||
import {
|
||||
getEntryModuleById,
|
||||
createEntryModule,
|
||||
updateEntryModule,
|
||||
uploadEntryModuleImage,
|
||||
type EntryModule,
|
||||
type AreaConfig
|
||||
} from "~/api/entry-modules/entry-modules";
|
||||
import { API_BASE_URL, DOCUMENT_URL } from "~/config/api-config";
|
||||
import { DOCUMENT_URL } from "~/config/api-config";
|
||||
import entryModulesStyles from "~/styles/pages/entry-modules.css?url";
|
||||
|
||||
// 引入CSS样式
|
||||
@@ -110,7 +109,6 @@ export default function EntryModuleNew() {
|
||||
module?.path ? `${DOCUMENT_URL}${module.path}` : null
|
||||
);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [showConfirmModal, setShowConfirmModal] = useState(false);
|
||||
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
@@ -185,48 +183,6 @@ export default function EntryModuleNew() {
|
||||
return true;
|
||||
};
|
||||
|
||||
// 上传logo图片
|
||||
const uploadLogo = async (): Promise<string | null> => {
|
||||
if (!logoFile) return module?.path || null;
|
||||
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append('file', logoFile);
|
||||
formData.append('folder', 'entryModule');
|
||||
|
||||
// ✅ 不需要手动添加 Authorization 头
|
||||
// fetch 可以自动使用浏览器的认证信息,或者我们也可以使用 axios
|
||||
const token = localStorage.getItem('access_token');
|
||||
|
||||
const response = await fetch(`${API_BASE_URL}/admin/upload`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
body: formData
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('图片上传失败');
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
console.log('图片上传结果:', result);
|
||||
|
||||
// 根据后端返回的数据结构提取路径
|
||||
if (result.data?.path) {
|
||||
return result.data.path;
|
||||
} else if (result.path) {
|
||||
return result.path;
|
||||
} else {
|
||||
throw new Error('未获取到图片路径');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('上传logo失败:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// 处理表单提交
|
||||
const handleSubmit = async () => {
|
||||
// ✅ Runtime permission check
|
||||
@@ -245,27 +201,26 @@ export default function EntryModuleNew() {
|
||||
setIsSubmitting(true);
|
||||
|
||||
try {
|
||||
// 上传logo
|
||||
let logoPath = module?.path || null;
|
||||
if (logoFile) {
|
||||
logoPath = await uploadLogo();
|
||||
}
|
||||
|
||||
// 🔑 准备提交数据
|
||||
// 🔑 步骤1: 先创建或更新模块(不包含图片上传)
|
||||
// areas 字段会在 API 层自动转换为 AreaConfig[] 格式
|
||||
const moduleData = {
|
||||
name: name.trim(),
|
||||
description: description.trim() || undefined,
|
||||
path: logoPath,
|
||||
// 创建时 path 为 null,编辑时保持原 path(图片上传接口会自动更新)
|
||||
path: isEditMode ? module?.path : null,
|
||||
areas: selectedAreas // 字符串数组,API会自动转换
|
||||
};
|
||||
|
||||
// ✅ 不需要传递 JWT,axios-client 会自动处理
|
||||
let result;
|
||||
let moduleId: number;
|
||||
|
||||
if (isEditMode) {
|
||||
result = await updateEntryModule(parseInt(id!), moduleData);
|
||||
moduleId = parseInt(id!);
|
||||
} else {
|
||||
result = await createEntryModule(moduleData);
|
||||
moduleId = result.data!.id!;
|
||||
}
|
||||
|
||||
if (result.error) {
|
||||
@@ -273,6 +228,19 @@ export default function EntryModuleNew() {
|
||||
return;
|
||||
}
|
||||
|
||||
// 🔑 步骤2: 如果有新的logo文件,调用专用的图片上传接口
|
||||
// 后端会自动更新数据库中的 path 字段,无需再手动调用 update
|
||||
if (logoFile) {
|
||||
const uploadResult = await uploadEntryModuleImage(moduleId, logoFile);
|
||||
|
||||
if (uploadResult.error) {
|
||||
toastService.error(`模块${isEditMode ? '更新' : '创建'}成功,但图片上传失败: ${uploadResult.error}`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('✅ 图片上传成功,访问URL:', uploadResult.data?.url);
|
||||
}
|
||||
|
||||
toastService.success(isEditMode ? '更新成功!' : '创建成功!');
|
||||
setTimeout(() => {
|
||||
navigate('/entry-modules');
|
||||
@@ -287,14 +255,10 @@ export default function EntryModuleNew() {
|
||||
|
||||
// 处理取消
|
||||
const handleCancel = () => {
|
||||
setShowConfirmModal(true);
|
||||
};
|
||||
|
||||
// 确认取消
|
||||
const confirmCancel = () => {
|
||||
navigate('/entry-modules');
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div className="entry-modules-new-page">
|
||||
<Card>
|
||||
@@ -429,33 +393,6 @@ export default function EntryModuleNew() {
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* 取消确认模态框 */}
|
||||
<Modal
|
||||
isOpen={showConfirmModal}
|
||||
onClose={() => setShowConfirmModal(false)}
|
||||
title="确认取消"
|
||||
size="small"
|
||||
footer={
|
||||
<div className="flex justify-end space-x-3">
|
||||
<Button
|
||||
type="default"
|
||||
onClick={() => setShowConfirmModal(false)}
|
||||
>
|
||||
继续编辑
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
danger
|
||||
onClick={confirmCancel}
|
||||
>
|
||||
确认取消
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<p className="text-gray-700">确定要取消吗?未保存的更改将丢失。</p>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user