14 Commits
Author SHA1 Message Date
zhangyi 4245a3f947 update:按钮特效优化 2026-07-31 11:16:34 +08:00
zhangyi d6f914ca7e update:新版优化练习结束语音 2026-07-31 10:56:41 +08:00
zhangyi 959244c03a update:更新新版个人训练结束播报 2026-07-31 10:32:45 +08:00
zhangyi 3a51142bd3 Merge branch 'feat-audio2' into test 2026-07-31 10:28:40 +08:00
zhangyi 07dc8a250c update:个人训练结束修改语音 2026-07-31 10:21:30 +08:00
zhangyi 970a9874b4 Merge branch 'test' 2026-07-16 16:41:16 +08:00
zhangyi b8c5f3dd91 Merge branch 'test' 2026-07-15 15:23:57 +08:00
zhangyi 6d1a910051 Merge branch 'test' 2026-07-15 09:55:37 +08:00
zhangyi 095884d7fc Merge branch 'fix-vip' 2026-07-06 11:16:52 +08:00
zhangyi a7897af861 Merge branch 'fix-vip' 2026-07-06 09:38:15 +08:00
zhangyi fd7c4b4bbf update:优化图片 2026-07-03 17:50:55 +08:00
zhangyi efb186d242 Merge branch 'test' 2026-07-03 17:49:40 +08:00
zhangyi 4ce2e6a7c4 Merge branch 'fix-bug' 2026-06-15 09:31:27 +08:00
zhangyi 52c5b9504a update:更新靶纸 2026-06-11 18:13:46 +08:00
10 changed files with 44 additions and 11 deletions
+3
View File
@@ -89,6 +89,8 @@ export const audioFils = {
"https://static.shelingxingqiu.com/attachment/2025-11-13/de7kzzllq0futwynso.mp3",
练习开始:
"https://static.shelingxingqiu.com/attachment/2025-11-14/de88w0lmmt43nnfmoi.mp3",
练习结束:
"https://static.shelingxingqiu.com/shootmini/static/audio/%E7%BB%83%E4%B9%A0%E7%BB%93%E6%9D%9F.mp3",
射箭声音:
"https://static.shelingxingqiu.com/shootaudio/v4/v4/%E7%AE%AD%E9%A3%9E%E8%A1%8C.mp3",
命中:
@@ -102,6 +104,7 @@ const AUDIO_WARM_PRIORITY_KEYS = [
"点击按钮",
"比赛开始",
"练习开始",
"练习结束",
"请开始射击",
"轮到你了",
"比赛结束",
+5 -1
View File
@@ -46,6 +46,10 @@ const props = defineProps({
type: Function,
default: () => {},
},
endAudioKey: {
type: String,
default: "比赛结束",
},
});
const barColor = ref("#fed847");
@@ -144,7 +148,7 @@ async function onReceiveMessage(msg) {
halfTime.value = false;
audioManager.play(audioKey);
} else if (msg.type === MESSAGETYPESV2.BattleEnd) {
audioManager.play("比赛结束", false);
audioManager.play(props.endAudioKey, false);
} else if (msg.type === MESSAGETYPESV2.ShootResult) {
let arrow = {};
if (msg.details && Array.isArray(msg.details)) {
+20 -3
View File
@@ -1,12 +1,17 @@
<script setup>
import { ref, watch } from "vue";
import SButton from "@/components/SButton.vue";
import audioManager from "@/audioManager";
const props = defineProps({
show: {
type: Boolean,
default: false,
},
clickSound: {
type: Boolean,
default: false,
},
onClose: {
type: Function,
default: () => {},
@@ -39,7 +44,19 @@ watch(
{}
);
const playClickSound = () => {
if (props.clickSound) {
audioManager.play("点击按钮");
}
};
const handleSelectTarget = (target) => {
playClickSound();
selectedTarget.value = target;
};
const handleConfirm = () => {
playClickSound();
props.onConfirm(selectedTarget.value);
props.onClose();
};
@@ -70,14 +87,14 @@ const handleConfirm = () => {
<view class="target-options">
<view
:class="{ 'target-btn': true, 'target-choosen': selectedTarget === 1 }"
@click="() => (selectedTarget = 1)"
@click="handleSelectTarget(1)"
>
<text>20厘米全环靶</text>
</view>
<view style="width: 30rpx"></view>
<view
:class="{ 'target-btn': true, 'target-choosen': selectedTarget === 2 }"
@click="() => (selectedTarget = 2)"
@click="handleSelectTarget(2)"
>
<text>40厘米全环靶</text>
</view>
@@ -194,4 +211,4 @@ const handleConfirm = () => {
color: #fed847;
border: 4rpx solid #fed847;
}
</style>
</style>
+3 -1
View File
@@ -373,7 +373,7 @@ function getAckAudioKeys(message, businessMessage) {
if (businessMessage?.type === MESSAGETYPESV2.HalfRest) return ["中场休息"];
return ["比赛结束"];
case ServerMessageType.SERVER_MSG_PRACTICE_END:
return ["比赛结束"];
return [currentContext?.practiceEndAudioKey || "比赛结束"];
case ServerMessageType.SERVER_MSG_CHECK:
return getTestDistanceAudioKeys(businessMessage?.shootData);
case ServerMessageType.SERVER_MSG_NOT_ENOUGH_DISTANCE:
@@ -850,6 +850,7 @@ export function connectMatchWebSocket(options = {}) {
mode,
requestPracticeInfoOnOpen = false,
appHideResumable = false,
practiceEndAudioKey = "",
force = false,
reconnecting = false,
reconnectReason = "",
@@ -922,6 +923,7 @@ export function connectMatchWebSocket(options = {}) {
Number.isFinite(normalizedMode) ? normalizedMode > 3 : undefined,
requestPracticeInfoOnOpen: requestPracticeInfoOnOpen === true,
appHideResumable: appHideResumable === true,
practiceEndAudioKey: String(practiceEndAudioKey || "").trim(),
meleeHalfRest: isSameContext
? currentContext?.meleeHalfRest === true
: false,
+1
View File
@@ -450,6 +450,7 @@ onBeforeUnmount(() => {
}`"
:start="start"
:onStop="onOver"
end-audio-key="练习结束"
/>
<view class="user-row">
<Avatar :src="user.avatar" :size="35" />
+1
View File
@@ -459,6 +459,7 @@ onBeforeUnmount(() => {
:start="start"
:total="3600"
:onStop="onOver"
end-audio-key="练习结束"
/>
<view class="user-row">
<Avatar :src="user.avatar" :size="35" />
@@ -205,7 +205,7 @@ async function onReceiveMessage(msg) {
halfTime.value = false;
audioManager.play("比赛开始");
} else if (msg.type === MESSAGETYPESV2.BattleEnd) {
audioManager.play("比赛结束", false);
audioManager.play("练习结束", false);
} else if (msg.type === MESSAGETYPESV2.ShootResult) {
// 精准训练由页面统一等待语音和飞箭结束,其他训练保持原播放链路。
if (props.externalShootResultAudio) return;
+4 -1
View File
@@ -5,6 +5,7 @@ import Container from "@/components/Container.vue";
import TrainingDifficultyBadge from "./components/TrainingDifficultyBadge.vue";
import TrainingDifficultyPreviewCard from "./components/TrainingDifficultyPreviewCard.vue";
import TrainingDifficultyStartButton from "./components/TrainingDifficultyStartButton.vue";
import audioManager from "@/audioManager";
import {
createPractiseV2API,
endPractiseAPI,
@@ -676,6 +677,8 @@ const handleSelectDifficulty = (node) => {
return;
}
audioManager.play("点击按钮");
if (node.id === selectedDifficultyId.value) {
return;
}
@@ -810,7 +813,7 @@ onShow(() => {
<view class="difficulty-page__start">
<TrainingDifficultyStartButton
:text="selectedDifficulty.startText"
@click="handleStart"
@click="$clickSound(handleStart)"
/>
</view>
</view>
+4 -3
View File
@@ -469,7 +469,7 @@ onShow(async () => {
</view>
<view class="radar-section">
<view class="record-bubble" @click="openTrainingRecord">
<view class="record-bubble" @click="$clickSound(openTrainingRecord)">
<image
class="record-bubble-bg"
src="https://static.shelingxingqiu.com/shootmini/static/training-home/img_28.png"
@@ -530,7 +530,7 @@ onShow(async () => {
</view>
</view>
<view class="featured-card" @click="openRoutineTraining">
<view class="featured-card" @click="$clickSound(openRoutineTraining)">
<image
class="featured-card-bg"
src="https://static.shelingxingqiu.com/shootmini/static/training-home/img_22.png"
@@ -547,7 +547,7 @@ onShow(async () => {
v-for="item in visibleTrainingItems"
:key="item.id"
class="mode-card"
@click="openTrainingItem(item)"
@click="$clickSound(() => openTrainingItem(item))"
>
<view v-if="item.id === recommendedTrainingId" class="mode-tag">
推荐
@@ -572,6 +572,7 @@ onShow(async () => {
</view>
<TargetPicker
:show="showRoutineTargetPicker"
:clickSound="true"
:onClose="() => (showRoutineTargetPicker = false)"
:onConfirm="handleRoutineTargetConfirm"
/>
+2 -1
View File
@@ -765,6 +765,7 @@ const connectPracticeServer = ({
userId: user.value.id,
requestPracticeInfoOnOpen: true,
appHideResumable: appHideResumable.value,
practiceEndAudioKey: "练习结束",
});
connectionClosed.value = false;
return true;
@@ -1192,7 +1193,7 @@ function onAudioEnded(key) {
Array.from(audioWaiters).forEach((waiter) => {
if (waiter.expectedKey === key) waiter.done();
});
if (String(key || "").includes("比赛结束")) {
if (["比赛结束", "练习结束"].includes(String(key || ""))) {
void onOver();
}
}