Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
U
uniapp_vedio
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
android
uniapp_vedio
Commits
5c0bea3f
Commit
5c0bea3f
authored
Sep 09, 2024
by
jyx
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
快手小程序
parent
9cf7f819
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
1027 additions
and
1057 deletions
+1027
-1057
page-route.js
vedio/common/services/page-route.js
+6
-6
userServices.js
vedio/common/services/userServices.js
+6
-4
recommend-list.vue
vedio/components/recommend-list/recommend-list.vue
+0
-2
vipback-popup.vue
vedio/components/vipback-popup/vipback-popup.vue
+8
-4
warehouse-list.vue
vedio/components/warehouse/components/warehouse-list.vue
+7
-10
warehouse.vue
vedio/components/warehouse/warehouse.vue
+17
-40
book-content.vue
vedio/page-subs/sub_A/book-content/book-content.vue
+1
-1
bean-pop.vue
vedio/page-subs/sub_A/book-content/components/bean-pop.vue
+1
-2
detail-buy.vue
vedio/page-subs/sub_A/book-content/components/detail-buy.vue
+485
-486
recommend-pop.vue
...page-subs/sub_A/book-content/components/recommend-pop.vue
+1
-2
vip-pop.vue
vedio/page-subs/sub_A/book-content/components/vip-pop.vue
+1
-2
bean-pop.vue
...page-subs/sub_A/book-long-content/components/bean-pop.vue
+1
-2
detail-buy.vue
...ge-subs/sub_A/book-long-content/components/detail-buy.vue
+491
-492
recommend-pop.vue
...subs/sub_A/book-long-content/components/recommend-pop.vue
+1
-1
vip-pop.vue
.../page-subs/sub_A/book-long-content/components/vip-pop.vue
+1
-2
search-header-bar.vue
...e-subs/sub_A/book-search/components/search-header-bar.vue
+0
-1
No files found.
vedio/common/services/page-route.js
View file @
5c0bea3f
...
...
@@ -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
...
...
vedio/common/services/userServices.js
View file @
5c0bea3f
...
...
@@ -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
})
...
...
vedio/components/recommend-list/recommend-list.vue
View file @
5c0bea3f
...
...
@@ -103,8 +103,6 @@
}
})
}
else
if
(
this
.
listType
==
2
)
{
console
.
log
(
'DDDDDDDD'
)
getRecommendV1
(
'newbook'
,
8
,
(
success
,
data
)
=>
{
if
(
success
)
{
this
.
changeData
(
data
)
...
...
vedio/components/vipback-popup/vipback-popup.vue
View file @
5c0bea3f
...
...
@@ -4,15 +4,15 @@
<view
class=
"dialog-container"
>
<view
class=
"dialog-content"
>
<text
style=
"font-size: 42rpx; color: #6C6A6A;"
>
{{
vipBean
.
topTitle
}}
{{
vipBean
2
.
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;"
>
{{
vipBean
2
.
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
}}
{{
vipBean
2
.
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
);
...
...
vedio/components/warehouse/components/warehouse-list.vue
View file @
5c0bea3f
<
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
();
}
...
...
vedio/components/warehouse/warehouse.vue
View file @
5c0bea3f
...
...
@@ -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
);
...
...
vedio/page-subs/sub_A/book-content/book-content.vue
View file @
5c0bea3f
...
...
@@ -100,7 +100,7 @@
}
},
this
)
//
this.refreshBookData(this.bookId)
this
.
refreshBookData
(
this
.
bookId
)
},
onShow
()
{
refreshUserInfo
();
...
...
vedio/page-subs/sub_A/book-content/components/bean-pop.vue
View file @
5c0bea3f
...
...
@@ -301,8 +301,7 @@
position
:
relative
;
.row
{
margin
:
8rpx
15rpx
;
marign-bottom
:
0
;
margin
:
8rpx
15rpx
0
15rpx
;
}
.row
:last-child
{
...
...
vedio/page-subs/sub_A/book-content/components/detail-buy.vue
View file @
5c0bea3f
<
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
vedio/page-subs/sub_A/book-content/components/recommend-pop.vue
View file @
5c0bea3f
...
...
@@ -186,8 +186,7 @@
position
:
relative
;
.row
{
margin
:
8rpx
15rpx
;
marign-bottom
:
0
;
margin
:
8rpx
15rpx
0
15rpx
;
}
.row
:last-child
{
...
...
vedio/page-subs/sub_A/book-content/components/vip-pop.vue
View file @
5c0bea3f
...
...
@@ -267,8 +267,7 @@
position
:
relative
;
.row
{
margin
:
8rpx
15rpx
;
marign-bottom
:
0
;
margin
:
8rpx
15rpx
0
15rpx
;
}
.row
:last-child
{
...
...
vedio/page-subs/sub_A/book-long-content/components/bean-pop.vue
View file @
5c0bea3f
...
...
@@ -272,8 +272,7 @@
position
:
relative
;
.row
{
margin
:
8rpx
15rpx
;
marign-bottom
:
0
;
margin
:
8rpx
15rpx
0
15rpx
;
}
.row
:last-child
{
...
...
vedio/page-subs/sub_A/book-long-content/components/detail-buy.vue
View file @
5c0bea3f
<
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
vedio/page-subs/sub_A/book-long-content/components/recommend-pop.vue
View file @
5c0bea3f
...
...
@@ -184,7 +184,7 @@
position
:
relative
;
.row
{
margin
:
8rpx
15rpx
;
margin
:
8rpx
15rpx
0
15rpx
;
marign-bottom
:
0
;
}
...
...
vedio/page-subs/sub_A/book-long-content/components/vip-pop.vue
View file @
5c0bea3f
...
...
@@ -267,8 +267,7 @@
position
:
relative
;
.row
{
margin
:
8rpx
15rpx
;
marign-bottom
:
0
;
margin
:
8rpx
15rpx
0
15rpx
;
}
.row
:last-child
{
...
...
vedio/page-subs/sub_A/book-search/components/search-header-bar.vue
View file @
5c0bea3f
...
...
@@ -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"
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment