new
All checks were successful
Deploy to Server / deploy (push) Successful in 17s

This commit is contained in:
jeremygan2021
2026-03-17 22:22:58 +08:00
parent 7695ac3edf
commit 75dbf22a43
5 changed files with 109 additions and 6 deletions

View File

@@ -1,5 +1,5 @@
import { View, Text, Button, Image, ScrollView } from '@tarojs/components' import { View, Text, Button, Image, ScrollView } from '@tarojs/components'
import Taro, { useLoad, useDidShow } from '@tarojs/taro' import Taro, { useLoad, useDidShow, useShareAppMessage, useShareTimeline } from '@tarojs/taro'
import { useState, useEffect } from 'react' import { useState, useEffect } from 'react'
import { getCompetitionDetail, enrollCompetition, getMyCompetitionEnrollment, getProjects } from '../../api' import { getCompetitionDetail, enrollCompetition, getMyCompetitionEnrollment, getProjects } from '../../api'
import MarkdownReader from '../../components/MarkdownReader' import MarkdownReader from '../../components/MarkdownReader'
@@ -29,6 +29,28 @@ export default function CompetitionDetail() {
} }
}) })
/**
* 配置并监听分享给朋友的功能
*/
useShareAppMessage(() => {
return {
title: detail?.title || '赛事详情',
path: `/pages/competition/detail?id=${detail?.id || ''}`,
imageUrl: detail?.display_cover_image || ''
}
})
/**
* 配置并监听分享到朋友圈的功能
*/
useShareTimeline(() => {
return {
title: detail?.title || '赛事详情',
query: `id=${detail?.id || ''}`,
imageUrl: detail?.display_cover_image || ''
}
})
const fetchDetail = async (id) => { const fetchDetail = async (id) => {
setLoading(true) setLoading(true)
try { try {

View File

@@ -1,5 +1,5 @@
import { View, Text, Image, ScrollView } from '@tarojs/components' import { View, Text, Image, ScrollView } from '@tarojs/components'
import Taro, { useLoad } from '@tarojs/taro' import Taro, { useLoad, useShareAppMessage, useShareTimeline } from '@tarojs/taro'
import { useState } from 'react' import { useState } from 'react'
import { getCompetitions } from '../../api' import { getCompetitions } from '../../api'
import './index.scss' import './index.scss'
@@ -13,6 +13,26 @@ export default function CompetitionList() {
fetchCompetitions() fetchCompetitions()
}) })
/**
* 配置并监听分享给朋友的功能
*/
useShareAppMessage(() => {
return {
title: '赛事中心',
path: '/pages/competition/index'
}
})
/**
* 配置并监听分享到朋友圈的功能
*/
useShareTimeline(() => {
return {
title: '赛事中心',
query: ''
}
})
const fetchCompetitions = async () => { const fetchCompetitions = async () => {
setLoading(true) setLoading(true)
setDebugMsg('开始加载...') setDebugMsg('开始加载...')

View File

@@ -1,5 +1,5 @@
import { View, Text, Image, Button, ScrollView } from '@tarojs/components' import { View, Text, Image, Button, ScrollView } from '@tarojs/components'
import Taro, { useLoad } from '@tarojs/taro' import Taro, { useLoad, useShareAppMessage, useShareTimeline, useRouter } from '@tarojs/taro'
import { useState } from 'react' import { useState } from 'react'
import { getProjectDetail, getComments } from '../../api' import { getProjectDetail, getComments } from '../../api'
import MarkdownReader from '../../components/MarkdownReader' import MarkdownReader from '../../components/MarkdownReader'
@@ -9,6 +9,7 @@ export default function ProjectDetail() {
const [project, setProject] = useState<any>(null) const [project, setProject] = useState<any>(null)
const [comments, setComments] = useState<any[]>([]) const [comments, setComments] = useState<any[]>([])
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const router = useRouter()
useLoad((options) => { useLoad((options) => {
const { id } = options const { id } = options
@@ -18,6 +19,30 @@ export default function ProjectDetail() {
} }
}) })
/**
* 配置并监听分享给朋友的功能
*/
useShareAppMessage(() => {
const id = project?.id || router.params.id || ''
return {
title: project?.title || '项目详情',
path: `/pages/competition/project-detail?id=${id}`,
imageUrl: project?.display_cover_image || project?.cover_image_url || ''
}
})
/**
* 配置并监听分享到朋友圈的功能
*/
useShareTimeline(() => {
const id = project?.id || router.params.id || ''
return {
title: project?.title || '项目详情',
query: `id=${id}`,
imageUrl: project?.display_cover_image || project?.cover_image_url || ''
}
})
/** /**
* 获取项目详情 * 获取项目详情
* @param id 项目ID * @param id 项目ID

View File

@@ -1,5 +1,5 @@
import { View, Text, Button, Image, Input, Textarea, Picker } from '@tarojs/components' import { View, Text, Button, Image, Input, Textarea, Picker } from '@tarojs/components'
import Taro, { useLoad } from '@tarojs/taro' import Taro, { useLoad, useShareAppMessage, useShareTimeline, useRouter } from '@tarojs/taro'
import { useState } from 'react' import { useState } from 'react'
import { getProjectDetail, createProject, updateProject, uploadProjectFile, submitProject, uploadMedia, getCompetitions } from '../../api' import { getProjectDetail, createProject, updateProject, uploadProjectFile, submitProject, uploadMedia, getCompetitions } from '../../api'
import './project.scss' import './project.scss'
@@ -15,6 +15,7 @@ export default function ProjectEdit() {
const [competitions, setCompetitions] = useState<any[]>([]) const [competitions, setCompetitions] = useState<any[]>([])
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [isEdit, setIsEdit] = useState(false) const [isEdit, setIsEdit] = useState(false)
const router = useRouter()
useLoad((options) => { useLoad((options) => {
fetchCompetitions() fetchCompetitions()
@@ -27,6 +28,32 @@ export default function ProjectEdit() {
} }
}) })
/**
* 配置并监听分享给朋友的功能
*/
useShareAppMessage(() => {
const id = project?.id || router.params.id || ''
const compId = competitionId || router.params.competitionId || ''
return {
title: project?.title || '提交作品',
path: `/pages/competition/project?id=${id}&competitionId=${compId}`,
imageUrl: project?.cover_image_url || project?.display_cover_image || ''
}
})
/**
* 配置并监听分享到朋友圈的功能
*/
useShareTimeline(() => {
const id = project?.id || router.params.id || ''
const compId = competitionId || router.params.competitionId || ''
return {
title: project?.title || '提交作品',
query: `id=${id}&competitionId=${compId}`,
imageUrl: project?.cover_image_url || project?.display_cover_image || ''
}
})
const fetchCompetitions = async () => { const fetchCompetitions = async () => {
try { try {
const res = await getCompetitions() const res = await getCompetitions()

View File

@@ -115,11 +115,19 @@ const ActivityDetail = () => {
} }
} }
/**
* 处理表单字段内容改变的事件
* 必须返回最新的 value以修复 Taro UI 中 AtInput 光标会跑到最前面的 Bug
* @param {string} fieldName - 表单字段名
* @param {any} value - 表单输入的最新的值
* @returns {any} 返回最新的值
*/
const handleFormChange = (fieldName, value) => { const handleFormChange = (fieldName, value) => {
setFormData(prev => ({ setFormData(prev => ({
...prev, ...prev,
[fieldName]: value [fieldName]: value
})) }))
return value // 修复 Taro UI AtInput 光标跳动问题:必须返回 value
} }
const handleModalConfirm = () => { const handleModalConfirm = () => {
@@ -267,7 +275,8 @@ const ActivityDetail = () => {
<AtModalHeader></AtModalHeader> <AtModalHeader></AtModalHeader>
<AtModalContent> <AtModalContent>
<View className='signup-form'> <View className='signup-form'>
{activity.signup_form_config && Array.isArray(activity.signup_form_config) && activity.signup_form_config.map((field, idx) => { {/* 修复小程序原生组件穿透问题:只在 modal 打开时渲染输入组件 */}
{showSignupModal && activity.signup_form_config && Array.isArray(activity.signup_form_config) && activity.signup_form_config.map((field, idx) => {
// Defensive programming: skip invalid fields or known bad data // Defensive programming: skip invalid fields or known bad data
if (!field || typeof field !== 'object' || field.label === '自定义报名配置') return null if (!field || typeof field !== 'object' || field.label === '自定义报名配置') return null
@@ -357,7 +366,7 @@ const ActivityDetail = () => {
title={field.label} title={field.label}
type={field.type === 'tel' ? 'phone' : (field.type === 'number' ? 'number' : 'text')} type={field.type === 'tel' ? 'phone' : (field.type === 'number' ? 'number' : 'text')}
placeholder={field.placeholder || `请输入${field.label}`} placeholder={field.placeholder || `请输入${field.label}`}
value={formData[field.name]} value={formData[field.name] || ''}
onChange={(val) => handleFormChange(field.name, val)} onChange={(val) => handleFormChange(field.name, val)}
required={field.required} required={field.required}
/> />