diff --git a/miniprogram/app.js b/miniprogram/app.js
index 0e021b83..1afb139f 100644
--- a/miniprogram/app.js
+++ b/miniprogram/app.js
@@ -81,9 +81,9 @@ App({
sessionKey: wxInfo.sessionKey,
encryptedData,
iv,
- nickname: userProfile?.nickName || "",
- avatar: userProfile?.avatarUrl || "",
- gender: userProfile?.gender || 0,
+ nickname: (userProfile && userProfile.nickName) || "",
+ avatar: (userProfile && userProfile.avatarUrl) || "",
+ gender: (userProfile && userProfile.gender) || 0,
},
success: (loginRes) => {
if (loginRes.data.code === 0) {
@@ -93,7 +93,7 @@ App({
// 处理天梯用户信息
if (loginRes.data.data.userInfo.ladderUsers && loginRes.data.data.userInfo.ladderUsers.length > 0) {
// 如果有当前门店,优先选择当前门店的天梯用户
- if (this.globalData.currentStore?.storeId) {
+ if (this.globalData.currentStore && this.globalData.currentStore.storeId) {
const currentStoreLadderUser = loginRes.data.data.userInfo.ladderUsers.find(
lu => lu.storeId === this.globalData.currentStore.storeId
);
@@ -139,7 +139,7 @@ App({
// 处理天梯用户信息
if (res.data.ladderUsers && res.data.ladderUsers.length > 0) {
// 如果有当前门店,优先选择当前门店的天梯用户
- if (this.globalData.currentStore?.storeId) {
+ if (this.globalData.currentStore && this.globalData.currentStore.storeId) {
const currentStoreLadderUser = res.data.ladderUsers.find(
lu => lu.storeId === this.globalData.currentStore.storeId
);
@@ -179,11 +179,11 @@ App({
this.globalData.currentStore = res.data;
// 如果当前门店有 ladderUserId,获取该门店的天梯用户信息
- if (res.data?.ladderUserId) {
+ if (res.data && res.data.ladderUserId) {
this.getLadderUser(res.data.storeId);
- } else if (res.data?.storeId) {
+ } else if (res.data && res.data.storeId) {
// 如果当前门店没有 ladderUserId,但用户信息中有该门店的天梯用户,使用它
- if (this.globalData.userInfo?.ladderUsers) {
+ if (this.globalData.userInfo && this.globalData.userInfo.ladderUsers) {
const currentStoreLadderUser = this.globalData.userInfo.ladderUsers.find(
lu => lu.storeId === res.data.storeId
);
@@ -207,11 +207,11 @@ App({
this.globalData.currentStore = res.data;
// 如果当前门店有 ladderUserId,获取该门店的天梯用户信息
- if (res.data?.ladderUserId) {
+ if (res.data && res.data.ladderUserId) {
this.getLadderUser(res.data.storeId);
- } else if (res.data?.storeId) {
+ } else if (res.data && res.data.storeId) {
// 如果当前门店没有 ladderUserId,但用户信息中有该门店的天梯用户,使用它
- if (this.globalData.userInfo?.ladderUsers) {
+ if (this.globalData.userInfo && this.globalData.userInfo.ladderUsers) {
const currentStoreLadderUser = this.globalData.userInfo.ladderUsers.find(
lu => lu.storeId === res.data.storeId
);
diff --git a/miniprogram/app.json b/miniprogram/app.json
index 65545ac9..ca91daf4 100644
--- a/miniprogram/app.json
+++ b/miniprogram/app.json
@@ -1,6 +1,7 @@
{
"pages": [
"pages/index/index",
+ "pages/player/index",
"pages/user/index",
"pages/match/challenge/index",
"pages/match/challenge-detail/index",
diff --git a/miniprogram/app.wxss b/miniprogram/app.wxss
index d6b91009..2c40f1a9 100644
--- a/miniprogram/app.wxss
+++ b/miniprogram/app.wxss
@@ -26,6 +26,19 @@ page {
--accent-light: #e6fbf7;
--accent-soft: rgba(0, 201, 167, 0.1);
+ --info: #3b82f6;
+ --info-soft: rgba(59, 130, 246, 0.12);
+ --info-text: #1d4ed8;
+ --success: #16a34a;
+ --success-soft: rgba(22, 163, 74, 0.12);
+ --success-text: #166534;
+ --warning: #ffba08;
+ --warning-soft: rgba(255, 186, 8, 0.14);
+ --warning-text: #8a5a00;
+ --danger: #ef4444;
+ --danger-soft: rgba(239, 68, 68, 0.12);
+ --danger-text: #b91c1c;
+
/* 浅色背景系 */
--bg-page: #f7f8fa;
--bg-white: #ffffff;
diff --git a/miniprogram/config.js b/miniprogram/config.js
index 58c5888a..f3e72b06 100644
--- a/miniprogram/config.js
+++ b/miniprogram/config.js
@@ -6,9 +6,9 @@
// 开发环境配置
const devConfig = {
// API 基础地址(本地开发)
- baseUrl: "https://yingsa-server.ethan.team",
+ baseUrl: "http://127.0.0.1:3000",
// WebSocket 地址(本地开发)
- wsUrl: "wss://yingsa-server.ethan.team/ws",
+ wsUrl: "ws://127.0.0.1:3000/ws",
};
// 生产环境配置
@@ -25,7 +25,10 @@ const prodConfig = {
const getEnv = () => {
try {
// 尝试获取微信环境
- const envVersion = __wxConfig?.envVersion || "develop";
+ const envVersion =
+ typeof __wxConfig !== "undefined" && __wxConfig && __wxConfig.envVersion
+ ? __wxConfig.envVersion
+ : "develop";
return envVersion === "release" ? "production" : "development";
} catch (e) {
return "development";
@@ -35,14 +38,9 @@ const getEnv = () => {
const env = getEnv();
const config = env === "production" ? prodConfig : devConfig;
-module.exports = {
- ...config,
+module.exports = Object.assign({}, config, {
env,
- // 其他配置项
- // 上传文件大小限制 (MB)
uploadMaxSize: 5,
- // 请求超时时间 (ms)
requestTimeout: 30000,
- // 版本号
version: "1.0.0",
-};
+});
diff --git a/miniprogram/images/icon-phone.svg b/miniprogram/images/icon-phone.svg
new file mode 100644
index 00000000..eb079fee
--- /dev/null
+++ b/miniprogram/images/icon-phone.svg
@@ -0,0 +1,5 @@
+
diff --git a/miniprogram/images/icon-shield.svg b/miniprogram/images/icon-shield.svg
new file mode 100644
index 00000000..8ca18e82
--- /dev/null
+++ b/miniprogram/images/icon-shield.svg
@@ -0,0 +1,4 @@
+
diff --git a/miniprogram/images/icon-user.svg b/miniprogram/images/icon-user.svg
new file mode 100644
index 00000000..190e4963
--- /dev/null
+++ b/miniprogram/images/icon-user.svg
@@ -0,0 +1,4 @@
+
diff --git a/miniprogram/images/icon-users.svg b/miniprogram/images/icon-users.svg
new file mode 100644
index 00000000..8a0881d3
--- /dev/null
+++ b/miniprogram/images/icon-users.svg
@@ -0,0 +1,6 @@
+
diff --git a/miniprogram/pages/index/index.js b/miniprogram/pages/index/index.js
index 1f26461d..2024f7d3 100644
--- a/miniprogram/pages/index/index.js
+++ b/miniprogram/pages/index/index.js
@@ -1,57 +1,59 @@
-const app = getApp()
-const util = require('../../utils/util')
+const app = getApp();
+const util = require("../../utils/util");
Page({
data: {
currentStore: null,
- gender: '',
+ gender: "",
list: [],
loading: false,
page: 1,
pageSize: 20,
- hasMore: true
+ hasMore: true,
},
onLoad() {
- this.initData()
+ this.initData();
},
onShow() {
- const newStore = app.globalData.currentStore
- const oldStoreId = this.data.currentStore?.storeId
+ const newStore = app.globalData.currentStore;
+ const oldStoreId = this.data.currentStore
+ ? this.data.currentStore.storeId
+ : null;
// 检查门店是否切换
if (newStore && newStore.storeId !== oldStoreId) {
- this.setData({
+ this.setData({
currentStore: newStore,
page: 1,
hasMore: true,
- list: []
- })
- this.fetchData()
+ list: [],
+ });
+ this.fetchData();
} else if (app.globalData.storeChanged) {
// 全局标记门店已切换
- app.globalData.storeChanged = false
- this.setData({
+ app.globalData.storeChanged = false;
+ this.setData({
currentStore: newStore,
page: 1,
hasMore: true,
- list: []
- })
- this.fetchData()
+ list: [],
+ });
+ this.fetchData();
}
},
onPullDownRefresh() {
- this.setData({ page: 1, hasMore: true })
+ this.setData({ page: 1, hasMore: true });
this.fetchData().then(() => {
- wx.stopPullDownRefresh()
- })
+ wx.stopPullDownRefresh();
+ });
},
onReachBottom() {
if (this.data.hasMore && !this.data.loading) {
- this.loadMore()
+ this.loadMore();
}
},
@@ -59,66 +61,76 @@ Page({
// 检查是否已登录(有 token)
if (!app.globalData.token) {
// 未登录,跳转到用户页面进行登录
- wx.switchTab({ url: '/pages/user/index' })
- return
+ wx.switchTab({ url: "/pages/user/index" });
+ return;
}
// 获取当前门店
try {
- const store = await app.getCurrentStore()
- this.setData({ currentStore: store })
- this.fetchData()
+ const store = await app.getCurrentStore();
+ this.setData({ currentStore: store });
+ this.fetchData();
} catch (e) {
- console.error('获取门店失败:', e)
+ console.error("获取门店失败:", e);
// 如果是认证失败,跳转到登录页
if (e.code === 401) {
- wx.switchTab({ url: '/pages/user/index' })
+ wx.switchTab({ url: "/pages/user/index" });
}
}
},
async fetchData() {
- if (!this.data.currentStore?.storeId) return
+ if (!this.data.currentStore || !this.data.currentStore.storeId) return;
- this.setData({ loading: true })
+ this.setData({ loading: true });
try {
- const res = await app.request('/api/ladder/ranking', {
+ const res = await app.request("/api/ladder/ranking", {
store_id: this.data.currentStore.storeId,
gender: this.data.gender,
page: this.data.page,
- pageSize: this.data.pageSize
- })
+ pageSize: this.data.pageSize,
+ });
- const list = res.data.list || []
+ const list = res.data.list || [];
this.setData({
- list: this.data.page === 1 ? list : [...this.data.list, ...list],
- hasMore: list.length >= this.data.pageSize
- })
+ list: this.data.page === 1 ? list : this.data.list.concat(list),
+ hasMore: list.length >= this.data.pageSize,
+ });
} catch (e) {
- console.error('获取排名失败:', e)
+ console.error("获取排名失败:", e);
} finally {
- this.setData({ loading: false })
+ this.setData({ loading: false });
}
},
loadMore() {
- this.setData({ page: this.data.page + 1 })
- this.fetchData()
+ this.setData({ page: this.data.page + 1 });
+ this.fetchData();
},
setGender(e) {
- const gender = e.currentTarget.dataset.gender
- this.setData({ gender, page: 1, hasMore: true })
- this.fetchData()
+ const gender = e.currentTarget.dataset.gender;
+ this.setData({ gender, page: 1, hasMore: true });
+ this.fetchData();
},
selectStore() {
- wx.navigateTo({ url: '/pages/store/index' })
+ wx.navigateTo({ url: "/pages/store/index" });
},
viewPlayer(e) {
- const id = e.currentTarget.dataset.id
- wx.navigateTo({ url: `/pages/player/index?id=${id}` })
- }
-})
+ const player = e.currentTarget.dataset.player;
+ const id = player && player.id ? player.id : e.currentTarget.dataset.id;
+ if (!id) return;
+
+ wx.navigateTo({
+ url: `/pages/player/index?id=${id}`,
+ success: (res) => {
+ if (res && res.eventChannel && player) {
+ res.eventChannel.emit("player", player);
+ }
+ },
+ });
+ },
+});
diff --git a/miniprogram/pages/index/index.wxml b/miniprogram/pages/index/index.wxml
index 813e8ec4..45a47157 100644
--- a/miniprogram/pages/index/index.wxml
+++ b/miniprogram/pages/index/index.wxml
@@ -41,14 +41,14 @@
bindtap="setGender"
data-gender="1"
>
- ♂ 男子
+ 男子
- ♀ 女子
+ 女子
@@ -62,11 +62,11 @@
wx:key="id"
bindtap="viewPlayer"
data-id="{{item.id}}"
+ data-player="{{item}}"
>
- {{item.rank === 1 ? '👑' : item.rank === 2 ? '🥈' : '🥉'}}
- {{item.rank}}
+ {{item.rank}}
diff --git a/miniprogram/pages/index/index.wxss b/miniprogram/pages/index/index.wxss
index a0a29c8c..2965a154 100644
--- a/miniprogram/pages/index/index.wxss
+++ b/miniprogram/pages/index/index.wxss
@@ -49,7 +49,7 @@
width: 12rpx;
height: 12rpx;
border-radius: 50%;
- background: #ff6b35;
+ background: var(--primary);
box-shadow: 0 0 8rpx rgba(255, 107, 53, 0.4);
animation: pulse 2s ease-in-out infinite;
}
@@ -57,7 +57,7 @@
.store-name {
font-size: 30rpx;
font-weight: 600;
- color: #333;
+ color: var(--text-primary);
letter-spacing: 0.5rpx;
}
@@ -77,13 +77,13 @@
.change-store-text {
font-size: 24rpx;
- color: #666;
+ color: var(--text-secondary);
font-weight: 500;
}
.change-store-arrow {
font-size: 22rpx;
- color: #999;
+ color: var(--text-muted);
font-weight: 300;
}
@@ -100,7 +100,7 @@
display: block;
font-size: 52rpx;
font-weight: 700;
- color: #1a1a1a;
+ color: var(--text-primary);
margin-bottom: 8rpx;
letter-spacing: 1rpx;
}
@@ -108,7 +108,7 @@
.page-subtitle {
display: block;
font-size: 26rpx;
- color: #999;
+ color: var(--text-muted);
font-weight: 400;
letter-spacing: 0.5rpx;
}
@@ -149,9 +149,9 @@
}
.filter-item.active {
- background: linear-gradient(135deg, #ff6b35 0%, #ff8c42 100%);
- color: #fff;
- box-shadow: 0 4rpx 16rpx rgba(255, 107, 53, 0.3);
+ background: var(--primary-gradient);
+ color: var(--text-white);
+ box-shadow: var(--shadow-primary);
font-weight: 600;
}
@@ -168,12 +168,12 @@
display: flex;
align-items: center;
padding: 24rpx;
- background: #fff;
+ background: var(--bg-card);
border-radius: 20rpx;
margin-bottom: 16rpx;
- box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
+ box-shadow: var(--shadow-card);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- border: 1rpx solid #f0f0f0;
+ border: 1rpx solid var(--border-soft);
}
.ranking-item:last-child {
@@ -186,9 +186,9 @@
}
.ranking-item.top-rank {
- background: linear-gradient(135deg, #fff5f0 0%, #fff 100%);
- border: 2rpx solid rgba(255, 107, 53, 0.2);
- box-shadow: 0 6rpx 20rpx rgba(255, 107, 53, 0.15);
+ background: linear-gradient(135deg, var(--primary-soft) 0%, var(--bg-white) 100%);
+ border: 2rpx solid var(--border-primary);
+ box-shadow: var(--shadow-primary);
}
/* 排名徽章 */
@@ -233,8 +233,8 @@
}
.rank-badge.normal {
- background: linear-gradient(135deg, #f5f5f5 0%, #e8e8e8 100%);
- color: #666;
+ background: linear-gradient(135deg, var(--bg-soft) 0%, var(--bg-card-hover) 100%);
+ color: var(--text-secondary);
font-weight: 600;
}
@@ -244,10 +244,10 @@
height: 80rpx;
border-radius: 50%;
margin-right: 20rpx;
- border: 3rpx solid #fff;
+ border: 3rpx solid var(--bg-white);
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
flex-shrink: 0;
- background: #f5f5f5;
+ background: var(--bg-soft);
}
/* 选手信息 */
@@ -260,7 +260,7 @@
display: block;
font-size: 30rpx;
font-weight: 600;
- color: #333;
+ color: var(--text-primary);
margin-bottom: 8rpx;
overflow: hidden;
text-overflow: ellipsis;
@@ -292,7 +292,7 @@
.player-stats {
font-size: 24rpx;
- color: #666;
+ color: var(--text-secondary);
font-weight: 500;
}
@@ -306,14 +306,14 @@
display: block;
font-size: 36rpx;
font-weight: 700;
- color: #ff6b35;
+ color: var(--primary);
line-height: 1.2;
margin-bottom: 4rpx;
}
.power-label {
font-size: 22rpx;
- color: #999;
+ color: var(--text-muted);
font-weight: 500;
}
diff --git a/miniprogram/pages/match/challenge-detail/index.js b/miniprogram/pages/match/challenge-detail/index.js
index e44d30bf..bccdde2c 100644
--- a/miniprogram/pages/match/challenge-detail/index.js
+++ b/miniprogram/pages/match/challenge-detail/index.js
@@ -198,8 +198,8 @@ Page({
canConfirmScore = true
console.log('进行中状态:设置确认比分权限(对方已提交,等待确认)', {
submitBy: game.submitBy,
- challengerId: matchInfo.challenger?.id,
- defenderId: matchInfo.defender?.id,
+ challengerId: matchInfo.challenger ? matchInfo.challenger.id : null,
+ defenderId: matchInfo.defender ? matchInfo.defender.id : null,
myRole
})
}
@@ -214,11 +214,11 @@ Page({
console.log('尝试通过游戏信息识别角色:', {
player1Id: game.player1Id,
player2Id: game.player2Id,
- challengerId: matchInfo.challenger?.id,
- defenderId: matchInfo.defender?.id,
+ challengerId: matchInfo.challenger ? matchInfo.challenger.id : null,
+ defenderId: matchInfo.defender ? matchInfo.defender.id : null,
currentUserId: currentUser.id,
- challengerUserId: matchInfo.challenger?.userId,
- defenderUserId: matchInfo.defender?.userId
+ challengerUserId: matchInfo.challenger ? matchInfo.challenger.userId : null,
+ defenderUserId: matchInfo.defender ? matchInfo.defender.userId : null
})
// 通过比较 challenger/defender 的 id(ladder_user_id)和 player1_id/player2_id 来判断
@@ -262,8 +262,8 @@ Page({
// 如果游戏状态为2(已提交)且对方已提交,等待我确认
else if (game.status === 2 && game.submitBy) {
// 判断当前用户是否是提交者
- const isSubmitter = (myRole === 'challenger' && game.submitBy == matchInfo.challenger?.id) ||
- (myRole === 'defender' && game.submitBy == matchInfo.defender?.id)
+ const isSubmitter = (myRole === 'challenger' && matchInfo.challenger && game.submitBy == matchInfo.challenger.id) ||
+ (myRole === 'defender' && matchInfo.defender && game.submitBy == matchInfo.defender.id)
if (!isSubmitter && game.confirmStatus === 0) {
canConfirmScore = true
@@ -317,10 +317,10 @@ Page({
canAccept,
canReject,
matchInfoStatus: matchInfo.status,
- defenderUserId: matchInfo.defender?.userId,
- currentUserId: app.globalData.userInfo?.id,
- defenderPhone: matchInfo.defender?.phone,
- currentUserPhone: app.globalData.userInfo?.phone
+ defenderUserId: matchInfo.defender ? matchInfo.defender.userId : null,
+ currentUserId: app.globalData.userInfo ? app.globalData.userInfo.id : null,
+ defenderPhone: matchInfo.defender ? matchInfo.defender.phone : null,
+ currentUserPhone: app.globalData.userInfo ? app.globalData.userInfo.phone : null
})
}
} catch (e) {
@@ -471,7 +471,7 @@ Page({
// 确认比分
async confirmScore(confirm) {
- const game = this.data.matchInfo.games?.[0]
+ const game = this.data.matchInfo.games && this.data.matchInfo.games[0]
if (!game) {
wx.showToast({ title: '比赛信息错误', icon: 'none' })
return
@@ -503,7 +503,7 @@ Page({
// 确认比分按钮
confirmScoreBtn() {
- const game = this.data.matchInfo.games?.[0]
+ const game = this.data.matchInfo.games && this.data.matchInfo.games[0]
if (!game) {
wx.showToast({ title: '比赛信息错误', icon: 'none' })
return
@@ -521,12 +521,12 @@ Page({
myScore = game.player1Score || 0
opponentScore = game.player2Score || 0
myName = this.data.matchInfo.challenger.realName || '挑战者'
- opponentName = this.data.matchInfo.defender?.realName || '被挑战者'
+ opponentName = (this.data.matchInfo.defender && this.data.matchInfo.defender.realName) || '被挑战者'
} else if (this.data.matchInfo.challenger && this.data.matchInfo.challenger.id == game.player2Id) {
myScore = game.player2Score || 0
opponentScore = game.player1Score || 0
myName = this.data.matchInfo.challenger.realName || '挑战者'
- opponentName = this.data.matchInfo.defender?.realName || '被挑战者'
+ opponentName = (this.data.matchInfo.defender && this.data.matchInfo.defender.realName) || '被挑战者'
} else {
// 如果无法确定,使用默认显示
myScore = game.player1Score || 0
@@ -538,12 +538,12 @@ Page({
myScore = game.player1Score || 0
opponentScore = game.player2Score || 0
myName = this.data.matchInfo.defender.realName || '被挑战者'
- opponentName = this.data.matchInfo.challenger?.realName || '挑战者'
+ opponentName = (this.data.matchInfo.challenger && this.data.matchInfo.challenger.realName) || '挑战者'
} else if (this.data.matchInfo.defender && this.data.matchInfo.defender.id == game.player2Id) {
myScore = game.player2Score || 0
opponentScore = game.player1Score || 0
myName = this.data.matchInfo.defender.realName || '被挑战者'
- opponentName = this.data.matchInfo.challenger?.realName || '挑战者'
+ opponentName = (this.data.matchInfo.challenger && this.data.matchInfo.challenger.realName) || '挑战者'
} else {
// 如果无法确定,使用默认显示
myScore = game.player1Score || 0
diff --git a/miniprogram/pages/match/challenge-detail/index.wxss b/miniprogram/pages/match/challenge-detail/index.wxss
index 6efe6d0b..512420c2 100644
--- a/miniprogram/pages/match/challenge-detail/index.wxss
+++ b/miniprogram/pages/match/challenge-detail/index.wxss
@@ -1,6 +1,6 @@
.page-container {
min-height: 100vh;
- background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
+ background: linear-gradient(135deg, var(--bg-page) 0%, var(--primary-soft) 100%);
padding: 20rpx;
}
@@ -9,14 +9,14 @@
justify-content: center;
align-items: center;
height: 60vh;
- color: #666;
+ color: var(--text-secondary);
}
.match-info {
- background: #fff;
- border-radius: 24rpx;
+ background: var(--bg-card);
+ border-radius: var(--radius-lg);
padding: 40rpx;
- box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.1);
+ box-shadow: var(--shadow-card);
}
.match-header {
@@ -25,13 +25,13 @@
align-items: center;
margin-bottom: 40rpx;
padding-bottom: 30rpx;
- border-bottom: 2rpx solid #f0f0f0;
+ border-bottom: 2rpx solid var(--border-soft);
}
.match-title {
font-size: 36rpx;
font-weight: 600;
- color: #333;
+ color: var(--text-primary);
}
.match-status {
@@ -41,23 +41,23 @@
}
.status-0 {
- background: #fff3cd;
- color: #856404;
+ background: var(--warning-soft);
+ color: var(--warning-text);
}
.status-1 {
- background: #d1ecf1;
- color: #0c5460;
+ background: var(--info-soft);
+ color: var(--info-text);
}
.status-2 {
- background: #d4edda;
- color: #155724;
+ background: var(--success-soft);
+ color: var(--success-text);
}
.status-3 {
- background: #f8d7da;
- color: #721c24;
+ background: var(--danger-soft);
+ color: var(--danger-text);
}
.opponent-section {
@@ -70,7 +70,7 @@
.opponent-label {
font-size: 24rpx;
- color: #999;
+ color: var(--text-muted);
margin-bottom: 20rpx;
}
@@ -84,7 +84,7 @@
width: 100rpx;
height: 100rpx;
border-radius: 50%;
- border: 4rpx solid #e0e0e0;
+ border: 4rpx solid var(--border-light);
}
.opponent-details {
@@ -97,12 +97,12 @@
.opponent-name {
font-size: 32rpx;
font-weight: 600;
- color: #333;
+ color: var(--text-primary);
}
.opponent-level {
font-size: 24rpx;
- color: #666;
+ color: var(--text-secondary);
}
.vs-divider {
@@ -110,25 +110,25 @@
margin: 30rpx 0;
font-size: 32rpx;
font-weight: 600;
- color: #999;
+ color: var(--text-muted);
}
.match-progress {
margin-bottom: 40rpx;
padding-top: 30rpx;
- border-top: 2rpx solid #f0f0f0;
+ border-top: 2rpx solid var(--border-soft);
}
.progress-title {
font-size: 28rpx;
font-weight: 600;
- color: #333;
+ color: var(--text-primary);
margin-bottom: 20rpx;
}
.game-item {
- background: #f8f9fa;
- border-radius: 16rpx;
+ background: var(--bg-soft);
+ border-radius: var(--radius-md);
padding: 24rpx;
margin-bottom: 16rpx;
}
@@ -141,33 +141,33 @@
.score-label {
font-size: 24rpx;
- color: #666;
+ color: var(--text-secondary);
}
.score-value {
font-size: 32rpx;
font-weight: 600;
- color: #333;
+ color: var(--text-primary);
margin-left: 12rpx;
}
.game-status {
font-size: 24rpx;
- color: #999;
+ color: var(--text-muted);
}
.confirm-tip {
margin-top: 16rpx;
padding: 16rpx 20rpx;
- background: linear-gradient(135deg, #fff5f0 0%, #ffe8d6 100%);
- border-radius: 12rpx;
- border-left: 4rpx solid #ff6b35;
- box-shadow: 0 2rpx 8rpx rgba(255, 107, 53, 0.1);
+ background: var(--primary-gradient-soft);
+ border-radius: var(--radius-sm);
+ border-left: 4rpx solid var(--primary);
+ box-shadow: var(--shadow-sm);
}
.confirm-tip .tip-text {
font-size: 26rpx;
- color: #d84315;
+ color: var(--primary-dark);
font-weight: 500;
}
@@ -181,13 +181,13 @@
margin-top: 40rpx;
padding: 30rpx;
text-align: center;
- background: #f8f9fa;
- border-radius: 16rpx;
+ background: var(--bg-soft);
+ border-radius: var(--radius-md);
}
.tip-text {
font-size: 28rpx;
- color: #999;
+ color: var(--text-muted);
}
.action-btn {
@@ -203,41 +203,42 @@
}
.accept-btn {
- background: linear-gradient(135deg, #ff6b35 0%, #ff8c42 100%);
+ background: var(--primary-gradient);
color: #fff;
- box-shadow: 0 4rpx 16rpx rgba(255, 107, 53, 0.3);
+ box-shadow: var(--shadow-primary);
}
.accept-btn:active {
- background: linear-gradient(135deg, #e55a2b 0%, #e67e2f 100%);
- box-shadow: 0 2rpx 8rpx rgba(255, 107, 53, 0.4);
+ background: var(--primary-dark);
+ box-shadow: var(--shadow-md);
}
.reject-btn {
- background: #f5f5f5;
- color: #666;
+ background: var(--bg-white);
+ color: var(--text-secondary);
+ border: 2rpx solid var(--border-light);
}
.submit-btn {
- background: linear-gradient(135deg, #ff6b35 0%, #ff8c42 100%);
+ background: var(--primary-gradient);
color: #fff;
- box-shadow: 0 4rpx 16rpx rgba(255, 107, 53, 0.3);
+ box-shadow: var(--shadow-primary);
}
.submit-btn:active {
- background: linear-gradient(135deg, #e55a2b 0%, #e67e2f 100%);
- box-shadow: 0 2rpx 8rpx rgba(255, 107, 53, 0.4);
+ background: var(--primary-dark);
+ box-shadow: var(--shadow-md);
}
.confirm-btn {
- background: linear-gradient(135deg, #ff6b35 0%, #ff8c42 100%);
+ background: var(--primary-gradient);
color: #fff;
- box-shadow: 0 4rpx 16rpx rgba(255, 107, 53, 0.3);
+ box-shadow: var(--shadow-primary);
}
.confirm-btn:active {
- background: linear-gradient(135deg, #e55a2b 0%, #e67e2f 100%);
- box-shadow: 0 2rpx 8rpx rgba(255, 107, 53, 0.4);
+ background: var(--primary-dark);
+ box-shadow: var(--shadow-md);
}
/* 填写比分弹框 */
@@ -257,10 +258,10 @@
.score-modal-content {
width: 600rpx;
max-width: 90%;
- background: #fff;
- border-radius: 24rpx;
+ background: var(--bg-card);
+ border-radius: var(--radius-lg);
overflow: hidden;
- box-shadow: 0 16rpx 48rpx rgba(0, 0, 0, 0.15);
+ box-shadow: var(--shadow-lg);
}
.modal-header {
@@ -269,7 +270,7 @@
align-items: center;
padding: 32rpx 40rpx;
border-bottom: 2rpx solid rgba(255, 255, 255, 0.2);
- background: linear-gradient(135deg, #ff6b35 0%, #ff8c42 100%);
+ background: var(--primary-gradient);
}
.modal-header .modal-title {
@@ -311,7 +312,7 @@
.input-label {
display: block;
font-size: 28rpx;
- color: #333;
+ color: var(--text-primary);
font-weight: 500;
margin-bottom: 12rpx;
}
@@ -319,27 +320,27 @@
.score-input {
width: 100%;
height: 88rpx;
- background: #fff;
- border-radius: 12rpx;
+ background: var(--bg-white);
+ border-radius: var(--radius-sm);
padding: 0 24rpx;
font-size: 32rpx;
- color: #333;
- border: 2rpx solid #e0e0e0;
+ color: var(--text-primary);
+ border: 2rpx solid var(--border-light);
box-sizing: border-box;
transition: all 0.3s ease;
}
.score-input:focus {
- border-color: #ff6b35;
- background: #fff5f0;
+ border-color: var(--primary);
+ background: var(--primary-soft);
}
.modal-footer {
display: flex;
gap: 20rpx;
padding: 32rpx 40rpx;
- border-top: 2rpx solid #f0f0f0;
- background: #fafafa;
+ border-top: 2rpx solid var(--border-soft);
+ background: var(--bg-card-hover);
}
.modal-btn {
@@ -353,31 +354,31 @@
align-items: center;
justify-content: center;
transition: all 0.3s ease;
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
+ box-shadow: var(--shadow-sm);
}
.modal-btn:active {
transform: scale(0.98);
- box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.15);
+ box-shadow: var(--shadow-md);
}
.cancel-btn {
- background: #fff;
- color: #666;
- border: 2rpx solid #e0e0e0;
+ background: var(--bg-white);
+ color: var(--text-secondary);
+ border: 2rpx solid var(--border-light);
}
.cancel-btn:active {
- background: #f5f5f5;
+ background: var(--bg-soft);
}
.modal-btn.submit-btn {
- background: linear-gradient(135deg, #ff6b35 0%, #ff8c42 100%);
+ background: var(--primary-gradient);
color: #fff;
- box-shadow: 0 4rpx 16rpx rgba(255, 107, 53, 0.3);
+ box-shadow: var(--shadow-primary);
}
.modal-btn.submit-btn:active {
- background: linear-gradient(135deg, #e55a2b 0%, #e67e2f 100%);
- box-shadow: 0 2rpx 8rpx rgba(255, 107, 53, 0.4);
+ background: var(--primary-dark);
+ box-shadow: var(--shadow-md);
}
diff --git a/miniprogram/pages/match/challenge/index.js b/miniprogram/pages/match/challenge/index.js
index 9da9d621..23032703 100644
--- a/miniprogram/pages/match/challenge/index.js
+++ b/miniprogram/pages/match/challenge/index.js
@@ -1,27 +1,27 @@
-const app = getApp()
+const app = getApp();
Page({
data: {
userInfo: null,
ladderUser: null,
currentStore: null,
- ongoingMatches: [], // 正在进行中的比赛
- pendingGames: [] // 待确认的比赛
+ ongoingMatches: [], // 正在进行中的比赛
+ pendingGames: [], // 待确认的比赛
},
onLoad() {
- this.initData()
+ this.initData();
},
onShow() {
- this.initData()
+ this.initData();
},
async onPullDownRefresh() {
try {
- await this.initData()
+ await this.initData();
} finally {
- wx.stopPullDownRefresh()
+ wx.stopPullDownRefresh();
}
},
@@ -29,259 +29,284 @@ Page({
// 检查是否已登录(有 token)
if (!app.globalData.token) {
// 未登录,跳转到用户页面进行登录
- wx.switchTab({ url: '/pages/user/index' })
- return
+ wx.switchTab({ url: "/pages/user/index" });
+ return;
}
// 每次显示页面时重新获取门店和天梯信息
try {
- await app.getCurrentStore()
+ await app.getCurrentStore();
// 如果有门店,获取该门店的天梯信息
- if (app.globalData.currentStore?.storeId) {
- await app.getLadderUser(app.globalData.currentStore.storeId)
+ if (app.globalData.currentStore && app.globalData.currentStore.storeId) {
+ await app.getLadderUser(app.globalData.currentStore.storeId);
}
} catch (e) {
- console.error('获取门店/天梯信息失败:', e)
+ console.error("获取门店/天梯信息失败:", e);
}
- this.refreshData()
+ this.refreshData();
},
refreshData() {
this.setData({
userInfo: app.globalData.userInfo,
ladderUser: app.globalData.ladderUser,
- currentStore: app.globalData.currentStore
- })
+ currentStore: app.globalData.currentStore,
+ });
if (app.globalData.ladderUser) {
- this.fetchOngoingMatches()
- this.fetchPendingGames()
+ this.fetchOngoingMatches();
+ this.fetchPendingGames();
}
},
// 获取正在进行中的比赛
async fetchOngoingMatches() {
try {
- const res = await app.request('/api/match/ongoing', {
- store_id: this.data.currentStore?.storeId
- })
- this.setData({ ongoingMatches: res.data || [] })
+ const res = await app.request("/api/match/ongoing", {
+ store_id: this.data.currentStore
+ ? this.data.currentStore.storeId
+ : null,
+ });
+ this.setData({ ongoingMatches: res.data || [] });
} catch (e) {
- console.error('获取进行中比赛失败:', e)
+ console.error("获取进行中比赛失败:", e);
}
},
// 手动刷新天梯信息
async refreshLadderInfo() {
- wx.showLoading({ title: '刷新中...' })
-
+ wx.showLoading({ title: "刷新中..." });
+
try {
// 重新获取门店信息
- await app.getCurrentStore()
-
+ await app.getCurrentStore();
+
// 重新获取天梯信息
- if (app.globalData.currentStore?.storeId) {
- await app.getLadderUser(app.globalData.currentStore.storeId)
+ if (app.globalData.currentStore && app.globalData.currentStore.storeId) {
+ await app.getLadderUser(app.globalData.currentStore.storeId);
}
-
- this.refreshData()
- wx.hideLoading()
-
+
+ this.refreshData();
+ wx.hideLoading();
+
if (app.globalData.ladderUser) {
- wx.showToast({ title: '已加入天梯', icon: 'success' })
+ wx.showToast({ title: "已加入天梯", icon: "success" });
} else {
- wx.showToast({ title: '暂未开通天梯', icon: 'none' })
+ wx.showToast({ title: "暂未开通天梯", icon: "none" });
}
} catch (e) {
- wx.hideLoading()
- console.error('刷新天梯信息失败:', e)
- wx.showToast({ title: '刷新失败', icon: 'none' })
+ wx.hideLoading();
+ console.error("刷新天梯信息失败:", e);
+ wx.showToast({ title: "刷新失败", icon: "none" });
}
},
async fetchPendingGames() {
try {
- const res = await app.request('/api/match/pending-confirm', {
- store_id: this.data.currentStore?.storeId
- })
- this.setData({ pendingGames: res.data || [] })
+ const res = await app.request("/api/match/pending-confirm", {
+ store_id: this.data.currentStore
+ ? this.data.currentStore.storeId
+ : null,
+ });
+ this.setData({ pendingGames: res.data || [] });
} catch (e) {
- console.error('获取待确认比赛失败:', e)
+ console.error("获取待确认比赛失败:", e);
}
},
startChallenge() {
if (!this.data.ladderUser) {
- wx.showToast({ title: '请先加入天梯系统', icon: 'none' })
- return
+ wx.showToast({ title: "请先加入天梯系统", icon: "none" });
+ return;
+ }
+ if (!this.data.currentStore || !this.data.currentStore.storeId) {
+ wx.showToast({ title: "请先选择门店", icon: "none" });
+ wx.navigateTo({ url: "/pages/store/index" });
+ return;
}
wx.scanCode({
onlyFromCamera: false,
- scanType: ['qrCode'],
+ scanType: ["qrCode"],
success: async (res) => {
- const memberCode = res.result
- this.checkAndChallenge(memberCode)
+ const memberCode = res.result;
+ this.checkAndChallenge(memberCode);
},
fail: (err) => {
- if (err.errMsg !== 'scanCode:fail cancel') {
- wx.showToast({ title: '扫码失败', icon: 'none' })
+ if (err.errMsg !== "scanCode:fail cancel") {
+ wx.showToast({ title: "扫码失败", icon: "none" });
}
- }
- })
+ },
+ });
},
async checkAndChallenge(memberCode) {
- wx.showLoading({ title: '检查中...' })
+ wx.showLoading({ title: "检查中..." });
try {
- const res = await app.request(`/api/match/challenge/check/${memberCode}`, {
- store_id: this.data.currentStore.storeId
- })
+ const res = await app.request(
+ `/api/match/challenge/check/${memberCode}`,
+ {
+ store_id: this.data.currentStore.storeId,
+ },
+ );
- wx.hideLoading()
+ wx.hideLoading();
if (!res.data.canChallenge) {
wx.showModal({
- title: '无法挑战',
+ title: "无法挑战",
content: res.data.reason,
- showCancel: false
- })
- return
+ showCancel: false,
+ });
+ return;
}
// 显示确认弹窗
- const target = res.data.targetUser
+ const target = res.data.targetUser;
wx.showModal({
- title: '确认挑战',
+ title: "确认挑战",
content: `确定要向 ${target.ladderUser.realName}(Lv${target.ladderUser.level}, 战力${target.ladderUser.powerScore}) 发起挑战吗?`,
success: async (modalRes) => {
if (modalRes.confirm) {
- await this.createChallenge(memberCode)
+ await this.createChallenge(memberCode);
}
- }
- })
+ },
+ });
} catch (e) {
- wx.hideLoading()
- console.error('检查挑战失败:', e)
+ wx.hideLoading();
+ console.error("检查挑战失败:", e);
}
},
async createChallenge(memberCode) {
- wx.showLoading({ title: '发起挑战中...' })
+ wx.showLoading({ title: "发起挑战中..." });
try {
- const res = await app.request('/api/match/challenge/create', {
- store_id: this.data.currentStore.storeId,
- target_member_code: memberCode
- }, 'POST')
+ const res = await app.request(
+ "/api/match/challenge/create",
+ {
+ store_id: this.data.currentStore.storeId,
+ target_member_code: memberCode,
+ },
+ "POST",
+ );
+
+ wx.hideLoading();
+ wx.showToast({ title: "挑战已发起", icon: "success" });
- wx.hideLoading()
- wx.showToast({ title: '挑战已发起', icon: 'success' })
-
// 跳转到挑战赛详情页面
if (res.data && res.data.matchId) {
setTimeout(() => {
wx.navigateTo({
- url: `/pages/match/challenge-detail/index?id=${res.data.matchId}`
- })
- }, 1500)
+ url: `/pages/match/challenge-detail/index?id=${res.data.matchId}`,
+ });
+ }, 1500);
}
} catch (e) {
- wx.hideLoading()
- console.error('发起挑战失败:', e)
- const errorMsg = e.message || e.data?.message || '发起挑战失败'
- wx.showToast({ title: errorMsg, icon: 'none', duration: 2000 })
+ wx.hideLoading();
+ console.error("发起挑战失败:", e);
+ const errorMsg =
+ e.message || (e.data && e.data.message) || "发起挑战失败";
+ wx.showToast({ title: errorMsg, icon: "none", duration: 2000 });
}
},
joinRankingMatch() {
if (!this.data.ladderUser) {
- wx.showToast({ title: '请先加入天梯系统', icon: 'none' })
- return
+ wx.showToast({ title: "请先加入天梯系统", icon: "none" });
+ return;
}
wx.scanCode({
onlyFromCamera: false,
- scanType: ['qrCode'],
+ scanType: ["qrCode"],
success: async (res) => {
- const matchCode = res.result
- wx.showLoading({ title: '加入中...' })
+ const matchCode = res.result;
+ wx.showLoading({ title: "加入中..." });
try {
- const joinRes = await app.request('/api/match/ranking/join', {
- match_code: matchCode
- }, 'POST')
+ const joinRes = await app.request(
+ "/api/match/ranking/join",
+ {
+ match_code: matchCode,
+ },
+ "POST",
+ );
- wx.hideLoading()
- wx.showToast({ title: '加入成功', icon: 'success' })
+ wx.hideLoading();
+ wx.showToast({ title: "加入成功", icon: "success" });
// 跳转到排位赛详情
wx.navigateTo({
- url: `/pages/match/ranking/index?code=${matchCode}`
- })
+ url: `/pages/match/ranking/index?code=${matchCode}`,
+ });
} catch (e) {
- wx.hideLoading()
- console.error('加入排位赛失败:', e)
+ wx.hideLoading();
+ console.error("加入排位赛失败:", e);
}
},
fail: (err) => {
- if (err.errMsg !== 'scanCode:fail cancel') {
- wx.showToast({ title: '扫码失败', icon: 'none' })
+ if (err.errMsg !== "scanCode:fail cancel") {
+ wx.showToast({ title: "扫码失败", icon: "none" });
}
- }
- })
+ },
+ });
},
goToStore() {
- wx.navigateTo({ url: '/pages/store/index' })
+ wx.navigateTo({ url: "/pages/store/index" });
},
// 跳转到比赛详情
goToMatchDetail(e) {
- const match = e.currentTarget.dataset.match
+ const match = e.currentTarget.dataset.match;
if (match.type === 1) {
// 挑战赛详情
wx.navigateTo({
- url: `/pages/match/challenge-detail/index?id=${match.id}`
- })
+ url: `/pages/match/challenge-detail/index?id=${match.id}`,
+ });
} else {
// 排位赛详情
wx.navigateTo({
- url: `/pages/match/ranking/index?code=${match.matchCode}`
- })
+ url: `/pages/match/ranking/index?code=${match.matchCode}`,
+ });
}
},
confirmGame(e) {
- const game = e.currentTarget.dataset.game
+ const game = e.currentTarget.dataset.game;
wx.showModal({
- title: '确认比分',
+ title: "确认比分",
content: `确认比分 ${game.myScore} : ${game.opponentScore} 吗?`,
- confirmText: '确认',
- cancelText: '有争议',
+ confirmText: "确认",
+ cancelText: "有争议",
success: async (res) => {
- wx.showLoading({ title: '处理中...' })
+ wx.showLoading({ title: "处理中..." });
try {
- await app.request('/api/match/challenge/confirm-score', {
- game_id: game.id,
- confirm: res.confirm
- }, 'POST')
+ await app.request(
+ "/api/match/challenge/confirm-score",
+ {
+ game_id: game.id,
+ confirm: res.confirm,
+ },
+ "POST",
+ );
- wx.hideLoading()
+ wx.hideLoading();
wx.showToast({
- title: res.confirm ? '确认成功' : '已标记争议',
- icon: 'success'
- })
- this.fetchPendingGames()
+ title: res.confirm ? "确认成功" : "已标记争议",
+ icon: "success",
+ });
+ this.fetchPendingGames();
} catch (e) {
- wx.hideLoading()
- console.error('确认比分失败:', e)
+ wx.hideLoading();
+ console.error("确认比分失败:", e);
}
- }
- })
- }
-})
+ },
+ });
+ },
+});
diff --git a/miniprogram/pages/match/challenge/index.wxml b/miniprogram/pages/match/challenge/index.wxml
index 045358e9..3fe73198 100644
--- a/miniprogram/pages/match/challenge/index.wxml
+++ b/miniprogram/pages/match/challenge/index.wxml
@@ -9,20 +9,22 @@
- 📍
+
{{currentStore.storeName}}
›
- 🏸
+
+
+
暂未开通天梯
请联系门店工作人员加入天梯系统
@@ -67,7 +69,7 @@
- ⚔️
+
挑战赛
1v1 对决
@@ -76,7 +78,7 @@
- 🏆
+
排位赛
多人竞技
@@ -88,7 +90,7 @@
- ⏳ 等待中
- 🎾 比赛中
- ✅ 已完成
+ 等待中
+ 比赛中
+ 已完成
@@ -152,7 +154,7 @@
@@ -171,7 +173,9 @@
@@ -197,7 +201,9 @@
- 🛡
+
+
+
新手保护
输分减半
@@ -205,7 +211,7 @@
- 💡 同一对手30天内仅限挑战1次
+ 提示:同一对手30天内仅限挑战1次
diff --git a/miniprogram/pages/match/challenge/index.wxss b/miniprogram/pages/match/challenge/index.wxss
index 4a5b9ad3..af11074f 100644
--- a/miniprogram/pages/match/challenge/index.wxss
+++ b/miniprogram/pages/match/challenge/index.wxss
@@ -4,7 +4,12 @@
.page-container {
min-height: 100vh;
- background: linear-gradient(180deg, #FEF7F3 0%, #FAFAFA 30%, #F5F5F5 100%);
+ background: linear-gradient(
+ 180deg,
+ var(--primary-soft) 0%,
+ var(--bg-page) 30%,
+ var(--bg-soft) 100%
+ );
position: relative;
overflow: hidden;
}
@@ -42,7 +47,9 @@
}
@keyframes spin {
- to { transform: translateX(-50%) rotate(360deg); }
+ to {
+ transform: translateX(-50%) rotate(360deg);
+ }
}
/* 主要内容 */
@@ -63,7 +70,7 @@
display: block;
font-size: 52rpx;
font-weight: 700;
- color: #1a1a1a;
+ color: var(--text-primary);
margin-bottom: 12rpx;
letter-spacing: 1rpx;
}
@@ -71,7 +78,7 @@
.page-subtitle {
display: block;
font-size: 26rpx;
- color: #999;
+ color: var(--text-muted);
font-weight: 400;
letter-spacing: 0.5rpx;
}
@@ -88,11 +95,12 @@
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
margin: 0 auto 24rpx;
width: fit-content;
- border: 1rpx solid rgba(0, 0, 0, 0.04);
+ border: 1rpx solid var(--border-soft);
}
.store-icon {
- font-size: 28rpx;
+ width: 28rpx;
+ height: 28rpx;
}
.store-name {
@@ -117,8 +125,12 @@
align-items: center;
gap: 20rpx;
padding: 28rpx 24rpx;
- background: linear-gradient(135deg, #FFF9F5 0%, #FFFFFF 100%);
- border: 2rpx solid #FFE8D5;
+ background: linear-gradient(
+ 135deg,
+ var(--primary-soft) 0%,
+ var(--bg-white) 100%
+ );
+ border: 2rpx solid var(--border-primary);
border-radius: 24rpx;
margin-bottom: 24rpx;
box-shadow: 0 4rpx 16rpx rgba(255, 152, 0, 0.1);
@@ -127,12 +139,16 @@
.notice-icon {
width: 80rpx;
height: 80rpx;
- background: linear-gradient(135deg, #FFF3E0, #FFE0B2);
+ background: var(--primary-gradient-soft);
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
- font-size: 40rpx;
+}
+
+.notice-icon-img {
+ width: 44rpx;
+ height: 44rpx;
}
.notice-content {
@@ -143,21 +159,21 @@
display: block;
font-size: 30rpx;
font-weight: 700;
- color: #E65100;
+ color: var(--primary-dark);
margin-bottom: 6rpx;
}
.notice-desc {
display: block;
font-size: 24rpx;
- color: #F57C00;
+ color: var(--primary);
}
.notice-action {
padding: 16rpx 28rpx;
- background: linear-gradient(135deg, #FF8A65, #FF6B35);
+ background: var(--primary-gradient);
border-radius: 50rpx;
- box-shadow: 0 4rpx 12rpx rgba(255, 107, 53, 0.3);
+ box-shadow: var(--shadow-primary);
}
.notice-action:active {
@@ -174,13 +190,17 @@
用户信息卡片 - 全新设计
========================================== */
.user-card {
- background: linear-gradient(135deg, #FFFFFF 0%, #FAFAFA 100%);
+ background: linear-gradient(
+ 135deg,
+ var(--bg-white) 0%,
+ var(--bg-card-hover) 100%
+ );
border-radius: 28rpx;
padding: 0;
margin-bottom: 24rpx;
box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.08);
overflow: hidden;
- border: 1rpx solid rgba(255, 107, 53, 0.1);
+ border: 1rpx solid var(--border-primary);
}
.user-card-inner {
@@ -192,13 +212,13 @@
}
.user-card-inner::before {
- content: '';
+ content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 6rpx;
- background: linear-gradient(90deg, #FF8A65, #FF6B35, #FFB74D);
+ background: var(--primary-gradient);
}
.user-avatar-box {
@@ -209,10 +229,10 @@
}
.user-avatar-box::before {
- content: '';
+ content: "";
position: absolute;
inset: -6rpx;
- background: linear-gradient(135deg, #FF8A65, #FFB74D);
+ background: var(--primary-gradient);
border-radius: 50%;
z-index: 0;
}
@@ -253,11 +273,26 @@
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
-.user-level.lv1 { background: linear-gradient(135deg, #81C784, #66BB6A); color: #fff; }
-.user-level.lv2 { background: linear-gradient(135deg, #64B5F6, #42A5F5); color: #fff; }
-.user-level.lv3 { background: linear-gradient(135deg, #FFB74D, #FFA726); color: #fff; }
-.user-level.lv4 { background: linear-gradient(135deg, #F06292, #EC407A); color: #fff; }
-.user-level.lv5 { background: linear-gradient(135deg, #BA68C8, #AB47BC); color: #fff; }
+.user-level.lv1 {
+ background: linear-gradient(135deg, #81c784, #66bb6a);
+ color: #fff;
+}
+.user-level.lv2 {
+ background: linear-gradient(135deg, #64b5f6, #42a5f5);
+ color: #fff;
+}
+.user-level.lv3 {
+ background: linear-gradient(135deg, #ffb74d, #ffa726);
+ color: #fff;
+}
+.user-level.lv4 {
+ background: linear-gradient(135deg, #f06292, #ec407a);
+ color: #fff;
+}
+.user-level.lv5 {
+ background: linear-gradient(135deg, #ba68c8, #ab47bc);
+ color: #fff;
+}
.user-stats-row {
display: flex;
@@ -278,7 +313,7 @@
}
.mini-stat-value.win {
- color: #00C853;
+ color: #00c853;
}
.mini-stat-label {
@@ -318,7 +353,7 @@
}
.scan-card::before {
- content: '';
+ content: "";
position: absolute;
top: 0;
left: 0;
@@ -329,11 +364,19 @@
}
.scan-card.challenge::before {
- background: linear-gradient(180deg, rgba(255, 107, 53, 0.08) 0%, transparent 50%);
+ background: linear-gradient(
+ 180deg,
+ rgba(255, 107, 53, 0.08) 0%,
+ transparent 50%
+ );
}
.scan-card.ranking::before {
- background: linear-gradient(180deg, rgba(255, 193, 7, 0.1) 0%, transparent 50%);
+ background: linear-gradient(
+ 180deg,
+ rgba(255, 193, 7, 0.1) 0%,
+ transparent 50%
+ );
}
.scan-card:active {
@@ -357,15 +400,16 @@
}
.scan-card.challenge .scan-icon-wrapper {
- background: linear-gradient(135deg, #FFE8DD, #FFCCBC);
+ background: linear-gradient(135deg, #ffe8dd, #ffccbc);
}
.scan-card.ranking .scan-icon-wrapper {
- background: linear-gradient(135deg, #FFF8E1, #FFE082);
+ background: linear-gradient(135deg, #fff8e1, #ffe082);
}
-.scan-icon {
- font-size: 52rpx;
+.scan-icon-img {
+ width: 56rpx;
+ height: 56rpx;
}
.scan-title {
@@ -387,7 +431,7 @@
.scan-badge {
display: inline-block;
padding: 8rpx 20rpx;
- background: linear-gradient(135deg, #FF8A65, #FF6B35);
+ background: linear-gradient(135deg, #ff8a65, #ff6b35);
color: #fff;
font-size: 22rpx;
font-weight: 700;
@@ -396,8 +440,8 @@
}
.scan-badge.accent {
- background: linear-gradient(135deg, #FFD54F, #FFB300);
- color: #5D4037;
+ background: linear-gradient(135deg, #ffd54f, #ffb300);
+ color: #5d4037;
box-shadow: 0 4rpx 12rpx rgba(255, 179, 0, 0.3);
}
@@ -418,7 +462,7 @@
align-items: center;
justify-content: space-between;
padding: 20rpx 24rpx;
- background: linear-gradient(90deg, #FFF3E0, #FFFFFF);
+ background: linear-gradient(90deg, #fff3e0, #ffffff);
border-bottom: 1rpx solid rgba(255, 152, 0, 0.1);
}
@@ -428,8 +472,10 @@
gap: 10rpx;
}
-.ongoing-icon {
- font-size: 28rpx;
+.ongoing-icon-img {
+ width: 28rpx;
+ height: 28rpx;
+ opacity: 0.9;
}
.ongoing-title {
@@ -442,7 +488,7 @@
min-width: 40rpx;
height: 40rpx;
padding: 0 14rpx;
- background: linear-gradient(135deg, #FF5722, #FF8A65);
+ background: linear-gradient(135deg, #ff5722, #ff8a65);
color: #fff;
font-size: 24rpx;
font-weight: 700;
@@ -458,7 +504,7 @@
}
.ongoing-item {
- background: linear-gradient(135deg, #FAFAFA, #F5F5F5);
+ background: linear-gradient(135deg, #fafafa, #f5f5f5);
border-radius: 20rpx;
margin-bottom: 16rpx;
overflow: hidden;
@@ -498,13 +544,13 @@
}
.match-type-tag.challenge {
- background: linear-gradient(135deg, #FFE8DD, #FFCCBC);
- color: #E65100;
+ background: linear-gradient(135deg, #ffe8dd, #ffccbc);
+ color: #e65100;
}
.match-type-tag.ranking {
- background: linear-gradient(135deg, #FFF8E1, #FFE082);
- color: #F57C00;
+ background: linear-gradient(135deg, #fff8e1, #ffe082);
+ color: #f57c00;
}
.match-status-tag {
@@ -515,19 +561,24 @@
}
.match-status-tag.waiting {
- background: #E3F2FD;
- color: #1565C0;
+ background: #e3f2fd;
+ color: #1565c0;
}
.match-status-tag.playing {
- background: #E8F5E9;
- color: #2E7D32;
+ background: #e8f5e9;
+ color: #2e7d32;
animation: pulse 2s infinite;
}
@keyframes pulse {
- 0%, 100% { opacity: 1; }
- 50% { opacity: 0.7; }
+ 0%,
+ 100% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0.7;
+ }
}
.ongoing-item-body {
@@ -545,7 +596,7 @@
width: 80rpx;
height: 80rpx;
border-radius: 50%;
- border: 3rpx solid #FFE0B2;
+ border: 3rpx solid #ffe0b2;
}
.opponent-detail {
@@ -567,7 +618,7 @@
.opponent-level {
padding: 4rpx 12rpx;
- background: linear-gradient(135deg, #FFB74D, #FFA726);
+ background: linear-gradient(135deg, #ffb74d, #ffa726);
color: #fff;
font-size: 20rpx;
font-weight: 600;
@@ -601,8 +652,8 @@
.ranking-stage {
padding: 4rpx 12rpx;
- background: #E3F2FD;
- color: #1565C0;
+ background: #e3f2fd;
+ color: #1565c0;
border-radius: 6rpx;
font-weight: 600;
}
@@ -633,11 +684,11 @@
}
.my-status.waiting {
- color: #1565C0;
+ color: #1565c0;
}
.my-status.playing {
- color: #2E7D32;
+ color: #2e7d32;
}
.my-status.finished {
@@ -655,7 +706,7 @@
.match-weight {
padding: 4rpx 12rpx;
- background: linear-gradient(135deg, #FF8A65, #FF6B35);
+ background: linear-gradient(135deg, #ff8a65, #ff6b35);
color: #fff;
font-size: 20rpx;
font-weight: 600;
@@ -685,7 +736,7 @@
align-items: center;
justify-content: space-between;
padding: 20rpx 24rpx;
- background: linear-gradient(90deg, #FFF5F2, #FFFFFF);
+ background: linear-gradient(90deg, #fff5f2, #ffffff);
border-bottom: 1rpx solid rgba(255, 107, 53, 0.1);
}
@@ -699,7 +750,7 @@
min-width: 40rpx;
height: 40rpx;
padding: 0 14rpx;
- background: linear-gradient(135deg, #FF8A65, #FF6B35);
+ background: linear-gradient(135deg, #ff8a65, #ff6b35);
color: #fff;
font-size: 24rpx;
font-weight: 700;
@@ -718,7 +769,7 @@
display: flex;
align-items: center;
padding: 18rpx 20rpx;
- background: linear-gradient(135deg, #FAFAFA, #F5F5F5);
+ background: linear-gradient(135deg, #fafafa, #f5f5f5);
border-radius: 16rpx;
margin-bottom: 12rpx;
transition: all 0.2s;
@@ -729,7 +780,7 @@
}
.pending-item:active {
- background: linear-gradient(135deg, #F5F5F5, #EEEEEE);
+ background: linear-gradient(135deg, #f5f5f5, #eeeeee);
}
.game-info {
@@ -741,7 +792,7 @@
.vs-tag {
padding: 6rpx 14rpx;
- background: linear-gradient(135deg, #FF8A65, #FF6B35);
+ background: linear-gradient(135deg, #ff8a65, #ff6b35);
color: #fff;
font-size: 20rpx;
font-weight: 800;
@@ -759,12 +810,12 @@
font-weight: 800;
color: var(--text-primary);
padding: 0 20rpx;
- font-family: 'SF Mono', 'Monaco', monospace;
+ font-family: "SF Mono", "Monaco", monospace;
}
.confirm-btn {
padding: 14rpx 28rpx;
- background: linear-gradient(135deg, #00C853, #00E676);
+ background: linear-gradient(135deg, #00c853, #00e676);
color: #fff;
font-size: 24rpx;
font-weight: 700;
@@ -798,12 +849,16 @@
.rules-icon {
width: 48rpx;
height: 48rpx;
- background: linear-gradient(135deg, #FFF3E0, #FFE0B2);
+ background: linear-gradient(135deg, #fff3e0, #ffe0b2);
border-radius: 14rpx;
display: flex;
align-items: center;
justify-content: center;
- font-size: 26rpx;
+}
+
+.rules-icon-img {
+ width: 28rpx;
+ height: 28rpx;
}
.rules-title {
@@ -823,7 +878,7 @@
align-items: center;
gap: 14rpx;
padding: 18rpx;
- background: linear-gradient(135deg, #FAFAFA, #F5F5F5);
+ background: linear-gradient(135deg, #fafafa, #f5f5f5);
border-radius: 18rpx;
transition: all 0.2s;
}
@@ -844,24 +899,29 @@
flex-shrink: 0;
}
+.rule-icon-img {
+ width: 28rpx;
+ height: 28rpx;
+}
+
.rule-icon.win {
- background: linear-gradient(135deg, #E8F5E9, #C8E6C9);
- color: #2E7D32;
+ background: linear-gradient(135deg, #e8f5e9, #c8e6c9);
+ color: #2e7d32;
}
.rule-icon.lose {
- background: linear-gradient(135deg, #FFEBEE, #FFCDD2);
- color: #C62828;
+ background: linear-gradient(135deg, #ffebee, #ffcdd2);
+ color: #c62828;
}
.rule-icon.bonus {
- background: linear-gradient(135deg, #FFF8E1, #FFECB3);
- color: #F57C00;
+ background: linear-gradient(135deg, #fff8e1, #ffecb3);
+ color: #f57c00;
}
.rule-icon.shield {
- background: linear-gradient(135deg, #E3F2FD, #BBDEFB);
- color: #1565C0;
+ background: linear-gradient(135deg, #e3f2fd, #bbdefb);
+ color: #1565c0;
}
.rule-text {
@@ -884,21 +944,21 @@
}
.rule-value.positive {
- color: #2E7D32;
+ color: #2e7d32;
}
.rule-value.negative {
- color: #C62828;
+ color: #c62828;
}
.rules-note {
margin-top: 18rpx;
padding: 18rpx;
- background: linear-gradient(135deg, #FFF8E1, #FFFDE7);
+ background: linear-gradient(135deg, #fff8e1, #fffde7);
border-radius: 14rpx;
text-align: center;
font-size: 24rpx;
- color: #F57C00;
+ color: #f57c00;
font-weight: 600;
border: 1rpx solid rgba(255, 152, 0, 0.15);
}
diff --git a/miniprogram/pages/match/history/index.js b/miniprogram/pages/match/history/index.js
index 2bb1804d..25257b96 100644
--- a/miniprogram/pages/match/history/index.js
+++ b/miniprogram/pages/match/history/index.js
@@ -1,5 +1,5 @@
-const app = getApp()
-const util = require('../../../utils/util')
+const app = getApp();
+const util = require("../../../utils/util");
Page({
data: {
@@ -7,89 +7,89 @@ Page({
loading: false,
page: 1,
pageSize: 20,
- hasMore: true
+ hasMore: true,
},
onLoad() {
- this.fetchMatches()
+ this.fetchMatches();
},
onShow() {
// 门店切换后刷新数据
if (app.globalData.storeChanged) {
- app.globalData.storeChanged = false
- this.setData({ page: 1, hasMore: true, matches: [] })
- this.fetchMatches()
+ app.globalData.storeChanged = false;
+ this.setData({ page: 1, hasMore: true, matches: [] });
+ this.fetchMatches();
}
},
onPullDownRefresh() {
- this.setData({ page: 1, hasMore: true })
+ this.setData({ page: 1, hasMore: true });
this.fetchMatches().then(() => {
- wx.stopPullDownRefresh()
- })
+ wx.stopPullDownRefresh();
+ });
},
onReachBottom() {
if (this.data.hasMore && !this.data.loading) {
- this.loadMore()
+ this.loadMore();
}
},
async fetchMatches() {
- const currentStore = app.globalData.currentStore
- if (!currentStore?.storeId) {
- return
+ const currentStore = app.globalData.currentStore;
+ if (!currentStore || !currentStore.storeId) {
+ return;
}
- this.setData({ loading: true })
+ this.setData({ loading: true });
try {
- const res = await app.request('/api/match/my-matches', {
+ const res = await app.request("/api/match/my-matches", {
store_id: currentStore.storeId,
page: this.data.page,
- pageSize: this.data.pageSize
- })
+ pageSize: this.data.pageSize,
+ });
- const matches = (res.data.list || []).map(match => {
+ const matches = (res.data.list || []).map((match) => {
// 确保 powerChange 是数字类型,移除可能存在的加号和其他非数字字符
- let powerChange = match.powerChange
+ let powerChange = match.powerChange;
if (powerChange != null && powerChange !== undefined) {
// 如果是字符串,移除所有加号、空格等非数字字符(保留负号)
- if (typeof powerChange === 'string') {
+ if (typeof powerChange === "string") {
// 保留负号,移除所有加号和其他字符
- const cleaned = powerChange.replace(/\+/g, '').trim()
- powerChange = parseFloat(cleaned) || 0
+ const cleaned = powerChange.replace(/\+/g, "").trim();
+ powerChange = parseFloat(cleaned) || 0;
}
// 确保是数字类型
- powerChange = Number(powerChange)
+ powerChange = Number(powerChange);
// 如果是 NaN,设为 0
if (isNaN(powerChange)) {
- powerChange = 0
+ powerChange = 0;
}
} else {
- powerChange = 0
+ powerChange = 0;
}
- return {
- ...match,
+ return Object.assign({}, match, {
powerChange: powerChange,
- confirmedAt: util.formatDate(match.confirmedAt)
- }
- })
+ confirmedAt: util.formatDate(match.confirmedAt),
+ });
+ });
this.setData({
- matches: this.data.page === 1 ? matches : [...this.data.matches, ...matches],
- hasMore: matches.length >= this.data.pageSize
- })
+ matches:
+ this.data.page === 1 ? matches : this.data.matches.concat(matches),
+ hasMore: matches.length >= this.data.pageSize,
+ });
} catch (e) {
- console.error('获取比赛记录失败:', e)
+ console.error("获取比赛记录失败:", e);
} finally {
- this.setData({ loading: false })
+ this.setData({ loading: false });
}
},
loadMore() {
- this.setData({ page: this.data.page + 1 })
- this.fetchMatches()
- }
-})
+ this.setData({ page: this.data.page + 1 });
+ this.fetchMatches();
+ },
+});
diff --git a/miniprogram/pages/match/history/index.wxss b/miniprogram/pages/match/history/index.wxss
index ba5a4d79..7460e4e1 100644
--- a/miniprogram/pages/match/history/index.wxss
+++ b/miniprogram/pages/match/history/index.wxss
@@ -4,7 +4,7 @@
.container {
min-height: 100vh;
- background: #f5f5f5;
+ background: var(--bg-page);
padding: 20rpx;
}
@@ -15,10 +15,10 @@
}
.match-item {
- background: #fff;
+ background: var(--bg-card);
border-radius: 20rpx;
overflow: hidden;
- box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
+ box-shadow: var(--shadow-card);
transition: all 0.3s ease;
}
@@ -32,7 +32,7 @@
justify-content: space-between;
align-items: center;
padding: 24rpx 28rpx;
- background: linear-gradient(135deg, #ff6b35 0%, #ff8c42 100%);
+ background: var(--primary-gradient);
border-bottom: 2rpx solid rgba(255, 255, 255, 0.2);
}
@@ -74,13 +74,13 @@
}
.result.win {
- background: linear-gradient(135deg, #4caf50 0%, #66bb6a 100%);
+ background: linear-gradient(135deg, var(--success) 0%, #34d399 100%);
color: #fff;
box-shadow: 0 4rpx 12rpx rgba(76, 175, 80, 0.3);
}
.result.lose {
- background: linear-gradient(135deg, #f44336 0%, #ef5350 100%);
+ background: linear-gradient(135deg, var(--danger) 0%, #f87171 100%);
color: #fff;
box-shadow: 0 4rpx 12rpx rgba(244, 67, 54, 0.3);
}
@@ -94,14 +94,14 @@
.opponent {
font-size: 28rpx;
- color: #666;
+ color: var(--text-secondary);
font-weight: 500;
}
.score {
font-size: 40rpx;
font-weight: 700;
- color: #333;
+ color: var(--text-primary);
letter-spacing: 4rpx;
}
@@ -126,13 +126,13 @@
.match-footer {
padding: 20rpx 28rpx;
- background: #fafafa;
- border-top: 1rpx solid #f0f0f0;
+ background: var(--bg-card-hover);
+ border-top: 1rpx solid var(--border-soft);
}
.match-time {
font-size: 24rpx;
- color: #999;
+ color: var(--text-muted);
}
.empty-state {
diff --git a/miniprogram/pages/match/ranking/index.wxml b/miniprogram/pages/match/ranking/index.wxml
index 46c089c9..e65546b7 100644
--- a/miniprogram/pages/match/ranking/index.wxml
+++ b/miniprogram/pages/match/ranking/index.wxml
@@ -9,7 +9,9 @@