zoukankan      html  css  js  c++  java
  • 19 ~ express ~ 文章的增加 , 查看 ,修改 ,删除

    一,前台

    1,添加文章 /views/admin/content_add.html

    {% extends 'layout.html' %}
    {% block main %}
    <ol class="breadcrumb">
    <li><a href="/admin">管理首页</a></li>
    <li><span>添加分类</span></li>
    </ol>

    <h3>添加分类</h3>
    <form method="POST">
    <div class="form-group">
    <label for="category_name">分类名称</label>
    <input type="text" class="form-control" name="category_name" id="category_name" placeholder="Category Name">
    </div>

    <button type="submit" class="btn btn-default">Submit</button>
    </form>
     

    {% endblock %}
     
    2,查看文章  /views/admin/content.html
     
    {% extends 'layout.html' %}
    {% block main %}
    <ol class="breadcrumb">
    <li><a href="/admin/content">内容首页</a></li>
    <li><span>内容列表</span></li>
    </ol>

    <h3>内容列表</h3>

    <table class="table table-bordered">
    <tr>
    <th>ID</th>
    <th>标题</th>
    <th>分类</th>
    <th>简介</th>
    <th>作者</th>
    <th>添加时间</th>
    <th>阅读量</th>
    <th>操作</th>
    </tr>
    <!-- 循环输出数组 . id是对象,需要转换成字符串 -->
     
    {% for content in contents %}
    <tr>
    <td> {{content._id.toString()}}</td>
    <td> {{content.title}}</td>
     
    <!-- 关联的具体使用 -->
    <td> {{content.category.category_name}}</td>
     
    <td> {{content.description}}</td>
    <td> {{content.user.username}}</td>
    <td> {{content.addTime|date('Y-m-d h:i:s')}}</td>
    <td> {{content.views}}</td>
    <td>
    <!-- 【 错误的案例 : 忘记加路由 】 <a href="/content/edit?id={{content._id.toString()}}">修改</a> | -->
    <a href="/admin/content/edit?id={{content._id.toString()}}">修改</a> |
    <a href="/admin/content/delete?id={{content._id.toString()}}">删除</a>
    </td>
    {% endfor %}
    </tr>
    </table>


    <div class="btn-group" role="group" aria-label="...">
    <a href="/admin/content?page={{page-1}}" class="btn btn-default">上一页</a>
    <a href="/admin/content?page={{page+1}}" class="btn btn-default">下一页</a>
    <li>一共有 {{count}} 条数据</li>
    <li>每页显示 {{limit}} 条数据</li>
    <li>一共有 {{pages}} 页</li>
    <li>当前是在 {{page}} 页</li>
    </div>
    {% endblock %}

    3, 修改文章 /views/admin/content_edit.html

    {% extends 'layout.html' %}
    {% block main %}
    <ol class="breadcrumb">
    <li><a href="/admin">管理首页</a></li>
    <li><span>文章内容编辑</span></li>
    </ol>

    <h3>文章内容编辑 -- {{content.title}}</h3>

    <hr> <h4>调试</h4>
    {% for category in categories %}
    {{category._id.toString()}} , {{category.category_name}}
    {% endfor %}
    <hr>

    <form method="POST">
    <div class="form-group">
    <label for="category">分类</label>
    <select name="category" id="category" class="form-control">
    <!--
    var categories = []
     
    【 读取category表 】

    Content.find().populate('category').then((rs) => {
    categories = rs
    -->
    {% for category in categories %}
    {% if category._id==content.category._id%}
    <option value="{{category._id.toString()}}" selected>{{category.category_name}}</option>
    {% else %}
    <option value="{{category._id.toString()}}">{{category.category_name}}</option>
    {% endif %}
    {% endfor %}
    </select>
    </div>
    <div class="form-group">
    <label for="title">标题</label>
    <input type="text" class="form-control" value="{{content.title}}" name="title" id="title" placeholder="Title">
    </div>
    <!-- 自动截取简介 -->
    <div class="form-group">
    <label for="description">简介</label>
    <textarea class="form-control" name="description" id="description" cols="30" rows="3"
    placeholder="Description">{{content.description}}</textarea>
    </div>
    <div class="form-group">
    <label for="content">内容</label>
    <textarea class="form-control" name="content" id="content" placeholder="Content" cols="30" rows="6">{{content.content}}</textarea>
    </div>

    <button type="submit" class="btn btn-default">Submit</button>
    </form>

    {% endblock %}
     
    二,数据库
     
    1,定义文章表 /schemas/contents.js
     
    var mongoose = require('mongoose')

    /**
    * 创建表结构
    */
    module.exports =new mongoose.Schema({
     
    // 关联字段(object) ———— 与分类表的 _id , category_name 是一样的
    category:{
    // 类型
    type:mongoose.Schema.Types.ObjectId, //【 要指定ObjectId的类型,请在声明中使用Schema.Types.ObjectId。 】
     
    /** 引用 【 引用另一张表的原型 】 => 实现关联
    *
    * 1, Category 指的是 /models/Category模型
    * 2, 配合路由数据库查询的 populate('category'),
    * 3, populate('category') 中的category 表示 category字段
    * 4, 具体使用, 模板文件中 : {{content.category.category_name}}
    */
    ref:'Category' //
    },


    title:String,

    description:{
    type:String,
    default:''
    },
     
    content:{
    type:String,
    default:''
    },
     
    /**
    * 拓展 */

    /**
    * 关联字段 : 用户 ID
    *
    * 具体使用 : 在admin/content.add 路由的数据库保存字段中添加 user:req.userInfo._id.toString() 即可
    */
    user:{
    type:mongoose.Schema.Types.ObjectId,
    ref:'User'
    },

    /**
    * 添加时间
    *
    * 具体使用 :(自动生成)
    */
    addTime:{
    type:Date,
    default:new Date()
    },

    /**
    * 点击量(阅读量)
    *
    * 具体使用 :(自动生成)
    */
    views:{
    type:Number,
    default:0
    }

    })
     
    2,定义文章数据模型  /models/Content.js 
     
    var mongoose = require('mongoose')
    var contentSchema = require('../schemas/contents')

    /**
    * 创建模型
    */
    module.exports= mongoose.model('Content',contentSchema)
     
     
     
    三,后台路由和业务逻辑   /router/admin.js
     
    /**内容首页 */
    router.get('/content',(req,res)=>{
     
    var page = Number(req.query.page || 1) // 如果没有传值,默认为1
    var limit = 10
    var pages = 1

    Content.count().then((count)=>{

    // 计算总页数,向上取整数,去最大值
    pages = Math.ceil(count / limit)
     
    // 页数取值不能超过总页数的值
    page = Math.min(page,pages)
     
    // 取值不能小于1
    page = Math.max(page,1)

    var skip = (page-1)*limit

    // 排序 : sort({第一个参数表示根据什么排序 : 第二个参数只能是( 1 和 -1 : 1 表示升序 ,-1 表示降序 )})
    // _id 值包含了时间戳
    Content.find().sort({_id:-1}).limit(limit).skip(skip).populate(['category','user']).then((contents) => {
    // console.log(contents)
    res.render('admin/content',{
    userInfo: req.userInfo,
    contents:contents,
    page:page,
    pages:pages,
    count:count,
    limit:limit
    })
     
    })
    })
     
     
    })

    /**文章添加 */
    router.get('/content/add',(req,res)=>{
    /**读取分类内容 */
    Category.find().sort({_id:-1}).then(categories=>{
    res.render('admin/content_add',{
    userInfo:req.userInfo,
    categories:categories
    })
    })

    })

    /** 文章添加 */
    router.post('/content/add',(req,res)=>{
    /** 一,验证 */
    if(req.body.category==''){
    res.render('admin/error',{
    user:req.userInfo,
    message:'分类不能为空'
    })
    return Promise.reject()
    }
    if(req.body.title==''){
    res.render('admin/error',{
    user:req.userInfo,
    message:'标题不能为空'
    })
    return Promise.reject()
    }
    if(req.body.description==''){
    res.render('admin/error',{
    user:req.userInfo,
    message:'简介不能为空'
    })
    return Promise.reject()
    }
    if(req.body.content==''){
    res.render('admin/error',{
    user:req.userInfo,
    message:'内容不能为空'
    })
    return Promise.reject()
    }

    /** 二,保存 */

    /**1,错误的示例 */
    // Content.save().then(fs=>{
    // if(fs){
    // res.render('admin/success',{
    // user:req.userInfo,
    // message:'添加内容成功'
    // })
    // }
    // })

    new Content({
    content:req.body.content,
    title:req.body.title,
    category:req.body.category,
    description:req.body.description,
    user:req.userInfo._id.toString()
    }).save().then(fs=>{
    if(fs){
    res.render('admin/success',{
    user:req.userInfo,
    message:'添加内容成功',
    url:'/admin/content'
    })
    }
    })

    })

    /** 文章的修改 */
    router.get('/content/edit',(req,res)=>{

    var id = req.query.id || ''
    // console.log('id=>'+id)

    /**
    * 从外部获取 categories (1)
    */
    var categories = []

    // 读取category表
     
    /** ——————————————————————————————————————————————————————————————————————————【Bug】
    * Content.find().sort({_id:-1}).populate('category').then((rs) => {
    * —————————————————————————————————————————————————————————————————————————— 【Bug】
    * */
    Category.find().sort({_id:-1}).populate('category').then((rs) => {
     
    /**
    * 从外部获取 categories (2)
    */
    categories = rs
     

    return Content.findOne({
    _id:id
    }).populate('category')


    }).then(content=>{
    // console.log(('categories=>'+categories).yellow)
    if(!content){
    res.render('admin/error',{
    user:req.userInfo,
    message:'要修改的内容不存在',
    url:'/admin/content'
    })
    }else{
    res.render('admin/content_edit',{
    user:req.userInfo,
    content:content,
    categories:categories
    })
    }
    })
    })

    /**
    * 保存修改的文章
    */
    router.post('/content/edit',(req,res)=>{
    var id = req.query.id || ''
    console.log(('req.body.category=>'+req.body.description).yellow)
    if(req.body.category==''){
    res.render('admin/error',{
    user:req.userInfo,
    message:'分类不能为空'
    })
    return Promise.reject()
    }
    if(req.body.title==''){
    res.render('admin/error',{
    user:req.userInfo,
    message:'标题不能为空'
    })
    return Promise.reject()
    }
    Content.update({
    /**条件 */
    _id:id
    },{
    /**更新的内容 */
    content:req.body.content,
    title:req.body.title,
    category:req.body.category,
    description:req.body.description,
    }).then((fs)=>{
    if(fs){
    res.render('admin/success',{
    user:req.userInfo,
    message:'修改内容成功',
    url:'/admin/content'
    })
    }
    })
    })

    /**
    * 文章删除
    */
    router.get('/content/delete',(req,res)=>{
     
    //获取要删除分类的id
    var id = req.query.id || ''

    //直接删除
    Content.remove({
    _id:id
    }).then((rs)=>{
    if(rs){
    res.render('admin/success',{
    user:req.userInfo,
    message:'文章删除成功',
    url:'/admin/content'
    })
    }
    })
     
    })
  • 相关阅读:
    ABP框架系列之三十:(Javascript-API-Javascript-API)
    MES制造执行系统
    ABP框架系列之二十九:(Hangfire-Integration-延迟集成)
    2017年总结
    ABP框架系列之二十八:(Handling-Exceptions-异常处理)
    ABP框架系列之二十七:(Feature-Management-特征管理)
    ABP框架系列之二十六:(EventBus-Domain-Events-领域事件)
    ABP框架系列之二十五:(Embedded-Resource-Files-嵌入式资源文件)
    mac pro使用2K(2056*1440)设置屏幕解决方法
    DevOps 转型到底难不难(转自成哥的世界)
  • 原文地址:https://www.cnblogs.com/500m/p/11054505.html
Copyright © 2011-2022 走看看