376 lines
9.6 KiB
Vue
376 lines
9.6 KiB
Vue
<template>
|
||
<view class="pages-claim" v-if="isLoad">
|
||
<fixed :refresh="refresh">
|
||
<view class="fill-base">
|
||
<banner :list="banner" :margin="0" :autoplay="true" :borderRadius="0" :height="420"
|
||
:indicatorActiveColor="primaryColor" v-if="banner.length > 0"></banner>
|
||
<view class="fill-base flex-between b-1px-b">
|
||
<view style="width: 650rpx;">
|
||
<tab @change="handerTabChange($event,'activeIndex')" :list="tabList" :activeIndex="activeIndex"
|
||
:activeColor="primaryColor" height="100rpx"></tab>
|
||
</view>
|
||
<view @tap.stop="toShowRank" class="flex-center c-caption b-1px-l" style="width: 100rpx;">
|
||
<i class="iconfont icon-down-bold" :class="[{'rotate-180':show_rank_item}]"></i>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</fixed>
|
||
|
||
<uni-popup @change="popupChange" ref="rank_item" type="top" :custom="true">
|
||
<view :style="{height: banner.length > 0 ? '520rpx':'100rpx'}"></view>
|
||
<view class="pd-lg fill-base">
|
||
<view @tap.stop="handerTabChange(index,'rankInd')" class="f-paragraph c-title"
|
||
:class="[{'mt-md':index!=0}]" :style="{color:index==rankInd?primaryColor:''}"
|
||
v-for="(item,index) in rankList" :key="index">
|
||
{{item.title}}
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
|
||
|
||
<view @tap.stop="goDetail(index)" class="claim-item fill-base mt-md ml-md mr-md box-shadow radius-24"
|
||
v-for="(item,index) in list.data" :key="index">
|
||
<view class="flex-between pt-lg pl-lg pr-lg">
|
||
<view class="flex-y-center">
|
||
<image mode="aspectFill" lazy-load class="avatar mini radius" :src="item.farmer_info.cover"></image>
|
||
<view class="ml-lg max-446 ellipsis">{{item.farmer_info.title}}</view>
|
||
</view>
|
||
<i class="iconfont icon-right c-caption" style="font-size: 28rpx;"></i>
|
||
</view>
|
||
<view class="flex-center pd-lg">
|
||
<image mode="aspectFill" lazy-load class="cover fill-body radius-24" :src="item.cover"></image>
|
||
<view class="flex-1 ml-lg max-380">
|
||
<view class="f-title c-title ellipsis-2">{{item.title}}</view>
|
||
<view class="f-paragraph c-title">{{`${item.start_time} ~ ${item.end_time}`}}</view>
|
||
<view class="flex-between mt-sm mb-md">
|
||
<view class="line-item rel">
|
||
<view class="cur abs" :style="{width:item.precent}"></view>
|
||
</view>
|
||
<view class="c-caption" style="font-size: 20rpx;">已认养{{item.precent}}</view>
|
||
</view>
|
||
<view class="count-list flex-warp">
|
||
<view class="count-item">
|
||
<view class="flex-y-center f-caption c-caption">
|
||
<view class="dot radius"></view>品种
|
||
</view>
|
||
<view class="f-paragraph c-title ellipsis">{{item.breed}}</view>
|
||
</view>
|
||
<view class="count-item">
|
||
<view class="flex-y-center f-caption c-caption">
|
||
<view class="dot radius"></view>周期
|
||
</view>
|
||
<view class="f-paragraph c-title ellipsis">{{item.cycle}}天</view>
|
||
</view>
|
||
<view class="count-item">
|
||
<view class="flex-y-center f-caption c-caption">
|
||
<view class="dot radius"></view>产量
|
||
</view>
|
||
<view class="f-paragraph c-title">{{item.output}}kg</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="flex-between ml-lg mr-lg pt-lg pb-sm b-1px-t">
|
||
<view class="flex-y-baseline">
|
||
<view class="f-lg-title c-warning">¥{{item.price}}</view>
|
||
<view class="f-caption c-caption ml-sm">/{{item.unit}}</view>
|
||
</view>
|
||
<view class="common-btn flex-center f-paragraph c-base radius-4" :style="{background:primaryColor}">
|
||
立即认养</view>
|
||
</view>
|
||
<view class="flex-y-center pl-lg pr-lg pb-lg">
|
||
<view class="flex-warp">
|
||
<block v-for="(item,index) in item.count.user_list" :key="index">
|
||
<view class="avatar-group" v-if="index<6">
|
||
<image mode="aspectFill" lazy-load class="abs avatar fill-body radius"
|
||
:src="item.avatarUrl"></image>
|
||
</view>
|
||
</block>
|
||
</view>
|
||
<view class="flex-y-center f-caption c-title pr-lg" :class="[{'ml-lg':item.count.user_count>0}]"
|
||
style="height: 48rpx;">
|
||
已有{{item.count.user_count}}人参与</view>
|
||
</view>
|
||
</view>
|
||
<load-more :noMore="list.current_page>=list.last_page&&list.data.length>0" :loading="loading" v-if="loading">
|
||
</load-more>
|
||
<abnor v-if="!loading&&list.data.length<=0&&list.current_page==1"></abnor>
|
||
<view class="space-footer"></view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
mapState,
|
||
mapActions,
|
||
mapMutations
|
||
} from "vuex"
|
||
export default {
|
||
components: {},
|
||
data() {
|
||
return {
|
||
isLoad: false,
|
||
options: {},
|
||
rankInd: 0,
|
||
rankList: [{
|
||
id: 1,
|
||
title: '综合排序'
|
||
}, {
|
||
id: 2,
|
||
title: '销量优先'
|
||
}, {
|
||
id: 3,
|
||
title: '距离优先'
|
||
}],
|
||
tabList: [],
|
||
activeIndex: 0,
|
||
cate_id: 0,
|
||
banner: [],
|
||
param: {
|
||
page: 1,
|
||
},
|
||
list: {
|
||
data: []
|
||
},
|
||
loading: true,
|
||
lockTap: false,
|
||
show_rank_item: false,
|
||
refresh: false
|
||
}
|
||
},
|
||
computed: mapState({
|
||
primaryColor: state => state.config.configInfo.primaryColor,
|
||
subColor: state => state.config.configInfo.subColor,
|
||
configInfo: state => state.config.configInfo,
|
||
userInfo: state => state.user.userInfo,
|
||
location: state => state.user.location,
|
||
loginType: state => state.user.loginType,
|
||
}),
|
||
async onLoad() {
|
||
if (this.isLoad) return
|
||
this.$util.showLoading()
|
||
this.initIndex()
|
||
},
|
||
async onShow() {
|
||
if (!this.isLoad || (this.location.lat && this.rankInd != 2)) return
|
||
let [err, result] = await uni.getSetting()
|
||
if (err || !result.authSetting[`scope.userLocation`]) return
|
||
this.initIndex()
|
||
},
|
||
onPullDownRefresh() {
|
||
// #ifndef APP-PLUS
|
||
uni.showNavigationBarLoading()
|
||
// #endif
|
||
this.initRefresh()
|
||
uni.stopPullDownRefresh()
|
||
},
|
||
onReachBottom() {
|
||
if (this.list.current_page >= this.list.last_page || this.loading) return
|
||
this.param.page = this.param.page + 1
|
||
this.loading = true
|
||
this.getList()
|
||
},
|
||
onShareAppMessage(e) {
|
||
let {
|
||
id: pid
|
||
} = this.userInfo
|
||
let path = `/pages/claim?pid=${pid}`
|
||
this.$util.log(path)
|
||
return {
|
||
title: '',
|
||
imageUrl: '',
|
||
path,
|
||
}
|
||
},
|
||
methods: {
|
||
...mapActions(['getConfigInfo']),
|
||
...mapMutations(['updateUserItem']),
|
||
async initIndex(refresh = false) {
|
||
if (!this.configInfo.id || refresh) {
|
||
await this.getConfigInfo()
|
||
if (this.loginType == 'apple') {
|
||
this.updateUserItem({
|
||
key: 'isShowLogin',
|
||
val: false
|
||
})
|
||
}
|
||
}
|
||
await this.getLocation()
|
||
let [banner, cate] = await Promise.all([this.$api.claim.claimBanner({
|
||
type: 3
|
||
}), this.$api.claim
|
||
.claimCateList({
|
||
type: 2
|
||
})
|
||
])
|
||
cate.unshift({
|
||
id: 0,
|
||
title: '全部'
|
||
})
|
||
this.banner = banner
|
||
this.tabList = cate
|
||
this.isLoad = true
|
||
this.refresh = false
|
||
this.param.page = 1
|
||
this.getList()
|
||
},
|
||
initRefresh() {
|
||
this.refresh = true
|
||
this.$refs.rank_item.close()
|
||
this.initIndex(true)
|
||
},
|
||
async getLocation() {
|
||
let {
|
||
location
|
||
} = this
|
||
if (!location.lat) {
|
||
location = await this.$util.getBmapLocation()
|
||
this.updateUserItem({
|
||
key: 'location',
|
||
val: location
|
||
})
|
||
}
|
||
},
|
||
handerTabChange(index, type) {
|
||
this[type] = index
|
||
this.$refs.rank_item.close()
|
||
if (type == 'activeIndex') {
|
||
this.cate_id = this.tabList[index].id
|
||
}
|
||
this.$util.showLoading()
|
||
this.param.page = 1
|
||
this.list.data = []
|
||
this.getList()
|
||
},
|
||
toShowRank() {
|
||
let {
|
||
show_rank_item,
|
||
} = this
|
||
if (this.lockTap) return
|
||
this.lockTap = true
|
||
setTimeout(() => {
|
||
let methodModel = show_rank_item ? 'close' : 'open'
|
||
this.$refs.rank_item[methodModel]()
|
||
}, 500)
|
||
},
|
||
popupChange(e) {
|
||
let {
|
||
show
|
||
} = e
|
||
this.show_rank_item = show
|
||
setTimeout(() => {
|
||
this.lockTap = false
|
||
}, 200)
|
||
},
|
||
async getList() {
|
||
let {
|
||
list: oldList,
|
||
param,
|
||
tabList,
|
||
activeIndex,
|
||
rankList,
|
||
rankInd,
|
||
cate_id
|
||
} = this
|
||
let ind = tabList.findIndex(item => {
|
||
return item.id == cate_id
|
||
})
|
||
cate_id = ind == -1 ? 0 : cate_id
|
||
activeIndex = ind == -1 ? 0 : ind
|
||
this.cate_id = cate_id
|
||
this.activeIndex = activeIndex
|
||
let {
|
||
id: sort
|
||
} = rankList[rankInd]
|
||
if (sort == 3 && !this.location.lat) {
|
||
this.$util.hideAll()
|
||
await this.getLocation()
|
||
return
|
||
}
|
||
let {
|
||
lng = 0,
|
||
lat = 0
|
||
} = this.location
|
||
param = Object.assign({}, param, {
|
||
cate_id,
|
||
sort,
|
||
});
|
||
if (sort === 3) {
|
||
param.lat = lat
|
||
param.lng = lng
|
||
}
|
||
let newList = await this.$api.claim.claimList(param)
|
||
newList.data.map(item => {
|
||
let {
|
||
stock,
|
||
sale_num
|
||
} = item
|
||
item.precent = (sale_num / (stock + sale_num) * 100).toFixed(2) + '%'
|
||
})
|
||
|
||
if (this.param.page == 1) {
|
||
this.list = newList
|
||
} else {
|
||
newList.data = oldList.data.concat(newList.data)
|
||
this.list = newList
|
||
}
|
||
this.loading = false
|
||
this.$util.hideAll()
|
||
},
|
||
async goDetail(index) {
|
||
let {
|
||
id
|
||
} = this.list.data[index]
|
||
let url = `/claim/pages/detail?id=${id}`
|
||
this.$util.toCheckLogin({
|
||
url
|
||
})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
|
||
<style lang="scss">
|
||
.pages-claim {
|
||
|
||
.claim-item {
|
||
|
||
.cover {
|
||
width: 240rpx;
|
||
height: 240rpx;
|
||
}
|
||
|
||
.line-item {
|
||
width: 230rpx;
|
||
height: 15rpx;
|
||
background: rgba(112, 152, 64, 0.2);
|
||
border-radius: 8rpx;
|
||
|
||
.cur {
|
||
top: 0;
|
||
left: 0;
|
||
height: 15rpx;
|
||
background: linear-gradient(0deg, #709840 0%, #91C84E 100%);
|
||
border-radius: 8rpx;
|
||
}
|
||
}
|
||
|
||
.count-list {
|
||
.count-item {
|
||
width: 33.33%;
|
||
|
||
.dot {
|
||
width: 10rpx;
|
||
height: 10rpx;
|
||
background: #B3D465;
|
||
margin-right: 10rpx;
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
</style>
|