diff --git a/backend/app.js b/backend/app.js index c325d6b6b5a901fd201044e0ef88b836d7b7bb28..a7bafa94cb3310409b0ebb19e71a3ecdb707e2ec 100644 --- a/backend/app.js +++ b/backend/app.js @@ -11,6 +11,7 @@ var FileStore = require("session-file-store")(session); var bookRouter = require("./routes/books"); var loginRouter = require("./routes/login"); var emailRouter = require("./routes/emails"); +var transactionRouter = require("./routes/transaction"); var app = express(); @@ -49,6 +50,7 @@ app.use(express.static(path.join(__dirname, "public"))); app.use("/api/books", bookRouter); app.use("/api/login", loginRouter); app.use("/api/emails", emailRouter); +app.use("/api/transaction", transactionRouter); // catch 404 and forward to error handler app.use(function(req, res, next) { diff --git a/backend/models/transaction.js b/backend/models/transaction.js index 82e1cc3c4aebff7db13f6727b41c4fc3641d18be..5e59e33d93f91449ca1250f0a87e1084f5f22624 100644 --- a/backend/models/transaction.js +++ b/backend/models/transaction.js @@ -4,9 +4,10 @@ var autoInc = require("mongoose-auto-increment"); const TransactionSchema = new Schema({ _id: Number, - buyerid: { type: String }, - sellerid: { type: String }, - ontransaction: { type: Boolean } + bookTitle: { type: String }, + buyerId: { type: String }, + sellerId: { type: String }, + on_transaction: { type: Boolean } }); autoInc.initialize(mongoose.connection); diff --git a/backend/models/user.js b/backend/models/user.js index 83512248fb1fc075b1554abd35a0c0ed6477b632..c5241913f43320a3c8c0c7316a0465287905306f 100644 --- a/backend/models/user.js +++ b/backend/models/user.js @@ -9,7 +9,7 @@ var userSchema = new Schema({ id: String, password: String, email: String, - isLoggedIn: Boolean, + phonenumber: String, create_date: { type: Date, default: Date.now } }); diff --git a/backend/routes/books.js b/backend/routes/books.js index c72f7c95b2047037f4c5e6d4373d33de49890ff8..93d3421c6fa1696bd0c74d5b6ccfc7ca5d658fff 100644 --- a/backend/routes/books.js +++ b/backend/routes/books.js @@ -43,7 +43,7 @@ router.post("/", function(req, res) { }); }); -// 梨� �먮ℓ +// 梨� 援щℓ 諛� �먮ℓ router.post("/:id", function(req, res) { Book.findById(req.params.id, function(err, book) { if (err) { @@ -51,6 +51,19 @@ router.post("/:id", function(req, res) { return; } console.log(req.body.userId); + if (req.body.isBuyer === true) { + // var soldbook = book.seller.shift(); + // book.stock--; + // book.save(); + console.log(book.seller); + var temp = book.seller.find(element => element.on_transaction === false); + // book.seller.find( + // element => element.on_transaction === false + // ).on_transaction = true; + // book.save(); + res.json({ result: temp }); + return; + } book.seller.push({ seller_id: req.body.userId, on_transaction: false }); book.stock++; book.save(); diff --git a/backend/routes/emails.js b/backend/routes/emails.js index 40d50c1caf1d672d8ccdc67acd2042fa24d78d46..da0be3ca25f42a5ae1a678db1be5d8c22e9a441f 100644 --- a/backend/routes/emails.js +++ b/backend/routes/emails.js @@ -1,33 +1,40 @@ -const express = require('express'); -const nodemailer = require('nodemailer'); +const express = require("express"); +const nodemailer = require("nodemailer"); const router = express.Router(); -router.get("", function(req, res, next){ - let email = "hj950000@ajou.ac.kr" +router.post("/", function(req, res, next) { + console.log("email backend start"); + let sellerEmail = req.body.sellerEmail; + let bookTitle = req.body.bookTitle; + let buyerPhoneNumber = req.body.buyerPhoneNumber; let transporter = nodemailer.createTransport({ - service: 'gmail', + service: "gmail", auth: { - user: 'majorbook202@gmail.com', // gmail 怨꾩젙 �꾩씠�붾� �낅젰 - pass: 'dnjfdydlf' // gmail 怨꾩젙�� 鍮꾨�踰덊샇瑜� �낅젰 + user: "majorbook202@gmail.com", // gmail 怨꾩젙 �꾩씠�붾� �낅젰 + pass: "dnjfdydlf" // gmail 怨꾩젙�� 鍮꾨�踰덊샇瑜� �낅젰 } }); let mailOptions = { - from: 'majorbook202@gmail.com', // 諛쒖넚 硫붿씪 二쇱냼 (�꾩뿉�� �묒꽦�� gmail 怨꾩젙 �꾩씠��) - to: "hj950000@ajou.ac.kr", // �섏떊 硫붿씪 二쇱냼 - subject: 'MajorBook援щℓ�붿껌�� �ㅼ뼱�붿뒿�덈떎.', // �쒕ぉ - text: '�щ━�� 梨� ~~�� ���� 援щℓ�붿껌�� �꾩갑�덉뒿�덈떎. �대떦 援щℓ�먯쓽 �꾪솕踰덊샇�� ~~�낅땲��.' // �댁슜 + from: "majorbook202@gmail.com", // (�꾩뿉�� �묒꽦�� gmail 怨꾩젙 �꾩씠��) + to: sellerEmail, // selleremail + subject: "MajorBook援щℓ�붿껌�� �ㅼ뼱�붿뒿�덈떎.", // �쒕ぉ + text: + "�щ━�� 梨�" + + bookTitle + + "�� ���� 援щℓ�붿껌�� �꾩갑�덉뒿�덈떎. �대떦 援щℓ�먯쓽 �꾪솕踰덊샇��" + + buyerPhoneNumber + + "�낅땲��." // �댁슜 }; - transporter.sendMail(mailOptions, function(error, info){ + transporter.sendMail(mailOptions, function(error, info) { if (error) { console.log(error); - } - else { - console.log('Email sent: ' + info.response); + } else { + console.log("Email sent: " + info.response); } }); -}) +}); -module.exports = router; \ No newline at end of file +module.exports = router; diff --git a/backend/routes/login.js b/backend/routes/login.js index 42b589b201bb27a26fab304ec79a81f6b9dc7252..1b4447fd535ba1e447dd77caf0a47fe16038c6ad 100644 --- a/backend/routes/login.js +++ b/backend/routes/login.js @@ -8,7 +8,7 @@ router.post("/signUp", function(req, res, next) { user.password = req.body.user.password; user.name = req.body.user.name; user.email = req.body.user.email; - user.isLoggedIn = req.body.user.isLoggedIn; + user.phonenumber = req.body.user.phonenumber; user.save(function(err) { if (err) { @@ -68,4 +68,19 @@ router.get("/getUserId", function(req, res) { } }); +router.post("/getUserInfo", function(req, res) { + console.log("getUserInfo start"); + var getInfoId = req.body.userId; + console.log(getInfoId); + User.findOne({ id: getInfoId }, function(err, user) { + if (err) { + res.send(err); + } + if (!user) { + return res.status(404).json({ error: "user not found" }); + } + res.json(user); + }); +}); + module.exports = router; diff --git a/backend/routes/transaction.js b/backend/routes/transaction.js new file mode 100644 index 0000000000000000000000000000000000000000..ad402d3cdf3e603d535f11831e7a24a8bfa55138 --- /dev/null +++ b/backend/routes/transaction.js @@ -0,0 +1,36 @@ +const express = require("express"); +const router = express.Router(); +const Transaction = require("../models/transaction"); + +router.get("/", function(req, res) { + console.log("Get transaction start"); + Transaction.find({}, function(err, transactions) { + if (err) { + res.json({ result: false, message: "Not found transactions" }); + return; + } + res.json(transactions); + }); +}); + +router.post("/", function(req, res) { + console.log("Post transaction start"); + var transaction = new Transaction(); + transaction.buyerId = req.body.buyerId; + console.log(req.body.buyerId); + transaction.sellerId = req.body.sellerId; + console.log(req.body.sellerId); + transaction.bookTitle = req.body.bookTitle; + transaction.on_transaction = true; + + transaction.save(function(err) { + if (err) { + console.error(err); + res.json({ result: 0 }); + return; + } + res.json({ result: 1 }); + }); +}); + +module.exports = router; diff --git a/frontend/src/components/BookSearchPage.vue b/frontend/src/components/BookSearchPage.vue index 6bcce5c8383ba66721f5fa8d5d0c3adb33425d7a..17f2008d819fe266dcd1a74d03741c983df7a517 100644 --- a/frontend/src/components/BookSearchPage.vue +++ b/frontend/src/components/BookSearchPage.vue @@ -22,8 +22,7 @@ color="#999" style="float: left; marginLeft: 1%; width: 2%; marginTop:0.1%" v-on:click="Search" - >寃���</md-button - > + >寃���</md-button> <!-- ==================================================================== --> <div v-if="SearchResult === true "> @@ -38,10 +37,7 @@ <br /> <br /> </div> - <div - class="md-subhead" - style="text-align:left;font-weight: bold;" - > + <div class="md-subhead" style="text-align:left;font-weight: bold;"> # �숇뀈: {{ Book.grade }} <br /> # �꾧났: {{ Book.major }} @@ -57,22 +53,15 @@ </md-card-media> </md-card-header> <md-card-actions> - <md-button - class="md-raised md-accent" - v-on:click="goSellPage(Book._id)" - >Sell</md-button - > - <md-button class="md-raised md-primary">Buy Now</md-button> + <md-button class="md-raised md-accent" v-on:click="goSellPage(Book._id)">Sell</md-button> + <md-button class="md-raised md-primary" v-on:click="goBuyPage(Book._id)">Buy Now</md-button> </md-card-actions> </md-card> </div> </div> <!-- ============================================= --> <div> - <md-speed-dial - :class="bottomPosition" - style="marginRight:20%; marginBottom:8%" - > + <md-speed-dial :class="bottomPosition" style="marginRight:20%; marginBottom:8%"> <md-button class="md-fab md-primary" v-on:click="active = true"> <img src="../assets/icon-add.svg" /> </md-button> @@ -80,10 +69,7 @@ </div> <!-- ============= �먮ℓ�꾩꽌 submit �묒떇 ================== --> <div> - <md-dialog - :md-active.sync="active" - style="width : 500px; height: 1000px " - > + <md-dialog :md-active.sync="active" style="width : 500px; height: 1000px "> <md-dialog-title>�먮ℓ�꾩꽌 �깅줉</md-dialog-title> <md-field class="select"> <label>梨낆젣紐�</label> @@ -102,9 +88,7 @@ <md-input v-model="submit.src"></md-input> </md-field> <md-dialog-actions> - <md-button class="md-primary" v-on:click="active = false" - >Close</md-button - > + <md-button class="md-primary" v-on:click="active = false">Close</md-button> <md-button class="md-primary" v-on:click="Register">Submit</md-button> </md-dialog-actions> </md-dialog> @@ -168,6 +152,9 @@ export default { }); this.active = false; }, + goBuyPage(bookId) { + this.$router.push({ name: "BookSearchPageBuy", params: { id: bookId } }); + }, goSellPage(bookId) { this.$router.push({ name: "BookSearchPageSell", params: { id: bookId } }); } diff --git a/frontend/src/components/Buy.vue b/frontend/src/components/Buy.vue index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9515470c42e14573f802f84806f9eea593f2af1b 100644 --- a/frontend/src/components/Buy.vue +++ b/frontend/src/components/Buy.vue @@ -0,0 +1,137 @@ +<template> + <div> + <md-card + style="width: 50%; margin: 4px; marginTop:100px; display: inline-block; vertical-align: top;" + > + <md-card-header> + <md-card-header-text> + <div class="md-title"> + {{ book.title }} + <br /> + <br /> + </div> + <div class="md-subhead" style="text-align:left; font-weight:bold;"> + # �숇뀈: {{ book.grade }} + <br /> + # �꾧났: {{ book.major }} + <br /> + # �몃��ы빆: {{ book.type }} + <br /> + # 留ㅻЪ: {{ book.stock }} + <br /> + </div> + </md-card-header-text> + <md-card-media md-medium> + <img v-bind:src="book.src" /> + </md-card-media> + </md-card-header> + </md-card> + + <md-card + style="width: 50%; margin: 4px; marginTop:100px; display: inline-block; vertical-align: top;" + > + <md-card-header> + <div class="md-title">�� 梨낆쓣 援щℓ�섏떆寃좎뒿�덇퉴?</div> + </md-card-header> + <md-card-actions> + <md-button class="md-raised md-primary" v-on:click="buyBook">援щℓ</md-button> + </md-card-actions> + </md-card> + </div> +</template> + +<script> +import Vue from "vue"; +import VueMaterial from "vue-material"; +import Multiselect from "vue-multiselect"; +import "vue-material/dist/vue-material.min.css"; +import "vue-material/dist/theme/default.css"; +Vue.use(VueMaterial); + +export default { + data() { + return { + buyer: {}, + seller: {}, + book: {}, + userId: "", + sellerId: "" + }; + }, + created() { + var id = this.$route.params.id; + this.$http.get(`/api/books/${id}`).then(response => { + this.book = response.data; + }); + }, + methods: { + buyBook() { + this.$http.get("/api/login/getUserId").then(response => { + console.log("rd" + response.data); + this.userId = response.data; + var id = this.$route.params.id; + console.log("user:" + this.userId); + this.$http + .post(`/api/books/${id}`, { + userId: this.userId, + isBuyer: true + }) + .then( + res => { + console.log(res.data); + this.sellerId = res.data.result.seller_id; + this.$http + .post("/api/transaction", { + buyerId: this.userId, + sellerId: this.sellerId, + bookTitle: this.book.title + }) + .then(response => { + console.log("buy.vue-transaction post"); + alert("援щℓ�� �깃났�섏��듬땲��. �먮ℓ�먯뿉寃� 硫붿씪�� 蹂대깄�덈떎."); + this.sendEmail(); + }); + }, + error => { + alert(error.response.data.error); + } + ) + .catch(error => { + alert(error); + }); + }); + }, + sendEmail() { + console.log("sendEmail start"); + this.$http + .post("/api/login/getUserInfo", { + userId: this.userId // buyer + }) + .then(response => { + this.buyer = response.data; + }); + + this.$http + .post("/api/login/getUserInfo", { + userId: this.sellerId + }) + .then(response => { + this.seller = response.data; + }); + + this.$http + .post("/api/emails", { + sellerEmail: this.seller.email, + bookTitle: this.book.title, + buyerPhoneNumber: this.buyer.phonenumber + }) + .then(response => { + alert("�대찓�� �꾩넚 �꾨즺"); + }), + error => { + alert(error.response.data.error); + }; + } + } +}; +</script> \ No newline at end of file diff --git a/frontend/src/components/Sell.vue b/frontend/src/components/Sell.vue index 21d7b157a341b9652bb4e0dad3fd11672f39c6a1..7c1bcc8d565c22d1ad1cbffa4c68dc0089c3b903 100644 --- a/frontend/src/components/Sell.vue +++ b/frontend/src/components/Sell.vue @@ -31,14 +31,10 @@ style="width: 50%; margin: 4px; marginTop:100px; display: inline-block; vertical-align: top;" > <md-card-header> - <div class="md-title"> - �� 梨낆쓣 �먮ℓ�섏떆寃좎뒿�덇퉴? - </div> + <div class="md-title">�� 梨낆쓣 �먮ℓ�섏떆寃좎뒿�덇퉴?</div> </md-card-header> <md-card-actions> - <md-button class="md-raised md-primary" v-on:click="sellBook" - >�먮ℓ</md-button - > + <md-button class="md-raised md-primary" v-on:click="sellBook">�먮ℓ</md-button> </md-card-actions> </md-card> </div> @@ -64,38 +60,31 @@ export default { this.$http.get(`/api/books/${id}`).then(response => { this.book = response.data; }); - // this.$http.get("/api/login/getUserId").then(response => { - // console.log("getUserIDstart"); - // this.userId = response.data; - // }); }, methods: { - getId() { + sellBook() { this.$http.get("/api/login/getUserId").then(response => { console.log("rd" + response.data); this.userId = response.data; + var id = this.$route.params.id; + console.log("user:" + this.userId); + this.$http + .post(`/api/books/${id}`, { + userId: this.userId + }) + .then( + response => { + alert("�먮ℓ ��湲곗뿴�� �깅줉�섏��듬땲��."); + //this.$router.push("home"); + }, + error => { + alert(error.response.data.error); + } + ) + .catch(error => { + alert(error); + }); }); - }, - sellBook() { - var id = this.$route.params.id; - this.getId(); - console.log("user:" + this.userId); - this.$http - .post(`/api/books/${id}`, { - userId: this.userId - }) - .then( - response => { - alert("�먮ℓ ��湲곗뿴�� �깅줉�섏��듬땲��."); - //this.$router.push("home"); - }, - error => { - alert(error.response.data.error); - } - ) - .catch(error => { - alert(error); - }); } } }; diff --git a/frontend/src/components/login/SignUp.vue b/frontend/src/components/login/SignUp.vue index 01ac07dfe52d6c9f13c939d24bf029faf3fe77ad..958e483c7e2f4d7349b3de013ce724cf85b23d9f 100644 --- a/frontend/src/components/login/SignUp.vue +++ b/frontend/src/components/login/SignUp.vue @@ -23,12 +23,13 @@ <md-input name="email" v-model="user.email" /> </md-field> - <md-button class="md-raised md-primary" v-on:click="signUp" - >Sign Up</md-button - > - <md-button class="md-primary" v-on:click="active = false" - >Close</md-button - > + <md-field class="select"> + <label for="phonenumber">Phone Number</label> + <md-input name="phonenumber" v-model="user.phonenumber" /> + </md-field> + + <md-button class="md-raised md-primary" v-on:click="signUp">Sign Up</md-button> + <md-button class="md-primary" v-on:click="active = false">Close</md-button> </md-dialog> </div> </template> @@ -60,7 +61,7 @@ export default { password: "", name: "", email: "", - isLoggedIn: false + phonenumber: "" }, sending: false, active: false @@ -79,7 +80,7 @@ export default { this.active = false; } if (response.data.result === 1) { - alert("Success"); + alert("Success Sign Up !"); this.active = false; } })