iot-ui-app/pages/configuration/configuration-share.vue

933 lines
24 KiB
Vue

<template>
<view class="configuration-share-box">
<view class="search-box">
<u-search placeholder="请输入名称或密码搜索" class="uni-search-bar" v-model="searchVal" @custom="searchChange" @clear="searchChange" @search="searchChange"></u-search>
</view>
<mescroll-body ref="mescrollRef" top="100" bottom="120" @init="mescrollInit" @down="downCallback" :up="upOption" @up="upCallback">
<view class="share-list">
<view class="share-item" v-for="(item,index) in shareList" :key="index">
<view v-if="item.expireType==1 && judgeTime(item.expireAt)" class="share-item-status" :style="{background:'#ccc'}">
{{judgeTime(item.expireAt)?'失效':''}}
</view>
<view class="share-item-box">
<view class="item-label">
标题:
</view>
<view class="item-value">
{{item.shareTitle}}
</view>
</view>
<view class="share-item-box">
<view class="item-label">
密码:
</view>
<view class="item-value">
{{item.password||'-'}}
</view>
</view>
<view class="share-item-box">
<view class="item-label">
有效期:
</view>
<view class="item-value">
<u-tag v-if="item.expireType===1" type="error" text="限期" mode="light" />
<u-tag v-else type="success" text="永久" mode="light" />
</view>
</view>
<view class="share-item-box">
<view class="item-label">
过期时间:
</view>
<view class="item-value">
{{item.expireAt||'-'}}
</view>
</view>
<view class="share-item-box">
<view class="item-label">
创建时间:
</view>
<view class="item-value">
{{item.createdAt}}
</view>
</view>
<div class="btn-list-box">
<u-button type="primary" :disabled="judgeTime(item.expireAt)" @click="getQrCode(item)">生成海报</u-button>
<u-button type="primary" :disabled="judgeTime(item.expireAt)" @click="lookQr(item)">查看二维码</u-button>
<u-button type="primary" :disabled="judgeTime(item.expireAt)" @click="copyUrl(item.shareUrl)">复制链接</u-button>
<!-- <u-button type="error" @click="delShare(item.id)">删除</u-button> -->
<u-button type="error" shape="square" @click="delShare(item.id)"><u-icon name="trash-fill" color="#fff" size="44"></u-icon></u-button>
</div>
</view>
</view>
</mescroll-body>
<view class="btn-box">
<button type="default" @click="add">新增分享</button>
</view>
<u-toast ref="uToast" />
<uqrcode ref="uqrcode" canvas-id="qrcode" :value="QrUrl" :queue="false" :hide="true"></uqrcode>
<u-modal v-model="QrShow" :show-confirm-button="false" :mask-close-able="true" :title="QrModelTitle">
<view class="qr-content">
<image :src="QrBase64">
<u-button cl type="primary" @click="saveQr">保存到本地</u-button>
</view>
</u-modal>
<!-- 新增分享 -->
<u-popup v-model="addShareShow" mode="bottom" border-radius="10" :closeable="true">
<view class="popup-box">
<view class="popup-box-title">
新增分享
</view>
<view class="popup-box-content">
<view class="content-item" @click="openTitlePopup">
<view class="content-item-label">
标题
</view>
<view class="content-item-value">
<text>{{addShareObj.shareTitle}}</text>
<u-icon name="arrow-right" color="#a5a4a5" style="margin-left:6rpx;" size="24"></u-icon>
</view>
</view>
<view class="content-item" @click="openPasswordPopup">
<view class="content-item-label">
密码
</view>
<view class="content-item-value">
<text>{{addShareObj.hasPw?addShareObj.password:'无'}}</text>
<u-icon name="arrow-right" color="#a5a4a5" style="margin-left:6rpx;" size="24"></u-icon>
</view>
</view>
<view class="content-item" @click="openTimePopup">
<view class="content-item-label">
有效期
</view>
<view class="content-item-value">
<text>{{addShareObj.expireType==1?addShareObj.expireAt:'永久有效'}}</text>
<u-icon name="arrow-right" color="#a5a4a5" style="margin-left:6rpx;" size="24"></u-icon>
</view>
</view>
</view>
<view class="popop-btn">
<button type="default" @click="saveShare">保存</button>
</view>
</view>
</u-popup>
<!-- 编译分享标题 -->
<u-modal v-model="shareTitleShow" title="编辑标题" :mask-close-able="true" @confirm="editTitle">
<view class="popup-title-box">
<input class="popup-title-input" placeholder="请输入标题" v-model="shareTitle" type="text">
</view>
</u-modal>
<!-- 选择密码 -->
<u-popup v-model="addPasswordShow" mode="bottom" border-radius="10" :closeable="true">
<view class="popup-box select-password">
<view class="popup-box-title">
设置密码
</view>
<view class="popup-box-content">
<view class="content-item" :class="index===2?'two':''" @click="selectPassWord(index)" v-for="(item,index) in passwordList" :key="item.id">
<view class="content-item-main">
<text>{{item.name}}</text>
<u-icon v-if="passwordIndex === index" name="checkbox-mark" color="#2979ff" class="content-item-main-icon" size="30"></u-icon>
</view>
<view class="content-item-input-box" v-if="passwordIndex===2 && index==2">
<input class="password-input" placeholder="请输入密码" cursor-spacing="30" v-model="item.value" type="text">
<view class="password-hint">
请不要输入过于简单的密码
</view>
</view>
</view>
</view>
<view class="popop-btn">
<button type="default" @click="editPassword">确认</button>
</view>
</view>
</u-popup>
<!-- 选择有效期 -->
<u-popup v-model="addTimeShow" mode="bottom" border-radius="10" :closeable="true">
<view class="popup-box select-time">
<view class="popup-box-title">
设置有效期
</view>
<view class="popup-box-content">
<view class="content-item" :class="index===4?'two':''" @click="selectTime(index)" v-for="(item,index) in timeList" :key="item.id">
<view class="content-item-main">
<text>{{item.name}}</text>
<u-icon v-if="timeIndex === index" name="checkbox-mark" color="#2979ff" class="content-item-main-icon" size="30"></u-icon>
</view>
<view class="content-item-input-box" v-if="timeIndex===4 && index==4">
<view class="time-hint">
{{item.value||'请不要输入过于简单的密码'}}
</view>
</view>
</view>
</view>
<view class="popop-btn">
<button type="default" @click="editTime">确认</button>
</view>
</view>
</u-popup>
<!-- 加载状态 -->
<u-mask :show="isOnLoadShow" >
<view class="mask-warp">
<view class="mask-box">
<u-loading mode="flower" size="40"></u-loading>
<view class="mask-txt">
加载中
</view>
</view>
</view>
</u-mask>
<!-- 时间选择器 -->
<u-picker mode="time" v-model="timeShow" :params="timeParams" @confirm="timeChange"></u-picker>
<!-- 生成海报 -->
<hch-poster ref="hchPoster" @cancel="handleCancel" :posterData.sync="posterData" />
</view>
</template>
<script>
import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js"
import HchPoster from "@/components/hch-poster/hch-poster.vue"
export default {
mixins: [MescrollMixin],
data() {
return {
searchVal:'',
upOption:{
noMoreSize: 4,
textNoMore: '---- 已经到底啦 ----',
empty:{
tip: '~ 暂无分数据 ~' // 提示
}
},
uuid:'',
name:'',
shareList:[],
total:10,
QrModelTitle:'分享二维码',
QrUrl:'1',
QrShow:false,
QrBase64:'',
addShareShow:false,
addShareObj:{
shareTitle:'',
hasPw:false,
password:'',
expireType:0,
expireAt:'',
sceneUuid:''
},
shareTitleShow:false,
shareTitle:'',
addPasswordShow:false,
passwordList:[
{
id:0,
name:'无',
status:false,
value:''
},{
id:1,
name:'系统随机生成',
status:true,
value:''
},{
id:2,
name:'自定义密码',
status:true,
value:''
}
],
passwordIndex:0,
addTimeShow:false,
timeIndex:0,
timeList:[
{
id:0,
name:'永久有效',
status:0,
day:0,
value:''
},{
id:1,
name:'7天',
status:1,
day:7,
value:''
},{
id:2,
name:'14天',
status:1,
day:14,
value:''
},{
id:3,
name:'30天',
status:1,
day:30,
value:''
},{
id:4,
name:'自定义到期时间',
status:1,
day:30,
value:''
}
],
timeShow:false,
timeParams: {
year: true,
month: true,
day: true,
hour: true,
minute: true,
second: true
},
imgPath:null,
// 海报模板数据
posterData: {
poster: {
//根据屏幕大小自动生成海报背景大小
url: "",//图片地址
r: 5, //圆角半径
w: 300, //海报宽度
h: 320, //海报高度
p: 20 //海报内边距padding
},
mainImg: {
//海报主商品图
url: "",//图片地址
r: 5, //圆角半径
w: 250, //宽度
h: 160 //高度
},
title: {
//商品标题
text: "标题",//文本
fontSize: 16, //字体大小
color: "#000", //颜色
lineHeight: 25, //行高
mt: 30, //margin-top
textAlign:"center"
},
codeImg: {
//小程序码
url: "",//图片地址
w: 70, //宽度
h: 70, //高度
mt: 20, //margin-top
r: 0 //圆角半径
},
tips: [
//提示信息
{
text: "Web 组态可视化分享~",//文本
fontSize: 14,//字体大小
color: "#2f1709",//字体颜色
align: "",//对齐方式
lineHeight: 25,//行高
mt: 20//margin-top
},
{
text: "长按/扫描识别查看",//文本
fontSize: 12,//字体大小
color: "#2f1709",//字体颜色
align: "",//对齐方式
lineHeight: 25,//行高
mt: 20//margin-top
}
]
},
isOnLoadShow:true,
}
},
components:{
HchPoster
},
onLoad(option) {
this.getFilePrefix();
// 添加加载状态、防止二维码生成太快为空
setTimeout(()=>{
this.isOnLoadShow = false;
},2000)
console.log("option",option);
this.uuid = option.uuid;
this.addShareObj.sceneUuid = option.uuid;
this.name = option.name;
this.imgPath = decodeURIComponent(option.imgPath);
uni.setNavigationBarTitle({
title: option.name + '分享列表'
});
},
methods:{
judgeTime(time){
if(time){
let oldTime = '';
let newTime = new Date().getTime();
if(this.$u.os()=='ios'){
oldTime = new Date(time.replace(/-/g,'/')).getTime();
}else{
oldTime = new Date(time).getTime();
}
if(newTime>oldTime){//判断是否
return true;
}else{
return false;
}
}else{
return false;
}
},
getFilePrefix(){
let configList = uni.getStorageSync('configList');
let configIndex = uni.getStorageSync('configIndex');
if(!configList || configIndex==-1){
uni.showToast({
title: '请求域名为空,请先添加',
icon: 'none',
duration: 1500
})
setTimeout(()=>{
uni.navigateTo({
url:'/pages/tabbar/config'
})
},1500)
}else{
console.log("filePrefix",filePrefix)
let filePrefix = configList[configIndex].protocol + configList[configIndex].address;
this.$set(this.posterData.poster,'url',filePrefix+ '/console/web/images/sys/poster.jpg')
}
},
upCallback(page){
let params = {
page: page.num,
pageSize: page.size,
// sceneUuid:this.uuid,
"Wheres": {
"wheres": [
{"field": "sceneUuid","operator": "=","value": this.uuid}
]
},
"Sorters": {
"sorters": [
{"columnKey":"id","order":"descend"}
]
},
}
if(this.searchVal!=''){
params.Wheres.wheres.push({"fields": ["shareTitle","password"],"operator": "keyword","value": this.searchVal})
}
this.$api.configurationApi.getConfigurationShareList(params).then(res => {
if(res.code === 0){
let curPageData = res.data && res.data.list;
let curPageLen = curPageData && curPageData.length || 0;
let totalSize = res.data.totalCount;
this.$nextTick(()=>{
// 隐藏下拉刷新和上拉加载的状态;
this.mescroll.endBySize(curPageLen, totalSize);
})
//设置列表数据
if(page.num == 1) this.shareList = []; //如果是第一页需手动制空列表
this.shareList = curPageLen > 0 && this.shareList.concat(curPageData); //追加新数据
this.total = totalSize;
}else{
this.$u.toast(res.msg);
this.mescroll.endErr();
}
}, error => {
this.$u.toast('服务器开小差了呢,请您稍后再试')
})
},
// 查看二维码
lookQr(item){
uni.showLoading({
mask: true,
title: '生成中...'
})
this.QrModelTitle = item.shareTitle + '分享二维码';
this.QrUrl = item.shareUrl;
// 延时150毫秒等待图片生成
setTimeout(()=>{
this.$refs.uqrcode.toTempFilePath({
success: res => {
uni.hideLoading()
this.QrBase64 = res.tempFilePath;
this.QrShow = true;
},
error:err=>{
uni.hideLoading()
}
});
},150)
},
// 获取小程序码
getQrCode(item){
let that = this;
uni.showLoading({
mask: true,
title: '生成中...'
})
this.QrModelTitle = item.shareTitle + '分享二维码';
this.QrUrl = item.shareUrl;
// 延时150毫秒等待图片生成
setTimeout(()=>{
this.$refs.uqrcode.toTempFilePath({
success: res => {
console.log("当前获取图片",res)
uni.hideLoading()
this.QrBase64 = res.tempFilePath;
// this.QrShow = true;
// #ifdef APP-PLUS
this.$set(this.posterData.mainImg,'url',this.imgPath)
this.$set(this.posterData.title,'text',this.name)
this.$set(this.posterData.codeImg,'url',res.tempFilePath)
this.$nextTick(()=>{
this.$refs.hchPoster.posterShow()
})
// #endif
// #ifdef MP-WEIXIN
this.base64ToTempFilePath(res.tempFilePath , function(tempFilePath) {
// that.orderqrpath = tempFilePath // 会在canvas中调用
that.$set(that.posterData.mainImg,'url',that.imgPath)
that.$set(that.posterData.title,'text',that.name)
that.$set(that.posterData.codeImg,'url',tempFilePath)
that.$nextTick(()=>{
that.$set(that.posterData.codeImg,'url',tempFilePath)
setTimeout(()=>{
that.$refs.hchPoster.posterShow()
},500)
})
}, function() {
console.log('转换失败')
})
// #endif
},
error:err=>{
uni.hideLoading()
}
});
},300)
},
// 将base64图片转换为临时地址
base64ToTempFilePath(base64Data, success, fail) {
const fs = uni.getFileSystemManager()
const fileName = 'temp_image_' + Date.now() + '.png' // 自定义文件名,可根据需要修改
const filePath = wx.env.USER_DATA_PATH + '/' + fileName
const imageData = base64Data.replace(/^data:image\/\w+;base64,/, "");
fs.writeFile({
filePath,
data: imageData,
encoding: 'base64',
success() {
success && success(filePath)
},
fail() {
fail && fail()
}
})
},
// 取消海报生成
handleCancel(){
console.log("取消海报生成")
},
searchChange(){
this.mescroll.resetUpScroll();
},
// 点击新增分享
add(){
this.addShareObj = {
shareTitle:this.name + this.$u.guid(4,false),
hasPw:false,
password:'',
expireType:0,
expireAt:'',
sceneUuid:this.uuid
};
this.addShareShow = true;
},
saveQr(){
this.$refs.uqrcode.save({
success: () => {
uni.showToast({
icon: 'success',
title: '保存成功'
});
}
});
},
copyUrl(url){
uni.setClipboardData({
data: url,
success: ()=>{
}
});
},
delShare(id){
uni.showModal({
title: '提示',
content: '确认要删除分享吗?',
success: (res)=>{
if (res.confirm) {
this.$api.configurationApi.delConfigurationShare({id}).then(res => {
if(res.code === 0){
this.$refs.uToast.show({
title: '删除成功',
type: 'success',
})
this.mescroll.resetUpScroll();
}else{
this.$refs.uToast.show({
title: res.message,
type: 'error',
})
}
}, error => {
this.$refs.uToast.show({
title: '服务器开小差了呢,请您稍后再试',
type: 'error',
})
})
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
},
openTitlePopup(){
this.shareTitle = this.addShareObj.shareTitle;
this.shareTitleShow = true;
},
editTitle(){
this.addShareObj.shareTitle = this.shareTitle;
},
openPasswordPopup(){
if(this.addShareObj.hasPw){
this.passwordIndex = 2;
this.passwordList[2].value = this.addShareObj.password;
}else{
this.passwordIndex = 0;
}
this.addPasswordShow = true;
},
// 选择密码
selectPassWord(index){
this.passwordIndex = index;
},
// 确认密码
editPassword(){
if(this.passwordIndex === 0){
this.addShareObj.hasPw = false;
this.addShareObj.password = '';
}else if(this.passwordIndex === 1){
this.addShareObj.hasPw = true;
this.addShareObj.password = this.$u.guid(6,false);
}else if(!this.passwordList[2].value){
this.$refs.uToast.show({
title: '请输入分享密码',
type: 'error',
})
return '';
}else{
this.addShareObj.hasPw = true;
this.addShareObj.password = this.passwordList[2].value;
}
this.addPasswordShow = false;
},
openTimePopup(){
if(this.addShareObj.expireType == 1){
this.timeIndex = 4;
this.timeList[4].value = this.addShareObj.expireAt;
}else{
this.timeIndex = 0;
}
this.addTimeShow = true;
},
selectTime(index){
this.timeIndex = index;
if(index === 0){
}else if(index === 4){
this.timeShow = true;
}else{
let time = new Date(new Date().getTime() + 60*60*24*1000*this.timeList[index].day);
if(this.$u.os() === 'ios'){
this.timeList[index].value = this.$u.timeFormat(time, 'yyyy/mm/dd hh:MM:ss');
}else{
this.timeList[index].value = this.$u.timeFormat(time, 'yyyy-mm-dd hh:MM:ss');
}
}
},
// 选择自定义时间
timeChange(e){
this.timeList[4].value = e.year + '-' + e.month + '-' + e.day + ' ' + e.hour + ':' + e.minute + ':' + e.second;
},
// 确认有效期
editTime(){
if(this.timeIndex===0){
this.addShareObj.expireType = 0;
this.addShareObj.expireAt = '';
}else if(this.timeIndex === 4 && !this.timeList[4].value){
this.$refs.uToast.show({
title: '请现在到期时间',
type: 'error',
})
return '';
}else{
this.addShareObj.expireType = 1;
this.addShareObj.expireAt = this.timeList[this.timeIndex].value;
}
this.addTimeShow = false;
},
saveShare(){
this.$api.configurationApi.addConfigurationShare(this.addShareObj).then(res => {
if(res.code === 0){
this.$refs.uToast.show({
title: '新增成功',
type: 'success',
})
this.mescroll.resetUpScroll();
this.addShareShow = false;
}else{
this.$refs.uToast.show({
title: res.message,
type: 'error',
})
}
}, error => {
this.$refs.uToast.show({
title: '服务器开小差了呢,请您稍后再试',
type: 'error',
})
})
}
}
}
</script>
<style lang="less">
.configuration-share-box{
background: #f5f5f5;
.search-box{
position: fixed;
top: 0;
left: 0;
box-sizing: border-box;
height: 100rpx;
padding: 18rpx;
background-color: #fff;
width: 100%;
z-index: 99;
}
.share-list{
padding: 20rpx;
position: relative;
.share-item-status{
position: absolute;
top: 15rpx;
right: 0;
width: 120rpx;
line-height: 50rpx;
height: 50rpx;
border-radius: 25rpx 0 0 25rpx;
text-align: center;
color: #fff;
}
.share-item{
margin-bottom: 20rpx;
background-color: #FFFFFF;
border-radius: 12rpx;
box-shadow: 0px 0px 10px 0px rgba(192,192,192,0.7);
display: flex;
flex-direction: column;
padding: 20rpx;
box-sizing: border-box;
position: relative;
.share-item-box{
display: flex;
align-items: center;
// font-size: 28rpx;
margin-bottom: 6rpx;
}
.btn-list-box{
margin-top: 16rpx;
display: flex;
justify-content: space-between;
align-items: center;
/deep/.u-btn{
padding: 0 20rpx;
}
/deep/.u-btn--error{
width: 80rpx;
// border-radius: 50%;
}
}
}
}
}
.qr-content{
display: flex;
flex-direction: column;
align-items: center;
padding: 20rpx;
image{
width: 400rpx;
height: 400rpx;
margin-bottom: 20rpx;
}
}
// 新增分享
.popup-box{
background: #f8f9fd;
padding: 0 20rpx;
padding-bottom: 36rpx;
.popup-box-title{
height: 100rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 34rpx;
font-weight: bold;
}
.popup-box-content{
background: #FFFFFF;
border-radius: 10rpx;
.content-item{
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
&.two{
display: block;
}
.content-item-label{
font-weight: bold;
}
.content-item-value{
display: flex;
align-items: center;
color: #2979ff;
}
}
}
.popop-btn{
margin-top: 20rpx;
button{
height: 85rpx;
background: #2979ff;
border-radius: 10rpx;
font-size: 32rpx;
color: #FFFFFF;
display: flex;
justify-content: center;
align-items: center;
}
}
}
// 编译分享标题
.popup-title-box{
padding: 20rpx 30rpx;
.popup-title-input{
background: #f8f9fd;
padding: 15rpx;
}
}
.select-password{
.content-item-main{
flex: 1;
position: relative;
.content-item-main-icon{
position: absolute;
right: 30rpx;
top:0rpx;
}
}
.content-item-input-box{
padding-top: 30rpx;
.password-input{
background: #f8f9fd;
padding: 15rpx;
}
.password-hint{
color: #999;
font-size: 24rpx;
margin-top: 15rpx;
}
}
}
.select-time{
.content-item-main{
flex: 1;
position: relative;
.content-item-main-icon{
position: absolute;
right: 30rpx;
top:0rpx;
}
}
.content-item-input-box{
// padding-top: 30rpx;
.time-hint{
color: #999;
font-size: 24rpx;
margin-top: 15rpx;
}
}
}
.btn-box{
display: flex;
justify-content: center;
border-top: 1px solid #f5f5f5;
// align-items: center;
padding-top: 10rpx;
height: 120rpx;
z-index: 99;
position: fixed;
left: 0;
right: 0;
bottom: 0;
background: #FFFFFF;
button{
width: 700rpx;
height: 85rpx;
background: #2979ff;
border-radius: 10rpx;
font-size: 32rpx;
color: #FFFFFF;
display: flex;
justify-content: center;
align-items: center;
}
}
.color-red{
color: red;
}
.mask-warp{
display: flex;
align-items: center;
justify-content: center;
height: 100%;
.mask-box{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.mask-txt{
margin-top: 20rpx;
font-size: 30rpx;
color: #FFFFFF;
font-weight: bold;
}
}
}
</style>