483 lines
13 KiB
Vue
483 lines
13 KiB
Vue
<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){
|
||
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
|
||
}
|
||
// 根据类型确定权限字符串和提示文本
|
||
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> |