03-02 礼物列表

______egon新书python全套来袭请看:https://egonlin.com/book.html

礼物列表

需求:从挑选礼物中到礼物列表,列表中有礼物分类。点击分类获取分类礼物

小程序端

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)

posted @ 2019-10-14 12:06  小猿取经-林海峰老师  阅读(630)  评论(0编辑  收藏  举报