mrr.sj.front/pages/shop/add-img-text.vue

505 lines
13 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="addTextAndImg">
<custom-navbar title="添加图文" :show-back="true"></custom-navbar>
<view class="firstAdd" v-if="list.length == 0">
<view class="firstAdd-garden" @click="showPop = true">
<image src="/static/images/shop/imgAndText/add.png" mode="widthFix" class="firstAdd-garden-img"></image>
</view>
<view class="firstAdd-text">快来添加内容,介绍你的服务吧!</view>
</view>
<view v-else class="addTextAndImg-content">
<view v-for="(item, index) in list" :key="index" class="addTextAndImg-content-card">
<!-- <rich-text :nodes="item.value" v-if="item.type==1"></rich-text> -->
<uv-divider dashed v-if="item.type == 1" ></uv-divider>
<view class="addTextAndImg-content-card-text" v-if="item.type==2">{{ item.value }}</view>
<image style="width: 100%;" mode="widthFix" :src="item.value" v-else-if="item.type==3|| item.type==4"></image>
<view class="addTextAndImg-content-card-btns">
<view class="addTextAndImg-content-card-btns-btn" v-for="item2 in btns" :key="item2.id"
@click.stop="handleCard(item2.id, index)" v-if="
!(index == 0 && item2.id == 2) &&
!(index == list.length - 1 && item2.id == 3)
">
{{ item2.text }}
</view>
</view>
</view>
</view>
<view class="bottom-buttons" v-if="list.length != 0">
<button class="btn-submit" @click="submitForm">保存</button>
</view>
<uv-overlay :show="showPop" @click="showPop = false">
<view class="pop-cards">
<view class="pop-cards-card" v-for="item in addWays" :key="item.id" @click.stop="addContent(item.id)">
<image :src="item.url" class="pop-cards-card-img"></image>
<view class="pop-cards-card-text">
{{ item.text }}
</view>
</view>
<view class="pop-cards-close"> </view>
</view>
</uv-overlay>
<uv-overlay :show="showTextarea" @click="setTextarea">
<view class="pop-textarea" @tap.stop>
<textarea maxlength="-1" fixed="true" style="width: 100%;" v-model="textareaValue" />
</view>
</uv-overlay>
<!-- 获取权限提示匡内容 -->
<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>
</view>
</view>
</template>
<script>
import uploadImage from '../../utils/uploadImage'
import permissionUtils from '../../utils/per'
import locationService from '../../utils/locationService';
export default {
data() {
return {
isReplace:false,
crIndex: null, //插入位置
nowQer: 'xc',
isShowPer: false,
list: [],
textareaValue: "",
showPop: false,
showTextarea: false,
addWays: [{
text: "分割线",
id: 1,
url: "/static/images/shop/imgAndText/fenge.png",
},
{
text: "文本",
id: 2,
url: "/static/images/shop/imgAndText/text.png",
},
{
text: "图片",
id: 3,
url: "/static/images/shop/imgAndText/bz.png",
},
{
text: "相机",
id: 4,
url: "/static/images/shop/imgAndText/camera.png",
},
],
btns: [{
text: "删除",
id: 1,
},
{
text: "上移",
id: 2,
},
{
text: "下移",
id: 3,
},
{
text: "替换",
id: 4,
},
{
text: "插入",
id: 5,
},
],
};
},
onLoad(options) {
console.log(options)
if(options.list){
this.list = JSON.parse(options.list)
console.log(this.list)
}
},
methods: {
submitForm(){
uni.$emit('updateGraphicDetails', this.list);
uni.navigateBack()
},
// 定义一个函数,在数组的指定索引后插入数据
insertAfterIndex(arr, index, data) {
// 检查索引是否有效
if (index < 0 || index >= arr.length) {
console.error("索引无效");
return arr;
}
// 使用splice方法在index + 1的位置插入数据
// 第二个参数0表示不删除任何元素后面的参数是要插入的数据
arr.splice(index + 1, 0, data);
this.crIndex = null
return arr;
},
// 定义一个函数,替换数组指定索引处的数据
replaceAtIndex(arr, index, data) {
// 检查索引是否有效有效索引范围0 <= index < arr.length
if (index < 0 || index >= arr.length) {
console.error("索引无效");
return arr; // 索引无效时返回原数组
}
// 直接替换指定索引处的数据
arr[index] = data;
// 保持与插入方法一致的业务逻辑如果crIndex是你的业务变量
this.crIndex = null;
this.isReplace = false
return arr; // 返回修改后的数组
},
//写入文本
setTextarea() {
let obj = {
value: this.textareaValue,
type: 2,
};
if (this.textareaValue.length == 0) {
this.showTextarea = false
this.crIndex = null
return
}
if (this.crIndex!=null) {
if(this.isReplace){
this.replaceAtIndex(this.list, this.crIndex, obj);
}else{
this.insertAfterIndex(this.list, this.crIndex, obj);
}
} else {
this.list.push(obj);
}
this.textareaValue = ""
this.showTextarea = false
},
//操作卡片 删除,上移等
handleCard(id, index) {
switch (id) {
case 1:
this.list.splice(index, 1); // 从索引 index 开始,删除 1 个元素
this.showPop = false
break;
case 2:
// 保存要交换的两个元素
let temp = this.list[index - 1];
// 用 splice 交换:先替换 index-1 位置为 index 的值,再替换 index 位置为 temp
this.list.splice(index - 1, 1, this.list[index]); // 把 index-1 位置换成 index 的值
this.list.splice(index, 1, temp); // 把 index 位置换成原来 index-1 的值
break;
case 3:
// 保存要交换的两个元素
let temp2 = this.list[index + 1];
// 用 splice 交换:先替换 index-1 位置为 index 的值,再替换 index 位置为 temp
this.list.splice(index + 1, 1, this.list[index]); // 把 index-1 位置换成 index 的值
this.list.splice(index, 1, temp2); // 把 index 位置换成原来 index-1 的值
break;
case 4:
this.crIndex = index
this.isReplace = true
this.showPop = true
break;
case 5:
this.crIndex = index
this.showPop = true
}
},
addContent(id) {
switch (id) {
case 1:
let obj = {
value: ``,
type: 1,
};
if (this.crIndex!=null) {
if(this.isReplace){
this.replaceAtIndex(this.list, this.crIndex, obj);
}else{
this.insertAfterIndex(this.list, this.crIndex, obj);
}
} else {
this.list.push(obj);
}
this.showPop = false
break;
case 2:
this.showTextarea = true
this.showPop = false
break;
case 3:
this.chooseAvatar(3)
break;
case 4:
this.chooseAvatar(4)
}
},
async chooseAvatar(type) {
try {
const systemInfo = uni.getSystemInfoSync()
if(systemInfo.platform === 'ios') {
this.openCamera(type);
return
}
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'
}
let firstRequest = ""
if (type == 3) {
const firstRequest = !plus.storage.getItem(`perm_${xcpermission}`)
} else {
const firstRequest = !plus.storage.getItem(`perm_${xjpermission}`)
}
if (firstRequest) {
this.isShowPer = true;
}
let xcj = null
let text1 = "相册权限申"
let text2 = "我们需要访问您的相册以完成图片添加"
if (type == 3) {
this.nowQer = 'xc';
xcj = await permissionUtils.checkPermission('photo_library', '需要相册权限用于上传照片');
} else {
this.nowQer = 'xj';
xcj = await permissionUtils.checkPermission('camera', '需要相机权限用于拍摄照片');
let text1 = "相机权限申"
let text2 = "我们需要访问您的相册以完成图片添加"
}
this.isShowPer = false;
this.nowQer = '';
if (xcj.granted) {
this.openCamera(type);
return;
}
// 2. 显示权限说明弹窗
const confirm = await this.showPermissionDialog(
text1,
text2
);
if (!confirm) return;
let result = null
if (type == 3) {
result = await permissionUtils.requestPermission('photo_library', '我们需要访问您的相册以上传图片');
} else {
result = await permissionUtils.requestPermission('camera', '我们需要访问您的相机以上传图片');
}
if (result) {
this.openCamera(type);
} else {
locationService.openAppSettings();
// uni.showToast({ title: '相机权限被拒绝', icon: 'none' });
}
} catch (error) {
console.error('权限处理出错:', error);
uni.showToast({
title: '权限检查失败',
icon: 'none'
});
}
},
// 显示权限说明弹窗
showPermissionDialog(title, content) {
return new Promise((resolve) => {
uni.showModal({
title,
content,
confirmText: '去开启',
success(res) {
resolve(res.confirm);
}
});
});
},
// 打开相机
async openCamera(type) {
this.isShowPer = false;
let result = null
if (type == 3) {
result = await uploadImage.handleUpload(this.$store.state.sjInfo.id ? this.$store.state.sjInfo.id :
Math.floor(Math.random() * 1000), 1, ['album']);
} else {
result = await uploadImage.handleUpload(this.$store.state.sjInfo.id ? this.$store.state.sjInfo.id :
Math.floor(Math.random() * 1000), 1, ['camera']);
}
uni.hideLoading();
// this.userInfo.head_photo = result;
let obj = {
value: result,
type: type,
};
if (this.crIndex!=null) {
if(this.isReplace){
this.replaceAtIndex(this.list, this.crIndex, obj);
}else{
this.insertAfterIndex(this.list, this.crIndex, obj);
}
} else {
this.list.push(obj);
}
this.showPop = false
},
},
};
</script>
<style lang="less">
.addTextAndImg {
padding-bottom: 110rpx;
.firstAdd {
position: fixed;
left: 50%;
top: 50%;
transform: translate3d(-50%, -50%, 0);
display: flex;
flex-wrap: wrap;
justify-content: center;
.firstAdd-garden {
width: 200rpx;
height: 200rpx;
border: 3px solid #000;
border-radius: 50%;
margin-bottom: 100rpx;
.firstAdd-garden-img{
width: 200rpx;
}
}
.firstAdd-text {
font-size: 32rpx;
text-align: center;
white-space: nowrap;
width: 750rpx;
}
}
.addTextAndImg-content {
.addTextAndImg-content-card {
.addTextAndImg-content-card-btns {
display: flex;
flex-wrap: nowrap;
justify-content: flex-end;
gap: 10rpx;
background: #f5f5f5;
padding-bottom: 10rpx;
.addTextAndImg-content-card-btns-btn {
color: rgba(232, 16, 30, 1);
border: 2rpx solid rgba(232, 16, 30, 1);
width: 80rpx;
height: 50rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
.addTextAndImg-content-card-text {
padding: 20rpx;
}
}
}
.pop-cards {
z-index: 10;
position: absolute;
left: 0;
right: 0;
bottom: 0;
background-color: #fff;
display: flex;
flex-wrap: nowrap;
gap: 63rpx;
padding: 68rpx 40rpx;
.pop-cards-card {
.pop-cards-card-img {
width: 120rpx;
height: 120rpx;
}
.pop-cards-card-text {
font-weight: 400;
font-size: 28rpx;
color: #333333;
line-height: 40rpx;
text-align: center;
font-style: normal;
}
}
}
.pop-textarea {
background-color: #fff;
margin: 200rpx 20rpx 20rpx 20rpx;
border-radius: 20rpx;
padding: 20rpx;
}
}
.permission.transform {
top: calc(var(--status-bar-height) + 88rpx + 20rpx);
opacity: 1;
visibility: visible;
}
.bottom-buttons {
position: fixed;
left: 0;
right: 0;
bottom: 0;
background-color: #fff;
height: 100rpx;
padding: 40rpx 0 64rpx;
box-sizing: border-box;
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
.btn-submit {
background-color: rgba(232, 16, 30, 1);
color: #fff;
width: 334rpx;
height: 78rpx;
line-height: 78rpx;
text-align: center;
font-size: 28rpx;
border-radius: 78rpx;
}
}
</style>