Browse Source

news模块实现

dygapp 6 years ago
parent
commit
f42a8a8cf3
4 changed files with 205 additions and 0 deletions
  1. 63 0
      app/controller/.news.js
  2. 16 0
      app/controller/news.js
  3. 39 0
      app/model/news.js
  4. 87 0
      app/service/news.js

+ 63 - 0
app/controller/.news.js

@@ -0,0 +1,63 @@
+module.exports = {
+  // 起草新闻
+  "create": {
+    "parameters": {
+      "query": ["!column"],
+    },
+    "requestBody": ["!title", "!content", "picurl", "top", "tags", "attachment", "issuer"],
+  },
+  // 修改新闻信息
+  "update": {
+    "parameters": {
+      "query": ["!id"],
+    },
+    "requestBody": ["title", "content", "picurl", "top", "tags", "attachment", "issuer"],
+  },
+  // 获取新闻详情
+  "fetch": {
+    "parameters": {
+      "query": ["!id"],
+    },
+  },
+  // 删除新闻
+  "delete": {
+    "parameters": {
+      "query": ["!id"],
+    },
+  },
+  // 后台查询新闻列表
+  "query": {
+    "parameters": {
+      "query": ["!column"],
+    },
+    "service": "query",
+    "options": {
+      "query": ["skip", "limit"],
+      "sort": ["meta.createdAt"],
+      "desc": true,
+      "count": true,
+      "projection": {
+        "attachment": 0
+      }
+    }
+  },
+  // 前台加载新闻列表
+  "list": {
+    "parameters": {
+      "query": ["!column"],
+      "options": {
+        "meta.state": 0, // 只显示未删除数据
+      },
+    },
+    "service": "query",
+    "options": {
+      "query": ["skip", "limit"],
+      "sort": ["top", "meta.createdAt"],
+      "desc": true,
+      "count": true,
+      "projection": {
+        "attachment": 0
+      }
+    }
+  },
+};

+ 16 - 0
app/controller/news.js

@@ -0,0 +1,16 @@
+'use strict';
+
+const _ = require('lodash');
+const meta = require('./.news.js');
+const Controller = require('egg').Controller;
+const { CrudController } = require('naf-framework-mongoose/lib/controller');
+
+class NewsController extends Controller {
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.news;
+  }
+
+}
+
+module.exports = CrudController(NewsController, meta);

+ 39 - 0
app/model/news.js

@@ -0,0 +1,39 @@
+/**
+ * 新闻信息
+ */
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose/lib/model/meta-plugin');
+
+// 附件信息
+const Attachment = new Schema({
+  name: { type: String, maxLength: 128 },
+  uri: { type: String, maxLength: 128 },
+}, { _id: false });
+
+// 新闻信息
+const SchemaDefine = {
+  column: { type: String, required: true, maxLength: 64 }, // 栏目
+  title: { type: String, required: true, maxLength: 128 }, // 标题
+  content: { type: String, required: true, maxLength: 102400, select: false }, // 内容详情
+  picurl: { type: String, required: false, maxLength: 256 }, // 标题图片URL
+  top: { type: Number, required: true, default: 0 }, // 置顶
+  tags: [{ type: String, maxLength: 64 }], // 标签
+  attachment: [ Attachment ], // 附件
+  issuer: String, // 发文单位
+  meta: {
+    createdBy: String, // 创建用户
+    updatedBy: String, // 修改用户
+  },
+  remark: { type: String, maxLength: 500 }, // 备注
+};
+const schema = new Schema(SchemaDefine, { 'multi-tenancy': true, toJSON: { virtuals: true } });
+schema.plugin(metaPlugin);
+schema.index({ column: 1 });
+schema.index({ 'meta.state': 1 });
+schema.index({ 'meta.createdAt': -1 });
+schema.index({ 'meta.createdAt': -1, top: -1, 'meta.state': 1 });
+module.exports = app => {
+  const { mongoose } = app;
+  return mongoose.model('NewsInfo', schema, 'cms_news');
+};

+ 87 - 0
app/service/news.js

@@ -0,0 +1,87 @@
+'use strict';
+
+const assert = require('assert');
+const _ = require('lodash');
+const { BusinessError, ErrorCode } = require('naf-core').Error;
+const { isNullOrUndefined, trimData } = require('naf-core').Util;
+const { CrudService } = require('naf-framework-mongoose/lib/service');
+
+class NewsService extends CrudService {
+  constructor(ctx) {
+    super(ctx);
+    this.model = this.ctx.model.News;
+  }
+
+  async create({ column }, { title, content, picurl, top, tags, attachment, issuer }) {
+    // 检查数据
+    assert(_.isString(column), 'column不能为空');
+    assert(_.isString(title), 'title不能为空');
+    assert(_.isString(content), 'content不能为空');
+    assert(!picurl || _.isString(picurl), 'picurl必须为字符串');
+    assert(_.isUndefined(top) || _.isNumber(top), 'top必须为数字');
+    assert(!tags || _.isArray(tags), 'tags必须为数组');
+    assert(!attachment || _.isArray(attachment), 'attachment必须为数组');
+    assert(!issuer || _.isString(issuer), 'issuer必须为字符串');
+
+    // TODO: 检查用户信息
+    const userid = this.ctx.userid;
+    if (!_.isString(userid)) throw new BusinessError(ErrorCode.NOT_LOGIN);
+
+    // TODO:保存数据
+    const data = {
+      column, title, content, picurl, top, tags, attachment, issuer,
+      meta: { createdBy: userid },
+    };
+
+    const res = await this.model.create(data);
+    return res;
+  }
+
+  async update({ id }, payload) {
+    // 检查数据
+    const { title, content, picurl, top, tags, attachment, issuer } = payload;
+    assert(id, 'id不能为空');
+    assert(!title || _.isString(title), 'title必须为字符串');
+    assert(!content || _.isString(content), 'content必须为字符串');
+    assert(!picurl || _.isString(picurl), 'picurl必须为字符串');
+    assert(_.isUndefined(top) || _.isNumber(top), 'top必须为数字');
+    assert(!tags || _.isArray(tags), 'tags必须为数组');
+    assert(!attachment || _.isArray(attachment), 'attachment必须为数组');
+    assert(!issuer || _.isString(issuer), 'issuer必须为字符串');
+
+    // TODO: 检查用户信息
+    const userid = this.ctx.userid;
+    if (!_.isString(userid)) throw new BusinessError(ErrorCode.NOT_LOGIN);
+
+    // TODO:检查数据是否存在
+    const doc = await this.model.findById(id).exec();
+    if (isNullOrUndefined(doc)) {
+      throw new BusinessError(ErrorCode.DATA_NOT_EXIST);
+    }
+
+    // TODO:保存数据
+    const data = trimData(payload);
+    const res = await this.model.findByIdAndUpdate(doc.id, { ...data, 'meta.updatedBy': userid }, { new: true }).exec();
+
+    return res;
+  }
+
+  async delete({ id }) {
+
+    // TODO: 检查数据状态
+    const doc = await this.model.findById(id).exec();
+    if (!doc) {
+      throw new BusinessError(ErrorCode.DATA_NOT_EXIST);
+    }
+
+    doc.meta.state = 1;
+    await doc.save();
+  }
+
+  async fetch({ id }) {
+    const doc = await this.model.findById(id, '+content').exec();
+    return doc;
+  }
+}
+
+module.exports = NewsService;