| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- import { defineStore } from 'pinia'
- import { skillApi } from '~/api/skill'
- import type { FirstOrderDiscountChanceVo } from '~/types/api'
- /**
- * Store for first-order discount (首单1折) chance.
- * Bound to the current user; refresh on app start after login and when order status changes.
- */
- export const useFirstOrderDiscountStore = defineStore('firstOrderDiscount', {
- state: (): FirstOrderDiscountChanceVo => ({
- hasChance: false,
- discountRate: 0,
- eligiblePrice: 0,
- }),
- getters: {
- /**
- * Format discount rate for display: e.g. 0.1 (1折) => "90%" (90% off).
- */
- discountRatePercent: (state) => {
- const rate = state.discountRate
- if (rate <= 0 || rate >= 1)
- return '0%'
- return `${Math.round((1 - rate) * 100)}%`
- },
- /**
- * Get display price for a skill: apply discount when has chance, skill is eligible, and not own.
- * @param price - Original price (coins)
- * @param ownerUserNo - Skill owner userNo (optional)
- * @param currentUserNo - Current user's userNo; when equal to ownerUserNo, discount is not applied
- */
- getDisplayPrice: state => (price: number, ownerUserNo?: string, currentUserNo?: string) => {
- if (!state.hasChance || state.discountRate <= 0)
- return price
- if (ownerUserNo && currentUserNo && ownerUserNo === currentUserNo)
- return price
- if (state.eligiblePrice > 0 && price !== state.eligiblePrice)
- return price
- return Math.round(price * state.discountRate)
- },
- /** Whether discount is applied for this skill (for showing original + discounted) */
- isDiscountEligible: state => (price: number, ownerUserNo?: string, currentUserNo?: string) => {
- if (!state.hasChance || state.discountRate <= 0)
- return false
- if (ownerUserNo && currentUserNo && ownerUserNo === currentUserNo)
- return false
- if (state.eligiblePrice > 0 && price !== state.eligiblePrice)
- return false
- return true
- },
- },
- actions: {
- setChance(data: FirstOrderDiscountChanceVo) {
- this.hasChance = data.hasChance
- this.discountRate = data.discountRate
- this.eligiblePrice = data.eligiblePrice
- },
- clear() {
- this.hasChance = false
- this.discountRate = 0
- this.eligiblePrice = 0
- },
- /** Fetch current user's first-order discount chance. Call when logged in. */
- async fetchChance() {
- try {
- const data = await skillApi.firstOrderDiscountChance()
- this.setChance(data)
- return data
- }
- catch {
- this.clear()
- return null
- }
- },
- },
- })
|