update:英文版代码备份

This commit is contained in:
2026-11-05 14:49:42 +08:00
parent 419cefd00e
commit 53ac4473f9
142 changed files with 1777 additions and 1604 deletions
+3 -1
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
const tabs = [
{ image: "https://static.shelingxingqiu.com/shootmini/static/tab-vip.png" },
{ image: "https://static.shelingxingqiu.com/shootmini/static/tab-point-book.png" },
@@ -8,7 +10,7 @@ const tabs = [
function handleTabClick(index) {
if (index === 0) {
uni.showToast({
title: "功能尚未开启",
title: t('coming_soon'),
icon: "none",
});
// uni.navigateTo({
+4 -2
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
import { onShow } from "@dcloudio/uni-app";
@@ -99,10 +101,10 @@ onBeforeUnmount(() => {
<image src="https://static.shelingxingqiu.com/shootmini/static/back-to-game-bg.png" mode="widthFix" />
<block v-if="game.inBattle">
<image src="https://static.shelingxingqiu.com/shootmini/static/pk-icon.png" mode="widthFix" />
<text>返回进行中的对局</text>
<text>{{ t('return_to_your_current_match') }}</text>
</block>
<block v-else-if="game.roomID">
<text>返回房间</text>
<text>{{ t('back_to_room') }}</text>
</block>
<image src="https://static.shelingxingqiu.com/shootmini/static/back.png" mode="widthFix" />
</view>
+12 -10
View File
@@ -1,5 +1,7 @@
=
<script setup>
import { t } from "@/locales";
import { computed } from "vue";
import BowPower from "@/components/BowPower.vue";
import { RoundImages } from "@/constants";
@@ -43,8 +45,8 @@ const normalRounds = computed(() => {
</view>
<view>
<image src="https://static.shelingxingqiu.com/shootmini/static/battle-header-melee.png" mode="widthFix" />
<text>蓝队({{ bluePoints }})</text>
<text>红队({{ redPoints }})</text>
<text>{{ t('blue') }}{{ bluePoints }})</text>
<text>{{ t('red') }}{{ redPoints }})</text>
</view>
<view class="players">
<view>
@@ -66,18 +68,18 @@ const normalRounds = computed(() => {
.reduce((last, next) => last + next, 0)
: ""
}}</text>
<text>环</text>
<text>{{ t('pts') }}</text>
</view>
</view>
<block v-if="roundResults.length < 3">
<view v-for="i in 3 - roundResults.length" :key="i">
<view v-for="pendingRoundNumber in 3 - roundResults.length" :key="pendingRoundNumber">
<image
:src="RoundImages[`round${i + roundResults.length}`]"
:src="RoundImages[`round${pendingRoundNumber + roundResults.length}`]"
mode="widthFix"
/>
<view>
<text></text>
<text>环</text>
<text>{{ t('pts') }}</text>
</view>
</view>
</block>
@@ -101,18 +103,18 @@ const normalRounds = computed(() => {
.reduce((last, next) => last + next, 0)
: ""
}}</text>
<text>环</text>
<text>{{ t('pts') }}</text>
</view>
</view>
<block v-if="roundResults.length < 3">
<view v-for="i in 3 - roundResults.length" :key="i">
<view v-for="pendingRoundNumber in 3 - roundResults.length" :key="pendingRoundNumber">
<image
:src="RoundImages[`round${i + roundResults.length}`]"
:src="RoundImages[`round${pendingRoundNumber + roundResults.length}`]"
mode="widthFix"
/>
<view>
<text></text>
<text>环</text>
<text>{{ t('pts') }}</text>
</view>
</view>
</block>
+4 -2
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { computed } from "vue";
import AppBackground from "@/components/AppBackground.vue";
import Avatar from "@/components/Avatar.vue";
@@ -66,9 +68,9 @@ const props = defineProps({
</view>
<view class="desc">
<text>{{ arrows.length }}</text>
<text>支箭,共</text>
<text>{{ t('arrows_total') }}</text>
<text>{{ arrows.reduce((a, b) => a + (b.ring || 0), 0) }}</text>
<text>环</text>
<text>{{ t('pts') }}</text>
</view>
<ScorePanel
:completeEffect="false"
+3 -1
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import useStore from "@/store";
import { storeToRefs } from "pinia";
@@ -9,7 +11,7 @@ const { deviceBattery: power } = storeToRefs(store);
<template>
<view class="container">
<image src="https://static.shelingxingqiu.com/shootmini/static/b-power.png" mode="widthFix" />
<view>{{ power === null ? "电量--" : `电量${power}%` }}</view>
<view>{{ power === null ? t('battery') : t('battery_value', { p0: power }) }}</view>
</view>
</template>
+12 -14
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import {
ref,
watch,
@@ -97,9 +99,9 @@ const ROUND_TIP_OFFSET_Y = -32;
const EXPERIENCE_TIP_OFFSET_Y = -68;
function getRoundText(shot) {
if (shot?.ringX) return "X环";
if (shot?.ring) return `${shot.ring}环`;
return props.missAsZero ? "0环" : "未上靶";
if (shot?.ringX) return t('x');
if (shot?.ring) return t('value_pts', { p0: shot.ring });
return props.missAsZero ? t('0_pts') : t('miss');
}
function buildShotEffectKey(team, shot, index) {
@@ -530,14 +532,12 @@ onBeforeUnmount(() => {
<image src="https://static.shelingxingqiu.com/shootmini/static/dot-circle.png" mode="widthFix" />
</view>
</view>
<view v-if="stop" class="stop-sign">中场休息</view>
<view v-if="stop" class="stop-sign">{{ t('halftime') }}</view>
<view
v-if="latestOne && latestOne.ring && user.id === latestOne.playerId"
class="e-value fade-in-out"
:style="getExperienceTipStyle(latestOne)"
>
经验 +1
</view>
>{{ t('xp_1') }}</view>
<view
v-if="latestOne"
class="round-tip fade-in-out"
@@ -552,9 +552,7 @@ onBeforeUnmount(() => {
"
class="e-value fade-in-out"
:style="getExperienceTipStyle(bluelatestOne)"
>
经验 +1
</view>
>{{ t('xp_1') }}</view>
<view
v-if="bluelatestOne"
class="round-tip fade-in-out"
@@ -638,10 +636,10 @@ onBeforeUnmount(() => {
/>
</view>
<view class="simul" v-if="env !== 'release'">
<button @click="simulShoot">模拟</button>
<button @click="simulShoot2">射箭</button>
<button @click="openAim">开瞄</button>
<button @click="closeAim">关瞄</button>
<button @click="simulShoot">{{ t('simulate') }}</button>
<button @click="simulShoot2">{{ t('shoot') }}</button>
<button @click="openAim">{{ t('sight_on') }}</button>
<button @click="closeAim">{{ t('sight_off') }}</button>
</view>
</view>
</template>
+3 -1
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, onMounted, onBeforeUnmount } from "vue";
import { getElementRect, calcRing, capsuleHeight } from "@/util";
@@ -258,7 +260,7 @@ onBeforeUnmount(() => {
fontSize: '16px',
marginLeft: '2px',
}"
>环</text
>{{ t('pts') }}</text
>
</view>
<view
+17 -23
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref } from "vue";
import { onShow } from "@dcloudio/uni-app";
import AppBackground from "@/components/AppBackground.vue";
@@ -179,43 +181,35 @@ const goCalibration = async () => {
</view>
<ScreenHint :show="showHint">
<view v-if="hintType === 1" class="tip-content">
<text>完成进行中的对局才能开启新的。</text>
<text>您有正在进行中的对局,是否进入?</text>
<text>{{ t('finish_your_current_match_before_starting_a_new_one') }}</text>
<text>{{ t('you_have_a_match_in_progress_join_it') }}</text>
<view>
<button hover-class="none" @click="() => (showHint = false)">
不进入
</button>
<button hover-class="none" @click="() => (showHint = false)">{{ t('stay_out') }}</button>
<button hover-class="none" @click="backToGame" :disabled="isLoading">
{{ isLoading ? "加载中..." : "进入" }}
{{ isLoading ? t('loading') : t('join') }}
</button>
</view>
</view>
<view v-if="hintType === 2" class="tip-content">
<text>离开比赛可能会导致比赛失败,</text>
<text>确认离开吗?</text>
<text>{{ t('leaving_may_result_in_a_loss') }}</text>
<text>{{ t('are_you_sure_you_want_to_leave') }}</text>
<view>
<button hover-class="none" @click="goBack">离开比赛</button>
<button hover-class="none" @click="() => (showHint = false)">
继续比赛
</button>
<button hover-class="none" @click="goBack">{{ t('leave_match') }}</button>
<button hover-class="none" @click="() => (showHint = false)">{{ t('continue_match') }}</button>
</view>
</view>
<view v-if="hintType === 3" class="tip-content">
<text>今天不玩了吗?</text>
<text>{{ t('done_playing_for_today') }}</text>
<view>
<button hover-class="none" @click="() => (showHint = false)">
取消
</button>
<button hover-class="none" @click="$clickSound(cancelMatching)">确认</button>
<button hover-class="none" @click="() => (showHint = false)">{{ t('cancel') }}</button>
<button hover-class="none" @click="$clickSound(cancelMatching)">{{ t('confirm') }}</button>
</view>
</view>
<view v-if="hintType === 4" class="tip-content">
<text>完成智能弓校准,即可解锁全部功能</text>
<text>{{ t('calibrate_your_smart_bow_to_unlock_all_features') }}</text>
<view>
<button hover-class="none" @click="() => (showHint = false)">
取消
</button>
<button hover-class="none" @click="goCalibration">去校准</button>
<button hover-class="none" @click="() => (showHint = false)">{{ t('cancel') }}</button>
<button hover-class="none" @click="goCalibration">{{ t('calibrate') }}</button>
</view>
</view>
</ScreenHint>
@@ -228,7 +222,7 @@ const goCalibration = async () => {
<view :style="{ width: '100%' }"></view>
</view>
<view>
<text>{{ loadingText || "加载中..." }}</text>
<text>{{ loadingText || t('loading') }}</text>
</view>
</view>
<DeviceChargingDialog />
+11 -9
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref } from "vue";
import SButton from "@/components/SButton.vue";
@@ -27,7 +29,7 @@ const roomNumber = ref("");
const createRoom = debounce(async () => {
// 校验必填项:对战模式与靶纸均必须选择
if (!battleMode.value || !targetMode.value) {
uni.showToast({ title: '请完善创建信息', icon: 'none' });
uni.showToast({ title: t('please_complete_the_room_settings'), icon: 'none' });
return;
}
if (game.value.inBattle) {
@@ -77,30 +79,30 @@ const createRoom = debounce(async () => {
:class="{ 'battle-btn': true, 'battle-choosen': battleMode === 1 }"
@click="() => (battleMode = 1)"
>
<text>对抗模式(1V1)</text>
<text>{{ t('versus_1v1') }}</text>
</view>
<view
:class="{ 'battle-btn': true, 'battle-choosen': battleMode === 3 }"
@click="() => (battleMode = 3)"
>
<text>对抗模式(2V2)</text>
<text>{{ t('versus_2v2') }}</text>
</view>
<view
:class="{ 'battle-btn': true, 'battle-choosen': battleMode === 4 }"
@click="() => (battleMode = 4)"
>
<text>对抗模式(3V3)</text>
<text>{{ t('versus_3v3') }}</text>
</view>
<view
:class="{ 'battle-btn': true, 'battle-choosen': battleMode === 2 }"
@click="() => (battleMode = 2)"
>
<text>乱斗模式(3-10人)</text>
<text>{{ t('free_for_all_3_10_players') }}</text>
</view>
</view>
<view class="target-options-header">
<view class="target-options-header-line-left"></view>
<view class="target-options-header-title">选择靶纸</view>
<view class="target-options-header-title">{{ t('select_target_face') }}</view>
<view class="target-options-header-line-right"></view>
</view>
<view class="target-options">
@@ -108,16 +110,16 @@ const createRoom = debounce(async () => {
:class="{ 'battle-btn': true, 'battle-choosen': targetMode === 1 }"
@click="() => (targetMode = 1)"
>
<text>20厘米全环靶</text>
<text>{{ t('20_cm_full_ring_target') }}</text>
</view>
<view
:class="{ 'battle-btn': true, 'battle-choosen': targetMode === 2 }"
@click="() => (targetMode = 2)"
>
<text>40厘米全环靶</text>
<text>{{ t('40_cm_full_ring_target') }}</text>
</view>
</view>
<SButton :disabled="loading" :onClick="() => { $clickSound(); return createRoom(); }">创建房间</SButton>
<SButton :disabled="loading" :onClick="() => { $clickSound(); return createRoom(); }">{{ t('create_room') }}</SButton>
</view>
</template>
+4 -2
View File
@@ -1,10 +1,12 @@
<script setup>
import { t } from "@/locales";
import { storeToRefs } from "pinia";
import ModalDialog from "@/components/ModalDialog.vue";
import useStore from "@/store";
const chargingNotice =
"检测到智能弓箭已开始充电,为保护电池,设备即将自动关机。\n(注意:此时拔出充电线将会重启设备。)";
t('your_smart_bow_is_charging_and_will_shut_down_automatically_to_p');
const store = useStore();
const { deviceChargingDialogVisible } = storeToRefs(store);
@@ -16,7 +18,7 @@ const { hideDeviceChargingDialog } = store;
:show="deviceChargingDialogVisible"
:content="chargingNotice"
:show-cancel="false"
confirm-text="我知道了"
:confirm-text="t('got_it')"
:on-confirm="hideDeviceChargingDialog"
/>
</template>
+15 -15
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, watch, onMounted, computed } from "vue";
import { getPointBookConfigAPI } from "@/apis";
const props = defineProps({
@@ -27,7 +29,7 @@ const props = defineProps({
default: "",
},
});
const itemTexts = ["选择弓种", "选择练习距离", "选择靶纸", "选择组/箭数"];
const itemTexts = [t('select_bow_type'), t('select_shooting_distance'), t('select_target_face'), t('select_ends_arrows')];
const distances = [5, 8, 10, 18, 25, 30, 50, 60, 70];
const groupArrows = [3, 6, 12, 18];
@@ -157,11 +159,9 @@ const formatSetAndAmount = computed(() => {
return itemTexts[props.itemIndex];
if (secondSelectIndex.value === 99 && !arrowAmount.value)
return itemTexts[props.itemIndex];
return `${selectedIndex.value === 99 ? sets.value : selectedIndex.value}组/${
secondSelectIndex.value === 99
return t('value_ends_value_arrows', { p0: selectedIndex.value === 99 ? sets.value : selectedIndex.value, p1: secondSelectIndex.value === 99
? arrowAmount.value
: groupArrows[secondSelectIndex.value]
}箭`;
: groupArrows[secondSelectIndex.value] });
});
onMounted(async () => {
const config = uni.getStorageSync("point-book-config");
@@ -187,13 +187,13 @@ onMounted(async () => {
<view></view>
<block>
<text v-if="expand" :style="{ color: '#999', fontWeight: 'normal' }">{{
itemIndex !== 3 ? itemTexts[itemIndex] : "选择组"
itemIndex !== 3 ? itemTexts[itemIndex] : t('select_ends')
}}</text>
<text v-if="!expand && itemIndex === 0">{{
value || itemTexts[itemIndex]
}}</text>
<text v-if="!expand && itemIndex === 1">{{
value && value > 0 ? value + "米" : itemTexts[itemIndex]
value && value > 0 ? value + t('m_92') : itemTexts[itemIndex]
}}</text>
<text v-if="!expand && itemIndex === 2">{{
value || itemTexts[itemIndex]
@@ -232,7 +232,7 @@ onMounted(async () => {
@click="onSelectItem(index)"
>
<text>{{ item }}</text>
<text>米</text>
<text>{{ t('m_92') }}</text>
</view>
<view
:style="{
@@ -242,12 +242,12 @@ onMounted(async () => {
<input
v-model="meter"
type="number"
placeholder="自定义"
:placeholder="t('custom')"
placeholder-style="color: #DDDDDD"
@focus="() => (selectedIndex = 9)"
@blur="onMeterChange"
/>
<text>米</text>
<text>{{ t('m_92') }}</text>
</view>
</view>
<view v-if="itemIndex === 2" class="bowtarget-items">
@@ -274,7 +274,7 @@ onMounted(async () => {
@click="onSelectItem(i)"
>
<text>{{ i }}</text>
<text>组</text>
<text>{{ t('ends') }}</text>
</view>
<view
:style="{
@@ -289,7 +289,7 @@ onMounted(async () => {
@focus="() => (selectedIndex = 99)"
@blur="onSetsChange"
/>
<text>组</text>
<text>{{ t('ends') }}</text>
</view>
</view>
<view
@@ -299,7 +299,7 @@ onMounted(async () => {
color: '#999999',
textAlign: 'center',
}"
>选择每组的箭数</view
>{{ t('select_arrows_per_end') }}</view
>
<view class="amount-items">
<view
@@ -311,7 +311,7 @@ onMounted(async () => {
@click="onSelectSecondItem(index)"
>
<text>{{ item }}</text>
<text>箭</text>
<text>{{ t('arrows') }}</text>
</view>
<view
:style="{
@@ -327,7 +327,7 @@ onMounted(async () => {
@focus="() => (secondSelectIndex = 99)"
@blur="onArrowAmountChange"
/>
<text>箭</text>
<text>{{ t('arrows') }}</text>
</view>
</view>
</view>
+9 -7
View File
@@ -1,4 +1,6 @@
<script setup>
import { t, translateStatic } from "@/locales";
import { ref, computed, onMounted, onBeforeUnmount } from "vue";
import HeaderProgress from "@/components/HeaderProgress.vue";
import Avatar from "@/components/Avatar.vue";
@@ -162,7 +164,7 @@ onBeforeUnmount(() => {
</block>
<block v-else>
<image src="https://static.shelingxingqiu.com/shootmini/static/user-icon.png" mode="widthFix" />
<text>新来的弓箭手你好呀~</text>
<text>{{ t('welcome_new_archer') }}</text>
</block>
</view>
<block
@@ -171,7 +173,7 @@ onBeforeUnmount(() => {
'-箭前准备-感知距离-小试牛刀'.indexOf(title) === 11
"
>
<text>{{ title }}</text>
<text>{{ ['-箭前准备', '-感知距离', '-小试牛刀', '小试牛刀'].includes(title) ? translateStatic(title) : title }}</text>
</block>
<block
v-if="
@@ -181,14 +183,14 @@ onBeforeUnmount(() => {
"
>
<view class="first-try-steps">
<text :class="title === '-箭前准备' ? 'current-step' : ''">箭前准备</text>
<text :class="title === '-箭前准备' ? 'current-step' : ''">{{ t('get_ready') }}</text>
<text>-</text>
<text :class="title === '-感知距离' ? 'current-step' : ''"
>感知距离</text
>{{ t('find_your_distance') }}</text
>
<text>-</text>
<text :class="title === '-小试牛刀' ? 'current-step' : ''"
>小试牛刀</text
>{{ t('first_challenge') }}</text
>
</view>
</block>
@@ -196,7 +198,7 @@ onBeforeUnmount(() => {
</view>
<view v-if="pointBook" class="point-book-info">
<text>{{ pointBook.bowType.name }}</text>
<text>{{ pointBook.distance }} 米</text>
<text>{{ pointBook.distance }}{{ t('m') }}</text>
<text
>{{
pointBook.bowtargetType.name.substring(
@@ -228,7 +230,7 @@ onBeforeUnmount(() => {
class="battle-room-number"
:style="battleRoomBtnStyle"
>
<text class="battle-room-number__text">房号: {{ game.roomNumber }}</text>
<text class="battle-room-number__text">{{ t('room') }}{{ game.roomNumber }}</text>
<image src="https://static.shelingxingqiu.com/shootmini/static/share2.png" mode="widthFix" class="battle-room-number__icon" />
</button>
</view>
+2 -1
View File
@@ -1,4 +1,5 @@
<script setup>
import { formatBattleTip } from "@/locales";
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
import audioManager from "@/audioManager";
import { MESSAGETYPESV2 } from "@/constants";
@@ -143,7 +144,7 @@ onBeforeUnmount(() => {
<template>
<view class="container">
<text>{{ (tips || "").replace(/你/g, "").replace(/重回/g, "") }}</text>
<text>{{ formatBattleTip(tips) }}</text>
<text v-if="totalShot > 0"> ({{ currentShot }}/{{ totalShot }}) </text>
<button v-if="!!tips" hover-class="none" @click="updateSound">
<image :src="`https://static.shelingxingqiu.com/shootmini/static/sound${sound ? '' : '-off'}-yellow.png`" mode="widthFix" />
+14 -12
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, onMounted, onBeforeUnmount, watch } from "vue";
const props = defineProps({
stopMatch: {
@@ -11,17 +13,17 @@ const props = defineProps({
},
});
const playerNames = [
"乐正青山",
"宇文玉兰",
"岑思宇",
"邬梓瑜",
"范子衿",
"旗鼓相当的对手",
"乐子睿",
"时春晓",
"柏孤鸿",
"东宫锦瑟",
"段干流云",
t('yuezheng_qingshan'),
t('yuwen_yulan'),
t('cen_siyu'),
t('wu_ziyu'),
t('fan_zijin'),
t('a_worthy_opponent'),
t('le_zirui'),
t('shi_chunxiao'),
t('bai_guhong'),
t('donggong_jinse'),
t('duangan_liuyun'),
];
const textStyles = [
{
@@ -123,7 +125,7 @@ onBeforeUnmount(() => {
</text>
</view>
</view>
<button hover-class="none" @click="$clickSound(stopMatch)">取消匹配</button>
<button hover-class="none" @click="$clickSound(stopMatch)">{{ t('cancel_matchmaking') }}</button>
</view>
</template>
+19 -5
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import IconButton from "./IconButton.vue";
const props = defineProps({
@@ -16,11 +18,11 @@ const props = defineProps({
},
cancelText: {
type: String,
default: "取消",
default: t('cancel_133'),
},
confirmText: {
type: String,
default: "确定",
default: t('confirm_134'),
},
showCancel: {
type: Boolean,
@@ -193,6 +195,9 @@ const handleClose = () => {
}
.dialog-content {
max-height: 45vh;
overflow-y: auto;
overflow-wrap: break-word;
position: relative;
z-index: 1;
display: flex;
@@ -216,6 +221,7 @@ const handleClose = () => {
}
.dialog-actions {
width: 100%;
position: relative;
z-index: 1;
display: flex;
@@ -229,11 +235,19 @@ const handleClose = () => {
justify-content: center;
}
.dialog-actions.single .dialog-button {
flex: 0 1 232rpx;
}
.dialog-button {
display: flex;
width: 232rpx;
height: 70rpx;
line-height: 70rpx;
flex: 1;
min-width: 0;
min-height: 70rpx;
padding: 12rpx 20rpx;
box-sizing: border-box;
line-height: 1.3;
text-align: center;
border-radius: 44rpx;
justify-content: center;
align-items: center;
+16 -14
View File
@@ -1,9 +1,11 @@
<script setup>
import { t } from "@/locales";
import { computed } from "vue";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const OTA_OFFLINE_TEXT = "请先开启智能弓";
const OTA_OFFLINE_TEXT = t('please_turn_on_your_smart_bow_first');
const store = useStore();
const { deviceStatus } = storeToRefs(store);
@@ -54,11 +56,11 @@ const isFailure = computed(() => props.state === "update_failure");
const progressValue = computed(() => Math.min(100, Math.max(0, Number(props.progress) || 0)));
const progressPhaseText = computed(() => {
const phaseText = {
started: "正在准备固件更新",
downloading: "正在下载固件",
installing: "正在安装固件",
started: t('preparing_firmware_update'),
downloading: t('downloading_firmware'),
installing: t('installing_firmware'),
};
return phaseText[props.phase] || "正在进行固件更新";
return phaseText[props.phase] || t('updating_firmware');
});
// 点击立即更新前先校验设备在线状态。
@@ -130,19 +132,19 @@ const handleUpdateClick = () => {
<text v-if="changelog" class="changelog-text">{{ changelog }}</text>
<view class="btn-group">
<view class="primary-btn" @click="handleUpdateClick">
<text class="primary-btn-text">立即更新</text>
<text class="primary-btn-text">{{ t('update_now') }}</text>
</view>
<text v-if="!forceUpdate" class="skip-text" @click="emit('skip')">暂不更新</text>
<text v-if="!forceUpdate" class="skip-text" @click="emit('skip')">{{ t('later') }}</text>
</view>
</block>
<!-- 更新成功:图片左边距 34rpx,文案左边距 44rpx,按钮浮动底部居中 -->
<block v-else-if="isSuccess">
<image src="https://static.shelingxingqiu.com/shootmini/static/ota/update-ok.png" mode="aspectFit" class="result-title-img" style="width: 220rpx; height: 62rpx;" />
<text class="dialog-desc">固件更新已完成</text>
<text class="dialog-desc">{{ t('firmware_update_complete') }}</text>
<view class="btn-group-result">
<view class="primary-btn" @click="emit('done')">
<text class="primary-btn-text">关闭</text>
<text class="primary-btn-text">{{ t('close') }}</text>
</view>
</view>
</block>
@@ -158,19 +160,19 @@ const handleUpdateClick = () => {
<view class="progress-track">
<view class="progress-fill" :style="{ width: `${progressValue}%` }"></view>
</view>
<text class="progress-warning">请勿离开当前页面!</text>
<text class="progress-warning">{{ t('please_stay_on_this_page') }}</text>
</view>
</block>
<!-- 更新失败:图片左边距 34rpx,文案左对齐 44rpx,按钮浮动底部居中 -->
<block v-else-if="isFailure">
<image src="https://static.shelingxingqiu.com/shootmini/static/ota/update-fail.png" mode="aspectFit" class="result-title-img" style="width: 222rpx; height: 62rpx;" />
<text class="dialog-desc">请确保:</text>
<text class="dialog-desc">1、智能弓已开启</text>
<text class="dialog-desc">2、网路连接稳定</text>
<text class="dialog-desc">{{ t('please_make_sure') }}</text>
<text class="dialog-desc">{{ t('1_your_smart_bow_is_on') }}</text>
<text class="dialog-desc">{{ t('2_your_network_connection_is_stable') }}</text>
<view class="btn-group-result">
<view class="primary-btn" @click="emit('retry')">
<text class="primary-btn-text">重试</text>
<text class="primary-btn-text">{{ t('retry') }}</text>
</view>
</view>
</block>
+5 -3
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const { user } = storeToRefs(useStore());
@@ -18,8 +20,8 @@ const rowCount = new Array(6).fill(0);
const getRingText = (arrow) => {
if (!arrow) return "-";
if (arrow.ringX && arrow.ring) return "X环";
return `${Number(arrow.ring) || 0}环`;
if (arrow.ringX && arrow.ring) return t('x');
return t('value_pts', { p0: Number(arrow.ring) || 0 });
};
const isMember = (player = {}) => player.vip === true || player.sVip === true;
@@ -71,7 +73,7 @@ const getMemberNicknameClass = (player = {}) => [
scores
.map((s) => (s || []).reduce((last, next) => last + next.ring, 0))
.reduce((last, next) => last + next, 0)
}}环</text
}}{{ t('pts') }}</text
>
</view>
</template>
+6 -4
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { topThreeColors } from "@/constants";
defineProps({
avatar: {
@@ -56,20 +58,20 @@ const rowCount = new Array(6).fill(0);
<view>
<view>
<view v-for="(_, index) in rowCount" :key="index">
<text>{{ arrows[index] ? `${arrows[index].ring}环` : "-" }}</text>
<text>{{ arrows[index] ? t('value_pts', { p0: arrows[index].ring }) : "-" }}</text>
</view>
</view>
<view>
<view v-for="(_, index) in rowCount" :key="index">
<text>{{
arrows[index + 6] ? `${arrows[index + 6].ring}环` : "-"
arrows[index + 6] ? t('value_pts', { p0: arrows[index + 6].ring }) : "-"
}}</text>
</view>
</view>
</view>
<view>
<text>{{ arrows.reduce((last, next) => last + next.ring, 0) }}环</text>
<text>积分{{ totalScore }}</text>
<text>{{ arrows.reduce((last, next) => last + next.ring, 0) }}{{ t('pts') }}</text>
<text>{{ t('points') }}{{ totalScore }}</text>
</view>
</view>
</template>
+5 -5
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import Avatar from "@/components/Avatar.vue";
const props = defineProps({
@@ -43,7 +45,7 @@ const seats = new Array(props.total).fill(1);
/>
<text
:style="{ opacity: players[index] && !!players[index].state ? 1 : 0 }"
>已准备</text
>{{ t('ready') }}</text
>
</view>
<view v-else class="player-unknow">
@@ -67,10 +69,8 @@ const seats = new Array(props.total).fill(1);
>
{{ players[index].name }}
</text>
<text v-else class="player-seat-name" :style="{ color: '#fff9' }">
虚位以待
</text>
<view v-if="index === 0" class="founder">管理员</view>
<text v-else class="player-seat-name" :style="{ color: '#fff9' }">{{ t('waiting_for_a_player') }}</text>
<view v-if="index === 0" class="founder">{{ t('host') }}</view>
<!-- <image
:src="`https://static.shelingxingqiu.com/shootmini/static/player-${index + 1}.png`"
mode="widthFix"
+6 -4
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, watch } from "vue";
import Avatar from "@/components/Avatar.vue";
@@ -70,19 +72,19 @@ const onClick = async () => {
</view>
<text v-else class="truncate">{{ data.name }}</text>
<view>
<text>{{ data.totalDay }}天</text>
<text>{{ data.totalDay }}{{ t('days') }}</text>
<view />
<text>平均{{ Number(data.averageRing.toFixed(1)) }}环</text>
<text>{{ t('average') }}{{ Number(data.averageRing.toFixed(1)) }}{{ t('pts') }}</text>
</view>
</view>
</view>
<view class="item-info">
<text>{{ data.weekArrow }}</text>
<text>箭</text>
<text>{{ t('arrows') }}</text>
</view>
<view class="item-info">
<text>{{ Math.round(data.weekArrow * 1.6) }}</text>
<text>千卡</text>
<text>{{ t('kcal') }}</text>
</view>
<button hover-class="none" @click="onClick">
<text>{{ likeCount }}</text>
+6 -4
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, onMounted, computed } from "vue";
const props = defineProps({
@@ -48,7 +50,7 @@ onMounted(() => {
<text>{{
bowOptions[data.bowType] ? bowOptions[data.bowType].name : ""
}}</text>
<text>{{ data.distance }} 米</text>
<text>{{ data.distance }}{{ t('m') }}</text>
<text>{{
targetOptions[data.targetType]
? targetOptions[data.targetType].name
@@ -59,9 +61,9 @@ onMounted(() => {
<text>{{ data.createAt }}</text>
</view>
<view>
<text>黄心率:{{ Number((data.yellowRate * 100).toFixed(2)) }}%</text>
<text>10环数:{{ data.tenRings }}</text>
<text>平均:{{ data.averageRing }}</text>
<text>{{ t('gold_hit_rate_156') }}{{ Number((data.yellowRate * 100).toFixed(2)) }}%</text>
<text>{{ t('10s_157') }}{{ data.tenRings }}</text>
<text>{{ t('average_158') }}{{ data.averageRing }}</text>
</view>
</view>
<view class="right-part">
+4 -2
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref } from "vue";
const props = defineProps({
@@ -25,9 +27,9 @@ const onClick = () => {
@click="onClick"
:style="{ transform: 'translateX(' + (mode ? '-58' : '4') + 'rpx)' }"
>
<text>放大</text>
<text>{{ t('zoom') }}</text>
<view :style="{ background: mode ? '#D8D8D8' : '#53EF56' }"></view>
<text>真实</text>
<text>{{ t('actual_size') }}</text>
</view>
</view>
</template>
+10 -8
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, reactive, watch, onMounted } from "vue";
import { getAppConfig, donateAPI } from "@/apis";
import useStore from "@/store";
@@ -47,7 +49,7 @@ const onPay = async (index) => {
signType: "RSA",
async success(res) {
uni.showToast({
title: "感谢您的支持!",
title: t('thank_you_for_your_support'),
icon: "none",
});
props.onClose();
@@ -55,7 +57,7 @@ const onPay = async (index) => {
fail(res) {
console.log("pay error", res);
uni.showToast({
title: "取消支付",
title: t('payment_canceled'),
icon: "none",
});
props.onClose();
@@ -94,7 +96,7 @@ onMounted(async () => {
<template>
<view class="container">
<image src="https://static.shelingxingqiu.com/shootmini/static/donate.png" mode="widthFix" />
<text>感谢您对我们公益项目的支持!</text>
<text>{{ t('thank_you_for_supporting_our_community_project') }}</text>
<view class="amounts">
<button
v-for="(item, index) in amounts"
@@ -115,23 +117,23 @@ onMounted(async () => {
>
<image v-if="checked" src="https://static.shelingxingqiu.com/shootmini/static/checked.png" mode="widthFix" />
<view v-else></view>
<text>我想给建议(选填)</text>
<text>{{ t('i_have_a_suggestion_optional') }}</text>
</view>
<view v-if="checked">
<view>
<text>您的姓名</text>
<text>{{ t('your_name') }}</text>
<input v-model="formData.name" />
</view>
<view>
<text>手机/微信号</text>
<text>{{ t('phone_wechat_id') }}</text>
<input v-model="formData.account" />
</view>
<view>
<text>所在机构</text>
<text>{{ t('organization') }}</text>
<input v-model="formData.organization" />
</view>
<view>
<text>建议</text>
<text>{{ t('suggestion') }}</text>
<textarea v-model="formData.suggestion" />
</view>
</view>
+3 -1
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, computed, onMounted } from "vue";
const props = defineProps({
@@ -56,7 +58,7 @@ const ringText = (ring) => {
{{ b && b.ring !== undefined ? b.ring : "" }}
</text>
</view>
<text>环值</text>
<text>{{ t('score') }}</text>
</view>
</template>
+20 -26
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, onMounted, onBeforeUnmount } from "vue";
const props = defineProps({
isFinal: {
@@ -47,64 +49,56 @@ onBeforeUnmount(() => {
<template>
<view class="round-end-tip">
<text>第{{ round }}轮射箭结束</text>
<text>{{ t('round') }}{{ round }}{{ t('shooting_complete') }}</text>
<block v-if="!isFinal">
<view class="point-view1" v-if="bluePoint !== 0 || redPoint !== 0">
<text>本轮蓝队</text>
<text>{{ t('blue_team_this_round') }}</text>
<text>{{
(roundData.shoots[1] || []).reduce(
(last, next) => last + next.ring,
0
)
}}</text>
<text>环,红队</text>
<text>{{ t('pts_red_team') }}</text>
<text>{{
(roundData.shoots[2] || []).reduce(
(last, next) => last + next.ring,
0
)
}}</text>
<text>环</text>
<text>{{ t('pts') }}</text>
</view>
<text
v-if="bluePoint === 0 && redPoint === 0"
:style="{ marginTop: '20px' }"
>
连续3个来回双方均无人射箭,比赛取消。
</text>
<text v-if="bluePoint !== 0 && bluePoint === redPoint">
红队、蓝队各得<text :style="{ color: '#fed847', margin: '0 5px' }">{{
>{{ t('no_arrows_were_shot_by_either_team_for_3_consecutive_turns_match') }}</text>
<text v-if="bluePoint !== 0 && bluePoint === redPoint">{{ t('red_and_blue_teams_each_earn') }}<text :style="{ color: '#fed847', margin: '0 5px' }">{{
redPoint
}}</text
>分
</text>
<text v-if="bluePoint > redPoint">
蓝队获胜,得<text :style="{ color: '#fed847', margin: '0 5px' }">{{
>{{ t('pts_175') }}</text>
<text v-if="bluePoint > redPoint">{{ t('blue_team_wins_and_earns') }}<text :style="{ color: '#fed847', margin: '0 5px' }">{{
bluePoint
}}</text
>分
</text>
<text v-if="bluePoint < redPoint">
红队获胜,得<text :style="{ color: '#fed847', margin: '0 5px' }">{{
>{{ t('pts_175') }}</text>
<text v-if="bluePoint < redPoint">{{ t('red_team_wins_and_earns') }}<text :style="{ color: '#fed847', margin: '0 5px' }">{{
redPoint
}}</text
>分
</text>
>{{ t('pts_175') }}</text>
</block>
<block v-if="isFinal">
<view class="point-view2">
<text>蓝队</text>
<text>{{ t('blue_team') }}</text>
<text>{{ bluePoint }}</text>
<text>分,红队</text>
<text>{{ t('pts_red_team_179') }}</text>
<text>{{ redPoint }}</text>
<text>分</text>
<text>{{ t('pts_180') }}</text>
</view>
<text>同分僵局!最后一箭定江山</text>
<text>{{ t('a_tie_one_final_arrow_decides_the_winner') }}</text>
<view class="final-shoot">
<text>{{ count }}</text>
<text>秒后蓝红双方</text>
<text>决金箭</text>
<text>一箭决胜负</text>
<text>{{ t('s_until_both_teams_shoot') }}</text>
<text>{{ t('golden_arrow') }}</text>
<text>{{ t('one_arrow_decides_it_all') }}</text>
</view>
</block>
</view>
+7 -2
View File
@@ -77,8 +77,13 @@ const onBtnClick = debounce(async () => {
<style scoped>
.sbtn {
margin: 0 auto;
height: 44px;
line-height: 44px;
min-height: 88rpx;
height: auto;
line-height: 1.3;
padding: 20rpx 24rpx;
box-sizing: border-box;
white-space: normal;
overflow-wrap: break-word;
font-weight: bold;
font-size: 15px;
display: flex;
+7 -5
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
const props = defineProps({
arrows: {
type: Array,
@@ -12,19 +14,19 @@ const getSum = (...arrows) => {
(total, arrow) => total + (Number(arrow.ring) || 0),
0
);
return `${sum}环`;
return t('value_pts', { p0: sum });
};
const roundsName = ["第一轮", "第二轮", "第三轮", "第四轮"];
const roundsName = [t('round_1'), t('round_2'), t('round_3'), t('round_4')];
const getShowText = (arrow) => {
if (!arrow) return "-";
return arrow.ringX ? "X" : `${Number(arrow.ring) || 0}环`;
return arrow.ringX ? "X" : t('value_pts', { p0: Number(arrow.ring) || 0 });
};
</script>
<template>
<view class="container">
<view>
<text :style="{ transform: 'translateX(-10%)' }">总成绩</text>
<text>{{ arrows.reduce((last, next) => last + next.ring, 0) }}环</text>
<text :style="{ transform: 'translateX(-10%)' }">{{ t('final_score') }}</text>
<text>{{ arrows.reduce((last, next) => last + next.ring, 0) }}{{ t('pts') }}</text>
</view>
<view
v-for="(_, index) in new Array(
+19 -20
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, onMounted, computed } from "vue";
import IconButton from "@/components/IconButton.vue";
import SButton from "@/components/SButton.vue";
@@ -86,9 +88,9 @@ const openCoachComment = () => {
<image :src="tipSrc" mode="widthFix" />
<image src="https://static.shelingxingqiu.com/shootmini/static/finish-frame.png" mode="widthFix" />
<text
>完成<text class="gold-text">{{ validArrows }}</text
>箭,获得<text class="gold-text">{{ validArrows }}</text
>点经验</text
>{{ t('completed') }}<text class="gold-text">{{ validArrows }}</text
>{{ t('arrows_earned') }}<text class="gold-text">{{ validArrows }}</text
>{{ t('xp') }}</text
>
</view>
<view
@@ -96,9 +98,9 @@ const openCoachComment = () => {
:style="{ transform: `translateY(${showPanel ? '0%' : '100%'})` }"
>
<view>
<text>本局成绩(共{{ totalRing }}环):</text>
<text>{{ t('score_this_match_total') }}{{ totalRing }}{{ t('pts_194') }}</text>
<button @click="() => (showBowData = true)">
<text>查看靶纸</text>
<text>{{ t('view_target') }}</text>
<image
src="https://static.shelingxingqiu.com/shootmini/static/enter-arrow-blue.png"
mode="widthFix"
@@ -109,19 +111,19 @@ const openCoachComment = () => {
<view :style="{ gridTemplateColumns: `repeat(${rowCount}, 1fr)` }">
<view v-for="(_, index) in new Array(total).fill(0)" :key="index">
{{ getRing(arrows[index])
}}<text v-if="getRing(arrows[index]) !== '-'">环</text>
}}<text v-if="getRing(arrows[index]) !== '-'">{{ t('pts') }}</text>
</view>
</view>
<view>
<block v-if="validArrows === total">
<IconButton
name="分享"
:name="t('share')"
src="https://static.shelingxingqiu.com/shootmini/static/share.png"
:onClick="onClickShare"
/>
<IconButton
v-if="isMember"
name="教练点评"
:name="t('coach_feedback')"
src="https://static.shelingxingqiu.com/shootmini/static/review.png"
:onClick="openCoachComment"
/>
@@ -130,7 +132,7 @@ const openCoachComment = () => {
:width="validArrows === total ? '70vw' : 'calc(100vw - 20px)'"
:rounded="30"
:onClick="closePanel"
>{{ validArrows === total ? "完成" : "返回" }}</SButton
>{{ validArrows === total ? t('completed') : t('back') }}</SButton
>
</view>
</view>
@@ -140,17 +142,16 @@ const openCoachComment = () => {
mode="tall"
>
<view class="coach-comment">
<text>
您本次练习取得了<text :style="{ color: '#fed847' }">{{
<text>{{ t('your_score_for_this_session_is') }}<text :style="{ color: '#fed847' }">{{
totalRing
}}</text
>环的成绩,所有箭支上靶后的平均点间距为<text
>{{ t('pts_the_average_distance_between_your_arrow_impacts_is') }}<text
:style="{ color: '#fed847' }"
>{{ Number((result?.interpretation?.spreadStability || 0).toFixed(2)) }}</text
>,{{
result.spreadEvaluation === "Dispersed"
? "还需要持续改进哦~"
: "成绩优秀。"
? t('keep_practicing')
: t('excellent_performance')
}}
</text>
<view>
@@ -159,14 +160,12 @@ const openCoachComment = () => {
mode="widthFix"
/>
<text :style="{ marginTop: '12px' }"
>针对您本次的练习,{{
>{{ t('for_this_session') }}{{
result.spreadEvaluation === "Dispersed"
? "我们建议您充分练习推弓、靠位以及撒放动作一致性。"
? t('we_recommend_practicing_consistency_in_your_bow_arm_anchor_point')
: totalRing >= 100
? "我们建议您继续保持即可。"
: `我们建议您将设备的瞄准器${
directionAdjusts[result.adjustmentHint]
}调整。`
? t('we_recommend_keeping_up_the_good_work')
: t('we_recommend_adjusting_your_sight_value', { p0: directionAdjusts[result.adjustmentHint] })
}}</text
>
</view>
+7
View File
@@ -90,4 +90,11 @@ const getContentHeight = () => {
bottom: -8rpx;
z-index: -1;
}
/* 英文教练点评较长,保持弹窗按钮可见。 */
.container :deep(.coach-comment) {
max-height: 100%;
overflow-y: auto;
overflow-wrap: break-word;
}
</style>
+4 -2
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref } from "vue";
import { onShow } from "@dcloudio/uni-app";
const props = defineProps({
@@ -73,8 +75,8 @@ onShow(async () => {
>
<slot></slot>
<view class="tips">
<text v-if="loading">加载中...</text>
<text v-if="noMore">{{ count === 0 ? "暂无数据" : "没有更多了" }}</text>
<text v-if="loading">{{ t('loading') }}</text>
<text v-if="noMore">{{ count === 0 ? t('no_data_yet') : t('no_more_results') }}</text>
</view>
</scroll-view>
</template>
+6 -4
View File
@@ -1,4 +1,6 @@
<script setup>
import { t, formatBattleTip } from "@/locales";
import { ref, watch, onMounted, onBeforeUnmount, computed } from "vue";
import audioManager from "@/audioManager";
import { MESSAGETYPESV2 } from "@/constants";
@@ -135,9 +137,9 @@ watch(
const tipContent = computed(() => {
if (halfTime.value) {
return props.battleId ? "中场休息" : `中场休息(${wait.value}秒)`;
return props.battleId ? t('halftime') : t('halftime_values', { p0: wait.value });
}
return props.start && remain.value === 0 ? "时间到!" : props.tips;
return props.start && remain.value === 0 ? t('time_s_up') : props.tips;
});
const updateSound = () => {
@@ -204,7 +206,7 @@ onBeforeUnmount(() => {
<view class="container" :style="{ display: show ? 'block' : 'none' }">
<view>
<image src="https://static.shelingxingqiu.com/shootmini/static/shooter.png" mode="widthFix" />
<text>{{ tipContent }}</text>
<text>{{ formatBattleTip(tipContent) }}</text>
<button hover-class="none" @click="updateSound">
<image
:src="`https://static.shelingxingqiu.com/shootmini/static/sound${sound ? '' : '-off'}-yellow.png`"
@@ -221,7 +223,7 @@ onBeforeUnmount(() => {
transition: transitionStyle,
}"
/>
<text>剩余{{ remain }}秒</text>
<text>{{ t('remaining') }}{{ remain }}{{ t('s') }}</text>
</view>
</view>
</template>
+3 -1
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import {ref, watch, onMounted, onBeforeUnmount} from "vue";
import {RoundGoldImages} from "@/constants";
@@ -129,7 +131,7 @@ onBeforeUnmount(() => {
transition: transitionStyle,
}"
/>
<text v-if="!loading">剩余{{ remain }}秒</text>
<text v-if="!loading">{{ t('remaining') }}{{ remain }}{{ t('s') }}</text>
<text v-else>···</text>
</view>
</view>
+18 -16
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, watch } from "vue";
import { onShow } from "@dcloudio/uni-app";
import SModal from "@/components/SModal.vue";
@@ -83,25 +85,25 @@ const handleLogin = async () => {
if (loading.value) return;
if (!phone.value) {
return uni.showToast({
title: "请获取手机号",
title: t('please_authorize_your_phone_number'),
icon: "none",
});
}
if (!avatarUrl.value) {
return uni.showToast({
title: "请选择头像",
title: t('please_select_an_avatar'),
icon: "none",
});
}
if (!nickName.value) {
return uni.showToast({
title: "请输入昵称",
title: t('please_enter_a_nickname'),
icon: "none",
});
}
if (!agree.value) {
return uni.showToast({
title: "请先同意协议",
title: t('please_agree_to_the_agreements_first'),
icon: "none",
});
}
@@ -165,7 +167,7 @@ onShow(() => {
<SModal :show="show" :onClose="onClose" :noBg="noBg">
<view class="container" :style="{ background: noBg ? '#fff' : 'none' }">
<view class="avatar" :style="{ borderColor: noBg ? '#E3E3E3' : '#fff3' }">
<text :style="{ color: noBg ? '#666' : '#fff' }">手机:</text>
<text :style="{ color: noBg ? '#666' : '#fff' }">{{ t('phone') }}</text>
<button
:open-type="!phone ? 'getPhoneNumber' : ''"
@getphonenumber="getphonenumber"
@@ -176,13 +178,13 @@ onShow(() => {
phone
}}</text>
<text v-else :style="{ color: noBg ? '#666' : '#fff9' }"
>点击获取</text
>{{ t('authorize') }}</text
>
<image src="https://static.shelingxingqiu.com/shootmini/static/enter.png" mode="widthFix" />
</button>
</view>
<view class="avatar" :style="{ borderColor: noBg ? '#E3E3E3' : '#fff3' }">
<text :style="{ color: noBg ? '#666' : '#fff' }">头像:</text>
<text :style="{ color: noBg ? '#666' : '#fff' }">{{ t('avatar') }}</text>
<button
open-type="chooseAvatar"
@chooseavatar="onChooseAvatar"
@@ -191,7 +193,7 @@ onShow(() => {
>
<Avatar v-if="avatarUrl" :src="avatarUrl" :size="30" />
<text v-else :style="{ color: noBg ? '#666' : '#fff9' }"
>点击获取</text
>{{ t('authorize') }}</text
>
<image src="https://static.shelingxingqiu.com/shootmini/static/enter.png" mode="widthFix" />
</button>
@@ -200,11 +202,11 @@ onShow(() => {
class="nickname"
:style="{ borderColor: noBg ? '#E3E3E3' : '#fff3' }"
>
<text :style="{ color: noBg ? '#666' : '#fff' }">昵称:</text>
<text :style="{ color: noBg ? '#666' : '#fff' }">{{ t('nickname') }}</text>
<input
type="nickname"
:value="nickName"
placeholder="请输入昵称"
:placeholder="t('please_enter_a_nickname')"
:placeholder-style="`color: ${noBg ? '#666' : '#fff9'} `"
@input="onNicknameChange"
@change="onNicknameChange"
@@ -213,7 +215,7 @@ onShow(() => {
</view>
<SButton :rounded="20" width="80vw" :onClick="handleLogin">
<block v-if="!loading">
<text :style="{ color: '#000' }">手机号快捷登录</text>
<text :style="{ color: '#000' }">{{ t('sign_in_with_phone_number') }}</text>
</block>
<block v-else>
<image
@@ -230,19 +232,19 @@ onShow(() => {
/>
<image v-if="agree" src="https://static.shelingxingqiu.com/shootmini/static/checked.png" mode="widthFix" />
<view>
<text>已同意并阅读</text>
<text>{{ t('i_have_read_and_agree_to_the') }}</text>
<view
@click.stop="openServiceLink"
:style="{ color: noBg ? '#333' : '#ffffff99' }"
>《用户协议》</view
>{{ t('user_agreement') }}</view
>
<text>及</text>
<text>{{ t('and') }}</text>
<view
@click.stop="openPrivacyLink"
:style="{ color: noBg ? '#333' : '#ffffff99' }"
>《隐私协议》</view
>{{ t('privacy_policy') }}</view
>
<text>内容</text>
<text>{{ t('terms') }}</text>
</view>
</view>
</view>
+6 -4
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, watch } from "vue";
import SButton from "@/components/SButton.vue";
import audioManager from "@/audioManager";
@@ -77,7 +79,7 @@ const handleConfirm = () => {
<view class="header">
<view class="header-title">
<view class="header-title-line-left"></view>
<text>选择靶型</text>
<text>{{ t('select_target_type') }}</text>
<view class="header-title-line-right"></view>
</view>
<view class="close-btn" @click="onClose">
@@ -89,17 +91,17 @@ const handleConfirm = () => {
:class="{ 'target-btn': true, 'target-choosen': selectedTarget === 1 }"
@click="handleSelectTarget(1)"
>
<text>20厘米全环靶</text>
<text>{{ t('20_cm_full_ring_target') }}</text>
</view>
<view style="width: 30rpx"></view>
<view
:class="{ 'target-btn': true, 'target-choosen': selectedTarget === 2 }"
@click="handleSelectTarget(2)"
>
<text>40厘米全环靶</text>
<text>{{ t('40_cm_full_ring_target') }}</text>
</view>
</view>
<SButton width="694rpx" :onClick="handleConfirm">确定</SButton>
<SButton width="694rpx" :onClick="handleConfirm">{{ t('confirm_134') }}</SButton>
</view>
</view>
</template>
+3 -1
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, watch } from "vue";
const props = defineProps({
isRed: {
@@ -90,7 +92,7 @@ watch(
<text
v-if="isFirst(item.id)"
:style="{ backgroundColor: isRed ? '#ff6060' : '#5fadff' }"
>{{ isRed ? "红队" : "蓝队" }}</text
>{{ isRed ? t('red_team') : t('blue_team') }}</text
>
</view>
<text
+9 -9
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, onMounted, onBeforeUnmount } from "vue";
import Guide from "@/components/Guide.vue";
import BowPower from "@/components/BowPower.vue";
@@ -135,8 +137,8 @@ onBeforeUnmount(() => {
<view class="container">
<Guide v-show="guide">
<view class="guide-tips">
<text>请确保站距达到5米</text>
<text>低于5米的射箭无效</text>
<text>{{ t('stand_at_least_5_m_from_the_target') }}</text>
<text>{{ t('shots_from_under_5_m_do_not_count') }}</text>
</view>
</Guide>
<view class="test-area">
@@ -150,15 +152,13 @@ onBeforeUnmount(() => {
@click="simulShoot"
hover-class="none"
v-if="showsimul"
>
模拟射箭
</button>
>{{ t('simulate_shot') }}</button>
<view class="warnning-text">
<block v-if="statusText">
<text>{{ statusText }}</text>
</block>
<block v-else>
<text>请射箭,测试站距与靶纸</text>
<text>{{ t('shoot_to_check_distance_and_target_face') }}</text>
</block>
</view>
<view class="user-row">
@@ -169,11 +169,11 @@ onBeforeUnmount(() => {
<view v-if="isBattle" class="ready-timer">
<image src="https://static.shelingxingqiu.com/shootmini/static/test-tip.png" mode="widthFix" />
<view v-if="count >= 0">
<text>距离正式比赛还有</text>
<text>{{ t('match_starts_in') }}</text>
<text>{{ count }}</text>
<text>秒</text>
<text>{{ t('s') }}</text>
</view>
<view v-else> 进入中... </view>
<view v-else>{{ t('joining') }}</view>
</view>
</view>
</template>
+5 -3
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
const props = defineProps({
countdown: {
@@ -42,11 +44,11 @@ onBeforeUnmount(() => {
class="container"
:style="{ transform: `translateX(${show ? '0' : '100'}%)` }"
>
<view>距离正式比赛</view>
<view>{{ t('match') }}</view>
<view>
<text>开始还有</text>
<text>{{ t('starts_in') }}</text>
<text>{{ count }}</text>
<text>秒</text>
<text>{{ t('s') }}</text>
</view>
</view>
</template>
+3 -4
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { computed } from "vue";
const MAX_VISIBLE_SCORE_CARDS = 60;
@@ -59,10 +61,7 @@ const displayArrows = computed(() => {
<template>
<view v-if="displayArrows.length" class="score-panel">
<text v-if="hiddenScoreCount" class="score-window-tip">
已省略前 {{ hiddenScoreCount }} 支,仅显示最近
{{ MAX_VISIBLE_SCORE_CARDS }} 支
</text>
<text v-if="hiddenScoreCount" class="score-window-tip">{{ t('earlier') }}{{ hiddenScoreCount }}{{ t('arrows_hidden_showing_the_latest') }}{{ MAX_VISIBLE_SCORE_CARDS }}{{ t('arrows_241') }}</text>
<view class="score-grid">
<view
v-for="(arrow, index) in displayArrows"
+10 -8
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, computed, watch } from "vue";
import Avatar from "@/components/Avatar.vue";
import useStore from "@/store";
@@ -100,7 +102,7 @@ watch(
/> -->
</view>
<view class="user-stats">
<text class="level-tag level-tag-first">段位积分</text>
<text class="level-tag level-tag-first">{{ t('rank_points') }}</text>
<view class="rank-tag">
<view
class="rank-tag-progress"
@@ -121,16 +123,16 @@ watch(
mode="widthFix"
/>
<block v-if="user.ranking > 0 && rankData.rank.length">
<text>本赛季全国</text>
<text>{{ t('national_rank_this_season') }}</text>
<text class="rank-number"
>第<text :style="{ color: '#ffd700' }"
>{{ t('round') }}<text :style="{ color: '#ffd700' }"
>{{ user.ranking }}/{{ rankData.rank.length }}</text
>名</text
>{{ t('empty') }}</text
>
</block>
<block v-else>
<text>本赛季</text>
<text>暂未上榜</text>
<text>{{ t('this_season') }}</text>
<text>{{ t('unranked') }}</text>
</block>
</view>
</block>
@@ -138,9 +140,9 @@ watch(
<view class="signin" @click="onSignin">
<image src="https://static.shelingxingqiu.com/shootmini/static/user-icon.png" mode="widthFix" />
<view>
<text>新来的弓箭手你好呀~</text>
<text>{{ t('welcome_new_archer') }}</text>
<view>
<text>登录</text>
<text>{{ t('sign_in') }}</text>
<image src="https://static.shelingxingqiu.com/shootmini/static/enter-arrow-blue.png" mode="widthFix" />
</view>
</view>
+4 -2
View File
@@ -1,4 +1,6 @@
<script setup>
import { t } from "@/locales";
import { ref, onMounted, onBeforeUnmount } from "vue";
import useStore from "@/store";
import { storeToRefs } from "pinia";
@@ -76,8 +78,8 @@ onBeforeUnmount(() => {
</view>
<view class="text-content">
<image src="https://static.shelingxingqiu.com/shootmini/static/update-text-bg.png" />
<text>恭喜你升级到</text>
<text>{{ showRank ? nextRankTitle : `射灵${lvl}级` }}</text>
<text>{{ t('congratulations_you_reached') }}</text>
<text>{{ showRank ? nextRankTitle : t('sheling_level_value', { p0: lvl }) }}</text>
<text>!</text>
</view>
<!-- <button @click="onClose" hover-class="none">关闭</button> -->