5. Bố cục đề tài
3.2.2 Giao diện truy cập vào cơ sở dữ liệu
Hình 3.2 là giao diện truy cập vào cơ sở dữ liệu thông qua Restful Service. Mỗi tài nguyên (ví dụ nutrient, ingredient,...) được cung cấp một bộ phương thức HTTP (GET, PUT, POST, DELETE) để người dùng thao tác dữ liệu thông qua truy vấn HTTP.
Hình 3.2. Giao diện nutrix web service
Hình 3.3 là giao diện truy cập vào tài nguyên nutrient với các phương thức HTTP (GET, PUT, POST, DELETE).
Hình 3.3. Giao diện khai thác dữ liệu cho nutrient 3.2.3 Giao diện quản lý hệ thống
Nutrix_ngadmin là giao diện dành cho người quản lý hệ thống với các chức năng quản lý (thêm, sửa, xóa) các thực phẩm, chất dinh dưỡng...và các chức năng quản lý tài khoản người dùng.
Hình 3.4. Giao diện trang quản lý hệ thống
Hình 3.5 là giao diện xem thông tin thực phẩm với các chức năng người quản lý có thể chọn là thêm, sửa, xóa thực phẩm.
Hình 3.5. Giao diện trang xem thông tin các thực phẩm
Hình 3.6 là giao diện xem thông tin chất dinh dưỡng như tên, kí hiệu và đơn vị tính của chất dinh dưỡng.
Hình 3.6. Giao diện trang xem thông tin chất dinh dưỡng
Hình 3.7 là giao diện chỉnh sửa thông tin của thực phẩm như thay đổi tên, mô tả, và thay đổi hàm lượng chất dinh dưỡng có trong thực phẩm.
Hình 3.7. Giao diện trang sửa thông tin thực phẩm
3.2.4 Giao diện dành cho người sử dụng
Nutrix_webapp là phần khai thác dành cho người sử dụng hệ thống. Người dùng có thể tìm kiếm, xem thông tin thực phẩm, giá trị chất dinh dưỡng trong thực phẩm và tạo mới thực đơn.
Hình 3.8 là giao diện tìm kiếm thông tin thực phẩm với đầy đủ hàm lượng dinh dưỡng có trong thực phẩm.
Hình 3.8. Giao diện trang quản lý người dùng
Hình 3.9 là giao diện xem chi tiết thực phẩm với hàm lượng dinh dưỡng có trong thực phẩm. Các hàm lượng được tính trong 100g thực phẩm ăn được.
Hình 3.9. Giao diện trang xem chi tiết thực phẩm
Hình 3.10 là giao diện tạo mới thực đơn theo nhu cầu của người dùng khi chọn thực phẩm và số lượng người sử dụng thực đơn.
Hình 3.10. Giao diện trang tạo mới thực đơn
Hình 3.11 là giao diện chỉnh sửa thực đơn với các chỉnh sửa thêm hoặc xóa thực phẩm. Lúc này các thông số về chất dinh dưỡng có trong thực đơn cũng được tính toán lại.
Hình 3.11. Giao diện trang chỉnh sửa thực đơn
Hình 3.12 là giao diện thêm mới thực phẩm trong thực đơn với các lựa chọn thực phẩm và số lượng thực phẩm sử dụng trong thực đơn.
Hình 3.12. Giao diện trang thêm mới thực phẩm trong thực đơn 3.2.5 Giao diện mobile trên nền tảng Android
Là giao diện trên mobile sử dụng Ionic framework. Với Ionic, có thể chạy trên Android, iOS, Winphone nhưng với khóa luận này, vì điều kiện còn hạn chế nên ứng dụng này chỉ chạy trên Android.
Hình 3.13. Các giao diện xem thông tin thực phẩm, chất dinh dưỡng và xem chi tiết thông tin thực phẩm.
Các hình trên là giao diện hiển thị xem danh sách thực phẩm, danh sách chất dinh dưỡng và xem chi tiết thực phẩm trên thiết bị di động chạy bằng Android.
KẾT LUẬN VÀ KIẾN NGHỊ
Sau thời gian được học tập và tìm hiểu các công nghệ mới,với hơn sáu tháng để hoàn thành khóa luận, em đã xây dựng được ứng dụng để tra cứu và xây dựng thực đơn dinh dưỡng dựa trên mô hình Web Service và Onepage Application. Thông qua khóa luận này, em đã hiểu thêm về các dịch vụ Web (Web Service), và cũng được học thêm về những công nghệ mới, xây dựng một Web Service bằng Java, sử dụng Spring Framework và phát triển ứng dụng phía client trên web và thiết bị di động với AngularJS, Ionic framework... Với thời gian và kỹ năng có hạn, ứng dụng còn thiếu sót rất nhiều tính năng nên hướng phát triển và nghiên cứu thêm là:
1. Có thể phát triển thêm các chức năng khác như lưu trữ thực đơn, tính năng lượng cần thiết tùy theo mỗi người...
2. Thu thập chính xác các dữ liệu về dinh dưỡng tại Việt Nam để làm đa dạng hơn cơ sở dữ liệu.
3. Phát triển hệ thống hướng đa nền tảng, đa thiết bị.
4. Bảo mật dữ liệu cho website.
Với kinh nghiệm tiếp cận công nghệ mới còn hạn chế nên kết quả của ứng dụng này còn rất nhiều thiếu sót. Rất mong thầy cô và các bạn đóng góp ý kiến để ứng dụng được hoàn thiện thêm. Cuối cùng, em xin chân thành cảm ơn toàn thể giảng viên khoa công nghệ thông tin Đại học Sư Phạm Đà Nẵng, và đặc biệt là giảng viên hướng dẫn Tiến sĩ Nguyễn Trần Quốc Vinh đã nhiệt tình giúp đỡ em hoàn thành đề tài này.
TÀI LIỆU THAM KHẢO
Tiếng Việt
[5] Hà Anh, Nâng cao tầm vóc trẻ em, 30/09/2013, truy cập ngày 29 tháng 01 năm 2015, <http://baodientu.chinhphu.vn/Doi-song/Nang-cao-tam-voc-tre-em- 80-do-dinh-duong-ren-luyen/181887.vgp>
[7]Viện dinh dưỡng. Chiến lược quốc gia về dinh dưỡng giai đoạn 2011-2020 và tầm nhìn đến năm 2030. Viện dinh dưỡng, pages 1–2, 02-2012.
[8]Viện dinh dưỡng. Số liệu thống kê về tình trạng dinh dưỡng trẻ em qua các năm, 3-2014, truy cập ngày 08 tháng 12 năm 2014, http://www.nutrition.org.vn/news/vi/134/89/a/so-lieu-thong-ke-ve-tinh-trang- dinh-duong-tre-em-qua-c aspx
[20] PGS. TS. Hà Thị Anh Đào PGS. TS. Nguyễn Công Khẩn. Bảng thành phần
thực phẩm Việt Nam. Nhà xuất bản Y học, 2007.
[26] Liên Hợp Quốc tại Việt Nam. Dinh dưỡng bà mẹ và trẻ em ở việt nam, 2013, truy cập ngày 25 tháng 11 năm 2014, <http://www.un.org.vn/vi/ feature- articles-press-centre-submenu-252/339-dinh-dung-ba-m-va-tr-em--vit-
nam.html>
Tiếng Anh
[1]Scott W. Ambler. Acceptance/customer tests as requirements artifacts: An agile introduction, truy cập ngày 11 tháng 01 năm 2015, <http://agilemodeling.com/artifacts/acceptanceTests>
[2]AngularJS. Conceptual overview, truy cập ngày 12 tháng 12 năm 2014, < https://docs.angularjs.org/guide/concepts>
[3]Scott Ambler + Associates. User stories: An agile introduction, 2014, truy cập ngày 09 tháng 12 năm 2014, <http://www.agilemodeling.com/artifacts/ userStory.htm>
[4]Dan Bunea. How tdd improves development speed and is very cost effective, September 22, 2005, truy cập ngày 23 tháng 12 năm 2014,
<http://danbunea.blogspot.com/2005/09/ how-tdd-improves-development-
speed-and.html>
[6] William C.Wake. Refactoring Workbook. Addsion-Wesley, 2004.
[9]Drifty. The ionic book, 2014, truy cập ngày 12 tháng 01 năm 2015, <http://ionicframework.com/docs/guide/>
[10] FAO. New developments in nutrition education utilising computer tech- nology, 2014, truy cập ngày 15 tháng 11 năm 2014, <http://www.fao.org/docrep/w3733e/ w3733e07.htm>
[11] Happyworm. The future of web apps – single page applications, Monday, August 23rd, 2010, truy cập ngày 09 tháng 01 năm 2015, <http://happyworm.com/blog/2010/08/23/ the-future-of-web-apps-single- page-applications/>
[12] United States Department of Agriculture. Usda national nutrient database for standard reference, 2014, truy cập ngày 16 tháng 11 năm 2014, <http://ndb.nal. usda.gov/>.
[13] Ruby on Rails insights for developers. Single page application done right, Monday, August 23rd, 2010, truy cập ngày 19 tháng 12 năm 2014,
<http://railsadventures.wordpress.com/2014/05/ 04/single-page-application-
[14] Oracle. The Java EE 6Tutorial - Developing RESTfulWeb Services with
JAX-RS.
[15] Oracle. The Java EE 6Tutorial. Oracle page 23-25
[16] Oracle. Developing Applications For the Java EE 6 Platform. Oracle page 120-124
[17] Oracle. Jdbc-oracle, 2014, truy cập ngày 09 tháng 12 năm 2014,
<http://www.oracle.com/technetwork/java/javase/jdbc/index.html>
[18] Oracle. Annotations, 2014, truy cập ngày 23 tháng 12 năm 2014, <http://docs.oracle.com/javase/tutorial/java/annotations/>
[19] David Orenstein. How to application programming interface.
Computerworld, October, 2000.
[21] Uri Shaked. Angularjs vs. backbone.js vs. ember.js, truy cập ngày 15 tháng 12 năm 2014, <https://www.airpair.com/js/javascript-framework- comparison>
[22] James Shore. The Art of Agile Development. 2010.
[23] Pathfinder Solutions. The pros and cons of tdd, June 11, 2012, truy cập
ngày 25 tháng 12 năm 2014,
<http://www.pathfindersolns.com/archives/1684>
[24] tutorialspoint. Http-request, 2014, truy cập ngày 08 tháng 01 năm 2014,
<http://www.tutorialspoint.com/http/http_requests.htm>
[25] tutorialspoint. Http-response, 2014, truy cập ngày 29 tháng 12 năm 2014,
[27] USDA. About the database, 2014, truy cập ngày 19 tháng 12 năm 2014, <http://ndb.nal.usda. gov/>
[28] versionone. Test-first programming, 2014, truy cập ngày 02 tháng 04 năm 2015, <http://www.versionone.com/Agile101/Test-First_ Programming.asp> [29] Wikipedia. Android, 2014, truy cập ngày 06 tháng 02 năm 2015,
<http://en.wikipedia.org/wiki/Android(operating_system)>
[30] Wikipedia. Hypertext transfer protocol, 2014, truy cập ngày 12 tháng 03 năm 2015, <http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol> [31] Wikipedia. Representational state transfer, 2014, truy cập ngày 16 tháng 12
năm 2014, <http://en.wikipedia.org/wiki/Representational_ state_transfer> [32] Wikipedia. Single-page application, 2014, truy cập ngày 18 tháng 02 năm
PHỤ LỤC
1. Mã nguồn file controller.js (nutrix_user_gui)
var app = angular.module('nutrixApp');
app.directive('listingredient', function($timeout, $log, $http, baseUrl, $stateParams) { return { restrict: 'E', scope: {}, templateUrl: 'tmpl/listingredient.html', replace: true,
controller: function ($scope , $http, baseUrl) {
$log.debug("IngredientCtrl get here"); $scope.ingredients = []; $scope.nutrients = []; $scope.selectedIngredient = {}; $scope.viewIngredientForm = null; $scope.init = function() { $scope.ingredients = []; $scope.query = undefined; $scope.currentPage = 1; $scope.itemsPerPage = 15; $scope.totalItems = -1; $scope.bigTotalItems = -1; $scope.bigCurrentPage = 1; $scope.maxSize = 7; } $scope.loadMoreIngredients = function() { var myparams = {
offset: ($scope.bigCurrentPage - 1) * $scope.itemsPerPage, max: $scope.itemsPerPage
}
if ($scope.query != undefined && $scope.query != null) { myparams['q'] = $scope.query;
$http.get(baseUrl + '/nutrix/adm/ingredient', { params: myparams }).then(function(resp) { console.log('Success', resp); $log.debug("Start:" + ($scope.bigCurrentPage - 1) * $scope.itemsPerPage); $scope.bigTotalItems = resp.data.total; $log.debug("Total:" + $scope.bigTotalItems); $scope.ingredients = resp.data.collection; console.log($scope.itemsPerPage); }, function(err) { console.error('ERR', err); }); };
$scope.$watch('bigCurrentPage + itemsPerPage', function() { $scope.loadMoreIngredients(); }); $scope.doSearchIngredients = function(q) { console.log('doSearchIngredients'); $scope.init(); $scope.query = q; $scope.loadMoreIngredients(); }; $scope.openViewIngredientForm = function(ingredient) { $scope.viewIngredientForm = "edit"; $scope.selectedIngredient = ingredient; } $scope.isViewIngredienShow = function() { return ($scope.viewIngredientForm == "edit"); }
$scope.init();
}, // end of controller
link: function($scope, element, attrs) { $log.debug("listingredient go to here");
} // end of link }
};
2. Mã nguồn file listrecipe.js (nutrix-user-gui)
var app = angular.module('nutrixApp');
app.directive('listrecipe', function($timeout, $log, $http, baseUrl) { return {
restrict: 'E', scope: {},
templateUrl: 'tmpl/listrecipe.html', replace: true,
controller: function ($scope , $http, baseUrl) { //init recipes $scope.recipes = []; $scope.recipe = {}; $scope.currentPage = 1; $scope.itemsPerPage = 4; $scope.totalItems = -1; $scope.bigTotalItems = -1; $scope.bigCurrentPage = 1; $scope.maxSize = 4; $scope.recipeForm = null;
$http.get(baseUrl + '/nutrix/adm/recipe').success(function (data) { $scope.recipes = data.collection;
});
$scope.loadMoreRecipes = function() { var myparams = {
offset: ($scope.bigCurrentPage - 1) * $scope.itemsPerPage, max: $scope.itemsPerPage
}
$http.get(baseUrl + '/nutrix/adm/recipe', { params: myparams
console.log('Success', resp); $log.debug("Start:" + ($scope.bigCurrentPage - 1) * $scope.itemsPerPage); $scope.bigTotalItems = resp.data.total; $log.debug("Total:" + $scope.bigTotalItems); $scope.recipes = resp.data.collection; console.log($scope.itemsPerPage); }, function(err) { console.error('ERR', err); }); };
$scope.$watch('bigCurrentPage + itemsPerPage', function() { $scope.loadMoreRecipes();
});
$scope.isRecipeFormShow = function() { return ($scope.recipeForm == "edit"); }
$scope.openEditRecipeForm = function(recipe) { $scope.recipeForm = "edit";
$scope.recipeItem = angular.copy(recipe); };
$scope.$watch("recipeForm", function(newValue, oldValue) { console.log('old:' + oldValue + ' / new:' + newValue);
if ($scope.recipeForm == "create-done") { $http.post(baseUrl + '/nutrix/adm/recipe', $scope.recipeItem).success(function (newRecipe) { $scope.recipes.push(newRecipe); }); } if ($scope.recipeForm == "update-done") {
$http.put(baseUrl + '/nutrix/adm/recipe' + '/'+ $scope.recipeItem.id, $scope.recipeItem)
.success(function (newRecipe) {
if ($scope.recipes[i].id == newRecipe.id) { $scope.recipes[i] = newRecipe; break; } } $scope.recipeItem = {};
$scope.recipeForm = null; //"edit" }); } if ($scope.recipeForm == "delete-done") { if (angular.isDefined($scope.recipeItem.id)) { $http.delete(baseUrl + '/nutrix/adm/recipe' +'/'+ $scope.recipeItem.id).success(function () { var position = -1;
for (var i = 0; i < $scope.recipes.length; i++) { if ($scope.recipes[i].id == $scope.recipeItem.id) { position = i; break; } } if (position >= 0) { $scope.recipes.splice(position, 1); } $scope.recipeItem = {};
$scope.recipeForm = null; //"edit" }); } } }); $scope.consoleLogModel = function() { $log.debug("---"); $log.debug("List Recipe object:");
$log.debug($scope.recipes); $log.debug($scope.recipeItem); };
// open directive editrecipe $scope.isCollapsed = true; },
link: function($scope, element, attrs) { $log.debug("listrecipe go to here"); }
} });
3. Mã nguồn file router.js
//Setting up route angular.module('nutrixApp').config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) { $urlRouterProvider.otherwise('/'); $stateProvider .state('viewingredient', { url: '/viewingredient/:id', resolve: { ingredientId: function($stateParams) { return $stateParams.id; }, }, controller: 'viewIngredientCtrl', templateUrl: 'view/viewingredient.html' }) .state('ingredients', { url: '/ingredients', controller: 'IngredientCtrl', templateUrl: 'view/ingredient.html' }) .state('listingredients', { url: '/listingredients', controller: 'IngredientCtrl', templateUrl: 'view/listingredients.html' }) .state('recipes', {
url: '/recipes', controller: 'IngredientCtrl', templateUrl: 'view/recipes.html' }) } ]);