小程序·云开发实战 - 校园约拍小程序

创意来源于生活,之所以开发这个校园约拍小程序,是因为在摄影选修课上常听老师抱怨外出写生老找不到模特,许多大学生都想拥有一套专属自己记忆的摄影作品,记录下不会磨灭的美好回忆,可如何找到让自己满意的摄影师是他们的难题。悦拍屋是一个校园摄影o2o的约拍平台,提供全方位的约拍服务,同时提供一个自我展示,学习交流,互动娱乐的平台。接下来我将结合项目的讲解给大家分享一些实用技术和对于云开发的一些经验,希望对正在学习小程序的你有帮助。

前言

在开发一个项目之前首先要进行技术选型从而降低产品开发的技术风险和提高开发效率,技术选型必须得紧紧围绕着业务场景来选择。

  • 产品原型设计:墨刀
  • UI组件库
    1.微信原生样式库WeUI,让用户使用感知更加统一
    2.注重视觉交互体验的ColorUI组件库,在感知统一的基础上视觉元素多样化
  • 前端
    1.小程序原生语法以及API
    2.Promise实现异步调用
    3.ES6编写页面交互逻辑
  • 后端
    1.云函数:无需自建服务器,在云端运行的代码,微信私有协议天然鉴权,开发者只需编写自身业务逻辑代码
    2.云数据库:无需自建数据库,一个既可在小程序前端操作,也能在云函数中读写的 JSON 数据库
    3.云存储:实现小程序前端直接上传/下载云端文件,在云开发控制台可视化管理
    4.云调用:由原生微信服务集成,基于云函数免鉴权使用小程序开放接口的能力,包括服务端调用、获取开放数据等能力
  • 其他
    1.使用微信提供的云测试对未上线的小程序进行缺陷测试、性能数据分析、机型覆盖测试,确保小程序上线后正常运营
    2.使用基于云开发的AI视觉能力-身份证识别实现实名认证,智能鉴黄结合人工完成发布信息的审核
    3.开发工具:微信开发者工具、VScode
    4.部分图标使用自阿里巴巴矢量图标库

总体设计

功能结构图

大家可以通过此图了解整个项目的主要功能点

功能结构图

产品原型图

此处给出一张主页原型图示例,墨刀还是挺好用的

主页原型图

色彩设计图

悦拍屋的整体色调为浅蓝色,各位小伙伴在开发自己项目的时候可以根据色彩标准搭配来设计项目所采用的色彩,合适的色彩搭配可以给用户良好的视觉体验

色彩设计图

功能模块详解

接下来我会对部分功能模块以图文结合的形式详细描述,将其中涉及的技术、知识分享给大家

约拍邀请

用户可在首页查看约拍需求,并点击查看需求详情,用户在了解需求后,若自己符合条件即可提交约拍信息,等待发布者的回复,可将此需求收藏方便查看

16b9e475ac6879b1?w=397&h=700&f=gif&s=2054353

技术分享:自定义顶部导航栏

官方默认的导航栏只能对背景颜色进行更改,对于想要在导航栏添加一些比较酷炫的效果则需要通过自定义导航栏实现

实现原理:通过设置app.json中页面配置的navigationStyle(导航栏样式)配置项的值为custom,即可实现自定义导航

"window":{"navigationStyle":"custom"
}

本项目的部分页面自定义导航栏实现使用了ColorUI的导航栏组件,在完成上一步属性设置后再引入导航栏组件即可

"usingComponents":{"cu-custom":"/colorui/components/cu-custom"  //该路径替换为自己项目内ColorUI组件所在位置
}

主页自定义导航栏通过设置背景图片加上GIF波浪效果

  <view class='page__bd'><view class="bg-img padding-tb-xl" style="background-image:url('http://wx4.sinaimg.cn/mw690/006UdlVNgy1g2v2t1ih8jj31hc0p0qej.jpg');background-size:cover;"><view class="cu-bar"><view class="content text-bold text-white">悦拍屋</view></view></view><view class="shadow-blur"><image src="https://image.weilanwl.com/gif/wave.gif" mode="scaleToFill" class="gif-black response" style="height:100rpx;margin-top:-100rpx;"></image></view></view>

效果图

16b9e85af5e5db08?w=397&h=120&f=gif&s=150182

使用组件定义的导航栏

<cu-custom bgImage="https://s2.ax1x.com/2019/05/02/Etiyng.jpg" isBack="{{true}}"><view slot="backText">返回</view><view slot="content">认证信息说明</view>
</cu-custom>

效果图

16b9e88d755efb48?w=391&h=50&f=png&s=23342

特别提醒1:使用自定义导航后,页面的返回需要在自定义导航栏中自行设置
特别提醒2:导航栏组件需要自行引入ColorUI组件库后才能使用,具体引入教程地址在附录中给出

发布约拍

选择发布约拍功能填写约拍需求,提交审核通过后可在首页实时查看发布结果
发布约拍

技术分享:入场动画

额。。录制可能略微有点卡顿,实际效果挺流畅的,各位大佬有什么好的录制工具推荐可以在评论中回复

实现原理:通过toggleDelay的布尔值为真动态添加动画类名,在生命周期函数onReady中控制toggleDelay的值从而控制整个动画过程(原理与Vue的动态类名相似)

data:{toggleDelay;false
},
onReady:function(){let that = this//toggleDelay的值为真,动画开始that.setData({toggleDelay: true})//控制整个动画的时长setTimeout(function() {that.setData({toggleDelay: false})}, 2000)
}
<view class="padding-xs {{toggleDelay?'animation-slide-bottom':''}}" style="animation-delay: {{item.time}}s;" wx:for="{{list}}" wx:key="{{index}}"><image class="img" id='img{{index}}' src="{{item.src}}" mode="widthFix" />
</view>
//所有动画的定义
[class*=animation-] {animation-duration: .5s;animation-timing-function: ease-out;animation-fill-mode: both
}
//animatioon-slide-bottom所定义的动画
.animation-slide-bottom {animation-name: slide-bottom
}
//动画效果
@keyframes slide-bottom {0% {opacity: 0;transform: translateY(100%)}100% {opacity: 1;transform: translateY(0)}
}

animation-slide-bottom是动画类名,animation-delay是每一个卡片动画执行的延迟时间,每一个动画的执行时长为0.5s,所以延迟时间是以0.5s递增的,三个卡片的动画总时长就为2s,即2s后就执行onReady中的settimeout事件结束动画

特别提醒:动画的延迟时间,执行时间可以自行设计,动画效果过渡自然即可
特别提醒:由于触发动画的钩子函数定义在页面初次渲染的生命周期函数中,故只有在页面初次渲染时才执行,避免每次显示页面时加载动画造成用户的视觉疲劳

智能推荐约拍对象

系统会根据约拍需求自动推荐约拍对象(个人开发精力有限,推荐算法后续推出。。。)

16ba13bfa125f13c?w=397&h=697&f=gif&s=4662891

技术分享:CSS3实现酷炫搜索动画

在模态框内放置两个view标签,以下是标签定义

 <view id='preloader'>               //外围的圆形框定义<view id='loader'></view>       //内部的线条定义
</view>
#preloader {width: 150px;height: 150px;border-radius: 50%;border: 1px solid #97b2ff;
}
#loader {         //中间线条定义display: block;position: relative;left: 50%;top: 50%;width: 150px;height: 150px;margin: -75px 0 0 -75px;border-radius: 50%;border: 3px solid transparent;border-top-color: #97b2ff;-webkit-animation: spin 2s linear infinite;animation: spin 2s linear infinite;
}
#loader:before {          //通过伪类元素定义外围线条content: "";position: absolute;top: 5px;left: 5px;right: 5px;bottom: 5px;border-radius: 50%;border: 3px solid transparent;border-top-color: #97b2ff;-webkit-animation: spin 3s linear infinite;animation: spin 3s linear infinite;
}
#loader:after {       //通过伪类元素定义最内部线条content: "";position: absolute;top: 15px;left: 15px;right: 15px;bottom: 15px;border-radius: 50%;border: 3px solid transparent;border-top-color: #97b2ff;-webkit-animation: spin 1.5s linear infinite;animation: spin 1.5s linear infinite;
}

实名认证

16ba233da0455a4f?w=397&h=697&f=gif&s=331988

嘿嘿,由于懒得给个人信息打码,就暂时不给大家演示认证过程了。。

技术分享:Ai视觉能力

很多小伙伴都有过在自己项目中使用AI技术的想法,但又因为入门AI的难度比较大,并且需要的时间较长就放弃了,现在给大家安利一个可以直接使用的AI服务,让AI不再具有神秘感(AI大佬可以忽略此部分。。)

  • 方案一
    在腾讯云中搜索身份证识别,上面会有详细的API文档以及测试工具帮助你快速使用

身份证识别

点击查看腾讯云-身份证识别

  • 方案二
    方案一是以提供API接口的形式提供身份证识别服务,而接下来要介绍的方案真的就比较简单了,在腾讯云中搜索智能图像,其中的增值服务AI智能图像能力,你可以通过云函数和云存储实现相应功能,基于小程序云开发的 AI DEMO中开发好了部分功能,你只需通过教程将云函数和组件引入你的项目即可使用

16ba20c7ba9b3aa9?w=1789&h=901&f=png&s=138973

点击查看腾讯云-智能图像
点击查看基于小程序云开发的 AI DEMO

特别提醒:当然使用这些服务也并非是完整的解决方案,对于身份证信息的加密、存储方案、安全协议等还是需要各位小伙伴自行设计解决方案哦。

云开发

云开发为开发者提供完整的原生云端支持和微信服务支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的 API 进行核心业务开发,即可实现快速上线和迭代,同时这一能力,同开发者已经使用的云服务相互兼容,并不互斥。

官方文档中API被分为了小程序端和服务端,一开始看过两端的API之后,感觉好像没有什么不同啊,在查阅相关资料以及实际开发中某些业务的处理总结出一些经验后才明白了两者的不同,下面给各位具体说说两者的不同之处,应该能帮助大家在使用云开发实战时少踩一点坑

初始化的不同

小程序端

全局声明一次

if (!wx.cloud) {console.error('请使用 2.2.3 或以上的基础库以使用云能力')} else {wx.cloud.init({env:'xxx',traceUser: true,})}

服务端

每个云函数中声明一次

const cloud = require('wx-server-sdk')
cloud.init()

权限不同

小程序端

在小程序端可以选择直接操作数据库,但由于是前端操作数据库存在一些安全问题,有较多的权限限制,在云控制中可对每个集合进行权限设置,这也就是为什么有小伙伴在小程序端对某些数据进行更新,显示更新成功但并未更新数据,就是因为小程序端默认只能更新当前用户写入的数据
16ba28cfebd5f487?w=1308&h=584&f=png&s=54194

特别提醒:在小程序端使用创建者的权限对数据进行修改时一定要确保该集合中有_openid字段,否则系统在权限判断时是没有办法识别当前操作为创建者的,数据修改无法执行

服务端

服务端拥有管理员的权限,对所有数据拥有读写权限

语法支持不同

小程序端

在微信开发者工具里,以及Android端手机(浏览器内核是QQ浏览器的X5),async/await是天然支持的,但 iOS 端手机在较低版本则不支持,因此需要引入额外的polyfill。可以在有使用async/await 的文件当中引入polyfill文件。

const runtime = require('相对路径/lib/runtime')

服务端

在云函数里,由于 Node 版本最低是 8.9,因此是天然支持 async/await 语法的
示例:获取约拍需求列表

//云函数入口文件
const cloud = require('wx-server-sdk')
//初始化
cloud.init()
//连接数据库
const db = cloud.database()
async function getAll(){const result = await db.collection('ypList').orderBy('cameraInfo.launchTime','desc').where({}).get()return result
}
// 云函数入口函数
exports.main = async (event, context) => {//此处的action是用来判断该调用哪一个方法if(event.action === 'getAll'){return getAll()}
}

结语

一个人手撸个全栈项目确实很辛苦,但收获也很多。至少对于小程序的实战开发更为熟练了,对MVVM的思想的理解也更加深刻了。技术发展得很快,学习一项技术如果不深入其本质,那么技术是学不完的。深入学习就是个解决问题的过程,或是帮助别人解决问题,或是借助他人的力量解决问题。目前在正在学习Vue、React、TypeScript等技术,后续会推出相关技术的项目解析文章,希望对于同样在学习的你有帮助。

特别说明:本项目已参加2019届中国高校计算机-微信应用开发赛完,开源至github,感兴趣的小伙伴可以看看

附录

在此提供一些本项目涉及到的技术、工具等链接供大家学习使用

  • 产品原型设计工具:墨刀
  • 色彩搭配设计:配色网
  • 在线作图:ProcessOn
  • UI样式库:WeUI
  • UI样式库:ColorUI
  • 图标库:Iconfont阿里巴巴矢量图标库
  • 开发工具:微信开发者工具
  • 开发者工具:Vscode
  • 腾讯云服务:身份证识别
  • 腾讯云服务:智能图像
  • API文档:微信官方文档.小程序
  • 技术文档:ES6

源码链接

https://github.com/TencentCloudBase/Good-practice-tutorial-recommended


如果你有关于使用云开发CloudBase相关的技术故事/技术实战经验想要跟大家分享,欢迎留言联系我们哦~比心!

aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9rbkhKUTZycDJJdTRqREU0Y1BzaWIxdEJvbTVCUWpyMFppYTJ6M21mUkpoVFppYmljdjFydFVHVTdZeWN3SXZYdUJPY3o3a3htaWNBVWhZUGlhdWljeERpYjQycllnLzA#pic_center

转载于:https://www.cnblogs.com/CloudBase/p/11303986.html

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

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

相关文章

mybatis学习(35):sql-where

目录结构 com.geyao.mybatis.mapper BlogMapper类 package com.geyao.mybatis.mapper;import java.util.List; import java.util.Map;import org.apache.ibatis.annotations.Param;import com.geyao.mybatis.pojo.Blog;public interface BlogMapper {Blog selectBlog(Integer…

mybatis学习(36):动态sql-set

目录结构 com.geyao.mybatis.mapper BlogMapper类 package com.geyao.mybatis.mapper;import java.util.List; import java.util.Map;import org.apache.ibatis.annotations.Param;import com.geyao.mybatis.pojo.Blog;public interface BlogMapper {Blog selectBlog(Integer…

从10亿光年到0.1飞米的世界 (经典!震撼!)

从10亿光年到0.1飞米的世界! 10亿光年,是一个什么概念?光年:光走一年的路程.光速:每秒299792458米,一秒可绕地球7圈半.在10亿光年下观测的宇宙.上面的每一个象素点所表现的事物都是无比古远的.1亿光年.把视野缩小了10倍,宇宙看起来还是星光点点,1000万光年,把眼光再降低一个数…

高效、稳定开发功能的一些心得

在开始编码前一定要足够了解案子&#xff0c;了解各种特殊情况&#xff0c;和美术、策划、服务器沟通好&#xff0c;最后写好伪代码。 一些建议 1.尽量复用&#xff0c;例如重复的对象单独抽出来做成item&#xff0c;别的模块也用到的做成通用item&#xff0c;不要写重复代码。…

Flume与Kafka整合案例详解

环境配置 名称 版本 下载地址 Centos 7.0 64x 百度 Zookeeper 3.4.5 Flume 1.6.0 Kafka 2.1.0 flume笔记 直接贴配置文件 [rootzero239 kafka_2.10-0.10.1.1]# cat /opt/hadoop/apache-flume-1.6.0-bin/conf/kafka-conf.properties # The configuration file needs to …

mybatis学习(37):动态sql-trim

目录结构 com.geyao.mybatis.mapper BlogMapper类 package com.geyao.mybatis.mapper;import java.util.List; import java.util.Map;import org.apache.ibatis.annotations.Param;import com.geyao.mybatis.pojo.Blog;public interface BlogMapper {Blog selectBlog(Integer…

SQL-简单查询

/*人员&#xff1a;LDH功能&#xff1a;SQL-简单查询日期&#xff1a;2018-7-18*/USE TSQLFundamentals2008; GO-- Select some columns information. SELECT empid,lastname,firstname,address,city,country FROM HR.Employees;-- GROUP BY SELECT 国家 country,COUNT(1) AS …

mybatis学习(38):动态sql-foreach

目录结构 com.geyao.mybatis.mapper BlogMapper类 package com.geyao.mybatis.mapper;import java.util.List; import java.util.Map;import org.apache.ibatis.annotations.Param;import com.geyao.mybatis.pojo.Blog;public interface BlogMapper {Blog selectBlog(Integer…

mybatis学习(39):动态sql片段

目录结构 com.geyao.mybatis.mapper BlogMapper类 package com.geyao.mybatis.mapper;import java.util.List; import java.util.Map;import org.apache.ibatis.annotations.Param;import com.geyao.mybatis.pojo.Blog;public interface BlogMapper {Blog selectBlog(Integer…

中国古代十三美男

一、潘安    潘岳&#xff0c;就是人所周知的潘安&#xff0c;西晋时河南人氏&#xff0c;表字安仁&#xff0c;小字檀奴。其人“姿容既好&#xff0c;神情亦佳”。潘岳年轻时&#xff0c;坐车到洛阳城外游玩&#xff0c;当时不少妙龄姑娘见了他&#xff0c;都会怦然心动给他…

mybatis学习(40):逆向工程的创建

目录 首先导入我们的jar包 链接&#xff1a;https://pan.baidu.com/s/1Ent3kAwOagOZLT0XxDLEeA 提取码&#xff1a;zqpu 建立一个com.geyao.generator的包 generator的java类 package com.geyao.generator; import java.io.File; import java.util.*;import org.mybatis.ge…

SpringBoot中Tomcat配置(学习SpringBoot实战)

1、Tomcat配置 Spring Boot默认内嵌的Tomcat为Servlet容器&#xff0c;所以本节只讲对Tomcat配置&#xff0c;其实本节的配置对Tomcat、Jetty和Undertow都是通用的。 1.1 配置Tomcat 关于Tomcat的所有属性都在org.springframework.boot.autoconfigure.web.ServerProperties配…

axios的数据请求方式及跨域

express 的三大功能&#xff1a;静态资源、路由、模板引擎 app.use(express.static(www));  只要是创建这个静态的目录&#xff0c;这个 www 的静态目录里面的文件就可以被访问 数据的请求方式 axios get 的 请求方式    axios.get(url地址).then(function(success){  //…

mybatis学习(41):使用逆向工程

新建一个项目&#xff0c;将逆向工程的生成的拷贝进来 配置文件 log4j.properties ### \u914D\u7F6E\u6839 ### log4j.rootLogger debug,console ,fileAppender,dailyRollingFile,ROLLING_FILE,MAIL,DATABASE### \u8BBE\u7F6E\u8F93\u51FAsql\u7684\u7EA7\u522B\uFF0C\u5176…

[Alg] 二叉树的非递归遍历

1. 非递归遍历二叉树算法 (使用stack) 以非递归方式对二叉树进行遍历的算法需要借助一个栈来存放访问过得节点。 (1) 前序遍历 从整棵树的根节点开始&#xff0c;对于任意节点V&#xff0c;访问节点V并将节点V入栈&#xff0c;并判断节点V的左子节点L是否为空。若L不为空&#…

[c++]访MSN浮出窗口的示例

【声明】严格来讲&#xff0c;这篇文章不属于我的原创。我在这里参考了codeproject上的国外作者的模仿MSN浮出窗口的C#代码。换句话说&#xff0c;可以认为我把C#代码翻译成了C代码。另外&#xff0c;为了简化代码&#xff0c;CloseButton我没有采用自己绘制&#xff0c;而是用…

mybatis学习(42):mybatis的一级缓存

目录结构 com.geyao.mybatis.mapper BlogMapper类 package com.geyao.mybatis.mapper;import java.util.List; import java.util.Map;import org.apache.ibatis.annotations.Param;import com.geyao.mybatis.pojo.Blog;public interface BlogMapper {Blog selectBlog(Integer…

防止ASP.NET按钮多次提交的办法

方法一<asp:Button ID"btnSumbit" runat"server" UseSubmitBehavior"false" OnClientClick"this.valueSumbit;this.disabledtrue; " Text"Sumbit" OnClick"btnSumbit_Click" /> 方法二1<html xmlns"…

mybatis学习(43):一级缓存被刷新情况

目录结构 com.geyao.mybatis.mapper BlogMapper类 package com.geyao.mybatis.mapper;import java.util.List; import java.util.Map;import org.apache.ibatis.annotations.Param;import com.geyao.mybatis.pojo.Blog;public interface BlogMapper {Blog selectBlog(Integer…

python文件读写小结

读文件 打开一个文件用open()方法(open()返回一个文件对象&#xff0c;它是可迭代的)&#xff1a; >>> f open(test.txt, r) r表示是文本文件&#xff0c;rb是二进制文件。&#xff08;这个mode参数默认值就是r&#xff09; 如果文件不存在&#xff0c;open()函数就会…