This commit is contained in:
@fawn-nine
2023-10-09 15:39:16 +08:00
parent 4184ec9c36
commit 4cd369bc1c
20 changed files with 3462 additions and 30 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -134,6 +134,11 @@
<u-popup mode="bottom" :show="addTextShow" :round="10" @close="addTextShow=false">
<view class="tanchu">
<view class="dp_title">今日签到随想</view>
<!-- <view class="flexbox">
<i @click="showEmj()" :class="emojiIcon"></i>
<editor id="editor" class="ql-container" :placeholder="placeholder" @ready="onEditorReady"></editor>
</view> -->
<view style="max-height: 1000rpx;overflow-y: scroll;">
<!-- 提交 -->
<view class="padding-bottom-sm flex padding-lr-sm" style="border-bottom: 1px solid #EEEEEE;">
@@ -166,7 +171,7 @@
</u-popup>
<view class="leaveBtn" v-if="!addTextShow && currentDay == linshiDay && taskInfo.id && myword.length == 0">
<button style="height: 70rpx; font-size: 28rpx; line-height: 70rpx;" type="primary" plain="true"
@click="addTextShow = true">说点什么</button>
@click="addTextShow = true">说点什么</button>
</view>
<music-play :playData="playData"></music-play>
<!-- <z-navigation></z-navigation> -->
@@ -186,6 +191,7 @@
export default {
data() {
return {
placeholder: '开始输入...',
dayCurrent: 0, // 载入页面时的显示页数
showBack: false,
currentIndex: 0,
@@ -264,6 +270,17 @@
...mapState(['userInfo'])
},
methods: {
onEditorReady() {
// #ifdef MP-BAIDU
this.editorCtx = requireDynamicLib('editorLib').createEditorContext('editor');
// #endif
// #ifdef APP-PLUS || H5 ||MP-WEIXIN
uni.createSelectorQuery().select('#editor').context((res) => {
this.editorCtx = res.context
}).exec()
// #endif
},
// 获取书籍信息
getBookInfo() {
this.$http
@@ -513,7 +530,7 @@
},
// 快捷签到
kuickSign() {
if (!this.taskInfo.id) {
uni.showToast({
title: '当天未发布打卡任务,不可签到哦',
@@ -521,36 +538,35 @@
})
return false
}
let data = {
"bookId": this.bookid,
"userId": this.userInfo.id,
"tid": this.taskInfo.id,
"days": this.currentDay
let data = {
"bookId": this.bookid,
"userId": this.userInfo.id,
"tid": this.taskInfo.id,
"days": this.currentDay
}
$http.request({
url: 'book/clockinPunch/save',
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
data,
header: { //默认 无 说明:请求头
'Content-Type': 'application/json'
},
}).then(res => {
if (res.code == 0) {
//console.log(res, '快捷签到')
uni.showToast({
title: '签到成功',
icon: 'success'
})
this.addTextShow = false
this.formData.content = ''
this.formData.images = []
this.getmySign()
this.getAllSign(this.taskInfo)
}
$http.request({
url: 'book/clockinPunch/save',
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
data,
header: { //默认 无 说明:请求头
'Content-Type': 'application/json'
},
}).then(res => {
if (res.code == 0) {
//console.log(res, '快捷签到')
uni.showToast({
title: '签到成功',
icon: 'success'
})
return false
this.addTextShow = false
this.formData.content = ''
this.formData.images = []
this.getmySign()
this.getAllSign(this.taskInfo)
}
});
});
},
// 说点什么
goToSign() {
@@ -715,6 +731,18 @@
</script>
<style lang="scss" scoped>
.ql-editor{min-height: 50rpx;}
.ql-container {
width: calc(100% - 30rpx);
min-height: 50rpx !important;
height: auto !important;
font-style: normal;
font-size: 30rpx;
margin: 0 auto;
border: 1px solid #ddd;
border-radius: 20rpx;
}
.pjimgs {
margin: 10px 0;
flex-wrap: wrap;

View File

@@ -0,0 +1,802 @@
<template>
<view style="background-color: #fff;padding: 30rpx;">
<z-nav-bar title="电子书详情"></z-nav-bar>
<view class="book_neir">
<img :src="bookMessage.images" class="bn_img">
<b class="leiXing" v-if="bookMessage.isVip==1" style="background: #c79119;">VIP</b>
<b class="leiXing" v-if="bookMessage.isVip==2" style="background: #c74119;">付费</b>
<view class="bn_nes">
<view style="font-weight: bold;margin-bottom: 30rpx;">
{{bookMessage.name}}
</view>
<view style="color: #9b9b9b;font-size: 28rpx;margin:20rpx 0 0 0;max-width: 400rpx;line-height: 38rpx;">
<p @click="onAuCHJump(bookMessage.authorId,1)" style="margin-bottom: 20rpx;">
{{bookMessage.authorName}} [] >
</p>
<p @click="onAuCHJump(item.id,2)" v-for="item in this.bookMessage.publisherNIList">
{{item.title}} >
</p>
</view>
<view v-if="this.bookMessage.chapterNum!=null"
style="color: #cdcdcd;font-size: 20rpx;margin:20rpx 0 0 0;max-width: 400rpx;line-height: 36rpx;">
上次阅读到{{this.bookCatalogue[this.bookMessage.chapterNum-1].chapterName}}
</view>
</view>
<br clear="both">
</view>
<view class="book_dredge" @click="onPageJump('../peanut/opeVip')" v-if="bookMessage.isVip!=0&&this.userMes.vip==0">
<image src="../../static/icon/mine_p.png" alt=""></image>
开通会员免费读本书
<b>></b>
</view>
<view class="book_dredge book_vip" v-if="this.userMes.vip==1">
<image src="../../static/icon/mine_v.png" alt=""></image>
尊享会员权益中
</view>
<view class="book_tab">
<view>
<u-tabs :list="tab_list" @click="tab_click" lineColor="#54a966 100% 100%"
:activeStyle="{color: '#303133',fontWeight: 'bold',transform: 'scale(1.1)'}"></u-tabs>
</view>
<view class="bt_cont">
<view v-if="tab_muJian==0" class="bt_jian">
<text>
{{bookMessage.description}}
</text>
</view>
<view v-if="tab_muJian==1">
<p style="text-align: right;color: #a5a5a5;margin-bottom: 10rpx;">
{{bookCatalogue.length}}</p>
<view class="bt_nulu" v-for='(item,index) in bookCatalogue'>
<!-- 最近阅读的 -->
<view @click="onBokReadJump(index)" v-if="bookMessage.isBuy==1" style="display: flex;justify-content: space-between;">
{{item.chapterName}}
<font v-if="bookMessage.chapterId==index">最近阅读</font>
</view>
<view v-if="bookMessage.isBuy==0">
<view @click="onBokReadJump(index)" v-if="index<bookMessage.freeChapterCount">
{{item.chapterName}}
<font v-if="bookMessage.chapterId==index">最近阅读</font>
</view>
<view v-if="index>=bookMessage.freeChapterCount" @click="collectFee()">
<!-- 不是会员显示锁 -->
<font style=" color:#bfa853;margin-left: 20rpx;">
<u-icon name="lock" color="#ccc" size="20" v-if="bookMessage.isBuy!==1"></u-icon>
</font>
{{item.chapterName}}
</view>
<view
</view>
</view>
<view style="height: 60rpx;"></view>
</view>
</view>
</view>
<view class="book_caozuo">
<view v-if="this.bookMessage.flag" style="color: #aaa;">已加入书架</view>
<view v-if="!this.bookMessage.flag" @click="joInshelf">加入书架</view>
<view @click="onBokReadJump(0)" v-if="this.bookMessage.isBuy==1&&this.bookMessage.chapterId==null">开始阅读</view>
<view @click="onBokReadJump(bookMessage.chapterNum-1)" v-if="this.bookMessage.isBuy==1&&this.bookMessage.chapterId!=null">
继续阅读
</view>
<view @click="onBokReadJump(0)" v-if="this.bookMessage.isBuy==0&&this.bookMessage.chapterNum==null&&this.bookMessage.freeChapterCount!=0">开始试读</view>
<view @click="onBokReadJump(bookMessage.chapterNum-1)" v-if="this.bookMessage.isBuy==0&&this.bookMessage.chapterNum!=null&&this.bookMessage.freeChapterCount!=0">继续试读</view>
<view v-if="this.bookMessage.isBuy==0&&this.bookMessage.freeChapterCount==0">购买阅读</view>
<view @click="buyShowFun" v-if="bookMessage.isBuy==0" style="background-color: #d85f54;">立即购买</view>
<view v-if="bookMessage.isBuy==1&&bookMessage.isVip!=0" style="background-color: #bfa853;">已购买</view>
<view v-if="bookMessage.isVip==0">本书免费</view>
</view>
<!-- 购买 -->
<u-popup :show="buyShow" :round="10" @close="buyShow=false" :closeable='true'>
<view class="tanchu">
<view class="by_title">购买</view>
<view class="by_package">
<view v-if="userMes.vip==0" :class="typeFen== 1?'Tab_by by_fen':'by_fen'" @click="chBuyType(1)">
<view class="biao">开通会员</view>
<view class="wenz">
连续包月
<text>节省{{bookMessage.salePrice}}天医币</text>
</view>
</view>
<br>
<view :class="typeFen== 2?'Tab_by by_fen':'by_fen'" @click="chBuyType(2)">
<view class="biao" v-if="userMes.vip==0">直接购买</view>
<view class="biao" v-if="userMes.vip==1">会员权益购买</view>
<view class="benl">
<b v-if="useCouponAmount != ''">{{useCouponAmount}}</b>
<span v-else>
<b v-if="bookMessage.isSale==1">{{bookMessage.salePrice}}</b>
<b v-if="bookMessage.isSale==0||bookMessage.isSale==null">{{bookMessage.price}}</b></span>
天医币
<text>{{bookMessage.price}}天医币</text>
</view>
</view>
<!-- 优惠券 ------------------------>
<view class="yq_youhui" @click="CyouhuiShow" style="margin-top:20px;">
<u-icon name="red-packet-fill" color="#e74141" size="18" class="yqLeft"></u-icon>
优惠券
<u-icon name="arrow-right" color="#aaa" size="18" class="yqRight"></u-icon>
<text class="dagnqian"
v-if="youhuiList.length>0&&youhuiContent.id==undefined">当前可选{{this.youhuiList.length}}</text>
<text class="dagnqian" v-if="youhuiList.length==0&&youhuiContent.id==undefined"
style="background-color: #999;">暂无优惠券</text>
<text class="dagnqian" v-if="youhuiContent.id!=undefined">
- {{youhuiContent.coupons.couponAmount}}</text>
</view>
</view>
<view style="height: 1px;width: 100%;background-color: #eee;margin-top: 50rpx;"></view>
<view style="margin: 40rpx 10rpx 20rpx 10rpx;font-size: 30rpx;">
<view style="float: left;">余额</view>
<view style="float: right;color: #999;">
{{userMes.peanutCoin}} 天医币
<view class="chongBtn" @click="buPoint()">充值天医币</view>
</view>
<br clear="both">
</view>
<view style="color: #c3c3c3;font-size: 20rpx;margin: 30rpx 0;">支付成功后立即解锁已购内容</view>
<view @click="buyVip()" v-if="typeFen== 1" class="by_btn">查看套餐开通VIP</view>
<view @click="buyMoneTip()" v-if="typeFen== 2" class="by_btn">购买本书</view>
</view>
</u-popup>
<u-modal :show="buysignShow" :content="buysignContent" :showCancelButton="true" @cancel="cancelMoney"
@confirm="buyMoney">
</u-modal>
<view>
<u-back-top :scroll-top="scrollTop" bottom="60" :customStyle='bgiStyle' :iconStyle="iconStyle"></u-back-top>
</view>
<!-- 优惠券弹1出 -->
<u-popup :show="youhuiShow" :round="10" @close="hideyouhui">
<view class="tanchu">
<view class="dp_title">请选择优惠券</view>
<view style="max-height: 1000rpx;overflow-y: scroll;">
<span @click="clearYouhui" style="font-size: 14px; display:inline-block;border: 1px solid #c74119; border-radius: 5px; float: right; color:#c74119; padding: 5px; margin-bottom: 10px;">不使用优惠券</span>
<view :class="youhuiIndex === index ? 'youhuiItem youItem_style' : 'youhuiItem'"
v-for="(item,index) in youhuiList" :key="index" @click="choseYouhui(index)">
<view style="width: 25%;color:#fd6004;text-align: center;">
<text></text>
<b style="font-size: 45rpx;">{{item.coupons.couponAmount}}</b>
<text
style="display: block;color: #666;font-size: 25rpx;margin-top: 10rpx;">{{item.coupons.useLevel}}元可用</text>
</view>
<view style="width: 68%;padding-left: 5%;">
<text>{{item.coupons.couponName}}</text>
<text
style="display: block;font-size: 20rpx;color: #999;margin-top: 10rpx;">到期时间{{item.coupons.expirationDate}}</text>
</view>
<view style="width: 7%;">
<text
style="border: 1px solid #d9d9d9;width: 35rpx;height:35rpx;display:inline-block;border-radius: 30rpx;"
v-if="youhuiIndex !== index"></text>
<u-icon name="checkmark-circle-fill" color="#fd6004" size="20" v-if="youhuiIndex === index">
</u-icon>
</view>
<br clear="both">
</view>
</view>
<view style="font-size: 20rpx;color: #aaa;margin-top: 30rpx;">* 每笔订单只能使用一张优惠价</view>
</view>
</u-popup>
</view>
</template>
<script>
import $http from '@/config/requestConfig.js';
import {
mapState
} from 'vuex';
export default {
data() {
return {
youhuiShow:false,
youhuiIndex:'',
youhuiList:[], // 优惠券列表
couponMz: 0, // 优惠券钱数
useCouponAmount: '' , // 使用的优惠券金额
bookJiageA: 0,
youhuiContent: {
coupons:{
id:'0'
}
},
scrollTop: 0,
tab_list: [{
name: '简介',
}, {
name: '目录',
}],
userMes: {},
bokMesDet: {},
tab_muJian: 0,
bookId: '',
bookMessage: {
flag: false
},
bookCatalogue: [],
bgiStyle: {
background: '#2ab58833'
},
iconStyle: {
fontSize: '40rpx',
fontWeight: 'bold',
color: '#54a966',
},
typeFen: 1,
buyShow: false,
buysignShow: false,
buysignContent: ''
};
},
onPageScroll(e) {
this.scrollTop = e.scrollTop;
},
//第一次加载
onLoad(e) {
this.bookId = e.Id
},
computed: {
...mapState(['userInfo'])
},
//页面显示
onShow() {
this.getData();
},
//方法
methods: {
getData() {
// 获取电子书详情
this.$http
.post('book/book/appinfo/' + this.bookId + '/' + this.userInfo.id)
.then(res => {
this.bookMessage = res.book
this.bokMesDet.bookId = res.book.id
this.bokMesDet.bookName = res.book.name,
this.bokMesDet.images = res.book.images
if (this.bookMessage.isSale == 1) {
this.buysignContent = '您确定要花费' + this.bookMessage.salePrice + '天医币购买' + this.bokMesDet
.bookName + '吗?'
} else {
this.buysignContent = '您确定要花费' + this.bookMessage.price + '天医币购买' + this.bokMesDet
.bookName + '吗?'
}
this.bokMesDet.userId = this.userInfo.id
if (this.bookMessage.publisherName.indexOf(',') > 0) {
this.bookMessage.publisherName = this.bookMessage.publisherName.split(',')
this.bookMessage.publisherId = this.bookMessage.publisherId.split(',')
this.bookMessage.publisherNIList = []
for (let i in this.bookMessage.publisherName) {
this.bookMessage.publisherNIList.push({
title: this.bookMessage.publisherName[i]
})
}
for (let j in this.bookMessage.publisherId) {
this.bookMessage.publisherNIList[j].id = this.bookMessage.publisherId[j]
}
} else {
this.bookMessage.publisherNIList = []
this.bookMessage.publisherNIList.push({
'title': this.bookMessage.publisherName,
'id': this.bookMessage.publisherId
})
}
});
// 获取电子目录
this.$http
.post('book/book/getBookCatalogue', {
'bookid': this.bookId
})
.then(res => {
this.bookCatalogue = res.bookCatalogue
});
// 用户详情
if (this.userInfo.id != undefined) {
this.$http
.post('book/user/info/' + this.userInfo.id)
.then(res => {
this.userMes = res.user
if (this.userMes.vip != 0) {
this.typeFen = 2
}
});
}
},
// 加入书架
joInshelf() {
const that = this;
$http.request({
url: "book/bookshelf/save",
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
data: that.bokMesDet,
header: { //默认 无 说明:请求头
'Content-Type': 'application/json'
},
}).then(function(res) {
if (res.code == 0) {
uni.showToast({
title: '加入书架成功'
})
that.bookMessage.flag = true
}
}).catch(function(error) {
//这里只会在接口是失败状态返回,不需要去处理错误提示
console.log(error);
});
},
// 点击tab
tab_click(e) {
this.tab_muJian = e.index
},
CyouhuiShow(){
this.youhuiShow = true
this.getCourpe()
this.buyShow = false // 隐藏购买弹窗
},
buyShowFun(){
this.buyShow = true
this.getCourpe()
},
hideyouhui(){
this.youhuiShow = false,
this.buyShow = true // 隐藏购买弹窗
},
clearYouhui(){
this.youhuiContent = {}
this.youhuiIndex = ''
this.useCouponAmount = ''
this.getData()
this.youhuiShow = false
this.buyShow = true // 隐藏购买弹窗
//this.couponMz = 0
},
// 选择优惠券
choseYouhui(e) {
this.youhuiIndex = e
this.youhuiContent = this.youhuiList[this.youhuiIndex]
console.log(this.youhuiContent, 'youhuiContent')
//this.couponMz = this.youhuiContent.coupons.couponAmount
if (this.bookMessage.isSale == 0) {
this.useCouponAmount = this.bookMessage.price - this.youhuiContent.coupons.couponAmount
} else {
this.useCouponAmount = this.bookMessage.salePrice - this.youhuiContent.coupons.couponAmount
}
this.buysignContent = '您确定要花费' + this.useCouponAmount + '天医币购买' + this.bokMesDet.bookName + '吗?'
// this.getData()
this.youhuiShow = false
this.buyShow = true // 隐藏购买弹窗
},
// 获取优惠券列表
getCourpe() {
let bookJiage = 0
if (this.bookMessage.isSale == 0) {
bookJiage = this.bookMessage.price
} else {
bookJiage = this.bookMessage.salePrice
}
this.bookJiageA = bookJiage
this.$http
.post('book/couponhistory/appGetUserCoupon?userId=' + this.userInfo.id + '&amount=' + this.bookJiageA + '&type=1' )
.then(res => {
this.youhuiList = res.userCoupons
});
},
// 跳转
onPageJump(url) {
uni.navigateTo({
url: url
});
},
// 电子书阅读跳转
onBokReadJump(e) {
const that = this;
// 加入阅读记录
$http.request({
// 存数据
url: "book/bookbrowserecords/save",
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
data: that.bokMesDet,
header: { //默认 无 说明:请求头
'Content-Type': 'application/json'
},
}).then(function(res) {
if (res.code == 0) {
console.log(res,'========');
if (res.browseRecordsId) {
$http.request({
// 更新
url: "book/bookbrowserecords/update",
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
data: {
'bookShelfId': res.browseRecordsId
},
header: { //默认 无 说明:请求头
'Content-Type': 'application/json'
},
}).then(function(res) {
if (res.code == 0) {
uni.navigateTo({
url: '../yRead/angbook?Id=' + that.bookId + '&cha=' + e
});
}
}).catch(function(error) {
//这里只会在接口是失败状态返回,不需要去处理错误提示
console.log(error);
});
} else {
uni.navigateTo({
url: '../yRead/angbook?Id=' + that.bookId + '&cha=' + e
});
}
}
}).catch(function(error) {
//这里只会在接口是失败状态返回,不需要去处理错误提示
console.log(error);
});
},
// 信息介绍跳转
onAuCHJump(id, e) {
uni.navigateTo({
url: './bookMessage?Id=' + id + '&typ=' + e
});
},
// 提示购买
collectFee() {
uni.showToast({
icon: 'none',
title: '请购买本书'
})
},
// 充值天医币
buPoint() {
uni.navigateTo({
url: '../peanut/reCharge'
});
},
// 选择vip还是直接购买
chBuyType(e) {
let that = this
that.typeFen = e
},
// 开通VIP
buyVip() {
uni.navigateTo({
url: '../peanut/opeVip'
});
},
// 购买本书
buyMoneTip() {
let bookJiage = 0
if (this.bookMessage.isSale == 0) {
bookJiage = this.bookMessage.price
} else {
bookJiage = this.bookMessage.salePrice
}
// this.bookJiageA = bookJiage
if (bookJiage > this.userMes.peanutCoin) {
uni.showToast({
icon: 'none',
title: '余额不足,请充值'
})
} else {
this.buysignShow = true
this.buyShow = false
}
},
buyMoney() {
let couponId = ''
if(this.youhuiContent.coupons.id != 0){ // 使用了优惠券
couponId = this.youhuiContent.coupons.id
}else{ // 未使用
couponId = '0'
}
console.log(this.youhuiIndex, this.youhuiContent.coupons.id, couponId)
this.$http
.post('book/user/buyEbook?bookId=' + this.bokMesDet.bookId + '&userId=' + this.userInfo.id + '&couponId=' + couponId)
.then(res => {
if (res.code == 0) {
if (res.status == 'error') {
this.buysignShow = false
uni.showToast({
icon: 'none',
title: res.msg
})
} else {
uni.showToast({
title: '购买成功'
})
this.buyShow = false
this.buysignShow = false
this.getData();
}
}
});
},
cancelMoney() {
this.buysignShow = false
this.buyShow = true
},
},
};
</script>
<style lang="scss" scoped>
@import '@/style/mixin.scss';
.yq_youhui {
.yqLeft {
display: inline-block;
margin-right: 10rpx;
}
.yqRight {
float: right;
}
.dagnqian {
float: right;
font-size: 22rpx;
background-color: #dd1919;
color: #fff;
border-radius: 20rpx;
padding: 5rpx 10rpx;
}
}
.yq_yunfei {
.yqLeft {
display: inline-block;
margin-right: 10rpx;
}
text {
float: right;
}
}
.book_neir {
margin: 20rpx 0 0 0;
position: relative;
.bn_img {
float: left;
width: 250upx;
height: 320upx;
}
.bn_nes {
float: left;
font-size: 36rpx;
margin-left: 40rpx;
view {
margin: 20rpx 0 0 0;
}
}
.leiXing {
display: block;
padding: 5rpx 10rpx;
border-radius: 10rpx;
text-align: center;
color: #fff;
font-weight: normal;
background: #27b386;
position: absolute;
left: -15upx;
top: 10upx;
font-size: 16rpx;
}
}
.book_dredge {
font-size: 26rpx;
color: #e4b58a;
margin: 40rpx 0 0 0;
padding: 20rpx 30rpx 25rpx 30rpx;
background-image: url('../../static/icon/mine_back.png');
background-size: 100% auto;
image {
width: 46rpx;
height: 40rpx;
display: inline-block;
vertical-align: text-bottom;
margin: 0 10rpx 0 0;
}
b {
float: right;
font-size: 35rpx;
font-weight: bold;
line-height: 40rpx;
}
}
.book_vip{
background: url('../../static/icon/mine_card.png') top center no-repeat;
color: #87510d;
font-weight: bold;
}
.book_tab {
margin: 20rpx 0 0 0;
.bt_cont {
font-size: 26rpx;
line-height: 42rpx;
color: #666;
padding: 0 10rpx;
.bt_jian {
padding-top: 30rpx;
margin-bottom: 15rpx;
}
.bt_nulu {
border-bottom: 1px solid #eee;
padding: 20rpx 0;
font {
color: #54a966;
float: right;
font-size: 20rpx;
}
}
}
}
.book_caozuo {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: #fff;
view {
display: inline-block;
width: 33.3%;
text-align: center;
padding: 28rpx 0;
font-size: 35rpx;
border-top: 1px solid #eee;
}
view:nth-child(3) {
background-color: #54a966;
color: #fff;
}
}
.tanchu {
padding: 30rpx 50rpx 60rpx 50rpx;
.by_title {
font-size: 32rpx;
margin: 0 0 80rpx 0;
text-align: center;
}
.by_package {
font-size: 28rpx;
.by_fen {
box-shadow: 0 0 20rpx 0 #0000001a;
padding: 20rpx 30rpx;
background-color: #fff;
border-radius: 20rpx;
margin-bottom: 10rpx;
.biao {
font-weight: bold;
font-size: 32rpx;
}
.wenz {
color: #b1b1b1;
margin-top: 20rpx;
text {
color: #fe6e09;
margin-left: 20rpx;
}
}
.benl {
margin-top: 20rpx;
color: #d75f54;
font-size: 31rpx;
text {
font-size: 30rpx;
text-decoration: line-through;
color: #c1c1c1;
margin-left: 20rpx;
}
}
}
.Tab_by {
box-shadow: 0 0 20rpx 0 #fe700bcc;
color: #7b4c0a;
}
}
.by_btn {
background-image: linear-gradient(90deg, #ed7161 0%, #efa574 100%);
color: #fff;
width: 100%;
margin: 50rpx auto 0 auto;
text-align: center;
font-size: 18px;
font-weight: bold;
padding: 20rpx 0;
border-radius: 50rpx;
}
.chongBtn {
background-color: #54a966;
color: #fff;
margin-left: 20rpx;
border-radius: 10rpx;
padding: 2rpx 10rpx;
font-size: 20rpx;
display: inline-block;
}
}
.youhuiItem {
border: 1px solid #d9d9d9;
border-radius: 10rpx;
width: 100%;
display: flex;
padding: 20rpx 10rpx;
margin: 25rpx 0 0 0;
align-items: center;
background-color: #fff;
font-size: 30rpx;
}
.youhuiItem>view {
float: left;
}
.youhuiItem.youItem_style {
border-color: #fd6004;
}
</style>

View File

@@ -96,6 +96,14 @@
if (res.code == 0) {
console.log(res, 'res')
this.bookInfo = res.book
if(!this.bookInfo.author || this.bookInfo.author == null){
this.bookInfo.author = {
'authorName' : '未知'
}
console.log(this.bookInfo.author.authorName,'this.bookInfo.author.authorName')
}
//console.log(this.bookInfo.author.authorName,'this.bookInfo.author.authorName')
this.voicesImg = res.book.images
// this.bookInfo.name = res.book.name
this.isBuy = res.book.isBuy

BIN
static/haoyou.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
static/quan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -0,0 +1,68 @@
## 1.8.32023-04-17
- 修复 uni-popup 重复打开时的 bug
## 1.8.22023-02-02
- uni-popup-dialog 组件新增 inputType 属性
## 1.8.12022-12-01
- 修复 nvue 下 v-show 报错
## 1.8.02022-11-29
- 优化 主题样式
## 1.7.92022-04-02
- 修复 弹出层内部无法滚动的bug
## 1.7.82022-03-28
- 修复 小程序中高度错误的bug
## 1.7.72022-03-17
- 修复 快速调用open出现问题的Bug
## 1.7.62022-02-14
- 修复 safeArea 属性不能设置为false的bug
## 1.7.52022-01-19
- 修复 isMaskClick 失效的bug
## 1.7.42022-01-19
- 新增 cancelText \ confirmText 属性 ,可自定义文本
- 新增 maskBackgroundColor 属性 ,可以修改蒙版颜色
- 优化 maskClick属性 更新为 isMaskClick ,解决微信小程序警告的问题
## 1.7.32022-01-13
- 修复 设置 safeArea 属性不生效的bug
## 1.7.22021-11-26
- 优化 组件示例
## 1.7.12021-11-26
- 修复 vuedoc 文字错误
## 1.7.02021-11-19
- 优化 组件UI并提供设计资源详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-popup](https://uniapp.dcloud.io/component/uniui/uni-popup)
## 1.6.22021-08-24
- 新增 支持国际化
## 1.6.12021-07-30
- 优化 vue3下事件警告的问题
## 1.6.02021-07-13
- 组件兼容 vue3如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.5.02021-06-23
- 新增 mask-click 遮罩层点击事件
## 1.4.52021-06-22
- 修复 nvue 平台中间弹出后点击内容再点击遮罩无法关闭的Bug
## 1.4.42021-06-18
- 修复 H5平台中间弹出后点击内容再点击遮罩无法关闭的Bug
## 1.4.32021-06-08
- 修复 错误的 watch 字段
- 修复 safeArea 属性不生效的问题
- 修复 点击内容再点击遮罩无法关闭的Bug
## 1.4.22021-05-12
- 新增 组件示例地址
## 1.4.12021-04-29
- 修复 组件内放置 input 、textarea 组件,无法聚焦的问题
## 1.4.0 2021-04-29
- 新增 type 属性的 left\right 值,支持左右弹出
- 新增 open(String:type) 方法参数 ,可以省略 type 属性 ,直接传入类型打开指定弹窗
- 新增 backgroundColor 属性,可定义主窗口背景色,默认不显示背景色
- 新增 safeArea 属性,是否适配底部安全区
- 修复 App\h5\微信小程序底部安全区占位不对的Bug
- 修复 App 端弹出等待的Bug
- 优化 提升低配设备性能,优化动画卡顿问题
- 优化 更简单的组件自定义方式
## 1.2.92021-02-05
- 优化 组件引用关系通过uni_modules引用组件
## 1.2.82021-02-05
- 调整为uni_modules目录规范
## 1.2.72021-02-05
- 调整为uni_modules目录规范
- 新增 支持 PC 端
- 新增 uni-popup-message 、uni-popup-dialog扩展组件支持 PC 端

View File

@@ -0,0 +1,45 @@
// #ifdef H5
export default {
name: 'Keypress',
props: {
disable: {
type: Boolean,
default: false
}
},
mounted () {
const keyNames = {
esc: ['Esc', 'Escape'],
tab: 'Tab',
enter: 'Enter',
space: [' ', 'Spacebar'],
up: ['Up', 'ArrowUp'],
left: ['Left', 'ArrowLeft'],
right: ['Right', 'ArrowRight'],
down: ['Down', 'ArrowDown'],
delete: ['Backspace', 'Delete', 'Del']
}
const listener = ($event) => {
if (this.disable) {
return
}
const keyName = Object.keys(keyNames).find(key => {
const keyName = $event.key
const value = keyNames[key]
return value === keyName || (Array.isArray(value) && value.includes(keyName))
})
if (keyName) {
// 避免和其他按键事件冲突
setTimeout(() => {
this.$emit(keyName, {})
}, 0)
}
}
document.addEventListener('keyup', listener)
this.$once('hook:beforeDestroy', () => {
document.removeEventListener('keyup', listener)
})
},
render: () => {}
}
// #endif

View File

@@ -0,0 +1,275 @@
<template>
<view class="uni-popup-dialog">
<view class="uni-dialog-title">
<text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{titleText}}</text>
</view>
<view v-if="mode === 'base'" class="uni-dialog-content">
<slot>
<text class="uni-dialog-content-text">{{content}}</text>
</slot>
</view>
<view v-else class="uni-dialog-content">
<slot>
<input class="uni-dialog-input" v-model="val" :type="inputType" :placeholder="placeholderText" :focus="focus" >
</slot>
</view>
<view class="uni-dialog-button-group">
<view class="uni-dialog-button" @click="closeDialog">
<text class="uni-dialog-button-text">{{closeText}}</text>
</view>
<view class="uni-dialog-button uni-border-left" @click="onOk">
<text class="uni-dialog-button-text uni-button-color">{{okText}}</text>
</view>
</view>
</view>
</template>
<script>
import popup from '../uni-popup/popup.js'
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import messages from '../uni-popup/i18n/index.js'
const { t } = initVueI18n(messages)
/**
* PopUp 弹出层-对话框样式
* @description 弹出层-对话框样式
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} value input 模式下的默认值
* @property {String} placeholder input 模式下输入提示
* @property {String} type = [success|warning|info|error] 主题样式
* @value success 成功
* @value warning 提示
* @value info 消息
* @value error 错误
* @property {String} mode = [base|input] 模式、
* @value base 基础对话框
* @value input 可输入对话框
* @property {String} content 对话框内容
* @property {Boolean} beforeClose 是否拦截取消事件
* @event {Function} confirm 点击确认按钮触发
* @event {Function} close 点击取消按钮触发
*/
export default {
name: "uniPopupDialog",
mixins: [popup],
emits:['confirm','close'],
props: {
inputType:{
type: String,
default: 'text'
},
value: {
type: [String, Number],
default: ''
},
placeholder: {
type: [String, Number],
default: ''
},
type: {
type: String,
default: 'error'
},
mode: {
type: String,
default: 'base'
},
title: {
type: String,
default: ''
},
content: {
type: String,
default: ''
},
beforeClose: {
type: Boolean,
default: false
},
cancelText:{
type: String,
default: ''
},
confirmText:{
type: String,
default: ''
}
},
data() {
return {
dialogType: 'error',
focus: false,
val: ""
}
},
computed: {
okText() {
return this.confirmText || t("uni-popup.ok")
},
closeText() {
return this.cancelText || t("uni-popup.cancel")
},
placeholderText() {
return this.placeholder || t("uni-popup.placeholder")
},
titleText() {
return this.title || t("uni-popup.title")
}
},
watch: {
type(val) {
this.dialogType = val
},
mode(val) {
if (val === 'input') {
this.dialogType = 'info'
}
},
value(val) {
this.val = val
}
},
created() {
// 对话框遮罩不可点击
this.popup.disableMask()
// this.popup.closeMask()
if (this.mode === 'input') {
this.dialogType = 'info'
this.val = this.value
} else {
this.dialogType = this.type
}
},
mounted() {
this.focus = true
},
methods: {
/**
* 点击确认按钮
*/
onOk() {
if (this.mode === 'input'){
this.$emit('confirm', this.val)
}else{
this.$emit('confirm')
}
if(this.beforeClose) return
this.popup.close()
},
/**
* 点击取消按钮
*/
closeDialog() {
this.$emit('close')
if(this.beforeClose) return
this.popup.close()
},
close(){
this.popup.close()
}
}
}
</script>
<style lang="scss" >
.uni-popup-dialog {
width: 300px;
border-radius: 11px;
background-color: #fff;
}
.uni-dialog-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
padding-top: 25px;
}
.uni-dialog-title-text {
font-size: 16px;
font-weight: 500;
}
.uni-dialog-content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
align-items: center;
padding: 20px;
}
.uni-dialog-content-text {
font-size: 14px;
color: #6C6C6C;
}
.uni-dialog-button-group {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
border-top-color: #f5f5f5;
border-top-style: solid;
border-top-width: 1px;
}
.uni-dialog-button {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
justify-content: center;
align-items: center;
height: 45px;
}
.uni-border-left {
border-left-color: #f0f0f0;
border-left-style: solid;
border-left-width: 1px;
}
.uni-dialog-button-text {
font-size: 16px;
color: #333;
}
.uni-button-color {
color: #007aff;
}
.uni-dialog-input {
flex: 1;
font-size: 14px;
border: 1px #eee solid;
height: 40px;
padding: 0 10px;
border-radius: 5px;
color: #555;
}
.uni-popup__success {
color: #4cd964;
}
.uni-popup__warn {
color: #f0ad4e;
}
.uni-popup__error {
color: #dd524d;
}
.uni-popup__info {
color: #909399;
}
</style>

View File

@@ -0,0 +1,143 @@
<template>
<view class="uni-popup-message">
<view class="uni-popup-message__box fixforpc-width" :class="'uni-popup__'+type">
<slot>
<text class="uni-popup-message-text" :class="'uni-popup__'+type+'-text'">{{message}}</text>
</slot>
</view>
</view>
</template>
<script>
import popup from '../uni-popup/popup.js'
/**
* PopUp 弹出层-消息提示
* @description 弹出层-消息提示
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} type = [success|warning|info|error] 主题样式
* @value success 成功
* @value warning 提示
* @value info 消息
* @value error 错误
* @property {String} message 消息提示文字
* @property {String} duration 显示时间,设置为 0 则不会自动关闭
*/
export default {
name: 'uniPopupMessage',
mixins:[popup],
props: {
/**
* 主题 success/warning/info/error 默认 success
*/
type: {
type: String,
default: 'success'
},
/**
* 消息文字
*/
message: {
type: String,
default: ''
},
/**
* 显示时间,设置为 0 则不会自动关闭
*/
duration: {
type: Number,
default: 3000
},
maskShow:{
type:Boolean,
default:false
}
},
data() {
return {}
},
created() {
this.popup.maskShow = this.maskShow
this.popup.messageChild = this
},
methods: {
timerClose(){
if(this.duration === 0) return
clearTimeout(this.timer)
this.timer = setTimeout(()=>{
this.popup.close()
},this.duration)
}
}
}
</script>
<style lang="scss" >
.uni-popup-message {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
}
.uni-popup-message__box {
background-color: #e1f3d8;
padding: 10px 15px;
border-color: #eee;
border-style: solid;
border-width: 1px;
flex: 1;
}
@media screen and (min-width: 500px) {
.fixforpc-width {
margin-top: 20px;
border-radius: 4px;
flex: none;
min-width: 380px;
/* #ifndef APP-NVUE */
max-width: 50%;
/* #endif */
/* #ifdef APP-NVUE */
max-width: 500px;
/* #endif */
}
}
.uni-popup-message-text {
font-size: 14px;
padding: 0;
}
.uni-popup__success {
background-color: #e1f3d8;
}
.uni-popup__success-text {
color: #67C23A;
}
.uni-popup__warn {
background-color: #faecd8;
}
.uni-popup__warn-text {
color: #E6A23C;
}
.uni-popup__error {
background-color: #fde2e2;
}
.uni-popup__error-text {
color: #F56C6C;
}
.uni-popup__info {
background-color: #F2F6FC;
}
.uni-popup__info-text {
color: #909399;
}
</style>

View File

@@ -0,0 +1,189 @@
<template>
<view class="uni-popup-share">
<view class="uni-share-title"><text class="uni-share-title-text">{{shareTitleText}}</text></view>
<view class="uni-share-content">
<view class="uni-share-content-box">
<view class="uni-share-content-item" v-for="(item,index) in bottomData" :key="index" @click.stop="select(item,index)">
<image class="uni-share-image" :src="item.icon" mode="aspectFill"></image>
<text class="uni-share-text" style="color: #777;">{{item.text}}</text>
</view>
</view>
</view>
<view class="uni-share-button-box">
<button class="uni-share-button" @click="close">{{cancelText}}</button>
</view>
</view>
</template>
<script>
import popup from '../uni-popup/popup.js'
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import messages from '../uni-popup/i18n/index.js'
const { t } = initVueI18n(messages)
export default {
name: 'UniPopupShare',
mixins:[popup],
emits:['select'],
props: {
title: {
type: String,
default: ''
},
beforeClose: {
type: Boolean,
default: false
}
},
data() {
return {
bottomData: [{
text: '微信好友',
icon: '../../static/haoyou.png',
// icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/c2b17470-50be-11eb-b680-7980c8a877b8.png',
name: 'wx'
},
{
text: '微信朋友圈',
// icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/d684ae40-50be-11eb-8ff1-d5dcf8779628.png',
icon: '../../static/quan.png',
name: 'wx'
},
// {
// text: 'QQ',
// icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/e7a79520-50be-11eb-b997-9918a5dda011.png',
// name: 'qq'
// },
// {
// text: '新浪',
// icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/0dacdbe0-50bf-11eb-8ff1-d5dcf8779628.png',
// name: 'sina'
// },
// {
// text: '百度',
// icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/1ec6e920-50bf-11eb-8a36-ebb87efcf8c0.png',
// name: 'copy'
// },
// {
// text: '其他',
// icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/2e0fdfe0-50bf-11eb-b997-9918a5dda011.png',
// name: 'more'
// }
]
}
},
created() {},
computed: {
cancelText() {
return t("uni-popup.cancel")
},
shareTitleText() {
return this.title || t("uni-popup.shareTitle")
}
},
methods: {
/**
* 选择内容
*/
select(item, index) {
this.$emit('select', {
item,
index
})
this.close()
},
/**
* 关闭窗口
*/
close() {
if(this.beforeClose) return
this.popup.close()
}
}
}
</script>
<style lang="scss" >
.uni-popup-share {
background-color: #fff;
border-top-left-radius: 11px;
border-top-right-radius: 11px;
}
.uni-share-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
height: 40px;
}
.uni-share-title-text {
font-size: 14px;
color: #666;
}
.uni-share-content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
padding-top: 10px;
}
.uni-share-content-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
flex-wrap: wrap;
// width: 360px;
}
.uni-share-content-item {
width: 90px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
padding: 10px 0;
align-items: center;
}
.uni-share-content-item:active {
background-color: #f5f5f5;
}
.uni-share-image {
width: 30px;
height: 30px;
}
.uni-share-text {
margin-top: 10px;
font-size: 14px;
color: #3B4144;
}
.uni-share-button-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
padding: 10px 15px;
}
.uni-share-button {
flex: 1;
border-radius: 50px;
color: #666;
font-size: 16px;
}
.uni-share-button::after {
border-radius: 50px;
}
</style>

View File

@@ -0,0 +1,7 @@
{
"uni-popup.cancel": "cancel",
"uni-popup.ok": "ok",
"uni-popup.placeholder": "pleace enter",
"uni-popup.title": "Hint",
"uni-popup.shareTitle": "Share to"
}

View File

@@ -0,0 +1,8 @@
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
en,
'zh-Hans': zhHans,
'zh-Hant': zhHant
}

View File

@@ -0,0 +1,7 @@
{
"uni-popup.cancel": "取消",
"uni-popup.ok": "确定",
"uni-popup.placeholder": "请输入",
"uni-popup.title": "提示",
"uni-popup.shareTitle": "分享到"
}

View File

@@ -0,0 +1,7 @@
{
"uni-popup.cancel": "取消",
"uni-popup.ok": "確定",
"uni-popup.placeholder": "請輸入",
"uni-popup.title": "提示",
"uni-popup.shareTitle": "分享到"
}

View File

@@ -0,0 +1,45 @@
// #ifdef H5
export default {
name: 'Keypress',
props: {
disable: {
type: Boolean,
default: false
}
},
mounted () {
const keyNames = {
esc: ['Esc', 'Escape'],
tab: 'Tab',
enter: 'Enter',
space: [' ', 'Spacebar'],
up: ['Up', 'ArrowUp'],
left: ['Left', 'ArrowLeft'],
right: ['Right', 'ArrowRight'],
down: ['Down', 'ArrowDown'],
delete: ['Backspace', 'Delete', 'Del']
}
const listener = ($event) => {
if (this.disable) {
return
}
const keyName = Object.keys(keyNames).find(key => {
const keyName = $event.key
const value = keyNames[key]
return value === keyName || (Array.isArray(value) && value.includes(keyName))
})
if (keyName) {
// 避免和其他按键事件冲突
setTimeout(() => {
this.$emit(keyName, {})
}, 0)
}
}
document.addEventListener('keyup', listener)
// this.$once('hook:beforeDestroy', () => {
// document.removeEventListener('keyup', listener)
// })
},
render: () => {}
}
// #endif

View File

@@ -0,0 +1,26 @@
export default {
data() {
return {
}
},
created(){
this.popup = this.getParent()
},
methods:{
/**
* 获取父元素实例
*/
getParent(name = 'uniPopup') {
let parent = this.$parent;
let parentName = parent.$options.name;
while (parentName !== name) {
parent = parent.$parent;
if (!parent) return false
parentName = parent.$options.name;
}
return parent;
},
}
}

View File

@@ -0,0 +1,473 @@
<template>
<view v-if="showPopup" class="uni-popup" :class="[popupstyle, isDesktop ? 'fixforpc-z-index' : '']">
<view @touchstart="touchstart">
<uni-transition key="1" v-if="maskShow" name="mask" mode-class="fade" :styles="maskClass"
:duration="duration" :show="showTrans" @click="onTap" />
<uni-transition key="2" :mode-class="ani" name="content" :styles="transClass" :duration="duration"
:show="showTrans" @click="onTap">
<view class="uni-popup__wrapper" :style="{ backgroundColor: bg }" :class="[popupstyle]" @click="clear">
<slot />
</view>
</uni-transition>
</view>
<!-- #ifdef H5 -->
<keypress v-if="maskShow" @esc="onTap" />
<!-- #endif -->
</view>
</template>
<script>
// #ifdef H5
import keypress from './keypress.js'
// #endif
/**
* PopUp 弹出层
* @description 弹出层组件,为了解决遮罩弹层的问题
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} type = [top|center|bottom|left|right|message|dialog|share] 弹出方式
* @value top 顶部弹出
* @value center 中间弹出
* @value bottom 底部弹出
* @value left 左侧弹出
* @value right 右侧弹出
* @value message 消息提示
* @value dialog 对话框
* @value share 底部分享示例
* @property {Boolean} animation = [true|false] 是否开启动画
* @property {Boolean} maskClick = [true|false] 蒙版点击是否关闭弹窗(废弃)
* @property {Boolean} isMaskClick = [true|false] 蒙版点击是否关闭弹窗
* @property {String} backgroundColor 主窗口背景色
* @property {String} maskBackgroundColor 蒙版颜色
* @property {Boolean} safeArea 是否适配底部安全区
* @event {Function} change 打开关闭弹窗触发e={show: false}
* @event {Function} maskClick 点击遮罩触发
*/
export default {
name: 'uniPopup',
components: {
// #ifdef H5
keypress
// #endif
},
emits: ['change', 'maskClick'],
props: {
// 开启动画
animation: {
type: Boolean,
default: true
},
// 弹出层类型可选值top: 顶部弹出层bottom底部弹出层center全屏弹出层
// message: 消息提示 ; dialog : 对话框
type: {
type: String,
default: 'center'
},
// maskClick
isMaskClick: {
type: Boolean,
default: null
},
// TODO 2 个版本后废弃属性 ,使用 isMaskClick
maskClick: {
type: Boolean,
default: null
},
backgroundColor: {
type: String,
default: 'none'
},
safeArea: {
type: Boolean,
default: true
},
maskBackgroundColor: {
type: String,
default: 'rgba(0, 0, 0, 0.4)'
},
},
watch: {
/**
* 监听type类型
*/
type: {
handler: function(type) {
if (!this.config[type]) return
this[this.config[type]](true)
},
immediate: true
},
isDesktop: {
handler: function(newVal) {
if (!this.config[newVal]) return
this[this.config[this.type]](true)
},
immediate: true
},
/**
* 监听遮罩是否可点击
* @param {Object} val
*/
maskClick: {
handler: function(val) {
this.mkclick = val
},
immediate: true
},
isMaskClick: {
handler: function(val) {
this.mkclick = val
},
immediate: true
},
// H5 下禁止底部滚动
showPopup(show) {
// #ifdef H5
// fix by mehaotian 处理 h5 滚动穿透的问题
document.getElementsByTagName('body')[0].style.overflow = show ? 'hidden' : 'visible'
// #endif
}
},
data() {
return {
duration: 300,
ani: [],
showPopup: false,
showTrans: false,
popupWidth: 0,
popupHeight: 0,
config: {
top: 'top',
bottom: 'bottom',
center: 'center',
left: 'left',
right: 'right',
message: 'top',
dialog: 'center',
share: 'bottom'
},
maskClass: {
position: 'fixed',
bottom: 0,
top: 0,
left: 0,
right: 0,
backgroundColor: 'rgba(0, 0, 0, 0.4)'
},
transClass: {
position: 'fixed',
left: 0,
right: 0
},
maskShow: true,
mkclick: true,
popupstyle: this.isDesktop ? 'fixforpc-top' : 'top'
}
},
computed: {
isDesktop() {
return this.popupWidth >= 500 && this.popupHeight >= 500
},
bg() {
if (this.backgroundColor === '' || this.backgroundColor === 'none') {
return 'transparent'
}
return this.backgroundColor
}
},
mounted() {
const fixSize = () => {
const {
windowWidth,
windowHeight,
windowTop,
safeArea,
screenHeight,
safeAreaInsets
} = uni.getSystemInfoSync()
this.popupWidth = windowWidth
this.popupHeight = windowHeight + (windowTop || 0)
// TODO fix by mehaotian 是否适配底部安全区 ,目前微信ios 、和 app ios 计算有差异,需要框架修复
if (safeArea && this.safeArea) {
// #ifdef MP-WEIXIN
this.safeAreaInsets = screenHeight - safeArea.bottom
// #endif
// #ifndef MP-WEIXIN
this.safeAreaInsets = safeAreaInsets.bottom
// #endif
} else {
this.safeAreaInsets = 0
}
}
fixSize()
// #ifdef H5
// window.addEventListener('resize', fixSize)
// this.$once('hook:beforeDestroy', () => {
// window.removeEventListener('resize', fixSize)
// })
// #endif
},
// #ifndef VUE3
// TODO vue2
destroyed() {
this.setH5Visible()
},
// #endif
// #ifdef VUE3
// TODO vue3
unmounted() {
this.setH5Visible()
},
// #endif
created() {
// this.mkclick = this.isMaskClick || this.maskClick
if (this.isMaskClick === null && this.maskClick === null) {
this.mkclick = true
} else {
this.mkclick = this.isMaskClick !== null ? this.isMaskClick : this.maskClick
}
if (this.animation) {
this.duration = 300
} else {
this.duration = 0
}
// TODO 处理 message 组件生命周期异常的问题
this.messageChild = null
// TODO 解决头条冒泡的问题
this.clearPropagation = false
this.maskClass.backgroundColor = this.maskBackgroundColor
},
methods: {
setH5Visible() {
// #ifdef H5
// fix by mehaotian 处理 h5 滚动穿透的问题
document.getElementsByTagName('body')[0].style.overflow = 'visible'
// #endif
},
/**
* 公用方法,不显示遮罩层
*/
closeMask() {
this.maskShow = false
},
/**
* 公用方法,遮罩层禁止点击
*/
disableMask() {
this.mkclick = false
},
// TODO nvue 取消冒泡
clear(e) {
// #ifndef APP-NVUE
e.stopPropagation()
// #endif
this.clearPropagation = true
},
open(direction) {
// fix by mehaotian 处理快速打开关闭的情况
if (this.showPopup) {
return
}
let innerType = ['top', 'center', 'bottom', 'left', 'right', 'message', 'dialog', 'share']
if (!(direction && innerType.indexOf(direction) !== -1)) {
direction = this.type
}
if (!this.config[direction]) {
console.error('缺少类型:', direction)
return
}
this[this.config[direction]]()
this.$emit('change', {
show: true,
type: direction
})
},
close(type) {
this.showTrans = false
this.$emit('change', {
show: false,
type: this.type
})
clearTimeout(this.timer)
// // 自定义关闭事件
// this.customOpen && this.customClose()
this.timer = setTimeout(() => {
this.showPopup = false
}, 300)
},
// TODO 处理冒泡事件,头条的冒泡事件有问题 ,先这样兼容
touchstart() {
this.clearPropagation = false
},
onTap() {
if (this.clearPropagation) {
// fix by mehaotian 兼容 nvue
this.clearPropagation = false
return
}
this.$emit('maskClick')
if (!this.mkclick) return
this.close()
},
/**
* 顶部弹出样式处理
*/
top(type) {
this.popupstyle = this.isDesktop ? 'fixforpc-top' : 'top'
this.ani = ['slide-top']
this.transClass = {
position: 'fixed',
left: 0,
right: 0,
backgroundColor: this.bg
}
// TODO 兼容 type 属性 ,后续会废弃
if (type) return
this.showPopup = true
this.showTrans = true
this.$nextTick(() => {
if (this.messageChild && this.type === 'message') {
this.messageChild.timerClose()
}
})
},
/**
* 底部弹出样式处理
*/
bottom(type) {
this.popupstyle = 'bottom'
this.ani = ['slide-bottom']
this.transClass = {
position: 'fixed',
left: 0,
right: 0,
bottom: 0,
paddingBottom: this.safeAreaInsets + 'px',
backgroundColor: this.bg
}
// TODO 兼容 type 属性 ,后续会废弃
if (type) return
this.showPopup = true
this.showTrans = true
},
/**
* 中间弹出样式处理
*/
center(type) {
this.popupstyle = 'center'
this.ani = ['zoom-out', 'fade']
this.transClass = {
position: 'fixed',
/* #ifndef APP-NVUE */
display: 'flex',
flexDirection: 'column',
/* #endif */
bottom: 0,
left: 0,
right: 0,
top: 0,
justifyContent: 'center',
alignItems: 'center'
}
// TODO 兼容 type 属性 ,后续会废弃
if (type) return
this.showPopup = true
this.showTrans = true
},
left(type) {
this.popupstyle = 'left'
this.ani = ['slide-left']
this.transClass = {
position: 'fixed',
left: 0,
bottom: 0,
top: 0,
backgroundColor: this.bg,
/* #ifndef APP-NVUE */
display: 'flex',
flexDirection: 'column'
/* #endif */
}
// TODO 兼容 type 属性 ,后续会废弃
if (type) return
this.showPopup = true
this.showTrans = true
},
right(type) {
this.popupstyle = 'right'
this.ani = ['slide-right']
this.transClass = {
position: 'fixed',
bottom: 0,
right: 0,
top: 0,
backgroundColor: this.bg,
/* #ifndef APP-NVUE */
display: 'flex',
flexDirection: 'column'
/* #endif */
}
// TODO 兼容 type 属性 ,后续会废弃
if (type) return
this.showPopup = true
this.showTrans = true
}
}
}
</script>
<style lang="scss">
.uni-popup {
position: fixed;
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
&.top,
&.left,
&.right {
/* #ifdef H5 */
top: var(--window-top);
/* #endif */
/* #ifndef H5 */
top: 0;
/* #endif */
}
.uni-popup__wrapper {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: relative;
/* iphonex 等安全区设置,底部安全区适配 */
/* #ifndef APP-NVUE */
// padding-bottom: constant(safe-area-inset-bottom);
// padding-bottom: env(safe-area-inset-bottom);
/* #endif */
&.left,
&.right {
/* #ifdef H5 */
padding-top: var(--window-top);
/* #endif */
/* #ifndef H5 */
padding-top: 0;
/* #endif */
flex: 1;
}
}
}
.fixforpc-z-index {
/* #ifndef APP-NVUE */
z-index: 999;
/* #endif */
}
.fixforpc-top {
top: 0;
}
</style>

View File

@@ -0,0 +1,87 @@
{
"id": "uni-popup",
"displayName": "uni-popup 弹出层",
"version": "1.8.3",
"description": " Popup 组件,提供常用的弹层",
"keywords": [
"uni-ui",
"弹出层",
"弹窗",
"popup",
"弹框"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-transition"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

View File

@@ -0,0 +1,17 @@
## Popup 弹出层
> **组件名uni-popup**
> 代码块: `uPopup`
> 关联组件:`uni-transition`
弹出层组件,在应用中弹出一个消息提示窗口、提示框等
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-popup)
#### 如使用过程中有任何问题或者您对uni-ui有一些好的建议欢迎加入 uni-ui 交流群871950839