当前位置: 首页 > article >正文

running小程序重要技术流程文档

一、项目文件说明:

(注:getMyMoney无用已删除)
在这里插入图片描述

二、重要文件介绍

1.reinfo.js:位于utils文件下,该文件封装有统一的请求URL,和请求API同意封装供页面调用;调用时候需要在页面上先引入该文件,如下(index/index.js为例):

//先引入
import API from "../../utils/reinfo.js";

// 后使用的时候如下
wx.request({
  url: API.getSysConfig,//这里的API就是上面引入时候的名字,getSysConfig就是我们reinfo.js文件里封装的
  method:"get",
  success: function (res) {
  	// 调用接口成功后执行的
  }
})

2.app.js:这个是小程序的启动文件,每次小程序启动的话,必定会执行这个文件里的方法。

//onLaunch 小程序生命周期,启动就会执行
onLaunch: function () {
  var that=this;
  // 展示本地存储能力
  var openId = wx.getStorageSync('openId') || null
  // 获取用户openid、使用 Promise 
  // 这里的获取用户openid使用Promise 因为需要让index.js可以调用他来获取openid,因为index作为第一个小程序页面,也具有优先执行权,有时候会在app.js执行之前先执行,有时候会在app.js执行之后执行,所以这里使用Promise做一个异步请求,来供index.js页面调用回调获取用户数据
  const getUserOpenId = new Promise((resolve, reject) => {
    if(openId){
      console.log('缓存openid',openId)
      resolve(openId); // resolve Promise
    }else{
      // 登录code获取openid
      wx.login({
        success: function (res) {
          var code = res.code;//发送给服务器的code
            if (code) {
              wx.request({
                url: API.getSessinOpenid,
                method:"post",
                data: {
                  code: code,
                },
                header: {
                  'content-tpe': 'application/json'
                },
                success: function (res) {
                  console.log('获取到的用户openid为:',res)
                  //可以把openid保存到本地缓存,方便以后调用
                  wx.setStorageSync('openId', res.data.data);
                  // that.getUserInfoFun(res.data.data)
                  resolve(res.data.data); // resolve Promise
                },
                fail:function(res){
                  reject(err); // reject Promise
                  console.log(res)
                }
              })
            }
            else {
              console.log("获取用户登录态失败!");
            }
        },
        fail: function (error) {
        }
      })
    }
  });
   // 将 Promise 对象存储到全局数据对象中
   this.globalData.getUserOpenId = getUserOpenId;

  //  获取用户信息
  //这个获取用户信息同上意思
  const getUserInfo = new Promise((resolve, reject) => {
    wx.request({
      url: API.getUserInfo,
      method:"post",
      data: {
        openId: wx.getStorageSync('openId') || null,
      },
      success: function (res) {
        console.log('openid获取用户信息:',res)
        wx.setStorageSync('userInfo', res.data.data);
        resolve(res.data.data); // resolve Promise
      }
    })
  })
  // 将 Promise 对象存储到全局数据对象中
  this.globalData.getUserInfo = getUserInfo;
  
},

这个页面底部有个changeTabBar方法这个是自定义底部导航组件用来切换页面的公共方法
小程序组件的使用方法如下:
1.封装组件如comment\tabbar\tabbar.wxml这里就是封装了一个底部导航组件:
在这里插入图片描述
其他需要使用的页面进行引入(index/index):
wxml:


<import src="../../comment/tabbar/tabbar.wxml" />
<template is="tabbar" data="{{tabbar}}"/>

js:

//获取应用实例
const app = getApp();
Page({
/**
   * 页面的初始数据
   */
  data: {
    //底部导航栏
    tabbar: {},
  },
  //在onshow或者onload调用app下的changeTabBar方法来进行点击切换页面
  onload(){
    //调用app中的函数
    app.changeTabBar(); 
 } 
})

3.postOrder:发布订单是一个大麻烦:这里需要使用一个点击切换和滑动切换(同用户订单列表页和跑腿订单列表页)。
wxml:

<view class="navbar">
  <text wx:for="{{navbar}}" data-idx="{{index}}" class="item {{currentTab==index ? 'active' : ''}}" wx:key="unique" bindtap="navbarTap">{{item}}</text>
</view>

js:

/**
 * 页面的初始数据
 */
data: {
  navbar: ['帮我买', '帮我送', '帮我取'],
  currentTab: 0,
}


  //电机头部切换bar
  navbarTap: function (e) {
    console.log( e.currentTarget.dataset.idx)
    let initPrice = app.globalData.sysConfig.minDeliveryPrice
    // 切换的时候需要将数据清空,让用户重新输入
    let postData = {
      "commodity": "",
      "commodityCost": 0,
      "commodityWeight": 1,
      "deliveryAddress": "",
      "deliveryConcat": "",
      "deliveryPhone": "",
      "deliveryTime": "",
      "openId": "",
      "orderType": e.currentTarget.dataset.idx*1,
      "pickUpAddress": "",
      "pickUpContact": "",
      "pickUpPhone": "",
      "pickUpTime": "",
      "remark": "",
      "tipCost": 0,
      "totalCost": 0
    }
    // 设置取货时间、配送时间
    postData.deliveryTime = this.calculateFutureTime()
    if(postData.orderType == 1||postData.orderType == 2){
      postData.pickUpTime = this.calculateFutureTime()
    }
    var userInfo = wx.getStorageSync('userInfo') || {}
    postData.deliveryPhone = userInfo.phone
    // postData.orderType = e.currentTarget.dataset.idx
    this.setData({
      currentTab: e.currentTarget.dataset.idx,
      postData,
      
      multiIndex1: [0, 0], // 默认选择当天和第一个时间段
      multiIndex2: [0, 0], // 默认选择当天和第一个时间段
      multiIndex3: [0, 0], // 默认选择当天和第一个时间段
      multiIndex4: [0, 0], // 默认选择当天和第一个时间段

      price: initPrice
    })
    //全局变量
    app.globalData.currentTab = e.currentTarget.dataset.idx;
  },
  // 轮播切换,即左右滑动切换
  swiperChange: function (e) {
    let initPrice = app.globalData.sysConfig.minDeliveryPrice
    // 切换类型的话清空
    let postData = {
      "commodity": "",
      "commodityCost": 0,
      "commodityWeight": 1,
      "deliveryAddress": "",
      "deliveryConcat": "",
      "deliveryPhone": "",
      "deliveryTime": "",
      "openId": "",
      "orderType": e.detail.current*1,
      "pickUpAddress": "",
      "pickUpContact": "",
      "pickUpPhone": "",
      "pickUpTime": "",
      "remark": "",
      "tipCost": 0,
      "totalCost": 0
    }
    // 设置取货时间、配送时间
    postData.deliveryTime = this.calculateFutureTime()
    if(postData.orderType == 1||postData.orderType == 2){
      postData.pickUpTime = this.calculateFutureTime()
    }
    var userInfo = wx.getStorageSync('userInfo') || {}
    postData.deliveryPhone = userInfo.phone
    this.setData({
      currentTab: e.detail.current,
      postData,
      
      multiIndex1: [0, 0], // 默认选择当天和第一个时间段
      multiIndex2: [0, 0], // 默认选择当天和第一个时间段
      multiIndex3: [0, 0], // 默认选择当天和第一个时间段
      multiIndex4: [0, 0], // 默认选择当天和第一个时间段
      price: initPrice
    })
    //全局变量
    app.globalData.postOrderCurrentTab = e.detail.current;
  },

来实现顶部以及点击切换:在这里插入图片描述
配送时间的选择,进行一个立即配送和之后的每隔30分钟可供选择,有当天和次日,
在这里插入图片描述
wxml:

<view class="v1-item">
  <view>预计送达时间</view>
  <picker mode="multiSelector" bindcolumnchange="bindMultiPickerColumnChange" range="{{[dateRange, timeRange]}}" value="{{multiIndex1}}" data-id="1" bindchange="bindMultiPickerChange">
    <view class="picker">
      {{dateRange[multiIndex1[0]]}} {{timeRange[multiIndex1[1]]}}
    </view>
  </picker>
</view>

js:

data:{
    dateRange: ['今天', '明天'],
    timeRange: [], // 存储时间段的数组
    multiIndex1: [0, 0], // 默认选择当天和第一个时间段  帮我买:预计送达时间
    multiIndex2: [0, 0], // 默认选择当天和第一个时间段  帮我送:预计取货时间
    multiIndex3: [0, 0], // 默认选择当天和第一个时间段  帮我送:预计送达时间
    multiIndex4: [0, 0], // 默认选择当天和第一个时间段  帮我取:预计送达时间
}

  // 配送时间选择列表发生改变时候监听
  bindMultiPickerColumnChange(e){
    console.log('修改的列为', e.detail.column, ',值为', e.detail.value,e);
    if(e.detail.column == 0 && e.detail.value == 1){
      var startOfDay = new Date();
      startOfDay.setHours(0, 0, 0, 0);
      dayType = 1
      this.generateTimeRange(startOfDay)
    }
    else if(e.detail.column == 0 && e.detail.value == 0){
      dayType = 0
      this.generateTimeRange(new Date())
    }
  },
  // 计算时间选择列表
  generateTimeRange: function(now) {
    // var now = new Date();
    var hours = now.getHours();
    var minutes = now.getMinutes();
    var timeRange = [];
    
    // 生成时间段,每半个小时为一个时间段,共24小时
    for (var i = 0; i < 48; i++) {
      var hour = Math.floor(i / 2);
      var minute = (i % 2) * 30;
      
      // 格式化时间,补零操作
      var hourStr = hour < 10 ? '0' + hour : '' + hour;
      var minuteStr = minute === 0 ? '00' : '' + minute;
      
      if (hour > hours || (hour == hours && minute >= minutes)) {
        timeRange.push(hourStr + ':' + minuteStr);
      }
    }
    if(dayType == 0){
      timeRange[0] = '立即配送'
    }
    
    this.setData({
      timeRange: timeRange
    });
  },
  // 根据当前时间自动计算30分钟后的时间,并在遇到23:40时能正确计算到次日
  calculateFutureTime() {
    var currentDate = new Date();
    var futureDate = new Date(currentDate.getTime() + 30 * 60000); // 加上30分钟的毫秒数
  
    // 如果超过了当天的23:59:59,就设置到次日的00:30
    if (futureDate.getDate() > currentDate.getDate()) {
      futureDate = new Date(futureDate.getFullYear(), futureDate.getMonth(), futureDate.getDate(), 0, 30, 0);
      
      var originalDate = new Date(futureDate);
      var hour = originalDate.getHours()<10?'0'+originalDate.getHours():originalDate.getHours();
      // var minute = originalDate.getMinutes();
      var minute = originalDate.getMinutes()<10?'0'+originalDate.getMinutes():originalDate.getMinutes();
      var formattedTime = hour + ':' + minute;
      // var formattedTime = hour<10?0+hour:hour + ':' + minute;
      console.log("当前时间0000:" , currentDate);
      console.log("30分钟后的时间000:" , futureDate,formattedTime);
      return '次日 '+formattedTime;
    }
    var originalDate = new Date(futureDate);
    var hour = originalDate.getHours()<10?'0'+originalDate.getHours():originalDate.getHours();
    var minute = originalDate.getMinutes()<10?'0'+originalDate.getMinutes():originalDate.getMinutes();
    // var minute = originalDate.getMinutes();
    var formattedTime = hour + ':' + minute;
    // var formattedTime = hour<10?0+hour:hour + ':' + minute;

    console.log("当前时间111:" , currentDate);
    console.log("30分钟后的时间1111:" , futureDate,formattedTime);
    return '今天 '+formattedTime;
  },
  // 选择
  bindMultiPickerChange: function(e) {
    console.log('选择',e)
    let postData = this.data.postData
    let type = e.currentTarget.dataset.id
    console.log('这样可以吗?',this.data['multiIndex'+type])
    // 如果是立即配送自动匹配现在的30分钟后
    if(this.data.timeRange[e.detail.value[1]] == '立即配送'){
      postData.deliveryTime = this.calculateFutureTime()
    }
    if(type == 1){
      postData.deliveryTime = this.data.dateRange[this.data['multiIndex'+type][0]] +' '+ this.data.timeRange[this.data['multiIndex'+type][1]]
    }
    if(type == 2){
      postData.pickUpTime = this.data.dateRange[this.data['multiIndex'+type][0]] +' '+ this.data.timeRange[this.data['multiIndex'+type][1]]
    }
    if(type == 3){
      postData.deliveryTime = this.data.dateRange[this.data['multiIndex'+type][0]] +' '+ this.data.timeRange[this.data['multiIndex'+type][1]]
    }
    if(type == 4){
      postData.deliveryTime = this.data.dateRange[this.data['multiIndex'+type][0]] +' '+ this.data.timeRange[this.data['multiIndex'+type][1]]
    }
    
    this.setData({
      ['multiIndex'+type]: e.detail.value,
      postData,
    });
    console.log('结果》》》?',this.data['multiIndex'+type])
  },

图片上传列表
wxml:

<view class="v1">
     <!-- 图片列表 -->
     <view class="image-list">
       <block wx:for="{{images}}" wx:key="index">
         <view class="image-item">
           <image src="{{item}}" mode="aspectFill" data-src="{{item}}" bindtap="previewImage"></image>
           <view class="delete-btn" bindtap="deleteImage" data-index="{{index}}">×</view>
         </view>
       </block>
       <!-- 添加图片按钮 -->
       <view class="add-image" bindtap="chooseImage">
         <text>+</text>
       </view>
     </view>
   </view>

js:

data:{
    images: [], // 存储已选择的图片列表
}

 // 选择图片
  chooseImage() {
    let that = this;
    wx.chooseImage({
      count: 1,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success: (res) => {
        console.log('选择图片',res)
        wx.uploadFile({
          url: API.uploadImg,
          filePath: res.tempFilePaths[0],
          name: 'file',
          header: {
            "Content-Type": "multipart/form-data"
          },
          formData: {
            'type': 4 //1-表示头像,2-表示身份证,4-订单图片
          },
          success (resFile){
            let fileData = JSON.parse(resFile.data)
            console.log("文件上传接口",JSON.parse(resFile.data))
            if(fileData.code == 0){
              // 上传成功时候插入原有的数据中
              const newImages = that.data.images.concat(fileData.data);
              that.setData({
                images: newImages,
              });
            }else{
              wx.showToast({
                title: fileData.msg,
                icon: 'error'
              })
            }
          }
        })
        
      },
    });
  },

  // 预览图片
  previewImage(e) {
    const current = e.target.dataset.src;
    wx.previewImage({
      current: current,
      urls: this.data.images,
    });
  },

  // 删除图片
  deleteImage(e) {
    const index = e.target.dataset.index;
    const newImages = this.data.images;
    // 删除指定位置index的图片
    newImages.splice(index, 1);
    this.setData({
      images: newImages,
    });
  },

4.index:抢单大厅样式

//<!-- class使用三元运算符,动态设置class名称,用遍历数据,判断奇偶数来实现左右不同样式 -->
<view class="{{index%2 == 0?'v2-body-v1':'v2-body-v2'}}" wx:for="{{orderHallList}}"  bindtap="gotoOrderDetail" data-paymentStatus="{{item.paymentStatus}}" data-orderStatus="{{item.orderStatus}}" data-id="{{item.id}}" data-type="orderHall">
  <view class="{{index%2 == 0?'v2-body-v1-price':'v2-body-v2-price'}}">{{item.totalCost}}</view>
  <view class="{{index%2 == 0?'v2-body-v1-text':'v2-body-v2-text'}}">
    <image src="{{index%2 == 0?'/images/zuo.png':'/images/you.png'}}"></image>
    <text>{{item.orderType == 'BUY'?'帮我买':item.orderType == 'SEND'?'帮我送':item.orderType == 'TAKE'?'帮我取':''}}</text>
  </view>
  <view class="{{index%2 == 0?'v2-body-v1-img':'v2-body-v2-img'}}">
    <view>{{item.deliveryAddress}}</view>
    <view>{{item.deliveryTime}}</view>
  </view>
</view>

5.订单完成的评价打分
wxml:

<view class="v1-item">
  // <!-- 星星打分实现 -->
    <view style="width: 100%;line-height: 60rpx;">
      <view style="width: unset;margin-left: unset;" class='starLen' bindtap="myStarChoose">
        <block wx:for="{{starMap}}">
          <image wx:if="{{star>=index+1}}" class='star' data-star="{{index+1}}" src="../../images/start-2.png" /> 
          <image wx:if="{{star<index+1}}" class='star' data-star="{{index+1}}" src="../../images/start-1.png" />    
        </block>
      </view>
      <view class="scoreContent" style="width: unset;margin-left: unset;">{{starMap[star-1]}}</view>
    </view>
  </view>

js:

/**
   * 页面的初始数据
   */
  data: {
    star: 0,  //默认0分
    starMap: [
      '非常差',
      '差',
      '一般',
      '好',
      '非常好',
    ],
  },
  
  // 选星
  myStarChoose(e) {
    let star = parseInt(e.target.dataset.star) || 0;
    // 获取打的分
    this.setData({
      star: star,
    });
  },

这里列举这几个比较难的流程,如果后面对哪些模块的流程有不明白的可以再提出来


http://www.kler.cn/a/163117.html

相关文章:

  • 第8章利用CSS制作导航菜单
  • 数学建模模型算法-Python实现
  • 记录日志中logback和log4j2不能共存的问题
  • 【Linux】基础IO及文件描述符相关内容详细梳理
  • Lodash的常用方法整理
  • aws xray通过设置采样规则对请求进行过滤
  • 【ELK03】ES 索引的Mapping映射详解、数据类型和settings属性设置
  • 算法:常见的链表算法
  • 插入排序——直接插入排序和希尔排序(C语言实现)
  • 如何进行更好的面试回复之缓存函数在项目中的性能优化?
  • Advanced Renamer
  • 利用R语言heatmap.2函数进行聚类并画热图
  • Shell脚本如何使用 for 循环、while 循环、break 跳出循环和 continue 结束本次循环
  • Vue学习笔记-Vue3中的计算属性与监视属性
  • 【数据结构】拆分详解 - 二叉树的链式存储结构
  • 消费升级:无人零售的崛起与优势
  • 【MATLAB源码-第97期】基于matlab的能量谷优化算法(EVO)机器人栅格路径规划,输出做短路径图和适应度曲线。
  • git操作:使用vscode集成
  • Spring Cloud Gateway中对admin端点进行认证
  • 自动补全的 select antd react
  • php+mysql期末作业小项目
  • kafka学习笔记--安装部署、简单操作
  • luceda ipkiss教程 43:画渐变圆弧型波导
  • ModuleNotFoundError: No module named ‘dlib‘
  • C_15练习题
  • Qt与Sqlite3