Showing
8 changed files
with
97 additions
and
26 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({ |
| ... | @@ -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) { | 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