6. Kết cấu của đề tài
3.1.2. Cài đặt môi trường lập trình và một số module cần thiết
3.1.2.1. Môi trường Node.js và NPM
Vào trang chủ của Node.js (https://nodejs.org/en/download/) để tài môi trường Node.js và cài đặt trong bản cài đặt đã có chứa sẵn chương trình npm. phiên bản mới nhất của node.js hiện tại là 8.11.1 và npm là 5.6.0. [1]
Để kiểm tra phiên bản của node.js hoặc npm thì ta dùng câu lệnh bên dưới.
node -v npm -v
Hình 3.1 Màn hình console hiển thị thông tin phiên bản của Node.js và NPM.
3.1.2.2. Cài các Module cần thiết sử dụng phần mềm NPM Cách sử dụng NPM Cách sử dụng NPM
Tạo một thư mục trống và mở cửa sổ CMD trong thư mục đó và chạy lệnh command như sau:
Một số câu hỏi được đặt ra để nhập vào thông tin dự án bạn có thể skip tất cả bằng cách nhấn nút enter hoặc điền đầy đủ thông tin vào.
Hình 3.2 Màn hình console khi gõ lệnh npm init.
Sau đó npm sẽ tạo một file pakage.json để chứa thông tin dự án và các module đã cài. Nếu di chuyển đi nơi khác hoặc triển khai dự án lên server thật thì chỉ cần có file này và chạy lệnh npm install thì các module sẽ được cài vào thư mục node_modules.
Cài đặt Module cần thiết
Sử dụng câu lệnh bên dưới để cài đặt các module cần thiết cho phía Web API.
npm install express body-parser express-validator dotenv debug http-errors jsonwebtoken mathjs md5 moment morgan multer mysql nodemailer
Hình 3.3 Thư mục node_modules chứa module đã cài đặt trong câu lệnh npm install.
3.1.3. Kết nối và truy vấn dữ liệu giữa Node.js và MySql 3.1.3.1. Kết nối với database Mysql 3.1.3.1. Kết nối với database Mysql
Tạo file pool.js để kết nối tới database.
const mysql = require('mysql');
const connection = mysql.createPool({ connectionLimit: 10,
user: process.env.FW_USER, port: process.env.FW_PORT, password: process.env.FW_PASS, database: process.env.FW_DATABASE }); module.exports = {connection};
Tạo tập tin helper.js trong thư mục helpers với nội dung như sau.
const db=require('../databases/pool').connection; function sendQueryToDatabase(queryStatement,
arrayValue) {
return new Promise((resolve, reject) => {
return db.query( queryStatement,arrayValue,(err, results) => {
if (err) { return reject(err); } resolve(results);
}); }); };
module.exports = { sendQueryToDatabase };
Hàm này là một hàm bất đồng bộ, hàm nhận vào 2 tham số queryStatement là câu lệnh truy vấn và arrayValue là một mảng giá trị, chức năng của hàm này là trả về dữ liệu cần lấy trong câu lệnh vừa truy vấn.
3.1.3.2. Truy vấn dữ liệu
Để truy vấn dữ liệu ta sử dụng hàm bất đồng bộ sendQueryToDatabase đã giới thiệu ở trên để sử dụng, ở đây tác giả tạo một server node.js tại port 3000.
const http = require(‘http’);
const router = require(‘express’).router(); const helper = require('../helpers/helper'); //Khai báo phương thức get có tên “get-user” kèm theo là một callback function
router.get(‘/get-user’,async function(req,res){ try{
let userID = req.query.useraccountid;//bắt query string có tên là useraccountid rồi gán vào biến let result = await
helper.sendQueryToDatabase( “SELECT * FROM
//Hàm dưới chuyển đổi dữ liệu từ object thành json và trả về cho Client
return res.json({"result": result});
}catch(err){//bắt lỗi xảy ra khi có lỗi khi truy vấn dữ liệu
return res.status(400).json({“err”: err.message}); }});
http.createServer(router).listen(3000);//chạy server trên port 3000
Câu lệnh trên sẽ trả về tất cả thông tin của một tài khoản dưới dạng JSON.
Hình 3.4 Server trả về dữ liệu dưới dạng JSON của tài khoản 100000001.
3.1.4. Chức năng của một số router có trong API
Bảng 3.1 Tên và một số chức năng của API
Tên router Phương
thức Chức năng
/api/account/login Post Đăng nhập, server sẽ trả về các dữ liệu cần thiết như json web token, ... để lưu trữ trong cookie.
/api/account/signup-for-both Post Đăng ký một tài khoản thợ hoặc khách, server gửi một mail xác minh tài khoản về mail người dùng đã đăng ký.
/api/account/verify Put Xác minh một tài khoản.
/api/account/profile/:useraccountid Get Lấy thông tin cá nhân của một người dùng với user id tương ứng.
/api/account/profile Put Cập nhật thông tin cá
nhân.
/api/account/put-change-password Put Thay đổi mật khẩu.
/api/account/put-forgot-password Put Khi quên mật khẩu thì dùng router này điền email
vào sau đó server tạo một mật khẩu rồi gửi về email đó.
/api/account/put-status-online Put Cập nhật trạng thái online. /api/category/get-all Get Lấy danh sách tất cả danh
mục.
/api/category/get-by-userworkerid Get Lấy danh sách các danh mục chưa gửi hồ sơ đăng ký.
/api/category/create-category Post Tạo mới một danh mục. /api/category/update-category Put Cập nhật một danh mục có
sẵn. /api/category/get-all-cv-by-
categoryid?categoryid=
Get Chức năng là lấy tất cả hồ sơ có trong một danh mục.
/api/cv/post Post Tạo mới một hồ sơ.
/api/cv/active-cv Put Active một CV.
/api/cv/active-
cv?categoryid=&userworkerid=
Delete Xóa một CV.
/api/cv/not-activated Get Lấy danh sách tất cả các cv chưa active.
/api/cv/activated-by-
query?categoryid=&provinceid=&distri ctid=&wardid=
Get Lọc danh sách hồ sơ theo từng danh mục và địa điểm /api/cv/get-all-cv-by-userid Get Lấy tất cả danh sách hồ sơ
theo mã tài khoản. /api/cv/get-all-cv-by-
categoryid?categoryid=
Get Lấy danh sách các hồ sơ của một danh mục bất kì. /api/location/geolocation Put Cập nhật thông tin vị trí. /api/upload/image-avatar Post Lưu trữ ảnh đại diện vào
server.
/api/upload/image-store Post Lưu trữ ảnh đại diện của danh mục vào server. /api/chat/create-chat-history Post Tạo mới một giao dịch. /api/chat/get-list-people-chated Get Lấy danh sách người đã
nhắn tin. /api/chat/get-message-
chated?historyid=&limit=&page=
Get Lấy về các tin nhắn đã nhắn.
/api/chat/put-cancel-transaction Put Hủy một giao dịch.
/api/chat/put-done-transaction Put Hoàn thành một giao dịch kèm theo đánh giá.
/api/chat/get-info-transaction-done-by- userid?useraccountid=&limit=&page=
Get Lấy tất cả thông tin của giao dịch theo mã tài khoản.
/api/statistical/get-all-user- worker?limit=&page=
Get Lấy danh sách các tài khoản người thợ.
/api/statistical/get-all-user- guest?limit=&page=
Get Lấy danh sách người khách.
/api/statistical/get-all-transaction- done?limit=&page=
Get Lấy danh sách giao dịch. /api/statistical/put-block-account-by- userid Put Chặn một người dùng. /api/statistical/put-enable-account-by- userid Put Mở chặn một người dùng. /api/dashboard/get-count-cv-by- categoryid
Get Tính tổng hồ sơ theo từng danh mục.
/api/dashboard/get-count-user-type Get Tính tổng tài khoản phân theo từng loại.
/api/dashboard/get-count-transaction Get Tính tổng giao dịch phân theo trạng thái.
3.2. Xây dựng Server Websocket sử dụng thư viện socket.io để làm ứng dụng nhắn tin thời gian thực nhắn tin thời gian thực
3.2.1. Giới thiệu chung về Server Websocket
Tác giả tạo Server Websocket bằng cách sử dụng thư viện Socket.io và môi trường Node.js được tải về từ chương trình NPM. Chức năng của server này là tạo ứng dụng nhắn tin thời gian thực giữa thợ với khách tìm thợ giúp gửi và bắt dữ liệu thời gian thực.
3.2.2. Cài đặt một số module cần thiết
Tác giả cài đặt một số module cần thiết cho việc nhắn tin thời gian thực bằng dòng command.
npm install express request socket.io
3.2.3. Chức năng của từng sự kiện trong Socket.io
Socket.io có 2 phương thức chính là:
socket.on(string event, callback data) sẽ thực hiện sự kiện lắng nghe từ client gửi lên.
socket.emit(string event, object data) sẽ thực hiện việc phát ra một sự kiện về client kèm theo dữ liệu.
socket.on('authorization', function (result) { token = result.access_token;
UserAccountID = result.UserAccountID;
callApi.PUT(seed.ACCOUNT.PUT_STATUS_ONLINE,
objectValue, token);//Gọi api cập nhật trạng thái online vào database.
});
Đoạn code trên với chức năng là lắng nghe sự kiện với tên authorization nhằm cập nhật giá trị một số loại biến và gọi API cập nhật trạng thái.
socket.on('array_room', function (result) {
result.map(function (value) {//Lặp qua một mảng và tạo một mảng mới.
socket.join(value + "");//tham gia vào room với tên được lưu trong biến value.
ArrayRoom.push(value + "");//Thêm giá trị vào mảng ArrayRoom.
socket.broadcast.to(value +
"").emit('is_online', UserAccountID);//Gửi trạng thái online tới từng phòng.
}); });
Đoạn code trên lắng nghe client gửi dữ liệu mã phòng lấy được nhờ vào cách gọi API lên và tiến hành tham gia vào từng room trong socket.io và gửi trạng thái online đến từng room đó.
socket.on('disconnect', function () { objectValue.StatusOnline = 0;
callApi.PUT( seed.ACCOUNT.PUT_STATUS_ONLINE, objectValue, token);//Gọi API để cập nhật trạng thái trên database
ArrayRoom.map(function (value){ //Gửi sự kiện offline tới từng room socket.broadcast.to(value +
"").emit( 'is_offline', UserAccountID); });
});
Khi Client tắt tab thì sự kiện này sẽ kích hoạt và sẽ thực thi gọi API để cập nhật trạng thái offline trên Database và một vòng lặp theo mảng nhằm mục đích gửi sự kiện offline vào các phòng Client này đã đặng nhập.
socket.on('send_message', function (result) { socket.broadcast.to(result.HistoryID +
"").emit('get_message', result);//Gửi tin nhắn vừa chat vào phòng cần gửi.
callApi.POST(seed.CHAT.NEW_MESSAGE, result, token);//Gọi API thêm mới một dòng chat vào database.
});
Ví dụ ở đây Client A, Client B đều online và đều đã vào chung một room chat, Client A gửi lên server một đoạn chat với thông tin là tới Client B và server sẽ gửi đoạn chat đó vào room chat mà 2 người đã tham gia vào Client B sẽ nhận được tin nhắn và hiển thị nó.
3.3. Giao diện Front-end sử dụng thư viện Angular.js 3.3.1. Giới thiệu 3.3.1. Giới thiệu
Ở đây tác giả sử dụng chủ đề đã được thiết kế sẵn có tên INSPINIA - Responsive Admin Theme. Sử dụng Angular.js để render ra HTML dùng dữ liệu JSON nhận từ server.
3.3.2. Giao diện Front-end của thợ 3.3.2.1. Đăng ký 3.3.2.1. Đăng ký
Hình 3.5 Giao diện đăng ký. Hình 3.6 Giao diện đăng ký khi bị lỗi.
3.3.2.2. Đăng nhập
Hình 3.7 Giao diện đăng nhập. Hình 3.8 Giao diện đăng nhập khi bị lỗi sai tài khoản hoặc mật khẩu.
Tại màn hình đăng nhập nếu lỡ quên mật khẩu thì có thể ấn vào dòng quên mật khẩu sau đó trang web sẽ hiển thị một popup người dùng có thể nhập email tài khoản đó vào để khôi phục tài khoản.
Sau khi đăng nhập thành công website sẽ tự động lấy vị trí hiện tại gửi lên server.
3.3.2.3. Trang cá nhân
Trong trang cá nhân, cột đầu tiên có tên là Chi tiết cá nhân nó chứa các thông tin của tài khoản, trạng thái online của tài khoản và nếu bạn là khách thì có thể chọn thợ thích hợp để nhắn tin trực tiếp với người đấy.
Với cột đầu tiên người dùng có thể xem các giao dịch đã được đánh giá bằng
cách click vào dòng để hiển thị popup thông tin
các giao dịch.
Hình 3.10 Giao diện Popup hiển thị lịch sử đã giao dịch
Cột thứ hai có tên là Danh sách hồ sơ chứa các thông tin các hồ sơ đã nộp và đã được kích hoạt bởi admin.
Click vào nếu muốn sửa thông tin cá nhân,
sau khi ấn nút sửa thông tin thì sẽ tự động chuyển tới trang để cập nhật thông tin cá nhân như hình dưới.
Hình 3.11 Giao diện cập nhật thông tin cá nhân.
Khi cập nhật thành công sẽ hiện một thông báo thành công và ngược lại nếu có lỗi trong quá trình cập nhật thì website sẽ hiển thị lỗi.
3.3.2.4. Hồ sơ Đăng hồ sơ Đăng hồ sơ
Hình 3.12 Giao diện đăng hồ sơ.
Ở dòng danh mục ngành nghề đó là một drop-down nhằm hiển thị danh sách các danh mục ngành nghề mà người thợ này chưa đăng ký.
Khi người dùng nhập tất cả các thông tin cần thiết và bắt đầu ấn đăng hồ sơ nếu gửi thành công sẽ hiển thị thông báo và ngược lại nếu có lỗi cũng sẽ hiển thị tên lỗi.
Danh sách hồ sơ đang đợi duyệt
Đây là giao diện danh sách hồ sơ đợi duyệt đây có thể tìm kiếm theo tên danh mục hoặc sắp xếp theo năm kinh nghiệm và ngày nạp hồ sơ.
Nếu muốn chỉnh sửa hồ sơ đang trong quá trình đợi thì có thể chọn vào nút để mở popup cập nhật thông tin hồ sơ.
Hình 3.14 Giao diện chỉnh sửa hồ sơ.
Hoặc có thể xóa hồ sơ nào đó bằng cách ấn vào nút sau đó website hiện lên popup xác nhận một lần nữa.
Danh sách hồ sơ đã duyệt
Hình 3.15 Giao diện danh sách các hồ sơ đã được admin duyệt.
Hình 3.16 Giao diện chat thời gian thực giữa thợ và khách.
Ở đây nếu màu nền của danh sách như Nguyễn Thành Đạt thì người đó chưa được trả lời tin nhắn còn nền màu trắng như Trần Đình Chiến thì tin nhắn đã được trả lời.
Bên cạnh tên của người nhắn có dấu chấm màu xanh lúc đó người đó đang online còn ngược lại là màu xám thì chứng tỏ người đấy hiện đang không online.
Nếu muốn nhắn bất kỳ điều gì cho người kia thì gõ vào ô input Nhập tin nhắn sau đó ấn Gửi hoặc nhấn nút Enter để tiến hành gửi nội dung lên server. Server xử lý xong gửi nội dung tới người nhận.
Trong quá trình nói chuyện có thể không đồng ý cho người này sửa thiết bị thì ấn để chuyển sang tìm kiếm người khác phù hợp hơn.
Sau khi mọi thứ đã được sửa chữa thành công thì ấn vào . Tiến hành đánh giá sao cho đối phương khi cả hai đều đánh giá giao dịch sẽ hoàn tất.
Hình 3.17 Giao diện đánh giá của một giao dịch.
3.3.3. Giao diện Front-end của khách
Giao diện của khách tương tự giao diện của thợ nhưng giao diện khách không có hồ sơ mà thay vào đó là tìm kiếm thợ theo danh mục ngành nghề và theo khu vực và hiển thị lên maps.
Hình 3.18 Giao diện tìm kiếm thợ
Trên giao diện có một danh sách chưa tất cả danh mục và một danh sách để người dụng chọn chứa tất cả các tên Tỉnh, Thành Phố, Quận, Phường, Xã,...
Hình 3.19 Giao diện khi đã được chọn một danh mục.
Hình trên, khi tác giả chọn danh mục Sửa chữa, bảo dưỡng bình nóng lạnh thì xuất hiện hai icon đại diện cho 2 thợ có thể sửa chữa được bình nóng lạnh ở khu vực này.
Hình 3.20 Thông tin của một thợ hiển thị khi được chọn.
Khi chọn một thợ, thông tin của thợ đó được hiển thị ra với các thông tin cơ bản và người dùng có thể xem rõ hơn thông tin của người thợ này bằng cách ấn
vào tên của thợ đấy . Nếu muốn nhắn tin trao đổi thì ấn website chuyển đến giao diện chat.
3.3.4. Giao diện Front-end của Admin
Website Admin bạn không thể đăng ký tài khoản mới như thợ hoặc khách. Ở website này có thêm một số quyền quản lý hệ thống như quản lý danh mục ngành nghề, quản lý tài khoản thợ và khách, ...
Hình 3.21 Giao diện đăng nhập của Admin
3.3.4.1. Trang tổng quan
Khi đăng nhập thành công website sẽ chuyển tới trang tổng quan với chức năng thống kê tổng các tài khoản, tổng các hồ sơ theo từng danh mục ngành nghề và thống kê tất cả các giao dịch trên hệ thống.
Hình 3.22 Giao diện trang tổng quan.
Giao diện trang tổng quan sẽ hiện thị dữ liệu dưới dạng biểu đồ với mục đích admin dễ so sánh dữ liệu.
Hình 3.23 Giao diện duyệt hồ sơ của thợ.
Khi thợ đăng hồ sơ lên thì admin tiến hành duyệt hồ sơ bằng cách nhấn vào nút , nếu hồ sơ không đạt yêu cầu thì tiến hành xóa hồ sơ sử dụng nút một popup xuất hiện.
Hình 3.24 Giao diện Popup khi nhấn xóa một hồ sơ.
3.3.4.3. Danh mục
Bên dưới là giao diện chỉnh sửa danh mục hoặc có thể thêm mới.
Để chỉnh sửa một danh mục ta chọn website hiển thị một popup. Ở đây người dùng có thể upload một ảnh lên server để làm ảnh đại diện cho danh mục đó.
Hình 3.26 Giao diện cập nhật một danh mục.
Để tạo mới một danh mục ta chọn website sẽ hiện một popup như khi cập nhật một danh mục sau đó admin nhập tên danh mục và upload ảnh khi thêm thành công website sẽ hiển thị thông báo thành công, ngược lại thì hiển thị thông báo lỗi. Admin sẽ xem được tất cả hồ sơ của một danh mục bằng cách ấn vào tên của một danh mục bất kỳ popup hiện ra như hình bên dưới chứa thông tin hồ sơ.