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获取openidwx.login({success: function (res) {var code = res.code;//发送给服务器的codeif (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 Promiseconsole.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,
}//电机头部切换barnavbarTap: 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.idxthis.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.phonethis.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 = 1this.generateTimeRange(startOfDay)}else if(e.detail.column == 0 && e.detail.value == 0){dayType = 0this.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:30if (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.postDatalet type = e.currentTarget.dataset.idconsole.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.rhkb.cn/news/214824.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

unittest与pytest的区别

Unittest vs Pytest 主要从用例编写规则、用例的前置和后置、参数化、断言、用例执行、失败重运行和报告这几个方面比较unittest和pytest的区别: 用例编写规则 用例前置与后置条件 断言 测试报告 失败重跑机制 参数化 用例分类执行 如果不好看&#xff0c;可以看下面表格&…

算能 MilkV Duo开发板实战——opencv-mobile (迷你版opencv库)的移植和应用

前言 OpenCV是一种开源的计算机视觉和机器学习软件库&#xff0c;旨在提供一组通用的计算机视觉工具。它用于图像处理、目标识别、人脸识别、机器学习等领域&#xff0c;广泛应用于计算机视觉任务。 OpenCV-Mobile是OpenCV库的轻量版本&#xff0c;专为移动平台&#xff08;A…

[MySQL] SQL优化之性能分析

&#x1f308;键盘敲烂&#xff0c;年薪30万&#x1f308; 目录 一、索引优化 1、索引是什么&#xff1a; 2、索引的数据结构&#xff1a; 3、索引种类&#xff1a; 4、sql分析&#xff08;回表查询&#xff09; 二、定位慢查询语句 1、慢查询日志 2、profile详情 3、…

洛谷P3807 Lucas定理

传送门&#xff1a; P3807 【模板】卢卡斯定理/Lucas 定理 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P3807题干&#xff1a; 给定整数n,m,p 的值&#xff0c;求出C&#xff08;nm&#xff0c;n&#xff09;​mod p 的值。 输入数据保证…

案例027:基于微信小程序的校园二手平台的设计与实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

SAP UI5 walkthrough step3 Controls

在上一步&#xff0c;我们是直接用index.html 中的body 里面的DIVision去输出 hello world&#xff0c; 在这个章节&#xff0c;我们将用SAP UI5 的标准控件 sap/m/Text 首先&#xff0c;我们去修改 webapp/index.html <!DOCTYPE html> <html> <head><…

Pytorch深度强化学习1-6:详解时序差分强化学习(SARSA、Q-Learning算法)

目录 0 专栏介绍1 时序差分强化学习2 策略评估原理3 策略改进原理3.1 SARSA算法3.2 Q-Learning算法 0 专栏介绍 本专栏重点介绍强化学习技术的数学原理&#xff0c;并且采用Pytorch框架对常见的强化学习算法、案例进行实现&#xff0c;帮助读者理解并快速上手开发。同时&#…

【论文极速读】LVM,视觉大模型的GPT时刻?

【论文极速读】LVM&#xff0c;视觉大模型的GPT时刻&#xff1f; FesianXu 20231210 at Baidu Search Team 前言 这一周&#xff0c;LVM在arxiv上刚挂出不久&#xff0c;就被众多自媒体宣传为『视觉大模型的GPT时刻』&#xff0c;笔者抱着强烈的好奇心&#xff0c;在繁忙工作之…

class073 背包dp-01背包、有依赖的背包【算法】

class073 背包dp-01背包、有依赖的背包【算法】 算法讲解073【必备】背包dp-01背包、有依赖的背包 code1 P1048 [NOIP2005 普及组] 采药 // 01背包(模版) // 给定一个正数t&#xff0c;表示背包的容量 // 有m个货物&#xff0c;每个货物可以选择一次 // 每个货物有自己的体积…

ChatGPT 应用开发(一)ChatGPT OpenAI API 免代理调用方式(通过 Cloudflare 的 AI Gateway)

前言 开发 ChatGPT 应用&#xff0c;我觉得最前置的点就是能使用 ChatGPT API 接口。首先我自己要能成功访问&#xff0c;这没问题&#xff0c;会魔法就可以本地调用。 那用户如何调用到我的应用 API 呢&#xff0c;我的理解是通过用户能访问到的中转服务器向 OpenAI 发起访问…

带阻滤波器:原理、应用及性能分析?|深圳比创达电子EMC

在现代电子技术和通信领域中&#xff0c;滤波器是一种常见的电路元件&#xff0c;用于处理信号&#xff0c;去除不需要的频率成分或者增强感兴趣的频率成分。本文将重点探讨带阻滤波器&#xff0c;它是一种特殊类型的滤波器&#xff0c;具有在特定频率范围内抑制信号的功能。我…

JVM Optimization Learning(五)

目录 一、JVM Optimization 1、G1 1、G1内存模型 2、基础概念 3、G1特点&#xff1a; 4、CMS日志分析 5、G1日志分析 2、GC参数 2.1、GC常用参数 2.2、Parallel常用参数 2.3、CMS常用参数 2.4、G1常用参数 一、JVM Optimization 1、G1 G1官网说明&#xff1a;Gar…

【微软技术栈】发布自己造的轮子 -- 创建Nuget包(分布操作)

目录 1、您的项目 2、创建 .nuspec 文件 3、一张图片胜过一千个拉取请求 4、包括自述文件 MD 文件 5、构建软件包 6、将包部署到 Nuget.Org 7、手动上传软件包 8、自动化和脚本化部署 9、我们如何构建和部署 ErrLog.IO Nuget 包 10、Nuget统计数据 11、最后的思考 创建 Nuget 包…

生产上线需要注意的安全漏洞

一、关闭swagger 1、关闭swagger v3 # 需同时设置auto-startupfalse&#xff0c;否则/v3/api-docs等接口仍能继续访问 springfox:documentation:enabled: falseauto-startup: falseswagger-ui:enabled: false 2、关闭swagger v2 # 只要不是true就不启用 swagger:enable: fa…

YOLOv8/YOLOv7/YOLOv5/YOLOv4/Faster-rcnn系列算法改进【NO.83】将主干特征提取网络Backbone改为RevCol

前言 作为当前先进的深度学习目标检测算法YOLOv8,已经集合了大量的trick,但是还是有提高和改进的空间,针对具体应用场景下的检测难点,可以不同的改进方法。此后的系列文章,将重点对YOLOv8的如何改进进行详细的介绍,目的是为了给那些搞科研的同学需要创新点或者搞工程项目…

Vue3: 给表格多个字段添加排序功能

问题 在Vue3项目中&#xff0c;使用element-plus的表格组件绘制表格后&#xff0c;需要令表格的多个字段可以进行选择排序&#xff08;选择升序或者降序&#xff09;但是排序功能好像有时候会出错&#xff0c;需要排序的字段多了之后&#xff0c;排序功能有时候会不起作用 解…

分子生成领域的stable diffusion - GEOLDM

一、关于stable diffusion 很多人都知道stable diffusion&#xff0c;stable diffusion的出现改变了机器生成领域&#xff0c;让AI技术第一次无比的接近正常人。大语言模型&#xff0c;AIGC概念于是兴起。基于stable diffusion 大家开发了lora&#xff0c; hyperwork等微调技术…

JDK 9 模块化系统 (Module System) 和 多版本兼容 Jar (Multi-Release Jar)

博文目录 文章目录 Module System原因JDK 模块化模块描述文件关键字 启用模块化测试结论 Multi-Release jar (MRJAR)原因原理结论用 IDEA 创建多版本兼容 Jar项目结构pom.xml测试 Module System 原因 Java 9引入了模块化系统的主要原因是为了解决Java平台面临的复杂性和可维…

从电商API接口谈电商ERP系统介绍

部分网友反馈小红书APP出现闪退问题。对此&#xff0c;小红书客服微博发文称&#xff0c;如遇到小红书APP无法启动的情况&#xff0c;用户可前往App Store下载最新版本&#xff08;详情可见&#xff1a; &#xff09;小红书闪退崩溃出bug&#xff0c;IT人员要背故障吗&#xff…

【计算机网络实验】实验三 IP网络规划与路由设计(头歌)

目录 一、知识点 二、实验任务 三、头歌测试 一、知识点 IP子网掩码的两种表示方法 32位IP子网掩码&#xff0c;特点是从高位开始连续都是1&#xff0c;后面是连续的0&#xff0c;它有以下两种表示方法&#xff1a; 传统表示法&#xff0c;如&#xff1a;255.255.255.0IP前…