Подключение Google API, отслеживание передвижения, Router
24.01.2019, 19:10. Показов 953. Ответов 0
Добрый день! Я недавно взялся изучать JS и Node и возникли некоторые вопросы.
Есть такое учебное задание для веб-приложения, спроектированного по REST:
Алекс является оператором небольшой пиццерии в городе. Чтобы расширить свою клиентуру, он решил в прошлом году предложить услугу доставки,но ему трудно правильно координировать поставки. Несколько водителей перевозят заказы по разным адресам в этом районе и поскольку Алекс не знает, как выглядит текущее состояние заказов и где находится курьер, ему и его сотрудникам сложно оптимально планировать поездки. Часто новые заказы добавляются, когда все курьеры находятся в пути. Пока что Алекс пытается выяснить по телефону, какой из курьеров должен логически принять новую доставку из пиццерии.
Таким образом, веб-приложение должно
1. Отслеживать трекинг курьеров в реальном времени через Google Maps API
2. Отслеживать состояние заказов, то есть, если пришел заказ, а все машины в пути, то из управления можно посмотреть, какая машина ближе и сколько у нее активных заказов и передать ей инструкцию, чтобы она заезжала за новым заказом (управление ивентами через Pusher)
3. Заказы можно удалить, обновить.
Засим у меня вопрос: Как правильно прикрутить этот google Maps API и использовать Pusher, так, чтобы это все работало совместно с модулями orders и suppliers, притом данные хранились в MongoDB?
Туториал по прикрутке Google API и Pusher для трекинга взять отсюда:
https://blog.pusher.com/track-... ogle-maps/ Git Репозиторий: https://github.com/ankeetmaini/food-express
Есть понимание общей концепции, но у меня нет пока опыта в прикрутке. Или надо "разбить" все тоже на модули? Но как?
К тому же, есть вопросы, правильно ли реализована коммуникация с модулями в app.js.
app.js начальный "чистый" вариант:
| JavaScript | 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
27
28
29
30
31
32
33
34
| const express = require('express')
const http = require('http')
const bodyparser = require('body-parser')
// PizzaNodes app Server Setup
const app = express(),
server = http.createServer(app)
// Bodyparser
app.use(bodyparser.json())
app.use(bodyparser.urlencoded({extended: false}))
// Routes
const supplierRoutes = require('./routes/suppliers')
const orderRoutes = require('./routes/orders')
// Server Setup / Connections
server.listen(3000, () => {
})
// Konfigurationen für 'Accessability' => Clients außerhalb des Servers können auf diese REST API zugreifen
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization')
if (req.method === 'OPTIONS') {
res.header('Acces-Control-Allow-Methods', 'PATCH, POST, GET, DELETE')
return res.status(200).json({})
}
next()
})
// Middleware supplierRoutes
app.use('/suppliers', supplierRoutes)
app.use('/orders', orderRoutes) |
|
router/orders.js
| JavaScript | 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
| const express = require('express')
const http = require('http')
const router = express.Router()
// MongoDB & Mongoose
const Supplier = require('../schemas/supplierSchema')
const Order = require('../schemas/orderSchema')
const MongoClient = require('mongodb').MongoClient
const assert = require('assert')
const mongoose = require('mongoose')
const url = 'mongodb://localhost:27017'
const dbname = 'pizzanodes'
const client = new MongoClient(url);
mongoose.connect('mongodb://localhost:27017')
//Mongoose methods
router.get('/:_id', (req, res, next) => {
Order.findOne({_id: req.params._id}, (err, result) => {
if (err) throw err
res.send(result)
})
})
router.get('/', (req, res, next) => {
Order.find({}).select('_id customer products link').exec((err, result) => {
if (err) res.send(err.message)
res.send(result)
})
})
router.patch('/:_id', (req, res, next) => {
Order.update({_id: req.params._id}, {
$set: {
customer: req.body.customer,
products: req.body.products
}
}, (err, result) => {
if (err) res.send(err.message)
res.send(result)
})
})
router.post('/', (req, res, next) => {
let _id = new mongoose.Types.ObjectId()
const order = new Order({
_id: _id,
customer: req.body.customer,
products: req.body.products,
orderlink: "http://localhost:3000/orders/" + _id
})
order.save()
res.send("Order " + req.body.customer + " created")
})
router.delete('/:_id', ((req, res, next) => {
Order.deleteOne({_id: req.params._id}, (err) => {
if (err) res.send(err.message)
res.send("Order " + req.params._id + " deleted")
})
}))
module.exports = router |
|
router/supplier.js
| JavaScript | 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
| const express = require('express')
const http = require('http')
const router = express.Router()
// MongoDB & Mongoose
const Supplier = require('../schemas/supplierSchema')
const MongoClient = require('mongodb').MongoClient
const assert = require('assert')
const mongoose = require('mongoose')
const url = 'mongodb://localhost:27017'
const dbname = 'pizzanodes'
const client = new MongoClient(url);
mongoose.connect('mongodb://localhost:27017')
//Mongoose Methoden
router.get('/:_id', (req, res, next) => {
Supplier.findOne({_id: req.params._id}, (err, result) => {
if (err) throw err
res.send(result)
})
})
router.get('/', (req, res, next) => {
Supplier.find({}).select('_id name orders').exec((err, result) => {
if (err) res.send(err.message)
res.send(result)
})
})
router.patch('/:_id', (req, res, next) => {
Supplier.update({_id: req.params._id}, {$set: {orders: req.body.orders}}, (err, result) => {
if (err) res.send(err.message)
res.send(result)
})
})
router.post('/', (req, res, next) => {
const supplier = new Supplier({
_id: new mongoose.Types.ObjectId(),
name: req.body.name,
orders: req.body.orders
})
supplier.save()
res.send("Supplier " + req.body.name + " created")
})
router.delete('/:_id', ((req, res, next) => {
Supplier.deleteOne({_id: req.params._id}, (err) => {
if (err) res.send(err.message)
res.send("Supplier " + req.params._id + " deleted")
})
}))
router.delete
module.exports = router |
|
schema/orderSchema.js
| JavaScript | 1
2
3
4
5
6
7
8
9
10
11
| const mongoose = require('mongoose')
const orderSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
customer: {type: String, required: true},
products: {type: [String], required: true},
orderlink: {type: String, required: true}
})
const Order = mongoose.model('Order', orderSchema)
module.exports = Order |
|
schema/supplierSchema.js
| JavaScript | 1
2
3
4
5
6
7
8
9
10
| const mongoose = require('mongoose')
const supplierSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: {type: String, required: true},
orders: {type: [String]}
})
const Supplier = mongoose.model('Supplier', supplierSchema)
module.exports = Supplier |
|
app.js с добавлением pusher и карт
| JavaScript | 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
| const express = require('express');
const http = require('http');
const bodyparser = require('body-parser');
const Pusher = require('pusher');
// PizzaNodes app Server Setup
const app = express(),
server = http.createServer(app)
// Bodyparser
app.use(bodyparser.json())
app.use(bodyparser.urlencoded({extended: false}))
// Routes
const supplierRoutes = require('./routes/suppliers')
const orderRoutes = require('./routes/orders')
const openweather = require('./routes/openweatherApi')
// Server Setup / Connections
server.listen(3000, () => {
})
// Konfigurationen für 'Accessability' => Clients außerhalb des Servers können auf diese REST API zugreifen
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*')
res.header('Acess-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization')
if (req.method === 'OPTIONS') {
res.header('Acces-Control-Allow-Methods', 'PATCH, POST, GET, DELETE')
return res.status(200).json({})
}
next()
})
// Middleware supplierRoutes
app.use('/suppliers', supplierRoutes)
app.use('/orders', orderRoutes)
(function () {
var username;
// reference for DOM nodes
var saveNameButton = document.getElementById('saveNameButton');
var saveNameBox = document.getElementById('name-box');
var nameInput = document.getElementById('name');
var welcomeHeading = document.getElementById('welcome-message');
var deliveryHeroBox = document.getElementById('delivery-hero-box');
var deliveryHeroesAddButton = document.getElementById('addDeliveryHeroButton');
var deliveryHeroNameInput = document.getElementById('deliveryHeroName');
var deliveryHeroesList = document.getElementById('delivery-heroes-list');
// handy variables
var locationWatcher;
var myLastKnownLocation;
var sendLocationInterval;
var deliveryHeroesLocationMap = {};
var deliveryHeroesMarkerMap = {};
// mode - user's or delivery guy's
var mode = getUrlParameter('mode') || 'user';
// load the map
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 14
});
// get the location via Geolocation API
if ('geolocation' in navigator) {
var currentLocation = navigator.geolocation.getCurrentPosition(function (position) {
// save my last location
var location = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
myLastKnownLocation = location;
map.setCenter(location);
});
}
// initialize pusher
var pusher = new Pusher('sjdhuh43372344656', {
cluster: 'eu',
encrypted: true
});
// add eventlisteners
saveNameButton.addEventListener('click', saveName);
deliveryHeroesAddButton.addEventListener('click', addDeliveryHero);
// all functions, event handlers
function saveName (e) {
var input = nameInput.value;
if (input && input.trim()) {
username = input;
// hide the name box
saveNameBox.classList.add('hidden');
// set the name
welcomeHeading.innerHTML = 'Hi! <strong>' + username +
(mode === 'user'
? '</strong>, type in your Delivery Hero\'s name to track your food.'
: '</strong>, type in the customer name to locate the address');
// show the delivery hero's div now
deliveryHeroBox.classList.remove('hidden');
// create a private channel with the username
createMyLocationChannel(username);
}
return;
}
function addDeliveryHero (e) {
var deliveryHeroName = deliveryHeroNameInput.value;
// if already present return
if (deliveryHeroesLocationMap[deliveryHeroName]) return;
if (deliveryHeroName) {
var deliveryHeroChannelName = 'private-' + deliveryHeroName;
var deliveryHeroChannel = pusher.subscribe(deliveryHeroChannelName);
deliveryHeroChannel.bind('client-location', function (nextLocation) {
// first save the location
// bail if location is same
var prevLocation = deliveryHeroesLocationMap[deliveryHeroName] || {};
deliveryHeroesLocationMap[deliveryHeroName] = nextLocation;
showDeliveryHeroOnMap(deliveryHeroName, false, true, prevLocation);
});
}
// add the name to the list
var deliveryHeroTrackButton = document.createElement('button');
deliveryHeroTrackButton.classList.add('small');
deliveryHeroTrackButton.innerHTML = deliveryHeroName;
deliveryHeroTrackButton.addEventListener('click', showDeliveryHeroOnMap.bind(null, deliveryHeroName, true, false, {}));
deliveryHeroesList.appendChild(deliveryHeroTrackButton);
}
function showDeliveryHeroOnMap (deliveryHeroName, center, addMarker, prevLocation) {
if (!deliveryHeroesLocationMap[deliveryHeroName]) return;
// first center the map
if (center) map.setCenter(deliveryHeroesLocationMap[deliveryHeroName]);
var nextLocation = deliveryHeroesLocationMap[deliveryHeroName];
// add a marker
if ((prevLocation.lat === nextLocation.lat) && (prevLocation.lng === nextLocation.lng)) {
return;
}
if (addMarker) {
var marker = deliveryHeroesMarkerMap[deliveryHeroName];
marker = marker || new google.maps.Marker({
map: map,
label: deliveryHeroName,
animation: google.maps.Animation.BOUNCE,
});
marker.setPosition(deliveryHeroesLocationMap[deliveryHeroName]);
deliveryHeroesMarkerMap[deliveryHeroName] = marker;
}
}
function triggerLocationChangeEvents (channel, location) {
// update myLastLocation
myLastKnownLocation = location;
channel.trigger('client-location', location);
}
function createMyLocationChannel (name) {
var myLocationChannel = pusher.subscribe('private-' + name);
myLocationChannel.bind('pusher:subscription_succeeded', function() {
// safe to now trigger events
// use the watchPosition API to watch the changing location
// and trigger events with new coordinates
locationWatcher = navigator.geolocation.watchPosition(function(position) {
var location = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
triggerLocationChangeEvents(myLocationChannel, location);
});
// also start a setInterval to keep sending the loction every 5 secs
sendLocationInterval = setInterval(function () {
// not using `triggerLocationChangeEvents` to keep the pipes different
myLocationChannel.trigger('client-location', myLastKnownLocation)
}, 5000);
});
}
// function to get a query param's value
function getUrlParameter(name) {
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
var results = regex.exec(location.search);
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
}
}()); |
|
server.js
| JavaScript | 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
27
28
| var express = require('express');
var bodyParser = require('body-parser');
var Pusher = require('pusher');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// to serve our JavaScript, CSS and index.html
app.use(express.static('./'));
var pusher = new Pusher({
appId: '6982244445',
key: 'abdf4534545b1a0897b58e79214',
secret: '3247623462332423423',
cluster: 'eu'
});
app.post('/pusher/auth', function(req, res) {
var socketId = req.body.socket_id;
var channel = req.body.channel_name;
var auth = pusher.authenticate(socketId, channel);
res.send(auth);
});
var port = process.env.PORT || 3000;
app.listen(port, () => console.log('Listening at http://localhost:3000')); |
|
0
|