From 75dbf22a4360485092f49e8f3e474d19c736e268 Mon Sep 17 00:00:00 2001 From: jeremygan2021 Date: Tue, 17 Mar 2026 22:22:58 +0800 Subject: [PATCH] new --- miniprogram/src/pages/competition/detail.tsx | 24 ++++++++++++++- miniprogram/src/pages/competition/index.tsx | 22 +++++++++++++- .../src/pages/competition/project-detail.tsx | 27 ++++++++++++++++- miniprogram/src/pages/competition/project.tsx | 29 ++++++++++++++++++- .../src/subpackages/forum/activity/detail.tsx | 13 +++++++-- 5 files changed, 109 insertions(+), 6 deletions(-) diff --git a/miniprogram/src/pages/competition/detail.tsx b/miniprogram/src/pages/competition/detail.tsx index 45f5d88..72e36f6 100644 --- a/miniprogram/src/pages/competition/detail.tsx +++ b/miniprogram/src/pages/competition/detail.tsx @@ -1,5 +1,5 @@ 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 { getCompetitionDetail, enrollCompetition, getMyCompetitionEnrollment, getProjects } from '../../api' 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) => { setLoading(true) try { diff --git a/miniprogram/src/pages/competition/index.tsx b/miniprogram/src/pages/competition/index.tsx index acfa3f2..75e7edf 100644 --- a/miniprogram/src/pages/competition/index.tsx +++ b/miniprogram/src/pages/competition/index.tsx @@ -1,5 +1,5 @@ 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 { getCompetitions } from '../../api' import './index.scss' @@ -13,6 +13,26 @@ export default function CompetitionList() { fetchCompetitions() }) + /** + * 配置并监听分享给朋友的功能 + */ + useShareAppMessage(() => { + return { + title: '赛事中心', + path: '/pages/competition/index' + } + }) + + /** + * 配置并监听分享到朋友圈的功能 + */ + useShareTimeline(() => { + return { + title: '赛事中心', + query: '' + } + }) + const fetchCompetitions = async () => { setLoading(true) setDebugMsg('开始加载...') diff --git a/miniprogram/src/pages/competition/project-detail.tsx b/miniprogram/src/pages/competition/project-detail.tsx index 87e1a12..78a249c 100644 --- a/miniprogram/src/pages/competition/project-detail.tsx +++ b/miniprogram/src/pages/competition/project-detail.tsx @@ -1,5 +1,5 @@ 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 { getProjectDetail, getComments } from '../../api' import MarkdownReader from '../../components/MarkdownReader' @@ -9,6 +9,7 @@ export default function ProjectDetail() { const [project, setProject] = useState(null) const [comments, setComments] = useState([]) const [loading, setLoading] = useState(false) + const router = useRouter() useLoad((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 diff --git a/miniprogram/src/pages/competition/project.tsx b/miniprogram/src/pages/competition/project.tsx index 2ae2ad8..87a6ec7 100644 --- a/miniprogram/src/pages/competition/project.tsx +++ b/miniprogram/src/pages/competition/project.tsx @@ -1,5 +1,5 @@ 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 { getProjectDetail, createProject, updateProject, uploadProjectFile, submitProject, uploadMedia, getCompetitions } from '../../api' import './project.scss' @@ -15,6 +15,7 @@ export default function ProjectEdit() { const [competitions, setCompetitions] = useState([]) const [loading, setLoading] = useState(false) const [isEdit, setIsEdit] = useState(false) + const router = useRouter() useLoad((options) => { 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 () => { try { const res = await getCompetitions() diff --git a/miniprogram/src/subpackages/forum/activity/detail.tsx b/miniprogram/src/subpackages/forum/activity/detail.tsx index b61252b..736d75c 100644 --- a/miniprogram/src/subpackages/forum/activity/detail.tsx +++ b/miniprogram/src/subpackages/forum/activity/detail.tsx @@ -115,11 +115,19 @@ const ActivityDetail = () => { } } + /** + * 处理表单字段内容改变的事件 + * 必须返回最新的 value,以修复 Taro UI 中 AtInput 光标会跑到最前面的 Bug + * @param {string} fieldName - 表单字段名 + * @param {any} value - 表单输入的最新的值 + * @returns {any} 返回最新的值 + */ const handleFormChange = (fieldName, value) => { setFormData(prev => ({ ...prev, [fieldName]: value })) + return value // 修复 Taro UI AtInput 光标跳动问题:必须返回 value } const handleModalConfirm = () => { @@ -267,7 +275,8 @@ const ActivityDetail = () => { 填写报名信息 - {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 if (!field || typeof field !== 'object' || field.label === '自定义报名配置') return null @@ -357,7 +366,7 @@ const ActivityDetail = () => { title={field.label} type={field.type === 'tel' ? 'phone' : (field.type === 'number' ? 'number' : 'text')} placeholder={field.placeholder || `请输入${field.label}`} - value={formData[field.name]} + value={formData[field.name] || ''} onChange={(val) => handleFormChange(field.name, val)} required={field.required} />