import { computed, reactive, readonly, ref } from 'vue' export interface QrCodePopupOptions { /** * Confirm callback for "Copy link" action. * Will be called when user clicks the primary button. */ onCopyLink?: (link: string) => void } export interface QrCodePopupState { visible: boolean skillId: string skillName: string skillIcon: string price: number unit: string currencyAmount: number /** Generated QR code content/URL */ qrcodeValue: string /** 当前激活的 tab:通用码 or 特定码 */ activeTab: 'general' | 'specific' /** 特定码的内部状态:表单 or 预览二维码 */ specificStep: 'form' | 'preview' /** 特定码 - 服务时长 */ specificQty: number } const state = reactive({ visible: false, skillId: '', skillName: '', skillIcon: '', price: 0, unit: '', currencyAmount: 0, qrcodeValue: '', activeTab: 'general', specificStep: 'form', specificQty: 1, }) const copyHandler = ref<((link: string) => void) | null>(null) const formattedPrice = computed(() => state.price.toLocaleString()) const currencyAmount = computed(() => state.currencyAmount.toLocaleString()) const isGeneralTab = computed(() => state.activeTab === 'general') const isSpecificForm = computed( () => state.activeTab === 'specific' && state.specificStep === 'form', ) const isSpecificPreview = computed( () => state.activeTab === 'specific' && state.specificStep === 'preview', ) const open = (options: QrCodePopupOptions) => { state.qrcodeValue = '' // Reset on open // reset tab & specific state every time open state.activeTab = 'general' state.specificStep = 'form' state.specificQty = 1 copyHandler.value = options.onCopyLink ?? null state.visible = true } const close = () => { state.visible = false } const switchTab = (tab: 'general' | 'specific') => { state.activeTab = tab // 切回通用码时,重置特定码到表单态 if (tab === 'general') { state.specificStep = 'form' } } const resetSpecificStep = () => { state.specificStep = 'form' } const setSpecificQty = (value: number) => { const next = value || 1 state.specificQty = next < 1 ? 1 : next } const generateSpecificQr = () => { state.specificStep = 'preview' } const updateQrcodeValue = (value: string) => { state.qrcodeValue = value } const updateCurrencyAmount = (value: number) => { state.currencyAmount = value } const updateSkillInfo = (info: { skillId: string, skillName: string, skillIcon: string, price: number, unit: string }) => { state.skillId = info.skillId state.skillName = info.skillName state.skillIcon = info.skillIcon state.price = info.price state.unit = info.unit } const handleCopyLink = () => { const handler = copyHandler.value if (handler) handler(state.qrcodeValue) } export const useQrCodePopup = () => { return { state: readonly(state), formattedPrice, currencyAmount, isGeneralTab, isSpecificForm, isSpecificPreview, open, close, switchTab, setSpecificQty, generateSpecificQr, handleCopyLink, updateQrcodeValue, updateCurrencyAmount, updateSkillInfo, resetSpecificStep, } }