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

484 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>
</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){
const parsed = JSON.parse(options.list)
this.list = Array.isArray(parsed) ? parsed : []
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
}
// 根据类型确定权限字符串和提示文本
const permissionKey = type === 3 ? 'photo_library' : 'camera';
const permissionAndroid = type === 3
? 'android.permission.READ_EXTERNAL_STORAGE,android.permission.WRITE_EXTERNAL_STORAGE'
: 'android.permission.CAMERA';
const dialogTitle = type === 3 ? '相册权限申请' : '相机权限申请';
const dialogContent = type === 3
? '我们需要访问您的相册以完成图片添加'
: '我们需要访问您的相机以完成图片拍摄';
const nowQer = type === 3 ? 'xc' : 'xj';
// 检查是否是首次请求(用于控制自定义视图显示)
const firstRequest = !plus.storage.getItem(`perm_${permissionKey}`);
if (firstRequest) {
this.isShowPer = true;
this.nowQer = nowQer;
}
// 1. 检查权限
const { granted } = await permissionUtils.checkPermission(permissionKey, dialogContent);
if (granted) {
this.isShowPer = false;
this.openCamera(type);
return;
}
// 2. 隐藏自定义视图,显示系统风格弹窗
this.isShowPer = false;
const confirm = await this.showPermissionDialog(dialogTitle, dialogContent);
if (!confirm) return;
// 3. 请求权限
const result = await permissionUtils.requestPermission(permissionKey, dialogContent);
if (result) {
this.openCamera(type);
} else {
locationService.openAppSettings();
}
} 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>