Showing
8 changed files
with
157 additions
and
86 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 is collapsed. Click to expand it.
| ... | @@ -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({ |
| ... | @@ -58,7 +59,8 @@ exports.register = async(ctx) => { | ... | @@ -58,7 +59,8 @@ exports.register = async(ctx) => { |
| 58 | userId, | 59 | userId, |
| 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,17 +6,20 @@ | ... | @@ -6,17 +6,20 @@ |
| 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'); |
| 18 | - | 20 | +const { sendPushMessage } = require('./FCM'); |
| 19 | - | 21 | + |
| 22 | + | ||
| 20 | // //매년 1월 1일 00시 00분에 1살씩 추가 | 23 | // //매년 1월 1일 00시 00분에 1살씩 추가 |
| 21 | // exports.CheckNewYear = () => { | 24 | // exports.CheckNewYear = () => { |
| 22 | // cron.schedule('0 0 0 1 1 *', async () => { | 25 | // cron.schedule('0 0 0 1 1 *', async () => { |
| ... | @@ -25,7 +28,7 @@ const updateMedicineInfo = require('../lib/UpdatingMedicineInfo'); | ... | @@ -25,7 +28,7 @@ const updateMedicineInfo = require('../lib/UpdatingMedicineInfo'); |
| 25 | // await profile.updateUserAge(); | 28 | // await profile.updateUserAge(); |
| 26 | // profile.save(); | 29 | // profile.save(); |
| 27 | // }); | 30 | // }); |
| 28 | - | 31 | + |
| 29 | // }, { | 32 | // }, { |
| 30 | // timezone : 'Asia/Tokyo', | 33 | // timezone : 'Asia/Tokyo', |
| 31 | // }); | 34 | // }); |
| ... | @@ -35,78 +38,111 @@ const updateMedicineInfo = require('../lib/UpdatingMedicineInfo'); | ... | @@ -35,78 +38,111 @@ 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', | ||
| 38 | }); | 43 | }); |
| 39 | }; | 44 | }; |
| 40 | - | 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', | ||
| 56 | + }); | ||
| 57 | +}; | ||
| 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 () => { |
| 47 | - const bottleMedicineList = await BottleMedicine.find({ useYn : 'Y', dosage : { $gte : 1 } }); | 65 | + const bottleMedicineList = await BottleMedicine.find({ useYn : 'Y', dosage : { $gte : 1 } }); |
| 48 | - bottleMedicineList.forEach(async bottleMedicine => { | 66 | + bottleMedicineList.forEach(async bottleMedicine => { |
| 49 | - const bottle = await Bottle.findOne({ bottleId : bottleMedicine.bottleId }); | 67 | + const bottle = await Bottle.findOne({ bottleId : bottleMedicine.bottleId }); |
| 50 | - const hub = await Hub.findOne({ hubId : bottle.hubId }); | 68 | + const hub = await Hub.findOne({ hubId : bottle.hubId }); |
| 51 | - const user = await User.findOne({ userId : hub.userId, useYn : 'Y' }); | 69 | + const user = await User.findOne({ userId : hub.userId, useYn : 'Y' }); |
| 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 | - | 73 | + const { deviceToken } = profile; |
| 56 | - const { deviceToken } = profile; | 74 | + |
| 57 | - PushNotify(deviceToken); | 75 | + if(deviceToken) { |
| 58 | - } | 76 | + const medicine = await Medicine.findOne({ medicineId : bottleMedicine.medicineId }); |
| 59 | - }); | 77 | + pushNotify({ |
| 60 | - }, { | 78 | + deviceToken, |
| 61 | - timezone : 'Asia/Tokyo', | 79 | + message : medicine.name + '을 복용하셔야 합니다.', |
| 62 | - }); | 80 | + }); |
| 63 | - | 81 | + } |
| 64 | - | 82 | + } |
| 65 | - //매일 점심 12시 : 복용량이 3인 환자들만 | 83 | + }); |
| 66 | - cron.schedule('0 0 12 * * *', async () => { | 84 | + }, { |
| 67 | - const bottleMedicineList = await BottleMedicine.find({ useYn : 'Y', dosage : { $gte : 3 } }); | 85 | + timezone : 'Asia/Tokyo', |
| 68 | - bottleMedicineList.forEach(async bottleMedicine => { | 86 | + }); |
| 69 | - const bottle = await Bottle.findOne({ bottleId : bottleMedicine.bottleId }); | 87 | + |
| 70 | - const hub = await Hub.findOne({ hubId : bottle.hubId }); | 88 | + |
| 71 | - const user = await User.findOne({ userId : hub.userId, useYn : 'Y' }); | 89 | + //매일 점심 12시 : 복용량이 3인 환자들만 |
| 72 | - | 90 | + cron.schedule('0 0 12 * * *', async () => { |
| 73 | - if(user) { | 91 | + const bottleMedicineList = await BottleMedicine.find({ useYn : 'Y', dosage : { $gte : 3 } }); |
| 74 | - const profile = await Profile.findOne({ userId : user.userId }); | 92 | + bottleMedicineList.forEach(async bottleMedicine => { |
| 75 | - | 93 | + const bottle = await Bottle.findOne({ bottleId : bottleMedicine.bottleId }); |
| 76 | - const { deviceToken } = profile; | 94 | + const hub = await Hub.findOne({ hubId : bottle.hubId }); |
| 77 | - PushNotify(deviceToken); | 95 | + const user = await User.findOne({ userId : hub.userId, useYn : 'Y' }); |
| 78 | - } | 96 | + |
| 79 | - }); | 97 | + if(user) { |
| 80 | - }, { | 98 | + const profile = await Profile.findOne({ userId : user.userId }); |
| 81 | - timezone : 'Asia/Tokyo', | 99 | + const { deviceToken } = profile; |
| 82 | - }); | 100 | + |
| 83 | - | 101 | + if(deviceToken) { |
| 84 | - | 102 | + const medicine = await Medicine.findOne({ medicineId : bottleMedicine.medicineId }); |
| 85 | - //매일 저녁 6시 | 103 | + pushNotify({ |
| 86 | - cron.schedule('0 0 18 * * *', async () => { | 104 | + deviceToken, |
| 87 | - const bottleMedicineList = await BottleMedicine.find({ useYn : 'Y', dosage : { $gte : 2 } }); | 105 | + message : medicine.name + '을 복용하셔야 합니다.', |
| 88 | - bottleMedicineList.forEach(async bottleMedicine => { | 106 | + }); |
| 89 | - const bottle = await Bottle.findOne({ bottleId : bottleMedicine.bottleId }); | 107 | + } |
| 90 | - const hub = await Hub.findOne({ hubId : bottle.hubId }); | 108 | + } |
| 91 | - const user = await User.findOne({ userId : hub.userId, useYn : 'Y' }); | 109 | + }); |
| 92 | - | 110 | + }, { |
| 93 | - if(user) { | 111 | + timezone : 'Asia/Tokyo', |
| 94 | - const profile = await Profile.findOne({ userId : user.userId }); | 112 | + }); |
| 95 | - | 113 | + |
| 96 | - const { deviceToken } = profile; | 114 | + |
| 97 | - PushNotify(deviceToken); | 115 | + //매일 저녁 6시 |
| 98 | - } | 116 | + cron.schedule('0 0 18 * * *', async () => { |
| 99 | - }); | 117 | + const bottleMedicineList = await BottleMedicine.find({ useYn : 'Y', dosage : { $gte : 2 } }); |
| 100 | - }, { | 118 | + bottleMedicineList.forEach(async bottleMedicine => { |
| 101 | - timezone : 'Asia/Tokyo', | 119 | + const bottle = await Bottle.findOne({ bottleId : bottleMedicine.bottleId }); |
| 102 | - }); | 120 | + const hub = await Hub.findOne({ hubId : bottle.hubId }); |
| 103 | - | 121 | + const user = await User.findOne({ userId : hub.userId, useYn : 'Y' }); |
| 104 | - }; | 122 | + |
| 105 | - | 123 | + if(user) { |
| 106 | - const PushNotify = async(deviceToken) => { | 124 | + const profile = await Profile.findOne({ userId : user.userId }); |
| 125 | + const { deviceToken } = profile; | ||
| 126 | + | ||
| 127 | + if(deviceToken) { | ||
| 128 | + const medicine = await Medicine.findOne({ medicineId : bottleMedicine.medicineId }); | ||
| 129 | + pushNotify({ | ||
| 130 | + deviceToken, | ||
| 131 | + message : medicine.name + '을 복용하셔야 합니다.', | ||
| 132 | + }); | ||
| 133 | + } | ||
| 134 | + } | ||
| 135 | + }); | ||
| 136 | + }, { | ||
| 137 | + timezone : 'Asia/Tokyo', | ||
| 138 | + }); | ||
| 139 | + | ||
| 140 | +}; | ||
| 141 | + | ||
| 142 | +const pushNotify = ({ deviceToken, message }) => { | ||
| 107 | //toDo : deviceToken을 받아서 push notification을 발송하는 함수 | 143 | //toDo : deviceToken을 받아서 push notification을 발송하는 함수 |
| 108 | - if(deviceToken) { | 144 | + sendPushMessage({ |
| 109 | - console.log(deviceToken); | 145 | + deviceToken, |
| 110 | - } | 146 | + message, |
| 111 | - }; | 147 | + }); |
| 112 | - | 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