Commit 4f7a21d8 authored by Kriengkrai Yothee's avatar Kriengkrai Yothee

เกือบเสร็จ

parent bc3ffdaa
Pipeline #1067 failed with stages
# communutyTOPIC
# topic1
for select topic1
.git/
dist/
examples/
node_modules/
# Editor configuration, see http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
max_line_length = off
trim_trailing_whitespace = false
NODE_ENV=development
SERVER_PORT=4040
JWT_SECRET=0a6b944d-d2fb-46fc-a85e-0295c986cd9f
MONGO_HOST=mongodb://localhost/odmp
MEAN_FRONTEND=angular
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/dist-server
/tmp
/out-tsc
# dependencies
/node_modules
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# e2e
/e2e/*.js
/e2e/*.map
# System Files
.DS_Store
Thumbs.db
# Env file
#*.env
FROM node:lts-buster
WORKDIR /usr/src/app
ADD . /usr/src/app
RUN yarn
RUN yarn build
EXPOSE 4040
CMD ["yarn", "serve"]
## Welcome to the mean stack
The mean stack is intended to provide a simple and fun starting point for cloud native fullstack javascript applications.
MEAN is a set of Open Source components that together, provide an end-to-end framework for building dynamic web applications; starting from the top (code running in the browser) to the bottom (database). The stack is made up of:
- **M**ongoDB : Document database – used by your back-end application to store its data as JSON (JavaScript Object Notation) documents
- **E**xpress (sometimes referred to as Express.js): Back-end web application framework running on top of Node.js
- **A**ngular (formerly Angular.js): Front-end web app framework; runs your JavaScript code in the user's browser, allowing your application UI to be dynamic
- **N**ode.js : JavaScript runtime environment – lets you implement your application back-end in JavaScript
### Pre-requisites
* git - [Installation guide](https://www.linode.com/docs/development/version-control/how-to-install-git-on-linux-mac-and-windows/) .
* node.js - [Download page](https://nodejs.org/en/download/) .
* npm - comes with node or download yarn - [Download page](https://yarnpkg.com/lang/en/docs/install) .
* mongodb - [Download page](https://www.mongodb.com/download-center/community) .
### Installation
```
git clone https://github.com/linnovate/mean
cd mean
cp .env.example .env
yarn
yarn start (for development)
```
### Docker based
```
git clone https://github.com/linnovate/mean
cd mean
cp .env.example .env
docker-compose up -d
```
### Credits
- The MEAN name was coined by Valeri Karpov.
- Initial concept and development was done by Amos Haviv and sponsered by Linnovate.
- Inspired by the great work of Madhusudhan Srinivasa.
# การเพิ่ม model ชื่อ Student ใน project
## 1. เพิ่มไฟล์ `server/models/student.model.js`
```js
const mongoose = require('mongoose');
/**
* อ่านเพิ่มเติม https://mongoosejs.com/docs/guide.html
*/
const StudentSchema = new mongoose.Schema(
{
sid: { type: String, required: true },
first: { type: String, required: true },
last: { type: String, required: true },
createdAt: { type: Date, default: Date.now },
},
{
versionKey: false
}
);
module.exports = mongoose.model('Student', StudentSchema);
```
## 2. เพิ่มไฟล์ `server/controllers/student.controller.js`
```js
const Joi = require('joi');
const Student = require('../models/student.model');
const studentSchema = Joi.object({
sid: Joi.number().integer().required(),
first: Joi.string().required(),
last: Joi.string().required()
})
module.exports = {
insert,
get,
getAll,
search,
}
async function insert(student) {
student = await Joi.validate(student, studentSchema, { abortEarly: false });
return await new Student(student).save();
}
/**
* อ่านเพิ่มเติม https://mongoosejs.com/docs/api.html
*/
async function get(sid) {
return await Student.find({sid: sid});
}
async function getAll() {
return await Student.find();
}
async function search(key, value) {
let query = {};
query[key] = value;
return await Student.find(query);
}
```
## 3. เพิ่มไฟล์ `server/routes/student.route.js`
```js
const express = require('express');
const asyncHandler = require('express-async-handler');
const studentCtrl = require('../controllers/student.controller');
const router = express.Router();
module.exports = router;
//router.use(passport.authenticate('jwt', { session: false }))
router.route('/').post(asyncHandler(insert));
router.route('/get/:sid(\d+)').get(asyncHandler(get));
router.route('/all').get(asyncHandler(getAll));
router.route('/search').get(asyncHandler(search));
async function insert(req, res) {
let student = await studentCtrl.insert(req.body);
res.json(student);
}
async function get(req, res) {
let all_students = await studentCtrl.get(req.params['sid']);
res.json(all_students);
}
async function getAll(req, res) {
let all_students = await studentCtrl.getAll();
res.json(all_students);
}
async function search(req, res) {
let result = await studentCtrl.search(req.params['key'], req.params['value']);
res.json(result);
}
```
## 4. เพิ่มเส้นทางการเรียกในไฟล์ `server/routes/index.route.js`
```js
const express = require('express');
const userRoutes = require('./user.route');
const studentRoutes = require('./student.route');
const authRoutes = require('./auth.route');
const router = express.Router(); // eslint-disable-line new-cap
/** GET /health-check - Check service health */
router.get('/health-check', (req, res) =>
res.send('OK')
);
router.use('/auth', authRoutes);
router.use('/user', userRoutes);
router.use('/student', studentRoutes);
module.exports = router;
```
## 5. ตัวอย่างสคริปเพื่อกำหนดข้อมูลเบื้องต้น `scripts/init-students.js`
```js
const mongoose = require('mongoose');
const util = require('util');
const debug = require('debug')('express-mongoose-es6-rest-api:index');
const config = require('../server/config/config');
const Student = require('../server/models/student.model');
// connect to mongo db
const mongoUri = config.mongo.host;
mongoose.connect(mongoUri, { keepAlive: 1 });
mongoose.connection.on('error', () => {
throw new Error(`unable to connect to database: ${mongoUri}`);
});
const students = [
{ sid: 60112233440, first: 'ชูใจ', last: 'เลิศล้ำ' },
{ sid: 60112233441, first: 'มานี', last: 'รักเผ่าไทย' },
{ sid: 60112233442, first: 'ปิติ', last: 'พิทักษ์ถิ่น' },
{ sid: 60112233443, first: 'มานะ', last: 'รักเผ่าไทย' },
{ sid: 60112233444, first: 'วีระ', last: 'ประสงค์สุข' }
];
Student.insertMany(students, (error, docs) => {
if (error) {
console.error(error);
} else {
console.log(docs);
}
mongoose.connection.close();
});
```
## 6. เรียกใช้ `scripts/init-students.js`
```sh
node scripts/init-students.js
```
## 7. เรียกดูข้อมูลได้จาก `http://localhost:4000/api/student/all`
theme: jekyll-theme-minimal
logo: https://www.linnovate.net/sites/all/themes/linnovate/images/mean-picture.png
<!DOCTYPE html>
<html lang="{{ site.lang | default: "en-US" }}">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% seo %}
<link rel="stylesheet" href="{{ "/assets/css/style.css?v=" | append: site.github.build_revision | relative_url }}">
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
<![endif]-->
</head>
<body>
<div class="wrapper">
<header>
{% if site.logo %}
<img class="logo" src="{{site.logo | relative_url}}" alt="Logo" />
{% endif %}
<p>{{ site.description | default: site.github.project_tagline }}</p>
{% if site.github.is_project_page %}
<p class="view"><a href="{{ site.github.repository_url }}">View the Project on GitHub <small>{{ site.github.repository_nwo }}</small></a></p>
{% endif %}
<!-- Place this tag where you want the button to render. -->
<a class="github-button" href="https://github.com/linnovate/mean" data-show-count="true" aria-label="Star ntkme/github-buttons on GitHub">Star</a>
{% if site.github.is_user_page %}
<p class="view"><a href="{{ site.github.owner_url }}">View My GitHub Profile</a></p>
{% endif %}
{% if site.show_downloads %}
<ul class="downloads">
<li><a href="{{ site.github.zip_url }}">Download <strong>ZIP File</strong></a></li>
<li><a href="{{ site.github.tar_url }}">Download <strong>TAR Ball</strong></a></li>
<li><a href="{{ site.github.repository_url }}">View On <strong>GitHub</strong></a></li>
</ul>
{% endif %}
<img class="ninja" src="/assets/img/ninja.jpg"/>
</header>
<section>
{{ content }}
{% if site.github.is_project_page %}
<p>This project is maintained by <a href="{{ site.github.owner_url }}">{{ site.github.owner_name }}</a></p>
{% endif %}
</section>
</div>
<script src="{{ "/assets/js/scale.fix.js" | relative_url }}"></script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-36499287-4"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
// gtag('config', 'UA-XXXXXX-XX'); // change this to your own UA config
</script>
<!-- Place this tag in your head or just before your close body tag. -->
<script async defer src="https://buttons.github.io/buttons.js"></script>
</body>
</html>
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"mean": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"tsConfig": "./tsconfig.app.json",
"polyfills": "src/polyfills.ts",
"assets": [
"src/assets",
"src/favicon.ico"
],
"styles": [
"src/styles.scss"
],
"scripts": []
},
"configurations": {
"production": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "mean:build"
},
"configurations": {
"production": {
"browserTarget": "mean:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "mean:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"karmaConfig": "./karma.conf.js",
"polyfills": "src/polyfills.ts",
"tsConfig": "./tsconfig.spec.json",
"scripts": [],
"styles": [
"src/styles.scss"
],
"assets": [
"src/assets",
"src/favicon.ico"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"./tsconfig.app.json",
"./tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "mean",
"schematics": {
"@schematics/angular:component": {
"prefix": "app",
"styleext": "scss"
},
"@schematics/angular:directive": {
"prefix": "app"
}
},
"cli": {
"analytics": "c4b1fc92-ebd6-4fa9-a8a1-067afbef23d9"
}
}
\ No newline at end of file
---
---
@import "{{ site.theme }}";
h1 {
a {
color:#00758f;
text-size:40px;
}
}
header {
img.logo {
margin-left:30px;
display:block;
height: auto;
width: auto;
max-width: 150px;
max-height: 200px;
margin-bottom: 17%;
}
img.ninja {
margin-top: 20px;
height: auto;
width: auto;
max-width: 350px;
max-height: 200px;
margin-bottom: 50px;
}
}
> 0.5%
last 2 versions
Firefox ESR
not dead
not IE 9-11
version: '3'
services:
app:
build: ./
image: mean
container_name: mean
ports:
- 80:4040
expose:
- 4040
environment:
NODE_ENV: production
SERVER_PORT: 4040
JWT_SECRET: 0a6b944d-d2fb-46fc-a85e-0295c986cd9f
MONGO_HOST: mongodb://mongo/odmp
restart: always
depends_on:
- mongo
meanexpress:
container_name: meanexpress
image: mongo-express
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_AUTH_DATABASE: odmp
#ME_CONFIG_MONGODB_AUTH_USERNAME: admin
#ME_CONFIG_MONGODB_AUTH_PASSWORD: pass
restart: always
depends_on:
- mongo
mongo:
container_name: meanmongo
image: mongo:3.6
ports:
- 27017:27017
expose:
- 27017
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
client:{
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true
},
angularCli: {
environment: 'dev'
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};
{
"name": "mean",
"version": "2.0.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"yarn": {
"version": "1.22.10",
"resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.10.tgz",
"integrity": "sha512-IanQGI9RRPAN87VGTF7zs2uxkSyQSrSPsju0COgbsKQOOXr5LtcVPeyXWgwVa0ywG3d8dg6kSYKGBuYK021qeA=="
}
}
}
{
"name": "mean",
"version": "2.0.2",
"license": "MIT",
"scripts": {
"ng": "ng",
"serve": "node server",
"import student": "node scripts/init-students.js",
"start": "concurrently -c \"yellow.bold,green.bold\" -n \"SERVER,BUILD\" \"nodemon server\" \"ng build --watch\"",
"build": "ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points"
},
"private": true,
"dependencies": {
"@angular/animations": "^9.1.4",
"@angular/cdk": "^9.2.1",
"@angular/common": "^9.1.4",
"@angular/compiler": "^9.1.4",
"@angular/core": "^9.1.4",
"@angular/forms": "^9.1.4",
"@angular/material": "^9.2.1",
"@angular/platform-browser": "^9.1.4",
"@angular/platform-browser-dynamic": "^9.1.4",
"@angular/router": "^9.1.4",
"bcrypt": "^3.0.2",
"body-parser": "^1.18.2",
"compression": "^1.7.2",