├── 智能快递柜
├── pages
│ └── index
│ │ ├── index.json
│ │ ├── enter
│ │ ├── enter.json
│ │ ├── enter.wxml
│ │ ├── enter.wxss
│ │ └── enter.js
│ │ ├── login
│ │ ├── login.json
│ │ ├── login.wxml
│ │ ├── login.wxss
│ │ └── login.js
│ │ ├── pickup
│ │ ├── pickup.json
│ │ ├── pickup.wxml
│ │ ├── pickup.wxss
│ │ └── pickup.js
│ │ ├── deposits
│ │ ├── deposits.json
│ │ ├── deposits.wxml
│ │ ├── deposits.wxss
│ │ └── deposits.js
│ │ ├── registe
│ │ ├── registe.json
│ │ ├── registe.wxss
│ │ ├── registe.wxml
│ │ └── registe.js
│ │ ├── depSucess
│ │ ├── depSucess.json
│ │ ├── depSucess.wxss
│ │ ├── depSucess.wxml
│ │ └── depSucess.js
│ │ ├── pickupSucc
│ │ ├── pickupSucc.json
│ │ ├── pickupSucc.wxss
│ │ ├── pickupSucc.wxml
│ │ └── pickupSucc.js
│ │ ├── enterVercode
│ │ ├── enterVercode.json
│ │ ├── enterVercode.wxml
│ │ ├── enterVercode.wxss
│ │ └── enterVercode.js
│ │ ├── index.wxml
│ │ ├── index.wxss
│ │ └── index.js
├── app.wxss
├── images
│ ├── logo.png
│ ├── phone.png
│ └── password.png
├── app.json
├── app.js
├── utils
│ └── getTime.js
└── project.config.json
├── images
├── 1.jpg
├── 10.png
├── 2.png
├── 3.png
├── 4.png
├── 5.png
├── 6.png
├── 7.png
├── 8.png
└── 9.png
├── 智能快递柜简介 .docx
├── node-koa2
├── config.js
├── db.js
├── model.js
├── models
│ ├── chest.js
│ ├── man.js
│ ├── deposits.js
│ └── takeout.js
├── app.js
├── package.json
├── getTime.js
├── controllers
│ ├── index.js
│ ├── user.js
│ ├── takeout.js
│ └── deposits.js
├── rest.js
└── controller.js
├── README.md
└── kuaidi.sql
/智能快递柜/pages/index/index.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "主页"
3 | }
--------------------------------------------------------------------------------
/智能快递柜/pages/index/enter/enter.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "存件"
3 | }
--------------------------------------------------------------------------------
/智能快递柜/pages/index/login/login.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "登录"
3 | }
--------------------------------------------------------------------------------
/智能快递柜/pages/index/pickup/pickup.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "请取件"
3 | }
--------------------------------------------------------------------------------
/智能快递柜/pages/index/deposits/deposits.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "请存件"
3 | }
--------------------------------------------------------------------------------
/智能快递柜/pages/index/registe/registe.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "注册"
3 | }
--------------------------------------------------------------------------------
/images/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jgchenu/Smart-courier-cabinet/HEAD/images/1.jpg
--------------------------------------------------------------------------------
/images/10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jgchenu/Smart-courier-cabinet/HEAD/images/10.png
--------------------------------------------------------------------------------
/images/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jgchenu/Smart-courier-cabinet/HEAD/images/2.png
--------------------------------------------------------------------------------
/images/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jgchenu/Smart-courier-cabinet/HEAD/images/3.png
--------------------------------------------------------------------------------
/images/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jgchenu/Smart-courier-cabinet/HEAD/images/4.png
--------------------------------------------------------------------------------
/images/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jgchenu/Smart-courier-cabinet/HEAD/images/5.png
--------------------------------------------------------------------------------
/images/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jgchenu/Smart-courier-cabinet/HEAD/images/6.png
--------------------------------------------------------------------------------
/images/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jgchenu/Smart-courier-cabinet/HEAD/images/7.png
--------------------------------------------------------------------------------
/images/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jgchenu/Smart-courier-cabinet/HEAD/images/8.png
--------------------------------------------------------------------------------
/images/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jgchenu/Smart-courier-cabinet/HEAD/images/9.png
--------------------------------------------------------------------------------
/智能快递柜/pages/index/depSucess/depSucess.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "存件成功"
3 | }
--------------------------------------------------------------------------------
/智能快递柜/pages/index/pickupSucc/pickupSucc.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "取件成功"
3 | }
--------------------------------------------------------------------------------
/智能快递柜简介 .docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jgchenu/Smart-courier-cabinet/HEAD/智能快递柜简介 .docx
--------------------------------------------------------------------------------
/智能快递柜/pages/index/enterVercode/enterVercode.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "取件"
3 | }
--------------------------------------------------------------------------------
/智能快递柜/app.wxss:
--------------------------------------------------------------------------------
1 | /**app.wxss**/
2 |
3 | page {
4 | font-size: 24rpx;
5 | font-family: 微软雅黑;
6 | }
7 |
--------------------------------------------------------------------------------
/智能快递柜/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jgchenu/Smart-courier-cabinet/HEAD/智能快递柜/images/logo.png
--------------------------------------------------------------------------------
/智能快递柜/images/phone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jgchenu/Smart-courier-cabinet/HEAD/智能快递柜/images/phone.png
--------------------------------------------------------------------------------
/智能快递柜/images/password.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jgchenu/Smart-courier-cabinet/HEAD/智能快递柜/images/password.png
--------------------------------------------------------------------------------
/智能快递柜/pages/index/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 存件
5 |
6 |
7 | 取件
8 |
9 |
--------------------------------------------------------------------------------
/node-koa2/config.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | database: 'kuaidi', // 使用哪个数据库
3 | username: 'root', // 用户名
4 | password: 'root', // 口令
5 | host: 'localhost', // 主机名
6 | port: 3306 // 端口号,MySQL默认3306
7 | }
8 | module.exports = config;
--------------------------------------------------------------------------------
/智能快递柜/pages/index/deposits/deposits.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 请使用
4 | {{chestid}}号柜
5 | 存件后请确认关好柜门!
6 |
7 |
--------------------------------------------------------------------------------
/智能快递柜/pages/index/enter/enter.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 请输入收件人手机号
5 |
6 |
7 |
--------------------------------------------------------------------------------
/智能快递柜/pages/index/pickup/pickup.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 你的快递在:
4 | {{chestid}}号柜
5 | 取件后请确认关好柜门!
6 |
7 |
8 |
--------------------------------------------------------------------------------
/智能快递柜/pages/index/enterVercode/enterVercode.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 请输入短信随机码
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/智能快递柜/pages/index/index.wxss:
--------------------------------------------------------------------------------
1 | .deposits, .pickup {
2 | width: 300rpx;
3 | height: 300rpx;
4 | font-size: 50rpx;
5 | border-radius: 50%;
6 | line-height: 300rpx;
7 | text-align: center;
8 | margin: 140rpx auto;
9 | background-color: rgb(109, 207, 210);
10 | color: #fff;
11 | }
12 |
13 | .pickup {
14 | background-color: rgb(137, 193, 210);
15 | }
16 |
--------------------------------------------------------------------------------
/智能快递柜/pages/index/pickup/pickup.wxss:
--------------------------------------------------------------------------------
1 | /* pages/index/pickup/pickup.wxss */
2 | .pickup{
3 | margin-top: 100rpx;
4 | font-size: 50rpx;
5 | text-align: center;
6 | }
7 | .tips{
8 | margin-top: 20rpx;
9 | font-size: 30rpx;
10 | color: #ccc;
11 | }
12 | .sure-button {
13 | width: 300rpx;
14 | height: 100rpx;
15 | margin: 500rpx auto 0 auto;
16 | line-height: 100rpx;
17 | }
--------------------------------------------------------------------------------
/智能快递柜/pages/index/deposits/deposits.wxss:
--------------------------------------------------------------------------------
1 | /* pages/index/deposits/deposits.wxss */
2 | .deposits{
3 | margin-top: 100rpx;
4 | font-size: 50rpx;
5 | text-align: center;
6 | }
7 | .tips{
8 | margin-top: 20rpx;
9 | font-size: 30rpx;
10 | color: #ccc;
11 | }
12 | .sure-button {
13 | width: 300rpx;
14 | height: 100rpx;
15 | margin: 500rpx auto 0 auto;
16 | line-height: 100rpx;
17 | }
--------------------------------------------------------------------------------
/node-koa2/db.js:
--------------------------------------------------------------------------------
1 | const Sequelize = require('sequelize');
2 | const config = require('./config')
3 | console.log('init sequelize...');
4 |
5 | var sequelize = new Sequelize(config.database, config.username, config.password, {
6 | host: config.host,
7 | dialect: 'mysql',
8 | pool: {
9 | max: 5,
10 | min: 0,
11 | idle: 5000
12 | }
13 | });
14 | module.exports = sequelize
--------------------------------------------------------------------------------
/node-koa2/model.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | let files = fs.readdirSync(__dirname + '/models');
3 |
4 | let js_files = files.filter((f) => {
5 | return f.endsWith('.js');
6 | }, files);
7 |
8 | module.exports = {};
9 |
10 | for (let f of js_files) {
11 | console.log(`import model from file ${f}...`);
12 | let name = f.substring(0, f.length - 3);
13 | module.exports[name] = require(__dirname + '/models/' + f);
14 | }
--------------------------------------------------------------------------------
/智能快递柜/pages/index/enter/enter.wxss:
--------------------------------------------------------------------------------
1 | /* pages/index/enter/enter.wxss */
2 |
3 | .enterPhone {
4 | margin-top: 140rpx;
5 | text-align: center;
6 | font-size: 40rpx;
7 | }
8 |
9 | .phone {
10 | height: 80rpx;
11 | width: 500rpx;
12 | border: 1rpx solid #000;
13 | border-radius: 10rpx;
14 | margin: 40rpx auto;
15 | }
16 |
17 | .next-button {
18 | width: 200rpx;
19 | height: 100rpx;
20 | margin: 100rpx auto;
21 | line-height: 100rpx;
22 | }
23 |
--------------------------------------------------------------------------------
/node-koa2/models/chest.js:
--------------------------------------------------------------------------------
1 | const sequelize = require('../db.js');
2 | const Sequelize = require('sequelize');
3 | module.exports = sequelize.define('chest', {
4 | chestid: {
5 | type: Sequelize.INTEGER(11),
6 | primaryKey: true
7 | },
8 | phone: Sequelize.STRING(11),
9 | randcode: Sequelize.INTEGER(6),
10 | status: Sequelize.BOOLEAN,
11 | manid: Sequelize.INTEGER(11)
12 | }, {
13 | timestamps: false,
14 | freezeTableName: true
15 | });
--------------------------------------------------------------------------------
/node-koa2/models/man.js:
--------------------------------------------------------------------------------
1 | const sequelize = require('../db.js');
2 | const Sequelize = require('sequelize');
3 | module.exports = sequelize.define('man', {
4 | manid: {
5 | type: Sequelize.INTEGER(11),
6 | primaryKey: true
7 | },
8 | phone: Sequelize.STRING(11),
9 | name: Sequelize.STRING(255),
10 | password: Sequelize.STRING(20),
11 | company: Sequelize.STRING(255)
12 | }, {
13 | timestamps: false,
14 | freezeTableName: true
15 | });
--------------------------------------------------------------------------------
/智能快递柜/pages/index/enterVercode/enterVercode.wxss:
--------------------------------------------------------------------------------
1 | /* pages/index/enterVercode/enterVercode.wxss */
2 | .enterPhone {
3 | margin-top: 140rpx;
4 | text-align: center;
5 | font-size: 40rpx;
6 | }
7 |
8 | .phone {
9 | height: 80rpx;
10 | width: 500rpx;
11 | border: 1rpx solid #000;
12 | border-radius: 10rpx;
13 | margin: 40rpx auto;
14 | }
15 |
16 | .next-button {
17 | width: 200rpx;
18 | height: 100rpx;
19 | margin: 100rpx auto;
20 | line-height: 100rpx;
21 | }
22 |
--------------------------------------------------------------------------------
/智能快递柜/pages/index/pickupSucc/pickupSucc.wxss:
--------------------------------------------------------------------------------
1 | /* pages/index/pickupSucc/pickupSucc.wxss */
2 | .pickSucc{
3 | width: 600rpx;
4 | margin: 110rpx auto;
5 | font-size: 40rpx;
6 | }
7 | .depSuccess view{
8 | margin: 10rpx 0;
9 | }
10 | .depSuccess text{
11 | margin-left:40rpx;
12 | }
13 |
14 | .enter-button,.quit-button {
15 | width: 300rpx;
16 | height: 100rpx;
17 | margin: 60rpx auto 0 auto;
18 | line-height: 100rpx;
19 | }
20 | .enter-button{
21 | margin-top: 140rpx;
22 | }
--------------------------------------------------------------------------------
/node-koa2/app.js:
--------------------------------------------------------------------------------
1 | const Koa = require('koa');
2 | const bodyParser = require('koa-bodyparser');
3 | const controller = require('./controller');
4 | const rest = require('./rest');
5 | const app = new Koa();
6 | app.use(bodyParser());
7 | app.use(async(ctx, next) => {
8 | // console.log(`Process ${ctx.request.method} ${ctx.request.url}...`);
9 | await next();
10 | });
11 |
12 | app.use(rest.restify());
13 | app.use(controller());
14 | app.listen(8080);
15 | console.log('app started at port 8080...');
--------------------------------------------------------------------------------
/node-koa2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "kuaidi",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "start": "node app.js"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "koa": "2.0.0",
14 | "koa-bodyparser": "3.2.0",
15 | "koa-router": "7.0.0",
16 | "sequelize": "3.24.1",
17 | "mysql": "2.11.1"
18 | }
19 | }
--------------------------------------------------------------------------------
/node-koa2/models/deposits.js:
--------------------------------------------------------------------------------
1 | const sequelize = require('../db.js');
2 | const Sequelize = require('sequelize');
3 | module.exports = sequelize.define('deposit', {
4 | id: {
5 | type: Sequelize.INTEGER(11),
6 | primaryKey: true
7 | },
8 | chestid: Sequelize.INTEGER(11),
9 | manid: Sequelize.INTEGER(11),
10 | phone: Sequelize.STRING(11),
11 | randcode: Sequelize.INTEGER(6),
12 | time: Sequelize.DATE
13 | }, {
14 | timestamps: false,
15 | freezeTableName: true
16 | });
--------------------------------------------------------------------------------
/node-koa2/models/takeout.js:
--------------------------------------------------------------------------------
1 | const sequelize = require('../db.js');
2 | const Sequelize = require('sequelize');
3 | module.exports = sequelize.define('takeout', {
4 | id: {
5 | type: Sequelize.INTEGER(11),
6 | primaryKey: true
7 | },
8 | chestid: Sequelize.INTEGER(11),
9 | manid: Sequelize.INTEGER(11),
10 | phone: Sequelize.STRING(11),
11 | randcode: Sequelize.INTEGER(6),
12 | time: Sequelize.DATE
13 | }, {
14 | timestamps: false,
15 | freezeTableName: true
16 | });
--------------------------------------------------------------------------------
/智能快递柜/pages/index/depSucess/depSucess.wxss:
--------------------------------------------------------------------------------
1 | /* pages/index/depSucess/depSucess.wxss */
2 |
3 | .depSuccess {
4 | width: 600rpx;
5 | margin: 110rpx auto;
6 | font-size: 40rpx;
7 | }
8 |
9 | .depSuccess view {
10 | margin: 10rpx 0;
11 | }
12 |
13 | .depSuccess text {
14 | margin-left: 40rpx;
15 | }
16 |
17 | .enter-button, .quit-button {
18 | width: 300rpx;
19 | height: 100rpx;
20 | margin: 60rpx auto 0 auto;
21 | line-height: 100rpx;
22 | }
23 |
24 | .enter-button {
25 | margin-top: 140rpx;
26 | }
27 |
--------------------------------------------------------------------------------
/智能快递柜/pages/index/depSucess/depSucess.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 快递员:
4 | {{name}}
5 |
6 | 快递公司:
7 | {{company}}
8 |
9 | 收件人:
10 | {{phone}}
11 | 柜号:
12 | {{chestid}}号柜
13 |
14 | 时间:
15 | {{time}}
16 |
17 |
18 |
--------------------------------------------------------------------------------
/智能快递柜/pages/index/pickupSucc/pickupSucc.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 快递员:
4 | {{name}}
5 |
6 | 快递公司:
7 | {{company}}
8 |
9 | 取件人:
10 | {{phone}}
11 | 柜号:
12 | {{chestid}}号柜
13 |
14 | 时间:
15 | {{time}}
16 |
17 |
18 |
--------------------------------------------------------------------------------
/智能快递柜/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages": [
3 | "pages/index/index",
4 | "pages/index/pickupSucc/pickupSucc",
5 | "pages/index/pickup/pickup",
6 | "pages/index/enterVercode/enterVercode",
7 | "pages/index/depSucess/depSucess",
8 | "pages/index/deposits/deposits",
9 | "pages/index/login/login",
10 | "pages/index/registe/registe",
11 | "pages/index/enter/enter"
12 | ],
13 | "window": {
14 | "backgroundTextStyle": "light",
15 | "navigationBarBackgroundColor": "#fff",
16 | "navigationBarTitleText": "WeChat",
17 | "navigationBarTextStyle": "black"
18 | }
19 | }
--------------------------------------------------------------------------------
/智能快递柜/app.js:
--------------------------------------------------------------------------------
1 | App({
2 | globalData: {
3 | phone: "0",
4 | vercode: "0",
5 | baseUrl: "http://127.0.0.1:8080/api",
6 | manid: "0"
7 | },
8 | /**
9 | * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
10 | */
11 | onLaunch: function () {
12 |
13 | },
14 |
15 | /**
16 | * 当小程序启动,或从后台进入前台显示,会触发 onShow
17 | */
18 | onShow: function (options) {
19 |
20 | },
21 |
22 | /**
23 | * 当小程序从前台进入后台,会触发 onHide
24 | */
25 | onHide: function () {
26 |
27 | },
28 |
29 | /**
30 | * 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
31 | */
32 | onError: function (msg) {
33 |
34 | }
35 | })
36 |
--------------------------------------------------------------------------------
/智能快递柜/utils/getTime.js:
--------------------------------------------------------------------------------
1 | function timetrans(date) {
2 | var date = new Date(date); //如果date为13位不需要乘1000
3 | var Y = date.getFullYear() + '-';
4 | var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
5 | var D = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate()) + ' ';
6 | var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
7 | var m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
8 | var s = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds());
9 | return Y + M + D + h + m + s;
10 | console.log(1);
11 | }
12 | module.exports = timetrans
--------------------------------------------------------------------------------
/node-koa2/getTime.js:
--------------------------------------------------------------------------------
1 | function timetrans(date) {
2 | var date = new Date(date); //如果date为13位不需要乘1000
3 | var Y = date.getFullYear() + '-';
4 | var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
5 | var D = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate()) + ' ';
6 | var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
7 | var m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
8 | var s = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds());
9 | return Y + M + D + h + m + s;
10 | console.log(1);
11 | }
12 | module.exports = timetrans
--------------------------------------------------------------------------------
/智能快递柜/project.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "项目配置文件。",
3 | "setting": {
4 | "urlCheck": false,
5 | "es6": true,
6 | "postcss": true,
7 | "minified": true,
8 | "newFeature": true
9 | },
10 | "compileType": "miniprogram",
11 | "libVersion": "1.9.91",
12 | "appid": "wxc84d60761533cb1e",
13 | "projectname": "%E6%99%BA%E8%83%BD%E5%BF%AB%E9%80%92%E6%9F%9C",
14 | "isGameTourist": false,
15 | "condition": {
16 | "search": {
17 | "current": -1,
18 | "list": []
19 | },
20 | "conversation": {
21 | "current": -1,
22 | "list": []
23 | },
24 | "game": {
25 | "currentL": -1,
26 | "list": []
27 | },
28 | "miniprogram": {
29 | "current": -1,
30 | "list": []
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/node-koa2/controllers/index.js:
--------------------------------------------------------------------------------
1 | // const APIError = require('../rest').APIError;
2 |
3 | // module.exports = {
4 | // 'GET /api/products': async(ctx, next) => {
5 | // ctx.rest({
6 | // products: '1'
7 | // });
8 | // },
9 |
10 | // 'POST /api/products': async(ctx, next) => {
11 |
12 | // ctx.rest({
13 | // products: '111'
14 | // });
15 | // },
16 |
17 | // 'DELETE /api/products/:id': async(ctx, next) => {
18 | // console.log(`delete product ${ctx.params.id}...`);
19 |
20 | // if (p) {
21 | // ctx.rest({
22 | // products: '1'
23 | // });
24 | // } else {
25 | // throw new APIError('product:not_found', 'product not found by id.');
26 | // }
27 | // }
28 | // };
--------------------------------------------------------------------------------
/智能快递柜/pages/index/registe/registe.wxss:
--------------------------------------------------------------------------------
1 | /* pages/index/registe/registe.wxss */
2 |
3 | .registe {
4 | width: 600rpx;
5 | margin: 100rpx auto;
6 | }
7 |
8 | .input-container {
9 | position: relative;
10 | }
11 |
12 | .input-container text {
13 | position: absolute;
14 | font-size: 40rpx;
15 | bottom: 2rpx;
16 | }
17 |
18 | .input-container input {
19 | width: 400rpx;
20 | border-bottom: 1rpx solid #000;
21 | padding-left: 200rpx;
22 | margin-top: 40rpx;
23 | }
24 |
25 | .select-container {
26 | margin-top: 40rpx;
27 | }
28 |
29 | .select-container text {
30 | font-size: 36rpx;
31 | }
32 |
33 | .select-container picker {
34 | display: inline-block;
35 | margin-left: 100rpx;
36 | font-size: 36rpx;
37 | }
38 | .registe-button{
39 | width: 500rpx;
40 | height: 100rpx;
41 | margin: 100rpx auto;
42 | }
43 |
--------------------------------------------------------------------------------
/智能快递柜/pages/index/registe/registe.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 姓名:
5 |
6 |
7 |
8 | 手机号
9 |
10 |
11 |
12 | 密码:
13 |
14 |
15 |
16 | 确认密码:
17 |
18 |
19 |
20 | 所属快递公司:
21 |
22 |
23 | {{array[index]}}
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/智能快递柜/pages/index/login/login.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | 记住我
19 |
20 |
21 | 注册
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/智能快递柜/pages/index/login/login.wxss:
--------------------------------------------------------------------------------
1 | /* pages/index/login/login.wxss */
2 |
3 | .logo {
4 | width: 100%;
5 | height: 300rpx;
6 | margin: 0 auto;
7 | }
8 |
9 | .loginContainer {
10 | display: flex;
11 | flex-direction: column;
12 | }
13 |
14 | .inputs {
15 | margin: 20rpx auto;
16 | width: 600rpx;
17 | height: 200rpx;
18 | border-radius: 20rpx;
19 | border: 1rpx solid #ccc;
20 | flex-direction: column;
21 | }
22 |
23 | .inputs input {
24 | font-size: 36rpx;
25 | height: 100rpx;
26 | padding-left: 80rpx;
27 | }
28 |
29 | .inputs-container {
30 | position: relative;
31 | }
32 |
33 | .inputs image {
34 | position: absolute;
35 | width: 60rpx;
36 | height: 60rpx;
37 | top: 20rpx;
38 | left: 10rpx;
39 | }
40 |
41 | .operating {
42 | margin: 10rpx auto;
43 | width: 600rpx;
44 | height: 50rpx;
45 | }
46 |
47 | .check-container {
48 | float: left;
49 | line-height: 50rpx;
50 | }
51 |
52 | .registered {
53 | float: right;
54 | line-height: 50rpx;
55 | }
56 | .login-button{
57 | width: 500rpx;
58 | height: 100rpx;
59 | margin: 100rpx auto;
60 | }
--------------------------------------------------------------------------------
/智能快递柜/pages/index/index.js:
--------------------------------------------------------------------------------
1 |
2 | Page({
3 |
4 | /**
5 | * 页面的初始数据
6 | */
7 | data: {
8 |
9 | },
10 |
11 | //方法
12 | toDeposits: function () {
13 | wx.navigateTo({
14 | url: 'login/login',
15 | })
16 | },
17 | toPickup: function () {
18 | wx.navigateTo({
19 | url: 'enterVercode/enterVercode',
20 | })
21 | },
22 |
23 | /**
24 | * 生命周期函数--监听页面加载
25 | */
26 | onLoad: function (options) {
27 |
28 |
29 | },
30 |
31 | /**
32 | * 生命周期函数--监听页面初次渲染完成
33 | */
34 | onReady: function () {
35 |
36 | },
37 |
38 | /**
39 | * 生命周期函数--监听页面显示
40 | */
41 | onShow: function () {
42 |
43 | },
44 |
45 | /**
46 | * 生命周期函数--监听页面隐藏
47 | */
48 | onHide: function () {
49 |
50 | },
51 |
52 | /**
53 | * 生命周期函数--监听页面卸载
54 | */
55 | onUnload: function () {
56 |
57 | },
58 |
59 | /**
60 | * 页面相关事件处理函数--监听用户下拉动作
61 | */
62 | onPullDownRefresh: function () {
63 |
64 | },
65 |
66 | /**
67 | * 页面上拉触底事件的处理函数
68 | */
69 | onReachBottom: function () {
70 |
71 | },
72 |
73 | /**
74 | * 用户点击右上角分享
75 | */
76 | onShareAppMessage: function () {
77 |
78 | }
79 | })
--------------------------------------------------------------------------------
/node-koa2/rest.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | APIError: function(code, message) {
3 | this.code = code || 'internal:unknown_error';
4 | this.message = message || '';
5 | },
6 | restify: (pathPrefix) => {
7 | pathPrefix = pathPrefix || '/api/';
8 | return async(ctx, next) => {
9 | if (ctx.request.path.startsWith(pathPrefix)) {
10 | console.log(`Process API ${ctx.request.method} ${ctx.request.url}...`);
11 | ctx.rest = (data) => {
12 | ctx.response.type = 'application/json';
13 | ctx.response.body = data;
14 | }
15 | try {
16 | await next();
17 | } catch (e) {
18 | console.log('Process API error...');
19 | ctx.response.status = 400;
20 | ctx.response.type = 'application/json';
21 | ctx.response.body = {
22 | code: e.code || 'internal:unknown_error',
23 | message: e.message || ''
24 | };
25 | }
26 | } else {
27 | await next();
28 | }
29 | };
30 | }
31 | };
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Smart-courier-cabinet
2 | ## 智能快递柜
3 | ### 前端使用小程序框架开发
4 | ### 后端使用nodejs中的koa2框架进行代码开发,使用Sequelize映射数据库模型;
5 | * > 智能快递柜文件夹里面是小程序文件 下载解压之后直接用小程序开发者工具打开文件夹,添加上自己的appid
6 | * > nodejs-koa2文件里面是后端代码 下载解压之后用vscode或者webstorm打开,然后在dos命令行格式下,在nodejs-koa2文件夹路径下,先输入cnpm install 或者 npm install 然后node app.js 或者npm start启动项目,默认端口为8080,可以自己修改。如需修改,那么小程序的app.js 的baseurl也要修改。
7 | * > kuaidi.sql 是数据库的建表以及插入相关数据的导出文件,里面已经有部分账号。
8 |
9 | ##### 此处注明小程序关于全局app.js变量的bug
10 |
11 | * > app.js里面的全局变量的值的获取会有bug(小程序本身的问题),在app.js中app.globalData.value的初始值为0,假如我在A页面设置了app.globalData.value的值为1,如果在B页面的顶部设置该页面的全局变量直接用let value=app.globalData.value;你猜一下,value是多少,value是0,而不是1。那么我在方法函数中使用let value=app.globalData.value,那么value是多少,value是1 真是神奇的bug,后面用到的同学需要注意一下,避免踩坑。
12 |
13 |
14 |
15 | 
16 |
17 | 
18 |
19 | 
20 |
21 | 
22 |
23 | 
24 |
25 | 
26 |
27 | 
28 |
29 | 
30 |
31 | 
32 |
33 | 
34 |
--------------------------------------------------------------------------------
/node-koa2/controller.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 |
3 | // add url-route in /controllers:
4 |
5 | function addMapping(router, mapping) {
6 | for (var url in mapping) {
7 | if (url.startsWith('GET ')) {
8 | var path = url.substring(4);
9 | router.get(path, mapping[url]);
10 | console.log(`register URL mapping: GET ${path}`);
11 | } else if (url.startsWith('POST ')) {
12 | var path = url.substring(5);
13 | router.post(path, mapping[url]);
14 | console.log(`register URL mapping: POST ${path}`);
15 | } else if (url.startsWith('PUT ')) {
16 | var path = url.substring(4);
17 | router.put(path, mapping[url]);
18 | console.log(`register URL mapping: PUT ${path}`);
19 | } else if (url.startsWith('DELETE ')) {
20 | var path = url.substring(7);
21 | router.del(path, mapping[url]);
22 | console.log(`register URL mapping: DELETE ${path}`);
23 | } else {
24 | console.log(`invalid URL: ${url}`);
25 | }
26 | }
27 | }
28 |
29 | function addControllers(router, dir) {
30 | fs.readdirSync(__dirname + '/' + dir).filter((f) => {
31 | return f.endsWith('.js');
32 | }).forEach((f) => {
33 | console.log(`process controller: ${f}...`);
34 | let mapping = require(__dirname + '/' + dir + '/' + f);
35 | addMapping(router, mapping);
36 | });
37 | }
38 |
39 | module.exports = function(dir) {
40 | let
41 | controllers_dir = dir || 'controllers',
42 | router = require('koa-router')();
43 | addControllers(router, controllers_dir);
44 | return router.routes();
45 | };
--------------------------------------------------------------------------------
/智能快递柜/pages/index/enter/enter.js:
--------------------------------------------------------------------------------
1 | // pages/index/enter/enter.js
2 | let app = getApp();
3 | Page({
4 |
5 | /**
6 | * 页面的初始数据
7 | */
8 | data: {
9 | phone:null
10 | },
11 | bindPhoneInput: function (e) {
12 | this.setData({
13 | phone: e.detail.value
14 | })
15 | },
16 | toDeposits: function () {
17 | if (!/^1[345789]\d{9}$/.test(this.data.phone)) {
18 | console.log(this.data);
19 | wx.showToast({
20 | title: '请输入正确的手机格式',
21 | icon: 'none',
22 | duration: 1000
23 | })
24 | }
25 | else {
26 | app.globalData.phone = this.data.phone;
27 | wx.showToast({
28 | title: '手机验证通过',
29 | icon: 'success',
30 | duration: 1000,
31 | success: () => {
32 | setTimeout(() => {
33 | wx.navigateTo({
34 | url: '../deposits/deposits',
35 | })
36 | }, 1000)
37 | }
38 | })
39 | }
40 |
41 |
42 | },
43 | /**
44 | * 生命周期函数--监听页面加载
45 | */
46 | onLoad: function (options) {
47 |
48 | },
49 |
50 | /**
51 | * 生命周期函数--监听页面初次渲染完成
52 | */
53 | onReady: function () {
54 |
55 | },
56 |
57 | /**
58 | * 生命周期函数--监听页面显示
59 | */
60 | onShow: function () {
61 |
62 | },
63 |
64 | /**
65 | * 生命周期函数--监听页面隐藏
66 | */
67 | onHide: function () {
68 |
69 | },
70 |
71 | /**
72 | * 生命周期函数--监听页面卸载
73 | */
74 | onUnload: function () {
75 |
76 | },
77 |
78 | /**
79 | * 页面相关事件处理函数--监听用户下拉动作
80 | */
81 | onPullDownRefresh: function () {
82 |
83 | },
84 |
85 | /**
86 | * 页面上拉触底事件的处理函数
87 | */
88 | onReachBottom: function () {
89 |
90 | },
91 |
92 | /**
93 | * 用户点击右上角分享
94 | */
95 | onShareAppMessage: function () {
96 |
97 | }
98 | })
--------------------------------------------------------------------------------
/智能快递柜/pages/index/pickupSucc/pickupSucc.js:
--------------------------------------------------------------------------------
1 | // pages/index/pickupSucc/pickupSucc.js
2 | let getTime = require('../../../utils/getTime.js')
3 | let app = getApp();
4 | let globalData = app.globalData;
5 | let baseUrl = globalData.baseUrl;
6 | Page({
7 |
8 | /**
9 | * 页面的初始数据
10 | */
11 | data: {
12 | chestid: "",
13 | name: "",
14 | company: "",
15 | time: "",
16 | phone:""
17 | },
18 | toEnter: function () {
19 | wx.navigateTo({
20 | url: '../enterVercode/enterVercode',
21 | })
22 | },
23 | quit: function () {
24 | wx.navigateTo({
25 | url: '../index',
26 | })
27 | },
28 | /**
29 | * 生命周期函数--监听页面加载
30 | */
31 | onLoad: function (options) {
32 | wx.request({
33 | url: `${baseUrl}/takeout/success/${globalData.vercode}`,
34 | method: 'GET',
35 | header: {
36 | "Content-type": "application/json"
37 | },
38 | success: (res) => {
39 | console.log(res);
40 | if (res.data.code === 200200) {
41 | let time = getTime(new Date(res.data.time).getTime());
42 | this.setData({
43 | chestid: res.data.chestid,
44 | company: res.data.company,
45 | name: res.data.name,
46 | time: time,
47 | phone: res.data.phone,
48 | })
49 | } else {
50 | wx.navigateTo({
51 | url: '../index',
52 | })
53 | }
54 | }
55 | })
56 | },
57 |
58 | /**
59 | * 生命周期函数--监听页面初次渲染完成
60 | */
61 | onReady: function () {
62 |
63 | },
64 |
65 | /**
66 | * 生命周期函数--监听页面显示
67 | */
68 | onShow: function () {
69 |
70 | },
71 |
72 | /**
73 | * 生命周期函数--监听页面隐藏
74 | */
75 | onHide: function () {
76 |
77 | },
78 |
79 | /**
80 | * 生命周期函数--监听页面卸载
81 | */
82 | onUnload: function () {
83 |
84 | },
85 |
86 | /**
87 | * 页面相关事件处理函数--监听用户下拉动作
88 | */
89 | onPullDownRefresh: function () {
90 |
91 | },
92 |
93 | /**
94 | * 页面上拉触底事件的处理函数
95 | */
96 | onReachBottom: function () {
97 |
98 | },
99 |
100 | /**
101 | * 用户点击右上角分享
102 | */
103 | onShareAppMessage: function () {
104 |
105 | }
106 | })
--------------------------------------------------------------------------------
/智能快递柜/pages/index/depSucess/depSucess.js:
--------------------------------------------------------------------------------
1 | // pages/index/depSucess/depSucess.js
2 | let getTime = require('../../../utils/getTime.js')
3 | let app = getApp();
4 | let globalData = app.globalData;
5 | let baseUrl = globalData.baseUrl;
6 | Page({
7 |
8 | /**
9 | * 页面的初始数据
10 | */
11 | data: {
12 | chestid: "",
13 | name: "",
14 | phone: "",
15 | company: "",
16 | time: ""
17 | },
18 |
19 | toEnter: function () {
20 | wx.navigateTo({
21 | url: '../enter/enter',
22 | })
23 | },
24 | quit: function () {
25 | wx.navigateTo({
26 | url: '../index',
27 | })
28 | },
29 | /**
30 | * 生命周期函数--监听页面加载
31 | */
32 | onLoad: function (options) {
33 | let chestid = options.chestid;
34 | console.log(chestid);
35 | wx.request({
36 | url: `${baseUrl}/deposits/success/${chestid}`,
37 | method: 'GET',
38 | header: {
39 | "Content-type": "application/json"
40 | },
41 | success: (res) => {
42 | if (res.data.code === 200200) {
43 | let time = getTime(new Date(res.data.time).getTime());
44 | this.setData({
45 | chestid: res.data.chestid,
46 | company: res.data.company,
47 | name: res.data.name,
48 | phone: res.data.phone,
49 | time: time
50 | })
51 | } else {
52 | wx.navigateTo({
53 | url: '../index',
54 | })
55 | }
56 | }
57 | })
58 | },
59 |
60 | /**
61 | * 生命周期函数--监听页面初次渲染完成
62 | */
63 | onReady: function () {
64 |
65 | },
66 |
67 | /**
68 | * 生命周期函数--监听页面显示
69 | */
70 | onShow: function () {
71 |
72 | },
73 |
74 | /**
75 | * 生命周期函数--监听页面隐藏
76 | */
77 | onHide: function () {
78 |
79 | },
80 |
81 | /**
82 | * 生命周期函数--监听页面卸载
83 | */
84 | onUnload: function () {
85 |
86 | },
87 |
88 | /**
89 | * 页面相关事件处理函数--监听用户下拉动作
90 | */
91 | onPullDownRefresh: function () {
92 |
93 | },
94 |
95 | /**
96 | * 页面上拉触底事件的处理函数
97 | */
98 | onReachBottom: function () {
99 |
100 | },
101 |
102 | /**
103 | * 用户点击右上角分享
104 | */
105 | onShareAppMessage: function () {
106 |
107 | }
108 | })
--------------------------------------------------------------------------------
/智能快递柜/pages/index/pickup/pickup.js:
--------------------------------------------------------------------------------
1 | // pages/index/pickup/pickup.js
2 | let app = getApp();
3 | let globalData = app.globalData;
4 | let baseUrl = globalData.baseUrl;
5 |
6 | Page({
7 |
8 | /**
9 | * 页面的初始数据
10 | */
11 | data: {
12 | chestid: ""
13 | },
14 | deposits: function () {
15 | let chestid = this.data.chestid;
16 | wx.request({
17 | url: `${baseUrl}/takeout/sure`,
18 | method: 'POST',
19 | header: {
20 | "Content-type": "application/json"
21 | },
22 | data: {
23 | vercode: globalData.vercode,
24 | chestid: chestid
25 | },
26 | success: (res) => {
27 | console.log(res);
28 | if (res.data.code === 200200) {
29 | wx.showToast({
30 | title: res.data.msg,
31 | icon: 'success',
32 | duration: 1000,
33 | success: () => {
34 | setTimeout(() => {
35 | wx.navigateTo({
36 | url: '../pickupSucc/pickupSucc',
37 | })
38 | }, 1000)
39 | }
40 | })
41 | }
42 |
43 | }
44 | })
45 |
46 | },
47 | /**
48 | * 生命周期函数--监听页面加载
49 | */
50 | onLoad: function (options) {
51 | wx.request({
52 | url: `${baseUrl}/takeout/enter/${globalData.vercode}`,
53 | method: 'GET',
54 | header: {
55 | "Content-type": "application/json"
56 | },
57 | success: (res) => {
58 | console.log(res);
59 | this.setData({
60 | chestid: res.data.chestid
61 | })
62 | }
63 | })
64 | },
65 |
66 | /**
67 | * 生命周期函数--监听页面初次渲染完成
68 | */
69 | onReady: function () {
70 |
71 | },
72 |
73 | /**
74 | * 生命周期函数--监听页面显示
75 | */
76 | onShow: function () {
77 |
78 | },
79 |
80 | /**
81 | * 生命周期函数--监听页面隐藏
82 | */
83 | onHide: function () {
84 |
85 | },
86 |
87 | /**
88 | * 生命周期函数--监听页面卸载
89 | */
90 | onUnload: function () {
91 |
92 | },
93 |
94 | /**
95 | * 页面相关事件处理函数--监听用户下拉动作
96 | */
97 | onPullDownRefresh: function () {
98 |
99 | },
100 |
101 | /**
102 | * 页面上拉触底事件的处理函数
103 | */
104 | onReachBottom: function () {
105 |
106 | },
107 |
108 | /**
109 | * 用户点击右上角分享
110 | */
111 | onShareAppMessage: function () {
112 |
113 | }
114 | })
--------------------------------------------------------------------------------
/node-koa2/controllers/user.js:
--------------------------------------------------------------------------------
1 | const APIError = require('../rest').APIError;
2 | const model = require('../model');
3 | module.exports = {
4 |
5 | 'POST /api/user/login': async(ctx, next) => {
6 | console.log(ctx.request.body)
7 | let phone = ctx.request.body.phone;
8 | let password = ctx.request.body.password;
9 | let man = model.man;
10 | let code = 200200;
11 | let msg = "登陆成功";
12 | let mans = await man.findAll({
13 | where: {
14 | phone: phone
15 | }
16 | });
17 | if (mans.length == 1 && mans[0].password != password) {
18 | code = 200201;
19 | msg = "密码错误"
20 | } else if (mans.length == 0) {
21 | code = 200202;
22 | msg = "用户不存在"
23 | } else if (mans.length == 1 && mans[0].password == password) {
24 | let manid = mans[0].manid;
25 | ctx.rest({
26 | code: code,
27 | msg: msg,
28 | manid: manid
29 | });
30 | return;
31 | }
32 | ctx.rest({
33 | code: code,
34 | msg: msg
35 | });
36 |
37 | },
38 | 'POST /api/user/register': async(ctx, next) => {
39 | console.log(ctx.request.body)
40 | let name = ctx.request.body.name;
41 | let phone = ctx.request.body.phone;
42 | let password = ctx.request.body.password;
43 | let company = ctx.request.body.company;
44 | let man = model.man;
45 | let code = 200200;
46 | let msg = "注册成功";
47 | let mans = await man.findAll({
48 | where: {
49 | phone: phone
50 | }
51 | });
52 | if (mans.length == 1) {
53 | code = 200201;
54 | msg = "用户已经存在"
55 | } else if (mans.length == 0) {
56 | var add = await man.create({
57 | name: name,
58 | phone: phone,
59 | password: password,
60 | company: company
61 | });
62 | ctx.rest({
63 | code: code,
64 | msg: msg,
65 | add: JSON.stringify(add)
66 | });
67 | return;
68 | }
69 | ctx.rest({
70 | code: code,
71 | msg: msg
72 | });
73 | }
74 | };
--------------------------------------------------------------------------------
/智能快递柜/pages/index/enterVercode/enterVercode.js:
--------------------------------------------------------------------------------
1 | // pages/index/enterVercode/enterVercode.js
2 | let app = getApp();
3 | let baseUrl = app.globalData.baseUrl;
4 | Page({
5 |
6 | /**
7 | * 页面的初始数据
8 | */
9 | data: {
10 | vercode: null
11 | },
12 | bindPhoneInput: function (e) {
13 | this.setData({
14 | vercode: e.detail.value
15 | })
16 | },
17 | toDeposits: function () {
18 | if (!/^\d{6}$/.test(this.data.vercode)) {
19 | console.log(this.data);
20 | wx.showToast({
21 | title: '请输入正确6位随机码',
22 | icon: 'none',
23 | duration: 1000
24 | })
25 | }
26 | else {
27 | console.log(this.data.vercode)
28 | wx.request({
29 | url: `${baseUrl}/takeout/enter/${this.data.vercode}`,
30 | method: 'GET',
31 | header: {
32 | "Content-type": "application/json"
33 | },
34 | success: (res) => {
35 | if (res.data.code === 200200) {
36 | app.globalData.vercode = this.data.vercode;
37 | wx.showToast({
38 | title: res.data.msg,
39 | icon: 'success',
40 | duration: 1000,
41 | success: () => {
42 | setTimeout(() => {
43 | wx.navigateTo({
44 | url: '../pickup/pickup',
45 | })
46 | }, 1000)
47 | }
48 | })
49 | } else {
50 | wx.showToast({
51 | title: res.data.msg,
52 | icon: 'none',
53 | duration: 1000
54 | })
55 | }
56 |
57 | }
58 | })
59 |
60 | }
61 |
62 |
63 | },
64 | /**
65 | * 生命周期函数--监听页面加载
66 | */
67 | onLoad: function (options) {
68 |
69 | },
70 |
71 | /**
72 | * 生命周期函数--监听页面初次渲染完成
73 | */
74 | onReady: function () {
75 |
76 | },
77 |
78 | /**
79 | * 生命周期函数--监听页面显示
80 | */
81 | onShow: function () {
82 |
83 | },
84 |
85 | /**
86 | * 生命周期函数--监听页面隐藏
87 | */
88 | onHide: function () {
89 |
90 | },
91 |
92 | /**
93 | * 生命周期函数--监听页面卸载
94 | */
95 | onUnload: function () {
96 |
97 | },
98 |
99 | /**
100 | * 页面相关事件处理函数--监听用户下拉动作
101 | */
102 | onPullDownRefresh: function () {
103 |
104 | },
105 |
106 | /**
107 | * 页面上拉触底事件的处理函数
108 | */
109 | onReachBottom: function () {
110 |
111 | },
112 |
113 | /**
114 | * 用户点击右上角分享
115 | */
116 | onShareAppMessage: function () {
117 |
118 | }
119 | })
--------------------------------------------------------------------------------
/智能快递柜/pages/index/login/login.js:
--------------------------------------------------------------------------------
1 | // pages/index/login/login.js
2 | let app = getApp();
3 | let globalData = app.globalData;
4 | let baseUrl = globalData.baseUrl;
5 | Page({
6 |
7 | /**
8 | * 页面的初始数据
9 | */
10 | data: {
11 | password: '',
12 | phone: ''
13 | },
14 | //方法
15 | bindPhoneInput: function (e) {
16 | this.setData({
17 | phone: e.detail.value
18 | })
19 | },
20 | bindPassInput: function (e) {
21 | this.setData({
22 | password: e.detail.value
23 | })
24 | },
25 | toRegiste: function () {
26 | wx.navigateTo({
27 | url: '../registe/registe',
28 | })
29 | },
30 | toEnter: function () {
31 | if (!/^1[345789]\d{9}$/.test(this.data.phone)) {
32 | console.log(this.data);
33 | wx.showToast({
34 | title: '请输入正确的手机格式',
35 | icon: 'none',
36 | duration: 1000
37 | })
38 | } else if (!/^\w{6,16}$/.test(this.data.password)) {
39 | console.log(this.data);
40 | wx.showToast({
41 | title: '请输入6至16位数字字母组成的密码',
42 | icon: 'none',
43 | duration: 1000
44 | })
45 | }
46 | else {
47 | wx.request({
48 | url: `${baseUrl}/user/login`,
49 | method: 'post',
50 | header: {
51 | "Content-type": "application/json"
52 | },
53 | data: {
54 | phone: this.data.phone,
55 | password: this.data.password
56 | },
57 | success: res => {
58 | console.log(res);
59 | if (res.data.code === 200200) {
60 | globalData.manid=res.data.manid;
61 | wx.showToast({
62 | title: res.data.msg,
63 | icon: 'success',
64 | duration: 1000,
65 | success: () => {
66 | setTimeout(() => {
67 | wx.navigateTo({
68 | url: '../enter/enter',
69 | })
70 | }, 1000)
71 | }
72 | })
73 | } else if (res.data.code === 200201 || 200202) {
74 | wx.showToast({
75 | title: res.data.msg,
76 | icon: 'none',
77 | duration: 1000
78 | })
79 | }
80 | },
81 | fail: err => {
82 | console.log(err.response);
83 | }
84 | })
85 |
86 |
87 | }
88 | },
89 | /**
90 | * 生命周期函数--监听页面加载
91 | */
92 | onLoad: function (options) {
93 | },
94 |
95 | /**
96 | * 生命周期函数--监听页面初次渲染完成
97 | */
98 | onReady: function () {
99 |
100 | },
101 |
102 | /**
103 | * 生命周期函数--监听页面显示
104 | */
105 | onShow: function () {
106 |
107 | },
108 |
109 | /**
110 | * 生命周期函数--监听页面隐藏
111 | */
112 | onHide: function () {
113 |
114 | },
115 |
116 | /**
117 | * 生命周期函数--监听页面卸载
118 | */
119 | onUnload: function () {
120 |
121 | },
122 |
123 | /**
124 | * 页面相关事件处理函数--监听用户下拉动作
125 | */
126 | onPullDownRefresh: function () {
127 |
128 | },
129 |
130 | /**
131 | * 页面上拉触底事件的处理函数
132 | */
133 | onReachBottom: function () {
134 |
135 | },
136 |
137 | /**
138 | * 用户点击右上角分享
139 | */
140 | onShareAppMessage: function () {
141 |
142 | }
143 | })
--------------------------------------------------------------------------------
/智能快递柜/pages/index/deposits/deposits.js:
--------------------------------------------------------------------------------
1 | // pages/index/deposits/deposits.js
2 | let app = getApp();
3 | let globalData = app.globalData;
4 | let baseUrl = globalData.baseUrl;
5 | Page({
6 |
7 | /**
8 | * 页面的初始数据
9 | */
10 | data: {
11 | chestid: ""
12 | },
13 | deposits: function () {
14 | wx.request({
15 | url: `${baseUrl}/deposits/sure`,
16 | method: 'POST',
17 | header: {
18 | "Content-type": "application/json"
19 | },
20 | data: {
21 | chestid: this.data.chestid,
22 | phone: globalData.phone,
23 | manid: globalData.manid
24 | },
25 | success: (res) => {
26 | console.log(res);
27 | if (res.data.code == 200200) {
28 | wx.showToast({
29 | title: res.data.msg,
30 | icon: 'success',
31 | duration: 1000,
32 | success: () => {
33 | wx.showToast({
34 | title: '存件成功',
35 | icon: 'success',
36 | duration: 1000,
37 | success: () => {
38 | setTimeout(() => {
39 | wx.navigateTo({
40 | url: `../depSucess/depSucess?chestid=${this.data.chestid}`,
41 | })
42 | }, 1000)
43 | }
44 | })
45 | }
46 | })
47 | }
48 | }
49 | })
50 |
51 |
52 | },
53 | /**
54 | * 生命周期函数--监听页面加载
55 | */
56 | onLoad: function (options) {
57 | wx.request({
58 | url: `${baseUrl}/deposits/find`,
59 | method: 'GET',
60 | header: {
61 | "Content-type": "application/json"
62 | },
63 | success: (res) => {
64 | if (res.data.code == 200200) {
65 | wx.showToast({
66 | title: res.data.msg,
67 | icon: 'success',
68 | duration: 1000,
69 | success: () => {
70 | this.setData({
71 | chestid: res.data.chestid
72 | });
73 | }
74 | })
75 | } else if (res.data.code == 200201) {
76 | wx.showToast({
77 | title: res.data.msg,
78 | icon: 'none',
79 | duration: 1000,
80 | success: () => {
81 | setTimeout(() => {
82 | wx.navigateBack({
83 | delta: 1
84 | })
85 | }, 1000)
86 | }
87 | })
88 | }
89 | }
90 | })
91 | },
92 |
93 | /**
94 | * 生命周期函数--监听页面初次渲染完成
95 | */
96 | onReady: function () {
97 |
98 | },
99 |
100 | /**
101 | * 生命周期函数--监听页面显示
102 | */
103 | onShow: function () {
104 |
105 | },
106 |
107 | /**
108 | * 生命周期函数--监听页面隐藏
109 | */
110 | onHide: function () {
111 |
112 | },
113 |
114 | /**
115 | * 生命周期函数--监听页面卸载
116 | */
117 | onUnload: function () {
118 |
119 | },
120 |
121 | /**
122 | * 页面相关事件处理函数--监听用户下拉动作
123 | */
124 | onPullDownRefresh: function () {
125 |
126 | },
127 |
128 | /**
129 | * 页面上拉触底事件的处理函数
130 | */
131 | onReachBottom: function () {
132 |
133 | },
134 |
135 | /**
136 | * 用户点击右上角分享
137 | */
138 | onShareAppMessage: function () {
139 |
140 | }
141 | })
--------------------------------------------------------------------------------
/node-koa2/controllers/takeout.js:
--------------------------------------------------------------------------------
1 | const APIError = require('../rest').APIError;
2 | const model = require('../model');
3 | const datetimeFormatUtil = require('../getTime')
4 | module.exports = {
5 |
6 | 'GET /api/takeout/enter/:vercode': async(ctx, next) => {
7 | let code = 200200;
8 | let msg = "查询成功";
9 | let vercode = ctx.params.vercode;
10 | let chest = model.chest;
11 | let onechest = await chest.findOne({
12 | where: {
13 | randcode: vercode
14 | }
15 | });
16 | if (!onechest) {
17 | code = 200201;
18 | msg = "匹配不到柜子,请重试";
19 | ctx.rest({
20 | code: code,
21 | msg: msg
22 | })
23 | } else {
24 | console.log(JSON.stringify(onechest));
25 | let chestid = onechest.chestid;
26 | ctx.rest({
27 | code: code,
28 | msg: msg,
29 | chestid: chestid
30 | })
31 | }
32 |
33 | },
34 |
35 | 'POST /api/takeout/sure': async(ctx, next) => {
36 | let code = 200200;
37 | let msg = "取件成功";
38 | let vercode = ctx.request.body.vercode;
39 | let chestid = ctx.request.body.chestid;
40 | let chest = model.chest;
41 | let takeout = model.takeout;
42 | let onechest = await chest.findOne({
43 | where: {
44 | randcode: vercode,
45 | chestid: chestid
46 | }
47 | });
48 | let manid = onechest.manid;
49 | let phone = onechest.phone;
50 | onechest.status = 0;
51 | onechest.randcode = null;
52 | onechest.phone = null;
53 | onechest.manid = null;
54 | await onechest.save();
55 | let now = datetimeFormatUtil(Date.now());
56 | let record = await takeout.create({
57 | chestid: chestid,
58 | manid: manid,
59 | phone: phone,
60 | randcode: vercode,
61 | time: now
62 | });
63 | ctx.rest({
64 | code: code,
65 | msg: msg,
66 | record: JSON.stringify(record)
67 | })
68 | },
69 | 'GET /api/takeout/success/:vercode': async(ctx, next) => {
70 | let code = 200200;
71 | let msg = "查询信息成功";
72 | let takeout = model.takeout;
73 | let man = model.man;
74 | let vercode = ctx.params.vercode;
75 |
76 | //根据randcode来查询记录的时间
77 | let onetakeout = await takeout.findOne({
78 | where: {
79 | randcode: vercode
80 | }
81 | })
82 | let phone = onetakeout.phone;
83 | let manid = onetakeout.manid;
84 | let chestid = onetakeout.chestid;
85 | let oneman = await man.findOne({
86 | where: {
87 | manid: manid
88 | }
89 | });
90 | let name = oneman.name;
91 | let company = oneman.company;
92 | let time = onetakeout.time;
93 |
94 | ctx.rest({
95 | code: code,
96 | msg: msg,
97 | time: time,
98 | mandid: manid,
99 | name: name,
100 | company: company,
101 | chestid: chestid,
102 | phone: phone
103 | });
104 | },
105 | };
--------------------------------------------------------------------------------
/node-koa2/controllers/deposits.js:
--------------------------------------------------------------------------------
1 | const APIError = require('../rest').APIError;
2 | const model = require('../model');
3 | const datetimeFormatUtil = require('../getTime')
4 | module.exports = {
5 |
6 | 'GET /api/deposits/find': async(ctx, next) => {
7 | let code = 200200;
8 | let msg = "查找到柜子";
9 | let chest = model.chest;
10 | let chests = await chest.findAll({
11 | where: {
12 | status: 0
13 | }
14 | });
15 | console.log(JSON.stringify(chests));
16 | if (chests.length == 0) {
17 | code = 200201;
18 | msg: "没有柜子可以用了"
19 | } else {
20 | let chestid = chests[0].chestid;
21 | ctx.rest({
22 | code: code,
23 | msg: msg,
24 | chestid: chestid
25 | });
26 | return;
27 | }
28 | ctx.rest({
29 | code: code,
30 | msg: msg
31 | });
32 |
33 | },
34 | 'POST /api/deposits/sure': async(ctx, next) => {
35 | let code = 200200;
36 | let msg = "存取成功";
37 | let chest = model.chest;
38 | let deposits = model.deposits;
39 | let chestid = ctx.request.body.chestid;
40 | let manid = ctx.request.body.manid;
41 | let phone = ctx.request.body.phone;
42 |
43 | //修改柜子状态成功
44 | let chests = await chest.findAll({
45 | where: {
46 | status: 0,
47 | chestid: chestid
48 | }
49 | });
50 | let randcode = Math.floor(Math.random() * (999999 - 100000 + 1) + 100000);
51 | chests[0].status = 1;
52 | chests[0].manid = manid;
53 | chests[0].phone = phone;
54 | chests[0].randcode = randcode;
55 | await chests[0].save();
56 |
57 | //增加存件记录
58 |
59 |
60 | let now = datetimeFormatUtil(Date.now());
61 | //获取当前的时间
62 | let record = await deposits.create({
63 | chestid: chestid,
64 | manid: manid,
65 | phone: phone,
66 | randcode: randcode,
67 | time: now
68 | });
69 | ctx.rest({
70 | code: code,
71 | msg: msg,
72 | record: JSON.stringify(record)
73 | });
74 | return;
75 |
76 | },
77 | 'GET /api/deposits/success/:chestid': async(ctx, next) => {
78 | let code = 200200;
79 | let msg = "查询信息成功";
80 | let chest = model.chest;
81 | let man = model.man;
82 | let deposit = model.deposits;
83 | let chestid = ctx.params.chestid;
84 | //查询存件的chest表
85 | let onechest = await chest.findOne({
86 | where: {
87 | chestid: chestid
88 | }
89 | });
90 | let manid = onechest.manid;
91 | let randcode = onechest.randcode;
92 | //根据chest表,根据chestid查到manid,然后到man去查
93 | let oneman = await man.findOne({
94 | where: {
95 | manid: manid
96 | }
97 | });
98 | //根据randcode来查询记录的时间
99 | let onedeposit = await deposit.findOne({
100 | where: {
101 | randcode: randcode
102 | }
103 | })
104 | let name = oneman.name;
105 | let company = oneman.company;
106 | let phone = onechest.phone;
107 | let time = onedeposit.time;
108 | ctx.rest({
109 | code: code,
110 | msg: msg,
111 | time: time,
112 | mandid: manid,
113 | name: name,
114 | company: company,
115 | chestid: chestid,
116 | phone: phone
117 | });
118 | },
119 |
120 |
121 | };
--------------------------------------------------------------------------------
/智能快递柜/pages/index/registe/registe.js:
--------------------------------------------------------------------------------
1 | // pages/index/registe/registe.js
2 | let app = getApp();
3 | let globalData = app.globalData;
4 | let baseUrl = globalData.baseUrl;
5 | Page({
6 |
7 | /**
8 | * 页面的初始数据
9 | */
10 | data: {
11 | array: ['申通快递', '圆通快递', '韵达快递', '顺丰快递'],
12 | index: 0,
13 | name: "",
14 | phone: '',
15 | pw: "",
16 | repw: ""
17 | },
18 | //方法
19 | bindPickerChange: function (e) {
20 | console.log('picker发送选择改变,携带值为', e.detail.value)
21 | this.setData({
22 | index: e.detail.value
23 | })
24 | },
25 | bindNameInput: function (e) {
26 | this.setData({
27 | name: e.detail.value
28 | })
29 | },
30 | bindPhoneInput: function (e) {
31 | this.setData({
32 | phone: e.detail.value
33 | })
34 | },
35 | bindPwInput: function (e) {
36 | this.setData({
37 | pw: e.detail.value
38 | })
39 | },
40 | bindRepwInput: function (e) {
41 | this.setData({
42 | repw: e.detail.value
43 | })
44 | },
45 | registe: function () {
46 | if (this.data.name.length > 16 || this.data.name.length < 2) {
47 | console.log(this.data);
48 | wx.showToast({
49 | title: '请输入正确的姓名',
50 | icon: 'none',
51 | duration: 1000
52 | })
53 | } else if (!/^1[345789]\d{9}$/.test(this.data.phone)) {
54 | console.log(this.data);
55 | wx.showToast({
56 | title: '请输入正确的手机格式',
57 | icon: 'none',
58 | duration: 1000
59 | })
60 | } else if (!/^\w{6,16}$/.test(this.data.pw)) {
61 | console.log(this.data);
62 | wx.showToast({
63 | title: '请输入6至16位数字字母组成的密码',
64 | icon: 'none',
65 | duration: 1000
66 | })
67 | } else if (this.data.pw !== this.data.repw) {
68 | console.log(this.data);
69 | wx.showToast({
70 | title: '两次密码输入不一致',
71 | icon: 'none',
72 | duration: 1000
73 | })
74 | }
75 | else {
76 | wx.request({
77 | url: `${baseUrl}/user/register`,
78 | method: 'post',
79 | header: {
80 | "Content-type": "application/json"
81 | },
82 | data: {
83 | name: this.data.name,
84 | password: this.data.pw,
85 | phone: this.data.phone,
86 | company: this.data.array[this.data.index]
87 | },
88 | success: (res) => {
89 | console.log(res);
90 | if (res.data.code == 200200) {
91 | wx.showToast({
92 | title: res.data.msg,
93 | icon: 'success',
94 | duration: 1000,
95 | success: () => {
96 | setTimeout(() => {
97 | wx.navigateTo({
98 | url: '../login/login',
99 | })
100 | }, 1000)
101 | }
102 | })
103 | }else if(res.data.code==200201){
104 | wx.showToast({
105 | title: res.data.msg,
106 | icon: 'none',
107 | duration: 1000
108 | })
109 | }
110 | },
111 | fail: (err) => {
112 |
113 | }
114 | })
115 |
116 |
117 | }
118 | },
119 | /**
120 | * 生命周期函数--监听页面加载
121 | */
122 | onLoad: function (options) {
123 |
124 | },
125 |
126 | /**
127 | * 生命周期函数--监听页面初次渲染完成
128 | */
129 | onReady: function () {
130 |
131 | },
132 |
133 | /**
134 | * 生命周期函数--监听页面显示
135 | */
136 | onShow: function () {
137 |
138 | },
139 |
140 | /**
141 | * 生命周期函数--监听页面隐藏
142 | */
143 | onHide: function () {
144 |
145 | },
146 |
147 | /**
148 | * 生命周期函数--监听页面卸载
149 | */
150 | onUnload: function () {
151 |
152 | },
153 |
154 | /**
155 | * 页面相关事件处理函数--监听用户下拉动作
156 | */
157 | onPullDownRefresh: function () {
158 |
159 | },
160 |
161 | /**
162 | * 页面上拉触底事件的处理函数
163 | */
164 | onReachBottom: function () {
165 |
166 | },
167 |
168 | /**
169 | * 用户点击右上角分享
170 | */
171 | onShareAppMessage: function () {
172 |
173 | }
174 | })
--------------------------------------------------------------------------------
/kuaidi.sql:
--------------------------------------------------------------------------------
1 | /*
2 | Navicat MySQL Data Transfer
3 |
4 | Source Server : localmysql
5 | Source Server Version : 50721
6 | Source Host : localhost:3306
7 | Source Database : kuaidi
8 |
9 | Target Server Type : MYSQL
10 | Target Server Version : 50721
11 | File Encoding : 65001
12 |
13 | Date: 2018-03-05 18:02:14
14 | */
15 |
16 | SET FOREIGN_KEY_CHECKS=0;
17 |
18 | -- ----------------------------
19 | -- Table structure for chest
20 | -- ----------------------------
21 | DROP TABLE IF EXISTS `chest`;
22 | CREATE TABLE `chest` (
23 | `chestid` int(11) unsigned NOT NULL AUTO_INCREMENT,
24 | `phone` varchar(11) DEFAULT NULL,
25 | `randcode` int(6) DEFAULT NULL,
26 | `status` tinyint(1) NOT NULL DEFAULT '0',
27 | `manid` int(11) DEFAULT NULL,
28 | PRIMARY KEY (`chestid`)
29 | ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4;
30 |
31 | -- ----------------------------
32 | -- Records of chest
33 | -- ----------------------------
34 | INSERT INTO `chest` VALUES ('1', null, null, '0', null);
35 | INSERT INTO `chest` VALUES ('2', null, null, '0', null);
36 | INSERT INTO `chest` VALUES ('3', null, null, '0', null);
37 | INSERT INTO `chest` VALUES ('4', null, null, '0', null);
38 | INSERT INTO `chest` VALUES ('5', null, null, '0', null);
39 | INSERT INTO `chest` VALUES ('6', null, null, '0', null);
40 | INSERT INTO `chest` VALUES ('7', null, null, '0', null);
41 | INSERT INTO `chest` VALUES ('8', null, null, '0', null);
42 | INSERT INTO `chest` VALUES ('9', null, null, '0', null);
43 | INSERT INTO `chest` VALUES ('10', null, null, '0', null);
44 |
45 | -- ----------------------------
46 | -- Table structure for deposit
47 | -- ----------------------------
48 | DROP TABLE IF EXISTS `deposit`;
49 | CREATE TABLE `deposit` (
50 | `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
51 | `chestid` int(11) NOT NULL,
52 | `manid` int(11) NOT NULL,
53 | `phone` varchar(11) NOT NULL,
54 | `randcode` int(6) NOT NULL,
55 | `time` datetime NOT NULL,
56 | PRIMARY KEY (`id`)
57 | ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4;
58 |
59 | -- ----------------------------
60 | -- Records of deposit
61 | -- ----------------------------
62 | INSERT INTO `deposit` VALUES ('4', '1', '1', '13434998099', '462968', '2018-03-05 07:15:16');
63 | INSERT INTO `deposit` VALUES ('5', '1', '8', '13005416332', '858474', '2018-03-05 09:04:38');
64 | INSERT INTO `deposit` VALUES ('6', '2', '8', '13005416332', '420571', '2018-03-05 09:07:29');
65 | INSERT INTO `deposit` VALUES ('7', '3', '8', '13005416332', '870481', '2018-03-05 09:17:47');
66 | INSERT INTO `deposit` VALUES ('8', '1', '8', '13005416332', '400864', '2018-03-05 09:48:36');
67 | INSERT INTO `deposit` VALUES ('9', '1', '8', '13434998099', '389358', '2018-03-05 09:55:31');
68 |
69 | -- ----------------------------
70 | -- Table structure for man
71 | -- ----------------------------
72 | DROP TABLE IF EXISTS `man`;
73 | CREATE TABLE `man` (
74 | `manid` int(11) unsigned NOT NULL AUTO_INCREMENT,
75 | `name` varchar(255) NOT NULL,
76 | `phone` varchar(11) NOT NULL,
77 | `password` varchar(20) NOT NULL,
78 | `company` varchar(255) NOT NULL,
79 | PRIMARY KEY (`manid`)
80 | ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4;
81 |
82 | -- ----------------------------
83 | -- Records of man
84 | -- ----------------------------
85 | INSERT INTO `man` VALUES ('1', 'jgchen', '13434998095', '13434998099', '深圳大学');
86 | INSERT INTO `man` VALUES ('2', '陈建光', '13434998090', '13434998099', '申通快递');
87 | INSERT INTO `man` VALUES ('3', '陈建光', '13434998091', '13434998099', '申通快递');
88 | INSERT INTO `man` VALUES ('4', '陈建光', '13434998092', '13434998099', '申通快递');
89 | INSERT INTO `man` VALUES ('5', '陈建光', '13434998093', '13434998099', '申通快递');
90 | INSERT INTO `man` VALUES ('6', '陈建光', '13434998094', '13434998099', '申通快递');
91 | INSERT INTO `man` VALUES ('7', '王馨', '13005416332', '13434998099', '申通快递');
92 | INSERT INTO `man` VALUES ('8', '隔壁老王', '13434998099', '13434998099', '顺丰快递');
93 |
94 | -- ----------------------------
95 | -- Table structure for takeout
96 | -- ----------------------------
97 | DROP TABLE IF EXISTS `takeout`;
98 | CREATE TABLE `takeout` (
99 | `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
100 | `chestid` int(11) NOT NULL,
101 | `manid` int(11) NOT NULL,
102 | `phone` varchar(11) NOT NULL,
103 | `randcode` int(6) NOT NULL,
104 | `time` datetime NOT NULL,
105 | PRIMARY KEY (`id`)
106 | ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4;
107 |
108 | -- ----------------------------
109 | -- Records of takeout
110 | -- ----------------------------
111 | INSERT INTO `takeout` VALUES ('1', '2', '1', '13434998099', '412855', '2018-03-05 08:38:41');
112 | INSERT INTO `takeout` VALUES ('2', '2', '8', '13005416332', '420571', '2018-03-05 09:43:27');
113 | INSERT INTO `takeout` VALUES ('3', '3', '8', '13005416332', '870481', '2018-03-05 09:44:27');
114 | INSERT INTO `takeout` VALUES ('4', '1', '8', '13005416332', '858474', '2018-03-05 09:47:21');
115 | INSERT INTO `takeout` VALUES ('5', '1', '8', '13005416332', '400864', '2018-03-05 09:48:52');
116 | INSERT INTO `takeout` VALUES ('6', '1', '8', '13434998099', '389358', '2018-03-05 09:56:51');
117 |
--------------------------------------------------------------------------------