mrr.sj.front/pages/shop/photoAlbum/addPhoto.vue

719 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="container">
<custom-navbar :title="pageTexts[formData.type][formData.class_type].title1"
:leftImg="'/static/images/back.png'" :showUser="true" backgroundColor="#fff" titleColor="#000"
borderBottom="none"></custom-navbar>
<view class="review" v-if="imgItem.apply_state==1">
<view class="review-title">
<text class="review-title-text">审核中</text>
</view>
<text class="review-text">预计24小时完成审核通过后将自动生效</text>
</view>
<view class="review" v-if="imgItem.apply_state==2">
<view class="review-title">
<text class="review-title-text">审核成功<text style="color: #E8101E;">线上展示中</text></text>
</view>
</view>
<view class="review" v-if="imgItem.apply_state==3">
<view class="review-title">
<text class="review-title-text">已驳回</text>
</view>
<text class="review-text" v-if="imgItem.back_text">驳回原因{{ imgItem.back_text }}</text>
</view>
<view :class="{haveReview:imgItem.apply_state}">
<view class="container-card">
<view class="card-header">
<text class="card-title">{{ pageTexts[formData.type][formData.class_type].title2 }}</text>
<text class="card-title2">({{ formData.type==1?"上传1张照片":"上传1个视频" }})</text>
</view>
<view class="card-content flex-row-center-center" v-if="formData.type==1">
<view class="card-content-container">
<image v-if="formData.url" :src="formData.url" mode="aspectFill" class="preview-image"></image>
<view class="content-default" @click="chooseImage" v-else>
<image class="content-default-img" src="/static/images/icons/addPhoto.png"></image>
<text class="content-default-text">添加照片</text>
</view>
<view class="content-photo-title" v-if="formData.url" @click.stop="chooseImage">
替换图片
</view>
</view>
</view>
<view class="card-content flex-row-center-center" v-else>
<view class="card-content-container">
<image v-if="formData.url" @click="goVideo"
:src="formData.url+`?x-oss-process=video/snapshot,t_1000,m_fast,f_jpg,w_600,ar_auto`"
mode="aspectFill" class="preview-video"></image>
<view class="content-default2" @click="chooseImage" v-else>
<image class="content-default2-img" src="/static/images/icons/addPhoto.png"></image>
<text class="content-default2-text">添加视频</text>
</view>
<view class="content-photo-title" @click.stop="chooseImage" v-if="formData.url">
替换视频
</view>
<view class="content-photo-play" v-if="formData.url">
<image class="content-photo-play-img" mode="aspectFill" src="/static/images/icons/play.png">
</image>
</view>
</view>
</view>
</view>
<view class="container-card">
<view class="card-header">
<text class="card-title">{{ formData.type==1?"图片名称":"视频名称" }}</text>
</view>
<view class="card-content">
<view class="card-content-input">
<input maxlength="6" :placeholder="formData.type==1?`请输入图片名称`:`请输入视频名称`" v-model="formData.name"
placeholder-class="inputClass" :disabled="disabled" />
</view>
</view>
</view>
</view>
<!-- <view class="container-buttons flex-row-center-center" v-if="">
<view class="container-buttons-cancel flex-row-center-center">取消</view>
<view class="container-buttons-sure flex-row-center-center" @click="submitPhoto">提交</view>
</view> -->
<view class="container-buttons flex-row-center-center" v-if="imgItem.apply_state">
<view class="container-buttons-sure2 flex-row-center-center" v-if="disabled==true"
@click="disabled = false">编辑</view>
<view class="container-buttons-cancel flex-row-center-center" v-if="disabled==false"
@click="disabled = true">取消</view>
<view class="container-buttons-sure flex-row-center-center" @click="editPhoto" v-if="disabled==false">提交
</view>
</view>
<view class="container-buttons flex-row-center-center" v-else>
<view class="container-buttons-sure2 flex-row-center-center" @click="submitPhoto">提交</view>
</view>
<!-- 获取权限提示匡内容 -->
<view class="permission" :class="{ transform: isShowPer && nowQer === 'xc' }">
<view class="per-tit">美融融plus 对储存空间/照片权限申请说明</view>
<view class="per-cont">便于您使用该功能上传您的照片/图片/视频以及用于更换头像、发布商品等场景中读取相册和文件内容。</view>
</view>
<view class="permission" :class="{ transform: isShowPer && nowQer === 'xj' }">
<view class="per-tit">美融融plus 对相机拍摄权限申请说明</view>
<view class="per-cont">便于您使用该功能上传您的照片/图片/视频以及用于更换头像、发布商品等场景中所需内容。</view>
</view>
<video v-show="videoPlay" :src="videoUrl" controls id="myvideo" style="height: 0; width: 0; position: absolute; top: -999rpx; left: -999rpx;"
@fullscreenchange="screenChange"></video>
<uv-divider></uv-divider>
</view>
</template>
<script>
import request from "@/utils/request";
import uploadImage from '@/utils/albumUploadImage';
import permissionUtils from '@/utils/per';
import locationService from '@/utils/locationService';
export default {
components: {
},
data() {
return {
videoContext:null,
videoPlay: false,
videoUrl: "",
disabled: false,
isShowPer: false,
nowQer: 'xc',
formData: {
name: "",
url: "",
class_type: 1, //1主(图片/视频) 2环境(图片/视频) 3作品(图片/视频) 4其它(图片/视频)
type: 1, //1图片 2视频
},
pageTexts: {
1: {
1: {
title1: '添加店铺图片',
title2: '店铺主图',
},
2: {
title1: '添加环境图片',
title2: '环境图片',
},
3: {
title1: '添加作品图片',
title2: '作品图片',
},
4: {
title1: '添加其它图片',
title2: '其它图片',
},
},
2: {
1: {
title1: '添加店铺视频',
title2: '店铺主视频',
},
2: {
title1: '添加环境视频',
title2: '环境视频',
},
3: {
title1: '添加作品视频',
title2: '作品视频',
},
4: {
title1: '添加其它视频',
title2: '其它视频',
},
},
},
userInfo: {},
isSubmitting: false,
imgItem: {}
}
},
async onLoad(options) {
if (options.id) {
this.formData.class_type = options.id;
}
if (options.type) {
this.formData.type = options.type;
}
if (options.item) {
try {
this.imgItem = JSON.parse(decodeURIComponent(options.item));
this.formData.name = this.imgItem.auth_name
this.formData.url = this.imgItem.auth_url
this.formData.id = this.imgItem.id
this.formData.auth_id = this.imgItem.auth_id
this.disabled = true
} catch (e) {
}
}
let type = 3;
let result = await request.post("/user/getuser", {
type,
});
this.userInfo = result.data;
},
methods: {
screenChange(e) {
let fullScreen = e.detail.fullScreen; // 值true为进入全屏false为退出全屏
console.log(e, "全屏");
if (!fullScreen) {
//退出全屏
this.videoContext.pause()
plus.screen.lockOrientation('portrait-primary');
this.videoPlay = false; // 隐藏播放盒子
}
},
goVideo() {
// let urls = [this.formData.url]
// uni.navigateTo({
// url: `/pages/album/list?urls=${encodeURIComponent(JSON.stringify(urls))}`
// });
this.videoPlay = true; // 显示播放盒子
this.videoContext = uni.createVideoContext("myvideo", this); // this这个是实例对象 必传
this.videoUrl = this.formData.url;
this.videoContext.requestFullScreen({
direction: 90
});
this.videoContext.play();
},
async submitPhoto() {
// 1. 防连点核心逻辑如果正在提交中直接return阻止后续执行
if (this.isSubmitting) return;
// 2. 表单必填项校验:校验图片和名称是否填写
if (!this.formData.url) {
uni.showToast({
title: '请先上传店铺主图',
icon: 'none',
duration: 2000
});
return
}
if (!this.formData.name || this.formData.name.trim() === '') {
uni.showToast({
title: '请输入图片名称',
icon: 'none',
duration: 2000
});
return
}
try {
// 3. 开启提交锁 + 显示加载中提示
this.isSubmitting = true;
uni.showLoading({
title: '提交中...',
mask: true
});
// 4. 提交接口请求 【修复原代码传参BUGformData → this.formData】
const res = await request.post("/sj/imgVideo/add", this.formData);
if (res.code == 200) {
// 5. 提交成功:提示 + 延时返回上一页(用户能看到提示)
uni.showToast({
title: '提交成功',
icon: 'success'
});
setTimeout(() => {
uni.navigateBack({
delta: 1
}); // 返回上一级页面,核心需求
}, 1500);
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
} catch (err) {
// 6. 提交失败:异常提示
console.error('图片提交失败:', err);
uni.showToast({
title: '提交失败,请稍后重试',
icon: 'none',
duration: 2000
});
} finally {
// 7. 核心兜底:无论成功/失败/报错,都关闭加载 + 释放提交锁
uni.hideLoading();
this.isSubmitting = false;
}
},
async editPhoto() {
// 1. 防连点核心逻辑如果正在提交中直接return阻止后续执行
if (this.isSubmitting) return;
// 2. 表单必填项校验:校验图片和名称是否填写
if (!this.formData.url) {
uni.showToast({
title: '请先上传店铺主图',
icon: 'none',
duration: 2000
});
return
}
if (!this.formData.name || this.formData.name.trim() === '') {
uni.showToast({
title: '请输入图片名称',
icon: 'none',
duration: 2000
});
return
}
try {
// 3. 开启提交锁 + 显示加载中提示
this.isSubmitting = true;
uni.showLoading({
title: '提交中...',
mask: true
});
// 4. 提交接口请求 【修复原代码传参BUGformData → this.formData】
const res = await request.post("/sj/imgVideo/edit", this.formData);
if (res.code == 200) {
// 5. 提交成功:提示 + 延时返回上一页(用户能看到提示)
uni.showToast({
title: '提交成功',
icon: 'success'
});
setTimeout(() => {
uni.navigateBack({
delta: 1
}); // 返回上一级页面,核心需求
}, 1500);
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
} catch (err) {
// 6. 提交失败:异常提示
console.error('图片提交失败:', err);
uni.showToast({
title: '提交失败,请稍后重试',
icon: 'none',
duration: 2000
});
} finally {
// 7. 核心兜底:无论成功/失败/报错,都关闭加载 + 释放提交锁
uni.hideLoading();
this.isSubmitting = false;
}
},
// 打开相机
async openCamera() {
this.isShowPer = false;
let res = null
try {
uni.showLoading({
title: '上传中'
})
console.log(this.formData,'=============================');
if (this.formData.type == 1) {
res = await uploadImage.handleUpload(this.userInfo.id, 3);
} else {
res = await uploadImage.handleUpload(this.userInfo.id, 3, ['album', 'camera'],
'video');
}
console.log('上传单张图片', res)
this.formData.url = res;
} catch (err) {
console.log(err)
uni.showToast({
title: '上传失败',
icon: 'none'
}); // 新增:上传失败提示
} finally {
uni.hideLoading(); // 移到这里,必执行
}
},
// 显示权限说明弹窗
showPermissionDialog(title, content) {
return new Promise((resolve) => {
uni.showModal({
title,
content,
confirmText: '去开启',
success(res) {
resolve(res.confirm);
}
});
});
},
// 选择图片
async chooseImage() {
if (this.disabled) return
try {
const systemInfo = uni.getSystemInfoSync()
if (systemInfo.platform === 'ios') {
this.openCamera();
} else {
let xcpermission = '';
let xjpermission = '';
if (systemInfo.platform === 'ios') {
xcpermission = 'photo_library',
xjpermission = 'camera'
} else {
xcpermission =
`android.permission.READ_EXTERNAL_STORAGE,android.permission.WRITE_EXTERNAL_STORAGE`
xjpermission = 'android.permission.CAMERA'
}
const xjfirstRequest = !plus.storage.getItem(`perm_${xjpermission}`)
const xcfirstRequest = !plus.storage.getItem(`perm_${xcpermission}`)
if (xcfirstRequest || xjfirstRequest) {
this.isShowPer = true;
}
// 1. 检查权限
// const { granted } = await permissionUtils.checkPermission('photo_library', '需要相册权限用于上传照片');
this.nowQer = 'xc';
const xc = await permissionUtils.checkPermission('photo_library',
'需要相册权限用于上传照片');
this.nowQer = 'xj';
const xj = await permissionUtils.checkPermission('camera', '需要相机权限用于拍摄照片');
this.isShowPer = false;
this.nowQer = '';
if (xc.granted && xj.granted) {
this.openCamera();
return;
}
// 2. 显示权限说明弹窗
const confirm = await this.showPermissionDialog(
'相机相册权限申请',
'我们需要访问您的相机以及相册以完成更换头像功能'
);
if (!confirm) return;
// 3. 请求权限
const result1 = await permissionUtils.requestPermission('photo_library',
'我们需要访问您的相册以上传图片/视频');
const result2 = await permissionUtils.requestPermission('camera',
'我们需要访问您的相机以上传图片/视频');
if (result1 && result2) {
this.openCamera();
} else {
locationService.openAppSettings();
// uni.showToast({ title: '相机权限被拒绝', icon: 'none' });
}
}
} catch (err) {
console.log(err)
}
},
}
}
</script>
<style lang="less">
.container {
.review {
background: #FAE7EC;
border-radius: 20rpx 20rpx 0rpx 0rpx;
margin: 20rpx;
padding: 26rpx 20rpx 30rpx 20rpx;
.review-title {
margin-bottom: 6rpx;
.review-title-text {
font-weight: 500;
font-size: 28rpx;
color: #E8101E;
line-height: 40rpx;
text-align: left;
font-style: normal;
}
}
.review-text {
font-weight: 400;
font-size: 24rpx;
color: #A43F45;
line-height: 33rpx;
text-align: left;
font-style: normal;
}
}
.container-card {
border-radius: 20rpx;
margin: 20rpx;
padding: 20rpx 20rpx 30rpx 20rpx;
background: #fff;
.card-header {
margin-bottom: 20rpx;
.card-title {
font-weight: 500;
font-size: 28rpx;
color: #1D2129;
line-height: 48rpx;
text-align: left;
font-style: normal;
}
.card-title2 {
font-weight: 400;
font-size: 24rpx;
color: #999999;
line-height: 33rpx;
text-align: left;
font-style: normal;
margin-left: 10rpx;
}
}
.card-content {
.card-content-container {
position: relative;
display: flex;
overflow: hidden;
border-radius: 20rpx;
}
.preview-image {
width: 370rpx;
height: 278rpx;
border-radius: 20rpx;
}
.preview-video {
width: 520rpx;
height: 220rpx;
border-radius: 20rpx;
}
.content-default {
width: 370rpx;
height: 278rpx;
background: #F5F5F5;
border-radius: 20rpx;
background: #F5F5F5;
border-radius: 20rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.content-default-img {
width: 42rpx;
height: 35rpx;
margin-bottom: 8rpx;
}
.content-default-text {
font-weight: 400;
font-size: 22rpx;
color: #666666;
line-height: 30rpx;
text-align: left;
font-style: normal;
display: block;
}
}
.content-default2 {
width: 520rpx;
height: 220rpx;
background: #F5F5F5;
border-radius: 20rpx;
background: #F5F5F5;
border-radius: 20rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.content-default2-img {
width: 42rpx;
height: 35rpx;
margin-bottom: 8rpx;
}
.content-default2-text {
font-weight: 400;
font-size: 22rpx;
color: #666666;
line-height: 30rpx;
text-align: left;
font-style: normal;
display: block;
}
}
.content-photo-title {
background: rgba(51, 51, 51, 0.6);
padding: 8rpx 0 6rpx 0;
position: absolute;
left: 0;
right: 0;
bottom: 0;
font-weight: 400;
font-size: 24rpx;
color: #FFFFFF;
line-height: 33rpx;
text-align: center;
font-style: normal;
}
.content-photo-play {
width: 25rpx;
height: 25rpx;
position: absolute;
right: 10rpx;
top: 6rpx;
.content-photo-play-img {
width: 25rpx;
height: 25rpx;
}
}
.card-content-input {
width: 670rpx;
height: 76rpx;
background: #F5F5F5;
border-radius: 20rpx;
box-sizing: border-box;
padding: 18rpx 20rpx;
.inputClass {
font-weight: 400;
font-size: 28rpx;
color: #BFBFBF;
line-height: 40rpx;
text-align: left;
font-style: normal;
}
}
}
}
.haveReview {
transform: translateY(-30rpx);
}
.container-buttons {
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 30rpx 0;
background: #FFFFFF;
gap: 60rpx;
.container-buttons-cancel {
width: 278rpx;
height: 98rpx;
border-radius: 49rpx;
border: 1rpx solid #E8101E;
font-weight: 400;
font-size: 32rpx;
color: #E8101E;
text-align: center;
font-style: normal;
}
.container-buttons-sure {
width: 278rpx;
height: 98rpx;
background: #E8101E;
border-radius: 49rpx;
font-weight: 400;
font-size: 32rpx;
color: #FFFFFF;
text-align: center;
font-style: normal;
}
.container-buttons-sure2 {
width: 710rpx;
height: 98rpx;
background: #E8101E;
border-radius: 49rpx;
font-weight: 400;
font-size: 38rpx;
color: #FFFFFF;
text-align: left;
font-style: normal;
}
}
}
/* APP适配 */
/* #ifdef APP-PLUS */
.permission.transform {
top: calc(var(--status-bar-height) + 108rpx + 20rpx);
opacity: 1;
visibility: visible;
}
/* #endif */
</style>