Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: stellacheng-chm/COMP4117Project
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: UG-CS-HKBU/COMP4117Project
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
Loading
Showing with 13,456 additions and 1,383 deletions.
  1. +307 −35 api/controllers/BookController.js
  2. +285 −29 api/controllers/GameController.js
  3. +206 −8 api/controllers/GiftController.js
  4. +447 −9 api/controllers/ItemController.js
  5. +289 −0 api/controllers/MaterialController.js
  6. +720 −6 api/controllers/UserController.js
  7. +20 −0 api/helpers/send-single-email.js
  8. +102 −1 api/models/Book.js
  9. +64 −0 api/models/Game.js
  10. +28 −1 api/models/Gift.js
  11. +6 −0 api/models/Item.js
  12. +95 −0 api/models/Material.js
  13. +67 −1 api/models/User.js
  14. +13 −0 api/policies/isAdmin.js
  15. +3 −17 api/policies/isUser.js
  16. BIN book.xlsx
  17. +74 −41 config/bootstrap.js
  18. +8 −0 config/custom.js
  19. +139 −7 config/policies.js
  20. +194 −24 config/routes.js
  21. BIN game.xlsx
  22. BIN gift.xlsx
  23. BIN material.xlsx
  24. +579 −15 package-lock.json
  25. +7 −1 package.json
  26. +153 −0 views/book/adminbookdetail.ejs
  27. +121 −0 views/book/adminbookedit.ejs
  28. +68 −0 views/book/adminbookresult.ejs
  29. +118 −0 views/book/adminbooksearch.ejs
  30. +81 −0 views/book/adminbookupdate.ejs
  31. +0 −64 views/book/bookresult.ejs
  32. +0 −95 views/book/booksearch.ejs
  33. +83 −0 views/book/borrow.ejs
  34. +45 −0 views/book/import_xlsx.ejs
  35. +27 −0 views/book/print.ejs
  36. +83 −0 views/book/return.ejs
  37. +4 −0 views/book/upload1.ejs
  38. +34 −0 views/book/uploadphoto.ejs
  39. +148 −0 views/book/useraddremark.ejs
  40. +156 −0 views/book/userbookdetail.ejs
  41. +131 −0 views/book/userbookdetail2.ejs
  42. +157 −0 views/book/userbookreserve.ejs
  43. +70 −0 views/book/userbookresult.ejs
  44. +173 −0 views/book/userbookreturn.ejs
  45. +100 −0 views/book/userbooksearch.ejs
  46. +0 −63 views/book/vbookresult.ejs
  47. +0 −96 views/book/vbooksearch.ejs
  48. +102 −0 views/book/vistorbookdetail.ejs
  49. +69 −0 views/book/vistorbookresult.ejs
  50. +93 −0 views/book/vistorbooksearch.ejs
  51. +144 −0 views/game/admingamedetail.ejs
  52. +117 −0 views/game/admingameedit.ejs
  53. +70 −0 views/game/admingameresult.ejs
  54. +105 −0 views/game/admingamesearch.ejs
  55. +83 −0 views/game/admingameupdate.ejs
  56. +83 −0 views/game/borrow.ejs
  57. +0 −66 views/game/gameresult.ejs
  58. +0 −94 views/game/gamesearch.ejs
  59. +45 −0 views/game/import_xlsx.ejs
  60. +27 −0 views/game/print.ejs
  61. +83 −0 views/game/return.ejs
  62. +34 −0 views/game/uploadphoto.ejs
  63. +142 −0 views/game/useraddremark.ejs
  64. +115 −0 views/game/usergamedetail.ejs
  65. +96 −0 views/game/usergamedetail2.ejs
  66. +150 −0 views/game/usergamereserve.ejs
  67. +71 −0 views/game/usergameresult.ejs
  68. +157 −0 views/game/usergamereturn.ejs
  69. +105 −0 views/game/usergamesearch.ejs
  70. +0 −68 views/game/vgameresult.ejs
  71. +0 −97 views/game/vgamesearch.ejs
  72. +94 −0 views/game/vistorgamedetail.ejs
  73. +71 −0 views/game/vistorgameresult.ejs
  74. +104 −0 views/game/vistorgamesearch.ejs
  75. +134 −0 views/gift/admingiftdetail.ejs
  76. +116 −0 views/gift/admingiftedit.ejs
  77. +69 −0 views/gift/admingiftresult.ejs
  78. +105 −0 views/gift/admingiftsearch.ejs
  79. +85 −0 views/gift/admingiftupdate.ejs
  80. +92 −0 views/gift/borrow.ejs
  81. +0 −64 views/gift/giftresult.ejs
  82. +0 −94 views/gift/giftsearch.ejs
  83. +45 −0 views/gift/import_xlsx.ejs
  84. +27 −0 views/gift/print.ejs
  85. +34 −0 views/gift/uploadphoto.ejs
  86. +121 −0 views/gift/useraddremark.ejs
  87. +101 −0 views/gift/usergiftdetail.ejs
  88. +81 −0 views/gift/usergiftdetail2.ejs
  89. +68 −0 views/gift/usergiftresult.ejs
  90. +99 −0 views/gift/usergiftsearch.ejs
  91. +0 −66 views/gift/vgiftresult.ejs
  92. +0 −97 views/gift/vgiftsearch.ejs
  93. +107 −0 views/item/adminaccount.ejs
  94. +88 −0 views/item/adminaccountupdate.ejs
  95. +109 −0 views/item/adminaddaccount.ejs
  96. +99 −0 views/item/adminaddbook.ejs
  97. +82 −0 views/item/adminaddgame.ejs
  98. +85 −0 views/item/adminaddgift.ejs
  99. +61 −0 views/item/adminadditem.ejs
  100. +73 −0 views/item/adminaddmaterial.ejs
  101. +56 −0 views/item/adminaddnoti.ejs
  102. +61 −0 views/item/adminedititem.ejs
  103. +196 −0 views/item/adminindex.ejs
  104. +59 −0 views/item/adminitemnotfound.ejs
  105. +65 −0 views/item/adminnoti.ejs
  106. +59 −0 views/item/adminnotlogin.ejs
  107. +64 −0 views/item/adminpasswordupdate.ejs
  108. +86 −0 views/item/adminsearch.ejs
  109. +53 −0 views/item/adminuserdetail.ejs
  110. +122 −0 views/item/adminuseredit.ejs
  111. +56 −0 views/item/adminuserpwupdate.ejs
  112. +87 −0 views/item/adminuserupdate.ejs
  113. +59 −0 views/item/cannotrenew.ejs
  114. +0 −38 views/item/itemsearch.ejs
  115. +58 −0 views/item/noaccount.ejs
  116. +71 −0 views/item/useraccount.ejs
  117. +88 −0 views/item/useraccountupdate.ejs
  118. +477 −23 views/item/userindex.ejs
  119. +59 −0 views/item/useritemnotfound.ejs
  120. +64 −0 views/item/usernoti.ejs
  121. +64 −0 views/item/userpasswordupdate.ejs
  122. +85 −0 views/item/usersearch.ejs
  123. +58 −0 views/item/visitoritemnotfound.ejs
  124. +58 −0 views/item/vistornotlogin.ejs
  125. +65 −0 views/item/vistorsearch.ejs
  126. +0 −38 views/item/vitemsearch.ejs
  127. +54 −0 views/item/wrongpassword.ejs
  128. +429 −96 views/layouts/layout.ejs
  129. +122 −0 views/material/adminmaterialdetail.ejs
  130. +116 −0 views/material/adminmaterialedit.ejs
  131. +66 −0 views/material/adminmaterialresult.ejs
  132. +99 −0 views/material/adminmaterialsearch.ejs
  133. +74 −0 views/material/adminmaterialupdate.ejs
  134. +86 −0 views/material/borrow.ejs
  135. +45 −0 views/material/import_xlsx.ejs
  136. +27 −0 views/material/print.ejs
  137. +86 −0 views/material/return.ejs
  138. +34 −0 views/material/uploadphoto.ejs
  139. +113 −0 views/material/useraddremark.ejs
  140. +90 −0 views/material/usermaterialdetail.ejs
  141. +73 −0 views/material/usermaterialdetail2.ejs
  142. +68 −0 views/material/usermaterialresult.ejs
  143. +119 −0 views/material/usermaterialreturn.ejs
  144. +95 −0 views/material/usermaterialsearch.ejs
  145. +44 −29 views/user/login.ejs
342 changes: 307 additions & 35 deletions api/controllers/BookController.js
Original file line number Diff line number Diff line change
@@ -7,62 +7,334 @@

module.exports = {

booksearch: async function (req, res) {
var models = await Book.find().sort([{id:'DESC'}]);
return res.view('book/booksearch', { book: models});
userbooksearch: async function (req, res) {
var models = await Book.find().sort([{ id: 'DESC' }]);
return res.view('book/userbooksearch', { book: models });
},

bookresult: async function(req, res){
const qCatrgory=req.query.category || "";
userbookresult: async function (req, res) {
const qCatrgory = req.query.category || "";
const qBookname = req.query.bookname;
const qAuthor = req.query.author;
const qPublisher = req.query.publisher;
const qISBN = req.query.ISBN;
const qNo = req.query.no;
// const qPublisher = req.query.publisher;
// const qISBN = req.query.ISBN;

var models = await Book.find({
where:{

category:{contains:qCatrgory},
bookname:{contains:qBookname},
author:{contains:qAuthor},
publisher:{contains:qPublisher},
ISBN:{contains:qISBN},
where: {
category: { contains: qCatrgory },
no: { contains: qNo },
category: { contains: qCatrgory },
bookname: { contains: qBookname },
author: { contains: qAuthor },
}

}).sort([{id:'DESC'}]);

return res.view('book/bookresult', {book:models});
}).sort([{ id: 'DESC' }]);

if (models.length == 0) {
return res.redirect('/item/useritemnotfound');
}

return res.view('book/userbookresult', { book: models });

},

userbookdetail: async function (req, res) {

var model = await Book.findOne(req.params.id);

if (!model) return res.notFound();

return res.view('book/userbookdetail', { book: model });

},

userbookdetail2: async function (req, res) {

var model = await Book.findOne(req.params.id);

if (!model) return res.notFound();

return res.view('book/userbookdetail2', { book: model });

},

userbookreturn: async function (req, res) {

var model = await Book.findOne(req.params.id);

if (!model) return res.notFound();

return res.view('book/userbookreturn', { book: model });

},

userbookreserve: async function (req, res) {

var model = await Book.findOne(req.params.id);

if (!model) return res.notFound();

return res.view('book/userbookreserve', { book: model });

},



vistorbooksearch: async function (req, res) {
var models = await Book.find().sort([{ id: 'DESC' }])
return res.view('book/vistorbooksearch', { book: models });
},

vistorbookresult: async function (req, res) {
const qCatrgory = req.query.category || "";
const qBookname = req.query.bookname;
const qAuthor = req.query.author;
const qNo = req.query.no;
// const qPublisher = req.query.publisher;
// const qISBN = req.query.ISBN;

var models = await Book.find({
where: {
category: { contains: qCatrgory },
no: { contains: qNo },
category: { contains: qCatrgory },
bookname: { contains: qBookname },
author: { contains: qAuthor },
}

}).sort([{ id: 'DESC' }]);

if (models.length == 0) {
return res.redirect('/item/visitoritemnotfound');
}

return res.view('book/vistorbookresult', { book: models });

},

vbooksearch: async function (req, res) {
var models = await Book.find().sort([{id:'DESC'}])
return res.view('book/vbooksearch', { book: models});


vistorbookdetail: async function (req, res) {

var model = await Book.findOne(req.params.id);

if (!model) return res.notFound();

return res.view('book/vistorbookdetail', { book: model });

},

vbookresult: async function(req, res){
const qCatrgory=req.query.category || "";
adminbooksearch: async function (req, res) {
var models = await Book.find().sort([{ id: 'DESC' }]);

return res.view('book/adminbooksearch', { book: models });
},

adminbookresult: async function (req, res) {
const qCatrgory = req.query.category || "";
const qBookname = req.query.bookname;
const qAuthor = req.query.author;
const qPublisher = req.query.publisher;
const qISBN = req.query.ISBN;
const qNo = req.query.no;
// const qPublisher = req.query.publisher;
// const qISBN = req.query.ISBN;

var models = await Book.find({
where:{

category:{contains:qCatrgory},
bookname:{contains:qBookname},
author:{contains:qAuthor},
publisher:{contains:qPublisher},
ISBN:{contains:qISBN},
where: {
category: { contains: qCatrgory },
no: { contains: qNo },
category: { contains: qCatrgory },
bookname: { contains: qBookname },
author: { contains: qAuthor },
}

}).sort([{ id: 'DESC' }]);

if (models.length == 0) {
return res.redirect('/item/adminitemnotfound');
}

return res.view('book/adminbookresult', { book: models });

},

adminbookdetail: async function (req, res) {

var model = await Book.findOne(req.params.id);

if (!model) return res.notFound();

return res.view('book/adminbookdetail', { book: model });

},

adminbookedit: async function (req, res) {
var models = await Book.find().sort([{ id: 'DESC' }]);

return res.view('book/adminbookedit', { book: models });
},

// action - adminupdate
adminbookupdate: async function (req, res) {

if (req.method == "GET") {

var model = await Book.findOne(req.params.id);

if (!model) return res.notFound();

return res.view('book/adminbookupdate', { book: model });

} else {

if (!req.body.Book)
return res.badRequest("Form-data not received.");

var models = await Book.update(req.params.id).set({
bookname: req.body.Book.bookname,
author: req.body.Book.author,
category: req.body.Book.category,
location: req.body.Book.location,
year: req.body.Book.year,
no: req.body.Book.no,
}).fetch();
if (models.length == 0) return res.notFound();

return res.redirect("/book/adminbookedit");

}
},

// action - delete
adminbookdelete: async function (req, res) {

if (req.method == "GET") return res.forbidden();

var models = await Book.destroy(req.params.id).fetch();

if (models.length == 0) return res.notFound();

if (req.wantsJSON) {
return res.json({ message: "該書本已被刪除", url: '/book/adminbookedit' });
} else {

return res.redirect("/book/adminbookedit");
}

},

import_xlsx: async function (req, res) {

if (req.method == 'GET')
return res.view('book/import_xlsx');

req.file('file').upload({ maxBytes: 10000000 }, async function whenDone(err, uploadedFiles) {
if (err) { return res.serverError(err); }
if (uploadedFiles.length === 0) { return res.badRequest('No file was uploaded'); }

var XLSX = require('xlsx');
var workbook = XLSX.readFile(uploadedFiles[0].fd);
var ws = workbook.Sheets[workbook.SheetNames[0]];
var data = XLSX.utils.sheet_to_json(ws);
console.log(data);
var models = await Book.createEach(data).fetch();
if (models.length == 0) {
return res.badRequest("No data imported.");
}

}).sort([{id:'DESC'}]);
return res.redirect("/book/adminbookedit");
});
},

borrow: async function (req, res) {
return res.view('book/borrow');
},

return: async function (req, res) {
return res.view('book/return');
},

return res.view('book/vbookresult', {book:models});
print: async function (req, res) {
var models = await Book.find().sort([{ id: 'DESC' }]);
return res.view('book/print', { book: models });

},


useraddremark: async function (req, res) {
var model = await Book.findOne(req.params.id);
if (req.method == "GET") {
return res.view('book/useraddremark', { book: model })
} else {

var userremarks = req.body.remarks;

await Item.create(
{
message: "書籍(" + model.bookname + ")新增備註: " + userremarks,
});


var models = await Book.update(req.params.id).set({
remarks: userremarks,
}).fetch();
if (models.length == 0) return res.notFound();

return res.redirect('/book/userbookreturn/' + model.id)
}
},

uploadphoto: async function (req, res) {
var model = await Book.findOne(req.params.id);

if (req.method == 'GET')
return res.view('book/uploadphoto', { book: model });

await Book.update({ id: model.id }, {
avatar: req.body.Book.avatar
});

return res.redirect('/book/adminbookedit');
},

export_xlsx: async function(req, res) {

var models = await Book.find();

var XLSX = require('xlsx');
var wb = XLSX.utils.book_new();

var ws = XLSX.utils.json_to_sheet(models.map(model => {
return {
no: model.no,
bookname: model.bookname,
category: model.category,
author: model.author,
year: model.year,
location: model.location,
remarks:model.remarks,
// borrowinfo: model.borrowinfo,
// returninfo: model.returninfo,
// ISBN: model.ISBN,
// QRcode:model.??
}
}));
XLSX.utils.book_append_sheet(wb, ws, "圖書");

res.set("Content-disposition", "attachment; filename=book.xlsx");
return res.end(XLSX.write(wb, { type: "buffer", bookType: "xlsx" }));
},














};

Loading