Commit 5c0bea3f authored by jyx's avatar jyx

快手小程序

parent 9cf7f819
......@@ -18,10 +18,10 @@ function gotoBookSearchPage(searchType = ENUM_SEARCH_TYPE.WAREHOUSE, keyword) {
// 文章详情
function gotoBookContentPage(bookId, shortis) {
if (shortis && shortis == 0) {
gotoShortBookContentPage(bookId)
} else {
gotoLongBookContentPage(bookId)
if (shortis && shortis == 0) {
gotoShortBookContentPage(bookId)
} else {
gotoLongBookContentPage(bookId)
}
}
......@@ -29,7 +29,7 @@ function gotoBookContentPage(bookId, shortis) {
function gotoShortBookContentPage(bookId) {
// 短篇小说
uni.navigateTo({
url: `/page-subs/sub_A/book-content/book-content`,
url: `/page-subs/sub_A/book-content/book-content?bookId=` + bookId,
success: (res) => {
res.eventChannel.emit("openBookContentPage", {
bookId
......@@ -41,7 +41,7 @@ function gotoShortBookContentPage(bookId) {
// 长篇文章详情
function gotoLongBookContentPage(bookId) {
uni.navigateTo({
url: `/page-subs/sub_A/book-long-content/book-long-content`,
url: `/page-subs/sub_A/book-long-content/book-long-content?bookId=` + bookId,
success: (res) => {
res.eventChannel.emit("openBookContentPage", {
bookId
......
......@@ -18,7 +18,7 @@ import {
} from "../utils/util.js";
import {
PAKEAGE_NAME,
PAKEAGE_NAME,
VERSION_CODE
} from "../../utils/utils.js";
import {
......@@ -114,7 +114,9 @@ function refreshUserInfo() {
id: userData.idcode,
memberExpirationDate: userData.expireTime
})
saveNickname(userData.nickname);
if (userData.nickname) {
saveNickname(userData.nickname);
}
saveUserInfo(user); // 存储用户数据
postNotification(KEY_NOTIFICATION_LOGIN_SUCCESS); // 通知登录成功
}
......@@ -149,7 +151,7 @@ function postPhone(data, callback) {
function requestToken(data, callback) {
let url = `${config["BASE_URL"]}/user/ttLogin`;
let header = {
pkgName: PAKEAGE_NAME,
pkgName: PAKEAGE_NAME,
version: VERSION_CODE,
token: ``
}
......@@ -183,7 +185,7 @@ function requestUserInfo(callback) {
Object.assign(header, {
token: readToken(),
pkgName: PAKEAGE_NAME,
pkgName: PAKEAGE_NAME,
version: VERSION_CODE,
proChannel: uniChannel
})
......
......@@ -103,8 +103,6 @@
}
})
} else if (this.listType == 2) {
console.log('DDDDDDDD')
getRecommendV1('newbook', 8, (success, data) => {
if (success) {
this.changeData(data)
......
......@@ -4,15 +4,15 @@
<view class="dialog-container">
<view class="dialog-content">
<text style="font-size: 42rpx; color: #6C6A6A;">
{{vipBean.topTitle}}
{{vipBean2.topTitle}}
</text>
<view style="display: flex;flex-direction: row;margin-top: 30rpx;">
<view style="font-size: 42rpx;color: #333232;margin-top: 18rpx;"></view>
<view style="font-size: 60rpx;color: #F32E2E;font-weight: 777;">{{vipBean.firstPayPrice}}</view>
<view style="font-size: 60rpx;color: #F32E2E;font-weight: 777;">{{vipBean2.firstPayPrice}}</view>
<view style="font-size: 42rpx;color: #333232;margin-top: 18rpx;"></view>
</view>
<text style="margin-top: 30rpx; font-size: 38rpx; color: #F32E2E">
{{vipBean.remarks}}
{{vipBean2.remarks}}
</text>
<image @click="handlePay"
......@@ -53,7 +53,8 @@
},
data() {
return {
os: 'android'
os: 'android',
vipBean2: {}
};
},
watch: {
......@@ -67,6 +68,9 @@
}
},
methods: {
onLoad(options) {
this.vipBean2 = this.vipBean
},
showdialog() {
this.$refs.vipback.open();
console.log('vipback-', this.vipBean);
......
<template>
<view>
<c-list ref='list' flag='warehouse' method="POST" :height="height" url='/book/articleList/'
:param="requestParam" @change='changeData'>
<book-list-item v-for='(item, index) in dataList' :key='index' :item='item' :showClose='false'
@tapItem='tapItem($event, index)' @close='tapClose($event, index)'>
</book-list-item>
</c-list>
</view>
<c-list ref='list' flag='warehouse' method="POST" :height="height" url='/book/articleList/' :param="requestParam"
@change='changeData'>
<book-list-item v-for='(item, index) in dataList' :key='index' :item='item' :showClose='false'
@tapItem='tapItem($event, index)' @close='tapClose($event, index)'>
</book-list-item>
</c-list>
</template>
<script>
......@@ -49,8 +47,7 @@
},
watch: {},
methods: {
initRefresh() {
console.log('YYYYYYY')
initRefresh() {
if (isEmpty(this.dataList)) {
this.refreshList();
}
......
......@@ -3,7 +3,7 @@
<CategoryBar id='category' :range='categorys' :current='currentIndex' @change='changeCategory'
@ready='readyCategory'></CategoryBar>
<view :style="[listStyle]" v-if='showEmpty'>
<c-empty emptyTitle="暂无数据"></c-empty>
<c-empty emptyTitle="正在加载中~"></c-empty>
</view>
<view :style="[listStyle]" v-else>
<swiper :style="[listStyle]" :indicator-dots="false" :autoplay="false" :current="currentIndex"
......@@ -13,14 +13,12 @@
</swiper-item>
</swiper>
</view>
<view style="height: 20rpx;"></view>
</scroll-view>
</template>
<script>
import CategoryBar from "./components/category-bar.vue";
import WarehouseList from "./components/warehouse-list.vue";
import CEmpty from "@/components/c-empty/c-empty.vue";
import SystemInfoMixin from "../../common/mixins/system-info-mixin.js";
import Category from "./models/Category.js";
import {
......@@ -39,8 +37,7 @@
mixins: [SystemInfoMixin],
components: {
CategoryBar,
WarehouseList,
CEmpty
WarehouseList
},
data() {
return {
......@@ -49,9 +46,8 @@
currentIndex: 0,
};
},
onLoad(options) {},
onReady() {
this.getCategoryData()
onLoad(options) {
},
computed: {
showEmpty: function() {
......@@ -59,7 +55,7 @@
},
listStyle: function() {
return {
height: `${this.listHeight}px`,
height: `${this.listHeight}px`
}
},
categroyChange: function() {
......@@ -76,36 +72,20 @@
watch: {
categroyChange: {
handler: function(n, o) {
// if (this.$refs[`bookList${n.currentIndex}`]) {
// this.$refs[`bookList${n.currentIndex}`][0].initRefresh();
// }
this.$nextTick(() => {
let ref = this.$refs.bookList;
if (ref) {
console.log('TTTTTTT')
ref[n.currentIndex].initRefresh();
}
})
setTimeout(() => {
this.$refs[`bookList${n.currentIndex}`][0].initRefresh();
}, 500)
},
deep: true
}
},
methods: {
show() {
// if (this.$refs[`bookList${this.currentIndex}`][0].isEmpty()) {
// this.$refs[`bookList${this.currentIndex}`][0].initRefresh();
// }
this.$nextTick(() => {
let ref = this.$refs.bookList;
if (ref) {
console.log('TTTTTTT')
ref[n.currentIndex].initRefresh();
}
})
this.getCategoryData();
},
hide() {
},
hide() {},
readyCategory() {
setTimeout(() => {
this.initHeight()
......@@ -114,7 +94,7 @@
getCategoryData() {
getCategorys((success, data) => {
if (success) {
var result = data.records ? data.records.map(item => {
let result = data.records ? data.records.map(item => {
return new Category(item)
}).sort((a, b) => {
return a.sort - b.sort
......@@ -123,23 +103,20 @@
name: "全部",
id: ""
}))
console.log('KKKKKKKKKKKKKKK', result)
this.categorys = result;
console.log('KKKKKKKKKKKKKKK', this.categorys)
}
})
},
initHeight() {
const query = uni.createSelectorQuery().in(this);
query.select("#navi").boundingClientRect();
query.select("#search").boundingClientRect();
query.select("#category").boundingClientRect();
query.exec((res) => {
let result = 0;
var result = 0;
res.forEach(item => {
if (item) {
result = result + item.height;
if (item.height) {
result = result + item.height;
}
}
})
this.listHeight = this.windowHeight - result - (this.windowHeight * 0.1);
......
......@@ -100,7 +100,7 @@
}
}, this)
// this.refreshBookData(this.bookId)
this.refreshBookData(this.bookId)
},
onShow() {
refreshUserInfo();
......
......@@ -301,8 +301,7 @@
position: relative;
.row {
margin: 8rpx 15rpx;
marign-bottom: 0;
margin: 8rpx 15rpx 0 15rpx;
}
.row:last-child {
......
<template>
<view class="detail-buy">
<view class="book-card">
<view class="cover-box">
<image class="cover" :src="detail.avatar" mode="aspectFill"></image>
</view>
<view class="info-box">
<view class="row">
<view class="book-title">
{{detail.title}}
</view>
<view class="book-value">
{{bookBeanCount}}
</view>
</view>
<view class="row">
<view class="desc">
{{detail.summary}}
</view>
</view>
<view class="row">
<view class="c-flex_row c-align_center">
<uni-icons type='icon-author' custom-prefix="readiconfont" size='20'
color='#378eff'></uni-icons>
<view class="book-author">
{{detail.author}}
</view>
</view>
<view class="buy-button disable-button" v-if='detail.isUnlock'>
已购买
</view>
<view class="buy-button" @click="tapBuy" v-else>
购买
</view>
</view>
</view>
</view>
<view class="pack-box">
<view class="pack-item" :class="[{active: index==selectedIndex}]" v-for='(item, index) in packList'
:key='index' @click="choosePack(item, index)">
<template v-if='item.isBeanPack'>
<view class="name row">
{{item.title}}
</view>
<view class="price row">
{{item.price}}
</view>
<view class="cut-down" v-if='item.giveNumber'>
赠送 {{item.giveNumber}} 书豆
</view>
</template>
<template v-else>
<view class="name row">
{{item.title}}
</view>
<view class="price row">
{{item.price}}
</view>
<view class="origin row" v-if='item.originalPrice'>
原价:{{item.originalPrice}}
</view>
<view class="cut-down" v-if='item.cutDown'>
立省 {{item.cutDown}}
</view>
</template>
</view>
</view>
<view class="warn-box">
<view class="warn-p">
1.目前充值会员暂不支持退款,一经购买不可退换
</view>
<view class="warn-p">
2.未满18岁的未成年人需要在监护人主导,同意下进行相关付费操作
</view>
<view class="warn-p">
3.充值一般在5分钟内到账,如未到账请提供支付截图在"我的"页面联系客服
</view>
<view class="warn-p">
4.之前充值账户请登录后继续阅读
</view>
</view>
</view>
</template>
<script>
import Pack from "../../../../common/models/Pack.js";
import PayInfo from "../../../../common/models/PayInfo.js"
import BookBeanPack from "../../../../common/models/BookBeanPack.js"
import {
getPackData,
getOpenId,
getPayInfo,
getBookBeanPackData,
ENUM_PAY_TYPE,
buyBookWithBookBean
} from "../../../../common/services/index.js";
import {
showLoginView,
refreshUserInfo
} from "../../../../common/services/userServices.js"
import {
toastHide,
toastLoading,
toastMessage
} from "../../../../common/utils/toastUtil.js";
export default {
props: {
detail: {
type: Object,
default: function() {
return {}
}
},
userInfo: {
type: Object,
default: function() {
return null
}
}
},
data: function() {
return {
packList: [],
vipPackList: [],
beanPackList: [],
selectedIndex: 0,
loading: false,
imageError: true
}
},
computed: {
bookBeanCount: function() {
return this.detail && this.detail.bookLegumes ? `${this.detail.bookLegumes}书豆` : "免费"
},
payButtonTitle: function() {
let pack = this.packList[this.selectedIndex];
return (pack instanceof Pack) ? "购买会员" : "购买书豆并解锁本书"
},
packChange: function() {
const {
vipPackList,
beanPackList
} = this;
return {
vipPackList,
beanPackList
}
}
},
watch: {
packChange: {
handler: function(n) {
this.packList = this.getPackList(n.vipPackList, n.beanPackList);
},
deep: true
}
},
mounted() {
this.refreshPackData();
},
methods: {
refreshPackData() {
// getPackData((success, data) => {
// if (success) {
// this.vipPackList = data.map(item => {
// let result = new Pack(item);
// result.isBeanPack = false;
// return result;
// })
// }
// })
getBookBeanPackData((success, data) => {
if (success) {
this.beanPackList = data.map(item => {
let result = new BookBeanPack(item);
result.isBeanPack = true;
return result;
})
}
})
},
getPackList(vipPackList, beanPackList) {
let vip = vipPackList || [];
let bean = beanPackList || [];
return [
...vip,
...bean
];
},
choosePack(item, index) {
this.selectedIndex = index;
this.tapPay();
},
tapPay() {
let isIOS = uni.getSystemInfoSync().platform == "ios" && false
if (isIOS) {
uni.showModal({
title: "提示",
content: "由于相关规范,iOS功能暂不可用"
})
} else {
if (!this.userInfo) {
uni.showModal({
title: "登录",
content: "购买前请前往登录系统",
success: (res) => {
if (res.confirm) {
showLoginView()
}
}
})
return;
}
if (this.loading) return;
let pack = this.packList[this.selectedIndex];
this.loading = true;
let sysLoginFn = (successCB) => {
uni.login({
provider: "weixin",
onlyAuthorize: true,
success: (res) => {
if (res) {
if (typeof successCB == 'function') successCB(res);
} else {
this.loading = false;
}
},
fail: (error) => {
this.loading = false;
}
})
}
let getOpenIdFn = (code, successCB) => {
getOpenId(code, (success, data) => {
if (success) {
if (typeof successCB == 'function') successCB(data);
} else {
this.loading = false;
}
})
}
let getPayInfoFn = (openId, successCB) => {
getPayInfo(pack.id, pack.price, openId, (success, data) => {
if (success) {
if (typeof successCB == 'function') successCB(new PayInfo(data));
} else {
this.loading = false;
}
}, (pack instanceof Pack) ? ENUM_PAY_TYPE.VIP.value : ENUM_PAY_TYPE.BEAN.value)
}
let payOrderFn = (payInfo, successCB) => {
uni.requestPayment({
timeStamp: payInfo.timeStamp,
nonceStr: payInfo.nonceStr,
package: payInfo.packageStr,
signType: payInfo.signType,
paySign: payInfo.paySign,
success: (res) => {
if (typeof successCB == 'function') successCB(res);
},
fail: (error) => {
this.loading = false;
}
})
}
sysLoginFn((code) => {
getOpenIdFn(code.code, (openId) => {
getPayInfoFn(openId, (payInfo) => {
payOrderFn(payInfo, (data) => {
this.loading = false;
toastMessage('会员购买成功')
refreshUserInfo();
})
})
})
})
}
},
tapBuy() {
if (!this.userInfo) {
uni.showModal({
title: "登录",
content: "购买前请前往登录系统",
success: (res) => {
if (res.confirm) {
showLoginView()
}
}
})
return;
}
if (this.userInfo.bookLegumes < this.detail.bookLegumes) {
uni.showModal({
title: "余额不足",
content: `当前余额:${this.userInfo.bookLegumes}, 请前往充值`,
showCancel: false,
confirmText: "知道了"
})
return;
}
toastLoading("购买中");
buyBookWithBookBean(this.detail.id, (success, data) => {
toastHide();
if (success) {
this.$emit("unlockBook")
}
})
},
}
}
</script>
<style lang="scss" scoped>
.detail-buy {
display: flex;
flex-direction: column;
.book-card {
margin: 20rpx;
padding: 20rpx;
background: #fdf6f0;
border-radius: 20rpx;
display: flex;
flex-direction: row;
.cover-box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.cover {
width: 140rpx;
height: 180rpx;
border-radius: 15rpx;
}
}
.info-box {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-around;
margin-left: 20rpx;
.row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.row:last-child {}
.book-title {
color: #333;
font-size: 36rpx;
font-weight: 700;
}
.book-value {
color: goldenrod;
font-size: 40rpx;
font-weight: 700;
}
.desc {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
font-size: 24rpx;
color: #999
}
.book-author {
color: #999;
font-size: 28rpx;
}
.buy-button {
background: #caad9c;
color: #333;
height: 60rpx;
line-height: 60rpx;
width: 180rpx;
text-align: center;
border-radius: 10rpx;
font-size: 30rpx;
color: #fff;
}
.disable-button {
background: #ededed;
color: #888;
}
}
}
.pack-box {
margin-top: 25rpx;
margin-left: 40rpx;
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
.active {
border: 6rpx solid #fd5350 !important;
}
.pack-item {
margin-bottom: 25rpx;
margin-right: 40rpx;
width: calc(31% - 40rpx);
height: 200rpx;
display: flex;
flex-direction: column;
justify-content: space-around;
background: #f5f5f5;
border: 6rpx solid #f5f5f5;
border-radius: 10rpx;
position: relative;
.row {
margin: 8rpx 15rpx;
marign-bottom: 0;
}
.row:last-child {
margin-bottom: 8rpx;
}
.name {
font-size: 26rpx;
font-weight: 700;
color: #333;
}
.price {
font-size: 30rpx;
color: #fd5350;
font-weight: 700;
}
.origin {
font-size: 22rpx;
color: #333;
text-decoration: line-through;
}
.cut-down {
position: absolute;
top: 0;
right: 0;
color: #fff;
background: #ff502f;
font-size: 22rpx;
border-radius: 15rpx;
height: 30rpx;
line-height: 30rpx;
padding: 0 10rpx;
transform: translate(0, -50%);
}
}
}
.warn-box {
color: #956244;
font-size: 26rpx;
display: flex;
flex-direction: column;
padding: 30rpx;
.warn-p {
margin-bottom: 15rpx;
}
.warn-p:last-child {
margin-bottom: 0;
}
}
}
<template>
<view class="detail-buy">
<view class="book-card">
<view class="cover-box">
<image class="cover" :src="detail.avatar" mode="aspectFill"></image>
</view>
<view class="info-box">
<view class="row">
<view class="book-title">
{{detail.title}}
</view>
<view class="book-value">
{{bookBeanCount}}
</view>
</view>
<view class="row">
<view class="desc">
{{detail.summary}}
</view>
</view>
<view class="row">
<view class="c-flex_row c-align_center">
<uni-icons type='icon-author' custom-prefix="readiconfont" size='20'
color='#378eff'></uni-icons>
<view class="book-author">
{{detail.author}}
</view>
</view>
<view class="buy-button disable-button" v-if='detail.isUnlock'>
已购买
</view>
<view class="buy-button" @click="tapBuy" v-else>
购买
</view>
</view>
</view>
</view>
<view class="pack-box">
<view class="pack-item" :class="[{active: index==selectedIndex}]" v-for='(item, index) in packList'
:key='index' @click="choosePack(item, index)">
<template v-if='item.isBeanPack'>
<view class="name row">
{{item.title}}
</view>
<view class="price row">
{{item.price}}
</view>
<view class="cut-down" v-if='item.giveNumber'>
赠送 {{item.giveNumber}} 书豆
</view>
</template>
<template v-else>
<view class="name row">
{{item.title}}
</view>
<view class="price row">
{{item.price}}
</view>
<view class="origin row" v-if='item.originalPrice'>
原价:{{item.originalPrice}}
</view>
<view class="cut-down" v-if='item.cutDown'>
立省 {{item.cutDown}}
</view>
</template>
</view>
</view>
<view class="warn-box">
<view class="warn-p">
1.目前充值会员暂不支持退款,一经购买不可退换
</view>
<view class="warn-p">
2.未满18岁的未成年人需要在监护人主导,同意下进行相关付费操作
</view>
<view class="warn-p">
3.充值一般在5分钟内到账,如未到账请提供支付截图在"我的"页面联系客服
</view>
<view class="warn-p">
4.之前充值账户请登录后继续阅读
</view>
</view>
</view>
</template>
<script>
import Pack from "../../../../common/models/Pack.js";
import PayInfo from "../../../../common/models/PayInfo.js"
import BookBeanPack from "../../../../common/models/BookBeanPack.js"
import {
getPackData,
getOpenId,
getPayInfo,
getBookBeanPackData,
ENUM_PAY_TYPE,
buyBookWithBookBean
} from "../../../../common/services/index.js";
import {
showLoginView,
refreshUserInfo
} from "../../../../common/services/userServices.js"
import {
toastHide,
toastLoading,
toastMessage
} from "../../../../common/utils/toastUtil.js";
export default {
props: {
detail: {
type: Object,
default: function() {
return {}
}
},
userInfo: {
type: Object,
default: function() {
return null
}
}
},
data: function() {
return {
packList: [],
vipPackList: [],
beanPackList: [],
selectedIndex: 0,
loading: false,
imageError: true
}
},
computed: {
bookBeanCount: function() {
return this.detail && this.detail.bookLegumes ? `${this.detail.bookLegumes}书豆` : "免费"
},
payButtonTitle: function() {
let pack = this.packList[this.selectedIndex];
return (pack instanceof Pack) ? "购买会员" : "购买书豆并解锁本书"
},
packChange: function() {
const {
vipPackList,
beanPackList
} = this;
return {
vipPackList,
beanPackList
}
}
},
watch: {
packChange: {
handler: function(n) {
this.packList = this.getPackList(n.vipPackList, n.beanPackList);
},
deep: true
}
},
mounted() {
this.refreshPackData();
},
methods: {
refreshPackData() {
// getPackData((success, data) => {
// if (success) {
// this.vipPackList = data.map(item => {
// let result = new Pack(item);
// result.isBeanPack = false;
// return result;
// })
// }
// })
getBookBeanPackData((success, data) => {
if (success) {
this.beanPackList = data.map(item => {
let result = new BookBeanPack(item);
result.isBeanPack = true;
return result;
})
}
})
},
getPackList(vipPackList, beanPackList) {
let vip = vipPackList || [];
let bean = beanPackList || [];
return [
...vip,
...bean
];
},
choosePack(item, index) {
this.selectedIndex = index;
this.tapPay();
},
tapPay() {
let isIOS = uni.getSystemInfoSync().platform == "ios" && false
if (isIOS) {
uni.showModal({
title: "提示",
content: "由于相关规范,iOS功能暂不可用"
})
} else {
if (!this.userInfo) {
uni.showModal({
title: "登录",
content: "购买前请前往登录系统",
success: (res) => {
if (res.confirm) {
showLoginView()
}
}
})
return;
}
if (this.loading) return;
let pack = this.packList[this.selectedIndex];
this.loading = true;
let sysLoginFn = (successCB) => {
uni.login({
provider: "weixin",
onlyAuthorize: true,
success: (res) => {
if (res) {
if (typeof successCB == 'function') successCB(res);
} else {
this.loading = false;
}
},
fail: (error) => {
this.loading = false;
}
})
}
let getOpenIdFn = (code, successCB) => {
getOpenId(code, (success, data) => {
if (success) {
if (typeof successCB == 'function') successCB(data);
} else {
this.loading = false;
}
})
}
let getPayInfoFn = (openId, successCB) => {
getPayInfo(pack.id, pack.price, openId, (success, data) => {
if (success) {
if (typeof successCB == 'function') successCB(new PayInfo(data));
} else {
this.loading = false;
}
}, (pack instanceof Pack) ? ENUM_PAY_TYPE.VIP.value : ENUM_PAY_TYPE.BEAN.value)
}
let payOrderFn = (payInfo, successCB) => {
uni.requestPayment({
timeStamp: payInfo.timeStamp,
nonceStr: payInfo.nonceStr,
package: payInfo.packageStr,
signType: payInfo.signType,
paySign: payInfo.paySign,
success: (res) => {
if (typeof successCB == 'function') successCB(res);
},
fail: (error) => {
this.loading = false;
}
})
}
sysLoginFn((code) => {
getOpenIdFn(code.code, (openId) => {
getPayInfoFn(openId, (payInfo) => {
payOrderFn(payInfo, (data) => {
this.loading = false;
toastMessage('会员购买成功')
refreshUserInfo();
})
})
})
})
}
},
tapBuy() {
if (!this.userInfo) {
uni.showModal({
title: "登录",
content: "购买前请前往登录系统",
success: (res) => {
if (res.confirm) {
showLoginView()
}
}
})
return;
}
if (this.userInfo.bookLegumes < this.detail.bookLegumes) {
uni.showModal({
title: "余额不足",
content: `当前余额:${this.userInfo.bookLegumes}, 请前往充值`,
showCancel: false,
confirmText: "知道了"
})
return;
}
toastLoading("购买中");
buyBookWithBookBean(this.detail.id, (success, data) => {
toastHide();
if (success) {
this.$emit("unlockBook")
}
})
},
}
}
</script>
<style lang="scss" scoped>
.detail-buy {
display: flex;
flex-direction: column;
.book-card {
margin: 20rpx;
padding: 20rpx;
background: #fdf6f0;
border-radius: 20rpx;
display: flex;
flex-direction: row;
.cover-box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.cover {
width: 140rpx;
height: 180rpx;
border-radius: 15rpx;
}
}
.info-box {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-around;
margin-left: 20rpx;
.row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.row:last-child {}
.book-title {
color: #333;
font-size: 36rpx;
font-weight: 700;
}
.book-value {
color: goldenrod;
font-size: 40rpx;
font-weight: 700;
}
.desc {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
font-size: 24rpx;
color: #999
}
.book-author {
color: #999;
font-size: 28rpx;
}
.buy-button {
background: #caad9c;
color: #333;
height: 60rpx;
line-height: 60rpx;
width: 180rpx;
text-align: center;
border-radius: 10rpx;
font-size: 30rpx;
color: #fff;
}
.disable-button {
background: #ededed;
color: #888;
}
}
}
.pack-box {
margin-top: 25rpx;
margin-left: 40rpx;
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
.active {
border: 6rpx solid #fd5350 !important;
}
.pack-item {
margin-bottom: 25rpx;
margin-right: 40rpx;
width: calc(31% - 40rpx);
height: 200rpx;
display: flex;
flex-direction: column;
justify-content: space-around;
background: #f5f5f5;
border: 6rpx solid #f5f5f5;
border-radius: 10rpx;
position: relative;
.row {
margin: 8rpx 15rpx 0 15rpx;
}
.row:last-child {
margin-bottom: 8rpx;
}
.name {
font-size: 26rpx;
font-weight: 700;
color: #333;
}
.price {
font-size: 30rpx;
color: #fd5350;
font-weight: 700;
}
.origin {
font-size: 22rpx;
color: #333;
text-decoration: line-through;
}
.cut-down {
position: absolute;
top: 0;
right: 0;
color: #fff;
background: #ff502f;
font-size: 22rpx;
border-radius: 15rpx;
height: 30rpx;
line-height: 30rpx;
padding: 0 10rpx;
transform: translate(0, -50%);
}
}
}
.warn-box {
color: #956244;
font-size: 26rpx;
display: flex;
flex-direction: column;
padding: 30rpx;
.warn-p {
margin-bottom: 15rpx;
}
.warn-p:last-child {
margin-bottom: 0;
}
}
}
</style>
\ No newline at end of file
......@@ -186,8 +186,7 @@
position: relative;
.row {
margin: 8rpx 15rpx;
marign-bottom: 0;
margin: 8rpx 15rpx 0 15rpx;
}
.row:last-child {
......
......@@ -267,8 +267,7 @@
position: relative;
.row {
margin: 8rpx 15rpx;
marign-bottom: 0;
margin: 8rpx 15rpx 0 15rpx;
}
.row:last-child {
......
......@@ -272,8 +272,7 @@
position: relative;
.row {
margin: 8rpx 15rpx;
marign-bottom: 0;
margin: 8rpx 15rpx 0 15rpx;
}
.row:last-child {
......
<template>
<view class="detail-buy">
<view class="book-card">
<view class="cover-box">
<image class="cover" :src="detail.avatar" mode="aspectFill"></image>
</view>
<view class="info-box">
<view class="row">
<view class="book-title">
{{detail.title}}
</view>
<view class="book-value">
{{bookBeanCount}}
</view>
</view>
<view class="row">
<view class="desc">
{{detail.summary}}
</view>
</view>
<view class="row">
<view class="c-flex_row c-align_center">
<uni-icons type='icon-author' custom-prefix="readiconfont" size='20'
color='#378eff'></uni-icons>
<view class="book-author">
{{detail.author}}
</view>
</view>
<view class="buy-button disable-button" v-if='detail.isUnlock'>
已购买
</view>
<view class="buy-button" @click="tapBuy" v-else>
购买
</view>
</view>
</view>
</view>
<view class="pack-box">
<view class="pack-item" :class="[{active: index==selectedIndex}]" v-for='(item, index) in packList'
:key='index' @click="choosePack(item, index)">
<template v-if='item.isBeanPack'>
<view class="name row">
{{item.title}}
</view>
<view class="price row">
{{item.price}}
</view>
<view class="cut-down" v-if='item.giveNumber'>
赠送 {{item.giveNumber}} 书豆
</view>
</template>
<template v-else>
<view class="name row">
{{item.title}}
</view>
<view class="price row">
{{item.price}}
</view>
<view class="origin row" v-if='item.originalPrice'>
原价:{{item.originalPrice}}
</view>
<view class="cut-down" v-if='item.cutDown'>
立省 {{item.cutDown}}
</view>
</template>
</view>
</view>
<view class="warn-box">
<view class="warn-p">
1.目前充值会员暂不支持退款,一经购买不可退换
</view>
<view class="warn-p">
2.未满18岁的未成年人需要在监护人主导,同意下进行相关付费操作
</view>
<view class="warn-p">
3.充值一般在5分钟内到账,如未到账请提供支付截图在"我的"页面联系客服
</view>
<view class="warn-p">
4.之前充值账户请登录后继续阅读
</view>
</view>
</view>
</template>
<script>
import Pack from "../../../../common/models/Pack.js";
import PayInfo from "../../../../common/models/PayInfo.js"
import BookBeanPack from "../../../../common/models/BookBeanPack.js"
import {
getPackData,
getOpenId,
getPayInfo,
getBookBeanPackData,
ENUM_PAY_TYPE,
buyBookWithBookBean
} from "../../../../common/services/index.js";
import {
showLoginView,
refreshUserInfo
} from "../../../../common/services/userServices.js"
import {
toastHide,
toastLoading,
toastMessage
} from "../../../../common/utils/toastUtil.js";
export default {
props: {
detail: {
type: Object,
default: function() {
return {}
}
},
userInfo: {
type: Object,
default: function() {
return null
}
}
},
data: function() {
return {
packList: [],
vipPackList: [],
beanPackList: [],
selectedIndex: 0,
loading: false,
imageError: true
}
},
computed: {
bookBeanCount: function() {
return this.detail && this.detail.bookLegumes ? `${this.detail.bookLegumes}书豆` : "免费"
},
payButtonTitle: function() {
let pack = this.packList[this.selectedIndex];
return (pack instanceof Pack) ? "购买会员" : "购买书豆并解锁本书"
},
packChange: function() {
const {
vipPackList,
beanPackList
} = this;
return {
vipPackList,
beanPackList
}
}
},
watch: {
packChange: {
handler: function(n) {
this.packList = this.getPackList(n.vipPackList, n.beanPackList);
},
deep: true
}
},
mounted() {
this.refreshPackData();
},
methods: {
loadImage() {
this.imageError = false
},
errorImage() {
this.imageError = true
},
refreshPackData() {
getPackData((success, data) => {
if (success) {
this.vipPackList = data.map(item => {
let result = new Pack(item);
result.isBeanPack = false;
return result;
})
}
})
getBookBeanPackData((success, data) => {
if (success) {
this.beanPackList = data.map(item => {
let result = new BookBeanPack(item);
result.isBeanPack = true;
return result;
})
}
})
},
getPackList(vipPackList, beanPackList) {
let vip = vipPackList || [];
let bean = beanPackList || [];
return [
...vip,
...bean
];
},
choosePack(item, index) {
this.selectedIndex = index;
this.tapPay();
},
tapPay() {
let isIOS = uni.getSystemInfoSync().platform == "ios" && false
if (isIOS) {
uni.showModal({
title: "提示",
content: "由于相关规范,iOS功能暂不可用"
})
} else {
if (!this.userInfo) {
uni.showModal({
title: "登录",
content: "购买前请前往登录系统",
success: (res) => {
if (res.confirm) {
showLoginView()
}
}
})
return;
}
if (this.loading) return;
let pack = this.packList[this.selectedIndex];
this.loading = true;
let sysLoginFn = (successCB) => {
uni.login({
provider: "weixin",
onlyAuthorize: true,
success: (res) => {
if (res) {
if (typeof successCB == 'function') successCB(res);
} else {
this.loading = false;
}
},
fail: (error) => {
this.loading = false;
}
})
}
let getOpenIdFn = (code, successCB) => {
getOpenId(code, (success, data) => {
if (success) {
if (typeof successCB == 'function') successCB(data);
} else {
this.loading = false;
}
})
}
let getPayInfoFn = (openId, successCB) => {
getPayInfo(pack.id, pack.price, openId, (success, data) => {
if (success) {
if (typeof successCB == 'function') successCB(new PayInfo(data));
} else {
this.loading = false;
}
}, (pack instanceof Pack) ? ENUM_PAY_TYPE.VIP.value : ENUM_PAY_TYPE.BEAN.value)
}
let payOrderFn = (payInfo, successCB) => {
uni.requestPayment({
timeStamp: payInfo.timeStamp,
nonceStr: payInfo.nonceStr,
package: payInfo.packageStr,
signType: payInfo.signType,
paySign: payInfo.paySign,
success: (res) => {
if (typeof successCB == 'function') successCB(res);
},
fail: (error) => {
this.loading = false;
}
})
}
sysLoginFn((code) => {
getOpenIdFn(code.code, (openId) => {
getPayInfoFn(openId, (payInfo) => {
payOrderFn(payInfo, (data) => {
this.loading = false;
toastMessage('会员购买成功')
refreshUserInfo();
})
})
})
})
}
},
tapBuy() {
if (!this.userInfo) {
uni.showModal({
title: "登录",
content: "购买前请前往登录系统",
success: (res) => {
if (res.confirm) {
showLoginView()
}
}
})
return;
}
if (this.userInfo.bookLegumes < this.detail.bookLegumes) {
uni.showModal({
title: "余额不足",
content: `当前余额:${this.userInfo.bookLegumes}, 请前往充值`,
showCancel: false,
confirmText: "知道了"
})
return;
}
toastLoading("购买中");
buyBookWithBookBean(this.detail.id, (success, data) => {
toastHide();
if (success) {
this.$emit("unlockBook")
}
})
},
}
}
</script>
<style lang="scss" scoped>
.detail-buy {
display: flex;
flex-direction: column;
.book-card {
margin: 20rpx;
padding: 20rpx;
background: #fdf6f0;
border-radius: 20rpx;
display: flex;
flex-direction: row;
.cover-box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.cover {
width: 140rpx;
height: 180rpx;
border-radius: 15rpx;
}
}
.info-box {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-around;
margin-left: 20rpx;
.row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.row:last-child {}
.book-title {
color: #333;
font-size: 36rpx;
font-weight: 700;
}
.book-value {
color: goldenrod;
font-size: 40rpx;
font-weight: 700;
}
.desc {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
font-size: 24rpx;
color: #999
}
.book-author {
color: #999;
font-size: 28rpx;
}
.buy-button {
background: #caad9c;
color: #333;
height: 60rpx;
line-height: 60rpx;
width: 180rpx;
text-align: center;
border-radius: 10rpx;
font-size: 30rpx;
color: #fff;
}
.disable-button {
background: #ededed;
color: #888;
}
}
}
.pack-box {
margin-top: 25rpx;
margin-left: 40rpx;
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
.active {
border: 6rpx solid #fd5350 !important;
}
.pack-item {
margin-bottom: 25rpx;
margin-right: 40rpx;
width: calc(31% - 40rpx);
height: 200rpx;
display: flex;
flex-direction: column;
justify-content: space-around;
background: #f5f5f5;
border: 6rpx solid #f5f5f5;
border-radius: 10rpx;
position: relative;
.row {
margin: 8rpx 15rpx;
marign-bottom: 0;
}
.row:last-child {
margin-bottom: 8rpx;
}
.name {
font-size: 26rpx;
font-weight: 700;
color: #333;
}
.price {
font-size: 30rpx;
color: #fd5350;
font-weight: 700;
}
.origin {
font-size: 22rpx;
color: #333;
text-decoration: line-through;
}
.cut-down {
position: absolute;
top: 0;
right: 0;
color: #fff;
background: #ff502f;
font-size: 22rpx;
border-radius: 15rpx;
height: 30rpx;
line-height: 30rpx;
padding: 0 10rpx;
transform: translate(0, -50%);
}
}
}
.warn-box {
color: #956244;
font-size: 26rpx;
display: flex;
flex-direction: column;
padding: 30rpx;
.warn-p {
margin-bottom: 15rpx;
}
.warn-p:last-child {
margin-bottom: 0;
}
}
}
<template>
<view class="detail-buy">
<view class="book-card">
<view class="cover-box">
<image class="cover" :src="detail.avatar" mode="aspectFill"></image>
</view>
<view class="info-box">
<view class="row">
<view class="book-title">
{{detail.title}}
</view>
<view class="book-value">
{{bookBeanCount}}
</view>
</view>
<view class="row">
<view class="desc">
{{detail.summary}}
</view>
</view>
<view class="row">
<view class="c-flex_row c-align_center">
<uni-icons type='icon-author' custom-prefix="readiconfont" size='20'
color='#378eff'></uni-icons>
<view class="book-author">
{{detail.author}}
</view>
</view>
<view class="buy-button disable-button" v-if='detail.isUnlock'>
已购买
</view>
<view class="buy-button" @click="tapBuy" v-else>
购买
</view>
</view>
</view>
</view>
<view class="pack-box">
<view class="pack-item" :class="[{active: index==selectedIndex}]" v-for='(item, index) in packList'
:key='index' @click="choosePack(item, index)">
<template v-if='item.isBeanPack'>
<view class="name row">
{{item.title}}
</view>
<view class="price row">
{{item.price}}
</view>
<view class="cut-down" v-if='item.giveNumber'>
赠送 {{item.giveNumber}} 书豆
</view>
</template>
<template v-else>
<view class="name row">
{{item.title}}
</view>
<view class="price row">
{{item.price}}
</view>
<view class="origin row" v-if='item.originalPrice'>
原价:{{item.originalPrice}}
</view>
<view class="cut-down" v-if='item.cutDown'>
立省 {{item.cutDown}}
</view>
</template>
</view>
</view>
<view class="warn-box">
<view class="warn-p">
1.目前充值会员暂不支持退款,一经购买不可退换
</view>
<view class="warn-p">
2.未满18岁的未成年人需要在监护人主导,同意下进行相关付费操作
</view>
<view class="warn-p">
3.充值一般在5分钟内到账,如未到账请提供支付截图在"我的"页面联系客服
</view>
<view class="warn-p">
4.之前充值账户请登录后继续阅读
</view>
</view>
</view>
</template>
<script>
import Pack from "../../../../common/models/Pack.js";
import PayInfo from "../../../../common/models/PayInfo.js"
import BookBeanPack from "../../../../common/models/BookBeanPack.js"
import {
getPackData,
getOpenId,
getPayInfo,
getBookBeanPackData,
ENUM_PAY_TYPE,
buyBookWithBookBean
} from "../../../../common/services/index.js";
import {
showLoginView,
refreshUserInfo
} from "../../../../common/services/userServices.js"
import {
toastHide,
toastLoading,
toastMessage
} from "../../../../common/utils/toastUtil.js";
export default {
props: {
detail: {
type: Object,
default: function() {
return {}
}
},
userInfo: {
type: Object,
default: function() {
return null
}
}
},
data: function() {
return {
packList: [],
vipPackList: [],
beanPackList: [],
selectedIndex: 0,
loading: false,
imageError: true
}
},
computed: {
bookBeanCount: function() {
return this.detail && this.detail.bookLegumes ? `${this.detail.bookLegumes}书豆` : "免费"
},
payButtonTitle: function() {
let pack = this.packList[this.selectedIndex];
return (pack instanceof Pack) ? "购买会员" : "购买书豆并解锁本书"
},
packChange: function() {
const {
vipPackList,
beanPackList
} = this;
return {
vipPackList,
beanPackList
}
}
},
watch: {
packChange: {
handler: function(n) {
this.packList = this.getPackList(n.vipPackList, n.beanPackList);
},
deep: true
}
},
mounted() {
this.refreshPackData();
},
methods: {
loadImage() {
this.imageError = false
},
errorImage() {
this.imageError = true
},
refreshPackData() {
getPackData((success, data) => {
if (success) {
this.vipPackList = data.map(item => {
let result = new Pack(item);
result.isBeanPack = false;
return result;
})
}
})
getBookBeanPackData((success, data) => {
if (success) {
this.beanPackList = data.map(item => {
let result = new BookBeanPack(item);
result.isBeanPack = true;
return result;
})
}
})
},
getPackList(vipPackList, beanPackList) {
let vip = vipPackList || [];
let bean = beanPackList || [];
return [
...vip,
...bean
];
},
choosePack(item, index) {
this.selectedIndex = index;
this.tapPay();
},
tapPay() {
let isIOS = uni.getSystemInfoSync().platform == "ios" && false
if (isIOS) {
uni.showModal({
title: "提示",
content: "由于相关规范,iOS功能暂不可用"
})
} else {
if (!this.userInfo) {
uni.showModal({
title: "登录",
content: "购买前请前往登录系统",
success: (res) => {
if (res.confirm) {
showLoginView()
}
}
})
return;
}
if (this.loading) return;
let pack = this.packList[this.selectedIndex];
this.loading = true;
let sysLoginFn = (successCB) => {
uni.login({
provider: "weixin",
onlyAuthorize: true,
success: (res) => {
if (res) {
if (typeof successCB == 'function') successCB(res);
} else {
this.loading = false;
}
},
fail: (error) => {
this.loading = false;
}
})
}
let getOpenIdFn = (code, successCB) => {
getOpenId(code, (success, data) => {
if (success) {
if (typeof successCB == 'function') successCB(data);
} else {
this.loading = false;
}
})
}
let getPayInfoFn = (openId, successCB) => {
getPayInfo(pack.id, pack.price, openId, (success, data) => {
if (success) {
if (typeof successCB == 'function') successCB(new PayInfo(data));
} else {
this.loading = false;
}
}, (pack instanceof Pack) ? ENUM_PAY_TYPE.VIP.value : ENUM_PAY_TYPE.BEAN.value)
}
let payOrderFn = (payInfo, successCB) => {
uni.requestPayment({
timeStamp: payInfo.timeStamp,
nonceStr: payInfo.nonceStr,
package: payInfo.packageStr,
signType: payInfo.signType,
paySign: payInfo.paySign,
success: (res) => {
if (typeof successCB == 'function') successCB(res);
},
fail: (error) => {
this.loading = false;
}
})
}
sysLoginFn((code) => {
getOpenIdFn(code.code, (openId) => {
getPayInfoFn(openId, (payInfo) => {
payOrderFn(payInfo, (data) => {
this.loading = false;
toastMessage('会员购买成功')
refreshUserInfo();
})
})
})
})
}
},
tapBuy() {
if (!this.userInfo) {
uni.showModal({
title: "登录",
content: "购买前请前往登录系统",
success: (res) => {
if (res.confirm) {
showLoginView()
}
}
})
return;
}
if (this.userInfo.bookLegumes < this.detail.bookLegumes) {
uni.showModal({
title: "余额不足",
content: `当前余额:${this.userInfo.bookLegumes}, 请前往充值`,
showCancel: false,
confirmText: "知道了"
})
return;
}
toastLoading("购买中");
buyBookWithBookBean(this.detail.id, (success, data) => {
toastHide();
if (success) {
this.$emit("unlockBook")
}
})
},
}
}
</script>
<style lang="scss" scoped>
.detail-buy {
display: flex;
flex-direction: column;
.book-card {
margin: 20rpx;
padding: 20rpx;
background: #fdf6f0;
border-radius: 20rpx;
display: flex;
flex-direction: row;
.cover-box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.cover {
width: 140rpx;
height: 180rpx;
border-radius: 15rpx;
}
}
.info-box {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-around;
margin-left: 20rpx;
.row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.row:last-child {}
.book-title {
color: #333;
font-size: 36rpx;
font-weight: 700;
}
.book-value {
color: goldenrod;
font-size: 40rpx;
font-weight: 700;
}
.desc {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
font-size: 24rpx;
color: #999
}
.book-author {
color: #999;
font-size: 28rpx;
}
.buy-button {
background: #caad9c;
color: #333;
height: 60rpx;
line-height: 60rpx;
width: 180rpx;
text-align: center;
border-radius: 10rpx;
font-size: 30rpx;
color: #fff;
}
.disable-button {
background: #ededed;
color: #888;
}
}
}
.pack-box {
margin-top: 25rpx;
margin-left: 40rpx;
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
.active {
border: 6rpx solid #fd5350 !important;
}
.pack-item {
margin-bottom: 25rpx;
margin-right: 40rpx;
width: calc(31% - 40rpx);
height: 200rpx;
display: flex;
flex-direction: column;
justify-content: space-around;
background: #f5f5f5;
border: 6rpx solid #f5f5f5;
border-radius: 10rpx;
position: relative;
.row {
margin: 8rpx 15rpx 0 15rpx;
}
.row:last-child {
margin-bottom: 8rpx;
}
.name {
font-size: 26rpx;
font-weight: 700;
color: #333;
}
.price {
font-size: 30rpx;
color: #fd5350;
font-weight: 700;
}
.origin {
font-size: 22rpx;
color: #333;
text-decoration: line-through;
}
.cut-down {
position: absolute;
top: 0;
right: 0;
color: #fff;
background: #ff502f;
font-size: 22rpx;
border-radius: 15rpx;
height: 30rpx;
line-height: 30rpx;
padding: 0 10rpx;
transform: translate(0, -50%);
}
}
}
.warn-box {
color: #956244;
font-size: 26rpx;
display: flex;
flex-direction: column;
padding: 30rpx;
.warn-p {
margin-bottom: 15rpx;
}
.warn-p:last-child {
margin-bottom: 0;
}
}
}
</style>
\ No newline at end of file
......@@ -184,7 +184,7 @@
position: relative;
.row {
margin: 8rpx 15rpx;
margin: 8rpx 15rpx 0 15rpx;
marign-bottom: 0;
}
......
......@@ -267,8 +267,7 @@
position: relative;
.row {
margin: 8rpx 15rpx;
marign-bottom: 0;
margin: 8rpx 15rpx 0 15rpx;
}
.row:last-child {
......
......@@ -4,7 +4,6 @@
<uni-easyinput v-model="searchKeyword" placeholder="请输入书名或者作者名" :focus='focus' confirmType="search"
trim="all" :inputBorder="true" @clear="clearInput" @change="changeInput"
@confirm="changeInput"></uni-easyinput>
</view>
<view class="button-box item" @click="tapSearch">
<view class="title">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment