feat:the words in the article can be clicked to play
This commit is contained in:
@@ -55,6 +55,9 @@ export function levelBenefits(params) {
|
||||
export function orderCreate(params) {
|
||||
return http<{ orderNo: string }>('/member/orderCreate', params, null, 'post')
|
||||
}
|
||||
export function testPay() {
|
||||
return http('/member/testPay', null, null, 'get')
|
||||
}
|
||||
|
||||
export function orderStatus(params) {
|
||||
return http('/member/orderStatus', null, params, 'get')
|
||||
|
||||
@@ -221,6 +221,16 @@ html, body {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
transition: all .3s;
|
||||
}
|
||||
|
||||
.mobile-page {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
|
||||
@@ -19,7 +19,7 @@ export const ENV = Object.assign(map['DEV'], common)
|
||||
|
||||
export let AppEnv = {
|
||||
TOKEN: localStorage.getItem('token') ?? '',
|
||||
IS_OFFICIAL: false,
|
||||
IS_OFFICIAL: true,
|
||||
IS_LOGIN: false,
|
||||
CAN_REQUEST: false
|
||||
}
|
||||
|
||||
@@ -49,10 +49,10 @@ function goHome() {
|
||||
<IconFluentCommentEdit20Regular/>
|
||||
<span v-if="settingStore.sideExpand">反馈</span>
|
||||
</div>
|
||||
<!-- <div class="row" @click="router.push('/user')">-->
|
||||
<!-- <IconFluentPerson20Regular/>-->
|
||||
<!-- <span v-if="settingStore.sideExpand">用户</span>-->
|
||||
<!-- </div>-->
|
||||
<div class="row" @click="router.push('/user')">
|
||||
<IconFluentPerson20Regular/>
|
||||
<span v-if="settingStore.sideExpand">用户</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom flex justify-evenly ">
|
||||
<BaseIcon
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import BasePage from '@/components/BasePage.vue'
|
||||
import BaseButton from '@/components/BaseButton.vue'
|
||||
import {useRouter} from 'vue-router'
|
||||
import {useUserStore} from '@/stores/user.ts'
|
||||
import {User} from "@/apis/user.ts";
|
||||
import {computed, onMounted, onUnmounted, ref, watch} from "vue";
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useUserStore } from '@/stores/user.ts'
|
||||
import { User } from "@/apis/user.ts";
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from "vue";
|
||||
import Header from "@/components/Header.vue";
|
||||
import {
|
||||
CouponInfo,
|
||||
@@ -13,13 +13,13 @@ import {
|
||||
levelBenefits,
|
||||
orderCreate,
|
||||
orderStatus,
|
||||
setAutoRenewApi
|
||||
setAutoRenewApi, testPay
|
||||
} from "@/apis/member.ts";
|
||||
import Radio from "@/components/base/radio/Radio.vue";
|
||||
import RadioGroup from "@/components/base/radio/RadioGroup.vue";
|
||||
import {APP_NAME} from "@/config/env.ts";
|
||||
import { APP_NAME } from "@/config/env.ts";
|
||||
import Toast from "@/components/base/toast/Toast.ts";
|
||||
import {_dateFormat, _nextTick} from "@/utils";
|
||||
import { _dateFormat, _nextTick } from "@/utils";
|
||||
import InputNumber from "@/components/base/InputNumber.vue";
|
||||
import dayjs from "dayjs";
|
||||
import BaseInput from "@/components/base/BaseInput.vue";
|
||||
@@ -38,6 +38,7 @@ interface Plan {
|
||||
}
|
||||
|
||||
let loading = $ref(false);
|
||||
let showPayDialog = $ref(false);
|
||||
let selectedPaymentMethod = $ref('wechat')
|
||||
let selectedPlanId = $ref('')
|
||||
let duration = $ref(1)
|
||||
@@ -117,35 +118,35 @@ const enoughDiscount = $computed(() => {
|
||||
})
|
||||
|
||||
const endPrice = $computed(() => {
|
||||
if (!coupon.is_valid) {
|
||||
return Number(originalPrice.toFixed(2))
|
||||
}
|
||||
|
||||
if (coupon.type === 'free_trial') return 0
|
||||
|
||||
if (!enoughDiscount) {
|
||||
return Number(originalPrice.toFixed(2))
|
||||
}
|
||||
|
||||
let discountAmount = 0
|
||||
if (coupon.type === 'discount') {
|
||||
// Discount coupon: e.g., 0.8 means 20% off
|
||||
const discountRate = Number(coupon.value)
|
||||
discountAmount = originalPrice * (1 - discountRate)
|
||||
|
||||
// Apply max_discount limit if available
|
||||
if (coupon.max_discount) {
|
||||
const maxDiscount = Number(coupon.max_discount)
|
||||
discountAmount = Math.min(discountAmount, maxDiscount)
|
||||
if (!coupon.is_valid) {
|
||||
return Number(originalPrice.toFixed(2))
|
||||
}
|
||||
} else if (coupon.type === 'amount') {
|
||||
// Amount coupon: fixed amount off
|
||||
discountAmount = Number(coupon.value)
|
||||
}
|
||||
|
||||
const finalPrice = Math.max(originalPrice - discountAmount, 0)
|
||||
return finalPrice.toFixed(2)
|
||||
}
|
||||
if (coupon.type === 'free_trial') return 0
|
||||
|
||||
if (!enoughDiscount) {
|
||||
return Number(originalPrice.toFixed(2))
|
||||
}
|
||||
|
||||
let discountAmount = 0
|
||||
if (coupon.type === 'discount') {
|
||||
// Discount coupon: e.g., 0.8 means 20% off
|
||||
const discountRate = Number(coupon.value)
|
||||
discountAmount = originalPrice * (1 - discountRate)
|
||||
|
||||
// Apply max_discount limit if available
|
||||
if (coupon.max_discount) {
|
||||
const maxDiscount = Number(coupon.max_discount)
|
||||
discountAmount = Math.min(discountAmount, maxDiscount)
|
||||
}
|
||||
} else if (coupon.type === 'amount') {
|
||||
// Amount coupon: fixed amount off
|
||||
discountAmount = Number(coupon.value)
|
||||
}
|
||||
|
||||
const finalPrice = Math.max(originalPrice - discountAmount, 0)
|
||||
return finalPrice.toFixed(2)
|
||||
}
|
||||
)
|
||||
|
||||
const startDate = $computed(() => {
|
||||
@@ -232,6 +233,26 @@ onUnmounted(() => {
|
||||
})
|
||||
|
||||
async function handlePayment() {
|
||||
// const win = window.open('about:blank');
|
||||
let res1 = await testPay()
|
||||
console.log('re', res1)
|
||||
if (res1.success) {
|
||||
// win.document.write(res1.data as string);
|
||||
// win.document.close();
|
||||
showPayDialog = true
|
||||
_nextTick(() => {
|
||||
// 2. 找到 iframe
|
||||
const iframe = document.getElementById('payFrame');
|
||||
|
||||
// 3. 写入 form 字符串
|
||||
const doc = iframe.contentWindow.document;
|
||||
doc.open();
|
||||
doc.write(res1.data); // 写入 form
|
||||
doc.close(); // form 会自动提交
|
||||
})
|
||||
}
|
||||
return
|
||||
|
||||
if (loading) return
|
||||
loading = true
|
||||
let data = {
|
||||
@@ -311,8 +332,8 @@ async function getCouponInfo() {
|
||||
<span>自动续费已开启</span>
|
||||
</div>
|
||||
<PopConfirm
|
||||
title="确认取消?"
|
||||
@confirm="toggleAutoRenew"
|
||||
title="确认取消?"
|
||||
@confirm="toggleAutoRenew"
|
||||
>
|
||||
<BaseButton size="small" type="info" :loading="loading2">关闭</BaseButton>
|
||||
</PopConfirm>
|
||||
@@ -352,6 +373,18 @@ async function getCouponInfo() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<teleport to="body">
|
||||
<div class="pay-dialog center" v-if="showPayDialog">
|
||||
<div class="mask"></div>
|
||||
<div class="z-9999 relative">
|
||||
<iframe id="payFrame" class="w-[205px] h-[205px] bg-red center"></iframe>
|
||||
<IconFluentDismiss20Regular @click="showPayDialog = false"
|
||||
class="close cp text-2xl absolute -top-10 -right-10"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</teleport>
|
||||
|
||||
<div id="pay" class="mb-50" v-if="selectedPlanId">
|
||||
<!-- Page Header -->
|
||||
<div class="text-center mb-6">
|
||||
@@ -481,10 +514,21 @@ async function getCouponInfo() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</BasePage>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.pay-dialog {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
.plans {
|
||||
display: grid;
|
||||
gap: 3rem;
|
||||
|
||||
Reference in New Issue
Block a user