新增:分享、下载图片、视频功能登

This commit is contained in:
2025-06-09 20:09:52 +08:00
parent 522281300f
commit 4eb8ef0f54
11 changed files with 1346 additions and 56 deletions

View File

@@ -5,15 +5,23 @@
<view class="swiper">
<view v-show="swiperType == 'image'">
<u-swiper :list="swiperList" height="500rpx" :radius="0" @change="e => currentNum = e.current"
indicatorStyle="right: 20px; bottom: 50px" @click="onSwiper">
indicatorStyle="right: 20px; bottom: 50px" @click="onSwiper" @longpress="onImageLongPress">
<view slot="indicator" class="indicator-num">
<text class="indicator-num__text">{{ currentNum + 1 }}/{{ swiperList.length }}</text>
</view>
</u-swiper>
<!-- 图片下载按钮 -->
<view class="download-btn" @click="downloadCurrentImage" v-if="swiperList.length > 0">
<u-icon name="download" color="#ffffff" size="20"></u-icon>
</view>
</view>
<view class="video-box" v-show="swiperType == 'video'">
<video loop class="swiper-video" muted :autoplay="true" :src="form.videoUrl"></video>
<video loop class="swiper-video" muted :autoplay="true" :src="form.videoUrl" @longpress="onVideoLongPress"></video>
<!-- 视频下载按钮 -->
<view class="download-btn2" @click="downloadCurrentVideo" v-if="form.videoUrl">
<u-icon name="download" color="#ffffff" size="20"></u-icon>
</view>
</view>
<view class="swiper-switch">
<view @click="swiperType = 'image'" :class="{active: swiperType == 'image'}" class="swiper-switch-item">
@@ -76,6 +84,12 @@
<view class="item col-2">
租金(/){{ form.rent || '' }}
</view>
<view class="item col-2">
楼层{{ form.floor || '' }}
</view>
<view class="item col-2">
朝向{{ form.toward || '' }}
</view>
<view v-if="isManager" class="item col-2">
房号{{ form.roomNumber || '' }}
</view>
@@ -115,7 +129,7 @@
<mp-html :content="form.content" />
</view>
</view>
<template v-if="isManager">
<u-gap></u-gap>
<view class="house-card">
@@ -127,7 +141,7 @@
</view>
</view>
</template>
<!-- 房源位置 -->
<u-gap></u-gap>
<view class="house-card">
@@ -166,6 +180,10 @@
<text v-if="form.liked">已收藏</text>
<text v-else>收藏</text>
</view>
<view class="item" @click="onShare">
<u-icon name="share" size="28" color="#666666"></u-icon>
<text>分享</text>
</view>
<view class="item">
<u-button icon="map" type="error" text="预约看房" disabled
@click="$push('sub_pages/checkout/checkout?id=' + form.houseId)"></u-button>
@@ -174,19 +192,44 @@
<u-button icon="phone" type="primary" text="电话咨询" disabled @click="onCall()"></u-button>
</view>
</view>
<!-- 分享弹窗 -->
<ShareSheet
v-model="showShareSheet"
:shareTitle="shareTitle"
:shareImageUrl="shareImageUrl"
:posterApiCall="handleGenerateHousePoster"
:posterApiParam="posterApiParam"
/>
<!-- 房源海报生成器 -->
<HousePosterGenerator
ref="housePosterGenerator"
:houseData="form"
:swiperList="swiperList"
@posterGenerated="onPosterGenerated"
/>
<!-- 海报预览弹窗 -->
<GoodsPosterPopup
v-model="showPosterPreview"
:apiCall="posterPreviewApiCall"
:apiParam="{}"
/>
</view>
</template>
<script>
import * as Util from '@/utils/util.js'
import store from '@/store'
import storage from '@/utils/storage'
import * as HouseInfoApi from '@/api/house-info.js'
import * as DictApi from '@/api/dict.js'
import {
getAgentUser,
getUser
} from '@/api/user.js'
import ShareSheet from '@/components/share-sheet'
import HousePosterGenerator from '@/components/house-poster-generator'
import GoodsPosterPopup from '@/components/goods-poster-popup'
const menu = [{
name: '推荐',
@@ -293,6 +336,11 @@
const loginUserId = uni.getStorageSync('userId')
export default {
components: {
ShareSheet,
HousePosterGenerator,
GoodsPosterPopup
},
data() {
return {
houseId: 0,
@@ -327,7 +375,15 @@
}],
agentUser: {},
isManager: false,
phone: ''
phone: '',
// 分享相关数据
showShareSheet: false,
shareTitle: '',
shareImageUrl: '',
posterApiParam: {},
// 海报预览相关
showPosterPreview: false,
currentPosterUrl: ''
};
},
@@ -377,6 +433,143 @@
onSwiper(e) {
console.log(e,'deeeeee')
},
// 图片长按事件
onImageLongPress() {
if (this.swiperList.length > 0) {
uni.showActionSheet({
itemList: ['下载当前图片', '下载所有图片'],
success: (res) => {
if (res.tapIndex === 0) {
this.downloadCurrentImage();
} else if (res.tapIndex === 1) {
this.downloadAllImages();
}
}
});
}
},
// 视频长按事件
onVideoLongPress() {
if (this.form.videoUrl) {
uni.showActionSheet({
itemList: ['下载视频'],
success: (res) => {
if (res.tapIndex === 0) {
this.downloadCurrentVideo();
}
}
});
}
},
// 下载当前图片
downloadCurrentImage() {
if (this.swiperList.length === 0) {
uni.showToast({
title: '暂无图片',
icon: 'none'
});
return;
}
const currentImage = this.swiperList[this.currentNum];
const imageUrl = currentImage.image || currentImage.src || currentImage;
console.log(imageUrl,'imageUrl')
if (!imageUrl.url) {
uni.showToast({
title: '图片地址无效',
icon: 'none'
});
return;
}
Util.downloadImage(imageUrl.url);
},
// 下载所有图片
downloadAllImages() {
if (this.swiperList.length === 0) {
uni.showToast({
title: '暂无图片',
icon: 'none'
});
return;
}
uni.showModal({
title: '确认下载',
content: `确定要下载所有 ${this.swiperList.length} 张图片吗?`,
success: (res) => {
if (res.confirm) {
this.batchDownloadImages();
}
}
});
},
// 批量下载图片
batchDownloadImages() {
let downloadCount = 0;
let successCount = 0;
let failCount = 0;
const totalCount = this.swiperList.length;
uni.showLoading({
title: `下载中 0/${totalCount}`,
mask: true
});
this.swiperList.forEach((item, index) => {
const imageUrl = item.image || item.src || item;
if (!imageUrl) {
downloadCount++;
failCount++;
this.updateBatchProgress(downloadCount, successCount, failCount, totalCount);
return;
}
setTimeout(() => {
Util.downloadImage(
imageUrl,
() => {
downloadCount++;
successCount++;
this.updateBatchProgress(downloadCount, successCount, failCount, totalCount);
},
() => {
downloadCount++;
failCount++;
this.updateBatchProgress(downloadCount, successCount, failCount, totalCount);
}
);
}, index * 1000); // 每张图片间隔1秒下载避免并发过多
});
},
// 更新批量下载进度
updateBatchProgress(downloadCount, successCount, failCount, totalCount) {
if (downloadCount < totalCount) {
uni.showLoading({
title: `下载中 ${downloadCount}/${totalCount}`,
mask: true
});
} else {
uni.hideLoading();
uni.showModal({
title: '下载完成',
content: `成功:${successCount}张,失败:${failCount}`,
showCancel: false
});
}
},
// 下载当前视频
downloadCurrentVideo() {
if (!this.form.videoUrl) {
uni.showToast({
title: '暂无视频',
icon: 'none'
});
return;
}
Util.downloadVideo(this.form.videoUrl);
},
getHouseInfo() {
const app = this
const {
@@ -415,6 +608,149 @@
app.form.liked = res.data
})
},
// 分享功能
onShare() {
// 检查是否有房源信息
if (!this.form.houseTitle) {
uni.showToast({
title: '房源信息加载中...',
icon: 'none'
});
return;
}
HouseInfoApi.getGeneratePoster(this.form.houseId).then(res => {
console.log(res.data,'12312312...');
// 点击后下载海报图片 res.data
this.downloadPosterImage(res.data);
})
},
// 处理海报生成确保this上下文正确
handleGenerateHousePoster(params) {
console.log('handleGenerateHousePoster 被调用,参数:', params);
console.log('当前房源图片列表:', this.swiperList);
console.log('房源信息:', this.form);
return new Promise(async (resolve, reject) => {
try {
// 检查房源信息是否完整
if (!this.form || !this.form.houseTitle) {
throw new Error('房源信息不完整');
}
// 显示加载提示
uni.showLoading({
title: '生成海报中...',
mask: true
});
// 使用新的海报生成器
const posterUrl = await this.$refs.housePosterGenerator.generatePoster();
console.log('海报生成成功:', posterUrl);
// 隐藏加载提示
uni.hideLoading();
// 保存海报URL并显示预览弹窗
this.currentPosterUrl = posterUrl;
this.showPosterPreview = true;
resolve({
data: {
imageUrl: posterUrl
}
});
} catch (error) {
console.error('handleGenerateHousePoster 执行出错:', error);
// 隐藏加载提示
uni.hideLoading();
// 如果新海报生成失败,回退到原有逻辑
this.handleFallbackPoster()
.then(imageUrl => {
console.log('回退海报生成成功:', imageUrl);
// 保存海报URL并显示预览弹窗
this.currentPosterUrl = imageUrl;
this.showPosterPreview = true;
resolve({
data: {
imageUrl: imageUrl
}
});
})
.catch(err => {
console.log('回退海报生成也失败:', err);
reject(err);
});
}
});
},
// 回退海报生成逻辑(当新海报生成失败时使用)
handleFallbackPoster() {
return new Promise((resolve) => {
try {
// 优先使用房源的第一张图片作为海报
if (this.swiperList && this.swiperList.length > 0) {
const firstImage = this.swiperList[0];
// 支持多种图片URL格式
const imageUrl = firstImage.url || firstImage.image || firstImage.src || firstImage;
console.log('第一张图片对象:', firstImage);
console.log('提取的图片URL:', imageUrl);
if (imageUrl && typeof imageUrl === 'string' && imageUrl.trim() !== '') {
console.log('使用房源图片作为回退海报:', imageUrl);
resolve(imageUrl.trim());
return;
}
}
console.log('没有可用的房源图片,生成文字海报');
// 如果没有房源图片,生成一个包含房源信息的文字海报
const houseTitle = (this.form && this.form.houseTitle) || '房源信息';
const monthlyRent = (this.form && this.form.monthlyRent) || 0;
const houseType = (this.form && this.form.houseType) || '';
const extent = (this.form && this.form.extent) || 0;
// 使用一个简单的占位图片服务
const defaultPosterUrl = 'https://dummyimage.com/400x600/4a90e2/ffffff&text=' +
encodeURIComponent(`${houseTitle}\n${monthlyRent}元/月\n${houseType}\n${extent}`);
console.log('生成的回退海报URL:', defaultPosterUrl);
resolve(defaultPosterUrl);
} catch (error) {
console.error('handleFallbackPoster 执行出错:', error);
// 如果生成回退海报也失败,使用一个简单的占位图
resolve('https://dummyimage.com/400x600/cccccc/666666&text=房源海报');
}
});
},
// 海报生成完成回调
onPosterGenerated(posterUrl) {
console.log('海报生成完成:', posterUrl);
// 可以在这里添加额外的处理逻辑
},
// 海报预览API调用用于GoodsPosterPopup组件
posterPreviewApiCall() {
return Promise.resolve({
data: {
imageUrl: this.currentPosterUrl
}
});
},
onCall() {
if (this.agentUser && this.agentUser.phone) {
uni.makePhoneCall({
@@ -448,6 +784,75 @@
})
}
})
},
// 下载海报图片
downloadPosterImage(imageUrl) {
if (!imageUrl) {
uni.showToast({
title: '图片地址无效',
icon: 'none'
});
return;
}
// 显示加载提示
uni.showLoading({
title: '下载中...',
mask: true
});
// 下载图片
uni.downloadFile({
url: imageUrl,
success: (downloadResult) => {
if (downloadResult.statusCode === 200) {
// 保存图片到相册
uni.saveImageToPhotosAlbum({
filePath: downloadResult.tempFilePath,
success: () => {
uni.hideLoading();
uni.showToast({
title: '保存成功',
icon: 'success'
});
},
fail: (saveError) => {
uni.hideLoading();
console.error('保存图片失败:', saveError);
// 如果是权限问题,提示用户
if (saveError.errMsg && saveError.errMsg.includes('auth')) {
uni.showModal({
title: '提示',
content: '需要相册权限才能保存图片,请在设置中开启相册权限',
showCancel: false
});
} else {
uni.showToast({
title: '保存失败',
icon: 'none'
});
}
}
});
} else {
uni.hideLoading();
uni.showToast({
title: '下载失败',
icon: 'none'
});
}
},
fail: (downloadError) => {
uni.hideLoading();
console.error('下载图片失败:', downloadError);
uni.showToast({
title: '下载失败',
icon: 'none'
});
}
});
}
},
watch: {
@@ -632,7 +1037,7 @@
.title {
font-size: 30rpx;
text-overflow: -o-ellipsis-lastline;
//text-overflow: -o-ellipsis-lastline;
overflow: hidden; //溢出内容隐藏
text-overflow: ellipsis; //文本溢出部分用省略号表示
display: -webkit-box; //特别显示模式
@@ -729,4 +1134,35 @@
}
}
}
</style>
.download-btn {
position: absolute;
right: 30rpx;
top: 30rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 60rpx;
height: 60rpx;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 40rpx;
color: #FFFFFF;
font-size: 20rpx;
}
.download-btn2 {
position: absolute;
right: 30rpx;
bottom: 95rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 60rpx;
height: 60rpx;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 40rpx;
color: #FFFFFF;
font-size: 20rpx;
}
</style>