424 lines
26 KiB
Vue
424 lines
26 KiB
Vue
<template>
|
||
<!-- 会员弹窗 — 通过 Teleport 挂载到 body -->
|
||
<Teleport to="body">
|
||
<!-- 遮罩层 — 点击关闭弹窗 -->
|
||
<div v-if="modelValue" class="member-dialog-overlay" @click="$emit('update:modelValue', false)">
|
||
<!-- 弹窗主体 — 左右布局 -->
|
||
<div class="member-dialog" @click.stop>
|
||
|
||
<!-- 左侧黑金权益栏 -->
|
||
<div class="member-dialog__left">
|
||
<!-- 装饰线条背景 -->
|
||
<div class="member-dialog__left-deco"></div>
|
||
<!-- 左栏标题 -->
|
||
<h2 class="member-dialog__left-title">Offer派会员专享权益</h2>
|
||
<p class="member-dialog__left-subtitle">解锁更多功能,让求职更高效</p>
|
||
<!-- 权益卡片列表 -->
|
||
<div class="member-dialog__benefits">
|
||
<div class="member-dialog__benefit-card">
|
||
<div class="member-dialog__benefit-icon">
|
||
<svg width="14" height="15" viewBox="0 0 13 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M4.67492 2.29867C5.07359 1.132 6.68559 1.09667 7.15825 2.19267L7.19825 2.29933L7.73625 3.87267C7.85955 4.23349 8.05879 4.56367 8.32054 4.84095C8.58229 5.11822 8.90046 5.33614 9.25359 5.48L9.39825 5.534L10.9716 6.07133C12.1383 6.47 12.1736 8.082 11.0783 8.55467L10.9716 8.59467L9.39825 9.13267C9.03731 9.25588 8.70699 9.45508 8.4296 9.71684C8.1522 9.97859 7.93418 10.2968 7.79025 10.65L7.73625 10.794L7.19892 12.368C6.80025 13.5347 5.18825 13.57 4.71625 12.4747L4.67492 12.368L4.13759 10.7947C4.01437 10.4337 3.81517 10.1034 3.55341 9.82601C3.29166 9.54862 2.97345 9.3306 2.62025 9.18667L2.47625 9.13267L0.902919 8.59533C-0.264415 8.19667 -0.299748 6.58467 0.796252 6.11267L0.902919 6.07133L2.47625 5.534C2.83707 5.4107 3.16726 5.21146 3.44453 4.94971C3.72181 4.68796 3.93973 4.36979 4.08359 4.01667L4.13759 3.87267L4.67492 2.29867ZM11.2703 1.20458e-07C11.395 -1.57315e-07 11.5172 0.0349855 11.623 0.100981C11.7288 0.166977 11.814 0.261335 11.8689 0.373333L11.9009 0.451333L12.1343 1.13533L12.8189 1.36867C12.9439 1.41113 13.0535 1.48974 13.1337 1.59454C13.214 1.69934 13.2613 1.82561 13.2698 1.95735C13.2782 2.08908 13.2473 2.22035 13.1811 2.33453C13.1148 2.4487 13.0161 2.54063 12.8976 2.59867L12.8189 2.63067L12.1349 2.864L11.9016 3.54867C11.859 3.67362 11.7804 3.78313 11.6755 3.86333C11.5707 3.94352 11.4444 3.99079 11.3127 3.99915C11.1809 4.0075 11.0497 3.97656 10.9356 3.91025C10.8214 3.84394 10.7296 3.74524 10.6716 3.62667L10.6396 3.54867L10.4063 2.86467L9.72159 2.63133C9.5966 2.58887 9.48703 2.51026 9.40677 2.40546C9.3265 2.30066 9.27916 2.17439 9.27073 2.04265C9.26231 1.91092 9.29318 1.77965 9.35944 1.66548C9.4257 1.5513 9.52436 1.45937 9.64292 1.40133L9.72159 1.36933L10.4056 1.136L10.6389 0.451333C10.6839 0.319617 10.7689 0.205272 10.8821 0.124333C10.9954 0.0433927 11.1311 -8.35209e-05 11.2703 1.20458e-07Z" fill="#FFE2A1"/>
|
||
</svg>
|
||
</div>
|
||
<div class="member-dialog__benefit-info">
|
||
<span class="member-dialog__benefit-name">AI智能投递</span>
|
||
<span class="member-dialog__benefit-desc">会员专享</span>
|
||
</div>
|
||
</div>
|
||
<div class="member-dialog__benefit-card">
|
||
<div class="member-dialog__benefit-icon">
|
||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<g clip-path="url(#clip0_2639_2062)">
|
||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.49998 1.66667C9.49998 1.62246 9.48242 1.58007 9.45116 1.54882C9.41991 1.51756 9.37752 1.5 9.33331 1.5H4.66665C4.18042 1.5 3.7141 1.69315 3.37028 2.03697C3.02647 2.38079 2.83331 2.8471 2.83331 3.33333V12.6667C2.83331 13.1529 3.02647 13.6192 3.37028 13.963C3.7141 14.3068 4.18042 14.5 4.66665 14.5H11.3333C11.8195 14.5 12.2859 14.3068 12.6297 13.963C12.9735 13.6192 13.1666 13.1529 13.1666 12.6667V6.098C13.1666 6.0538 13.1491 6.0114 13.1178 5.98015C13.0866 5.94889 13.0442 5.93133 13 5.93133H9.99998C9.86737 5.93133 9.74019 5.87865 9.64643 5.78489C9.55266 5.69112 9.49998 5.56394 9.49998 5.43133V1.66667ZM9.99998 8.16667C10.1326 8.16667 10.2598 8.21935 10.3535 8.31311C10.4473 8.40688 10.5 8.53406 10.5 8.66667C10.5 8.79927 10.4473 8.92645 10.3535 9.02022C10.2598 9.11399 10.1326 9.16667 9.99998 9.16667H5.99998C5.86737 9.16667 5.74019 9.11399 5.64643 9.02022C5.55266 8.92645 5.49998 8.79927 5.49998 8.66667C5.49998 8.53406 5.55266 8.40688 5.64643 8.31311C5.74019 8.21935 5.86737 8.16667 5.99998 8.16667H9.99998ZM9.99998 10.8333C10.1326 10.8333 10.2598 10.886 10.3535 10.9798C10.4473 11.0735 10.5 11.2007 10.5 11.3333C10.5 11.4659 10.4473 11.5931 10.3535 11.6869C10.2598 11.7807 10.1326 11.8333 9.99998 11.8333H5.99998C5.86737 11.8333 5.74019 11.7807 5.64643 11.6869C5.55266 11.5931 5.49998 11.4659 5.49998 11.3333C5.49998 11.2007 5.55266 11.0735 5.64643 10.9798C5.74019 10.886 5.86737 10.8333 5.99998 10.8333H9.99998Z" fill="#FFE2A1"/>
|
||
<path d="M10.5 1.88272C10.5 1.76005 10.6287 1.68205 10.724 1.75872C10.8049 1.82405 10.8767 1.90005 10.9393 1.98672L12.948 4.78472C12.9933 4.84872 12.944 4.93139 12.8653 4.93139H10.6667C10.6225 4.93139 10.5801 4.91383 10.5488 4.88257C10.5176 4.85131 10.5 4.80892 10.5 4.76472V1.88272Z" fill="#FFE2A1"/>
|
||
</g>
|
||
<defs>
|
||
<clipPath id="clip0_2639_2062">
|
||
<rect width="16" height="16" fill="white"/>
|
||
</clipPath>
|
||
</defs>
|
||
</svg>
|
||
</div>
|
||
<div class="member-dialog__benefit-info">
|
||
<span class="member-dialog__benefit-name">AI优化简历</span>
|
||
<span class="member-dialog__benefit-desc">享受无限次数</span>
|
||
</div>
|
||
</div>
|
||
<div class="member-dialog__benefit-card">
|
||
<div class="member-dialog__benefit-icon">
|
||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M8.655 1.64404C8.70394 1.5974 8.76182 1.56116 8.82516 1.53753C8.8885 1.5139 8.95597 1.50335 9.0235 1.50654C11.9815 1.64504 14.355 4.01854 14.4935 6.97654C14.4967 7.04411 14.4861 7.11162 14.4624 7.17499C14.4388 7.23835 14.4025 7.29626 14.3558 7.3452C14.3091 7.39414 14.253 7.4331 14.1908 7.45971C14.1286 7.48632 14.0616 7.50004 13.994 7.50004H9C8.86739 7.50004 8.74021 7.44736 8.64645 7.35359C8.55268 7.25982 8.5 7.13264 8.5 7.00004V2.00604C8.49999 1.93835 8.51372 1.87136 8.54036 1.80913C8.567 1.74691 8.60601 1.69074 8.655 1.64404ZM7.345 3.14404C7.39399 3.19074 7.43299 3.24691 7.45964 3.30913C7.48628 3.37136 7.50001 3.43835 7.5 3.50604V7.25004C7.5 7.58156 7.6317 7.8995 7.86612 8.13392C8.10054 8.36834 8.41848 8.50004 8.75 8.50004H12.494C12.5617 8.49996 12.6287 8.51363 12.6909 8.54021C12.7532 8.5668 12.8094 8.60574 12.8561 8.65469C12.9029 8.70364 12.9392 8.76157 12.9629 8.82497C12.9866 8.88837 12.9972 8.95593 12.994 9.02354C12.85 12.0725 10.3335 14.5 7.25 14.5C4.0745 14.5 1.5 11.9255 1.5 8.75004C1.5 5.66604 3.9275 3.14954 6.9765 3.00654C7.04403 3.00335 7.1115 3.0139 7.17484 3.03753C7.23818 3.06116 7.29606 3.0974 7.345 3.14404Z" fill="#FFE2A1"/>
|
||
</svg>
|
||
</div>
|
||
<div class="member-dialog__benefit-info">
|
||
<span class="member-dialog__benefit-name">海量岗位数据</span>
|
||
<span class="member-dialog__benefit-desc">全网实时更新</span>
|
||
</div>
|
||
</div>
|
||
<div class="member-dialog__benefit-card">
|
||
<div class="member-dialog__benefit-icon">
|
||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M12 2C11.4696 2 10.9609 2.21071 10.5858 2.58579C10.2107 2.96086 10 3.46957 10 4C10 4.53043 10.2107 5.03914 10.5858 5.41421C10.9609 5.78929 11.4696 6 12 6C12.5304 6 13.0391 5.78929 13.4142 5.41421C13.7893 5.03914 14 4.53043 14 4C14 3.46957 13.7893 2.96086 13.4142 2.58579C13.0391 2.21071 12.5304 2 12 2Z" fill="#FFE2A1"/>
|
||
<path d="M3.33333 2.66663C2.6 2.66663 2 3.26663 2 3.99996V12.6666C2 13.4 2.6 14 3.33333 14H12C12.7333 14 13.3333 13.4 13.3333 12.6666V6.67329C12.9267 6.87329 12.48 6.99996 12 6.99996C10.3467 6.99996 9 5.65329 9 3.99996C9 3.51996 9.12667 3.07329 9.32667 2.66663H3.33333Z" fill="#FFE2A1"/>
|
||
</svg>
|
||
</div>
|
||
<div class="member-dialog__benefit-info">
|
||
<span class="member-dialog__benefit-name">校招公告速递</span>
|
||
<span class="member-dialog__benefit-desc">名企动态抢先看</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 左右分割金边 -->
|
||
<div class="member-dialog__divider"></div>
|
||
|
||
<!-- 右侧内容区 -->
|
||
<div class="member-dialog__right">
|
||
<!-- 顶部标题行 -->
|
||
<div class="member-dialog__header">
|
||
<h2 class="member-dialog__title">会员中心</h2>
|
||
<div class="member-dialog__header-actions">
|
||
<!-- 联系客服 -->
|
||
<span class="member-dialog__contact-wrap">
|
||
<span class="member-dialog__contact">联系客服</span>
|
||
<div class="member-dialog__contact-qr">
|
||
<img src="@/assets/images/nav/kg-qcCode.png" alt="客服二维码" />
|
||
<div class="member-dialog__contact-qr-arrow"></div>
|
||
</div>
|
||
</span>
|
||
<!-- 关闭按钮 -->
|
||
<span class="member-dialog__close" @click="$emit('update:modelValue', false)">✕</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 套餐选择区域 -->
|
||
<div class="member-dialog__plans">
|
||
<div
|
||
v-for="plan in plans"
|
||
:key="plan.key"
|
||
class="member-dialog__plan-card"
|
||
:class="{ 'member-dialog__plan-card--active': selectedPlan === plan.key }"
|
||
@click="selectedPlan = plan.key"
|
||
>
|
||
<!-- 推荐角标 -->
|
||
<div v-if="plan.recommend" class="member-dialog__plan-badge">超值推荐</div>
|
||
<!-- 套餐名称 -->
|
||
<div class="member-dialog__plan-name">{{ plan.name }}</div>
|
||
<!-- 价格行 -->
|
||
<div class="member-dialog__plan-price">
|
||
<span class="member-dialog__plan-price-symbol">¥</span>
|
||
<span class="member-dialog__plan-price-num">{{ plan.priceInt }}</span>
|
||
<span v-if="plan.originalPrice" class="member-dialog__plan-original">{{ plan.originalPrice }}</span>
|
||
</div>
|
||
<!-- 标签描述 -->
|
||
<div class="member-dialog__plan-tag">{{ plan.tag }}</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 步骤一:选择支付方式 + 底部应付金额购买按钮(未创建订单时显示) -->
|
||
<div v-if="!showQrCode" class="member-dialog__step-pay">
|
||
<!-- 支付方式选择 -->
|
||
<div class="member-dialog__payment-section">
|
||
<span class="member-dialog__payment-label">选择支付方式</span>
|
||
<div class="member-dialog__payment-methods">
|
||
<!-- 微信支付 -->
|
||
<div
|
||
class="member-dialog__payment-item"
|
||
:class="{ 'member-dialog__payment-item--active': selectedPayment === 'wechat' }"
|
||
@click="selectedPayment = 'wechat'"
|
||
>
|
||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<g clip-path="url(#clip0_2639_1996)">
|
||
<path d="M20.8249 10.8533C21.3364 10.8533 21.8348 10.8933 22.32 10.96C21.4282 7 17.3364 4 12.4184 4C6.8446 4 2.32001 7.84 2.32001 12.5733C2.32001 15.3067 3.8282 17.72 6.17574 19.2933L4.85116 22L8.47083 20.4133C9.2446 20.6933 10.0577 20.92 10.9233 21.04C10.8053 20.52 10.7397 19.9867 10.7397 19.4267C10.7266 14.7067 15.2512 10.8533 20.8249 10.8533ZM15.7757 7.85333C15.9411 7.85333 16.1048 7.88644 16.2576 7.95077C16.4103 8.01509 16.5491 8.10938 16.666 8.22824C16.7829 8.3471 16.8757 8.4882 16.9389 8.6435C17.0022 8.7988 17.0348 8.96524 17.0348 9.13333C17.0348 9.30143 17.0022 9.46787 16.9389 9.62317C16.8757 9.77847 16.7829 9.91957 16.666 10.0384C16.5491 10.1573 16.4103 10.2516 16.2576 10.3159C16.1048 10.3802 15.9411 10.4133 15.7757 10.4133C15.4418 10.4133 15.1216 10.2785 14.8855 10.0384C14.6494 9.79838 14.5167 9.47281 14.5167 9.13333C14.5167 8.79386 14.6494 8.46828 14.8855 8.22824C15.1216 7.98819 15.4418 7.85333 15.7757 7.85333ZM9.04788 10.4267C8.71396 10.4267 8.39373 10.2918 8.15762 10.0518C7.92151 9.81172 7.78886 9.48614 7.78886 9.14667C7.78886 8.80719 7.92151 8.48162 8.15762 8.24157C8.39373 8.00152 8.71396 7.86667 9.04788 7.86667C9.38179 7.86667 9.70202 8.00152 9.93814 8.24157C10.1742 8.48162 10.3069 8.80719 10.3069 9.14667C10.3069 9.48614 10.1742 9.81172 9.93814 10.0518C9.70202 10.2918 9.38179 10.4267 9.04788 10.4267Z" fill="#07C160"/>
|
||
<path d="M29 19.6638C29 15.9818 25.1942 13 20.5 13C15.8058 13 12 15.9818 12 19.6638C12 23.3457 15.8058 26.3276 20.5 26.3276C21.2691 26.3276 22.0117 26.2239 22.7145 26.0683L27.3027 28L25.7114 24.8885C27.7005 23.6698 29 21.8029 29 19.6638ZM17.9407 19.2489C17.6889 19.2489 17.4428 19.1759 17.2335 19.0392C17.0241 18.9024 16.861 18.708 16.7646 18.4806C16.6683 18.2532 16.643 18.0029 16.6922 17.7615C16.7413 17.5201 16.8625 17.2983 17.0406 17.1243C17.2186 16.9502 17.4454 16.8317 17.6924 16.7836C17.9393 16.7356 18.1953 16.7603 18.4279 16.8545C18.6605 16.9487 18.8593 17.1082 18.9992 17.3129C19.1391 17.5175 19.2137 17.7582 19.2137 18.0043C19.227 18.6914 18.6435 19.2489 17.9407 19.2489ZM23.046 19.2489C22.7084 19.2489 22.3846 19.1178 22.1459 18.8844C21.9071 18.651 21.773 18.3344 21.773 18.0043C21.773 17.6742 21.9071 17.3577 22.1459 17.1243C22.3846 16.8909 22.7084 16.7597 23.046 16.7597C23.3836 16.7597 23.7074 16.8909 23.9462 17.1243C24.1849 17.3577 24.319 17.6742 24.319 18.0043C24.319 18.3344 24.1849 18.651 23.9462 18.8844C23.7074 19.1178 23.3836 19.2489 23.046 19.2489Z" fill="#07C160"/>
|
||
</g>
|
||
<defs>
|
||
<clipPath id="clip0_2639_1996">
|
||
<rect width="32" height="32" fill="white"/>
|
||
</clipPath>
|
||
</defs>
|
||
</svg>
|
||
<span class="member-dialog__payment-text">微信支付</span>
|
||
<!-- 选中圆圈 -->
|
||
<div class="member-dialog__payment-radio">
|
||
<div v-if="selectedPayment === 'wechat'" class="member-dialog__payment-radio-inner"></div>
|
||
</div>
|
||
</div>
|
||
<!-- 支付宝支付 -->
|
||
<div
|
||
class="member-dialog__payment-item"
|
||
:class="{ 'member-dialog__payment-item--active': selectedPayment === 'alipay' }"
|
||
@click="selectedPayment = 'alipay'"
|
||
>
|
||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<g clip-path="url(#clip0_2639_2002)">
|
||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.4127 4.03125C17.5281 4.03125 17.6226 4.12374 17.6226 4.23954V7.82858H25.2414C25.3583 7.82858 25.4488 7.92605 25.4492 8.0431C25.4496 8.79249 25.2601 9.75641 24.8287 9.75641H17.623V12.2974H22.8164C23.0565 12.2974 23.2477 12.5015 23.2303 12.7419L23.2267 12.7891C23.2051 15.6153 22.2698 18.4489 20.7417 20.9244L21.0142 21.0439C23.4297 22.0928 26.0812 22.9505 29.3624 23.0535C29.7298 23.0652 30.0163 23.3761 29.9993 23.7449L29.9929 23.8687C29.8888 25.7353 29.3682 28.0312 27.4979 28.0312C27.2227 28.0312 26.9576 28.014 26.7016 27.9808C24.2628 27.6909 21.8177 26.1933 19.3166 24.526L18.775 24.1633L18.3641 23.8868C17.6939 24.5493 16.9634 25.1524 16.1769 25.6805C15.9834 25.8062 15.779 25.9218 15.5652 26.0275C13.5181 27.2551 11.1213 27.9891 8.45844 27.9895C4.76459 27.9895 2.05466 25.5465 2.00081 22.4783L2 22.3858L2.00081 22.3325C2.05288 19.2583 4.65006 16.8441 8.34497 16.7956L8.45841 16.7949C11.6748 16.7949 14.2916 17.8455 16.9109 19.0864L16.9248 19.0984L16.978 18.9897C17.6426 17.6065 18.1167 16.0147 18.3135 14.2254L8.16359 14.2252C8.10869 14.2252 8.05603 14.2033 8.01716 14.1645C7.97829 14.1256 7.95638 14.0728 7.95622 14.0178C7.95497 13.333 8.14369 12.2974 8.57666 12.2974H13.6419V9.75641H5.99781C5.88084 9.75641 5.79044 9.65934 5.79044 9.54188C5.79 8.83332 5.97956 7.82858 6.41087 7.82858H13.6419V5.79663L13.6428 5.73444C13.6712 4.76532 14.3841 4.03125 17.4127 4.03125ZM8.028 19.3837C5.69156 19.3837 3.76147 20.6349 3.71934 22.3791L3.71875 22.4185L3.72122 22.5201C3.72714 22.6636 3.74369 22.8064 3.77072 22.9475C4.40375 25.9708 10.6506 27.0115 15.1562 21.801L14.9053 21.6531C12.6859 20.3584 10.4044 19.3837 8.028 19.3837Z" fill="#1677FF"/>
|
||
</g>
|
||
<defs>
|
||
<clipPath id="clip0_2639_2002">
|
||
<rect width="32" height="32" fill="white"/>
|
||
</clipPath>
|
||
</defs>
|
||
</svg>
|
||
<span class="member-dialog__payment-text">支付宝支付</span>
|
||
<!-- 选中圆圈 -->
|
||
<div class="member-dialog__payment-radio">
|
||
<div v-if="selectedPayment === 'alipay'" class="member-dialog__payment-radio-inner"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 底部栏:步骤一显示应付金额+购买按钮,步骤二显示二维码+已支付 -->
|
||
<div class="member-dialog__bottom-bar" :class="{ 'member-dialog__bottom-bar--qrcode': showQrCode }">
|
||
<!-- 步骤一:应付金额 + 购买按钮 -->
|
||
<template v-if="!showQrCode">
|
||
<div class="member-dialog__footer-price">
|
||
<span class="member-dialog__footer-price-label">应付金额</span>
|
||
<span class="member-dialog__footer-price-symbol">¥</span>
|
||
<span class="member-dialog__footer-price-num">{{ currentPlan.priceInt }}</span>
|
||
</div>
|
||
<button
|
||
class="member-dialog__buy-btn"
|
||
:disabled="!selectedPayment"
|
||
@click="handleBuy"
|
||
>购买会员</button>
|
||
</template>
|
||
|
||
<!-- 步骤二:扫码支付区域 -->
|
||
<template v-else>
|
||
<!-- 二维码 -->
|
||
<div class="member-dialog__qrcode-box">
|
||
<!-- 支付宝:iframe 渲染 -->
|
||
<iframe
|
||
v-if="selectedPayment === 'alipay' && paymentFormHtml"
|
||
:srcdoc="paymentFormHtml"
|
||
frameborder="0"
|
||
class="member-dialog__qrcode-iframe qrcode-zhifubao"
|
||
scrolling="auto"
|
||
></iframe>
|
||
<!-- 微信:qrcode.js 渲染 -->
|
||
<iframe
|
||
v-if="selectedPayment === 'wechat' && wechatCodeUrl"
|
||
:srcdoc="wechatQrHtml"
|
||
frameborder="0"
|
||
class="member-dialog__qrcode-iframe qrcode-wechat"
|
||
scrolling="no"
|
||
></iframe>
|
||
</div>
|
||
<!-- 右侧信息 -->
|
||
<div class="member-dialog__qrcode-info">
|
||
<div class="member-dialog__qrcode-price-row">
|
||
<span class="member-dialog__qrcode-price-num">¥{{ currentPlan.priceInt }}</span>
|
||
<span class="member-dialog__qrcode-tip">扫码完成支付</span>
|
||
</div>
|
||
<p class="member-dialog__qrcode-agreement">
|
||
开通即代表同意 <a href="javascript:;" @click.prevent="openMemberAgreement">《会员服务协议》</a>
|
||
</p>
|
||
<!-- 已支付成功按钮 -->
|
||
<button class="member-dialog__paid-btn" @click="handleConfirmPaid">我已支付成功</button>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 协议预览弹窗 -->
|
||
<AgreementPreviewDialog v-model="showAgreementDialog" code="ae8065i3" />
|
||
</Teleport>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, computed, watch, onMounted } from 'vue'
|
||
import { useStore } from 'vuex'
|
||
import { ElMessage } from 'element-plus'
|
||
import { fetchMemberProductList, createMemberOrder, fetchOrderDetail, type MemberProduct } from '@/api/member'
|
||
import AgreementPreviewDialog from '@/components/tools/AgreementPreviewDialog.vue'
|
||
|
||
/** 组件 Props — 控制弹窗显示/隐藏 */
|
||
const props = defineProps<{ modelValue: boolean }>()
|
||
|
||
/** 组件 Emits — 通知父组件更新 modelValue */
|
||
const emit = defineEmits<{ (e: 'update:modelValue', value: boolean): void }>()
|
||
|
||
const store = useStore()
|
||
|
||
// ==================== 类型定义 ====================
|
||
|
||
/** 套餐项类型 */
|
||
interface PlanItem {
|
||
key: string
|
||
name: string
|
||
priceInt: string
|
||
originalPrice: string
|
||
tag: string
|
||
recommend?: boolean
|
||
raw: MemberProduct
|
||
}
|
||
|
||
// ==================== 状态 ====================
|
||
|
||
/** 当前选中的套餐 key */
|
||
const selectedPlan = ref('')
|
||
|
||
/** 当前选中的支付方式 */
|
||
const selectedPayment = ref('')
|
||
|
||
/** 是否显示扫码支付区域 */
|
||
const showQrCode = ref(false)
|
||
|
||
/** 支付宝表单 HTML */
|
||
const paymentFormHtml = ref('')
|
||
|
||
/** 微信支付 code_url */
|
||
const wechatCodeUrl = ref('')
|
||
|
||
/** 微信二维码 iframe srcdoc */
|
||
const wechatQrHtml = computed(() => {
|
||
if (!wechatCodeUrl.value) return ''
|
||
return `<!DOCTYPE html><html><head><meta charset="UTF-8"><script src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"><\/script><style>body{display:flex;align-items:center;justify-content:center;margin:0;height:100%;}</style></head><body><div id="qrcode"></div><script>new QRCode(document.getElementById("qrcode"),{text:"${wechatCodeUrl.value}",width:160,height:160,colorDark:"#000000",colorLight:"#ffffff",correctLevel:QRCode.CorrectLevel.H});<\/script></body></html>`
|
||
})
|
||
|
||
/** 当前订单ID */
|
||
const orderId = ref('')
|
||
|
||
/** 是否正在创建订单 */
|
||
const creatingOrder = ref(false)
|
||
|
||
/** 协议预览弹窗 */
|
||
const showAgreementDialog = ref(false)
|
||
|
||
// ==================== 监听 ====================
|
||
|
||
/** 监听弹窗开关 */
|
||
watch(() => props.modelValue, (val) => {
|
||
document.body.style.overflow = val ? 'hidden' : ''
|
||
if (!val) {
|
||
showQrCode.value = false
|
||
selectedPayment.value = ''
|
||
paymentFormHtml.value = ''
|
||
wechatCodeUrl.value = ''
|
||
orderId.value = ''
|
||
}
|
||
})
|
||
|
||
// ==================== 计算属性 ====================
|
||
|
||
/** 当前选中的套餐对象 */
|
||
const currentPlan = computed(() => {
|
||
return plans.value.find(p => p.key === selectedPlan.value) || plans.value[0] || { priceInt: '0', name: '', key: '', originalPrice: '', tag: '', raw: {} as MemberProduct }
|
||
})
|
||
|
||
// ==================== 数据 ====================
|
||
|
||
/** 套餐列表 */
|
||
const plans = ref<PlanItem[]>([])
|
||
|
||
/** 后端商品数据转换 */
|
||
function mapProductToPlan(product: MemberProduct): PlanItem {
|
||
const priceYuan = product.price / 100
|
||
const originalPriceYuan = product.originalPrice ? product.originalPrice / 100 : 0
|
||
const name = product.productName
|
||
const priceDisplay = Number.isInteger(priceYuan) ? String(priceYuan) : priceYuan.toFixed(2)
|
||
const originalDisplay = originalPriceYuan > priceYuan
|
||
? `¥${Number.isInteger(originalPriceYuan) ? originalPriceYuan : originalPriceYuan.toFixed(2)}`
|
||
: ''
|
||
|
||
return {
|
||
key: String(product.id),
|
||
name,
|
||
priceInt: priceDisplay,
|
||
originalPrice: originalDisplay,
|
||
tag: product.tag || '',
|
||
recommend: product.isFeatured === 1,
|
||
raw: product,
|
||
}
|
||
}
|
||
|
||
/** 加载会员商品列表 */
|
||
async function loadMemberProducts() {
|
||
try {
|
||
const res = await fetchMemberProductList()
|
||
if (res.data && res.data.length) {
|
||
const sorted = [...res.data].sort((a, b) => a.sortOrder - b.sortOrder)
|
||
plans.value = sorted.map(mapProductToPlan)
|
||
const featured = plans.value.find(p => p.recommend)
|
||
selectedPlan.value = featured ? featured.key : plans.value[0].key
|
||
}
|
||
} catch (e) {
|
||
console.error('加载会员商品列表失败', e)
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
loadMemberProducts()
|
||
})
|
||
|
||
// ==================== 事件处理 ====================
|
||
|
||
/** 点击购买会员按钮 */
|
||
async function handleBuy() {
|
||
if (!selectedPayment.value) {
|
||
ElMessage.warning('请选择付款方式')
|
||
return
|
||
}
|
||
if (creatingOrder.value) return
|
||
const plan = currentPlan.value
|
||
if (!plan || !plan.raw) return
|
||
|
||
creatingOrder.value = true
|
||
try {
|
||
const payChannel = selectedPayment.value === 'alipay' ? 2 : 1
|
||
const res = await createMemberOrder({
|
||
productId: plan.key,
|
||
payChannel,
|
||
})
|
||
if (res.data) {
|
||
orderId.value = String(res.data.orderId)
|
||
if (selectedPayment.value === 'wechat') {
|
||
wechatCodeUrl.value = res.data.payData
|
||
paymentFormHtml.value = ''
|
||
} else {
|
||
paymentFormHtml.value = res.data.payData
|
||
wechatCodeUrl.value = ''
|
||
}
|
||
showQrCode.value = true
|
||
}
|
||
} catch (e) {
|
||
console.error('创建订单失败', e)
|
||
} finally {
|
||
creatingOrder.value = false
|
||
}
|
||
}
|
||
|
||
/** 点击"我已支付成功"按钮 */
|
||
async function handleConfirmPaid() {
|
||
if (!orderId.value) return
|
||
try {
|
||
const res = await fetchOrderDetail(orderId.value)
|
||
const status = res.data?.status
|
||
if (status === 1) {
|
||
showQrCode.value = false
|
||
ElMessage.success('开通成功')
|
||
emit('update:modelValue', false)
|
||
store.dispatch('loadMemberStatus')
|
||
} else {
|
||
ElMessage.warning('未查询到支付订单,请再次确认')
|
||
}
|
||
} catch (e) {
|
||
console.error('查询订单状态失败', e)
|
||
ElMessage.error('查询失败,请稍后重试')
|
||
}
|
||
}
|
||
|
||
/** 打开会员服务协议 */
|
||
function openMemberAgreement() {
|
||
showAgreementDialog.value = true
|
||
}
|
||
</script>
|