процессе проектирования курсового проекта был разработан интернет-магазин по продажам товаров для домашних животных.
Интернет-магазин предназначен для продажи различных товаров через интернет. Областью применения данного Web-приложения выступает интернет-торговля.
Создание данного интернет-магазина позволит продвигать и продавать товары, уменьшить издержки на рекламу и приобрести дополнительный рынок сбыта своего товара, расширить клиентскую аудиторию и, как следствие, увеличение прибыли.
Интернет-магазин имеет удобный и понятный интерфейс, благодаря которому не требуется излишних усилий в освоении работы с сайтом. Вся информация не содержит ничего лишнего.
Результаты проверки показали, что система работает без ошибок, имеется возможность работы с веб-сайтом во всех популярных браузерах.
В результате разработки курсового проекта были отточены навыки в дизайне сайтов, проектировки интерфейсов, разработке логотипов. Приобретены практические умения JavaScript, HTML и CSS верстки сайтов.
1. Node.js Разработка серверных веб-приложений на JavaScript/ Дэвид Хэррон Изд-во: ДМК Пресс, 2012 – 146 с.
2. Изучаем JavaScript // Майкл Моррисон — СПб.: Питер, 2012. — С.608
3. Титтел Эд, Бурмейстер Мэри. HTML 4 для "чайников". 6-е издание. М.: Из-дательский дом “Диалектика -Вильямс” – 2009. - 368с.
4. Веб-приложения на JavaScript. Год: 2012. // Маккоу — СПб.: Питер, 2012. — С.560 608.
5. Большая книга CSS3. // Дэвид Макфарланд. — СПб.: Питер, 2014. — С. 608.
6. HTML5 и CSS3. Веб-разработка по стандартам нового поколения // Брайан Хоган — СПб.: Питер, 2014. — С. 272.
7. Лебедев А. Руководство Лебедев А. – Москва.: Издательство Студии Артемия Лебедева, 2011. – 452 с.
8. Спейнауэр С. Справочник Web-мастера. СПб.: BHV, 1997. – 368 с.
9. Ратшиллер Т., Геркен Т. PHP4: разработка Web-приложений. - СПб: Питер, 2001. - 384 с.
10. Томсон Л., Веллинг Л. Разработка Web-приложений на PHP и MySQL. - К.: "ДиаСофт", 2001. - 672 с
11. Яргер Р., Риз Дж., Кинг Т. MySQL и mSQL. Базы данных для небольших предприятий и Интернета. - СПб: Символ-Плюс, 2000 - 560 с.
12. Орлов С.Д. Технологии разработки программного обеспечения. Учеб. пособие. 2-е изд. СПб.: Питер, 2003. – 480 с.
Листинг файла package.json
{ "dependencies": { "async": "^2.4.1", "body-parser": "^1.17.2", "connect-mongo": "^1.3.2", "cookie-parser": "^1.4.3", "express": "^4.15.3", "express-session": "^1.15.3", "mongoose": "^4.10.3", "serve-favicon": "^2.4.3" } }
Листинг файла config.js
module.exports = { port: 49002, mongodb: { "main": "mongodb://127.0.0.1:27017/main" }, session: "aXVmN7y{Xw5|9zN%El2m" };
Листинг файла createDB.js
var mongoose = require('./lib/mongoose'); var async = require('async'); async.series([ open, dropDatabase, requireModels, createUsers, createCategory, createGoods ], function(err) { console.log(arguments); }); function open(callback) { mongoose.connection.on('open', callback); } function dropDatabase(callback) { var db = mongoose.connection.db; db.dropDatabase(callback); } function requireModels(callback) { require('./models/user'); require('./models/category'); require('./models/goods'); async.each(Object.keys(mongoose.models), function(modelName, callback) { mongoose.models[modelName].ensureIndexes(callback); }, callback); } function createUsers(callback) { var users = [ {username: 'Вася', password: 'supervasya'}, {username: 'Петя', password: '123'}, {username: 'admin', password: 'thetruehero'} ]; async.each(users, function(userData, callback) { var user = new mongoose.models.User(userData); user.save(callback); }, callback); } function createCategory(callback) { var categories = [ {id: 0, name: 'Товары для собак', img: 'dogs.jpg'}, {id: 1, name: 'Товары для котов', img: 'cats.jpg'} ]; async.each(categories, function(categoryData, callback) { var category = new mongoose.models.Category(categoryData); category.save(callback); }, callback); } function createGoods(callback) { var goods = [ {id: 0, category: 0, price: 10, name: 'Корм для собак Чаппи', img: 'dogs1.jpg'}, {id: 1, category: 0, price: 20, name: 'Корм для собак Trainer Natural Mini Adult', img: 'dogs2.jpg'}, {id: 2, category: 1, price: 30, name: 'Корм Brit Care Crazy для котят', img: 'cats1.jpg'}, {id: 3, category: 0, price: 40, name: 'Корм для собак Acana PACIFICA DOG', img: 'dogs3.jpg'}, {id: 4, category: 1, price: 50, name: 'Корм для кошек Gourmet Кусочки в соусе', img: 'cats2.jpg'}, {id: 5, category: 1, price: 60, name: 'Консервированный корм для кошек Friskies', img: 'cats3.jpg'}, ]; async.each(goods, function(goodsData, callback) { var good = new mongoose.models.Goods(goodsData); good.save(callback); }, callback); }Листинг файла error.js
var util = require('util'); var http = require('http'); // ошибки для выдачи посетителю function HttpError(status, message) { Error.apply(this, arguments); Error.captureStackTrace(this, HttpError); this.status = status; this.message = message || http.STATUS_CODES[status] || "Error"; } util.inherits(HttpError, Error); HttpError.prototype.name = 'HttpError'; exports.HttpError = HttpError;
Листинг файла index.js
'use strict'; const http = require('http'), express = require('express'), cookieParser = require('cookie-parser'), bodyParser = require('body-parser'), favicon = require('serve-favicon'), config = require('./config'), path = require('path'); var app = express(), port, server; app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.use(cookieParser()); app.use(bodyParser.urlencoded({limit: '<100mb>'})); app.use(require('./middleware/session')); app.use(require('./middleware/sendHttpError')); app.use(require('./middleware/loadUser')); port = config.port || 49001; app.set('port', port); server = http.createServer(app); server.on('error', serverError); server.on('listening', serverListening); require('./routes')(app); app.use(express.static(path.join(__dirname, 'public'))); server.listen(port); require('./createDB'); function serverError(error) { if (error.syscall !== 'listen') { throw error; } var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; if (error.code === 'EACCES') { console.error(bind + ' requires elevated privileges'); process.exit(1); } else if (error.code === 'EADDRINUSE') { console.error(bind + ' is already in use'); process.exit(1); } else { throw error; } } function serverListening() { var address = server.address(), bind = typeof address === 'string' ? 'pipe ' + address : 'port ' + address.port; console.log('Listening on ' + bind); }
Листинг файла routes.js
var path = require('path'), checkAuth = require('./middleware/checkAuth'); module.exports = function(app) { app.get('/', function(req, res) { res.sendFile(path.join(__dirname + '/public/template/index.html')); }); app.post('/register', require('./routes/register').post); app.post('/login', require('./routes/login').post); app.get('/login', checkAuth, require('./routes/login').get); app.post('/logout', require('./routes/logout').post); app.get('/categories', checkAuth, require('./routes/categories').get); app.post('/goods', checkAuth, require('./routes/goods').post); };
Листинг файла lib/mongoose.js
var mongoose = require('mongoose'); var config = require('../config'); mongoose.connect(config.mongodb.main); module.exports = mongoose;
Листинг файла lib/session_store.js
const session = require('express-session'); const MongoStore = require('connect-mongo')(session); module.exports = function (mongoose) { return new MongoStore({ mongooseConnection: mongoose.connection }) };
Листинг файла middleware/checkAuth.js
module.exports = function(req, res, next) { if (!req.session.user) { return res.status(401).send({ error: "Вы не авторизованы" }); } next(); };
Листинг файла middleware/loadUser.js
var User = require('../models/user').User; module.exports = function(req, res, next) { req.user = res.locals.user = null; if (!req.session.user) return next(); User.findById(req.session.user, function(err, user) { if (err) return next(err); req.user = res.locals.user = user; next(); }); };
Листинг файла middleware/sendHttpError.js
module.exports = function (req, res, next) { res.sendHttpError = function (error) { res.status(error.status); if (res.req.headers['x-requested-with'] == 'XMLHttpRequest') { res.json(error); } else { res.send(error.message); } }; next(); };
Листинг файла middleware/session.js
var session = require('express-session'), config = require('../config'), mongoose = require('../lib/mongoose'), sessionStore = require('../lib/session_store')(mongoose); module.exports = session({ secret: config.session, name: 'sid', resave: false, saveUninitialized: false, cookie: { maxAge: null }, store: sessionStore });
Листинг файла models/category.js
var util = require('util'); var mongoose = require('../lib/mongoose'), Schema = mongoose.Schema; var schema = new Schema({ id: { type: Number, required: true }, name: { type: String, required: true }, img: { type: String, required: true } }); exports.Category = mongoose.model('Category', schema);
Листинг файла models/goods.js
var util = require('util'); var mongoose = require('../lib/mongoose'), Schema = mongoose.Schema; var schema = new Schema({ id: { type: Number, required: true }, name: { type: String, required: true }, img: { type: String, required: true }, price: { type: Number, required: true }, category: { type: Number, required: true }, quantity: { type: Number, required: true, default: 0 } }); exports.Goods = mongoose.model('Goods', schema);
Листинг файла models/user.js
var crypto = require('crypto'); var async = require('async'); var util = require('util'); var mongoose = require('../lib/mongoose'), Schema = mongoose.Schema; var schema = new Schema({ username: { type: String, unique: true, required: true }, hashedPassword: { type: String, required: true }, salt: { type: String, required: true }, created: { type: Date, default: Date.now } }); schema.methods.encryptPassword = function (password) { return crypto.createHmac('sha1', this.salt).update(password).digest('hex'); }; schema.virtual('password') .set(function (password) { this._plainPassword = password; this.salt = Math.random() + ''; this.hashedPassword = this.encryptPassword(password); }) .get(function () { return this._plainPassword; }); schema.methods.checkPassword = function (password) { return this.encryptPassword(password) === this.hashedPassword; }; schema.statics.authorize = function (username, password, callback) { var User = this; async.waterfall([ function (callback) { User.findOne({username: username}, callback); }, function (user, callback) { if (user) { if (user.checkPassword(password)) { callback(null, user); } else { callback(new AuthError("Неправильный пароль")); } } else { callback(new AuthError("Пользователь с таким логином не зарегистрирован")); } } ], callback); }; schema.statics.register = function (username, password, repeat, callback) { var User = this; async.waterfall([ function (callback) { User.findOne({username: username}, callback); }, function (user, callback) { if (user) { callback(new AuthError("Такой пользователь уже зарегистрирован")); } else { if (password === repeat) { var user = new User({username: username, password: password}); user.save(function (err) { if (err) return callback(err); callback(null, user); }); } else { callback(new AuthError("Пароли не совпадают")); } } } ], callback); }; exports.User = mongoose.model('User', schema); function AuthError(message) { Error.apply(this, arguments); Error.captureStackTrace(this, AuthError); this.message = message; } util.inherits(AuthError, Error); AuthError.prototype.name = 'AuthError'; exports.AuthError = AuthError;Листинг файла public/app.js
'use strict'; angular .module('myApp', ['ui.router']) .config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) { $stateProvider.state('home', { url: '/home', templateUrl: 'template/home.html', pageTitle: 'Главная', params: {} }).state('chat', { url: '/chat', templateUrl: 'template/chat.html', pageTitle: 'Чат', params: {} }).state('login', { url: '/login', templateUrl: 'template/login.html', pageTitle: 'Вход', params: {} }).state('logout', { url: '/logout', pageTitle: 'Выход', params: {}, controller: function ($http, $state) { $http({method: 'POST', url: '/logout'}); $state.go('home'); window.location.reload(); } }).state('categories', { url: '/categories', templateUrl: 'template/categories.html', pageTitle: 'Каталог', params: {}, resolve:{ access: function($http){ return $http({method: 'GET', url: '/login'}).then(function (res) { return res; }, function (res) { return res; }); }, } }).state('goods', { url: '/goods', templateUrl: 'template/goods.html', pageTitle: 'Товары', params: { category: null }, resolve:{ access: function($http){ return $http({method: 'GET', url: '/login'}).then(function (res) { return res; }, function (res) { return res; }); }, } }).state('cart', { url: '/cart', templateUrl: 'template/cart.html', pageTitle: 'Корзина', params: { category: null }, resolve:{ access: function($http){ return $http({method: 'GET', url: '/login'}).then(function (res) { return res; }, function (res) { return res; }); }, } }).state('about', { url: '/about', templateUrl: 'template/about.html', pageTitle: 'О нас', params: {} }).state('shipping', { url: '/shipping', templateUrl: 'template/shipping.html', pageTitle: 'Доставка', params: {} }).state('profile', { url: '/profile', templateUrl: 'template/profile.html', pageTitle: 'Личный кабинет', params: {} }); $urlRouterProvider.otherwise('/home'); $stateProvider.state("otherwise", {url: '/otherwise'}); }]) .run(['$state', '$rootScope', '$stateParams', 'userService', '$http', function ($state, $rootScope, $stateParams, userService, $http) { $rootScope.$state = $state; $rootScope.$stateParams = $stateParams; $rootScope.$on("$includeContentLoaded", function () { $('body').scrollTop(0); }); $rootScope.$on('$stateChangeSuccess', function () { userService.navChange(); }); $http({ url: "/login", method: "GET" }).then(function (res) { userService.username = res.data.username; }, function (res) { userService.username = false; }); }]) .service('userService', function () { return { goods: null, username: null, order: {} }; }) .controller('navController', function ($state, userService, $http, $scope, $rootScope) { var vm = this; userService.navChange = function () { var tabs = { home: {name: 'Главная', url: 'home', active: false}, login: {name: 'Авторизация', url: 'login', active: false}, logout: {name: 'Выход', url: 'logout', active: false}, categories: {name: 'Каталог', url: 'categories', active: false}, cart: {name: 'Корзина', url: 'cart', active: false}, about: {name: 'О нас', url: 'about', active: false}, profile: {name: 'Личный кабинет', url: 'profile', active: false}, shipping: {name: 'Доставка', url: 'shipping', active: false} }; if (tabs[$state.current.name]) { tabs[$state.current.name].active = true; } else { tabs['categories'].active = true; } if (userService.username) { vm.tabs = [tabs.home, tabs.about, tabs.shipping, tabs.categories, tabs.cart, tabs.profile, tabs.logout]; } else { vm.tabs = [tabs.home, tabs.about, tabs.shipping, tabs.login]; } } }) .controller('homeController', function ($state, $scope, $rootScope) { var vm = this; }) .controller('aboutController', function ($state, $scope, $rootScope) { var vm = this; }) .controller('shippingController', function ($state, $scope, $rootScope) { var vm = this; }) .controller('profileController', function ($state, $scope, $rootScope) { var vm = this; }) .controller('loginController', function ($state, $http, userService, $scope, $rootScope) { var vm = this; vm.loginRegister = true; vm.registerForm = function () { vm.loginRegister = false; vm.error = false; }; vm.loginForm = function () { vm.loginRegister = true; vm.error = false; }; vm.register = function () { if (vm.password === vm.repeat) { $http({ url: "/register", method: "POST", headers: { "content-type": 'application/x-www-form-urlencoded' }, data: 'username=' + vm.username + '&password=' + vm.password + '&repeat=' + vm.repeat }).then(function (res) { userService.username = vm.username; userService.navChange(); $state.go('categories'); }, function (res) { if (res.status === 403) { vm.error = res.data.message; } else { $state.go('error'); } }); } else { vm.error = 'Введенные пароли не совпадают'; } }; vm.login = function () { $http({ url: "/login", method: "POST", headers: { "content-type": 'application/x-www-form-urlencoded' }, data: 'username=' + vm.username + '&password=' + vm.password }).then(function (res) { userService.username = vm.username; userService.navChange(); $state.go('categories'); }, function (res) { if (res.status === 403) { vm.error = res.data.message; } else { $state.go('error'); } }); } }) .controller('categoriesController', function ($state, $http, $scope, $rootScope) { var vm = this; $state.current.resolve.access($http).then(function(res){ if (res.status === 401) { vm.error = res.data.error; } }); $http({ url: "/categories", method: "GET" }).then(function (res) { vm.categories = res.data; }, function (res) { vm.error = res.data.error; }); vm.openCategory = function (id) { $state.go('goods', { category: id }) }; }) .controller('goodsController', function ($state, $http, $scope, $rootScopeУважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.