Các bước cấu hình

1. Cài đặt các gói cần thiết
#npm install --save ejs
#npm install --save bootstrap
#npm install --save jquery
#npm install --save popper

2. Tạo 1 thư mục views
- Folder: include : chưa cái file được xử dụng lại như : header, footer. nav
- 2 file: index.ejs, about.ejs
index.ejs
<!DOCTYPE html>
<html lang="en">
    <% include ('./include/head'%>
    <body>
        <% include ('./include/nav')  %>
        <div class="container">
            <div class="row">
            <h1>Home</h1>
            </div>
            <hr>
            <div class="row">
                <p style="height:300px;">Content Here...</p>
            </div>
        </div>
        <% include ('./include/scripts'%>
        <% include ('./include/footer'%>
    </body>
</html>
about.ejs
<!DOCTYPE html>
<html lang="en">
    <% include ('./include/head'%>
    <body>
        <% include ('./include/nav'%>
        <div class="container">
            <div class="row">
                <h1>About</h1>
            </div>
            <hr>
            <div class="row">
                <p style="height:300px;">Content Here...</p>
            </div>
        </div>
        <% include ('./include/scripts')  %>
        <% include ('./include/footer'%>
    </body>
</html>

Cầu hình app.js , do ở đây mình sử dụng chung để viết API nên sẽ cấu hình hơi khác.
const express = require('express')
const bodyParser = require('body-parser');
const path = require('path');
const app = express()

var port = process.env.HOST_PORT || 3300;
// Require static assets from public folder--------------------------- EJS
app.use(express.static(path.join(__dirname'public')));
// Set 'views' directory for any views 
// being rendered res.render()
app.set('views'path.join(__dirname'views'));
// Set view engine as EJS
app.engine('html'require('ejs').renderFile);
app.set('view engine''ejs');
//-------------------------------------------------------END EJS config
app.listen(port, () => {
    console.log("This port: " + port + " is running");
});

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var router = require('./routes')();
app.use('/'router);

//CORS Middleware
app.use(function (reqresnext) {
    //Enabling CORS 
    res.header("Access-Control-Allow-Origin""*");
    res.header("Access-Control-Allow-Methods""GET,HEAD,OPTIONS,POST,PUT");
    res.header("Access-Control-Allow-Headers""Origin, X-Requested-With, contentType,Content-Type, Accept, Authorization");
    next();
});

Tạo 1 file route.js
- Ở đây mình có require 2 file route, 1 cái của API , 1 cái của view. (API sẽ trình bày trong bày khác
const express = require('express'); 
function eRoutes() {
    const router = express.Router();
    var user = require('./routes/user.routes')(router);
    var view = require('./routes/view.routes')(router);
    return router;
}
module.exports = eRoutes;
Tạo 1 thư mục route, để chưa file route
Tạo 1 file view.route.js trong thư mục route

const express = require('express');
module.exports = function (router) {
    router.get('/', (reqres=> {
        console.log('Request for home recieved');
        res.render('index');
    });
    router.get('/about', (reqres=> {
        console.log('Request for about page recieved');
        res.render('about');
    });
    router.get('/contact', (reqres=> {
        console.log('Request for contact page recieved');
        res.render('contact');
    });
}

Xem kết quả nào:
Trang home

Trang About


 Để phục hồi mật khẩu đầu ghi HIK bị mất pass.

Bước 1: Đầu tiên các bạn phải tải phần mềm SADP về:

    Link download từ nhà cung cấp: Tại đây

    Link download từ GG Drive: 

    Sau khi tải về tiến hành cài đặt bình thường.

Bước 2: Export private key của đầu ghi

- Chú ý: Không được restart lại đầu ghi cho đến khi nhận được code recover pass của nhà cung cấp.

Chọn "Forgot Password" => Mode: Export/Import.... => Export như hình bên dưới.


Bước 4: Sau khi lưu file Key, bạn gửi mail yêu cầu phục hồi mật khẩu đến email: support@hikvision.com. 

Bước 5: Khoảng 30 phút team support cuare HIK sẽ gửi lại cho bạn code để phục hồi mật khẩu.
sau đó bạn làm theo hướng dẫn mà họ đính kèm.








  Bài viết hướng dẫn gửi thông báo vào group Telegram thông qua Bot API. các phần của bài viết

1. Tạo Bot Telegram

2. Tạo Group Telegram , ad bot và test gửi tin nhắn

3. Tạo API resfull với .net core và test bằng postman

I. TẠO BOT TRÊN TELEGRAM

Bước 1: Tìm BotFather tại ô tìm kiếm (Chú ý cái có tic xanh nhé)

Tìm BotFather

Bước 2: CLick "Start" để bắt đầu tạo Bot

Lệnh trên Bot

 - /newbot: Chọn tên cho Bot của bạn -> Chọn username cho Bot của bạn (Chú ý phải kết thúc bằng chữ "bot"
- Sau khi tạo xong Bot sẽ gửi cho bạn một Token, nhớ lưu lại để dùng gửi tin nhắn nhé.

Token mà bot gửi về


II. TẠO GROUP TELEGRAM - ADD BOT VÀ TEST
Bước 1: Tạo Group Telegram và add bot và group, chú ý coi chừng add nhằm bot nhé =))

Tạo group chat với Bot.


Bước 2 : Test thông báo 

 1. Lấy ID Bot và các group chat: https://api.telegram.org/bot<Token>/getUpdates 
(Chạy trên trình duyệt hoặc Postman đều đc nhé)
    
ID của Bot chat
ID của group chat

 2. Kiểm tra message trên Bot: https://api.telegram.org/bot<Token>/sendMessage?chat_id=<ID Chat>&text=<Message> (Chạy trên trình duyệt hoặc Postman đều đc nhé)
Thông báo trên bot

Thông báo trên group đã add bot


III. TẠO RESFUL API TRÊN .NET CORE 
  Bước 1: Tạo mới một project: API .Net Core



Bước 2: Tạo mới 1 Controller và test trên postman xem ok ko.
Bước 3: Tạo model chưa body Json và tạo 1 hàm post như bên dưới



Bước 4: test lại trên postman.




















 Have 2 ways validate form in angular.

First Way: Use FormBuilder

HTML file

 <form [formGroup]="angForm" novalidate>

<div class="form-group"> <label class="center-block">Name: <input class="form-control" formControlName="name"> </label> </div> <div *ngIf="angForm.controls['name'].invalid && (angForm.controls['name'].dirty || angForm.controls['name'].touched)" class="alert alert-danger"> <div *ngIf="angForm.controls['name'].errors.required"> Name is required. </div> </div> </form> <p>Form value: {{ angForm.value | json }}</p> <p>Form status: {{ angForm.status | json }}</p>

TS file

import { FormGroup, FormBuilder, Validators } from '@angular/forms';
@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'Angular Form Validation Tutorial'; angForm: FormGroup; constructor(private fb: FormBuilder) { this.createForm(); } createForm() { this.angForm = this.fb.group({ name: ['', Validators.required ] }); } }

Second Way: Use ngModel
Create model file class
    
export class ContactForm {
    constructor(
        public namestring,
        public emailstring,
        public subjectstring,
        public phone?: string,
        public content?: string
    ) { }
}

HTML File
<form (ngSubmit)="onSubmit()" #requestForm="ngForm" id="requestForm" name="requestForm">
    <div class="row">
        <div class="col-lg-6">
            <input class="form-control" type="text" name="name" value="" size="40" required minlength="2" appForbiddenName="admin"
            [(ngModel)]="model.name" #name="ngModel" #_name placeholder="(1) Họ tên *">
            
        </div>
        <div class="col-lg-6">
            <input class="form-control" type="email" name="email" #_email value="" size="40"
                aria-required="true" aria-invalid="false" placeholder="Email">
        </div>
        <div class="col-lg-6">
            <input class="form-control" type="text" name="subject" value="" size="40" required minlength="3" #_subject
                #subject="ngModel" [(ngModel)]="model.subject" aria-invalid="false" placeholder="(2) Tiêu đề *">
        </div>

        <div class="col-lg-6">
            <input class="form-control" type="text" name="phone" value="" size="40" required pattern="^\+?(?:[0-9]??).{5,14}[0-9]$" #_phone
                #phone="ngModel" [(ngModel)]="model.phone" aria-required="true" aria-invalid="false" placeholder="(3) Số điện thoại *">
        </div>
        <div class="col-xs-12">
            <textarea class="form-control" name="message" cols="40" rows="4" required #_message
            #message="ngModel" [(ngModel)]="model.content" aria-invalid="false" placeholder="(4) Nội dung bạn quan tâm *"></textarea>
        </div>
        <div class="col-xs-12">
            <input class="btn btn-primary" [disabled]="!requestForm.form.valid" type="submit" #submit_bt value="    Gửi    ">
        </div>
    </div>
</form>
<div>
    <p *ngIf="name.invalid && (name.dirty || name.touched)" class="alert alert-danger">
        <span *ngIf="name.errors.required">
            (1) Họ tên không được trống.
        </span>
        <span *ngIf="name.errors.minlength">
            (1) Tên ít nhất phải 2 ký tự.
        </span>
        <span *ngIf="name.errors.forbiddenName">
            (1) Tên bạn không thể là "admin".
        </span>
    </p>
    <p *ngIf="subject.invalid && (subject.dirty || subject.touched)" class="alert alert-danger">
        <span *ngIf="subject.errors.required">
            (2) Tiêu đề không được trống.
        </span>
        <span *ngIf="subject.errors.minlength">
            (2) Tiêu đề ít nhất phải 3 ký tự.
        </span>
    </p>
    <p *ngIf="phone.invalid && (phone.dirty || phone.touched)" class="alert alert-danger">
        <span *ngIf="phone.errors.required">
            (3) Số điện thoại không được trống.
        </span>
        <span *ngIf="phone.errors.pattern">
            (3) Điện thoại không đúng định dạng.
        </span>
    </p>
    <p *ngIf="message.invalid && (message.dirty || message.touched)" class="alert alert-danger">
        <span *ngIf="message.errors.required">
            (4) Nội dung không được trống.
        </span>
    </p>
</div>

TS File

import { Contact } from '../../Class/contact';
model = new Contact('','','','','');
  @ViewChild('_name', {static: true}) name: ElementRef;
  @ViewChild('_subject', {static: true}) subject: ElementRef;
  @ViewChild('_phone', {static: true}) phone: ElementRef;
  @ViewChild('_email', {static: true}) email:ElementRef;
  @ViewChild('_message', {static: true}) message: ElementRef;
  // @ViewChild('submit_bt',{static: true}) submit_bt: ElementRef;
  async onSubmit(){
    let _name = this.name.nativeElement.value;
    let _subject = this.subject.nativeElement.value;
    let _phone = this.phone.nativeElement.value;
    let _email = this.email.nativeElement.value;
    let _message = this.message.nativeElement.value;
    alert(_name + " - " + _subject + " - " + _phone + " - " + _email + " - " + _message)
  }

Không cần khai báo trong ts file, nhưng muốn lấy giá trị form cần dùng @ViewChild('Name',{static:true}) name:ElementRef;


 Trên các máy ảo Hyper-V không thể nhận trực tiếp ổ đĩa ngoài. Bạn có thể làm cách sau:

Bước 1: Vào manage từ Right-click My PC


Bước 2: Chuyển ổ đĩa cần map thành offline

Bước 3: Tắt máy ảo và thêm ổ cứng ngoài

Bước 4: Start lại máy ảo sẽ thấy nhé.








Mình giới thiệu với các bạn một phần mềm tháo gỡ các phần mềm đã cài đặt khá hay.


Tải phần mềm: Tại đây.
Sau khi giải nén , cài đặt bình thường. bên trong đã có file đăng ký

Đăng ký bằng name và code trong file key nhé.








Hôm nay mình sẽ chia sẽ một phần mềm dùng in mã vạch rất tiện lợi cho các bạn cần in tem để ban hàng online nha.

Bước 1: Bạn tải phần mềm Bartender phiên bản 9.4 về máy và giải nén ra

Tải phần mềm: tại đây
Giải nén phần mềm 


Bước 2: Nhấn chuột phải => chọn "Run as administrator"



Cài đặt với quyền administrator

Bước 3: Thực hiện các bước cài đặt bên dưới







Các bước cài đặt

Bước 4: Crack phần mềm bằng file patch => Copy vào thư mục cài đặt phần mềm (Program file)


CÁCH SỬ DỤNG
Bước 1: Mở trương trình lên


Bước 2: Chọn Blank Label Format


Bước 3: Chọn "Ring 408PEL+"


Bước 4: Chọn Specify Custom Setting


Bước 5: Chọn Singel Label => Finish