Explorar o código

新改栏目,菜单,新闻,新加模块,信息列表

nihao %!s(int64=5) %!d(string=hai) anos
pai
achega
0d32796cb8

+ 3 - 3
app/controller/.column.js

@@ -4,14 +4,14 @@ module.exports = {
     "parameters": {
       "query": ["!site"],
     },
-    "requestBody": ["!moudle", "!columnname", "picurl", "description", "inMenu", "showModes", "isAudit", "attachment", "issuer"],
+    "requestBody": ["title", "type", "parent_id", "parent", "is_use"],
   },
   // 修改栏目
   "update": {
     "parameters": {
       "params": ["!id"],
     },
-    "requestBody": ["moudle", "columnname", "picurl", "description", "inMenu", "showModes", "isAudit", "attachment", "issuer"],
+    "requestBody": ["title", "type", "parent_id", "parent", "is_use"],
     // "options": {
     //   "projection": "+name",
     // },
@@ -40,7 +40,7 @@ module.exports = {
   // 后台查询栏目列表
   "query": {
     "parameters": {
-      "query": ["!site"],
+      "query": ["!site", "parent_id"],
       "options": {
         "meta.state": 0, // 只显示未删除数据
       },

+ 3 - 3
app/controller/.menu.js

@@ -4,14 +4,14 @@ module.exports = {
     "parameters": {
       "query": ["!site"],
     },
-    "requestBody": ["parent_id", "level", "parent_name", "path", "position",  "name", "picurl", "description", "isShow", "issuer"],
+    "requestBody": ["title", "type", "is_use"],
   },
   // 修改菜单
   "update": {
     "parameters": {
       "params": ["!id"],
     },
-    "requestBody": ["parent_id", "level", "parent_name", "path", "position","name", "picurl", "description", "isShow", "issuer"],
+    "requestBody": ["title", "type","is_use"],
     // "options": {
     //   "projection": "+name",
     // },
@@ -40,7 +40,7 @@ module.exports = {
   // 后台查询菜单列表
   "query": {
     "parameters": {
-      "query": ["!site", "level"],
+      "query": ["!site"],
       "options": {
         "meta.state": 0, // 只显示未删除数据
         // "sort": ["position"],

+ 78 - 0
app/controller/.modules.js

@@ -0,0 +1,78 @@
+module.exports = {
+  // 添加模块
+  "create": {
+    "parameters": {
+      "query": ["!site"],
+    },
+    "requestBody": ["title", "type", "is_use","category"],
+  },
+  // 修改模块
+  "update": {
+    "parameters": {
+      "params": ["!id"],
+    },
+    "requestBody": ["title", "type", "is_use", "category"],
+    // "options": {
+    //   "projection": "+name",
+    // },
+  },
+  // 获取模块详情
+  "fetch": {
+    "parameters": {
+      "params": ["!id"],
+    },
+    // "options": {
+    //   "projection": "+content",
+    // },
+  },
+  // 删除模块
+  "delete": {
+    "parameters": {
+      "params": ["!id"],
+    },
+  },
+  // 恢复模块
+  "restore": {
+    "parameters": {
+      "params": ["!id"],
+    },
+  },
+  // 后台查询模块列表
+  "query": {
+    "parameters": {
+      "query": ["!site"],
+      "options": {
+        "meta.state": 0, // 只显示未删除数据
+      },
+    },
+    "service": "query",
+    "options": {
+      "query": ["skip", "limit"],
+      "sort": ["meta.createdAt"],
+      "desc": true,
+      "count": true,
+      "projection": {
+        "attachment": 0
+      }
+    }
+  },
+  // 前台加载模块列表
+  "list": {
+    "parameters": {
+      "query": ["!site"],
+      "options": {
+        "meta.state": 0, // 只显示未删除数据
+      },
+    },
+    "service": "query",
+    "options": {
+      "query": ["skip", "limit"],
+      "sort": ["meta.createdAt"],
+      "desc": true,
+      "count": true,
+      "projection": {
+        "attachment": 0
+      }
+    }
+  },
+};

+ 6 - 6
app/controller/.news.js

@@ -2,16 +2,16 @@ module.exports = {
   // 起草新闻
   "create": {
     "parameters": {
-      "query": ["!column", "site"],
+      "query": ["!site"],
     },
-    "requestBody": ["!title", "!content", "picurl", "top", "tags", "attachment", "issuer"],
+    "requestBody": ["title", "pic", "content", "type", "parent_id", "parent", "attachment", "is_use"],
   },
   // 修改新闻信息
   "update": {
     "parameters": {
       "params": ["!id"],
     },
-    "requestBody": ["title", "content", "picurl", "top", "tags", "attachment", "issuer"],
+    "requestBody": ["title", "pic", "content", "type", "parent_id", "parent","attachment", "is_use"],
     "options": {
       "projection": "+content",
     },
@@ -34,13 +34,13 @@ module.exports = {
   // 恢复新闻
   "restore": {
     "parameters": {
-      "query": ["!id"],
+      "params": ["!id"],
     },
   },
   // 后台查询新闻列表
   "query": {
     "parameters": {
-      "query": ["column","site"],
+      "query": ["site","parent_id"],
       "options": {
         "meta.state": 0, // 只显示未删除数据
       },
@@ -59,7 +59,7 @@ module.exports = {
   // 前台加载新闻列表
   "list": {
     "parameters": {
-      "query": ["column", "site"],
+      "query": ["parent_id", "site"],
       "options": {
         "meta.state": 0, // 只显示未删除数据
       },

+ 78 - 0
app/controller/.newslist.js

@@ -0,0 +1,78 @@
+module.exports = {
+  // 添加信息列表
+  "create": {
+    "parameters": {
+      "query": ["!site"],
+    },
+    "requestBody": ["title", "type", "is_use"],
+  },
+  // 修改信息列表
+  "update": {
+    "parameters": {
+      "params": ["!id"],
+    },
+    "requestBody": ["title", "type", "is_use"],
+    // "options": {
+    //   "projection": "+name",
+    // },
+  },
+  // 获取信息列表详情
+  "fetch": {
+    "parameters": {
+      "params": ["!id"],
+    },
+    // "options": {
+    //   "projection": "+content",
+    // },
+  },
+  // 删除信息列表
+  "delete": {
+    "parameters": {
+      "params": ["!id"],
+    },
+  },
+  // 恢复信息列表
+  "restore": {
+    "parameters": {
+      "params": ["!id"],
+    },
+  },
+  // 后台查询信息列表
+  "query": {
+    "parameters": {
+      "query": ["!site"],
+      "options": {
+        "meta.state": 0, // 只显示未删除数据
+      },
+    },
+    "service": "query",
+    "options": {
+      "query": ["skip", "limit"],
+      "sort": ["meta.createdAt"],
+      "desc": true,
+      "count": true,
+      "projection": {
+        "attachment": 0
+      }
+    }
+  },
+  // 前台加载信息列表
+  "list": {
+    "parameters": {
+      "query": ["!site"],
+      "options": {
+        "meta.state": 0, // 只显示未删除数据
+      },
+    },
+    "service": "query",
+    "options": {
+      "query": ["skip", "limit"],
+      "sort": ["meta.createdAt"],
+      "desc": true,
+      "count": true,
+      "projection": {
+        "attachment": 0
+      }
+    }
+  },
+};

+ 16 - 0
app/controller/modules.js

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

+ 16 - 0
app/controller/newslist.js

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

+ 3 - 0
app/controller/verify.js

@@ -53,6 +53,9 @@ class VerifyController extends Controller {
       ctx.body = { errcode: 1, errmsg: 'error', data: [] };
     }
   }
+  async creeper() {
+    await this.service.tool.creeper();
+  }
 }
 
 module.exports = VerifyController;

+ 21 - 14
app/model/column.js

@@ -6,28 +6,35 @@ 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 Attachment = new Schema({
+//   name: { type: String, maxLength: 128 },
+//   uri: { type: String, maxLength: 128 },
+// }, { _id: false });
 
 // 栏目信息
 const SchemaDefine = {
+  // site: { type: String, required: true, maxLength: 64 }, // 归属站点
+  // moudle: { type: String, required: true, maxLength: 20 }, // 栏目模块
+  // columnname: { type: String, required: false, maxLength: 100 }, // 栏目名称
+  // picurl: { type: String, required: false, maxLength: 256 }, // 栏目图片URL
+  // description: { type: String, required: false, maxLength: 256 }, // 栏目描述
+  // inMenu: { type: String, required: false, maxLength: 5 }, // 是否在菜单中显示
+  // showModes: { type: String, required: false, maxLength: 5 }, // 展现方式
+  // isAudit: { type: String, required: false, maxLength: 5 }, // 是否需要审核
+  // attachment: [ Attachment ], // 附件
+  // issuer: String, // 栏目单位
   site: { type: String, required: true, maxLength: 64 }, // 归属站点
-  moudle: { type: String, required: true, maxLength: 20 }, // 栏目模块
-  columnname: { type: String, required: false, maxLength: 100 }, // 栏目名称
-  picurl: { type: String, required: false, maxLength: 256 }, // 栏目图片URL
-  description: { type: String, required: false, maxLength: 256 }, // 栏目描述
-  inMenu: { type: String, required: false, maxLength: 5 }, // 是否在菜单中显示
-  showModes: { type: String, required: false, maxLength: 5 }, // 展现方式
-  isAudit: { type: String, required: false, maxLength: 5 }, // 是否需要审核
-  attachment: [ Attachment ], // 附件
-  issuer: String, // 栏目单位
+  title: { type: String, required: false, maxLength: 100 }, // 栏目名称
+  type: { type: String, required: false, maxLength: 5 }, // 所属类型
+  parent_id: { type: String, required: false, maxLength: 64 }, // 所属id
+  parent: { type: String, required: false, maxLength: 100 }, // 所属名称
+  is_use: { type: String, required: false, maxLength: 5 }, // 是否使用,0=>使用中;1=>已禁止
+
   meta: {
     createdBy: String, // 创建用户
     updatedBy: String, // 修改用户
   },
-  remark: { type: String, maxLength: 500 }, // 备注
+  // remark: { type: String, maxLength: 500 }, // 备注
 };
 const schema = new Schema(SchemaDefine, { 'multi-tenancy': true, toJSON: { virtuals: true } });
 schema.plugin(metaPlugin);

+ 4 - 12
app/model/menu.js

@@ -14,22 +14,14 @@ const metaPlugin = require('naf-framework-mongoose/lib/model/meta-plugin');
 // 栏目信息
 const SchemaDefine = {
   site: { type: String, required: true, maxLength: 64 }, // 归属站点
-  parent_id: { type: String, required: false, maxLength: 64 }, // 父级ID
-  parent_name: { type: String, required: false, maxLength: 64 }, // 父级名称
-  level: { type: String, required: false, maxLength: 5 }, // 层级
-  path: { type: String, required: false, maxLength: 500 }, // 路径
-  position: { type: Number, required: false, maxLength: 5 }, // 位置
-  name: { type: String, required: false, maxLength: 100 }, // 菜单名称
-  picurl: { type: String, required: false, maxLength: 256 }, // 栏目图片URL
-  description: { type: String, required: false, maxLength: 256 }, // 栏目描述
-  isShow: { type: String, required: false, maxLength: 5 }, // 是否需要审核
-  // attachment: [ Attachment ], // 附件
-  issuer: String, // 栏目单位
+  title: { type: String, required: false, maxLength: 100 }, // 菜单名称
+  type: { type: String, required: false, maxLength: 5 }, // :类型,'content'=>信息内容类型/'column'=>'栏目',
+  is_use: { type: String, required: false, maxLength: 5 }, // 是否使用,0=>使用中;1=>已禁止
   meta: {
     createdBy: String, // 创建用户
     updatedBy: String, // 修改用户
   },
-  remark: { type: String, maxLength: 500 }, // 备注
+  // remark: { type: String, maxLength: 500 }, // 备注
 };
 const schema = new Schema(SchemaDefine, { 'multi-tenancy': true, toJSON: { virtuals: true } });
 schema.plugin(metaPlugin);

+ 30 - 0
app/model/modules.js

@@ -0,0 +1,30 @@
+/**
+ * 模块信息
+ */
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose/lib/model/meta-plugin');
+
+
+// 模块信息
+const SchemaDefine = {
+  site: { type: String, required: true, maxLength: 64 }, // 归属站点
+  title: { type: String, required: false, maxLength: 100 }, // 模块名称
+  type: { type: String, required: false, maxLength: 5 }, // 类型,'content'=>信息内容类型/'list'=>'信息列表'类型,
+  is_use: { type: String, required: false, maxLength: 5 }, // 是否使用,0=>使用中;1=>已禁止
+  category: { type: String, required: false, maxLength: 5 }, // 类别
+  meta: {
+    createdBy: String, // 创建用户
+    updatedBy: String, // 修改用户
+  },
+};
+const schema = new Schema(SchemaDefine, { 'multi-tenancy': true, toJSON: { virtuals: true } });
+schema.plugin(metaPlugin);
+schema.index({ site: 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('ModulesInfo', schema, 'cms_modules');
+};

+ 9 - 9
app/model/news.js

@@ -13,24 +13,24 @@ const Attachment = new Schema({
 
 // 新闻信息
 const SchemaDefine = {
-  column: { type: String, required: true, maxLength: 64 }, // 栏目
   site: { 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 }], // 标签
+  title: { type: String, required: false, maxLength: 128 }, // 标题
+  pic: { type: String, required: false, maxLength: 256 }, // 标题图片URL
+  content: { type: String, required: false, maxLength: 102400, select: false }, // 内容详情
+  type: { type: String, required: false, maxLength: 5 }, // 所属类型
+  parent_id: { type: String, required: false, maxLength: 64 }, // 所属id
+  parent: { type: String, required: false, maxLength: 100 }, // 所属名称
   attachment: [ Attachment ], // 附件
-  issuer: String, // 发文单位
+  is_use: { type: String, required: false, maxLength: 5 }, // 是否使用,0=>使用中;1=>已禁止
   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({ site: 1 });
 schema.index({ 'meta.state': 1 });
 schema.index({ 'meta.createdAt': -1 });
 schema.index({ 'meta.createdAt': -1, top: -1, 'meta.state': 1 });

+ 30 - 0
app/model/newslist.js

@@ -0,0 +1,30 @@
+/**
+ * 信息列表管理
+ */
+'use strict';
+const Schema = require('mongoose').Schema;
+const metaPlugin = require('naf-framework-mongoose/lib/model/meta-plugin');
+
+
+// 模块信息
+const SchemaDefine = {
+  site: { type: String, required: true, maxLength: 64 }, // 归属站点
+  title: { type: String, required: false, maxLength: 100 }, // 信息列表名称
+  type: { type: String, required: false, maxLength: 5 }, // 类型,'content'=>信息内容类型/'list'=>'信息列表'类型,
+  is_use: { type: String, required: false, maxLength: 5 }, // 是否使用,0=>使用中;1=>已禁止
+
+  meta: {
+    createdBy: String, // 创建用户
+    updatedBy: String, // 修改用户
+  },
+};
+const schema = new Schema(SchemaDefine, { 'multi-tenancy': true, toJSON: { virtuals: true } });
+schema.plugin(metaPlugin);
+schema.index({ site: 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('NewslistInfo', schema, 'cms_newslist');
+};

+ 25 - 0
app/router.js

@@ -18,6 +18,11 @@ module.exports = app => {
   router.get('/api/menu/list', controller.menu.list); // 菜单列表,隐藏删除信息,按照置顶和时间排序
   router.get('/api/menu/fetch/:id', controller.menu.fetch); // 获取菜单详情
 
+  router.get('/api/modules/list', controller.modules.list); // 模块列表,隐藏删除信息,按照置顶和时间排序
+  router.get('/api/modules/fetch/:id', controller.modules.fetch); // 获取模块详情
+
+  router.get('/api/newslist/list', controller.newslist.list); // 新闻信息列表,隐藏删除信息,按照置顶和时间排序
+  router.get('/api/newslist/fetch/:id', controller.newslist.fetch); // 获取新闻信息详情
   // 管理接口
   // 【分站】新闻接口
   router.get('/adminapi/news/query', controller.news.query); // 查询新闻信息
@@ -45,6 +50,24 @@ module.exports = app => {
   router.post('/adminapi/menu/delete/:id', controller.menu.delete); // 删除菜单信息
   router.post('/adminapi/menu/restore/:id', controller.menu.restore); // 恢复菜单信息
 
+  // 菜单列表接口
+  // 【分站】菜单列表接口
+  router.get('/adminapi/newslist/query', controller.newslist.query); // 查询菜单列表信息
+  router.get('/adminapi/newslist/fetch/:id', controller.newslist.fetch); // 获得菜单列表详情
+  router.post('/adminapi/newslist/create', controller.newslist.create); // 发布菜单列表信息
+  router.post('/adminapi/newslist/update/:id', controller.newslist.update); // 修改菜单列表信息
+  router.post('/adminapi/newslist/delete/:id', controller.newslist.delete); // 删除菜单列表信息
+  router.post('/adminapi/newslist/restore/:id', controller.newslist.restore); // 恢复菜单列表信息
+
+  // 模块接口
+  // 【分站】模块接口
+  router.get('/adminapi/modules/query', controller.modules.query); // 查询模块信息
+  router.get('/adminapi/modules/fetch/:id', controller.modules.fetch); // 获得模块详情
+  router.post('/adminapi/modules/create', controller.modules.create); // 发布模块信息
+  router.post('/adminapi/modules/update/:id', controller.modules.update); // 修改模块信息
+  router.post('/adminapi/modules/delete/:id', controller.modules.delete); // 删除模块信息
+  router.post('/adminapi/modules/restore/:id', controller.modules.restore); // 恢复模块信息
+
   // 分站配置接口,用于分站管理员配置本分站信息
   router.get('/adminapi/site/config', controller.site.config_fetch); // 分站获取自身配置
   router.post('/adminapi/site/config', controller.site.config_set); // 分站配置自身
@@ -61,4 +84,6 @@ module.exports = app => {
   router.get('/adminapi/verify/sendmessage', controller.verify.sendmessage); // 发送手机验证码并保存
   router.post('/adminapi/verify/check_message', controller.verify.check_message); // 检测手机验证码
 
+
+  router.get('/adminapi/verify/creeper', controller.verify.creeper); // 测试爬虫
 };

+ 13 - 20
app/service/column.js

@@ -12,17 +12,14 @@ class ColumnService extends CrudService {
     this.model = this.ctx.model.Column;
   }
 
-  async create({ site }, { moudle, columnname, picurl, description, inMenu, showModes, isAudit, issuer }) {
+  async create({ site }, { title, type, parent_id, parent, is_use }) {
     // 检查数据
     assert(_.isString(site), 'site不能为空');
-    assert(_.isString(moudle), 'moudle不能为空');
-    assert(_.isString(columnname), 'columnname不能为空');
-    assert(!picurl || _.isString(picurl), 'picurl必须为字符串');
-    assert(!description || _.isString(description), 'description必须为字符串');
-    assert(!inMenu || _.isString(inMenu), 'inMenu必须为字符串');
-    assert(!showModes || _.isString(showModes), 'showModes必须为字符串');
-    assert(!isAudit || _.isString(isAudit), 'isAudit必须为字符串');
-    assert(!issuer || _.isString(issuer), 'issuer必须为字符串');
+    assert(!title || _.isString(title), 'title必须为字符串');
+    assert(!type || _.isString(type), 'type必须为字符串');
+    assert(!parent_id || _.isString(parent_id), 'parent_id必须为字符串');
+    assert(!parent || _.isString(parent), 'parent必须为字符串');
+    assert(!is_use || _.isString(is_use), 'is_use必须为字符串');
 
     // TODO: 检查用户信息
     const userid = this.ctx.userid;
@@ -30,7 +27,7 @@ class ColumnService extends CrudService {
 
     // TODO:保存数据
     const data = {
-      site, moudle, columnname, picurl, description, inMenu, showModes, isAudit, issuer,
+      site, title, type, parent_id, parent, is_use,
       meta: { createdBy: userid },
     };
     
@@ -40,17 +37,13 @@ class ColumnService extends CrudService {
 
   async update({ id }, payload) {
     // 检查数据
-    const { moudle, columnname, picurl, description, inMenu, showModes, isAudit, issuer } = payload;
+    const { title, type, parent_id, parent, is_use } = payload;
     assert(id, 'id不能为空');
-    // assert(_.isString(site), 'site不能为空');
-    assert(_.isString(moudle), 'moudle不能为空');
-    assert(_.isString(columnname), 'columnname不能为空');
-    assert(!picurl || _.isString(picurl), 'picurl必须为字符串');
-    assert(!description || _.isString(description), 'description必须为字符串');
-    assert(!inMenu || _.isString(inMenu), 'inMenu必须为字符串');
-    assert(!showModes || _.isString(showModes), 'showModes必须为字符串');
-    assert(!isAudit || _.isString(isAudit), 'isAudit必须为字符串');
-    assert(!issuer || _.isString(issuer), 'issuer必须为字符串');
+    assert(!title || _.isString(title), 'title必须为字符串');
+    assert(!type || _.isString(type), 'type必须为字符串');
+    assert(!parent_id || _.isString(parent_id), 'parent_id必须为字符串');
+    assert(!parent || _.isString(parent), 'parent必须为字符串');
+    assert(!is_use || _.isString(is_use), 'is_use必须为字符串');
 
     // TODO: 检查用户信息
     const userid = this.ctx.userid;

+ 9 - 24
app/service/menu.js

@@ -12,19 +12,12 @@ class MenuService extends CrudService {
     this.model = this.ctx.model.Menu;
   }
 
-  async create({ site }, { parent_id, level, parent_name, position,path,name, picurl, description, isShow,  issuer }) {
+  async create({ site }, { title, type, is_use}) {
     // 检查数据
     assert(_.isString(site), 'site不能为空');
-    assert(!level || _.isString(level), 'level不能为空');
-    assert(!path || _.isString(path), 'path不能为空');
-    assert(!position || _.isNumber(position), 'position不能为空');
-    assert(!parent_id || _.isString(parent_id), 'parent_id不能为空');
-    assert(!parent_name || _.isString(parent_name), 'parent_name不能为空');
-    assert(!name || _.isString(name), 'name不能为空');
-    assert(!picurl || _.isString(picurl), 'picurl必须为字符串');
-    assert(!description || _.isString(description), 'description必须为字符串');
-    assert(!isShow || _.isString(isShow), 'isShow必须为字符串');
-    assert(!issuer || _.isString(issuer), 'issuer必须为字符串');
+    assert(!title || _.isString(title), 'title必须为字符串');
+    assert(!type || _.isString(type), 'type必须为字符串');
+    assert(!is_use || _.isString(is_use), 'is_use必须为字符串');
 
     // TODO: 检查用户信息
     const userid = this.ctx.userid;
@@ -32,7 +25,7 @@ class MenuService extends CrudService {
 
     // TODO:保存数据
     const data = {
-      site, parent_id, parent_name, level, position,path,name, picurl, description, isShow, issuer,
+      site, title, type, is_use,
       meta: { createdBy: userid },
     };
 
@@ -42,19 +35,11 @@ class MenuService extends CrudService {
 
   async update({ id }, payload) {
     // 检查数据
-    const { parent_id, level, parent_name, position,path,name, picurl, description, isShow, issuer } = payload;
+    const { title, type, is_use } = payload;
     assert(id, 'id不能为空');
-    assert(!parent_id || _.isString(parent_id), 'parent_id不能为空');
-    assert(!level || _.isString(level), 'level不能为空');
-    assert(!position || _.isNumber(position), 'position不能为空');
-    assert(!path || _.isString(path), 'path不能为空');
-    assert(!parent_name || _.isString(parent_name), 'parent_name不能为空');
-    assert(!name || _.isString(name), 'name不能为空');
-    assert(!picurl || _.isString(picurl), 'picurl必须为字符串');
-    assert(!description || _.isString(description), 'description必须为字符串');
-    assert(!isShow || _.isString(isShow), 'isShow必须为字符串');
-    assert(!issuer || _.isString(issuer), 'issuer必须为字符串');
-
+    assert(!title || _.isString(title), 'title必须为字符串');
+    assert(!type || _.isString(type), 'type必须为字符串');
+    assert(!is_use || _.isString(is_use), 'is_use必须为字符串');
     // TODO: 检查用户信息
     const userid = this.ctx.userid;
     if (!_.isString(userid)) throw new BusinessError(ErrorCode.NOT_LOGIN);

+ 82 - 0
app/service/modules.js

@@ -0,0 +1,82 @@
+'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 ModulesService extends CrudService {
+  constructor(ctx) {
+    super(ctx);
+    this.model = this.ctx.model.Modules;
+  }
+
+  async create({ site }, { title, type, is_use, category }) {
+    // 检查数据
+    assert(_.isString(site), 'site不能为空');
+    assert(!title || _.isString(title), 'title必须为字符串');
+    assert(!type || _.isString(type), 'type必须为字符串');
+    assert(!is_use || _.isString(is_use), 'is_use必须为字符串');
+    assert(!category || _.isString(category), 'category必须为字符串');
+    // TODO: 检查用户信息
+    const userid = this.ctx.userid;
+    if (!_.isString(userid)) throw new BusinessError(ErrorCode.NOT_LOGIN);
+
+    // TODO:保存数据
+    const data = {
+      site, title, type, is_use, category,
+      meta: { createdBy: userid },
+    };
+    
+    const res = await this.model.create(data);
+    return res;
+  }
+
+  async update({ id }, payload) {
+    // 检查数据
+    const { title, type, is_use, category} = payload;
+    assert(id, 'id不能为空');
+    assert(!title || _.isString(title), 'title必须为字符串');
+    assert(!type || _.isString(type), 'type必须为字符串');
+    assert(!is_use || _.isString(is_use), 'is_use必须为字符串');
+    assert(!category || _.isString(category), 'category必须为字符串');
+    // 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);
+    await this.model.findByIdAndUpdate(doc.id, { ...data, 'meta.updatedBy': userid }, { new: true }).exec();
+    const res = this.model.findById(id, '+modulesname').exec();
+    return res;
+  }
+
+  async status({ id, state }) {
+
+    // TODO: 检查数据状态
+    const doc = await this.model.findById(id).exec();
+    if (!doc) {
+      throw new BusinessError(ErrorCode.DATA_NOT_EXIST);
+    }
+
+    doc.meta.state = state;
+    return await doc.save();
+  }
+
+  async delete({ id }) {
+    return await this.status({ id, state: 1 });
+  }
+
+  async restore({ id }) {
+    return await this.status({ id, state: 0 });
+  }
+}
+
+module.exports = ModulesService;

+ 14 - 14
app/service/news.js

@@ -12,17 +12,17 @@ class NewsService extends CrudService {
     this.model = this.ctx.model.News;
   }
 
-  async create({ column, site }, { title,  content, picurl, top, tags, attachment, issuer }) {
+  async create({ site }, { title, pic, content, type, parent_id, parent, attachment, is_use }) {
     // 检查数据
-    assert(_.isString(column), 'column不能为空');
     assert(_.isString(site), 'site不能为空');
     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(!pic || _.isString(pic), 'pic必须为字符串');
+    assert(!content || _.isString(content), 'content必须为字符串');
+    assert(!type || _.isString(type), 'type必须为字符串');
+    assert(!parent_id || _.isString(parent_id), 'parent_id必须为字符串');
+    assert(!parent || _.isString(parent), 'parent必须为字符串');
     assert(!attachment || _.isArray(attachment), 'attachment必须为数组');
-    assert(!issuer || _.isString(issuer), 'issuer必须为字符串');
+    assert(!is_use || _.isString(is_use), 'is_use必须为字符串');
 
     // TODO: 检查用户信息
     const userid = this.ctx.userid;
@@ -30,7 +30,7 @@ class NewsService extends CrudService {
 
     // TODO:保存数据
     const data = {
-      site,column, title, content, picurl, top, tags, attachment, issuer,
+      site, title, pic, content, type, parent_id, parent, attachment, is_use,
       meta: { createdBy: userid },
     };
 
@@ -40,16 +40,16 @@ class NewsService extends CrudService {
 
   async update({ id }, payload) {
     // 检查数据
-    const { title, content, picurl, top, tags, attachment, issuer } = payload;
+    const { title, pic, content, type, parent_id, parent, attachment, is_use } = payload;
     assert(id, 'id不能为空');
     assert(!title || _.isString(title), 'title必须为字符串');
-    // assert(_.isString(site), 'site不能为空');
+    assert(!pic || _.isString(pic), 'pic必须为字符串');
     assert(!content || _.isString(content), 'content必须为字符串');
-    assert(!picurl || _.isString(picurl), 'picurl必须为字符串');
-    assert(_.isUndefined(top) || _.isNumber(top), 'top必须为数字');
-    assert(!tags || _.isArray(tags), 'tags必须为数组');
+    assert(!type || _.isString(type), 'type必须为字符串');
+    assert(!parent_id || _.isString(parent_id), 'parent_id必须为字符串');
+    assert(!parent || _.isString(parent), 'parent必须为字符串');
     assert(!attachment || _.isArray(attachment), 'attachment必须为数组');
-    assert(!issuer || _.isString(issuer), 'issuer必须为字符串');
+    assert(!is_use || _.isString(is_use), 'is_use必须为字符串');
 
     // TODO: 检查用户信息
     const userid = this.ctx.userid;

+ 82 - 0
app/service/newslist.js

@@ -0,0 +1,82 @@
+'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 NewslistService extends CrudService {
+  constructor(ctx) {
+    super(ctx);
+    this.model = this.ctx.model.Newslist;
+  }
+
+  async create({ site }, { title, type, is_use }) {
+    // 检查数据
+    assert(_.isString(site), 'site不能为空');
+    assert(!title || _.isString(title), 'title必须为字符串');
+    assert(!type || _.isString(type), 'type必须为字符串');
+    assert(!is_use || _.isString(is_use), 'is_use必须为字符串');
+
+    // TODO: 检查用户信息
+    const userid = this.ctx.userid;
+    if (!_.isString(userid)) throw new BusinessError(ErrorCode.NOT_LOGIN);
+
+    // TODO:保存数据
+    const data = {
+      site, title, type, is_use,
+      meta: { createdBy: userid },
+    };
+    
+    const res = await this.model.create(data);
+    return res;
+  }
+
+  async update({ id }, payload) {
+    // 检查数据
+    const { title, type, is_use } = payload;
+    assert(id, 'id不能为空');
+    assert(!title || _.isString(title), 'title必须为字符串');
+    assert(!type || _.isString(type), 'type必须为字符串');
+    assert(!is_use || _.isString(is_use), 'is_use必须为字符串');
+
+    // 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);
+    await this.model.findByIdAndUpdate(doc.id, { ...data, 'meta.updatedBy': userid }, { new: true }).exec();
+    const res = this.model.findById(id, '+newslistname').exec();
+    return res;
+  }
+
+  async status({ id, state }) {
+
+    // TODO: 检查数据状态
+    const doc = await this.model.findById(id).exec();
+    if (!doc) {
+      throw new BusinessError(ErrorCode.DATA_NOT_EXIST);
+    }
+
+    doc.meta.state = state;
+    return await doc.save();
+  }
+
+  async delete({ id }) {
+    return await this.status({ id, state: 1 });
+  }
+
+  async restore({ id }) {
+    return await this.status({ id, state: 0 });
+  }
+}
+
+module.exports = NewslistService;

+ 29 - 87
app/service/tool.js

@@ -3,7 +3,9 @@ const Service = require('egg').Service;
 const svgCaptcha = require('svg-captcha');
 // const cheerio = require('cheerio');
 // const puppeteer = require('puppeteer');
-
+const request = require('superagent');
+const cheerio = require('cheerio');
+const fs = require('fs');
 class ToolsService extends Service {
 
   // 产生验证码
@@ -30,93 +32,33 @@ class ToolsService extends Service {
     });
     return result;
   }
-
-  async spider(ctx, app) {
-    const url = 'http://job.ccut.edu.cn/module/getindustry?start_page=1&k=&type_id=300025&count=15&start=1&_=1564563909055';
-    const result = await app.curl(url, {
-      method: 'GET',
-      dataType: 'json',
+  // 输入路径返回文本
+  async creeper() {
+    // 目标链接 吉林省人事考试网第一页
+    const targetUrl = 'http://www.jlzkb.com/cms/root/ksbmList.vm?dir=L-iAg-ivleaKpeWQjS_kuovkuJrljZXkvY3mi5vogZjogIPor5U&page=1&rows=8';
+    // 用来暂时保存解析到的内容和图片地址数据
+    const content = '';
+    // const imgs = [];
+    // 发起请求
+    request.get(targetUrl).end((error, res) => {
+      if (error) { // 请求出错,打印错误,返回
+        console.log(error);
+        return;
+      }
+      // cheerio需要先load html
+      const $ = cheerio.load(res.text);
+      // 循环列表,获取标题、a标签路径、日期,然后根据a标签路径再次进行爬出内容、保存即可
+      $('#DivInfoList tr').each((index, element) => {
+        // const title = $(element).find('td a').attr('title');
+        // console.log(title);
+        // const uri = $(element).find('td a').attr('href');
+        // console.log(uri);
+        // const time = $(element).find('td[width="12%"]').text();
+        // console.log(time);
+      });
+      // 点击下一页
+      console.log($('#DivPageControl').find('a').attr('href'));
     });
-    // const dataarray = result.data.data;
-    // for(let i = 0;i < dataarray.length; i++){
-    //   const dataInfo = dataarray[i];
-    //   const info_id = dataInfo.info_id;
-    //   const path = 'http://job.ccut.edu.cn/detail/industry?menu_id=&type_id=300025&id=' + info_id;
-    //   const res = await app.curl(path, {
-    //     method: 'GET',
-    //     dataType: 'json',
-    //   });
-    //   console.log(result.data);
-    //   const data = JSON.parse(response.data);
-    //   console.log(data);
-    //   // console.log(info_id);
-    //   // const browser = await puppeteer.launch({
-    //   //   headless: true, // 使用无头浏览器抓取
-    //   // });
-    //   // const page = await browser.newPage();
-    //   // // 设置客户端
-    //   // await page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36');
-    //   // await page.goto('http://job.ccut.edu.cn/detail/industry?menu_id=&type_id=300025&id='+info_id, {
-    //   //   waitUntil: [ 'domcontentloaded' ],
-    //   // });
-    //   // await page.screenshot({ path: 'static.png' });
-    //   // const data = await page.evaluate(() => {
-    //   //   var storage = {};
-    //   //   // 单页爬取
-    //   //   var $div = $('#data_details');
-    //   //   storage = {
-    //   //     title: $div.find('.dh-tit').html(),
-    //   //     time: $div.find('.dh-info').html(),
-    //   //     content: $div.find('.details-content').html(),
-    //   //   };
-    //   //   return storage;
-    //   // });
-    //   //console.log(resultInfo.data.data);
-    // }
-    return result.data.data;
-    // console.log(result.data.toString('utf8',0,result.data.length));
-
-    // const data = JSON.parse(result.data);
-    // eslint-disable-next-line no-undef
-    // const $ = cheerio.load(result);
-    // const resultStr = [];
-    // $('#DivInfoList').find('table').find('tr').each(function(index,ele) {
-    //   console.log(111);
-    //   var obj = {};
-    //   obj.jobName = $(this).find('td').find('a').text();
-    //   //obj.salary = $(this).find('.red').text();
-    //   resultStr.push(obj);
-    // });
-    // const browser = await puppeteer.launch({
-    //   headless: true, // 使用无头浏览器抓取
-    // });
-    // const page = await browser.newPage();
-    // // 设置客户端
-    // await page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36');
-    // await page.goto('http://job.ccut.edu.cn/module/getindustry?start_page=1&k=&type_id=300025&count=15&start=1&_=1564563909055', {
-    //   waitUntil: [ 'domcontentloaded' ],
-    // });
-    // await page.screenshot({ path: 'static.png' });
-    // const data = await page.evaluate(() => {
-    //   var storage = [];
-    //   // 单页爬取
-    //   var $table = $('#DivInfoList table tbody');
-    //   if ($table.length) {
-    //     $table.find('tr').each(function (index, item) {
-    //       if (index !== 0) {
-    //         var $td = $(item).find('td');
-    //         storage.push({
-    //           title: $td.eq(1).find('a').html(),
-    //           time: $td.eq(2).html(),
-    //         });
-    //       }
-    //     });
-    //   }
-    //   return storage;
-    // });
-    // console.log(data);
-    // await browser.close();
-    // return JSON.stringify(data);
   }
 }
 

+ 2 - 0
package.json

@@ -7,10 +7,12 @@
     "framework": "naf-framework-mongoose"
   },
   "dependencies": {
+    "cheerio": "^1.0.0-rc.3",
     "egg-redis": "^2.4.0",
     "naf-framework-mongoose": "^0.6.12",
     "redis": "^2.8.0",
     "string-random": "^0.1.3",
+    "superagent": "^5.1.0",
     "svg-captcha": "^1.4.0"
   },
   "devDependencies": {