feat:the words in the article can be clicked to play

This commit is contained in:
Zyronon
2025-12-01 01:00:10 +08:00
parent dab5139e7c
commit e69e6c53b8
5 changed files with 98 additions and 41 deletions

View File

@@ -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')

View File

@@ -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;

View File

@@ -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
}

View File

@@ -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

View File

@@ -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;