Commit 7375eeb9 authored by jyx's avatar jyx

更新首页UI

parent c78d0055
......@@ -36,7 +36,7 @@
this.globalData.bottomSafePadding = Math.max(res.screenHeight - res.safeArea.bottom, 12);
// #endif
try {
let value = uni.getStorageSync('token') || '';
let value = uni.getStorageSync('TOKEN') || '';
let inviteUId = uni.getStorageSync('inviteUId') || '';
if (!inviteUId && options.query.inviteUId) {
......
// export default {
// created() {
// //#ifdef MP-WEIXIN
// wx.showShareMenu({
// withShareTicket: true,
// menus: ['shareAppMessage', 'shareTimeline']
// });
// //#endif
// },
// }
export default {
data() {
......
import Label from "./Label";
export default class Book {
constructor(param) {
const {
id,
title,
avatar,
summary,
author,
isStick,
isOriginal,
isPublish,
content,
username,
userAvatar,
quantity,
commentCount,
likeCount,
collectCount,
isCollect,
commentContent,
categoryName,
categoryId,
createTime,
tagList,
isUnlock,
free,
charge,
bookLegumes,
lockRate
} = param || {}
this.id = id;
this.title = title;
this.avatar = avatar || "/static/images/logo.png";
this.summary = summary;
this.tagList = tagList ? tagList.map(item => {
return new Label(item)
}).sort((a, b) => {
return a.sort - b.sort
}) : [];
this.author = author;
this.isStick = isStick;
this.isOriginal = isOriginal;
this.isPublish = isPublish;
this.content = content;
this.username = username;
this.userAvatar = userAvatar;
this.quantity = quantity;
this.commentContent = commentContent;
this.commentCount = commentCount
this.likeCount = likeCount;
this.collectCount = collectCount;
this.isCollect = isCollect;
this.categoryName = categoryName;
this.categoryId = categoryId;
this.createTime = createTime;
this.isUnlock = isUnlock;
this.charge = charge;
this.free = free;
this.bookLegumes = bookLegumes;
this.lockRate = lockRate;
}
import Label from "./Label";
export default class Book {
constructor(param) {
const {
id,
title,
avatar,
summary,
author,
isStick,
isOriginal,
isPublish,
content,
username,
userAvatar,
quantity,
commentCount,
likeCount,
collectCount,
isCollect,
commentContent,
categoryName,
categoryId,
createTime,
tagList,
isUnlock,
bookLegumes,
lockRate,
shortis,
articleChapterList,
freeNum,
carouselUrl,
isChecked
} = param || {}
this.id = id;
this.title = title;
this.avatar = avatar || "/static/images/logo.png";
this.summary = summary;
this.tagList = tagList ? tagList.map(item => {
return new Label(item)
}).sort((a, b) => {
return a.sort - b.sort
}) : [];
this.author = author;
this.isStick = isStick;
this.isOriginal = isOriginal;
this.isPublish = isPublish;
this.content = content;
this.username = username;
this.userAvatar = userAvatar;
this.quantity = quantity;
this.commentContent = commentContent;
this.commentCount = commentCount
this.likeCount = likeCount;
this.collectCount = collectCount;
this.isCollect = isCollect;
this.categoryName = categoryName;
this.categoryId = categoryId;
this.createTime = createTime;
this.isUnlock = isUnlock;
this.bookLegumes = bookLegumes;
this.lockRate = lockRate;
this.shortis = shortis;
this.freeNum = freeNum;
this.carouselUrl = carouselUrl;
this.isChecked = isChecked;
this.articleChapterList = articleChapterList;
}
}
\ No newline at end of file
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
......@@ -167,7 +167,7 @@ function collectionBook(isCollected, bookId, callback) {
apiPOST({
url,
data: {
articleId:bookId
articleId: bookId
},
callback
})
......@@ -284,6 +284,14 @@ function getBookBeanPackData(callback) {
})
}
function getCollects(callback) {
apiPOST({
url: "/book/collectList",
data: {},
callback
})
}
/**
* 解锁书籍
......@@ -299,7 +307,43 @@ function buyBookWithBookBean(bookId, callback) {
callback
})
}
/**
* 获取推荐书籍
* @param {Object} flag
* @param {Object} quantity
*/
function getRecommendV1(flag, quantity, callback) {
apiPOST({
url: `/book/recommendv1`,
data: {
flag: flag,
quantity: quantity
},
callback
})
}
/**
* 猜你喜欢
* @param {Object} flag
*/
function getArticleLike(quantity, callback) {
apiPOST({
url: `/book/articleLike`,
data: {
quantity: quantity
},
callback
})
}
module.exports = {
getRecommendV1,
getArticleLike,
getCollects,
getOpens,
getReadTimeCount,
startCountReadTime,
......
const {
ENUM_SEARCH_TYPE,
ENUM_MESSAGE_PAGE_TYPE
} = require("../../static/enums/enum_value");
// 搜索页面
function gotoBookSearchPage(searchType = ENUM_SEARCH_TYPE.WAREHOUSE, keyword) {
uni.navigateTo({
url: `/page-subs/sub_A/book-search/book-search`,
success: (res) => {
res.eventChannel.emit("openBookSearchPage", {
keyword,
searchType
})
}
})
}
// 文章详情
function gotoBookContentPage(bookId) {
uni.navigateTo({
url: `/page-subs/sub_A/book-content/book-content`,
success: (res) => {
res.eventChannel.emit("openBookContentPage", {
bookId
})
}
})
}
// 文章封面
function gotoBookCoverPage(bookId) {
return;
uni.navigateTo({
url: `/page-subs/sub_A/book-cover/book-cover`,
success: (res) => {
res.eventChannel.emit("openBookCoverPage", {
bookId
})
}
})
}
// vip申请
function gotoVIPApplyPage() {
uni.navigateTo({
url: `/pagesA//vipPay/vipPay`,
})
}
// 用户编辑
function gotoUserEditPage(userInfo) {
uni.navigateTo({
url: `/page-subs/sub_B/user-edit/user-edit`,
success: (res) => {
res.eventChannel.emit("openUserEditPage", {
userInfo
})
}
})
}
module.exports = {
/** sub_A */
gotoBookSearchPage,
gotoBookContentPage,
gotoBookCoverPage,
/** sub_B */
gotoVIPApplyPage,
gotoUserEditPage,
const {
ENUM_SEARCH_TYPE,
ENUM_MESSAGE_PAGE_TYPE
} = require("../../static/enums/enum_value");
// 搜索页面
function gotoBookSearchPage(searchType = ENUM_SEARCH_TYPE.WAREHOUSE, keyword) {
uni.navigateTo({
url: `/page-subs/sub_A/book-search/book-search`,
success: (res) => {
res.eventChannel.emit("openBookSearchPage", {
keyword,
searchType
})
}
})
}
// 文章详情
function gotoBookContentPage(bookId, shortis) {
if (shortis && shortis == 0) {
gotoShortBookContentPage(bookId)
} else {
gotoLongBookContentPage(bookId)
}
}
// 短篇文章详情
function gotoShortBookContentPage(bookId) {
// 短篇小说
uni.navigateTo({
url: `/page-subs/sub_A/book-content/book-content`,
success: (res) => {
res.eventChannel.emit("openBookContentPage", {
bookId
})
}
})
}
// 长篇文章详情
function gotoLongBookContentPage(bookId) {
uni.navigateTo({
url: `/page-subs/sub_A/book-long-content/book-long-content`,
success: (res) => {
res.eventChannel.emit("openBookContentPage", {
bookId
})
}
})
}
// 文章封面
function gotoBookCoverPage(bookId) {
return;
uni.navigateTo({
url: `/page-subs/sub_A/book-cover/book-cover`,
success: (res) => {
res.eventChannel.emit("openBookCoverPage", {
bookId
})
}
})
}
// vip申请
function gotoVIPApplyPage() {
uni.navigateTo({
url: `/pagesA//vipPay/vipPay`,
})
}
// 用户编辑
function gotoUserEditPage(userInfo) {
uni.navigateTo({
url: `/page-subs/sub_B/user-edit/user-edit`,
success: (res) => {
res.eventChannel.emit("openUserEditPage", {
userInfo
})
}
})
}
module.exports = {
/** sub_A */
gotoBookSearchPage,
gotoBookContentPage,
gotoBookCoverPage,
/** sub_B */
gotoVIPApplyPage,
gotoUserEditPage,
}
\ No newline at end of file
......@@ -247,8 +247,7 @@ function saveToken(token) {
function readToken() {
if (!LOCAL_TOKEN) {
// LOCAL_TOKEN = readStorage(KEY_STORAGE_TOKEN)
LOCAL_TOKEN = readStorage('token')
LOCAL_TOKEN = readStorage(KEY_STORAGE_TOKEN)
}
return LOCAL_TOKEN;
}
......
<template>
<view class="banneritem">
<swiper :autoplay="true" :interval="2000" :duration="500">
<swiper-item @click="handleBanner(item)" v-for='(item, index) in bannerList' :key='index'
style="border-radius: 20rpx;">
<image class="banner-img" :src="item.carouselUrl" mode="aspectFill"></image>
</swiper-item>
</swiper>
</view>
</template>
<script>
import {
gotoBookContentPage
} from '../../common/services/page-route.js';
import {
getRecommendV1
} from "../../common/services/index.js"
import BookshelfBookItem from '../../common/models/BookshelfBookItem.js';
import SystemInfoMixin from "../../common/mixins/system-info-mixin.js"
export default {
mixins: [SystemInfoMixin],
data() {
return {
bannerList: []
};
},
methods: {
handleBanner(e) {
gotoBookContentPage(e.id, e.shortis)
},
initData() {
this.refreshList();
},
// 刷新数据列表
refreshList() {
getRecommendV1('carousel', 10, (success, data) => {
if (success) {
this.changeData(data)
}
})
},
changeData(e) {
this.bannerList = e.records.map(item => {
return new BookshelfBookItem(item)
})
},
}
}
</script>
<style lang="scss">
.banneritem {
margin: 20rpx 30rpx 0 30rpx;
// height: 310rpx;
.banner-img {
height: 320rpx;
}
}
</style>
\ No newline at end of file
<template>
<view class="book-list-item" @click="tapItem">
<view class="cover-box item">
<!-- <image v-show="imageError" class="cover" src="/static/images/image_error.png" mode="aspectFill"></image> -->
<image class="cover" :src="item.avatar" mode="aspectFill"></image>
</view>
<view class="c-flex_column">
<view class="c-flex_row row" style="justify-content: space-between;padding-left:20rpx;">
<view class="c-flex_row row" style="justify-content: space-between;">
<view class="c-flex_column c-justify_center item">
<view class="title">
{{item.title}}
{{item.title?item.title:''}}
</view>
</view>
<view class="close-button item" v-if='showClose'>
......@@ -17,9 +16,9 @@
</view>
</view>
<view class="c-flex_row row">
<view class="c-flex_column c-justify_between content c-flex_1 item">
<view class="c-flex_column c-justify_between c-flex_1 item">
<view class="desc row">
{{item.summary}}
{{item.summary?item.summary:''}}
</view>
<view class="c-flex_row c-align_center label-box row">
<slot name="footer">
......@@ -60,7 +59,11 @@
watch: {},
computed: {
showCategory: function() {
return this.item.categoryName
if (this.item && this.item.categoryName) {
return true
} else {
return false
}
},
showErrorImage: function() {
return this.imageError;
......@@ -96,10 +99,10 @@
</script>
<style lang="scss" scoped>
.book-list-item {
.book-list-item {
display: flex;
flex-direction: row;
padding: 20rpx 40rpx;
padding: 20rpx 20rpx;
.row {
margin-bottom: 20rpx;
......@@ -121,6 +124,9 @@
font-size: 32rpx;
font-weight: 700;
color: #333;
overflow: hidden;
white-space: nowrap; //单行显示
text-overflow: ellipsis; //超出部分省略号显示
}
.close-button {
......@@ -150,7 +156,7 @@
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
font-size: 26rpx;
......@@ -158,13 +164,17 @@
}
.label-box {
flex-wrap: wrap;
flex-wrap: wrap;
flex-direction: row;
overflow: auto;
.label {
padding: 5rpx 10rpx;
font-size: 20rpx;
margin-right: 20rpx;
border-radius: 10rpx;
border-radius: 10rpx;
flex-shrink: 0;
display: inline-block;
}
.label-color-1 {
......@@ -173,8 +183,8 @@
}
.label-color-2 {
color: #3d99fd;
background: #d8ebff;
color: #F1413C;
background: #FEF3F3;
}
.label-color-3 {
......@@ -186,8 +196,8 @@
.cover-box {
.cover {
width: 150rpx;
height: 200rpx;
width: 165rpx;
height: 220rpx;
border-radius: 15rpx;
}
}
......
<template>
<view class="cover-box" @click="tapItem">
<image v-if="!last" class="cover" :style="'height:'+ coverHeight + 'rpx;'" :src="item.avatar" mode="aspectFill">
</image>
<image v-else class="cover" :style="'height:'+ coverHeight + 'rpx;'"
src="https://mints-pkg.oss-cn-beijing.aliyuncs.com/pkg/img/bg_book_more.png" mode="scaleToFill"></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
},
coverHeight: {
type: Number,
default: 220
}
},
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;
height: 70rpx;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2; //元素几行显示
-webkit-box-orient: vertical;
}
.cover {
width: 100%;
border-radius: 15rpx;
}
.label-box {
margin-top: 6rpx;
display: flex;
flex-direction: row;
overflow: auto;
.label {
padding: 5rpx 10rpx;
font-size: 20rpx;
margin-right: 20rpx;
border-radius: 10rpx;
flex-shrink: 0;
display: inline-block;
}
.label-color-1 {
background: #faefe6;
color: #cc6008;
}
.label-color-2 {
color: #F1413C;
background: #FEF3F3;
}
.label-color-3 {
background: #ff8787;
color: #ff3737;
}
}
}
</style>
\ No newline at end of file
<template>
<view class="book-list-item" @click="tapItem">
<view class="cover-box">
<image class="cover" :src="item.avatar" mode="aspectFill"></image>
</view>
<view class="c-flex_column">
<view class="c-flex_row row" style="justify-content: space-between;">
<view class="c-flex_column c-justify_center item">
<view class="title">
{{item.title?item.title:''}}
</view>
</view>
</view>
<view class="c-flex_row row">
<view class="c-flex_column c-justify_between c-flex_1 item">
<view class="desc row">
{{item.summary?item.summary:''}}
</view>
<view class="label-box row">
<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>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
item: {
type: Object,
default: function() {
return {}
}
}
},
data: function() {
return {
imageError: true
}
},
watch: {},
computed: {
showCategory: function() {
if (this.item && this.item.categoryName) {
return true
} else {
return false
}
},
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>
.book-list-item {
display: flex;
flex-direction: row;
// padding: 20rpx 20rpx;
.row {
margin-bottom: 20rpx;
}
.row:last-child {
margin-bottom: 0;
}
.item {
width: 140rpx;
}
.title {
width: 100%;
font-size: 26rpx;
margin-top: 10rpx;
color: #383B3D;
height: 70rpx;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2; //元素几行显示
-webkit-box-orient: vertical;
}
.desc {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
font-size: 26rpx;
color: #999
}
.label-box {
display: flex;
flex-direction: row;
overflow: auto;
.label {
padding: 5rpx 10rpx;
font-size: 20rpx;
margin-right: 20rpx;
border-radius: 10rpx;
flex-shrink: 0;
display: inline-block;
}
.label-color-1 {
background: #faefe6;
color: #cc6008;
}
.label-color-2 {
color: #F1413C;
background: #FEF3F3;
}
.label-color-3 {
background: #ff8787;
color: #ff3737;
}
}
}
.cover-box {
margin-right: 20rpx;
.cover {
width: 165rpx;
height: 260rpx;
border-radius: 15rpx;
}
}
</style>
\ No newline at end of file
......@@ -2,12 +2,12 @@
<view class="search-box" @click="search">
<view class="search-zone c-flex_row c-align_center">
<view class="item">
<uni-icons type='search' size='28' color="#e5e5e5"></uni-icons>
<uni-icons type='search' size='26' color="#949CA4"></uni-icons>
</view>
<input class="item c-flex_1" placeholder="搜索书名/作者名" disabled />
<view class="mbutton item">
<!-- <view class="mbutton item">
搜索
</view>
</view> -->
</view>
</view>
</template>
......@@ -39,17 +39,19 @@
<style lang="scss" scoped>
.search-box {
background: transparent;
padding: 10rpx 20rpx;
padding: 10rpx 30rpx;
.search-zone {
width: 100%;
// width: 100%;
border: solid 1rpx #FFE2E2;
border-radius: 35rpx;
background: #fff;
padding: 4rpx;
font-size: 28rpx;
.item {
margin-left: 20rpx;
margin-left: 20rpx;
color: #949CA4;
}
.mbutton {
......
<template>
<scroll-view scroll-y style="height: 100%;">
<book-search-box id='search'></book-search-box>
<Banner ref='banner'></Banner>
<RecommendList ref='recommendList1' :listType="1"></RecommendList>
<RecommendList ref='recommendList2' :listType="2"></RecommendList>
<view style="height: 20rpx;"></view>
</scroll-view>
</template>
<script>
import {
gotoBookContentPage
} from '../../common/services/page-route'
import {
getFirstShow
} from "./services/index.js"
import RecommendList from "../recommend-list/recommend-list.vue";
import Banner from "../banner/banner.vue";
import SystemInfoMixin from "../../common/mixins/system-info-mixin.js"
export default {
mixins: [SystemInfoMixin],
components: {
RecommendList,
Banner
},
data() {
return {
listHeight: 0
};
},
onReady() {
// this.initHeight();
this.initData();
},
onShow() {},
onUnload() {
// 移除监听
removeUserInfoChangeWatch(this);
},
methods: {
show() {
this.getFirstShowData();
},
hide() {
},
getFirstShowData() {
getFirstShow((success, data) => {
if (success) {
setTimeout(() => {
// 匹配用户直接跳转小说
if (data.articleMsg != null) {
gotoBookContentPage(data.articleMsg.id, data.articleMsg.shortis);
}
}, 800);
}
})
},
initData() {
this.refreshList();
},
// 刷新数据列表
refreshList() {
let ref2 = this.$refs.recommendList1;
if (ref2) {
ref2.refreshList();
}
let banner = this.$refs.banner;
if (banner) {
banner.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';
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)
}
}
}
</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"
function getFirstShow(callback) {
apiPOST({
url: "/book/firstArticle",
callback
})
}
module.exports = {
getFirstShow
}
\ 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' v-on:showEditBarR="showEditBarR"></BookshelfList>
<RecommendList ref='recommendList' :listType="0"></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,30 +17,27 @@
export default {
mixins: [SystemInfoMixin],
components: {
BookshelfList
BookshelfList,
RecommendList
},
data() {
return {
searchType: ENUM_SEARCH_TYPE.BOOKSHELF,
listHeight: 0
};
},
onReady() {
this.initHeight();
// 监听用户变动
watchUserInfoChange((info) => {
if (info.userInfo) {
this.initData();
}
}, this)
this.initData();
// 监听收藏变动
watchCollectionChange(() => {
this.refreshList();
this.refreshCollect();
}, this);
},
onShow() {
// 更新阅读时间统计
this.refreshTimeCount();
let ref = this.$refs.bookList;
if (ref) {
ref.refreshTimeCount();
}
},
onUnload() {
// 移除监听
......@@ -56,56 +45,33 @@
removeCollectionChangeWatch(this);
},
methods: {
show() {
this.$refs.timeCount.refresh()
this.initHeight();
// 监听用户变动
watchUserInfoChange((info) => {
if (info.userInfo) {
this.initData();
}
}, this)
// 监听收藏变动
watchCollectionChange(() => {
this.refreshList();
}, this);
show() {
let ref = this.$refs.bookList;
if (ref) {
ref.refreshTimeCount();
}
},
hide() {
},
resizeTimeCount() {
this.initHeight();
},
initData() {
this.refreshList();
this.refreshCollect();
this.refreshBook();
},
// 初始化刷新
initRefresh() {
let ref = this.$refs.bookList;
if (ref) {
ref.initRefresh();
}
},
// 刷新数据列表
refreshList() {
refreshCollect() {
let ref = this.$refs.bookList;
if (ref) {
ref.refreshList();
}
},
refreshTimeCount() {
let ref = this.$refs.timeCount;
refreshBook() {
let ref = this.$refs.recommendList;
if (ref) {
ref.refresh();
ref.refreshList();
}
},
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 => {
......@@ -114,6 +80,18 @@
this.listHeight = this.windowHeight - result;
})
},
showEditBarR(b) {
this.$emit("showEditBarH", b);
},
fullChoice() {
this.$refs.bookList.fullChoice()
},
noChoice() {
this.$refs.bookList.noChoice()
},
deleteCollect() {
this.$refs.bookList.deleteCollect()
},
}
}
</script>
......
<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>
</template>
<script>
import {
gotoBookContentPage
} from '../../../common/services/page-route';
import {
isEmpty
} from '../../../common/utils/util';
import BookshelfBookItem from '../models/BookshelfBookItem';
import {
collectionBook,
noticeCollectionListChange
} from "../../../common/services/index.js"
export default {
props: {
height: {
type: Number,
default: 0
},
},
data: function() {
return {
dataList: [],
}
},
computed: {
requestParam: function() {
return {}
}
},
methods: {
initRefresh() {
if (isEmpty(this.dataList)) {
this.refreshList();
}
},
refreshList() {
let ref = this.$refs.list;
if (ref) {
ref.onPullRefreshing();
}
},
changeData(e) {
console.log(e)
this.dataList = e.detail.data.map(item => {
return new BookshelfBookItem(item)
})
},
tapItem(e, index) {
gotoBookContentPage(e.detail.data.id)
},
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>
.info {
font-size: 26rpx;
color: #999;
margin-left: 10rpx;
}
<template>
<view class="bookshelf">
<view class="topitem">
<read-time-count-row id='count' ref='timeCount'></read-time-count-row>
<view @click="showEditBar = !showEditBar">
<image v-if="showEditBar" mode="widthFix" src="@/static/images/close.png">
</image>
<image v-else mode="widthFix" src="@/static/images/edit.png">
</image>
</view>
</view>
<view class="bookitem" v-if="dataList.length>0">
<shelf-list-item class="item" v-for='(item, index) in dataList' :key='index' :item='item'
:last="index>=dataList.length-1" @tapItem='tapItem($event, index)' @cbClick='cbClick(index)'
:showChecked="showEditBar" v-on:showEditBarR="showEditBarR">
</shelf-list-item>
</view>
<c-shelf-empty v-else></c-shelf-empty>
</view>
</template>
<script>
import SystemInfoMixin from "../../../common/mixins/system-info-mixin.js"
import ShelfListItem from "./shelf-list-item.vue";
import ReadTimeCountRow from "@/components/read-time-count-row/read-time-count-row.vue";
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: [SystemInfoMixin],
props: {
height: {
type: Number,
default: 0
},
},
components: {
ShelfListItem,
ReadTimeCountRow
},
data: function() {
return {
dataList: [],
bookMore: 'https://mints-pkg.oss-cn-beijing.aliyuncs.com/pkg/img/bg_book_more.png',
isEditStyle: false,
showEditBar: false
}
},
watch: {
showEditBar: {
handler(newValue, oldValue) {
this.$emit("showEditBarR", newValue)
}
},
},
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)
})
if (this.dataList.length > 0) {
this.dataList.push(
new BookshelfBookItem({}))
}
},
tapItem(e, index) {
if (index >= this.dataList.length - 1) {
uni.$emit('goWareHouse')
return
}
gotoBookContentPage(e.detail.data.id, e.detail.data.shortis)
},
showEditBarR(e) {
this.showEditBar = e
},
changeEditStyle(e) {
this.isEditStyle = e
if (!this.isEditStyle) {
this.noChoice()
}
},
cbClick(index) {
let newData = this.dataList[index]
newData.isChecked = !newData.isChecked
this.$set(this.dataList, index, newData)
},
longClick(index) {
this.isEditStyle = true
this.dataList[index].isChecked = true
},
fullChoice() {
for (let i = 0; i < this.dataList.length; i++) {
this.dataList[i].isChecked = true
}
},
noChoice() {
for (let i = 0; i < this.dataList.length; i++) {
this.dataList[i].isChecked = false
}
},
deleteCollect() {
let str = ''
for (let i = 0; i < this.dataList.length; i++) {
if (this.dataList[i].isChecked) {
if (this.dataList[i].id) {
str += (this.dataList[i].id + ',')
}
}
}
collectionBook(false, str, (success, data) => {
if (success) {
this.showEditBar = false
this.refreshList()
// noticeCollectionListChange('', false)
}
})
},
}
}
</script>
<style lang="scss" scoped>
.bookshelf {
display: flex;
flex-direction: column;
border-radius: 20rpx;
background-color: white;
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.1);
margin: 30rpx;
.topitem {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 0 30rpx;
image {
width: 50rpx;
height: 50rpx;
}
}
.bookitem {
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding-left: 20rpx;
.item {
width: 30%;
margin-bottom: 20rpx;
margin-right: 20rpx;
}
.item:last-child {
// margin-bottom: 0;
// margin-right: 0;
}
}
}
</style>
\ No newline at end of file
<template>
<view class="cover-box" @click.stop="tapItem" @longpress.stop="longClick">
<!-- <image v-show="imageError" class="cover" src="/static/images/image_error.png" mode="aspectFill"></image> -->
<image v-if="!last" class="cover" :src="item.avatar" mode="aspectFill">
</image>
<image v-else class="cover" src="https://mints-pkg.oss-cn-beijing.aliyuncs.com/pkg/img/bg_book_more.png"
mode="scaleToFill"></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 v-if="isEditStyle && !last" @click.stop="cbClick" style="position: absolute;background: #000000; opacity: 0.6;width: 92%;height: 96%;top: 0;border-radius:20rpx;
padding-left: 20rpx;padding-top: 20rpx;">
<image v-if="item.isChecked" src="@/static/images/ic_selected.png" style="width: 50rpx;height: 50rpx;" />
<image v-else src="@/static/images/ic_unselected.png" style="width: 50rpx;height: 50rpx;" />
</view>
</view>
</template>
<script>
export default {
props: {
item: {
type: Object,
default: function() {
return {}
}
},
last: {
type: Boolean,
default: false
},
showChecked: {
type: Boolean,
default: false
}
},
computed: {
showCategory: function() {
return this.item.categoryName
},
showErrorImage: function() {
return this.imageError;
},
hideErrorImage: function() {
return !this.imageError
}
},
watch: {
showChecked: {
handler(newValue, oldValue) {
this.isEditStyle = newValue
}
},
isEditStyle: {
handler(newValue, oldValue) {
this.$emit("showEditBarR", newValue)
}
},
},
data() {
return {
isEditStyle: false
};
},
methods: {
longClick() {
if (!this.isEditStyle) {
this.isEditStyle = true
this.cbClick()
}
},
tapItem() {
this.$emit("tapItem", {
detail: {
data: this.item
}
})
},
loadImage() {
this.imageError = false;
},
errorImage() {
this.imageError = true
},
changeEditStyle(e) {
this.isEditStyle = e
},
cbClick() {
this.$emit("cbClick")
}
}
}
</script>
<style lang="scss" scoped>
.cover-box {
display: flex;
flex-direction: column;
position: relative;
.title {
width: 100%;
font-size: 26rpx;
margin-top: 10rpx;
color: #383B3D;
height: 70rpx;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2; //元素几行显示
-webkit-box-orient: vertical;
}
.cover {
width: 100%;
height: 300rpx;
border-radius: 15rpx;
}
.label-box {
margin-top: 6rpx;
display: flex;
flex-direction: row;
overflow: auto;
.label {
padding: 5rpx 10rpx;
font-size: 20rpx;
margin-right: 20rpx;
border-radius: 10rpx;
flex-shrink: 0;
display: inline-block;
}
.label-color-1 {
background: #faefe6;
color: #cc6008;
}
.label-color-2 {
color: #F1413C;
background: #FEF3F3;
}
.label-color-3 {
background: #ff8787;
color: #ff3737;
}
}
}
</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
<template>
<scroll-view class="c-list" :style="[scrollStyle]" scroll-y :refresher-enabled='ableRefresh'
refresher-threshold='100' :enable-flex='true' :refresher-triggered='refreshTrigger' @refresherrefresh='refresh'
@scrolltolower='onLoadMore'>
refresher-default-style="black" refresher-threshold='100' :enable-flex='true'
:refresher-triggered='refreshTrigger' @refresherrefresh='refresh' @scrolltolower='onLoadMore'>
<view class="content" :style="[contentStyle]">
<template v-if='showCover'>
<slot name="cover"></slot>
</template>
<template v-else-if='showEmpty'>
<c-shelf-empty v-if="showShelfEmpty"></c-shelf-empty>
<c-search-empty v-if="showSearchEmpty"></c-search-empty>
<c-empty v-else></c-empty>
</template>
<template v-else>
......@@ -17,7 +18,7 @@
</template>
</view>
<uni-load-more v-if='ableLoadMore' :status="loadMoreStatus.value" :contentText="loadMoreContentText"
iconType="snow"></uni-load-more>
iconType="circle"></uni-load-more>
</scroll-view>
</template>
......@@ -68,6 +69,10 @@
type: Boolean,
default: false
},
showSearchEmpty: {
type: Boolean,
default: false
},
/** 初始数据源 */
sources: {
type: Array,
......@@ -274,7 +279,7 @@
}
},
/** customeRequst 不会使用的接口*/
requestData() {
requestData(noLoading) {
if (this.needLogin && !this.userInfo) {
this.loading = false;
this.closeTrigger();
......@@ -299,7 +304,9 @@
header: this.header || {},
callback: (success, data) => {
this.loading = false;
this.closeTrigger();
if (!noLoading) {
this.closeTrigger();
}
if (success) {
let rows = data.records;
let total = data.total;
......
......@@ -114,43 +114,37 @@
getPhoneNumber() {
this.ttLoging();
},
ttLoging() {
var that = this;
var obj = tt.getLaunchOptionsSync()
var bookId = '';
var thirdParam = '';
var tips2 = '';
// 抖音feed页参数
thirdParam = JSON.stringify(obj.query);
bookId = obj.query.book_id ?? ''
tips2 = obj.query.tips2 ?? ''
if (this.tips1 == 'mints_book' || tips2 == 'mints_book') {
this.slotParam = JSON.stringify(obj.query);
this.$refs.select.open('center');
}
tt.login({
force: true,
success(res) {
login({
vedioId: bookId,
code: res.code,
anonymousCode: res.anonymousCode,
thirdParam: thirdParam
})
},
fail(res) {
// 登录授权失败
uni.navigateTo({
url: `/pages/warehouse/warehousetemp`,
})
},
});
ttLoging() {
var that = this;
var obj = wx.getLaunchOptionsSync()
var bookId = '';
var thirdParam = '';
var tips2 = '';
// 抖音feed页参数
thirdParam = JSON.stringify(obj.query);
bookId = obj.query.book_id ?? ''
tips2 = obj.query.tips2 ?? ''
if (this.tips1 == 'mints_book' || tips2 == 'mints_book') {
this.slotParam = JSON.stringify(obj.query);
this.$refs.select.open('center');
}
wx.login({
force: true,
success(res) {
login({
vedioId: bookId,
code: res.code,
thirdParam: thirdParam
})
},
fail(res) {},
});
}
}
}
......@@ -216,7 +210,7 @@
}
.info {
height: 100rpx;
height: 100rpx;
color: #fff;
line-height: 100rpx;
font-size: 30rpx;
......
......@@ -20,7 +20,7 @@
props: {
title: {
type: String,
default: "逸想小说阁"
default: "河狸小故事"
}
},
data() {
......
<template>
<view class="c-empty">
<image class='empty-image' :src='emptyImg'>
</image>
<slot></slot>
</view>
</template>
<script>
export default {
name: "c-shelf-empty",
data() {
return {
emptyImg: "https://mints-pkg.oss-cn-beijing.aliyuncs.com/pkg/img/bg_search_data.png"
}
},
}
</script>
<style lang="scss" scoped>
.c-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 400rpx;
.empty-image {
width: 324rpx;
height: 184rpx;
}
}
</style>
\ No newline at end of file
<template>
<view class="c-empty">
<view class="empty-title">
<image class='empty-image' :src='emptyImg'>
</image>
<!-- <view class="empty-title">
暂未添加到书架
</view>
</view> -->
<view class="empty-button" @click="goWareHouse">
去书
去书城看看
</view>
<slot></slot>
</view>
......@@ -15,11 +17,11 @@
name: "c-shelf-empty",
data() {
return {
};
emptyImg: "https://mints-pkg.oss-cn-beijing.aliyuncs.com/pkg/img/bg_book_data.png"
}
},
methods: {
goWareHouse() {
goWareHouse() {
uni.$emit('goWareHouse')
// uni.switchTab({
// url: '/pages/warehouse/warehouse'
......@@ -36,20 +38,26 @@
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-image {
width: 240rpx;
height: 240rpx;
}
.empty-button {
margin-top: 30rpx;
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
<template>
<view>
<view style="z-index: 999;">
<uni-popup type="bottom" ref="coinPop" :maskClick="false" :isMaskClick="false">
<view style="position: relative;">
<view v-if="agreeFlag"
......@@ -17,23 +16,28 @@
<view class="body" style="width: 100%;height: 100%;background-color: white;">
<scroll-view scroll-y>
<view style="display: flex;flex-direction: column;align-items: flex-end;">
<view style="display: flex;flex-direction: column;">
<view style="display: flex;flex-direction: row;">
<view @click="handleAgree" style="margin-top: 12rpx;margin-right: 10rpx;">付费须知></view>
<image @click="handleClickClose"
style="width: 30rpx;height: 30rpx;display: flex;align-items: right;margin-top: 20rpx;margin-right: 20rpx;margin-bottom: 10rpx;"
src="@/static/index/ic_quit_white.png"></image>
<view v-if="agreementDto != null" @click="handleUnsign"
style="margin-top: 12rpx;margin-left: 10rpx;">自动续费管理></view>
<view style="margin-top: 12rpx;margin-left: auto;display: flex;flex-direction: row;">
<view @click="handleAgree" style="margin-right: 10rpx;">付费须知></view>
<image @click="handleClickClose"
style="width: 30rpx;height: 30rpx;display: flex;align-items: right;margin-top: 20rpx;margin-left: auto;margin-right: 20rpx;margin-bottom: 10rpx;"
src="@/static/index/ic_quit_white.png"></image>
</view>
</view>
</view>
<view class="section">
<view class="pack-box">
<view class="pack-item"
:class="[{active: index==selectedIndex}]" v-for='(item, index) in vipList'
:key='index' @click="choosePack(item, index)">
<view class="pack-item" :class="[{active: index==selectedIndex}]"
v-for='(item, index) in vipList' :key='index' @click="choosePack(item, index)">
<view style="display: flex;flex-direction: column;align-items: center;">
<view class="price row">
{{item.firstPayPrice}}
{{item.firstPayPrice<=0 ? '免费试用' : item.firstPayPrice+'元'}}
</view>
<view class="name row" v-if="item.title!=null&&item.title!=''">
......@@ -58,6 +62,10 @@
</view>
</view>
<text class="trialStyle" v-show="hintText!=null&&hintText!=''">
{{hintText}}
</text>
<view style="display: flex;flex-direction: column;align-items: center;">
<view style="font-size: 24rpx;color: gray;margin-top: 16rpx;margin-bottom: 18rpx;">
订单中如有疑问,请在个人中心联系客服</view>
......@@ -75,7 +83,8 @@
<script>
import common from '@/mixins/common';
import {
message
message,
navigateTo
} from '@/utils/fun';
export default {
name: 'coinPopup',
......@@ -100,6 +109,8 @@
selectedIndex: 0,
agreeFlag: false,
userBean: {},
agreementDto: null,
hintText: '',
os: 'android',
titleText: '超多精彩小说一键解锁',
showClone: false
......@@ -115,12 +126,12 @@
let that = this;
this.$refs.coinPop.open('bottom');
if (tt.getSystemInfoSync().platform === 'ios') {
if (wx.getSystemInfoSync().platform === 'ios') {
this.os = 'ios';
}
this.post({
url: '/vip/getVipProducts',
url: '/vip/getVipProducts/cyc',
data: {
bookId: that.vedioId
},
......@@ -130,7 +141,7 @@
}) => {
this.vipList = data.list;
if (data.list != null) {
// this.selectedIndex = data.list[0].activityType;
this.hintText = this.vipList[0].trailRemark;
for (let i = 0; i < data.list.length; i++) {
if (data.list[i].activityType == 1) {
this.selectedIndex = i;
......@@ -142,15 +153,28 @@
});
this.post({
url: '/user/baseMsg',
url: '/vip/getOrderList',
showLoading: false,
success: ({
data
}) => {
this.userBean = data;
console.log("agreement=", data.agreement);
if (data.agreement == undefined) {
console.log("agreement=22222");
this.agreementDto = null;
} else {
this.agreementDto = data.agreement;
}
}
});
},
handleUnsign() {
if (this.agreementDto) {
let params = JSON.stringify(this.agreementDto)
navigateTo(`/pagesA/unsign/unsign?params=` + params)
}
},
handleAgree() {
this.agreeFlag = true
},
......@@ -165,96 +189,82 @@
},
choosePack(item, index) {
this.selectedIndex = index;
if (this.vipList[this.selectedIndex].trailRemark != null) {
this.hintText = this.vipList[this.selectedIndex].trailRemark;
} else {
this.hintText = '';
}
this.handlePay();
},
handlePay() {
let that = this;
var vipBean = this.vipList[this.selectedIndex];
if (this.os == 'ios') {
message.notify('iOS暂不支持购买');
return
}
message.notify('暂不支持ios系统~');
} else {
this.post({
url: '/vip/getVipPayParams/wechat',
data: {
pid: vipBean.pid,
payChannel: 'WEIXIN'
},
showLoading: true,
success: ({
data
}) => {
if (vipBean.firstPayPrice == 0) {
//签约
that.wxSign(data, vipBean.largeType);
} else {
//普通支付
that.wxPay(data, vipBean.largeType);
}
}
});
}
},
wxPay(wxData, largeType) {
let wxParams = wxData.params;
let that = this;
let vipBean = this.vipList[this.selectedIndex];
// 抖音支付
this.post({
url: '/vip/getVipPayParams/douyin',
data: {
bookId: that.vedioId,
os: that.os,
pid: vipBean.pid
// 发起微信支付
wx.requestPayment({
timeStamp: wxParams.timeStamp,
nonceStr: wxParams.nonceStr,
package: wxParams.packageStr,
signType: wxParams.signType,
paySign: wxParams.paySign,
success(res) {
that.queryOrderStatus(largeType, wxData.tidStr);
},
showLoading: true,
success: ({
data
}) => {
that.ttPrePay(data, vipBean.largeType);
}
});
fail(res) {}
})
},
ttPrePay(ttData, largeType) {
if (!tt.canIUse('requestOrder')) {
message.notify('请升级抖音APP版本.');
return
}
uni.showLoading({
title: '加载中...'
});
wxSign(wxData, largeType) {
let wxParams = wxData.params;
let that = this;
tt.requestOrder({
data: ttData.params.data,
byteAuthorization: ttData.params.byteAuthorization,
// 发起微信签约
wx.navigateToMiniProgram({
appId: "wxbd687630cd02ce1d",
path: 'pages/index/index',
extraData: wxData.params,
success(res) {
that.ttPay(largeType, res.orderId, ttData);
console.log("wxSign suc=", res);
if (res.return_code == 'SUCCESS') {
console.log("wxSign suc1111");
// 成功跳转到签约小程序
that.queryOrderStatus(largeType, wxData.tidStr);
} else {
// 签约失败
console.log("wxSign fail22222");
}
},
fail(res) {
uni.hideLoading();
console.log('ttPrePay', res.errMsg);
// message.notify(res.errMsg);
},
});
},
ttPay(largeType, oid, ttData) {
uni.hideLoading();
if (!tt.canIUse('getOrderPayment')) {
message.notify('请升级抖音APP版本!');
return
}
let that = this;
if (this.os == 'ios') {
if (!tt.canIUse('getOrderPayment.object.imId')) {
message.notify('请升级抖音APP版本~');
return
// 未成功跳转到签约小程序
console.log("wxSign fail=3333", res);
}
tt.getOrderPayment({
orderId: oid,
imId: ttData.imId,
success(res) {
that.queryOrderStatus(largeType, ttData.tidStr);
},
fail(res) {
console.log('ios pay', res.errMsg);
// message.notify(res.errMsg);
},
});
} else {
tt.getOrderPayment({
orderId: oid,
success(res) {
that.queryOrderStatus(largeType, ttData.tidStr);
},
fail(res) {
console.log('android pay', res.errMsg);
// message.notify(res.errMsg);
},
});
}
})
},
queryOrderStatus(largeType, tid) {
let that = this;
......@@ -309,7 +319,7 @@
align-items: center;
flex-wrap: wrap;
.active {
.active {
background-color: #f4c98b !important;
border: 6rpx solid #fd5350 !important;
}
......@@ -337,7 +347,7 @@
}
.name {
width: calc(90%);
width: calc(90%);
text-align: center;
font-size: 29rpx;
color: #333;
......@@ -386,4 +396,16 @@
}
}
}
.trialStyle {
display: flex;
align-items: center;
font-size: 30rpx;
color: darkgray;
margin-left: 20rpx;
margin-right: 20rpx;
word-wrap: break-word;
word-break: break-all;
white-space: pre-line;
}
</style>
\ No newline at end of file
This diff is collapsed.
......@@ -5,8 +5,9 @@
<image @click="onClose" style="width: 50rpx; height: 50rpx;margin-left:auto;margin-right: 30rpx;
margin-bottom: 30rpx;" src="https://mints-web.oss-cn-beijing.aliyuncs.com/images/ic_close_white.png"></image>
<view class="content">
<button class="button1" type="default" size="default" @click="tapMakePhoneCall">客服电话</button>
<button class="button2" open-type="im" data-im-id="93264117800">客服在线</button>
<button class="button1" type="default" size="default"
@click="tapMakePhoneCall">客服电话:400-096-9950</button>
<!-- <button class="button2" open-type="im" data-im-id="93264117800">客服在线</button> -->
</view>
</view>
</uni-popup>
......@@ -14,6 +15,8 @@
</template>
<script>
// import uniPopuo from 'uniPopuo'
export default {
name: 'kefuPopup',
props: {
......@@ -35,9 +38,9 @@
this.$refs.kefuPop.close('bottom');
this.$emit('close');
},
tapMakePhoneCall() {
let that=this
tt.makePhoneCall({
tapMakePhoneCall() {
let that = this
wx.makePhoneCall({
phoneNumber: "4000969950",
success(res) {
// 调用成功 makePhoneCall:ok
......
<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="label">
<view class="title">
今日<br>已读
</view>
</view> -->
<image class="labelimg" src="../../static/images/readtext.png"></image>
<!-- <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">小时</view>
</view>
<view class="count">
<view class="count-value">{{count.minute?count.minute:'00'}}</view>
<view class="count-unit"></view>
</view>
<view class="count">
<view class="count-value">{{count.second?count.second:'00'}}</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;
padding-left: 0;
.labelimg {
margin-top: 10rpx;
margin-right: 20rpx;
width: 65rpx;
height: 70rpx;
}
.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: #383B3D;
.count-value {
position: absolute;
top: 42%;
left: 50%;
transform: translate(-50%, -50%);
color: #383B3D;
font-size: 46rpx;
font-weight: 700;
}
.count-unit {
font-size: 20rpx;
position: absolute;
left: 50%;
transform: translate(-50%);
bottom: 4rpx;
}
}
}
}
</style>
\ No newline at end of file
<template>
<view class="recommendlist">
<view class="booklabel">
<view class="title">{{title}}</view>
<view class="flex">
<image class="img" src="@/static/images/change.png"></image>
<view class="change" @click="refreshList">换一换</view>
</view>
</view>
<view class="rowitem" v-if="listType==0">
<!-- 猜你喜欢 -->
<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' @tapItem='tapItem($event, index)'>
</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="rowitem" v-else-if="listType==2">
<!-- 新书推荐 -->
<book-list-item3 class="item2" v-for='(item, index) in dataList' :key='index' :item='item'
:showClose='false' @tapItem='tapItem($event, index)'>
</book-list-item3>
</view>
<view class="columnitem" v-else-if="listType==3">
<!-- 热门推荐-搜索页 -->
<book-list-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 {
getRecommendV1,
getArticleLike
} from "../../common/services/index.js"
import {
gotoBookContentPage
} from '../../common/services/page-route.js';
import BookshelfBookItem from '../../common/models/BookshelfBookItem.js';
import BookListItem from "@/components/book-list-item/book-list-item.vue";
import BookListItem2 from "@/components/book-list-item2/book-list-item2.vue";
import BookListItem3 from "@/components/book-list-item3/book-list-item3.vue";
export default {
mixins: [common],
components: {
BookListItem,
BookListItem2,
BookListItem3
},
props: {
listType: {
type: Number,
default: 0
}
},
data: function() {
return {
dataList: [],
title: '猜你喜欢',
flag: 'hot'
}
},
mounted() {
if (this.listType == 0) {
this.flag = 'like'
this.title = '猜你喜欢'
} else if (this.listType == 1 || this.listType == 3) {
this.flag = 'hot'
this.title = '热门推荐'
} else if (this.listType == 2) {
this.flag = 'newbook'
this.title = '新书推荐'
}
},
methods: {
refreshList() {
if (this.listType == 0) {
getArticleLike(8, (success, data) => {
if (success) {
this.changeData(data)
}
})
} else if (this.listType == 1) {
getRecommendV1(this.flag, 5, (success, data) => {
if (success) {
this.changeData(data)
}
})
} else if (this.listType == 2) {
getRecommendV1(this.flag, 8, (success, data) => {
if (success) {
this.changeData(data)
}
})
} else if (this.listType == 3) {
getRecommendV1(this.flag, 8, (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;
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.1);
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;
}
.img {
margin-right: 10rpx;
width: 30rpx;
height: 26rpx;
}
.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;
.item2 {
width: 47%;
margin-bottom: 20rpx;
margin-right: 20rpx;
}
.item:last-child {
margin-right: 0;
}
.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>
<view v-if="showPopup" class="uni-popup" @touchmove.stop.prevent="clear">
<uni-transition :mode-class="['fade']" :styles="maskClass" :duration="duration" :show="showTrans" @click="onTap" />
<uni-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @click="onTap">
<view class="uni-popup__wrapper-box" @click.stop="clear">
<slot />
</view>
</uni-transition>
</view>
</template>
<script>
/**
* PopUp 弹出层
* @description 弹出层组件,为了解决遮罩弹层的问题
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} type = [top|center|bottom] 弹出方式
* @value top 顶部弹出
* @value center 中间弹出
* @value bottom 底部弹出
* @property {Boolean} animation = [ture|false] 是否开启动画
* @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗
* @event {Function} change 打开关闭弹窗触发,e={show: false}
*/
export default {
name: 'UniPopup',
props: {
// 开启动画
animation: {
type: Boolean,
default: true
},
// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
type: {
type: String,
default: 'center'
},
// maskClick
maskClick: {
type: Boolean,
default: true
}
},
data() {
return {
duration: 300,
ani: [],
showPopup: false,
showTrans: false,
maskClass: {
'position': 'fixed',
'bottom': 0,
'top': 0,
'left': 0,
'right': 0,
'backgroundColor': 'rgba(0, 0, 0, 0.4)'
},
transClass: {
'position': 'fixed',
'left': 0,
'right': 0,
}
}
},
watch: {
type: {
handler: function(newVal) {
switch (this.type) {
case 'top':
this.ani = ['slide-top']
this.transClass = {
'position': 'fixed',
'left': 0,
'right': 0,
}
break
case 'bottom':
this.ani = ['slide-bottom']
this.transClass = {
'position': 'fixed',
'left': 0,
'right': 0,
'bottom': 0
}
break
case 'center':
this.ani = ['zoom-out', 'fade']
this.transClass = {
'position': 'fixed',
/* #ifndef APP-NVUE */
'display': 'flex',
'flexDirection': 'column',
/* #endif */
'bottom': 0,
'left': 0,
'right': 0,
'top': 0,
'justifyContent': 'center',
'alignItems': 'center'
}
break
}
},
immediate: true
}
},
created() {
if (this.animation) {
this.duration = 300
} else {
this.duration = 0
}
},
methods: {
clear(e) {
// TODO nvue 取消冒泡
e.stopPropagation()
},
open() {
this.showPopup = true
this.$nextTick(() => {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.showTrans = true
}, 50);
})
this.$emit('change', {
show: true
})
},
close(type) {
this.showTrans = false
this.$nextTick(() => {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.$emit('change', {
show: false
})
this.showPopup = false
}, 300)
})
},
onTap() {
if (!this.maskClick) return
this.close()
}
}
}
</script>
<style lang="scss" scoped>
.uni-popup {
position: fixed;
/* #ifdef H5 */
top: var(--window-top);
/* #endif */
/* #ifndef H5 */
top: 0;
/* #endif */
bottom: 0;
left: 0;
right: 0;
/* #ifndef APP-NVUE */
z-index: 99999999999;
/* #endif */
}
.uni-popup__mask {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: $uni-bg-color-mask;
opacity: 0;
}
.mask-ani {
transition-property: opacity;
transition-duration: 0.2s;
}
.uni-top-mask {
opacity: 1;
}
.uni-bottom-mask {
opacity: 1;
}
.uni-center-mask {
opacity: 1;
}
.uni-popup__wrapper {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: absolute;
}
.top {
top: 0;
left: 0;
right: 0;
transform: translateY(-500px);
}
.bottom {
bottom: 0;
left: 0;
right: 0;
transform: translateY(500px);
}
.center {
/* #ifndef APP-NVUE */
display: flex;
flex-direction: column;
/* #endif */
bottom: 0;
left: 0;
right: 0;
top: 0;
justify-content: center;
align-items: center;
transform: scale(1.2);
opacity: 0;
}
.uni-popup__wrapper-box {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: relative;
}
.content-ani {
// transition: transform 0.3s;
transition-property: transform, opacity;
transition-duration: 0.2s;
}
.uni-top-content {
transform: translateY(0);
}
.uni-bottom-content {
transform: translateY(0);
}
.uni-center-content {
transform: scale(1);
opacity: 1;
}
</style>
<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 :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>
<view>
<c-list ref='list' flag='warehouse' method="POST" :height="height" url='/book/articleList/' :param="requestParam"
@change='changeData'>
<book-list-item v-for='(item, index) in dataList' :key='index' :item='item' :showClose='false'
@tapItem='tapItem($event, index)' @close='tapClose($event, index)'>
</book-list-item>
</c-list>
</view>
</template>
<script>
import {
gotoBookContentPage
} from '../../../common/services/page-route';
import {
isEmpty
} from '../../../common/utils/util'
import WarehouseBookItem from '../models/WarehouseBookItem.js';
export default {
components: {},
props: {
height: {
type: Number,
default: 0
},
category: {
type: Object,
default: function() {
return {}
}
},
},
data: function() {
return {
dataList: [],
}
},
computed: {
requestParam: function() {
return {
categoryId: this.category.value
}
}
},
watch: {},
methods: {
initRefresh() {
if (isEmpty(this.dataList)) {
this.refreshList();
}
},
refreshList() {
this.$nextTick(() => {
let ref = this.$refs.list;
if (ref) {
ref.onPullRefreshing();
}
})
},
changeData(e) {
this.dataList = e.detail.data.map(item => {
return new WarehouseBookItem(item)
})
},
tapItem(e, index) {
gotoBookContentPage(e.detail.data.id)
},
tapClose(e, index) {
// TODO 仓库点击关闭按钮,弹窗选择关闭原因
uni.showModal({
title: "不喜欢",
content: `是否确认减少推荐此类书籍?`
})
}
}
}
</script>
<style>
<template>
<view>
<c-list ref='list' flag='warehouse' method="POST" :height="height" url='/book/articleList/'
:param="requestParam" @change='changeData'>
<book-list-item v-for='(item, index) in dataList' :key='index' :item='item' :showClose='false'
@tapItem='tapItem($event, index)' @close='tapClose($event, index)'>
</book-list-item>
</c-list>
</view>
</template>
<script>
import {
gotoBookContentPage
} from '../../../common/services/page-route';
import {
isEmpty
} from '../../../common/utils/util'
import WarehouseBookItem from '../models/WarehouseBookItem.js';
import CList from "@/components/c-list/c-list.vue";
export default {
components: {
CList
},
props: {
height: {
type: Number,
default: 0
},
category: {
type: Object,
default: function() {
return {}
}
},
},
data: function() {
return {
dataList: [],
}
},
computed: {
requestParam: function() {
return {
categoryId: this.category.value
}
}
},
watch: {},
methods: {
initRefresh() {
if (isEmpty(this.dataList)) {
this.refreshList();
}
},
refreshList() {
this.$nextTick(() => {
let ref = this.$refs.list;
if (ref) {
ref.requestData(1);
}
})
},
changeData(e) {
this.dataList = e.detail.data.map(item => {
return new WarehouseBookItem(item)
})
},
tapItem(e, index) {
gotoBookContentPage(e.detail.data.id, e.detail.data.shortis)
},
tapClose(e, index) {
// TODO 仓库点击关闭按钮,弹窗选择关闭原因
uni.showModal({
title: "不喜欢",
content: `是否确认减少推荐此类书籍?`
})
}
}
}
</script>
<style>
</style>
\ No newline at end of file
import {
apiGET,
apiPOST
} from "../../../common/utils/apiRequest.js"
function getCategorys(callback) {
apiPOST({
url: "/book/categoryList/",
callback
})
}
function getFirstShow(callback) {
apiPOST({
url: "/book/firstArticle",
callback
})
}
module.exports = {
getCategorys,
getFirstShow
import {
apiGET,
apiPOST
} from "../../../common/utils/apiRequest.js"
function getCategorys(callback) {
apiPOST({
url: "/book/categoryList/",
callback
})
}
module.exports = {
getCategorys
}
\ 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,25 +10,24 @@
@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 style="height: 20rpx;"></view>
</scroll-view>
</template>
<script>
import CategoryBar from "./components/category-bar.vue";
import WarehouseList from "./components/warehouse-list.vue";
import CEmpty from "@/components/c-empty/c-empty.vue";
import SystemInfoMixin from "../../common/mixins/system-info-mixin.js";
import Category from "./models/Category.js";
import {
gotoBookContentPage
} from '../../common/services/page-route'
import {
getCategorys,
getFirstShow
getCategorys
} from "./services/index.js"
import {
isEmpty
......@@ -42,7 +39,8 @@
mixins: [SystemInfoMixin],
components: {
CategoryBar,
WarehouseList
WarehouseList,
CEmpty
},
data() {
return {
......@@ -51,8 +49,9 @@
currentIndex: 0,
};
},
onLoad(options) {
onLoad(options) {},
onReady() {
this.getCategoryData()
},
computed: {
showEmpty: function() {
......@@ -60,7 +59,7 @@
},
listStyle: function() {
return {
height: `${this.listHeight}px`
height: `${this.listHeight}px`,
}
},
categroyChange: function() {
......@@ -79,53 +78,20 @@
handler: function(n, o) {
setTimeout(() => {
this.$refs[`bookList${n.currentIndex}`][0].initRefresh();
}, 500)
// this.$nextTick(() => {
// // this.$refs[`bookList${n.currentIndex}`][0].initRefresh();
// let ref = this.$refs.bookList;
// if (ref) {
// ref[n.currentIndex].initRefresh();
// }
// })
}, 300)
},
deep: true
}
},
methods: {
show() {
this.getFirstShowData();
this.getCategoryData();
if (wx.setVisualEffectOnCapture) {
wx.setVisualEffectOnCapture({
visualEffect: 'hidden',
success: (res) => {
},
})
}
},
hide() {
},
readyCategory() {
setTimeout(() => {
this.initHeight()
}, 300)
},
getFirstShowData(){
getFirstShow((success, data) => {
if (success) {
setTimeout(() => {
// 匹配用户直接跳转小说
if (data.articleMsg != null) {
gotoBookContentPage(data.articleMsg.id);
}
}, 800);
}
})
},
getCategoryData() {
getCategorys((success, data) => {
......@@ -151,7 +117,9 @@
query.exec((res) => {
let result = 0;
res.forEach(item => {
result = result + item.height;
if (item) {
result = result + item.height;
}
})
this.listHeight = this.windowHeight - result - (this.windowHeight * 0.1);
})
......
<template>
<view style="padding-top: 50rpx;">
<profile-header :userInfo='userInfo'></profile-header>
<CategoryBar id='category' :range='categorys' :current='currentIndex' @change='changeCategory'
@ready='readyCategory'></CategoryBar>
<view :style="[listStyle]" v-if='showEmpty'>
<c-empty emptyTitle="暂无数据"></c-empty>
</view>
<view :style="[listStyle]" v-else>
<swiper :style="[listStyle]" :indicator-dots="false" :autoplay="false" :current="currentIndex"
@change="changeSwiper">
<swiper-item v-for='(item, index) in categorys' :key='index'>
<WarehouseList ref='bookList' :category='item' :height='listHeight'></WarehouseList>
</swiper-item>
</swiper>
</view>
<c-login></c-login>
</view>
</template>
<script>
import ProfileHeader from "./components/profile-headertemp.vue";
import {
watchUserInfoChange,
refreshUserInfo
} from "../../common/services/userServices.js"
import CategoryBar from "./components/category-bar.vue";
import WarehouseList from "./components/warehouse-list.vue";
import SystemInfoMixin from "../../common/mixins/system-info-mixin.js";
import Category from "./models/Category.js";
import {
getCategorys
} from "./services/index.js"
import {
isEmpty
} from "../../common/utils/util";
import {
readStorage,
saveStorage
} from '../../common/utils/storageUtil';
export default {
mixins: [SystemInfoMixin],
components: {
CategoryBar,
ProfileHeader,
WarehouseList
},
data() {
return {
userInfo: null,
listHeight: 0,
categorys: [],
currentIndex: 0
};
},
onLoad() {
this.getCategoryData();
watchUserInfoChange((info) => {
this.userInfo = info.userInfo
}, this);
},
onShow() {
this.refreshUserData();
},
computed: {
showEmpty: function() {
return isEmpty(this.categorys);
},
listStyle: function() {
return {
height: `${this.listHeight}px`
}
},
categroyChange: function() {
const {
categorys,
currentIndex
} = this;
return {
categorys,
currentIndex
}
}
},
watch: {
categroyChange: {
handler: function(n, o) {
this.$nextTick(() => {
let ref = this.$refs.bookList;
if (ref) {
ref[n.currentIndex].initRefresh();
}
})
},
deep: true
}
},
methods: {
readyCategory() {
setTimeout(() => {
this.initHeight()
}, 300)
},
getCategoryData() {
getCategorys((success, data) => {
if (success) {
let result = data ? data.map(item => {
return new Category(item)
}).sort((a, b) => {
return a.sort - b.sort
}) : [];
result.unshift(new Category({
name: "全部",
id: ""
}))
this.categorys = result;
}
})
},
initHeight() {
const query = uni.createSelectorQuery().in(this);
// query.select("#navi").boundingClientRect();
// query.select("#search").boundingClientRect();
query.select("#category").boundingClientRect();
query.exec((res) => {
let result = 0;
res.forEach(item => {
result = result + item.height;
})
this.listHeight = this.windowHeight - result;
})
},
changeCategory(e) {
this.changeCurrent(e.index);
},
changeSwiper(e) {
this.changeCurrent(e.detail.current);
},
changeCurrent(index) {
if (index != this.currentIndex) {
this.currentIndex = index;
}
},
refreshUserData() {
if (this.userInfo) {
refreshUserInfo();
}
}
}
}
</script>
<style lang="scss">
.name {
font-size: 34rpx;
font-weight: 700;
}
</style>
\ No newline at end of file
This diff is collapsed.
<template>
<view class="read" id="read">
<view class="read-content" :class="'read-content'+index" :style="elStyle" v-for="(item,index) in list"
:key="index" @click="toClick">
{{item.content}}
</view>
<!-- <view class="read-content" :style="elStyle" @click="toNext">{{content}}</view>
<view class="read-content-next" :style="elStyle">{{contentNext}}</view> -->
<view class="top-info" v-if="setShow">
<view class="top-info-item">
<text text="上一章" block align="center" v-if="partInfo.previousPartNum != -1"
@tap.native.stop="toPrePart">上一章
</text>
</view>
<view class="top-info-item">
<!-- <u-button type="default" size="mini" plain shape="circle" text="目录" @tap.native.stop="toMenu">
</u-button> -->
<text text="目录" align="center" @tap.native.stop="toMenu">目录</text>
</view>
<view class="top-info-item">
<text text="下一章" align="center" v-if="partInfo.nextPartNum != -1" @tap.native.stop="toNextPart">下一章
</text>
</view>
</view>
<view class="bottom-info" v-if="setShow">
<view class="bottom-info-item">
<text text="设置" prefixIcon="setting" size="17" lineHeight="20" :iconStyle="{fontSize: '20px'}"
align="center" @tap.native.stop="toSet">设置</text>
</view>
<view class="bottom-info-item">
<text text="|" align="center" size="17" color="#dadada">|</text>
</view>
<view class="bottom-info-item">
<text text="返回书城" prefixIcon="home" size="17" lineHeight="20" align="center"
:iconStyle="{fontSize: '20px'}" @tap.native.stop="toHome">返回书城</text>
</view>
</view>
<view class="bottom-info font-style" v-if="setStyleShow">
<view class="item">
<view class="item-title">
字号
</view>
<view class="item-cont">
<view class="item-cont-item" @click="setFontSize(1)">
-
</view>
<view class="item-cont-item" @click="setFontSize(2)">
+
</view>
</view>
</view>
<view class="item">
<view class="item-title">
背景
</view>
<view class="item-cont">
<view class="item-cont-item" :class="curColor==item?'active':''" @click="setBgColor(item)"
v-for="(item,index) in colors" :key="index" :style="'background-color:'+item+';'">
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import datas from "./data.js"
export default {
data() {
return {
content: "22222",
contentPre: "11111",
contentNext: "3333",
list: [],
colors: [
"#F1FAFA",
"#e8ffe8",
"#e8e8ff",
"#8080c0",
],
curColor: "#F1FAFA",
setShow: false,
setStyleShow: false,
isStart: true,
isEnd: false,
width: 0,
height: 0,
start: 0,
end: 0,
length: 0,
heightOffset: 16,
styleObj: {
fontSize: 16,
lineHeight: 1
},
elStyle: "",
partInfo: {
previousPartNum: 1,
nextPartNum: 1
}
};
},
mounted() {
this.$nextTick(() => {
this.init()
})
},
methods: {
setFontSize(flag) {
//-
if (flag == 1) {
if (this.styleObj.fontSize < 10) {
return;
}
this.styleObj.fontSize -= 1;
} else { //+
if (this.styleObj.fontSize > 40) {
return;
}
this.styleObj.fontSize += 1;
}
this.init()
},
setBgColor(color) {
this.curColor = color;
this.setStyle()
},
toSet() {
console.log("设置")
this.setStyleShow = true;
this.setShow = false;
},
toPrePart() {
console.log("上一章节")
},
toNextPart() {
console.log("下一章节")
},
toHome() {
console.log("返回首页")
},
toMenu() {
// this.$refs.parts.open();
console.log("显示目录")
},
toClick(e) {
if (this.setStyleShow || this.setShow) {
this.setStyleShow = false;
this.setShow = false;
return;
}
const width = this.width;
const x = e.detail.x;
if (x < width / 3) {
this.toPre()
} else if (x > (width / 3) * 2) {
this.toNext()
} else {
this.setShow = !this.setShow;
}
},
toPre() {
if (this.isStart) {
uni.showToast({
title: "已经是第一页了",
icon: "none"
})
return;
}
this.start -= this.length;
this.setContent()
},
toNext() {
if (this.isEnd) {
uni.showToast({
title: "已经是最后一页了",
icon: "none"
})
return;
}
this.start += this.length;
this.setContent()
// console.log(this.start, this.list)
},
init() {
console.log(111111111, this.content)
const query = uni.createSelectorQuery().in(this);
const el = query.select("#read").boundingClientRect(data => {
console.log(11111, data)
const width = data.width - 20;
const height = data.height - 20;
this.width = width;
this.height = height;
let lineHeight = ((this.styleObj.fontSize) * this.styleObj.lineHeight) + this.heightOffset;
let lineNum = parseInt(height / lineHeight) - 1;
let fonts = parseInt(width / (this.styleObj.fontSize));
let allFonts = lineNum * fonts;
this.length = allFonts;
console.log("--->>>", allFonts, fonts, lineNum, height, lineHeight)
this.setStyle()
this.setContent()
}).exec();
},
setContent() {
this.list = []
let cont0 = "";
let cont1 = datas.substr(this.start, this.length);
let cont2 = datas.substr(this.start + this.length, this.length);
if (cont1.length < this.length) {
this.isEnd = true;
} else {
this.isEnd = false;
}
if (this.start != 0) {
this.isStart = false;
cont0 = datas.substr(this.start - this.length, this.length)
} else {
this.isStart = true;
}
this.list.push({
index: 0,
content: cont0
})
this.list.push({
index: 1,
content: cont1
})
this.list.push({
index: 2,
content: cont2
})
},
setStyle() {
let fontSize = this.styleObj.fontSize;
let lineHeight = (((this.styleObj.fontSize) * this.styleObj.lineHeight) + this.heightOffset);
this.elStyle = `font-size: ${fontSize}px;line-height: ${lineHeight}px;background-color:${this.curColor};`;
// console.log(1,this.elStyle)
}
},
}
</script>
<style lang="scss">
page {
width: 100%;
height: 100%;
}
</style>
<style lang="scss" scoped>
* {
box-sizing: border-box;
}
.read {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
box-sizing: border-box;
&-content {
padding: 20rpx;
width: 100%;
height: 100%;
box-sizing: border-box;
position: absolute;
background-color: #f5ebdc;
}
&-content0 {
z-index: 1;
}
&-content1 {
z-index: 20;
}
&-content2 {
z-index: 10;
}
}
.top-info {
position: fixed;
top: 0rpx;
left: 0rpx;
display: flex;
background-color: #fff;
height: 90rpx;
border-bottom: 1px solid #dadada;
width: 100%;
z-index: 999;
&-item {
padding: 10rpx 0rpx;
flex: 1;
text-align: center;
}
}
.bottom-info {
position: absolute;
box-sizing: border-box;
bottom: 0rpx;
left: 0rpx;
display: flex;
background-color: #fff;
height: 210rpx;
padding: 50rpx 30rpx;
border-top: 1px solid #dadada;
width: 100%;
z-index: 999;
&-item {
padding: 10rpx 0rpx;
flex: 1;
text-align: center;
}
}
.font-style {
height: 400rpx;
flex-direction: column;
}
.item {
display: flex;
padding: 20rpx;
height: 150rpx;
line-height: 110rpx;
&-title {
width: 140rpx;
}
&-cont {
width: calc(100% - 140rpx);
display: flex;
&-item {
flex: 1;
background-color: #d8ebf5;
height: 100rpx;
border-radius: 60rpx;
margin-right: 30rpx;
text-align: center;
font-size: 60rpx;
line-height: 90rpx;
color: #03a9f4;
}
.active {
border: 1px solid #03a9f4;
}
}
}
</style>
......@@ -80,7 +80,6 @@ export default {
// navigateTo('user/login?redirect=' + encodeURIComponent(redirect));
},
logout() {
uni.removeStorageSync('token');
},
post(options) {
options = Object.assign({
......
......@@ -179,7 +179,7 @@
onShareAppMessage() {
let result = {
title: this.bookData.title,
imageUrl: this.bookData.cover,
imageUrl: this.bookData.cover,
path: '/pages/loading?shareId='
}
return result;
......@@ -261,7 +261,7 @@
this.bookData = new BookDetail(data);
// console.log('bookData=' + JSON.stringify(this.bookData));
}
}, 1000)
}, 100)
})
},
paySuccess() {
......
<template>
<view>
<c-login></c-login>
</view>
</template>
<script>
export default {
data() {
return {
bookId: null,
bookCoverData: null
};
},
onReady() {
const eventChannel = this.getOpenerEventChannel();
eventChannel.on("openBookCoverPage", (info) => {
this.bookId = info.bookId
})
},
watch: {
bookId: function(n) {
if (n) {
this.$nextTick(() => {
uni.startPullDownRefresh({
})
})
}
}
},
onPullDownRefresh() {
this.refreshBookCoverData(this.bookId)
},
methods: {
refreshBookCoverData(bookId) {
}
}
}
</script>
<style lang="scss">
</style>
\ No newline at end of file
<template>
</template>
<script>
</script>
<style>
</style>
\ No newline at end of file
<template>
<view :style="[bgStyle]">
<c-empty v-if='showEmpty'></c-empty>
<template v-else>
<detail-content ref="content" :detail='bookData' @tabVip2="tapVipPop"
@changeCurrent="changeCurrent"></detail-content>
<detail-bottom :detail='bookData' :userInfo='userInfo' @tapBottomItem='tapBottomItem'></detail-bottom>
<setting-pop :show='showSetting' @close='closePop'></setting-pop>
<catalogue-pop :detail='bookData' :show='showCatalogue' @close='closeCataPop' :current="current"
@tabVip='tapVipPop'></catalogue-pop>
<!-- <vip-pop v-if="bookData.isUnlock==0 && !isVip()" :show='showVip' @close='closeVipPop'></vip-pop>
<bean-pop v-if="bookData.isUnlock==0 && userInfo.bookLegumes<bookData.bookLegumes" :show='showBean'
@close='closeBeanPop'></bean-pop> -->
<recommend-pop :show='showRecommend' @close='closeRecommendPop' :bookId="bookId"></recommend-pop>
<coin-popup v-if="bookData.isUnlock==0 && !isVip()" :show="showVip" @close="closeVipPop"
:vedioId="bookData.id">
</coin-popup>
</template>
</view>
</template>
<script>
import {
isEmpty
} from "../../../common/utils/util.js";
import BookDetail from "./models/BookDetail.js";
import {
getBookDetailData,
addReadRecord
} from "./services/index.js"
import {
collectionBook
} from "../../../common/services/index.js"
import DetailWarn from "./components/detail-warn.vue";
import DetailThumb from "./components/detail-thumb.vue";
import DetailContent from "./components/detail-content.vue";
import DetailBottom from "./components/detail-bottom.vue";
import DetailNewBuy from "./components/detail-new-buy.vue";
import config from "../../../config/index.js";
import SettingPop from "./components/setting-pop.vue";
import CataloguePop from "./components/catalogue-pop.vue";
import VipPop from "./components/vip-pop.vue";
import BeanPop from "./components/bean-pop.vue";
import RecommendPop from "./components/recommend-pop.vue";
import SystemInfoMixin from "../../../common/mixins/system-info-mixin.js";
import {
gotoBookCoverPage
} from "../../../common/services/page-route.js"
import {
watchUserInfoChange,
removeUserInfoChangeWatch,
refreshUserInfo,
postPhone
} from "../../../common/services/userServices.js"
import {
noticeCollectionListChange,
startCountReadTime,
endCountReadTime,
getOpens
} from "../../../common/services/index.js"
import {
saveStorage,
readStorage
} from "../../../common/utils/storageUtil.js";
export default {
mixins: [SystemInfoMixin],
components: {
DetailWarn,
DetailThumb,
DetailContent,
DetailNewBuy,
DetailBottom,
SettingPop,
VipPop,
BeanPop,
RecommendPop,
CataloguePop
},
data() {
return {
bookId: null,
bookData: null,
showSetting: false,
showCatalogue: false,
showVip: false,
showBean: false,
showRecommend: false,
userInfo: null,
showVipOpen: 0,
showBeanOpen: 0,
current: 1
};
},
onLoad(options) {
if (options.bookId) { // 非navigate进入,读取path参数
this.bookId = options.bookId;
} else { // navigate 进入,接受channel传参
const eventChannel = this.getOpenerEventChannel();
eventChannel.on("openBookContentPage", (info) => {
this.bookId = info.bookId;
})
}
},
onReady() {
// 监听用户变动
watchUserInfoChange((info) => {
this.userInfo = info.userInfo;
// 用户已登录需要记录阅读记录
if (info.userInfo && this.bookId) {
addReadRecord(this.bookId)
}
if (this.isVip() && this.bookData) {
this.paySuccess()
}
// // 用户变动,需要刷新数据
// this.$nextTick(() => {
// uni.startPullDownRefresh({})
// })
}, this)
this.$nextTick(() => {
uni.startPullDownRefresh({})
})
// 绑定分享参数
// #ifdef MP-WEIXIN
wx.onCopyUrl(() => {
return {
query: `bookId=${this.bookData.id}`
}
})
// #endif
},
onShow() {
refreshUserInfo();
// 开始记录阅读时长
startCountReadTime();
},
onHide() {
// 停止记录阅读时长
endCountReadTime();
},
onUnload() {
// 停止记录阅读时长,部分情况下页面无法响应onHide事件
endCountReadTime();
// 移除监听
removeUserInfoChangeWatch(this);
// 取消绑定分享参数
// #ifdef MP-WEIXIN
wx.offCopyUrl()
// #endif
},
onPullDownRefresh() {
this.refreshBookData(this.bookId)
},
// 文章分享
onShareAppMessage() {
let result = {
title: this.bookData.title,
imageUrl: this.bookData.cover,
type: config.env == 'Prod' ? 0 : config.env == 'Dev' ? 1 : 2,
path: `/page-subs/sub_A/book-long-content/book-long-content?bookId=${this.bookData.id}`
}
return result;
},
computed: {
showEmpty: function() {
return isEmpty(this.bookData)
},
bgStyle: function() {
let height = 300;
if (this.windowHeight) {
height = this.windowHeight;
}
return {
minHeight: `${height}px`,
position: "relative",
}
}
},
watch: {
bookData: {
handler: function(n) {
if (n) {
uni.setNavigationBarTitle({
title: `阅读:${n.title}`
})
}
}
}
},
methods: {
// 解锁回调
paySuccess() {
this.$set(this.bookData, "isUnlock", 1);
this.$set(this.bookData, "freeNum", this.bookData.articleChapterList.length);
this.$refs.content.reloadChapterinfoData()
},
// 文章数据刷新
refreshBookData(bookId) {
// getOpens((success, data) => {
// this.showBeanOpen = data.openBeans
// this.showVipOpen = data.openVips
// })
getBookDetailData(bookId, (success, data) => {
uni.stopPullDownRefresh();
if (success) {
if (data.isUnlock) {
data.freeNum = data.articleChapterList.length
}
this.bookData = new BookDetail(data);
console.log('bookData=' + JSON.stringify(this.bookData));
}
})
},
// 点击底部按钮
tapBottomItem(e) {
let flag = e.detail.flag;
switch (flag) {
case 'like': // 点赞
break;
case 'collection': // 收藏
let target = !this.bookData.isCollect;
collectionBook(target, this.bookId, (success, data) => {
if (success) {
this.$set(this.bookData, 'isCollect', target);
noticeCollectionListChange(this.bookId, target);
}
})
break;
case 'setting': // 设置
this.showSetting = true;
break;
case 'catalogue': // 目录
this.showCatalogue = true;
break;
default:
break;
}
},
isVip() {
if (this.userInfo != null && this.userInfo.memberExpirationDate > 0) {
return true;
}
return false;
},
tapPayPop() {
if (this.showVipOpen != 1 && this.showBeanOpen == 1) {
this.tapBeanPop()
return
}
this.tapVipPop()
},
// 展示充值VIP弹框
tapVipPop() {
this.showVip = true;
},
// 展示充值书豆弹框
tapBeanPop() {
this.showBean = true;
},
// 关闭设置弹窗
closePop(e) {
this.showSetting = false;
},
// 关闭目录弹窗
closeCataPop(e) {
this.showCatalogue = false;
},
// 关闭会员弹窗
closeVipPop(e) {
this.showVip = false;
if (this.bookData.isUnlock == 0) {
setTimeout(() => {
this.showRecommend = true;
}, 300);
}
},
// 关闭书豆弹窗
closeBeanPop(e) {
this.showBean = false;
// setTimeout(() => {
// this.showRecommend = true;
// }, 300);
},
// 关闭推荐弹窗
closeRecommendPop(e) {
this.showRecommend = false;
},
changeCurrent(current) {
this.current = current
}
}
}
</script>
<style lang="scss">
</style>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -90,7 +90,6 @@
display: flex;
flex-direction: row;
align-items: center;
background: #fff;
font-size: 28rpx;
.item {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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