一段學習的結束 我也不知道我這是在寫些什麼,只是覺得學完了一些東西,就是想把它記錄 一下,這樣我就可以知道我是學過這一塊的,要多激勵自己,^_^O(∩_∩)O哈哈~ 以下內容並不完全與標題匹配,不過以下內容綜合了前面幾篇的應用,並增加了 部分東西 js帶碼要和html代碼一起看 ...
一段學習的結束
我也不知道我這是在寫些什麼,只是覺得學完了一些東西,就是想把它記錄
一下,這樣我就可以知道我是學過這一塊的,要多激勵自己,^^O(∩∩)O哈哈~
以下內容並不完全與標題匹配,不過以下內容綜合了前面幾篇的應用,並增加了
部分東西
js帶碼要和html代碼一起看
import express from 'express'
import Advert from '../models/advert'
import formidable from 'formidable'
import config from '../config'
import { basename } from 'path'
// 創建一個路由容器,將所有的路由中間件掛載給路由容器
const router = express.Router()
router.get('/advert', (req, res, next) => {
const page = Number.parseInt(req.query.page, 10)
const pageSize = 5
Advert
.find()
.skip((page - 1) * pageSize)
.limit(pageSize)
.exec((err, adverts) => {
if (err) {
return next(err)
}
Advert.count((err, count) => {
if (err) {
return next(err)
}
const totalPage = Math.ceil(count / pageSize) // 總頁碼 = 總記錄數 / 每頁顯示大小
res.render('advert_list.html', {
adverts,
totalPage,
page
})
})
})
})
router.get('/advert/add', (req, res, next) => {
res.render('advert_add.html')
})
/**
* POST /advert/add
* body: { title, image, link, start_time, end_time }
*/
router.post('/advert/add', (req, res, next) => {
const form = new formidable.IncomingForm()
form.uploadDir = config.uploadDir // 配置 formidable 文件上傳接收路徑
form.keepExtensions = true // 配置保持文件原始的擴展名
form.parse(req, (err, fields, files) => {
if (err) {
return next(err)
}
const body = fields // 普通表單欄位
body.image = basename(files.image.path) // 這裡解析提取上傳的文件名,保存到資料庫
const advert = new Advert({
title: body.title,
image: body.image,
link: body.link,
start_time: body.start_time,
end_time: body.end_time,
})
advert.save((err, result) => {
if (err) {
return next(err)
}
res.json({
err_code: 0
})
})
})
})
router.get('/advert/list', (req, res, next) => {
Advert.find((err, docs) => {
if (err) {
return next(err)
}
res.json({
err_code: 0,
result: docs
})
})
})
// /advert/one/:advertId 是一個模糊匹配路徑
// 可以匹配 /advert/one/* 的路徑形式
// 例如:/advert/one/1 /advert/one/2 /advert/one/a /advert/one/abc 等路徑
// 但是 /advert/one 或者 /advert/one/a/b 是不行的
// 至於 advertId 是自己起的一個名字,可以在處理函數中通過 req.params 來進行獲取
router.get('/advert/one/:advertId', (req, res, next) => {
Advert.findById(req.params.advertId, (err, result) => {
if (err) {
return next(err)
}
res.json({
err_code: 0,
result: result
})
})
})
// /advert/edit
router.post('/advert/edit', (req, res, next) => {
Advert.findById(req.body.id, (err, advert) => {
if (err) {
return next(err)
}
const body = req.body
advert.title = body.title
advert.image = body.image
advert.link = body.link
advert.start_time = body.start_time
advert.end_time = body.end_time
advert.last_modified = Date.now()
// 這裡的 save 因為內部有一個 _id 所以這裡是不會新增數據的,而是更新已有的數據
advert.save((err, result) => {
if (err) {
return next(err)
}
res.json({
err_code: 0
})
})
})
})
router.get('/advert/remove/:advertId', (req, res, next) => {
Advert.remove({ _id: req.params.advertId }, err => {
if (err) {
return next(err)
}
res.json({
err_code: 0
})
})
})
export default router
{% extends "layout.html" %} {% block body %}
<div class="container-fluid">
<div class="body advert">
<!-- 麵包屑 -->
<ol class="breadcrumb">
<li><a href="javascript:;">廣告管理</a></li>
<li class="active">添加廣告</li>
</ol>
<div class="advert-add">
<form action="/advert/add" method="post" class="form-horizontal" enctype="multipart/form-data">
<div class="form-group">
<label for="" class="col-md-3 control-label">標題</label>
<div class="col-md-5">
<input type="text" required class="form-control input-sm" name="title" placeholder="填寫廣告標題">
</div>
</div>
<div class="form-group">
<label for="" class="col-md-3 control-label">圖片</label>
<div class="col-md-5">
<input type="file" required id="file" class="form-control input-sm" name="image" placeholder="填寫廣告圖片">
</div>
</div>
<div class="form-group">
<label for="" class="col-md-3 control-label">鏈接</label>
<div class="col-md-5">
<input type="text" required class="form-control input-sm" name="link" placeholder="填寫廣告鏈接">
</div>
</div>
<div class="form-group">
<label for="" class="col-md-3 control-label">開始時間</label>
<div class="col-md-5">
<input type="text" required class="form-control input-sm" name="start_time" placeholder="填寫開始時間">
</div>
</div>
<div class="form-group">
<label for="" class="col-md-3 control-label">結束時間</label>
<div class="col-md-5">
<input type="text" required class="form-control input-sm" name="end_time" placeholder="填寫結束時間">
</div>
</div>
<div class="form-group">
<div class="col-md-8">
<input type="submit" class="btn btn-success btn-sm pull-right" value="保存">
</div>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
{% block script %}
<script>
// XMLHTTPRequest 1
// XMLHTTPRequest 2
$('form').on('submit', function (e) {
// var formData = new FormData()
// formData.append('name', 'Jack')
// formData.append('age', '18')
// formData.append('file', document.getElementById('file').files[0])
// var xhr = new XMLHttpRequest()
// xhr.open('post', '/advert/add')
// xhr.send(formData)
// return false
$.ajax({
url: $(this).attr('action'),
type: $(this).attr('method'),
data: new FormData($(this)[0]),
// 當你的 data 選項被提交為一個 FormData 對象的時候,一定要將 processData 配置為 false
// 否則 jQuery 的非同步提交不生效
processData: false, // tell jQuery not to process the data
// 當提交一個 FormData 對象的時候,記得要將 contentType 設置為 false
// 否則 jQuery 會預設把 Content-Type 設置為 application/x-www-form-urlencoded; charset=UTF-8
contentType: false, // tell jQuery not to set contentType
success: function (data) {
if (data.err_code === 0) {
window.location.href = '/advert'
}
}
})
return false
})
</script>
{% endblock %}
{% extends "layout.html" %}
{% block body %}
<div class="container-fluid">
<div class="body advert">
<!-- 麵包屑 -->
<ol class="breadcrumb">
<li><a href="javascript:;">廣告管理</a></li>
<li class="active">廣告列表</li>
</ol>
<div class="page-title">
<a href="/advert/add" class="btn btn-success btn-sm pull-right">添加廣告</a>
</div>
<div class="panel panel-default">
<div class="panel-body">
<form action="" class="form-inline">
<select name="" class="form-control input-sm">
<option value="">按年齡</option>
</select>
<select name="" class="form-control input-sm">
<option value="">按性別</option>
</select>
<select name="" class="form-control input-sm">
<option value="">按地區</option>
</select>
<select name="" class="form-control input-sm">
<option value="">按日期</option>
</select>
<button class="btn btn-success btn-sm">篩選</button>
</form>
</div>
<table class="table table-bordered">
<thead>
<tr>
<td>序號</td>
<th>標題</th>
<th>圖片</th>
<th>鏈接</th>
<th>開始時間</th>
<th>結束時間</th>
<th>點擊次數</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for item in adverts %}
<tr>
<td>0</td>
<td>{{ item.title }}</td>
<td>
<img src="/public/uploads/{{ item.image }}" style="width: 100px;" alt="">
</td>
<td>{{ item.link }}</td>
<td>{{ item.start_time }}</td>
<td>{{ item.end_time }}</td>
<td>1</td>
<td>
<a href="javascript:;" class="btn btn-info btn-xs">編輯</a>
<a href="javascript:;" class="btn btn-danger btn-xs">刪除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- 分頁 -->
<ul class="pagination pull-right">
<li><a href="/advert?page={{ page - 1 }}">上一頁</a></li>
{% for i in range(0, totalPage) -%}
{% if (i + 1) === page %}
<li class="active"><a href="/advert?page={{ i + 1 }}">{{ i + 1 }}</a></li>
{% else %}
<li><a href="/advert?page={{ i + 1 }}">{{ i + 1 }}</a></li>
{% endif %}
{%- endfor %}
<li><a href="/advert?page={{ page + 1 }}">下一頁</a></li>
</ul>
</div>
</div>
{% endblock %} {% block script %} {% endblock %}