Compare commits
No commits in common. "main" and "master" have entirely different histories.
24
.hbuilderx/launch.json
Normal file
24
.hbuilderx/launch.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
// launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
|
||||
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
|
||||
"version" : "0.0",
|
||||
"configurations" : [
|
||||
{
|
||||
"app-plus" : {
|
||||
"launchtype" : "local"
|
||||
},
|
||||
"default" : {
|
||||
"launchtype" : "local"
|
||||
},
|
||||
"type" : "uniCloud"
|
||||
},
|
||||
{
|
||||
"playground" : "custom",
|
||||
"type" : "uni-app:app-ios"
|
||||
},
|
||||
{
|
||||
"playground" : "custom",
|
||||
"type" : "uni-app:app-android"
|
||||
}
|
||||
]
|
||||
}
|
23
App.vue
Normal file
23
App.vue
Normal file
@ -0,0 +1,23 @@
|
||||
<script>
|
||||
export default {
|
||||
onLaunch: function() {
|
||||
console.log('App Launch')
|
||||
},
|
||||
onShow: function() {
|
||||
console.log('App Show')
|
||||
},
|
||||
onHide: function() {
|
||||
console.log('App Hide')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/uni_modules/uview-ui/index.scss";
|
||||
/*每个页面公共css */
|
||||
uni-page-body,
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
78
components/commBookItem/index.vue
Normal file
78
components/commBookItem/index.vue
Normal file
@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<view class="_book_content">
|
||||
<view class="book_box">
|
||||
<view class="book_box_image">
|
||||
<image class="is_image" :src="bookImage"></image>
|
||||
</view>
|
||||
<view class="book_box_title">
|
||||
{{bookName}}
|
||||
</view>
|
||||
<view class="book_box_tips">
|
||||
{{bookTips}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
bookTips: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
bookName: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
bookImage: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.is_image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
._book_content {
|
||||
width: 100%;
|
||||
|
||||
.book_box {
|
||||
width: 100%;
|
||||
|
||||
.book_box_image {
|
||||
width: 100%;
|
||||
height: 266rpx;
|
||||
}
|
||||
|
||||
.book_box_title {
|
||||
width: 100%;
|
||||
font-size: 34rpx;
|
||||
color: #1A1A1A;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
.book_box_tips {
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
line-height: 1;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
196
components/commBookItemThree/index.vue
Normal file
196
components/commBookItemThree/index.vue
Normal file
@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<view class="commBookLeftRigth_content">
|
||||
<view>
|
||||
<view class="commBookLeftRigth_book_box">
|
||||
<view class="commBookLeftRigth_content_left">
|
||||
<image class="is_image" :src="bookImage"></image>
|
||||
</view>
|
||||
<view class="commBookLeftRigth_content_right">
|
||||
<view class="_content_right_title">{{bookName}}</view>
|
||||
<view class="_content_right_tips">{{bookTips}}</view>
|
||||
<view class="_content_right_introduction">{{bookIntroduction}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="_book_operate_all">
|
||||
<view v-if="bookcase == 1" :class="['operate_all_add_bookshelf', 'active' ]">
|
||||
已加入书架
|
||||
</view>
|
||||
<view v-else :class="['operate_all_add_bookshelf']" @tap="addBookshelf">
|
||||
加入书架
|
||||
</view>
|
||||
<view class="operate_all_start_read" @tap="toNovelReading">
|
||||
开始阅读
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
bookTips: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
bookName: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
bookImage: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
bookIntroduction: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
bookId: {
|
||||
type: [Number, String],
|
||||
default: ''
|
||||
},
|
||||
bookcase: {
|
||||
type: [Number, String],
|
||||
default: ''
|
||||
},
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
addBookshelfFlag: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addBookshelf() {
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
const parameter = {
|
||||
custom: {
|
||||
token: true
|
||||
}
|
||||
}
|
||||
const data = {
|
||||
sid: this.bookId,
|
||||
}
|
||||
uni.$u.http.post('/addBookshelf', data, parameter).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
this.$emit('addBookshelf', this.bookId);
|
||||
uni.showToast({
|
||||
title: '加入成功',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
})
|
||||
},
|
||||
toNovelReading() {
|
||||
const bookId = this.bookId;
|
||||
uni.navigateTo({
|
||||
url: `/pages/novelReading/novelReading?sid=${bookId}`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.commBookLeftRigth_content {
|
||||
width: 100%;
|
||||
|
||||
.commBookLeftRigth_book_box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
.commBookLeftRigth_content_left {
|
||||
width: 200rpx;
|
||||
height: 266rpx;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 8rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0 8rpx rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.commBookLeftRigth_content_right {
|
||||
flex: 1;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding: 10rpx 0 10rpx 20rpx;
|
||||
overflow: hidden;
|
||||
|
||||
._content_right_title {
|
||||
font-size: 34rpx;
|
||||
color: #1A1A1A;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
._content_right_tips {
|
||||
font-size: 30rpx;
|
||||
color: #999999;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
._content_right_introduction {
|
||||
font-size: 30rpx;
|
||||
color: #999999;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
._book_operate_all {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 26rpx;
|
||||
|
||||
.operate_all_add_bookshelf {
|
||||
width: 296rpx;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
background-color: #FFEDF0;
|
||||
border-radius: 20rpx;
|
||||
font-size: 30rpx;
|
||||
color: #FF728F;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.operate_all_add_bookshelf.active {
|
||||
background: #F1F1F1;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.operate_all_start_read {
|
||||
width: 358rpx;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
background-color: #FF728F;
|
||||
border-radius: 20rpx;
|
||||
font-size: 30rpx;
|
||||
color: #FFFFFF;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
99
components/commBookLeftRigth/index.vue
Normal file
99
components/commBookLeftRigth/index.vue
Normal file
@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<view class="commBookLeftRigth_content">
|
||||
<view class="commBookLeftRigth_content_left">
|
||||
<image class="is_image" :src="bookImage"></image>
|
||||
</view>
|
||||
<view class="commBookLeftRigth_content_right">
|
||||
<view class="_content_right_title">{{bookName}}</view>
|
||||
<view class="_content_right_tips">{{bookTips}}</view>
|
||||
<view class="_content_right_introduction">{{bookIntroduction}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
bookTips: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
bookName: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
bookImage: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
bookIntroduction: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.commBookLeftRigth_content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
.commBookLeftRigth_content_left {
|
||||
width: 200rpx;
|
||||
height: 266rpx;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.commBookLeftRigth_content_right {
|
||||
flex: 1;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding: 10rpx 0 10rpx 20rpx;
|
||||
overflow: hidden;
|
||||
|
||||
._content_right_title {
|
||||
font-size: 34rpx;
|
||||
color: #1A1A1A;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
._content_right_tips {
|
||||
font-size: 30rpx;
|
||||
color: #999999;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
._content_right_introduction {
|
||||
font-size: 30rpx;
|
||||
color: #999999;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
28
components/commFooter/index.vue
Normal file
28
components/commFooter/index.vue
Normal file
@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<view class="commFooter_content">
|
||||
{{footerTips}}
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:'commFooter',
|
||||
props :{
|
||||
footerTips:{
|
||||
type: String,
|
||||
default:'到底啦,不要再划了~'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.commFooter_content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
line-height: 1;
|
||||
}
|
||||
</style>
|
174
components/commNavBar/index.vue
Normal file
174
components/commNavBar/index.vue
Normal file
@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<view class="commNavBar_content">
|
||||
<uni-nav-bar :border="false" :statusBar="true" leftWidth="0" rightWidth="0" height="80rpx" :fixed="false"
|
||||
backgroundColor="transparent">
|
||||
<view class="nav_bar_box">
|
||||
<view class="nav_bar_box_left">
|
||||
<view class="_box_left_list">
|
||||
<view class="_left_list_item" v-for="m in navBarList" :key="m.id" @tap="navBarClick"
|
||||
:data-id="m.id">
|
||||
<view :class="['_left_list_item_box', navBarActive == m.id ? 'active':'']">
|
||||
<view :class="['_list_item_name', navBarActive==m.id ? 'active' :'']">{{m.name}}
|
||||
</view>
|
||||
<view class="_list_item_iamge" v-if="navBarActive == m.id">
|
||||
<image class="is_image" src="../../static/images/nav-bar_Vector.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="nav_bar_box_right" @tap="toBooksSearchList">
|
||||
<view class="_box_right_search" >
|
||||
<view class="_search_iamge">
|
||||
<image class="is_image" src="/static/images/nav_bar_search.png"></image>
|
||||
</view>
|
||||
<view class="_search_tips">
|
||||
搜索小说
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-nav-bar>
|
||||
<view class="commNavBar_bag" />
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'commNavBar',
|
||||
props: {
|
||||
navBarList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
navBarActive: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
navBarClick(event) {
|
||||
this.$emit('navBarClick', event)
|
||||
},
|
||||
toBooksSearchList() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/booksSearchList/booksSearchList'
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
::v-deep.uni-navbar {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding-bottom: 32rpx;
|
||||
// .uni-navbar__content {
|
||||
// padding-bottom: 32rpx;
|
||||
// }
|
||||
}
|
||||
|
||||
.commNavBar_bag {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 400rpx;
|
||||
background: linear-gradient(to bottom, #FFC7D3 0%, #FFEBEE 50%, #fff 100%);
|
||||
}
|
||||
|
||||
.commNavBar_content {
|
||||
width: 100%;
|
||||
|
||||
.nav_bar_box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
|
||||
.nav_bar_box_left {
|
||||
|
||||
// height: ;
|
||||
._box_left_list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
._left_list_item {
|
||||
// padding-right: 20;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 120rpx;
|
||||
|
||||
._left_list_item_box {
|
||||
._list_item_name {
|
||||
font-size: 30rpx;
|
||||
color: #666666;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
._list_item_name.active {
|
||||
font-size: 38rpx;
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
._list_item_iamge {
|
||||
width: 30rpx;
|
||||
height: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
._left_list_item_box.active {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 54rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.nav_bar_box_right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
border-radius: 40rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 38rpx;
|
||||
|
||||
._box_right_search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
._search_iamge {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
}
|
||||
|
||||
._search_tips {
|
||||
font-size: 26rpx;
|
||||
color: #BBBBBB;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
117
components/commVipInfo/index.vue
Normal file
117
components/commVipInfo/index.vue
Normal file
@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<view class="commVipInfo_content">
|
||||
<view class="vip_info_box">
|
||||
<view class="vip_info_box_left">
|
||||
<view class="vip_info_sculpture">
|
||||
<image class="is_image" src="/static/images/myInfo/default_sculpture.png" />
|
||||
</view>
|
||||
<view class="vip_whether_tips_box">
|
||||
<view class="vip_whether_tips">
|
||||
<view class="vip_whether_tips_test">
|
||||
尊贵的VIP会员
|
||||
</view>
|
||||
<view class="vip_whether_tips_icon">
|
||||
<image src="/static/images/myInfo/VIP_whether.png" class="is_image" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="vip_time_tips">尊享无限时书城免费畅读</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="vip_info_box_right">
|
||||
<view class="vip_info_renew">续费</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'commVipInfo',
|
||||
data() {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.commVipInfo_content {
|
||||
width: 100%;
|
||||
|
||||
.vip_info_box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 142rpx;
|
||||
padding: 0 40rpx;
|
||||
background: url('/static/images/member_vip_bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.vip_info_box_left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.vip_info_sculpture {
|
||||
width: 68rpx;
|
||||
height: 68rpx;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.vip_whether_tips_box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-center: center;
|
||||
|
||||
.vip_whether_tips {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.vip_whether_tips_test {
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.vip_whether_tips_icon {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.vip_time_tips {
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
line-height: 1;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.vip_info_box_right {
|
||||
.vip_info_renew {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0 30rpx;
|
||||
border-radius: 34rpx;
|
||||
height: 68rpx;
|
||||
background-color: rgba(255, 255, 255, 0.65);
|
||||
font-size: 28rpx;
|
||||
color: #E0385B;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
82
components/originalBoolItem/index.vue
Normal file
82
components/originalBoolItem/index.vue
Normal file
@ -0,0 +1,82 @@
|
||||
<template>
|
||||
<view class="_book_content">
|
||||
<view class="book_box">
|
||||
<view class="book_box_image">
|
||||
<image class="is_image" :src="bookImage"></image>
|
||||
</view>
|
||||
<view class="book_box_title">
|
||||
{{bookName}}
|
||||
</view>
|
||||
<view class="book_box_tips">
|
||||
{{bookTips}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'originalBoolItem',
|
||||
props: {
|
||||
bookTips: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
bookName: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
bookImage: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.is_image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
._book_content {
|
||||
width: 100%;
|
||||
|
||||
.book_box {
|
||||
width: 100%;
|
||||
|
||||
.book_box_image {
|
||||
width: 100%;
|
||||
height: 204rpx;
|
||||
}
|
||||
|
||||
.book_box_title {
|
||||
width: 100%;
|
||||
font-size: 32rpx;
|
||||
color: #1A1A1A;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
font-weight: 600;
|
||||
// line-height: 1;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.book_box_tips {
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
line-height: 1;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
12
config/index.js
Normal file
12
config/index.js
Normal file
@ -0,0 +1,12 @@
|
||||
// const baseUrl = 'https://console-mock.apipost.cn';
|
||||
|
||||
|
||||
// export default baseUrl;
|
||||
const config = {
|
||||
baseUrl: `https://qjnovelweb.qinjiuxiaoshuo.com`, /*, 根域名 */
|
||||
header: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded;'
|
||||
}
|
||||
}
|
||||
|
||||
export default config
|
20
index.html
Normal file
20
index.html
Normal file
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<script>
|
||||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||
CSS.supports('top: constant(a)'))
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||
</script>
|
||||
<title></title>
|
||||
<!--preload-links-->
|
||||
<!--app-context-->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"><!--app-html--></div>
|
||||
<script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
</html>
|
15
libs/config/config.js
Normal file
15
libs/config/config.js
Normal file
@ -0,0 +1,15 @@
|
||||
// 此版本发布于2022-04-19
|
||||
let version = '1.8.6';
|
||||
|
||||
export default {
|
||||
v: version,
|
||||
version: version,
|
||||
// 主题名称
|
||||
type: [
|
||||
'primary',
|
||||
'success',
|
||||
'info',
|
||||
'error',
|
||||
'warning'
|
||||
]
|
||||
}
|
20
libs/config/zIndex.js
Normal file
20
libs/config/zIndex.js
Normal file
@ -0,0 +1,20 @@
|
||||
// uniapp在H5中各API的z-index值如下:
|
||||
/**
|
||||
* actionsheet: 999
|
||||
* modal: 999
|
||||
* navigate: 998
|
||||
* tabbar: 998
|
||||
* toast: 999
|
||||
*/
|
||||
|
||||
export default {
|
||||
toast: 10090,
|
||||
noNetwork: 10080,
|
||||
// popup包含popup,actionsheet,keyboard,picker的值
|
||||
popup: 10075,
|
||||
mask: 10070,
|
||||
navbar: 980,
|
||||
topTips: 975,
|
||||
sticky: 970,
|
||||
indexListSticky: 965,
|
||||
}
|
155
libs/css/color.scss
Normal file
155
libs/css/color.scss
Normal file
@ -0,0 +1,155 @@
|
||||
.u-type-primary-light {
|
||||
color: $u-type-primary-light;
|
||||
}
|
||||
|
||||
.u-type-warning-light {
|
||||
color: $u-type-warning-light;
|
||||
}
|
||||
|
||||
.u-type-success-light {
|
||||
color: $u-type-success-light;
|
||||
}
|
||||
|
||||
.u-type-error-light {
|
||||
color: $u-type-error-light;
|
||||
}
|
||||
|
||||
.u-type-info-light {
|
||||
color: $u-type-info-light;
|
||||
}
|
||||
|
||||
.u-type-primary-light-bg {
|
||||
background-color: $u-type-primary-light;
|
||||
}
|
||||
|
||||
.u-type-warning-light-bg {
|
||||
background-color: $u-type-warning-light;
|
||||
}
|
||||
|
||||
.u-type-success-light-bg {
|
||||
background-color: $u-type-success-light;
|
||||
}
|
||||
|
||||
.u-type-error-light-bg {
|
||||
background-color: $u-type-error-light;
|
||||
}
|
||||
|
||||
.u-type-info-light-bg {
|
||||
background-color: $u-type-info-light;
|
||||
}
|
||||
|
||||
.u-type-primary-dark {
|
||||
color: $u-type-primary-dark;
|
||||
}
|
||||
|
||||
.u-type-warning-dark {
|
||||
color: $u-type-warning-dark;
|
||||
}
|
||||
|
||||
.u-type-success-dark {
|
||||
color: $u-type-success-dark;
|
||||
}
|
||||
|
||||
.u-type-error-dark {
|
||||
color: $u-type-error-dark;
|
||||
}
|
||||
|
||||
.u-type-info-dark {
|
||||
color: $u-type-info-dark;
|
||||
}
|
||||
|
||||
.u-type-primary-dark-bg {
|
||||
background-color: $u-type-primary-dark;
|
||||
}
|
||||
|
||||
.u-type-warning-dark-bg {
|
||||
background-color: $u-type-warning-dark;
|
||||
}
|
||||
|
||||
.u-type-success-dark-bg {
|
||||
background-color: $u-type-success-dark;
|
||||
}
|
||||
|
||||
.u-type-error-dark-bg {
|
||||
background-color: $u-type-error-dark;
|
||||
}
|
||||
|
||||
.u-type-info-dark-bg {
|
||||
background-color: $u-type-info-dark;
|
||||
}
|
||||
|
||||
.u-type-primary-disabled {
|
||||
color: $u-type-primary-disabled;
|
||||
}
|
||||
|
||||
.u-type-warning-disabled {
|
||||
color: $u-type-warning-disabled;
|
||||
}
|
||||
|
||||
.u-type-success-disabled {
|
||||
color: $u-type-success-disabled;
|
||||
}
|
||||
|
||||
.u-type-error-disabled {
|
||||
color: $u-type-error-disabled;
|
||||
}
|
||||
|
||||
.u-type-info-disabled {
|
||||
color: $u-type-info-disabled;
|
||||
}
|
||||
|
||||
.u-type-primary {
|
||||
color: $u-type-primary;
|
||||
}
|
||||
|
||||
.u-type-warning {
|
||||
color: $u-type-warning;
|
||||
}
|
||||
|
||||
.u-type-success {
|
||||
color: $u-type-success;
|
||||
}
|
||||
|
||||
.u-type-error {
|
||||
color: $u-type-error;
|
||||
}
|
||||
|
||||
.u-type-info {
|
||||
color: $u-type-info;
|
||||
}
|
||||
|
||||
.u-type-primary-bg {
|
||||
background-color: $u-type-primary;
|
||||
}
|
||||
|
||||
.u-type-warning-bg {
|
||||
background-color: $u-type-warning;
|
||||
}
|
||||
|
||||
.u-type-success-bg {
|
||||
background-color: $u-type-success;
|
||||
}
|
||||
|
||||
.u-type-error-bg {
|
||||
background-color: $u-type-error;
|
||||
}
|
||||
|
||||
.u-type-info-bg {
|
||||
background-color: $u-type-info;
|
||||
}
|
||||
|
||||
.u-main-color {
|
||||
color: $u-main-color;
|
||||
}
|
||||
|
||||
.u-content-color {
|
||||
color: $u-content-color;
|
||||
}
|
||||
|
||||
.u-tips-color {
|
||||
color: $u-tips-color;
|
||||
}
|
||||
|
||||
.u-light-color {
|
||||
color: $u-light-color;
|
||||
}
|
176
libs/css/common.scss
Normal file
176
libs/css/common.scss
Normal file
@ -0,0 +1,176 @@
|
||||
.u-relative,
|
||||
.u-rela {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.u-absolute,
|
||||
.u-abso {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
// nvue不能用标签命名样式,不能放在微信组件中,否则微信开发工具会报警告,无法使用标签名当做选择器
|
||||
/* #ifndef APP-NVUE */
|
||||
image {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
// 在weex,也即nvue中,所有元素默认为border-box
|
||||
view,
|
||||
text {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
.u-font-xs {
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.u-font-sm {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.u-font-md {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.u-font-lg {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.u-font-xl {
|
||||
font-size: 34rpx;
|
||||
}
|
||||
|
||||
.u-flex {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.u-flex-wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.u-flex-nowrap {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.u-col-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.u-col-top {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.u-col-bottom {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.u-row-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.u-row-left {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.u-row-right {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.u-row-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.u-row-around {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.u-text-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.u-text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.u-text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.u-flex-col {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
// 定义flex等分
|
||||
@for $i from 0 through 12 {
|
||||
.u-flex-#{$i} {
|
||||
flex: $i;
|
||||
}
|
||||
}
|
||||
|
||||
// 定义字体(px)单位,小于20都为px单位字体
|
||||
@for $i from 9 to 20 {
|
||||
.u-font-#{$i} {
|
||||
font-size: $i + px;
|
||||
}
|
||||
}
|
||||
|
||||
// 定义字体(rpx)单位,大于或等于20的都为rpx单位字体
|
||||
@for $i from 20 through 40 {
|
||||
.u-font-#{$i} {
|
||||
font-size: $i + rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 定义内外边距,历遍1-80
|
||||
@for $i from 0 through 80 {
|
||||
// 只要双数和能被5除尽的数
|
||||
@if $i % 2 == 0 or $i % 5 == 0 {
|
||||
// 得出:u-margin-30或者u-m-30
|
||||
.u-margin-#{$i}, .u-m-#{$i} {
|
||||
margin: $i + rpx!important;
|
||||
}
|
||||
|
||||
// 得出:u-padding-30或者u-p-30
|
||||
.u-padding-#{$i}, .u-p-#{$i} {
|
||||
padding: $i + rpx!important;
|
||||
}
|
||||
|
||||
@each $short, $long in l left, t top, r right, b bottom {
|
||||
// 缩写版,结果如: u-m-l-30
|
||||
// 定义外边距
|
||||
.u-m-#{$short}-#{$i} {
|
||||
margin-#{$long}: $i + rpx!important;
|
||||
}
|
||||
|
||||
// 定义内边距
|
||||
.u-p-#{$short}-#{$i} {
|
||||
padding-#{$long}: $i + rpx!important;
|
||||
}
|
||||
|
||||
// 完整版,结果如:u-margin-left-30
|
||||
// 定义外边距
|
||||
.u-margin-#{$long}-#{$i} {
|
||||
margin-#{$long}: $i + rpx!important;
|
||||
}
|
||||
|
||||
// 定义内边距
|
||||
.u-padding-#{$long}-#{$i} {
|
||||
padding-#{$long}: $i + rpx!important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 重置nvue的默认关于flex的样式
|
||||
.u-reset-nvue {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
7
libs/css/style.components.scss
Normal file
7
libs/css/style.components.scss
Normal file
@ -0,0 +1,7 @@
|
||||
// 定义混入指令,用于在非nvue环境下的flex定义,因为nvue没有display属性,会报错
|
||||
@mixin vue-flex($direction: row) {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
flex-direction: $direction;
|
||||
/* #endif */
|
||||
}
|
8
libs/css/style.h5.scss
Normal file
8
libs/css/style.h5.scss
Normal file
@ -0,0 +1,8 @@
|
||||
/* H5的时候,隐藏滚动条 */
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0 !important;
|
||||
height: 0 !important;
|
||||
-webkit-appearance: none;
|
||||
background: transparent;
|
||||
}
|
72
libs/css/style.mp.scss
Normal file
72
libs/css/style.mp.scss
Normal file
@ -0,0 +1,72 @@
|
||||
/* start--微信小程序编译后页面有组件名的元素,特别处理--start */
|
||||
/* #ifdef MP-WEIXIN || MP-QQ */
|
||||
u-td, u-th {
|
||||
flex: 1;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.u-td {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
u-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
// 各家小程序宫格组件外层设置为100%,避免受到父元素display: flex;的影响
|
||||
u-grid {
|
||||
width: 100%;
|
||||
flex: 0 0 100%;
|
||||
}
|
||||
|
||||
// 避免小程序线条组件因为父组件display: flex;而失效
|
||||
u-line {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
u-switch {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
u-dropdown {
|
||||
flex: 1;
|
||||
}
|
||||
/* #endif */
|
||||
/* end-微信小程序编译后页面有组件名的元素,特别处理--end */
|
||||
|
||||
|
||||
/* #ifdef MP-QQ || MP-TOUTIAO */
|
||||
// 需要做这一切额外的兼容,都是因为TX的无能
|
||||
u-icon {
|
||||
line-height: 0;
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
/* start--头条小程序编译后页面有组件名的元素,特别处理--start */
|
||||
// 由于头条小程序不支持直接组件名形式写样式,目前只能在写组件的时候给组件加上对应的类名
|
||||
/* #ifdef MP-TOUTIAO */
|
||||
.u-td, .u-th, .u-tr {
|
||||
flex: 1;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.u-row, .u-col {
|
||||
flex: 1;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
// 避免小程序线条组件因为父组件display: flex;而失效
|
||||
.u-line {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.u-dropdown {
|
||||
flex: 1;
|
||||
}
|
||||
/* #endif */
|
||||
/* end-头条小程序编译后页面有组件名的元素,特别处理--end */
|
||||
|
||||
|
||||
|
3
libs/css/style.nvue.scss
Normal file
3
libs/css/style.nvue.scss
Normal file
@ -0,0 +1,3 @@
|
||||
.nvue {
|
||||
font-size: 24rpx;
|
||||
}
|
175
libs/css/style.vue.scss
Normal file
175
libs/css/style.vue.scss
Normal file
@ -0,0 +1,175 @@
|
||||
page {
|
||||
color: $u-main-color;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
/* start--去除webkit的默认样式--start */
|
||||
.u-fix-ios-appearance {
|
||||
-webkit-appearance:none;
|
||||
}
|
||||
/* end--去除webkit的默认样式--end */
|
||||
|
||||
/* start--icon图标外层套一个view,让其达到更好的垂直居中的效果--start */
|
||||
.u-icon-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
/* end-icon图标外层套一个view,让其达到更好的垂直居中的效果--end */
|
||||
|
||||
/* start--iPhoneX底部安全区定义--start */
|
||||
.safe-area-inset-bottom {
|
||||
padding-bottom: 0;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
/* end-iPhoneX底部安全区定义--end */
|
||||
|
||||
/* start--各种hover点击反馈相关的类名-start */
|
||||
.u-hover-class {
|
||||
// background-color: #f7f8f9!important;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.u-cell-hover {
|
||||
background-color: #f7f8f9!important;
|
||||
}
|
||||
/* end--各种hover点击反馈相关的类名--end */
|
||||
|
||||
/* start--文本行数限制--start */
|
||||
.u-line-1 {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.u-line-2 {
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
|
||||
.u-line-3 {
|
||||
-webkit-line-clamp: 3;
|
||||
}
|
||||
|
||||
.u-line-4 {
|
||||
-webkit-line-clamp: 4;
|
||||
}
|
||||
|
||||
.u-line-5 {
|
||||
-webkit-line-clamp: 5;
|
||||
}
|
||||
|
||||
.u-line-2, .u-line-3, .u-line-4, .u-line-5 {
|
||||
overflow: hidden;
|
||||
word-break: break-all;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box; // 弹性伸缩盒
|
||||
-webkit-box-orient: vertical; // 设置伸缩盒子元素排列方式
|
||||
}
|
||||
|
||||
/* end--文本行数限制--end */
|
||||
|
||||
|
||||
/* start--Retina 屏幕下的 1px 边框--start */
|
||||
.u-border,
|
||||
.u-border-bottom,
|
||||
.u-border-left,
|
||||
.u-border-right,
|
||||
.u-border-top,
|
||||
.u-border-top-bottom {
|
||||
position: relative
|
||||
}
|
||||
|
||||
.u-border-bottom:after,
|
||||
.u-border-left:after,
|
||||
.u-border-right:after,
|
||||
.u-border-top-bottom:after,
|
||||
.u-border-top:after,
|
||||
.u-border:after {
|
||||
/* #ifndef APP-NVUE */
|
||||
content: ' ';
|
||||
/* #endif */
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
pointer-events: none;
|
||||
box-sizing: border-box;
|
||||
-webkit-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
// 多加0.1%,能解决有时候边框缺失的问题
|
||||
width: 199.8%;
|
||||
height: 199.7%;
|
||||
transform: scale(0.5, 0.5);
|
||||
border: 0 solid $u-border-color;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.u-border-top:after {
|
||||
border-top-width: 1px
|
||||
}
|
||||
|
||||
.u-border-left:after {
|
||||
border-left-width: 1px
|
||||
}
|
||||
|
||||
.u-border-right:after {
|
||||
border-right-width: 1px
|
||||
}
|
||||
|
||||
.u-border-bottom:after {
|
||||
border-bottom-width: 1px
|
||||
}
|
||||
|
||||
.u-border-top-bottom:after {
|
||||
border-width: 1px 0
|
||||
}
|
||||
|
||||
.u-border:after {
|
||||
border-width: 1px
|
||||
}
|
||||
/* end--Retina 屏幕下的 1px 边框--end */
|
||||
|
||||
|
||||
/* start--clearfix--start */
|
||||
.u-clearfix:after,
|
||||
.clearfix:after {
|
||||
/* #ifndef APP-NVUE */
|
||||
content: '';
|
||||
/* #endif */
|
||||
display: table;
|
||||
clear: both
|
||||
}
|
||||
/* end--clearfix--end */
|
||||
|
||||
/* start--高斯模糊tabbar底部处理--start */
|
||||
.u-blur-effect-inset {
|
||||
width: 750rpx;
|
||||
height: var(--window-bottom);
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
/* end--高斯模糊tabbar底部处理--end */
|
||||
|
||||
/* start--提升H5端uni.toast()的层级,避免被uView的modal等遮盖--start */
|
||||
/* #ifdef H5 */
|
||||
uni-toast {
|
||||
z-index: 10090;
|
||||
}
|
||||
uni-toast .uni-toast {
|
||||
z-index: 10090;
|
||||
}
|
||||
/* #endif */
|
||||
/* end--提升H5端uni.toast()的层级,避免被uView的modal等遮盖--end */
|
||||
|
||||
/* start--去除button的所有默认样式--start */
|
||||
.u-reset-button {
|
||||
padding: 0;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
background-color: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.u-reset-button::after {
|
||||
border: none;
|
||||
}
|
||||
/* end--去除button的所有默认样式--end */
|
||||
|
18
libs/function/$parent.js
Normal file
18
libs/function/$parent.js
Normal file
@ -0,0 +1,18 @@
|
||||
// 获取父组件的参数,因为支付宝小程序不支持provide/inject的写法
|
||||
// this.$parent在非H5中,可以准确获取到父组件,但是在H5中,需要多次this.$parent.$parent.xxx
|
||||
// 这里默认值等于undefined有它的含义,因为最顶层元素(组件)的$parent就是undefined,意味着不传name
|
||||
// 值(默认为undefined),就是查找最顶层的$parent
|
||||
export default function $parent(name = undefined) {
|
||||
let parent = this.$parent;
|
||||
// 通过while历遍,这里主要是为了H5需要多层解析的问题
|
||||
while (parent) {
|
||||
// 父组件
|
||||
if (parent.$options && parent.$options.name !== name) {
|
||||
// 如果组件的name不相等,继续上一级寻找
|
||||
parent = parent.$parent;
|
||||
} else {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
8
libs/function/addUnit.js
Normal file
8
libs/function/addUnit.js
Normal file
@ -0,0 +1,8 @@
|
||||
import validation from './test.js';
|
||||
|
||||
// 添加单位,如果有rpx,%,px等单位结尾或者值为auto,直接返回,否则加上rpx单位结尾
|
||||
export default function addUnit(value = 'auto', unit = 'rpx') {
|
||||
value = String(value);
|
||||
// 用uView内置验证规则中的number判断是否为数值
|
||||
return validation.number(value) ? `${value}${unit}` : value;
|
||||
}
|
5
libs/function/bem.js
Normal file
5
libs/function/bem.js
Normal file
@ -0,0 +1,5 @@
|
||||
function bem(name, conf) {
|
||||
|
||||
}
|
||||
|
||||
module.exports.bem = bem;
|
37
libs/function/color.js
Normal file
37
libs/function/color.js
Normal file
@ -0,0 +1,37 @@
|
||||
// 为了让用户能够自定义主题,会逐步弃用此文件,各颜色通过css提供
|
||||
// 为了给某些特殊场景使用和向后兼容,无需删除此文件(2020-06-20)
|
||||
let color = {
|
||||
primary: "#2979ff",
|
||||
primaryDark: "#2b85e4",
|
||||
primaryDisabled: "#a0cfff",
|
||||
primaryLight: "#ecf5ff",
|
||||
bgColor: "#f3f4f6",
|
||||
|
||||
info: "#909399",
|
||||
infoDark: "#82848a",
|
||||
infoDisabled: "#c8c9cc",
|
||||
infoLight: "#f4f4f5",
|
||||
|
||||
warning: "#ff9900",
|
||||
warningDark: "#f29100",
|
||||
warningDisabled: "#fcbd71",
|
||||
warningLight: "#fdf6ec",
|
||||
|
||||
error: "#fa3534",
|
||||
errorDark: "#dd6161",
|
||||
errorDisabled: "#fab6b6",
|
||||
errorLight: "#fef0f0",
|
||||
|
||||
success: "#19be6b",
|
||||
successDark: "#18b566",
|
||||
successDisabled: "#71d5a1",
|
||||
successLight: "#dbf1e1",
|
||||
|
||||
mainColor: "#303133",
|
||||
contentColor: "#606266",
|
||||
tipsColor: "#909399",
|
||||
lightColor: "#c0c4cc",
|
||||
borderColor: "#e4e7ed"
|
||||
}
|
||||
|
||||
export default color;
|
134
libs/function/colorGradient.js
Normal file
134
libs/function/colorGradient.js
Normal file
@ -0,0 +1,134 @@
|
||||
/**
|
||||
* 求两个颜色之间的渐变值
|
||||
* @param {string} startColor 开始的颜色
|
||||
* @param {string} endColor 结束的颜色
|
||||
* @param {number} step 颜色等分的份额
|
||||
* */
|
||||
function colorGradient(startColor = 'rgb(0, 0, 0)', endColor = 'rgb(255, 255, 255)', step = 10) {
|
||||
let startRGB = hexToRgb(startColor, false); //转换为rgb数组模式
|
||||
let startR = startRGB[0];
|
||||
let startG = startRGB[1];
|
||||
let startB = startRGB[2];
|
||||
|
||||
let endRGB = hexToRgb(endColor, false);
|
||||
let endR = endRGB[0];
|
||||
let endG = endRGB[1];
|
||||
let endB = endRGB[2];
|
||||
|
||||
let sR = (endR - startR) / step; //总差值
|
||||
let sG = (endG - startG) / step;
|
||||
let sB = (endB - startB) / step;
|
||||
let colorArr = [];
|
||||
for (let i = 0; i < step; i++) {
|
||||
//计算每一步的hex值
|
||||
let hex = rgbToHex('rgb(' + Math.round((sR * i + startR)) + ',' + Math.round((sG * i + startG)) + ',' + Math.round((sB *
|
||||
i + startB)) + ')');
|
||||
colorArr.push(hex);
|
||||
}
|
||||
return colorArr;
|
||||
}
|
||||
|
||||
// 将hex表示方式转换为rgb表示方式(这里返回rgb数组模式)
|
||||
function hexToRgb(sColor, str = true) {
|
||||
let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
|
||||
sColor = sColor.toLowerCase();
|
||||
if (sColor && reg.test(sColor)) {
|
||||
if (sColor.length === 4) {
|
||||
let sColorNew = "#";
|
||||
for (let i = 1; i < 4; i += 1) {
|
||||
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
|
||||
}
|
||||
sColor = sColorNew;
|
||||
}
|
||||
//处理六位的颜色值
|
||||
let sColorChange = [];
|
||||
for (let i = 1; i < 7; i += 2) {
|
||||
sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));
|
||||
}
|
||||
if(!str) {
|
||||
return sColorChange;
|
||||
} else {
|
||||
return `rgb(${sColorChange[0]},${sColorChange[1]},${sColorChange[2]})`;
|
||||
}
|
||||
} else if (/^(rgb|RGB)/.test(sColor)) {
|
||||
let arr = sColor.replace(/(?:\(|\)|rgb|RGB)*/g, "").split(",")
|
||||
return arr.map(val => Number(val));
|
||||
} else {
|
||||
return sColor;
|
||||
}
|
||||
};
|
||||
|
||||
// 将rgb表示方式转换为hex表示方式
|
||||
function rgbToHex(rgb) {
|
||||
let _this = rgb;
|
||||
let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
|
||||
if (/^(rgb|RGB)/.test(_this)) {
|
||||
let aColor = _this.replace(/(?:\(|\)|rgb|RGB)*/g, "").split(",");
|
||||
let strHex = "#";
|
||||
for (let i = 0; i < aColor.length; i++) {
|
||||
let hex = Number(aColor[i]).toString(16);
|
||||
hex = String(hex).length == 1 ? 0 + '' + hex : hex; // 保证每个rgb的值为2位
|
||||
if (hex === "0") {
|
||||
hex += hex;
|
||||
}
|
||||
strHex += hex;
|
||||
}
|
||||
if (strHex.length !== 7) {
|
||||
strHex = _this;
|
||||
}
|
||||
return strHex;
|
||||
} else if (reg.test(_this)) {
|
||||
let aNum = _this.replace(/#/, "").split("");
|
||||
if (aNum.length === 6) {
|
||||
return _this;
|
||||
} else if (aNum.length === 3) {
|
||||
let numHex = "#";
|
||||
for (let i = 0; i < aNum.length; i += 1) {
|
||||
numHex += (aNum[i] + aNum[i]);
|
||||
}
|
||||
return numHex;
|
||||
}
|
||||
} else {
|
||||
return _this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* JS颜色十六进制转换为rgb或rgba,返回的格式为 rgba(255,255,255,0.5)字符串
|
||||
* sHex为传入的十六进制的色值
|
||||
* alpha为rgba的透明度
|
||||
*/
|
||||
function colorToRgba(color, alpha = 0.3) {
|
||||
color = rgbToHex(color)
|
||||
// 十六进制颜色值的正则表达式
|
||||
var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
|
||||
/* 16进制颜色转为RGB格式 */
|
||||
let sColor = color.toLowerCase()
|
||||
if (sColor && reg.test(sColor)) {
|
||||
if (sColor.length === 4) {
|
||||
var sColorNew = '#'
|
||||
for (let i = 1; i < 4; i += 1) {
|
||||
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
|
||||
}
|
||||
sColor = sColorNew
|
||||
}
|
||||
// 处理六位的颜色值
|
||||
var sColorChange = []
|
||||
for (let i = 1; i < 7; i += 2) {
|
||||
sColorChange.push(parseInt('0x' + sColor.slice(i, i + 2)))
|
||||
}
|
||||
// return sColorChange.join(',')
|
||||
return 'rgba(' + sColorChange.join(',') + ',' + alpha + ')'
|
||||
}
|
||||
else {
|
||||
return sColor
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
colorGradient,
|
||||
hexToRgb,
|
||||
rgbToHex,
|
||||
colorToRgba
|
||||
}
|
29
libs/function/debounce.js
Normal file
29
libs/function/debounce.js
Normal file
@ -0,0 +1,29 @@
|
||||
let timeout = null;
|
||||
|
||||
/**
|
||||
* 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
|
||||
*
|
||||
* @param {Function} func 要执行的回调函数
|
||||
* @param {Number} wait 延时的时间
|
||||
* @param {Boolean} immediate 是否立即执行
|
||||
* @return null
|
||||
*/
|
||||
function debounce(func, wait = 500, immediate = false) {
|
||||
// 清除定时器
|
||||
if (timeout !== null) clearTimeout(timeout);
|
||||
// 立即执行,此类情况一般用不到
|
||||
if (immediate) {
|
||||
var callNow = !timeout;
|
||||
timeout = setTimeout(function() {
|
||||
timeout = null;
|
||||
}, wait);
|
||||
if (callNow) typeof func === 'function' && func();
|
||||
} else {
|
||||
// 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
|
||||
timeout = setTimeout(function() {
|
||||
typeof func === 'function' && func();
|
||||
}, wait);
|
||||
}
|
||||
}
|
||||
|
||||
export default debounce
|
23
libs/function/deepClone.js
Normal file
23
libs/function/deepClone.js
Normal file
@ -0,0 +1,23 @@
|
||||
// 判断arr是否为一个数组,返回一个bool值
|
||||
function isArray (arr) {
|
||||
return Object.prototype.toString.call(arr) === '[object Array]';
|
||||
}
|
||||
|
||||
// 深度克隆
|
||||
function deepClone (obj) {
|
||||
// 对常见的“非”值,直接返回原来值
|
||||
if([null, undefined, NaN, false].includes(obj)) return obj;
|
||||
if(typeof obj !== "object" && typeof obj !== 'function') {
|
||||
//原始类型直接返回
|
||||
return obj;
|
||||
}
|
||||
var o = isArray(obj) ? [] : {};
|
||||
for(let i in obj) {
|
||||
if(obj.hasOwnProperty(i)){
|
||||
o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i];
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
export default deepClone;
|
30
libs/function/deepMerge.js
Normal file
30
libs/function/deepMerge.js
Normal file
@ -0,0 +1,30 @@
|
||||
import deepClone from "./deepClone";
|
||||
|
||||
// JS对象深度合并
|
||||
function deepMerge(target = {}, source = {}) {
|
||||
target = deepClone(target);
|
||||
if (typeof target !== 'object' || typeof source !== 'object') return false;
|
||||
for (var prop in source) {
|
||||
if (!source.hasOwnProperty(prop)) continue;
|
||||
if (prop in target) {
|
||||
if (typeof target[prop] !== 'object') {
|
||||
target[prop] = source[prop];
|
||||
} else {
|
||||
if (typeof source[prop] !== 'object') {
|
||||
target[prop] = source[prop];
|
||||
} else {
|
||||
if (target[prop].concat && source[prop].concat) {
|
||||
target[prop] = target[prop].concat(source[prop]);
|
||||
} else {
|
||||
target[prop] = deepMerge(target[prop], source[prop]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
target[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
export default deepMerge;
|
47
libs/function/getParent.js
Normal file
47
libs/function/getParent.js
Normal file
@ -0,0 +1,47 @@
|
||||
// 获取父组件的参数,因为支付宝小程序不支持provide/inject的写法
|
||||
// this.$parent在非H5中,可以准确获取到父组件,但是在H5中,需要多次this.$parent.$parent.xxx
|
||||
export default function getParent(name, keys) {
|
||||
let parent = this.$parent;
|
||||
// 通过while历遍,这里主要是为了H5需要多层解析的问题
|
||||
while (parent) {
|
||||
// 父组件
|
||||
if (parent.$options.name !== name) {
|
||||
// 如果组件的name不相等,继续上一级寻找
|
||||
parent = parent.$parent;
|
||||
} else {
|
||||
let data = {};
|
||||
// 判断keys是否数组,如果传过来的是一个数组,那么直接使用数组元素值当做键值去父组件寻找
|
||||
if(Array.isArray(keys)) {
|
||||
keys.map(val => {
|
||||
data[val] = parent[val] ? parent[val] : '';
|
||||
})
|
||||
} else {
|
||||
// 历遍传过来的对象参数
|
||||
for(let i in keys) {
|
||||
// 如果子组件有此值则用,无此值则用父组件的值
|
||||
// 判断是否空数组,如果是,则用父组件的值,否则用子组件的值
|
||||
if(Array.isArray(keys[i])) {
|
||||
if(keys[i].length) {
|
||||
data[i] = keys[i];
|
||||
} else {
|
||||
data[i] = parent[i];
|
||||
}
|
||||
} else if(keys[i].constructor === Object) {
|
||||
// 判断是否对象,如果是对象,且有属性,那么使用子组件的值,否则使用父组件的值
|
||||
if(Object.keys(keys[i]).length) {
|
||||
data[i] = keys[i];
|
||||
} else {
|
||||
data[i] = parent[i];
|
||||
}
|
||||
} else {
|
||||
// 只要子组件有传值,即使是false值,也是“传值”了,也需要覆盖父组件的同名参数
|
||||
data[i] = (keys[i] || keys[i] === false) ? keys[i] : parent[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
41
libs/function/guid.js
Normal file
41
libs/function/guid.js
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 本算法来源于简书开源代码,详见:https://www.jianshu.com/p/fdbf293d0a85
|
||||
* 全局唯一标识符(uuid,Globally Unique Identifier),也称作 uuid(Universally Unique IDentifier)
|
||||
* 一般用于多个组件之间,给它一个唯一的标识符,或者v-for循环的时候,如果使用数组的index可能会导致更新列表出现问题
|
||||
* 最可能的情况是左滑删除item或者对某条信息流"不喜欢"并去掉它的时候,会导致组件内的数据可能出现错乱
|
||||
* v-for的时候,推荐使用后端返回的id而不是循环的index
|
||||
* @param {Number} len uuid的长度
|
||||
* @param {Boolean} firstU 将返回的首字母置为"u"
|
||||
* @param {Number} radix 生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制
|
||||
*/
|
||||
function guid(len = 32, firstU = true, radix = null) {
|
||||
let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
|
||||
let uuid = [];
|
||||
radix = radix || chars.length;
|
||||
|
||||
if (len) {
|
||||
// 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位
|
||||
for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
|
||||
} else {
|
||||
let r;
|
||||
// rfc4122标准要求返回的uuid中,某些位为固定的字符
|
||||
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
|
||||
uuid[14] = '4';
|
||||
|
||||
for (let i = 0; i < 36; i++) {
|
||||
if (!uuid[i]) {
|
||||
r = 0 | Math.random() * 16;
|
||||
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
|
||||
}
|
||||
}
|
||||
}
|
||||
// 移除第一个字符,并用u替代,因为第一个字符为数值时,该guid不能用作id或者class
|
||||
if (firstU) {
|
||||
uuid.shift();
|
||||
return 'u' + uuid.join('');
|
||||
} else {
|
||||
return uuid.join('');
|
||||
}
|
||||
}
|
||||
|
||||
export default guid;
|
385
libs/function/md5.js
Normal file
385
libs/function/md5.js
Normal file
@ -0,0 +1,385 @@
|
||||
/*
|
||||
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
|
||||
* Digest Algorithm, as defined in RFC 1321.
|
||||
* Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
|
||||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||||
* Distributed under the BSD License
|
||||
* See http://pajhome.org.uk/crypt/md5 for more info.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Configurable variables. You may need to tweak these to be compatible with
|
||||
* the server-side, but the defaults work in most cases.
|
||||
*/
|
||||
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
|
||||
var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
|
||||
|
||||
/*
|
||||
* These are the functions you'll usually want to call
|
||||
* They take string arguments and return either hex or base-64 encoded strings
|
||||
*/
|
||||
function hex_md5(s) { return rstr2hex(rstr_md5(str2rstr_utf8(s))); }
|
||||
function b64_md5(s) { return rstr2b64(rstr_md5(str2rstr_utf8(s))); }
|
||||
function any_md5(s, e) { return rstr2any(rstr_md5(str2rstr_utf8(s)), e); }
|
||||
function hex_hmac_md5(k, d)
|
||||
{ return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
|
||||
function b64_hmac_md5(k, d)
|
||||
{ return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
|
||||
function any_hmac_md5(k, d, e)
|
||||
{ return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
|
||||
|
||||
/*
|
||||
* Perform a simple self-test to see if the VM is working
|
||||
*/
|
||||
function md5_vm_test()
|
||||
{
|
||||
return hex_md5("abc").toLowerCase() == "900150983cd24fb0d6963f7d28e17f72";
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the MD5 of a raw string
|
||||
*/
|
||||
function rstr_md5(s)
|
||||
{
|
||||
return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the HMAC-MD5, of a key and some data (raw strings)
|
||||
*/
|
||||
function rstr_hmac_md5(key, data)
|
||||
{
|
||||
var bkey = rstr2binl(key);
|
||||
if(bkey.length > 16) bkey = binl_md5(bkey, key.length * 8);
|
||||
|
||||
var ipad = Array(16), opad = Array(16);
|
||||
for(var i = 0; i < 16; i++)
|
||||
{
|
||||
ipad[i] = bkey[i] ^ 0x36363636;
|
||||
opad[i] = bkey[i] ^ 0x5C5C5C5C;
|
||||
}
|
||||
|
||||
var hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
|
||||
return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a raw string to a hex string
|
||||
*/
|
||||
function rstr2hex(input)
|
||||
{
|
||||
try { hexcase } catch(e) { hexcase=0; }
|
||||
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
|
||||
var output = "";
|
||||
var x;
|
||||
for(var i = 0; i < input.length; i++)
|
||||
{
|
||||
x = input.charCodeAt(i);
|
||||
output += hex_tab.charAt((x >>> 4) & 0x0F)
|
||||
+ hex_tab.charAt( x & 0x0F);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a raw string to a base-64 string
|
||||
*/
|
||||
function rstr2b64(input)
|
||||
{
|
||||
try { b64pad } catch(e) { b64pad=''; }
|
||||
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
var output = "";
|
||||
var len = input.length;
|
||||
for(var i = 0; i < len; i += 3)
|
||||
{
|
||||
var triplet = (input.charCodeAt(i) << 16)
|
||||
| (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
|
||||
| (i + 2 < len ? input.charCodeAt(i+2) : 0);
|
||||
for(var j = 0; j < 4; j++)
|
||||
{
|
||||
if(i * 8 + j * 6 > input.length * 8) output += b64pad;
|
||||
else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a raw string to an arbitrary string encoding
|
||||
*/
|
||||
function rstr2any(input, encoding)
|
||||
{
|
||||
var divisor = encoding.length;
|
||||
var i, j, q, x, quotient;
|
||||
|
||||
/* Convert to an array of 16-bit big-endian values, forming the dividend */
|
||||
var dividend = Array(Math.ceil(input.length / 2));
|
||||
for(i = 0; i < dividend.length; i++)
|
||||
{
|
||||
dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Repeatedly perform a long division. The binary array forms the dividend,
|
||||
* the length of the encoding is the divisor. Once computed, the quotient
|
||||
* forms the dividend for the next step. All remainders are stored for later
|
||||
* use.
|
||||
*/
|
||||
var full_length = Math.ceil(input.length * 8 /
|
||||
(Math.log(encoding.length) / Math.log(2)));
|
||||
var remainders = Array(full_length);
|
||||
for(j = 0; j < full_length; j++)
|
||||
{
|
||||
quotient = Array();
|
||||
x = 0;
|
||||
for(i = 0; i < dividend.length; i++)
|
||||
{
|
||||
x = (x << 16) + dividend[i];
|
||||
q = Math.floor(x / divisor);
|
||||
x -= q * divisor;
|
||||
if(quotient.length > 0 || q > 0)
|
||||
quotient[quotient.length] = q;
|
||||
}
|
||||
remainders[j] = x;
|
||||
dividend = quotient;
|
||||
}
|
||||
|
||||
/* Convert the remainders to the output string */
|
||||
var output = "";
|
||||
for(i = remainders.length - 1; i >= 0; i--)
|
||||
output += encoding.charAt(remainders[i]);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode a string as utf-8.
|
||||
* For efficiency, this assumes the input is valid utf-16.
|
||||
*/
|
||||
function str2rstr_utf8(input)
|
||||
{
|
||||
var output = "";
|
||||
var i = -1;
|
||||
var x, y;
|
||||
|
||||
while(++i < input.length)
|
||||
{
|
||||
/* Decode utf-16 surrogate pairs */
|
||||
x = input.charCodeAt(i);
|
||||
y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
|
||||
if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
|
||||
{
|
||||
x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Encode output as utf-8 */
|
||||
if(x <= 0x7F)
|
||||
output += String.fromCharCode(x);
|
||||
else if(x <= 0x7FF)
|
||||
output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
|
||||
0x80 | ( x & 0x3F));
|
||||
else if(x <= 0xFFFF)
|
||||
output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
|
||||
0x80 | ((x >>> 6 ) & 0x3F),
|
||||
0x80 | ( x & 0x3F));
|
||||
else if(x <= 0x1FFFFF)
|
||||
output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
|
||||
0x80 | ((x >>> 12) & 0x3F),
|
||||
0x80 | ((x >>> 6 ) & 0x3F),
|
||||
0x80 | ( x & 0x3F));
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode a string as utf-16
|
||||
*/
|
||||
function str2rstr_utf16le(input)
|
||||
{
|
||||
var output = "";
|
||||
for(var i = 0; i < input.length; i++)
|
||||
output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
|
||||
(input.charCodeAt(i) >>> 8) & 0xFF);
|
||||
return output;
|
||||
}
|
||||
|
||||
function str2rstr_utf16be(input)
|
||||
{
|
||||
var output = "";
|
||||
for(var i = 0; i < input.length; i++)
|
||||
output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
|
||||
input.charCodeAt(i) & 0xFF);
|
||||
return output;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a raw string to an array of little-endian words
|
||||
* Characters >255 have their high-byte silently ignored.
|
||||
*/
|
||||
function rstr2binl(input)
|
||||
{
|
||||
var output = Array(input.length >> 2);
|
||||
for(var i = 0; i < output.length; i++)
|
||||
output[i] = 0;
|
||||
for(var i = 0; i < input.length * 8; i += 8)
|
||||
output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32);
|
||||
return output;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an array of little-endian words to a string
|
||||
*/
|
||||
function binl2rstr(input)
|
||||
{
|
||||
var output = "";
|
||||
for(var i = 0; i < input.length * 32; i += 8)
|
||||
output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
|
||||
return output;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the MD5 of an array of little-endian words, and a bit length.
|
||||
*/
|
||||
function binl_md5(x, len)
|
||||
{
|
||||
/* append padding */
|
||||
x[len >> 5] |= 0x80 << ((len) % 32);
|
||||
x[(((len + 64) >>> 9) << 4) + 14] = len;
|
||||
|
||||
var a = 1732584193;
|
||||
var b = -271733879;
|
||||
var c = -1732584194;
|
||||
var d = 271733878;
|
||||
|
||||
for(var i = 0; i < x.length; i += 16)
|
||||
{
|
||||
var olda = a;
|
||||
var oldb = b;
|
||||
var oldc = c;
|
||||
var oldd = d;
|
||||
|
||||
a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
|
||||
d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
|
||||
c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
|
||||
b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
|
||||
a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
|
||||
d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
|
||||
c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
|
||||
b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
|
||||
a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
|
||||
d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
|
||||
c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
|
||||
b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
|
||||
a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
|
||||
d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
|
||||
c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
|
||||
b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
|
||||
|
||||
a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
|
||||
d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
|
||||
c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
|
||||
b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
|
||||
a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
|
||||
d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
|
||||
c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
|
||||
b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
|
||||
a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
|
||||
d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
|
||||
c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
|
||||
b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
|
||||
a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
|
||||
d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
|
||||
c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
|
||||
b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
|
||||
|
||||
a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
|
||||
d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
|
||||
c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
|
||||
b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
|
||||
a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
|
||||
d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
|
||||
c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
|
||||
b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
|
||||
a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
|
||||
d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
|
||||
c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
|
||||
b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
|
||||
a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
|
||||
d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
|
||||
c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
|
||||
b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
|
||||
|
||||
a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
|
||||
d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
|
||||
c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
|
||||
b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
|
||||
a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
|
||||
d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
|
||||
c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
|
||||
b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
|
||||
a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
|
||||
d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
|
||||
c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
|
||||
b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
|
||||
a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
|
||||
d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
|
||||
c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
|
||||
b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
|
||||
|
||||
a = safe_add(a, olda);
|
||||
b = safe_add(b, oldb);
|
||||
c = safe_add(c, oldc);
|
||||
d = safe_add(d, oldd);
|
||||
}
|
||||
return Array(a, b, c, d);
|
||||
}
|
||||
|
||||
/*
|
||||
* These functions implement the four basic operations the algorithm uses.
|
||||
*/
|
||||
function md5_cmn(q, a, b, x, s, t)
|
||||
{
|
||||
return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
|
||||
}
|
||||
function md5_ff(a, b, c, d, x, s, t)
|
||||
{
|
||||
return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
|
||||
}
|
||||
function md5_gg(a, b, c, d, x, s, t)
|
||||
{
|
||||
return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
|
||||
}
|
||||
function md5_hh(a, b, c, d, x, s, t)
|
||||
{
|
||||
return md5_cmn(b ^ c ^ d, a, b, x, s, t);
|
||||
}
|
||||
function md5_ii(a, b, c, d, x, s, t)
|
||||
{
|
||||
return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
|
||||
* to work around bugs in some JS interpreters.
|
||||
*/
|
||||
function safe_add(x, y)
|
||||
{
|
||||
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
|
||||
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
||||
return (msw << 16) | (lsw & 0xFFFF);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitwise rotate a 32-bit number to the left.
|
||||
*/
|
||||
function bit_rol(num, cnt)
|
||||
{
|
||||
return (num << cnt) | (num >>> (32 - cnt));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
md5 : function(str){
|
||||
return hex_md5(str);
|
||||
}
|
||||
}
|
58
libs/function/queryParams.js
Normal file
58
libs/function/queryParams.js
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 对象转url参数
|
||||
* @param {*} data,对象
|
||||
* @param {*} isPrefix,是否自动加上"?"
|
||||
*/
|
||||
function queryParams(data = {}, isPrefix = true, arrayFormat = 'brackets') {
|
||||
let prefix = isPrefix ? '?' : ''
|
||||
let _result = []
|
||||
if (['indices', 'brackets', 'repeat', 'comma'].indexOf(arrayFormat) == -1) arrayFormat = 'brackets';
|
||||
for (let key in data) {
|
||||
let value = data[key]
|
||||
// 去掉为空的参数
|
||||
if (['', undefined, null].indexOf(value) >= 0) {
|
||||
continue;
|
||||
}
|
||||
// 如果值为数组,另行处理
|
||||
if (value.constructor === Array) {
|
||||
// e.g. {ids: [1, 2, 3]}
|
||||
switch (arrayFormat) {
|
||||
case 'indices':
|
||||
// 结果: ids[0]=1&ids[1]=2&ids[2]=3
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
_result.push(key + '[' + i + ']=' + value[i])
|
||||
}
|
||||
break;
|
||||
case 'brackets':
|
||||
// 结果: ids[]=1&ids[]=2&ids[]=3
|
||||
value.forEach(_value => {
|
||||
_result.push(key + '[]=' + _value)
|
||||
})
|
||||
break;
|
||||
case 'repeat':
|
||||
// 结果: ids=1&ids=2&ids=3
|
||||
value.forEach(_value => {
|
||||
_result.push(key + '=' + _value)
|
||||
})
|
||||
break;
|
||||
case 'comma':
|
||||
// 结果: ids=1,2,3
|
||||
let commaStr = "";
|
||||
value.forEach(_value => {
|
||||
commaStr += (commaStr ? "," : "") + _value;
|
||||
})
|
||||
_result.push(key + '=' + commaStr)
|
||||
break;
|
||||
default:
|
||||
value.forEach(_value => {
|
||||
_result.push(key + '[]=' + _value)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
_result.push(key + '=' + value)
|
||||
}
|
||||
}
|
||||
return _result.length ? prefix + _result.join('&') : ''
|
||||
}
|
||||
|
||||
export default queryParams;
|
10
libs/function/random.js
Normal file
10
libs/function/random.js
Normal file
@ -0,0 +1,10 @@
|
||||
function random(min, max) {
|
||||
if (min >= 0 && max > 0 && max >= min) {
|
||||
let gab = max - min + 1;
|
||||
return Math.floor(Math.random() * gab + min);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
export default random;
|
7
libs/function/randomArray.js
Normal file
7
libs/function/randomArray.js
Normal file
@ -0,0 +1,7 @@
|
||||
// 打乱数组
|
||||
function randomArray(array = []) {
|
||||
// 原理是sort排序,Math.random()产生0<= x < 1之间的数,会导致x-0.05大于或者小于0
|
||||
return array.sort(() => Math.random() - 0.5);
|
||||
}
|
||||
|
||||
export default randomArray
|
122
libs/function/route.js
Normal file
122
libs/function/route.js
Normal file
@ -0,0 +1,122 @@
|
||||
/**
|
||||
* 路由跳转方法,该方法相对于直接使用uni.xxx的好处是使用更加简单快捷
|
||||
* 并且带有路由拦截功能
|
||||
*/
|
||||
|
||||
class Router {
|
||||
constructor() {
|
||||
// 原始属性定义
|
||||
this.config = {
|
||||
type: 'navigateTo',
|
||||
url: '',
|
||||
delta: 1, // navigateBack页面后退时,回退的层数
|
||||
params: {}, // 传递的参数
|
||||
animationType: 'pop-in', // 窗口动画,只在APP有效
|
||||
animationDuration: 300, // 窗口动画持续时间,单位毫秒,只在APP有效
|
||||
intercept: false, // 是否需要拦截
|
||||
}
|
||||
// 因为route方法是需要对外赋值给另外的对象使用,同时route内部有使用this,会导致route失去上下文
|
||||
// 这里在构造函数中进行this绑定
|
||||
this.route = this.route.bind(this)
|
||||
}
|
||||
|
||||
// 判断url前面是否有"/",如果没有则加上,否则无法跳转
|
||||
addRootPath(url) {
|
||||
return url[0] === '/' ? url : `/${url}`
|
||||
}
|
||||
|
||||
// 整合路由参数
|
||||
mixinParam(url, params) {
|
||||
url = url && this.addRootPath(url)
|
||||
|
||||
// 使用正则匹配,主要依据是判断是否有"/","?","="等,如“/page/index/index?name=mary"
|
||||
// 如果有url中有get参数,转换后无需带上"?"
|
||||
let query = ''
|
||||
if (/.*\/.*\?.*=.*/.test(url)) {
|
||||
// object对象转为get类型的参数
|
||||
query = uni.$u.queryParams(params, false);
|
||||
// 因为已有get参数,所以后面拼接的参数需要带上"&"隔开
|
||||
return url += "&" + query
|
||||
} else {
|
||||
// 直接拼接参数,因为此处url中没有后面的query参数,也就没有"?/&"之类的符号
|
||||
query = uni.$u.queryParams(params);
|
||||
return url += query
|
||||
}
|
||||
}
|
||||
|
||||
// 对外的方法名称
|
||||
async route(options = {}, params = {}) {
|
||||
// 合并用户的配置和内部的默认配置
|
||||
let mergeConfig = {}
|
||||
|
||||
if (typeof options === 'string') {
|
||||
// 如果options为字符串,则为route(url, params)的形式
|
||||
mergeConfig.url = this.mixinParam(options, params)
|
||||
mergeConfig.type = 'navigateTo'
|
||||
} else {
|
||||
mergeConfig = uni.$u.deepClone(options, this.config)
|
||||
// 否则正常使用mergeConfig中的url和params进行拼接
|
||||
mergeConfig.url = this.mixinParam(options.url, options.params)
|
||||
}
|
||||
|
||||
if(params.intercept) {
|
||||
this.config.intercept = params.intercept
|
||||
}
|
||||
// params参数也带给拦截器
|
||||
mergeConfig.params = params
|
||||
// 合并内外部参数
|
||||
mergeConfig = uni.$u.deepMerge(this.config, mergeConfig)
|
||||
// 判断用户是否定义了拦截器
|
||||
if (typeof uni.$u.routeIntercept === 'function') {
|
||||
// 定一个promise,根据用户执行resolve(true)或者resolve(false)来决定是否进行路由跳转
|
||||
const isNext = await new Promise((resolve, reject) => {
|
||||
uni.$u.routeIntercept(mergeConfig, resolve)
|
||||
})
|
||||
// 如果isNext为true,则执行路由跳转
|
||||
isNext && this.openPage(mergeConfig)
|
||||
} else {
|
||||
this.openPage(mergeConfig)
|
||||
}
|
||||
}
|
||||
|
||||
// 执行路由跳转
|
||||
openPage(config) {
|
||||
// 解构参数
|
||||
const {
|
||||
url,
|
||||
type,
|
||||
delta,
|
||||
animationType,
|
||||
animationDuration
|
||||
} = config
|
||||
if (config.type == 'navigateTo' || config.type == 'to') {
|
||||
uni.navigateTo({
|
||||
url,
|
||||
animationType,
|
||||
animationDuration
|
||||
});
|
||||
}
|
||||
if (config.type == 'redirectTo' || config.type == 'redirect') {
|
||||
uni.redirectTo({
|
||||
url
|
||||
});
|
||||
}
|
||||
if (config.type == 'switchTab' || config.type == 'tab') {
|
||||
uni.switchTab({
|
||||
url
|
||||
});
|
||||
}
|
||||
if (config.type == 'reLaunch' || config.type == 'launch') {
|
||||
uni.reLaunch({
|
||||
url
|
||||
});
|
||||
}
|
||||
if (config.type == 'navigateBack' || config.type == 'back') {
|
||||
uni.navigateBack({
|
||||
delta
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default (new Router()).route
|
9
libs/function/sys.js
Normal file
9
libs/function/sys.js
Normal file
@ -0,0 +1,9 @@
|
||||
export function os() {
|
||||
return uni.getSystemInfoSync().platform;
|
||||
};
|
||||
|
||||
export function sys() {
|
||||
return uni.getSystemInfoSync();
|
||||
}
|
||||
|
||||
|
232
libs/function/test.js
Normal file
232
libs/function/test.js
Normal file
@ -0,0 +1,232 @@
|
||||
/**
|
||||
* 验证电子邮箱格式
|
||||
*/
|
||||
function email(value) {
|
||||
return /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/.test(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证手机格式
|
||||
*/
|
||||
function mobile(value) {
|
||||
return /^1[3-9]\d{9}$/.test(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证URL格式
|
||||
*/
|
||||
function url(value) {
|
||||
return /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w-.\/?%&=]*)?/.test(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证日期格式
|
||||
*/
|
||||
function date(value) {
|
||||
return !/Invalid|NaN/.test(new Date(value).toString())
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证ISO类型的日期格式
|
||||
*/
|
||||
function dateISO(value) {
|
||||
return /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证十进制数字
|
||||
*/
|
||||
function number(value) {
|
||||
return /^[\+-]?(\d+\.?\d*|\.\d+|\d\.\d+e\+\d+)$/.test(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证整数
|
||||
*/
|
||||
function digits(value) {
|
||||
return /^\d+$/.test(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证身份证号码
|
||||
*/
|
||||
function idCard(value) {
|
||||
return /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
|
||||
value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否车牌号
|
||||
*/
|
||||
function carNo(value) {
|
||||
// 新能源车牌
|
||||
const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/;
|
||||
// 旧车牌
|
||||
const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/;
|
||||
if (value.length === 7) {
|
||||
return creg.test(value);
|
||||
} else if (value.length === 8) {
|
||||
return xreg.test(value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 金额,只允许2位小数
|
||||
*/
|
||||
function amount(value) {
|
||||
//金额,只允许保留两位小数
|
||||
return /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0\.\d{1,2}$/.test(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 中文
|
||||
*/
|
||||
function chinese(value) {
|
||||
let reg = /^[\u4e00-\u9fa5]+$/gi;
|
||||
return reg.test(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 只能输入字母
|
||||
*/
|
||||
function letter(value) {
|
||||
return /^[a-zA-Z]*$/.test(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 只能是字母或者数字
|
||||
*/
|
||||
function enOrNum(value) {
|
||||
//英文或者数字
|
||||
let reg = /^[0-9a-zA-Z]*$/g;
|
||||
return reg.test(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证是否包含某个值
|
||||
*/
|
||||
function contains(value, param) {
|
||||
return value.indexOf(param) >= 0
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证一个值范围[min, max]
|
||||
*/
|
||||
function range(value, param) {
|
||||
return value >= param[0] && value <= param[1]
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证一个长度范围[min, max]
|
||||
*/
|
||||
function rangeLength(value, param) {
|
||||
return value.length >= param[0] && value.length <= param[1]
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否固定电话
|
||||
*/
|
||||
function landline(value) {
|
||||
let reg = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/;
|
||||
return reg.test(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为空
|
||||
*/
|
||||
function empty(value) {
|
||||
switch (typeof value) {
|
||||
case 'undefined':
|
||||
return true;
|
||||
case 'string':
|
||||
if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true;
|
||||
break;
|
||||
case 'boolean':
|
||||
if (!value) return true;
|
||||
break;
|
||||
case 'number':
|
||||
if (0 === value || isNaN(value)) return true;
|
||||
break;
|
||||
case 'object':
|
||||
if (null === value || value.length === 0) return true;
|
||||
for (var i in value) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否json字符串
|
||||
*/
|
||||
function jsonString(value) {
|
||||
if (typeof value == 'string') {
|
||||
try {
|
||||
var obj = JSON.parse(value);
|
||||
if (typeof obj == 'object' && obj) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否数组
|
||||
*/
|
||||
function array(value) {
|
||||
if (typeof Array.isArray === "function") {
|
||||
return Array.isArray(value);
|
||||
} else {
|
||||
return Object.prototype.toString.call(value) === "[object Array]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否对象
|
||||
*/
|
||||
function object(value) {
|
||||
return Object.prototype.toString.call(value) === '[object Object]';
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否短信验证码
|
||||
*/
|
||||
function code(value, len = 6) {
|
||||
return new RegExp(`^\\d{${len}}$`).test(value);
|
||||
}
|
||||
|
||||
|
||||
export default {
|
||||
email,
|
||||
mobile,
|
||||
url,
|
||||
date,
|
||||
dateISO,
|
||||
number,
|
||||
digits,
|
||||
idCard,
|
||||
carNo,
|
||||
amount,
|
||||
chinese,
|
||||
letter,
|
||||
enOrNum,
|
||||
contains,
|
||||
range,
|
||||
rangeLength,
|
||||
empty,
|
||||
isEmpty: empty,
|
||||
jsonString,
|
||||
landline,
|
||||
object,
|
||||
array,
|
||||
code
|
||||
}
|
32
libs/function/throttle.js
Normal file
32
libs/function/throttle.js
Normal file
@ -0,0 +1,32 @@
|
||||
let timer, flag;
|
||||
/**
|
||||
* 节流原理:在一定时间内,只能触发一次
|
||||
*
|
||||
* @param {Function} func 要执行的回调函数
|
||||
* @param {Number} wait 延时的时间
|
||||
* @param {Boolean} immediate 是否立即执行
|
||||
* @return null
|
||||
*/
|
||||
function throttle(func, wait = 500, immediate = true) {
|
||||
if (immediate) {
|
||||
if (!flag) {
|
||||
flag = true;
|
||||
// 如果是立即执行,则在wait毫秒内开始时执行
|
||||
typeof func === 'function' && func();
|
||||
timer = setTimeout(() => {
|
||||
flag = false;
|
||||
}, wait);
|
||||
}
|
||||
} else {
|
||||
if (!flag) {
|
||||
flag = true
|
||||
// 如果是非立即执行,则在wait毫秒内的结束处执行
|
||||
timer = setTimeout(() => {
|
||||
flag = false
|
||||
typeof func === 'function' && func();
|
||||
}, wait);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
export default throttle
|
51
libs/function/timeFormat.js
Normal file
51
libs/function/timeFormat.js
Normal file
@ -0,0 +1,51 @@
|
||||
// padStart 的 polyfill,因为某些机型或情况,还无法支持es7的padStart,比如电脑版的微信小程序
|
||||
// 所以这里做一个兼容polyfill的兼容处理
|
||||
if (!String.prototype.padStart) {
|
||||
// 为了方便表示这里 fillString 用了ES6 的默认参数,不影响理解
|
||||
String.prototype.padStart = function(maxLength, fillString = ' ') {
|
||||
if (Object.prototype.toString.call(fillString) !== "[object String]") throw new TypeError(
|
||||
'fillString must be String')
|
||||
let str = this
|
||||
// 返回 String(str) 这里是为了使返回的值是字符串字面量,在控制台中更符合直觉
|
||||
if (str.length >= maxLength) return String(str)
|
||||
|
||||
let fillLength = maxLength - str.length,
|
||||
times = Math.ceil(fillLength / fillString.length)
|
||||
while (times >>= 1) {
|
||||
fillString += fillString
|
||||
if (times === 1) {
|
||||
fillString += fillString
|
||||
}
|
||||
}
|
||||
return fillString.slice(0, fillLength) + str;
|
||||
}
|
||||
}
|
||||
|
||||
// 其他更多是格式化有如下:
|
||||
// yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合
|
||||
function timeFormat(dateTime = null, fmt = 'yyyy-mm-dd') {
|
||||
// 如果为null,则格式化当前时间
|
||||
if (!dateTime) dateTime = Number(new Date());
|
||||
// 如果dateTime长度为10或者13,则为秒和毫秒的时间戳,如果超过13位,则为其他的时间格式
|
||||
if (dateTime.toString().length == 10) dateTime *= 1000;
|
||||
let date = new Date(dateTime);
|
||||
let ret;
|
||||
let opt = {
|
||||
"y+": date.getFullYear().toString(), // 年
|
||||
"m+": (date.getMonth() + 1).toString(), // 月
|
||||
"d+": date.getDate().toString(), // 日
|
||||
"h+": date.getHours().toString(), // 时
|
||||
"M+": date.getMinutes().toString(), // 分
|
||||
"s+": date.getSeconds().toString() // 秒
|
||||
// 有其他格式化字符需求可以继续添加,必须转化成字符串
|
||||
};
|
||||
for (let k in opt) {
|
||||
ret = new RegExp("(" + k + ")").exec(fmt);
|
||||
if (ret) {
|
||||
fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
|
||||
};
|
||||
};
|
||||
return fmt;
|
||||
}
|
||||
|
||||
export default timeFormat
|
47
libs/function/timeFrom.js
Normal file
47
libs/function/timeFrom.js
Normal file
@ -0,0 +1,47 @@
|
||||
import timeFormat from '../../libs/function/timeFormat.js';
|
||||
|
||||
/**
|
||||
* 时间戳转为多久之前
|
||||
* @param String timestamp 时间戳
|
||||
* @param String | Boolean format 如果为时间格式字符串,超出一定时间范围,返回固定的时间格式;
|
||||
* 如果为布尔值false,无论什么时间,都返回多久以前的格式
|
||||
*/
|
||||
function timeFrom(dateTime = null, format = 'yyyy-mm-dd') {
|
||||
// 如果为null,则格式化当前时间
|
||||
if (!dateTime) dateTime = Number(new Date());
|
||||
// 如果dateTime长度为10或者13,则为秒和毫秒的时间戳,如果超过13位,则为其他的时间格式
|
||||
if (dateTime.toString().length == 10) dateTime *= 1000;
|
||||
let timestamp = + new Date(Number(dateTime));
|
||||
|
||||
let timer = (Number(new Date()) - timestamp) / 1000;
|
||||
// 如果小于5分钟,则返回"刚刚",其他以此类推
|
||||
let tips = '';
|
||||
switch (true) {
|
||||
case timer < 300:
|
||||
tips = '刚刚';
|
||||
break;
|
||||
case timer >= 300 && timer < 3600:
|
||||
tips = parseInt(timer / 60) + '分钟前';
|
||||
break;
|
||||
case timer >= 3600 && timer < 86400:
|
||||
tips = parseInt(timer / 3600) + '小时前';
|
||||
break;
|
||||
case timer >= 86400 && timer < 2592000:
|
||||
tips = parseInt(timer / 86400) + '天前';
|
||||
break;
|
||||
default:
|
||||
// 如果format为false,则无论什么时间戳,都显示xx之前
|
||||
if(format === false) {
|
||||
if(timer >= 2592000 && timer < 365 * 86400) {
|
||||
tips = parseInt(timer / (86400 * 30)) + '个月前';
|
||||
} else {
|
||||
tips = parseInt(timer / (86400 * 365)) + '年前';
|
||||
}
|
||||
} else {
|
||||
tips = timeFormat(timestamp, format);
|
||||
}
|
||||
}
|
||||
return tips;
|
||||
}
|
||||
|
||||
export default timeFrom;
|
9
libs/function/toast.js
Normal file
9
libs/function/toast.js
Normal file
@ -0,0 +1,9 @@
|
||||
function toast(title, duration = 1500) {
|
||||
uni.showToast({
|
||||
title: title,
|
||||
icon: 'none',
|
||||
duration: duration
|
||||
})
|
||||
}
|
||||
|
||||
export default toast
|
15
libs/function/trim.js
Normal file
15
libs/function/trim.js
Normal file
@ -0,0 +1,15 @@
|
||||
function trim(str, pos = 'both') {
|
||||
if (pos == 'both') {
|
||||
return str.replace(/^\s+|\s+$/g, "");
|
||||
} else if (pos == "left") {
|
||||
return str.replace(/^\s*/, '');
|
||||
} else if (pos == 'right') {
|
||||
return str.replace(/(\s*$)/g, "");
|
||||
} else if (pos == 'all') {
|
||||
return str.replace(/\s+/g, "");
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
export default trim
|
35
libs/function/type2icon.js
Normal file
35
libs/function/type2icon.js
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 根据主题type值,获取对应的图标
|
||||
* @param String type 主题名称,primary|info|error|warning|success
|
||||
* @param String fill 是否使用fill填充实体的图标
|
||||
*/
|
||||
function type2icon(type = 'success', fill = false) {
|
||||
// 如果非预置值,默认为success
|
||||
if (['primary', 'info', 'error', 'warning', 'success'].indexOf(type) == -1) type = 'success';
|
||||
let iconName = '';
|
||||
// 目前(2019-12-12),info和primary使用同一个图标
|
||||
switch (type) {
|
||||
case 'primary':
|
||||
iconName = 'info-circle';
|
||||
break;
|
||||
case 'info':
|
||||
iconName = 'info-circle';
|
||||
break;
|
||||
case 'error':
|
||||
iconName = 'close-circle';
|
||||
break;
|
||||
case 'warning':
|
||||
iconName = 'error-circle';
|
||||
break;
|
||||
case 'success':
|
||||
iconName = 'checkmark-circle';
|
||||
break;
|
||||
default:
|
||||
iconName = 'checkmark-circle';
|
||||
}
|
||||
// 是否是实体类型,加上-fill,在icon组件库中,实体的类名是后面加-fill的
|
||||
if (fill) iconName += '-fill';
|
||||
return iconName;
|
||||
}
|
||||
|
||||
export default type2icon
|
64
libs/mixin/mixin.js
Normal file
64
libs/mixin/mixin.js
Normal file
@ -0,0 +1,64 @@
|
||||
module.exports = {
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
onLoad() {
|
||||
// getRect挂载到$u上,因为这方法需要使用in(this),所以无法把它独立成一个单独的文件导出
|
||||
this.$u.getRect = this.$uGetRect
|
||||
},
|
||||
methods: {
|
||||
// 查询节点信息
|
||||
// 目前此方法在支付宝小程序中无法获取组件跟接点的尺寸,为支付宝的bug(2020-07-21)
|
||||
// 解决办法为在组件根部再套一个没有任何作用的view元素
|
||||
$uGetRect(selector, all) {
|
||||
return new Promise(resolve => {
|
||||
uni.createSelectorQuery().
|
||||
in(this)[all ? 'selectAll' : 'select'](selector)
|
||||
.boundingClientRect(rect => {
|
||||
if (all && Array.isArray(rect) && rect.length) {
|
||||
resolve(rect)
|
||||
}
|
||||
if (!all && rect) {
|
||||
resolve(rect)
|
||||
}
|
||||
})
|
||||
.exec()
|
||||
})
|
||||
},
|
||||
getParentData(parentName = '') {
|
||||
// 避免在created中去定义parent变量
|
||||
if(!this.parent) this.parent = false;
|
||||
// 这里的本质原理是,通过获取父组件实例(也即u-radio-group的this)
|
||||
// 将父组件this中对应的参数,赋值给本组件(u-radio的this)的parentData对象中对应的属性
|
||||
// 之所以需要这么做,是因为所有端中,头条小程序不支持通过this.parent.xxx去监听父组件参数的变化
|
||||
this.parent = this.$u.$parent.call(this, parentName);
|
||||
if(this.parent) {
|
||||
// 历遍parentData中的属性,将parent中的同名属性赋值给parentData
|
||||
Object.keys(this.parentData).map(key => {
|
||||
this.parentData[key] = this.parent[key];
|
||||
});
|
||||
}
|
||||
},
|
||||
// 阻止事件冒泡
|
||||
preventEvent(e) {
|
||||
e && e.stopPropagation && e.stopPropagation()
|
||||
}
|
||||
},
|
||||
onReachBottom() {
|
||||
uni.$emit('uOnReachBottom')
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 判断当前页面是否存在parent和children,一般在checkbox和checkbox-group父子联动的场景会有此情况
|
||||
// 组件销毁时,移除子组件在父组件children数组中的实例,释放资源,避免数据混乱
|
||||
if(this.parent && uni.$u.test.array(this.parent.children)) {
|
||||
// 组件销毁时,移除父组件中的children数组中对应的实例
|
||||
const childrenList = this.parent.children
|
||||
childrenList.map((child, index) => {
|
||||
// 如果相等,则移除
|
||||
if(child === this) {
|
||||
childrenList.splice(index, 1)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
18
libs/mixin/mpShare.js
Normal file
18
libs/mixin/mpShare.js
Normal file
@ -0,0 +1,18 @@
|
||||
module.exports = {
|
||||
onLoad() {
|
||||
// 设置默认的转发参数
|
||||
this.$u.mpShare = {
|
||||
title: '', // 默认为小程序名称
|
||||
path: '', // 默认为当前页面路径
|
||||
imageUrl: '' // 默认为当前页面的截图
|
||||
}
|
||||
},
|
||||
onShareAppMessage() {
|
||||
return this.$u.mpShare
|
||||
},
|
||||
// #ifdef MP-WEIXIN
|
||||
onShareTimeline() {
|
||||
return this.$u.mpShare
|
||||
}
|
||||
// #endif
|
||||
}
|
169
libs/request/index.js
Normal file
169
libs/request/index.js
Normal file
@ -0,0 +1,169 @@
|
||||
import deepMerge from "../function/deepMerge";
|
||||
import validate from "../function/test";
|
||||
class Request {
|
||||
// 设置全局默认配置
|
||||
setConfig(customConfig) {
|
||||
// 深度合并对象,否则会造成对象深层属性丢失
|
||||
this.config = deepMerge(this.config, customConfig);
|
||||
}
|
||||
|
||||
// 主要请求部分
|
||||
request(options = {}) {
|
||||
// 检查请求拦截
|
||||
if (this.interceptor.request && typeof this.interceptor.request === 'function') {
|
||||
let tmpConfig = {};
|
||||
let interceptorRequest = this.interceptor.request(options);
|
||||
if (interceptorRequest === false) {
|
||||
// 返回一个处于pending状态中的Promise,来取消原promise,避免进入then()回调
|
||||
return new Promise(()=>{});
|
||||
}
|
||||
this.options = interceptorRequest;
|
||||
}
|
||||
options.dataType = options.dataType || this.config.dataType;
|
||||
options.responseType = options.responseType || this.config.responseType;
|
||||
options.url = options.url || '';
|
||||
options.params = options.params || {};
|
||||
options.header = Object.assign({}, this.config.header, options.header);
|
||||
options.method = options.method || this.config.method;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
options.complete = (response) => {
|
||||
// 请求返回后,隐藏loading(如果请求返回快的话,可能会没有loading)
|
||||
uni.hideLoading();
|
||||
// 清除定时器,如果请求回来了,就无需loading
|
||||
clearTimeout(this.config.timer);
|
||||
this.config.timer = null;
|
||||
// 判断用户对拦截返回数据的要求,如果originalData为true,返回所有的数据(response)到拦截器,否则只返回response.data
|
||||
if(this.config.originalData) {
|
||||
// 判断是否存在拦截器
|
||||
if (this.interceptor.response && typeof this.interceptor.response === 'function') {
|
||||
let resInterceptors = this.interceptor.response(response);
|
||||
// 如果拦截器不返回false,就将拦截器返回的内容给this.$u.post的then回调
|
||||
if (resInterceptors !== false) {
|
||||
resolve(resInterceptors);
|
||||
} else {
|
||||
// 如果拦截器返回false,意味着拦截器定义者认为返回有问题,直接接入catch回调
|
||||
reject(response);
|
||||
}
|
||||
} else {
|
||||
// 如果要求返回原始数据,就算没有拦截器,也返回最原始的数据
|
||||
resolve(response);
|
||||
}
|
||||
} else {
|
||||
if (response.statusCode == 200) {
|
||||
if (this.interceptor.response && typeof this.interceptor.response === 'function') {
|
||||
let resInterceptors = this.interceptor.response(response.data);
|
||||
if (resInterceptors !== false) {
|
||||
resolve(resInterceptors);
|
||||
} else {
|
||||
reject(response.data);
|
||||
}
|
||||
} else {
|
||||
// 如果不是返回原始数据(originalData=false),且没有拦截器的情况下,返回纯数据给then回调
|
||||
resolve(response.data);
|
||||
}
|
||||
} else {
|
||||
// 不返回原始数据的情况下,服务器状态码不为200,modal弹框提示
|
||||
// if(response.errMsg) {
|
||||
// uni.showModal({
|
||||
// title: response.errMsg
|
||||
// });
|
||||
// }
|
||||
reject(response)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 判断用户传递的URL是否/开头,如果不是,加上/,这里使用了uView的test.js验证库的url()方法
|
||||
options.url = validate.url(options.url) ? options.url : (this.config.baseUrl + (options.url.indexOf('/') == 0 ?
|
||||
options.url : '/' + options.url));
|
||||
|
||||
// 是否显示loading
|
||||
// 加一个是否已有timer定时器的判断,否则有两个同时请求的时候,后者会清除前者的定时器id
|
||||
// 而没有清除前者的定时器,导致前者超时,一直显示loading
|
||||
if(this.config.showLoading && !this.config.timer) {
|
||||
this.config.timer = setTimeout(() => {
|
||||
uni.showLoading({
|
||||
title: this.config.loadingText,
|
||||
mask: this.config.loadingMask
|
||||
})
|
||||
this.config.timer = null;
|
||||
}, this.config.loadingTime);
|
||||
}
|
||||
uni.request(options);
|
||||
})
|
||||
// .catch(res => {
|
||||
// // 如果返回reject(),不让其进入this.$u.post().then().catch()后面的catct()
|
||||
// // 因为很多人都会忘了写后面的catch(),导致报错捕获不到catch
|
||||
// return new Promise(()=>{});
|
||||
// })
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.config = {
|
||||
baseUrl: '', // 请求的根域名
|
||||
// 默认的请求头
|
||||
header: {},
|
||||
method: 'POST',
|
||||
// 设置为json,返回后uni.request会对数据进行一次JSON.parse
|
||||
dataType: 'json',
|
||||
// 此参数无需处理,因为5+和支付宝小程序不支持,默认为text即可
|
||||
responseType: 'text',
|
||||
showLoading: true, // 是否显示请求中的loading
|
||||
loadingText: '请求中...',
|
||||
loadingTime: 800, // 在此时间内,请求还没回来的话,就显示加载中动画,单位ms
|
||||
timer: null, // 定时器
|
||||
originalData: false, // 是否在拦截器中返回服务端的原始数据,见文档说明
|
||||
loadingMask: true, // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透
|
||||
}
|
||||
|
||||
// 拦截器
|
||||
this.interceptor = {
|
||||
// 请求前的拦截
|
||||
request: null,
|
||||
// 请求后的拦截
|
||||
response: null
|
||||
}
|
||||
|
||||
// get请求
|
||||
this.get = (url, data = {}, header = {}) => {
|
||||
return this.request({
|
||||
method: 'GET',
|
||||
url,
|
||||
header,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// post请求
|
||||
this.post = (url, data = {}, header = {}) => {
|
||||
return this.request({
|
||||
url,
|
||||
method: 'POST',
|
||||
header,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// put请求,不支持支付宝小程序(HX2.6.15)
|
||||
this.put = (url, data = {}, header = {}) => {
|
||||
return this.request({
|
||||
url,
|
||||
method: 'PUT',
|
||||
header,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// delete请求,不支持支付宝和头条小程序(HX2.6.15)
|
||||
this.delete = (url, data = {}, header = {}) => {
|
||||
return this.request({
|
||||
url,
|
||||
method: 'DELETE',
|
||||
header,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
export default new Request
|
19
libs/store/index.js
Normal file
19
libs/store/index.js
Normal file
@ -0,0 +1,19 @@
|
||||
// 暂时不用vuex模块方式实现,将该方法直接放入到/store/index.js中
|
||||
const module = {
|
||||
actions: {
|
||||
$uStore({rootState}, params) {
|
||||
let nameArr = params.name.split('.');
|
||||
if(nameArr.length >= 2) {
|
||||
let obj = rootState[nameArr[0]];
|
||||
for(let i = 1; i < nameArr.length - 1; i ++) {
|
||||
obj = obj[nameArr[i]];
|
||||
}
|
||||
obj[nameArr[nameArr.length - 1]] = params.value;
|
||||
} else {
|
||||
rootState[params.name] = params.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default module
|
1
libs/util/area.js
Normal file
1
libs/util/area.js
Normal file
File diff suppressed because one or more lines are too long
1356
libs/util/async-validator.js
Normal file
1356
libs/util/async-validator.js
Normal file
File diff suppressed because it is too large
Load Diff
1
libs/util/city.js
Normal file
1
libs/util/city.js
Normal file
File diff suppressed because one or more lines are too long
51
libs/util/emitter.js
Normal file
51
libs/util/emitter.js
Normal file
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* 递归使用 call 方式this指向
|
||||
* @param componentName // 需要找的组件的名称
|
||||
* @param eventName // 事件名称
|
||||
* @param params // 需要传递的参数
|
||||
*/
|
||||
function broadcast(componentName, eventName, params) {
|
||||
// 循环子节点找到名称一样的子节点 否则 递归 当前子节点
|
||||
this.$children.map(child=>{
|
||||
if (componentName===child.$options.name) {
|
||||
child.$emit.apply(child,[eventName].concat(params))
|
||||
}else {
|
||||
broadcast.apply(child,[componentName,eventName].concat(params))
|
||||
}
|
||||
})
|
||||
}
|
||||
export default {
|
||||
methods: {
|
||||
/**
|
||||
* 派发 (向上查找) (一个)
|
||||
* @param componentName // 需要找的组件的名称
|
||||
* @param eventName // 事件名称
|
||||
* @param params // 需要传递的参数
|
||||
*/
|
||||
dispatch(componentName, eventName, params) {
|
||||
let parent = this.$parent || this.$root;//$parent 找到最近的父节点 $root 根节点
|
||||
let name = parent.$options.name; // 获取当前组件实例的name
|
||||
// 如果当前有节点 && 当前没名称 且 当前名称等于需要传进来的名称的时候就去查找当前的节点
|
||||
// 循环出当前名称的一样的组件实例
|
||||
while (parent && (!name||name!==componentName)) {
|
||||
parent = parent.$parent;
|
||||
if (parent) {
|
||||
name = parent.$options.name;
|
||||
}
|
||||
}
|
||||
// 有节点表示当前找到了name一样的实例
|
||||
if (parent) {
|
||||
parent.$emit.apply(parent,[eventName].concat(params))
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 广播 (向下查找) (广播多个)
|
||||
* @param componentName // 需要找的组件的名称
|
||||
* @param eventName // 事件名称
|
||||
* @param params // 需要传递的参数
|
||||
*/
|
||||
broadcast(componentName, eventName, params) {
|
||||
broadcast.call(this,componentName, eventName, params)
|
||||
}
|
||||
}
|
||||
}
|
1
libs/util/province.js
Normal file
1
libs/util/province.js
Normal file
@ -0,0 +1 @@
|
||||
var provinceData=[{"label":"北京市","value":"11"},{"label":"天津市","value":"12"},{"label":"河北省","value":"13"},{"label":"山西省","value":"14"},{"label":"内蒙古自治区","value":"15"},{"label":"辽宁省","value":"21"},{"label":"吉林省","value":"22"},{"label":"黑龙江省","value":"23"},{"label":"上海市","value":"31"},{"label":"江苏省","value":"32"},{"label":"浙江省","value":"33"},{"label":"安徽省","value":"34"},{"label":"福建省","value":"35"},{"label":"江西省","value":"36"},{"label":"山东省","value":"37"},{"label":"河南省","value":"41"},{"label":"湖北省","value":"42"},{"label":"湖南省","value":"43"},{"label":"广东省","value":"44"},{"label":"广西壮族自治区","value":"45"},{"label":"海南省","value":"46"},{"label":"重庆市","value":"50"},{"label":"四川省","value":"51"},{"label":"贵州省","value":"52"},{"label":"云南省","value":"53"},{"label":"西藏自治区","value":"54"},{"label":"陕西省","value":"61"},{"label":"甘肃省","value":"62"},{"label":"青海省","value":"63"},{"label":"宁夏回族自治区","value":"64"},{"label":"新疆维吾尔自治区","value":"65"},{"label":"台湾","value":"66"},{"label":"香港","value":"67"},{"label":"澳门","value":"68"}];export default provinceData;
|
29
main.js
Normal file
29
main.js
Normal file
@ -0,0 +1,29 @@
|
||||
import App from './App'
|
||||
import uView from '@/uni_modules/uview-ui'
|
||||
Vue.use(uView);
|
||||
|
||||
// #ifndef VUE3
|
||||
import Vue from 'vue'
|
||||
import './uni.promisify.adaptor'
|
||||
Vue.config.productionTip = false
|
||||
App.mpType = 'app'
|
||||
const app = new Vue({
|
||||
...App
|
||||
})
|
||||
require('./utils/request/index')(app)
|
||||
app.$mount()
|
||||
|
||||
// #endif
|
||||
|
||||
// #ifdef VUE3
|
||||
import {
|
||||
createSSRApp
|
||||
} from 'vue'
|
||||
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App);
|
||||
return {
|
||||
app
|
||||
}
|
||||
}
|
||||
// #endif
|
118
manifest.json
Normal file
118
manifest.json
Normal file
@ -0,0 +1,118 @@
|
||||
{
|
||||
"name" : "古言小说",
|
||||
"appid" : "__UNI__474F351",
|
||||
"description" : "",
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : "100",
|
||||
"transformPx" : false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus" : {
|
||||
"safearea" : {
|
||||
//安全区域配置,仅ioS平台生效
|
||||
"background" : "#F5F6F9", //安全区域外的背景颜色,默认值为"#FFFFFF"
|
||||
"bottom" : {
|
||||
// 底部安全区域配置
|
||||
"offset" : "none|auto" // 底部安全区域偏移,"none"表示不空出安全区域,"auto"自动计算空出安全区域,默认值为"none"
|
||||
}
|
||||
},
|
||||
"bounce" : "none", // 将回弹属性关掉
|
||||
"usingComponents" : true,
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
/* 模块配置 */
|
||||
"modules" : {},
|
||||
/* 应用发布信息 */
|
||||
"distribute" : {
|
||||
/* android打包配置 */
|
||||
"android" : {
|
||||
"permissions" : [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
]
|
||||
},
|
||||
/* ios打包配置 */
|
||||
"ios" : {
|
||||
"dSYMs" : false
|
||||
},
|
||||
/* SDK配置 */
|
||||
"sdkConfigs" : {
|
||||
"ad" : {}
|
||||
},
|
||||
"icons" : {
|
||||
"android" : {
|
||||
"hdpi" : "unpackage/res/icons/72x72.png",
|
||||
"xhdpi" : "unpackage/res/icons/96x96.png",
|
||||
"xxhdpi" : "unpackage/res/icons/144x144.png",
|
||||
"xxxhdpi" : "unpackage/res/icons/192x192.png"
|
||||
},
|
||||
"ios" : {
|
||||
// "appstore" : "static/app_logo.png",
|
||||
"iphone" : {
|
||||
"app@2x" : "unpackage/res/icons/120x120.png",
|
||||
"app@3x" : "unpackage/res/icons/180x180.png",
|
||||
"spotlight@2x" : "unpackage/res/icons/80x80.png",
|
||||
"spotlight@3x" : "unpackage/res/icons/120x120.png",
|
||||
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||
"settings@3x" : "unpackage/res/icons/87x87.png",
|
||||
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||
"notification@3x" : "unpackage/res/icons/60x60.png"
|
||||
},
|
||||
"ipad" : {
|
||||
"app" : "unpackage/res/icons/76x76.png",
|
||||
"app@2x" : "unpackage/res/icons/152x152.png",
|
||||
"proapp@2x" : "unpackage/res/icons/167x167.png",
|
||||
"spotlight" : "unpackage/res/icons/40x40.png",
|
||||
"spotlight@2x" : "unpackage/res/icons/80x80.png",
|
||||
"settings" : "unpackage/res/icons/29x29.png",
|
||||
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||
"notification" : "unpackage/res/icons/20x20.png"
|
||||
},
|
||||
"appstore" : "unpackage/res/icons/1024x1024.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
"quickapp" : {},
|
||||
/* 小程序特有相关 */
|
||||
"mp-weixin" : {
|
||||
"appid" : "",
|
||||
"setting" : {
|
||||
"urlCheck" : false
|
||||
},
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : false
|
||||
},
|
||||
"vueVersion" : "2"
|
||||
}
|
326
pages.json
Normal file
326
pages.json
Normal file
@ -0,0 +1,326 @@
|
||||
{
|
||||
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||
{
|
||||
// 初始化页面
|
||||
"path": "pages/initialization/initialization",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"navigationStyle": "custom",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
// 协议和政策
|
||||
"path": "pages/agreement/agreement",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
// "navigationStyle": "custom",
|
||||
"app-plus": {
|
||||
"bounce": "none" ,// 将回弹属性关掉
|
||||
"safearea": {
|
||||
//安全区域配置,仅ioS平台生效
|
||||
"background": "#FFFFFF", //安全区域外的背景颜色,默认值为"#FFFFFF"
|
||||
"bottom": {
|
||||
// 底部安全区域配置
|
||||
"offset": "auto" // 底部安全区域偏移,"none"表示不空出安全区域,"auto"自动计算空出安全区域,默认值为"none"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/bookCity/bookCity/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "书城",
|
||||
"navigationStyle": "custom",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/bookshelf/bookshelf/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "书架",
|
||||
"navigationStyle": "custom",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/login",
|
||||
"style": {
|
||||
// 登录页面
|
||||
"navigationBarTitleText": "",
|
||||
"navigationStyle": "custom",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/loginMobile/loginMobile",
|
||||
"style": {
|
||||
// 登录验证码页面
|
||||
"navigationBarTitleText": "",
|
||||
"navigationStyle": "custom",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/classification/classification/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "分类",
|
||||
"navigationStyle": "custom",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/myInfo/myInfo/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/myInfo/aboutMy/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "关于我们",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/myInfo/mySetUp/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "设置",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/myInfo/problemList/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "常见问题",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/myInfo/problemDetail/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "常见问题",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/voucherCenter/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "充值中心",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/readingRecords/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "阅读记录",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/signInBookCurrency/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "签到领取书币",
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTextStyle": "white",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/booksListAll/index",
|
||||
"style": {
|
||||
//完本和新书的 书籍列表
|
||||
"navigationBarTitleText": "",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
// "app-plus": {
|
||||
// "safearea": { //安全区域配置,仅ioS平台生效
|
||||
// "background": "#FFFFFF", //安全区域外的背景颜色,默认值为"#FFFFFF"
|
||||
// "bottom": { // 底部安全区域配置
|
||||
// "offset": "none" // 底部安全区域偏移,"none"表示不空出安全区域,"auto"自动计算空出安全区域,默认值为"none"
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// "app-plus": {
|
||||
// "bottom": "0",
|
||||
// "contentAdjust": "false",
|
||||
// "bounce": "none",
|
||||
// "safearea": {
|
||||
// "bottom": "none"
|
||||
// }
|
||||
// }
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/booksTheCharts/index",
|
||||
"style": {
|
||||
// booksTheCharts
|
||||
"navigationBarTitleText": "",
|
||||
// "navigationBarBackgroundColor": "transparent",
|
||||
"navigationStyle": "custom",
|
||||
// "app-plus": {
|
||||
// "titleNView": {
|
||||
// "backgroundColor": "transparent",
|
||||
// "background": "transparent"
|
||||
// }
|
||||
// }
|
||||
|
||||
// "enablePullDownRefresh": false,
|
||||
// "disableScroll": true,
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/voucherCenterDetail/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "充值记录",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/bookCoinDetail/bookCoinDetail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "书币明细",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/giveCoinDetail/giveCoinDetail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "赠币明细",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/booksSearchList/booksSearchList",
|
||||
"style": {
|
||||
"navigationBarTitleText": "搜索",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/novelReading/novelReading",
|
||||
"style": {
|
||||
// 阅读页面
|
||||
"navigationBarTitleText": "",
|
||||
"navigationStyle": "custom",
|
||||
"app-plus": {
|
||||
"bounce": "none"
|
||||
},
|
||||
// "enablePullDownRefresh": true
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/booksReadingDetail/booksReadingDetail",
|
||||
"style": {
|
||||
// 书籍详细页面
|
||||
"navigationBarTitleText": "",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/bookRecommendList/bookRecommendList",
|
||||
"style": {
|
||||
// 书籍章节列表
|
||||
"navigationBarTitleText": "",
|
||||
"app-plus": {
|
||||
"bounce": "none" // 将回弹属性关掉
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "uni-app",
|
||||
"navigationBarBackgroundColor": "#F8F8F8",
|
||||
"backgroundColor": "#F8F8F8"
|
||||
},
|
||||
"uniIdRouter": {},
|
||||
"easycom": {
|
||||
// "autoscan": true,
|
||||
"custom": {
|
||||
// "^u--(.*)": "@/uni_modules/uview-plus/components/u-$1/u-$1.vue",
|
||||
// "^up-(.*)": "@/uni_modules/uview-plus/components/u-$1/u-$1.vue",
|
||||
// "^u-([^-].*)": "@/uni_modules/uview-plus/components/u-$1/u-$1.vue",
|
||||
"fui-(.*)": "firstui-uni/firstui/fui-$1/fui-$1.vue",
|
||||
"^u-(.*)": "@/uni_modules/uview-ui/components/u-$1/u-$1.vue"
|
||||
}
|
||||
},
|
||||
"tabBar": {
|
||||
"backgroundColor": "#FFFFFF",
|
||||
"borderStyle": "#F5F5F5",
|
||||
"selectedColor": "#FF5000",
|
||||
"iconWidth": "24px",
|
||||
"color": "#666666",
|
||||
"fontSize": "10px",
|
||||
"height": "68px",
|
||||
"list": [{
|
||||
"pagePath": "pages/bookshelf/bookshelf/index",
|
||||
"text": "书架",
|
||||
"iconPath": "/static/images/tabbar/bookshelf.png",
|
||||
"selectedIconPath": "/static/images/tabbar/bookshelfActive.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/bookCity/bookCity/index",
|
||||
"text": "书城",
|
||||
"iconPath": "/static/images/tabbar/bookCity.png",
|
||||
"selectedIconPath": "/static/images/tabbar/bookCityActive.png"
|
||||
}, {
|
||||
"pagePath": "pages/classification/classification/index",
|
||||
"text": "分类",
|
||||
"iconPath": "/static/images/tabbar/classification.png",
|
||||
"selectedIconPath": "/static/images/tabbar/classificationActive.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/myInfo/myInfo/index",
|
||||
"text": "我的",
|
||||
"iconPath": "/static/images/tabbar/myInfo.png",
|
||||
"selectedIconPath": "/static/images/tabbar/myInfoActive.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
56
pages/agreement/agreement.vue
Normal file
56
pages/agreement/agreement.vue
Normal file
@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<view class="agreement_content">
|
||||
<web-view :webview-styles="webviewStyles" :src="webViewSrc"></web-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
webviewStyles: {
|
||||
progress: false
|
||||
},
|
||||
webViewType: '',
|
||||
webViewSrc: ''
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
const type = options.type;
|
||||
const obj = {
|
||||
// 用户协议
|
||||
'1': {
|
||||
title: '《用户协议》',
|
||||
src: `https://qjnovelweb.qinjiuxiaoshuo.com/UserAgreement.html`
|
||||
},
|
||||
// 隐私政策
|
||||
'2': {
|
||||
title: '《隐私协议》',
|
||||
src: `https://qjnovelweb.qinjiuxiaoshuo.com/privacypolicy.html`
|
||||
}
|
||||
}
|
||||
uni.setNavigationBarTitle({
|
||||
title: obj[type].title
|
||||
});
|
||||
this.webViewSrc = obj[type].src;
|
||||
this.webViewType = type;
|
||||
},
|
||||
onShow() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.agreement_content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
/* 兼容 iOS 设备 */
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
</style>
|
162
pages/bookCity/bookCity/index.vue
Normal file
162
pages/bookCity/bookCity/index.vue
Normal file
@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<!-- -->
|
||||
<view class="bookCity_content">
|
||||
<CommNavBar :navBarList="navBarList" @navBarClick="handelCommNavBar" :navBarActive="navBarActive" />
|
||||
<view class="bookCity_content_body">
|
||||
<scroll-view scroll-y="true" class="scroll_y">
|
||||
<view class="scroll_y_item">
|
||||
<Home v-if="navBarActive == '1'" ref="bookCityHome" @handelRankingList="handelRankingList"
|
||||
:explosiveDataList="explosiveDataList" :rankingDataList="rankingDataList"
|
||||
:headerListActive="headerListActive" :popularityDataList="popularityDataList"
|
||||
:originalDataList="originalDataList" :recommendDataList="recommendDataList"
|
||||
:moreBooksList="moreBooksList" :swiperList="swiperList" :skeletonLoading="skeletonLoading" />
|
||||
<Member v-if="navBarActive == '2'" />
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommNavBar from '@/components/commNavBar/index.vue'
|
||||
import Home from '@/pages/bookCity/components/home/index.vue'
|
||||
import Member from '@/pages/bookCity/components/member/index.vue'
|
||||
import {
|
||||
isGetSystemInfo
|
||||
} from '@/utils/systemInfo.js'
|
||||
import {
|
||||
baseUrlImage
|
||||
} from '@/utils/utils'
|
||||
export default {
|
||||
components: {
|
||||
CommNavBar,
|
||||
Home,
|
||||
Member
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
navBarList: [{
|
||||
id: '1',
|
||||
name: '首页'
|
||||
},
|
||||
// {
|
||||
// id: '2',
|
||||
// name: '会员'
|
||||
// },
|
||||
],
|
||||
navBarActive: '1',
|
||||
// 全网火爆
|
||||
explosiveDataList: [],
|
||||
// 榜单
|
||||
rankingDataList: [],
|
||||
rankingDataObj: {},
|
||||
headerListActive: '1',
|
||||
// 人气作品
|
||||
popularityDataList: [],
|
||||
// 原创优选
|
||||
originalDataList: [],
|
||||
// 书友推荐
|
||||
recommendDataList: [],
|
||||
// 跟多书籍
|
||||
moreBooksList: [],
|
||||
swiperList: [],
|
||||
skeletonLoading: false
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
onShow() {
|
||||
// this.$nextTick(() => {
|
||||
// this.$refs.bookCityHome.isGetIndex()
|
||||
// })
|
||||
this.isGetHomeIndex();
|
||||
},
|
||||
methods: {
|
||||
handelCommNavBar(event) {
|
||||
this.navBarActive = event.currentTarget.dataset.id
|
||||
},
|
||||
isGetHomeIndex() {
|
||||
// this.skeletonLoading = true;
|
||||
// uni.showLoading({
|
||||
// title: '加载中...'
|
||||
// });
|
||||
// 也可以直接通过uni.$u.post发出请求,注意此处需要写上接口地址
|
||||
const parameter = {
|
||||
custom: {
|
||||
token: true
|
||||
}
|
||||
}
|
||||
uni.$u.http.post('/Index', {}, parameter).then((res) => {
|
||||
// uni.hideLoading();
|
||||
this.skeletonLoading = false;
|
||||
if (res.status == 1) {
|
||||
const {
|
||||
ads,
|
||||
module1,
|
||||
charts1,
|
||||
charts2,
|
||||
charts3,
|
||||
charts4,
|
||||
module3,
|
||||
module4,
|
||||
module5,
|
||||
module6
|
||||
} = res.data;
|
||||
this.swiperList = baseUrlImage(ads);
|
||||
this.explosiveDataList = baseUrlImage(module1);
|
||||
this.explosiveDataList = baseUrlImage(module1);
|
||||
const rankingDataObj = {
|
||||
'1': baseUrlImage(charts1),
|
||||
'2': baseUrlImage(charts2),
|
||||
'3': baseUrlImage(charts3),
|
||||
'4': baseUrlImage(charts4)
|
||||
}
|
||||
this.rankingDataList = rankingDataObj[this.headerListActive];
|
||||
this.rankingDataObj = rankingDataObj;
|
||||
this.popularityDataList = baseUrlImage(module3);
|
||||
this.originalDataList = baseUrlImage(module4);
|
||||
this.recommendDataList = baseUrlImage(module5);
|
||||
this.moreBooksList = baseUrlImage(module6);
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
})
|
||||
},
|
||||
handelRankingList(event) {
|
||||
const id = event.currentTarget.dataset.id;
|
||||
this.headerListActive = id;
|
||||
this.rankingDataList = this.rankingDataObj[id];
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.bookCity_content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
|
||||
.bookCity_content_body {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
flex-shrink: 0;
|
||||
|
||||
.scroll_y {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
.scroll_y_item {}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
83
pages/bookCity/components/home/explosiveList.vue
Normal file
83
pages/bookCity/components/home/explosiveList.vue
Normal file
@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<view class="explosiveList_content">
|
||||
<view class="_explosive_title">全网火爆</view>
|
||||
<view class="_explosive_list">
|
||||
<view class="_explosive_list_item" v-for="m in dataList" :key="m.id" @tap="toBooksReadingDetail(m)">
|
||||
<view class="_explosive_list_item_box">
|
||||
<CommBookItem :bookName="m.title" :bookTips="m.category_name" :bookImage="m.cover" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommBookItem from '@/components/commBookItem/index.vue'
|
||||
export default {
|
||||
name: 'explosiveList',
|
||||
components: {
|
||||
CommBookItem
|
||||
},
|
||||
props: {
|
||||
dataList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return []
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
toBooksReadingDetail(row) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/booksReadingDetail/booksReadingDetail?sid=${row.id}&t=${row.title}`
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.explosiveList_content {
|
||||
width: 100%;
|
||||
|
||||
._explosive_title {
|
||||
font-size: 36rpx;
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
._explosive_list {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
// justify-content: safe center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
._explosive_list_item {
|
||||
width: 200rpx;
|
||||
padding-top: 32rpx;
|
||||
margin-left: 32rpx;
|
||||
|
||||
._explosive_list_item_box {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
._explosive_list_item:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
._explosive_list_item:nth-child(4n + 0) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
294
pages/bookCity/components/home/index.vue
Normal file
294
pages/bookCity/components/home/index.vue
Normal file
@ -0,0 +1,294 @@
|
||||
<template>
|
||||
<view class="bookCity_home_content">
|
||||
<view class="my_x_skeleton" v-if="skeletonLoading">
|
||||
<x-skeleton type="banner" :loading="skeletonLoading" class="step_swiper_skeleton"></x-skeleton>
|
||||
<x-skeleton type="menu" :loading="skeletonLoading" class="step_operate_skeleton"
|
||||
:configs="{'gridRows': 1,'gridColumns':4, 'textWidth': '40%'}"></x-skeleton>
|
||||
<x-skeleton type="waterfall" :loading="skeletonLoading" class="step_explosive_skeleton"
|
||||
:configs="{'gridRows': 1,'gridColumns':3, 'headWidth': '100%', 'headHeight':'266rpx','headBorderRadius':'8rpx','textRows':2 ,'textRowsGap':'20rpx','textWidth':['100%','80%']}"></x-skeleton>
|
||||
<x-skeleton type="menu" :loading="skeletonLoading" class="step_ranking_skeleton"
|
||||
:configs="{'gridRows': 1,'gridColumns':4, 'headWidth': '100%', 'headHeight':'70rpx','textShow':false,'headBorderRadius':'8rpx','gridColumnsGap':'20rpx','padding':'15px 15px 0 15px'}"></x-skeleton>
|
||||
<x-skeleton type="menu" :loading="skeletonLoading" class="step_ranking_skeleton"
|
||||
:configs="{'gridRows': 2,'gridColumns':2, 'headWidth': '130rpx', 'headHeight':'180rpx','headBorderRadius':'8rpx','gridColumnsGap':'20rpx','itemDirection':'row', 'textRows':3,'textWidth':['100%','80%','60%'],'textRowsGap':'20rpx','gridRowsGap':'32rpx'}"></x-skeleton>
|
||||
<x-skeleton type="menu" :loading="skeletonLoading" class="step_ranking_skeleton"
|
||||
:configs="{'gridRows': 1,'gridColumns':1, 'headWidth': '100%', 'headHeight':'82rpx','headBorderRadius':'8rpx','textShow':false,'padding':'0 15px 15px 15px'}"></x-skeleton>
|
||||
</view>
|
||||
<view class="home_content_box" v-if="!skeletonLoading">
|
||||
<!-- 焦点图 -->
|
||||
<view class="step_swiper">
|
||||
<!-- style="height: 260rpx;" -->
|
||||
<u-swiper :list="swiperList" keyName="cover" indicator indicatorMode="line" circular></u-swiper>
|
||||
</view>
|
||||
<!--九宫格操作列表 -->
|
||||
<view class="step_operate">
|
||||
<u-grid :border="false" col="4">
|
||||
<u-grid-item v-for="(m,listIndex) in list" :key="listIndex" @click="toGridItemPath(m)">
|
||||
<u-icon :name="m.name" :size="34" />
|
||||
<text class="grid-text">{{m.title}}</text>
|
||||
</u-grid-item>
|
||||
</u-grid>
|
||||
</view>
|
||||
<!-- 全网火爆 -->
|
||||
<view class="step_explosive">
|
||||
<ExplosiveList :dataList="explosiveDataList" />
|
||||
</view>
|
||||
<view style="width: 100%">
|
||||
<u-gap height="14rpx" bgColor="#F6F6F6"></u-gap>
|
||||
</view>
|
||||
<!-- 榜单 -->
|
||||
<view class="step_ranking_list">
|
||||
<RankingList :dataList="rankingDataList" @handelRankingList="handelRankingList"
|
||||
:headerListActive="headerListActive" />
|
||||
</view>
|
||||
<view style="width: 100%">
|
||||
<u-gap height="14rpx" bgColor="#F6F6F6"></u-gap>
|
||||
</view>
|
||||
<!-- 人气作品 -->
|
||||
<view class="step_popularity_list">
|
||||
<PopularityList isTitle="人气作品" :dataList="popularityDataList" />
|
||||
</view>
|
||||
<view style="width: 100%">
|
||||
<u-gap height="14rpx" bgColor="#F6F6F6"></u-gap>
|
||||
</view>
|
||||
<!-- 原创优选 -->
|
||||
<view class="step_original_list">
|
||||
<OriginalList :dataList="originalDataList" />
|
||||
</view>
|
||||
<view style="width: 100%">
|
||||
<u-gap height="14rpx" bgColor="#F6F6F6"></u-gap>
|
||||
</view>
|
||||
<!-- 书友推荐 -->
|
||||
<view class="step_recommend_list">
|
||||
<RecommendList :dataList="recommendDataList" />
|
||||
</view>
|
||||
<view style="width: 100%">
|
||||
<u-gap height="14rpx" bgColor="#F6F6F6"></u-gap>
|
||||
</view>
|
||||
<!-- 人气作品 -->
|
||||
<view class="step_popularity_list step_more_list ">
|
||||
<PopularityList isTitle="更多书籍" :dataList="moreBooksList" />
|
||||
</view>
|
||||
<!-- 底部 -->
|
||||
<!-- <view class="step_footer">
|
||||
<CommFooter />
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import complete from '@/static/images/bookCity/complete.png';
|
||||
import new_book from '@/static/images/bookCity/new_book.png';
|
||||
import recharge from '@/static/images/bookCity/recharge.png';
|
||||
import the_charts from '@/static/images/bookCity/the_charts.png';
|
||||
import RankingList from './rankingList.vue'
|
||||
import PopularityList from './popularityList.vue'
|
||||
import ExplosiveList from './explosiveList.vue'
|
||||
import OriginalList from './originalList.vue'
|
||||
import RecommendList from './recommendList.vue'
|
||||
import CommFooter from '@/components/commFooter/index.vue'
|
||||
import config from '@/config/index';
|
||||
import {
|
||||
baseUrlImage
|
||||
} from '@/utils/utils'
|
||||
import {
|
||||
myGetStorage,
|
||||
} from '@/utils/storage/index.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
RankingList,
|
||||
PopularityList,
|
||||
ExplosiveList,
|
||||
OriginalList,
|
||||
RecommendList,
|
||||
CommFooter,
|
||||
},
|
||||
props: {
|
||||
explosiveDataList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
rankingDataList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
headerListActive: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
popularityDataList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
originalDataList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
recommendDataList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
moreBooksList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
swiperList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
skeletonLoading:{
|
||||
type: Boolean,
|
||||
default: () => {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
baseUrl: config.baseUrl,
|
||||
list: [{
|
||||
name: the_charts,
|
||||
title: '榜单',
|
||||
toPath: '/pages/booksTheCharts/index'
|
||||
},
|
||||
{
|
||||
name: complete,
|
||||
title: '完本',
|
||||
toPath: '/pages/booksListAll/index',
|
||||
type: 'complete'
|
||||
},
|
||||
{
|
||||
name: new_book,
|
||||
title: '新书',
|
||||
toPath: '/pages/booksListAll/index',
|
||||
type: 'new_book'
|
||||
},
|
||||
{
|
||||
name: recharge,
|
||||
title: '充值',
|
||||
toPath: '/pages/voucherCenter/index',
|
||||
type: 'recharge'
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toGridItemPath(row) {
|
||||
const token = myGetStorage('token');
|
||||
if (row.type == 'recharge' && !token) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/login/login?to=3`
|
||||
})
|
||||
} else if (row.toPath) {
|
||||
uni.navigateTo({
|
||||
url: `${row.toPath}?titleType=${row.type}`
|
||||
})
|
||||
}
|
||||
},
|
||||
handelRankingList(event) {
|
||||
this.$emit('handelRankingList', event)
|
||||
// const id = event.currentTarget.dataset.id;
|
||||
// this.headerListActive = id;
|
||||
// this.rankingDataList = this.rankingDataObj[id];
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.bookCity_home_content {
|
||||
// padding: 0 0 150rpx;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.my_x_skeleton {
|
||||
.step_swiper_skeleton {
|
||||
/deep/.x-skeleton__wrapper__head {
|
||||
height: 260rpx !important;
|
||||
}
|
||||
}
|
||||
|
||||
.step_operate_skeleton {
|
||||
/deep/.x-skeleton__wrapper__text {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.home_content_box {
|
||||
.step_swiper {
|
||||
width: 100%;
|
||||
padding: 0 32rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.step_operate {
|
||||
width: 100%;
|
||||
padding: 40rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.grid-text {
|
||||
font-size: 30rpx;
|
||||
color: #222222;
|
||||
}
|
||||
}
|
||||
|
||||
.step_explosive {
|
||||
width: 100%;
|
||||
padding: 0 32rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.step_ranking_list {
|
||||
width: 100%;
|
||||
padding: 40rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.step_popularity_list {
|
||||
width: 100%;
|
||||
padding: 40rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.step_original_list {
|
||||
width: 100%;
|
||||
padding: 40rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.step_recommend_list {
|
||||
width: 100%;
|
||||
padding: 40rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.step_footer {
|
||||
width: 100%;
|
||||
padding: 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.step_more_list {
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
83
pages/bookCity/components/home/originalList.vue
Normal file
83
pages/bookCity/components/home/originalList.vue
Normal file
@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<view class="originalList_content">
|
||||
<view class="originalList_content_header">
|
||||
<view class="_content_headertitle">原创优选</view>
|
||||
</view>
|
||||
<view class="originalList_content_body">
|
||||
<view class="_content_body_original_list">
|
||||
<view class="_original_list_item" v-for="m in dataList" :key="m.id" @tap="toBooksReadingDetail(m)">
|
||||
<OriginalBoolItem :bookName="m.title" :bookTips="m.category_name" :bookImage="m.cover" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import OriginalBoolItem from '@/components/originalBoolItem/index.vue'
|
||||
export default {
|
||||
components: {
|
||||
OriginalBoolItem,
|
||||
},
|
||||
props: {
|
||||
dataList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toBooksReadingDetail(row) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/booksReadingDetail/booksReadingDetail?sid=${row.id}&t=${row.title}`
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.originalList_content {
|
||||
width: 100%;
|
||||
|
||||
.originalList_content_header {
|
||||
width: 100%;
|
||||
|
||||
._content_headertitle {
|
||||
font-size: 36rpx;
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.originalList_content_body {
|
||||
width: 100%;
|
||||
|
||||
._content_body_original_list {
|
||||
display: flex;
|
||||
// justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
|
||||
._original_list_item {
|
||||
width: 150rpx;
|
||||
margin-top: 32rpx;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
._original_list_item:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
._original_list_item:nth-child(5n+0) {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
67
pages/bookCity/components/home/popularityList.vue
Normal file
67
pages/bookCity/components/home/popularityList.vue
Normal file
@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<view class="PopularityList_content">
|
||||
<view class="PopularityList_header">
|
||||
<view class="PopularityList_header_title">{{isTitle}}</view>
|
||||
</view>
|
||||
<view class="PopularityList_body">
|
||||
<view class="PopularityList_body_item" v-for="m in dataList" :key="m.id" @tap="toBooksReadingDetail(m)">
|
||||
<CommBookLeftRigth :bookTips="m.category_name" :bookName="m.title" :bookImage="m.cover" :bookIntroduction="m.intro"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommBookLeftRigth from '@/components/commBookLeftRigth/index.vue'
|
||||
export default {
|
||||
name:'PopularityList',
|
||||
components: {
|
||||
CommBookLeftRigth
|
||||
},
|
||||
props:{
|
||||
dataList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
isTitle: {
|
||||
type: String,
|
||||
default:''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
toBooksReadingDetail(row) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/booksReadingDetail/booksReadingDetail?sid=${row.id}&t=${row.title}`
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.PopularityList_content {
|
||||
width: 100%;
|
||||
|
||||
.PopularityList_header {
|
||||
width: 100%;
|
||||
|
||||
.PopularityList_header_title {
|
||||
font-size: 36rpx;
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.PopularityList_body {
|
||||
.PopularityList_body_item {
|
||||
margin-top: 32rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
242
pages/bookCity/components/home/rankingList.vue
Normal file
242
pages/bookCity/components/home/rankingList.vue
Normal file
@ -0,0 +1,242 @@
|
||||
<template>
|
||||
<view class="rankingList_content">
|
||||
<view class="rankingList_header">
|
||||
<scroll-view class="_header_list_scroll" scroll-x="true">
|
||||
<view class="_header_list" v-for="m in headerList" :key="m.id" @tap="handelRankingList" :data-id="m.id">
|
||||
<view :class="['_header_list_item',headerListActive == m.id ? 'active' : '']">
|
||||
{{m.name}}
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="rankingList_body">
|
||||
<view class="rankingList_body_box">
|
||||
<view class="_body_box_book_list">
|
||||
<view class="_book_list_item" v-for="(m,idx) in dataList" :key="m.id" @tap="toBooksReadingDetail(m)">
|
||||
<view class="_book_list_item_left">
|
||||
<image class="is_image" :src="m.cover"></image>
|
||||
<view class="_book_list_item_ranking_icon">
|
||||
<image class="is_image" :src="rankingIconList[idx]"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="_book_list_item_right">
|
||||
<view class="_book_list_item_title">{{m.title}}</view>
|
||||
<view class="_book_list_item_tips">{{m.category_name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="rankingList_more">
|
||||
<view class="rankingList_more_btn" @tap="toBooksTheCharts">
|
||||
查看全部
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ranking_one from '@/static/images/bookCity/ranking_one.png';
|
||||
import ranking_two from '@/static/images/bookCity/ranking_two.png';
|
||||
import ranking_three from '@/static/images/bookCity/ranking_three.png';
|
||||
import ranking_four from '@/static/images/bookCity/ranking_four.png';
|
||||
export default {
|
||||
props: {
|
||||
dataList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
headerListActive: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
headerList: [{
|
||||
id: '1',
|
||||
name: '人气榜'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: '畅销榜'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
name: '新书榜'
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
name: '完结榜'
|
||||
},
|
||||
],
|
||||
rankingIconList: [
|
||||
ranking_one,
|
||||
ranking_two,
|
||||
ranking_three,
|
||||
ranking_four
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handelRankingList(event) {
|
||||
this.$emit('handelRankingList', event);
|
||||
},
|
||||
toBooksReadingDetail(row) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/booksReadingDetail/booksReadingDetail?sid=${row.id}&t=${row.title}`
|
||||
})
|
||||
},
|
||||
toBooksTheCharts() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/booksTheCharts/index?chartsType=${this.headerListActive}`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.rankingList_content {
|
||||
width: 100%;
|
||||
|
||||
.rankingList_header {
|
||||
width: 100%;
|
||||
|
||||
._header_list_scroll {
|
||||
white-space: nowrap;
|
||||
|
||||
// width: 1000rpx;
|
||||
._header_list {
|
||||
// display: flex;
|
||||
display: inline-block;
|
||||
margin-left: 10rpx;
|
||||
|
||||
._header_list_item {
|
||||
width: 160rpx;
|
||||
height: 70rpx;
|
||||
text-align: center;
|
||||
line-height: 70rpx;
|
||||
background-color: #F6F6F6;
|
||||
border-radius: 8rpx;
|
||||
color: #666666;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
._header_list_item.active {
|
||||
color: #FC0538;
|
||||
background-color: #FFDCE3;
|
||||
}
|
||||
}
|
||||
|
||||
._header_list:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.rankingList_body {
|
||||
width: 100%;
|
||||
|
||||
.rankingList_body_box {
|
||||
width: 100%;
|
||||
|
||||
._body_box_book_list {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
._book_list_item {
|
||||
|
||||
display: flex;
|
||||
width: 50%;
|
||||
margin-top: 30rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
|
||||
._book_list_item_left {
|
||||
position: relative;
|
||||
width: 130rpx;
|
||||
height: 180rpx;
|
||||
flex: 0 0 auto;
|
||||
z-index: 2;
|
||||
border-radius: 8rpx;
|
||||
overflow: hidden;
|
||||
|
||||
._book_list_item_ranking_icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 3;
|
||||
width: 38rpx;
|
||||
height: 38rpx;
|
||||
}
|
||||
}
|
||||
|
||||
._book_list_item_right {
|
||||
flex: 1;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
margin-left: 16rpx;
|
||||
overflow: hidden;
|
||||
|
||||
._book_list_item_title {
|
||||
width: 100%;
|
||||
font-size: 30rpx;
|
||||
color: #1A1A1A;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
._book_list_item_tips {
|
||||
width: 100%;
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
._book_list_item:nth-child(2n) {
|
||||
padding-left: 15rpx;
|
||||
}
|
||||
|
||||
._book_list_item:nth-child(2n-1) {
|
||||
padding-right: 15rpx;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rankingList_more {
|
||||
width: 100%;
|
||||
margin-top: 32rpx;
|
||||
|
||||
.rankingList_more_btn {
|
||||
width: 100%;
|
||||
height: 82rpx;
|
||||
border-radius: 16rpx;
|
||||
background-color: #F1F1F1;
|
||||
color: #666666;
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
line-height: 82rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
78
pages/bookCity/components/home/recommendList.vue
Normal file
78
pages/bookCity/components/home/recommendList.vue
Normal file
@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<view class="explosiveList_content">
|
||||
<view class="_explosive_title">书友推荐</view>
|
||||
<view class="_explosive_list">
|
||||
<view class="_explosive_list_item" v-for="m in dataList" :key="m.id" @tap="toBooksReadingDetail(m)">
|
||||
<view class="_explosive_list_item_box">
|
||||
<CommBookItem :bookName="m.title" :bookTips="m.category_name" :bookImage="m.cover" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommBookItem from '@/components/commBookItem/index.vue'
|
||||
export default {
|
||||
components: {
|
||||
CommBookItem
|
||||
},
|
||||
props: {
|
||||
dataList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
toBooksReadingDetail(row) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/booksReadingDetail/booksReadingDetail?sid=${row.id}&t=${row.title}`
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.explosiveList_content {
|
||||
width: 100%;
|
||||
|
||||
._explosive_title {
|
||||
font-size: 36rpx;
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
._explosive_list {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
// justify-content: safe center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
._explosive_list_item {
|
||||
width: 200rpx;
|
||||
padding-top: 32rpx;
|
||||
margin-left: 32rpx;
|
||||
|
||||
._explosive_list_item_box {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
._explosive_list_item:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
._explosive_list_item:nth-child(4n + 0) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
63
pages/bookCity/components/member/index.vue
Normal file
63
pages/bookCity/components/member/index.vue
Normal file
@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<view class="member_content">
|
||||
<view class="step_member_user_info">
|
||||
<MemberUserInfo />
|
||||
</view>
|
||||
<!-- 会员专享 -->
|
||||
<view class="step_member_exclusive">
|
||||
<MemberExclusive />
|
||||
</view>
|
||||
<view style="width: 100%">
|
||||
<u-gap height="14rpx" bgColor="#F6F6F6"></u-gap>
|
||||
</view>
|
||||
<!-- 为你推荐 -->
|
||||
<view class="step_member_recommend">
|
||||
<MemberRecommend />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MemberUserInfo from './memberUserInfo.vue'
|
||||
import MemberExclusive from './memberExclusive.vue'
|
||||
import MemberRecommend from './memberRecommend.vue'
|
||||
export default {
|
||||
components: {
|
||||
MemberExclusive,
|
||||
MemberRecommend,
|
||||
MemberUserInfo
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.member_content {
|
||||
width: 100%;
|
||||
padding: 32rpx 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
.step_member_user_info {
|
||||
width: 100%;
|
||||
padding: 0 32rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.step_member_exclusive {
|
||||
width: 100%;
|
||||
padding: 0rpx 0 32rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.step_member_recommend {
|
||||
width: 100%;
|
||||
padding: 32rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
</style>
|
96
pages/bookCity/components/member/memberExclusive.vue
Normal file
96
pages/bookCity/components/member/memberExclusive.vue
Normal file
@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<view class="memberExclusive_content">
|
||||
<view class="exclusive_content_header">
|
||||
<view class="_header_title_all">
|
||||
<view class="_title_all_vip_image">
|
||||
<image class="is_image" src="/static/images/myInfo/VIP_active.png"></image>
|
||||
</view>
|
||||
<view class="_title_all_name">
|
||||
会员专享
|
||||
</view>
|
||||
</view>
|
||||
<view class="_header_tips">
|
||||
会员免费阅读
|
||||
</view>
|
||||
</view>
|
||||
<view class="exclusive_content_body">
|
||||
<view class="_content_body_list">
|
||||
<view class="_content_body_list_item" v-for="m in 6" :key="m">
|
||||
<CommBookItem />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommBookItem from '@/components/commBookItem/index.vue';
|
||||
export default {
|
||||
components: {
|
||||
CommBookItem
|
||||
},
|
||||
data() {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.memberExclusive_content {
|
||||
width: 100%;
|
||||
|
||||
.exclusive_content_header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding-right: 32rpx;
|
||||
|
||||
._header_title_all {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
._title_all_vip_image {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
}
|
||||
|
||||
._title_all_name {
|
||||
font-size: 36rpx;
|
||||
color: #F45576;
|
||||
line-height: 1;
|
||||
margin-left: 8rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
._header_tips {
|
||||
font-size: 26rpx;
|
||||
line-height: 1;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
.exclusive_content_body {
|
||||
width: 100%;
|
||||
|
||||
._content_body_list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
._content_body_list_item {
|
||||
width: 210rpx;
|
||||
margin-right: 28rpx;
|
||||
margin-top: 32rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
97
pages/bookCity/components/member/memberRecommend.vue
Normal file
97
pages/bookCity/components/member/memberRecommend.vue
Normal file
@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<view class="memberRecommend_content">
|
||||
<view class="recommend_content_header">
|
||||
<view class="_header_title_all">
|
||||
<view class="_title_all_vip_image">
|
||||
<image class="is_image" src="/static/images/myInfo/VIP_active.png"></image>
|
||||
</view>
|
||||
<view class="_title_all_name">
|
||||
为你推荐
|
||||
</view>
|
||||
</view>
|
||||
<view class="_header_tips">
|
||||
<!-- 会员免费阅读 -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="recommend_content_body">
|
||||
<view class="_content_body_list">
|
||||
<view class="_content_body_list_item" v-for="m in 8" :key="m">
|
||||
<commBookItemThree />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommBookItem from '@/components/commBookItem/index.vue';
|
||||
import commBookItemThree from '@/components/commBookItemThree/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CommBookItem,
|
||||
commBookItemThree
|
||||
},
|
||||
data() {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.memberRecommend_content {
|
||||
width: 100%;
|
||||
|
||||
.recommend_content_header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding-right: 32rpx;
|
||||
|
||||
._header_title_all {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
._title_all_vip_image {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
}
|
||||
|
||||
._title_all_name {
|
||||
font-size: 36rpx;
|
||||
color: #F45576;
|
||||
line-height: 1;
|
||||
margin-left: 8rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
._header_tips {
|
||||
font-size: 26rpx;
|
||||
line-height: 1;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
.recommend_content_body {
|
||||
width: 100%;
|
||||
|
||||
._content_body_list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
._content_body_list_item {
|
||||
margin-top: 32rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
32
pages/bookCity/components/member/memberUserInfo.vue
Normal file
32
pages/bookCity/components/member/memberUserInfo.vue
Normal file
@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<view class="memberUserInfo_centent">
|
||||
<view class="member_tips_info">
|
||||
<CommVipInfo />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommVipInfo from '@/components/commVipInfo/index.vue'
|
||||
export default {
|
||||
components: {
|
||||
CommVipInfo
|
||||
},
|
||||
data() {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.memberUserInfo_centent {
|
||||
width: 100%;
|
||||
|
||||
.member_tips_info {
|
||||
width: 100%;
|
||||
// height: 134rpx;
|
||||
// background: url('/static/images/bookCity/member_vip_bg.png') no-repeat;
|
||||
// background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
137
pages/bookCoinDetail/bookCoinDetail.vue
Normal file
137
pages/bookCoinDetail/bookCoinDetail.vue
Normal file
@ -0,0 +1,137 @@
|
||||
<template>
|
||||
<view class="bookCoinDetail_content">
|
||||
<view class="_list_body">
|
||||
<view class="_list_body_item">
|
||||
<view class="_item_book_img">
|
||||
<image class="is_image" src="/static/images/book_111.png"></image>
|
||||
</view>
|
||||
<view class="_item_book_title_other">
|
||||
<view class="_item_book_title">
|
||||
女主拿了反派剧本女主拿了反派剧本
|
||||
</view>
|
||||
<view class="_item_book_other_tips">
|
||||
整本
|
||||
</view>
|
||||
<view class="_item_book_purchase_time">
|
||||
购买时间:2022.03.14
|
||||
</view>
|
||||
</view>
|
||||
<view class="_item_book_coin_num">
|
||||
<view class="_coin_num">
|
||||
-6000书币
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="_list_body_item">
|
||||
<view class="_item_book_img">
|
||||
<image class="is_image" src="/static/images/book_111.png"></image>
|
||||
</view>
|
||||
<view class="_item_book_title_other">
|
||||
<view class="_item_book_title">
|
||||
女主拿了反派剧本女主拿了反派剧本
|
||||
</view>
|
||||
<view class="_item_book_other_tips">
|
||||
整本
|
||||
</view>
|
||||
<view class="_item_book_purchase_time">
|
||||
购买时间:2022.03.14
|
||||
</view>
|
||||
</view>
|
||||
<view class="_item_book_coin_num">
|
||||
<view class="_coin_num">
|
||||
-6000书币
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.bookCoinDetail_content {
|
||||
width: 100%;
|
||||
|
||||
._list_body {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 32rpx;
|
||||
|
||||
._list_body_item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 212rpx;
|
||||
overflow: hidden;
|
||||
margin-bottom: 32rpx;
|
||||
|
||||
._item_book_img {
|
||||
width: 160rpx;
|
||||
height: 100%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
._item_book_title_other {
|
||||
flex: 1;
|
||||
padding: 0 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
overflow: hidden;
|
||||
|
||||
._item_book_title {
|
||||
width: 100%;
|
||||
font-size: 32rpx;
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
white-space: nowrap; //不支持换行
|
||||
overflow: hidden; //隐藏多出部分文字
|
||||
text-overflow: ellipsis; //用省略号代替多出部分文字
|
||||
}
|
||||
|
||||
._item_book_other_tips {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
._item_book_purchase_time {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
line-height: 1;
|
||||
white-space: nowrap; //不支持换行
|
||||
overflow: hidden; //隐藏多出部分文字
|
||||
text-overflow: ellipsis; //用省略号代替多出部分文字
|
||||
}
|
||||
}
|
||||
|
||||
._item_book_coin_num {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
|
||||
._coin_num {
|
||||
font-size: 32rpx;
|
||||
color: #FF728F;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
236
pages/bookRecommendList/bookRecommendList.vue
Normal file
236
pages/bookRecommendList/bookRecommendList.vue
Normal file
@ -0,0 +1,236 @@
|
||||
<template>
|
||||
<view class="bookRecommendList_content">
|
||||
<view class="bookRecommendList_header">
|
||||
<view class="_header_chapter_num">
|
||||
已完结 共{{directoryCount}}章
|
||||
</view>
|
||||
<view class="_header_chapter_all_list" @tap="handelChapterShow">
|
||||
{{columnsLabel}}
|
||||
<u-icon name="arrow-down" color="#666666" size="28rpx"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bookRecommendList_body">
|
||||
<view class="chapter_list_box">
|
||||
<view :class="[`_list_item`,]" v-for="m in directory" :key="m.id" @tap="handelDirectoryItem(m)">
|
||||
<view :class="[`_item_name`,chapterorder == m.chapterorder ?'active':'']">
|
||||
{{m.chaptername}}
|
||||
</view>
|
||||
<view v-if="m.isvip" class="_item_chapter_lock">
|
||||
<image class="is_image" src="/static/images/chapter_lock.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="commFooter_box" v-if="commFooterFlag">
|
||||
<CommFooter />
|
||||
</view>
|
||||
<u-picker :show="chapterShow" :columns="columns" @confirm="confirmChapterPicker" @cancel="cancelChapterPicker"
|
||||
keyName="label"></u-picker>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommFooter from '@/components/commFooter/index.vue'
|
||||
export default {
|
||||
components: {
|
||||
CommFooter
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
columns: [],
|
||||
chapterShow: false,
|
||||
bookSid: '',
|
||||
pageNum: 1,
|
||||
startOrder: '',
|
||||
directory: [],
|
||||
directoryCount: 0,
|
||||
columnsLabel: '',
|
||||
commFooterFlag: false,
|
||||
barTitle: '',
|
||||
chapterorder: '',
|
||||
directoryAll: {}
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.bookSid = options.sid;
|
||||
this.barTitle = options.t;
|
||||
this.chapterorder = options.c;
|
||||
},
|
||||
onShow() {
|
||||
const bookSid = this.bookSid;
|
||||
const pageNum = this.pageNum;
|
||||
const barTitle = this.barTitle;
|
||||
uni.setNavigationBarTitle({
|
||||
title: barTitle,
|
||||
});
|
||||
this.isGetDirectory(bookSid, pageNum)
|
||||
},
|
||||
onReachBottom() {
|
||||
const bookSid = this.bookSid;
|
||||
const pageNum = this.pageNum + 1;
|
||||
this.pageNum = pageNum;
|
||||
this.isGetDirectory(bookSid, pageNum)
|
||||
},
|
||||
methods: {
|
||||
handelChapterShow() {
|
||||
this.chapterShow = true;
|
||||
},
|
||||
handelDirectoryItem(row) {
|
||||
const directoryAll = this.directoryAll;
|
||||
let flag = true;
|
||||
let chapterFlag = false;
|
||||
Object.keys(directoryAll).forEach((m) => {
|
||||
directoryAll[m].forEach((j) => {
|
||||
if(flag) {
|
||||
if (j.id != row.id && j.isvip == 1) {
|
||||
chapterFlag = true;
|
||||
}
|
||||
if (j.id == row.id) {
|
||||
flag = false
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
if(chapterFlag) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '前面章节未解锁,暂不支持跳章节观看',
|
||||
})
|
||||
return;
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: `/pages/novelReading/novelReading?sid=${this.bookSid}&n=${this.barTitle}&id=${row.id}`
|
||||
})
|
||||
},
|
||||
confirmChapterPicker(data) {
|
||||
this.chapterShow = false;
|
||||
const bookSid = this.bookSid;
|
||||
const pageNum = 1;
|
||||
this.startOrder = data.value[0].start;
|
||||
this.columnsLabel = data.value[0].label;
|
||||
this.pageNum = pageNum;
|
||||
this.isGetDirectory(bookSid, pageNum)
|
||||
},
|
||||
cancelChapterPicker() {
|
||||
this.chapterShow = false;
|
||||
},
|
||||
isGetDirectory(sid, page, startOrder) {
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
const data = {
|
||||
sid,
|
||||
page,
|
||||
}
|
||||
if (startOrder) {
|
||||
data.startOrder = startOrder;
|
||||
}
|
||||
uni.$u.http.post('/getDirectory', data).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
const directory = res.data.directory;
|
||||
const stage = res.data.stage;
|
||||
const directoryCount = res.data.directory_count;
|
||||
let columnsLabel = ''
|
||||
const columns = stage.map((m, idx) => {
|
||||
if (idx === 0 && !startOrder) {
|
||||
columnsLabel = `${m.start}-${m.end}`
|
||||
}
|
||||
return {
|
||||
...m,
|
||||
id: idx,
|
||||
label: `${m.start}-${m.end}`
|
||||
}
|
||||
})
|
||||
if (page == 1) {
|
||||
this.directory = directory;
|
||||
} else {
|
||||
this.directory = [...this.directory, ...directory];
|
||||
}
|
||||
this.directoryAll = {
|
||||
...this.directoryAll,
|
||||
[columnsLabel]: directory
|
||||
}
|
||||
this.commFooterFlag = directory.length ? false : true;
|
||||
this.columns = [columns];
|
||||
this.directoryCount = directoryCount;
|
||||
this.columnsLabel = columnsLabel;
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.bookRecommendList_content {
|
||||
width: 100%;
|
||||
padding: 32rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.bookRecommendList_header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
._header_chapter_num {
|
||||
font-size: 30rpx;
|
||||
color: #666666;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
._header_chapter_all_list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 30rpx;
|
||||
color: #666666;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.bookRecommendList_body {
|
||||
width: 100%;
|
||||
margin-top: 20rpx;
|
||||
|
||||
.chapter_list_box {
|
||||
width: 100%;
|
||||
|
||||
._list_item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 120rpx;
|
||||
border-bottom: 1rpx solid #F2F2F2;
|
||||
|
||||
._item_name {
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
._item_name.active {
|
||||
color: #FF728F;
|
||||
}
|
||||
|
||||
._item_chapter_lock {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.commFooter_box {
|
||||
padding: 32rpx 0;
|
||||
}
|
||||
}
|
||||
</style>
|
111
pages/booksListAll/index.vue
Normal file
111
pages/booksListAll/index.vue
Normal file
@ -0,0 +1,111 @@
|
||||
<template>
|
||||
<view class="booksListAll_content">
|
||||
<view class="booksListAll_list">
|
||||
<scroll-view scroll-y="true" class="scroll_y">
|
||||
<view class="scroll_y_item">
|
||||
<view class="booksListAll_list_item" v-for="m in booksList" :key="m.id"
|
||||
@tap="toBooksReadingDetail(m)">
|
||||
<CommBookLeftRigth :bookTips="m.category_name" :bookName="m.title" :bookImage="m.cover"
|
||||
:bookIntroduction="m.intro" />
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommBookLeftRigth from '@/components/commBookLeftRigth/index.vue';
|
||||
import {
|
||||
baseUrlImage
|
||||
} from '@/utils/utils'
|
||||
export default {
|
||||
components: {
|
||||
CommBookLeftRigth
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
booksList: []
|
||||
}
|
||||
},
|
||||
onLoad(query) {
|
||||
const titleType = query.titleType;
|
||||
const barTitleObj = {
|
||||
'complete': '完本书籍',
|
||||
'new_book': '热门新书'
|
||||
}
|
||||
const barTitle = titleType ? barTitleObj[titleType] : '书籍列表'
|
||||
uni.setNavigationBarTitle({
|
||||
title: barTitle,
|
||||
});
|
||||
let httpUrl = ''
|
||||
if (titleType == 'complete') {
|
||||
httpUrl = '/getIntact'
|
||||
} else if (titleType == 'new_book') {
|
||||
httpUrl = '/getNewbook'
|
||||
}
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
const parameter = {
|
||||
custom: {
|
||||
token: true
|
||||
}
|
||||
}
|
||||
uni.$u.http.post(httpUrl, {}, parameter).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
const {
|
||||
module
|
||||
} = res.data;
|
||||
this.booksList = baseUrlImage(module);
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
toBooksReadingDetail(row) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/booksReadingDetail/booksReadingDetail?sid=${row.id}&t=${row.title}`
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.booksListAll_content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 32rpx;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
/* 兼容 iOS 设备 */
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
/* 兼容 iPhone X 及以上设备 */
|
||||
|
||||
.booksListAll_list {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
.scroll_y {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
.scroll_y_item {
|
||||
padding-bottom: 32rpx;
|
||||
.booksListAll_list_item {
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
138
pages/booksReadingDetail/bookBasicInfo.vue
Normal file
138
pages/booksReadingDetail/bookBasicInfo.vue
Normal file
@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<view class="bookBasicInfo_content">
|
||||
<view class="bookBasicInfo_body">
|
||||
<view class="bookBasicInfo_body_left">
|
||||
<view class="book_cover_box">
|
||||
<image class="is_image" :src="bookInfo.cover"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bookBasicInfo_body_right">
|
||||
<view class="book_title">
|
||||
{{bookInfo.title}}
|
||||
</view>
|
||||
<view class="book_tips">
|
||||
{{bookInfo.author}}
|
||||
</view>
|
||||
<!-- <view class="book_vip">
|
||||
<view class="book_vip_txt">
|
||||
开通VIP会员,正版抢先看
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="book_type">
|
||||
<view class="book_type_item">
|
||||
{{bookInfo.category_name}}
|
||||
</view>
|
||||
<!-- <view class="book_type_item">
|
||||
穿越
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
bookInfo: {
|
||||
type: Object,
|
||||
default: {
|
||||
title: '',
|
||||
author: '',
|
||||
category_name: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.bookBasicInfo_content {
|
||||
width: 100%;
|
||||
|
||||
.bookBasicInfo_body {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
||||
.bookBasicInfo_body_left {
|
||||
.book_cover_box {
|
||||
width: 210rpx;
|
||||
height: 280rpx;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 8rpx;
|
||||
box-shadow: 0 0 8rpx rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.bookBasicInfo_body_right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding-left: 36rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.book_title {
|
||||
font-size: 44rpx;
|
||||
line-height: 1;
|
||||
color: #1A1A1D;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.book_tips {
|
||||
font-size: 28rpx;
|
||||
color: #6E6E6E;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.book_vip {
|
||||
display: flex;
|
||||
margin-top: 20rpx;
|
||||
|
||||
.book_vip_txt {
|
||||
padding: 0 20rpx;
|
||||
height: 40rpx;
|
||||
line-height: 40rpx;
|
||||
background: linear-gradient(to left, #F2D4A8, #F6DEC2);
|
||||
border-radius: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #9A7C62;
|
||||
}
|
||||
}
|
||||
|
||||
.book_type {
|
||||
display: flex;
|
||||
margin-top: 10rpx;
|
||||
|
||||
.book_type_item {
|
||||
padding: 0 20rpx;
|
||||
height: 52rpx;
|
||||
line-height: 52rpx;
|
||||
background: #F3F3F3;
|
||||
border-radius: 26rpx;
|
||||
font-size: 24rpx;
|
||||
color: #222222;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
126
pages/booksReadingDetail/bookChapterInfo.vue
Normal file
126
pages/booksReadingDetail/bookChapterInfo.vue
Normal file
@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<view class="bookChapterInfo_content">
|
||||
<view class="bookChapterInfo_body">
|
||||
<view class="bookChapterInfo_header">
|
||||
<view class="_header_title">
|
||||
查看目录
|
||||
</view>
|
||||
<view class="_header_chapter" @tap="toBookRecommendList">
|
||||
共{{directoryCount}}章
|
||||
<u-icon name="arrow-right" color="#666666" size="26rpx" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="bookChapterInfo_list_box">
|
||||
<view class="list_chapter_item" v-for="m in bookDirectory" :key="m.id">
|
||||
<view class="chapter_item_name">
|
||||
{{m.chaptername}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="_check_all_chapter" @tap="toBookRecommendList">
|
||||
查看全部
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
directoryCount: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
bookDirectory: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
bookSid: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
bookInfo: {
|
||||
type: Object,
|
||||
default: {
|
||||
title: '',
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toBookRecommendList() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/bookRecommendList/bookRecommendList?sid=${this.bookSid}&t=${this.bookInfo.title}`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bookChapterInfo_content {
|
||||
width: 100%;
|
||||
|
||||
.bookChapterInfo_body {
|
||||
width: 100%;
|
||||
|
||||
.bookChapterInfo_header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
._header_title {
|
||||
font-size: 36rpx;
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
._header_chapter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
.bookChapterInfo_list_box {
|
||||
margin-top: 20rpx;
|
||||
|
||||
.list_chapter_item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 106rpx;
|
||||
border-bottom: 2rpx solid #E5E5E5;
|
||||
|
||||
.chapter_item_name {
|
||||
font-size: 30rpx;
|
||||
color: #222222;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.list_chapter_item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
._check_all_chapter {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
background: #EEEEEE;
|
||||
color: #444444;
|
||||
font-size: 32rpx;
|
||||
border-radius: 8rpx;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
109
pages/booksReadingDetail/bookOtherInfo.vue
Normal file
109
pages/booksReadingDetail/bookOtherInfo.vue
Normal file
@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<view class="bookOtherInfo_content">
|
||||
<view class="bookOtherInfo_body">
|
||||
<view class="bookOtherInfo_item">
|
||||
<view class="bookOtherInfo_top">
|
||||
<view class="book_item_num">
|
||||
{{bookInfo.score}}
|
||||
</view>
|
||||
<view class="book_item_tex">
|
||||
评分
|
||||
</view>
|
||||
</view>
|
||||
<view class="bookOtherInfo_bottom">
|
||||
分数
|
||||
</view>
|
||||
</view>
|
||||
<view class="bookOtherInfo_item">
|
||||
<view class="bookOtherInfo_top">
|
||||
<view class="book_item_num">
|
||||
{{bookInfo.userNum}}
|
||||
</view>
|
||||
<view class="book_item_tex">
|
||||
万人
|
||||
</view>
|
||||
</view>
|
||||
<view class="bookOtherInfo_bottom">
|
||||
在读
|
||||
</view>
|
||||
</view>
|
||||
<view class="bookOtherInfo_item">
|
||||
<view class="bookOtherInfo_top">
|
||||
<view class="book_item_num">
|
||||
{{bookInfo.size}}
|
||||
</view>
|
||||
<view class="book_item_tex">
|
||||
万字
|
||||
</view>
|
||||
</view>
|
||||
<view class="bookOtherInfo_bottom">
|
||||
已完结
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
bookInfo: {
|
||||
type: Object,
|
||||
default: {
|
||||
// 字数
|
||||
size: '',
|
||||
// 评论
|
||||
score: '',
|
||||
// 在线人数
|
||||
userNum: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bookOtherInfo_content {
|
||||
width: 100%;
|
||||
|
||||
.bookOtherInfo_body {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
.bookOtherInfo_item {
|
||||
.bookOtherInfo_top {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
.book_item_num {
|
||||
font-size: 50rpx;
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
font-weight: 600;
|
||||
}
|
||||
.book_item_tex {
|
||||
margin-left: 4rpx;
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.bookOtherInfo_bottom {
|
||||
line-height: 1;
|
||||
color: #666666;
|
||||
font-size: 26rpx;
|
||||
margin-top: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
103
pages/booksReadingDetail/bookRecommendInfo.vue
Normal file
103
pages/booksReadingDetail/bookRecommendInfo.vue
Normal file
@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<view class="bookRecommendInfo_content">
|
||||
<view class="bookRecommendInfo_box">
|
||||
<view class="_header_box">
|
||||
<view class="_header_box_title">
|
||||
推荐书籍
|
||||
</view>
|
||||
</view>
|
||||
<view class="_body_list_box">
|
||||
<view class="_body_list">
|
||||
<view class="_body_list_item" v-for="m in recommendBooks" :key="m.id">
|
||||
<view class="_item_book_over">
|
||||
<image class="is_image" :src="m.cover"></image>
|
||||
</view>
|
||||
<view class="_item_book_name">
|
||||
{{m.title}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
recommendBooks: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.bookRecommendInfo_content {
|
||||
width: 100%;
|
||||
|
||||
.bookRecommendInfo_box {
|
||||
width: 100%;
|
||||
|
||||
._header_box {
|
||||
width: 100%;
|
||||
|
||||
._header_box_title {
|
||||
font-size: 36rpx;
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
._body_list_box {
|
||||
width: 100%;
|
||||
|
||||
._body_list {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
._body_list_item {
|
||||
width: 202rpx;
|
||||
margin-right: 32rpx;
|
||||
|
||||
._item_book_over {
|
||||
width: 202rpx;
|
||||
height: 270rpx;
|
||||
border-radius: 8rpx;
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
|
||||
._item_book_name {
|
||||
width: 100%;
|
||||
margin-top: 24rpx;
|
||||
font-size: 30rpx;
|
||||
line-height: 1;
|
||||
color: #1A1A1A;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
._body_list_item:nth-child(3n+0) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
72
pages/booksReadingDetail/bookSynopsisInfo.vue
Normal file
72
pages/booksReadingDetail/bookSynopsisInfo.vue
Normal file
@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<view class="bookSynopsisInfo_content">
|
||||
<view class="bookSynopsisInfo_body">
|
||||
<view class="bookSynopsisInfo_title">
|
||||
书籍简介
|
||||
</view>
|
||||
<view class="bookSynopsisInfo_box">
|
||||
<u-read-more ref="uReadMore" showHeight="200rpx" fontSize="30rpx" :toggle="true" closeText="展开"
|
||||
openText="收起" color="#FF728F">
|
||||
<u-parse :content="bookInfo.intro" @load="load"></u-parse>
|
||||
</u-read-more>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
bookInfo: {
|
||||
type: Object,
|
||||
default: {
|
||||
intro: '',
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// content: '叶家小神医叶明沁带着自家二哈哥哥穿越了!开局不打怪, 不宅斗, 而是…… 逃荒!可怜叶家兄妹从小锦衣玉食, 这下没了父母留下的巨额遗产, 两兄妹相依为命, 孤苦伶仃……但是, 没了遗产, 咱有金手指, 随拿随补充的综合商城和酒窖, 兄妹俩不仅不会孤苦伶仃, 还完全可以混吃等死。'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
this.$refs.uReadMore.init();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bookSynopsisInfo_box::v-deep.u-read-more__content__inner {
|
||||
span {
|
||||
line-height: 1.8;
|
||||
}
|
||||
}
|
||||
|
||||
.bookSynopsisInfo_box::v-deep.u-read-more__toggle {
|
||||
justify-content: flex-end;
|
||||
.u-text__value {
|
||||
font-size: 26rpx !important;
|
||||
}
|
||||
}
|
||||
|
||||
.bookSynopsisInfo_content {
|
||||
width: 100%;
|
||||
|
||||
.bookSynopsisInfo_body {
|
||||
width: 100%;
|
||||
|
||||
.bookSynopsisInfo_title {
|
||||
color: #1A1A1A;
|
||||
line-height: 1;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
.bookSynopsisInfo_box {
|
||||
margin-top: 30rpx;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
262
pages/booksReadingDetail/booksReadingDetail.vue
Normal file
262
pages/booksReadingDetail/booksReadingDetail.vue
Normal file
@ -0,0 +1,262 @@
|
||||
<template>
|
||||
<view class="booksReadingDetail_content">
|
||||
<view class="step_book_basic_info">
|
||||
<view class="step_book_basic_info_comm">
|
||||
<BookBasicInfo :bookInfo="bookInfo" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="step_book_other_info">
|
||||
<view class="step_book_other_info_comm">
|
||||
<BookOtherInfo :bookInfo="bookInfo" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="step_book_synopsis_info">
|
||||
<view class="step_book_synopsis_info_comm">
|
||||
<BookSynopsisInfo :bookInfo="bookInfo" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="step_book_chapter_info">
|
||||
<view class="step_book_chapter_info_comm">
|
||||
<BookChapterInfo :directoryCount="directoryCount" :bookDirectory="bookDirectory" :bookSid="bookSid"
|
||||
:bookInfo="bookInfo" />
|
||||
</view>
|
||||
</view>
|
||||
<view style="width: 100%">
|
||||
<u-gap height="14rpx" bgColor="#F6F6F6"></u-gap>
|
||||
</view>
|
||||
<view class="step_book_recommend_info">
|
||||
<view class="step_book_recommend_info_comm">
|
||||
<BookRecommendInfo :recommendBooks="recommendBooks" :bookSid="bookSid" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="step_book_button_info">
|
||||
<view class="step_book_button_info_comm">
|
||||
<view v-if="!bookcase" class="_add_book_shelf" @tap="addBookshelf">
|
||||
加入书架
|
||||
</view>
|
||||
<view v-else class="_add_book_shelf active">
|
||||
已加书架
|
||||
</view>
|
||||
<view class="_start_read_book" @tap="toNovelReading">
|
||||
开始阅读
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BookBasicInfo from './bookBasicInfo.vue';
|
||||
import BookOtherInfo from './bookOtherInfo.vue';
|
||||
import BookSynopsisInfo from './bookSynopsisInfo.vue';
|
||||
import BookChapterInfo from './bookChapterInfo.vue';
|
||||
import BookRecommendInfo from './bookRecommendInfo.vue';
|
||||
import config from '@/config/index';
|
||||
import {
|
||||
baseUrlImage
|
||||
} from '@/utils/utils'
|
||||
export default {
|
||||
components: {
|
||||
BookBasicInfo,
|
||||
BookOtherInfo,
|
||||
BookSynopsisInfo,
|
||||
BookChapterInfo,
|
||||
BookRecommendInfo
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
bookSid: '',
|
||||
bookDirectory: [],
|
||||
recommendBooks: [],
|
||||
bookInfo: {},
|
||||
directoryCount: 0,
|
||||
bookcase: 0
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.bookSid = options.sid
|
||||
},
|
||||
onShow() {
|
||||
const bookSid = this.bookSid
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
const data = {
|
||||
sid: bookSid,
|
||||
}
|
||||
uni.$u.http.post('/bookdetails', data).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
const directory = res.data.directory;
|
||||
const info = res.data.info;
|
||||
const module = res.data.module;
|
||||
const directory_count = res.data.directory_count;
|
||||
const bookcase = res.data.bookcase;
|
||||
this.bookDirectory = directory;
|
||||
this.recommendBooks = baseUrlImage(module);
|
||||
this.directoryCount = directory_count;
|
||||
this.bookcase = bookcase
|
||||
const cover = info.cover.includes('http') ? info.cover : `${config.baseUrl}${info.cover}`;
|
||||
this.bookInfo = {
|
||||
...info,
|
||||
cover
|
||||
};
|
||||
console.log(res, this.bookInfo, "=======")
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
addBookshelf() {
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
const data = {
|
||||
sid: this.bookSid,
|
||||
}
|
||||
uni.$u.http.post('/addBookshelf', data).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
uni.showToast({
|
||||
title: '加入成功',
|
||||
icon: 'none'
|
||||
})
|
||||
this.bookcase = 1;
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
})
|
||||
},
|
||||
toNovelReading() {
|
||||
const bookInfo = this.bookInfo;
|
||||
uni.navigateTo({
|
||||
url: `/pages/novelReading/novelReading?sid=${bookInfo.id}`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.booksReadingDetail_content {
|
||||
width: 100%;
|
||||
// padding-bottom: 130rpx;
|
||||
padding-bottom: calc(constant(safe-area-inset-bottom) + 90px); /* 兼容 iOS 设备 */
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 90px); /* 兼容 iPhone X 及以上设备 */
|
||||
|
||||
.step_book_basic_info {
|
||||
width: 100%;
|
||||
padding: 0 32rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.step_book_basic_info_comm {
|
||||
width: 100%;
|
||||
padding: 32rpx 0;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 2rpx solid #E5E5E5;
|
||||
}
|
||||
}
|
||||
|
||||
.step_book_other_info {
|
||||
width: 100%;
|
||||
padding: 0 32rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.step_book_other_info_comm {
|
||||
width: 100%;
|
||||
padding: 32rpx 0;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 2rpx solid #E5E5E5;
|
||||
}
|
||||
}
|
||||
|
||||
.step_book_synopsis_info {
|
||||
width: 100%;
|
||||
padding: 0 32rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.step_book_synopsis_info_comm {
|
||||
width: 100%;
|
||||
padding: 32rpx 0;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 2rpx solid #E5E5E5;
|
||||
}
|
||||
}
|
||||
|
||||
.step_book_chapter_info {
|
||||
width: 100%;
|
||||
padding: 0 32rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.step_book_chapter_info_comm {
|
||||
width: 100%;
|
||||
padding: 32rpx 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
.step_book_recommend_info {
|
||||
width: 100%;
|
||||
padding: 0 32rpx;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 32rpx;
|
||||
|
||||
.step_book_recommend_info_comm {
|
||||
width: 100%;
|
||||
padding: 32rpx 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
.step_book_button_info {
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background-color: #fff;
|
||||
border-top: 1rpx solid #E5E5E5;
|
||||
padding-bottom: constant(safe-area-inset-bottom); /* 兼容 iOS 设备 */
|
||||
padding-bottom: env(safe-area-inset-bottom); /* 兼容 iPhone X 及以上设备 */
|
||||
|
||||
.step_book_button_info_comm {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
padding: 14rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
._add_book_shelf {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 328rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 10rpx;
|
||||
border: 2rpx solid #1A1A1A;
|
||||
box-sizing: border-box;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
|
||||
.active {
|
||||
font-size: 36rpx;
|
||||
color: #999999;
|
||||
border-color: #999999;
|
||||
}
|
||||
|
||||
._start_read_book {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 328rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 10rpx;
|
||||
color: #fff;
|
||||
background: linear-gradient(to left, #FF728F, #FF4D71);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
227
pages/booksSearchList/booksSearchList.vue
Normal file
227
pages/booksSearchList/booksSearchList.vue
Normal file
@ -0,0 +1,227 @@
|
||||
<template>
|
||||
<view class="booksSearchList_content">
|
||||
<view v-if="!searchFlag">
|
||||
<view class="step_search_box">
|
||||
<view class="search_box_con">
|
||||
<u-search v-model="bookKeyword" placeholder="输入您想看的小说" height="80rpx" :showAction="false"
|
||||
bgColor="#F3F4F6" @clear="clearBookKeyword" confirmType="search"></u-search>
|
||||
<view class="search_button" @tap="handelSearch">
|
||||
<text>搜索</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="!searchBooksData.length">
|
||||
<view class="search_record_box">
|
||||
<view class="search_popular_record">
|
||||
<SearchRecord searchRecordTitle="热门搜索" :dataList="searchRecordList"
|
||||
@handelSearchRecord="handelSearchRecord" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="search_history_box">
|
||||
<view class="search_history_record">
|
||||
<SearchRecord @handelDel="searchHistoryDel" :headerRightDelete="true" searchRecordTitle="历史搜索"
|
||||
:dataList="searchHistoryList" @handelSearchRecord="handelSearchRecord" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="search_books_body" v-else>
|
||||
<view class="search_books_list">
|
||||
<view class="search_books_list_item" v-for="m in searchBooksData" :key="m.id">
|
||||
<CommBookItemThree :bookTips="m.category_name" :bookName="m.title" :bookImage="m.cover"
|
||||
:bookIntroduction="m.intro" :bookId="m.id" :bookcase="bookcase"
|
||||
@addBookshelf="addBookshelf" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<u-empty :icon="search_empty" width="504rpx" text="未找到小说,正在努力产出中..." />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SearchRecord from './searchRecord.vue'
|
||||
import CommBookItemThree from '@/components/commBookItemThree/index.vue'
|
||||
import search_empty from '@/static/images/search_empty.png'
|
||||
import {
|
||||
myGetStorage,
|
||||
mySetStorage
|
||||
} from '@/utils/storage/index.js'
|
||||
import {
|
||||
baseUrlImage
|
||||
} from '@/utils/utils'
|
||||
export default {
|
||||
components: {
|
||||
SearchRecord,
|
||||
CommBookItemThree
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
search_empty: search_empty,
|
||||
searchRecordList: [],
|
||||
searchFlag: false,
|
||||
bookKeyword: '',
|
||||
searchHistoryList: [],
|
||||
searchBooksData: [],
|
||||
bookcase: 0
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
const parameter = {
|
||||
custom: {
|
||||
token: true
|
||||
}
|
||||
}
|
||||
uni.$u.http.post('/getSearchTags', {}, parameter).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
const {
|
||||
module
|
||||
} = res.data;
|
||||
this.searchRecordList = module;
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
})
|
||||
this.getAndSetSearchHistory();
|
||||
},
|
||||
methods: {
|
||||
searchHistoryDel() {
|
||||
mySetStorage('searchHistory', JSON.stringify([]));
|
||||
this.searchHistoryList = [];
|
||||
},
|
||||
getSearchBooks(keyword) {
|
||||
if (!keyword) {
|
||||
uni.showToast({
|
||||
title: '请先输入您想看的小说',
|
||||
icon: 'none'
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
uni.showLoading({
|
||||
title: '搜索中...'
|
||||
});
|
||||
|
||||
const data = {
|
||||
keyword,
|
||||
}
|
||||
|
||||
uni.$u.http.post('/getSearch', data).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
const {
|
||||
module,
|
||||
bookcase
|
||||
} = res.data;
|
||||
// this.searchRecordList = module;
|
||||
this.bookcase = bookcase;
|
||||
this.searchBooksData = baseUrlImage([module]);
|
||||
this.getAndSetSearchHistory(keyword);
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
})
|
||||
},
|
||||
handelSearch() {
|
||||
const bookKeyword = this.bookKeyword;
|
||||
this.getSearchBooks(bookKeyword);
|
||||
},
|
||||
getAndSetSearchHistory(keyword) {
|
||||
const searchHistoryList = myGetStorage('searchHistory') || '[]';
|
||||
const list = JSON.parse(searchHistoryList);
|
||||
let temp = list;
|
||||
if (keyword) {
|
||||
temp = [{
|
||||
id: Math.random(),
|
||||
title: keyword
|
||||
}, ...list]
|
||||
if (temp.length > 10) {
|
||||
temp.splice(11, temp.length - 10)
|
||||
}
|
||||
mySetStorage('searchHistory', JSON.stringify(temp))
|
||||
}
|
||||
this.searchHistoryList = temp
|
||||
},
|
||||
handelSearchRecord(event) {
|
||||
const title = event.currentTarget.dataset.title;
|
||||
this.bookKeyword = title;
|
||||
this.getSearchBooks(title);
|
||||
},
|
||||
addBookshelf() {
|
||||
this.bookcase = 1;
|
||||
},
|
||||
clearBookKeyword() {
|
||||
this.searchBooksData = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.booksSearchList_content {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 32rpx;
|
||||
|
||||
.step_search_box {
|
||||
width: 100%;
|
||||
|
||||
.search_box_con {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #F3F4F6;
|
||||
border-radius: 40rpx;
|
||||
|
||||
.search_button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 136rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
background-color: #FF728F;
|
||||
border-radius: 40rpx;
|
||||
font-size: 36rpx;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search_record_box {
|
||||
width: 100%;
|
||||
|
||||
.search_popular_record {
|
||||
width: 100%;
|
||||
padding: 32rpx 0;
|
||||
}
|
||||
}
|
||||
|
||||
.search_history_box {
|
||||
width: 100%;
|
||||
|
||||
.search_history_record {
|
||||
width: 100%;
|
||||
padding: 32rpx 0;
|
||||
}
|
||||
}
|
||||
|
||||
.search_books_body {
|
||||
width: 100%;
|
||||
|
||||
.search_books_list {
|
||||
width: 100%;
|
||||
|
||||
.search_books_list_item {
|
||||
margin-top: 32rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
98
pages/booksSearchList/searchRecord.vue
Normal file
98
pages/booksSearchList/searchRecord.vue
Normal file
@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<view class="searchRecord_content">
|
||||
<view class="searchRecord_content_header">
|
||||
<view class="_header_title">
|
||||
{{searchRecordTitle}}
|
||||
</view>
|
||||
<view class="_header_right">
|
||||
<view class="_header_right_delete_icon" v-if="headerRightDelete" @tap="handelDelSearch">
|
||||
<!-- delete_icon.png -->
|
||||
<image class="is_image" src="/static/images/delete_icon.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="searchRecord_list">
|
||||
<view class="searchRecord_list_item" v-for="m in dataList" :key="m.id" :data-title="m.title" @tap="handelSearchRecord">
|
||||
<text>{{m.title}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
searchRecordTitle: {
|
||||
type: String,
|
||||
default: '热门搜索'
|
||||
},
|
||||
headerRightDelete: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
dataList: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handelDelSearch() {
|
||||
this.$emit('handelDel')
|
||||
},
|
||||
handelSearchRecord(e) {
|
||||
this.$emit('handelSearchRecord',e)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.is_image {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.searchRecord_content {
|
||||
width: 100%;
|
||||
|
||||
.searchRecord_content_header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
._header_title {
|
||||
font-size: 30rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
._header_right_delete_icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.searchRecord_list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
|
||||
.searchRecord_list_item {
|
||||
height: 56rpx;
|
||||
line-height: 56rpx;
|
||||
padding: 0 16rpx;
|
||||
background-color: #F3F4F6;
|
||||
color: #333333;
|
||||
font-size: 28rpx;
|
||||
border-radius: 12rpx;
|
||||
margin-top: 30rpx;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
388
pages/booksTheCharts/index.vue
Normal file
388
pages/booksTheCharts/index.vue
Normal file
@ -0,0 +1,388 @@
|
||||
<template>
|
||||
<view class="booksTheCharts_content">
|
||||
<u-navbar title="排行榜" bgColor="transparent" leftIconColor="#000" @leftClick="navbarLeftClick"
|
||||
:placeholder="true" :safeAreaInsetTop="true" />
|
||||
<!-- <uni-nav-bar title="排行榜" :border="false" backgroundColor="transparent" leftIcon="back" @clickLeft="navbarLeftClick">
|
||||
</uni-nav-bar> -->
|
||||
<view class="booksTheCharts_header_bag"></view>
|
||||
<!-- :style="`height:${booksTheChartsContentHeigth}px`"-->
|
||||
<view class="booksTheCharts_content_body">
|
||||
<view class="booksTheCharts_body_btn_list">
|
||||
<scroll-view scroll-x="true" class="btn_list_scroll_view">
|
||||
<view :class="[`btn_list_scroll_view_item`,oneTitleActive == m.id ?'active':''] "
|
||||
v-for="m in oneTitleList" :key="m.id" :data-id="m.id" @tap="handelOneTitle">{{m.title}}</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="booksTheCharts_main_body">
|
||||
<view class="_main_body_title_list">
|
||||
<!-- :style="`height:${titleListscroll}px`" -->
|
||||
<scroll-view scroll-y="true" class="_title_list_scroll_view">
|
||||
<view :class="['_title_list_scroll_view_item',m.id == twoTitleActive ? 'active':'']"
|
||||
v-for="(m,idx) in twoTitleList" :key="m.id" :data-id="m.id" @tap="handelTwoTitle">
|
||||
{{m.name}}
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="_main_body_book_list">
|
||||
<!-- :style="`height:${titleListscroll}px`" -->
|
||||
<scroll-view scroll-y="true" class="_book_list_scroll_view">
|
||||
<view :class="['_book_list_scroll_view_item']" v-for="(m,idx) in booksList" :key="m.id"
|
||||
@tap="toBooksReadingDetail(m)">
|
||||
<view class="scroll_view_item_book_image">
|
||||
<image class="is_image" :src="m.cover"></image>
|
||||
</view>
|
||||
<view class="scroll_view_item_book_tips">
|
||||
<view class="_book_tips_title">
|
||||
{{m.title}}
|
||||
</view>
|
||||
<view class="_book_tips_msg">
|
||||
{{m.category_name}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="_book_list_scroll_view_empty">
|
||||
<CommFooter />
|
||||
</view> -->
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
isGetSystemInfo
|
||||
} from '@/utils/systemInfo.js'
|
||||
import CommFooter from '@/components/commFooter/index.vue'
|
||||
import {
|
||||
baseUrlImage
|
||||
} from '@/utils/utils'
|
||||
export default {
|
||||
components: {
|
||||
CommFooter
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
booksTheChartsContentHeigth: 0,
|
||||
titleListscroll: 0,
|
||||
booksList: [],
|
||||
oneTitleList: [],
|
||||
twoTitleList: [{
|
||||
id: '0',
|
||||
name: '全部'
|
||||
},
|
||||
{
|
||||
id: '1',
|
||||
name: '人气榜'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: '畅销版'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
name: '新书榜'
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
name: '完结版'
|
||||
}
|
||||
],
|
||||
twoTitleActive: '0',
|
||||
oneTitleActive: '0',
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
const {
|
||||
windowHeight,
|
||||
screenHeight,
|
||||
statusBarHeight,
|
||||
devicePixelRatio
|
||||
} = isGetSystemInfo();
|
||||
this.booksTheChartsContentHeigth = screenHeight - statusBarHeight;
|
||||
this.twoTitleActive = options.chartsType ? options.chartsType : '0';
|
||||
// #ifdef APP-PLUS
|
||||
this.titleListscroll = screenHeight - statusBarHeight;
|
||||
// #endif
|
||||
// #ifdef H5 || MP-WEIXIN
|
||||
this.titleListscroll = screenHeight - statusBarHeight - devicePixelRatio * 55;
|
||||
// #endif
|
||||
|
||||
},
|
||||
onShow() {
|
||||
//
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
const data = {}
|
||||
uni.$u.http.post('/getCategory', data).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
const list = res.data.list;
|
||||
this.oneTitleList = [{
|
||||
id: '0',
|
||||
title: '全部'
|
||||
}, ...list];
|
||||
}
|
||||
this.getBooks(this.twoTitleActive, 0);
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
this.getBooks(this.twoTitleActive, 0);
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
navbarLeftClick() {
|
||||
uni.navigateBack()
|
||||
},
|
||||
getBooks(type, category_id) {
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
const parameter = {
|
||||
custom: {
|
||||
token: true
|
||||
}
|
||||
}
|
||||
const data = {
|
||||
type,
|
||||
category_id,
|
||||
}
|
||||
uni.$u.http.post('/getChartsCategory', data, parameter).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
const {
|
||||
module
|
||||
} = res.data;
|
||||
this.booksList = baseUrlImage(module);
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
})
|
||||
},
|
||||
handelTwoTitle(event) {
|
||||
const id = event.currentTarget.dataset.id;
|
||||
this.twoTitleActive = id;
|
||||
this.getBooks(id, this.oneTitleActive);
|
||||
},
|
||||
toBooksReadingDetail(row) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/booksReadingDetail/booksReadingDetail?sid=${row.id}&t=${row.title}`
|
||||
})
|
||||
},
|
||||
handelOneTitle(event) {
|
||||
const id = event.currentTarget.dataset.id;
|
||||
this.oneTitleActive = id;
|
||||
this.getBooks(this.twoTitleActive, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
::v-deep.u-navbar__content__title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.booksTheCharts_content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
.uni-navbar {
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.booksTheCharts_header_bag {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 330rpx;
|
||||
background: linear-gradient(to left bottom, rgba(252, 194, 202, 0.5), rgba(253, 255, 227, 0.5));
|
||||
|
||||
}
|
||||
|
||||
.booksTheCharts_content_body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.booksTheCharts_body_btn_list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 110rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 0 32rpx;
|
||||
flex: 0 0 auto;
|
||||
position: relative;
|
||||
|
||||
.btn_list_scroll_view {
|
||||
white-space: nowrap;
|
||||
|
||||
.btn_list_scroll_view_item {
|
||||
display: inline-block;
|
||||
background-color: transparent;
|
||||
height: 64rpx;
|
||||
padding: 0 16rpx;
|
||||
color: #222222;
|
||||
line-height: 64rpx;
|
||||
margin-left: 16rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.btn_list_scroll_view_item.active {
|
||||
background-color: #FF728F;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn_list_scroll_view_item:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.booksTheCharts_main_body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
border-top: 2rpx solid #E5E5E5;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
box-sizing: border-box;
|
||||
|
||||
._main_body_title_list {
|
||||
|
||||
width: 160rpx;
|
||||
height: 100%;
|
||||
background-color: #F1EEEC;
|
||||
flex: 0 0 auto;
|
||||
position: relative;
|
||||
|
||||
._title_list_scroll_view {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
._title_list_scroll_view_item {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 124rpx;
|
||||
text-align: center;
|
||||
line-height: 124rpx;
|
||||
color: #666666;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
._title_list_scroll_view_item.active {
|
||||
background-color: #fff;
|
||||
color: #FF728F;
|
||||
}
|
||||
|
||||
._title_list_scroll_view_item.active::before {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
content: '';
|
||||
width: 6rpx;
|
||||
height: 124rpx;
|
||||
background-color: #FF728F;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
._main_body_book_list {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
|
||||
|
||||
._book_list_scroll_view {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 32rpx 32rpx 0;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
/* 兼容 iOS 设备 */
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
/* 兼容 iPhone X 及以上设备 */
|
||||
box-sizing: border-box;
|
||||
|
||||
._book_list_scroll_view_item {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding-bottom: 32rpx;
|
||||
|
||||
.scroll_view_item_book_image {
|
||||
width: 128rpx;
|
||||
height: 170rpx;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 8rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0 8rpx rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.scroll_view_item_book_tips {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
padding-left: 28rpx;
|
||||
overflow: hidden;
|
||||
|
||||
._book_tips_title {
|
||||
font-size: 30rpx;
|
||||
line-height: 1;
|
||||
color: #1A1A1A;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
._book_tips_msg {
|
||||
font-size: 28rpx;
|
||||
line-height: 1;
|
||||
color: #999999;
|
||||
// white-space: nowrap;
|
||||
// overflow: hidden;
|
||||
// text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
._book_list_scroll_view_empty {
|
||||
width: 100%;
|
||||
height: 60rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
488
pages/bookshelf/bookshelf/bookshelfListBody.vue
Normal file
488
pages/bookshelf/bookshelf/bookshelfListBody.vue
Normal file
@ -0,0 +1,488 @@
|
||||
<template>
|
||||
<view class="bookshelfListBody_content">
|
||||
<view class="bookshelfListBody_content_header">
|
||||
<view class="_header_left">
|
||||
<view class="_header_name" v-if="!swipeActionBatch">
|
||||
列表
|
||||
</view>
|
||||
<view class="_header_name" v-else-if="swipeActionBatch">
|
||||
<u-checkbox-group @change="handelbookBatch" v-model="delCheckedAll">
|
||||
<u-checkbox activeColor="#FF728F" labelSize="32rpx" labelColor="#1A1A1A" label="全选"
|
||||
name="all" />
|
||||
</u-checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
<view class="_header_right">
|
||||
<view class="_header_right_edit" @tap="handelSwipeBatch" v-if="!swipeActionBatch">
|
||||
批量编辑
|
||||
</view>
|
||||
<view class="_header_right_confim" v-else-if="swipeActionBatch" @tap="bathComplete">
|
||||
完成
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bookshelfListBody_content_body">
|
||||
<view class="_content_body_list">
|
||||
<view class="_swipe_action_box" @longpress="swipeActionLongpress(m)" v-for="m in bookshelfList"
|
||||
:key="m.id">
|
||||
<view class="_swipe_action_box_book_image">
|
||||
<image class="is_image" :src="m.cover" />
|
||||
</view>
|
||||
<view class="_swipe_action_book_info">
|
||||
<view class="_book_info_title">
|
||||
{{m.title}}
|
||||
</view>
|
||||
<view class="_book_info_chapter">
|
||||
{{m.history_txt}}
|
||||
</view>
|
||||
<view class="_book_info_tips">
|
||||
{{m.txt}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="_swipe_action_book_button" v-if="swipeActionList.indexOf(m.id) == -1">
|
||||
<view class="_book_button_text" v-if="!swipeActionBatch" @tap="toNovelReading(m)">
|
||||
去阅读
|
||||
</view>
|
||||
<view class="_book_button_checkbox_box" v-else-if="swipeActionBatch">
|
||||
<u-checkbox-group @change="handelcheckbox($event,m)" v-model="m.checkedFlag">
|
||||
<u-checkbox :name="m.id" activeColor="#FF728F" />
|
||||
</u-checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
<view class="_swipe_action_book_del" v-else @tap="deleteBook(m)">
|
||||
删除
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="_swipe_action_box" @longpress="swipeActionLongpress(m)" v-for="m in bookshelfList"
|
||||
:key="m.id">
|
||||
<fui-swipe-action @click="onClick">
|
||||
<view class="_swipe_action_box_book_image">
|
||||
<image class="is_image" :src="m.cover" />
|
||||
</view>
|
||||
<view class="_swipe_action_book_info">
|
||||
<view class="_book_info_title">
|
||||
{{m.title}}
|
||||
</view>
|
||||
<view class="_book_info_chapter">
|
||||
{{m.history_txt}}
|
||||
</view>
|
||||
<view class="_book_info_tips">
|
||||
{{m.txt}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="_swipe_action_book_button" v-if="swipeActionList.indexOf(m.id) == -1">
|
||||
<view class="_book_button_text" v-if="!swipeActionBatch" @tap="toNovelReading(m)">
|
||||
去阅读
|
||||
</view>
|
||||
<view class="_book_button_checkbox_box" v-else-if="swipeActionBatch">
|
||||
<u-checkbox-group @change="handelcheckbox($event,m)" v-model="m.checkedFlag">
|
||||
<u-checkbox :name="m.id" activeColor="#FF728F" />
|
||||
</u-checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
<view class="_swipe_action_book_del" v-else @tap="deleteBook(m)">
|
||||
删除
|
||||
</view>
|
||||
</fui-swipe-action>
|
||||
</view> -->
|
||||
<view class="_swipe_action_box" @tap="toBookCity">
|
||||
<view class="_swipe_action_add_img_box">
|
||||
<view class="_swipe_action_add_img">
|
||||
<image class="is_image" src="/static/images/bookshelf/_swipe_add.png" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="_swipe_action_no_tips">
|
||||
去找书
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-popup :show="swipeActionBatch" mode="bottom" :overlay="false" bgColor="transparent" zIndex="999"
|
||||
:safeAreaInsetBottom="false">
|
||||
<view class="bookshelf_checked_all_del" @tap="checkedAllDel">
|
||||
<view class="_all_del_button">
|
||||
<image v-if="booksIds.length" class="is_image" src="/static/images/bookshelf/del_all.png" />
|
||||
<image v-else class="is_image" src="/static/images/bookshelf/del_all_checked.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import config from '@/config/index';
|
||||
import {
|
||||
isGetSystemInfo
|
||||
} from '@/utils/systemInfo.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
swipeActionList: [],
|
||||
swipeActionBatch: false,
|
||||
bookshelfList: [],
|
||||
delCheckedAll: [],
|
||||
booksIds: [],
|
||||
// options1: [{
|
||||
// text: '删除',
|
||||
// style: {
|
||||
// backgroundColor: '#FF728F'
|
||||
// }
|
||||
// }],
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const {
|
||||
windowHeight = 0, screenHeight = 0, windowTop = 0
|
||||
} = isGetSystemInfo();
|
||||
const footerSafeHeight = screenHeight - windowHeight - windowTop;
|
||||
if (footerSafeHeight) {
|
||||
this.footerSafeHeight = footerSafeHeight;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getBooksData() {
|
||||
// uni.showLoading({
|
||||
// title: '加载中...'
|
||||
// });
|
||||
const data = {}
|
||||
uni.$u.http.post('/getBookshelf', data).then((res) => {
|
||||
// setTimeout(() => {
|
||||
// uni.hideLoading();
|
||||
// }, 1000);
|
||||
if (res.status == 1) {
|
||||
const {
|
||||
module
|
||||
} = res.data;
|
||||
if (Array.isArray(module)) {
|
||||
this.bookshelfList = module.map((m, idx) => {
|
||||
return {
|
||||
...m,
|
||||
cover: `${config.baseUrl}${m.cover}`,
|
||||
checkedFlag: [],
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.bookshelfList = [];
|
||||
}
|
||||
}
|
||||
}).catch((err) => {
|
||||
// setTimeout(() => {
|
||||
// uni.hideLoading();
|
||||
// }, 1000);
|
||||
console.log(err, "========")
|
||||
})
|
||||
},
|
||||
// 长安删除多个
|
||||
swipeActionLongpress(row) {
|
||||
if (!this.swipeActionBatch) {
|
||||
// setTimeout(() => {
|
||||
// uni.hideTabBar({
|
||||
// animation: true
|
||||
// })
|
||||
// this.swipeActionBatch = true;
|
||||
// this.swipeActionList = [];
|
||||
// this.$emit('bookshelfContentBodyZindexFn', 999);
|
||||
// }, 1000)
|
||||
// const swipeActionList = [...this.swipeActionList];
|
||||
// if (swipeActionList.indexOf(row.id) != -1) {
|
||||
// this.swipeActionList = swipeActionList.filter((m) => m != row.id);;
|
||||
// } else {
|
||||
// this.swipeActionList = [...swipeActionList, row.id];
|
||||
// }
|
||||
}
|
||||
|
||||
},
|
||||
// 批量选择
|
||||
handelSwipeBatch() {
|
||||
uni.hideTabBar({
|
||||
animation: true
|
||||
})
|
||||
this.swipeActionBatch = true;
|
||||
this.swipeActionList = [];
|
||||
this.$emit('bookshelfContentBodyZindexFn', 999);
|
||||
},
|
||||
// 去书城
|
||||
toBookCity() {
|
||||
uni.reLaunch({
|
||||
url: '/pages/bookCity/bookCity/index'
|
||||
});
|
||||
},
|
||||
// 删除单个
|
||||
deleteBook(row) {
|
||||
this.handelDeleteBookFn([row.id]);
|
||||
},
|
||||
// 选择全部
|
||||
handelbookBatch(isCheckeds) {
|
||||
this.delCheckedAll = isCheckeds;
|
||||
const bookshelfList = [...this.bookshelfList];
|
||||
const ids = [];
|
||||
this.bookshelfList = bookshelfList.map((m) => {
|
||||
ids.push(m.id);
|
||||
return {
|
||||
...m,
|
||||
checkedFlag: isCheckeds.length ? [m.id] : [],
|
||||
}
|
||||
})
|
||||
this.booksIds = ids;
|
||||
},
|
||||
handelcheckbox(e, row) {
|
||||
const booksIds = [...this.booksIds];
|
||||
if (e.length) {
|
||||
this.booksIds = [...booksIds, row.id];
|
||||
this.delCheckedAll = this.booksIds.length == this.bookshelfList.length ? ['all'] : [];
|
||||
} else {
|
||||
this.delCheckedAll = [];
|
||||
this.booksIds = booksIds.filter((m) => m != row.id);
|
||||
}
|
||||
},
|
||||
handelDeleteBookFn(ids, allType = false) {
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
const parameter = {
|
||||
custom: {
|
||||
token: true
|
||||
}
|
||||
}
|
||||
const data = {
|
||||
ids: JSON.stringify(ids),
|
||||
}
|
||||
uni.$u.http.post('/delBookshelf', data, parameter).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
this.getBooksData();
|
||||
if (allType) {
|
||||
this.bathComplete();
|
||||
}
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
})
|
||||
},
|
||||
checkedAllDel() {
|
||||
this.handelDeleteBookFn(this.booksIds, true);
|
||||
},
|
||||
// 选择全部之后完成
|
||||
bathComplete() {
|
||||
this.swipeActionBatch = false;
|
||||
uni.showTabBar({
|
||||
animation: true
|
||||
})
|
||||
this.delCheckedAll = [];
|
||||
this.booksIds = [];
|
||||
this.$emit('bookshelfContentBodyZindexFn', 2);
|
||||
const bookshelfList = [...this.bookshelfList];
|
||||
this.bookshelfList = bookshelfList.map((m) => {
|
||||
return {
|
||||
...m,
|
||||
checkedFlag: [],
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
toNovelReading(row) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/booksReadingDetail/booksReadingDetail?sid=${row.sid}&t=${row.title}`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
::v-deep.u-checkbox {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.bookshelfListBody_content {
|
||||
width: 100%;
|
||||
|
||||
.bookshelfListBody_content_header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 40rpx;
|
||||
|
||||
._header_left {
|
||||
._header_name {
|
||||
font-size: 32rpx;
|
||||
line-height: 1;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
}
|
||||
|
||||
._header_right {
|
||||
._header_right_edit {
|
||||
font-size: 28rpx;
|
||||
line-height: 1;
|
||||
color: #929292;
|
||||
}
|
||||
|
||||
._header_right_confim {
|
||||
font-size: 32rpx;
|
||||
line-height: 1;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bookshelfListBody_content_body {
|
||||
width: 100%;
|
||||
|
||||
._content_body_list {
|
||||
width: 100%;
|
||||
|
||||
|
||||
// .bookshelf_list_swipe_action {
|
||||
// width: 100%;
|
||||
|
||||
._swipe_action_box {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 192rpx;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
margin-top: 32rpx;
|
||||
margin-bottom: 32rpx;
|
||||
|
||||
._swipe_action_box_book_image {
|
||||
width: 144rpx;
|
||||
height: 192rpx;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 8rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0 8rpx rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
._swipe_action_book_info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 28rpx;
|
||||
padding-top: 16rpx;
|
||||
padding-bottom: 16rpx;
|
||||
flex-shrink: 0;
|
||||
|
||||
._book_info_title {
|
||||
width: 100%;
|
||||
font-size: 32rpx;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
|
||||
._book_info_chapter {
|
||||
width: 100%;
|
||||
font-size: 26rpx;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color: #6F6F6F;
|
||||
margin-top: 36rpx;
|
||||
}
|
||||
|
||||
._book_info_tips {
|
||||
width: 100%;
|
||||
font-size: 24rpx;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color: #999999;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
._swipe_action_book_button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
width: 100rpx;
|
||||
height: 100%;
|
||||
flex: 0 0 auto;
|
||||
|
||||
._book_button_text {
|
||||
font-size: 28rpx;
|
||||
color: #FF728F;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
._swipe_action_book_del {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100rpx;
|
||||
height: 192rpx;
|
||||
text-align: center;
|
||||
line-height: 192rpx;
|
||||
color: #ffffff;
|
||||
background-color: #FF728F;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
._swipe_action_add_img_box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 144rpx;
|
||||
height: 192rpx;
|
||||
flex: 0 0 auto;
|
||||
background-color: #F6F6F6;
|
||||
|
||||
._swipe_action_add_img {
|
||||
width: 42rpx;
|
||||
height: 42rpx;
|
||||
}
|
||||
}
|
||||
|
||||
._swipe_action_no_tips {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 28rpx;
|
||||
font-size: 32rpx;
|
||||
color: #AAAAAA;
|
||||
}
|
||||
}
|
||||
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
.bookshelf_checked_all_del {
|
||||
// position: fixed;
|
||||
// bottom: 0;
|
||||
// left: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 130rpx;
|
||||
z-index: 1000;
|
||||
background-color: #fff;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
/* 兼容 iOS 设备 */
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
|
||||
._all_del_button {
|
||||
width: 150rpx;
|
||||
height: 56rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
152
pages/bookshelf/bookshelf/index.vue
Normal file
152
pages/bookshelf/bookshelf/index.vue
Normal file
@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<view class="bookshelf_content">
|
||||
<CommNavBar :navBarList="navBarList" @navBarClick="handelCommNavBar" :navBarActive="navBarActive" />
|
||||
<view class="bookshelf_content_body" :style="`z-index:${bookshelfContentBodyZindex}`">
|
||||
<scroll-view scroll-y="true" class="scroll_y">
|
||||
<view class="scroll_y_item">
|
||||
<view class="bookshelf_content_sign_in_box" @tap="toSignInBookCurrency">
|
||||
<view class="_sign_in_box_tips">
|
||||
<view class="_sign_in_text">
|
||||
<text>本周已连续签到</text>
|
||||
<text class="_sign_in_Days">{{totalNum}}</text>
|
||||
<text>天</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bookshelf_list_body">
|
||||
<BookshelfListBody @bookshelfContentBodyZindexFn="bookshelfContentBodyZindexFn"
|
||||
ref="BookshelfListBody" />
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommNavBar from '@/components/commNavBar/index.vue'
|
||||
import BookshelfListBody from './bookshelfListBody.vue'
|
||||
export default {
|
||||
components: {
|
||||
CommNavBar,
|
||||
BookshelfListBody
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
navBarList: [{
|
||||
id: '1',
|
||||
name: '书架'
|
||||
}],
|
||||
navBarActive: '1',
|
||||
totalNum: 0,
|
||||
bookshelfContentBodyZindex: 2
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
uni.$u.http.post('/getSigInfo', {}).then((res) => {
|
||||
if (res.status == 1) {
|
||||
const {
|
||||
totalNum,
|
||||
} = res.data;
|
||||
this.totalNum = totalNum;
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "errerr")
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
this.$refs.BookshelfListBody.getBooksData()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handelCommNavBar() {
|
||||
|
||||
},
|
||||
toSignInBookCurrency() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/signInBookCurrency/index`
|
||||
})
|
||||
},
|
||||
bookshelfContentBodyZindexFn(z) {
|
||||
this.bookshelfContentBodyZindex = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
height: 100%;
|
||||
}
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.bookshelf_content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// padding-bottom: 40rpx;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
|
||||
.bookshelf_content_body {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
z-index: 996;
|
||||
|
||||
.scroll_y {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
.scroll_y_item {
|
||||
// padding-bottom: 40rpx;
|
||||
.bookshelf_content_sign_in_box {
|
||||
width: 100%;
|
||||
padding: 0 32rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
._sign_in_box_tips {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 146rpx;
|
||||
background: url('/static/images/bookshelf/_sign_in.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
|
||||
._sign_in_text {
|
||||
position: absolute;
|
||||
left: 40rpx;
|
||||
bottom: 22rpx;
|
||||
font-size: 28rpx;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
|
||||
._sign_in_Days {
|
||||
color: #fff;
|
||||
margin: 0 6rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bookshelf_list_body {
|
||||
width: 100%;
|
||||
padding: 10rpx 32rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
// background-color: #fff;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
227
pages/classification/classification/index.vue
Normal file
227
pages/classification/classification/index.vue
Normal file
@ -0,0 +1,227 @@
|
||||
<template>
|
||||
<view class="classification_content">
|
||||
<CommNavBar :navBarList="navBarList" @navBarClick="handelCommNavBar" :navBarActive="navBarActive" />
|
||||
<view class="classification_content_body">
|
||||
<view class="classification_body_btn_list">
|
||||
<!-- <u-tabs :list="oneTitleList" lineColor="#FF728F" :inactiveStyle="inactiveStyle"></u-tabs> -->
|
||||
<scroll-view scroll-x="true" class="btn_list_scroll_view">
|
||||
<view :class="[`btn_list_scroll_view_item`,oneTitleActive == m.id?'active':''] "
|
||||
v-for="m in oneTitleList" :key="m.id" :data-id="m.id" @tap="handelOneTitle">{{m.name}}
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="classification_body_book_list">
|
||||
<scroll-view scroll-y="true" class="scroll_y">
|
||||
<view class="scroll_y_item">
|
||||
<view class="_book_list_box">
|
||||
<view class="_book_list_box_con_item" v-for="m in searchBooksList" :key="m.is"
|
||||
@tap="toBooksReadingDetail(m)">
|
||||
<CommBookLeftRigth :bookTips="m.category_name" :bookName="m.title" :bookImage="m.cover"
|
||||
:bookIntroduction="m.intro" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommNavBar from '@/components/commNavBar/index.vue'
|
||||
import CommBookLeftRigth from '@/components/commBookLeftRigth/index.vue'
|
||||
import {
|
||||
baseUrlImage
|
||||
} from '@/utils/utils';
|
||||
|
||||
const inactiveStyle = {
|
||||
color: '#222222',
|
||||
fontSize:'32rpx'
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CommNavBar,
|
||||
CommBookLeftRigth
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
navBarList: [{
|
||||
id: '1',
|
||||
name: '分类'
|
||||
}],
|
||||
navBarActive: '1',
|
||||
searchBooksList: [],
|
||||
oneTitleActive: 0,
|
||||
oneTitleList: [],
|
||||
inactiveStyle: inactiveStyle
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
//
|
||||
// uni.showLoading({
|
||||
// title: '加载中...'
|
||||
// });
|
||||
const data = {}
|
||||
uni.$u.http.post('/getCategory', data).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1 && Array.isArray(res.data.list)) {
|
||||
const list = res.data.list.map((m) => {
|
||||
return {
|
||||
...m,
|
||||
name: m.title,
|
||||
}
|
||||
});
|
||||
this.oneTitleList = [{
|
||||
id: '0',
|
||||
name: '全部',
|
||||
}, ...list];
|
||||
}
|
||||
this.getBooks(0, 0);
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
this.getBooks(0, 0);
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handelCommNavBar() {
|
||||
|
||||
},
|
||||
getBooks(type, category_id) {
|
||||
// uni.showLoading({
|
||||
// title: '加载中...'
|
||||
// });
|
||||
const parameter = {
|
||||
custom: {
|
||||
token: true
|
||||
}
|
||||
}
|
||||
const data = {
|
||||
type,
|
||||
category_id,
|
||||
}
|
||||
uni.$u.http.post('/getChartsCategory', data, parameter).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
const {
|
||||
module
|
||||
} = res.data;
|
||||
this.searchBooksList = baseUrlImage(module);
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
})
|
||||
},
|
||||
handelOneTitle(event) {
|
||||
const id = event.currentTarget.dataset.id;
|
||||
this.oneTitleActive = id;
|
||||
this.getBooks(0, id);
|
||||
},
|
||||
toBooksReadingDetail(row) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/booksReadingDetail/booksReadingDetail?sid=${row.id}&t=${row.title}`
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.classification_content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// padding-bottom: 150rpx;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
|
||||
.classification_content_body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// padding: 32rpx 0;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
.classification_body_btn_list {
|
||||
width: 100%;
|
||||
padding: 0 32rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.btn_list_scroll_view {
|
||||
white-space: nowrap;
|
||||
|
||||
.btn_list_scroll_view_item {
|
||||
display: inline-block;
|
||||
background-color: transparent;
|
||||
height: 64rpx;
|
||||
padding: 0 16rpx;
|
||||
color: #222222;
|
||||
line-height: 64rpx;
|
||||
margin-left: 16rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.btn_list_scroll_view_item.active {
|
||||
background-color: #FF728F;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn_list_scroll_view_item:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
.classification_body_book_list {
|
||||
width: 100%;
|
||||
|
||||
box-sizing: border-box;
|
||||
flex: 1;
|
||||
position: relative;
|
||||
|
||||
// background: #fff;
|
||||
.scroll_y {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 0 32rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.scroll_y_item {
|
||||
|
||||
._book_list_box {
|
||||
width: 100%;
|
||||
// display: flex;
|
||||
// margin-top: 32rpx;
|
||||
padding-bottom: 40rpx;
|
||||
|
||||
._book_list_box_con_item {
|
||||
padding: 32rpx 0;
|
||||
border-bottom: 2rpx solid #E5E5E5;
|
||||
}
|
||||
|
||||
._book_list_box_con_item:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
._book_list_box_con_item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
142
pages/giveCoinDetail/giveCoinDetail.vue
Normal file
142
pages/giveCoinDetail/giveCoinDetail.vue
Normal file
@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<view class="giveCoinDetail_content">
|
||||
<view class="give_list_body">
|
||||
<view class="give_list_item">
|
||||
<view class="give_list_item_header">
|
||||
<view class="item_header_time">
|
||||
2022-06
|
||||
</view>
|
||||
</view>
|
||||
<view class="give_list_item_con">
|
||||
<view class="_item_con_give_record">
|
||||
<view class="give_record_item">
|
||||
<view class="record_item_title">
|
||||
充值赠送金币
|
||||
</view>
|
||||
<view class="record_item_num">
|
||||
+6000
|
||||
</view>
|
||||
</view>
|
||||
<view class="give_record_item mt16rpx">
|
||||
<view class="record_item_time">
|
||||
2022-06-24 21:06:54
|
||||
</view>
|
||||
<view class="record_item_become_due">
|
||||
到期时间06-29
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="_item_con_give_record">
|
||||
<view class="give_record_item">
|
||||
<view class="record_item_title">
|
||||
充值赠送金币
|
||||
</view>
|
||||
<view class="record_item_num">
|
||||
+6000
|
||||
</view>
|
||||
</view>
|
||||
<view class="give_record_item mt16rpx">
|
||||
<view class="record_item_time">
|
||||
2022-06-24 21:06:54
|
||||
</view>
|
||||
<view class="record_item_become_due">
|
||||
到期时间06-29
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background-color: #F6F6F6;
|
||||
}
|
||||
|
||||
.mt16rpx {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.giveCoinDetail_content {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 0 32rpx 32rpx;
|
||||
|
||||
.give_list_body {
|
||||
width: 100%;
|
||||
|
||||
.give_list_item {
|
||||
width: 100%;
|
||||
|
||||
.give_list_item_header {
|
||||
width: 100%;
|
||||
padding: 24rpx 0;
|
||||
|
||||
.item_header_time {
|
||||
font-size: 32rpx;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
}
|
||||
|
||||
.give_list_item_con {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
border-radius: 8rpx;
|
||||
|
||||
._item_con_give_record {
|
||||
width: 100%;
|
||||
padding: 24rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.give_record_item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
line-height: 1;
|
||||
|
||||
.record_item_title {
|
||||
font-size: 30rpx;
|
||||
color: #1A1A1A;
|
||||
// font-weight: 600;
|
||||
}
|
||||
|
||||
.record_item_num {
|
||||
font-size: 30rpx;
|
||||
color: #FF728F;
|
||||
}
|
||||
|
||||
.record_item_time {
|
||||
font-size: 22rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.record_item_become_due {
|
||||
font-size: 22rpx;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
._item_con_give_record {
|
||||
border-bottom: 2rpx solid #EEEEEE;
|
||||
}
|
||||
|
||||
._item_con_give_record:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
166
pages/initialization/initialization.vue
Normal file
166
pages/initialization/initialization.vue
Normal file
@ -0,0 +1,166 @@
|
||||
<template>
|
||||
<view class="initialization_content">
|
||||
<view class="initialization_body">
|
||||
<view class="app_logo">
|
||||
<image src="/static/app_logo.png" class="is_image"></image>
|
||||
</view>
|
||||
<view class="app_title">
|
||||
古言小说
|
||||
</view>
|
||||
</view>
|
||||
<view class="initialization_footer">
|
||||
|
||||
<!-- <view class="app_title">
|
||||
古言小说
|
||||
</view> -->
|
||||
</view>
|
||||
<u-modal :show="modalShowOne" title="欢迎使用" :showCancelButton="true" cancelColor="#999" confirmText="同意并继续"
|
||||
cancelText="不同意" confirmColor="#FF728F" @confirm="toAgreeWith" @cancel="handelOnceMore">
|
||||
<view class="slot_content">
|
||||
<text>感谢您信任并使用古言小说!本服务需联网,申请通知权限用于为您提供书籍更新、优惠活动等信息服务。点击“同意”,即表示您同意上述内容及</text>
|
||||
<text class="user_agreement" @tap="toAgreement('1')">《古言用户服务协议》</text>
|
||||
<text>及</text>
|
||||
<text class="privacy" @tap="toAgreement('2')">《古言隐私政策》</text>
|
||||
</view>
|
||||
</u-modal>
|
||||
<u-modal :show="modalShowTwo" title="您需要同意以下协议才能正常使用古言" :showCancelButton="true" cancelColor="#999"
|
||||
confirmText="同意" cancelText="不同意并退出" confirmColor="#FF728F" @confirm="toAgreeWith"
|
||||
@cancel="toExitApplication">
|
||||
<view class="slot_content">
|
||||
<view>若您不同意,很遗憾我们将无法为您提供服务。</view>
|
||||
<view class="user_agreement" @tap="toAgreement('1')">《古言用户服务协议》</view>
|
||||
<view class="privacy" @tap="toAgreement('2')">《古言隐私政策》</view>
|
||||
</view>
|
||||
</u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
myGetStorage,
|
||||
mySetStorage
|
||||
} from '@/utils/storage/index.js';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
giveService: false,
|
||||
modalShowOne: false,
|
||||
modalShowTwo: false
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
const giveService = myGetStorage('giveService');
|
||||
this.giveService = giveService ? false : true;
|
||||
this.modalShowOne = giveService ? false : true;
|
||||
if (giveService) {
|
||||
setTimeout(() => {
|
||||
uni.switchTab({
|
||||
url: `/pages/bookCity/bookCity/index`
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toAgreeWith() {
|
||||
setTimeout(() => {
|
||||
uni.switchTab({
|
||||
url: `/pages/bookCity/bookCity/index`
|
||||
})
|
||||
}, 300)
|
||||
mySetStorage('giveService', 1);
|
||||
this.modalShowOne = false;
|
||||
this.modalShowTwo = false;
|
||||
},
|
||||
toExitApplication() {
|
||||
if (uni.getSystemInfoSync().platform == 'ios') {
|
||||
plus.ios.import("UIApplication").sharedApplication().performSelector("exit")
|
||||
} else if (uni.getSystemInfoSync().platform == 'android') {
|
||||
plus.runtime.quit();
|
||||
}
|
||||
},
|
||||
toAgreement(type) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/agreement/agreement?type=${type}`
|
||||
})
|
||||
},
|
||||
handelOnceMore() {
|
||||
this.modalShowOne = false;
|
||||
this.modalShowTwo = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 0 16rpx rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.initialization_content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
background: linear-gradient(to bottom, #FFC7D3 0%, #FFEBEE 50%, #fff 100%);
|
||||
|
||||
.initialization_body {
|
||||
padding-top: 260rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
// .app_title_image {
|
||||
// width: 200rpx;
|
||||
// height: 400rpx;
|
||||
// }
|
||||
.app_logo {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
}
|
||||
|
||||
.app_title {
|
||||
font-size: 60rpx;
|
||||
font-weight: 600;
|
||||
margin-left: 16rpx;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.initialization_footer {
|
||||
// position: absolute;
|
||||
// bottom: 180rpx;
|
||||
// left: 0;
|
||||
// display: flex;
|
||||
// justify-content: center;
|
||||
// align-items: center;
|
||||
// width: 100%;
|
||||
|
||||
// .app_logo {
|
||||
// width: 100rpx;
|
||||
// height: 100rpx;
|
||||
// }
|
||||
|
||||
// .app_title {
|
||||
// font-size: 46rpx;
|
||||
// font-weight: 600;
|
||||
// margin-left: 16rpx;
|
||||
// }
|
||||
}
|
||||
|
||||
.slot_content {
|
||||
font-size: 30rpx;
|
||||
color: #999;
|
||||
|
||||
.user_agreement {
|
||||
color: #FF728F;
|
||||
}
|
||||
|
||||
.privacy {
|
||||
color: #FF728F;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
151
pages/login/login.vue
Normal file
151
pages/login/login.vue
Normal file
@ -0,0 +1,151 @@
|
||||
<template>
|
||||
<view class="login_content">
|
||||
<view class="login_content_bg" />
|
||||
<u-navbar :autoBack="true" bgColor="transparent" :safeAreaInsetTop="true" :placeholder="true" />
|
||||
<view class="login_content_body">
|
||||
<view class="login_title">手机验证码登录</view>
|
||||
<view class="login_tips">未注册的手机验证后自动创建账户</view>
|
||||
<view class="login_mobile">
|
||||
<u-input type="number" placeholder="请输入手机号码" border="node" clearable fontSize="44rpx" v-model="mobile">
|
||||
<template slot='prefix'>
|
||||
<text class="login_mobile_tips">+86</text>
|
||||
</template>
|
||||
</u-input>
|
||||
</view>
|
||||
<view :class="[`login_mobile_Code`, mobile.length == 11 ? '' : 'active']" @tap="handelLoginCode">
|
||||
<text>获取验证码</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
mobile: "",
|
||||
bookTitle:'',
|
||||
bookSid :'',
|
||||
chapterorder:'',
|
||||
bookId:'',
|
||||
toPath:''
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
// this.bookTitle = options.t;
|
||||
this.bookSid = options.sid;
|
||||
this.chapterorder = options.c;
|
||||
this.bookId = options.i;
|
||||
this.toPath = options.to;
|
||||
},
|
||||
methods: {
|
||||
handelLoginCode() {
|
||||
const mobile = this.mobile;
|
||||
// const bookTitle = this.bookTitle;
|
||||
const bookSid = this.bookSid;
|
||||
const chapterorder = this.chapterorder;
|
||||
const bookId = this.bookId;
|
||||
const toPath = this.toPath
|
||||
if (mobile.length >= 11) {
|
||||
const data = {
|
||||
phone: mobile,
|
||||
}
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
// 也可以直接通过uni.$u.post发出请求,注意此处需要写上接口地址
|
||||
uni.$u.http.post('/SendCode', data).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/loginMobile/loginMobile?phone=${mobile}&sid=${bookSid}&i=${bookId}&c=${chapterorder}&to=${toPath}`
|
||||
})
|
||||
}
|
||||
}).catch((err) => {
|
||||
cosnole.log(err, "========")
|
||||
uni.hideLoading();
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// ::v-deep.u-input__content {
|
||||
/deep/.u-input__content {
|
||||
height: 116rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 58rpx;
|
||||
}
|
||||
|
||||
// ::v-deep.u-input--square {
|
||||
/deep/.u-input--square {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.login_content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.login_content_bg {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 1056rpx;
|
||||
background: url("/static/images/login_bg.png") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.login_content_body {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
padding: 40rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.login_title {
|
||||
font-size: 56rpx;
|
||||
color: #1d242c;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.login_tips {
|
||||
font-size: 28rpx;
|
||||
color: #524e5c;
|
||||
line-height: 1;
|
||||
margin-top: 32rpx;
|
||||
}
|
||||
|
||||
.login_mobile {
|
||||
margin-top: 90rpx;
|
||||
|
||||
.login_mobile_tips {
|
||||
margin: 0 32rpx;
|
||||
font-size: 44rpx;
|
||||
color: #1d242c;
|
||||
}
|
||||
}
|
||||
|
||||
.login_mobile_Code {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 116rpx;
|
||||
line-height: 1;
|
||||
background: linear-gradient(to left, #f27e49, #f25a14);
|
||||
color: #fff;
|
||||
font-size: 40rpx;
|
||||
margin-top: 64rpx;
|
||||
border-radius: 58rpx;
|
||||
}
|
||||
|
||||
.login_mobile_Code.active {
|
||||
background: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
167
pages/loginMobile/loginMobile.vue
Normal file
167
pages/loginMobile/loginMobile.vue
Normal file
@ -0,0 +1,167 @@
|
||||
<template>
|
||||
<view class="login_content">
|
||||
<view class="login_content_bg" />
|
||||
<u-navbar :autoBack="true" bgColor="transparent" :safeAreaInsetTop="true" :placeholder="true" />
|
||||
<view class="login_content_body">
|
||||
<view class="login_title">手机验证码登录</view>
|
||||
<view class="login_tips">未注册的手机验证后自动创建账户</view>
|
||||
<view class="login_mobile">
|
||||
<u-input v-model="mobileCode" type="number" placeholder="请输入手机验证码" border="node" clearable
|
||||
fontSize="44rpx">
|
||||
<template #prefix>
|
||||
<text class="login_mobile_tips"></text>
|
||||
</template>
|
||||
</u-input>
|
||||
</view>
|
||||
<view class="login_mobile_Code" @tap="confirmLogin">
|
||||
<text>确认登录</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mySetStorage
|
||||
} from '@/utils/storage/index.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
mobileCode: '',
|
||||
bookTitle: '',
|
||||
bookSid: '',
|
||||
chapterorder: '',
|
||||
bookId: ''
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.phone = options.phone;
|
||||
// this.bookTitle = options.t;
|
||||
this.bookSid = options.sid;
|
||||
this.chapterorder = options.c;
|
||||
this.bookId = options.i;
|
||||
this.toPath = options.to;
|
||||
},
|
||||
methods: {
|
||||
confirmLogin() {
|
||||
const bookSid = this.bookSid;
|
||||
const chapterorder = this.chapterorder;
|
||||
const bookId = this.bookId;
|
||||
const toPath = this.toPath;
|
||||
let toPathUrl = ''
|
||||
const toPathObj = {
|
||||
'1': `/pages/novelReading/novelReading?sid=${bookSid}&id=${bookId}&c=${chapterorder}`,
|
||||
'2': `/pages/myInfo/myInfo/index`,
|
||||
'3': `/pages/bookCity/bookCity/index`
|
||||
}
|
||||
if (toPathObj[toPath]) {
|
||||
toPathUrl = `${toPathObj[toPath]}`
|
||||
} else {
|
||||
toPathUrl = `/pages/bookCity/bookCity/index`
|
||||
}
|
||||
|
||||
const data = {
|
||||
phone: this.phone,
|
||||
code: this.mobileCode
|
||||
}
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
uni.$u.http.post('/Login', data).then((res) => {
|
||||
uni.hideLoading();
|
||||
const {
|
||||
token,
|
||||
uid
|
||||
} = res.data;
|
||||
if (res.status == 1) {
|
||||
mySetStorage('token', token);
|
||||
mySetStorage('uid', uid);
|
||||
uni.reLaunch({
|
||||
url: toPathUrl
|
||||
})
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/deep/.u-input__content {
|
||||
height: 116rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 58rpx;
|
||||
}
|
||||
|
||||
// ::v-deep
|
||||
/deep/.u-input--square {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.login_content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.login_content_bg {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 1056rpx;
|
||||
background: url('/static/images/login_bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.login_content_body {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
padding: 40rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.login_title {
|
||||
font-size: 56rpx;
|
||||
color: #1D242C;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.login_tips {
|
||||
font-size: 28rpx;
|
||||
color: #524E5C;
|
||||
line-height: 1;
|
||||
margin-top: 32rpx;
|
||||
}
|
||||
|
||||
.login_mobile {
|
||||
margin-top: 90rpx;
|
||||
|
||||
.login_mobile_tips {
|
||||
margin: 0 32rpx;
|
||||
font-size: 44rpx;
|
||||
color: #1D242C;
|
||||
}
|
||||
}
|
||||
|
||||
.login_mobile_Code {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 116rpx;
|
||||
line-height: 1;
|
||||
background: linear-gradient(to left, #F27E49, #F25A14);
|
||||
color: #fff;
|
||||
font-size: 40rpx;
|
||||
margin-top: 64rpx;
|
||||
border-radius: 58rpx;
|
||||
}
|
||||
|
||||
.login_mobile_Code.active {
|
||||
background-color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
23
pages/myInfo/aboutMy/index.vue
Normal file
23
pages/myInfo/aboutMy/index.vue
Normal file
@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="version_info">
|
||||
<view>当前版本</view>
|
||||
<view>1.23</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.content {
|
||||
padding: 32rpx;
|
||||
|
||||
.version_info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
111
pages/myInfo/myInfo/index.vue
Normal file
111
pages/myInfo/myInfo/index.vue
Normal file
@ -0,0 +1,111 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="step_user_info">
|
||||
<view class="_info_box">
|
||||
<MyUserInfo ref="MyUserInfo"/>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="step_vip_info">
|
||||
<CommVipInfo />
|
||||
</view> -->
|
||||
<view style="width: 100%">
|
||||
<u-gap height="14rpx" bgColor="#F6F6F6"></u-gap>
|
||||
</view>
|
||||
<view class="step_recharge_grid_info">
|
||||
<view class="rechargeGrid_box">
|
||||
<rechargeGrid />
|
||||
</view>
|
||||
</view>
|
||||
<view style="width: 100%">
|
||||
<u-gap height="14rpx" bgColor="#F6F6F6"></u-gap>
|
||||
</view>
|
||||
<view class="step_other_info">
|
||||
<view class="otherCellInfo_box">
|
||||
<otherCellInfo />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommVipInfo from '@/components/commVipInfo/index.vue'
|
||||
import MyUserInfo from './myUserInfo.vue'
|
||||
import rechargeGrid from './rechargeGrid.vue'
|
||||
import otherCellInfo from './otherCellInfo.vue'
|
||||
export default {
|
||||
components: {
|
||||
CommVipInfo,
|
||||
MyUserInfo,
|
||||
rechargeGrid,
|
||||
otherCellInfo
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.MyUserInfo.isGetUserInfo()
|
||||
})
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.content {
|
||||
background: #f6f6f6;
|
||||
padding: 32rpx 0 0;
|
||||
|
||||
.step_user_info {
|
||||
width: 100%;
|
||||
padding: 0 32rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
._info_box {
|
||||
width: 100%;
|
||||
height: 348rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 24rpx;
|
||||
// border-radius: 24rpx 24rpx 0 0;
|
||||
box-sizing: border-box;
|
||||
padding: 32rpx 32rpx 56rpx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.step_vip_info {
|
||||
width: 100%;
|
||||
padding: 0 32rpx;
|
||||
margin-top: -30rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.step_recharge_grid_info {
|
||||
background-color: #fff;
|
||||
border-radius: 24rpx 24rpx 0 0;
|
||||
padding: 32rpx;
|
||||
margin-top: -2rpx;
|
||||
|
||||
.rechargeGrid_box {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.step_other_info {
|
||||
// margin-top: 26rpx;
|
||||
background-color: #fff;
|
||||
|
||||
.otherCellInfo_box {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
229
pages/myInfo/myInfo/myUserInfo.vue
Normal file
229
pages/myInfo/myInfo/myUserInfo.vue
Normal file
@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<view class="myUserInfo_content">
|
||||
<view class="myUserInfo_body">
|
||||
<view class="_info_user_information">
|
||||
<view class="_information_left">
|
||||
<view class="_information_left_sculpture">
|
||||
<image class="image" src="@/static/images/myInfo/default_sculpture.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="_information_right">
|
||||
<view class="_information_right_name_box">
|
||||
<view class="_information_right_name">{{userInfo.nickname}}</view>
|
||||
<!-- <view class="_information_right_vip">
|
||||
<image class="image" :src="usersVipImage"></image>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="_information_right_userId">ID:{{userInfo.uid}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="_info_box_money">
|
||||
<view class="_money_coin_info">
|
||||
<view class="_book_coin">
|
||||
<view class="_book_coin_box">
|
||||
<view class="_coin_num">
|
||||
{{userInfo.egold || '0'}}
|
||||
</view>
|
||||
<view class="_coin_name" @tap="toBookCoinDetail">
|
||||
书币
|
||||
<u-icon name="arrow-right" size="24rpx" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="_book_coin">
|
||||
<view class="_book_coin_box">
|
||||
<view class="_coin_num">
|
||||
{{userInfo.zb || '0'}}
|
||||
</view>
|
||||
<view class="_coin_name" @tap="toGiveCoinDetail">
|
||||
赠币
|
||||
<u-icon name="arrow-right" size="24rpx" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="_money_recharge_btn" @tap="toVoucherCenter">
|
||||
<u-button type="primary" text="充值" shape="circle"
|
||||
color="linear-gradient(to right, #FF2E53, #FF6086)" class="_money_up_button"></u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="">
|
||||
<u-modal :show="showModal" title="提示" content='还未登录,请登录...' :showCancelButton="true" @cancel="modalCancel"
|
||||
@confirm="modalConfirm" />
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import usersVipImage from '@/static/images/myInfo/VIP.png';
|
||||
import {
|
||||
myGetStorage
|
||||
} from '@/utils/storage/index.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userInfo: {},
|
||||
usersVipImage: usersVipImage,
|
||||
showModal: false,
|
||||
// /static/images/myInfo/VIP_active.png
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toBookCoinDetail() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/bookCoinDetail/bookCoinDetail`
|
||||
})
|
||||
},
|
||||
toGiveCoinDetail() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/giveCoinDetail/giveCoinDetail`
|
||||
})
|
||||
},
|
||||
toVoucherCenter() {
|
||||
const token = myGetStorage('token');
|
||||
if (token) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/voucherCenter/index`
|
||||
})
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: `/pages/login/login?to=2`
|
||||
})
|
||||
}
|
||||
},
|
||||
modalConfirm() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/login/login`,
|
||||
success: () => {
|
||||
this.showModal = false;
|
||||
}
|
||||
})
|
||||
},
|
||||
isGetUserInfo() {
|
||||
// uni.showLoading({
|
||||
// title: '加载中...'
|
||||
// });
|
||||
const data = {}
|
||||
uni.$u.http.post('/getUserInfo', data).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
const user = res.data.user
|
||||
this.userInfo = user;
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.myUserInfo_content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.myUserInfo_body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
._info_user_information {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
._information_left {
|
||||
._information_left_sculpture {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
}
|
||||
}
|
||||
|
||||
._information_right {
|
||||
margin-left: 36rpx;
|
||||
|
||||
._information_right_name_box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
._information_right_name {
|
||||
font-size: 40rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
max-width: 400rpx;
|
||||
white-space: nowrap; //不支持换行
|
||||
overflow: hidden; //隐藏多出部分文字
|
||||
text-overflow: ellipsis; //用省略号代替多出部分文字
|
||||
|
||||
}
|
||||
|
||||
._information_right_vip {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
|
||||
._information_right_userId {
|
||||
font-size: 26rpx;
|
||||
color: #888888;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
._info_box_money {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
._money_coin_info {
|
||||
flex: 1;
|
||||
padding-right: 26rpx;
|
||||
display: flex;
|
||||
|
||||
._book_coin {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
|
||||
._book_coin_box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
._coin_num {
|
||||
font-size: 36rpx;
|
||||
color: #FF728F;
|
||||
margin-left: 18rpx;
|
||||
}
|
||||
|
||||
._coin_name {
|
||||
display: flex;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
._money_recharge_btn {
|
||||
width: 148rpx;
|
||||
|
||||
.u-button {
|
||||
height: 66rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
76
pages/myInfo/myInfo/otherCellInfo.vue
Normal file
76
pages/myInfo/myInfo/otherCellInfo.vue
Normal file
@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<view class="otherCellInfo_content">
|
||||
<u-cell-group :border="false">
|
||||
<u-cell v-for="(m,idx) in otherSteUpList" :key="idx" :title="m.title" isLink :border="false"
|
||||
:titleStyle="m.titleStyle" size="large" :url="m.toPath" :icon="m.icon">
|
||||
<!-- <template > -->
|
||||
<!-- <u-icon :size="m.size" :name="m.icon" /> -->
|
||||
<!-- <view solt="value" class="my_icon_box">
|
||||
<image :src="m.icon" class="is_image" />
|
||||
</view> -->
|
||||
<!-- </template> -->
|
||||
</u-cell>
|
||||
</u-cell-group>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import myInfo_chat from '@/static/images/myInfo_chat.png';
|
||||
import myInfo_setting from '@/static/images/myInfo_setting.png';
|
||||
import myInfo_info_circle from '@/static/images/myInfo_info_circle.png';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
otherSteUpList: [{
|
||||
title: '联系客服',
|
||||
icon: myInfo_chat,
|
||||
size: 26,
|
||||
titleStyle: {
|
||||
fontSize: '32rpx',
|
||||
marginLeft: '16rpx'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '关于我们',
|
||||
icon: myInfo_info_circle,
|
||||
size: 26,
|
||||
titleStyle: {
|
||||
fontSize: '32rpx',
|
||||
marginLeft: '16rpx'
|
||||
},
|
||||
toPath: '/pages/myInfo/aboutMy/index'
|
||||
},
|
||||
{
|
||||
title: '设置',
|
||||
icon: myInfo_setting,
|
||||
size: 26,
|
||||
titleStyle: {
|
||||
fontSize: '32rpx',
|
||||
marginLeft: '16rpx'
|
||||
},
|
||||
toPath: '/pages/myInfo/mySetUp/index'
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.otherCellInfo_content {
|
||||
.otherCellInfo {
|
||||
width: 100%;
|
||||
|
||||
.my_icon_box {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
72
pages/myInfo/myInfo/rechargeGrid.vue
Normal file
72
pages/myInfo/myInfo/rechargeGrid.vue
Normal file
@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<view class="rechargeGrid_content">
|
||||
<u-grid :border="false" col="3">
|
||||
<u-grid-item v-for="(m,listIndex) in rechargeGridList" :key="listIndex" @click="gridClick(m)">
|
||||
<!-- <u-icon :customStyle="{paddingTop:20+'rpx'}" :name="listItem.name" :size="22"></u-icon> -->
|
||||
<view class="_recharge_grid_image">
|
||||
<image class="image" :src="m.imageSrc"></image>
|
||||
</view>
|
||||
<text class="_recharge_grid-text">{{m.title}}</text>
|
||||
</u-grid-item>
|
||||
</u-grid>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import browsingHistoryImage from '@/static/images/myInfo/browsingHistoryImage.png'
|
||||
import rechargeHistoryImage from '@/static/images/myInfo/rechargeHistoryImage.png'
|
||||
import bookCoinHistoryImage from '@/static/images/myInfo/bookCoinHistoryImage.png'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
rechargeGridList: [{
|
||||
imageSrc: browsingHistoryImage,
|
||||
title: '浏览记录',
|
||||
toPath: '/pages/readingRecords/index'
|
||||
},
|
||||
{
|
||||
imageSrc: rechargeHistoryImage,
|
||||
title: '充值记录',
|
||||
toPath: '/pages/voucherCenterDetail/index'
|
||||
},
|
||||
{
|
||||
imageSrc: bookCoinHistoryImage,
|
||||
title: '书币明细',
|
||||
toPath: '/pages/bookCoinDetail/bookCoinDetail'
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
gridClick(row) {
|
||||
if (row.toPath) {
|
||||
uni.navigateTo({
|
||||
url: row.toPath
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.rechargeGrid_content {
|
||||
width: 100%;
|
||||
|
||||
._recharge_grid_image {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
|
||||
}
|
||||
|
||||
._recharge_grid-text {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
39
pages/myInfo/mySetUp/index.vue
Normal file
39
pages/myInfo/mySetUp/index.vue
Normal file
@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="step_other_info">
|
||||
<!-- url="/pages/componentsB/tag/tag" -->
|
||||
<u-cell-group :border="false">
|
||||
<u-cell v-for="(m,idx) in otherSteUpList" :key="idx" :title="m.title" isLink :border="false"
|
||||
:titleStyle="m.titleStyle" size="large" :url="m.toPath">
|
||||
</u-cell>
|
||||
</u-cell-group>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
otherSteUpList: [
|
||||
// {
|
||||
// title: '同步微信昵称和头像',
|
||||
// toPath: ''
|
||||
// },
|
||||
{
|
||||
title: '常见问题',
|
||||
toPath: '/pages/myInfo/problemList/index'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
onShow(query) {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.content {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
56
pages/myInfo/problemDetail/index.vue
Normal file
56
pages/myInfo/problemDetail/index.vue
Normal file
@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="problem_title">
|
||||
{{problemTitle}}
|
||||
</view>
|
||||
<view class="problem_describe" v-for="(m,idx) in problemList" :key="idx">
|
||||
{{m}}
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
problemTitle:'',
|
||||
problemList:[]
|
||||
}
|
||||
},
|
||||
onLoad(query) {
|
||||
console.log(query);
|
||||
const problemStatus = query.problemStatus || 1;
|
||||
const problemObj = {
|
||||
1:{
|
||||
problemTitle:'赠币有有效期吗',
|
||||
problemList :['参加不定时活动充值赠送的赠币有效期通常为发放后的3天,如有特殊有效期,会在活动中说明;','赠币到账后可在“我的”-“我的账户”-“赠币”页面中查看使用截止日期。']
|
||||
},
|
||||
2:{
|
||||
problemTitle:'解锁得章节可以永久免费看吗?',
|
||||
problemList :['可以。']
|
||||
}
|
||||
}
|
||||
this.problemList = problemObj[problemStatus].problemList;
|
||||
this.problemTitle = problemObj[problemStatus].problemTitle
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.content {
|
||||
padding: 32rpx;
|
||||
|
||||
.problem_title {
|
||||
font-size: 34rpx;
|
||||
color: #1A1A1A;
|
||||
}
|
||||
.problem_describe {
|
||||
margin-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
</style>
|
36
pages/myInfo/problemList/index.vue
Normal file
36
pages/myInfo/problemList/index.vue
Normal file
@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="step_other_info">
|
||||
<!-- url="/pages/componentsB/tag/tag" -->
|
||||
<u-cell-group :border="false">
|
||||
<u-cell v-for="(m,idx) in otherSteUpList" :key="idx" :title="m.title" :isLink="false"
|
||||
:titleStyle="m.titleStyle" size="large" :url="m.toPath">
|
||||
</u-cell>
|
||||
</u-cell-group>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
otherSteUpList: [{
|
||||
title: '赠币有有效期吗?',
|
||||
toPath: `/pages/myInfo/problemDetail/index?problemStatus=1`
|
||||
},
|
||||
{
|
||||
title: '解锁得章节可以永久免费看吗?',
|
||||
toPath: `/pages/myInfo/problemDetail/index?problemStatus=2`
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.content {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
1135
pages/novelReading/novelReading.vue
Normal file
1135
pages/novelReading/novelReading.vue
Normal file
File diff suppressed because it is too large
Load Diff
114
pages/novelReading/setUpReadingColorAll.js
Normal file
114
pages/novelReading/setUpReadingColorAll.js
Normal file
@ -0,0 +1,114 @@
|
||||
const setUpReadingColorAll = {
|
||||
'F3EFE9': {
|
||||
// 背景色:#F3EFE9
|
||||
'mainBodyBg': '#F3EFE9',
|
||||
// 一级标题文字颜色:#2F1904
|
||||
h1Title: '#2F1904',
|
||||
// 导航栏文字颜色 #999999
|
||||
navigationBarTitleTextColor: '#999999',
|
||||
// 导航栏返回文字颜色 #130F26
|
||||
navigationBarTitleTextBackColor: '#130F26',
|
||||
// 内容文字颜色:#30150A
|
||||
novelContentColor: '#30150A',
|
||||
// 上一章背景颜色:#CFCDC9
|
||||
previousChapterBbuttonBg: '#CFCDC9',
|
||||
// 上一章文字颜色:#2D2C2B
|
||||
previousChapterBbuttonTextColor: '#2D2C2B',
|
||||
// 下一章背景颜色:#2D2C2B
|
||||
nextChapterBbuttonBg: '#2D2C2B',
|
||||
// 下一章文字颜色:#ffffff
|
||||
nextChapterBbuttonTextColor: '#ffffff',
|
||||
// 背景 字号文字颜色:#524843
|
||||
dialogTextColor: '#524843',
|
||||
// A- A+背景颜色:#E3DFDA
|
||||
dialogATextBg: '#E3DFDA',
|
||||
// A- A+字体颜色:#2F1904
|
||||
dialogATextColor: '#2F1904',
|
||||
// 文字颜色:#2F1904
|
||||
tabBarTextColor: '#2F1904',
|
||||
// 进度条背景颜色:#E3DCDA
|
||||
progressBg: '#E3DCDA',
|
||||
// 进度条背景深色:#C9BAB1
|
||||
progressActiveBg: '#C9BAB1',
|
||||
// 进度条圆圈颜色:#F5F5F5
|
||||
progressRoundBg: '#F5F5F5',
|
||||
// 阴影颜色:#3E465B
|
||||
boxShowBg: '#3E465B'
|
||||
},
|
||||
'CCD9E2': {
|
||||
// 背景色:#CCD9E2
|
||||
mainBodyBg: '#CCD9E2',
|
||||
// 一级标题文字颜色:#041D2F
|
||||
h1Title: '#041D2F',
|
||||
// 导航栏文字颜色 #999999
|
||||
navigationBarTitleTextColor: '#999999',
|
||||
// 导航栏返回文字颜色 #130F26
|
||||
navigationBarTitleTextBackColor: '#130F26',
|
||||
// 内容文字颜色:#0A1E30
|
||||
novelContentColor: '#0A1E30',
|
||||
// 上一章背景颜色:#CFCDC9
|
||||
previousChapterBbuttonBg: '#CFCDC9',
|
||||
// 上一章文字颜色:#2D2C2B
|
||||
previousChapterBbuttonTextColor: '#2D2C2B',
|
||||
// 下一章背景颜色:#2D2C2B
|
||||
nextChapterBbuttonBg: '#2D2C2B',
|
||||
// 下一章文字颜色:#ffffff
|
||||
nextChapterBbuttonTextColor: '#ffffff',
|
||||
// 背景 字号文字颜色:#434852
|
||||
dialogTextColor: '#434852',
|
||||
// A- A+背景颜色:#DCE5E8
|
||||
dialogATextBg: '#DCE5E8',
|
||||
// A- A+字体颜色:#041D2F
|
||||
dialogATextColor: '#041D2F',
|
||||
// 文字颜色:#041D2F
|
||||
tabBarTextColor: '#041D2F',
|
||||
// 进度条背景颜色:#DAE0E3
|
||||
progressBg: '#DAE0E3',
|
||||
// 进度条背景深色:#B1C1C9
|
||||
progressActiveBg: '#B1C1C9',
|
||||
// 进度条圆圈颜色:#F5F5F5
|
||||
progressRoundBg: '#F5F5F5',
|
||||
// 阴影颜色:#3E465B
|
||||
boxShowBg: '#3E465B'
|
||||
},
|
||||
'333333': {
|
||||
// 背景色:#333333
|
||||
mainBodyBg: '#333333',
|
||||
// 一级标题文字颜色:#9C9C9C
|
||||
h1Title: '#9C9C9C',
|
||||
// 导航栏文字颜色 #999999
|
||||
navigationBarTitleTextColor: '#999999',
|
||||
// 导航栏返回文字颜色 #FFFFFF
|
||||
navigationBarTitleTextBackColor: '#FFFFFF',
|
||||
// 内容文字颜色:#9D9D9D
|
||||
novelContentColor: '#9D9D9D',
|
||||
// 上一章背景颜色:#555555
|
||||
previousChapterBbuttonBg: '#555555',
|
||||
// 上一章文字颜色:#989898
|
||||
previousChapterBbuttonTextColor: '#989898',
|
||||
// 下一章背景颜色:#9D9D9D
|
||||
nextChapterBbuttonBg: '#9D9D9D',
|
||||
// 下一章文字颜色:#333333
|
||||
nextChapterBbuttonTextColor: '#333333',
|
||||
// 背景 字号文字颜色:#8F8F8F
|
||||
dialogTextColor: '#8F8F8F',
|
||||
// A- A+背景颜色:#E7E7E7
|
||||
dialogATextBg: '#E7E7E7',
|
||||
// A- A+字体颜色:#333333
|
||||
dialogATextColor: '#333333',
|
||||
// 文字颜色:#9C9C9C
|
||||
tabBarTextColor: '#9C9C9C',
|
||||
// 进度条背景颜色:#5C5C5C
|
||||
progressBg: '#5C5C5C',
|
||||
// 进度条背景深色:#797979
|
||||
progressActiveBg: '#797979',
|
||||
// 进度条圆圈颜色:#CCCCCC
|
||||
progressRoundBg: '#CCCCCC',
|
||||
// 阴影颜色:#3E465B
|
||||
boxShowBg: '#3E465B',
|
||||
// 弹出背景颜色:#303030
|
||||
dialogBg:'#303030'
|
||||
}
|
||||
}
|
||||
|
||||
export default setUpReadingColorAll;
|
248
pages/readingRecords/index.vue
Normal file
248
pages/readingRecords/index.vue
Normal file
@ -0,0 +1,248 @@
|
||||
<template>
|
||||
<view class="readingRecords_content">
|
||||
<view class="reading_records_list">
|
||||
<view class="_records_list_item" v-for="m in historyList" :key="m.id">
|
||||
<view class="_list_item_book_img">
|
||||
<image class="is_image" :src="m.cover"></image>
|
||||
</view>
|
||||
<view class="_list_item_right">
|
||||
<view class="_list_item_title">
|
||||
{{m.title}}
|
||||
</view>
|
||||
<view class="_list_item_operate">
|
||||
<view class="_item_operate_name">{{m.order}}</view>
|
||||
<view class="_item_operate_all">
|
||||
<view class="_operate_all_have" v-if="m.bookcase == 1">
|
||||
<view class="_all_have_image">
|
||||
<image class="is_image" src="/static/images/readingRecords_have.png" />
|
||||
</view>
|
||||
<view class="_all_have_name">已有</view>
|
||||
</view>
|
||||
<view class="_operate_all_add" v-else @tap="addBookshelf(m)">
|
||||
<view class="_all_add_image">
|
||||
<image class="is_image" src="/static/images/readingRecords_add.png" />
|
||||
</view>
|
||||
<view class="_all_add_name">书架</view>
|
||||
</view>
|
||||
<view class="_operate_all_del" @tap="deteleBookHistory(m)">
|
||||
<view class="_all_del_image">
|
||||
<image class="is_image" src="/static/images/readingRecords_add_sdelete.png" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="_list_item_time">{{m.update_time}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
baseUrlImage
|
||||
} from '@/utils/utils'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
historyList: []
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.siGetHistory();
|
||||
},
|
||||
methods: {
|
||||
addBookshelf(row) {
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
const data = {
|
||||
sid: row.sid,
|
||||
}
|
||||
uni.$u.http.post('/addBookshelf', data).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
uni.showToast({
|
||||
title: '加入成功',
|
||||
icon: 'none'
|
||||
})
|
||||
this.siGetHistory(false);
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
})
|
||||
},
|
||||
siGetHistory(showLoadingFlag = true) {
|
||||
if (showLoadingFlag) {
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
}
|
||||
const data = {};
|
||||
uni.$u.http.post('/getHistory', data).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
const history = res.data.history;
|
||||
const historyList = baseUrlImage(history);
|
||||
this.historyList = historyList;
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, '========');
|
||||
});
|
||||
},
|
||||
deteleBookHistory(row) {
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
const data = {
|
||||
id: row.id,
|
||||
}
|
||||
uni.$u.http.post('/delHistory', data).then((res) => {
|
||||
setTimeout(() => {
|
||||
uni.hideLoading();
|
||||
}, 1000);
|
||||
if (res.status == 1) {
|
||||
uni.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'none'
|
||||
})
|
||||
this.siGetHistory(false);
|
||||
}
|
||||
}).catch((err) => {
|
||||
setTimeout(() => {
|
||||
uni.hideLoading();
|
||||
}, 1000);
|
||||
console.log(err, "========")
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.is_image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.readingRecords_content {
|
||||
padding: 32rpx;
|
||||
|
||||
.reading_records_list {
|
||||
|
||||
._records_list_item {
|
||||
display: flex;
|
||||
margin-bottom: 32rpx;
|
||||
|
||||
._list_item_book_img {
|
||||
width: 150rpx;
|
||||
height: 200rpx;
|
||||
}
|
||||
|
||||
._list_item_right {
|
||||
flex: 1;
|
||||
padding: 16rpx 0 16rpx 24rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
._list_item_title {
|
||||
color: #1A1A1A;
|
||||
font-size: 32rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
._list_item_operate {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
|
||||
._item_operate_name {
|
||||
color: #999999;
|
||||
font-size: 26rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
._item_operate_all {
|
||||
display: flex;
|
||||
|
||||
._operate_all_add {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 114rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
border-radius: 30rpx;
|
||||
border: 1px solid #FF728F;
|
||||
|
||||
._all_add_image {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
}
|
||||
|
||||
._all_add_name {
|
||||
font-size: 26rpx;
|
||||
color: #FF728F;
|
||||
margin-left: 4rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
._operate_all_have {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 114rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
border-radius: 30rpx;
|
||||
border: 1px solid #999999;
|
||||
|
||||
._all_have_image {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
}
|
||||
|
||||
._all_have_name {
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
margin-left: 4rpx;
|
||||
}
|
||||
}
|
||||
|
||||
._operate_all_del {
|
||||
margin-left: 16rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 72rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
border-radius: 30rpx;
|
||||
border: 1px solid #696969;
|
||||
|
||||
._all_del_image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
._list_item_time {
|
||||
color: #999999;
|
||||
font-size: 26rpx;
|
||||
line-height: 1;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
269
pages/signInBookCurrency/index.vue
Normal file
269
pages/signInBookCurrency/index.vue
Normal file
@ -0,0 +1,269 @@
|
||||
<template>
|
||||
<view class="signInBookCurrency_content">
|
||||
<u-navbar bgColor="transparent" leftIconColor="#fff" @leftClick="navbarLeftClick" />
|
||||
<view class="signInBookCurrency_header_bag"></view>
|
||||
<view class="signIn_list_box">
|
||||
<view class="list_box_body">
|
||||
<view class="list_box_body_sign_tips">
|
||||
<view class="_sign_tips_header">
|
||||
<text>已连续签到</text>
|
||||
<text class="_sign_tips_header_num">{{totalNum}}</text>
|
||||
<text>天 </text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="_body_sign_tips_box">
|
||||
<view :class="['_body_sign_tips_box_item',m.status == 1 ? 'active':'']" v-for="m in signInList"
|
||||
:key="m">
|
||||
<view v-if="m.status == 1" class="_box_item_sign_in_success">
|
||||
<image class="is_image" src="/static/images/sign_in_success.png"></image>
|
||||
</view>
|
||||
<view v-else class="_box_item_coin">
|
||||
<image class="is_image" src="/static/images/_coin.png" />
|
||||
</view>
|
||||
<view class="_box_item_coin_num">
|
||||
{{m.egold}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="sign_tips_button" @tap="handelSignIn">
|
||||
<text v-if="signInFlag">已签到,点击前往看书</text>
|
||||
<text v-else>点击签到领取福利</text>
|
||||
</view>
|
||||
</view>
|
||||
<u-transition :show="transitionShow" mode="fade" duration="1000">
|
||||
<view class="transition_sign_box">
|
||||
<view class="transition_sign_box_calendar">
|
||||
<image class="is_image" src="../../static/images/sign_in_calendar.png"></image>
|
||||
</view>
|
||||
<view class="transition_sign_box_text">
|
||||
<!-- <text>领取</text>
|
||||
<text>10</text>
|
||||
<text>书币</text> -->
|
||||
{{signInMsg}}
|
||||
</view>
|
||||
</view>
|
||||
</u-transition>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// const transitionCustomStyle =
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
signInFlag: false,
|
||||
transitionShow: false,
|
||||
signInList: [],
|
||||
totalNum: 0,
|
||||
signInMsg: ''
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.getSignIn()
|
||||
},
|
||||
methods: {
|
||||
handelSignIn() {
|
||||
const signInFlag = this.signInFlag;
|
||||
if (signInFlag) {
|
||||
uni.navigateTo({
|
||||
url: `pages/bookCity/bookCity/index`,
|
||||
})
|
||||
} else {
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
const parameter = {
|
||||
custom: {
|
||||
token: true
|
||||
}
|
||||
}
|
||||
uni.$u.http.post('/startSignin', {}, parameter).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
const {
|
||||
list,
|
||||
totalNum,
|
||||
daycheck
|
||||
} = res.data;
|
||||
this.signInMsg = res.msg;
|
||||
this.transitionShow = true;
|
||||
setTimeout(() => {
|
||||
this.transitionShow = false
|
||||
}, 2000);
|
||||
this.getSignIn();
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, "========")
|
||||
})
|
||||
}
|
||||
},
|
||||
navbarLeftClick() {
|
||||
uni.navigateBack();
|
||||
|
||||
},
|
||||
getSignIn() {
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
const parameter = {
|
||||
custom: {
|
||||
token: true
|
||||
}
|
||||
}
|
||||
uni.$u.http.post('/getSigInfo', {}, parameter).then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
const {
|
||||
list,
|
||||
totalNum,
|
||||
daycheck
|
||||
} = res.data;
|
||||
this.signInList = list;
|
||||
this.totalNum = totalNum;
|
||||
this.signInFlag = daycheck == 1 ? true : false;
|
||||
}
|
||||
}).catch((err) => {
|
||||
uni.hideLoading();
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
.is_image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.signInBookCurrency_content {
|
||||
width: 100%;
|
||||
|
||||
.signInBookCurrency_header_bag {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 536rpx;
|
||||
background: url("/static/images/signInBookCurrency_header_bag.png") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.signIn_list_box {
|
||||
position: relative;
|
||||
top: 460rpx;
|
||||
left: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 0 32rpx;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.list_box_body {
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
padding: 40rpx 0 40rpx 28rpx;
|
||||
border-radius: 24rpx;
|
||||
|
||||
._sign_tips_header {
|
||||
display: flex;
|
||||
font-size: 34rpx;
|
||||
color: #222222;
|
||||
line-height: 1;
|
||||
|
||||
._sign_tips_header_num {
|
||||
margin: 0 8rpx;
|
||||
color: #FE9800;
|
||||
}
|
||||
}
|
||||
|
||||
._body_sign_tips_box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
flex-wrap: wrap;
|
||||
|
||||
._body_sign_tips_box_item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 134rpx;
|
||||
height: 178rpx;
|
||||
background-color: #FFB423;
|
||||
border-radius: 16rpx;
|
||||
margin-right: 30rpx;
|
||||
margin-top: 44rpx;
|
||||
|
||||
._box_item_coin {
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
}
|
||||
|
||||
._box_item_coin_num {
|
||||
font-size: 28rpx;
|
||||
color: #FFFFFF;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
._box_item_sign_in_success {
|
||||
width: 62rpx;
|
||||
height: 42rpx;
|
||||
}
|
||||
}
|
||||
|
||||
._body_sign_tips_box_item.active {
|
||||
background-color: #FFCD6C;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sign_tips_button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 604rpx;
|
||||
height: 102rpx;
|
||||
line-height: 1;
|
||||
margin-top: 40rpx;
|
||||
background: linear-gradient(to left, #FE5139, #F19138);
|
||||
font-size: 38rpx;
|
||||
color: #ffffff;
|
||||
border-radius: 51rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.transition_sign_box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 372rpx;
|
||||
height: 282rpx;
|
||||
background-color: rgba(20, 20, 20, 0.6);
|
||||
transform: translate(-50%, -60%);
|
||||
border-radius: 18rpx;
|
||||
|
||||
.transition_sign_box_calendar {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
}
|
||||
|
||||
.transition_sign_box_text {
|
||||
font-size: 34rpx;
|
||||
line-height: 1;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
420
pages/voucherCenter/index.vue
Normal file
420
pages/voucherCenter/index.vue
Normal file
@ -0,0 +1,420 @@
|
||||
<template>
|
||||
<view class="voucherCenter_content" :style="`padding-bottom:${contentSafeHeight}rpx`">
|
||||
<view class="balance_info">
|
||||
<view class="balance_info_box">
|
||||
<view class="balance_info_name">您的余额</view>
|
||||
<view class="balance_coin_box">
|
||||
<view class="balance_num">{{ userInfo.egold }}</view>
|
||||
<view class="balance_title">书币</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="voucher_center_info">
|
||||
<view class="voucher_annual_pass_box">
|
||||
<view class="_annual_pass_tips">
|
||||
<view class="_pass_tips_name">年卡</view>
|
||||
<view class="_pass_tips_msg">尊享无限时书城免费畅读</view>
|
||||
</view>
|
||||
<view class="_annual_pass_money">
|
||||
<view class="_pass_money_unit">¥</view>
|
||||
<view class="_pass_money_num">{{ annualPass.price }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="voucher_center_list">
|
||||
<view class="_center_list_col_box" v-for="m in payList" :key="m.id" @tap="selectVoucherMoney($event, m)" :data-id="m.id">
|
||||
<view :class="['_center_list_col_item', selectVoucherMoneyId === m.id ? 'active' : '']">
|
||||
<view class="_col_item_money">
|
||||
<view class="_item_money_num">{{ m.price }}</view>
|
||||
<view class="_item_money_unit">元</view>
|
||||
</view>
|
||||
<view class="_col_item_coin">
|
||||
<!-- {{m.egold}}书币+{{zb}}书币 -->
|
||||
{{ m.title }}
|
||||
</view>
|
||||
<view class="_col_item_deliver">
|
||||
{{ m.description }}
|
||||
</view>
|
||||
<view v-if="m.poster" class="_col_item_hot_sales">{{ m.poster }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="voucher_center_illustrate">
|
||||
<view class="_center_illustrate_box">
|
||||
<view class="_illustrate_box_title">充值说明</view>
|
||||
<view class="_illustrate_box_tips_">
|
||||
<view class="_illustrate_box_tips_item">1、1元=100书币,IP和书币属于虚拟商品,一旦购买不作退换,望周知。</view>
|
||||
<view class="_illustrate_box_tips_item">
|
||||
2、充值后书币到账可能有延迟,15分钟内未到账请联系微信客服,微信号:
|
||||
<text style="color: #ff728f">yttfyyl,</text>
|
||||
<text style="color: #ff728f">yt20216688</text>
|
||||
, 工作时间:周一到周五9:00-17:00。
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="voucher_center_confirm" >
|
||||
<view class="_center_confirm_money">
|
||||
<view class="_center_confirm_money_box">
|
||||
<view class="_confirm_money_unit">¥</view>
|
||||
<view class="_confirm_money_num">{{ price }}</view>
|
||||
<!-- <view class="_confirm_money_preferential">已优惠12元</view> -->
|
||||
<view class="_confirm_money_preferential">{{ preferential }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="_center_confirm_btn">确认充值</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { isGetSystemInfo } from '@/utils/systemInfo.js';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
selectVoucherMoneyId: '',
|
||||
footerSafeHeight: 0,
|
||||
contentSafeHeight: 130,
|
||||
payList: [],
|
||||
annualPass: {},
|
||||
userInfo: {},
|
||||
price: 0,
|
||||
preferential: ''
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
const { windowHeight = 0, screenHeight = 0, windowTop = 0 } = isGetSystemInfo();
|
||||
const footerSafeHeight = screenHeight - windowHeight - windowTop;
|
||||
if (footerSafeHeight) {
|
||||
// this.footerSafeHeight = footerSafeHeight;
|
||||
this.contentSafeHeight = footerSafeHeight + 130;
|
||||
}
|
||||
this.isGetPayList();
|
||||
const data = {};
|
||||
uni.$u.http
|
||||
.post('/getUserInfo', data)
|
||||
.then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
const user = res.data.user;
|
||||
this.userInfo = user;
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, '========');
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
selectVoucherMoney(event, row) {
|
||||
this.selectVoucherMoneyId = event.currentTarget.dataset.id;
|
||||
this.price = row.price;
|
||||
this.preferential = row.title;
|
||||
},
|
||||
isGetPayList() {
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
const data = {};
|
||||
uni.$u.http
|
||||
.post('/getPayList', data)
|
||||
.then((res) => {
|
||||
uni.hideLoading();
|
||||
if (res.status == 1) {
|
||||
this.annualPass = res.data.AnnualPass;
|
||||
this.payList = res.data.list;
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
uni.hideLoading();
|
||||
console.log(err, '========');
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.voucherCenter_content {
|
||||
width: 100%;
|
||||
// padding-bottom: 130rpx;
|
||||
|
||||
.balance_info {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
padding: 32rpx 32rpx 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
.balance_info_box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 168rpx;
|
||||
background: url('/static/images/myInfo/balance_bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
padding: 30rpx 40rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
.balance_info_name {
|
||||
font-size: 30rpx;
|
||||
color: #ffffff;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.balance_coin_box {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
line-height: 1;
|
||||
|
||||
.balance_num {
|
||||
font-size: 50rpx;
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.balance_title {
|
||||
font-size: 30rpx;
|
||||
color: #ffffff;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.voucher_center_info {
|
||||
width: 100%;
|
||||
padding: 32rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 24rpx 24rpx 0 0;
|
||||
box-shadow: 0 -10rpx 10rpx 0 rgba(0, 0, 0, 0.2);
|
||||
box-sizing: border-box;
|
||||
|
||||
.voucher_annual_pass_box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 132rpx;
|
||||
padding: 24rpx 40rpx;
|
||||
background: linear-gradient(to left, #fecca7, #ffe5d6);
|
||||
border-radius: 16rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
._annual_pass_tips {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
// justify-content: space-between;
|
||||
._pass_tips_name {
|
||||
font-size: 38rpx;
|
||||
color: #5b0c0c;
|
||||
line-height: 1;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
._pass_tips_msg {
|
||||
font-size: 26rpx;
|
||||
color: #5b0c0c;
|
||||
line-height: 1;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
._annual_pass_money {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
|
||||
._pass_money_unit {
|
||||
font-size: 28rpx;
|
||||
color: #5b0c0c;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
._pass_money_num {
|
||||
font-size: 52rpx;
|
||||
color: #5b0c0c;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.voucher_center_list {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
|
||||
._center_list_col_box {
|
||||
width: 50%;
|
||||
padding-top: 32rpx;
|
||||
box-sizing: border-box;
|
||||
|
||||
._center_list_col_item {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 200rpx;
|
||||
border: 1px solid #dddddd;
|
||||
border-radius: 16rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 30rpx 24rpx 0;
|
||||
|
||||
._col_item_money {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
|
||||
._item_money_num {
|
||||
font-size: 48rpx;
|
||||
color: #1a1a1a;
|
||||
line-height: 1;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
._item_money_unit {
|
||||
font-size: 26rpx;
|
||||
color: #1a1a1a;
|
||||
margin-left: 8rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
._col_item_coin {
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
line-height: 1;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
._col_item_deliver {
|
||||
font-size: 26rpx;
|
||||
color: #ff4876;
|
||||
line-height: 1;
|
||||
margin-top: 18rpx;
|
||||
}
|
||||
|
||||
._col_item_hot_sales {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
// width: 104rpx;
|
||||
padding: 0 16rpx;
|
||||
height: 40rpx;
|
||||
line-height: 40rpx;
|
||||
transform: translateY(-50%);
|
||||
background: linear-gradient(to left, #ff2d2d, #ff5c5c);
|
||||
font-size: 26rpx;
|
||||
color: #ffffff;
|
||||
border-radius: 0 20rpx 0 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
._center_list_col_item.active {
|
||||
background-color: #ffeaef;
|
||||
border-color: #ff4876;
|
||||
}
|
||||
}
|
||||
|
||||
._center_list_col_box:nth-child(2n-1) {
|
||||
// padding-left: 16rpx;
|
||||
padding-right: 16rpx;
|
||||
}
|
||||
|
||||
._center_list_col_box:nth-child(2n) {
|
||||
padding-left: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.voucher_center_illustrate {
|
||||
margin-top: 64rpx;
|
||||
|
||||
._center_illustrate_box {
|
||||
._illustrate_box_title {
|
||||
font-size: 32rpx;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
._illustrate_box_tips_ {
|
||||
width: 100%;
|
||||
padding: 30rpx;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff3f6;
|
||||
border-radius: 24rpx;
|
||||
|
||||
._illustrate_box_tips_item {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
margin-bottom: 8rpx;
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.voucher_center_confirm {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 130rpx;
|
||||
box-shadow: 0 -6rpx 6rpx 0 rgba(207, 207, 207, 0.25);
|
||||
background-color: #ffffff;
|
||||
padding-bottom: constant(safe-area-inset-bottom); /* 兼容 iOS 设备 */
|
||||
padding-bottom: env(safe-area-inset-bottom); /* 兼容 iPhone X 及以上设备 */
|
||||
|
||||
._center_confirm_money {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 32rpx;
|
||||
|
||||
._center_confirm_money_box {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
|
||||
._confirm_money_unit {
|
||||
font-size: 26rpx;
|
||||
color: #ff4876;
|
||||
line-height: 1;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
._confirm_money_num {
|
||||
font-size: 52rpx;
|
||||
color: #ff4876;
|
||||
line-height: 1;
|
||||
font-weight: 600;
|
||||
margin-left: 6rpx;
|
||||
}
|
||||
|
||||
._confirm_money_preferential {
|
||||
font-size: 26rpx;
|
||||
color: #8a8a8a;
|
||||
line-height: 1;
|
||||
margin-left: 26rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
._center_confirm_btn {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 320rpx;
|
||||
height: 130rpx;
|
||||
line-height: 130rpx;
|
||||
font-size: 36rpx;
|
||||
color: #ffffff;
|
||||
background: linear-gradient(to left, #ff87b5, #ff4775);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user