关于【积分获取】的说明关于【附件下载】的说明
查看: 886|回复: 9

微信小程序实战--流动图书馆

[复制链接]

467

主题

563

帖子

14万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
140845
发表于 2018-1-8 21:26:08 | 显示全部楼层 |阅读模式

登录后查看更多内容,推荐微信扫码快速登录

您需要 登录 才可以下载或查看,没有帐号?【建议使用下方微信快捷登录注册】

x
流动图书馆流动图书馆是一个图书漂流和借阅工具,旨在共享闲置图书,并链接趣味相投的小伙伴。预览链接技术栈小程序MINA框架: 一个响应的数据绑定框架。分为两块视图层(View)和逻辑层(App Service)Flex:flex弹性布 ...

流动图书馆
流动图书馆是一个图书漂流和借阅工具,旨在共享闲置图书,并链接趣味相投的小伙伴。
预览http://xinwenke.top/travelib/

技术栈
  • [color=rgb(54, 54, 54) !important]小程序MINA框架: 一个响应的数据绑定框架。分为两块视图层(View)和逻辑层(App Service)
  • Flex:flex弹性布局
  • Express : http服务框架
  • websocket: 前后端消息的实时推送
  • mongoose: 操作mongodb数据库
  • pm2: 服务端使用pm2部署,常驻进程
截图
首页


借阅书架


发布的图书


借阅的图书


客户端
  • 代码结构

微信小程序中每个页面会有四个文件 .js .json .wxml .wxss
js文件中是页面的逻辑,json文件是页面的一些配置,wxml是小程序的页面结构,wxss为页面的样式。
  • 封装http请求
  1. const request = (obj) => {
  2.   if(obj.header){
  3.     obj.header.sessionId = session.sessionId;
  4.   }else{
  5.     obj.header = { sessionId: session.sessionId};
  6.   }
  7.   wx.request(obj);
  8. }
复制代码
在请求头中手动加上sessionId,因为小程序没有cookie。
  • websocket
  1. //连接websocket
  2. wx.connectSocket({
  3.   url: 'wss://liudongtushuguan.cn/socket?sessionId=' + session.sessionId,
  4. });

  5. wx.onSocketOpen(function(res){

  6. });
  7. wx.onSocketClose(function(res){
  8.   console.log('websocket closed');
  9. });

  10. wx.onSocketMessage(function(res){  //收到消息的回调
  11.   let msg = JSON.parse(res.data);
  12.   let msgs = that.data.borrowMessage;
  13.   msgs.unshift(msg);
  14.   that.setData({ borrowMessage: msgs});
  15. });


  16. //发送socket消息
  17.   let data = JSON.stringify({
  18.     targetId: bookData.ownerId,
  19.     nickName: APP.globalData.userInfo.nickName,
  20.     bookName: bookData.title,
  21.     time: new Date().toLocaleString(),
  22.     bookId: bookId,
  23.     wxNum: wxNum,
  24.     phoneNum: phoneNum,
  25.     msg: msg,
  26.   });
  27.   wx.sendSocketMessage({
  28.     data: data,
  29.   });
复制代码
服务端
  • 代码目录
  • Express框架实现http服务
  1. const https = require('https');
  2. const fs = require('fs');
  3. const express = require('express')
  4. const cookieParser = require('cookie-parser');
  5. const bodyParser = require('body-parser');
  6. const app = express();
  7. const queryString = require('querystring');
  8. const URL = require('url');
  9. const socket = require('./service/socket');

  10. const router = require('./routes/router').router;

  11. //获取认证证书
  12. var key = fs.readFileSync('./key/2_www.liudongtushuguan.cn.key');
  13. var cert = fs.readFileSync('./key/1_www.liudongtushuguan.cn_bundle.crt');

  14. var options = {
  15.         key : key,
  16.         cert : cert,
  17. };

  18. app.use(cookieParser());
  19. app.use(bodyParser.json());

  20. const httpsServer = https.createServer(options,app);
  21. httpsServer.listen(443,() =>{
  22.     console.log('listening 443 port');
  23. });

  24. socket(httpsServer);  //websocket

  25. app.use(router);
复制代码
小程序规定必须要用https协议。
  • websocket模块
这里使用ws模块而没有选择使用http://socket.io,因为小程序客户端不支持http://socket.io
  1. const WebSocket = require('ws');  //使用ws模块
  2. const queryString = require('querystring');
  3. const URL = require('url');
  4. const sessions = require('./session');



  5. module.exports = (httpServer) => {

  6.         const wss = new WebSocket.Server({server : httpServer});

  7.         wss.on('connection',(ws, req) => {
  8.                         let sessionId = queryString.parse(URL.parse(req.url).query).sessionId;
  9.                         ws.id = sessionId;
  10.                 ws.on('message' , (msg) => {
  11.                                 let msgObj = JSON.parse(msg);
  12.                                 if(sessions[msgObj.targetId]){
  13.                                         wss.clients.forEach((client) => {
  14.                                             if(client.id === msgObj.targetId){
  15.                                                     let data = {
  16.                                                             time : msgObj.time,
  17.                                                             borrower :msgObj.nickName,
  18.                                                             book :msgObj.bookName,
  19.                                                             borrowerId : sessions[sessionId],
  20.                                                             bookId : msgObj.bookId,
  21.                                                             wxNum : msgObj.wxNum,
  22.                                                             phoneNum : msgObj.phoneNum,
  23.                                                             msg : msgObj.msg
  24.                                                     };
  25.                                                     client.send(JSON.stringify(data));
  26.                                             }
  27.                                     });
  28.                                 }
  29.                 });
  30.         });
  31. };
复制代码
  • mongoose操作数据库
db.js:

  1. const mongoose = require('mongoose');

  2. mongoose.connect('mongodb://app:12345678@127.0.0.1/wxapp');

  3. const connection = mongoose.connection;
  4. connection.once('open', (err) => {
  5.         if(err){
  6.                 console.log('Database connection failure');
  7.         }else{
  8.                 console.log('Database opened');

  9.         }
  10. });

  11. connection.on('error',(err) => {
  12.         console.log('Mongoose connected error '+ err);
  13. });

  14. connection.on('disconnected', () => {
  15.         console.log('Mongoose disconnected');
  16. });

  17. module.exports = {
  18.         connection : connection,
  19.         mongoose : mongoose,
  20. };
复制代码
model.js:

  1. const Schema = mongoose.Schema;

  2. const UserSchema = new Schema({
  3.         onlyId : {type: String},
  4.         publishedBooks : {type: Array},
  5.         borrowedBooks : {type: Array},
  6.         borrowMessages : Array,
  7. });

  8. const BookSchma = new Schema({
  9.         isbn : String,
  10.         title : String,
  11.         press : String,
  12.         author : String,
  13.         rate : String,
  14.         tags : String,
  15.         image : String,
  16.         status : {type : Boolean,default : true},
  17.         ownerId : String,
  18.         owner : String,
  19.         ownerImage : String,
  20. });

  21. const userModel =  mongoose.model('user' , UserSchema);
  22. const bookModel = mongoose.model('book' , BookSchma);

  23. module.exports = {
  24.         UserModel  : userModel,
  25.         BookModel : bookModel,
  26. }
复制代码
  • 获得微信用户的openId
小程序前端会请求微信服务器得到一个code, 将code发送给自己的服务器,然后自己的服务器给微信服务器发送请求,得到微信用户的唯一标识openId
  1. const https = require('https');
  2. const queryString = require('querystring');

  3. const sessions = require('./session');


  4. module.exports = (req, res, next) => {
  5.                 let code = req.query.code;
  6.                 let otherRes = res;
  7.                 DATA.js_code = code;
  8.                 OPTION.path = PATH + queryString.stringify(DATA);
  9.                 let wxReq = https.request(OPTION, (res) => {
  10.                         if(res.statusCode == 200){
  11.                                 let json = '';
  12.                                 res.on('data' , (data) => {
  13.                                         json+=data;
  14.                                 });
  15.                                 res.on('end' , () => {
  16.                                         json =JSON.parse(json);
  17.                                         let openId = json.openid;
  18.                                         sessions[openId] = openId;
  19.                                         otherRes.type('application/json');
  20.                                         otherRes.json({
  21.                                                 data : {'sessionId' : openId},
  22.                                         });
  23.                                         otherRes.status(200);
  24.                                 });
  25.                         }
  26.                 });
  27.                 wxReq.end();
  28. };
复制代码
使用pm2部署
安装pm2
  1. npm install  -g pm2
复制代码

启动应用
  1. pm2 start app.js
复制代码
总结
流动图书馆小程序是由三个人的小团队设计和开发的。我主要负责前后端的开发工作。这对从来没接触过服务端和小程序开发的我来说是一个挑战当然也是一次难得的学习机会。从最初对小程序,服务端两眼一抹黑,到搭建出应用的雏形,实现基本的效果,再到最后的拆分整合代码,这期间经历了很多,也收获了很多。从数据库的设计到后台数据库操作、会话管理、http服务接口一直到前后端数据交互、小程序前端,我对程序开发的大致流程有了更进一步的了解,弥补的之前对服务端知识的缺失。
三个人的小团队,因为兴趣结在一起,利用工作之余的时间完成自己喜欢的事情真的是一件令人十分有成就感的事情。
有兴趣的可以看源码
如果觉得不错,就毫不吝啬地给个star吧。后期项目还会继续更新和完善。


文档介绍:
游客,如果您要查看本帖隐藏内容请回复

回复

使用道具 举报

0

主题

5

帖子

29

积分

新手上路

Rank: 1

积分
29
发表于 2018-1-9 09:59:02 | 显示全部楼层
教程可以写详细点
回复

使用道具 举报

3

主题

27

帖子

55

积分

注册会员

Rank: 2

积分
55
发表于 2018-1-9 22:00:26 | 显示全部楼层
哈哈不错
回复

使用道具 举报

0

主题

1

帖子

4

积分

新手上路

Rank: 1

积分
4
发表于 2018-2-24 10:21:25 | 显示全部楼层
很好的项目
回复

使用道具 举报

0

主题

22

帖子

167

积分

注册会员

Rank: 2

积分
167
发表于 2018-3-19 10:58:44 | 显示全部楼层
学习学习中
回复

使用道具 举报

0

主题

31

帖子

34

积分

新手上路

Rank: 1

积分
34
发表于 2018-4-5 23:39:39 | 显示全部楼层
学习学习谢谢分享
回复

使用道具 举报

0

主题

14

帖子

17

积分

新手上路

Rank: 1

积分
17
发表于 2018-4-6 09:52:12 | 显示全部楼层
微信小程序实战--流动图书馆 [
回复

使用道具 举报

1

主题

4

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2018-4-20 14:11:48 | 显示全部楼层
教程看起来还不错
回复

使用道具 举报

0

主题

30

帖子

32

积分

新手上路

Rank: 1

积分
32
发表于 2018-5-14 13:43:50 | 显示全部楼层
多谢分享。。看看能用吗?
回复

使用道具 举报

0

主题

7

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2018-5-19 00:55:34 | 显示全部楼层
谢谢楼主,好人一生平安。
回复

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|Archiver|手机版|小黑屋|小程序大全|小程序开发者论坛-汇集最优质源码、开发者教程、小程序资源

GMT+8, 2018-10-24 14:00 , Processed in 3.191317 second(s), 11 queries , File On.

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表