比赛
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { View, Text, Button, Image, Input, Textarea } from '@tarojs/components'
|
||||
import { View, Text, Button, Image, Input, Textarea, Picker } from '@tarojs/components'
|
||||
import Taro, { useLoad } from '@tarojs/taro'
|
||||
import { useState } from 'react'
|
||||
import { getProjectDetail, createProject, updateProject, uploadProjectFile, submitProject, uploadMedia } from '../../api'
|
||||
import { getProjectDetail, createProject, updateProject, uploadProjectFile, submitProject, uploadMedia, getCompetitions } from '../../api'
|
||||
import './project.scss'
|
||||
|
||||
export default function ProjectEdit() {
|
||||
@@ -12,10 +12,12 @@ export default function ProjectEdit() {
|
||||
files: []
|
||||
})
|
||||
const [competitionId, setCompetitionId] = useState<string>('')
|
||||
const [competitions, setCompetitions] = useState<any[]>([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [isEdit, setIsEdit] = useState(false)
|
||||
|
||||
useLoad((options) => {
|
||||
fetchCompetitions()
|
||||
const { id, competitionId } = options
|
||||
if (id) {
|
||||
setIsEdit(true)
|
||||
@@ -25,6 +27,17 @@ export default function ProjectEdit() {
|
||||
}
|
||||
})
|
||||
|
||||
const fetchCompetitions = async () => {
|
||||
try {
|
||||
const res = await getCompetitions()
|
||||
if (res && res.results) {
|
||||
setCompetitions(res.results)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取比赛列表失败', e)
|
||||
}
|
||||
}
|
||||
|
||||
const fetchProject = async (id) => {
|
||||
setLoading(true)
|
||||
try {
|
||||
@@ -59,6 +72,49 @@ export default function ProjectEdit() {
|
||||
}
|
||||
}
|
||||
|
||||
const handleUploadFile = async () => {
|
||||
if (!project.id) {
|
||||
Taro.showToast({ title: '请先保存草稿再上传附件', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await Taro.chooseMessageFile({ count: 1, type: 'file' })
|
||||
const tempFiles = res.tempFiles
|
||||
if (!tempFiles.length) return
|
||||
|
||||
Taro.showLoading({ title: '上传中...' })
|
||||
const file = tempFiles[0]
|
||||
|
||||
// @ts-ignore
|
||||
const result = await uploadProjectFile(file.path, project.id, file.name)
|
||||
|
||||
// Update file list
|
||||
setProject(prev => ({
|
||||
...prev,
|
||||
files: [...(prev.files || []), result]
|
||||
}))
|
||||
|
||||
Taro.hideLoading()
|
||||
Taro.showToast({ title: '上传成功', icon: 'success' })
|
||||
} catch (e) {
|
||||
Taro.hideLoading()
|
||||
console.error(e)
|
||||
Taro.showToast({ title: '上传失败', 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 handleSave = async (submit = false) => {
|
||||
if (!project.title) {
|
||||
Taro.showToast({ title: '请输入项目标题', icon: 'none' })
|
||||
@@ -105,6 +161,26 @@ export default function ProjectEdit() {
|
||||
|
||||
return (
|
||||
<View className='project-edit'>
|
||||
<View className='form-item'>
|
||||
<Text className='label'>所属比赛</Text>
|
||||
<Picker
|
||||
mode='selector'
|
||||
range={competitions}
|
||||
rangeKey='title'
|
||||
onChange={e => {
|
||||
const idx = Number(e.detail.value)
|
||||
const selected = competitions[idx]
|
||||
if (selected) {
|
||||
setCompetitionId(String(selected.id))
|
||||
}
|
||||
}}
|
||||
>
|
||||
<View className='picker'>
|
||||
{competitions.find(c => String(c.id) === String(competitionId))?.title || '请选择比赛'}
|
||||
</View>
|
||||
</Picker>
|
||||
</View>
|
||||
|
||||
<View className='form-item'>
|
||||
<Text className='label'>项目标题</Text>
|
||||
<Input
|
||||
@@ -151,7 +227,21 @@ export default function ProjectEdit() {
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* 附件列表略,暂不支持上传非图片附件 */}
|
||||
<View className='form-item'>
|
||||
<View className='label-row' style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '10px' }}>
|
||||
<Text className='label' style={{ marginBottom: 0 }}>项目附件</Text>
|
||||
<Button size='mini' style={{ margin: 0, fontSize: '12px' }} onClick={handleUploadFile}>上传附件</Button>
|
||||
</View>
|
||||
<View className='file-list'>
|
||||
{project.files && project.files.map((file, index) => (
|
||||
<View key={index} className='file-item' style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '10px', background: '#f8f8f8', marginBottom: '8px', borderRadius: '4px' }}>
|
||||
<Text className='file-name' style={{ flex: 1, fontSize: '14px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{file.name || '未知文件'}</Text>
|
||||
{/* <Text className='delete' style={{ color: 'red', marginLeft: '10px' }} onClick={() => handleDeleteFile(file.id)}>删除</Text> */}
|
||||
</View>
|
||||
))}
|
||||
{(!project.files || project.files.length === 0) && <Text style={{ color: '#999', fontSize: '12px' }}>暂无附件 (PDF/PPT/视频)</Text>}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className='footer-btns'>
|
||||
<Button className='btn save' onClick={() => handleSave(false)}>保存草稿</Button>
|
||||
|
||||
Reference in New Issue
Block a user