|
@@ -50,8 +50,7 @@
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
- <u-popup v-model="loginShow"
|
|
|
- :mask="false" :closeable='false' mode="bottom" :mask-close-able='false'
|
|
|
+ <u-popup v-model="loginShow" :mask="false" :closeable='false' mode="bottom" :mask-close-able='false'
|
|
|
safe-area-inset-bottom>
|
|
|
<view style="height: 70vh;padding: 40rpx;position: relative;background:none;">
|
|
|
<view style="text-align: center;margin: 70rpx 0;">
|
|
@@ -59,6 +58,8 @@
|
|
|
</view>
|
|
|
</view>
|
|
|
</u-popup>
|
|
|
+ <canvas canvas-id="shareCanvas"
|
|
|
+ :style="{ position: 'absolute', top: '-10000px', width: '750px', height: '600px' }"></canvas>
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
@@ -69,7 +70,9 @@
|
|
|
loadCommentList,
|
|
|
sendComment
|
|
|
} from "@/api/edu.js"
|
|
|
- import { getToken } from '@/utils/auth.js'
|
|
|
+ import {
|
|
|
+ getToken
|
|
|
+ } from '@/utils/auth.js'
|
|
|
import {
|
|
|
useAuthStore
|
|
|
} from '@/store/authStore'
|
|
@@ -84,7 +87,7 @@
|
|
|
onLoad,
|
|
|
onShow,
|
|
|
onShareAppMessage,
|
|
|
- onShareTimeline
|
|
|
+ onShareTimeline
|
|
|
} from '@dcloudio/uni-app'
|
|
|
|
|
|
const courseDetail = ref({});
|
|
@@ -113,7 +116,7 @@
|
|
|
})
|
|
|
// 评论列表
|
|
|
const commentList = ref([])
|
|
|
-
|
|
|
+
|
|
|
// 点击tabs,切换
|
|
|
function onClickItem(e) {
|
|
|
if (currentTab.value != e) {
|
|
@@ -149,6 +152,80 @@
|
|
|
// console.log("购买该课程", courseDetail.value.id)
|
|
|
}
|
|
|
|
|
|
+ // 定义 Canvas 画布尺寸(按 5:4 比例)
|
|
|
+ const canvasWidth = ref(750); // 推荐 2倍图尺寸
|
|
|
+ const canvasHeight = ref(600);
|
|
|
+ const shareImageUrl = ref(''); // 存储处理后的图片路径
|
|
|
+
|
|
|
+ // 获取图片信息
|
|
|
+ const getImageInfo = (imgUrl) => {
|
|
|
+ return new Promise((resolve) => {
|
|
|
+ uni.getImageInfo({
|
|
|
+ src: imgUrl,
|
|
|
+ success: (res) => resolve(res),
|
|
|
+ fail: () => resolve(null)
|
|
|
+ });
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ // 动态裁剪并填充背景
|
|
|
+ const processShareImage = async (imgUrl) => {
|
|
|
+ try {
|
|
|
+ const imageInfo = await getImageInfo(imgUrl);
|
|
|
+ if (!imageInfo) return imgUrl;
|
|
|
+
|
|
|
+ const ctx = uni.createCanvasContext('shareCanvas', this);
|
|
|
+ const targetRatio = 5 / 4;
|
|
|
+ const originalRatio = imageInfo.width / imageInfo.height;
|
|
|
+
|
|
|
+ // 1. 绘制背景填充
|
|
|
+ ctx.setFillStyle('#FFFFFF'); // 自定义背景色
|
|
|
+ ctx.fillRect(0, 0, canvasWidth.value, canvasHeight.value);
|
|
|
+
|
|
|
+ // 2. 计算绘制区域
|
|
|
+ if (originalRatio < targetRatio) {
|
|
|
+ // 比例不足时:居中缩放 + 左右填充
|
|
|
+ const scale = canvasHeight.value / imageInfo.height;
|
|
|
+ const drawWidth = imageInfo.width * scale;
|
|
|
+ ctx.drawImage(
|
|
|
+ imageInfo.path,
|
|
|
+ (canvasWidth.value - drawWidth) / 2, // 水平居中
|
|
|
+ 0,
|
|
|
+ drawWidth,
|
|
|
+ canvasHeight.value
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ // 比例足够时:裁剪中间区域
|
|
|
+ const cropWidth = imageInfo.height * targetRatio;
|
|
|
+ ctx.drawImage(
|
|
|
+ imageInfo.path,
|
|
|
+ (imageInfo.width - cropWidth) / 2, // 水平居中裁剪
|
|
|
+ 0,
|
|
|
+ cropWidth,
|
|
|
+ imageInfo.height,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ canvasWidth.value,
|
|
|
+ canvasHeight.value
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 导出临时图片
|
|
|
+ ctx.draw(false, () => {
|
|
|
+ setTimeout(async () => { // 解决 Canvas 渲染延迟
|
|
|
+ const res = await uni.canvasToTempFilePath({
|
|
|
+ canvasId: 'shareCanvas',
|
|
|
+ fileType: 'jpg',
|
|
|
+ quality: 0.9
|
|
|
+ });
|
|
|
+ shareImageUrl.value = res.tempFilePath;
|
|
|
+ }, 300);
|
|
|
+ });
|
|
|
+ } catch (err) {
|
|
|
+ return imgUrl; // 降级处理
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
function toSend() {
|
|
|
sendComment({
|
|
|
courseId: courseId.value,
|
|
@@ -173,7 +250,7 @@
|
|
|
|
|
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
function showBuyAction() {
|
|
|
if (courseDetail.value.viewMode === '2' &&
|
|
|
!isMember.value &&
|
|
@@ -197,13 +274,14 @@
|
|
|
return authStore.userInfo.isMember == '0' ? false : true
|
|
|
})
|
|
|
const isLogin = computed(() => {
|
|
|
- if(getToken() && authStore.isAuthenticated){
|
|
|
+ if (getToken() && authStore.isAuthenticated) {
|
|
|
return true
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
return false
|
|
|
}
|
|
|
})
|
|
|
const loginShow = ref(true)
|
|
|
+
|
|
|
function toLogin() {
|
|
|
// loginShow.value = false
|
|
|
let url = {
|
|
@@ -227,15 +305,15 @@
|
|
|
uni.setNavigationBarTitle({
|
|
|
title: title
|
|
|
});
|
|
|
- if(isLogin.value){
|
|
|
+ if (isLogin.value) {
|
|
|
loginShow.value = false
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
loginShow.value = true
|
|
|
}
|
|
|
// loginShow.value = true
|
|
|
})
|
|
|
onShow(() => {
|
|
|
- if(isLogin.value){
|
|
|
+ if (isLogin.value) {
|
|
|
init(courseId.value)
|
|
|
getComment(courseId.value)
|
|
|
}
|
|
@@ -270,15 +348,17 @@
|
|
|
new Date(formatDateS(b.commentTime)) - new Date(formatDateS(a.commentTime))
|
|
|
);
|
|
|
});
|
|
|
-
|
|
|
+
|
|
|
onShareAppMessage(async (res) => {
|
|
|
+ const processedImage = await processShareImage(courseDetail.value.cover);
|
|
|
+ // console.log(processedImage)
|
|
|
return {
|
|
|
title: courseName.value,
|
|
|
path: `/pages/goOnEdu/course/courseDetail/courseDetail?id=${courseId.value}&title=${courseName.value}`,
|
|
|
- imageUrl: courseDetail.value.cover
|
|
|
+ imageUrl: processedImage
|
|
|
};
|
|
|
})
|
|
|
-
|
|
|
+
|
|
|
onShareTimeline(async () => {
|
|
|
return {
|
|
|
title: courseName.value,
|
|
@@ -288,8 +368,8 @@
|
|
|
})
|
|
|
</script>
|
|
|
<style lang="scss">
|
|
|
- .u-drawer-bottom{
|
|
|
- background-color: transparent!important;
|
|
|
+ .u-drawer-bottom {
|
|
|
+ background-color: transparent !important;
|
|
|
}
|
|
|
</style>
|
|
|
<style lang="scss" scoped>
|