feat: card music

This commit is contained in:
zzc
2026-02-12 08:59:06 +08:00
parent 03fa790ca2
commit b6d4a8074e

View File

@@ -22,6 +22,16 @@
{{ cardDetail?.festival || "丙午马年" }} {{ cardDetail?.festival || "丙午马年" }}
</view> </view>
</view> </view>
<!-- Music Control -->
<view
v-if="cardDetail?.musicUrl"
class="music-control"
:class="{ playing: isBgmPlaying }"
@tap="toggleBgm"
>
<text class="music-icon">{{ isBgmPlaying ? "🎵" : "🔇" }}</text>
</view>
</view> </view>
<!-- Card Preview Area --> <!-- Card Preview Area -->
@@ -114,14 +124,50 @@
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref, onUnmounted } from "vue";
import { onLoad, onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app"; import {
onLoad,
onHide,
onUnload,
onShareAppMessage,
onShareTimeline,
} from "@dcloudio/uni-app";
import { getPageDetail } from "@/api/system.js"; import { getPageDetail } from "@/api/system.js";
import { getShareToken, saveViewRequest } from "@/utils/common.js"; import { getShareToken, saveViewRequest } from "@/utils/common.js";
import NavBar from "@/components/NavBar/NavBar.vue"; import NavBar from "@/components/NavBar/NavBar.vue";
const cardId = ref(""); const cardId = ref("");
const cardDetail = ref({}); const cardDetail = ref({});
const isBgmPlaying = ref(false);
const innerAudioContext = uni.createInnerAudioContext();
const initBgm = (url) => {
if (!url) return;
innerAudioContext.src = url;
innerAudioContext.loop = true;
innerAudioContext.autoplay = true;
innerAudioContext.onPlay(() => {
isBgmPlaying.value = true;
});
innerAudioContext.onPause(() => {
isBgmPlaying.value = false;
});
innerAudioContext.onStop(() => {
isBgmPlaying.value = false;
});
innerAudioContext.onError((res) => {
console.error("BGM播放错误:", res);
isBgmPlaying.value = false;
});
};
const toggleBgm = () => {
if (isBgmPlaying.value) {
innerAudioContext.pause();
} else {
innerAudioContext.play();
}
};
onLoad(async (options) => { onLoad(async (options) => {
if (options.shareToken) { if (options.shareToken) {
@@ -129,9 +175,23 @@ onLoad(async (options) => {
cardId.value = card.id; cardId.value = card.id;
cardDetail.value = card; cardDetail.value = card;
saveViewRequest(options.shareToken, "card_generate", card.id); saveViewRequest(options.shareToken, "card_generate", card.id);
if (card.musicUrl) {
initBgm(card.musicUrl);
}
} }
}); });
onHide(() => {
if (isBgmPlaying.value) {
innerAudioContext.pause();
}
});
onUnload(() => {
innerAudioContext.destroy();
});
onShareAppMessage(async () => { onShareAppMessage(async () => {
const token = await getShareToken("card_generate", cardDetail.value?.id); const token = await getShareToken("card_generate", cardDetail.value?.id);
return { return {
@@ -246,6 +306,39 @@ const goToWallpaper = () => {
padding: 20rpx 30rpx 60rpx; padding: 20rpx 30rpx 60rpx;
} }
/* Music Control */
.music-control {
margin-left: auto;
width: 64rpx;
height: 64rpx;
background: rgba(255, 59, 48, 0.05);
border: 2rpx solid rgba(255, 59, 48, 0.1);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
&.playing {
animation: rotate 3s linear infinite;
background: rgba(255, 59, 48, 0.1);
border-color: rgba(255, 59, 48, 0.2);
}
}
.music-icon {
font-size: 32rpx;
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* User Header */ /* User Header */
.user-header { .user-header {
display: flex; display: flex;