【小程序】微信小程序课程 -4 项目实战

目录

[1、 效果图](#1、 效果图)

2、创建项目

[2.1 创建小程序端](#2.1 创建小程序端)

[2.1.1 先创建纯净项目](#2.1.1 先创建纯净项目)

[2.1.2 删除components](#2.1.2 删除components)

[2.1.4 删除app.json红色部分](#2.1.4 删除app.json红色部分)

[2.1.5 删除index.json红色部分](#2.1.5 删除index.json红色部分)

[2.1.6 删除index.wxss全部内容](#2.1.6 删除index.wxss全部内容)

[2.1.7 删除index.wxml全部内容](#2.1.7 删除index.wxml全部内容)

[2.1.8 app.json创建4个页面](#2.1.8 app.json创建4个页面)

[2.1.9 app.json添加底部导航](#2.1.9 app.json添加底部导航)

[2.1.10 app.json设置窗口栏](#2.1.10 app.json设置窗口栏)

[2.1.11 删除app.wxss全部内容](#2.1.11 删除app.wxss全部内容)

[2.1.12 不校验http](#2.1.12 不校验http)

[2.2 创建小程序后端项目](#2.2 创建小程序后端项目)

[2.2.1 创建项目](#2.2.1 创建项目)

[2.2.2 安装配置mysql数据库](#2.2.2 安装配置mysql数据库)

[2.2.3 settings配置修改(国际化修改)](#2.2.3 settings配置修改(国际化修改))

[2.2.4 运行后端](#2.2.4 运行后端)

[2.2.5 后期涉及需要安装的库](#2.2.5 后期涉及需要安装的库)

3、小程序中集成的vant-app

[3.1 node介绍](#3.1 node介绍)

[3.2 使用vant样式引用(这里是示例,代码不需要)](#3.2 使用vant样式引用(这里是示例,代码不需要))

4、欢迎页面

[4.1 纯静态](#4.1 纯静态)

[4.1.1 welcome. wxml](#4.1.1 welcome. wxml)

[4.1.2 welcome.wxss](#4.1.2 welcome.wxss)

[4.1.3 welcome.js](#4.1.3 welcome.js)

[4.2 后端加载欢迎页](#4.2 后端加载欢迎页)

[4.2.1 创建表模型](#4.2.1 创建表模型)

[4.2.2 开启media访问](#4.2.2 开启media访问)

[4.2.3 使用admin上传图片](#4.2.3 使用admin上传图片)

[4.2.3.1 配置](#4.2.3.1 配置)

[4.2.3.2 上传图片](#4.2.3.2 上传图片)

[4.2.4 写视图函数(后期使用cbv改造)](#4.2.4 写视图函数(后期使用cbv改造))

[4.3 小程序端改造(动态获取广告)](#4.3 小程序端改造(动态获取广告))

[4.3.1 welcome. wxml](#4.3.1 welcome. wxml)

[4.3.2 welcome. wxss](#4.3.2 welcome. wxss)

[5、 首页](#5、 首页)

[5.1 首页静态页面](#5.1 首页静态页面)

[5.1.1 index.wxml](#5.1.1 index.wxml)

[5.1.2 index.wxss](#5.1.2 index.wxss)

[5.1.3 app.json](#5.1.3 app.json)

[5.2 首页菜单跳转](#5.2 首页菜单跳转)

[5.2.1 app.json创建菜单新页面](#5.2.1 app.json创建菜单新页面)

[5.2.2 index.wxjs设置跳转](#5.2.2 index.wxjs设置跳转)

[5.3 首页轮播图和公告接口](#5.3 首页轮播图和公告接口)

[5.3.1 models](#5.3.1 models)

[5.3.2 admin.py注册好新表和创建文件目录](#5.3.2 admin.py注册好新表和创建文件目录)

[5.3.3 admin录入数据](#5.3.3 admin录入数据)

[5.3.4 轮播图接口](#5.3.4 轮播图接口)

[5.3.4.1 smart应用下新建serializer](#5.3.4.1 smart应用下新建serializer)

[5.3.4.2 views.py实现BannerViewSet](#5.3.4.2 views.py实现BannerViewSet)

[5.3.4.3 分发路由urls.py](#5.3.4.3 分发路由urls.py)

[5.3.4.4 settings项目当中注册rest_framework](#5.3.4.4 settings项目当中注册rest_framework)

[5.3.4.5 启动服务验证](#5.3.4.5 启动服务验证)

[5.3.4.6 整合通知到一个接口](#5.3.4.6 整合通知到一个接口)

[5.3.4.6.1 serializer.py](#5.3.4.6.1 serializer.py)

[5.3.4.6.2 views.py](#5.3.4.6.2 views.py)

[5.3.4.6.3 查看接口返回数据](#5.3.4.6.3 查看接口返回数据)

[5.4 小程序轮播图与公告获取后端数据](#5.4 小程序轮播图与公告获取后端数据)

[5.4.1 index.wxjs](#5.4.1 index.wxjs)

[5.4.2 index.wxml](#5.4.2 index.wxml)

[5.5 接口全局IP设置](#5.5 接口全局IP设置)

[5.5.1 新建全局settings.js](#5.5.1 新建全局settings.js)

[5.5.3 welcome.js引入应用](#5.5.3 welcome.js引入应用)

[5.5.3 index.js引入应用](#5.5.3 index.js引入应用)

6、信息采集

[6.1 信息采集静态页面](#6.1 信息采集静态页面)

[6.1.1 collection.json](#6.1.1 collection.json)

[6.1.2 collection.wxml](#6.1.2 collection.wxml)

[6.1.3 collection.wxjs](#6.1.3 collection.wxjs)

[6.1.4 collection.wxss](#6.1.4 collection.wxss)

[6.2 信息采集后端接口](#6.2 信息采集后端接口)

[6.2.1 新建model.py创建表](#6.2.1 新建model.py创建表)

[6.2.2 录入数据](#6.2.2 录入数据)

[6.2.3 serializer.py](#6.2.3 serializer.py)

[6.2.4 views.py实现数据采集查询接口](#6.2.4 views.py实现数据采集查询接口)

[6.2.5 分发路由](#6.2.5 分发路由)

[6.2.6 验证](#6.2.6 验证)

[6.3 引入矢量图标库](#6.3 引入矢量图标库)

[6.4 小程序信息采集打通接口](#6.4 小程序信息采集打通接口)

[6.4.1 完成全局配置信息采集页面](#6.4.1 完成全局配置信息采集页面)

[6.4.2 完成collection.wxjs](#6.4.2 完成collection.wxjs)

[6.4.3 实现删除功能](#6.4.3 实现删除功能)

[6.4.3.1 views实现删除](#6.4.3.1 views实现删除)

[6.4.3.2 collection.js实现删除](#6.4.3.2 collection.js实现删除)

[6.4.3.3 删除查询总数那有个bug总数不对](#6.4.3.3 删除查询总数那有个bug总数不对)

7、信息采集详情页

[7.1 小程序端--拍照页面-- camera](#7.1 小程序端--拍照页面-- camera)

[7.1.1 app.json新增camera页面与form页面](#7.1.1 app.json新增camera页面与form页面)

[7.1.2 camera.wxml](#7.1.2 camera.wxml)

[7.1.3 camera.wxss](#7.1.3 camera.wxss)

[7.1.4 camera.js](#7.1.4 camera.js)

[7.2 小程序端--采集页面--form](#7.2 小程序端--采集页面--form)

[7.2.1 collection.wxjs新增跳转到form页面](#7.2.1 collection.wxjs新增跳转到form页面)

[7.2.2 form.wxml](#7.2.2 form.wxml)

[7.2.3 form.wxss](#7.2.3 form.wxss)

[7.2.3 form.js](#7.2.3 form.js)

[7.3 后端接口](#7.3 后端接口)

[7.3.1 Serializer新增AreaSerializer](#7.3.1 Serializer新增AreaSerializer)

[7.3.2 views新增AreaViewSet](#7.3.2 views新增AreaViewSet)

[7.3.3 urls配置](#7.3.3 urls配置)

[7.4 小程序实现form.js](#7.4 小程序实现form.js)

[7.4.1 全局配置添加form后端路径](#7.4.1 全局配置添加form后端路径)

[7.4.2 后端处理接口](#7.4.2 后端处理接口)

[7.4.2.1 serializer新增CollectionSaveSerializer](#7.4.2.1 serializer新增CollectionSaveSerializer)

[7.4.2.2 views修改Collectionviewset](#7.4.2.2 views修改Collectionviewset)

[7.4.3 form.js](#7.4.3 form.js)

[7.4.4 collection.js 新增一个刷新查询](#7.4.4 collection.js 新增一个刷新查询)

8、信息统计-采集统计页面实现

[8.1 小程序端](#8.1 小程序端)

[8.1.1 app.json新增采集统计](#8.1.1 app.json新增采集统计)

[8.1.2 statistics.wxml](#8.1.2 statistics.wxml)

[8.1.3 statistics.wxss](#8.1.3 statistics.wxss)

[8.1.4 更新iconfont.wxss](#8.1.4 更新iconfont.wxss)

[8.2 后端接口](#8.2 后端接口)

[8.2.1 serializer新增StatisticsListSerializer](#8.2.1 serializer新增StatisticsListSerializer)

[8.2.2 views](#8.2.2 views)

[8.2.3 urls路由](#8.2.3 urls路由)

[8.3 采集统计联调](#8.3 采集统计联调)

[8.3.1 settings.js注册](#8.3.1 settings.js注册)

[8.3.2 collection.js添加点击跳转](#8.3.2 collection.js添加点击跳转)

[9、 人脸识别](#9、 人脸识别)

[9.1 人脸识别](#9.1 人脸识别)

[9.1.1 使用步骤](#9.1.1 使用步骤)

[9.1.2 上传-删除-匹配人脸](#9.1.2 上传-删除-匹配人脸)

10、个人中心

[10.1 个人中心静态页面](#10.1 个人中心静态页面)

[10.1.1 my.json](#10.1.1 my.json)

[10.1.2 my.wxss](#10.1.2 my.wxss)

[10.1.3 my.wxml](#10.1.3 my.wxml)

[10.1.4 my.wxjs](#10.1.4 my.wxjs)


前言:通过前面学习,来做一个智慧社区的小程序,包含:

1、 效果图

2、创建项目

2.1 创建小程序端

2.1.1 先创建纯净项目

2.1.2 删除components

2.1.4 删除app.json红色部分

2.1.5 删除index.json红色部分

2.1.6 删除index.wxss全部内容

2.1.7 删除index.wxml全部内容

2.1.8 app.json创建4个页面

  "pages": [
    "pages/index/index",
    "pages/my/my",
    "pages/activity/activity",
    "pages/notice/notice"
  ]

2.1.9 app.json添加底部导航

 "tabBar": {
    "selectedColor": "#1c1c1b",
    "position": "bottom",
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "首页",
        "iconPath": "static/images/icon/home.png",
        "selectedIconPath": "static/images/icon/home-o.png"
      },
      {
        "pagePath": "pages/activity/activity",
        "text": "活动",
        "iconPath": "static/images/icon/activity.png",
        "selectedIconPath": "static/images/icon/activity-o.png"
      },
      {
        "pagePath": "pages/notice/notice",
        "text": "公告",
        "iconPath": "static/images/icon/notice.png",
        "selectedIconPath": "static/images/icon/notice-o.png"
      },
      {
        "pagePath": "pages/my/my",
        "text": "我的",
        "iconPath": "static/images/icon/my.png",
        "selectedIconPath": "static/images/icon/my-o.png"
      }
    ]
  },

2.1.10 app.json设置窗口栏

 "window": {
    "navigationBarTitleText": "智慧社区",
    "navigationBarBackgroundColor": "#fff",
    "enablePullDownRefresh": false,
    "backgroundColor": "#00FFFF",
    "backgroundTextStyle":"light",
    "navigationBarTextStyle": "black"
  }, 

完整代码

{
  "pages": [
    "pages/index/index",
    "pages/my/my",
    "pages/activity/activity",
    "pages/notice/notice"
  ],
  "window": {
    "navigationBarTitleText": "智慧社区",
    "navigationBarBackgroundColor": "#fff",
    "enablePullDownRefresh": false,
    "backgroundColor": "#00FFFF",
    "backgroundTextStyle":"light",
    "navigationBarTextStyle": "black"
  }, 
  "tabBar": {
    "selectedColor": "#1c1c1b",
    "position": "bottom",
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "首页",
        "iconPath": "static/images/icon/home.png",
        "selectedIconPath": "static/images/icon/home-o.png"
      },
      {
        "pagePath": "pages/activity/activity",
        "text": "活动",
        "iconPath": "static/images/icon/activity.png",
        "selectedIconPath": "static/images/icon/activity-o.png"
      },
      {
        "pagePath": "pages/notice/notice",
        "text": "公告",
        "iconPath": "static/images/icon/notice.png",
        "selectedIconPath": "static/images/icon/notice-o.png"
      },
      {
        "pagePath": "pages/my/my",
        "text": "我的",       
        "iconPath": "static/images/icon/my.png",
        "selectedIconPath": "static/images/icon/my-o.png"
      }
    ]
  },
  "sitemapLocation": "sitemap.json"

}

2.1.11 删除app.wxss全部内容

2.1.12 不校验http

2.2 创建小程序后端项目

django+ drf +mysql

2.2.1 创建项目

2.2.2 安装配置mysql数据库

 pip install pymysql

项目__init__.py添加

import pymysql
pymysql.install_as_MySQLdb()

修改为mysql数据库,这时候去把mysql数据库创建好,与下面name匹配的数据库

DATABASES = {
            'default': {
            'ENGINE': 'django.db.backends.mysql',#数据库的类型
            'NAME': '33', #所使用的的数据库的名字
            'USER': 'root', #数据库服务器的用户
            'PASSWORD': '33#33', #密码
            'HOST': '192.168.1.13', #主机
            'PORT': '3306', #端口
            }
}

2.2.3 settings配置修改(国际化修改)

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'


USE_TZ = False

'rest_framework', 'django_filters',

2.2.4 运行后端

python manage.py runserver 0.0.0.0:8000

2.2.5 后期涉及需要安装的库

# 上传图片
pip install pillow

# django后台页面美化  simpleui
pip install django-simpleui -i https://pypi.tuna.tsinghua.edu.cn/simple


# rest_framework
pip install djangorestframework


# baidu人脸识别
pip install baidu-aip

3、小程序中集成的vant-app

使用谷歌浏览器打开

https://vant-ui.github.io/vant-weapp/#/home

3.1 node介绍

安装node(略)

npm install -g cnpm --registry=https://registry.npm.taobao.org

#上面地址不行了,然后注意这个要使用管理员身份打开cmd
npm install -g cnpm --registry=https://registry.npmmirror.com
npm init -y
#npm i @vant/weapp -S  # 慢

# 这个快
cnpm i @vant/weapp -S  

(第6步 在之前步骤已经删除)

修改之前

修改之后

"packNpmManually": true,
    "packNpmRelationList": [
      {
        "packageJsonPath": "./package.json",
        "miniprogramNpmDistDir": "./"
      }
    ]

3.2 使用vant样式引用(这里是示例,代码不需要)

需要什么样式就引入,参照官网

  "usingComponents": {
    "van-cell": "@vant/weapp/cell/index",
    "van-cell-group":"@vant/weapp/cell-group/index",
    "van-calendar":"@vant/weapp/calendar/index",
    "van-notice-bar":"@vant/weapp/notice-bar/index",
     "van-grid": "@vant/weapp/grid/index",
    "van-grid-item": "@vant/weapp/grid-item/index"
  },

4、欢迎页面

app.json新增welcome 放第一位,作为首页

  "pages": [
    "pages/welcome/welcome",
    "pages/index/index",
    "pages/my/my",
    "pages/activity/activity",
    "pages/notice/notice"   
  ],

4.1 纯静态

4.1.1 welcome. wxml

<view class="container">
  <text class="jump" bindtap="doJump">跳过{{second}}秒</text>
  <image class="img" src="/static/images/bg/splash.png" />
</view>

4.1.2 welcome.wxss

page{
  height: 100%;
}

.container{
  width: 100%;
  height: 100%;
}
.container .img{
  width: 100%;
  height: 100%;
}
.jump{
  font-size: 30rpx;
  position: absolute;
  left: 600rpx;
  top: 80rpx;
  background-color: #dddddd;
  padding: 10rpx 20rpx;
  border-radius: 20rpx;
}

4.1.3 welcome.js

主要实现前端广告默认3秒倒计时自动跳转到首页

// pages/welcome/welcome.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    second: 3

  },
  doJump(){
    // 点击跳转到首页
    wx.switchTab({
      url: '/pages/index/index',
    })
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    // 启动广告的定时器,倒计时
    // 清除定时器
    var instance = setInterval(() =>{
      if(this.data.second<=0) {
        // 清除定时器
        clearInterval(instance)
        // 跳转到index页面
        this.doJump()
      }
      else{
        this.setData({
          second: this.data.second-1
        })
      }
      
    },1000)
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

4.2 后端加载欢迎页

4.2.1 创建表模型

models

from django.db import models


# 开启app广页业模型表
class Welcome(models.Model):
    # upload_to 图片上传后,放到media文件夹下的welcome文件夹下
    # 必须安装pillo库 pip install pillow
    img = models.ImageField(upload_to='welcome', default='/welcome/splash.png', verbose_name="图片")
    order = models.IntegerField(verbose_name="排序")
    # 这个字段不用穿,自动生成时间
    created_time = models.DateTimeField(auto_now=True, verbose_name="创建时间")
    is_delete = models.BooleanField(default=False, verbose_name="是否删除")
    # 如果表已存在且你不想Django管理它(如迁移),可以设置managed=False

    class Meta:
        managed = True
        db_table = 'welcome'
        verbose_name_plural = '欢迎表'

将数据迁移到mysql数据库

执行命令

# 默认所有修改过的model层转为迁移文件
makemigrations
# 默认将所有的迁移文件都执行,更新数据库
migrate

小知识:上你我使用的是第2种方法

4.2.2 开启media访问

django根目录下创建media文件夹(存储上传的图片),然后在settings设置

我使用的是这个,我认为一样

MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

在django项目当中进行如下设置

下面是我的设置,有一些差别

from django.contrib import admin
from django.urls import path, re_path
from django.views.static import serve
from django.conf import settings

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'^media/(?P<path>.*)$', serve, {
        'document_root': settings.MEDIA_ROOT,
    }),
]

4.2.3 使用admin上传图片

4.2.3.1 配置
# 输入命令
createsuperuser


# 创建用户root
root

# 邮箱
market@163.com

#密码
123456

# 再次输入密码
123456

# 提示密码不安全,输入Y
y
from django.contrib import admin
from .models import Welcome

# Register your models here.
admin.site.register(Welcome)
http://127.0.0.1:8000/admin/login/?next=/admin

美化上面的django管理页面

# simpleui
https://github.com/newpanjing/simpleui

# simpleui文档
https://newpanjing.github.io/simpleui_docs/

# 快速上手
https://newpanjing.github.io/simpleui_docs/config.html

安装库(略,前面安装了),再settings注册simpleui

INSTALLED_APPS = [
    'simpleui',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'smart.apps.SmartConfig',
]

apps.py 新增下图

from django.apps import AppConfig


class SmartConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'smart'
    verbose_name = "首页欢迎"
4.2.3.2 上传图片

输入地址验证

http://127.0.0.1:8000/media/welcome/splash.png

4.2.4 写视图函数(后期使用cbv改造)

views

from django.shortcuts import render
from .models import Welcome
from django.http import JsonResponse
# Create your views here.


def welcome(request):
    # 查询order最大的一张图片
    result = Welcome.objects.all().order_by('-order').first()
    img = 'http://127.0.0.1:8000/media/'+str(result.img)
    return JsonResponse({'code': 100, 'msg': '成功', 'result': img})

项目路由urls

from django.contrib import admin
from django.urls import path, re_path,include
from django.views.static import serve
from django.conf import settings

urlpatterns = [
    path('admin/', admin.site.urls),
    path('smart/', include('smart.urls')),
    re_path(r'^media/(?P<path>.*)$', serve, {
        'document_root': settings.MEDIA_ROOT,
    }),
]

在smart下新建urls 应用路由

from django.contrib import admin
from django.urls import path
from .views import welcome

urlpatterns = [
    # http://127.0.0.1:8000/smart/welcome/   --> 就能获得突破数据
    path('welcome/', welcome),
]

输入地址验证(没有使用postman接口调用,偷懒)

http://127.0.0.1:8000/smart/welcome/

4.3 小程序端改造(动态获取广告)

4.3.1 welcome. wxml

img做成变量获取

<view class="container">
  <text class="jump" bindtap="doJump">跳过{{second}}秒</text>
  <image class="img" src="{{img}}" />
</view>

4.3.2 welcome. wxss

加载页面的时候调用后端接口

// pages/welcome/welcome.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    second: 3,
    img: '/static/images/bg/splash.png'

  },
  doJump(){
    // 点击跳转到首页
    wx.switchTab({
      url: '/pages/index/index',
    })
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    // 向后端发送请求--》 获取广告页 --》 赋值给img
  wx.request({
    url: 'http://127.0.0.1:8000/smart/welcome/',
    method: "GET",
    success:(res) => {
      if(res.data.code == 100){
        console.log(res)
        this.setData({
          
          img: res.data.result
        })
      }else{
        wx.showToast({
          title: '网络请求异常',
        })
      }
    }
  })

    // 启动广告的定时器,倒计时
    // 清除定时器
    var instance = setInterval(() =>{
      if(this.data.second<=0) {
        // 清除定时器
        clearInterval(instance)
        // 跳转到index页面
        this.doJump()
      }
      else{
        this.setData({
          second: this.data.second-1
        })
      }
      
    },1000)
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

5、 首页

5.1 首页静态页面

5.1.1 index.wxml

<view class="container">
  <!-- 轮播图 -->
  <view class="banner">
    <swiper autoplay indicator-dots circular indicator-color="#FFFFFF" interval="3000">
      <swiper-item>
        <image src="/static/images/index/banner/banner1.png" mode="widthFix" />
      </swiper-item>
      <swiper-item>
        <image src="/static/images/index/banner/banner2.png" mode="widthFix" />
      </swiper-item>
      <swiper-item>
        <image src="/static/images/index/banner/banner3.png" mode="widthFix" />
      </swiper-item>
    </swiper>
  </view>
  <!-- 通知 -->
  <van-notice-bar left-icon="volume-o" text="在代码阅读过程中人们说脏话的频率是衡量代码质量的唯一标准。" />
  <!-- 快捷入口 -->
  <van-grid column-num="3">
    <van-grid-item icon="/static/images/index/menu/xx.png" text="信息采集" bind:click="gotoCollection" />
    <van-grid-item icon="/static/images/index/menu/sq.png" text="社区活动" bind:click="gotoActivity" />
    <van-grid-item icon="/static/images/index/menu/rl.png" text="人脸检测" bind:click="gotoFace" />
    <van-grid-item icon="/static/images/index/menu/yy.png" text="语言识别" bind:click="gotoVoice" />
    <van-grid-item icon="/static/images/index/menu/xl.png" text="心率检测" bind:click="gotoHeart" />
    <van-grid-item icon="/static/images/index/menu/jf.png" text="积分商城" bind:click="gotoGoods" />
  </van-grid>
  <!-- 底部 -->
  <view class="bottom">
    <view class="btv">
    <image class="btimg"  src="/static/images/index/bottom/cute1.png" mode="scaleToFill" />       
    </view>  
    <view class="btv">
    <image class="btimg"  src="/static/images/index/bottom/cute2.png" mode="scaleToFill" />       
    </view>  
    <view  class="btv">
    <image class="btimg"  src="/static/images/index/bottom/cute3.png" mode="scaleToFill" />       
    </view>  
    <view  class="btv">
    <image class="btimg"  src="/static/images/index/bottom/cute4.png" mode="scaleToFill" />       
    </view>  
    <view  class="btv">
    <image class="btimg"  src="/static/images/index/bottom/cute5.png" mode="scaleToFill" />       
    </view>  
    <view  class="btv">
    <image class="btimg"  src="/static/images/index/bottom/cute6.png" mode="scaleToFill" />       
    </view>  
  </view>

</view>

5.1.2 index.wxss

.banner image{
  width: 100%;           /* 图片宽度拉伸至容器宽度  */
  height: 100%;          /* 图片高度拉伸至容器宽度  */
  object-fit: cover;     /* 图片将覆盖整个容器区域,可能被裁剪 */
}

.bottom{
  display: flex;
  justify-content: space-evenly;
  margin-top: 20rpx;
  flex-wrap: wrap;
}
.bottom .btv .btimg{
  width: 345rpx;
  height: 200rpx;
}

5.1.3 app.json

  "usingComponents": {
    "van-cell": "@vant/weapp/cell/index",
    "van-cell-group":"@vant/weapp/cell-group/index",
    "van-calendar":"@vant/weapp/calendar/index",
    "van-notice-bar":"@vant/weapp/notice-bar/index",
    "van-grid": "@vant/weapp/grid/index",
    "van-grid-item": "@vant/weapp/grid-item/index"
  },

5.2 首页菜单跳转

5.2.1 app.json创建菜单新页面

  "pages": [
    "pages/welcome/welcome",
    "pages/index/index",
    "pages/my/my",
    "pages/activity/activity",
    "pages/notice/notice",
    "pages/collection/collection",
    "pages/face/face",
    "pages/voice/voice",
    "pages/heart/heart",
    "pages/goods/goods"   
  ],

5.2.2 index.wxjs设置跳转

// index.js
Page({
  gotoCollection(){
      wx.navigateTo({
        url: '/pages/collection/collection',
      })
    },
  gotoActivity(){
    wx.switchTab({
      url: '/pages/activity/activity',
    })
  },
  gotoFace(){
    wx.navigateTo({
      url: '/pages/face/face',
    })
  },
  gotoVoice(){
    wx.navigateTo({
      url: '/pages/voice/voice',
    })
  },
  gotoHeart(){
    wx.navigateTo({
      url: '/pages/heart/heart',
    })
  },
  gotoGoods(){
    wx.navigateTo({
      url: '/pages/goods/goods',
    })
  }
})

5.3 首页轮播图和公告接口

5.3.1 models

新增两张表,迁移不再累述

from django.db import models


# 开启app广页业模型表
class Welcome(models.Model):
    # upload_to 图片上传后,放到media文件夹下的welcome文件夹下
    # 必须安装pillo库 pip install pillow
    img = models.ImageField(upload_to='welcome', default='/welcome/splash.png', verbose_name="图片")
    order = models.IntegerField(verbose_name="排序")
    # 这个字段不用穿,自动生成时间
    created_time = models.DateTimeField(auto_now=True, verbose_name="创建时间")
    is_delete = models.BooleanField(default=False, verbose_name="是否删除")
    # 如果表已存在且你不想Django管理它(如迁移),可以设置managed=False

    class Meta:
        managed = True
        db_table = 'welcome'
        verbose_name_plural = '欢迎表'
    def __str__(self):
        return str(self.img)

# 轮播图模型表
class Banner(models.Model):
    img = models.ImageField(upload_to='banner', default='/banner/banner.png', verbose_name="图片")
    order = models.IntegerField(verbose_name="排序")
    # 这个字段不用传,自动生成时间
    created_time = models.DateTimeField(auto_now=True, verbose_name="创建时间")
    is_delete = models.BooleanField(default=False, verbose_name="是否删除")
    # 如果表已存在且你不想Django管理它(如迁移),可以设置managed=False
    class Meta:
        managed = True
        db_table = 'banner'
        verbose_name_plural = '轮播图表'

    def __str__(self):
        return str(self.img)


# 通知表
class Notice(models.Model):
    title = models.CharField(max_length=64, verbose_name="公告标题")
    content = models.TextField(verbose_name="公告内容")
    img = models.ImageField(upload_to='notice', default='/notice/notice.png', verbose_name="公告图片")
    created_time = models.DateTimeField(auto_now=True, verbose_name="创建时间")
    is_delete = models.BooleanField(default=False, verbose_name="是否删除")

    class Meta:
        managed = True
        db_table = 'notice'
        verbose_name_plural = '通知公告表'

    def __str__(self):
        return self.title

5.3.2 admin.py注册好新表和创建文件目录

from django.contrib import admin
from .models import Banner, Welcome, Notice

# Register your models here.
admin.site.register(Welcome)
admin.site.register(Banner)
admin.site.register(Notice)

media下新建2个文件夹

5.3.3 admin录入数据

登录后台系统

5.3.4 轮播图接口

5.3.4.1 smart应用下新建serializer
# -*- coding: utf-8 -*-
# @Time    : 2024/9/26 9:20
# @Author  : super
# @File    : serializer.py
# @Software: PyCharm
# @Describe:
from rest_framework import serializers
from .models import Banner

class BannerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Banner
        fields = "__all__"
5.3.4.2 views.py实现BannerViewSet
from django.shortcuts import render
from .models import Welcome
from django.http import JsonResponse
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin
from .models import Banner
from .serializer import BannerSerializer
# Create your views here.


# 比较low 使用fbv实现
def welcome(request):
    # 查询order最大的一张图片
    result = Welcome.objects.all().order_by('-order').first()
    img = 'http://127.0.0.1:8000/media/'+str(result.img)
    return JsonResponse({'code': 100, 'msg': '成功', 'result': img})

class BannerViewSet(GenericViewSet,ListModelMixin):
    queryset = Banner.objects.filter(is_delete=False).order_by('-order')[:3]
    serializer_class = BannerSerializer
5.3.4.3 分发路由urls.py
from django.contrib import admin
from django.urls import path
from .views import welcome
from rest_framework.routers import SimpleRouter
from .views import BannerViewSet

router = SimpleRouter()
router.register('banner', BannerViewSet, basename='banners')
urlpatterns = [
    # http://127.0.0.1:8000/smart/welcome/   --> 就能获得突破数据
    path('welcome/', welcome),
]
urlpatterns += router.urls
5.3.4.4 settings项目当中注册rest_framework
INSTALLED_APPS = [
    'simpleui',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'smart.apps.SmartConfig',
    'rest_framework'
]
5.3.4.5 启动服务验证
 python manage.py runserver

http://127.0.0.1:8000/smart/banner/
5.3.4.6 整合通知到一个接口
5.3.4.6.1 serializer.py
# -*- coding: utf-8 -*-
# @Time    : 2024/9/26 9:20
# @Author  : super
# @File    : serializer.py
# @Software: PyCharm
# @Describe:
from rest_framework import serializers
from .models import Banner, Notice


class BannerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Banner
        fields = "__all__"


class NoticeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Notice
        fields = "__all__"
5.3.4.6.2 views.py
from django.shortcuts import render
from .models import Welcome
from django.http import JsonResponse
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin
from .models import Banner, Notice
from .serializer import BannerSerializer, NoticeSerializer
from rest_framework.response import Response
# Create your views here.


# 比较low 使用fbv实现
def welcome(request):
    # 查询order最大的一张图片
    result = Welcome.objects.all().order_by('-order').first()
    img = 'http://127.0.0.1:8000/media/'+str(result.img)
    return JsonResponse({'code': 100, 'msg': '成功', 'result': img})


class BannerViewSet(GenericViewSet, ListModelMixin):
    queryset = Banner.objects.filter(is_delete=False).order_by('-order')[:3]
    serializer_class = BannerSerializer
    # 重写list方法,将通知也整合进去
    def list(self, request, *args, **kwargs):

        response = super().list(request, *args, **kwargs)

        # 获取最后一条通知

        notice = Notice.objects.filter(is_delete=False).order_by('-create_time').first()
        serializer = NoticeSerializer(instance=notice)


        return Response({'code': 100,'msg': '成功', 'banner': response.data, 'notice': serializer.data})
5.3.4.6.3 查看接口返回数据

5.4 小程序轮播图与公告获取后端数据

5.4.1 index.wxjs

新增获取轮播图的接口

// index.js
Page({
  data:{
    banner_list:[{'img': '/static/images/index/banner/banner1.png'},{'img': '/static/images/index/banner/banner3.png'}],
    notice: '春天的菠菜是来自china的中国小伙,为了成为棒棒的,我必须红旗飘飘!'
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    wx.request({
      url: 'http://127.0.0.1:8000/smart/banner/',
      method: 'GET',
      success: (res) =>{
        this.setData({
          banner_list:res.data.banner,
          notice: res.data.notice.title
        })
      }
    })
  },

  gotoCollection(){
      wx.navigateTo({
        url: '/pages/collection/collection',
      })
    },
  gotoActivity(){
    wx.switchTab({
      url: '/pages/activity/activity',
    })
  },
  gotoFace(){
    wx.navigateTo({
      url: '/pages/face/face',
    })
  },
  gotoVoice(){
    wx.navigateTo({
      url: '/pages/voice/voice',
    })
  },
  gotoHeart(){
    wx.navigateTo({
      url: '/pages/heart/heart',
    })
  },
  gotoGoods(){
    wx.navigateTo({
      url: '/pages/goods/goods',
    })
  }
})

5.4.2 index.wxml

<view class="container">
  <!-- 轮播图 -->
  <view class="banner">
    <swiper autoplay indicator-dots circular indicator-color="#FFFFFF" interval="3000">
      <swiper-item wx:for="{{banner_list}}" wx:key="index">
        <image src="{{item.img}}" mode="widthFix" />
      </swiper-item>   
    </swiper>
  </view>
  <!-- 通知 -->
  <van-notice-bar left-icon="volume-o" text="{{notice}}" />
  <!-- 快捷入口 -->
  <van-grid column-num="3">
    <van-grid-item icon="/static/images/index/menu/xx.png" text="信息采集" bindtap="gotoCollection" />
    <van-grid-item icon="/static/images/index/menu/sq.png" text="社区活动" bind:click="gotoActivity" />
    <van-grid-item icon="/static/images/index/menu/rl.png" text="人脸检测" bind:click="gotoFace" />
    <van-grid-item icon="/static/images/index/menu/yy.png" text="语言识别" bind:click="gotoVoice" />
    <van-grid-item icon="/static/images/index/menu/xl.png" text="心率检测" bind:click="gotoHeart" />
    <van-grid-item icon="/static/images/index/menu/jf.png" text="积分商城" bind:click="gotoGoods" />
  </van-grid>
  <!-- 底部 -->
  <view class="bottom">
    <view class="btv">
    <image class="btimg"  src="/static/images/index/bottom/cute1.png" mode="scaleToFill" />       
    </view>  
    <view class="btv">
    <image class="btimg"  src="/static/images/index/bottom/cute2.png" mode="scaleToFill" />       
    </view>  
    <view  class="btv">
    <image class="btimg"  src="/static/images/index/bottom/cute3.png" mode="scaleToFill" />       
    </view>  
    <view  class="btv">
    <image class="btimg"  src="/static/images/index/bottom/cute4.png" mode="scaleToFill" />       
    </view>  
    <view  class="btv">
    <image class="btimg"  src="/static/images/index/bottom/cute5.png" mode="scaleToFill" />       
    </view>  
    <view  class="btv">
    <image class="btimg"  src="/static/images/index/bottom/cute6.png" mode="scaleToFill" />       
    </view>  
  </view>

</view>

5.5 接口全局IP设置

5.5.1 新建全局settings.js

根目录新增config目录 --》 新建settings.js

const rootUrl='http://127.0.0.1:8000/smart/'
// 表示导出, 在任意js中可以导入 导入就是这个对象
module.exports={
  welcome:rootUrl + 'welcome/',
  banner:rootUrl + 'banner/',
}

5.5.3 welcome.js引入应用

import api from '../../config/settings'
Page({

  /**
   * 页面的初始数据
   */
  data: {
    second: 3,
    img: '/static/images/bg/splash.png'

  },
  doJump(){
    // 点击跳转到首页
    wx.switchTab({
      url: '/pages/index/index',
    })
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    // 向后端发送请求--》 获取广告页 --》 赋值给img
  wx.request({
    url: api.welcome,
    method: "GET",
    success:(res) => {
      if(res.data.code == 100){
        console.log(res)
        this.setData({
          
          img: res.data.result
        })
      }else{
        wx.showToast({
          title: '网络请求异常',
        })
      }
    }
  })

    // 启动广告的定时器,倒计时
    // 清除定时器
    var instance = setInterval(() =>{
      if(this.data.second<=0) {
        // 清除定时器
        clearInterval(instance)
        // 跳转到index页面
        this.doJump()
      }
      else{
        this.setData({
          second: this.data.second-1
        })
      }
      
    },1000)
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

5.5.3 index.js引入应用

import api from '../../config/settings'
Page({
  data:{
    banner_list:[{'img': '/static/images/index/banner/banner1.png'},{'img': '/static/images/index/banner/banner3.png'}],
    notice: '春天的菠菜是来自china的中国小伙,为了成为棒棒的,我必须红旗飘飘!'
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    wx.request({
      url: api.banner,
      method: 'GET',
      success: (res) =>{
        this.setData({
          banner_list:res.data.banner,
          notice: res.data.notice.title
        })
      }
    })
  },

  gotoCollection(){
      wx.navigateTo({
        url: '/pages/collection/collection',
      })
    },
  gotoActivity(){
    wx.switchTab({
      url: '/pages/activity/activity',
    })
  },
  gotoFace(){
    wx.navigateTo({
      url: '/pages/face/face',
    })
  },
  gotoVoice(){
    wx.navigateTo({
      url: '/pages/voice/voice',
    })
  },
  gotoHeart(){
    wx.navigateTo({
      url: '/pages/heart/heart',
    })
  },
  gotoGoods(){
    wx.navigateTo({
      url: '/pages/goods/goods',
    })
  }
})

6、信息采集

6.1 信息采集静态页面

6.1.1 collection.json

{
  "usingComponents": {},
 "navigationBarBackgroundColor": "#01ccb6",
 "navigationBarTitleText": "",
 "enablePullDownRefresh": true,
 "navigationBarTextStyle":"white",
 "backgroundColor": "#01ccb6" 
}

6.1.2 collection.wxml

<!--三部分-->
<view class="container">
  <!--第一部分 top -->
  <view class="top">
    <view class="tip">今日采集数量(人)</view>
    <view class="count">{{dataDict.today_count}}</view>
  </view>

  <!--第二部分 top 下方function -->
  <view class="function">
    <view class="menu" style="border-right:1rpx solid #ddd;" bindtap="bindToForm">
      <text class="fa fa-camera-retro">信息采集</text>
    </view>
    <view class="menu" bindtap="bindToStatistics">
      <text class="fa fa-camera-retro">数据统计</text>
    </view>

  </view>

  <!--第三部分 列表 -->
  <view class="table">
    <view class="item">
      <view class="title">社区信息列表({{dataDict.today_count}}人)</view>
    </view>
    <!-- 循环 -->
    <view class="item" wx:for="{{dataDict.result}}" wx:for-item="row" wx:key="index">
      <view class="record">
        <view class="avatar">
          <image src="{{row.avatar}}"></image>
        </view>

        <view class="desc">
          <view class="username">{{row.name}}</view>
          <view>
            <view class="txt-group">
              <label class="zh">网格区域</label>
              <label class="en"> | {{row.area.desc}}</label>
            </view>
            <view class="area">
              <label class="fa fa-map-marker"></label>{{row.area.name}}
            </view>
          </view>
        </view>
        <view class="delete" bindtap="doDeleteRow" data-nid="{{row.id}}" data-index="{{index}}">
          <label class="iconfont icon-shanchu"></label>
        </view>
      </view>
    </view>
  </view>
</view>

6.1.3 collection.wxjs

// pages/collection/collection.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    dataDict:{
      result:[
        {
          "id": 1,
          "name": "张学友",
          "area": "#19",
          "avatar": "/static/images/collection/zxy.png"
        },
        {
          "id": 2,
          "name": "黎姿",
          "area": "#18",
          "avatar": "/static/images/collection/lz.png"
        }
      ],
      today_count: 66
    }

  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

6.1.4 collection.wxss

/* pages/collection/collection.wxss */
.top{
  background-color: #01ccb6;
  height: 200rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  color: white;
}

.top .tip{
  font-size: 22rpx;
  font-weight: 100;
}
.top .count{
  padding: 10rpx;
  font-size: 58rpx;
}
.function{
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  background-color: #02bfae;
}

.function .menu{
  font-size: 28rpx;
  margin: 25rpx 0;
  color: white;
  width: 50%;
  text-align: center;
  flex-direction: row;
  flex-direction: column;
  align-items: center;
}
.table .item{
  border-bottom: 1rpx solid #e7e7e7;
}
.table .item .title{
  margin: 20rpx 30rpx;
  padding-left: 10rpx;
  border-left: 5rpx solid #02bfae;
  font-size: 26rpx;
}

.record{
  margin: 30rpx 40rpx;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
}

.record .avatar{
  width: 200rpx;
  height: 200rpx;
}

.record .avatar image{
  width: 100%;
  height: 100%;
  border-radius: 30%;
}


.record .desc{
  margin: 0 40rpx
}


.desc{
  width: 290rpx;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.desc .username{
  margin-top: 25rpx;
  font-size: 38rpx;
}

.txt-group{
  font-size: 27rpx;
  margin: 10rpx 0;
}

.txt-group zh{
  color: #8c8c8c
}

.txt-group .en{
  color: #cccccc;
}

.area{
  color: #00c8b6;
  font-weight: bold;
}

.delete{
  width: 100rpx;
  color: red;
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

6.2 信息采集后端接口

6.2.1 新建model.py创建表

新建采集表collection、区域表area与用户userinfo表,迁移不再累述

from django.db import models


# 开启app广页业模型表
class Welcome(models.Model):
    # upload_to 图片上传后,放到media文件夹下的welcome文件夹下
    # 必须安装pillo库 pip install pillow
    img = models.ImageField(upload_to='welcome', default='/welcome/splash.png', verbose_name="图片")
    order = models.IntegerField(verbose_name="排序")
    # 这个字段不用穿,自动生成时间
    created_time = models.DateTimeField(auto_now=True, verbose_name="创建时间")
    is_delete = models.BooleanField(default=False, verbose_name="是否删除")
    # 如果表已存在且你不想Django管理它(如迁移),可以设置managed=False

    class Meta:
        managed = True
        db_table = 'welcome'
        verbose_name_plural = '欢迎表'
    def __str__(self):
        return str(self.img)

# 轮播图模型表
class Banner(models.Model):
    img = models.ImageField(upload_to='banner', default='/banner/banner.png', verbose_name="图片")
    order = models.IntegerField(verbose_name="排序")
    # 这个字段不用传,自动生成时间
    create_time = models.DateTimeField(auto_now=True, verbose_name="创建时间")
    is_delete = models.BooleanField(default=False, verbose_name="是否删除")
    # 如果表已存在且你不想Django管理它(如迁移),可以设置managed=False
    class Meta:
        managed = True
        db_table = 'banner'
        verbose_name_plural = '轮播图表'

    def __str__(self):
        return str(self.img)


# 通知表
class Notice(models.Model):
    title = models.CharField(max_length=64, verbose_name="公告标题")
    content = models.TextField(verbose_name="公告内容")
    img = models.ImageField(upload_to='notice', default='/notice/notice.png', verbose_name="公告图片")
    create_time = models.DateTimeField(auto_now=True, verbose_name="创建时间")
    is_delete = models.BooleanField(default=False, verbose_name="是否删除")

    class Meta:
        managed = True
        db_table = 'notice'
        verbose_name_plural = '通知公告表'

    def __str__(self):
        return self.title


##采集表
class Collection(models.Model):
    name = models.CharField(max_length=32, verbose_name="采集人员名称")
    # 姓名拼音作为后期人脸识别的ID号
    name_pinyin = models.CharField(max_length=32, verbose_name="采集人员姓名拼音")
    avatar = models.ImageField(upload_to='collection/%Y/%m/%d/', default='/collection/default.png', verbose_name="头像")
    create_time = models.DateTimeField(auto_now=True, verbose_name="采集时间")
    # face_token  后期使用 人脸识别token唯一码
    area = models.ForeignKey(to='Area', null=True, verbose_name="网格区域", on_delete=models.CASCADE)


    class Meta:
        managed = True
        db_table = 'collection'
        verbose_name_plural = '采集表'

    def __str__(self):
        return self.name


##  区域表
class Area(models.Model):
    name = models.CharField(max_length=32, verbose_name="网格区域员")
    desc = models.CharField(max_length=32, verbose_name="网格简称")
    # 跟用户是一对多的关系  一个网格员可以采集多个网格
    user = models.ForeignKey(to='UserInfo', null=True, verbose_name="负责用户", on_delete=models.CASCADE)
    create_time = models.DateTimeField(auto_now=True, verbose_name="创建时间")


    class Meta:
        managed = True
        db_table = 'area'
        verbose_name_plural = '区域表'

    def __str__(self):
        return self.name



### 用户表
class UserInfo(models.Model):
    username = models.CharField(max_length=32, verbose_name="用户名")
    password = models.CharField(max_length=100, verbose_name="密码")
    avatar = models.ImageField(upload_to='avatar', default='/avatar/avatar.png', verbose_name="头像")
    phone = models.CharField(max_length=111, verbose_name="手机号")
    email = models.EmailField(null=True, blank=True, verbose_name="邮箱")
    score = models.IntegerField(default=0, verbose_name="积分")
    create_time = models.DateTimeField(auto_now=True, verbose_name="创建时间")

    class Meta:
        managed = True
        db_table = 'userinfo'
        verbose_name_plural = '用户表'

    def __str__(self):
        return self.username

6.2.2 录入数据

在admin.py注册三张表

from django.contrib import admin
from .models import Banner, Welcome, Notice, Collection, Area, UserInfo

# Register your models here.
admin.site.register(Welcome)
admin.site.register(Banner)
admin.site.register(Notice)
admin.site.register(Collection)
admin.site.register(Area)
admin.site.register(UserInfo)

用户

区域表

采集表

6.2.3 serializer.py

新增CollectionSerializer类

# -*- coding: utf-8 -*-
# @Time    : 2024/9/26 9:20
# @Author  : super
# @File    : serializer.py
# @Software: PyCharm
# @Describe:
from rest_framework import serializers
from .models import Banner, Notice, Collection


class BannerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Banner
        fields = "__all__"


#  通知
class NoticeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Notice
        fields = "__all__"


## 采集
class CollectionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Collection
        fields = ['id', 'name', 'avatar', 'area']
        depth = 1 # area 外键关联详情拿到

6.2.4 views.py实现数据采集查询接口

from django.shortcuts import render
from .models import Welcome
from django.http import JsonResponse
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin
from .models import Banner, Notice, Collection
from .serializer import BannerSerializer, NoticeSerializer, CollectionSerializer
from rest_framework.response import Response
from datetime import datetime

# Create your views here.


# 比较low 使用fbv实现
def welcome(request):
    # 查询order最大的一张图片
    result = Welcome.objects.all().order_by('-order').first()
    img = 'http://127.0.0.1:8000/media/'+str(result.img)
    return JsonResponse({'code': 100, 'msg': '成功', 'result': img})


class BannerViewSet(GenericViewSet, ListModelMixin):
    queryset = Banner.objects.filter(is_delete=False).order_by('-order')[:3]
    serializer_class = BannerSerializer

    # 重写list方法,将通知也整合进去
    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        # 获取最后一条通知
        notice = Notice.objects.filter(is_delete=False).order_by('-create_time').first()
        serializer = NoticeSerializer(instance=notice)
        return Response({'code': 100, 'msg': '成功', 'banner': response.data, 'notice': serializer.data})




# 信息采集接口  -- 查询登录用户当天采集的所有数据  ---因为还有登录实现 所以暂时先查询当天采集所有数据
class Collectionviewset(GenericViewSet, ListModelMixin):
    queryset = Collection.objects.all().filter(create_time__gte=datetime.now().date()).order_by('-create_time')
    serializer_class = CollectionSerializer
    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        today_count = len(self.queryset)
        return Response({'code': 100, 'msg': '成功', 'result': response.data, 'today_count': today_count})

6.2.5 分发路由

from django.contrib import admin
from django.urls import path
from .views import welcome
from rest_framework.routers import SimpleRouter
from .views import BannerViewSet, Collectionviewset

router = SimpleRouter()
router.register('banner', BannerViewSet, 'banner')
router.register('collection', Collectionviewset, 'collection')
urlpatterns = [
    # http://127.0.0.1:8000/smart/welcome/   --> 就能获得突破数据
    path('welcome/', welcome),
]
urlpatterns += router.urls

6.2.6 验证

6.3 引入矢量图标库

@font-face {
  font-family: "iconfont"; /* Project id 4696732 */
  src: 
       url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAM8AAsAAAAABygAAALuAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHFQGYACCcAqCIIIHATYCJAMICwYABCAFhGcHNBtHBhHVk+Fkf0w67908UWFIIi6ywu0mJysC2auri1yWN5DW8ZhD7ENMmiZ4vubI93c3udzmCEgeF4mSqUKyCLqqdcCO0ZHsxANuhAs6RJnUCzlkN0prYAOOuAgSsOUcyRjMhwI23dww6ULvGgxJeYg/wnMSNuBknp9jWM9LXuMk0DAvBJrFOadkhBnKW/ToCynw0pwCwOf/3mljalHHL4C3J421aeIDywP6QO1p2Rbv5AXAKajXdLoAZfIlCGBp0kn17T90LAlLZ61dTg6D0ymQV8rSRQtm4RlBDAYZD8FlVxrkIBxQu+QhcCB+v/yiJQSFo3FqRs7vN5fbyx2jgw2gXxMs14TzFOAAGqgDBmRsf3I4GmkTaqzTUIJ6g8BX0YYO5NB/HuLilMcBkAfZM8l9xaP+UgFgABeYCyyalAuutaWJzv5bgmzc7hEncXbIj9/jEJdoJZyWOQ/s0QoupfsI/jp63Vs3xPH3nPDywmCw6DDO7z57FBW0LfJPJO2k4FjHM0NNes8eTU+dnZx1PsnZy3LOvvlOtv+y0uZxbxVHVhLh3ckre5pLa09xvr+Xs2xRQp/8vvfXllB7QFO8cUNC2zH3lb7Y0NIghii+bUIi0663DQl96QYgej/ocb/9Oww+9af9H98A8KmHiv3RB+cG776cAj9ZP5UkGjMEyrTJjaxiLu5911ksEHG8Kd5ONaW+TFbwSH0ldwy5OTQeJXTDroGDTwtcPDpgqdVvvU+qlWjExAIVdgoISS5BkcBNaJLcoRv2Mzhk+AaXJP9hGS/xu/lURFFHQsGoQf7Bq1qMZ+SY6g3tOwlqir2QukcE1mmpZq5YkOaY0z92YzZgqGa4aOdhShUa1YCKJ8fcDvNs2q4yqZqHI6Fg1CD/4FUtJiRz+fNuaN9JEEl/Jal7UId1Wgj6VVeotgfZp3/sxmzAkEhnuBjDMKUKrX1YQMWTmxBvh9klGVY3bW/Iv7YLgDhmEXeRhrPG7kRR7r0OAwAA') format('woff2'),
       url('//at.alicdn.com/t/c/font_4696732_24c374vcgqo.woff?t=1727339436396') format('woff'),
       url('//at.alicdn.com/t/c/font_4696732_24c374vcgqo.ttf?t=1727339436396') format('truetype');
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-a-shanchu1:before {
  content: "\e604";
}

app.wxss

@import "/static/css/iconfont.wxss";
复制代码
collection,wxml根据实际情况调整 

6.4 小程序信息采集打通接口

6.4.1 完成全局配置信息采集页面

const rootUrl='http://127.0.0.1:8000/smart/'
// 表示导出, 在任意js中可以导入 导入就是这个对象
module.exports={
  welcome:rootUrl + 'welcome/',
  banner:rootUrl + 'banner/',
  collection:rootUrl + 'collection/',
}

6.4.2 完成collection.wxjs

import api from '../../config/settings'
Page({

  /**
   * 页面的初始数据
   */
  data: {
    dataDict:{
      result:[
        {
          "id": 1,
          "name": "张学友",
          "area": "#19",
          "avatar": "/static/images/collection/zxy.png"
        },
        {
          "id": 2,
          "name": "黎姿",
          "area": "#18",
          "avatar": "/static/images/collection/lz.png"
        }
      ],
      today_count: 66
    }

  },
  refresh(){
    // 加载
    wx.showLoading({
      mask: true
    })
    wx.request({
      url: api.collection,
      method: "GET",
      success: (res)=>{
        if(res.data.code == 100){
          this.setData({
            dataDict: res.data
          })
        }else{
          wx.showToast({
            title: '网络加载失败',
          })
        }
      },
      complete: ()=>{
        wx.hideLoading()
      },
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    // 一进页面就调用这个函数
    this.refresh()
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
    // 下拉重新加载
    this.refresh()
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

6.4.3 实现删除功能

6.4.3.1 views实现删除
from django.shortcuts import render
from .models import Welcome
from django.http import JsonResponse
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin
from .models import Banner, Notice, Collection
from .serializer import BannerSerializer, NoticeSerializer, CollectionSerializer
from rest_framework.response import Response
from datetime import datetime
from rest_framework.mixins import DestroyModelMixin
# Create your views here.


# 比较low 使用fbv实现
def welcome(request):
    # 查询order最大的一张图片
    result = Welcome.objects.all().order_by('-order').first()
    img = 'http://127.0.0.1:8000/media/'+str(result.img)
    return JsonResponse({'code': 100, 'msg': '成功', 'result': img})


class BannerViewSet(GenericViewSet, ListModelMixin):
    queryset = Banner.objects.filter(is_delete=False).order_by('-order')[:3]
    serializer_class = BannerSerializer

    # 重写list方法,将通知也整合进去
    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        # 获取最后一条通知
        notice = Notice.objects.filter(is_delete=False).order_by('-create_time').first()
        serializer = NoticeSerializer(instance=notice)
        return Response({'code': 100, 'msg': '成功', 'banner': response.data, 'notice': serializer.data})




# 信息采集接口  -- 查询登录用户当天采集的所有数据  ---因为还有登录实现 所以暂时先查询当天采集所有数据
class Collectionviewset(GenericViewSet, ListModelMixin, DestroyModelMixin):
    queryset = Collection.objects.all().filter(create_time__gte=datetime.now().date()).order_by('-create_time')
    serializer_class = CollectionSerializer
    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        today_count = len(self.queryset)
        print(today_count)
        return Response({'code': 100, 'msg': '成功', 'result': response.data, 'today_count': today_count})
6.4.3.2 collection.js实现删除
import api from '../../config/settings'
Page({

  /**
   * 页面的初始数据
   */
  data: {
    dataDict:{
      result:[
        {
          "id": 1,
          "name": "张学友",
          "area": "#19",
          "avatar": "/static/images/collection/zxy.png"
        },
        {
          "id": 2,
          "name": "黎姿",
          "area": "#18",
          "avatar": "/static/images/collection/lz.png"
        }
      ],
      today_count: 66
    }

  },
    /**
   * 查询后台数据接口
   */
  refresh(){
    // 加载
    wx.showLoading({
      mask: true
    })
    wx.request({
      url: api.collection,
      method: "GET",
      success: (res)=>{
        if(res.data.code == 100){
          console.log(res)
          this.setData({
            dataDict: res.data
          })
        }else{
          wx.showToast({
            title: '网络加载失败',
          })
        }
      },
      complete: ()=>{
        wx.hideLoading()
      },
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    // 一进页面就调用这个函数
    this.refresh()
  },
    /**
   * 删除接口
   */
  
  doDeleteRow(e){
    wx.showModal({
      title: '确认是否删除',
      
      complete: (res) => {
        if (res.cancel) {     
          return     
        }    
        if (res.confirm) {
          //  真删除
          var nid = e.currentTarget.dataset.nid
          wx.showLoading({
            title: '删除中。。。',
            mask: true
          })
          wx.request({
            url: api.collection + nid + '/',
            method: "DELETE",
            success: (res)=>{
              // 删除完成或没有完成,都刷新页面
              this.refresh()

            },
            complete:()=>{
              wx.hideLoading()
            }
          })
        
        }
      }
    })
 
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
    // 下拉重新加载
    this.refresh()
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})
6.4.3.3 删除查询总数那有个bug总数不对

修改后端代码

from django.shortcuts import render
from .models import Welcome
from django.http import JsonResponse
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin
from .models import Banner, Notice, Collection
from .serializer import BannerSerializer, NoticeSerializer, CollectionSerializer
from rest_framework.response import Response
from datetime import datetime
from rest_framework.mixins import DestroyModelMixin
# Create your views here.


# 比较low 使用fbv实现
def welcome(request):
    # 查询order最大的一张图片
    result = Welcome.objects.all().order_by('-order').first()
    img = 'http://127.0.0.1:8000/media/'+str(result.img)
    return JsonResponse({'code': 100, 'msg': '成功', 'result': img})


class BannerViewSet(GenericViewSet, ListModelMixin):
    queryset = Banner.objects.filter(is_delete=False).order_by('-order')[:3]
    serializer_class = BannerSerializer

    # 重写list方法,将通知也整合进去
    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        # 获取最后一条通知
        notice = Notice.objects.filter(is_delete=False).order_by('-create_time').first()
        serializer = NoticeSerializer(instance=notice)
        return Response({'code': 100, 'msg': '成功', 'banner': response.data, 'notice': serializer.data})

# 信息采集接口  -- 查询登录用户当天采集的所有数据  ---因为还有登录实现 所以暂时先查询当天采集所有数据
class Collectionviewset(GenericViewSet, ListModelMixin, DestroyModelMixin):
    serializer_class = CollectionSerializer

    def get_queryset(self):
        # 获取当前日期
        today = datetime.now().date()
        # 返回今天及之后创建的所有集合
        return Collection.objects.filter(create_time__gte=today).order_by('-create_time')

    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        today_count = queryset.count()
        print(today_count)
        return Response({'code': 100, 'msg': '成功', 'result': serializer.data, 'today_count': today_count})


# # 信息采集接口  -- 查询登录用户当天采集的所有数据  ---因为还有登录实现 所以暂时先查询当天采集所有数据
# class Collectionviewset(GenericViewSet, ListModelMixin, DestroyModelMixin):
#     queryset = Collection.objects.all().filter(create_time__gte=datetime.now().date()).order_by('-create_time')
#     serializer_class = CollectionSerializer
#     def list(self, request, *args, **kwargs):
#         response = super().list(request, *args, **kwargs)
#         today_count = len(self.queryset)
#         print(today_count)
#         return Response({'code': 100, 'msg': '成功', 'result': response.data, 'today_count': today_count})

7、信息采集详情页

7.1 小程序端--拍照页面-- camera

7.1.1 app.json新增camera页面与form页面

"pages": [
    "pages/welcome/welcome",
    "pages/index/index",
    "pages/my/my",
    "pages/activity/activity",
    "pages/notice/notice",
    "pages/collection/collection",
    "pages/face/face",
    "pages/voice/voice",
    "pages/heart/heart",
    "pages/goods/goods",
    "pages/camera/camera",
    "pages/form/form"  
  ],

7.1.2 camera.wxml

<!--pages/camera/camera.wxml-->
<camera class="camera" device-position="{{backFont ? 'back' : 'font'}}" flash="off" frame-size="medium"></camera>

<view class="function">
  <view class="switch"></view>
  <view class="record" bindtap="takePhoto">
    <image src="/static/images/camera/record-on.png"></image>
  </view>

  <view class="switch" bindtap="switchCamera">
    <image src="/static/images/camera/rotate-camera-white.png"></image>  
  </view>
</view>

7.1.3 camera.wxss

page{
  height: 100%;
  }
.camera{
  height: 80%;
  width: 100%;
}

.function{
  height: 20%;  
  background-color: black;
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  align-items: center;
}

.record image{
  width: 160rpx;
  height: 160rpx;
}
.switch{
  color: white;
  width: 80rpx;
  height: 80rpx;
}
.switch image{
  width: 80rpx;
  height: 80rpx;
}

7.1.4 camera.js

// pages/camera/camera.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    backFont: true
  },

    /**
   * 翻转摄像头
   */
  switchCamera(){
    this.setData({
      backFont: !this.data.backFont
    })
  },

    /**
   * 拍照
   */
  takePhoto() {
    const ctx = wx.createCameraContext()
    ctx.takePhoto({
      quality: 'high',
      success: (res) => {
        // 这里我是要把拍的照片 返回给上个页面
        var pages = getCurrentPages() //取到当前打开的所有页面
        var prevPage = pages[pages.length-2] //拿到上个页面
        prevPage.setData({
          avatar: res.tempImagePath  //上个页面的avatar赋值图片路径
        })
        // this.setData({
              // 如果当前页面data中有src属性  的到的就是图片地址
          // src: res.tempImagePath    
  
        // })
         // 拍完就跳到上个页面
        wx.navigateBack({});
      }
    })
  },
  error(e) {
    console.log(e.detail)
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

7.2 小程序端--采集页面--form

7.2.1 collection.wxjs新增跳转到form页面

   /**
   * 跳转到信息采集列表
   */
  bindToForm(){
    wx.navigateTo({
      url: '/pages/form/form',
    })
  },
    /**
   * 信息统计
   */
  bindToStatistics(){
    // 先占位
  },

7.2.2 form.wxml

<view class="avatar">
  <image src="{{avatar}}" bindtap="bindToCamera"></image>
</view>

<view class="form">
  <view class="row-group">
    <input placeholder="请填写姓名" placeholder-class='txt' model:value="{{name}}" bindinput="bindNameChange" />
    <!-- <input placeholder="请填写姓名" placeholder-class='txt' model:value="{{name}}" bindinput="bindNameChange" /> -->
  </view>

  <view class="picker-group">
   <picker bindchange="bindPickerChange" value="{{index}}" range="{{objectArray}}" range-key="name" >
    <view wx:if="{{index > -1}}" class="picker-txt picker">当前网格:{{objectArray[index].name}}</view>
    <view wx:else class="picker-txt">请选择网格</view>
   </picker>  
  </view>
  <view>
    <button class="submit" bindtap="postUser"> 提 交</button>  
    <!-- <van-button class="submit" bintap="postUser" type="primary" size="large">提 交</van-button> -->
  </view>
</view>

7.2.3 form.wxss

.avatar{
  display: flex;
  flex-direction: column;
  align-items: center;
}
.avatar image{
  margin-top: 140rpx;
  width: 300rpx;
  height: 300rpx;
  border-radius: 30rpx;
  border: 1px sold #ddd;
}


.form{
  padding: 40rpx;
}


.form .row-group{
  padding: 10rpx 0;
  border-bottom: 1rpx solid#ddd;
  position: relative;
  margin-top: 30rpx;
}

.form .row-group text{
  font-size: 28rpx;
  padding: 20rpx 0;
}

.form .row-group input{
  padding: 10rpx 0;
}

.form .row-group .txt{
  color: #ccc;
  font-size: 28rpx;
}


.form .picker-group{
  border-bottom: 1rpx solid #ddd;
}


.form .picker-group .picker-txt{
  color: #ccc;
  font-size: 28rpx;
  padding: 40rpx 0 20rpx 0;
}

.form .picker-group .picker{
  color:black
}

.form .submit{
  margin-top: 80rpx;
  color: #fff;
  border: 2rpx solid #00c8b6;
  background-color:#00c8b6;
  font-size: 32rpx;
  font-weight: bold
}
/* 
.form .submit{
  margin-top: 80rpx;
} */

7.2.3 form.js

// pages/form/form.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    avatar: '/static/images/camera/camera.png'
  },
/**
   * 点击图片跳转到form页面
   */
  bindToCamera(){
    wx.navigateTo({
      url: '/pages/camera/camera',
    })
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

7.3 后端接口

7.3.1 Serializer新增AreaSerializer

# -*- coding: utf-8 -*-
# @Time    : 2024/9/26 9:20
# @Author  : super
# @File    : serializer.py
# @Software: PyCharm
# @Describe:
from rest_framework import serializers
from .models import Banner, Notice, Collection,Area


class BannerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Banner
        fields = "__all__"


#  通知
class NoticeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Notice
        fields = "__all__"


## 采集
class CollectionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Collection
        fields = ['id', 'name', 'avatar', 'area']
        depth = 1 # area 外键关联详情拿到


## 网格系列化列
class AreaSerializer(serializers.ModelSerializer):
    class Meta:
        model = Area
        fields = ['id', 'name', 'desc']

7.3.2 views新增AreaViewSet

from django.shortcuts import render
from .models import Welcome
from django.http import JsonResponse
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin
from .models import Banner, Notice, Collection, Area
from .serializer import BannerSerializer, NoticeSerializer, CollectionSerializer ,AreaSerializer
from rest_framework.response import Response
from datetime import datetime
from rest_framework.mixins import DestroyModelMixin
# Create your views here.


# 比较low 使用fbv实现
def welcome(request):
    # 查询order最大的一张图片
    result = Welcome.objects.all().order_by('-order').first()
    img = 'http://127.0.0.1:8000/media/'+str(result.img)
    return JsonResponse({'code': 100, 'msg': '成功', 'result': img})


class BannerViewSet(GenericViewSet, ListModelMixin):
    queryset = Banner.objects.filter(is_delete=False).order_by('-order')[:3]
    serializer_class = BannerSerializer

    # 重写list方法,将通知也整合进去
    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        # 获取最后一条通知
        notice = Notice.objects.filter(is_delete=False).order_by('-create_time').first()
        serializer = NoticeSerializer(instance=notice)
        return Response({'code': 100, 'msg': '成功', 'banner': response.data, 'notice': serializer.data})

# 信息采集接口  -- 查询登录用户当天采集的所有数据  ---因为还有登录实现 所以暂时先查询当天采集所有数据
class Collectionviewset(GenericViewSet, ListModelMixin, DestroyModelMixin):
    serializer_class = CollectionSerializer

    def get_queryset(self):
        # 获取当前日期
        today = datetime.now().date()
        # 返回今天及之后创建的所有集合
        return Collection.objects.filter(create_time__gte=today).order_by('-create_time')

    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        today_count = queryset.count()
        print(today_count)
        return Response({'code': 100, 'msg': '成功', 'result': serializer.data, 'today_count': today_count})



# # 信息采集接口  -- 查询登录用户当天采集的所有数据  ---因为还有登录实现 所以暂时先查询当天采集所有数据
# class Collectionviewset(GenericViewSet, ListModelMixin, DestroyModelMixin):
#     queryset = Collection.objects.all().filter(create_time__gte=datetime.now().date()).order_by('-create_time')
#     serializer_class = CollectionSerializer
#     def list(self, request, *args, **kwargs):
#         response = super().list(request, *args, **kwargs)
#         today_count = len(self.queryset)
#         print(today_count)
#         return Response({'code': 100, 'msg': '成功', 'result': response.data, 'today_count': today_count})

# 查询当前用户负责的网格-- 暂时拿全部
class AreaViewSet(GenericViewSet, ListModelMixin):
    queryset = Area.objects.all()
    serializer_class = AreaSerializer

7.3.3 urls配置

from django.contrib import admin
from django.urls import path
from .views import welcome
from rest_framework.routers import SimpleRouter
from .views import BannerViewSet, Collectionviewset, AreaViewSet

router = SimpleRouter()
router.register('banner', BannerViewSet, 'banner')
router.register('collection', Collectionviewset, 'collection')
router.register('area', AreaViewSet, 'area')
urlpatterns = [
    # http://127.0.0.1:8000/smart/welcome/   --> 就能获得突破数据
    path('welcome/', welcome),
]
urlpatterns += router.urls

7.4 小程序实现form.js

7.4.1 全局配置添加form后端路径

settings里面

const rootUrl='http://127.0.0.1:8000/smart/'
// 表示导出, 在任意js中可以导入 导入就是这个对象
module.exports={
  welcome:rootUrl + 'welcome/',
  banner:rootUrl + 'banner/',
  collection:rootUrl + 'collection/',  
  area:rootUrl + 'area/',
}

7.4.2 后端处理接口

7.4.2.1 serializer新增CollectionSaveSerializer
# -*- coding: utf-8 -*-
# @Time    : 2024/9/26 9:20
# @Author  : super
# @File    : serializer.py
# @Software: PyCharm
# @Describe:
from rest_framework import serializers
from .models import Banner, Notice, Collection,Area


class BannerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Banner
        fields = "__all__"


#  通知
class NoticeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Notice
        fields = "__all__"


## 采集--查询所有的序列化类
class CollectionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Collection
        fields = ['id', 'name', 'avatar', 'area']
        depth = 1 # area 外键关联详情拿到


## 采集--新增
class CollectionSaveSerializer(serializers.ModelSerializer):
    class Meta:
        model = Collection
        fields = ['name', 'avatar','area']

## 网格系列化列
class AreaSerializer(serializers.ModelSerializer):
    class Meta:
        model = Area
        fields = ['id', 'name', 'desc']
    def create(self, validated_data):
        instance = super().create(validated_data)
        return instance
7.4.2.2 views修改Collectionviewset
from django.shortcuts import render
from .models import Welcome
from django.http import JsonResponse
from rest_framework.viewsets import GenericViewSet
from .models import Banner, Notice, Collection, Area
from .serializer import BannerSerializer, NoticeSerializer, CollectionSerializer ,AreaSerializer, CollectionSaveSerializer
from rest_framework.response import Response
from datetime import datetime
from rest_framework.mixins import ListModelMixin,DestroyModelMixin,CreateModelMixin
# Create your views here.


# 比较low 使用fbv实现
def welcome(request):
    # 查询order最大的一张图片
    result = Welcome.objects.all().order_by('-order').first()
    img = 'http://127.0.0.1:8000/media/'+str(result.img)
    return JsonResponse({'code': 100, 'msg': '成功', 'result': img})


class BannerViewSet(GenericViewSet, ListModelMixin):
    queryset = Banner.objects.filter(is_delete=False).order_by('-order')[:3]
    serializer_class = BannerSerializer

    # 重写list方法,将通知也整合进去
    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        # 获取最后一条通知
        notice = Notice.objects.filter(is_delete=False).order_by('-create_time').first()
        serializer = NoticeSerializer(instance=notice)
        return Response({'code': 100, 'msg': '成功', 'banner': response.data, 'notice': serializer.data})

# 信息采集接口  -- 查询登录用户当天采集的所有数据  ---因为还有登录实现 所以暂时先查询当天采集所有数据
class Collectionviewset(GenericViewSet, ListModelMixin, DestroyModelMixin, CreateModelMixin):
    serializer_class = CollectionSerializer

    def get_serializer_class(self):
        if self.action == 'create':
            return CollectionSaveSerializer
        else:
            return self.serializer_class

    def get_queryset(self):
        # 获取当前日期
        today = datetime.now().date()
        # 返回今天及之后创建的所有集合
        return Collection.objects.filter(create_time__gte=today).order_by('-create_time')

    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        today_count = queryset.count()
        print(today_count)
        return Response({'code': 100, 'msg': '成功', 'result': serializer.data, 'today_count': today_count})



# # 信息采集接口  -- 查询登录用户当天采集的所有数据  ---因为还有登录实现 所以暂时先查询当天采集所有数据
# class Collectionviewset(GenericViewSet, ListModelMixin, DestroyModelMixin):
#     queryset = Collection.objects.all().filter(create_time__gte=datetime.now().date()).order_by('-create_time')
#     serializer_class = CollectionSerializer
#     def list(self, request, *args, **kwargs):
#         response = super().list(request, *args, **kwargs)
#         today_count = len(self.queryset)
#         print(today_count)
#         return Response({'code': 100, 'msg': '成功', 'result': response.data, 'today_count': today_count})

# 查询当前用户负责的网格-- 暂时拿全部
class AreaViewSet(GenericViewSet, ListModelMixin):
    queryset = Area.objects.all()
    serializer_class = AreaSerializer

新增接口完成

7.4.3 form.js

import api from '../../config/settings'
Page({

  /**
   * 页面的初始数据
   */
  data: {
    avatar: '/static/images/camera/camera.png',
    name: '',
    objectArray:[{
      id: 1,
      name: '1号楼2单元',
      desc: '1#2'
    },
    {
      id: 2,
      name: '2号楼2单元',
      desc: '2#2'
    }
  ],
  index: -1

  },
/**
   * 点击图片跳转到form页面
   */
  bindToCamera(){
    wx.navigateTo({
      url: '/pages/camera/camera',
    })
  },

      /**
   * 查询后台数据接口
   */
  refresh(){
    // 加载
    wx.showLoading({
      mask: true
    })
    wx.request({
      url: api.area,
      method: "GET",
      success: (res)=>{
        this.setData({
          objectArray:res.data
        })
      },
      complete: ()=>{
        wx.hideLoading()
      },
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.refresh()
  },
  /**
   * 选择网格
   */
  bindPickerChange(e){
    this.setData({
      index: e.detail.value
    })
  },
  /**
   * 提交数据,上传图片等
   */
  postUser(e){
    wx.showLoading({
      title: '提交中',
      mask: true
    })

    wx.uploadFile({
      filePath: this.data.avatar,
      name: 'avatar',
      url: 'api.collection',
      formData:{
        name:this.data.name,
        area:this.data.objectArray[this.data.index].id
      },
      success:()=>{
        // 跳转回上一页
        wx.navigateBack({})
      },
      complete: ()=>{
        wx.hideLoading()
      }
    })

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

7.4.4 collection.js 新增一个刷新查询

 onShow() {
    this.refresh()
  },

8、信息统计-采集统计页面实现

8.1 小程序端

8.1.1 app.json新增采集统计

  "pages": [
    "pages/welcome/welcome",
    "pages/index/index",
    "pages/my/my",
    "pages/activity/activity",
    "pages/notice/notice",
    "pages/collection/collection",
    "pages/face/face",
    "pages/voice/voice",
    "pages/heart/heart",
    "pages/goods/goods",
    "pages/camera/camera",
    "pages/form/form",
    "pages/statistics/statistics" 
  ],

8.1.2 statistics.wxml

<view class="container">

  <view class="menu" wx:for="{{dataList}}" wx:key="index">
    <view><label class="iconfont icon-rilitianchong"></label> {{item.date}}</view>
    <label>{{item.count}}个</label>
  </view>
</view>

8.1.3 statistics.wxss

.container{
  border-top: 1px solid #ddd;
}

.container .menu{
  font-size: small;
  padding: 10px 40rpx;
  border-bottom: 1px dotted #ddd;
  text-align: center;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  background-color: white;
}

8.1.4 更新iconfont.wxss

@font-face {
  font-family: "iconfont"; /* Project id 4696732 */
  src: 
       url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAPoAAsAAAAACIQAAAOaAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHFQGYACDBgqEUIN/ATYCJAMMCwgABCAFhGcHRBtpBxHVmwfJfiSmWwzyTfON5bbaKd4ED6gz/8mSU0U+AtpKMBGT03KuwLAS4/RhdgMEyEHfmrN6IHzUXFHWjjz6hzwV0sunA+HFLi5NU6qGkvEF8NTWKHhg8QAFqLRqXfy7Pb+Y/iK7M8iLugQBGCo0YDVr0bIjYSP7TRxNEoVVLSDNFiOHDemHFlWolmyBRuCDTlSIldhgLbHuAivCtxd/qEqDhS2xlmk7uPlALn5X349L13NBvsWvQoA7W4ANSKBkYxrRu93UFRmHSkhMnUiRZB8KgTWp1/MIWbrAZ//DAwsBwoeVGQJAAQlb8F25rFR8HHOumv2EEt+AyDPgo2iJQX0jn8pJjwgNNSY73JoyxbHMCIN7MHhYiJDwz5ngyaMo99gpJ7z2zAlhB46fHirctcYE1wc2OI5A7tp1DGrRCJn/wejaDUIE1gfXgrsuVGo2wz1rQoLnhR3eH4YOpRISbgTna4acBbP2oHso1lHupXsNijMXFo5zao8EDg/1GCO3WL8/uHctlnvIZMkbNqM2UtYdCsUGBLEtQ7vm3e16N6HbuLrhzdObh9edEpLSOt1gXPLrY8kjUo69Tv6T/PtYyojkY7+vjkIf8f+nz0Sc0R83fUSoDU1PR57W//kP6/lz9BkeOKJdfbhL3mldvtV/19/ZFUX5hpvmLFedjcbLUPHSxMiE/QmRiaOS9g61B9uJ9GXZlZ3eZ2d6WYlZXmb2h4fZKTkPh43MLt6VvT/xn5oGSaOGhTVNbXZ7XnhN2BSzQkfpFWZKWM26sGZZuz/gj8F0TAut6RKONdv7p4Q1oy8A3v/yhewO3hH5SXb6+7/D74pOf/uE1/tfOwqALynJFaHTO6KAp6GxQGD9a3FPIKLS3SBVHcstRwCScfzKfhZgMICHbFHeD7dEIzUItMjGYFGHZJBostAKXwQ2DlXgQ1MfDMWaT3eINhaJUH4gzzwEggiHwCKMUyCJcAOt8C/AJs4P8BGB/sPGq/1iW4fMkVEJWtA/iIZm50glrPeGfh0VV/lfyDliL7RVU4xecUYeY0h++07EgWOa4MK3w3EkWJgSGqmCyNLXtau7SmVoKo4YUgSygPYDIoPMnI8s+Y93g7zVSGEg+hViWcT1g1alAaCvohlUcSPNszevI4Sj3RxGJuCiG9BohwhY6tslyBCVMCCw6NUEyUFF1fKS6eXWAIZ1iswSUij2i2OUqGYTaPYbVeaQOte2KAAAAA==') format('woff2'),
       url('//at.alicdn.com/t/c/font_4696732_u0hsdlhku1.woff?t=1727425200183') format('woff'),
       url('//at.alicdn.com/t/c/font_4696732_u0hsdlhku1.ttf?t=1727425200183') format('truetype');
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-rilitianchong:before {
  content: "\e6ae";
}

.icon-a-shanchu1:before {
  content: "\e604";
}

8.2 后端接口

8.2.1 serializer新增StatisticsListSerializer

# -*- coding: utf-8 -*-
# @Time    : 2024/9/26 9:20
# @Author  : super
# @File    : serializer.py
# @Software: PyCharm
# @Describe:
from rest_framework import serializers
from .models import Banner, Notice, Collection,Area


class BannerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Banner
        fields = "__all__"


#  通知
class NoticeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Notice
        fields = "__all__"


## 采集--查询所有的序列化类
class CollectionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Collection
        fields = ['id', 'name', 'avatar', 'area']
        depth = 1 # area 外键关联详情拿到


## 采集--新增
class CollectionSaveSerializer(serializers.ModelSerializer):
    class Meta:
        model = Collection
        fields = ['name', 'avatar','area']

## 网格系列化列
class AreaSerializer(serializers.ModelSerializer):
    class Meta:
        model = Area
        fields = ['id', 'name', 'desc']
    def create(self, validated_data):
        instance = super().create(validated_data)
        return instance


# 统计信息
class StatisticsListSerializer(serializers.Serializer):
    date = serializers.DateTimeField(format='%Y-%m-%d')
    count = serializers.IntegerField()

8.2.2 views

from django.shortcuts import render

from django.http import JsonResponse
from rest_framework.viewsets import GenericViewSet
from .models import Welcome,Banner, Notice, Collection, Area
from .serializer import BannerSerializer, NoticeSerializer, CollectionSerializer ,AreaSerializer, CollectionSaveSerializer,StatisticsListSerializer
from rest_framework.response import Response
from datetime import datetime
from rest_framework.mixins import ListModelMixin,DestroyModelMixin,CreateModelMixin
from django.db.models.functions import Trunc
from django.db.models import Count
# Create your views here.


# 比较low 使用fbv实现
def welcome(request):
    # 查询order最大的一张图片
    result = Welcome.objects.all().order_by('-order').first()
    img = 'http://127.0.0.1:8000/media/'+str(result.img)
    return JsonResponse({'code': 100, 'msg': '成功', 'result': img})


class BannerViewSet(GenericViewSet, ListModelMixin):
    queryset = Banner.objects.filter(is_delete=False).order_by('-order')[:3]
    serializer_class = BannerSerializer

    # 重写list方法,将通知也整合进去
    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        # 获取最后一条通知
        notice = Notice.objects.filter(is_delete=False).order_by('-create_time').first()
        serializer = NoticeSerializer(instance=notice)
        return Response({'code': 100, 'msg': '成功', 'banner': response.data, 'notice': serializer.data})

# 信息采集接口  -- 查询登录用户当天采集的所有数据  ---因为还有登录实现 所以暂时先查询当天采集所有数据
class Collectionviewset(GenericViewSet, ListModelMixin, DestroyModelMixin, CreateModelMixin):
    serializer_class = CollectionSerializer

    def get_serializer_class(self):
        if self.action == 'create':
            return CollectionSaveSerializer
        else:
            return self.serializer_class

    def get_queryset(self):
        # 获取当前日期
        today = datetime.now().date()
        # 返回今天及之后创建的所有集合
        return Collection.objects.filter(create_time__gte=today).order_by('-create_time')

    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        today_count = queryset.count()
        print(today_count)
        return Response({'code': 100, 'msg': '成功', 'result': serializer.data, 'today_count': today_count})



# # 信息采集接口  -- 查询登录用户当天采集的所有数据  ---因为还有登录实现 所以暂时先查询当天采集所有数据
# class Collectionviewset(GenericViewSet, ListModelMixin, DestroyModelMixin):
#     queryset = Collection.objects.all().filter(create_time__gte=datetime.now().date()).order_by('-create_time')
#     serializer_class = CollectionSerializer
#     def list(self, request, *args, **kwargs):
#         response = super().list(request, *args, **kwargs)
#         today_count = len(self.queryset)
#         print(today_count)
#         return Response({'code': 100, 'msg': '成功', 'result': response.data, 'today_count': today_count})

# 查询当前用户负责的网格-- 暂时拿全部
class AreaViewSet(GenericViewSet, ListModelMixin):
    queryset = Area.objects.all()
    serializer_class = AreaSerializer


# 统计每天采集人数接口
class StatisticsViewSet(GenericViewSet, ListModelMixin):
    queryset = Collection.objects.annotate(date=Trunc("create_time","day")).values("date").\
        annotate(count=Count("id")).values("date", "count")
    serializer_class = StatisticsListSerializer

8.2.3 urls路由

from django.contrib import admin
from django.urls import path
from .views import welcome
from rest_framework.routers import SimpleRouter
from .views import BannerViewSet, Collectionviewset, AreaViewSet,StatisticsViewSet

router = SimpleRouter()
router.register('banner', BannerViewSet, 'banner')
router.register('collection', Collectionviewset, 'collection')
router.register('area', AreaViewSet, 'area')
router.register('statistics', StatisticsViewSet, 'statistics')
urlpatterns = [
    # http://127.0.0.1:8000/smart/welcome/   --> 就能获得突破数据
    path('welcome/', welcome),
]
urlpatterns += router.urls

8.3 采集统计联调

8.3.1 settings.js注册

const rootUrl='http://127.0.0.1:8000/smart/'
// 表示导出, 在任意js中可以导入 导入就是这个对象
module.exports={
  welcome:rootUrl + 'welcome/',
  banner:rootUrl + 'banner/',
  collection:rootUrl + 'collection/',  
  area:rootUrl + 'area/',
  statistics:rootUrl + 'statistics/',
}

8.3.2 collection.js添加点击跳转

import api from '../../config/settings'
Page({

  /**
   * 页面的初始数据
   */
  data: {
    dataDict:{
      result:[
        {
          "id": 1,
          "name": "张学友",
          "area": "#19",
          "avatar": "/static/images/collection/zxy.png"
        },
        {
          "id": 2,
          "name": "黎姿",
          "area": "#18",
          "avatar": "/static/images/collection/lz.png"
        }
      ],
      today_count: 66
    }

  },
    /**
   * 查询后台数据接口
   */
  refresh(){
    // 加载
    wx.showLoading({
      mask: true
    })
    wx.request({
      url: api.collection,
      method: "GET",
      success: (res)=>{
        if(res.data.code == 100){
          console.log(res)
          this.setData({
            dataDict: res.data
          })
        }else{
          wx.showToast({
            title: '网络加载失败',
          })
        }
      },
      complete: ()=>{
        wx.hideLoading()
      },
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    // 一进页面就调用这个函数
    this.refresh()
  },
    /**
   * 删除接口
   */
  
  doDeleteRow(e){
    wx.showModal({
      title: '确认是否删除',
      
      complete: (res) => {
        if (res.cancel) {     
          return     
        }    
        if (res.confirm) {
          //  真删除
          var nid = e.currentTarget.dataset.nid
          wx.showLoading({
            title: '删除中。。。',
            mask: true
          })
          wx.request({
            url: api.collection + nid + '/',
            method: "DELETE",
            success: (res)=>{
              // 删除完成或没有完成,都刷新页面
              this.refresh()

            },
            complete:()=>{
              wx.hideLoading()
            }
          })
        
        }
      }
    })
 
  },
    /**
   * 跳转到信息采集列表
   */
  bindToForm(){
    wx.navigateTo({
      url: '/pages/form/form',
    })
  },

    /**
   * 信息统计
   */
  bindToStatistics(){
    wx.navigateTo({
      url: '/pages/statistics/statistics',
    })
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
    this.refresh()
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
    // 下拉重新加载
    this.refresh()
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

8.3.3 statistics.js

import api from '../../config/settings'
Page({

  /**
   * 页面的初始数据
   */
  data: {
    dataList: [{
      "date": "2023-09-26",
      "count": 1
  },
  {
      "date": "2023-09-27",
      "count": 3
  }]
  },

    /**
   * 查询数据
   */
  getRecord(){
    wx.showLoading({
      title: '加载中',
      mask: true
    })
    wx.request({
      url: api.statistics,
      method:"GET",
      success:(res)=>{
          this.setData({
            dataList: res.data
          })
      },
      complete:()=>{
        wx.hideLoading()
      }
    })
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.getRecord()
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

9、 人脸识别

9.1 人脸识别

9.1.1 使用步骤

后端代码根目录新增文件夹script

9.1.2 上传-删除-匹配人脸

10、个人中心

10.1 个人中心静态页面

10.1.1 my.json

{
  "usingComponents": {},
  "navigationBarTitleText": "个人中心"
}

10.1.2 my.wxss

page{
  height: 100%;
}

.login-area{
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.login-area .btn{
  width: 200rpx;
  height: 200rpx;
  border-radius: 500%;
  background-color: #5cb85c;
  color: white;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
}
.user-area{
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.user-area image{
  width: 200rpx;
  height: 200rpx;
  border-radius: 500%;

}
.user-area .name{
  font-size: 30rpx;
  padding: 30rpx 0;
}
.user-area .logout{
  color: #a94442;
}


.top-view{
  background-color: #01ccb6;
  color: white;
  padding: 40rpx;
}

.top-view .user{
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
}

.top-view .user .row{
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
}

.top-view .user .avatar{
  width: 100rpx;
  height: 100rpx;
  border-radius: 50%;
}

.top-view .user .name{
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  padding-left: 20rpx;
}

.top-view .user .name navigator{
  padding: 0 5rpx;
}

.top-view .site{
  background-color: rgba(0, 0, 0, 0.16);
  padding: 20rpx;
  border-top-left-radius: 32rpx;
  border-bottom-left-radius: 32rpx;
}


.top-view .numbers{
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  font-size: 28rpx;
  padding: 40rpx;
  padding-bottom: 0rpx;
}


.top-view .numbers .row{
  display: flex;
  flex-direction: column;
  align-items: center;
}

10.1.3 my.wxml

<!--pages/my/my.wxml-->

<block wx:if="{{userInfo==null}}">
  <navigator class="login-area" url="/pages/login/login">
    <view class="btn">一键登录</view>
  </navigator>  
</block>
<block wx:else>
 <view class="container">
  <view class="top-view">
    <!--绿色区域=====用户部分-->
    <view class="user">
      <view class="row">
        <image class="avatar" src="{{userInfo.avatar}}"></image>
        <view class="name">
          <view bindtap="logout">{{userInfo.name}}</view>
        </view>      
      </view>      
    </view>
    <!--绿色区域======数字部分-->
    <view class="numbers">
      <view class="row">
        <text>{{userInfo.score}}</text>
        <text>积分</text>
      </view>
      <view class="row">
        <text>55</text>
        <text>其他</text>
      </view>
      <view class="row">
        <text>77</text>
        <text>其他</text>
      </view>
      <view class="row">
        <text>56</text>
        <text>其他</text>
      </view>    
    </view>  
  </view>
  <van-list>
      <van-cell title="积分兑换记录" is-link />
      <van-cell title="我参加的活动" is-link />
      <van-cell title="分享应用" is-link />
      <van-cell title="联系客服" is-link />

    </van-list>
 
 
 </view>
  
</block>

10.1.4 my.wxjs

// pages/my/my.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    userInfo:{
      avatar: '/static/images/tx.png',
      name: '卢卡斯',
      score: 100
    },
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})
相关推荐
一 乐30 分钟前
畅阅读小程序|畅阅读系统|基于java的畅阅读系统小程序设计与实现(源码+数据库+文档)
java·小程序·vue·源码·springboot·阅读小程序
weixin_422201302 小时前
PC端微信小程序如何调试?
微信小程序·编译·调试·微信小程序开发工具·pc端
_斯洛伐克3 小时前
关于vue2+uniapp+uview+vuex 私募基金项目小程序总结
前端·小程序·uni-app
计算机学姐3 小时前
基于微信小程序的旧衣回收系统
java·vue.js·spring boot·微信小程序·小程序·tomcat·mybatis
wang_book3 小时前
uniapp学习(002 常用的内置组件)
前端·学习·微信小程序·小程序·uni-app·node.js·vue
一 乐3 小时前
助农小程序|助农扶贫系统|基于java的助农扶贫系统小程序设计与实现(源码+数据库+文档)
java·数据库·小程序·vue·源码·助农
程序员阿龙3 小时前
个人健康管理小程序(源码+参考文档+定制)
微信小程序·小程序·健康数据管理·个人健康管理·健康监测·移动医疗·健康管理平台
汇匠源3 小时前
零工市场小程序如何提高找兼职的效率?
java·大数据·开发语言·小程序·团队开发
说私域3 小时前
开源 AI 智能名片 O2O 商城小程序与抖音:品牌传播的新机遇与挑战
大数据·人工智能·小程序
星光一影3 小时前
废品回收小程序/环保垃圾回收/收二手垃圾小程序/分类资源回收系统/独立版系统源码
小程序·废品回收小程序·生活服务