diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d57b528 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM node:16 +WORKDIR /admin_server +COPY ["package.json", "package-lock.json", "./"] +RUN npm install +COPY . . + +EXPOSE 5000 +CMD ["node", "app.js"] \ No newline at end of file diff --git a/admin_app.js b/admin_app.js new file mode 100644 index 0000000..8cc9e36 --- /dev/null +++ b/admin_app.js @@ -0,0 +1,191 @@ +const express = require('express'); +const app = express(); +const db = require('./db'); +const cors = require('cors'); +const upload = require('./uploads'); + +app.use(cors()); +app.use(express.json()); +app.use(express.urlencoded({ extended: true })); + +//스토어 앱() +app.get("/test", async (req, res, next) => { //md_id=2인 상품 데이터 출력 + try { + const [test] = await db.execute(`select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id where md.md_id= 2`); + + resultCode = 200; + + return res.json({ + code: resultCode, + test : test + }); + } catch (err) { + console.error(err); + return res.status(500).json(err); + } + }); +app.get("/store/items/:store_id", async (req, res, next) => { //특정 스토어에서 진행하는 상품들 출력 + const store_id = req.params.store_id; + + const [mdInfo] = await db.execute( + `select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id join farm on md.farm_id=farm.farm_id join md_Img on md.md_id=md_Img.md_id + where store_id = ?`,[store_id]); + + res.send(mdInfo); + + }); +app.get("/:md_id", async (req, res, next) => { //특정 상품 + + const md_id = req.params.md_id; + let [row2, field] = await db.execute(`select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id join md_Img on md.md_id=md_Img.md_id join farm on md.farm_id=farm.farm_id where md.md_id=?`, [md_id]); + res.send(row2); + + + }); +app.get("/pickup/:md_id", async (req, res, next) => { //특정 스토어에서 진행하는 상품의 픽업리스트 + const md_id = req.params.md_id; + try { + const [pickupList] = await db.execute( + `select * from `+"`"+"order"+"`"+` join md on `+"`"+"order"+"`"+`.md_id=md.md_id where `+"`"+"order"+"`"+`.md_id= ${md_id} and order_cancel=0 ` + ); + + res.send(pickupList); + } catch (err) { + console.error(err); + return res.status(500).json(err); + } + }); +app.get('/store/:store_id', async (req, res) => {//특정 store만 get + const store_id = req.params.store_id; + try { + const [store] = await db.execute( + `select * from store join Hours on store.store_id=Hours.hours_PartnerId where store.store_id=${store_id} and Hours.hours_partner=1` + ); + + res.send(store); + } catch (err) { + console.error(err); + return res.status(500).json(err); + } + }); + app.post("/storeDetail", async (req, res, next) => { + const store_id = parseInt(req.body.id); + let resultCode = 404; + let message = "에러가 발생했습니다."; + + try { + //문제 없으면 try문 실행 + + let d = new Date(); + let weekday = new Array(7); + weekday[0] = "일"; + weekday[1] = "월"; + weekday[2] = "화"; + weekday[3] = "수"; + weekday[4] = "목"; + weekday[5] = "금"; + weekday[6] = "토"; + + let n = weekday[d.getDay()]; + + //스토어 상세정보 + const [store_result] = await db.execute( + `SELECT * FROM store WHERE store_id= ${store_id}` + ); + + //스토어에 있는 제품리뷰 + const [review_result] = await db.execute( + `SELECT rvw_rating, rvw_content, md.md_id, md.md_name FROM review join md on review.md_id=md.md_id WHERE (store_id=${store_id}) and (md_result is null or md_result=1)` + ); + + //스토어 현재 진행중인 공동구매 + const [md_data] = await db.execute( + `select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id join farm on md.farm_id=farm.farm_id join md_Img on md.md_id=md_Img.md_id + where store_id = ?`,[store_id]); + + //스토어 운영 시간 + const [store_date] = await db.execute( + `SELECT * FROM Hours WHERE hours_partner = 1 and hours_partnerId = ${store_id}` + ); + + resultCode = 200; + message = "스토어 상세로 정보보내기 성공"; + + let pu_start = new Array(); + let pu_end = new Array(); + let dDay = new Array(); + let now = new Date(); + + for (let i = 0; i < md_data.length; i++) { + pu_start[i] = new Date(md_data[i].pu_start).toLocaleDateString(); + pu_end[i] = new Date(md_data[i].pu_end).toLocaleDateString(); + + let distance = new Date(md_data[i].md_end).getTime() - now.getTime(); + dDay[i] = Math.floor(distance / (1000 * 60 * 60 * 24)); + } + + return res.json({ + code: resultCode, + message: message, + store_result: store_result, + jp_result: md_data, + pu_start: pu_start, + pu_end: pu_end, + review_result: review_result, + store_date: store_date, + dDay: dDay, + day: n, + }); + } catch (err) { + console.error(err); + return res.status(500).json(err); + } + }); + app.get('/time/:store_id', async (req, res) => {//특정 store만 get + const store_id = req.params.store_id; + try { + //스토어 운영 시간 + const [store_date] = await db.execute( + `SELECT * FROM Hours WHERE hours_partner = 1 and hours_partnerId = ${store_id}` + ); + + res.send(store_date); + } catch (err) { + console.error(err); + return res.status(500).json(err); + } + }); +app.get('/read/store/imgs', async (req, res) => {//특정 상가의 이미지만 + const store_id = req.query.store_id;//`select * from md where md_id=?`, [md_id] + try{ + const [storeImgs] = await db.execute(`select store_thumbnail, store_mainImg, store_detailImg from store where store_id = ${store_id}`); + + resultCode = 200; + message = "store get 성공"; + + return res.json({ + code: resultCode, + message: message, + storeImgs : storeImgs + }); + } catch (err) { + console.error(err); + return res.status(500).json(err); + } + }); +app.post('/pickup/user/:order_id', async (req, res) => {//픽업상태 바꾸기 + const order_id = req.params.order_id; + try { + const [update] = await db.execute( + `UPDATE`+"`"+"order"+"`"+` SET order_md_status =1 WHERE order_id = ${order_id} ;` + + ) + res.send(update); + console.log("done") + } + catch (err) { + console.error(err); + return res.status(500).json(err); + } +}); +module.exports = app; \ No newline at end of file diff --git a/app.js b/app.js new file mode 100644 index 0000000..ab01be2 --- /dev/null +++ b/app.js @@ -0,0 +1,48 @@ +//const { swaggerUi, specs } = require('./modules/swagger'); +const express = require('express'); +const app = express(); + +const cors = require('cors'); +const read = require('./read'); +const md = require('./md'); +const partner = require('./partner'); +const review = require('./review'); +const store = require('./admin_app'); + +const PORT = 5000; + +app.use('/api/admin', store); +app.use('/api/read', read); +app.use('/api/md', md); +app.use('/api/partner', partner); +app.use('/api/review', review); + +// 5000 포트로 서버 오픈 +app.listen(PORT, function() { + console.log("start! express server on port 5000") +}) + +const login_register = require('./login'); +const notificationRegister = require('./notification'); +const notice_register = require('./notice'); +const content_register = require('./content'); + +const signup_register = require('./signup'); +//const cors = require('cors'); +const auth_middleware = require('./auth_middleware'); + +app.use(cors()); +app.use(auth_middleware); +app.use('/api/login', login_register); +app.use('/api/notification', notificationRegister); +app.use('/api/notice', notice_register); +app.use('/api/content', content_register); + +app.use('/api/signup', signup_register); + +app.get('/api', async (req, res) => { + res.send(req.decode); +}) + +//app.listen(5000); + diff --git a/auth_middleware.js b/auth_middleware.js index a598638..e261028 100644 --- a/auth_middleware.js +++ b/auth_middleware.js @@ -13,9 +13,22 @@ const get_cookies = (req) => { }; +/** 로그인, 콘텐츠 조회는 토큰 필요 없게 처리 */ +const checkPass = (req) => { + if (req.originalUrl.indexOf('/login') !== -1){ + return true; + } + if (req.originalUrl.indexOf('/signup') !== -1){ + return true; + } + if (req.method === 'GET' && (req.originalUrl === '/api/content' || req.originalUrl === '/api/content/banner')) { + return true; + } +} + const auth_middleware = async (req, res, next) => { - if (req.originalUrl.indexOf('/login') !== -1) { // 로그인 관련 시도는 auth_middleware 통과하게 - console.log('login pass'); + if (checkPass(req)) { + console.log(`AUTH_PASS :: url = ${req.originalUrl}`); next(); } else { let token = get_cookies(req); diff --git a/content.js b/content.js new file mode 100644 index 0000000..f69b36a --- /dev/null +++ b/content.js @@ -0,0 +1,312 @@ +const express = require('express'); +const app = express(); +const aws_key = require('./config').aws_access; +const aws = require('aws-sdk'); +const multer = require('multer'); +const multer_s3 = require('multer-s3'); +const db = require('./db'); + +const s3 = new aws.S3({ + accessKeyId: aws_key.access, + secretAccessKey: aws_key.secret, + region: aws_key.region +}); +const storage = multer_s3({ + s3: s3, + bucket: 'ggdjang', + contentType: multer_s3.AUTO_CONTENT_TYPE, + acl: 'public-read', + metadata: function(req, file, cb) { + cb(null, {fieldName: file.fieldname}); + }, + key: function (req, file, cb) { + cb(null, `contents/${Date.now()}_${file.originalname}`); + } +}) +const upload = multer({ + storage: storage +}) + +app.use(express.json()); + +// 홍보용 배너 콘텐츠 등록 +app.post('/banner', async (req, res) => { + const bannerIds = req.body; + + try { + // 기존의 배너 콘텐츠는 NULL로 변경 후 새로 등록 + await db.execute(`UPDATE content SET promotion_banner = ?`, [null]); + + for (let bannerId of bannerIds) { + const id = bannerId.id; + const order = bannerId.order; + + await db.execute(`UPDATE content SET promotion_banner = ? WHERE content_id = ?`, [order, id]); + } + + console.log(`BANNER_CONTENT_CREATE_SUCCESS :: bannerIds = ${bannerIds}`); + res.send({msg: 'BANNER_CONTENT_CREATE_SUCCESS', data: bannerIds}); + } catch (e) { + console.log(`BANNER_CONTENT_CREATE_FAILED :: msg = {${e}}`); + res.status(500).send({msg: 'BANNER_CONTENT_CREATE_FAIL'}) + } +}) + +// 홍보용 배너 콘텐츠 조회 +app.get('/banner', async (req, res) => { + try { + const [result, field] = await db.execute(`SELECT * FROM content WHERE promotion_banner IS NOT NULL ORDER BY promotion_banner ASC`); + + console.log(`BANNER_CONTENT_READ_SUCCESS :: `); + res.send({msg: 'BANNER_CONTENT_READ_SUCCESS', data: result}); + } catch (e) { + console.log(`BANNER_CONTENT_READ_FAILED :: msg = ${e}`); + res.status(500).send({msg: 'BANNER_CONTENT_READ_FAIL'}); + } +}) + +// 모든 content 리스트 +app.get('/', async (req, res) => { + const query = req.query.aspect; + const is_tmp = req.query.is_tmp; + const category = req.query.category; + + try { + let return_content; + if (query === 'admin') { // 관리자용 + if (!category) { + const [contents, field] = await db.execute(`SELECT * FROM content WHERE is_tmp = ? ORDER BY content_date DESC`, [is_tmp]); + return_content = contents; + } else { + const [contents, field] = await db.execute(`SELECT * FROM content WHERE content_category = ? AND is_tmp = ? ORDER BY content_date DESC`, [category, is_tmp]); + return_content = contents; + } + } + else { // 소비자용 + const [contents, fields] = await db.execute(`SELECT * FROM content WHERE is_tmp = 0 AND upload_date < CURRENT_DATE() ORDER BY content_date DESC`); + return_content = contents; + } + console.log(`CONTENT_READ_SUCCESS :: `); + res.send(return_content); + } catch (e) { + console.log(`CONTENT_READ_FAILED :: msg = ${e}`); + res.status(500).send({msg: 'CONTENT_READ_FAIL'}); + } +}) + +// content 제목으로 검색 +app.get('/search', async (req, res) => { + const search_word = req.query.search; + + try { + const [contents, fields] = await db.execute(`SELECT * FROM content WHERE CONCAT_WS(' ', content_context, content_title) LIKE ? AND is_tmp = 0 ORDER BY content_date DESC`, ['%' + search_word + '%']); + + console.log(`CONTENT_SEARCH_SUCCESS :: searchWord = ${search_word}`); + res.send(contents); + } catch (e) { + console.log(`CONTENT_SEARCH_FAILED :: msg = ${e}`); + res.status(500).send({msg: 'CONTENT_SEARCH_FAIL'}); + } +}) + +// 특정 content +app.get('/:content_id', async (req, res) => { + const content_id = req.params.content_id; + + try { + const [content, field] = await db.execute(`SELECT * FROM content WHERE content_id = ?`, [content_id]); + + console.log(`CONTENT_READ_SUCCESS :: contentId = ${content_id}`); + res.send(content[0]); + } catch (e) { + console.log(`CONTENT_READ_FAILED :: msg = ${e}`); + res.status(500).send({msg: 'CONTENT_READ_FAIL'}); + } +}) + +// content 작성 +app.post('/', upload.fields([{name: 'photo', maxCount: 1}, {name: 'thumbnail', maxCount: 1}, {name: 'main', maxCount: 1}]), async (req, res) => { + const body = req.body; + const title = body.title; + const context = body.context; + const upload_type = body.upload_type; + const upload_date = body.upload_date; + // const link = body.link; + const md1 = body.md1; + const md2 = body.md2; + const category = body.category; + const is_tmp = body.is_tmp === 'true'; + let photo; + if (req.files['photo'] !== undefined) { + photo = req.files['photo'][0].key; + } else { + photo = null; + } + let thumbnail; + if (req.files['thumbnail'] !== undefined) { + thumbnail = req.files['thumbnail'][0].key; + } else { + thumbnail = null; + } + let main; + if (req.files['main'] !== undefined) { + main = req.files['main'][0].key; + } else { + main = null; + } + + try { + const [result] = await db.execute(`INSERT INTO content(content_title, content_context, content_photo, content_thumbnail, is_tmp, upload_type, upload_date, content_main, content_category, content_md_id1, content_md_id2) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [title, context, photo, thumbnail, is_tmp, upload_type, upload_date, main, category, md1, md2]); + + console.log(`CONTENT_CREATE_SUCCESS :: contentId = ${result.insertId}`); + res.send({id: result.insertId}); + } catch (e) { + console.log(`CONTENT_CREATE_FAILED :: msg = ${e}`); + res.status(500).send({msg: "CONTENT_CREATE_FAILED"}); + } +}); + +// content 수정 +app.patch('/:content_id', upload.fields([{name: 'photo', maxCount: 1}, {name: 'thumbnail', maxCount: 1}, {name: 'main', maxCount: 1}]), async (req, res) => { + const content_id = req.params.content_id; + let body = req.body; + body.is_tmp = body.is_tmp === 'true'; + let photo_update = false; + let thumbnail_update = false; + let main_update = false; + + // 요청하는 것만 update + let sql_key = Object.keys(body).map((key) => { + if (key !== 'is_tmp' && !key.includes('upload')) return `content_${key} = ?`; + else return `${key} = ?` + }).join(", "); + let sql_parameter = [...Object.values(body)]; + // 사진 수정 요청 + if (req.files['photo'] !== undefined) { + if (sql_key) sql_key += ', content_photo = ?'; + else sql_key = 'content_photo = ?'; + sql_parameter.push(req.files['photo'][0].key); + photo_update = true; + } + // 썸네일 수정 요청 + if (req.files['thumbnail'] !== undefined) { + if (sql_key) sql_key += ', content_thumbnail = ?'; + else sql_key = 'content_thumbnail = ?'; + sql_parameter.push(req.files['thumbnail'][0].key); + thumbnail_update = true; + } + // 메인 사진 수정 요청 + if (req.files['main'] !== undefined) { + if (sql_key) sql_key += ', content_main = ?'; + else sql_key = 'content_main = ?'; + sql_parameter.push(req.files['main'][0].key); + main_update = true; + } + sql_parameter.push(content_id); + + try { + const [content, field] = await db.execute(`SELECT * FROM content WHERE content_id = ?`, [content_id]); + const [result] = await db.execute(`UPDATE content SET ${sql_key} WHERE content_id = ?`, sql_parameter); + + // 사진이나 썸네일/메인 수정 시, s3에서 이전 사진/썸네일/메인 삭제 + if (photo_update || thumbnail_update || main_update) { + const photo = content[0].content_photo; + const thumbnail = content[0].content_thumbnail; + const main = content[0].content_main; + + if (photo_update) { + s3.deleteObject({ + Bucket: 'ggdjang', + Key: photo + }, (err, data) => { + if (err) console.log(err); + else console.log(data); + }); + } + if (thumbnail_update) { + s3.deleteObject({ + Bucket: 'ggdjang', + Key: thumbnail + }, (err, data) => { + if (err) console.log(err); + else console.log(data); + }); + } + if (main) { + s3.deleteObject({ + Bucket: 'ggdjang', + Key: main + }, (err, data) => { + if (err) console.log(err); + else console.log(data); + }); + } + } + + console.log(`CONTENT_UPDATED_SUCCESS :: contentId = ${content_id}`); + res.send(result); + } catch (e) { + console.log(`CONTENT_UPDATE_FAILED :: msg = ${e}`); + res.status(500).send({msg: "CONTENT_UPDATED_FAILED"}); + } +}) + +// content 삭제(편집) +app.post('/delete', async (req, res) => { + const content_ids = req.body.content_ids; + + try { + for (let content_id of content_ids) { + content_id = content_id.id; + const [content, field] = await db.execute(`SELECT * FROM content WHERE content_id=?`, [content_id]); + const photo = content[0].content_photo; + const thumbnail = content[0].content_thumbnail; + const main = content[0].content_main; + + // db 에서 content 삭제 + const [result] = await db.execute(`DELETE FROM content WHERE content_id=?`, [content_id]); + // 성공하면 + if (result) { + s3.deleteObject({ + Bucket: 'ggdjang', + Key: thumbnail + }, (err, data) => { + if (err) console.log(err); + else console.log(data); + }); + + // 만약 첨부 사진이 있으면 + if (photo) { + s3.deleteObject({ + Bucket: 'ggdjang', + Key: photo + }, (err, data) => { + if (err) console.log(err); + else console.log(data); + }); + } + + if (main) { + s3.deleteObject({ + Bucket: 'ggdjang', + Key: main + }, (err, data) => { + if (err) console.log(err); + else console.log(data); + }) + } + } else { + console.log(`CONTENT_DELETE_FAILED :: contentIds = ${content_ids}`); + res.status(400).send({msg: '삭제 실패'}); + } + } + console.log(`CONTENT_DELETE_SUCCESS :: contentIds = ${content_ids}`); + res.send({content_id: content_ids, msg: '삭제 성공'}); + } catch (e) { + console.log(`CONTENT_DELETE_FAILED :: msg = ${e}`); + res.status(400).send({msg: '잘못된 content 삭제 시도'}); + } +}) + +module.exports = app; \ No newline at end of file diff --git a/index.js b/index.js index d15c3f1..cdd1fa8 100644 --- a/index.js +++ b/index.js @@ -1,15 +1,23 @@ const express = require('express'); const app = express(); const login_register = require('./login'); +const signup_register = require('./signup'); +const notificationRegister = require('./notification'); +const notice_register = require('./notice'); +const content_register = require('./content'); const cors = require('cors'); const auth_middleware = require('./auth_middleware'); app.use(cors()); app.use(auth_middleware); app.use('/api/login', login_register); +app.use('/api/signup', signup_register); +app.use('/api/notification', notificationRegister); +app.use('/api/notice', notice_register); +app.use('/api/content', content_register); app.get('/api', async (req, res) => { res.send(req.decode); }) -app.listen(5000); \ No newline at end of file +app.listen(5000); diff --git a/login.js b/login.js index ada30dc..4273b75 100644 --- a/login.js +++ b/login.js @@ -14,42 +14,57 @@ app.post('/', async (req, res) => { const password = body.password; if (id === undefined || password === undefined) { + console.log(`LOGIN_FAILED :: userID = {${id}}`); res.send({access_token: 'false'}); } else { - const [user, field] = await db.execute(`SELECT * FROM admin_user WHERE admin_id = ?`, [id]); - - if (user.length === 0) { - res.send({access_token: 'id_false'}); - } else { - const encode_pwd = await bcrypt.compare(password, user[0].password); - - if (encode_pwd) { - const access_token = await jwt.sign( - { - id: user[0].admin_id, - nickname: user[0].nickname, - name: user[0].admin_name - }, - jwt_secret, - {expiresIn: '1h'} - ); - const refresh_token = await jwt.sign( - { - id: user[0].admin_id - }, - jwt_secret, - {expiresIn: '14d'} - ) - - res.cookie('access_token', access_token, {httpOnly: true, maxAge: 60000 * 60}); - res.cookie('refresh_token', refresh_token, {httpOnly: true, maxAge: 60000 * 60 * 24 * 14}); - res.send({ - access_token: access_token, - refresh_token: refresh_token - }); + try { + const [user, field] = await db.execute(`SELECT * FROM admin_user WHERE admin_id = ?`, [id]); + + if (user.length === 0) { + res.send({access_token: 'id_false'}); } else { - res.send({access_token: 'pwd_false'}); + const encode_pwd = await bcrypt.compare(password, user[0].password); + + if (encode_pwd) { + const access_token = await jwt.sign( + { + id: user[0].admin_id, + nickname: user[0].nickname, + name: user[0].admin_name + }, + jwt_secret, + {expiresIn: '1d'} + ); + const refresh_token = await jwt.sign( + { + id: user[0].admin_id + }, + jwt_secret, + {expiresIn: '14d'} + ) + + res.cookie('access_token', access_token, {httpOnly: false, maxAge: 60000 * 60}); + res.cookie('refresh_token', refresh_token, {httpOnly: false, maxAge: 60000 * 60 * 24 * 14}); + + let body = { + access_token: access_token, + refresh_token: refresh_token + } + + const [store, fields] = await db.execute(`SELECT store_id FROM store WHERE store_name = ?`, [user[0].admin_name]); + if (store.length !== 0) { + body.storeId = store[0].store_id; + } + + console.log(`LOGIN_SUCCESS :: userID = {${id}}`); + res.send(body); + } else { + console.log(`LOGIN_FAILED :: userID = {${id}}`); + res.send({access_token: 'pwd_false'}); + } } + } catch (e) { + console.log(`LOGIN_FAILED :: msg = {${e}}`); } } }) @@ -88,11 +103,14 @@ app.get('/refresh', async (req, res) => { ); res.cookie('access_token', access_token, {httpOnly: true, maxAge: 60000 * 60, overwrite: true}); + + console.log(`REFRESH_SUCCESS ::`); res.send({ access_token: access_token, refresh_token: refresh_token }) } catch (e) { + console.log(`REFRESH_FAILED :: msg = {${e}}`); res.status(401).send({msg: "retry login"}); } } @@ -102,6 +120,8 @@ app.get('/refresh', async (req, res) => { app.post('/logout', async (req, res) => { res.clearCookie('access_token'); res.clearCookie('refresh_token'); + + console.log(`LOGOUT_SUCCESS ::`); res.send(); }) diff --git a/md.js b/md.js new file mode 100644 index 0000000..42c7a40 --- /dev/null +++ b/md.js @@ -0,0 +1,521 @@ +const express = require('express'); +const app = express(); +const db = require('./db'); +const cors = require('cors'); +const upload = require('./uploads'); + +app.use(cors()); +app.use(express.json()); +app.use(express.urlencoded({ extended: true })); + +let insertId; + +//읽어오기 +app.get('/:md_id', async (req, res) => {//특정 md만 get + const md_id = req.params.md_id; + + try{ + + let [row2, field] = await db.execute(`select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id where md.md_id=?`, [md_id]); + res.send(row2); + console.log(row2); + } + catch (e) { + console.log(e); + } +}); +app.get('/imgs/:md_id', async (req, res) => {//특정 md의 이미지 + const md_id = req.params.md_id;//`select * from md where md_id=?`, [md_id] + try{ + const [row23, field] = await db.execute(`select * from md_Img where md_id = ?`,[md_id]); + res.send(row23); + //console.log(row23); + } + catch (e) { + console.log(e); + } +}); +app.get('/name/:md_id', async (req, res) => {//md_id에 따라 상점,농장 이름 출력 + const md_id = req.params.md_id; + const [row, field] = await db.execute(`select md.farm_id ,pickup.store_id from md join pickup using (md_id) where md_id=?`, [md_id]); + /*console.log(row[0].farm_id); + let farmId = row[0].farm_id; + console.log(farmId); + + let farmId = row[0].farm_id; + let storeId = row[0].store_id; + + const [row4, field2] = await db.execute(`select farm_name from farm where farm_id=?`, [farmId]); + const [row5, field3] = await db.execute(`select store_name from store where store_id=?`, [storeId]); + let farmName = row4[0].farm_name; + let storeName = row5[0].store_name; + res.json( { farm_name: farmName ,store_name:storeName }); + */ + }); +app.get('/pickup/:md_id', async (req, res) => {//특정 md의 픽업리스트 출력 + const md_id = req.params.md_id; + + try{ + + let [row2, field] = await db.execute("select * from "+"`"+"order"+"`"+` where md_id=? and order_cancel=0`, [md_id]); + res.send(row2); + + } + catch (e) { + consoe.log(e); + } + }); +app.get('/all/farm', async (req, res) => {//모든 농가 이름만 출력 + + const [row3, field] = await db.execute('select farm_name from farm'); + res.send(row3); + + });//*** +app.get('/all/store', async (req, res) => {//모든 상점 이름만 출력 + + const [row3, field] = await db.execute('select store_name from store'); + res.send(row3); + + });//*** + + +//수정,삭제,종료 +app.delete('/delete/:md_id', async(req, res)=>{ //특정 md 삭제 + const md_id = req.params.md_id; + + try { + // md 삭제(외래키때문에 마지막으로 md테이블 삭제) + const [result_keep] = await db.execute('DELETE FROM keep WHERE md_id=?', [md_id]); + const [result_payment] = await db.execute('DELETE FROM payment WHERE md_id=?', [md_id]); + const [result_pickup] = await db.execute('DELETE FROM pickup WHERE md_id=?', [md_id]); + const [result_stock] = await db.execute('DELETE FROM stock WHERE md_id=?', [md_id]); + const [result_md] = await db.execute('DELETE FROM md WHERE md_id=?', [md_id]); + + if (result_payment&&result_pickup&&result_stock&&result_md) { + res.send({md_id: md_id, msg: '삭제 성공'}); + } else { + res.status(400).send({msg: '삭제 실패'}); + } + } catch (e) { + console.log(e); + res.status(400).send({msg: '삭제 오류'}); + } + }); +app.post("/update/:md_id", async(req, res) => { //특정 md 수정 + + const MDID = req.params.md_id; + const body = req.body + //MD + const name =body.mdName; + const type =body.type; + const start = body.start; + const end =body.end; + const dd =body.dd; + const fridge=body.isFridge; + + //paypent + const price =body.price ; + const dc =body.dc ; + const comp =body.comp ; + + const farmName =body.farmName ; + //stock + const goal =body.goal ; + const storeName =body.storeName ; + const stkConfirm =body.stkConfirm; + //pu + const puStart =body.puStart ; + const puEnd =body.puEnd ; + const puWaybill=body.puWaybill; + const puTimeStart=body.puTimeStart; + const puTimeEnd=body.puTimeEnd; + console.log("날짜 : "+start+" "+end+" "+puStart+" "+puEnd+" "+puWaybill); + try{ + //search id + let [rows1, fields] = await db.execute("SELECT farm_id FROM farm where farm_name='"+farmName+"'"); + let [rows2, fields2] = await db.execute("SELECT store_id FROM store where store_name='"+storeName+"'"); + let farmId = rows1[0].farm_id; + let storeId = rows2[0].store_id; + + // UPDATE example SET name = "First" WHERE id =1; + //edit MD table + const [result1] = await db.execute('update md set md_name=?, md_type=?, md_start=?, md_end=?, md_dd=?,md_isFridge=?, farm_id=? where md_id=?', + [name,type,start, end, dd,fridge,farmId ,MDID]); + + //edit payment table + const [result2] = await db.execute('update payment set pay_price=?, pay_comp=?, pay_dc=? where md_id=?', + [price, comp, dc, MDID ]); + + //edit pickup table + const [result3] = await db.execute('update pickup set pu_start=?, pu_end=?, store_id=? ,pu_waybill=? ,pu_timeStart=?, pu_timeEnd=? where md_id=?', + [puStart, puEnd, storeId ,puWaybill,puTimeStart,puTimeEnd, MDID]); + + //edit stock table + const [result4] = await db.execute('update stock set stk_goal=?, stk_confirm=? where md_id=?', + [goal, stkConfirm, MDID ]); + + console.log('insert 완료'); + } + catch(err){ + console.log(err); + res.send( "server error"); + } +}); +app.post("/cancle/:md_id", async(req, res) => { //특정 md 종료시키기 + + const MDID = req.params.md_id; + + try{ + //edit MD table + const [result1] = await db.execute('update md set md_result=2 where md_id=?', [MDID]); + console.log("종료"); + } + catch(err){ + console.log(err); + res.send( "server error"); + } +}); + +//등록 +app.post('/post', async(req, res)=>{ //md 등록 + + const body = req.body; + console.log(body); + //MD + const name =body.mdName; + const date =body.mdDate; + const type =body.type; + const start = body.start; + const end =body.end; + const dd =body.dd; + + const isFridge = body.isFridge; + //paypent + const price =body.price ; + const dc =body.dc ; + const comp =body.comp ; + + const farmName =body.farmName ; + //stock + const goal =body.goal ; + const storeName =body.storeName ; + const stkConfirm =body.stkConfirm; + + //pu + const puStart =body.puStart ; + const puEnd =body.puEnd ; + const puWaybill=body.puWaybill; + const puTimeStart=body.puTimeStart; + const puTimeEnd=body.puTimeEnd; + + try{ + //search id + let [rows1, fields] = await db.execute("SELECT farm_id FROM farm where farm_name='"+farmName+"'"); + let [rows2, fields2] = await db.execute("SELECT store_id FROM store where store_name='"+storeName+"'"); + let farmId = rows1[0].farm_id; + let storeId = rows2[0].store_id; + + //insert MD table + const [result1] = await db.execute('INSERT INTO md (md_name,md_type,md_start,md_end,md_dd,md_isFridge,md_date, farm_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)', + [name, type, start, end, dd, isFridge, date, farmId ]); + + //insertId == md_id + insertId = result1.insertId; + console.log("md"+insertId); + //insert payment table + const [result2] = await db.execute('insert into payment(pay_price,pay_comp,pay_dc,md_id) VALUES (?, ?, ?, ?)', + [price, comp, dc, insertId ]); + + //insert pickup table + const [result3] = await db.execute('INSERT INTO pickup(pu_start,pu_end,md_id,store_id,pu_waybill,pu_timeStart,pu_timeEnd) VALUES (?, ?, ?, ?, ?,?,?)', + [puStart, puEnd, insertId, storeId ,puWaybill,puTimeStart,puTimeEnd]); + + //insert stock table //남은 재고 //주문 총량//성공 여부 + const [result4] = await db.execute('insert into stock(stk_goal,stk_remain,stk_total,stk_confirm,md_id) VALUES (?, ?, ?, ?, ?)', + [goal, goal, 0, stkConfirm, insertId ]); + + console.log('insert 완료'); + } + catch(err){ + console.log(err); + res.send( "server error"); + } + +}); +const uploadFiles=upload.fields([{name: 'thumbnail', maxCount: 1},{name:'slides',maxCount:5},{name: 'detail', maxCount: 1}]); +app.post('/post/imgs',uploadFiles, async (req,res)=>{ //상품 이미지 업로드 + console.log("img "+insertId); + let thumbnail,detail; + let slides = new Array(); + if (req.files['thumbnail'] !== undefined) { + thumbnail = req.files['thumbnail'][0].key; + } else { + thumbnail = null; + } + + for(let i=0;i<5;i++){ + if (req.files['slides'][i] !== undefined) { + slides[i] = req.files['slides'][i].key; + console.log("if "+slides[i]); + } else { + slides[i] = null; + console.log("else "+slides[i]); + } + } + + if (req.files['detail'] !== undefined) { + detail = req.files['detail'][0].key; + } else { + detail = null; + } + + //insert MD_img table + const [result1] = await db.execute('INSERT INTO md_Img (mdimg_thumbnail, mdImg_slide01, mdImg_slide02, mdImg_slide03, mdImg_slide04, mdImg_slide05, mdImg_detail, md_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)', + [thumbnail, slides[0],slides[1] ,slides[2] ,slides[3] ,slides[4] ,detail,insertId ]); + + + }); +//검색 +app.get('/sort/:sort', async(req, res) => { // md 정렬 + + const sort = req.params.sort; + switch(sort){ + case 'recent': + try {//최근등록순 + //제일 처음 출력-초기화과정 + // 공구 성공 기준 넘으면 공구결과 성공으로 수정 + //진행기간이 끝나지않은 상품은 공구 종료되지않음 + // select case md_result when stk_total>=(stk_goal*0.3) then 0 else 1 end from md join stock on md.md_id=stock.md_id; + await db.execute("set sql_safe_updates=0"); + await db.execute("update md inner join stock on md.md_id=stock.md_id set md_result= case when md_end >= now() then null when md_result=2 then 2 when stk_total>=(stk_goal*0.3) then 1 else 0 end "); + //공구 진행단계 수정(상품준비중,배송중과 스토어 도착은 적용되지않음,,) //when pu_waybill is not null then "상품배송중" + await db.execute('update stock inner join md on md.md_id=stock.md_id join pickup on md.md_id=pickup.md_id set stk_confirm = case when md_result = 0 then "공구 취소" when pu_end=now() and md_result=1;"); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + case 'done': + try {//진행확정 + let [rows, fields] = await db.execute("select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id where md_result=1;"); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + } + }); + app.get('/MDResult/:sort', async(req, res) => { //md 완료페이지 정렬 + + const sort = req.params.sort; + switch(sort){ + case 'recent': + try { + //최근등록순 출력 + let [rows, fields] = await db.execute("select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id where md.md_result =0 || md.md_result =2 ORDER BY md.md_id desc"); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + + + case 'cancle': + try {//진행취소 + let [rows, fields] = await db.execute("select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id where md_result=0;"); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + case 'out': + try {//진행종료 + let [rows, fields] = await db.execute("select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id where md_result=2;"); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + } + }); + + app.get('/:search/:search_value', async(req, res) => { //md 검색 + + const search = req.params.search; + const search_value ='%'+ req.params.search_value+'%'; + + switch(search){ + + case 'name': + try {//상품이름 + let [rows, fields] = await db.execute('select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id where md.md_name like ?',[search_value]); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + case 'farm2': + try {//농가 + console.log(search_value); + //search id + let [rows1, fields1] = await db.execute('SELECT farm_id FROM farm where farm_name like ?',[search_value]); + let farmId = rows1[0].farm_id; + + let [rows, fields2] = await db.execute('select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id where md.farm_id=?',[farmId]); + res.send(rows); + } + catch (e) { + if (e instanceof TypeError) { + console.log('검색결과가 없습니다'); + res.send(); + }else{ + console.log(e); + } + } + break; + + case 'store': + try {//상점 + let [rows2, fields2] = await db.execute('SELECT store_id FROM store where store_name like ?',[search_value]); + let storeId = rows2[0].store_id; + let [rows, fields] = await db.execute('select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id where pickup.store_id=?',[storeId]); + res.send(rows); + } + catch (e) { + if (e instanceof TypeError) { + console.log('검색결과가 없습니다'); + res.send(); + }else{ + console.log(e); + } + } + break; + + } + }); + app.get('/MDResult/:search/:search_value', async(req, res) => { //md 검색 + + const search = req.params.search; + const search_value ='%'+ req.params.search_value+'%'; + + switch(search){ + + case 'name': + try {//상품이름 + let [rows, fields] = await db.execute('select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id where md.md_name like ?',[search_value]); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + case 'farm2': + try {//농가 + console.log(search_value); + //search id + let [rows1, fields1] = await db.execute('SELECT farm_id FROM farm where farm_name like ?',[search_value]); + let farmId = rows1[0].farm_id; + + let [rows, fields2] = await db.execute('select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id where md.farm_id=?',[farmId]); + res.send(rows); + } + catch (e) { + if (e instanceof TypeError) { + console.log('검색결과가 없습니다'); + res.send(); + }else{ + console.log(e); + } + } + break; + + case 'store': + try {//상점 + let [rows2, fields2] = await db.execute('SELECT store_id FROM store where store_name like ?',[search_value]); + let storeId = rows2[0].store_id; + let [rows, fields] = await db.execute('select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id where pickup.store_id=?',[storeId]); + res.send(rows); + } + catch (e) { + if (e instanceof TypeError) { + console.log('검색결과가 없습니다'); + res.send(); + }else{ + console.log(e); + } + } + break; + + } + });//*** + app.get('/name/:farm_id/:store_id', async (req, res) => {//특정 상점,농장 이름/소개 출력 + const farmId = req.params.farm_id; + const storeId = req.params.store_id; + + const [row4, field2] = await db.execute(`select farm_name,farm_info from farm where farm_id=?`, [farmId]); + const [row5, field3] = await db.execute(`select store_name,store_info from store where store_id=?`, [storeId]); + let farmName = row4[0].farm_name; + let farmInfo = row4[0].farm_info; + let storeName = row5[0].store_name; + let storeInfo = row5[0].store_info; + res.json( { farm_name: farmName ,farm_info:farmInfo,store_name:storeName,store_info:storeInfo }); + + }); + +module.exports = app; \ No newline at end of file diff --git a/notice.js b/notice.js new file mode 100644 index 0000000..5090e7b --- /dev/null +++ b/notice.js @@ -0,0 +1,133 @@ +const express = require('express'); +const app = express(); +const db = require('./db'); +const aws_key = require('./config').aws_access; +const aws = require('aws-sdk'); +const multer = require('multer'); +const multer_s3 = require('multer-s3'); + +const s3 = new aws.S3({ + accessKeyId: aws_key.access, + secretAccessKey: aws_key.secret, + region: aws_key.region +}); +const storage = multer_s3({ + s3: s3, + bucket: 'ggdjang', + contentType: multer_s3.AUTO_CONTENT_TYPE, + acl: 'public-read', + metadata: function(req, file, cb) { + cb(null, {fieldName: file.fieldname}); + }, + key: function (req, file, cb) { + cb(null, `notice/${Date.now()}_${file.originalname}`); + } +}) +const upload = multer({ + storage: storage +}) + +app.use(express.json()); + +/** 특정 notice 가져오기 */ +app.get('/:noticeId', async (req, res) => { + const noticeId = req.params.noticeId; + + try { + const [notice, fields] = await db.execute(`SELECT * FROM notice WHERE notice_id = ?`, [noticeId]); + + console.log(`NOTICE_READ_SUCCESS :: noticeId = ${noticeId}`); + res.send({ + msg: 'NOTICE_READ_SUCCESS', + data: notice[0] + }); + } catch (e) { + console.log(`NOTICE_READ_FAILED :: msg = ${e}`); + res.status(500).send({msg: 'NOTICE_READ_FAILED'}); + } +}) + +// notice 가져오기 +app.get('/', async (req, res) => { + const aspect = req.query.aspect; + + try { + let returnNotice; + if (aspect !== undefined) { + const [notices, fields] = await db.execute(`SELECT * FROM notice ORDER BY notice_date DESC`); + returnNotice = notices; + } else { + const [notices, fields] = await db.execute(`SELECT * FROM notice WHERE notice_date < CURRENT_DATE() ORDER BY notice_date DESC`); + returnNotice = notices; + } + + console.log(`NOTICE_READ_SUCCESS :: `); + res.send(returnNotice); + } catch (e) { + console.log(`NOTICE_READ_FAILED :: msg = ${e}`); + res.status(500).send({msg: "server error"}); + } +}) + +// notice 작성 +app.post('/', upload.single('photo'), async (req, res) => { + const body = req.body; + const title = body.title; + const context = body.context; + const target = '소비자'; + const type = body.type; + const date = body.date; + let photo; + if (req.file) photo = req.file.key; + else photo = null; + + try { + const [result] = await db.execute(`INSERT INTO notice (notice_title, notice_context, notice_photo, notice_date, notice_target, notice_type) VALUES (?, ?, ?, ?, ?, ?)`, + [title, context, photo, date, target, type]); + + console.log(`NOTICE_CREATE_SUCCESS :: noticeId = ${result.insertId}`); + res.send({id: result.insertId}); + } catch (e) { + console.log(`NOTICE_CREATE_FAILED :: msg = ${e}`); + res.status(500).send({msg: "server error"}); + } +}) + +// notice 삭제 +app.post('/delete', async (req, res) => { + const notice_ids = req.body.notice_ids; + + try { + for (let notice_id of notice_ids) { + notice_id = notice_id.id; + + const [notice, field] = await db.execute(`SELECT * FROM notice WHERE notice_id = ?`, [notice_id]); + const photo = notice[0].notice_photo; + + const [result] = await db.execute(`DELETE FROM notice WHERE notice_id = ?`, [notice_id]); + // 삭제 성공하면 photo 도 s3 에서 삭제 + if (result) { + if (photo) { + s3.deleteObject({ + Bucket: 'ggdjang', + Key: photo + }, (err, data) => { + if (err) console.log(err); + else console.log(data); + }); + } + } else { + console.log(`NOTICE_DELETE_FAILED :: noticeIds = ${notice_ids}`); + res.status(400).send({msg: '삭제 실패'}); + } + } + + console.log(`NOTICE_DELETE_SUCCESS :: noticeIds = ${notice_ids}`); + res.send({notice_id: notice_ids, msg: '삭제 성공'}); + } catch (e) { + console.log(`NOTICE_DELETE_FAILED :: msg = ${e}`); + res.status(500).send({msg: 'server error'}); + } +}) + +module.exports = app; diff --git a/notification.js b/notification.js new file mode 100644 index 0000000..24dfc1e --- /dev/null +++ b/notification.js @@ -0,0 +1,334 @@ +const express = require('express'); +const app = express(); +const aws_key = require('./config').aws_access; +const aws = require('aws-sdk'); +const multer = require('multer'); +const multer_s3 = require('multer-s3'); +const db = require('./db'); +const firebase = require('firebase-admin') +const firebaseCredential = require('./config').firebase; +const scheduler = require('node-schedule'); + +app.use(express.json()) + +const s3 = new aws.S3({ + accessKeyId: aws_key.access, + secretAccessKey: aws_key.secret, + region: aws_key.region +}); +const storage = multer_s3({ + s3: s3, + bucket: 'ggdjang', + contentType: multer_s3.AUTO_CONTENT_TYPE, + acl: 'public-read', + metadata: function(req, file, cb) { + cb(null, {fieldName: file.fieldname}); + }, + key: function (req, file, cb) { + cb(null, `notification/${Date.now()}_${file.originalname}`); + } +}) +const upload = multer({ + storage: storage +}) + +firebase.initializeApp({ + credential: firebase.credential.cert(firebaseCredential), +}); + +/** 알림을 보낼 사용자 조회 */ +app.get('/user', async (req, res) => { + try { + const [result, field] = await db.execute(`SELECT user_no, user_id, user_name FROM user`); + + console.log(`USER_READ_SUCCESS :: `); + res.send({msg: 'USER_READ_SUCCESS', data: result}); + } catch (e) { + console.log(`USER_READ_FAILED :: msg = ${e}`); + res.status(500).send({msg: 'USER_READ_FAILED'}); + } +}) + +/** 알림 리스트 조회 */ +app.get('/', async (req, res) => { + const body = req.body; + const filter = req.query.filter; + + const resBody = {msg: 'NOTIFICATION_READ_SUCCESS'}; + try { + if (!filter) { + const [result, field] = await db.execute(`SELECT * + FROM notification + ORDER BY createdAt DESC`); + resBody['data'] = result; + } else { + const [result, field] = await db.execute(`SELECT * + FROM notification WHERE notification_target = ? + ORDER BY createdAt DESC`, [filter]); + resBody['data'] = result; + } + + console.log(`NOTIFICATION_READ_SUCCESS :: `); + res.send(resBody); + } catch (e) { + console.log(`NOTIFICATION_READ_FAILED :: msg = ${e}`); + res.status(500).send({msg: 'NOTIFICATION_READ_FAILED'}); + } +}) + + +/** 개별 알림 조회 */ +app.get('/:notificationId', async (req, res) => { + const notificationId = req.params.notificationId; + const resBody = {msg: 'NOTIFICATION_READ_SUCCESS'}; + + try { + const [result, field] = await db.execute(`SELECT *FROM notification WHERE notification_id = ?`, [notificationId]); + resBody['data'] = result[0]; + + console.log(`NOTIFICATION_READ_SUCCESS :: notificationId = ${notificationId}`); + res.send(resBody); + } catch (e) { + console.log(`NOTIFICATION_READ_FAILED :: msg = ${e}`); + res.status(500).send({msg: 'NOTIFICATION_READ_FAILED'}); + } +}) + +/** 사용자 아이디로 토큰 찾기 */ +const getTokensByUser = async (userIds) => { + let tokens = []; + + for (let userId of userIds) { + const [result, field] = await db.execute(`SELECT fcm_token FROM user WHERE user_no = ?`, [userId]); + tokens.push(result[0].fcm_token); + } + + return tokens; +} + +/** 사용자별 알림 리스트 생성 */ +const createNotificationByUser = async (noticeId, userIds, status) => { + for (let userId of userIds) { + if (status === 'SENT') + await db.execute(`INSERT INTO notification_by_user (notification_user, notification_id) VALUES (?, ?)`, + [userId, noticeId]); + else + await db.execute(`INSERT INTO notification_by_user (notification_user, notification_id, status) VALUES (?, ?, ?)`, + [userId, noticeId, 'SCHEDULED']); + } +} + +/** 알림 생성 */ +const createNotification = async (body, image) => { + const title = body.title; + const content = body.content; + const type = body.type; + const target = body.target; + const pushType = body.pushType; + const date = body.date; + + const [result, fields] = await db.execute(`INSERT INTO notification (notification_title, notification_content, notification_type, notification_target, notification_img, + notification_push_type, notification_date) VALUES (?, ?, ?, ?, ?, ?, ?)`, [title, content, type, target, image, pushType, date]); + + return result; +} + +const createTokenMessage = (userIds, tokens, title, content, image) => { + let message; + + if (image !== null) { + const url = encodeURI(`https://ggdjang.s3.ap-northeast-2.amazonaws.com/${image}`) + message = { + notification: { + title: title, + body: content, + imageUrl: url + }, + data: { + title: title, + body: content, + // userId: userIds + }, + tokens: tokens + } + } else { + message = { + notification: { + title: title, + body: content + }, + data: { + title: title, + body: content, + // uerId: userIds + }, + tokens: tokens + } + } + + return message; +} + +const createTopicMessage = (topic, title, content, image) => { + let message; + + if (image !== null) { + const url = encodeURI(`https://ggdjang.s3.ap-northeast-2.amazonaws.com/${image}`) + message = { + notification: { + title: title, + body: content, + imageUrl: url + }, + data: { + title: title, + body: content + }, + topic: topic + } + } else { + message = { + notification: { + title: title, + body: content + }, + data: { + title: title, + body: content + }, + topic: topic + } + } + + return message; +} + +/** 토큰으로 알림 전송 */ +app.post('/token', upload.single('image'), async (req, res) => { + const body = req.body; + let userIds = req.body.userIds; + if (!Array.isArray(userIds)) { + userIds = userIds.split(',') + } + const tokens = await getTokensByUser(userIds); + + const title = body.title; + const content = body.content; + const pushType = body.pushType; + let image = null; + if (req.file !== undefined) image = req.file.key; + + try { + const noticeResult = await createNotification(body, image); + + if (pushType === '실시간') { + const message = createTokenMessage(userIds, tokens, title, content, image); + + const msgResult = await firebase.messaging().sendMulticast(message); + await createNotificationByUser(noticeResult.insertId, userIds, 'SENT'); + + console.log(`NOTIFICATION_SEND_SUCCESS :: notificationId = ${noticeResult.insertId}`); + res.send({ + msg: "NOTIFICATION_SEND_SUCCESS", + data: { + successCount: msgResult.successCount, + failureCount: msgResult.failureCount + }} + ); + } else { + await createNotificationByUser(noticeResult.insertId, userIds, 'SCHEDULED'); + + console.log(`NOTIFICATION_RESERVE_SUCCESS :: notificationId = ${noticeResult.insertId}`); + res.send({msg: "NOTIFICATION_RESERVE_SUCCESS"}); + } + } catch (e) { + console.log(`NOTIFICATION_SEND_FAILED :: msg = ${e}`); + res.status(500).send({msg: 'NOTIFICATION_SEND_FAILED'}); + } +}) + +/** 토픽으로 알림 전송 */ +app.post('/topic', upload.single('image'), async (req, res) => { + const body = req.body; + const topic = body.topic; + + const title = body.title; + const content = body.content; + const pushType = body.pushType; + let image = null; + if (req.file !== undefined) image = req.file.key; + + try { + const noticeResult = await createNotification(body, image); + + const [userResult, field] = await db.execute('SELECT user_no FROM user'); + let userIds = []; + for (let user of userResult) { + userIds.push(user.user_no); + } + + if (pushType === '실시간') { + const message = createTopicMessage(topic, title, content, image); + + const msgResult = await firebase.messaging().send(message); + await createNotificationByUser(noticeResult.insertId, userIds, 'SENT'); + + console.log(`NOTIFICATION_SEND_SUCCESS (topic) :: notificationId = ${noticeResult.insertId}`); + res.send({ + msg: "NOTIFICATION_SEND_SUCCESS", + data: { + successCount: msgResult.successCount, + failureCount: msgResult.failureCount + }} + ); + } else { + await createNotificationByUser(noticeResult.insertId, userIds, 'SCHEDULED'); + + console.log(`NOTIFICATION_RESERVE_SUCCESS (topic) :: notificationId = ${noticeResult.insertId}`); + res.send({msg: "NOTIFICATION_RESERVE_SUCCESS"}); + } + } catch (e) { + console.log(`NOTIFICATION_SEND_FAILED (topic) :: msg = ${e}`); + res.status(500).send({msg: 'NOTIFICATION_SEND_FAILED'}); + } +}) + +/** 매 정각에 예약된 알림(정각 ~ 5분 사이) 확인 후 발송 */ +scheduler.scheduleJob('0 * * * *', async () => { + try { + const [notifications, field] = await db.execute(`SELECT notification_id, notification_target, notification_title, notification_content FROM notification + WHERE notification_push_type = ? AND notification_date BETWEEN NOW() and NOW() + INTERVAL 5 MINUTE`, ['예약']); + + for (const notification of notifications) { + const notificationId = notification.notification_id; + const target = notification.notification_target; + const title = notification.notification_title; + const content = notification.notification_content; + const image = notification.notification_img; + + const [users, fields] = await db.execute(`SELECT notification_user FROM notification_by_user WHERE notification_id = ?`, [notificationId]); + let userIds = []; + for (let user of users) { + userIds.push(user.notification_user); + } + + if (target === '개인') { + const tokens = await getTokensByUser(userIds); + + const message = createTokenMessage(tokens, title, content, image); + const msgResult = await firebase.messaging().sendMulticast(message); + } else if (target === '소비자') { + const message = createTopicMessage('userTopic', title, content, image); + const msgResult = await firebase.messaging().send(message); + } + // TODO: 관리자 알림 개발 완료 후 추가 + + await db.execute(`UPDATE notification_by_user SET status = ? WHERE notification_id = ?`, ['SENT', notificationId]); + console.log(`NOTIFICATION_SEND_SUCCESS (schedule) :: notificationId = ${notificationId}`); + } + } catch (e) { + console.log(`NOTIFICATION_SEND_FAILED (schedule) :: msg = ${e}`); + } +}) + +module.exports = app; \ No newline at end of file diff --git a/package.json b/package.json index e772acf..5fc822d 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,17 @@ "author": "", "license": "ISC", "dependencies": { + "axios": "^0.27.2", + "crypto-js": "^4.1.1", + "aws-sdk": "^2.1099.0", "bcrypt": "^5.0.1", "cors": "^2.8.5", - "express": "^4.17.3", + "express": "^4.18.2", + "firebase-admin": "^11.5.0", "jsonwebtoken": "^8.5.1", - "mysql2": "^2.3.3" + "multer": "^1.4.4", + "multer-s3": "^2.10.0", + "mysql2": "^2.3.3", + "node-schedule": "^2.1.1" } } diff --git a/partner.js b/partner.js new file mode 100644 index 0000000..2d5dd5c --- /dev/null +++ b/partner.js @@ -0,0 +1,571 @@ +const express = require('express'); +const app = express(); +const db = require('./db'); +const upload = require('./uploads'); +const cors = require('cors'); + +app.use(cors()); +app.use(express.json()); +app.use(express.urlencoded({ extended: true })); + +let insertId; + +//읽어오기 +/* +app.get('/farm', async(req, res) => { //모든 농가 + + try {//모든 상점 + let [rows, fields] = await db.execute(`select * from farm join Hours on farm.farm_id=Hours.hours_PartnerId where Hours.hours_partner=0`); + res.send(rows); + } + catch (e) { + console.log(e); + } + + }); +app.get('/store', async(req, res) => { //모든 상점 + + try {//모든 상점 + let [rows, fields] = await db.execute(`select * from store join Hours on store.store_id=Hours.hours_PartnerId where Hours.hours_partner=1`); + res.send(rows); + } + catch (e) { + console.log(e); + } + + }); +*/ +app.get('/read/farm/:farm_id', async (req, res) => {//특정 농가만 get + const farm_id = req.params.farm_id; + + try{ + //농가별 진행한 공구 횟수 count + let [row1, field1] = await db.execute(`SELECT COUNT(case when farm_id=? then 1 end) as farmCount FROM md;`, [farm_id]); + let farmCount=row1[0].farmCount; + console.log(row1); + await db.execute('update farm set farm_saleQty=? where farm_id=?', [farmCount,farm_id]); + let [row2, field] = await db.execute(`select * from farm join Hours on farm.farm_id=Hours.hours_PartnerId where farm.farm_id=? and Hours.hours_partner=0`, [farm_id]); + res.send(row2); + console.log(row2); + } + catch (e) { + console.log(e); + } + }); +app.get('/read/farm/imgs/:farm_id', async (req, res) => {//특정 농가의 이미지만 + const farm_id = req.params.farm_id;//`select * from md where md_id=?`, [md_id] + try{ + //농가별 진행한 공구 횟수 count + let [row1, field1] = await db.execute(`SELECT COUNT(case when farm_id=? then 1 end) as farmCount FROM md;`, [farm_id]); + let farmCount=row1[0].farmCount; + await db.execute('update farm set farm_saleQty=? where farm_id=?', [farmCount,farm_id]); + const [row23, field] = await db.execute(`select farm_saleQty,farm_thumbnail, farm_mainImg, farm_detailImg from farm where farm_id = ?`,[farm_id]); + res.send(row23); + //console.log(row23); + } + catch (e) { + console.log(e); + } + }); //*** + +app.get('/read/store/:store_id', async (req, res) => {//특정 store만 get + const store_id = req.params.store_id; + + try{ + + let [row2, field] = await db.execute(`select * from store join Hours on store.store_id=Hours.hours_PartnerId where store.store_id=? and Hours.hours_partner=1`, [store_id]); + res.send(row2); + console.log(row2); + } + catch (e) { + console.log(e); + } + }); +app.get('/read/store/imgs/:store_id', async (req, res) => {//특정 상가의 이미지만 + const store_id = req.params.store_id;//`select * from md where md_id=?`, [md_id] + try{ + const [row23, field] = await db.execute(`select store_thumbnail, store_mainImg, store_detailImg from store where store_id = ?`,[store_id]); + res.send(row23); + console.log(store_id); + } + catch (e) { + console.log(e); + } + }); //**** + app.get('/md/farm/:farm_id', async (req, res) => {//농가에서 진행했던 md + + const farm_id = req.params.farm_id; + + const [row3, field] = await db.execute(`select md_name,md.md_id,stk_confirm from md join stock on md.md_id=stock.md_id where farm_id=?`,[farm_id]); + + res.send(row3); + + }); + app.get('/md/store/:store_id', async (req, res) => {//상점에서 진행했던 md + const store_id = req.params.store_id; + const [row3, field] = await db.execute(`select md_name,md.md_id,stk_confirm from md join stock on md.md_id=stock.md_id join pickup on md.md_id=pickup.md_id where pickup.store_id=?`,[store_id]); + + res.send(row3); + + }); +//수정 +app.post("/farm/update/:farm_id", async(req, res) => { //특정 농가 수정 + + const FarmID = req.params.farm_id; + const body = req.body + + //farm + const name =body.farm_name; + const info =body.farm_info; + const loc =body.farm_loc; + const detailLoc =body.farm_detailLoc; + const zonecode =body.farm_zonecode; + const size = body.farm_size; + + const farmer =body.farm_farmer; + const phone =body.farm_phone; + const email =body.farm_email; + const mainItem =body.farm_mainItem; + const saleItem = body.farm_saleItem; + + const start = body.farm_start; + const end =body.farm_end; + const term =body.farm_contractTerm; + const isContract =body.farm_isContract; + const saleQty =body.farm_saleQty; + //const img = body.farm_img; + const businessNum =body.farm_businessNum; + const memo = body.farm_memo; + + //운영시간 + const mon1 = body.hours_mon1; const mon2 = body.hours_mon2; + const tue1 = body.hours_tue1; const tue2 = body.hours_tue2; + const wed1 = body.hours_wed1; const wed2 = body.hours_wed2; + const thu1 = body.hours_thu1; const thu2 = body.hours_thu2; + const fri1 = body.hours_fri1; const fri2 = body.hours_fri2; + const sat1 = body.hours_sat1; const sat2 = body.hours_sat2; + const sun1 = body.hours_sun1; const sun2 = body.hours_sun2; + const week= body.hours_week; + console.log(body); + try{ + + //insert farm table + const [result1] = await db.execute('update farm set farm_name=?, farm_info=? ,farm_loc=? ,farm_detailLoc=?, farm_zonecode=?, farm_mainItem=?, farm_saleItem=?, farm_saleQty=?, farm_farmer=?, farm_phone=?, farm_email =?, farm_size=?, farm_start=?, farm_end=?, farm_contractTerm=?, farm_isContract=?, farm_businessNum=?, farm_memo=? where farm_id=?', + [name, info, loc , detailLoc, zonecode , mainItem, saleItem,saleQty, farmer, phone, email, size, start, end, term, isContract, businessNum, memo,FarmID]); + //hours_partner : 농가는 0, + const [result2] = await db.execute('update Hours set hours_mon1=?,hours_mon2=?,hours_tue1=?,hours_tue2=?,hours_wed1=?,hours_wed2=?,hours_thu1=?,hours_thu2=?,hours_fri1=?,hours_fri2=?,hours_sat1=?,hours_sat2=?,hours_sun1=?,hours_sun2=?,hours_week=? where hours_partnerId=?', + [mon1,mon2,tue1,tue2,wed1,wed2,thu1,thu2,fri1,fri2,sat1,sat2,sun1,sun2,week,FarmID]); + console.log('insert 완료'); + } + catch(err){ + console.log(err); + res.send( "server error"); + } +}); + + +app.post("/store/update/:store_id", async(req, res) => { //특정 상점 수정 + + const StoreID = req.params.store_id; + const body = req.body + + //store + const name =body.store_name; + const info =body.store_info; + const loc =body.store_loc; + const detailLoc =body.store_detailLoc; + const zonecode =body.store_zonecode; + + const size = body.store_size; + + const owner =body.store_owner; + const phone =body.store_phone; + const email =body.store_email; + const start = body.store_start; + const end =body.store_end; + const term =body.store_contractTerm; + const isContract =body.store_isContract; + + const memo = body.store_memo; + const type = body.store_type; + const fridge= body.store_fridge; + const number = body.store_number; + const businessNum = body.store_businessNum; + + //운영시간 + const mon1 = body.hours_mon1; const mon2 = body.hours_mon2; + const tue1 = body.hours_tue1; const tue2 = body.hours_tue2; + const wed1 = body.hours_wed1; const wed2 = body.hours_wed2; + const thu1 = body.hours_thu1; const thu2 = body.hours_thu2; + const fri1 = body.hours_fri1; const fri2 = body.hours_fri2; + const sat1 = body.hours_sat1; const sat2 = body.hours_sat2; + const sun1 = body.hours_sun1; const sun2 = body.hours_sun2; + const week= body.hours_week; + + console.log(body); + try{ + + //insert farm table + const [result1] = await db.execute('update store set store_name=?, store_info=? ,store_loc=? ,store_detailLoc=?, store_zonecode=?, store_owner=?, store_phone=?, store_email=? , store_size=?, store_start=?, store_end=?, store_contractTerm=?, store_isContract=?, store_memo=?,store_type=?, store_fridge=?,store_number=?,store_businessNum=? where store_id=?', + [name, info, loc , detailLoc, zonecode , owner, phone, email, size, start, end, term, isContract, memo , type, fridge,number,businessNum,StoreID]); + //hours_partner : 스토어는 1, + const [result2] = await db.execute('update Hours set hours_mon1=?,hours_mon2=?,hours_tue1=?,hours_tue2=?,hours_wed1=?,hours_wed2=?,hours_thu1=?,hours_thu2=?,hours_fri1=?,hours_fri2=?,hours_sat1=?,hours_sat2=?,hours_sun1=?,hours_sun2=?,hours_week=? where hours_partnerId=?', + [mon1,mon2,tue1,tue2,wed1,wed2,thu1,thu2,fri1,fri2,sat1,sat2,sun1,sun2,week,StoreID]); + console.log('insert 완료'); + } + catch(err){ + console.log(err); + res.send( "server error"); + } +}); + +//등록 +app.post('/post/farm', async(req, res)=>{ //농가 등록 + + const body = req.body; + console.log(body); + //farm + const name =body.farm_name; + const info =body.farm_info; + const loc =body.farm_loc; + const detailLoc =body.farm_detailLoc; + const zonecode =body.farm_zonecode; + const size = body.farm_size; + + const farmer =body.farm_farmer; + const phone =body.farm_phone; + const email =body.farm_email; + const mainItem =body.farm_mainItem; + const saleItem = body.farm_saleItem; + + const start = body.farm_start; + const end =body.farm_end; + const term =body.farm_contractTerm; + const isContract =body.farm_isContract; + const saleQty =body.farm_saleQty; + //const img = body.farm_img; + const businessNum=body.farm_businessNum; + const memo = body.farm_memo; + + //운영시간 + const mon1 = body.hours_mon1; const mon2 = body.hours_mon2; + const tue1 = body.hours_tue1; const tue2 = body.hours_tue2; + const wed1 = body.hours_wed1; const wed2 = body.hours_wed2; + const thu1 = body.hours_thu1; const thu2 = body.hours_thu2; + const fri1 = body.hours_fri1; const fri2 = body.hours_fri2; + const sat1 = body.hours_sat1; const sat2 = body.hours_sat2; + const sun1 = body.hours_sun1; const sun2 = body.hours_sun2; + const week= body.hours_week; + + try{ + + //insert farm table + const [result1] = await db.execute('INSERT INTO farm (farm_name, farm_info ,farm_loc ,farm_detailLoc, farm_zonecode, farm_mainItem, farm_saleItem, farm_saleQty, farm_farmer, farm_phone, farm_email , farm_size, farm_start, farm_end, farm_contractTerm, farm_isContract, farm_businessNum, farm_memo) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + [name, info, loc , detailLoc, zonecode , mainItem, saleItem,saleQty, farmer, phone, email, size, start, end, term, isContract, businessNum, memo]); + insertId = result1.insertId; + + //hours_partner : 농가는 0, + const [result2] = await db.execute('INSERT INTO Hours (hours_partner,hours_partnerId,hours_mon1,hours_mon2,hours_tue1,hours_tue2,hours_wed1,hours_wed2,hours_thu1,hours_thu2,hours_fri1,hours_fri2,hours_sat1,hours_sat2,hours_sun1,hours_sun2,hours_week) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + [0,insertId,mon1,mon2,tue1,tue2,wed1,wed2,thu1,thu2,fri1,fri2,sat1,sat2,sun1,sun2,week]); + console.log('insert 완료'); + } + catch(err){ + console.log(err); + res.send( "server error"); + } + +}); +const farmUploadFiles=upload.fields([{name: 'thumbnail', maxCount: 1},{name:'main',maxCount:1},{name: 'detail', maxCount: 1}]); +app.post('/post/farm/img',farmUploadFiles, async (req,res)=>{ //농가 이미지 업로드 + +let thumbnail,main,detail; + + if (req.files['thumbnail'] !== undefined) { + thumbnail = req.files['thumbnail'][0].key; + } else { + thumbnail = null; + } + + + if (req.files['main']!== undefined) { + main = req.files['main'][0].key; + + } else { + main= null; + } + + + if (req.files['detail'] !== undefined) { + detail = req.files['detail'][0].key; + } else { + detail = null; + } + + //insert store table UPDATE store SET store_type= '식료품' WHERE store_id =11; + const [result1] = await db.execute('UPDATE farm SET farm_thumbnail=?, farm_mainImg=?, farm_detailImg=? where farm_id=?', + [thumbnail, main,detail,insertId ]); + +}); + app.post('/post/store', async(req, res)=>{ //상점 등록 + + const body = req.body; + console.log(body); + //store + const name =body.store_name; + const info =body.store_info; + const loc =body.store_loc; + const detailLoc =body.store_detailLoc; + const zonecode =body.store_zonecode; + + const size = body.store_size; + + const owner =body.store_owner; + const phone =body.store_phone; + const email =body.store_email; + const start = body.store_start; + const end =body.store_end; + const term =body.store_contractTerm; + const isContract =body.store_isContract; + + const memo = body.store_memo; + const type = body.store_type; + const fridge= body.store_fridge; + const number = body.store_number; + const businessNum = body.store_businessNum; + + //운영시간 + const mon1 = body.hours_mon1; const mon2 = body.hours_mon2; + const tue1 = body.hours_tue1; const tue2 = body.hours_tue2; + const wed1 = body.hours_wed1; const wed2 = body.hours_wed2; + const thu1 = body.hours_thu1; const thu2 = body.hours_thu2; + const fri1 = body.hours_fri1; const fri2 = body.hours_fri2; + const sat1 = body.hours_sat1; const sat2 = body.hours_sat2; + const sun1 = body.hours_sun1; const sun2 = body.hours_sun2; + const week= body.hours_week; + + try{ + + //insert store table + const [result1] = await db.execute('INSERT INTO store (store_name, store_info ,store_loc ,store_detailLoc, store_zonecode, store_owner, store_phone, store_email , store_size, store_start, store_end, store_contractTerm, store_isContract, store_memo,store_type, store_fridge,store_number,store_businessNum) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)', + [name, info, loc , detailLoc, zonecode , owner, phone, email, size, start, end, term, isContract, memo , type, fridge,number,businessNum]); + insertId = result1.insertId; + + + //hours_partner : 스토어는 1, + const [result2] = await db.execute('INSERT INTO Hours (hours_partner,hours_partnerId,hours_mon1,hours_mon2,hours_tue1,hours_tue2,hours_wed1,hours_wed2,hours_thu1,hours_thu2,hours_fri1,hours_fri2,hours_sat1,hours_sat2,hours_sun1,hours_sun2,hours_week) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + [1,insertId,mon1,mon2,tue1,tue2,wed1,wed2,thu1,thu2,fri1,fri2,sat1,sat2,sun1,sun2,week]); + console.log('insert 완료'); + } + catch(err){ + console.log(err); + res.send( "server error"); + } + +}); +const storeUploadFiles=upload.fields([{name: 'thumbnail', maxCount: 1},{name:'main',maxCount:1},{name: 'detail', maxCount: 1}]); +app.post('/post/store/popo',storeUploadFiles, async (req,res)=>{ //상점 이미지 업로드 + + let thumbnail,main,detail; + + if (req.files['thumbnail'] !== undefined) { + thumbnail = req.files['thumbnail'][0].key; + } else { + thumbnail = null; + } + + + if (req.files['main']!== undefined) { + main = req.files['main'][0].key; + + } else { + main= null; + } + + + if (req.files['detail'] !== undefined) { + detail = req.files['detail'][0].key; + } else { + detail = null; + } + + //insert store table UPDATE store SET store_type= '식료품' WHERE store_id =11; + const [result1] = await db.execute('UPDATE store SET store_thumbnail=?, store_mainImg=?, store_detailImg=? where store_id=?', + [thumbnail, main,detail,insertId ]); + + + + }); //**** +//검색 +app.get('/:partner/:sort', async(req, res) => { //파트너 정렬 + + + const partner = req.params.partner;//농가면 0 스토어는 1 + const sort = req.params.sort; + if(partner=='store')//1이면 스토어 + { + switch(sort){ + case 'recent': + try {//최근등록순 + let [rows, fields] = await db.execute("select * from store join Hours on store.store_id=Hours.hours_PartnerId where Hours.hours_partner=1 ORDER BY store.store_id desc"); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + case 'building': + try {//협업기획중 + let [rows, fields] = await db.execute("select * from store join Hours on store.store_id=Hours.hours_PartnerId where Hours.hours_partner=1 and store_isContract='협업기획중' "); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + case 'proceeding': + try {//공동구매 진행중 + let [rows, fields] = await db.execute("select * from store join Hours on store.store_id=Hours.hours_PartnerId where Hours.hours_partner=1 and store_isContract='공동구매진행'"); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + case 'keep': + try {//미활동 + let [rows, fields] = await db.execute("select * from store join Hours on store.store_id=Hours.hours_PartnerId where Hours.hours_partner=1 and store_isContract='미활동'"); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + } + } + else if (partner=='farm')//농가 + { + switch(sort){ + case 'recent': + try {//최근등록순 + let [rows, fields] = await db.execute("select * from farm join Hours on farm.farm_id=Hours.hours_PartnerId where Hours.hours_partner=0 ORDER BY farm.farm_id desc"); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + case 'building': + try {//협업기획중 + let [rows, fields] = await db.execute("select * from farm join Hours on farm.farm_id=Hours.hours_PartnerId where Hours.hours_partner=0 and farm_isContract='협업기획중' "); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + case 'proceeding': + try {//공동구매 진행중 + let [rows, fields] = await db.execute("select * from farm join Hours on farm.farm_id=Hours.hours_PartnerId where Hours.hours_partner=0 and farm_isContract='공동구매진행'"); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + case 'keep': + try {//미활동 + let [rows, fields] = await db.execute("select * from farm join Hours on farm.farm_id=Hours.hours_PartnerId where Hours.hours_partner=0 and farm_isContract='미활동'"); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + } + } + + }); + app.get('/:partner/:search/:search_value', async(req, res) => { //파트너 검색 + + const partner = req.params.partner;//농가, 스토어 + const search = req.params.search; + const search_value ='%'+ req.params.search_value+'%'; + + if(partner=='store')// 스토어 + { + switch(search){ + + case 'name': + try {//가게이름 + let [rows, fields] = await db.execute('select * from store where store_name like ?',[search_value]); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + case 'owner': + try {//가게주 + console.log(search_value); + let [rows, fields] = await db.execute('select * from store where store_owner like ?',[search_value]); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + } + } + else if (partner=='farm')//농가 + { + switch(search){ + + case 'name': + try {//농가이름 + let [rows, fields] = await db.execute('select * from farm where farm_name like ?',[search_value]); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + case 'owner': + try {//농장주 + console.log(search_value); + let [rows, fields] = await db.execute('select * from farm where farm_farmer like ?',[search_value]); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + case 'item': + try {//주거래품목 + console.log(search_value); + let [rows, fields] = await db.execute('select * from farm where farm_saleItem like ?',[search_value]); + res.send(rows); + } + catch (e) { + console.log(e); + } + break; + + } + } + + + + }); + +module.exports = app; \ No newline at end of file diff --git a/read.js b/read.js new file mode 100644 index 0000000..0e58958 --- /dev/null +++ b/read.js @@ -0,0 +1,181 @@ +const express = require('express'); +const app = express(); +const db = require('./db'); +const cors = require('cors'); + +app.use(cors()); +app.use(express.json()); + + + +//read +app.get('/', async(req, res) => { //굳이 필요는 없지만,, + + try {//최근등록순 + let [rows, fields] = await db.execute("select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id ORDER BY md.md_id desc"); + res.send(rows); + } + catch (e) { + console.log(e); + } + + }); +app.get('/farm', async(req, res) => { + + try {//모든 상점 + let [rows, fields] = await db.execute(`select * from farm join Hours on farm.farm_id=Hours.hours_PartnerId where Hours.hours_partner=0`); + res.send(rows); + } + catch (e) { + console.log(e); + } + + }); +app.get('/store', async(req, res) => { + + try {//모든 상점 + let [rows, fields] = await db.execute(`select * from store join Hours on store.store_id=Hours.hours_PartnerId where Hours.hours_partner=1`); + res.send(rows); + } + catch (e) { + console.log(e); + } + + }); +app.get('/review', async(req, res) => { + + try {//모든 상점 + let [rows, fields] = await db.execute("select * from review where rvw_isDelete =0 ORDER BY rvw_id desc"); + res.send(rows); + } + catch (e) { + console.log(e); + } + + }); +app.get('/reviewDelete', async(req, res) => { + + try {//모든 상점 + let [rows, fields] = await db.execute("select * from review where rvw_isDelete =1 ORDER BY rvw_id desc"); + res.send(rows); + } + catch (e) { + console.log(e); + } + +}); +app.get('/MD/MDResult', async(req, res) => { + + try {//최근등록순 + let [rows, fields] = await db.execute("select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id where md.md_result is not null ORDER BY md.md_id desc"); + res.send(rows); + } + catch (e) { + console.log(e); + } + + }); +app.get('/:md_id', async (req, res) => {//특정 md만 get + const md_id = req.params.md_id; + + try{ + + let [row2, field] = await db.execute(`select * from md join pickup on md.md_id=pickup.md_id join stock on md.md_id=stock.md_id join payment on md.md_id=payment.md_id where md.md_id=?`, [md_id]); + res.send(row2); + console.log(row2); + } + catch (e) { + console.log(e); +} +}); + +app.get('/imgs/:md_id', async (req, res) => {//특정 md만 get + const md_id = req.params.md_id;//`select * from md where md_id=?`, [md_id] + try{ + const [row23, field] = await db.execute(`select * from md_Img where md_id = ?`,[md_id]); + res.send(row23); + //console.log(row23); + } + catch (e) { + console.log(e); + } +}); +app.get('/farm/:farm_id', async (req, res) => {//특정 md만 get + const farm_id = req.params.farm_id; + + try{ + + let [row2, field] = await db.execute(`select * from farm join Hours on farm.farm_id=Hours.hours_PartnerId where farm.farm_id=? and Hours.hours_partner=0`, [farm_id]); + res.send(row2); + console.log(row2); + } + catch (e) { + console.log(e); +} +}); +app.get('/farm/imgs/:farm_id', async (req, res) => {//특정 md만 get + const farm_id = req.params.farm_id;//`select * from md where md_id=?`, [md_id] + try{ + const [row23, field] = await db.execute(`select farm_thumbnail, farm_mainImg, farm_detailImg from farm where farm_id = ?`,[farm_id]); + res.send(row23); + //console.log(row23); + } + catch (e) { + console.log(e); + } +}); + +app.get('/store/:store_id', async (req, res) => {//특정 store만 get + const store_id = req.params.store_id; + + try{ + + let [row2, field] = await db.execute(`select * from store join Hours on store.store_id=Hours.hours_PartnerId where store.store_id=? and Hours.hours_partner=1`, [store_id]); + res.send(row2); + console.log(row2); + } + catch (e) { + console.log(e); +} +}); +app.get('/store/imgs/:store_id', async (req, res) => {//특정 md만 get + const store_id = req.params.store_id;//`select * from md where md_id=?`, [md_id] + try{ + const [row23, field] = await db.execute(`select store_thumbnail, store_mainImg, store_detailImg from store where store_id = ?`,[store_id]); + res.send(row23); + console.log(store_id); + } + catch (e) { + console.log(e); + } +}); + +app.get('/name/:md_id', async (req, res) => {//md_id에 따라 상점,농장 이름 출력 + const md_id = req.params.md_id; + const [row3, field] = await db.execute(`select md.farm_id ,pickup.store_id from md join pickup using (md_id) where md_id=?`, [md_id]); + let farmId = row3[0].farm_id; + let storeId = row3[0].store_id; + + const [row4, field2] = await db.execute(`select farm_name from farm where farm_id=?`, [farmId]); + const [row5, field3] = await db.execute(`select store_name from store where store_id=?`, [storeId]); + let farmName = row4[0].farm_name; + let storeName = row5[0].store_name; + res.json( { farm_name: farmName ,store_name:storeName }); + +}); + +app.get('/pickup/:md_id', async (req, res) => {//특정 md의 픽업리스트 출력 + const md_id = req.params.md_id; + + try{ + + let [row2, field] = await db.execute("select * from "+"`"+"order"+"`"+` where md_id=?`, [md_id]); + res.send(row2); + + } + catch (e) { + consoe.log(e); +} +}); + +module.exports = app; \ No newline at end of file diff --git a/review.js b/review.js new file mode 100644 index 0000000..a055953 --- /dev/null +++ b/review.js @@ -0,0 +1,95 @@ +const express = require('express'); +const app = express(); +const db = require('./db'); +const cors = require('cors'); + +app.use(cors()); +app.use(express.json()); + +app.get('/', async(req, res) => { //삭제되지않은 리뷰 가져오기 + + try {//모든 상점 + let [rows, fields] = await db.execute("select * from review where rvw_isDelete =0 ORDER BY rvw_id desc"); + res.send(rows); + } + catch (e) { + console.log(e); + } + +}); +app.get('/reviewDelete', async(req, res) => { //삭제된 리뷰 가져오기 + + try {//모든 상점 + let [rows, fields] = await db.execute("select * from review where rvw_isDelete =1 ORDER BY rvw_id desc"); + res.send(rows); + } + catch (e) { + console.log(e); + } + +}); + +app.get('/:rvw_id', async(req, res) => { //리뷰의 상품 명,사용자 아이디 + const rvw_id = req.params.rvw_id; + try {//모든 상점 + let [rows, fields] = await db.execute(`select md_name,user_id from review join md on md.md_id=review.md_id join`+"`"+"user"+"`"+ `on`+"`"+"user"+"`"+`.user_no =review.user_no where rvw_id=?;`, [rvw_id]); + res.send(rows); + } + catch (e) { + console.log(e); + } + +}); +app.get('/img/:rvw_id', async (req, res) => {//특정 상가의 이미지만 + const rvw_id = req.params.rvw_id;//`select * from md where md_id=?`, [md_id] + try{ + const [row23, field] = await db.execute(`select rvw_img1,rvw_img2,rvw_img3 from review where rvw_id = ?`,[rvw_id]); + res.send(row23); + console.log(rvw_id); + } + catch (e) { + console.log(e); + } +}); + +app.post('/delete/:rvw_id', async (req, res) => { + const rvw_id = req.params.rvw_id; + + try { + await db.execute(`update review set rvw_who=1,rvw_isDelete=1 WHERE rvw_id=?`, [rvw_id]); + + console.log(rvw_id, '삭제 성공'); + } catch (e) { + console.log(e); + res.status(400).send({msg: '잘못된 리뷰 삭제 시도'}); + } +}) +app.post('/recover/:rvw_id', async (req, res) => { + const rvw_id = req.params.rvw_id; + + try { + await db.execute(`update review set rvw_who=null,rvw_isDelete=0 WHERE rvw_id=?`, [rvw_id]); + + console.log(rvw_id, '복구 성공'); + } catch (e) { + console.log(e); + res.status(400).send({msg: '잘못된 리뷰 복구 시도'}); + } +}) +app.post('/delete', async (req, res) => { + const rvw_ids = req.body.rvw_ids; + console.log(rvw_ids); + + try { + for (let rvw_id of rvw_ids) { + rvw_id = rvw_id.id; + + const [result] = await db.execute(`update review set rvw_who=1,rvw_isDelete=1 WHERE rvw_id=?`, [rvw_id]); + } + console.log(rvw_id, rvw_ids, '삭제 성공'); + } catch (e) { + console.log(e); + res.status(400).send({msg: '잘못된 리뷰 삭제 시도'}); + } +}) +module.exports = app; \ No newline at end of file diff --git a/signup.js b/signup.js new file mode 100644 index 0000000..a930465 --- /dev/null +++ b/signup.js @@ -0,0 +1,168 @@ +const express = require('express'); +const app = express(); +const bcrypt = require('bcrypt'); +const db = require('./db'); +const axios = require('axios'); +const CryptoJS = require('crypto-js'); +const naver = require('./config').naver; +const fromNumber = require('./config').phoneNumber; + +app.use(express.json()); + +// 사장님용 회원가입 +app.post('/', async (req, res) => { + const body = req.body; + const id = body.id; + const password = body.password; + const nickname = body.nickname; + const phone_number = body.phone_number; + + const encode_pwd = await bcrypt.hash(password, 10); + try { + const [result] = await db.execute(`INSERT INTO admin_user (admin_id, password, admin_name, mobile_number) VALUES (?, ?, ?, ?)`, + [id, encode_pwd, nickname, phone_number]); + res.send({ id: result.insertId }); + console.log(`SIGNUP_SUCCESS :: userID = {${result.insertId}}` ); + } catch (e) { + console.log(`SIGNUP_FAILED :: msg = ${e}`); + res.status(500).send({ msg: 'signup error'}); + } +}) + +// id 중복 확인 +app.post('/id-check', async (req, res) => { + const body = req.body; + const id = body.id; + let is_valid = true; + + try { + const [result, field] = await db.execute(`SELECT * FROM admin_user WHERE admin_id = ?`, [id]); + // id가 이미 존재하면 is_valid 는 false + if (result.length !== 0) is_valid = false; + res.send({ is_valid: is_valid }); + console.log(`ID_CHECK_SUCCESS`); + } catch (e) { + res.status(500).send({ msg: 'server error' }); + console.log(`ID_CHECK_FAILED :: msg = ${e}`); + } +}) + +// sms 인증 +function makeSignature(time) { + var space = " "; // one space + var newLine = "\n"; // new line + var method = "POST"; // method + var url = `/sms/v2/services/${naver.id}/messages`; // url (include query string) + var timestamp = time; // current timestamp (epoch) + var accessKey = naver.access; // access key id (from portal or Sub Account) + var secretKey = naver.console_secret; // secret key (from portal or Sub Account) + + var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, secretKey); + hmac.update(method); + hmac.update(space); + hmac.update(url); + hmac.update(newLine); + hmac.update(timestamp); + hmac.update(newLine); + hmac.update(accessKey); + + var hash = hmac.finalize(); + + return hash.toString(CryptoJS.enc.Base64); +} + +app.post('/phone-check', async (req, res) => { + const body = req.body; + const phone_number = body.phone_number; + + const sms_url = `https://sens.apigw.ntruss.com/sms/v2/services/${naver.id}/messages`; + const time_stamp = Date.now().toString(); + const signature = makeSignature(time_stamp); + let code = ''; + for (let i = 0; i < 6; i++) code += Math.floor(Math.random() * 10); + try { + const sms_res = await axios.post(sms_url, { + "type":"SMS", + "from": fromNumber, + "countryCode": "82", + "content":`공동장 인증번호는 [${code}]입니다.`, + "messages":[ + { + "to": phone_number, + "content":`공동장 인증번호는 [${code}]입니다.` + } + ] + }, { + headers: { + 'Content-Type': 'application/json; charset=utf-8', + 'x-ncp-apigw-timestamp': time_stamp, + 'x-ncp-iam-access-key': naver.access, + 'x-ncp-apigw-signature-v2': signature + } + } + ) + const [result] = await db.execute(`INSERT INTO sms_validation(phone_number, code, expire) + VALUES (?, ?, NOW() + INTERVAL 3 MINUTE) ON DUPLICATE KEY + UPDATE code = ?, expire = NOW() + INTERVAL 3 MINUTE`, + [phone_number, code, code]); + res.send({ msg: 'success' }); + console.log(`SMS_SEND_SUCCESS :: phoneNumber = ${phone_number}`); + } catch (e) { + console.log(`SMS_SEND_FAILED :: msg = ${e}`); + res.status(500).send({ msg: 'server error' }); + } +}) + +app.post('/phone-check/verify', async (req, res) => { + const body = req.body; + const code = body.code; + const phone_number = body.phone_number; + + let phone_valid = false; + + try { + const [result, field] = await db.execute(`SELECT * + FROM sms_validation + WHERE phone_number = ?`, [phone_number]); + const expire_time = new Date(result[0].expire).setHours(result[0].expire.getHours() + 9); + const now = Date.now(); + console.log(expire_time, now) + if (code === result[0].code && expire_time > now) { + phone_valid = true; + } + + res.send({phone_valid: phone_valid}); + console.log(`SMS_VERIFY_SUCCESS :: phoneNumber = ${phone_number}`); + } catch (e) { + console.log(`SMS_VERIFY_FAILED :: msg = ${e}`); + res.status(500).send({ msg: 'server error' }); + } +}) + +app.post('/unique-number', async (req, res) => { + const body = req.body; + const storeName = body.storeName; + const uniqueNumber = body.uniqueNumber; + + try { + const [result, field] = await db.execute(`SELECT store_number FROM store WHERE store_name= ?`, [storeName]); + + if (result.length === 0) { + res.status(400).send({msg: 'STORE_NOT_FOUND'}); + console.log(`STORE_NOT_FOUND :: storeName = ${storeName}`); + } else if (uniqueNumber === result[0].store_number) { + console.log(`UNIQUE_VERIFY_SUCCESS :: storeName = ${storeName}`); + res.send({ + msg: 'UNIQUE_NUMBER_VERIFY_SUCCESS', + }); + } else { + console.log(`UNIQUE_VERIFY_FAILED :: storeName = ${storeName}`); + res.status(400).send({msg: 'UNIQUE_NUMBER_VERIFY_FAIL'}); + } + } catch (e) { + console.log(`UNIQUE_VERIFY_FAILED :: msg = ${e}`); + res.status(500).send({msg: 'SERVER_ERROR'}); + } +}) + +module.exports = app; \ No newline at end of file diff --git a/uploads.js b/uploads.js new file mode 100644 index 0000000..1d2a3f0 --- /dev/null +++ b/uploads.js @@ -0,0 +1,28 @@ +const multer = require('multer'); +const multerS3 = require('multer-s3') +const AWS = require("aws-sdk"); +const aws_key = require('./config').aws_access; + +const s3 = new AWS.S3({ + accessKeyId: aws_key.access, + secretAccessKey: aws_key.secret, + region: aws_key.region +}); +const storage = multerS3({ + s3: s3, + bucket: 'ggdjang', + contentType: multerS3.AUTO_CONTENT_TYPE, + acl: 'public-read', + metadata: function(req, file, cb) { + cb(null, {fieldName: file.fieldname}); + }, + key: function (req, file, cb) { + cb(null, `md/${Date.now()}_${file.originalname}`); + } +}) +const upload = multer({ + storage: storage +}) + +module.exports = upload; +//export default upload \ No newline at end of file