From 3714621173c606c4c58439ed8941100ce9ddea14 Mon Sep 17 00:00:00 2001
From: Codex Assistant <codex@example.com>
Date: 星期三, 05 十一月 2025 15:10:49 +0800
Subject: [PATCH] bug
---
wx/pages/judge/review.js | 124 ++++-
wx/pages/judge/review.wxss | 20
wx/pages/judge/review.wxml | 3
wx/pages/index/index.wxml | 14
backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerDetailService.java | 6
wx/pages/index/index.wxss | 78 +++
backend/src/main/java/com/rongyichuang/config/SecurityConfig.java | 1
web/src/utils/cos.ts | 484 ++++++++++++++-------
backend/src/main/java/com/rongyichuang/config/GraphQLConfig.java | 1
wx/pages/index/index.js | 179 +++++++
web/src/utils/appConfig.js | 77 ++-
backend/src/main/resources/graphql/player.graphqls | 11
wx/pages/registration/registration.js | 2
web/vite.config.ts | 15
web/src/views/next-list.vue | 11
wx/app.js | 25
backend/src/main/java/com/rongyichuang/activity/repository/ActivityRepository.java | 6
web/src/utils/cos-simple.ts | 192 +++++--
web/src/api/media.js | 3
wx/pages/index/index.json | 2
backend/src/main/java/com/rongyichuang/activity/service/ActivityService.java | 7
web/src/api/promotion.js | 28
backend/src/main/java/com/rongyichuang/player/api/PlayerGraphqlApi.java | 3
backend/src/main/java/com/rongyichuang/player/service/PromotionService.java | 28
wx/pages/profile/profile.js | 2
wx/app.json | 2
web/src/views/check-detail.vue | 5
backend/src/main/java/com/rongyichuang/auth/util/JwtUtil.java | 30 +
wx/pages/message/message.js | 5
29 files changed, 1,011 insertions(+), 353 deletions(-)
diff --git a/backend/src/main/java/com/rongyichuang/activity/repository/ActivityRepository.java b/backend/src/main/java/com/rongyichuang/activity/repository/ActivityRepository.java
index c2d9d43..306d039 100644
--- a/backend/src/main/java/com/rongyichuang/activity/repository/ActivityRepository.java
+++ b/backend/src/main/java/com/rongyichuang/activity/repository/ActivityRepository.java
@@ -19,8 +19,14 @@
Page<Activity> findByPidAndStateOrderByCreateTimeDesc(Long pid, int state, Pageable pageable);
+ Page<Activity> findByPidAndStateNotOrderByCreateTimeDesc(Long pid, int state, Pageable pageable);
+
+ Page<Activity> findByPidAndStateNotAndNameContainingOrderByCreateTimeDesc(Long pid, int state, String name, Pageable pageable);
+
List<Activity> findByPidAndStateOrderByCreateTimeAsc(Long pid, int state);
+ List<Activity> findByPidAndStateOrderByCreateTimeDesc(Long pid, int state);
+
List<Activity> findByStateOrderByPidAscNameAsc(int state);
@Query("SELECT a FROM Activity a WHERE a.pid = 0 ORDER BY a.createTime DESC")
diff --git a/backend/src/main/java/com/rongyichuang/activity/service/ActivityService.java b/backend/src/main/java/com/rongyichuang/activity/service/ActivityService.java
index 0a257b0..fb8b6e4 100644
--- a/backend/src/main/java/com/rongyichuang/activity/service/ActivityService.java
+++ b/backend/src/main/java/com/rongyichuang/activity/service/ActivityService.java
@@ -72,10 +72,11 @@
page = activityRepository.findByPidAndStateOrderByCreateTimeDesc(0L, state, pageable);
}
} else if (hasName) {
- page = activityRepository.findByPidAndNameContainingOrderByCreateTimeDesc(0L, name, pageable);
+ // 褰搒tate涓簄ull浣嗘湁鍚嶇О鎼滅储鏃讹紝闇�瑕佽繃婊ゆ帀宸插垹闄ょ殑姣旇禌锛坰tate != 0锛�
+ page = activityRepository.findByPidAndStateNotAndNameContainingOrderByCreateTimeDesc(0L, 0, name, pageable);
} else {
- // 鏌ヨ鎵�鏈変富娲诲姩锛坧id = 0锛�
- page = activityRepository.findByPidOrderByCreateTimeDesc(0L, pageable);
+ // 褰搒tate涓簄ull鏃讹紝鏌ヨ鎵�鏈夋湭鍒犻櫎鐨勪富娲诲姩锛坧id = 0 涓� state != 0锛�
+ page = activityRepository.findByPidAndStateNotOrderByCreateTimeDesc(0L, 0, pageable);
}
List<ActivityResponse> content = page.getContent().stream()
diff --git a/backend/src/main/java/com/rongyichuang/auth/util/JwtUtil.java b/backend/src/main/java/com/rongyichuang/auth/util/JwtUtil.java
index 489d0f8..6207646 100644
--- a/backend/src/main/java/com/rongyichuang/auth/util/JwtUtil.java
+++ b/backend/src/main/java/com/rongyichuang/auth/util/JwtUtil.java
@@ -8,6 +8,9 @@
import org.springframework.stereotype.Component;
import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
import java.util.Date;
/**
@@ -38,7 +41,7 @@
Date now = new Date();
Date expiryDate = new Date(now.getTime() + jwtExpiration);
- SecretKey key = Keys.hmacShaKeyFor(jwtSecret.getBytes());
+ SecretKey key = getSigningKey();
JwtBuilder builder = Jwts.builder()
.setSubject(userId.toString())
@@ -56,6 +59,29 @@
}
return builder.signWith(key, SignatureAlgorithm.HS256).compact();
+ }
+
+ /**
+ * 鏍规嵁閰嶇疆鐨勫瘑閽ョ敓鎴愭弧瓒� HMAC-SHA 瑕佹眰鐨勭鍚嶅瘑閽ワ細
+ * - 鑻ユ槑鏂囧瘑閽ラ暱搴︿笉瓒� 256 bit锛屼娇鐢� SHA-256 琛嶇敓涓� 256-bit
+ * - 淇濇寔瀵圭幇鏈� app.jwt.secret 鐨勫吋瀹癸紝涓嶄慨鏀归厤缃敭鍚嶆垨鍏跺畠閫昏緫
+ */
+ private SecretKey getSigningKey() {
+ try {
+ byte[] keyBytes = jwtSecret.getBytes(StandardCharsets.UTF_8);
+ if (keyBytes.length < 32) {
+ MessageDigest digest = MessageDigest.getInstance("SHA-256");
+ keyBytes = digest.digest(keyBytes);
+ }
+ if (keyBytes.length < 32) {
+ byte[] padded = new byte[32];
+ System.arraycopy(keyBytes, 0, padded, 0, Math.min(keyBytes.length, 32));
+ keyBytes = padded;
+ }
+ return new SecretKeySpec(keyBytes, "HmacSHA256");
+ } catch (Exception e) {
+ throw new RuntimeException("鍒濆鍖朖WT绛惧悕瀵嗛挜澶辫触", e);
+ }
}
/**
@@ -111,7 +137,7 @@
* 浠巘oken涓В鏋怌laims
*/
private Claims getClaimsFromToken(String token) {
- SecretKey key = Keys.hmacShaKeyFor(jwtSecret.getBytes());
+ SecretKey key = getSigningKey();
return Jwts.parserBuilder()
.setSigningKey(key)
.build()
diff --git a/backend/src/main/java/com/rongyichuang/config/GraphQLConfig.java b/backend/src/main/java/com/rongyichuang/config/GraphQLConfig.java
index 3eccde8..42eb94f 100644
--- a/backend/src/main/java/com/rongyichuang/config/GraphQLConfig.java
+++ b/backend/src/main/java/com/rongyichuang/config/GraphQLConfig.java
@@ -12,7 +12,6 @@
@Bean
public RuntimeWiringConfigurer runtimeWiringConfigurer() {
return wiringBuilder -> wiringBuilder
- .scalar(ExtendedScalars.GraphQLLong)
.scalar(longScalar());
}
diff --git a/backend/src/main/java/com/rongyichuang/config/SecurityConfig.java b/backend/src/main/java/com/rongyichuang/config/SecurityConfig.java
index 8101d60..0accc67 100644
--- a/backend/src/main/java/com/rongyichuang/config/SecurityConfig.java
+++ b/backend/src/main/java/com/rongyichuang/config/SecurityConfig.java
@@ -49,6 +49,7 @@
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/auth/**", "/actuator/**", "/test/**", "/cleanup/**").permitAll()
+ .requestMatchers("/api/health/**").permitAll() // 鍏佽鍋ュ悍妫�鏌ョ鐐硅闂�
.requestMatchers("/upload/**").permitAll()
.requestMatchers("/graphiql/**", "/graphql/**", "/api/graphql/**", "/api/graphiql/**").permitAll() // 鍏佽GraphQL鍜孏raphiQL璁块棶
.requestMatchers("/**/graphql", "/**/graphiql").permitAll() // 鏇村娉涚殑GraphQL璺緞鍖归厤
diff --git a/backend/src/main/java/com/rongyichuang/player/api/PlayerGraphqlApi.java b/backend/src/main/java/com/rongyichuang/player/api/PlayerGraphqlApi.java
index a58e054..67f728c 100644
--- a/backend/src/main/java/com/rongyichuang/player/api/PlayerGraphqlApi.java
+++ b/backend/src/main/java/com/rongyichuang/player/api/PlayerGraphqlApi.java
@@ -15,6 +15,7 @@
import com.rongyichuang.player.dto.response.PlayerRegistrationResponse;
import com.rongyichuang.player.dto.response.StageJudgeRatingDetailResponse;
import com.rongyichuang.player.dto.PromotionCompetitionResponse;
+import com.rongyichuang.player.dto.response.PromotionCompetitionPageResponse;
import com.rongyichuang.player.dto.CompetitionParticipantResponse;
import com.rongyichuang.player.dto.PromotionInput;
import com.rongyichuang.player.dto.PromotionResult;
@@ -285,7 +286,7 @@
* 鑾峰彇姣旇禌鏅嬬骇鍒楄〃
*/
@QueryMapping
- public List<PromotionCompetitionResponse> promotionCompetitions(
+ public PromotionCompetitionPageResponse promotionCompetitions(
@Argument String name,
@Argument Integer page,
@Argument Integer size) {
diff --git a/backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerDetailService.java b/backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerDetailService.java
index 1ab5cf0..df96807 100644
--- a/backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerDetailService.java
+++ b/backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerDetailService.java
@@ -158,9 +158,11 @@
}
Object birthdayObj = row.get("birthday");
- playerInfo.setBirthday(birthdayObj != null ?
+ playerInfo.setBirthday(birthdayObj != null ?
(birthdayObj instanceof java.sql.Date ? ((java.sql.Date) birthdayObj).toString() : birthdayObj.toString()) : null);
- playerInfo.setEducation(row.get("education") != null ? row.get("education").toString() : "");
+ Object educationObj = row.get("education");
+ log.info("璋冭瘯锛氫粠鏁版嵁搴撴煡璇㈠埌鐨別ducation鍊�: {}", educationObj);
+ playerInfo.setEducation(educationObj != null ? educationObj.toString() : "");
playerInfo.setIntroduction(row.get("introduction") != null ? row.get("introduction").toString() : "");
// 鏋勫缓鍖哄煙淇℃伅
diff --git a/backend/src/main/java/com/rongyichuang/player/service/PromotionService.java b/backend/src/main/java/com/rongyichuang/player/service/PromotionService.java
index 4ca32ea..e85c772 100644
--- a/backend/src/main/java/com/rongyichuang/player/service/PromotionService.java
+++ b/backend/src/main/java/com/rongyichuang/player/service/PromotionService.java
@@ -8,6 +8,7 @@
import com.rongyichuang.common.repository.MediaRepository;
import com.rongyichuang.message.service.MessageService;
import com.rongyichuang.player.dto.*;
+import com.rongyichuang.player.dto.response.PromotionCompetitionPageResponse;
import com.rongyichuang.player.entity.ActivityPlayer;
import com.rongyichuang.player.repository.ActivityPlayerRepository;
import org.springframework.beans.factory.annotation.Autowired;
@@ -45,11 +46,11 @@
/**
* 鑾峰彇姣旇禌鏅嬬骇鍒楄〃
*/
- public List<PromotionCompetitionResponse> getPromotionCompetitions(String name, Integer page, Integer size) {
- List<PromotionCompetitionResponse> result = new ArrayList<>();
+ public PromotionCompetitionPageResponse getPromotionCompetitions(String name, Integer page, Integer size) {
+ List<PromotionCompetitionResponse> allResults = new ArrayList<>();
// 鏌ヨ鎵�鏈夋湁鏁堢殑涓绘瘮璧涳紙pid = 0锛�
- List<Activity> competitions = activityRepository.findByPidAndStateOrderByCreateTimeAsc(0L, 1);
+ List<Activity> competitions = activityRepository.findByPidAndStateOrderByCreateTimeDesc(0L, 1);
// 濡傛灉鏈夊悕绉拌繃婊ゆ潯浠讹紝杩涜杩囨护
if (name != null && !name.trim().isEmpty()) {
@@ -60,7 +61,7 @@
// 涓烘瘡涓瘮璧涙煡璇㈠叾闃舵
for (Activity competition : competitions) {
- List<Activity> stages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(competition.getId(), 1);
+ List<Activity> stages = activityRepository.findByPidAndStateOrderByCreateTimeDesc(competition.getId(), 1);
for (Activity stage : stages) {
// 缁熻褰撳墠闃舵鐨勫弬璧涗汉鏁�
@@ -68,22 +69,27 @@
Integer currentCount = playerCountLong != null ? playerCountLong.intValue() : 0;
PromotionCompetitionResponse response = new PromotionCompetitionResponse(competition, stage, currentCount);
- result.add(response);
+ allResults.add(response);
}
}
- // 绠�鍗曞垎椤靛鐞嗭紙瀹為檯椤圭洰涓缓璁娇鐢ㄦ暟鎹簱鍒嗛〉锛�
+ // 璁$畻鎬绘暟
+ long totalElements = allResults.size();
+
+ // 鍒嗛〉澶勭悊
+ List<PromotionCompetitionResponse> pagedResults = allResults;
if (page != null && size != null && page > 0 && size > 0) {
int start = (page - 1) * size;
- int end = Math.min(start + size, result.size());
- if (start < result.size()) {
- result = result.subList(start, end);
+ int end = Math.min(start + size, allResults.size());
+ if (start < allResults.size()) {
+ pagedResults = allResults.subList(start, end);
} else {
- result = new ArrayList<>();
+ pagedResults = new ArrayList<>();
}
}
- return result;
+ // 杩斿洖鍒嗛〉鍝嶅簲瀵硅薄
+ return new PromotionCompetitionPageResponse(pagedResults, totalElements, page, size);
}
/**
diff --git a/backend/src/main/resources/graphql/player.graphqls b/backend/src/main/resources/graphql/player.graphqls
index ee07e45..373e6fe 100644
--- a/backend/src/main/resources/graphql/player.graphqls
+++ b/backend/src/main/resources/graphql/player.graphqls
@@ -24,7 +24,7 @@
# 寰俊绔幏鍙栭�夋墜鎶ュ悕鐘舵��
getPlayerRegistrationState(activityId: ID!): PlayerRegistrationResponse
# 鑾峰彇姣旇禌鏅嬬骇鍒楄〃
- promotionCompetitions(name: String, page: Int, size: Int): [PromotionCompetitionResponse!]!
+ promotionCompetitions(name: String, page: Int, size: Int): PromotionCompetitionPageResponse!
# 鑾峰彇鍙檵绾у弬璧涜�呭垪琛�
promotableParticipants(currentStageId: ID!): PromotableParticipantsResponse
}
@@ -310,6 +310,15 @@
state: Int
}
+# 姣旇禌鏅嬬骇鍒楄〃鍒嗛〉鍝嶅簲绫诲瀷
+type PromotionCompetitionPageResponse {
+ content: [PromotionCompetitionResponse!]!
+ totalElements: Long!
+ page: Int!
+ size: Int!
+ totalPages: Int!
+}
+
# 鍙檵绾у弬璧涜�呭垪琛ㄥ搷搴旂被鍨�
type PromotableParticipantsResponse {
participants: [PromotableParticipantResponse!]!
diff --git a/web/src/api/media.js b/web/src/api/media.js
index c351e39..91f522b 100644
--- a/web/src/api/media.js
+++ b/web/src/api/media.js
@@ -1,5 +1,6 @@
// 濯掍綋鏌ヨ API
import { graphqlRequest, API_CONFIG } from '../config/api.ts';
+import { serverUrl } from '../utils/appConfig.js';
const GRAPHQL_ENDPOINT = API_CONFIG.GRAPHQL_ENDPOINT;
@@ -80,7 +81,7 @@
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
- const response = await fetch('http://localhost:8080/api/upload/image', {
+ const response = await fetch(`${serverUrl}/api/upload/image`, {
method: 'POST',
headers: headers,
body: formData,
diff --git a/web/src/api/promotion.js b/web/src/api/promotion.js
index c2b315d..ff02737 100644
--- a/web/src/api/promotion.js
+++ b/web/src/api/promotion.js
@@ -4,17 +4,23 @@
const GET_PROMOTION_COMPETITIONS = `
query GetPromotionCompetitions($name: String, $page: Int, $size: Int) {
promotionCompetitions(name: $name, page: $page, size: $size) {
- id
- competitionId
- competitionName
- stageName
- maxParticipants
- currentCount
- status
- startTime
- endTime
- sortOrder
- state
+ content {
+ id
+ competitionId
+ competitionName
+ stageName
+ maxParticipants
+ currentCount
+ status
+ startTime
+ endTime
+ sortOrder
+ state
+ }
+ totalElements
+ page
+ size
+ totalPages
}
}
`
diff --git a/web/src/utils/appConfig.js b/web/src/utils/appConfig.js
index 5b47beb..72b8a12 100644
--- a/web/src/utils/appConfig.js
+++ b/web/src/utils/appConfig.js
@@ -1,25 +1,54 @@
-import { graphqlRequest } from '../config/api.ts';
-
-const GET_APP_CONFIG = `
- query AppConfig {
- appConfig {
- mediaBaseUrl
- }
- }
-`;
-
-export async function loadAppConfig() {
- try {
- const result = await graphqlRequest(GET_APP_CONFIG);
- const mediaBaseUrl = result.data?.appConfig?.mediaBaseUrl || '';
- // 浣滀负鍏ㄥ眬鍙橀噺鏆撮湶
- window.__APP_MEDIA_BASE_URL__ = mediaBaseUrl;
- return mediaBaseUrl;
- } catch (e) {
- // 濡傛灉GraphQL鏌ヨ澶辫触锛屼娇鐢ㄩ粯璁ら厤缃�
- console.warn('loadAppConfig failed, using default config:', e?.message || e);
- const defaultMediaBaseUrl = 'http://localhost:8080';
- window.__APP_MEDIA_BASE_URL__ = defaultMediaBaseUrl;
- return defaultMediaBaseUrl;
- }
+import { graphqlRequest } from '../config/api.ts';
+
+export const serverUrl =
+ (typeof window !== 'undefined' && window.__APP_SERVER_URL__) ||
+ (typeof import.meta !== 'undefined' && import.meta.env && import.meta.env.VITE_SERVER_URL) ||
+ 'http://139.155.104.10:8080';
+
+
+
+const GET_APP_CONFIG = `
+
+ query AppConfig {
+
+ appConfig {
+
+ mediaBaseUrl
+
+ }
+
+ }
+
+`;
+
+
+
+export async function loadAppConfig() {
+
+ try {
+
+ const result = await graphqlRequest(GET_APP_CONFIG);
+
+ const mediaBaseUrl = result.data?.appConfig?.mediaBaseUrl || '';
+
+ // 浣滀负鍏ㄥ眬鍙橀噺鏆撮湶
+
+ window.__APP_MEDIA_BASE_URL__ = mediaBaseUrl;
+
+ return mediaBaseUrl;
+
+ } catch (e) {
+
+ // 濡傛灉GraphQL鏌ヨ澶辫触锛屼娇鐢ㄩ粯璁ら厤缃�
+
+ console.warn('loadAppConfig failed, using default config:', e?.message || e);
+
+ const defaultMediaBaseUrl = serverUrl;
+
+ window.__APP_MEDIA_BASE_URL__ = defaultMediaBaseUrl;
+
+ return defaultMediaBaseUrl;
+
+ }
+
}
\ No newline at end of file
diff --git a/web/src/utils/cos-simple.ts b/web/src/utils/cos-simple.ts
index 6f3e835..76fc4a5 100644
--- a/web/src/utils/cos-simple.ts
+++ b/web/src/utils/cos-simple.ts
@@ -1,65 +1,129 @@
-import axios from 'axios'
-
-// GraphQL鏌ヨ鑾峰彇涓婁紶鍑瘉
-const GET_UPLOAD_CREDENTIALS = `
- query GetUploadCredentials {
- getUploadCredentials {
- bucket
- region
- key
- presignedUrl
- expiration
- }
- }
-`
-
-// 浠庡悗绔疓raphQL鑾峰彇涓婁紶鍑瘉
-const getUploadCredentials = async () => {
- try {
- const response = await axios.post('http://localhost:8080/graphql', {
- query: GET_UPLOAD_CREDENTIALS
- })
-
- if (response.data.errors) {
- throw new Error(response.data.errors[0].message)
- }
-
- return response.data.data.getUploadCredentials
- } catch (error) {
- console.error('鑾峰彇涓婁紶鍑瘉澶辫触:', error)
- throw error
- }
-}
-
-/**
- * 浣跨敤棰勭鍚峌RL涓婁紶鏂囦欢鍒拌吘璁簯COS
- * @param file 瑕佷笂浼犵殑鏂囦欢
- * @returns Promise<string> 杩斿洖鏂囦欢鐨勮闂甎RL
- */
-export const uploadToCOS = async (file: File): Promise<string> => {
- try {
- // 鑾峰彇涓婁紶鍑瘉
- const credentials = await getUploadCredentials()
-
- // 浣跨敤棰勭鍚峌RL
- const uploadUrl = credentials.presignedUrl
-
- // 浣跨敤棰勭鍚峌RL涓婁紶鏂囦欢
- const uploadResponse = await axios.put(uploadUrl, file, {
- headers: {
- 'Content-Type': file.type,
- }
- })
-
- if (uploadResponse.status === 200) {
- // 杩斿洖鏂囦欢鐨勮闂甎RL锛堝幓鎺夋煡璇㈠弬鏁帮級
- const fileUrl = `https://${credentials.bucket}.cos.${credentials.region}.myqcloud.com/${credentials.key}`
- return fileUrl
- } else {
- throw new Error(`涓婁紶澶辫触锛岀姸鎬佺爜: ${uploadResponse.status}`)
- }
-
- } catch (error) {
- throw error
- }
+import axios from 'axios'
+import { serverUrl } from './appConfig.js'
+
+
+
+// GraphQL鏌ヨ鑾峰彇涓婁紶鍑瘉
+
+const GET_UPLOAD_CREDENTIALS = `
+
+ query GetUploadCredentials {
+
+ getUploadCredentials {
+
+ bucket
+
+ region
+
+ key
+
+ presignedUrl
+
+ expiration
+
+ }
+
+ }
+
+`
+
+
+
+// 浠庡悗绔疓raphQL鑾峰彇涓婁紶鍑瘉
+
+const getUploadCredentials = async () => {
+
+ try {
+
+ const response = await axios.post(`${serverUrl}/graphql`, {
+
+ query: GET_UPLOAD_CREDENTIALS
+
+ })
+
+
+ if (response.data.errors) {
+
+ throw new Error(response.data.errors[0].message)
+
+ }
+
+
+
+ return response.data.data.getUploadCredentials
+
+ } catch (error) {
+
+ console.error('鑾峰彇涓婁紶鍑瘉澶辫触:', error)
+
+ throw error
+
+ }
+
+}
+
+
+
+/**
+
+ * 浣跨敤棰勭鍚峌RL涓婁紶鏂囦欢鍒拌吘璁簯COS
+
+ * @param file 瑕佷笂浼犵殑鏂囦欢
+
+ * @returns Promise<string> 杩斿洖鏂囦欢鐨勮闂甎RL
+
+ */
+
+export const uploadToCOS = async (file: File): Promise<string> => {
+
+ try {
+
+ // 鑾峰彇涓婁紶鍑瘉
+
+ const credentials = await getUploadCredentials()
+
+
+
+ // 浣跨敤棰勭鍚峌RL
+
+ const uploadUrl = credentials.presignedUrl
+
+
+
+ // 浣跨敤棰勭鍚峌RL涓婁紶鏂囦欢
+
+ const uploadResponse = await axios.put(uploadUrl, file, {
+
+ headers: {
+
+ 'Content-Type': file.type,
+
+ }
+
+ })
+
+
+
+ if (uploadResponse.status === 200) {
+
+ // 杩斿洖鏂囦欢鐨勮闂甎RL锛堝幓鎺夋煡璇㈠弬鏁帮級
+
+ const fileUrl = `https://${credentials.bucket}.cos.${credentials.region}.myqcloud.com/${credentials.key}`
+
+ return fileUrl
+
+ } else {
+
+ throw new Error(`涓婁紶澶辫触锛岀姸鎬佺爜: ${uploadResponse.status}`)
+
+ }
+
+
+
+ } catch (error) {
+
+ throw error
+
+ }
+
}
\ No newline at end of file
diff --git a/web/src/utils/cos.ts b/web/src/utils/cos.ts
index 2a61394..53ccd09 100644
--- a/web/src/utils/cos.ts
+++ b/web/src/utils/cos.ts
@@ -1,162 +1,324 @@
-import COS from 'cos-js-sdk-v5'
-import axios from 'axios'
-
-// 浠庡悗绔幏鍙栦复鏃跺瘑閽�
-const getCredentialsFromBackend = async () => {
- try {
- const response = await axios.get('http://localhost:8080/api/cos/credentials')
- return response.data
- } catch (error) {
- throw error
- }
-}
-
-// 鍒涘缓COS瀹炰緥
-const cos = new COS({
- getAuthorization: async function (options: any, callback: any) {
- try {
- console.log('姝e湪浠庡悗绔幏鍙朇OS涓存椂瀵嗛挜...')
- // 浠庡悗绔幏鍙栦复鏃跺瘑閽�
- const credentials = await getCredentialsFromBackend()
-
- console.log('鎴愬姛鑾峰彇涓存椂瀵嗛挜:', {
- TmpSecretId: credentials.TmpSecretId?.substring(0, 10) + '...',
- bucket: credentials.config?.bucket,
- region: credentials.config?.region
- })
-
- callback({
- TmpSecretId: credentials.TmpSecretId,
- TmpSecretKey: credentials.TmpSecretKey,
- SecurityToken: credentials.SecurityToken,
- StartTime: credentials.StartTime,
- ExpiredTime: credentials.ExpiredTime,
- })
- } catch (error) {
- console.error('鑾峰彇涓存椂瀵嗛挜澶辫触:', error)
- callback(error)
- }
- }
-})
-
-// 鑾峰彇COS閰嶇疆淇℃伅
-export const getCOSConfig = async () => {
- try {
- const response = await axios.get('http://localhost:8080/api/cos/config')
- return response.data
- } catch (error) {
- console.error('鑾峰彇COS閰嶇疆澶辫触:', error)
- throw error
- }
-}
-
-/**
- * 涓婁紶鏂囦欢鍒拌吘璁簯COS
- * @param file 瑕佷笂浼犵殑鏂囦欢
- * @param folder 瀛樺偍鏂囦欢澶硅矾寰勶紝濡� 'avatars/', 'documents/'
- * @returns Promise<string> 杩斿洖鏂囦欢鐨勮闂甎RL
- */
-export const uploadToCOS = async (file: File, folder: string = ''): Promise<string> => {
- try {
- // 鑾峰彇COS閰嶇疆
- const config = await getCOSConfig()
-
- // 鐢熸垚鍞竴鏂囦欢鍚�
- const timestamp = Date.now()
- const randomStr = Math.random().toString(36).substring(2, 8)
- const fileExt = file.name.split('.').pop()
- const fileName = `${folder}${timestamp}_${randomStr}.${fileExt}`
-
- console.log('寮�濮嬩笂浼犳枃浠�:', fileName, '鍒板瓨鍌ㄦ《:', config.bucket)
-
- return new Promise((resolve, reject) => {
- cos.uploadFile({
- Bucket: config.bucket,
- Region: config.region,
- Key: fileName,
- Body: file,
- SliceSize: 1024 * 1024 * 5, // 澶т簬5MB鐨勬枃浠朵娇鐢ㄥ垎鍧椾笂浼�
- onProgress: (progressData) => {
- console.log('涓婁紶杩涘害:', Math.round(progressData.percent * 100) + '%')
- }
- }, (err, data) => {
- if (err) {
- console.error('涓婁紶澶辫触:', err)
- reject(err)
- } else {
- console.log('涓婁紶鎴愬姛:', data)
- // 杩斿洖鏂囦欢鐨勮闂甎RL
- const fileUrl = `https://${data.Location}`
- resolve(fileUrl)
- }
- })
- })
- } catch (error) {
- console.error('涓婁紶鏂囦欢澶辫触:', error)
- throw error
- }
-}
-
-/**
- * 鍒犻櫎COS涓殑鏂囦欢
- * @param key 鏂囦欢鐨凨ey锛堣矾寰勶級
- * @returns Promise<boolean>
- */
-export const deleteFromCOS = async (key: string): Promise<boolean> => {
- try {
- const config = await getCOSConfig()
-
- return new Promise((resolve, reject) => {
- cos.deleteObject({
- Bucket: config.bucket,
- Region: config.region,
- Key: key
- }, (err, data) => {
- if (err) {
- console.error('鍒犻櫎澶辫触:', err)
- reject(err)
- } else {
- console.log('鍒犻櫎鎴愬姛:', data)
- resolve(true)
- }
- })
- })
- } catch (error) {
- console.error('鍒犻櫎鏂囦欢澶辫触:', error)
- throw error
- }
-}
-
-/**
- * 鑾峰彇鏂囦欢鐨勪复鏃惰闂甎RL锛堢敤浜庣鏈夎鍙栫殑鏂囦欢锛�
- * @param key 鏂囦欢鐨凨ey锛堣矾寰勶級
- * @param expires 杩囨湡鏃堕棿锛堢锛夛紝榛樿1灏忔椂
- * @returns Promise<string>
- */
-export const getObjectUrl = async (key: string, expires: number = 3600): Promise<string> => {
- try {
- const config = await getCOSConfig()
-
- return new Promise((resolve, reject) => {
- cos.getObjectUrl({
- Bucket: config.bucket,
- Region: config.region,
- Key: key,
- Expires: expires,
- Sign: true
- }, (err, data) => {
- if (err) {
- console.error('鑾峰彇URL澶辫触:', err)
- reject(err)
- } else {
- resolve(data.Url)
- }
- })
- })
- } catch (error) {
- console.error('鑾峰彇鏂囦欢URL澶辫触:', error)
- throw error
- }
-}
-
+import COS from 'cos-js-sdk-v5'
+
+import axios from 'axios'
+import { serverUrl } from './appConfig.js'
+
+
+
+// 浠庡悗绔幏鍙栦复鏃跺瘑閽�
+
+const getCredentialsFromBackend = async () => {
+
+ try {
+
+ const response = await axios.get(`${serverUrl}/api/cos/credentials`)
+
+ return response.data
+
+ } catch (error) {
+
+ throw error
+
+ }
+
+}
+
+
+
+// 鍒涘缓COS瀹炰緥
+
+const cos = new COS({
+
+ getAuthorization: async function (options: any, callback: any) {
+
+ try {
+
+ console.log('姝e湪浠庡悗绔幏鍙朇OS涓存椂瀵嗛挜...')
+
+ // 浠庡悗绔幏鍙栦复鏃跺瘑閽�
+
+ const credentials = await getCredentialsFromBackend()
+
+
+
+ console.log('鎴愬姛鑾峰彇涓存椂瀵嗛挜:', {
+
+ TmpSecretId: credentials.TmpSecretId?.substring(0, 10) + '...',
+
+ bucket: credentials.config?.bucket,
+
+ region: credentials.config?.region
+
+ })
+
+
+
+ callback({
+
+ TmpSecretId: credentials.TmpSecretId,
+
+ TmpSecretKey: credentials.TmpSecretKey,
+
+ SecurityToken: credentials.SecurityToken,
+
+ StartTime: credentials.StartTime,
+
+ ExpiredTime: credentials.ExpiredTime,
+
+ })
+
+ } catch (error) {
+
+ console.error('鑾峰彇涓存椂瀵嗛挜澶辫触:', error)
+
+ callback(error)
+
+ }
+
+ }
+
+})
+
+
+
+// 鑾峰彇COS閰嶇疆淇℃伅
+
+export const getCOSConfig = async () => {
+
+ try {
+
+ const response = await axios.get(`${serverUrl}/api/cos/config`)
+
+ return response.data
+
+ } catch (error) {
+
+ console.error('鑾峰彇COS閰嶇疆澶辫触:', error)
+
+ throw error
+
+ }
+
+}
+
+
+
+/**
+
+ * 涓婁紶鏂囦欢鍒拌吘璁簯COS
+
+ * @param file 瑕佷笂浼犵殑鏂囦欢
+
+ * @param folder 瀛樺偍鏂囦欢澶硅矾寰勶紝濡� 'avatars/', 'documents/'
+
+ * @returns Promise<string> 杩斿洖鏂囦欢鐨勮闂甎RL
+
+ */
+
+export const uploadToCOS = async (file: File, folder: string = ''): Promise<string> => {
+
+ try {
+
+ // 鑾峰彇COS閰嶇疆
+
+ const config = await getCOSConfig()
+
+
+
+ // 鐢熸垚鍞竴鏂囦欢鍚�
+
+ const timestamp = Date.now()
+
+ const randomStr = Math.random().toString(36).substring(2, 8)
+
+ const fileExt = file.name.split('.').pop()
+
+ const fileName = `${folder}${timestamp}_${randomStr}.${fileExt}`
+
+
+
+ console.log('寮�濮嬩笂浼犳枃浠�:', fileName, '鍒板瓨鍌ㄦ《:', config.bucket)
+
+
+
+ return new Promise((resolve, reject) => {
+
+ cos.uploadFile({
+
+ Bucket: config.bucket,
+
+ Region: config.region,
+
+ Key: fileName,
+
+ Body: file,
+
+ SliceSize: 1024 * 1024 * 5, // 澶т簬5MB鐨勬枃浠朵娇鐢ㄥ垎鍧椾笂浼�
+
+ onProgress: (progressData) => {
+
+ console.log('涓婁紶杩涘害:', Math.round(progressData.percent * 100) + '%')
+
+ }
+
+ }, (err, data) => {
+
+ if (err) {
+
+ console.error('涓婁紶澶辫触:', err)
+
+ reject(err)
+
+ } else {
+
+ console.log('涓婁紶鎴愬姛:', data)
+
+ // 杩斿洖鏂囦欢鐨勮闂甎RL
+
+ const fileUrl = `https://${data.Location}`
+
+ resolve(fileUrl)
+
+ }
+
+ })
+
+ })
+
+ } catch (error) {
+
+ console.error('涓婁紶鏂囦欢澶辫触:', error)
+
+ throw error
+
+ }
+
+}
+
+
+
+/**
+
+ * 鍒犻櫎COS涓殑鏂囦欢
+
+ * @param key 鏂囦欢鐨凨ey锛堣矾寰勶級
+
+ * @returns Promise<boolean>
+
+ */
+
+export const deleteFromCOS = async (key: string): Promise<boolean> => {
+
+ try {
+
+ const config = await getCOSConfig()
+
+
+
+ return new Promise((resolve, reject) => {
+
+ cos.deleteObject({
+
+ Bucket: config.bucket,
+
+ Region: config.region,
+
+ Key: key
+
+ }, (err, data) => {
+
+ if (err) {
+
+ console.error('鍒犻櫎澶辫触:', err)
+
+ reject(err)
+
+ } else {
+
+ console.log('鍒犻櫎鎴愬姛:', data)
+
+ resolve(true)
+
+ }
+
+ })
+
+ })
+
+ } catch (error) {
+
+ console.error('鍒犻櫎鏂囦欢澶辫触:', error)
+
+ throw error
+
+ }
+
+}
+
+
+
+/**
+
+ * 鑾峰彇鏂囦欢鐨勪复鏃惰闂甎RL锛堢敤浜庣鏈夎鍙栫殑鏂囦欢锛�
+
+ * @param key 鏂囦欢鐨凨ey锛堣矾寰勶級
+
+ * @param expires 杩囨湡鏃堕棿锛堢锛夛紝榛樿1灏忔椂
+
+ * @returns Promise<string>
+
+ */
+
+export const getObjectUrl = async (key: string, expires: number = 3600): Promise<string> => {
+
+ try {
+
+ const config = await getCOSConfig()
+
+
+
+ return new Promise((resolve, reject) => {
+
+ cos.getObjectUrl({
+
+ Bucket: config.bucket,
+
+ Region: config.region,
+
+ Key: key,
+
+ Expires: expires,
+
+ Sign: true
+
+ }, (err, data) => {
+
+ if (err) {
+
+ console.error('鑾峰彇URL澶辫触:', err)
+
+ reject(err)
+
+ } else {
+
+ resolve(data.Url)
+
+ }
+
+ })
+
+ })
+
+ } catch (error) {
+
+ console.error('鑾峰彇鏂囦欢URL澶辫触:', error)
+
+ throw error
+
+ }
+
+}
+
+
+
export default cos
\ No newline at end of file
diff --git a/web/src/views/check-detail.vue b/web/src/views/check-detail.vue
index 57d9776..cfa0d6e 100644
--- a/web/src/views/check-detail.vue
+++ b/web/src/views/check-detail.vue
@@ -417,7 +417,7 @@
}
// 鑾峰彇瀛﹀巻鏂囨湰
-const getEducationText = (education: number) => {
+const getEducationText = (education: number | string) => {
const educationMap: Record<number, string> = {
1: '楂樹腑',
2: '澶т笓',
@@ -425,7 +425,8 @@
4: '纭曞+',
5: '鍗氬+'
}
- return educationMap[education] || '-'
+ const numEducation = typeof education === 'string' ? parseInt(education) : education
+ return educationMap[numEducation] || '-'
}
// 鑾峰彇鐘舵�佹枃鏈�
diff --git a/web/src/views/next-list.vue b/web/src/views/next-list.vue
index a8200db..4158bf8 100644
--- a/web/src/views/next-list.vue
+++ b/web/src/views/next-list.vue
@@ -276,8 +276,15 @@
size: pagination.size
})
- competitions.value = data || []
- pagination.total = data ? data.length : 0
+ // 澶勭悊鍒嗛〉鍝嶅簲瀵硅薄
+ if (data && data.content) {
+ competitions.value = data.content
+ pagination.total = parseInt(data.totalElements) || 0
+ } else {
+ // 鍏煎鏃х殑杩斿洖鏍煎紡锛堝鏋滃悗绔繕娌℃洿鏂帮級
+ competitions.value = data || []
+ pagination.total = data ? data.length : 0
+ }
} catch (error) {
console.error('鑾峰彇姣旇禌鏅嬬骇鍒楄〃澶辫触:', error)
ElMessage.error('鑾峰彇姣旇禌鏁版嵁澶辫触: ' + (error.message || '鏈煡閿欒'))
diff --git a/web/vite.config.ts b/web/vite.config.ts
index 95ede8f..d0a27bd 100644
--- a/web/vite.config.ts
+++ b/web/vite.config.ts
@@ -10,12 +10,25 @@
}
},
server: {
+ host: '0.0.0.0',
port: 3000,
open: true,
proxy: {
'/api': {
- target: 'http://localhost:8080',
+ target: 'http://127.0.0.1:8080',
changeOrigin: true,
+ secure: false,
+ configure: (proxy, options) => {
+ proxy.on('error', (err, req, res) => {
+ console.log('proxy error', err);
+ });
+ proxy.on('proxyReq', (proxyReq, req, res) => {
+ console.log('Sending Request to the Target:', req.method, req.url);
+ });
+ proxy.on('proxyRes', (proxyRes, req, res) => {
+ console.log('Received Response from the Target:', proxyRes.statusCode, req.url);
+ });
+ },
// 涓嶉渶瑕侀噸鍐欒矾寰勶紝鍥犱负鍚庣鐨刢ontext-path灏辨槸/api
// rewrite: (path) => path.replace(/^\/api/, '/api')
}
diff --git a/wx/app.js b/wx/app.js
index 12709af..ba9f405 100644
--- a/wx/app.js
+++ b/wx/app.js
@@ -4,7 +4,10 @@
userInfo: null,
token: null,
sessionKey: null, // 寰俊浼氳瘽瀵嗛挜锛岀敤浜庤В瀵嗘墜鏈哄彿绛夋晱鎰熸暟鎹�
- baseUrl: 'http://localhost:8080/api/graphql', // 鍚庡彴GraphQL鎺ュ彛鍦板潃
+ baseUrl: 'https://ryc.9village.cn/api/graphql', // 鍚庡彴GraphQL鎺ュ彛鍦板潃
+ loginUrl:'https://ryc.9village.cn',
+ // baseUrl: 'http://localhost:8080/api/graphql', // 鍚庡彴GraphQL鎺ュ彛鍦板潃
+ // loginUrl:'http://localhost:8080',
hasPhoneAuth: false, // 鏄惁宸叉巿鏉冩墜鏈哄彿
rejectPhone: false, // 鏄惁鎷掔粷杩囨墜鏈哄彿鎺堟潈
cos: {
@@ -101,10 +104,6 @@
wx.login({
success: (res) => {
if (res.code) {
- console.log('鉁� 鑾峰彇寰俊鐧诲綍code鎴愬姛')
- console.log('鐧诲綍code:', res.code)
- console.log('code闀垮害:', res.code.length)
- console.log('鍑嗗璋冪敤鍚庣wxLogin鎺ュ彛...')
this.wxLogin(res.code)
} else {
console.error('鉂� 鑾峰彇寰俊鐧诲綍code澶辫触')
@@ -130,29 +129,21 @@
const deviceInfo = this.getDeviceInfo()
const requestData = {
code: code,
- loginIp: '127.0.0.1', // 灏忕▼搴忔棤娉曡幏鍙栫湡瀹濱P锛屼娇鐢ㄩ粯璁ゅ��
+ // loginIp: '127.0.0.1', // 灏忕▼搴忔棤娉曡幏鍙栫湡瀹濱P锛屼娇鐢ㄩ粯璁ゅ��
deviceInfo: deviceInfo
}
- console.log('=== 鍑嗗璋冪敤鍚庣wxLogin鎺ュ彛 ===')
- console.log('璇锋眰URL:', 'http://localhost:8080/api/auth/wx-login')
- console.log('璁惧淇℃伅:', deviceInfo)
- console.log('璇锋眰鍙傛暟:', requestData)
- console.log('璇锋眰寮�濮嬫椂闂�:', new Date().toISOString())
+
wx.request({
- url: 'http://localhost:8080/api/auth/wx-login',
+ url: this.globalData.loginUrl + '/api/auth/wx-login',
method: 'POST',
header: {
'Content-Type': 'application/json'
},
data: requestData,
success: (res) => {
- console.log('=== 鍚庣wxLogin鎺ュ彛鍝嶅簲 ===')
- console.log('鍝嶅簲鏃堕棿:', new Date().toISOString())
- console.log('HTTP鐘舵�佺爜:', res.statusCode)
- console.log('鍝嶅簲澶�:', res.header)
- console.log('鍝嶅簲鏁版嵁:', JSON.stringify(res.data, null, 2))
+
if (res.statusCode !== 200) {
console.error('鉂� HTTP璇锋眰澶辫触锛岀姸鎬佺爜:', res.statusCode)
diff --git a/wx/app.json b/wx/app.json
index 8bea719..6e950e6 100644
--- a/wx/app.json
+++ b/wx/app.json
@@ -17,7 +17,7 @@
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#ffffff",
- "navigationBarTitleText": "钃夋槗鍒�",
+ "navigationBarTitleText": "钃塭鍒�",
"navigationBarTextStyle": "black",
"backgroundColor": "#f5f5f5"
},
diff --git a/wx/pages/index/index.js b/wx/pages/index/index.js
index cf405ea..f9cba3f 100644
--- a/wx/pages/index/index.js
+++ b/wx/pages/index/index.js
@@ -21,19 +21,20 @@
// 绛涢�夋潯浠�
filterStatus: 'all', // all, upcoming, ongoing, ended
// 杞挱鍥惧綋鍓嶇储寮�
- currentBannerIndex: 0
+ currentBannerIndex: 0,
+ // 鍒嗕韩鐩稿叧鏁版嵁
+ shareActivityId: null,
+ shareActivityName: null
},
onLoad(options) {
console.log('棣栭〉鍔犺浇')
- this.loadBanners()
- this.loadActivities()
},
onShow() {
console.log('棣栭〉鏄剧ず')
// 缁熶竴绯荤粺瀵艰埅鏍忔爣棰�
- try { wx.setNavigationBarTitle({ title: '钃夋槗鍒�' }) } catch (e) {}
+ try { wx.setNavigationBarTitle({ title: '钃塭鍒�' }) } catch (e) {}
// 妫�鏌ョ櫥褰曠姸鎬�
if (!app.globalData.token) {
app.login()
@@ -42,6 +43,9 @@
if (typeof this.getTabBar === 'function' && this.getTabBar()) {
this.getTabBar().init();
}
+ // 鍔犺浇鏁版嵁
+ this.loadBanners()
+ this.loadActivities()
},
onPullDownRefresh() {
@@ -175,9 +179,9 @@
if (filterStatus !== 'all') {
// 鏍规嵁filterStatus鏄犲皠鍒板搴旂殑state鍊�
const stateMapping = {
- 'upcoming': 1, // 鍗冲皢寮�濮�
- 'ongoing': 2, // 杩涜涓�
- 'ended': 3 // 宸茬粨鏉�
+ 'upcoming': 1, // 鍗冲皢寮�濮� -> 鍙戝竷鐘舵��
+ 'ongoing': 1, // 杩涜涓� -> 鍙戝竷鐘舵��
+ 'ended': 2 // 宸茬粨鏉� -> 鍏抽棴鐘舵��
}
stateFilter = stateMapping[filterStatus]
}
@@ -214,7 +218,7 @@
page: currentPage,
size: pageSize,
name: nameFilter,
- state: stateFilter
+ state: 1
}).then(data => {
if (data.activities) {
let newActivities = data.activities.content
@@ -434,5 +438,164 @@
return now <= signupDeadline &&
activity.state === 'SIGNUP' &&
activity.playerCount < activity.playerMax
+ },
+
+ // 鍒嗕韩鍗曚釜姣旇禌
+ onShareActivity(e) {
+ const { id, name } = e.currentTarget.dataset
+
+ // 鏄剧ず鍒嗕韩閫夐」
+ wx.showActionSheet({
+ itemList: ['鍒嗕韩缁欐湅鍙�', '鐢熸垚鍒嗕韩娴锋姤'],
+ success: (res) => {
+ if (res.tapIndex === 0) {
+ // 鍒嗕韩缁欐湅鍙�
+ this.shareToFriend(id, name)
+ } else if (res.tapIndex === 1) {
+ // 鐢熸垚鍒嗕韩娴锋姤
+ this.generateSharePoster(id, name)
+ }
+ },
+ fail: (res) => {
+ console.log('鐢ㄦ埛鍙栨秷鍒嗕韩')
+ }
+ })
+ },
+
+ // 鍒嗕韩缁欐湅鍙�
+ shareToFriend(activityId, activityName) {
+ wx.showShareMenu({
+ withShareTicket: true,
+ menus: ['shareAppMessage', 'shareTimeline']
+ })
+
+ // 璁剧疆褰撳墠瑕佸垎浜殑娲诲姩淇℃伅
+ this.setData({
+ shareActivityId: activityId,
+ shareActivityName: activityName
+ })
+
+ // 瑙﹀彂鍒嗕韩
+ wx.updateShareMenu({
+ withShareTicket: true,
+ isUpdatableMessage: true,
+ activityId: 'share_activity_' + activityId,
+ templateInfo: {
+ parameterList: [{
+ name: 'activity_name',
+ value: activityName
+ }]
+ }
+ })
+
+ wx.showToast({
+ title: '璇风偣鍑诲彸涓婅鍒嗕韩',
+ icon: 'none',
+ duration: 2000
+ })
+ },
+
+ // 鐢熸垚鍒嗕韩娴锋姤
+ generateSharePoster(activityId, activityName) {
+ wx.showLoading({
+ title: '鐢熸垚娴锋姤涓�...'
+ })
+
+ // 杩欓噷鍙互璋冪敤鍚庣API鐢熸垚鍒嗕韩娴锋姤
+ // 鎴栬�呬娇鐢╟anvas鍦ㄥ墠绔敓鎴�
+ setTimeout(() => {
+ wx.hideLoading()
+ wx.showToast({
+ title: '娴锋姤鐢熸垚鍔熻兘寮�鍙戜腑',
+ icon: 'none',
+ duration: 2000
+ })
+ }, 1500)
+ },
+
+ // 椤甸潰鍒嗕韩鍔熻兘 - 鍒嗕韩缁欐湅鍙�
+ onShareAppMessage(res) {
+ console.log('鍒嗕韩缁欐湅鍙�', res)
+
+ // 濡傛灉鏄粠姣旇禌鍗$墖鍒嗕韩
+ if (this.data.shareActivityId && this.data.shareActivityName) {
+ const shareData = {
+ title: `${this.data.shareActivityName} - 钃塭鍒涙瘮璧涘钩鍙癭,
+ path: `/pages/activity/detail?id=${this.data.shareActivityId}`,
+ imageUrl: '', // 鍙互璁剧疆鍒嗕韩鍥剧墖
+ success: (res) => {
+ console.log('鍒嗕韩鎴愬姛', res)
+ wx.showToast({
+ title: '鍒嗕韩鎴愬姛',
+ icon: 'success',
+ duration: 2000
+ })
+ // 娓呴櫎鍒嗕韩鐘舵��
+ this.setData({
+ shareActivityId: null,
+ shareActivityName: null
+ })
+ },
+ fail: (res) => {
+ console.log('鍒嗕韩澶辫触', res)
+ wx.showToast({
+ title: '鍒嗕韩澶辫触',
+ icon: 'none',
+ duration: 2000
+ })
+ }
+ }
+ return shareData
+ }
+
+ // 榛樿鍒嗕韩鏁翠釜棣栭〉
+ return {
+ title: '钃塭鍒涙瘮璧涘钩鍙� - 鍙戠幇绮惧僵姣旇禌',
+ path: '/pages/index/index',
+ imageUrl: '', // 鍙互璁剧疆榛樿鍒嗕韩鍥剧墖
+ success: (res) => {
+ console.log('鍒嗕韩鎴愬姛', res)
+ wx.showToast({
+ title: '鍒嗕韩鎴愬姛',
+ icon: 'success',
+ duration: 2000
+ })
+ },
+ fail: (res) => {
+ console.log('鍒嗕韩澶辫触', res)
+ wx.showToast({
+ title: '鍒嗕韩澶辫触',
+ icon: 'none',
+ duration: 2000
+ })
+ }
+ }
+ },
+
+ // 鍒嗕韩鍒版湅鍙嬪湀
+ onShareTimeline() {
+ console.log('鍒嗕韩鍒版湅鍙嬪湀')
+
+ return {
+ title: '钃塭鍒涙瘮璧涘钩鍙� - 鍙戠幇绮惧僵姣旇禌',
+ query: '',
+ imageUrl: '', // 鍙互璁剧疆鍒嗕韩鍥剧墖
+ success: (res) => {
+ console.log('鍒嗕韩鍒版湅鍙嬪湀鎴愬姛', res)
+ wx.showToast({
+ title: '鍒嗕韩鎴愬姛',
+ icon: 'success',
+ duration: 2000
+ })
+ },
+ fail: (res) => {
+ console.log('鍒嗕韩鍒版湅鍙嬪湀澶辫触', res)
+ wx.showToast({
+ title: '鍒嗕韩澶辫触',
+ icon: 'none',
+ duration: 2000
+ })
+ }
+ }
}
})
\ No newline at end of file
diff --git a/wx/pages/index/index.json b/wx/pages/index/index.json
index b92d296..305ce4b 100644
--- a/wx/pages/index/index.json
+++ b/wx/pages/index/index.json
@@ -1,3 +1,3 @@
{
- "navigationBarTitleText": "钃夋槗鍒�"
+ "navigationBarTitleText": "钃塭鍒�"
}
\ No newline at end of file
diff --git a/wx/pages/index/index.wxml b/wx/pages/index/index.wxml
index eb5a980..dd5a8d3 100644
--- a/wx/pages/index/index.wxml
+++ b/wx/pages/index/index.wxml
@@ -1,6 +1,17 @@
<wxs src="./filters.wxs" module="filters" />
<!--pages/index/index.wxml-->
<view class="container">
+ <!-- 椤甸潰澶撮儴鍒嗕韩鍖哄煙 -->
+ <view class="header-section">
+ <view class="page-title">钃塭鍒涙瘮璧涘钩鍙�</view>
+ <view class="share-section">
+ <!-- <button class="share-btn" open-type="share">
+ <text class="share-icon">馃摛</text>
+ <text class="share-text">鍒嗕韩</text>
+ </button> -->
+ </view>
+ </view>
+
<!-- 鎼滅储鏍� - 鏆傛椂闅愯棌 -->
<view class="search-bar" style="display: none;">
<view class="search-input-wrapper">
@@ -93,6 +104,9 @@
<view class="registered">宸叉姤鍚嶏細{{item.playerCount}}浜�</view>
<view class="btn-row">
<button class="ghost-btn" catchtap="onActivityDetailTap" data-idx="{{index}}" data-id="{{item.id}}" data-xid="{{item.name}}" >鏌ョ湅璇︽儏</button>
+ <!-- <button class="share-activity-btn" catchtap="onShareActivity" data-idx="{{index}}" data-id="{{item.id}}" data-name="{{item.name}}">
+ <text class="share-icon-small">馃摛</text>
+ </button> -->
</view>
</view>
</view>
diff --git a/wx/pages/index/index.wxss b/wx/pages/index/index.wxss
index 71aa4c6..d2ef0c1 100644
--- a/wx/pages/index/index.wxss
+++ b/wx/pages/index/index.wxss
@@ -1,5 +1,83 @@
/* pages/index/index.wxss */
+/* 椤甸潰澶撮儴鍒嗕韩鍖哄煙鏍峰紡 */
+.header-section {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 20rpx;
+ background: #ffffff;
+ border-bottom: 1rpx solid #f0f0f0;
+}
+
+.page-title {
+ font-size: 36rpx;
+ font-weight: 700;
+ color: #0f172a;
+}
+
+.share-section {
+ display: flex;
+ align-items: center;
+}
+
+.share-btn {
+ display: flex;
+ align-items: center;
+ gap: 8rpx;
+ background: #007aff;
+ color: #ffffff;
+ border: none;
+ border-radius: 50rpx;
+ padding: 16rpx 24rpx;
+ font-size: 26rpx;
+ line-height: 1;
+}
+
+.share-btn::after {
+ border: none;
+}
+
+.share-btn:active {
+ background: #0056cc;
+}
+
+.share-icon {
+ font-size: 28rpx;
+}
+
+.share-text {
+ font-size: 26rpx;
+}
+
+/* 姣旇禌鍗$墖鍒嗕韩鎸夐挳鏍峰紡 */
+.share-activity-btn {
+ width: 80rpx;
+ height: 60rpx;
+ background: #f8fafc;
+ border: 1rpx solid #e2e8f0;
+ border-radius: 12rpx;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-left: 16rpx;
+ padding: 0;
+ line-height: 1;
+}
+
+.share-activity-btn::after {
+ border: none;
+}
+
+.share-activity-btn:active {
+ background: #e2e8f0;
+}
+
+.share-icon-small {
+ font-size: 24rpx;
+ color: #64748b;
+}
+
/* 鎼滅储鏍忔牱寮� */
.search-bar {
padding: 20rpx;
diff --git a/wx/pages/judge/review.js b/wx/pages/judge/review.js
index c8d16d2..112e080 100644
--- a/wx/pages/judge/review.js
+++ b/wx/pages/judge/review.js
@@ -149,9 +149,27 @@
videos: detail.submissionFiles ? detail.submissionFiles
.filter(file => file.mediaType === 2)
.map(file => file.fullUrl || file.url) : [],
+ mediaList: (detail.submissionFiles || []).map(file => {
+ const mt = file.mediaType
+ let typeStr = ''
+ if (mt === 1 || mt === 'image' || (typeof mt === 'string' && mt.startsWith('image'))) typeStr = 'image'
+ else if (mt === 2 || mt === 'video' || (typeof mt === 'string' && mt.startsWith('video'))) typeStr = 'video'
+ else if ((file.fileExt || '').toLowerCase().includes('pdf')) typeStr = 'pdf'
+ else if ((file.fileExt || '').toLowerCase().includes('doc')) typeStr = 'word'
+ else typeStr = 'file'
+ return {
+ id: file.id,
+ name: file.name,
+ size: file.fileSize,
+ mediaType: typeStr,
+ thumbUrl: file.fullThumbUrl || file.thumbUrl || file.fullUrl || file.url,
+ url: file.fullUrl || file.url
+ }
+ }),
participant: {
id: detail.playerInfo.id,
name: detail.playerInfo.name,
+ phone: detail.playerInfo.phone || '',
gender: this.getGenderText(detail.playerInfo.gender),
birthday: detail.playerInfo.birthday || '',
region: detail.regionInfo ? detail.regionInfo.name : '',
@@ -293,20 +311,39 @@
})
},
- // 濯掍綋鐐瑰嚮
+ // 濯掍綋鐐瑰嚮锛堥�氳繃 index 瀹氫綅 mediaList 椤癸級
onMediaTap(e) {
- const { url, type } = e.currentTarget.dataset
-
- if (type === 'image') {
+ const { index } = e.currentTarget.dataset
+ const item = this.data.submission?.mediaList?.[index]
+ if (!item) return
+ if (item.mediaType === 'image') {
+ const imgs = (this.data.submission.mediaList || [])
+ .filter(it => it.mediaType === 'image')
+ .map(it => it.url)
wx.previewImage({
- current: url,
- urls: this.data.submission.images || []
+ current: item.url,
+ urls: imgs.length ? imgs : [item.url]
})
- } else if (type === 'video') {
+ } else if (item.mediaType === 'video') {
this.setData({
showMediaPreview: true,
- currentMedia: url,
+ currentMedia: item.url,
mediaType: 'video'
+ })
+ } else {
+ wx.downloadFile({
+ url: item.url,
+ success: (res) => {
+ if (res.statusCode === 200) {
+ wx.openDocument({
+ filePath: res.tempFilePath,
+ showMenu: true
+ })
+ } else {
+ wx.showToast({ title: '棰勮澶辫触', icon: 'none' })
+ }
+ },
+ fail: () => wx.showToast({ title: '涓嬭浇澶辫触', icon: 'none' })
})
}
},
@@ -317,6 +354,44 @@
showMediaPreview: false,
currentMedia: null
})
+ },
+
+ // 鐐瑰嚮棰勮鎸夐挳锛氬浘鐗�/瑙嗛鐢� wx.previewMedia锛屾枃妗g敤 openDocument
+ onPreviewTap(e) {
+ const { index } = e.currentTarget.dataset
+ const list = this.data.submission?.mediaList || []
+ const item = list[index]
+ if (!item) return
+
+ if (item.mediaType === 'image' || item.mediaType === 'video') {
+ const mediaList = list
+ .filter(m => m.mediaType === 'image' || m.mediaType === 'video')
+ .map(m => ({
+ url: m.url,
+ type: m.mediaType === 'video' ? 'video' : 'image',
+ poster: m.thumbUrl || m.url
+ }))
+ const current = Math.max(0, mediaList.findIndex(m => m.url === item.url))
+ wx.previewMedia({
+ sources: mediaList,
+ current
+ })
+ } else {
+ wx.downloadFile({
+ url: item.url,
+ success: (res) => {
+ if (res.statusCode === 200) {
+ wx.openDocument({
+ filePath: res.tempFilePath,
+ showMenu: true
+ })
+ } else {
+ wx.showToast({ title: '棰勮澶辫触', icon: 'none' })
+ }
+ },
+ fail: () => wx.showToast({ title: '涓嬭浇澶辫触', icon: 'none' })
+ })
+ }
},
// 涓嬭浇鏂囦欢
@@ -560,30 +635,15 @@
},
*/
- // 鑱旂郴鍙傝禌鑰�
+ // 鑱旂郴鍙傝禌鑰咃細鐩存帴鎷ㄦ墦鐢佃瘽
onContactParticipant() {
- const { submission } = this.data
-
- if (submission.participant) {
- wx.showActionSheet({
- itemList: ['鍙戦�佹秷鎭�', '鏌ョ湅璇︽儏'],
- success: (res) => {
- switch (res.tapIndex) {
- case 0:
- // 鍙戦�佹秷鎭姛鑳�
- wx.navigateTo({
- url: `/pages/chat/chat?userId=${submission.participant.id}`
- })
- break
- case 1:
- // 鏌ョ湅鐢ㄦ埛璇︽儏
- wx.navigateTo({
- url: `/pages/user/profile?userId=${submission.participant.id}`
- })
- break
- }
- }
- })
+ const phone =
+ this.data.submission?.participant?.phone ||
+ this.data.submission?.participant?.userInfo?.phone
+ if (phone) {
+ wx.makePhoneCall({ phoneNumber: String(phone) })
+ } else {
+ wx.showToast({ title: '鏃犺仈绯荤數璇�', icon: 'none' })
}
},
@@ -619,7 +679,7 @@
// 鍒嗕韩椤甸潰
onShareAppMessage() {
return {
- title: '钃夋槗鍒� - 璇勫浣滃搧',
+ title: '钃塭鍒� - 璇勫浣滃搧',
path: '/pages/index/index'
}
}
diff --git a/wx/pages/judge/review.wxml b/wx/pages/judge/review.wxml
index 0a2cae6..3b6d467 100644
--- a/wx/pages/judge/review.wxml
+++ b/wx/pages/judge/review.wxml
@@ -74,6 +74,9 @@
<view class="media-info">
<text class="media-name">{{item.name}}</text>
<text class="media-size">{{getFileSizeText(item.size)}}</text>
+ <view class="preview-btn" catchtap="onPreviewTap" data-index="{{index}}">
+ <text>棰勮</text>
+ </view>
</view>
</view>
</view>
diff --git a/wx/pages/judge/review.wxss b/wx/pages/judge/review.wxss
index 24f04d5..edc89f9 100644
--- a/wx/pages/judge/review.wxss
+++ b/wx/pages/judge/review.wxss
@@ -454,6 +454,26 @@
font-size: 24rpx;
}
+/* 棰勮鎸夐挳鏍峰紡锛堜娇鐢� view 鍛堢幇涓烘寜閽瑙傦級 */
+.preview-btn {
+ align-self: flex-start;
+ margin-top: 8rpx;
+ padding: 10rpx 24rpx;
+ border: 2rpx solid #007aff;
+ color: #007aff;
+ border-radius: 999rpx;
+ font-size: 24rpx;
+ line-height: 1;
+ background-color: #ffffff;
+}
+.preview-btn:active {
+ background-color: #e6f0ff;
+}
+
+/* 淇濇寔濯掍綋淇℃伅鍖虹殑绱у噾鎬� */
+.media-info .media-name {
+ margin-bottom: 4rpx;
+}
@media (max-width: 375px) {
.container {
padding-bottom: 100rpx;
diff --git a/wx/pages/message/message.js b/wx/pages/message/message.js
index 4fa1f29..508d1fb 100644
--- a/wx/pages/message/message.js
+++ b/wx/pages/message/message.js
@@ -24,11 +24,6 @@
// 妫�鏌ョ敤鎴锋槸鍚﹀凡鐧诲綍
const userInfo = app.globalData.userInfo
if (!userInfo || !userInfo.userId) {
- console.error('鐢ㄦ埛鏈櫥褰曟垨userId涓嶅瓨鍦�')
- wx.showToast({
- title: '璇峰厛鐧诲綍',
- icon: 'error'
- })
return
}
diff --git a/wx/pages/profile/profile.js b/wx/pages/profile/profile.js
index a1123db..d55cf34 100644
--- a/wx/pages/profile/profile.js
+++ b/wx/pages/profile/profile.js
@@ -690,7 +690,7 @@
// 鍒嗕韩椤甸潰
onShareAppMessage() {
return {
- title: '钃夋槗鍒� - 鎴戠殑涓汉涓績',
+ title: '钃塭鍒� - 鎴戠殑涓汉涓績',
path: '/pages/index/index'
}
}
diff --git a/wx/pages/registration/registration.js b/wx/pages/registration/registration.js
index 719571c..66dd0d5 100644
--- a/wx/pages/registration/registration.js
+++ b/wx/pages/registration/registration.js
@@ -1292,7 +1292,7 @@
// 绗笁姝ワ細鎶ュ悕鎴愬姛鍚庡己鍒惰皟鐢╳xlogin鑾峰彇鏂扮殑JWT token
console.log('馃摫 鎶ュ悕鎴愬姛锛屽紑濮嬪己鍒惰皟鐢╳xlogin鑾峰彇鏂扮殑JWT token')
try {
- await app.wxLogin()
+ await app.login()
console.log('鉁� 鎶ュ悕鎴愬姛鍚巜xlogin璋冪敤鎴愬姛锛屽凡鑾峰彇鏂扮殑JWT token')
} catch (wxLoginError) {
console.error('鉂� 鎶ュ悕鎴愬姛鍚巜xlogin璋冪敤澶辫触:', wxLoginError)
--
Gitblit v1.8.0