805 lines
19 KiB
Vue
805 lines
19 KiB
Vue
|
|
<template>
|
|||
|
|
<view class="scoring-page">
|
|||
|
|
<!-- 顶部导航栏 -->
|
|||
|
|
<view class="header">
|
|||
|
|
<view class="back-btn" @click="goBack">
|
|||
|
|
<uni-icons type="arrow-left" size="24" color="#fff"></uni-icons>
|
|||
|
|
</view>
|
|||
|
|
<view class="title">第{{ roundCount }}局</view>
|
|||
|
|
<view class="header-right">
|
|||
|
|
<view class="more-btn" @click="showMoreOptions">...</view>
|
|||
|
|
<view class="separator"></view>
|
|||
|
|
<view class="sound-toggle" @click="toggleSound">
|
|||
|
|
<text class="sound-icon">{{ soundEnabled ? '🔊' : '🔇' }}</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 玩家列表区域 -->
|
|||
|
|
<view class="players-list">
|
|||
|
|
<!-- 表头 -->
|
|||
|
|
<view class="list-header">
|
|||
|
|
<view class="col-player">玩家</view>
|
|||
|
|
<view class="col-result">胜负</view>
|
|||
|
|
<view class="col-score">得分</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 玩家行 -->
|
|||
|
|
<view
|
|||
|
|
v-for="(player, index) in players"
|
|||
|
|
:key="player.id"
|
|||
|
|
class="player-row"
|
|||
|
|
:class="{ 'selected': selectedPlayerIndex === index }"
|
|||
|
|
@click="selectPlayer(index)"
|
|||
|
|
>
|
|||
|
|
<view class="col-player">
|
|||
|
|
<image :src="player.avatar" mode="aspectFill" class="player-avatar"></image>
|
|||
|
|
<text class="player-name">{{ player.name }}</text>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="col-result">
|
|||
|
|
<view class="result-buttons">
|
|||
|
|
<button
|
|||
|
|
class="result-btn win"
|
|||
|
|
:class="{ 'active': player.result === 'win' }"
|
|||
|
|
@click.stop="setPlayerResult(index, 'win')"
|
|||
|
|
>胜</button>
|
|||
|
|
<button
|
|||
|
|
class="result-btn lose"
|
|||
|
|
:class="{ 'active': player.result === 'lose' }"
|
|||
|
|
@click.stop="setPlayerResult(index, 'lose')"
|
|||
|
|
>负</button>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<view class="col-score">
|
|||
|
|
<view class="score-input-container">
|
|||
|
|
<input
|
|||
|
|
type="number"
|
|||
|
|
class="score-input"
|
|||
|
|
:value="selectedPlayerIndex === index && showKeyboard ? currentInput : player.score"
|
|||
|
|
@focus.prevent
|
|||
|
|
@click.stop="selectPlayer(index)"
|
|||
|
|
readonly
|
|||
|
|
disabled
|
|||
|
|
/>
|
|||
|
|
<!-- 合分按钮 -->
|
|||
|
|
<button
|
|||
|
|
class="combine-btn"
|
|||
|
|
@click.stop="combineScore(index)"
|
|||
|
|
:disabled="!selectedPlayerIndex === index"
|
|||
|
|
>合分</button>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 底部数字键盘 -->
|
|||
|
|
<view class="number-keyboard" v-if="showKeyboard">
|
|||
|
|
<view class="keyboard-row">
|
|||
|
|
<view class="key" @click="inputNumber(1)">1</view>
|
|||
|
|
<view class="key" @click="inputNumber(2)">2</view>
|
|||
|
|
<view class="key" @click="inputNumber(3)">3</view>
|
|||
|
|
<view class="key operation" @click="inputOperation('+')">+</view>
|
|||
|
|
<view class="key delete" @click="deleteLastChar">
|
|||
|
|
<text>⌫</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="keyboard-row">
|
|||
|
|
<view class="key" @click="inputNumber(4)">4</view>
|
|||
|
|
<view class="key" @click="inputNumber(5)">5</view>
|
|||
|
|
<view class="key" @click="inputNumber(6)">6</view>
|
|||
|
|
<view class="key operation" @click="inputOperation('-')">-</view>
|
|||
|
|
<view class="key empty"></view>
|
|||
|
|
</view>
|
|||
|
|
<view class="keyboard-row">
|
|||
|
|
<view class="key" @click="inputNumber(7)">7</view>
|
|||
|
|
<view class="key" @click="inputNumber(8)">8</view>
|
|||
|
|
<view class="key" @click="inputNumber(9)">9</view>
|
|||
|
|
<view class="key operation" @click="clearInput">C</view>
|
|||
|
|
<view class="key confirm" @click="confirmInput">提交</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="keyboard-row">
|
|||
|
|
<view class="key zero" @click="inputNumber(0)">0</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 底部操作栏 -->
|
|||
|
|
<view class="bottom-actions" v-if="!showKeyboard">
|
|||
|
|
<button class="action-btn" type="default" @click="nextRound">下一局</button>
|
|||
|
|
<button class="action-btn primary" type="primary" @click="endGame">结束对局</button>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script setup>
|
|||
|
|
import { ref, onMounted, onUnmounted } from 'vue'
|
|||
|
|
|
|||
|
|
// 从上个页面接收的玩家数据
|
|||
|
|
const players = ref([])
|
|||
|
|
const roundCount = ref(1)
|
|||
|
|
const history = ref([])
|
|||
|
|
const selectedPlayerIndex = ref(-1)
|
|||
|
|
const showKeyboard = ref(false)
|
|||
|
|
const currentInput = ref('')
|
|||
|
|
const soundEnabled = ref(true)
|
|||
|
|
|
|||
|
|
// 初始化玩家数据
|
|||
|
|
const loadPlayersData = () => {
|
|||
|
|
try {
|
|||
|
|
const playersData = uni.getStorageSync('currentPlayers')
|
|||
|
|
if (playersData) {
|
|||
|
|
// 解析并添加result字段
|
|||
|
|
const parsedPlayers = JSON.parse(playersData).map(player => ({
|
|||
|
|
...player,
|
|||
|
|
result: '', // 初始胜负状态为空
|
|||
|
|
score: player.score || 0
|
|||
|
|
}))
|
|||
|
|
players.value = parsedPlayers
|
|||
|
|
saveHistoryState()
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('加载玩家数据失败:', error)
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '加载数据失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 保存历史状态
|
|||
|
|
const saveHistoryState = () => {
|
|||
|
|
const stateCopy = JSON.parse(JSON.stringify(players.value))
|
|||
|
|
history.value.push(stateCopy)
|
|||
|
|
if (history.value.length > 50) {
|
|||
|
|
history.value.shift()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 返回上一页
|
|||
|
|
const goBack = () => {
|
|||
|
|
uni.showModal({
|
|||
|
|
title: '提示',
|
|||
|
|
content: '当前分数未保存,确定要返回吗?',
|
|||
|
|
success: (res) => {
|
|||
|
|
if (res.confirm) {
|
|||
|
|
uni.navigateBack()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 选择玩家
|
|||
|
|
const selectPlayer = (index) => {
|
|||
|
|
selectedPlayerIndex.value = index
|
|||
|
|
showKeyboard.value = true
|
|||
|
|
// 显示当前分数
|
|||
|
|
currentInput.value = players.value[index].score.toString()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 设置玩家胜负
|
|||
|
|
const setPlayerResult = (index, result) => {
|
|||
|
|
// 如果已经是当前状态,则取消选择
|
|||
|
|
if (players.value[index].result === result) {
|
|||
|
|
players.value[index].result = ''
|
|||
|
|
// 取消状态时,保持当前分数符号不变
|
|||
|
|
} else {
|
|||
|
|
players.value[index].result = result
|
|||
|
|
|
|||
|
|
// 根据胜负状态调整分数正负号,并考虑当前输入框的内容
|
|||
|
|
let currentScore = players.value[index].score
|
|||
|
|
let currentInputValue = currentInput.value
|
|||
|
|
|
|||
|
|
if (result === 'win') {
|
|||
|
|
// 胜利时确保分数为正数
|
|||
|
|
if (currentScore !== 0) {
|
|||
|
|
// 根据输入框当前内容或分数值判断是否需要调整符号
|
|||
|
|
if (currentInputValue && currentInputValue !== '-' && parseInt(currentInputValue) !== 0) {
|
|||
|
|
// 使用输入框的值并确保为正数
|
|||
|
|
currentScore = Math.abs(parseInt(currentInputValue))
|
|||
|
|
} else {
|
|||
|
|
// 使用现有分数值并确保为正数
|
|||
|
|
currentScore = Math.abs(currentScore)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
} else if (result === 'lose') {
|
|||
|
|
// 失败时确保分数为负数
|
|||
|
|
if (currentScore !== 0) {
|
|||
|
|
// 根据输入框当前内容或分数值判断是否需要调整符号
|
|||
|
|
if (currentInputValue && currentInputValue !== '-' && parseInt(currentInputValue) !== 0) {
|
|||
|
|
// 使用输入框的值并确保为负数
|
|||
|
|
currentScore = -Math.abs(parseInt(currentInputValue))
|
|||
|
|
} else {
|
|||
|
|
// 使用现有分数值并确保为负数
|
|||
|
|
currentScore = -Math.abs(currentScore)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新分数
|
|||
|
|
players.value[index].score = currentScore
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果当前正在编辑该玩家,同步更新currentInput
|
|||
|
|
if (selectedPlayerIndex.value === index && showKeyboard.value) {
|
|||
|
|
currentInput.value = players.value[index].score.toString()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
saveHistoryState()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 数字键盘输入
|
|||
|
|
const inputNumber = (num) => {
|
|||
|
|
// 处理特殊情况:如果当前是负号,直接添加数字
|
|||
|
|
if (currentInput.value === '-') {
|
|||
|
|
currentInput.value += num.toString()
|
|||
|
|
}
|
|||
|
|
// 避免以0开头的数字(除了单独的0和负数中的0)
|
|||
|
|
else if (currentInput.value === '0' && num !== 0) {
|
|||
|
|
currentInput.value = num.toString()
|
|||
|
|
}
|
|||
|
|
// 避免输入过多的数字
|
|||
|
|
else if (currentInput.value.length < 10) {
|
|||
|
|
currentInput.value += num.toString()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 实时保存输入内容到玩家分数(不等待提交)
|
|||
|
|
if (selectedPlayerIndex.value !== -1) {
|
|||
|
|
let score = 0
|
|||
|
|
if (currentInput.value && currentInput.value !== '-') {
|
|||
|
|
score = parseInt(currentInput.value)
|
|||
|
|
if (isNaN(score)) {
|
|||
|
|
score = 0
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
players.value[selectedPlayerIndex.value].score = score
|
|||
|
|
saveHistoryState()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 操作符输入
|
|||
|
|
const inputOperation = (op) => {
|
|||
|
|
if (op === '-') {
|
|||
|
|
// 支持负数输入
|
|||
|
|
if (currentInput.value === '') {
|
|||
|
|
// 当输入框为空时,按减号开始负数输入
|
|||
|
|
currentInput.value = '-'
|
|||
|
|
} else if (currentInput.value.startsWith('-')) {
|
|||
|
|
// 如果已经是负数,移除负号变为正数
|
|||
|
|
currentInput.value = currentInput.value.substring(1)
|
|||
|
|
} else {
|
|||
|
|
// 如果已有数字,添加负号变为负数
|
|||
|
|
currentInput.value = '-' + currentInput.value
|
|||
|
|
}
|
|||
|
|
} else if (op === '+') {
|
|||
|
|
// 按加号确保是正数(移除负号)
|
|||
|
|
if (currentInput.value.startsWith('-')) {
|
|||
|
|
currentInput.value = currentInput.value.substring(1)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 实时保存操作符结果到玩家分数
|
|||
|
|
if (selectedPlayerIndex.value !== -1) {
|
|||
|
|
let score = 0
|
|||
|
|
if (currentInput.value && currentInput.value !== '-') {
|
|||
|
|
score = parseInt(currentInput.value)
|
|||
|
|
if (isNaN(score)) {
|
|||
|
|
score = 0
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
players.value[selectedPlayerIndex.value].score = score
|
|||
|
|
saveHistoryState()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 删除最后一个字符
|
|||
|
|
const deleteLastChar = () => {
|
|||
|
|
if (currentInput.value.length > 0) {
|
|||
|
|
currentInput.value = currentInput.value.slice(0, -1)
|
|||
|
|
|
|||
|
|
// 实时保存删除后的内容到玩家分数
|
|||
|
|
if (selectedPlayerIndex.value !== -1) {
|
|||
|
|
let score = 0
|
|||
|
|
if (currentInput.value && currentInput.value !== '-') {
|
|||
|
|
score = parseInt(currentInput.value)
|
|||
|
|
if (isNaN(score)) {
|
|||
|
|
score = 0
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
players.value[selectedPlayerIndex.value].score = score
|
|||
|
|
saveHistoryState()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 清空输入
|
|||
|
|
const clearInput = () => {
|
|||
|
|
currentInput.value = ''
|
|||
|
|
|
|||
|
|
// 实时保存清空操作到玩家分数
|
|||
|
|
if (selectedPlayerIndex.value !== -1) {
|
|||
|
|
players.value[selectedPlayerIndex.value].score = 0
|
|||
|
|
saveHistoryState()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 确认输入
|
|||
|
|
const confirmInput = () => {
|
|||
|
|
if (selectedPlayerIndex.value !== -1) {
|
|||
|
|
// 播放音效
|
|||
|
|
if (soundEnabled.value) {
|
|||
|
|
playSound()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 隐藏键盘
|
|||
|
|
showKeyboard.value = false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 合分功能
|
|||
|
|
const combineScore = (index) => {
|
|||
|
|
// 计算其他玩家分数的总和
|
|||
|
|
const otherPlayersTotal = players.value.reduce((sum, player, i) => {
|
|||
|
|
if (i !== index) {
|
|||
|
|
return sum + player.score
|
|||
|
|
}
|
|||
|
|
return sum
|
|||
|
|
}, 0)
|
|||
|
|
|
|||
|
|
// 设置被点击玩家的分数为其他玩家分数总和的相反数,确保所有分数相加为零
|
|||
|
|
players.value[index].score = -otherPlayersTotal
|
|||
|
|
|
|||
|
|
// 如果当前正在编辑该玩家,同步更新currentInput
|
|||
|
|
if (selectedPlayerIndex.value === index && showKeyboard.value) {
|
|||
|
|
currentInput.value = players.value[index].score.toString()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
saveHistoryState()
|
|||
|
|
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '合分成功',
|
|||
|
|
icon: 'success'
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 下一局
|
|||
|
|
const nextRound = () => {
|
|||
|
|
uni.showModal({
|
|||
|
|
title: '确认',
|
|||
|
|
content: '确定要开始下一局吗?',
|
|||
|
|
success: (res) => {
|
|||
|
|
if (res.confirm) {
|
|||
|
|
// 保存当前状态
|
|||
|
|
saveHistoryState()
|
|||
|
|
|
|||
|
|
// 重置分数和胜负状态
|
|||
|
|
players.value.forEach(player => {
|
|||
|
|
player.score = 0
|
|||
|
|
player.result = ''
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
roundCount.value++
|
|||
|
|
uni.showToast({
|
|||
|
|
title: `第${roundCount.value}局`,
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 播放音效
|
|||
|
|
const playSound = () => {
|
|||
|
|
// #ifdef MP-WEIXIN
|
|||
|
|
const innerAudioContext = uni.createInnerAudioContext()
|
|||
|
|
innerAudioContext.src = '/static/sound/click.mp3' // 需要准备音效文件
|
|||
|
|
innerAudioContext.play()
|
|||
|
|
innerAudioContext.onEnded(() => {
|
|||
|
|
innerAudioContext.destroy()
|
|||
|
|
})
|
|||
|
|
// #endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 切换音效
|
|||
|
|
const toggleSound = () => {
|
|||
|
|
soundEnabled.value = !soundEnabled.value
|
|||
|
|
uni.setStorageSync('soundEnabled', soundEnabled.value)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 显示更多选项
|
|||
|
|
const showMoreOptions = () => {
|
|||
|
|
uni.showActionSheet({
|
|||
|
|
itemList: ['历史记录', '设置', '帮助'],
|
|||
|
|
success: (res) => {
|
|||
|
|
switch (res.tapIndex) {
|
|||
|
|
case 0:
|
|||
|
|
uni.navigateTo({ url: '/pages/history-game/index' })
|
|||
|
|
break
|
|||
|
|
case 1:
|
|||
|
|
uni.showToast({ title: '设置功能开发中', icon: 'none' })
|
|||
|
|
break
|
|||
|
|
case 2:
|
|||
|
|
uni.showToast({ title: '帮助文档开发中', icon: 'none' })
|
|||
|
|
break
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 结束对局
|
|||
|
|
const endGame = () => {
|
|||
|
|
uni.showModal({
|
|||
|
|
title: '确认',
|
|||
|
|
content: '确定要结束当前对局吗?',
|
|||
|
|
success: (res) => {
|
|||
|
|
if (res.confirm) {
|
|||
|
|
try {
|
|||
|
|
// 保存最终分数
|
|||
|
|
uni.setStorageSync('updatedPlayers', JSON.stringify(players.value))
|
|||
|
|
|
|||
|
|
// 触发全局事件通知其他页面
|
|||
|
|
uni.$emit('updatePlayers')
|
|||
|
|
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '对局已结束',
|
|||
|
|
icon: 'success',
|
|||
|
|
duration: 1500,
|
|||
|
|
success: () => {
|
|||
|
|
setTimeout(() => {
|
|||
|
|
uni.navigateBack()
|
|||
|
|
}, 1500)
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('结束对局失败:', error)
|
|||
|
|
uni.showToast({
|
|||
|
|
title: '操作失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 生命周期
|
|||
|
|
onMounted(() => {
|
|||
|
|
console.log('计分页面加载完成')
|
|||
|
|
loadPlayersData()
|
|||
|
|
|
|||
|
|
// 加载音效设置
|
|||
|
|
const savedSound = uni.getStorageSync('soundEnabled')
|
|||
|
|
if (savedSound !== '') {
|
|||
|
|
soundEnabled.value = savedSound
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
onUnmounted(() => {
|
|||
|
|
// 清理工作
|
|||
|
|
})
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
|
|||
|
|
<style lang="less" scoped>
|
|||
|
|
.scoring-page {
|
|||
|
|
width: 750rpx;
|
|||
|
|
margin: 0;
|
|||
|
|
padding: 0;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
background-color: #f5f5f5;
|
|||
|
|
min-height: 100vh;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
/* #ifdef MP-WEIXIN */
|
|||
|
|
user-select: none;
|
|||
|
|
/* #endif */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 顶部导航栏 */
|
|||
|
|
.header {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: row;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
height: 90rpx;
|
|||
|
|
background-color: #3a68b9;
|
|||
|
|
color: white;
|
|||
|
|
padding: 0 30rpx;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.back-btn {
|
|||
|
|
font-size: 36rpx;
|
|||
|
|
padding: 10rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.back-btn:active {
|
|||
|
|
opacity: 0.8;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.title {
|
|||
|
|
font-size: 36rpx;
|
|||
|
|
font-weight: bold;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.header-right {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: row;
|
|||
|
|
align-items: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.more-btn,
|
|||
|
|
.sound-toggle {
|
|||
|
|
font-size: 36rpx;
|
|||
|
|
padding: 10rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.separator {
|
|||
|
|
width: 2rpx;
|
|||
|
|
height: 40rpx;
|
|||
|
|
background-color: rgba(255, 255, 255, 0.3);
|
|||
|
|
margin: 0 10rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 玩家列表区域 */
|
|||
|
|
.players-list {
|
|||
|
|
flex: 1;
|
|||
|
|
background-color: #fff;
|
|||
|
|
margin: 20rpx;
|
|||
|
|
border-radius: 10rpx;
|
|||
|
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
|||
|
|
overflow: hidden;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 列表表头 */
|
|||
|
|
.list-header {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: row;
|
|||
|
|
height: 80rpx;
|
|||
|
|
background-color: #f0f0f0;
|
|||
|
|
border-bottom: 1rpx solid #e0e0e0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.col-player,
|
|||
|
|
.col-result,
|
|||
|
|
.col-score {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
font-weight: bold;
|
|||
|
|
color: #666;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.col-player {
|
|||
|
|
flex: 2;
|
|||
|
|
justify-content: flex-start;
|
|||
|
|
padding-left: 30rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.col-result {
|
|||
|
|
flex: 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.col-score {
|
|||
|
|
flex: 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 玩家行 */
|
|||
|
|
.player-row {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: row;
|
|||
|
|
height: 100rpx;
|
|||
|
|
border-bottom: 1rpx solid #f0f0f0;
|
|||
|
|
transition: background-color 0.2s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.player-row:last-child {
|
|||
|
|
border-bottom: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.player-row.selected {
|
|||
|
|
background-color: #e6f0ff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.player-row .col-player {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: row;
|
|||
|
|
align-items: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.player-avatar {
|
|||
|
|
width: 60rpx;
|
|||
|
|
height: 60rpx;
|
|||
|
|
border-radius: 30rpx;
|
|||
|
|
margin-right: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.player-name {
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #333;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 胜负按钮 */
|
|||
|
|
.result-buttons {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: row;
|
|||
|
|
gap: 10rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.result-btn {
|
|||
|
|
width: 60rpx;
|
|||
|
|
height: 40rpx;
|
|||
|
|
line-height: 40rpx;
|
|||
|
|
padding: 0;
|
|||
|
|
margin: 0;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
border-radius: 20rpx;
|
|||
|
|
border: 1rpx solid #ddd;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.result-btn.win.active {
|
|||
|
|
background-color: #4cd964;
|
|||
|
|
color: white;
|
|||
|
|
border-color: #4cd964;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.result-btn.lose.active {
|
|||
|
|
background-color: #ff3b30;
|
|||
|
|
color: white;
|
|||
|
|
border-color: #ff3b30;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 分数输入区域 */
|
|||
|
|
.score-input-container {
|
|||
|
|
position: relative;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
align-items: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.score-input {
|
|||
|
|
width: 100rpx;
|
|||
|
|
height: 50rpx;
|
|||
|
|
text-align: center;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
font-weight: bold;
|
|||
|
|
border: 1rpx solid #ddd;
|
|||
|
|
border-radius: 8rpx;
|
|||
|
|
padding: 0;
|
|||
|
|
margin: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.combine-btn {
|
|||
|
|
position: absolute;
|
|||
|
|
bottom: -40rpx;
|
|||
|
|
width: 80rpx;
|
|||
|
|
height: 30rpx;
|
|||
|
|
line-height: 30rpx;
|
|||
|
|
font-size: 20rpx;
|
|||
|
|
padding: 0;
|
|||
|
|
margin: 0;
|
|||
|
|
background-color: #34aadc;
|
|||
|
|
color: white;
|
|||
|
|
border: none;
|
|||
|
|
border-radius: 15rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 数字键盘 */
|
|||
|
|
.number-keyboard {
|
|||
|
|
width: 100%;
|
|||
|
|
background-color: #f0f0f0;
|
|||
|
|
padding: 20rpx;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.keyboard-row {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: row;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
margin-bottom: 20rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.keyboard-row:last-child {
|
|||
|
|
margin-bottom: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.key {
|
|||
|
|
flex: 1;
|
|||
|
|
height: 80rpx;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
background-color: white;
|
|||
|
|
border-radius: 10rpx;
|
|||
|
|
margin: 0 10rpx;
|
|||
|
|
font-size: 36rpx;
|
|||
|
|
font-weight: bold;
|
|||
|
|
color: #333;
|
|||
|
|
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.key:active {
|
|||
|
|
background-color: #e0e0e0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.key.zero {
|
|||
|
|
flex: 3;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.key.operation {
|
|||
|
|
background-color: #ff9500;
|
|||
|
|
color: white;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.key.delete {
|
|||
|
|
background-color: #ff3b30;
|
|||
|
|
color: white;
|
|||
|
|
position: relative;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
min-width: 80rpx; /* 确保按钮有足够宽度 */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.key.delete img {
|
|||
|
|
width: 52rpx;
|
|||
|
|
height: 52rpx;
|
|||
|
|
object-fit: contain;
|
|||
|
|
transition: transform 0.1s ease, opacity 0.1s ease;
|
|||
|
|
/* #ifdef MP-WEIXIN */
|
|||
|
|
pointer-events: none; /* 防止图片在微信小程序中捕获点击事件 */
|
|||
|
|
/* #endif */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.key.delete:active {
|
|||
|
|
background-color: #e03024; /* 点击时背景色变深 */
|
|||
|
|
transform: scale(0.98);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.key.delete:active img {
|
|||
|
|
transform: scale(0.9);
|
|||
|
|
opacity: 0.85;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.key.delete-icon {
|
|||
|
|
font-size: 36rpx;
|
|||
|
|
transform: rotate(180deg);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.key.confirm {
|
|||
|
|
background-color: #34c759;
|
|||
|
|
color: white;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.key.empty {
|
|||
|
|
background-color: transparent;
|
|||
|
|
box-shadow: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 底部操作栏 */
|
|||
|
|
.bottom-actions {
|
|||
|
|
padding: 20rpx;
|
|||
|
|
background-color: white;
|
|||
|
|
border-top: 1rpx solid #e0e0e0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.action-btn {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 80rpx;
|
|||
|
|
line-height: 80rpx;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
margin-bottom: 15rpx;
|
|||
|
|
border-radius: 40rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.action-btn:last-child {
|
|||
|
|
margin-bottom: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.action-btn.primary {
|
|||
|
|
background-color: #007aff;
|
|||
|
|
color: white;
|
|||
|
|
border: none;
|
|||
|
|
}
|
|||
|
|
</style>
|