1. 礼物特效

This commit is contained in:
李琦
2026-08-03 13:28:26 +08:00
parent 43957f6547
commit e9410c47a9
2 changed files with 127 additions and 39 deletions

View File

@@ -372,6 +372,44 @@
</div>
</div>
<!-- 送礼未填姓名弹出姓名模态框 -->
<Teleport to="body">
<div
v-if="showGiftNameModal"
class="fixed inset-0 z-[80] bg-black/40 flex items-center justify-center px-5"
@click.self="closeGiftNameModal"
>
<div class="gift-name-modal w-full max-w-[360px] bg-white rounded-2xl shadow-2xl px-5 pt-5 pb-4">
<div class="text-center mb-4">
<div class="text-[15px] text-[#2c2c2c] tracking-[0.12em]">留下您的姓名</div>
<div class="text-[11px] text-[#8A8680] mt-1.5 leading-relaxed">送礼需要署名方便新人知道心意来自谁</div>
</div>
<input
ref="giftNameInputRef"
v-model="giftNameDraft"
type="text"
maxlength="20"
placeholder="您的姓名"
class="w-full bg-[#Fdfbf7] border-[0.5px] border-[#a88c6b]/35 rounded-xl px-4 py-3 text-[14px] focus:outline-none focus:border-[#a88c6b]"
@keyup.enter="confirmGiftName"
/>
<div class="flex gap-2 mt-4">
<button
type="button"
class="flex-1 py-3 rounded-full text-[12px] tracking-[0.2em] border border-[#a88c6b]/30 text-[#8A8680]"
@click="closeGiftNameModal"
>取消</button>
<button
type="button"
class="flex-1 py-3 rounded-full text-[12px] tracking-[0.2em] bg-[#a88c6b] text-white"
:disabled="giftBusy"
@click="confirmGiftName"
>确认送礼</button>
</div>
</div>
</div>
</Teleport>
<!-- 主滚动区域注意不要加 scroll-smooth它会劫持 JS 滚动赋值导致卡顿 -->
<!-- iOS 自由自动滚时对该节点做 translate3d避免每帧写 scrollTop 与系统合成器打架 -->
<div ref="scrollContainerRef"
@@ -886,6 +924,10 @@ const giftTotal = ref(0)
const giftBusy = ref(false)
const showGiftPanel = ref(false)
const giftForm = reactive({ name: '' })
const showGiftNameModal = ref(false)
const giftNameDraft = ref('')
const giftNameInputRef = ref(null)
const pendingGiftType = ref('')
const giftQuota = reactive({
my_likes: 0,
spent: 0,
@@ -1776,6 +1818,62 @@ const closeGiftPanel = () => {
showGiftPanel.value = false
}
const closeGiftNameModal = () => {
showGiftNameModal.value = false
pendingGiftType.value = ''
giftNameDraft.value = ''
}
const openGiftNameModal = (giftType) => {
pendingGiftType.value = giftType
giftNameDraft.value = giftForm.name.trim() || getGuestName() || ''
showGiftNameModal.value = true
nextTick(() => {
giftNameInputRef.value?.focus?.()
})
}
const sendGiftRequest = async (giftType, name) => {
giftBusy.value = true
try {
const res = await submitGift({
giftType,
name,
clientId: getClientId(),
})
setGuestName(name)
giftForm.name = name
syncGuestNameIntoForms()
applyGiftCounts(res.data?.counts, res.data?.total)
applyGiftQuota(res.data?.quota)
if (showGiftFx.value) {
giftEffectRef.value?.play({ giftType, name, count: 1 })
}
toast.success('心意已送达')
scheduleGiftPanelClose()
} catch (e) {
toast.error(e.message || '送礼失败')
try {
const res = await getGiftStatus(getClientId())
applyGiftQuota(res.data?.quota)
} catch { /* ignore */ }
} finally {
giftBusy.value = false
}
}
const confirmGiftName = async () => {
const name = giftNameDraft.value.trim()
if (!name) return toast.error('请填写姓名')
const giftType = pendingGiftType.value
showGiftNameModal.value = false
pendingGiftType.value = ''
giftNameDraft.value = ''
if (!giftType) return
clearGiftPanelCloseTimer()
await sendGiftRequest(giftType, name)
}
const handleSendGift = async (giftType) => {
// 点了任意礼物就延后关闭;忙碌中也续上 800ms方便连送
clearGiftPanelCloseTimer()
@@ -1789,34 +1887,12 @@ const handleSendGift = async (giftType) => {
scheduleGiftPanelClose()
return toast.error(`点赞不足,再点赞 ${need} 次可兑换`)
}
const name = giftForm.name.trim()
if (!name) return toast.error('请填写姓名')
giftBusy.value = true
try {
const res = await submitGift({
giftType,
name,
clientId: getClientId(),
})
setGuestName(name)
syncGuestNameIntoForms()
applyGiftCounts(res.data?.counts, res.data?.total)
applyGiftQuota(res.data?.quota)
if (showGiftFx.value) {
giftEffectRef.value?.play({ giftType, name, count: 1 })
}
toast.success('心意已送达')
// 800ms 内再点其他礼物则继续送;否则自动收起面板
scheduleGiftPanelClose()
} catch (e) {
toast.error(e.message || '送礼失败')
try {
const res = await getGiftStatus(getClientId())
applyGiftQuota(res.data?.quota)
} catch { /* ignore */ }
} finally {
giftBusy.value = false
const name = giftForm.name.trim() || getGuestName()
if (!name) {
openGiftNameModal(giftType)
return
}
await sendGiftRequest(giftType, name)
}
const loadLikeStatus = async () => {