Commit c992094b authored by jyx's avatar jyx

代码优化

parent 288e3652
import Book from "../../../common/models/Book";
import {
getTimeDesc
} from "../../../common/utils/timeUtil";
export default class BookshelfBookItem extends Book {
constructor(param) {
super(param || {})
const {
lastReadTime
} = param || {}
this.lastReadTime = lastReadTime || "";
this.lastReadTimeDesc = lastReadTime ? getTimeDesc(lastReadTime) : "";
}
import Book from "../models/Book.js";
import {
getTimeDesc
} from "../utils/timeUtil";
export default class BookshelfBookItem extends Book {
constructor(param) {
super(param || {})
const {
lastReadTime
} = param || {}
this.lastReadTime = lastReadTime || "";
this.lastReadTimeDesc = lastReadTime ? getTimeDesc(lastReadTime) : "";
}
}
\ No newline at end of file
......@@ -282,6 +282,14 @@ function getBookBeanPackData(callback) {
url: `//system/bookLegumesType/list`,
callback
})
}
function getCollects(callback) {
apiPOST({
url: "/book/collectList",
data: {},
callback
})
}
/**
......@@ -299,7 +307,8 @@ function buyBookWithBookBean(bookId, callback) {
callback
})
}
module.exports = {
module.exports = {
getCollects,
getOpens,
getReadTimeCount,
startCountReadTime,
......
<template>
<view class="banneritem">
<swiper :autoplay="true" :interval="2000" :duration="500">
<swiper-item @click="handleBanner" v-for='(item, index) in bannerList' :key='index'>
<image class="banner-img" src="https://mints-pkg.oss-cn-beijing.aliyuncs.com/pkg/img/ic_banner_ar.png"
mode="scaleToFill"></image>
</swiper-item>
</swiper>
</view>
</template>
<script>
import SystemInfoMixin from "../../common/mixins/system-info-mixin.js"
import {
watchUserInfoChange,
removeUserInfoChangeWatch
} from "../../common/services/userServices.js";
export default {
mixins: [SystemInfoMixin],
data() {
return {
bannerList: ['', '', '']
};
},
onReady() {
// this.initHeight();
// 监听用户变动
watchUserInfoChange((info) => {
if (info.userInfo) {
this.initData();
}
}, this)
},
onShow() {},
onUnload() {
// 移除监听
removeUserInfoChangeWatch(this);
},
methods: {
show() {
// 监听用户变动
watchUserInfoChange((info) => {
if (info.userInfo) {
this.initData();
}
}, this)
},
handleBanner() {},
hide() {
},
initData() {
this.refreshList();
},
// 刷新数据列表
refreshList() {
}
}
}
</script>
<style lang="scss">
.banneritem {
margin: 20rpx 20rpx 0 20rpx;
height: 260rpx;
.banner-img {
height: 260rpx;
}
}
</style>
\ No newline at end of file
......@@ -99,7 +99,7 @@
.book-list-item {
display: flex;
flex-direction: row;
padding: 20rpx 40rpx;
padding: 20rpx 20rpx;
.row {
margin-bottom: 20rpx;
......@@ -173,8 +173,8 @@
}
.label-color-2 {
color: #3d99fd;
background: #d8ebff;
color: #F1413C;
background: #FEF3F3;
}
.label-color-3 {
......@@ -186,8 +186,8 @@
.cover-box {
.cover {
width: 150rpx;
height: 200rpx;
width: 165rpx;
height: 220rpx;
border-radius: 15rpx;
}
}
......
<template>
<view class="cover-box" @click="tapItem">
<!-- <image v-show="imageError" class="cover" src="/static/images/image_error.png" mode="aspectFill"></image> -->
<image class="cover" v-if="!last" :src="item.avatar" mode="aspectFill"></image>
<image v-else class="cover" src="/static/images/image_error.png" mode="aspectFill"></image>
<view class="title" v-if="!last">
{{item.title}}
</view>
<view class="c-flex_row c-align_center label-box" v-if="!last">
<slot name="footer">
<view class="label label-color-1" v-if='showCategory'>
{{item.categoryName}}
</view>
<view class="label label-color-2" v-for='(label, labelIndex) in item.tagList' :key='labelIndex'>
{{label.name}}
</view>
</slot>
</view>
</view>
</template>
<script>
export default {
props: {
item: {
type: Object,
default: function() {
return {}
}
},
last: {
type: Boolean,
default: false
}
},
data: function() {
return {
imageError: true
}
},
watch: {},
computed: {
showCategory: function() {
return this.item.categoryName
},
showErrorImage: function() {
return this.imageError;
},
hideErrorImage: function() {
return !this.imageError
}
},
methods: {
tapItem() {
this.$emit("tapItem", {
detail: {
data: this.item
}
})
},
loadImage() {
this.imageError = false;
},
errorImage() {
this.imageError = true
}
}
}
</script>
<style lang="scss" scoped>
.cover-box {
display: flex;
flex-direction: column;
.title {
width: 100%;
font-size: 26rpx;
margin-top: 10rpx;
color: #383B3D;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.cover {
width: 100%;
height: 220rpx;
border-radius: 15rpx;
}
}
</style>
\ No newline at end of file
<template>
<scroll-view scroll-y style="height: 100%;">
<book-search-box id='search'></book-search-box>
<Banner></Banner>
<RecommendList ref='recommendList1' :listType="1"></RecommendList>
<RecommendList ref='recommendList2' :listType="2"></RecommendList>
<view style="height: 20rpx;"></view>
</scroll-view>
</template>
<script>
import RecommendList from "../recommend-list/recommend-list.vue";
import Banner from "../banner/banner.vue";
import SystemInfoMixin from "../../common/mixins/system-info-mixin.js"
import {
watchUserInfoChange,
removeUserInfoChangeWatch
} from "../../common/services/userServices.js";
export default {
mixins: [SystemInfoMixin],
components: {
RecommendList,
Banner
},
data() {
return {
listHeight: 0
};
},
onReady() {
// this.initHeight();
// 监听用户变动
watchUserInfoChange((info) => {
if (info.userInfo) {
this.initData();
}
}, this)
this.refreshList()
},
onShow() {},
onUnload() {
// 移除监听
removeUserInfoChangeWatch(this);
},
methods: {
show() {
// 监听用户变动
watchUserInfoChange((info) => {
if (info.userInfo) {
this.initData();
}
}, this)
},
hide() {
},
initData() {
this.refreshList();
},
// 刷新数据列表
refreshList() {
let ref2 = this.$refs.recommendList1;
if (ref2) {
ref2.refreshList();
}
let ref = this.$refs.recommendList2;
if (ref) {
ref.refreshList();
}
},
initHeight() {
const query = uni.createSelectorQuery().in(this);
query.exec((res) => {
let result = 0;
res.forEach(item => {
result = result + item.height;
})
this.listHeight = this.windowHeight - result;
})
},
}
}
</script>
<style lang="scss">
</style>
\ No newline at end of file
<template>
<view class="bookshelf">
<read-time-count-row id='count' ref='timeCount'></read-time-count-row>
<view class="bookitem" v-if="dataList.length>0">
<book-list-item2 class="item" v-for='(item, index) in dataList' :key='index' :item='item'
:last="index>=dataList.length-1" @tapItem='tapItem($event, index)' @close='tapClose($event, index)'>
</book-list-item2>
</view>
<c-shelf-empty v-else></c-shelf-empty>
</view>
</template>
<script>
import common from '@/mixins/common';
import {
getCollects,
} from "../../../common/services/index.js"
import {
gotoBookContentPage
} from '../../../common/services/page-route';
import BookshelfBookItem from '../../../common/models/BookshelfBookItem.js';
import {
collectionBook,
noticeCollectionListChange
} from "../../../common/services/index.js"
export default {
mixins: [common],
props: {
height: {
type: Number,
default: 0
},
},
data: function() {
return {
dataList: [],
}
},
methods: {
refreshList() {
getCollects((success, data) => {
if (success) {
this.changeData(data)
}
})
this.refreshTimeCount()
},
refreshTimeCount() {
let ref = this.$refs.timeCount;
if (ref) {
ref.refresh()
}
},
changeData(e) {
this.dataList = e.records.map(item => {
return new BookshelfBookItem(item)
})
this.dataList.push({})
},
tapItem(e, index) {
if (index >= this.dataList.length - 1) {
uni.$emit('goWareHouse')
return
}
gotoBookContentPage(e.detail.data.id, e.detail.data.shortis)
},
tapClose(e, index) {
let item = e.detail.data;
uni.showModal({
title: "确认移除",
content: `是否确认从书架中移除《${item.title}》`,
success: (res) => {
if (res.confirm) {
collectionBook(false, item.id, (success, data) => {
if (success) {
this.dataList.splice(index, 1)
this.$forceUpdate()
noticeCollectionListChange(item.id, false)
}
})
}
}
})
}
}
}
</script>
<style lang="scss" scoped>
.bookshelf {
display: flex;
flex-direction: column;
border-radius: 20rpx;
background-color: white;
margin: 30rpx;
.bookitem {
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding-left: 20rpx;
.item {
width: 22%;
margin-bottom: 20rpx;
margin-right: 20rpx;
}
.item:last-child {
margin-bottom: 0;
margin-right: 0;
}
}
}
</style>
\ No newline at end of file
import {
apiGET,
apiPOST
} from "../../../common/utils/apiRequest.js"
module.exports = {
}
\ No newline at end of file
<template>
<z-paging>
<c-navi id='navi'></c-navi>
<book-search-box id='search' :searchType='searchType'></book-search-box>
<read-time-count-row id='count' ref='timeCount' @resize='resizeTimeCount'></read-time-count-row>
<BookshelfList ref='bookList' :height='listHeight'></BookshelfList>
<c-login></c-login>
</z-paging>
<scroll-view scroll-y style="height: 100%;">
<BookshelfList ref='bookList'></BookshelfList>
<RecommendList ref='recommendList'></RecommendList>
<view style="height: 20rpx;"></view>
</scroll-view>
</template>
<script>
import BookshelfList from "./components/bookshelf-list.vue";
import RecommendList from "../recommend-list/recommend-list.vue";
import SystemInfoMixin from "../../common/mixins/system-info-mixin.js"
import {
watchUserInfoChange,
removeUserInfoChangeWatch
} from "../../common/services/userServices.js";
import {
ENUM_SEARCH_TYPE
} from "../../static/enums/enum_value";
import {
removeCollectionChangeWatch,
watchCollectionChange
......@@ -25,16 +21,16 @@
export default {
mixins: [SystemInfoMixin],
components: {
BookshelfList
BookshelfList,
RecommendList
},
data() {
return {
searchType: ENUM_SEARCH_TYPE.BOOKSHELF,
listHeight: 0
};
},
onReady() {
this.initHeight();
// this.initHeight();
// 监听用户变动
watchUserInfoChange((info) => {
if (info.userInfo) {
......@@ -56,10 +52,8 @@
removeCollectionChangeWatch(this);
},
methods: {
show() {
this.$refs.timeCount.refresh()
this.initHeight();
show() {
// this.initHeight();
// 监听用户变动
watchUserInfoChange((info) => {
if (info.userInfo) {
......@@ -73,39 +67,23 @@
},
hide() {
},
resizeTimeCount() {
this.initHeight();
},
initData() {
this.refreshList();
},
// 初始化刷新
initRefresh() {
let ref = this.$refs.bookList;
if (ref) {
ref.initRefresh();
}
},
// 刷新数据列表
refreshList() {
let ref2 = this.$refs.recommendList;
if (ref2) {
ref2.refreshList();
}
let ref = this.$refs.bookList;
if (ref) {
ref.refreshList();
}
},
refreshTimeCount() {
let ref = this.$refs.timeCount;
if (ref) {
ref.refresh();
}
},
initHeight() {
const query = uni.createSelectorQuery().in(this);
query.select("#navi").boundingClientRect();
query.select("#search").boundingClientRect();
query.select("#count").boundingClientRect();
query.select("#count").boundingClientRect();
query.exec((res) => {
let result = 0;
res.forEach(item => {
......
<template>
<view>
<c-list ref='list' :showShelfEmpty="true" flag='bookshelf' :needLogin="true" :height="height"
url='/book/collectList' :param="requestParam" @change='changeData' method="POST">
<book-list-item v-for='(item, index) in dataList' :key='index' :item='item'
@tapItem='tapItem($event, index)' @close='tapClose($event, index)'>
<template v-slot:footer>
<view class="c-flex_row c-aligns_center">
<uni-icons type='calendar' size="16" color="#999"></uni-icons>
<view class="info">
{{item.lastReadTime}} 前阅读过
</view>
</view>
</template>
</book-list-item>
</c-list>
<view class="bookshelf">
<read-time-count-row id='count' ref='timeCount'></read-time-count-row>
<view class="bookitem" v-if="dataList.length>0">
<book-list-item2 class="item" v-for='(item, index) in dataList' :key='index' :item='item'
:last="index>=dataList.length-1" @tapItem='tapItem($event, index)' @close='tapClose($event, index)'>
</book-list-item2>
</view>
<c-shelf-empty v-else></c-shelf-empty>
</view>
</template>
<script>
import common from '@/mixins/common';
import {
getCollects,
} from "../../../common/services/index.js"
import {
gotoBookContentPage
} from '../../../common/services/page-route';
import {
isEmpty
} from '../../../common/utils/util';
import BookshelfBookItem from '../models/BookshelfBookItem';
import BookshelfBookItem from '../../../common/models/BookshelfBookItem.js';
import {
collectionBook,
noticeCollectionListChange
} from "../../../common/services/index.js"
export default {
mixins: [common],
props: {
height: {
type: Number,
......@@ -41,30 +41,33 @@
dataList: [],
}
},
computed: {
requestParam: function() {
return {}
}
},
methods: {
initRefresh() {
if (isEmpty(this.dataList)) {
this.refreshList();
}
},
refreshList() {
let ref = this.$refs.list;
getCollects((success, data) => {
if (success) {
this.changeData(data)
}
})
this.refreshTimeCount()
},
refreshTimeCount() {
let ref = this.$refs.timeCount;
if (ref) {
ref.onPullRefreshing();
ref.refresh()
}
},
changeData(e) {
console.log(e)
this.dataList = e.detail.data.map(item => {
this.dataList = e.records.map(item => {
return new BookshelfBookItem(item)
})
this.dataList.push({})
},
tapItem(e, index) {
if (index >= this.dataList.length - 1) {
uni.$emit('goWareHouse')
return
}
gotoBookContentPage(e.detail.data.id, e.detail.data.shortis)
},
tapClose(e, index) {
......@@ -76,9 +79,9 @@
if (res.confirm) {
collectionBook(false, item.id, (success, data) => {
if (success) {
this.dataList.splice(index, 1);
this.$forceUpdate();
noticeCollectionListChange(item.id, false);
this.dataList.splice(index, 1)
this.$forceUpdate()
noticeCollectionListChange(item.id, false)
}
})
}
......@@ -91,9 +94,29 @@
</script>
<style lang="scss" scoped>
.info {
font-size: 26rpx;
color: #999;
margin-left: 10rpx;
.bookshelf {
display: flex;
flex-direction: column;
border-radius: 20rpx;
background-color: white;
margin: 30rpx;
.bookitem {
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding-left: 20rpx;
.item {
width: 22%;
margin-bottom: 20rpx;
margin-right: 20rpx;
}
.item:last-child {
margin-bottom: 0;
margin-right: 0;
}
}
}
</style>
\ No newline at end of file
module.exports = {}
\ No newline at end of file
import {
apiGET,
apiPOST
} from "../../../common/utils/apiRequest.js"
module.exports = {
}
\ No newline at end of file
......@@ -4,7 +4,7 @@
暂未添加到书架
</view>
<view class="empty-button" @click="goWareHouse">
去书
去书城看看
</view>
<slot></slot>
</view>
......@@ -19,7 +19,7 @@
};
},
methods: {
goWareHouse() {
goWareHouse() {
uni.$emit('goWareHouse')
// uni.switchTab({
// url: '/pages/warehouse/warehouse'
......@@ -36,20 +36,20 @@
align-items: center;
justify-content: center;
width: 100%;
height: 800rpx;
height: 400rpx;
.empty-title {
color: #999;
font-size: 26rpx;
margin-bottom: 40rpx;
margin-bottom: 20rpx;
}
.empty-button {
font-size: 30rpx;
border: 1px solid #FECF02;
padding: 10rpx 40rpx;
border-radius: 30rpx;
color: #FECF02;
color: white;
background: linear-gradient(90deg, #F1413C, #FD6864);
}
}
</style>
\ No newline at end of file
This diff is collapsed.
<template>
<view class="c-flex_row c-aligns_center c-justify_between read-time-count-row">
<view class="c-flex_column c-aligns_center">
<view class="title">
今日阅读时间
</view>
<view class="value" v-if='count.count'>
<view class="count" v-if='count.hour'>
<view class="count-value">{{count.hour}}</view>
<view class="count-unit">小时</view>
</view>
<view class="count" v-if='count.minute'>
<view class="count-value">{{count.minute}}</view>
<view class="count-unit">分钟</view>
</view>
<view class="count" v-if='count.second'>
<view class="count-value">{{count.second}}</view>
<view class="count-unit"></view>
</view>
</view>
<view class="value" v-else>
<view class="count">
<view class="count-value" style="color: #ffffff00;">
0
</view>
<view class="count-unit">
尚未开始
</view>
</view>
</view>
</view>
<view class="c-flex_column c-aligns_center">
<slot name="right"></slot>
</view>
</view>
</template>
<script>
import ReadCount from '../../common/models/ReadCount';
import {
getReadTimeCount
} from '../../common/services';
export default {
name: "read-time-count-row",
props: {},
data() {
return {
count: {
count: 1,
hour: 0,
minute: 0,
second: 0
}
};
},
mounted() {
this.refresh();
},
methods: {
refresh() {
this.count = new ReadCount({
count: getReadTimeCount()
})
this.$nextTick(() => {
this.$emit("resize");
})
},
}
}
</script>
<style lang="scss">
.read-time-count-row {
padding: 20rpx 40rpx;
.title {
font-size: 28rpx;
color: #333;
margin-bottom: 20rpx;
}
.value {
display: flex;
flex-direction: row;
align-items: center;
.count {
display: flex;
flex-direction: row;
margin-right: 10rpx;
font-size: 24rpx;
color: #333;
.count-value {
color: #007aff;
font-size: 38rpx;
font-weight: 700;
height: 40rpx;
line-height: 40rpx;
}
.count-unit {
margin-left: 8rpx;
height: 40rpx;
line-height: 40rpx;
}
}
}
}
<template>
<view class="c-flex_row c-aligns_center c-justify_between read-time-count-row">
<view class="c-flex_row c-aligns_center">
<view class="title">
今日<br>已读
</view>
<!-- <view class="value" v-if='count.count'> -->
<view class="value">
<view class="count">
<view class="count-value">{{count.hour ?count.hour:'00'}}</view>
<view class="count-unit">h</view>
</view>
<view class="count">
<view class="count-value">{{count.minute?count.minute:'00'}}</view>
<view class="count-unit">m</view>
</view>
<view class="count">
<view class="count-value">{{count.second?count.second:'00'}}</view>
<view class="count-unit">s</view>
</view>
</view>
<!-- <view class="value" v-else>
<view class="count">
<view class="count-value" style="color: #ffffff00;">
0
</view>
<view class="count-unit">
尚未开始
</view>
</view>
</view> -->
</view>
<view class="c-flex_column c-aligns_center">
<slot name="right"></slot>
</view>
</view>
</template>
<script>
import ReadCount from '../../common/models/ReadCount';
import {
getReadTimeCount
} from '../../common/services';
export default {
name: "read-time-count-row",
props: {},
data() {
return {
count: {
count: 1,
hour: 0,
minute: 0,
second: 0
}
};
},
mounted() {
this.refresh();
},
methods: {
refresh() {
this.count = new ReadCount({
count: getReadTimeCount()
})
this.$nextTick(() => {
this.$emit("resize");
})
},
}
}
</script>
<style lang="scss">
.read-time-count-row {
padding: 20rpx;
.title {
width: 80rpx;
font-size: 30rpx;
color: #000000;
margin-right: 15rpx;
}
.value {
display: flex;
flex-direction: row;
.count {
position: relative;
margin-right: 15rpx;
font-size: 24rpx;
background-color: #FEF3F3;
border-radius: 10rpx;
width: 90rpx;
height: 90rpx;
color: #000000;
.count-value {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #000000;
font-size: 46rpx;
font-weight: 700;
}
.count-unit {
position: absolute;
right: 8rpx;
bottom: 8rpx;
}
}
}
}
</style>
\ No newline at end of file
<template>
<view class="recommendlist">
<view class="booklabel">
<view class="title">{{title}}</view>
<view class="change" @click="refreshList">换一换</view>
</view>
<view class="rowitem" v-if="listType==0||listType==2">
<book-list-item2 class="item" v-for='(item, index) in dataList' :key='index' :item='item'
@tapItem='tapItem($event, index)'>
</book-list-item2>
</view>
<view class="columnitem" v-else-if="listType==1">
<book-list-item :item='dataList[0]' :showClose='false'>
</book-list-item>
<view class="rowitem">
<book-list-item2 class="item" :item='item' v-if="index!=0" v-for='(item, index) in dataList'
:key='index' @tapItem='tapItem($event, index)'>
</book-list-item2>
</view>
</view>
<view class="columnitem" v-else-if="listType==3">
<book-list-item class="item" v-for='(item, index) in dataList' :key='index' :item='item'
@tapItem='tapItem($event, index)' :showClose='false'>
</book-list-item>
</view>
</view>
</template>
<script>
import common from '@/mixins/common';
import {
getCollects,
} from "../../common/services/index.js"
import {
gotoBookContentPage
} from '../../common/services/page-route.js';
import BookshelfBookItem from '../../common/models/BookshelfBookItem.js';
import {
collectionBook,
noticeCollectionListChange
} from "../../common/services/index.js"
export default {
mixins: [common],
props: {
listType: {
type: Number,
default: 0
}
},
data: function() {
return {
dataList: [],
title: '猜你喜欢',
}
},
mounted() {
if (this.listType == 0) {
this.title = '猜你喜欢'
} else if (this.listType == 1 || this.listType == 3) {
this.title = '热门推荐'
} else if (this.listType == 2) {
this.title = '新书推荐'
}
},
methods: {
refreshList() {
if (this.listType == 0) {
getCollects((success, data) => {
if (success) {
this.changeData(data)
}
})
} else if (this.listType == 1) {
getCollects((success, data) => {
if (success) {
this.changeData(data)
}
})
} else if (this.listType == 2) {
getCollects((success, data) => {
if (success) {
this.changeData(data)
}
})
} else if (this.listType == 3) {
getCollects((success, data) => {
if (success) {
this.changeData(data)
}
})
}
},
changeData(e) {
this.dataList = e.records.map(item => {
return new BookshelfBookItem(item)
})
},
tapItem(e, index) {
gotoBookContentPage(e.detail.data.id, e.detail.data.shortis)
},
}
}
</script>
<style lang="scss" scoped>
.recommendlist {
display: flex;
flex-direction: column;
border-radius: 20rpx;
background-color: white;
margin: 30rpx;
margin-bottom: 0;
.booklabel {
display: flex;
flex-direction: row;
justify-content: space-between;
height: 100rpx;
line-height: 100rpx;
padding: 0 20rpx;
.title {
font-weight: 500;
font-size: 34rpx;
color: #383B3D;
}
.change {
font-weight: 400;
font-size: 24rpx;
color: #A5A5AD;
}
}
.columnitem {
display: flex;
flex-direction: column;
}
.rowitem {
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding-left: 20rpx;
.item {
width: 22%;
margin-bottom: 20rpx;
margin-right: 20rpx;
}
.item:last-child {
margin-bottom: 0;
margin-right: 0;
}
}
}
</style>
\ No newline at end of file
<template>
<scroll-view class="bar-box" scroll-x id='box' :scroll-into-view="scrollId">
<view v-if='showEmpty' class="tab-item">
<view class="title">
暂无分类数据
</view>
</view>
<view v-else :id="'item_'+index" class="tab-item" :class="{'tab-item-selected': item.selected}"
v-for="(item, index) in tabs" :key='item.name' @click="tapTab(index)">
<view class="title">
{{item.name}}
</view>
</view>
</scroll-view>
</template>
<script>
import {
isEmpty
} from '../../../common/utils/util';
class Tab {
constructor(param) {
const {
name,
selected = false,
data
} = param || {}
this.name = name;
this.selected = selected;
this.data = data;
}
}
export default {
props: {
range: {
type: Array,
default: function() {
return []
}
},
rangeKey: {
type: String,
default: "name"
},
current: {
type: Number,
default: 0
}
},
data: function() {
return {
tabs: [],
tabIndex: 0,
scrollId: null
}
},
computed: {
showEmpty: function() {
return isEmpty(this.tabs);
},
tabValueChange: function() {
const {
range,
rangeKey,
tabIndex
} = this;
return {
range,
rangeKey,
tabIndex
}
},
},
watch: {
tabValueChange: {
handler: function(n) {
let range = n.range;
let rangeKey = n.rangeKey;
let tabIndex = n.tabIndex;
if (range) {
this.tabs = range.map((item, index) => {
return new Tab({
name: typeof item == 'object' ? item[rangeKey] : item,
selected: index == tabIndex,
data: item
})
})
} else {
this.tabs = [];
}
},
deep: true,
immediate: true
},
current: {
handler: function(n) {
this.tabIndex = n;
},
immediate: true
},
tabIndex: {
handler: function(n) {
this.scrollId = `item_${n}`
},
},
tabs: {
handler: function(n) {
this.$nextTick(() => {
this.$emit("ready")
})
},
immediate: true,
deep: true
}
},
methods: {
tapTab(index) {
if (this.tabIndex != index) {
this.tabIndex = index;
this.$emit("change", {
index: index,
value: this.tabs[index].data
})
}
}
}
}
</script>
<style lang="scss">
.bar-box {
white-space: nowrap;
padding: 0 20rpx;
width: calc(100% - 40rpx);
}
.tab-item {
display: inline-flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 25rpx 20rpx;
font-size: 30rpx;
background: transparent;
color: #888;
.title {
min-width: 80rpx;
text-align: center;
}
}
.tab-item:first-child {
padding-left: 0;
}
.tab-item:last-child {
padding-right: 0;
}
.tab-item-selected {
font-size: 36rpx;
font-weight: 700;
color: #333
}
<template>
<scroll-view class="bar-box" scroll-x id='box' :scroll-into-view="scrollId">
<view v-if='showEmpty' class="tab-item">
<view class="title">
暂无分类数据
</view>
</view>
<view v-else :id="'item_'+index" class="tab-item" :class="{'tab-item-selected': item.selected}"
v-for="(item, index) in tabs" :key='item.name' @click="tapTab(index)">
<view class="title">
{{item.name}}
</view>
</view>
</scroll-view>
</template>
<script>
import {
isEmpty
} from '../../../common/utils/util';
class Tab {
constructor(param) {
const {
name,
selected = false,
data
} = param || {}
this.name = name;
this.selected = selected;
this.data = data;
}
}
export default {
props: {
range: {
type: Array,
default: function() {
return []
}
},
rangeKey: {
type: String,
default: "name"
},
current: {
type: Number,
default: 0
}
},
data: function() {
return {
tabs: [],
tabIndex: 0,
scrollId: null
}
},
computed: {
showEmpty: function() {
return isEmpty(this.tabs);
},
tabValueChange: function() {
const {
range,
rangeKey,
tabIndex
} = this;
return {
range,
rangeKey,
tabIndex
}
},
},
watch: {
tabValueChange: {
handler: function(n) {
let range = n.range;
let rangeKey = n.rangeKey;
let tabIndex = n.tabIndex;
if (range) {
this.tabs = range.map((item, index) => {
return new Tab({
name: typeof item == 'object' ? item[rangeKey] : item,
selected: index == tabIndex,
data: item
})
})
} else {
this.tabs = [];
}
},
deep: true,
immediate: true
},
current: {
handler: function(n) {
this.tabIndex = n;
},
immediate: true
},
tabIndex: {
handler: function(n) {
this.scrollId = `item_${n}`
},
},
tabs: {
handler: function(n) {
this.$nextTick(() => {
this.$emit("ready")
})
},
immediate: true,
deep: true
}
},
methods: {
tapTab(index) {
if (this.tabIndex != index) {
this.tabIndex = index;
this.$emit("change", {
index: index,
value: this.tabs[index].data
})
}
}
}
}
</script>
<style lang="scss">
.bar-box {
margin: 20rpx 0;
white-space: nowrap;
padding: 0 20rpx;
width: calc(100% - 40rpx);
}
.tab-item {
display: inline-flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: 30rpx;
padding: 8rpx 16rpx;
font-size: 30rpx;
background: #EEEEEE;
color: #6B6B6B;
margin: 0 16rpx;
.title {
min-width: 80rpx;
text-align: center;
}
}
.tab-item:first-child {
margin-left: 0;
}
.tab-item:last-child {
margin-right: 0;
}
.tab-item-selected {
background: #F1413C;
color: white;
}
</style>
\ No newline at end of file
<template>
<z-paging>
<c-navi id='navi'></c-navi>
<book-search-box id='search'></book-search-box>
<scroll-view scroll-y style="height: 100%;">
<CategoryBar id='category' :range='categorys' :current='currentIndex' @change='changeCategory'
@ready='readyCategory'></CategoryBar>
<view :style="[listStyle]" v-if='showEmpty'>
......@@ -12,12 +10,11 @@
@change="changeSwiper">
<swiper-item v-for='(item, index) in categorys' :key='index'>
<WarehouseList :ref="`bookList${index}`" :category='item' :height='listHeight'></WarehouseList>
<!-- <WarehouseList ref="bookList" :category='item' :height='listHeight'></WarehouseList> -->
</swiper-item>
</swiper>
</view>
<c-login></c-login>
</z-paging>
</view>
<view style="height: 20rpx;"></view>
</scroll-view>
</template>
<script>
......@@ -60,7 +57,7 @@
},
listStyle: function() {
return {
height: `${this.listHeight}px`
height: `${this.listHeight}px`,
}
},
categroyChange: function() {
......@@ -119,7 +116,7 @@
if (success) {
setTimeout(() => {
// 匹配用户直接跳转小说
if (data.articleMsg != null) {
if (data.articleMsg != null) {
gotoBookContentPage(data.articleMsg.id, data.articleMsg.shortis);
}
}, 800);
......
<template>
<view>
<search-header-bar id='headerBar' :keyword='keyword' @clear='clearSearch'
@start='startSearch'></search-header-bar>
<view :style='[placeholderViewStyle]'>
<search-placeholder-view ref='placeholder' :height='listHeight'
@chooseKeyword='chooseKeyword'></search-placeholder-view>
</view>
<view :style="[resultViewStyle]">
<search-result-view ref='searchList' :height='listHeight' :keyword='keyword' :searchType='searchType'
:result='result' @change='changeResult'></search-result-view>
</view>
<c-login></c-login>
</view>
</template>
<script>
import SearchHeaderBar from "./components/search-header-bar.vue";
import SearchPlaceholderView from "./components/search-placeholder.vue";
import SearchResultView from "./components/search-result.vue"
import {
isEmpty,
isNotEmpty
} from "../../../common/utils/util.js"
import {
ENUM_SEARCH_TYPE
} from "../../../static/enums/enum_value";
export default {
components: {
SearchHeaderBar,
SearchPlaceholderView,
SearchResultView
},
data() {
return {
searchType: null,
keyword: "",
result: null,
listHeight: 0
};
},
onReady() {
const eventChannel = this.getOpenerEventChannel();
eventChannel.on("openBookSearchPage", (info) => {
this.keyword = info.keyword || '';
this.searchType = info.searchType || ENUM_SEARCH_TYPE.WAREHOUSE;
uni.setNavigationBarTitle({
title: this.searchType.name
})
})
},
onShow() {
this.initHeight();
},
computed: {
placeholderViewStyle() {
return isNotEmpty(this.result, true) ? {
display: "none"
} : {}
},
resultViewStyle: function() {
return isEmpty(this.result, true) ? {
display: "none"
} : {}
},
},
methods: {
chooseKeyword(e) {
this.keyword = e.detail.keyword;
this.result = [];
this.refreshSearchList();
},
clearSearch(e) {
this.keyword = "";
this.result = null;
},
startSearch(e) {
if (isEmpty(this.result, true)) {
this.result = [];
}
this.keyword = e.detail.keyword;
this.refreshSearchList()
},
refreshSearchList() {
if (!this.keyword) return;
let ref = this.$refs.searchList;
if (ref) {
ref.refreshList()
}
},
changeResult(e) {
this.resultList = e.detail.data;
},
initHeight() {
const query = uni.createSelectorQuery().in(this);
query.select("#headerBar").boundingClientRect();
query.exec((res) => {
let height = 0;
res.forEach(item => {
if (item && item.height) {
height = height + item.height;
}
})
this.listHeight = uni.getSystemInfoSync().windowHeight - height;
})
},
}
}
</script>
<style lang="scss" scoped>
.test {
display: none;
}
<template>
<scroll-view scroll-y style="height: 100%;background: #FFF7F7;">
<search-header-bar id='headerBar' :keyword='keyword' @clear='clearSearch'
@start='startSearch'></search-header-bar>
<view :style='[placeholderViewStyle]'>
<search-placeholder-view ref='placeholder' :height='listHeight'
@chooseKeyword='chooseKeyword'></search-placeholder-view>
</view>
<view :style="[resultViewStyle]">
<search-result-view ref='searchList' :height='listHeight' :keyword='keyword' :searchType='searchType'
:result='result' @change='changeResult'></search-result-view>
</view>
<view style="height: 20rpx;"></view>
</scroll-view>
</template>
<script>
import SearchHeaderBar from "./components/search-header-bar.vue";
import SearchPlaceholderView from "./components/search-placeholder.vue";
import SearchResultView from "./components/search-result.vue"
import {
isEmpty,
isNotEmpty
} from "../../../common/utils/util.js"
import {
ENUM_SEARCH_TYPE
} from "../../../static/enums/enum_value";
export default {
components: {
SearchHeaderBar,
SearchPlaceholderView,
SearchResultView
},
data() {
return {
searchType: null,
keyword: "",
result: null,
listHeight: 0
};
},
onReady() {
const eventChannel = this.getOpenerEventChannel();
eventChannel.on("openBookSearchPage", (info) => {
this.keyword = info.keyword || '';
this.searchType = info.searchType || ENUM_SEARCH_TYPE.WAREHOUSE;
uni.setNavigationBarTitle({
title: this.searchType.name
})
})
},
onShow() {
this.initHeight();
},
computed: {
placeholderViewStyle() {
return isNotEmpty(this.result, true) ? {
display: "none"
} : {}
},
resultViewStyle: function() {
return isEmpty(this.result, true) ? {
display: "none"
} : {}
},
},
methods: {
chooseKeyword(e) {
this.keyword = e.detail.keyword;
this.result = [];
this.refreshSearchList();
},
clearSearch(e) {
this.keyword = "";
this.result = null;
},
startSearch(e) {
if (isEmpty(this.result, true)) {
this.result = [];
}
this.keyword = e.detail.keyword;
this.refreshSearchList()
},
refreshSearchList() {
if (!this.keyword) return;
let ref = this.$refs.searchList;
if (ref) {
ref.refreshList()
}
},
changeResult(e) {
this.resultList = e.detail.data;
},
initHeight() {
const query = uni.createSelectorQuery().in(this);
query.select("#headerBar").boundingClientRect();
query.exec((res) => {
let height = 0;
res.forEach(item => {
if (item && item.height) {
height = height + item.height;
}
})
this.listHeight = uni.getSystemInfoSync().windowHeight - height;
})
},
}
}
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
......@@ -90,7 +90,6 @@
display: flex;
flex-direction: row;
align-items: center;
background: #fff;
font-size: 28rpx;
.item {
......
<template>
<view>
<c-list ref='list' :height="height" :ableRefresh="true" :ableLoadMore="true" :customRequest="true"
:sources="[1]" :needLogin="false" @refresh='refreshData' @loadMore='loadMoreData'>
<placeholder-section title='搜索历史' :itemSource='searchHistory' @tapItem='tapItem($event, "history")'>
<template v-slot:headerButton>
<view class="header-button" @click="tapDeleteHistory">
<uni-icons type='trash' size='30' color="#999"></uni-icons>
</view>
</template>
</placeholder-section>
<placeholder-section title='热门搜索' :itemSource='hotSearch' @tapItem='tapItem($event, "hot")' v-if='false'>
</placeholder-section>
<placeholder-section title='热门推荐'>
<c-empty v-if='recommondEmpty'></c-empty>
<template v-else>
<recommond-item v-for='(item, index) in hotRecommond' :key='index' :item='item'></recommond-item>
</template>
</placeholder-section>
</c-list>
</view>
</template>
<script>
import PlaceholderSection from "./search-placeholder-section.vue"
import {
saveSearchHistory,
watchSearchHistoryChange,
clearSearchHistory,
removeSearchHistoryChangeWatch,
getHotRecommondData,
} from "../services/index.js"
import HotRecommondBook from "../models/HotRecommondBook.js"
import RecommondItem from "./recommond-item.vue"
import {
isEmpty
} from "../../../../common/utils/util"
export default {
components: {
PlaceholderSection,
RecommondItem
},
props: {
height: {
type: Number,
default: 0
}
},
data: function() {
return {
searchHistory: [],
hotSearch: [],
hotRecommond: [],
}
},
mounted() {
watchSearchHistoryChange((result) => {
this.searchHistory = result;
}, this);
this.initRefresh();
},
destroyed() {
removeSearchHistoryChangeWatch(this);
},
computed: {
recommondEmpty: function() {
return isEmpty(this.hotRecommond);
},
},
methods: {
tapDeleteHistory() {
clearSearchHistory()
},
tapItem(e, flag) {
this.$emit('chooseKeyword', {
detail: {
keyword: e.detail.item
}
})
},
initRefresh() {
let ref = this.$refs.list;
if (ref) {
ref.initRefresh();
}
},
refreshData(e) {
let pageNo = e.detail.pageNo;
let pageSize = e.detail.pageSize;
this.getHotRecommondData(pageNo, pageSize)
},
loadMoreData(e) {
let pageNo = e.detail.pageNo;
let pageSize = e.detail.pageSize;
this.getHotRecommondData(pageNo, pageSize)
},
getHotRecommondData(pageNo, pageSize) {
getHotRecommondData(pageNo, pageSize, (success, data) => {
let ref = this.$refs.list;
if (success) {
ref.pageNoStep();
data = data.map(item => {
return new HotRecommondBook(item)
})
if (pageNo == 0) {
this.hotRecommond = data;
} else {
this.hotRecommond = this.hotRecommond.concat(data);
}
}
ref.closeTrigger();
ref.changeLoadMoreStatus(this.hotRecommond.length < 16, false);
})
},
}
}
</script>
<style lang="scss" scoped>
.header-button {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 50rpx;
width: 50rpx;
}
<template>
<view>
<!-- <c-list ref='list' :height="height" :ableRefresh="true" :ableLoadMore="true" :customRequest="true"
:sources="[1]" :needLogin="false" @refresh='refreshData' @loadMore='loadMoreData'> -->
<placeholder-section title='搜索历史' :itemSource='searchHistory' @tapItem='tapItem($event, "history")'>
<template v-slot:headerButton>
<view class="header-button" @click="tapDeleteHistory">
<uni-icons type='trash' size='30' color="#999"></uni-icons>
</view>
</template>
</placeholder-section>
<placeholder-section title='热门搜索' :itemSource='hotSearch' @tapItem='tapItem($event, "hot")' v-if='false'>
</placeholder-section>
<RecommendList ref='recommendList' :listType="3"></RecommendList>
<!-- <placeholder-section title='热门推荐'> -->
<!-- <c-empty v-if='recommondEmpty'></c-empty> -->
<!-- <template v-else> -->
<!-- </template> -->
<!-- </placeholder-section> -->
<!-- </c-list> -->
</view>
</template>
<script>
import PlaceholderSection from "./search-placeholder-section.vue"
import {
saveSearchHistory,
watchSearchHistoryChange,
clearSearchHistory,
removeSearchHistoryChangeWatch,
getHotRecommondData,
} from "../services/index.js"
import HotRecommondBook from "../models/HotRecommondBook.js"
// import RecommondItem from "./recommond-item.vue"
import RecommendList from "../../../../components/recommend-list/recommend-list.vue"
import {
isEmpty
} from "../../../../common/utils/util"
export default {
components: {
PlaceholderSection,
// RecommondItem,
RecommendList
},
props: {
height: {
type: Number,
default: 0
}
},
data: function() {
return {
searchHistory: [],
hotSearch: [],
hotRecommond: [],
}
},
mounted() {
watchSearchHistoryChange((result) => {
this.searchHistory = result;
}, this);
this.initRefresh();
},
destroyed() {
removeSearchHistoryChangeWatch(this);
},
computed: {
recommondEmpty: function() {
return isEmpty(this.hotRecommond);
},
},
methods: {
tapDeleteHistory() {
clearSearchHistory()
},
tapItem(e, flag) {
this.$emit('chooseKeyword', {
detail: {
keyword: e.detail.item
}
})
},
initRefresh() {
// let ref = this.$refs.list;
// if (ref) {
// ref.initRefresh();
// }
let ref = this.$refs.recommendList;
if (ref) {
ref.refreshList();
}
},
refreshData(e) {
let pageNo = e.detail.pageNo;
let pageSize = e.detail.pageSize;
this.getHotRecommondData(pageNo, pageSize)
},
loadMoreData(e) {
let pageNo = e.detail.pageNo;
let pageSize = e.detail.pageSize;
this.getHotRecommondData(pageNo, pageSize)
},
getHotRecommondData(pageNo, pageSize) {
let ref = this.$refs.recommendList;
if (ref) {
ref.refreshList();
}
// getHotRecommondData(pageNo, pageSize, (success, data) => {
// let ref = this.$refs.list;
// if (success) {
// ref.pageNoStep();
// data = data.map(item => {
// return new HotRecommondBook(item)
// })
// if (pageNo == 0) {
// this.hotRecommond = data;
// } else {
// this.hotRecommond = this.hotRecommond.concat(data);
// }
// }
// ref.closeTrigger();
// ref.changeLoadMoreStatus(this.hotRecommond.length < 16, false);
// })
},
}
}
</script>
<style lang="scss" scoped>
.header-button {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 50rpx;
width: 50rpx;
}
</style>
\ No newline at end of file
......@@ -2,12 +2,12 @@
<view v-if="localActiviteFlag==1" class="body">
<view style="height: 92%;">
<bookshelf v-show="currentPage==0" ref="index" />
<warehouse v-show="currentPage==1" ref="recommend" />
<userPage v-show="currentPage==2" ref="user" />
<bookcity v-show="currentPage==1" ref="city" />
<warehouse v-show="currentPage==2" ref="recommend" />
<userPage v-show="currentPage==3" ref="user" />
</view>
<view class="tabs-bar" style="z-index: 999;">
<view :class="currentPage==0?'tab active': 'tab'" :style="'padding-bottom:' + bottomSafePadding + 'px;'"
@click="tabChange(0)">
<view :class="currentPage==0?'tab active': 'tab'" @click="tabChange(0)">
<view style="margin: 16rpx 0 11rpx;">
<image v-if="currentPage==0" class="tabs-image" src="/static/tab/index_selected.png"
mode="heightFix">
......@@ -16,19 +16,25 @@
</view>
书架
</view>
<view :class="currentPage == 1?'tab active': 'tab'" :style="'padding-bottom:' + bottomSafePadding + 'px;'"
@click="tabChange(1)">
<view :class="currentPage == 1?'tab active': 'tab'" @click="tabChange(1)">
<view style="margin: 16rpx 0 11rpx;">
<image v-if="currentPage==1" class="tabs-image" src="/static/tab/promote_selected.png"
mode="heightFix"></image>
<image v-else class="tabs-image" src="/static/tab/promote_unselected.png" mode="heightFix"></image>
</view>
书城
</view>
<view :class="currentPage == 2?'tab active': 'tab'" @click="tabChange(2)">
<view style="margin: 16rpx 0 11rpx;">
<image v-if="currentPage==2" class="tabs-image" src="/static/tab/promote_selected.png"
mode="heightFix"></image>
<image v-else class="tabs-image" src="/static/tab/promote_unselected.png" mode="heightFix"></image>
</view>
书库
</view>
<view :class="currentPage == 2?'tab active': 'tab'" :style="'padding-bottom:' + bottomSafePadding + 'px;'"
@click="tabChange(2)">
<view :class="currentPage == 3?'tab active': 'tab'" @click="tabChange(3)">
<view style="margin: 16rpx 0 11rpx;">
<image v-if="currentPage==2" class="tabs-image" src="/static/tab/my_selected.png" mode="heightFix">
<image v-if="currentPage==3" class="tabs-image" src="/static/tab/my_selected.png" mode="heightFix">
</image>
<image v-else class="tabs-image" src="/static/tab/my_unselected.png" mode="heightFix"></image>
</view>
......@@ -63,6 +69,7 @@
const app = getApp();
import bookshelf from "@/components/bookshelf/bookshelf.vue";
import bookcity from "@/components/bookcity/bookcity.vue";
import warehouse from "@/components/warehouse/warehouse.vue";
import userPage from "@/components/home/my.vue";
......@@ -71,6 +78,7 @@
mixins: [common],
components: {
bookshelf,
bookcity,
warehouse,
userPage
},
......@@ -91,13 +99,7 @@
},
onShow() {
try {
// 在子组件重写show()代替onShow()
// if (this.currentPage == 0) {
// this.$refs.index.show();
// } else if (this.currentPage == 1) {
// this.$refs.recommend.show();
// } else
if (this.currentPage == 2) {
if (this.currentPage == 3) {
this.$refs.user.show();
}
} catch (e) {
......@@ -108,7 +110,7 @@
uni.$on('refreshPreviousPage', (data) => {
if (data.vipFlag == '1') {
// 开通vip刷新状态
if (that.currentPage == 2) {
if (that.currentPage == 3) {
that.$refs.user.show();
}
}
......@@ -138,13 +140,15 @@
if (this.currentPage == 0) {
this.$refs.index.show();
} else if (this.currentPage == 1) {
this.$refs.recommend.show();
this.$refs.city.show();
} else if (this.currentPage == 2) {
this.$refs.recommend.show();
} else if (this.currentPage == 3) {
this.$refs.user.show();
}
} else {
if (this.currentPage == 1) {
this.$refs.recommend.show();
this.$refs.city.show();
}
}
}
......@@ -155,7 +159,7 @@
<style lang="scss">
.body {
height: 100%;
background-color: whitesmoke;
background: #FFF7F7;
}
.avatar {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment