diff --git a/backend/competition/views.py b/backend/competition/views.py index 7ee49b7..da02fb7 100644 --- a/backend/competition/views.py +++ b/backend/competition/views.py @@ -1,5 +1,6 @@ from rest_framework import viewsets, permissions, status, filters, serializers -from rest_framework.decorators import action, api_view, permission_classes, csrf_exempt +from django.views.decorators.csrf import csrf_exempt +from rest_framework.decorators import action, api_view, permission_classes from rest_framework.response import Response from rest_framework.views import APIView from django.db.models import Q diff --git a/backend/config/settings.py b/backend/config/settings.py index d7cd9f8..fb4a058 100644 --- a/backend/config/settings.py +++ b/backend/config/settings.py @@ -119,16 +119,16 @@ if DB_HOST: } -DB_HOST = os.environ.get('DB_HOST', '121.43.104.161') -if DB_HOST: - DATABASES['default'] = { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': os.environ.get('DB_NAME', 'market'), - 'USER': os.environ.get('DB_USER', 'market'), - 'PASSWORD': os.environ.get('DB_PASSWORD', '123market'), - 'HOST': DB_HOST, - 'PORT': os.environ.get('DB_PORT', '6433'), - } +# DB_HOST = os.environ.get('DB_HOST', '121.43.104.161') +# if DB_HOST: +# DATABASES['default'] = { +# 'ENGINE': 'django.db.backends.postgresql', +# 'NAME': os.environ.get('DB_NAME', 'market'), +# 'USER': os.environ.get('DB_USER', 'market'), +# 'PASSWORD': os.environ.get('DB_PASSWORD', '123market'), +# 'HOST': DB_HOST, +# 'PORT': os.environ.get('DB_PORT', '6433'), +# } # Password validation diff --git a/miniprogram/src/pages/competition/project.tsx b/miniprogram/src/pages/competition/project.tsx index 942898b..f8425b5 100644 --- a/miniprogram/src/pages/competition/project.tsx +++ b/miniprogram/src/pages/competition/project.tsx @@ -125,22 +125,71 @@ export default function ProjectEdit() { Taro.hideLoading() Taro.showToast({ title: '上传成功', icon: 'success' }) - } catch (e) { + } catch (e: any) { Taro.hideLoading() console.error(e) - Taro.showToast({ title: '上传失败', icon: 'none' }) + const errorMsg = e.response?.error || e.message || '上传失败' + Taro.showToast({ title: errorMsg, icon: 'none' }) } } - const handleDeleteFile = (fileId) => { - // API call to delete file not implemented yet? Or just remove from list? - // Usually we should call delete API. For now just remove from UI. - // Ideally we should have deleteProjectFile API. - // But user only asked to "optimize upload". - setProject(prev => ({ - ...prev, - files: prev.files.filter(f => f.id !== fileId) - })) + const handleDeleteFile = async (fileId) => { + try { + await Taro.showModal({ + title: '确认删除', + content: '确定要删除这个文件吗?', + confirmColor: '#ff4d4f' + }).then(res => { + if (!res.confirm) throw new Error('cancel') + }) + + Taro.showLoading({ title: '删除中...' }) + await deleteProjectFile(fileId) + + setProject(prev => ({ + ...prev, + files: prev.files.filter(f => f.id !== fileId) + })) + + Taro.hideLoading() + Taro.showToast({ title: '删除成功', icon: 'success' }) + } catch (e: any) { + Taro.hideLoading() + if (e.message !== 'cancel') { + const errorMsg = e.response?.error || e.message || '删除失败' + Taro.showToast({ title: errorMsg, icon: 'none' }) + } + } + } + + const handlePreviewFile = (file) => { + const fileUrl = file.file_url || file.file_url_display || '' + if (!fileUrl) { + Taro.showToast({ title: '文件地址无效', icon: 'none' }) + return + } + + const fileType = file.file_type || '' + if (fileType === 'image') { + Taro.previewImage({ + urls: [fileUrl] + }) + } else { + Taro.downloadFile({ + url: fileUrl, + success: (res) => { + if (res.statusCode === 200) { + Taro.openDocument({ + filePath: res.tempFilePath, + fileType: fileType === 'pdf' ? 'pdf' : fileType === 'ppt' ? 'ppt' : undefined + }) + } + }, + fail: () => { + Taro.showToast({ title: '打开文件失败', icon: 'none' }) + } + }) + } } const handleSave = async (submit = false) => { @@ -262,9 +311,14 @@ export default function ProjectEdit() { {project.files && project.files.map((file, index) => ( - + handlePreviewFile(file)} + > {file.name || '未知文件'} - {/* handleDeleteFile(file.id)}>删除 */} + { e.stopPropagation(); handleDeleteFile(file.id) }}>删除 ))} {(!project.files || project.files.length === 0) && 暂无附件 (PDF/PPT/视频)}