박권수

feat. 처방API, QRCode 생성 등

......@@ -23,7 +23,8 @@
"moment": "^2.29.1",
"moment-timezone": "^0.5.33",
"mqtt": "^4.2.6",
"node-cron": "^3.0.0"
"node-cron": "^3.0.0",
"qrcode": "^1.4.4"
},
"devDependencies": {
"eslint": "^7.32.0"
......
......@@ -9,8 +9,13 @@ const Feedback = require('../../models/feedback');
const Hub = require('../../models/hub');
const PatientInfo = require('../../models/patientInfo');
const DoctorInfo = require('../../models/doctorInfo');
const PrescribeInfo = require('../../models/prescribeInfo');
const jwt = require('jsonwebtoken');
const { uploadQrCode, viewQrCode } = require('../../util/GoogleCloudStorage');
const QrCodeUtil = require('../../util/QrCodeUtil');
/**
* 현재 로그인한 유저의 의사 정보를 가져온다
......@@ -342,6 +347,11 @@ exports.writeReqBottleFeedback = async ctx => {
};
/**
* 이메일로 환자를 검색한다.
* @param {*} ctx
* @returns
*/
exports.searchPatientById = async ctx => {
const token = ctx.req.headers.authorization;
if (!token || !token.length) {
......@@ -483,3 +493,107 @@ exports.removeReqPatient = async ctx => {
ctx.status = 200;
};
/**
* 특정 환자에게 특정 약을 처방한다
* @param {*} ctx
* http methods : post
*/
exports.prescribeMedicine = async ctx => {
const token = ctx.req.headers.authorization;
if(!token || !token.length) {
ctx.status = 401;
return;
}
// eslint-disable-next-line no-undef
const { userId } = jwt.verify(token, process.env.JWT_SECRET);
const user = await User.findByUserId(userId);
if(!user || user.userTypeCd !== 'DOCTOR') {
ctx.status = 403;
ctx.body = {
error : '권한 없는 유저',
};
return;
}
const {
patientId,
medicineId,
dosage,
} = ctx.request.body;
const patientInfo = await PatientInfo.findOne({
patientId,
doctorId : userId,
useYn : 'Y',
})
if(!patientInfo) {
ctx.status = 403;
ctx.body = {
error : '권한 없는 환자',
};
return;
}
const medicine = await Medicine.findOne({
medicineId
});
if(!medicine) {
ctx.status = 404;
ctx.body = {
error : '존재하지 않는 약',
};
return;
}
const qrCodeResult = await QrCodeUtil.generateQrCode_prescribe({
medicine,
dosage,
patientId,
doctorId : userId,
});
if(!qrCodeResult) {
ctx.status = 400;
ctx.body = {
error : 'QR 코드 생성 에러',
};
return;
}
const qrCodeUrl = await uploadQrCode(qrCodeResult);
if(!qrCodeUrl) {
ctx.status = 400;
ctx.body = {
error : 'QR 코드 생성 후 서버 업로드 에러',
};
return;
}
const prescribeInfo = new PrescribeInfo({
doctorId : userId,
patientId,
dosage,
medicineId,
qrCodeUrl,
});
await prescribeInfo.save();
//특이사항에 처방기록 저장
patientInfo.updateInfo(`${medicine.name}, 하루 ${dosage}알 처방`);
await patientInfo.save();
const { qrCodeFileName } = qrCodeResult;
const qrCode = await viewQrCode({ qrCodeFileName });
ctx.status = 200;
ctx.body = {
qrCode,
};
};
\ No newline at end of file
......
......@@ -7,7 +7,7 @@ const doctor = new Router();
/**
* 현재 로그인한 유저(의사)의 정보를 가져옴.
* request parameter : token
* url : http://localhost:4000/doctor/
* url : http://localhost:4000/api/doctor/
* return : doctor's Info
*/
doctor.get('/', doctorCtrl.getDoctorsInfo);
......@@ -15,7 +15,7 @@ doctor.get('/', doctorCtrl.getDoctorsInfo);
/**
* 현재 로그인한 유저(의사)의 관리 환자 목록을 가져옴
* request parameter
* url : http://localhost:4000/doctor/patient
* url : http://localhost:4000/api/doctor/patient
* return : patient List
*/
doctor.get('/patient', doctorCtrl.getPatientList);
......@@ -23,7 +23,7 @@ doctor.get('/patient', doctorCtrl.getPatientList);
/**
* 현재 로그인한 유저(의사)의 관리 환자 상세 정보를 가져옴
* request parameter : patient Id
* url : http://localhost:4000/doctor/patient/:patientId
* url : http://localhost:4000/api/doctor/patient/:patientId
* return : patient Detail
*/
doctor.get('/patient/:patientId', doctorCtrl.getPatientDetail);
......@@ -31,7 +31,7 @@ doctor.get('/patient/:patientId', doctorCtrl.getPatientDetail);
/**
* 현재 로그인한 유저(의사)의 관리 약병 상세 정보를 가져옴
* request parameter : bottle Id
* url : http://localhost:4000/doctor/bottle/:bottleId
* url : http://localhost:4000/api/doctor/bottle/:bottleId
* return : bottle Detail
*/
doctor.get('/bottle/:bottleId', doctorCtrl.getBottleDetail);
......@@ -39,7 +39,7 @@ doctor.get('/bottle/:bottleId', doctorCtrl.getBottleDetail);
/**
* 현재 로그인한 유저(의사)의 특정 관리 환자의 특이사항을 기록함
* request parameter : reqUserId, info
* url : http://localhost:4000/doctor/patient
* url : http://localhost:4000/api/doctor/patient
* return : null
*/
doctor.patch('/patient', doctorCtrl.writeReqPatientReport);
......@@ -47,7 +47,7 @@ doctor.patch('/patient', doctorCtrl.writeReqPatientReport);
/**
* 현재 로그인한 유저(의사)의 특정 관리 환자의 약병의 피드백을 등록함.
* request parameter : bottleId, fdbType, feedback
* url : http://localhost:4000/doctor/bottle
* url : http://localhost:4000/api/doctor/bottle
* return : null
*/
doctor.post('/bottle', doctorCtrl.writeReqBottleFeedback);
......@@ -55,7 +55,7 @@ doctor.post('/bottle', doctorCtrl.writeReqBottleFeedback);
/**
* 현재 로그인한 유저(의사)가 이메일로 유저를 검색함
* request parameter : patientId
* url : http://localhost:4000/api/doctor/patient/search/:patientId
* url : http://localhost:4000/api/api/doctor/patient/search/:patientId
* return : patient Info(simple)
*/
doctor.get('/patient/search/:patientId', doctorCtrl.searchPatientById);
......@@ -63,7 +63,7 @@ doctor.get('/patient/search/:patientId', doctorCtrl.searchPatientById);
/**
* 현재 로그인한 유저(의사)의 관리 환자를 등록함.
* request parameter : patientId
* url : http://localhost:4000/doctor/patient
* url : http://localhost:4000/api/doctor/patient
* return : null
*/
doctor.post('/patient', doctorCtrl.registerNewPatient);
......@@ -71,11 +71,18 @@ doctor.post('/patient', doctorCtrl.registerNewPatient);
/**
* 현재 로그인한 유저(의사)의 특정 관리 환자를 삭제함.
* request parameter : patientId
* url : http://localhost:4000/doctor/patient/:patientId
* url : http://localhost:4000/api/doctor/patient/:patientId
* return : null
*/
doctor.delete('/patient/:patientId', doctorCtrl.removeReqPatient);
/**
* 의사가 관리하는 환자에 대해 특정 약을 처방함
* request paramter : patientId, medicineId, dosage
* url : http://localhost:4000/api/doctor/prescribe
* return : null
*/
doctor.post('/prescribe', doctorCtrl.prescribeMedicine);
module.exports = doctor;
module.exports = doctor;
\ No newline at end of file
......
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const PrescribeInfoSchema = new Schema({
doctorId : { type : String, require : true, },
patientId : { type : String, require : true, },
medicineId : { type : Number, require : true, },
dosage : { type : Number, require : true, },
qrCodeUrl : { type : String, require : true, },
});
module.exports = mongoose.model('PrescribeInfo', PrescribeInfoSchema);
\ No newline at end of file
const { Storage } = require('@google-cloud/storage');
const fs = require('fs');
const storage = new Storage();
const GoogleStorageUrl = 'https://storage.googleapis.com/';
......@@ -7,6 +8,7 @@ const GoogleStorageUrl = 'https://storage.googleapis.com/';
//의사 아이디, 업로드할 파일명, 업로드할 파일 경로를 인자로 받아, File을 GCS에 업로드 후 GCS 주소를 반환
exports.uploadDoctorLicense = async ({ userId, fileName, filePath }) => {
const destination = userId + '_' + fileName;
try {
const result = await storage.bucket('doctor-info').upload(filePath, {
destination,
});
......@@ -14,12 +16,15 @@ exports.uploadDoctorLicense = async ({ userId, fileName, filePath }) => {
const doctorLicenseUrl = GoogleStorageUrl + `${result[0].bucket.id}/${result[0].name}`;
return doctorLicenseUrl;
} catch(e) {
return null;
}
};
//의사 정보를 인자로 받아 해당 Doctor License의 Signed URL을 반환
exports.viewDoctorLicense = async ({ doctorInfo }) => {
const fileName = doctorInfo.info.doctorLicense.split('/').pop();
const file = new Storage().bucket('doctor-info').file(fileName);
const file = storage.bucket('doctor-info').file(fileName);
const option = {
version : 'v4',
expires : Date.now() + 1000 * 60 * 15,
......@@ -32,6 +37,36 @@ exports.viewDoctorLicense = async ({ doctorInfo }) => {
};
//의사 ID, 약 ID, 복용량을 인자로 받아, QR Code를 생성
exports.prescribeMedicine = async ({ doctorId, medicineId, dosage }) => {
//toDo
exports.uploadQrCode = async ({ directory, qrCodeFileName }) => {
const destination = qrCodeFileName;
try {
//파일을 GCS에 업로드
const result = await storage.bucket('prescribe-medicine-qrcode').upload(directory + qrCodeFileName, {
destination
});
//업로드 후 파일 삭제
fs.rm(directory + qrCodeFileName, () => {});
const qrCodeUrl = GoogleStorageUrl + `${result[0].bucket.id}/${result[0].name}`;
return qrCodeUrl;
} catch(e) {
return null;
}
};
//생성된 QR코드의 signedUrl을 가져옴
exports.viewQrCode = async ({ qrCodeFileName }) => {
const fileName = qrCodeFileName;
const file = storage.bucket('prescribe-medicine-qrcode').file(fileName);
const option = {
version : 'v4',
expires : Date.now() + 1000 * 60 * 15,
action : 'read',
};
const [signedUrl] = file ? await file.getSignedUrl(option) : [null];
return signedUrl;
};
\ No newline at end of file
......
const QrCode = require('qrcode');
const moment = require('moment');
exports.generateQrCode_prescribe = async ({ medicine, dosage, patientId, doctorId }) => {
const directory = "/Users/parkkwonsoo/Desktop/Project/Capstone_Design_1/server/data/";
const now = moment().format('YYYY-MM-DD_HH:mm');
const qrCodeFileName = `${now}_${doctorId}_${patientId}_${medicine.medicineId}_${dosage}.png`;
try {
await QrCode.toFile(
directory + qrCodeFileName,
`${medicine.name}/${medicine.medicineId}/${dosage}/${patientId}/${doctorId}`,
{
color : {
dark : '#337DFF',
light : '#FFF'
},
}
);
return {
directory,
qrCodeFileName,
};
} catch(e) {
console.log(e);
return null;
}
};
\ No newline at end of file
This diff could not be displayed because it is too large.