比赛
All checks were successful
Deploy to Server / deploy (push) Successful in 37s

This commit is contained in:
jeremygan2021
2026-03-10 13:47:28 +08:00
parent af763b1bee
commit 3d74ccc04f
9 changed files with 470 additions and 27 deletions

View File

@@ -0,0 +1,162 @@
import { View, Text, Button, Image, Input, Textarea } from '@tarojs/components'
import Taro, { useLoad } from '@tarojs/taro'
import { useState } from 'react'
import { getProjectDetail, createProject, updateProject, uploadProjectFile, submitProject, uploadMedia } from '../../api'
import './project.scss'
export default function ProjectEdit() {
const [project, setProject] = useState<any>({
title: '',
description: '',
team_info: '',
files: []
})
const [competitionId, setCompetitionId] = useState<string>('')
const [loading, setLoading] = useState(false)
const [isEdit, setIsEdit] = useState(false)
useLoad((options) => {
const { id, competitionId } = options
if (id) {
setIsEdit(true)
fetchProject(id)
} else if (competitionId) {
setCompetitionId(competitionId)
}
})
const fetchProject = async (id) => {
setLoading(true)
try {
const res = await getProjectDetail(id)
setProject(res)
setCompetitionId(res.competition)
} catch (e) {
Taro.showToast({ title: '加载项目失败', icon: 'none' })
} finally {
setLoading(false)
}
}
const handleInput = (key, value) => {
setProject(prev => ({ ...prev, [key]: value }))
}
const handleUploadCover = async () => {
try {
const { tempFilePaths } = await Taro.chooseImage({ count: 1 })
if (!tempFilePaths.length) return
Taro.showLoading({ title: '上传中...' })
const res = await uploadMedia(tempFilePaths[0], 'image')
handleInput('cover_image_url', res.file) // 假设返回 { file: 'url...' }
Taro.hideLoading()
} catch (e) {
Taro.hideLoading()
Taro.showToast({ title: '上传失败', icon: 'none' })
}
}
const handleSave = async (submit = false) => {
if (!project.title) {
Taro.showToast({ title: '请输入项目标题', icon: 'none' })
return
}
setLoading(true)
try {
const data = {
competition: competitionId,
title: project.title,
description: project.description,
team_info: project.team_info,
cover_image_url: project.cover_image_url
}
let res
if (isEdit) {
res = await updateProject(project.id, data)
} else {
res = await createProject(data)
}
if (submit) {
await submitProject(res.id)
Taro.showToast({ title: '提交成功', icon: 'success' })
setTimeout(() => Taro.navigateBack(), 1500)
} else {
Taro.showToast({ title: '保存成功', icon: 'success' })
if (!isEdit) {
// 创建变编辑
setIsEdit(true)
setProject(res)
}
}
} catch (e) {
Taro.showToast({ title: e.message || '操作失败', icon: 'none' })
} finally {
setLoading(false)
}
}
if (loading && !project.id && isEdit) return <View className='loading'>...</View>
return (
<View className='project-edit'>
<View className='form-item'>
<Text className='label'></Text>
<Input
className='input'
placeholder='请输入项目标题'
value={project.title}
onInput={e => handleInput('title', e.detail.value)}
/>
</View>
<View className='form-item'>
<Text className='label'></Text>
<View className='upload-box' onClick={handleUploadCover}>
{project.cover_image_url || project.display_cover_image ? (
<Image
className='preview'
mode='aspectFill'
src={project.cover_image_url || project.display_cover_image}
/>
) : (
<Text className='placeholder'></Text>
)}
</View>
</View>
<View className='form-item'>
<Text className='label'></Text>
<Textarea
className='textarea'
placeholder='请输入项目详细介绍'
value={project.description}
onInput={e => handleInput('description', e.detail.value)}
maxlength={2000}
/>
</View>
<View className='form-item'>
<Text className='label'></Text>
<Textarea
className='textarea small'
placeholder='请输入团队成员信息'
value={project.team_info}
onInput={e => handleInput('team_info', e.detail.value)}
/>
</View>
{/* 附件列表略,暂不支持上传非图片附件 */}
<View className='footer-btns'>
<Button className='btn save' onClick={() => handleSave(false)}>稿</Button>
<Button className='btn submit' onClick={() => handleSave(true)}></Button>
</View>
</View>
)
}