Showing
8 changed files
with
1914 additions
and
65 deletions
... | @@ -8,6 +8,7 @@ const Mongoose = require('mongoose'); | ... | @@ -8,6 +8,7 @@ const Mongoose = require('mongoose'); |
8 | const api = require('./src/api'); | 8 | const api = require('./src/api'); |
9 | const MqttServer = require('./src/util/MqttServer'); | 9 | const MqttServer = require('./src/util/MqttServer'); |
10 | const BatchSystem = require('./src/util/Batch'); | 10 | const BatchSystem = require('./src/util/Batch'); |
11 | +const FCM = require('./src/util/FCM'); | ||
11 | 12 | ||
12 | require('dotenv').config(); | 13 | require('dotenv').config(); |
13 | // eslint-disable-next-line no-undef | 14 | // eslint-disable-next-line no-undef |
... | @@ -37,5 +38,7 @@ app.use(router.routes()).use(router.allowedMethods()); | ... | @@ -37,5 +38,7 @@ app.use(router.routes()).use(router.allowedMethods()); |
37 | app.listen(SERVER_PORT, () => { | 38 | app.listen(SERVER_PORT, () => { |
38 | console.log('\x1b[1;36mPORT : ', SERVER_PORT, 'is connected\x1b[0m'); | 39 | console.log('\x1b[1;36mPORT : ', SERVER_PORT, 'is connected\x1b[0m'); |
39 | MqttServer.on(); | 40 | MqttServer.on(); |
40 | - BatchSystem.PushNotifyByDosage(); | 41 | + FCM.initializeFCM(); |
42 | + BatchSystem.removeQrCode(); | ||
43 | + BatchSystem.pushNotifyByDosage(); | ||
41 | }); | 44 | }); |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
This diff could not be displayed because it is too large.
... | @@ -19,6 +19,7 @@ | ... | @@ -19,6 +19,7 @@ |
19 | "dependencies": { | 19 | "dependencies": { |
20 | "@google-cloud/storage": "^5.14.2", | 20 | "@google-cloud/storage": "^5.14.2", |
21 | "@koa/cors": "^3.1.0", | 21 | "@koa/cors": "^3.1.0", |
22 | + "firebase-admin": "^9.11.1", | ||
22 | "koa-body": "^4.2.0", | 23 | "koa-body": "^4.2.0", |
23 | "moment": "^2.29.1", | 24 | "moment": "^2.29.1", |
24 | "moment-timezone": "^0.5.33", | 25 | "moment-timezone": "^0.5.33", | ... | ... |
... | @@ -17,6 +17,7 @@ exports.register = async(ctx) => { | ... | @@ -17,6 +17,7 @@ exports.register = async(ctx) => { |
17 | userNm, | 17 | userNm, |
18 | birth, | 18 | birth, |
19 | contact, | 19 | contact, |
20 | + deviceToken, | ||
20 | } = ctx.request.body; | 21 | } = ctx.request.body; |
21 | 22 | ||
22 | const schema = Joi.object().keys({ | 23 | const schema = Joi.object().keys({ |
... | @@ -59,6 +60,7 @@ exports.register = async(ctx) => { | ... | @@ -59,6 +60,7 @@ exports.register = async(ctx) => { |
59 | userNm, | 60 | userNm, |
60 | birth, | 61 | birth, |
61 | contact, | 62 | contact, |
63 | + deviceToken, | ||
62 | }); | 64 | }); |
63 | 65 | ||
64 | await user.save(); | 66 | await user.save(); |
... | @@ -192,7 +194,7 @@ exports.doctorRegister = async ctx => { | ... | @@ -192,7 +194,7 @@ exports.doctorRegister = async ctx => { |
192 | } | 194 | } |
193 | 195 | ||
194 | exports.login = async(ctx) => { | 196 | exports.login = async(ctx) => { |
195 | - const { userId, password } = ctx.request.body; | 197 | + const { userId, password, deviceToken } = ctx.request.body; |
196 | 198 | ||
197 | const schema = Joi.object().keys({ | 199 | const schema = Joi.object().keys({ |
198 | userId : Joi.string().email().max(50).required(), | 200 | userId : Joi.string().email().max(50).required(), |
... | @@ -225,7 +227,6 @@ exports.login = async(ctx) => { | ... | @@ -225,7 +227,6 @@ exports.login = async(ctx) => { |
225 | }; | 227 | }; |
226 | return; | 228 | return; |
227 | } | 229 | } |
228 | - | ||
229 | if(user.useYn !== 'Y') { | 230 | if(user.useYn !== 'Y') { |
230 | ctx.status = 403; | 231 | ctx.status = 403; |
231 | ctx.body = { | 232 | ctx.body = { |
... | @@ -234,6 +235,16 @@ exports.login = async(ctx) => { | ... | @@ -234,6 +235,16 @@ exports.login = async(ctx) => { |
234 | return; | 235 | return; |
235 | } | 236 | } |
236 | 237 | ||
238 | + //일반 유저의 deviceToken값이 바뀌면 업데이트한다 = 기기가 바뀌면 | ||
239 | + if(user.userTypeCd === 'NORMAL') { | ||
240 | + const profile = await Profile.findByUserId(user.userId); | ||
241 | + if(deviceToken && profile.deviceToken !== deviceToken) { | ||
242 | + profile.updateDeviceToken(deviceToken); | ||
243 | + await profile.save(); | ||
244 | + } | ||
245 | + } | ||
246 | + | ||
247 | + | ||
237 | const token = await user.generateToken(); | 248 | const token = await user.generateToken(); |
238 | ctx.cookies.set('access_token', token, { | 249 | ctx.cookies.set('access_token', token, { |
239 | httpOnly : true, | 250 | httpOnly : true, |
... | @@ -243,7 +254,7 @@ exports.login = async(ctx) => { | ... | @@ -243,7 +254,7 @@ exports.login = async(ctx) => { |
243 | ctx.status = 200; | 254 | ctx.status = 200; |
244 | ctx.body = { | 255 | ctx.body = { |
245 | userTypeCd : user.userTypeCd, | 256 | userTypeCd : user.userTypeCd, |
246 | - token | 257 | + token, |
247 | }; | 258 | }; |
248 | 259 | ||
249 | }; | 260 | }; | ... | ... |
... | @@ -6,15 +6,18 @@ | ... | @@ -6,15 +6,18 @@ |
6 | * 1) Dosage에 따라, Push Notification 발송 | 6 | * 1) Dosage에 따라, Push Notification 발송 |
7 | */ | 7 | */ |
8 | 8 | ||
9 | - const cron = require('node-cron'); | 9 | +const cron = require('node-cron'); |
10 | +const fs = require('fs'); | ||
10 | 11 | ||
11 | - const Profile = require('../models/profile'); | 12 | +const Profile = require('../models/profile'); |
12 | - const User = require('../models/user'); | 13 | +const User = require('../models/user'); |
13 | - const Hub = require('../models/hub'); | 14 | +const Hub = require('../models/hub'); |
14 | - const Bottle = require('../models/bottle'); | 15 | +const Bottle = require('../models/bottle'); |
15 | - const BottleMedicine = require('../models/bottleMedicine'); | 16 | +const BottleMedicine = require('../models/bottleMedicine'); |
17 | +const Medicine = require('../models/medicine'); | ||
16 | 18 | ||
17 | const updateMedicineInfo = require('../lib/UpdatingMedicineInfo'); | 19 | const updateMedicineInfo = require('../lib/UpdatingMedicineInfo'); |
20 | +const { sendPushMessage } = require('./FCM'); | ||
18 | 21 | ||
19 | 22 | ||
20 | // //매년 1월 1일 00시 00분에 1살씩 추가 | 23 | // //매년 1월 1일 00시 00분에 1살씩 추가 |
... | @@ -35,12 +38,27 @@ const updateMedicineInfo = require('../lib/UpdatingMedicineInfo'); | ... | @@ -35,12 +38,27 @@ const updateMedicineInfo = require('../lib/UpdatingMedicineInfo'); |
35 | exports.updateMedicineData = async () => { | 38 | exports.updateMedicineData = async () => { |
36 | cron.schedule('0 0 0 1 * *', () => { | 39 | cron.schedule('0 0 0 1 * *', () => { |
37 | updateMedicineInfo.updateMedicineInfo(); | 40 | updateMedicineInfo.updateMedicineInfo(); |
41 | + }, { | ||
42 | + timezone : 'Asia/Tokyo', | ||
43 | + }); | ||
44 | +}; | ||
45 | + | ||
46 | +//매주 일요일마다 불필요한 qrcode 제거 | ||
47 | +exports.removeQrCode = () => { | ||
48 | + cron.schedule('0 0 0 * * 0', () => { | ||
49 | + // eslint-disable-next-line no-undef | ||
50 | + const qrDir = process.env.QR_DIR; | ||
51 | + fs.rm(qrDir, { recursive : true, force : true, }, () => { | ||
52 | + fs.mkdir(qrDir, (err) => { if(err) console.log(err) }); | ||
53 | + }); | ||
54 | + }, { | ||
55 | + timezone : 'Asia/Tokyo', | ||
38 | }); | 56 | }); |
39 | }; | 57 | }; |
40 | 58 | ||
41 | //dosage에 따라, Push Notification을 발송한다. | 59 | //dosage에 따라, Push Notification을 발송한다. |
42 | //아침 8시, 점심 12시, 저녁 6시에 한번씩 발송 | 60 | //아침 8시, 점심 12시, 저녁 6시에 한번씩 발송 |
43 | - exports.PushNotifyByDosage = async() => { | 61 | +exports.pushNotifyByDosage = async() => { |
44 | 62 | ||
45 | //매일 아침 8시 : 복용량 상관 없이 보냄 | 63 | //매일 아침 8시 : 복용량 상관 없이 보냄 |
46 | cron.schedule('0 0 8 * * *', async () => { | 64 | cron.schedule('0 0 8 * * *', async () => { |
... | @@ -52,9 +70,15 @@ exports.updateMedicineData = async () => { | ... | @@ -52,9 +70,15 @@ exports.updateMedicineData = async () => { |
52 | 70 | ||
53 | if(user) { | 71 | if(user) { |
54 | const profile = await Profile.findOne({ userId : user.userId }); | 72 | const profile = await Profile.findOne({ userId : user.userId }); |
55 | - | ||
56 | const { deviceToken } = profile; | 73 | const { deviceToken } = profile; |
57 | - PushNotify(deviceToken); | 74 | + |
75 | + if(deviceToken) { | ||
76 | + const medicine = await Medicine.findOne({ medicineId : bottleMedicine.medicineId }); | ||
77 | + pushNotify({ | ||
78 | + deviceToken, | ||
79 | + message : medicine.name + '을 복용하셔야 합니다.', | ||
80 | + }); | ||
81 | + } | ||
58 | } | 82 | } |
59 | }); | 83 | }); |
60 | }, { | 84 | }, { |
... | @@ -72,9 +96,15 @@ exports.updateMedicineData = async () => { | ... | @@ -72,9 +96,15 @@ exports.updateMedicineData = async () => { |
72 | 96 | ||
73 | if(user) { | 97 | if(user) { |
74 | const profile = await Profile.findOne({ userId : user.userId }); | 98 | const profile = await Profile.findOne({ userId : user.userId }); |
75 | - | ||
76 | const { deviceToken } = profile; | 99 | const { deviceToken } = profile; |
77 | - PushNotify(deviceToken); | 100 | + |
101 | + if(deviceToken) { | ||
102 | + const medicine = await Medicine.findOne({ medicineId : bottleMedicine.medicineId }); | ||
103 | + pushNotify({ | ||
104 | + deviceToken, | ||
105 | + message : medicine.name + '을 복용하셔야 합니다.', | ||
106 | + }); | ||
107 | + } | ||
78 | } | 108 | } |
79 | }); | 109 | }); |
80 | }, { | 110 | }, { |
... | @@ -92,21 +122,27 @@ exports.updateMedicineData = async () => { | ... | @@ -92,21 +122,27 @@ exports.updateMedicineData = async () => { |
92 | 122 | ||
93 | if(user) { | 123 | if(user) { |
94 | const profile = await Profile.findOne({ userId : user.userId }); | 124 | const profile = await Profile.findOne({ userId : user.userId }); |
95 | - | ||
96 | const { deviceToken } = profile; | 125 | const { deviceToken } = profile; |
97 | - PushNotify(deviceToken); | 126 | + |
127 | + if(deviceToken) { | ||
128 | + const medicine = await Medicine.findOne({ medicineId : bottleMedicine.medicineId }); | ||
129 | + pushNotify({ | ||
130 | + deviceToken, | ||
131 | + message : medicine.name + '을 복용하셔야 합니다.', | ||
132 | + }); | ||
133 | + } | ||
98 | } | 134 | } |
99 | }); | 135 | }); |
100 | }, { | 136 | }, { |
101 | timezone : 'Asia/Tokyo', | 137 | timezone : 'Asia/Tokyo', |
102 | }); | 138 | }); |
103 | 139 | ||
104 | - }; | 140 | +}; |
105 | 141 | ||
106 | - const PushNotify = async(deviceToken) => { | 142 | +const pushNotify = ({ deviceToken, message }) => { |
107 | //toDo : deviceToken을 받아서 push notification을 발송하는 함수 | 143 | //toDo : deviceToken을 받아서 push notification을 발송하는 함수 |
108 | - if(deviceToken) { | ||
109 | - console.log(deviceToken); | ||
110 | - } | ||
111 | - }; | ||
112 | - | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
144 | + sendPushMessage({ | ||
145 | + deviceToken, | ||
146 | + message, | ||
147 | + }); | ||
148 | +}; | ... | ... |
server/src/util/FCM.js
0 → 100644
1 | +const fcm = require('firebase-admin'); | ||
2 | + | ||
3 | + | ||
4 | +exports.initializeFCM = () => { | ||
5 | + fcm.initializeApp({ | ||
6 | + credential : fcm.credential.applicationDefault(), | ||
7 | + }); | ||
8 | +}; | ||
9 | + | ||
10 | +exports.sendPushMessage = async ({ deviceToken, message }) => { | ||
11 | + const notifyMessage = { | ||
12 | + notification : { | ||
13 | + title : '약 먹을 시간입니다', | ||
14 | + body : message, | ||
15 | + }, | ||
16 | + token : deviceToken, | ||
17 | + }; | ||
18 | + fcm.messaging().send(notifyMessage); | ||
19 | +}; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -3,14 +3,15 @@ const moment = require('moment'); | ... | @@ -3,14 +3,15 @@ const moment = require('moment'); |
3 | 3 | ||
4 | 4 | ||
5 | exports.generateQrCode_prescribe = async ({ medicine, dosage, patientId, doctorId }) => { | 5 | exports.generateQrCode_prescribe = async ({ medicine, dosage, patientId, doctorId }) => { |
6 | - const directory = "/Users/parkkwonsoo/Desktop/Project/Capstone_Design_1/server/data/"; | 6 | + // eslint-disable-next-line no-undef |
7 | + const directory = process.env.QR_DIR; | ||
7 | 8 | ||
8 | const now = moment().format('YYYY-MM-DD_HH:mm'); | 9 | const now = moment().format('YYYY-MM-DD_HH:mm'); |
9 | const qrCodeFileName = `${now}_${doctorId}_${patientId}_${medicine.medicineId}_${dosage}.png`; | 10 | const qrCodeFileName = `${now}_${doctorId}_${patientId}_${medicine.medicineId}_${dosage}.png`; |
10 | 11 | ||
11 | try { | 12 | try { |
12 | await QrCode.toFile( | 13 | await QrCode.toFile( |
13 | - directory + qrCodeFileName, | 14 | + directory + '/' + qrCodeFileName, |
14 | `${medicine.name}/${medicine.medicineId}/${dosage}/${patientId}/${doctorId}`, | 15 | `${medicine.name}/${medicine.medicineId}/${dosage}/${patientId}/${doctorId}`, |
15 | { | 16 | { |
16 | color : { | 17 | color : { | ... | ... |
This diff could not be displayed because it is too large.
-
Please register or login to post a comment