feat: update
This commit is contained in:
@@ -16,8 +16,8 @@ export function useWxSDK() {
|
||||
"chooseImage",
|
||||
"uploadImage",
|
||||
"previewImage",
|
||||
"onMenuShareTimeline",
|
||||
"onMenuShareAppMessage",
|
||||
"updateAppMessageShareData",
|
||||
"updateAppMessageShareData",
|
||||
"chooseWXPay",
|
||||
],
|
||||
openTagList: [],
|
||||
@@ -35,20 +35,23 @@ export function useWxSDK() {
|
||||
onSuccess = () => { },
|
||||
onCancel = () => { }
|
||||
) {
|
||||
wx.onMenuShareTimeline({
|
||||
console.log("setShareInfo called", shareInfo);
|
||||
wx.updateTimelineShareData({
|
||||
title: shareInfo.title, // 分享标题
|
||||
link: shareInfo.link, // 分享链接,可以不是当前页面,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
|
||||
imgUrl: shareInfo.imgUrl,
|
||||
success: function () {
|
||||
console.log("分享朋友圈成功", e);
|
||||
// 用户确认分享后执行的回调函数
|
||||
onSuccess();
|
||||
},
|
||||
cancel: function () {
|
||||
console.log("分享朋友圈取消", e);
|
||||
onCancel();
|
||||
// 用户取消分享后执行的回调函数
|
||||
},
|
||||
});
|
||||
wx.onMenuShareAppMessage({
|
||||
wx.updateAppMessageShareData({
|
||||
title: shareInfo.title, // 分享标题
|
||||
desc: shareInfo.desc,
|
||||
link: shareInfo.link, // 分享链接,可以不是当前页面,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
|
||||
@@ -56,13 +59,13 @@ export function useWxSDK() {
|
||||
type: "link", // 分享类型,music、video或link,不填默认为link
|
||||
success: function (e) {
|
||||
// 用户确认分享后执行的回调函数
|
||||
onSuccess();
|
||||
console.log("分享成功", e);
|
||||
onSuccess();
|
||||
},
|
||||
cancel: function (e) {
|
||||
// 用户取消分享后执行的回调函数
|
||||
onCancel();
|
||||
console.log("分享取消", e);
|
||||
onCancel();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,131 +1,159 @@
|
||||
<script setup>
|
||||
import Plyr from 'plyr'
|
||||
import 'plyr/dist/plyr.css'
|
||||
import { onMounted, onUnmounted, ref } from 'vue'
|
||||
import { BsChevronLeft } from 'vue-icons-plus/bs'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { postApi } from '../api/postApi'
|
||||
import { wechatApi } from '../api/wechatApi'
|
||||
import { useWxSDK } from '../hooks/useWxSDK'
|
||||
import Plyr from "plyr";
|
||||
import "plyr/dist/plyr.css";
|
||||
import { onMounted, onUnmounted, ref } from "vue";
|
||||
import { BsChevronLeft } from "vue-icons-plus/bs";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { postApi } from "../api/postApi";
|
||||
import { wechatApi } from "../api/wechatApi";
|
||||
import { useWxSDK } from "../hooks/useWxSDK";
|
||||
|
||||
const wx = useWxSDK()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const article = ref(null)
|
||||
const buying = ref(false)
|
||||
const player = ref(null)
|
||||
const videoElement = ref(null)
|
||||
const wx = useWxSDK();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const article = ref(null);
|
||||
const buying = ref(false);
|
||||
const player = ref(null);
|
||||
const videoElement = ref(null);
|
||||
|
||||
const mediaLoaded = ref(false)
|
||||
const mediaLoaded = ref(false);
|
||||
|
||||
const initializePlayer = () => {
|
||||
if (videoElement.value) {
|
||||
player.value = new Plyr(videoElement.value, {
|
||||
controls: ['play', 'progress', 'current-time', 'duration', 'settings', 'fullscreen'],
|
||||
settings: ['speed'],
|
||||
controls: [
|
||||
"play",
|
||||
"progress",
|
||||
"current-time",
|
||||
"duration",
|
||||
"settings",
|
||||
"fullscreen",
|
||||
],
|
||||
settings: ["speed"],
|
||||
speed: { selected: 1, options: [0.5, 0.75, 1] },
|
||||
autoplay: false
|
||||
})
|
||||
autoplay: false,
|
||||
});
|
||||
|
||||
player.value.on('play', async () => {
|
||||
player.value.on("play", async () => {
|
||||
if (!mediaLoaded.value) {
|
||||
await loadVideoSource()
|
||||
await loadVideoSource();
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
player.value.on('ended', () => {
|
||||
mediaLoaded.value = false
|
||||
videoElement.value.src = ''
|
||||
})
|
||||
player.value.on("ended", () => {
|
||||
mediaLoaded.value = false;
|
||||
videoElement.value.src = "";
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const loadVideoSource = async () => {
|
||||
try {
|
||||
const { data } = await postApi.play(route.params.id)
|
||||
const { data } = await postApi.play(route.params.id);
|
||||
if (videoElement.value) {
|
||||
mediaLoaded.value = true
|
||||
|
||||
videoElement.value.src = data.url
|
||||
await player.value.restart()
|
||||
await player.value.play()
|
||||
mediaLoaded.value = true;
|
||||
|
||||
videoElement.value.src = data.url;
|
||||
await player.value.restart();
|
||||
await player.value.play();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load video:', error)
|
||||
alert('视频加载失败: ' + error.response.data)
|
||||
await player.value.stop()
|
||||
console.error("Failed to load video:", error);
|
||||
alert("视频加载失败: " + error.response.data);
|
||||
await player.value.stop();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleBuy = async () => {
|
||||
if (buying.value) return
|
||||
buying.value = true
|
||||
if (buying.value) return;
|
||||
buying.value = true;
|
||||
try {
|
||||
const response = await postApi.buy(article.value.id)
|
||||
const payData = response.data
|
||||
const response = await postApi.buy(article.value.id);
|
||||
const payData = response.data;
|
||||
|
||||
// 调用微信支付
|
||||
window.WeixinJSBridge.invoke('getBrandWCPayRequest', {
|
||||
...payData
|
||||
}, function (res) {
|
||||
if (res.err_msg === 'get_brand_wcpay_request:ok') {
|
||||
// 支付成功,刷新文章数据
|
||||
fetchArticle()
|
||||
} else {
|
||||
// 支付失败或取消
|
||||
console.error('Payment failed:', res.err_msg)
|
||||
alert('支付失败:' + (res.err_msg === 'get_brand_wcpay_request:cancel' ? '支付已取消' : '支付异常'))
|
||||
window.WeixinJSBridge.invoke(
|
||||
"getBrandWCPayRequest",
|
||||
{
|
||||
...payData,
|
||||
},
|
||||
function (res) {
|
||||
if (res.err_msg === "get_brand_wcpay_request:ok") {
|
||||
// 支付成功,刷新文章数据
|
||||
fetchArticle();
|
||||
} else {
|
||||
// 支付失败或取消
|
||||
console.error("Payment failed:", res.err_msg);
|
||||
alert(
|
||||
"支付失败:" +
|
||||
(res.err_msg === "get_brand_wcpay_request:cancel"
|
||||
? "支付已取消"
|
||||
: "支付异常")
|
||||
);
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Failed to initiate payment:', error)
|
||||
alert('发起支付失败,请稍后重试')
|
||||
console.error("Failed to initiate payment:", error);
|
||||
alert("发起支付失败,请稍后重试");
|
||||
} finally {
|
||||
buying.value = false
|
||||
buying.value = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const fetchArticle = async () => {
|
||||
try {
|
||||
const { id } = route.params
|
||||
const { data } = await postApi.show(id)
|
||||
article.value = data
|
||||
document.title = article.value.title
|
||||
const { id } = route.params;
|
||||
const { data } = await postApi.show(id);
|
||||
article.value = data;
|
||||
document.title = article.value.title;
|
||||
|
||||
// 调用微信 JS SDK 分享接口
|
||||
wx.setShareInfo({
|
||||
title: data.title,
|
||||
desc: data.content,
|
||||
title: article.value.title,
|
||||
desc: article.value.content,
|
||||
link: window.location.href,
|
||||
imgUrl: data.head_images[0]
|
||||
})
|
||||
imgUrl: data.head_images[0],
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch article:', error)
|
||||
alert("加载失败!")
|
||||
console.error("Failed to fetch article:", error);
|
||||
alert("加载失败!");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
router.back()
|
||||
}
|
||||
router.back();
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchArticle()
|
||||
initializePlayer()
|
||||
wechatApi
|
||||
.jsSdk()
|
||||
.then((resp) => {
|
||||
wx.initConfig(resp.data).then(() => {
|
||||
wx.setShareInfo({
|
||||
title: article.value.title,
|
||||
desc: article.value.content,
|
||||
link: window.location.href,
|
||||
imgUrl: article.value.head_images[0],
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Failed to initialize WeChat SDK:", error);
|
||||
})
|
||||
.finally(() => {
|
||||
|
||||
wechatApi.jsSdk().then(resp => {
|
||||
wx.initConfig(resp.data)
|
||||
}).catch(error => {
|
||||
console.error('Failed to initialize WeChat SDK:', error)
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
await fetchArticle();
|
||||
initializePlayer();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (player.value) {
|
||||
player.value.destroy()
|
||||
player.value.destroy();
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -156,7 +184,7 @@ onUnmounted(() => {
|
||||
<div class="flex items-center justify-between max-w-md mx-auto p-4">
|
||||
<div class="text-orange-600 text-2xl">
|
||||
<span class="mr-2 text-xl">¥</span>
|
||||
<span class="font-bold font-mono">
|
||||
<span class="font-bold font-mono">
|
||||
{{ (article.price / 100).toFixed(2) }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -184,7 +212,6 @@ onUnmounted(() => {
|
||||
<div class="animate-spin rounded-full h-8 w-8 border-4 border-gray-200 border-t-blue-600"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -194,4 +221,4 @@ onUnmounted(() => {
|
||||
width: 100%;
|
||||
max-height: 100vh;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -18,6 +18,7 @@ export default defineConfig({
|
||||
server: {
|
||||
port: 3000,
|
||||
open: true,
|
||||
allowedHosts: [".jdwan.com", "0.0.0.0", "127.0.0.1", "localhost", "10.1.1.108"],
|
||||
proxy: {
|
||||
'/v1': 'http://localhost:8088',
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user