礼物列表
需求:从挑选礼物中到礼物列表,列表中有礼物分类。点击分类获取分类礼物
小程序端
app.json文件,由于json数据不能注释,所有注释添加在开头,添加商品列表页路由。
{
"pages": [
"pages/list/list",
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#e50e38",
"navigationBarTitleText": "百步生活",
"navigationBarTextStyle": "#fff",
"enablePullDownRefresh": false,
"backgroundColor": "#e50e38"
},
}
app.js
在app.js文件中配置我们接口的域名
App({
//设置全局的变量,apiDomain这是我们接口的ip
globalData: {
apiDomain:'http://127.0.0.1:8000',
}
})
list.json
在list.json配置当前list页面的信息
{
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#da2a2a",
"navigationBarTitleText": "选择礼物",
"navigationBarTextStyle": "#fff",
"enablePullDownRefresh": "true",
"enablePullDownRefresh": false,
"onReachBottomDistance": 100
}
list.wxml
<view class="container">
<view class="searcher">
<navigator class="inner" url="/pages/list/search/search">
<image class="icon-search" src='../../images/searcher.png'></image>
<text>搜索热门礼物</text>
</navigator>
</view>
<!--分类横向滑动-->
<scroll-view scroll-x="true" class="category">
<!--如果curId等于0,则添加active属性,bindtap='loadLists',将此标签绑定该方法,在方法中我们可以获取data-index和data-id的值-->
<view class="cateItem {{curId==0?'active':''}}" data-index="0" data-id="0" bindtap='loadLists'>
<text>全部</text>
</view>
<!--循环category,其他的标签的意思同上-->
<block wx:for="{{category}}" wx:for-index="index" wx:key="key">
<view class="cateItem {{curId==item.cat_id?'active':''}}" data-index="{{index+1}}" data-id="{{item.cat_id}}" bindtap='loadLists'>
<text>{{item.category_name}}</text>
</view>
</block>
</scroll-view>
<view class="line"></view>
<scroll-view class="lists">
<!--循环contentlist商品列表,其他的标签的意思同上-->
<block wx:for="{{contentlist}}" wx:for-index="index" wx:key="key">
<view class="item" data-url="{{item.product_id}}" data-img="{{item.m_url}}" data-brief="{{item.brief}}" data-price="{{item.price}}" bindtap="loadDetail">
<view class="inner">
<image class="p-image" src="{{item.m_url}}" mode="aspectFill" style="width:100%;"/>
<view class="p-name">{{item.name}}</view>
<view class="p-brief">{{item.brief}}</view>
<view class="p-price">¥{{item.price}}</view>
</view>
</view>
</block>
</scroll-view>
</view>
list.wxss
/* pages/list/list.wxss */
.searcher{
height: 80rpx;
width: 100%;
position: fixed;
top: 0;
border-bottom: 2rpx solid #f2f2f2;
line-height: 80rpx;
font-size: 24rpx;
z-index: 999;
background-color: #fff;
}
.searcher .inner{
width: 670rpx;
background: #f2f2f2;
height: 60rpx;
line-height: 60rpx;
position: absolute;
left: 40rpx;
top: 10rpx;
border-radius: 8rpx;
}
.icon-search{
width: 36rpx;
height: 36rpx;
position: absolute;
left: 12rpx;
top: 12rpx;
}
.searcher .inner text{
color: #999;
padding-left: 80rpx;
}
.category{
height: 80rpx;
white-space: nowrap;
position: fixed;
z-index: 999;
top: 82rpx;
background-color: #fff;
}
.cateItem{
display: inline-block;
line-height: 80rpx;
width: 115rpx;
text-align: center;
white-space: nowrap;
font-size: 24rpx;
}
.cateItem.active text{
line-height: 74rpx;
border-bottom:2rpx solid #e03131;
display: inline-block;
}
.line{
border-top: 2rpx solid #eee;
width: 100%;
}
.container{
padding: 0;
}
.lists{
padding-top: 162rpx;
}
.item{
width: 335rpx;
float: left;
padding: 20rpx;
}
.p-image{
width: 335rpx;
height: 335rpx;
}
.p-name{
width: 100%;
height: 40rpx;
font-size: 14px;
line-height: 40rpx;
word-break: break-all;
-webkit-box-orient: vertical;
-webkit-line-clamp:1;
overflow: hidden;
text-overflow:ellipsis;
display: -webkit-box;
}
.p-brief{
width: 100%;
font-size: 13px;
height: 40rpx;
color: #ccc;
line-height: 40rpx;
word-break: break-all;
-webkit-box-orient: vertical;
-webkit-line-clamp:1;
overflow: hidden;
text-overflow:ellipsis;
display: -webkit-box;
}
.p-price{
width: 100%;
font-size: 16px;
height: 40rpx;
color: #e03131;
line-height: 50rpx;
word-break: break-all;
-webkit-box-orient: vertical;
-webkit-line-clamp:1;
overflow: hidden;
text-overflow:ellipsis;
display: -webkit-box;
}
.intro{
transform: rotate(45deg);
background: #e03131;
color: #fff;
font-size: 14px;
text-align: center;
position: absolute;
right:-112rpx;
width:100%;
top:36rpx;
}
.inner{
overflow: hidden;
position: relative;
}
list.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
category:[],
page: 1,
pageSize: 30,
hasMoreData: true,
contentlist: [],//全部列表
cateLists:[],//保存分类列表缓存数据
curId:0,//头部分类默认选中的分类id
curIndex:0//当前选中分类的index索引值
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {//初始化加载首页全部数据
wx.showLoading({
title: '加载中',
})
var _self = this;
wx.request({//获取分类数据
url: app.globalData.apiDomain +'/api/indexlist/categoryList',
data: {
},
header: {
'content-type': 'application/json' // 默认值
},
success: function (res) {
console.log(res.data.data)
_self.setData({
category: res.data.data
},function(){
var tmp_Lists = [];
tmp_Lists.push(new Array());
for(var j=1;j<=res.data.data.length;j++){
tmp_Lists.push(new Array());
};
_self.setData({
cateLists:tmp_Lists
},function(){
wx.request({//获取分类首页列表数据
url: app.globalData.apiDomain + '/api/indexlist/IndexProductList',
data: {
'page': _self.data.page,
},
method: 'POST',
header: {
'content-type': 'application/json' // 默认值
},
success: function (res) {
console.log(res)
_self.setData({
page: _self.data.page + 1
});
if (res.data.data.prev < res.data.data.sums_page) {//下一页有数据
_self.setData({
hasMoreData: true
});
} else {
_self.setData({
hasMoreData: false
});
};
var homeListsName = 'cateLists[0]';
_self.setData({
[homeListsName]: res.data.data,
contentlist: res.data.data.list
});
wx.hideLoading();
}
})
})
});
}
});
},
getMoreLists:function(){//加载更多列表
var _this = this;
//全部列表接口
var _url = app.globalData.apiDomain + '/api/indexlist/IndexProductList';
var _data = '';
if (_this.data.curId!=0){
//分类列表接口
_url = app.globalData.apiDomain + '/api/indexlist/categoryProductsList';
_data = {
'page': _this.data.page,
'category_id': _this.data.curId
}
}else{
_data = {
'page': _this.data.page
}
};
wx.request({
url: _url,
data:_data,
method: 'POST',
header: {
'content-type': 'application/json' // 默认值
},
success: function (res) {
_this.setData({
page: _this.data.page + 1
});
if (res.data.data.prev < res.data.data.sums_page) {//下一页有数据
_this.setData({
hasMoreData: true
});
} else {
_this.setData({
hasMoreData: false
});
}
var tmpArr = _this.data.contentlist;
for(var i=0;i<res.data.data.list.length;i++){
tmpArr.push(res.data.data.list[i]);
}
var homeListsName = 'cateLists[' + _this.data.curIndex+']';
var curListsName = 'cateLists[' + _this.data.curIndex + '].list';
_this.setData({
contentlist: tmpArr,
[homeListsName]: res.data.data
},function(){
_this.setData({
[curListsName]: tmpArr
})
});
wx.hideLoading();
}
})
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
var _this = this;
if (_this.data.hasMoreData) {
wx.showLoading({
title: '加载更多数据',
});
_this.getMoreLists();
} else {
wx.showToast({
title: '没有更多数据',
})
}
},
loadDetail: function (e) {//跳转详情页
var pid = e.currentTarget.dataset.url;
var img = e.currentTarget.dataset.img;
var brief = e.currentTarget.dataset.brief;
var price = e.currentTarget.dataset.price;
wx.navigateTo({
url: '../item/item?id=' + pid + '&img=' + img + '&brief=' + brief + '&price=' + price,
success: function (res) { },
fail: function (res) { },
complete: function (res) { },
})
},
loadLists: function (e) {//点击分类tab事件
var id = e.currentTarget.dataset.id;
var index = e.currentTarget.dataset.index;
var _this = this;
_this.setData({
curIndex:index
},function(){
if (id != _this.data.curId) {//点击的不是当前选中项
_this.setData({
curId: id
},function(){
console.log(id);
if (id != 0) {//不是全部
if (_this.data.cateLists[index].list) {//判断当前分类的列表数据是否存在
//console.log('已有数据');
_this.showLists();
} else {//不存在加载第一页的数据
//console.log('没有数据');
_this.getCateLists();
}
} else if(id==0) {//首页
if (_this.data.cateLists[index].list) {//判断当前分类的列表数据是否存在
//console.log('首页已有数据');
_this.showLists();
} else {
//console.log('首页没有数据');
//_this.getCateLists();
}
};
})
};
})
},
getCateLists:function(){//获取当前分类的第一页数据
var _this = this;
var cate_id = _this.data.curId;
wx.showLoading({
title: '加载中',
});
wx.pageScrollTo({
scrollTop: 0,
})
wx.request({
url: app.globalData.apiDomain + '/api/indexlist/categoryProductsList',
data: { 'page': 1, 'category_id': _this.data.curId},
method: 'POST',
header: {
'content-type': 'application/json' // 默认值
},
success: function (res) {
_this.setData({
page: 2
});
if (res.data.data.prev < res.data.data.sums_page) {//下一页有数据
_this.setData({
hasMoreData: true
});
} else {
_this.setData({
hasMoreData: false
});
}
var tmpArr = [];
for (var i = 0; i < res.data.data.list.length; i++) {
tmpArr.push(res.data.data.list[i]);
}
var homeListsName = 'cateLists[' + _this.data.curIndex + ']';
var curListsName = 'cateLists[' + _this.data.curIndex + '].list';
_this.setData({
contentlist: tmpArr,
[homeListsName]: res.data.data
}, function () {
_this.setData({
[curListsName]: tmpArr
})
});
wx.hideLoading();
}
})
},
showLists:function(){//存在数据,显示切换
var _this = this;
wx.pageScrollTo({
scrollTop: 0,
})
if (_this.data.cateLists[_this.data.curIndex].sums_page >= _this.data.cateLists[_this.data.curIndex].next) {//有下一页
_this.setData({
hasMoreData: true
})
} else {
_this.setData({
hasMoreData: false
})
};
_this.setData({//更新列表数据和其他相关数据
contentlist:_this.data.cateLists[_this.data.curIndex].list,//列表内容
});
}
})
服务端
1.创建获取分类列表product.caetgoryList.as_view()
2.获所有商品列表product.ProductList.as_view()
3.获取分类下的商品列表 product.categoryProductsList
url.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from api.views import product
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^api/indexlist/categoryList$', product.caetgoryList.as_view()),
url(r'^api/indexlist/IndexProductList$', product.ProductList.as_view()),
url(r'^api/indexlist/categoryProductsList$', product.categoryProductsList.as_view()),
]
product.py
from rest_framework.views import APIView
from api import baseResponse
from api import models
from django.http import JsonResponse
from rest_framework.pagination import PageNumberPagination
import math
from api.MySer.MySer import ProductsSerializer,CategorySerializer
#分类列表接口
class caetgoryList(APIView):
def get(self, request):
#这里因为模拟数据,我这里将分类id固定
data_obj = models.Category.objects.filter(cat_id__in=[6458,6460,6477,6486,6481,6500,6552]).order_by('p_order')
#序列化组件,序列化返回的数据
data_list=CategorySerializer(instance=data_obj, many=True)
data=data_list.data
re_data = baseResponse.resdic("success", "查询成功",data)
return JsonResponse(re_data)
#所有商品列表接口
class ProductList(APIView,):
def post(self,request):
params = request.data
#判断是否有页数参数
if params.get('page'):
page=params['page']
ret = models.Products.objects.all()
count=ret.count()
sums_page=math.ceil(count/10)
next= page + 1 if (page+1) <sums_page else sums_page
prev = page - 1 if (page - 1) > 0 else 1
# 创建分页对象
page_obj = PageNumberPagination()
page_obj.page_size = 10
page_obj.page_query_param = 'page'
# 定制传参
page_obj.page_size_query_param = 'size'
# 最大一页的数据
page_obj.max_page_size = 10
# 在数据库中获取分页的数据
page_list = page_obj.paginate_queryset(ret, request, view=self)
# 对分页进行序列化
data_list=ProductsSerializer(instance=page_list, many=True)
p_data={}
p_data['sums_page'] = sums_page
p_data['next'] =next
p_data['prev'] = prev
p_data['list'] = data_list.data
print('list')
print(type(data_list.data))
re_data = baseResponse.resdic("success", "查询成功", p_data)
return JsonResponse(re_data)
else:
re_data = baseResponse.resdic("error", "缺少参数")
return JsonResponse(re_data)
#分类商品列表
class categoryProductsList(APIView):
def post(self,request):
params = request.data
if params.get('page') and params.get('category_id'):
page=params['page']
category_id=params['category_id']
ret = models.Products.objects.filter(cat_id__cat_id=category_id)
count=ret.count()
sums_page=math.ceil(count/10)
#值1 if 条件 else 值2
next= page + 1 if (page+1) <sums_page else sums_page
prev = page - 1 if (page - 1) > 0 else 1
# 创建分页对象
page_obj = PageNumberPagination()
page_obj.page_size = 10
page_obj.page_query_param = 'page'
# 定制传参
page_obj.page_size_query_param = 'size'
# 最大一页的数据
page_obj.max_page_size = 10
# 在数据库中获取分页的数据
page_list = page_obj.paginate_queryset(ret, request, view=self)
# 对分页进行序列化
data_list=ProductsSerializer(instance=page_list, many=True)
p_data={}
p_data['sums_page'] = sums_page
p_data['next'] =next
p_data['prev'] = prev
p_data['list'] = data_list.data
print('list')
print(data_list.data)
re_data = baseResponse.resdic("success", "查询成功", p_data)
return JsonResponse(re_data)
else:
re_data = baseResponse.resdic("error", "缺少参数")
return JsonResponse(re_data)