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

news2025/1/11 5:38:02

目录

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个页面

2.1.9 app.json添加底部导航

 2.1.10 app.json设置窗口栏

2.1.11 删除app.wxss全部内容

2.1.12 不校验http

2.2 创建小程序后端项目

2.2.1 创建项目

 2.2.2 安装配置mysql数据库

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

2.2.4 运行后端

2.2.5 后期涉及需要安装的库

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

3.1 node介绍

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

4、欢迎页面

4.1 纯静态

4.1.1 welcome. wxml

4.1.2 welcome.wxss

4.1.3 welcome.js

4.2 后端加载欢迎页

4.2.1 创建表模型

4.2.2 开启media访问

 4.2.3 使用admin上传图片

4.2.3.1 配置

 4.2.3.2 上传图片

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

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

4.3.1 welcome. wxml

4.3.2 welcome. wxss

5、 首页

5.1 首页静态页面

5.1.1 index.wxml

5.1.2 index.wxss

5.1.3 app.json

5.2 首页菜单跳转

5.2.1 app.json创建菜单新页面

5.2.2 index.wxjs设置跳转

5.3 首页轮播图和公告接口

5.3.1 models

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

5.3.3 admin录入数据

5.3.4 轮播图接口

5.3.4.1 smart应用下新建serializer

5.3.4.2 views.py实现BannerViewSet

5.3.4.3 分发路由urls.py

5.3.4.4 settings项目当中注册rest_framework

5.3.4.5 启动服务验证

5.3.4.6 整合通知到一个接口

5.3.4.6.1 serializer.py

5.3.4.6.2 views.py

5.3.4.6.3 查看接口返回数据

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

5.4.1 index.wxjs

 5.4.2 index.wxml

5.5 接口全局IP设置

5.5.1 新建全局settings.js

5.5.3 welcome.js引入应用

5.5.3 index.js引入应用

6、信息采集

6.1 信息采集静态页面 

6.1.1 collection.json

6.1.2 collection.wxml

6.1.3 collection.wxjs

6.1.4 collection.wxss

6.2 信息采集后端接口

6.2.1 新建model.py创建表

6.2.2 录入数据

6.2.3 serializer.py

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

6.2.5 分发路由

6.2.6 验证

 6.3 引入矢量图标库

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

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

6.4.2 完成collection.wxjs

6.4.3 实现删除功能

6.4.3.1 views实现删除

6.4.3.2 collection.js实现删除

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

7、信息采集详情页

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

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

7.1.2 camera.wxml

7.1.3 camera.wxss

7.1.4 camera.js

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

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

7.2.2 form.wxml

7.2.3 form.wxss

7.2.3 form.js

7.3 后端接口

7.3.1 Serializer新增AreaSerializer

7.3.2 views新增AreaViewSet

7.3.3 urls配置

7.4 小程序实现form.js

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

7.4.2 后端处理接口

7.4.2.1 serializer新增CollectionSaveSerializer

7.4.2.2 views修改Collectionviewset

 7.4.3 form.js

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

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

8.1 小程序端

8.1.1 app.json新增采集统计

8.1.2 statistics.wxml

8.1.3 statistics.wxss

8.1.4 更新iconfont.wxss

8.2 后端接口

8.2.1 serializer新增StatisticsListSerializer

8.2.2 views

8.2.3 urls路由

8.3 采集统计联调

8.3.1 settings.js注册

8.3.2 collection.js添加点击跳转

9、 人脸识别

9.1 人脸识别

9.1.1 使用步骤

9.1.2 上传-删除-匹配人脸

10、个人中心

10.1 个人中心静态页面

10.1.1 my.json

10.1.2 my.wxss

10.1.3 my.wxml

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() {

  }
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2179333.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【拥抱AIGC】通义灵码网络代理配置

在公司网络环境下&#xff0c;无法访问公共网络时&#xff0c;可在插件端配置网络代理后使用通义灵码。 配置网络代理 公司网络通常使用 HTTP 代理服务器在网络流量发送到目标位置之前进行拦截&#xff0c;以便检测可疑流量或者限制进入公司内网络的内容。如果你使用的公司网…

【Python报错已解决】 NameError: name ‘scio‘ is not defined

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

Star 3w+,向更安全、更泛化、更云原生的 Nacos3.0 演进

作者&#xff1a;席翁 Nacos 社区刚刚迎来了 Star 突破 30000 的里程碑&#xff0c;从此迈上了一个新的阶段。感谢大家的一路支持、信任和帮助&#xff01; Nacos /nɑ:kəʊs/是 Dynamic Naming and Configuration Service 的首字母简称&#xff0c;定位于一个更易于构建云原…

c++就业磁盘链式b树与b+树

linux上/a.out启动一个进程 最上面是内核 在heap里 一个节点只想左子树 另一个节点指向右子树 找到根节点 对比找 磁盘寻址过程 对比次数多了之后 找下一个节点次数变多 磁盘面-道-区 一个节点4k 不断在磁盘上寻址 开叉 中间存储数据 b树 所有的叶子节点在同一层 b树 所有节点…

Llama 3.1 技术研究报告-7

7.6 图像识别结果 我们评估了 Llama 3 在⼀系列任务上的图像理解能⼒&#xff0c;这些任务涵盖了⾃然图像理解、⽂本理解、图表理解和多模态推理&#xff1a; MMMU (Yue 等⼈&#xff0c;2024a) 是⼀个具有挑战性的数据集&#xff0c;⽤于多模态推理&#xff0c;模型需要理解…

tesseract:一个.Net版本的开源OCR项目

推荐一个.Net版本的开源OCR项目&#xff0c;方便我们在项目中集成OCR功能。 01 项目简介 tesseract是针对Tesseract-OCR&#xff08;C&#xff09;引擎封装的.NET版本&#xff0c;支持超过100种语言的文本识别&#xff0c;使得.NET开发者能够轻松地利用Tesseract的强大功能&a…

LLM基础概念-训练集

数据集 训练集(Training Set) 用来训练模型的数据。就像给学生提供教材一样&#xff0c;训练集帮助模型学习如何从输入数据预测出正确的结果。 验证集(Validation Set) 这个数据集用来检查模型在训练过程中的表现。它帮助我们调整模型训练参数的设置&#xff0c;以确保模型不…

《基于 Spring Boot 的健身房管理系统功能介绍》

一、系统概述 本健身房管理系统基于 Spring Boot 框架开发&#xff0c;旨在为健身房提供一套高效、便捷的管理解决方案。系统涵盖了会员卡查询、会员管理、员工管理、器材管理和课程管理等核心功能&#xff0c;帮助健身房实现全面的数字化管理。 二、会员卡查询 用户可以通过输…

影响 Linux、Unix 系统的 CUPS 漏洞可导致 RCE

在经过大量炒作和第三方过早泄露信息之后&#xff0c;安全研究员 Simone Margaritelli 公布了有关通用 UNIX 打印系统 (CUPS) 中的四个零日漏洞的详细信息。 这些漏洞可被远程、未经身份验证的攻击者滥用&#xff0c;在易受攻击的 Linux 和类 Unix 系统上实现代码执行。 CUPS…

【多线程】多线程(2):Thread方法,线程核心操作

【Thread类其他的属性和方法】 给线程命名的方法&#xff0c;不起名字则默认叫做Thread-0&#xff0c;Thread-1…… 【线程的属性】 ID&#xff0c;名称&#xff0c;状态&#xff0c;优先级&#xff1a;JVM自动分配&#xff0c;不能手动设置 状态&#xff1a;java中把线程的…

速通数据结构与算法第六站 树堆

系列文章目录 速通数据结构与算法系列 1 速通数据结构与算法第一站 复杂度 http://t.csdnimg.cn/sxEGF 2 速通数据结构与算法第二站 顺序表 http://t.csdnimg.cn/WVyDb 3 速通数据结构与算法第三站 单链表 http://t.csdnimg.cn/cDpcC 4 速通…

长期提供APX515/B原装二手APX525/B音频分析仪

Audio Precision APx515 是一款针对生产测试而优化的高性能音频分析仪。它因其速度、性能、自动化和易用性而成为一流的仪器。它具有卓越的性能&#xff0c;具有 –106 dB 的典型 THDN、1M 点 FFT 和 192k 数字 I/O&#xff0c;以及所有 APx 系列音频分析仪的一键式自动化和易用…

Flask-1

文章目录 Flask准备创建flask项目flask加载项目配置的二种方式 路由的基本定义接收任意路由参数接收限定类型参数自定义路由参数转换器 终端运行Flask项目http的请求与响应flask的生命周期请求获取请求中各项数据获取请求URL参数获取请求体获取请求头相关信息 响应响应html文本…

通信工程学习:什么是LAN局域网、MAN城域网、WAN广域网

LAN局域网、MAN城域网、WAN广域网 LAN&#xff08;Local Area Network&#xff0c;局域网&#xff09;、MAN&#xff08;Metropolitan Area Network&#xff0c;城域网&#xff09;和WAN&#xff08;Wide Area Network&#xff0c;广域网&#xff09;是计算机网络中根据覆盖范围…

Hive数仓操作(五)

一、Hive 信息查看 Hive的元数据管理&#xff1a; Hive 将表的元数据&#xff08;如表名、列名、类型等&#xff09;存储在关系型数据库中&#xff0c;通常是 MySQL。元数据的主要表包括&#xff1a; TBLS&#xff1a;存储表的信息&#xff08;表名、类型、ID 等&#xff09;。…

VMware NSX Advanced Load Balancer (NSX ALB) 22.1.7 发布下载,新增功能概览

VMware NSX Advanced Load Balancer (NSX ALB) 22.1.7 - 多云负载均衡平台 应用交付&#xff1a;多云负载均衡、Web 应用防火墙和容器 Ingress 服务 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-nsx-alb-22/&#xff0c;查看最新版。原创作品&#xff0c;转载请…

一、Spring Boot集成Spring Security之自动装配

Spring Boot集成Spring Security之自动装配介绍 一、实现功能及软件版本说明二、创建Spring Boot项目三、查看自动装配配置类四、自动装配配置类之SecurityAutoConfiguration1、SecurityAutoConfiguration部分源码2、主要作用3、SpringBootWebSecurityConfiguration3.1、Spring…

D - Hidden Weights

题目链接: D - Hidden Weights (atcoder.jp) 题目描述: 数据范围限制: 样例: 输入: 3 3 1 2 2 3 2 3 1 3 -1 输出: 3 5 2 样例图&#xff1a; 思路&#xff1a; 第一次想的是从没有入节点的点去出发&#xff0c;然后去依次去更新&#xff0c;但是发现这个是错误的。 用dfs…

GPG error golang 1.19

1. 问题描述及原因分析 在飞腾2000的服务器&#xff0c;OS为Kylin Linux Advanced Server release V10环境下&#xff0c;docker版本为18.09.0&#xff08;docker-engine-18.09.0-101.ky10.aarch64&#xff09;&#xff0c;基于容器镜像golang:1.19编译新的容器镜像&#xff0…

图解C#高级教程(二):事件

在现实生活当中&#xff0c;有一些事情发生时&#xff0c;会连带另一些事情的发生。例如&#xff0c;当某国的总统发生换届时&#xff0c;不同党派会表现出不同的行为。两者构成了“因果”关系&#xff0c;因为发生了A&#xff0c;所以发生了B。在编程语言当中&#xff0c;具有…